import { chmodSync, copyFileSync, existsSync, readFileSync, statSync, writeFileSync } from "node:fs";
import { join } from "node:path";
import { spawnSync } from "node:child_process";
import { rootPath, type UniDeskConfig } from "./config";
import type { RenderedCliResult } from "./output";
import { applyLocalCaddyManagedSite } from "./pk01-caddy";
import { runSshCommandCapture, type SshCaptureResult } from "./ssh";
import { runRemoteSshCommandCapture } from "./remote";
import { startJob } from "./jobs";
import {
  AGENTRUN_CONFIG_PATH,
  agentRunLaneSummary,
  agentRunPipelineRunName,
  agentRunProviderCredentialRefs,
  resolveAgentRunLaneTarget,
  type AgentRunLaneSpec,
} from "./agentrun-lanes";
import {
  agentRunImageArtifact,
  placeholderAgentRunImage,
  renderedFilesDigest,
  renderedObjectsDigest,
  renderAgentRunControlPlaneManifests,
  renderAgentRunGitopsFiles,
  type AgentRunArtifactService,
} from "./agentrun-manifests";
import { sha256Fingerprint } from "./platform-infra-ops-library";

export function agentRunHelp(): unknown {
  return {
    command: "agentrun get|describe|events|logs|result|ack|cancel|dispatch|create|apply|send|explain",
    output: "human by default; use -o json|yaml or --raw for machine/debug output",
    usage: [
      "bun scripts/cli.ts agentrun get tasks --queue commander --limit 20",
      "bun scripts/cli.ts agentrun describe run/<runId> --node D601 --lane v02",
      "bun scripts/cli.ts agentrun get tasks -o wide",
      "bun scripts/cli.ts agentrun get tasks -o json",
      "bun scripts/cli.ts agentrun describe task/<taskId>",
      "bun scripts/cli.ts agentrun events run/<runId> --after-seq 0 --limit 100",
      "bun scripts/cli.ts agentrun logs session/<sessionId> --tail 100",
      "bun scripts/cli.ts agentrun result run/<runId> --command <commandId>",
      "bun scripts/cli.ts agentrun ack task/<taskId> --reader-id cli",
      "bun scripts/cli.ts agentrun cancel task/<taskId> --reason <text> --dry-run",
      "bun scripts/cli.ts agentrun dispatch task/<taskId>",
      "bun scripts/cli.ts agentrun create task --aipod Artificer --prompt-stdin --idempotency-key <key>",
      "bun scripts/cli.ts agentrun apply -f - --dry-run",
      "bun scripts/cli.ts agentrun send session/<sessionId> --aipod Artificer --prompt-stdin",
      "bun scripts/cli.ts agentrun explain task",
      "bun scripts/cli.ts agentrun explain session-policy",
      "bun scripts/cli.ts agentrun control-plane plan --node D601 --lane v02",
      "bun scripts/cli.ts agentrun control-plane apply --node D601 --lane v02 --dry-run",
      "bun scripts/cli.ts agentrun control-plane status --node D601 --lane v02",
      "bun scripts/cli.ts agentrun control-plane secret-sync --node D601 --lane v02 --dry-run",
      "bun scripts/cli.ts agentrun control-plane secret-sync --node D601 --lane v02 --confirm",
      "bun scripts/cli.ts agentrun control-plane restart --node D601 --lane v02 --dry-run",
      "bun scripts/cli.ts agentrun control-plane restart --node D601 --lane v02 --confirm",
      "bun scripts/cli.ts agentrun control-plane trigger-current --node D601 --lane v02 --dry-run",
      "bun scripts/cli.ts agentrun control-plane trigger-current --node D601 --lane v02 --confirm",
      "bun scripts/cli.ts agentrun control-plane status",
      "bun scripts/cli.ts agentrun control-plane status --full",
      "bun scripts/cli.ts agentrun control-plane status --pipeline-run agentrun-vNN-ci-<short-sha>",
      "bun scripts/cli.ts agentrun control-plane status --source-commit <full-sha>",
      "bun scripts/cli.ts agentrun control-plane expose --dry-run",
      "bun scripts/cli.ts agentrun control-plane expose --confirm",
      "bun scripts/cli.ts agentrun control-plane trigger-current --dry-run",
      "bun scripts/cli.ts agentrun control-plane trigger-current --confirm",
      "bun scripts/cli.ts agentrun control-plane refresh --dry-run",
      "bun scripts/cli.ts agentrun control-plane refresh --confirm",
      "bun scripts/cli.ts agentrun control-plane cleanup-runners --node D601 --lane v02 --dry-run",
      "bun scripts/cli.ts agentrun control-plane cleanup-runners --node D601 --lane v02 --confirm",
      "bun scripts/cli.ts agentrun control-plane cleanup-runs --min-age-minutes 30 --limit 200 --dry-run",
      "bun scripts/cli.ts agentrun control-plane cleanup-runs --min-age-minutes 30 --limit 200 --confirm",
      "bun scripts/cli.ts agentrun control-plane cleanup-released-pvs --limit 200 --dry-run",
      "bun scripts/cli.ts agentrun control-plane cleanup-released-pvs --limit 200 --confirm",
      "bun scripts/cli.ts agentrun git-mirror status",
      "bun scripts/cli.ts agentrun git-mirror status --full",
      "bun scripts/cli.ts agentrun git-mirror sync --confirm",
      "bun scripts/cli.ts agentrun git-mirror flush --confirm",
    ],
    resources: ["task/qt", "run", "command/cmd", "runnerjob/rjob", "session/ses", "aipodspec/aps"],
    description: "Operate AgentRun through Kubernetes-style resource verbs. Human output is compact by default; -o json|yaml returns the UniDesk render-only client schema, --raw exposes the REST envelope, and --node/--lane targets a YAML-declared runtime lane.",
    legacyCompatibility: "queue/runs/commands/runner/sessions/aipod-specs remain as compatibility groups backed by direct HTTP; new commander work should use get/describe/events/logs/result/ack/cancel/dispatch/create/apply/send. sessions turn/steer are removed; use send only.",
  };
}

export async function runAgentRunCommand(config: UniDeskConfig | null, args: string[]): Promise<Record<string, unknown> | RenderedCliResult> {
  const route = normalizeAgentRunCommandArgs(args);
  const { group, action, actionArgs } = route;
  if (group === undefined || isHelpArg(group)) return renderAgentRunHelp(route.canonicalArgs);
  if (isHelpArg(action) || actionArgs.some(isHelpArg)) return renderAgentRunHelp(route.canonicalArgs);
  if (isResourceVerb(group)) return await runAgentRunResourceCommand(config, group, action, actionArgs, route.canonicalArgs);
  if (isAgentRunRestCompatGroup(group)) {
    return await runAgentRunRestCompatCommand(config, group, route.forwardArgs, route.canonicalArgs);
  }
  if (config === null) throw new Error("agentrun control-plane and git-mirror commands require UniDesk config");
  if (group === "control-plane") {
    if (action === "plan") return await controlPlanePlan(config, parseStatusOptions(actionArgs));
    if (action === "apply") return await controlPlaneApply(config, parseLaneConfirmOptions(actionArgs));
    if (action === "status") {
      const options = parseStatusOptions(actionArgs);
      const result = await status(config, options);
      return options.full || options.raw ? result : renderAgentRunControlPlaneStatusSummary(result);
    }
    if (action === "secret-sync") return await secretSync(config, parseSecretSyncOptions(actionArgs));
    if (action === "restart") return await restartYamlLane(config, parseLaneConfirmOptions(actionArgs));
    if (action === "expose") return await exposeAgentRun(config, parseConfirmOptions(actionArgs));
    if (action === "trigger-current") return await triggerCurrent(config, parseTriggerOptions(actionArgs));
    if (action === "refresh") return await refresh(config, parseRefreshOptions(actionArgs));
    if (action === "cleanup-runners") return await cleanupRunners(config, parseCleanupRunnersOptions(actionArgs));
    if (action === "cleanup-runs") return await cleanupRuns(config, parseCleanupRunsOptions(actionArgs));
    if (action === "cleanup-released-pvs") return await cleanupReleasedPvs(config, parseCleanupReleasedPvOptions(actionArgs));
  }
  if (group === "git-mirror") {
    if (action === "status") return await gitMirrorStatus(config, parseGitMirrorStatusOptions(actionArgs));
    if (action === "sync" || action === "flush") {
      const options = parseGitMirrorOptions(actionArgs);
      const { spec } = resolveAgentRunLaneTarget(options);
      if (options.confirm && !options.wait) {
        return startAsyncAgentRunJob(
          `agentrun_${spec.lane}_git_mirror_${action}`,
          ["bun", "scripts/cli.ts", "agentrun", "git-mirror", action, "--node", spec.nodeId, "--lane", spec.lane, "--confirm", "--wait", "--timeout-seconds", String(options.timeoutSeconds)],
          `Run AgentRun ${spec.version} git mirror ${action} on ${spec.nodeId}`,
        );
      }
      return await runGitMirrorJob(config, action, options);
    }
  }
  return unsupported(route.canonicalArgs);
}

function isAgentRunRestCompatGroup(group: string | undefined): group is AgentRunRestCompatGroup {
  return group === "queue" || group === "sessions" || group === "aipod-specs" || group === "aipods" || group === "runs" || group === "commands" || group === "runner";
}

interface AgentRunCommandRoute {
  canonicalArgs: string[];
  group: string | undefined;
  action: string | undefined;
  actionArgs: string[];
  forwardArgs: string[];
}

function normalizeAgentRunCommandArgs(args: string[]): AgentRunCommandRoute {
  const canonicalArgs = args[0] === "v01" ? args.slice(1) : args;
  const [group, action, ...actionArgs] = canonicalArgs;
  return {
    canonicalArgs,
    group,
    action,
    actionArgs,
    forwardArgs: canonicalArgs.slice(1),
  };
}

function isHelpArg(value: string | undefined): boolean {
  return value === "help" || value === "--help" || value === "-h";
}

function isResourceVerb(value: string | undefined): value is AgentRunResourceVerb {
  return value === "get"
    || value === "describe"
    || value === "events"
    || value === "logs"
    || value === "result"
    || value === "ack"
    || value === "cancel"
    || value === "dispatch"
    || value === "create"
    || value === "apply"
    || value === "send"
    || value === "explain";
}

function renderAgentRunHelp(args: string[]): RenderedCliResult {
  const text = agentRunHelpText(args);
  return renderedCliResult(true, "agentrun help", text);
}

function agentRunHelpText(args: string[]): string {
  const [verb, kind] = args.filter((arg) => !isHelpArg(arg));
  if (verb === "get" && kind !== undefined) return agentRunGetKindHelp(kind);
  if (verb === "get") {
    return [
      "Usage: bun scripts/cli.ts agentrun get <resource> [options]",
      "",
      "Resources: tasks|sessions|runs|commands|runnerjobs|aipodspecs",
      "Output: table by default; use -o wide|name|json|yaml.",
      "",
      "Examples:",
      "  bun scripts/cli.ts agentrun get tasks --queue commander --limit 20",
      "  bun scripts/cli.ts agentrun get sessions --limit 20",
      "  bun scripts/cli.ts agentrun get tasks -o json",
    ].join("\n");
  }
  if (verb === "describe") {
    return [
      "Usage: bun scripts/cli.ts agentrun describe <kind/name> [--node <node> --lane <lane>] [--full] [-o json|yaml] [--raw]",
      "",
      "Kinds: task|run|command|runnerjob|session|aipodspec",
      "Examples:",
      "  bun scripts/cli.ts agentrun describe task/qt_...",
      "  bun scripts/cli.ts agentrun describe run/<runId> --node D601 --lane v02",
      "  bun scripts/cli.ts agentrun describe command/cmd_... --run <runId>",
      "  bun scripts/cli.ts agentrun describe session/<sessionId> --full",
    ].join("\n");
  }
  if (verb === "events") {
    return "Usage: bun scripts/cli.ts agentrun events run/<runId> [--after-seq N] [--limit 100] [-o json|yaml] [--raw]";
  }
  if (verb === "logs") {
    return "Usage: bun scripts/cli.ts agentrun logs session/<sessionId> [--tail 100|--after-seq N] [--limit 100] [--full-text] [-o json|yaml] [--raw]";
  }
  if (verb === "result") {
    return "Usage: bun scripts/cli.ts agentrun result run/<runId> --command <commandId> | agentrun result command/<commandId> --run <runId>";
  }
  if (verb === "ack") {
    return "Usage: bun scripts/cli.ts agentrun ack task/<taskId>|session/<sessionId> [--reader-id cli]";
  }
  if (verb === "cancel") {
    return "Usage: bun scripts/cli.ts agentrun cancel task/<taskId>|session/<sessionId>|run/<runId>|command/<commandId> --reason <text> [--run <runId>] [--dry-run]";
  }
  if (verb === "dispatch") {
    return "Usage: bun scripts/cli.ts agentrun dispatch task/<taskId>";
  }
  if (verb === "create") {
    return "Usage: bun scripts/cli.ts agentrun create task --aipod Artificer --prompt-stdin [--idempotency-key <key>] [--dry-run]";
  }
  if (verb === "apply") {
    return "Usage: bun scripts/cli.ts agentrun apply -f task.yaml|json|- [--dry-run]\nTask manifests use kind: Task and spec: <AgentRun task payload>.";
  }
  if (verb === "send") {
    return "Usage: bun scripts/cli.ts agentrun send session/<sessionId> --aipod Artificer --prompt-stdin\nThe server decides whether this becomes an internal steer or a new turn from session state.";
  }
  if (verb === "explain") return agentRunExplain(kind ?? "task");
  if (verb === "control-plane") {
    return [
      "Usage: bun scripts/cli.ts agentrun control-plane <action> [options]",
      "",
      "Actions: plan, apply, status, secret-sync, expose, trigger-current, refresh, cleanup-runners, cleanup-runs, cleanup-released-pvs",
      "Examples:",
      "  bun scripts/cli.ts agentrun control-plane plan --node D601 --lane v02",
      "  bun scripts/cli.ts agentrun control-plane apply --node D601 --lane v02 --dry-run",
      "  bun scripts/cli.ts agentrun control-plane status --node D601 --lane v02",
      "  bun scripts/cli.ts agentrun control-plane secret-sync --node D601 --lane v02 --dry-run",
      "  bun scripts/cli.ts agentrun control-plane trigger-current --node D601 --lane v02 --dry-run",
      "  bun scripts/cli.ts agentrun control-plane status",
      "  bun scripts/cli.ts agentrun control-plane status --pipeline-run agentrun-vNN-ci-<short-sha>",
      "  bun scripts/cli.ts agentrun control-plane expose --dry-run",
      "  bun scripts/cli.ts agentrun control-plane trigger-current --dry-run",
      "  bun scripts/cli.ts agentrun control-plane cleanup-runners --node D601 --lane v02 --dry-run",
      "  bun scripts/cli.ts agentrun control-plane cleanup-runs --min-age-minutes 30 --limit 200 --dry-run",
    ].join("\n");
  }
  if (verb === "git-mirror") {
    return [
      "Usage: bun scripts/cli.ts agentrun git-mirror <status|sync|flush> [--full|--raw|--confirm]",
      "",
      "Confirmed sync/flush returns an async job unless --wait is set.",
    ].join("\n");
  }
  if (verb !== undefined && isAgentRunRestCompatGroup(verb)) {
    return [
      `Compatibility group: agentrun ${verb} ...`,
      "",
      "Use resource primitives for daily commander work:",
      "  bun scripts/cli.ts agentrun get tasks --queue commander --limit 20",
      "  bun scripts/cli.ts agentrun describe task/<taskId>",
      "  bun scripts/cli.ts agentrun describe run/<runId> --node D601 --lane v02",
      "  bun scripts/cli.ts agentrun events run/<runId> --after-seq 0 --limit 100",
      "  bun scripts/cli.ts agentrun logs session/<sessionId> --tail 100",
      "",
      "Use --raw on a resource command when you need the direct AgentRun REST envelope.",
    ].join("\n");
  }
  return [
    "Usage: bun scripts/cli.ts agentrun <verb> <resource> [options]",
    "",
    "Verbs: get, describe, events, logs, result, ack, cancel, dispatch, create, apply, send, explain",
    "Resources: task/qt, run, command/cmd, runnerjob/rjob, session/ses, aipodspec/aps",
    "",
    "Common:",
    "  bun scripts/cli.ts agentrun get tasks --queue commander --limit 20",
    "  bun scripts/cli.ts agentrun describe task/<taskId>",
    "  bun scripts/cli.ts agentrun describe run/<runId> --node D601 --lane v02",
    "  bun scripts/cli.ts agentrun events run/<runId> --after-seq 0 --limit 100",
    "  bun scripts/cli.ts agentrun logs session/<sessionId> --tail 100",
    "  bun scripts/cli.ts agentrun create task --aipod Artificer --prompt-stdin",
    "",
    "Machine/debug output:",
    "  -o json|yaml emits a stable UniDesk resource object without the global JSON envelope.",
    "  --raw emits the direct AgentRun REST envelope.",
    "  --node/--lane targets a YAML-declared AgentRun runtime lane; default remains the configured public manager.",
  ].join("\n");
}

function agentRunGetKindHelp(kindRaw: string): string {
  const kind = parseResourceKind(kindRaw);
  if (kind === "task") return "Usage: bun scripts/cli.ts agentrun get tasks [--queue commander] [--state running,pending,completed,failed] [--unread] [--limit 20] [-o wide|name|json|yaml]";
  if (kind === "session") return "Usage: bun scripts/cli.ts agentrun get sessions [--limit 20] [-o wide|name|json|yaml]";
  if (kind === "run") return "Usage: bun scripts/cli.ts agentrun get runs --task <taskId> [--limit 20] [-o wide|name|json|yaml]";
  if (kind === "command") return "Usage: bun scripts/cli.ts agentrun get commands --run <runId> [--command <commandId>] [-o wide|name|json|yaml]";
  if (kind === "runnerjob") return "Usage: bun scripts/cli.ts agentrun get runnerjobs --run <runId> --command <commandId> [-o wide|name|json|yaml]";
  if (kind === "aipodspec") return "Usage: bun scripts/cli.ts agentrun get aipodspecs [-o wide|name|json|yaml]";
  return "Unknown resource. Supported: tasks, sessions, runs, commands, runnerjobs, aipodspecs.";
}

async function runAgentRunResourceCommand(config: UniDeskConfig | null, verb: AgentRunResourceVerb, action: string | undefined, actionArgs: string[], canonicalArgs: string[]): Promise<RenderedCliResult> {
  if (isHelpArg(action) || actionArgs.some(isHelpArg)) return renderAgentRunHelp(canonicalArgs);
  if (verb === "explain") return renderedCliResult(true, "agentrun explain", agentRunExplain(action ?? "task"));
  const resourceArgs = action === undefined ? actionArgs : [action, ...actionArgs];
  const options = parseResourceOptions(resourceArgs);
  const bridgeActionArgs = stripAgentRunResourceWrapperArgs(actionArgs);
  const command = `agentrun ${canonicalArgs.join(" ")}`.trim();
  try {
    return await withAgentRunRestTarget(resolveAgentRunRestTarget(config, options), async () => {
      if (verb === "get") return await resourceGet(config, command, action, bridgeActionArgs, options);
      if (verb === "describe") return await resourceDescribe(config, command, action, bridgeActionArgs, options);
      if (verb === "events") return await resourceEvents(config, command, action, bridgeActionArgs, options);
      if (verb === "logs") return await resourceLogs(config, command, action, bridgeActionArgs, options);
      if (verb === "result") return await resourceResult(config, command, action, bridgeActionArgs, options);
      if (verb === "ack") return await resourceAck(config, command, action, bridgeActionArgs, options);
      if (verb === "cancel") return await resourceCancel(config, command, action, bridgeActionArgs, options);
      if (verb === "dispatch") return await resourceDispatch(config, command, action, bridgeActionArgs, options);
      if (verb === "create") return await resourceCreate(config, command, action, bridgeActionArgs, options);
      if (verb === "apply") return await resourceApply(config, command, bridgeActionArgs, options);
      if (verb === "send") return await resourceSessionPromptCommand(config, command, action, bridgeActionArgs, options);
      return renderedCliResult(false, command, `Unsupported AgentRun resource command. Try: bun scripts/cli.ts agentrun --help`);
    });
  } catch (error) {
    if (error instanceof AgentRunRestError) return renderAgentRunRestError(command, error, options);
    return renderedCliResult(false, command, `Error: ${error instanceof Error ? error.message : String(error)}`);
  }
  return renderedCliResult(false, command, `Unsupported AgentRun resource command. Try: bun scripts/cli.ts agentrun --help`);
}

export function stripAgentRunResourceWrapperArgs(args: string[]): string[] {
  const result: string[] = [];
  for (let index = 0; index < args.length; index += 1) {
    const arg = args[index] ?? "";
    if (arg === "-o" || arg === "--output") {
      index += 1;
      continue;
    }
    if (arg === "--node" || arg === "--lane") {
      index += 1;
      continue;
    }
    if (arg.startsWith("--output=") || arg.startsWith("-o=")) continue;
    if (arg.startsWith("--node=") || arg.startsWith("--lane=")) continue;
    if (arg === "--full" || arg === "--raw" || arg === "--debug" || arg === "--full-text") continue;
    result.push(arg);
  }
  return result;
}

function parseResourceOptions(args: string[]): AgentRunResourceOptions {
  const options: AgentRunResourceOptions = {
    output: "human",
    full: false,
    raw: false,
    debug: false,
    limit: 20,
    queue: null,
    state: null,
    unread: false,
    readerId: "cli",
    taskId: null,
    runId: null,
    commandId: null,
    sessionId: null,
    afterSeq: null,
    tail: null,
    fullText: false,
    reason: null,
    dryRun: false,
    file: null,
    aipod: null,
    idempotencyKey: null,
    promptStdin: false,
    node: null,
    lane: null,
    passthroughArgs: [],
  };
  const valueFlags = new Set(["-o", "--output", "--limit", "--queue", "--state", "--reader-id", "--task", "--task-id", "--run", "--run-id", "--command", "--command-id", "--session", "--session-id", "--after-seq", "--tail", "--reason", "-f", "--file", "--filename", "--aipod", "--idempotency-key", "--node", "--lane"]);
  const booleanFlags = new Set(["--full", "--raw", "--debug", "--unread", "--dry-run", "--full-text", "--prompt-stdin", "--stdin"]);
  for (let index = 0; index < args.length; index += 1) {
    const arg = args[index] ?? "";
    if (!arg.startsWith("-")) continue;
    if (arg.startsWith("--") && arg.includes("=")) {
      const [flag, ...rest] = arg.split("=");
      applyResourceOption(options, flag, rest.join("="));
      continue;
    }
    if (booleanFlags.has(arg)) {
      applyResourceOption(options, arg, null);
      continue;
    }
    if (valueFlags.has(arg)) {
      const value = args[index + 1];
      if (value === undefined || value.startsWith("--")) throw new Error(`${arg} requires a value`);
      applyResourceOption(options, arg, value);
      index += 1;
      continue;
    }
  }
  return options;
}

function applyResourceOption(options: AgentRunResourceOptions, flag: string, value: string | null): void {
  if (flag === "-o" || flag === "--output") {
    if (value !== "human" && value !== "wide" && value !== "name" && value !== "json" && value !== "yaml") throw new Error(`${flag} must be one of human,wide,name,json,yaml`);
    options.output = value;
    return;
  }
  if (flag === "--full") options.full = true;
  else if (flag === "--raw") options.raw = true;
  else if (flag === "--debug") options.debug = true;
  else if (flag === "--unread") options.unread = true;
  else if (flag === "--dry-run") options.dryRun = true;
  else if (flag === "--full-text") options.fullText = true;
  else if (flag === "--prompt-stdin" || flag === "--stdin") options.promptStdin = true;
  else if (flag === "--limit") options.limit = parseNonNegativeInt(value, "--limit", 20, 500);
  else if (flag === "--queue") options.queue = requiredValue(value, flag);
  else if (flag === "--state") options.state = requiredValue(value, flag);
  else if (flag === "--reader-id") options.readerId = requiredValue(value, flag);
  else if (flag === "--task" || flag === "--task-id") options.taskId = requiredValue(value, flag);
  else if (flag === "--run" || flag === "--run-id") options.runId = requiredValue(value, flag);
  else if (flag === "--command" || flag === "--command-id") options.commandId = requiredValue(value, flag);
  else if (flag === "--session" || flag === "--session-id") options.sessionId = requiredValue(value, flag);
  else if (flag === "--after-seq") options.afterSeq = parseNonNegativeInt(value, "--after-seq", 0, Number.MAX_SAFE_INTEGER);
  else if (flag === "--tail") options.tail = parseNonNegativeInt(value, "--tail", 100, 1000);
  else if (flag === "--reason") options.reason = requiredValue(value, flag);
  else if (flag === "-f" || flag === "--file" || flag === "--filename") options.file = requiredValue(value, flag);
  else if (flag === "--aipod") options.aipod = requiredValue(value, flag);
  else if (flag === "--idempotency-key") options.idempotencyKey = requiredValue(value, flag);
  else if (flag === "--node") options.node = requiredValue(value, flag);
  else if (flag === "--lane") options.lane = requiredValue(value, flag);
}

function parseNonNegativeInt(raw: string | null, flag: string, defaultValue: number, maxValue: number): number {
  if (raw === null || raw.length === 0) return defaultValue;
  const value = Number(raw);
  if (!Number.isInteger(value) || value < 0) throw new Error(`${flag} must be a non-negative integer`);
  return Math.min(value, maxValue);
}

function requiredValue(value: string | null, flag: string): string {
  if (value === null || value.length === 0) throw new Error(`${flag} requires a value`);
  return value;
}

async function resourceGet(config: UniDeskConfig | null, command: string, action: string | undefined, args: string[], options: AgentRunResourceOptions): Promise<RenderedCliResult> {
  const kind = parseResourceKind(action);
  if (kind === null) throw new Error("get requires a resource: tasks|sessions|runs|commands|runnerjobs|aipodspecs");
  let result: Record<string, unknown>;
  if (kind === "task") {
    const taskListArgs = options.unread
      ? ["commander", "--reader-id", options.readerId, "--limit", String(options.limit)]
      : [
          "list",
          "--state",
          taskListState(options),
          "--limit",
          String(options.queue === null ? options.limit : Math.max(options.limit, 100)),
          ...(options.queue === null ? [] : ["--queue", options.queue]),
        ];
    result = await runAgentRunRestCommand(config, "queue", taskListArgs);
    return renderResourceResult(command, result, options, "Task", normalizeTaskItems(innerData(result), options).slice(0, options.limit));
  }
  if (kind === "session") {
    result = await runAgentRunRestCommand(config, "sessions", ["ps", "--limit", String(options.limit)]);
    return renderResourceResult(command, result, options, "Session", normalizeSessionItems(innerData(result)).slice(0, options.limit));
  }
  if (kind === "aipodspec") {
    result = await runAgentRunRestCommand(config, "aipod-specs", ["list"]);
    return renderResourceResult(command, result, options, "AipodSpec", normalizeAipodSpecItems(innerData(result)).slice(0, options.limit));
  }
  if (kind === "run" && options.taskId !== null) {
    result = await runAgentRunRestCommand(config, "queue", ["show", options.taskId]);
    const task = record(innerData(result));
    return renderResourceResult(command, result, options, "Run", normalizeAttemptResources(task, "run"));
  }
  if (kind === "command" && options.runId !== null && options.commandId !== null) {
    result = await runAgentRunRestCommand(config, "commands", ["show", options.commandId, "--run-id", options.runId]);
    return renderResourceResult(command, result, options, "Command", normalizeSingleCommand(innerData(result)));
  }
  if (kind === "runnerjob" && options.runId !== null && options.commandId !== null) {
    result = await runAgentRunRestCommand(config, "runner", ["jobs", "--run-id", options.runId, "--command-id", options.commandId]);
    return renderResourceResult(command, result, options, "RunnerJob", normalizeRunnerJobItems(innerData(result)));
  }
  throw new Error(`get ${kind}s requires more context; use --task, --run/--command, or describe <kind>/<id>`);
}

async function resourceDescribe(config: UniDeskConfig | null, command: string, action: string | undefined, args: string[], options: AgentRunResourceOptions): Promise<RenderedCliResult> {
  const ref = parseResourceRef(action, args);
  if (ref.kind === "task") {
    const result = await runAgentRunRestCommand(config, "queue", ["show", ref.name, ...(options.full ? ["--full"] : [])]);
    const data = record(innerData(result));
    const task = unwrapTaskDetail(data);
    if (options.raw) return renderMachine(command, result, "json", result.ok !== false);
    if (options.output === "json" || options.output === "yaml") return renderMachine(command, { kind: ref.kind, name: ref.name, resource: task }, options.output, result.ok !== false);
    return renderedCliResult(result.ok !== false, command, renderTaskDescription(task, options));
  }
  if (ref.kind === "run") {
    const result = await runAgentRunRestCommand(config, "runs", ["show", ref.name, ...(options.full ? ["--full"] : [])]);
    return renderDescribe(command, result, options, ref, renderGenericDescription(ref, innerData(result)));
  }
  if (ref.kind === "command") {
    const runId = options.runId ?? requiredContext("command describe", "--run <runId>");
    const result = await runAgentRunRestCommand(config, "commands", ["show", ref.name, "--run-id", runId, ...(options.full ? ["--full"] : [])]);
    return renderDescribe(command, result, options, ref, renderGenericDescription(ref, innerData(result)));
  }
  if (ref.kind === "runnerjob") {
    const runId = options.runId ?? requiredContext("runnerjob describe", "--run <runId>");
    const result = await runAgentRunRestCommand(config, "runner", ["job-status", ref.name, "--run-id", runId]);
    return renderDescribe(command, result, options, ref, renderGenericDescription(ref, innerData(result)));
  }
  if (ref.kind === "session") {
    const result = await runAgentRunRestCommand(config, "sessions", ["show", ref.name, ...(options.full ? ["--full"] : [])]);
    return renderDescribe(command, result, options, ref, renderGenericDescription(ref, innerData(result)));
  }
  if (ref.kind === "aipodspec") {
    const result = await runAgentRunRestCommand(config, "aipod-specs", ["show", ref.name, ...(options.full ? ["--full"] : [])]);
    return renderDescribe(command, result, options, ref, renderGenericDescription(ref, innerData(result)));
  }
  throw new Error(`unsupported describe kind: ${ref.kind}`);
}

async function resourceEvents(config: UniDeskConfig | null, command: string, action: string | undefined, args: string[], options: AgentRunResourceOptions): Promise<RenderedCliResult> {
  const ref = parseResourceRef(action, args, "run");
  const runId = ref.kind === "run" ? ref.name : options.runId ?? requiredContext("events", "--run <runId>");
  const eventArgs = ["events", runId, "--after-seq", String(options.afterSeq ?? 0), "--limit", String(options.limit), "--tail-summary"];
  const result = await runAgentRunRestCommand(config, "runs", eventArgs);
  return renderEventLike(command, result, options, "Event", normalizeEventItems(innerData(result)), runId);
}

async function resourceLogs(config: UniDeskConfig | null, command: string, action: string | undefined, args: string[], options: AgentRunResourceOptions): Promise<RenderedCliResult> {
  const ref = parseResourceRef(action, args, "session");
  if (ref.kind !== "session") throw new Error("logs currently requires session/<sessionId>");
  const effectiveLimit = options.tail ?? options.limit;
  const logArgs = ["output", ref.name, "--limit", String(effectiveLimit)];
  if (options.afterSeq !== null) logArgs.push("--after-seq", String(options.afterSeq));
  if (options.fullText) logArgs.push("--full-text");
  let result: Record<string, unknown>;
  if (options.afterSeq === null && options.tail !== null) {
    result = await resourceLogsTailResult(config, ref.name, effectiveLimit, options.fullText);
  } else {
    result = await runAgentRunRestCommand(config, "sessions", logArgs);
  }
  return renderEventLike(command, result, { ...options, limit: effectiveLimit }, "Log", normalizeLogItems(innerData(result)), ref.name);
}

async function resourceLogsTailResult(config: UniDeskConfig | null, sessionId: string, limit: number, fullText: boolean): Promise<Record<string, unknown>> {
  const session = record(innerData(await runAgentRunRestCommand(config, "sessions", ["show", sessionId])));
  const lastSeq = nonNegativeIntegerOrNull(session.lastEventSeq) ?? 0;
  let window = Math.max(limit * 4, 100);
  let result: Record<string, unknown> | null = null;
  let data: Record<string, unknown> = {};
  for (let attempt = 0; attempt < 6; attempt += 1) {
    const afterSeq = Math.max(0, lastSeq - window);
    const queryLimit = Math.max(limit, Math.min(1000, window));
    const args = ["output", sessionId, "--limit", String(queryLimit), "--after-seq", String(afterSeq)];
    if (fullText) args.push("--full-text");
    result = await runAgentRunRestCommand(config, "sessions", args);
    data = record(innerData(result));
    const items = arrayRecords(data.items);
    if (items.length >= limit || afterSeq === 0) break;
    window *= 2;
  }
  if (result === null) return await runAgentRunRestCommand(config, "sessions", ["output", sessionId, "--limit", String(limit), "--after-seq", "0"]);
  const items = arrayRecords(data.items);
  const tailedItems = items.slice(-limit);
  const lastReturnedSeq = tailedItems.length > 0 ? nonNegativeIntegerOrNull(tailedItems[tailedItems.length - 1]?.seq) : null;
  return {
    ...result,
    data: {
      ...data,
      items: tailedItems,
      count: tailedItems.length,
      cursor: lastReturnedSeq === null ? data.cursor : String(lastReturnedSeq),
      clientTail: {
        requested: limit,
        sourceLastEventSeq: lastSeq,
        scanned: items.length,
        valuesPrinted: false,
      },
    },
  };
}

async function resourceResult(config: UniDeskConfig | null, command: string, action: string | undefined, args: string[], options: AgentRunResourceOptions): Promise<RenderedCliResult> {
  const ref = parseResourceRef(action, args);
  if (ref.kind === "run") {
    const commandId = options.commandId ?? requiredContext("run result", "--command <commandId>");
    const result = await runAgentRunRestCommand(config, "runs", ["result", ref.name, "--command-id", commandId]);
    return renderResultSummary(command, result, options, ref);
  }
  if (ref.kind === "command") {
    const runId = options.runId ?? requiredContext("command result", "--run <runId>");
    const result = await runAgentRunRestCommand(config, "commands", ["result", ref.name, "--run-id", runId]);
    return renderResultSummary(command, result, options, ref);
  }
  throw new Error("result supports run/<runId> or command/<commandId>");
}

async function resourceAck(config: UniDeskConfig | null, command: string, action: string | undefined, args: string[], options: AgentRunResourceOptions): Promise<RenderedCliResult> {
  const ref = parseResourceRef(action, args, "task");
  const result = ref.kind === "task"
    ? await runAgentRunRestCommand(config, "queue", ["read", ref.name, "--reader-id", options.readerId])
    : ref.kind === "session"
      ? await runAgentRunRestCommand(config, "sessions", ["read", ref.name, "--reader-id", options.readerId])
      : null;
  if (result === null) throw new Error("ack supports task/<taskId> or session/<sessionId>");
  return renderMutationSummary(command, result, options, `Acknowledged ${ref.kind}/${shortId(ref.name)}`);
}

async function resourceCancel(config: UniDeskConfig | null, command: string, action: string | undefined, args: string[], options: AgentRunResourceOptions): Promise<RenderedCliResult> {
  const ref = parseResourceRef(action, args, "task");
  const cancelArgs = ["cancel", ref.name];
  if (options.reason !== null) cancelArgs.push("--reason", options.reason);
  if (ref.kind === "command") cancelArgs.push("--run-id", options.runId ?? requiredContext("command cancel", "--run <runId>"));
  if (options.dryRun) {
    const result = agentRunResourceCancelDryRunPlan(ref, options, rerunWithoutDryRun(command));
    return renderMutationSummary(command, result, options, `Planned cancel ${ref.kind}/${shortId(ref.name)}`, [rerunWithoutDryRun(command)]);
  }
  const result = ref.kind === "task"
    ? await runAgentRunRestCommand(config, "queue", cancelArgs)
    : ref.kind === "session"
      ? await runAgentRunRestCommand(config, "sessions", cancelArgs)
      : ref.kind === "run"
        ? await runAgentRunRestCommand(config, "runs", cancelArgs)
        : ref.kind === "command"
          ? await runAgentRunRestCommand(config, "commands", cancelArgs)
          : null;
  if (result === null) throw new Error("cancel supports task/<taskId>, session/<sessionId>, run/<runId>, or command/<commandId>");
  return renderMutationSummary(command, result, options, `${options.dryRun ? "Planned cancel" : "Cancel requested"} ${ref.kind}/${shortId(ref.name)}`, options.dryRun ? [rerunWithoutDryRun(command)] : undefined);
}

function agentRunResourceCancelDryRunPlan(ref: AgentRunResourceRef, options: AgentRunResourceOptions, confirmCommand: string): Record<string, unknown> {
  const body: Record<string, unknown> = {};
  if (options.reason !== null) body.reason = options.reason;
  if (ref.kind === "task") return agentRunDryRunPlan("task-cancel", `/api/v1/queue/tasks/${encodeURIComponent(ref.name)}/cancel`, body, confirmCommand);
  if (ref.kind === "session") return agentRunDryRunPlan("session-cancel", `/api/v1/sessions/${encodeURIComponent(ref.name)}/control`, { action: "cancel", ...body }, confirmCommand);
  if (ref.kind === "run") return agentRunDryRunPlan("run-cancel", `/api/v1/runs/${encodeURIComponent(ref.name)}/cancel`, body, confirmCommand);
  if (ref.kind === "command") {
    const runId = options.runId ?? requiredContext("command cancel", "--run <runId>");
    return agentRunDryRunPlan("command-cancel", `/api/v1/commands/${encodeURIComponent(ref.name)}/cancel`, body, confirmCommand, "POST", {
      commandRef: { runId, commandId: ref.name, valuesPrinted: false },
    });
  }
  throw new Error("cancel supports task/<taskId>, session/<sessionId>, run/<runId>, or command/<commandId>");
}

async function resourceDispatch(config: UniDeskConfig | null, command: string, action: string | undefined, args: string[], options: AgentRunResourceOptions): Promise<RenderedCliResult> {
  const ref = parseResourceRef(action, args, "task");
  if (ref.kind !== "task") throw new Error("dispatch supports task/<taskId>");
  const result = await runAgentRunRestCommand(config, "queue", ["dispatch", ref.name, ...stripLeadingResource(args, ref.name)]);
  return renderMutationSummary(command, result, options, `Task dispatch submitted ${shortId(ref.name)}`, [
    `bun scripts/cli.ts agentrun describe task/${ref.name}`,
  ]);
}

async function resourceCreate(config: UniDeskConfig | null, command: string, action: string | undefined, args: string[], options: AgentRunResourceOptions): Promise<RenderedCliResult> {
  const kind = parseResourceKind(action);
  if (kind !== "task") throw new Error("create currently supports: create task");
  const submitArgs = ["submit", ...stripLeadingResource(args, "task")];
  const result = await runAgentRunRestCommand(config, "queue", submitArgs);
  return renderMutationSummary(command, result, options, "Task create submitted", options.dryRun ? [rerunWithoutDryRun(command)] : undefined);
}

async function resourceApply(config: UniDeskConfig | null, command: string, args: string[], options: AgentRunResourceOptions): Promise<RenderedCliResult> {
  void config;
  const file = options.file ?? requiredContext("apply", "-f <file>|-");
  const raw = file === "-" ? readFileSync(0, "utf8") : readFileSync(file, "utf8");
  const parsed = parseTaskManifest(raw, file);
  const result = options.dryRun
    ? agentRunDryRunPlan("queue-submit", "/api/v1/queue/tasks", parsed, `bun scripts/cli.ts ${command.replace(/\s+--dry-run\b/gu, "").trim()}`)
    : await agentRunRestRequest("agentrun queue submit", "POST", "/api/v1/queue/tasks", parsed);
  return renderMutationSummary(command, result, options, `${options.dryRun ? "Dry-run applied" : "Applied"} task manifest`, options.dryRun ? [rerunWithoutDryRun(command)] : undefined);
}

async function resourceSessionPromptCommand(config: UniDeskConfig | null, command: string, action: string | undefined, args: string[], options: AgentRunResourceOptions): Promise<RenderedCliResult> {
  const ref = parseResourceRef(action, args, "session");
  if (ref.kind !== "session") throw new Error("send requires session/<sessionId>");
  const sessionArgs = ["send", ref.name, ...stripLeadingResource(args, ref.name)];
  const result = await runAgentRunRestCommand(config, "sessions", sessionArgs);
  return renderMutationSummary(command, result, options, options.dryRun ? "Session send plan" : "Session send submitted");
}

function renderedCliResult(ok: boolean, command: string, renderedText: string, contentType: RenderedCliResult["contentType"] = "text/plain"): RenderedCliResult {
  return { ok, command, renderedText, contentType };
}

function renderResourceResult(command: string, raw: Record<string, unknown>, options: AgentRunResourceOptions, kindLabel: string, items: Record<string, unknown>[]): RenderedCliResult {
  if (options.raw) return renderMachine(command, raw, "json", raw.ok !== false);
  const payload = { kind: `${kindLabel}List`, count: items.length, items };
  if (options.output === "json" || options.output === "yaml") return renderMachine(command, payload, options.output);
  if (options.output === "name") return renderedCliResult(raw.ok !== false, command, items.map((item) => `${String(item.kind ?? kindLabel).toLowerCase()}/${String(item.name ?? "")}`).join("\n"));
  if (items.length === 0) return renderedCliResult(raw.ok !== false, command, `No ${kindLabel.toLowerCase()} resources found.`);
  return renderedCliResult(raw.ok !== false, command, renderResourceTable(items, options.output === "wide"));
}

function renderDescribe(command: string, raw: Record<string, unknown>, options: AgentRunResourceOptions, ref: AgentRunResourceRef, text: string): RenderedCliResult {
  if (options.raw) return renderMachine(command, raw, "json", raw.ok !== false);
  if (options.output === "json" || options.output === "yaml") return renderMachine(command, { kind: ref.kind, name: ref.name, resource: innerData(raw) }, options.output, raw.ok !== false);
  return renderedCliResult(raw.ok !== false, command, text);
}

function renderEventLike(command: string, raw: Record<string, unknown>, options: AgentRunResourceOptions, kind: string, items: Record<string, unknown>[], sourceName: string): RenderedCliResult {
  if (options.raw) return renderMachine(command, raw, "json", raw.ok !== false);
  const data = record(innerData(raw));
  const payload = { kind: `${kind}List`, source: sourceName, nextAfterSeq: data.nextAfterSeq ?? null, count: items.length, items };
  if (options.output === "json" || options.output === "yaml") return renderMachine(command, payload, options.output, raw.ok !== false);
  const lines = [
    `${kind}s for ${sourceName}`,
    renderTable(["SEQ", "TYPE", "STATUS", "COMMAND", "SUMMARY"], items.map((item) => [
      String(item.seq ?? "-"),
      String(item.type ?? "-"),
      String(item.status ?? item.phase ?? "-"),
      shortId(String(item.commandId ?? "-")),
      truncateOneLine(String(item.summary ?? item.text ?? "") || "-", 96),
    ])),
  ];
  if (data.nextAfterSeq !== undefined && data.nextAfterSeq !== null) lines.push(`Next: bun scripts/cli.ts ${nextPagedResourceCommand(command, String(data.nextAfterSeq), options.limit)}`);
  return renderedCliResult(raw.ok !== false, command, lines.join("\n"));
}

function renderResultSummary(command: string, raw: Record<string, unknown>, options: AgentRunResourceOptions, ref: AgentRunResourceRef): RenderedCliResult {
  if (options.raw) return renderMachine(command, raw, "json", raw.ok !== false);
  const data = record(innerData(raw));
  if (options.output === "json" || options.output === "yaml") return renderMachine(command, { kind: "Result", ref, result: data }, options.output, raw.ok !== false);
  const executionOk = typeof data.executionOk === "boolean"
    ? data.executionOk
    : typeof data.ok === "boolean"
      ? data.ok
      : raw.ok !== false;
  const lines = [
    `Result: ${ref.kind}/${shortId(ref.name)}`,
    `State:  ${displayValue(data.state ?? data.status ?? data.terminalStatus ?? "-")}`,
    `OK:     ${String(executionOk)}`,
  ];
  const providerTerminalFailure = typeof data.providerTerminalFailure === "boolean" ? data.providerTerminalFailure : null;
  const authority = stringOrNull(data.finalResponseAuthority);
  const fallback = typeof data.finalResponseFallback === "boolean" ? data.finalResponseFallback : null;
  const needsContinuation = typeof data.needsContinuation === "boolean" ? data.needsContinuation : null;
  if (providerTerminalFailure !== null) lines.push(`ProviderTerminalFailure: ${String(providerTerminalFailure)}`);
  if (authority !== null) lines.push(`Authority: ${authority}`);
  if (fallback !== null) lines.push(`Fallback: ${String(fallback)}`);
  if (needsContinuation !== null) lines.push(`NeedsContinuation: ${String(needsContinuation)}`);
  const finalRecord = record(data.finalResponse);
  const final = stringOrNull(data.finalResponse)
    ?? stringOrNull(finalRecord.content)
    ?? stringOrNull(finalRecord.text)
    ?? stringOrNull(finalRecord.message)
    ?? stringOrNull(data.output)
    ?? stringOrNull(data.summary)
    ?? stringOrNull(data.result);
  if (final !== null) lines.push("", truncateMultiline(final, options.fullText ? 8000 : 1600));
  else {
    const failure = renderFailureLines(data);
    lines.push("", ...(failure.length > 0 ? failure : ["No final response is available yet."]));
  }
  return renderedCliResult(raw.ok !== false, command, lines.join("\n"));
}

function renderMutationSummary(command: string, raw: Record<string, unknown>, options: AgentRunResourceOptions, headline: string, overrideNextLines?: string[]): RenderedCliResult {
  if (options.raw) return renderMachine(command, raw, "json", raw.ok !== false);
  if (options.output === "json" || options.output === "yaml") return renderMachine(command, raw, options.output, raw.ok !== false);
  const data = record(innerData(raw));
  const id = stringOrNull(data.id) ?? stringOrNull(data.taskId) ?? stringOrNull(data.sessionId);
  const lines = [
    headline,
    `OK: ${String(raw.ok !== false)}`,
  ];
  if (id !== null) lines.push(`Name: ${id}`);
  const decision = stringOrNull(data.decision);
  const internalCommandType = stringOrNull(data.internalCommandType);
  if (data.dryRun !== undefined) lines.push(`DryRun: ${String(data.dryRun)}`);
  if (data.mutation !== undefined) lines.push(`Mutation: ${String(data.mutation)}`);
  if (decision !== null) lines.push(`Decision: ${decision}`);
  if (internalCommandType !== null) lines.push(`InternalCommandType: ${internalCommandType}`);
  const next = record(raw.next ?? data.next);
  const nextLines = (overrideNextLines ?? Object.values(next).map(String)).filter((line) => line.length > 0).slice(0, 5);
  if (nextLines.length > 0) lines.push("", "Next:", ...nextLines.map((line) => `  ${line}`));
  return renderedCliResult(raw.ok !== false, command, lines.join("\n"));
}

function rerunWithoutDryRun(command: string): string {
  return `bun scripts/cli.ts ${command.replace(/\s+--dry-run\b/gu, "").trim()}`;
}

function renderMachine(command: string, value: unknown, mode: "json" | "yaml", ok = true): RenderedCliResult {
  const text = mode === "json" ? `${JSON.stringify(value, null, 2)}\n` : `${Bun.YAML.stringify(value)}\n`;
  return renderedCliResult(ok, command, text, mode === "json" ? "application/json" : "application/yaml");
}

function parseResourceKind(raw: string | undefined): AgentRunResourceKind | null {
  if (raw === undefined) return null;
  const value = raw.toLowerCase().replace(/s$/u, "");
  if (value === "task" || value === "qt" || value === "queue" || value === "queuetask") return "task";
  if (value === "run") return "run";
  if (value === "command" || value === "cmd") return "command";
  if (value === "runnerjob" || value === "runner-job" || value === "rjob" || value === "job") return "runnerjob";
  if (value === "session" || value === "ses") return "session";
  if (value === "aipodspec" || value === "aipod-spec" || value === "aipod-specs" || value === "aps") return "aipodspec";
  return null;
}

function parseResourceRef(action: string | undefined, args: string[], defaultKind: AgentRunResourceKind | null = null): AgentRunResourceRef {
  const raw = action ?? "";
  if (raw.includes("/")) {
    const [kindRaw, ...nameParts] = raw.split("/");
    const kind = parseResourceKind(kindRaw);
    const name = nameParts.join("/");
    if (kind === null || name.length === 0) throw new Error(`invalid resource reference: ${raw}`);
    return { kind, name };
  }
  const kind = parseResourceKind(raw);
  if (kind !== null) {
    const name = args.find((arg) => !arg.startsWith("-") && arg !== raw);
    if (name === undefined) throw new Error(`${kind} reference requires a name`);
    return { kind, name };
  }
  if (defaultKind !== null && raw.length > 0) return { kind: defaultKind, name: raw };
  throw new Error("resource reference required, for example task/<id> or session/<id>");
}

function stripLeadingResource(args: string[], resourceName: string): string[] {
  let skipped = false;
  const result: string[] = [];
  for (const arg of args) {
    if (!skipped && (arg === resourceName || arg.endsWith(`/${resourceName}`) || parseResourceKind(arg) !== null)) {
      skipped = true;
      continue;
    }
    result.push(arg);
  }
  return result;
}

function requiredContext(context: string, flag: string): never {
  throw new Error(`${context} requires ${flag}`);
}

function innerData(raw: Record<string, unknown>): unknown {
  const data = raw.data;
  if (typeof data === "object" && data !== null && "data" in data && Object.keys(raw).length <= 3) return record(data).data;
  return data ?? raw;
}

function normalizeTaskItems(data: unknown, options: AgentRunResourceOptions): Record<string, unknown>[] {
  const items = arrayRecords(record(data).items ?? data);
  return items
    .filter((item) => options.queue === null || String(item.queue ?? "") === options.queue)
    .filter((item) => options.state === null || options.state.split(",").includes(String(item.state ?? "")))
    .filter((item) => !options.unread || item.unread === true || item.attention === true)
    .map((item) => {
      const attempt = record(item.latestAttempt);
      return {
        kind: "task",
        name: item.id,
        state: item.state,
        queue: item.queue,
        lane: item.lane,
        profile: item.backendProfile,
        run: attempt.runId,
        command: attempt.commandId,
        runnerjob: attempt.runnerJobId,
        session: attempt.sessionId ?? stringOrNull(record(item.sessionRef).sessionId),
        age: relativeAge(stringOrNull(item.updatedAt) ?? stringOrNull(item.createdAt)),
        title: item.title,
        updatedAt: item.updatedAt,
        attention: item.unread === true || item.attention === true ? "unread" : "",
      };
    });
}

function taskListState(options: AgentRunResourceOptions): string {
  const requested = options.state?.split(",").map((item) => item.trim()).filter((item) => item.length > 0);
  return requested?.[0] ?? "running";
}

function normalizeSessionItems(data: unknown): Record<string, unknown>[] {
  const items = arrayRecords(record(data).items ?? data);
  return items.map((item) => ({
    kind: "session",
    name: item.id ?? item.sessionId ?? item.name,
    state: item.state ?? item.status ?? item.phase ?? "-",
    queue: item.queue ?? "",
    lane: item.lane ?? "",
    profile: item.backendProfile ?? item.profile ?? "",
    run: item.runId ?? "",
    command: item.commandId ?? "",
    runnerjob: item.runnerJobId ?? "",
    session: item.id ?? item.sessionId ?? item.name,
    age: relativeAge(stringOrNull(item.updatedAt) ?? stringOrNull(item.createdAt)),
    title: item.title ?? "",
  }));
}

function normalizeAipodSpecItems(data: unknown): Record<string, unknown>[] {
  const items = arrayRecords(record(data).items ?? data);
  return items.map((item) => ({
    kind: "aipodspec",
    name: item.name ?? item.id ?? item.metadata?.toString(),
    state: item.state ?? "available",
    queue: "",
    lane: item.lane ?? "",
    profile: item.backendProfile ?? item.profile ?? "",
    title: item.description ?? item.title ?? "",
  }));
}

function normalizeAttemptResources(task: Record<string, unknown>, kind: "run" | "command" | "runnerjob"): Record<string, unknown>[] {
  const attempt = record(task.latestAttempt);
  const key = kind === "run" ? "runId" : kind === "command" ? "commandId" : "runnerJobId";
  const name = stringOrNull(attempt[key]);
  if (name === null) return [];
  return [{
    kind,
    name,
    state: attempt.state ?? task.state,
    queue: task.queue,
    lane: task.lane,
    run: attempt.runId,
    command: attempt.commandId,
    runnerjob: attempt.runnerJobId,
    session: attempt.sessionId,
    title: task.title,
  }];
}

function normalizeSingleCommand(data: unknown): Record<string, unknown>[] {
  const item = record(data);
  return [{
    kind: "command",
    name: item.id ?? item.commandId ?? "",
    state: item.state ?? item.status ?? "",
    run: item.runId ?? "",
    command: item.id ?? item.commandId ?? "",
    session: item.sessionId ?? "",
    title: item.summary ?? item.commandType ?? "",
  }];
}

function normalizeRunnerJobItems(data: unknown): Record<string, unknown>[] {
  const items = arrayRecords(record(data).items ?? data);
  return items.map((item) => ({
    kind: "runnerjob",
    name: item.id ?? item.runnerJobId ?? item.name ?? item.jobName,
    state: item.phase ?? item.state ?? item.status ?? "",
    run: item.runId ?? "",
    command: item.commandId ?? "",
    runnerjob: item.id ?? item.runnerJobId ?? item.name ?? item.jobName,
    session: item.sessionId ?? "",
    title: item.image ?? item.namespace ?? "",
  }));
}

function normalizeEventItems(data: unknown): Record<string, unknown>[] {
  return arrayRecords(record(data).items ?? data).map((item) => {
    const payload = record(item.payload);
    return {
      seq: item.seq,
      type: item.type,
      status: agentRunEventStatus(item, payload),
      phase: item.phase ?? payload.phase,
      commandId: agentRunEventCommandId(item, payload),
      summary: agentRunEventSummary(item, payload),
    };
  });
}

function normalizeLogItems(data: unknown): Record<string, unknown>[] {
  return arrayRecords(record(data).items ?? data).map((item) => {
    const payload = record(item.payload);
    return {
      seq: item.seq,
      type: item.type ?? item.role ?? "output",
      status: agentRunEventStatus(item, payload),
      commandId: agentRunEventCommandId(item, payload),
      summary: agentRunEventSummary(item, payload),
    };
  });
}

function agentRunEventCommandId(item: Record<string, unknown>, payload: Record<string, unknown>): string {
  return stringOrNull(item.commandId)
    ?? stringOrNull(payload.commandId)
    ?? stringOrNull(record(payload.summary).commandId)
    ?? "-";
}

function agentRunEventStatus(item: Record<string, unknown>, payload: Record<string, unknown>): string {
  return stringOrNull(item.status)
    ?? stringOrNull(item.phase)
    ?? stringOrNull(payload.status)
    ?? stringOrNull(payload.phase)
    ?? stringOrNull(payload.failureKind)
    ?? (item.type === "error" ? "error" : "");
}

function agentRunEventSummary(item: Record<string, unknown>, payload: Record<string, unknown>): string {
  const type = stringOrNull(item.type);
  const parts: string[] = [];
  const push = (value: unknown): void => {
    const text = eventText(value);
    if (text !== null && !parts.includes(text)) parts.push(text);
  };

  if (type === "error") {
    push(payload.failureKind);
    const error = record(payload.error);
    push(error.message);
    push(error.additionalDetails);
    if (payload.willRetry === true) push("willRetry=true");
  }

  if (type === "backend_status") {
    push(payload.phase);
    push(formatCountField("tools", record(payload.tools).count));
    push(formatCountField("bundles", record(payload.bundles).count));
    push(formatCountField("promptRefs", record(payload.promptRefs).count));
    push(payload.jobName);
    push(payload.namespace);
  }

  if (type === "tool_call") {
    push(payload.summary);
    push(payload.toolName);
    push(payload.command);
    const exitCode = payload.exitCode;
    if (exitCode !== undefined && exitCode !== null) push(`exit=${String(exitCode)}`);
    push(payload.outputSummary);
  }

  if (type === "command_output") {
    push(commandOutputSummary(payload));
  }

  if (type === "assistant_message") {
    push(payload.summary);
    push(payload.text);
  }

  push(item.summary);
  push(item.outputSummary);
  push(item.text);
  if (type !== "command_output") {
    push(payload.summary);
    push(payload.outputSummary);
    push(payload.text);
  }
  push(payload.message);
  push(payload.reason);

  return parts.join("; ");
}

function commandOutputSummary(payload: Record<string, unknown>): string | null {
  const raw = commandOutputText(payload);
  if (raw === null) return null;
  const structured = parseJsonRecordFromText(raw);
  if (structured !== null) {
    const summary = summarizeStructuredCliOutput(structured);
    if (summary !== null) return summary;
  }
  return summarizePartialJsonCommandOutput(raw) ?? summarizeTextCommandOutput(raw);
}

function commandOutputText(payload: Record<string, unknown>): string | null {
  const summary = record(payload.summary);
  const summaryText = stringOrNull(summary.text);
  const payloadText = stringOrNull(payload.text);
  if (summary.textTruncated === true && payloadText !== null) return payloadText;
  return summaryText
    ?? payloadText
    ?? stringOrNull(payload.outputSummary)
    ?? eventText(payload.summary);
}

function parseJsonRecordFromText(raw: string): Record<string, unknown> | null {
  const trimmed = raw.trim();
  const direct = tryParseJsonRecord(trimmed);
  if (direct !== null) return direct;

  const firstBrace = trimmed.indexOf("{");
  const lastBrace = trimmed.lastIndexOf("}");
  if (firstBrace >= 0 && lastBrace > firstBrace) {
    const sliced = tryParseJsonRecord(trimmed.slice(firstBrace, lastBrace + 1));
    if (sliced !== null) return sliced;
  }

  const line = trimmed
    .split(/\r?\n/u)
    .map((item) => item.trim())
    .reverse()
    .find((item) => item.startsWith("{") && item.endsWith("}"));
  return line === undefined ? null : tryParseJsonRecord(line);
}

function tryParseJsonRecord(raw: string): Record<string, unknown> | null {
  try {
    const parsed = JSON.parse(raw) as unknown;
    return isRecord(parsed) ? parsed : null;
  } catch {
    return null;
  }
}

function summarizeStructuredCliOutput(value: Record<string, unknown>): string | null {
  const parts: string[] = [];
  const action = firstPathText(value, ["action", "operation", "command", "kind"]);
  const status = firstPathText(value, ["status", "state", "phase", "body.status"]);
  const failure = firstPathText(value, ["failureKind", "error.failureKind", "body.failureKind"]);
  const message = firstPathText(value, ["error.message", "error.additionalDetails", "message", "reason", "body.message", "body.error", "result.message"]);
  const primary = [
    action,
    status,
    labeledSummaryValue("http", firstPathText(value, ["httpStatus", "request.httpStatus"])),
  ].filter((item): item is string => item !== null);
  if (primary.length > 0) pushSummaryPart(parts, primary.join(" "));

  pushLabeledSummaryPart(parts, "failure", failure);
  if (failure !== null || isFailureLikeStatus(status)) pushLabeledSummaryPart(parts, "message", message);
  pushLabeledSummaryPart(parts, "trace", firstPathText(value, ["traceId", "lastTraceId", "trace.traceId", "trace.id", "body.traceId", "body.trace.id", "providerTrace.traceId", "runnerTrace.traceId"]), true);
  pushLabeledSummaryPart(parts, "session", firstPathText(value, ["sessionId", "session.sessionId", "body.sessionId", "workspace.selectedAgentSessionId", "workspace.selectedConversation.sessionId"]), true);
  pushLabeledSummaryPart(parts, "conversation", firstPathText(value, ["conversationId", "session.conversationId", "body.conversationId", "workspace.selectedConversationId", "workspace.selectedConversation.conversationId"]), true);
  pushLabeledSummaryPart(parts, "thread", firstPathText(value, ["threadId", "session.threadId", "body.threadId", "workspace.selectedConversation.threadId"]), true);
  pushLabeledSummaryPart(parts, "provider", firstPathText(value, ["providerProfile", "backendProfile", "profile", "session.providerProfile", "workspace.providerProfile"]));
  pushLabeledSummaryPart(parts, "route", commandOutputRouteSummary(value));
  pushLabeledSummaryPart(parts, "pipeline", firstPathText(value, ["pipelineRun", "pipelineRunName", "pipelineRun.name", "pipeline.runName", "pipeline.name"]), true);
  pushLabeledSummaryPart(parts, "run", firstPathText(value, ["runId", "agentRun.runId"]), true);
  pushLabeledSummaryPart(parts, "cmd", firstPathText(value, ["commandId", "agentRun.commandId", "providerTrace.commandId", "runnerTrace.commandId"]), true);
  pushLabeledSummaryPart(parts, "job", firstPathText(value, ["jobName", "agentRun.jobName", "runnerJobId"]), true);
  pushLabeledSummaryPart(parts, "lane", firstPathText(value, ["runtimeEndpoint.lane", "lane"]));
  pushLabeledSummaryPart(parts, "ns", firstPathText(value, ["runtimeEndpoint.namespace", "namespace"]));
  pushLabeledSummaryPart(parts, "actor", firstPathText(value, ["actor.username", "body.actor.username", "actor.displayName", "body.actor.displayName"]));
  pushLabeledSummaryPart(parts, "auth", firstPathText(value, ["authMethod", "auth.authMethod", "body.authMethod"]));
  pushLabeledSummaryPart(parts, "reply", firstPathText(value, ["reply.content", "result.reply.content", "body.reply.content", "answer", "content", "body.content"]));
  if (failure === null && !isFailureLikeStatus(status)) pushLabeledSummaryPart(parts, "message", message);

  const itemsCount = arrayRecords(value.items).length;
  if (itemsCount > 0) pushSummaryPart(parts, `items=${itemsCount}`);
  const eventsCount = arrayRecords(value.events).length;
  if (eventsCount > 0) pushSummaryPart(parts, `events=${eventsCount}`);
  if (value.sessionUsable === false) pushSummaryPart(parts, "sessionUsable=false");
  if (record(value.summary).textTruncated === true || value.textTruncated === true || value.outputTruncated === true) pushSummaryPart(parts, "truncated=true");

  return parts.length > 0 ? parts.slice(0, 10).join("; ") : null;
}

function commandOutputRouteSummary(value: Record<string, unknown>): string | null {
  const route = record(value.route);
  const request = record(value.request);
  const method = stringOrNull(route.method) ?? stringOrNull(request.method);
  const path = stringOrNull(route.path) ?? stringOrNull(request.path);
  if (method !== null && path !== null) return `${method} ${path}`;
  return stringOrNull(request.url) ?? stringOrNull(value.baseUrl);
}

function firstPathText(value: Record<string, unknown>, paths: string[]): string | null {
  for (const path of paths) {
    const text = summaryScalar(pathValue(value, path));
    if (text !== null) return text;
  }
  return null;
}

function pathValue(value: Record<string, unknown>, path: string): unknown {
  let current: unknown = value;
  for (const key of path.split(".")) {
    if (!isRecord(current)) return undefined;
    current = current[key];
  }
  return current;
}

function summaryScalar(value: unknown): string | null {
  if (typeof value === "string") {
    const trimmed = value.trim();
    return trimmed.length > 0 ? trimmed : null;
  }
  if (typeof value === "number" && Number.isFinite(value)) return String(value);
  if (typeof value === "boolean") return String(value);
  return null;
}

function isFailureLikeStatus(value: string | null): boolean {
  return value !== null && /(?:fail|error|timeout|cancel|interrupt|denied|rejected)/iu.test(value);
}

function pushLabeledSummaryPart(parts: string[], label: string, value: string | null, shorten = false): void {
  const text = labeledSummaryValue(label, value, shorten);
  if (text !== null) pushSummaryPart(parts, text);
}

function labeledSummaryValue(label: string, value: string | null, shorten = false): string | null {
  if (value === null) return null;
  const rendered = shorten ? shortId(value) : truncateOneLine(value, 80);
  return `${label}=${rendered}`;
}

function pushSummaryPart(parts: string[], value: string): void {
  const text = truncateOneLine(value, 160);
  if (text.length > 0 && !parts.includes(text)) parts.push(text);
}

function summarizeTextCommandOutput(raw: string): string | null {
  const lines = raw
    .split(/\r?\n/u)
    .map((line) => line.trim())
    .filter((line) => line.length > 0 && !isLowSignalCommandOutputLine(line));
  const signal = lines.find((line) => /(?:trace|session|conversation|thread|status|failure|error|route|http|pipeline|provider|commit|succeeded|failed|created)/iu.test(line))
    ?? lines[0]
    ?? null;
  if (signal === null) return null;
  return truncateOneLine(cleanCommandOutputLine(signal), 220);
}

function summarizePartialJsonCommandOutput(raw: string): string | null {
  const fields = new Map<string, string>();
  for (const line of raw.split(/\r?\n/u)) {
    const field = jsonLineField(line);
    if (field === null || isLowSignalJsonField(field.key)) continue;
    if (!fields.has(field.key) && field.value.length > 0) fields.set(field.key, field.value);
  }

  const parts: string[] = [];
  const action = fields.get("action") ?? fields.get("operation") ?? fields.get("command") ?? fields.get("kind") ?? null;
  const status = fields.get("status") ?? fields.get("state") ?? fields.get("phase") ?? null;
  const http = fields.get("httpStatus") ?? null;
  const failure = fields.get("failureKind") ?? null;
  const message = fields.get("message") ?? fields.get("reason") ?? fields.get("error") ?? null;
  const primary = [action, status, labeledSummaryValue("http", http)].filter((item): item is string => item !== null);
  if (primary.length > 0) pushSummaryPart(parts, primary.join(" "));

  pushLabeledSummaryPart(parts, "failure", failure);
  if (failure !== null || isFailureLikeStatus(status)) pushLabeledSummaryPart(parts, "message", message);
  pushLabeledSummaryPart(parts, "trace", fields.get("traceId") ?? fields.get("lastTraceId") ?? null, true);
  pushLabeledSummaryPart(parts, "session", fields.get("sessionId") ?? fields.get("selectedAgentSessionId") ?? null, true);
  pushLabeledSummaryPart(parts, "conversation", fields.get("conversationId") ?? fields.get("selectedConversationId") ?? null, true);
  pushLabeledSummaryPart(parts, "thread", fields.get("threadId") ?? null, true);
  pushLabeledSummaryPart(parts, "provider", fields.get("providerProfile") ?? fields.get("backendProfile") ?? fields.get("profile") ?? null);
  pushLabeledSummaryPart(parts, "route", partialRouteSummary(fields));
  pushLabeledSummaryPart(parts, "pipeline", fields.get("pipelineRun") ?? fields.get("pipelineRunName") ?? null, true);
  pushLabeledSummaryPart(parts, "run", fields.get("runId") ?? null, true);
  pushLabeledSummaryPart(parts, "cmd", fields.get("commandId") ?? null, true);
  pushLabeledSummaryPart(parts, "job", fields.get("jobName") ?? fields.get("runnerJobId") ?? null, true);
  pushLabeledSummaryPart(parts, "lane", fields.get("lane") ?? null);
  pushLabeledSummaryPart(parts, "ns", fields.get("namespace") ?? null);
  pushLabeledSummaryPart(parts, "actor", fields.get("username") ?? fields.get("displayName") ?? null);
  pushLabeledSummaryPart(parts, "auth", fields.get("authMethod") ?? null);
  if (failure === null && !isFailureLikeStatus(status)) pushLabeledSummaryPart(parts, "message", message);

  return parts.length > 0 ? parts.slice(0, 10).join("; ") : null;
}

function partialRouteSummary(fields: Map<string, string>): string | null {
  const method = fields.get("method") ?? null;
  const path = fields.get("path") ?? null;
  if (method !== null && path !== null) return `${method} ${path}`;
  return fields.get("url") ?? fields.get("baseUrl") ?? null;
}

function jsonLineField(line: string): { key: string; value: string } | null {
  const match = line.trim().replace(/,$/u, "").match(/^"([^"]+)":\s*(.+)$/u);
  if (match === null) return null;
  return { key: match[1], value: cleanJsonScalar(match[2]) };
}

function cleanJsonScalar(raw: string): string {
  const trimmed = raw.trim();
  if (trimmed === "null" || trimmed === "{" || trimmed === "[" || trimmed === "}" || trimmed === "]") return "";
  if (trimmed.startsWith('"') && trimmed.endsWith('"')) {
    try {
      const parsed = JSON.parse(trimmed) as unknown;
      return typeof parsed === "string" ? parsed.trim() : String(parsed);
    } catch {
      return trimmed.slice(1, -1).trim();
    }
  }
  return trimmed;
}

function cleanCommandOutputLine(line: string): string {
  const trimmed = line.replace(/,$/u, "").trim();
  const jsonField = trimmed.match(/^"([^"]+)":\s*(.+)$/u);
  if (jsonField === null) return trimmed;
  const key = jsonField[1];
  const value = jsonField[2].replace(/^"|"$/gu, "").trim();
  return `${key}=${value}`;
}

function isLowSignalCommandOutputLine(line: string): boolean {
  const trimmed = line.replace(/,$/u, "").trim();
  if (trimmed === "{" || trimmed === "}" || trimmed === "}," || trimmed === "];" || trimmed === "[") return true;
  const field = jsonLineField(trimmed);
  return field !== null && isLowSignalJsonField(field.key);
}

function isLowSignalJsonField(key: string): boolean {
  return key === "generatedAt" || key === "cli" || key === "version" || key === "valuesRedacted" || key === "secretMaterialStored";
}

function eventText(value: unknown): string | null {
  const direct = stringOrNull(value);
  if (direct !== null && direct.trim().length > 0) return direct.trim();
  const nested = record(value);
  return stringOrNull(nested.text)
    ?? stringOrNull(nested.message)
    ?? stringOrNull(nested.reason)
    ?? stringOrNull(nested.summary);
}

function formatCountField(label: string, value: unknown): string | null {
  if (typeof value === "number" && Number.isFinite(value)) return `${label}=${value}`;
  if (typeof value === "string" && value.length > 0) return `${label}=${value}`;
  return null;
}

function renderResourceTable(items: Record<string, unknown>[], wide: boolean): string {
  const headers = wide
    ? ["NAME", "STATE", "QUEUE", "LANE", "PROFILE", "RUN", "CMD", "RJOB", "SESSION", "AGE", "TITLE"]
    : ["NAME", "STATE", "QUEUE", "LANE", "RUN", "CMD", "RJOB", "SESSION", "AGE", "ATTENTION"];
  const rows = items.map((item) => {
    if (wide) {
      return [
        resourceName(item),
        displayValue(item.state),
        displayValue(item.queue),
        displayValue(item.lane),
        displayValue(item.profile),
        shortId(stringOrDash(item.run)),
        shortId(stringOrDash(item.command)),
        shortId(stringOrDash(item.runnerjob)),
        shortId(stringOrDash(item.session)),
        displayValue(item.age),
        truncateOneLine(displayValue(item.title), 48),
      ];
    }
    return [
      resourceName(item),
      displayValue(item.state),
      displayValue(item.queue),
      displayValue(item.lane),
      shortId(stringOrDash(item.run)),
      shortId(stringOrDash(item.command)),
      shortId(stringOrDash(item.runnerjob)),
      shortId(stringOrDash(item.session)),
      displayValue(item.age),
      displayValue(item.attention),
    ];
  });
  return renderTable(headers, rows);
}

function renderTaskDescription(task: Record<string, unknown>, options: AgentRunResourceOptions): string {
  const attempt = record(task.latestAttempt);
  const taskId = displayValue(task.id);
  const runId = stringOrNull(attempt.runId);
  const commandId = stringOrNull(attempt.commandId);
  const runnerJobId = stringOrNull(attempt.runnerJobId);
  const sessionId = stringOrNull(attempt.sessionId) ?? stringOrNull(record(task.sessionRef).sessionId);
  const lines = [
    `Name:      task/${taskId}`,
    `State:     ${displayValue(task.state)}        Attention: ${displayValue(task.unread === true ? "unread" : "")}`,
    `Queue:     ${displayValue(task.queue)}`,
    `Lane:      ${displayValue(task.lane)}             Profile: ${displayValue(task.backendProfile)}        Provider: ${displayValue(task.providerId)}`,
    `Title:     ${displayValue(task.title)}`,
    "",
    "Latest Attempt:",
    `  Attempt: ${displayValue(attempt.attemptId)}  State: ${displayValue(attempt.state)}`,
    `  Run:     ${runId === null ? "-" : `run/${runId}`}`,
    `  Command: ${commandId === null ? "-" : `command/${commandId}`}`,
    `  Runner:  ${runnerJobId === null ? "-" : `runnerjob/${runnerJobId}`}`,
    `  Session: ${sessionId === null ? "-" : `session/${sessionId}`}`,
    "",
    "Conditions:",
    `  Terminal: ${displayValue(task.state)}`,
    `  Failure:  ${displayValue(task.failureKind ?? task.degradedReason ?? "none")}`,
    "  Values:   redacted",
    "",
    "Next:",
  ];
  const next = [
    runId === null ? null : `bun scripts/cli.ts agentrun events run/${runId} --after-seq 0 --limit 100`,
    sessionId === null ? null : `bun scripts/cli.ts agentrun logs session/${sessionId} --tail 100`,
    runId === null || commandId === null ? null : `bun scripts/cli.ts agentrun result run/${runId} --command ${commandId}`,
    `bun scripts/cli.ts agentrun ack task/${taskId}`,
    options.full ? null : `bun scripts/cli.ts agentrun describe task/${taskId} --full`,
  ].filter((item): item is string => item !== null).slice(0, 5);
  lines.push(...next.map((item) => `  ${item}`));
  return lines.join("\n");
}

function unwrapTaskDetail(data: Record<string, unknown>): Record<string, unknown> {
  const task = record(data.task);
  if (Object.keys(task).length > 0) return task;
  return data;
}

function renderGenericDescription(ref: AgentRunResourceRef, data: unknown): string {
  const value = record(data);
  const lines = [
    `Name:  ${ref.kind}/${ref.name}`,
    `State: ${displayValue(value.state ?? value.status ?? value.phase ?? value.executionState ?? value.terminalStatus ?? "-")}`,
  ];
  const identity = renderResourceIdentityLines(ref, value);
  if (identity.length > 0) lines.push("", ...identity);
  const supervisor = renderSupervisorLines(ref, value);
  if (supervisor.length > 0) lines.push("", "Supervisor:", ...supervisor.map((line) => `  ${line}`));
  const failure = renderFailureLines(value);
  if (failure.length > 0) lines.push("", ...failure);
  const next = renderResourceNextLines(ref, value);
  if (next.length > 0) lines.push("", "Next:", ...next.map((line) => `  ${line}`));
  if (identity.length === 0 && failure.length === 0 && next.length === 0) {
    lines.push(
      "",
      "Summary:",
      JSON.stringify(pickCompact(value, ["id", "name", "runId", "commandId", "runnerJobId", "sessionId", "state", "status", "phase", "reason", "failureKind", "valuesPrinted"]), null, 2),
    );
  }
  return lines.join("\n");
}

function renderResourceIdentityLines(ref: AgentRunResourceRef, value: Record<string, unknown>): string[] {
  const supervisor = record(value.supervisor);
  const fields: [string, unknown][] = [
    ["Run", firstKnownString(value.runId, value.activeRunId, value.lastRunId, supervisor.runId, supervisor.activeRunId, supervisor.lastRunId)],
    ["Command", firstKnownString(value.commandId, value.activeCommandId, value.lastCommandId, supervisor.commandId, supervisor.activeCommandId, supervisor.lastCommandId)],
    ["RunnerJob", value.runnerJobId ?? (ref.kind === "runnerjob" ? value.id : null)],
    ["Session", firstKnownString(value.sessionId, supervisor.sessionId)],
    ["Namespace", value.namespace],
    ["Job", value.jobName],
    ["Image", value.image],
    ["LogPath", value.logPath],
    ["Started", value.startedAt],
    ["Finished", value.finishedAt],
  ];
  if (ref.kind !== "runnerjob") {
    return fields
      .filter(([label]) => label === "Run" || label === "Command" || label === "RunnerJob" || label === "Session")
      .map(([label, item]) => formatResourceField(label, item))
      .filter((line): line is string => line !== null);
  }
  return fields.map(([label, item]) => formatResourceField(label, item)).filter((line): line is string => line !== null);
}

function firstKnownString(...values: unknown[]): string | null {
  for (const value of values) {
    const text = stringOrNull(value);
    if (text !== null && text.length > 0) return text;
  }
  return null;
}

function formatResourceField(label: string, value: unknown): string | null {
  const text = stringOrNull(value);
  if (text === null || text.length === 0) return null;
  return `${label}: ${text}`;
}

function renderSupervisorLines(ref: AgentRunResourceRef, value: Record<string, unknown>): string[] {
  if (ref.kind !== "session" && ref.kind !== "task") return [];
  const supervisor = record(value.supervisor);
  const liveness = record(value.liveness);
  const source = Object.keys(supervisor).length > 0 ? supervisor : liveness;
  if (Object.keys(source).length === 0) return [];
  const timeoutBudget = record(source.timeoutBudget);
  const terminalClassification = record(source.terminalClassification);
  const runId = firstKnownString(source.activeRunId, source.runId, source.lastRunId, value.activeRunId, value.runId, value.lastRunId);
  const commandId = firstKnownString(source.activeCommandId, source.commandId, source.lastCommandId, value.activeCommandId, value.commandId, value.lastCommandId);
  const lines: string[] = [];
  const executionState = firstKnownString(source.executionState, value.executionState);
  if (executionState !== null) lines.push(`Execution: ${executionState}`);
  if (typeof source.active === "boolean") lines.push(`Active: ${String(source.active)}`);
  if (runId !== null) lines.push(`Run: run/${runId}`);
  if (commandId !== null) lines.push(`Command: command/${commandId}`);
  const phase = firstKnownString(source.phase, liveness.phase);
  const lastEventAgeMs = typeof source.lastEventAgeMs === "number" ? source.lastEventAgeMs : typeof liveness.lastEventAgeMs === "number" ? liveness.lastEventAgeMs : null;
  if (phase !== null || lastEventAgeMs !== null) lines.push(`Liveness: ${displayValue(phase)}${lastEventAgeMs === null ? "" : ` ageMs=${String(lastEventAgeMs)}`}`);
  const timeoutKind = firstKnownString(timeoutBudget.timeoutKind);
  const timeoutState = firstKnownString(timeoutBudget.state);
  const remainingMs = typeof timeoutBudget.remainingMs === "number" ? timeoutBudget.remainingMs : null;
  if (timeoutKind !== null || timeoutState !== null || remainingMs !== null) lines.push(`Timeout: ${displayValue(timeoutKind)} / ${displayValue(timeoutState)}${remainingMs === null ? "" : ` remainingMs=${String(remainingMs)}`}`);
  const category = firstKnownString(terminalClassification.category);
  const reason = firstKnownString(terminalClassification.reason);
  if (category !== null || reason !== null) lines.push(`Classification: ${displayValue(category)}${reason === null ? "" : `; ${reason}`}`);
  return lines;
}

function renderFailureLines(value: Record<string, unknown>): string[] {
  const terminalClassification = record(value.terminalClassification);
  const nestedTerminalClassification = Object.keys(terminalClassification).length > 0
    ? terminalClassification
    : record(record(value.liveness).terminalClassification);
  const failureKind = stringOrNull(value.failureKind)
    ?? stringOrNull(nestedTerminalClassification.failureKind)
    ?? stringOrNull(value.degradedReason);
  const failureMessage = stringOrNull(value.failureMessage)
    ?? stringOrNull(nestedTerminalClassification.failureMessage)
    ?? stringOrNull(value.message)
    ?? stringOrNull(value.reason);
  const category = stringOrNull(nestedTerminalClassification.category);
  const timeoutKind = stringOrNull(nestedTerminalClassification.timeoutKind);
  const timeoutState = stringOrNull(nestedTerminalClassification.timeoutState);
  const providerInterruption = stringOrNull(nestedTerminalClassification.providerInterruption);
  const lastActivity = stringOrNull(nestedTerminalClassification.lastActivityKind);
  const lastActivitySeq = nestedTerminalClassification.lastActivitySeq;
  const lines: string[] = [];
  if (failureKind !== null) lines.push(`Failure: ${failureKind}`);
  if (failureMessage !== null) lines.push(`Message: ${failureMessage}`);
  if (category !== null) lines.push(`Category: ${category}`);
  if (timeoutKind !== null || timeoutState !== null) lines.push(`Timeout: ${displayValue(timeoutKind)} / ${displayValue(timeoutState)}`);
  if (providerInterruption !== null) lines.push(`Provider: ${providerInterruption}`);
  if (lastActivity !== null) lines.push(`LastActivity: ${lastActivity}${lastActivitySeq === undefined ? "" : ` seq=${String(lastActivitySeq)}`}`);
  return lines;
}

function renderResourceNextLines(ref: AgentRunResourceRef, value: Record<string, unknown>): string[] {
  const supervisor = record(value.supervisor);
  const runId = firstKnownString(value.runId, value.activeRunId, value.lastRunId, supervisor.runId, supervisor.activeRunId, supervisor.lastRunId);
  const commandId = firstKnownString(value.commandId, value.activeCommandId, value.lastCommandId, supervisor.commandId, supervisor.activeCommandId, supervisor.lastCommandId);
  const runnerJobId = stringOrNull(value.runnerJobId) ?? (ref.kind === "runnerjob" ? ref.name : null);
  const sessionId = firstKnownString(value.sessionId, supervisor.sessionId);
  const lines = [
    runId === null ? null : `bun scripts/cli.ts agentrun events run/${runId} --after-seq 0 --limit 100`,
    sessionId === null ? null : `bun scripts/cli.ts agentrun logs session/${sessionId} --tail 100`,
    runId === null || commandId === null ? null : `bun scripts/cli.ts agentrun result run/${runId} --command ${commandId}`,
    runId === null || commandId === null ? null : `bun scripts/cli.ts agentrun describe command/${commandId} --run ${runId} --full`,
    runId === null || runnerJobId === null ? null : `bun scripts/cli.ts agentrun describe runnerjob/${runnerJobId} --run ${runId} --full`,
    ref.kind !== "session" || sessionId === null ? null : `bun scripts/cli.ts agentrun send session/${sessionId} --prompt-stdin`,
  ];
  const unique: string[] = [];
  for (const line of lines) {
    if (line !== null && !unique.includes(line)) unique.push(line);
  }
  return unique.slice(0, 5);
}

function parseTaskManifest(raw: string, source: string): Record<string, unknown> {
  const parsed = source.endsWith(".json") ? JSON.parse(raw) as unknown : Bun.YAML.parse(raw) as unknown;
  const input = record(parsed);
  const kind = stringOrNull(input.kind);
  if (kind !== null && kind.toLowerCase() !== "task") throw new Error("apply currently supports kind: Task only");
  const spec = record(input.spec);
  const payload = Object.keys(spec).length > 0 ? spec : input;
  if (!isRecord(payload.payload) && !isRecord(payload.executionPolicy) && stringOrNull(payload.title) === null) {
    throw new Error("task manifest must contain spec with an AgentRun task payload");
  }
  return payload;
}

function nextPagedResourceCommand(command: string, nextAfterSeq: string, limit: number): string {
  const parts = command
    .replace(/\s+--after-seq\s+\S+/gu, "")
    .replace(/\s+--tail(?:\s+\S+)?/gu, "")
    .replace(/\s+--limit\s+\S+/gu, "")
    .trim();
  return `${parts} --after-seq ${nextAfterSeq} --limit ${limit}`;
}

function agentRunExplain(kindRaw: string): string {
  if (kindRaw === "session-policy" || kindRaw === "provider-policy") return renderAgentRunSessionPolicyExplanation();
  const kind = parseResourceKind(kindRaw);
  if (kind === "task") {
    return [
      "KIND: task",
      "FIELDS:",
      "  metadata.name: optional client name/idempotency hint",
      "  spec.tenantId, spec.projectId, spec.queue, spec.title",
      "  spec.payload.prompt or spec.payload.<structured fields>",
      "  spec.executionPolicy, spec.resourceBundleRef, spec.workspaceRef",
      "",
      "Apply example:",
      "  kind: Task",
      "  spec:",
      "    tenantId: unidesk",
      "    projectId: pikasTech/unidesk",
      "    queue: commander",
      "    title: Example",
      "    payload:",
      "      prompt: Do the work",
    ].join("\n");
  }
  return `KIND: ${kindRaw}\nUse get/describe with -o json to inspect the current stable UniDesk resource schema.`;
}

function arrayRecords(value: unknown): Record<string, unknown>[] {
  if (Array.isArray(value)) return value.map(record).filter((item) => Object.keys(item).length > 0);
  if (typeof value === "object" && value !== null && Array.isArray((value as { items?: unknown }).items)) return arrayRecords((value as { items: unknown }).items);
  return [];
}

function renderTable(headers: string[], rows: string[][]): string {
  const widths = headers.map((header, index) => Math.max(header.length, ...rows.map((row) => (row[index] ?? "").length)));
  const line = (values: string[]): string => values.map((value, index) => value.padEnd(widths[index] ?? value.length)).join("  ").trimEnd();
  return [line(headers), ...rows.map(line)].join("\n");
}

function resourceName(item: Record<string, unknown>): string {
  const kind = String(item.kind ?? "resource");
  return `${kind}/${shortId(displayValue(item.name))}`;
}

function shortId(value: string): string {
  if (value === "-" || value.length <= 18) return value;
  const known = ["qt_", "run_", "cmd_", "rjob_"];
  const prefix = known.find((item) => value.startsWith(item));
  if (prefix !== undefined) return `${prefix}${value.slice(prefix.length, prefix.length + 8)}...`;
  if (/^\w+-\d+/u.test(value)) return value.length > 28 ? `${value.slice(0, 25)}...` : value;
  return `${value.slice(0, 14)}...`;
}

function displayValue(value: unknown): string {
  if (value === undefined || value === null || value === "") return "-";
  return String(value);
}

function stringOrDash(value: unknown): string {
  return displayValue(value);
}

function truncateOneLine(value: string, maxChars: number): string {
  const oneLine = value.replace(/\s+/gu, " ").trim();
  return oneLine.length <= maxChars ? oneLine : `${oneLine.slice(0, Math.max(0, maxChars - 3))}...`;
}

function truncateMultiline(value: string, maxChars: number): string {
  return value.length <= maxChars ? value : `${value.slice(0, maxChars)}\n...[truncated ${value.length - maxChars} chars; rerun with --full-text or --full]`;
}

function relativeAge(iso: string | null): string {
  if (iso === null) return "-";
  const ms = Date.now() - Date.parse(iso);
  if (!Number.isFinite(ms) || ms < 0) return "-";
  const minutes = Math.floor(ms / 60000);
  if (minutes < 60) return `${minutes}m`;
  const hours = Math.floor(minutes / 60);
  if (hours < 48) return `${hours}h`;
  return `${Math.floor(hours / 24)}d`;
}

function pickCompact(value: Record<string, unknown>, keys: string[]): Record<string, unknown> {
  const picked: Record<string, unknown> = {};
  for (const key of keys) {
    if (value[key] !== undefined) picked[key] = value[key];
  }
  return picked;
}

function isRecord(value: unknown): value is Record<string, unknown> {
  return typeof value === "object" && value !== null && !Array.isArray(value);
}

interface TriggerOptions {
  confirm: boolean;
  dryRun: boolean;
  node: string | null;
  lane: string | null;
  wait: boolean;
}

interface ConfirmOptions {
  confirm: boolean;
  dryRun: boolean;
}

interface SecretSyncOptions extends ConfirmOptions {
  node: string | null;
  lane: string | null;
}

interface LaneConfirmOptions extends ConfirmOptions {
  node: string | null;
  lane: string | null;
}

interface RefreshOptions extends ConfirmOptions {
  node: string | null;
  lane: string | null;
}

interface GitMirrorStatusOptions extends DisclosureOptions {
  node: string | null;
  lane: string | null;
}

interface GitMirrorOptions extends ConfirmOptions {
  node: string | null;
  lane: string | null;
  timeoutSeconds: number;
  wait: boolean;
}

interface CleanupRunnersOptions extends ConfirmOptions {
  node: string | null;
  lane: string | null;
  timeoutSeconds: number;
  forceActive: boolean;
}

interface CleanupRunsOptions extends ConfirmOptions {
  node: string | null;
  lane: string | null;
  minAgeMinutes: number;
  limit: number;
  timeoutSeconds: number;
}

interface CleanupReleasedPvOptions extends ConfirmOptions {
  node: string | null;
  lane: string | null;
  limit: number;
  timeoutSeconds: number;
}

interface DisclosureOptions {
  full: boolean;
  raw: boolean;
}

interface StatusOptions extends DisclosureOptions {
  node: string | null;
  lane: string | null;
  sourceCommit: string | null;
  pipelineRun: string | null;
  targetMode: "latest-source-head" | "source-commit" | "pipeline-run";
}

interface TimedValue<T> {
  value: T;
  elapsedMs: number;
}

function parseDisclosureOptions(args: string[]): DisclosureOptions {
  for (let index = 0; index < args.length; index += 1) {
    const arg = args[index];
    if (arg === "--node" || arg === "--lane") {
      const value = args[index + 1];
      if (value === undefined || value.startsWith("--")) throw new Error(`${arg} requires a value`);
      index += 1;
      continue;
    }
    if (arg !== "--full" && arg !== "--raw") throw new Error(`unsupported status option: ${arg}`);
  }
  const raw = args.includes("--raw");
  return { full: raw || args.includes("--full"), raw };
}

function parseGitMirrorStatusOptions(args: string[]): GitMirrorStatusOptions {
  validateOptions(args, new Set(["--full", "--raw"]), new Set(["--node", "--lane"]));
  const raw = args.includes("--raw");
  return {
    full: raw || args.includes("--full"),
    raw,
    node: optionValue(args, "--node") ?? null,
    lane: optionValue(args, "--lane") ?? null,
  };
}

function parseStatusOptions(args: string[]): StatusOptions {
  let node: string | null = null;
  let lane: string | null = null;
  let sourceCommit: string | null = null;
  let pipelineRun: string | null = null;
  let full = false;
  let raw = false;
  for (let index = 0; index < args.length; index += 1) {
    const arg = args[index];
    if (arg === "--full") {
      full = true;
      continue;
    }
    if (arg === "--raw") {
      raw = true;
      full = true;
      continue;
    }
    if (arg === "--node") {
      const value = args[index + 1];
      if (value === undefined || value.startsWith("--")) throw new Error("--node requires a value");
      node = value;
      index += 1;
      continue;
    }
    if (arg === "--lane") {
      const value = args[index + 1];
      if (value === undefined || value.startsWith("--")) throw new Error("--lane requires a value");
      lane = value;
      index += 1;
      continue;
    }
    if (arg === "--source-commit") {
      const value = args[index + 1];
      if (value === undefined || value.startsWith("--")) throw new Error("--source-commit requires a value");
      if (!isGitSha(value)) throw new Error("--source-commit must be a full 40-character git SHA");
      sourceCommit = value;
      index += 1;
      continue;
    }
    if (arg === "--pipeline-run") {
      const value = args[index + 1];
      if (value === undefined || value.startsWith("--")) throw new Error("--pipeline-run requires a value");
      if (!isAgentRunPipelineRunName(value)) throw new Error("--pipeline-run must be an agentrun-vNN-ci-<12+ hex> PipelineRun name");
      pipelineRun = value;
      index += 1;
      continue;
    }
    throw new Error(`unsupported status option: ${arg}`);
  }
  if (sourceCommit !== null && pipelineRun !== null) throw new Error("control-plane status accepts only one of --source-commit or --pipeline-run");
  return {
    full,
    raw,
    node,
    lane,
    sourceCommit,
    pipelineRun,
    targetMode: pipelineRun !== null ? "pipeline-run" : sourceCommit !== null ? "source-commit" : "latest-source-head",
  };
}


function parseTriggerOptions(args: string[]): TriggerOptions {
  const base = parseConfirmOptions(args);
  let node: string | null = null;
  let lane: string | null = null;
  let wait = false;
  for (let index = 0; index < args.length; index += 1) {
    const arg = args[index];
    if (arg === "--confirm" || arg === "--dry-run") continue;
    if (arg === "--wait") {
      wait = true;
      continue;
    }
    if (arg === "--node") {
      const value = args[index + 1];
      if (value === undefined || value.startsWith("--")) throw new Error("--node requires a value");
      node = value;
      index += 1;
      continue;
    }
    if (arg === "--lane") {
      const value = args[index + 1];
      if (value === undefined || value.startsWith("--")) throw new Error("--lane requires a value");
      lane = value;
      index += 1;
      continue;
    }
    throw new Error(`unsupported trigger-current option: ${arg}`);
  }
  return { ...base, node, lane, wait };
}

function parseSecretSyncOptions(args: string[]): SecretSyncOptions {
  const base = parseConfirmOptions(args);
  let node: string | null = null;
  let lane: string | null = null;
  for (let index = 0; index < args.length; index += 1) {
    const arg = args[index];
    if (arg === "--confirm" || arg === "--dry-run") continue;
    if (arg === "--node") {
      const value = args[index + 1];
      if (value === undefined || value.startsWith("--")) throw new Error("--node requires a value");
      node = value;
      index += 1;
      continue;
    }
    if (arg === "--lane") {
      const value = args[index + 1];
      if (value === undefined || value.startsWith("--")) throw new Error("--lane requires a value");
      lane = value;
      index += 1;
      continue;
    }
    throw new Error(`unsupported secret-sync option: ${arg}`);
  }
  return { ...base, node, lane };
}

function parseLaneConfirmOptions(args: string[]): LaneConfirmOptions {
  const base = parseConfirmOptions(args);
  let node: string | null = null;
  let lane: string | null = null;
  for (let index = 0; index < args.length; index += 1) {
    const arg = args[index];
    if (arg === "--confirm" || arg === "--dry-run") continue;
    if (arg === "--node") {
      const value = args[index + 1];
      if (value === undefined || value.startsWith("--")) throw new Error("--node requires a value");
      node = value;
      index += 1;
      continue;
    }
    if (arg === "--lane") {
      const value = args[index + 1];
      if (value === undefined || value.startsWith("--")) throw new Error("--lane requires a value");
      lane = value;
      index += 1;
      continue;
    }
    throw new Error(`unsupported control-plane option: ${arg}`);
  }
  if (node === null && lane === null) throw new Error("control-plane apply requires --node and --lane");
  return { ...base, node, lane };
}

function parseRefreshOptions(args: string[]): RefreshOptions {
  const base = parseConfirmOptions(args);
  let node: string | null = null;
  let lane: string | null = null;
  for (let index = 0; index < args.length; index += 1) {
    const arg = args[index];
    if (arg === "--confirm" || arg === "--dry-run") continue;
    if (arg === "--node") {
      const value = args[index + 1];
      if (value === undefined || value.startsWith("--")) throw new Error("--node requires a value");
      node = value;
      index += 1;
      continue;
    }
    if (arg === "--lane") {
      const value = args[index + 1];
      if (value === undefined || value.startsWith("--")) throw new Error("--lane requires a value");
      lane = value;
      index += 1;
      continue;
    }
    throw new Error(`unsupported refresh option: ${arg}`);
  }
  return { ...base, node, lane };
}

function parseConfirmOptions(args: string[]): ConfirmOptions {
  if (args.includes("--confirm") && args.includes("--dry-run")) throw new Error("accepts only one of --confirm or --dry-run");
  return {
    confirm: args.includes("--confirm"),
    dryRun: args.includes("--dry-run") || !args.includes("--confirm"),
  };
}

function parseGitMirrorOptions(args: string[]): GitMirrorOptions {
  validateOptions(args, new Set(["--confirm", "--dry-run", "--wait"]), new Set(["--timeout-seconds", "--node", "--lane"]));
  const base = parseConfirmOptions(args);
  const timeoutIndex = args.indexOf("--timeout-seconds");
  const timeoutSeconds = timeoutIndex >= 0 ? Number(args[timeoutIndex + 1]) : 300;
  if (!Number.isFinite(timeoutSeconds) || timeoutSeconds < 30) throw new Error("--timeout-seconds must be a number >= 30");
  return {
    ...base,
    node: optionValue(args, "--node") ?? null,
    lane: optionValue(args, "--lane") ?? null,
    timeoutSeconds,
    wait: args.includes("--wait"),
  };
}

function parseCleanupRunnersOptions(args: string[]): CleanupRunnersOptions {
  validateOptions(args, new Set(["--confirm", "--dry-run", "--force-active"]), new Set(["--timeout-seconds", "--node", "--lane"]));
  const base = parseConfirmOptions(args);
  return {
    ...base,
    node: optionValue(args, "--node") ?? null,
    lane: optionValue(args, "--lane") ?? null,
    timeoutSeconds: positiveIntegerOption(args, "--timeout-seconds", 180, 600),
    forceActive: args.includes("--force-active"),
  };
}

function parseCleanupRunsOptions(args: string[]): CleanupRunsOptions {
  validateOptions(args, new Set(["--confirm", "--dry-run"]), new Set(["--min-age-minutes", "--limit", "--timeout-seconds", "--node", "--lane"]));
  const base = parseConfirmOptions(args);
  return {
    ...base,
    node: optionValue(args, "--node") ?? null,
    lane: optionValue(args, "--lane") ?? null,
    minAgeMinutes: positiveIntegerOption(args, "--min-age-minutes", 60, 10080),
    limit: positiveIntegerOption(args, "--limit", 20, 500),
    timeoutSeconds: positiveIntegerOption(args, "--timeout-seconds", 180, 600),
  };
}

function parseCleanupReleasedPvOptions(args: string[]): CleanupReleasedPvOptions {
  validateOptions(args, new Set(["--confirm", "--dry-run"]), new Set(["--limit", "--timeout-seconds", "--node", "--lane"]));
  const base = parseConfirmOptions(args);
  return {
    ...base,
    node: optionValue(args, "--node") ?? null,
    lane: optionValue(args, "--lane") ?? null,
    limit: positiveIntegerOption(args, "--limit", 20, 500),
    timeoutSeconds: positiveIntegerOption(args, "--timeout-seconds", 120, 600),
  };
}

function validateOptions(args: string[], booleanOptions: Set<string>, valueOptions: Set<string>): void {
  for (let index = 0; index < args.length; index += 1) {
    const arg = args[index];
    if (booleanOptions.has(arg)) continue;
    if (valueOptions.has(arg)) {
      const value = args[index + 1];
      if (value === undefined || value.startsWith("--")) throw new Error(`${arg} requires a value`);
      index += 1;
      continue;
    }
    throw new Error(`unsupported option: ${arg}`);
  }
}

function optionValue(args: string[], name: string): string | undefined {
  const index = args.indexOf(name);
  if (index === -1) return undefined;
  const value = args[index + 1];
  if (value === undefined || value.startsWith("--")) throw new Error(`${name} requires a value`);
  return value;
}

function positiveIntegerOption(args: string[], name: string, defaultValue: number, maxValue: number): number {
  const raw = optionValue(args, name);
  if (raw === undefined) return defaultValue;
  const value = Number(raw);
  if (!Number.isInteger(value) || value < 0) throw new Error(`${name} must be a non-negative integer`);
  return Math.min(value, maxValue);
}

async function controlPlanePlan(_config: UniDeskConfig, options: StatusOptions): Promise<Record<string, unknown>> {
  const target = resolveAgentRunLaneTarget(options);
  const spec = target.spec;
  return {
    ok: true,
    command: "agentrun control-plane plan",
    mode: "yaml-declared-node-lane",
    configPath: target.configPath,
    target: agentRunLaneSummary(spec),
    plannedChecks: [
      "source-branch-exists",
      "source-worktree-exists-and-clean",
      "git-mirror-services-ready",
      "ci-namespace-pipeline-serviceaccount",
      "argo-application-alignment",
      "runtime-namespace-manager-service",
      "database-secretref-present",
      "local-postgres-absent-when-external",
    ],
    deploymentBoundary: {
      mutation: false,
      note: "plan/status are read-only. Long writes must use controlled AgentRun/Platform DB commands and this YAML target.",
    },
    next: {
      status: `bun scripts/cli.ts agentrun control-plane status --node ${spec.nodeId} --lane ${spec.lane}`,
      postgresStatus: spec.database.configRef ? `bun scripts/cli.ts platform-db postgres status --config ${spec.database.configRef}` : null,
      postgresApply: spec.database.configRef ? `bun scripts/cli.ts platform-db postgres apply --config ${spec.database.configRef} --confirm` : null,
      controlPlaneApply: `bun scripts/cli.ts agentrun control-plane apply --node ${spec.nodeId} --lane ${spec.lane} --dry-run`,
    },
    valuesPrinted: false,
  };
}

async function controlPlaneApply(config: UniDeskConfig, options: LaneConfirmOptions): Promise<Record<string, unknown>> {
  const { configPath, spec } = resolveAgentRunLaneTarget(options);
  const objects = renderAgentRunControlPlaneManifests(spec);
  const manifestYaml = `${objects.map((object) => Bun.YAML.stringify(object).trim()).join("\n---\n")}\n`;
  const objectRefs = objects.map((object) => manifestObjectRef(object));
  const plan = {
    node: spec.nodeId,
    kubeRoute: spec.nodeKubeRoute,
    lane: spec.lane,
    version: spec.version,
    objectCount: objects.length,
    objects: objectRefs,
    manifestBytes: Buffer.byteLength(manifestYaml, "utf8"),
    manifestDigest: renderedObjectsDigest(objects),
    fieldManager: "unidesk-agentrun-control-plane",
    valuesPrinted: false,
  };
  if (options.dryRun || !options.confirm) {
    return {
      ok: true,
      command: "agentrun control-plane apply",
      mode: "dry-run",
      mutation: false,
      configPath,
      target: agentRunLaneSummary(spec),
      plan,
      next: {
        confirm: `bun scripts/cli.ts agentrun control-plane apply --node ${spec.nodeId} --lane ${spec.lane} --confirm`,
        status: `bun scripts/cli.ts agentrun control-plane status --node ${spec.nodeId} --lane ${spec.lane}`,
      },
      valuesPrinted: false,
    };
  }
  const applied = await capture(config, spec.nodeKubeRoute, ["sh", "--", applyYamlScript(manifestYaml, "unidesk-agentrun-control-plane", false)]);
  const payload = captureJsonPayload(applied);
  return {
    ok: applied.exitCode === 0 && payload.ok !== false,
    command: "agentrun control-plane apply",
    mode: "confirmed-apply",
    mutation: true,
    configPath,
    target: agentRunLaneSummary(spec),
    plan,
    result: payload,
    capture: compactCapture(applied, { full: applied.exitCode !== 0, stdoutTailChars: 5000, stderrTailChars: 5000 }),
    next: {
      secretSync: `bun scripts/cli.ts agentrun control-plane secret-sync --node ${spec.nodeId} --lane ${spec.lane} --confirm`,
      status: `bun scripts/cli.ts agentrun control-plane status --node ${spec.nodeId} --lane ${spec.lane}`,
    },
    valuesPrinted: false,
  };
}

async function status(config: UniDeskConfig, options: StatusOptions): Promise<Record<string, unknown>> {
  return await statusYamlLane(config, options, resolveAgentRunLaneTarget(options));
}

async function statusYamlLane(config: UniDeskConfig, options: StatusOptions, target: { configPath: string; spec: AgentRunLaneSpec }): Promise<Record<string, unknown>> {
  const spec = target.spec;
  const sourceProbe = await timedStatusStage("source", () => capture(config, `${spec.nodeRoute}:${spec.source.workspace}`, ["sh", "--", yamlLaneSourceStatusScript(spec)]));
  const sourcePayload = captureJsonPayload(sourceProbe.value);
  const branchTipCommit = stringOrNull(sourcePayload.remoteBranchCommit) ?? stringOrNull(sourcePayload.localHead);
  const initialSourceCommit = options.sourceCommit
    ?? stringOrNull(sourcePayload.remoteBranchCommit)
    ?? stringOrNull(sourcePayload.localHead);
  const pipelineRunName = options.pipelineRun ?? (initialSourceCommit ? agentRunPipelineRunName(spec, initialSourceCommit) : null);
  const [runtimeProbe, mirrorProbe] = await Promise.all([
    timedStatusStage("runtime", () => capture(config, spec.nodeKubeRoute, ["sh", "--", yamlLaneRuntimeStatusScript(spec, pipelineRunName)])),
    timedStatusStage("git-mirror", () => capture(config, spec.nodeKubeRoute, ["sh", "--", yamlLaneGitMirrorStatusScript(spec)])),
  ]);
  const runtimePayload = captureJsonPayload(runtimeProbe.value);
  const mirrorPayload = captureJsonPayload(mirrorProbe.value);
  const pipeline = record(runtimePayload.pipeline);
  const pipelineRunStatus = record(runtimePayload.pipelineRun);
  const argo = record(runtimePayload.argo);
  const manager = record(runtimePayload.manager);
  const database = record(runtimePayload.database);
  const secrets = record(runtimePayload.secrets);
  const localPostgres = record(runtimePayload.localPostgres);
  const expectedGitopsRevision = stringOrNull(mirrorPayload.gitopsCommit);
  const mirrorSourceCommit = stringOrNull(mirrorPayload.sourceCommit);
  const pipelineRunSourceCommit = stringOrNull(pipelineRunStatus.sourceCommit);
  const sourceCommit = options.sourceCommit
    ?? (options.pipelineRun !== null ? pipelineRunSourceCommit ?? initialSourceCommit : initialSourceCommit);
  const managerSourceMatchesExpected = Boolean(sourceCommit && manager.sourceCommit === sourceCommit);
  const argoSyncedToGitops = Boolean(expectedGitopsRevision && argo.revision === expectedGitopsRevision);
  const pipelineSucceeded = pipelineRunStatus.status === "True";
  const sourceWorktreeDetached = sourcePayload.branch === "HEAD";
  const targetMode = options.pipelineRun !== null ? "pipeline-run" : options.sourceCommit !== null ? "source-commit" : "latest-source-head";
  const sourceBranchAdvanced = targetMode !== "latest-source-head"
    && sourceCommit !== null
    && branchTipCommit !== null
    && sourceCommit !== branchTipCommit;
  const branchDrift = {
    targetMode,
    sourceBranch: spec.source.branch,
    currentBranchTipCommit: branchTipCommit,
    targetSourceCommit: sourceCommit,
    pipelineRunSourceCommit,
    sourceBranchAdvanced,
    targetSupersededByCurrentBranch: sourceBranchAdvanced,
    closeoutHint: sourceBranchAdvanced
      ? "target PipelineRun/source commit is not the current branch tip; verify the branch tip contains the fix, then trigger-current again for latest-tip closeout"
      : null,
    valuesPrinted: false,
  };
  const warnings = [
    ...(sourceWorktreeDetached ? ["source-worktree-detached"] : []),
    ...(sourceBranchAdvanced ? ["source-branch-advanced-after-target"] : []),
  ];
  const blockers = [
    ...(sourcePayload.workspaceExists === true ? [] : ["source-worktree-missing"]),
    ...(sourcePayload.remoteBranchExists === true ? [] : ["source-branch-missing"]),
    ...(sourcePayload.workspaceClean === true || sourcePayload.workspaceExists !== true ? [] : ["source-worktree-dirty"]),
    ...(mirrorPayload.readReady === true ? [] : ["git-mirror-read-not-ready"]),
    ...(mirrorPayload.writeReady === true ? [] : ["git-mirror-write-not-ready"]),
    ...(mirrorPayload.cachePvcExists === true ? [] : ["git-mirror-cache-pvc-missing"]),
    ...(runtimePayload.ciNamespaceExists === true ? [] : ["ci-namespace-missing"]),
    ...(pipeline.exists === true ? [] : ["pipeline-missing"]),
    ...(pipelineRunName !== null && pipelineRunStatus.exists !== true ? ["pipelinerun-missing"] : []),
    ...(pipelineRunStatus.exists !== true || pipelineRunStatus.status === undefined || pipelineRunStatus.status === null || pipelineRunStatus.status === "True" ? [] : ["pipelinerun-not-succeeded"]),
    ...(runtimePayload.serviceAccountExists === true ? [] : ["ci-serviceaccount-missing"]),
    ...(argo.exists === true ? [] : ["argo-application-missing"]),
    ...(mirrorPayload.readReady === true && expectedGitopsRevision === null ? ["gitops-revision-unresolved"] : []),
    ...(argo.exists !== true || expectedGitopsRevision === null || argoSyncedToGitops ? [] : ["argo-revision-stale"]),
    ...(runtimePayload.runtimeNamespaceExists === true ? [] : ["runtime-namespace-missing"]),
    ...(manager.deploymentExists === true ? [] : ["manager-deployment-missing"]),
    ...(manager.deploymentExists !== true || sourceCommit === null || managerSourceMatchesExpected ? [] : ["manager-source-stale"]),
    ...(manager.serviceExists === true ? [] : ["manager-service-missing"]),
    ...(spec.database.mode === "external-postgres" && database.secretPresent !== true ? ["database-secret-missing"] : []),
    ...(secrets.ready === true ? [] : ["lane-secret-missing"]),
    ...(spec.database.localPostgresExpectedAbsent && localPostgres.absent !== true ? ["local-postgres-present"] : []),
  ];
  const ciBlockerNames = new Set(["ci-namespace-missing", "pipeline-missing", "pipelinerun-missing", "pipelinerun-not-succeeded", "ci-serviceaccount-missing"]);
  const ciBlockers = blockers.filter((blocker) => ciBlockerNames.has(blocker));
  const runtimeBlockers = blockers.filter((blocker) => !ciBlockerNames.has(blocker));
  const aligned = blockers.length === 0 && pipelineSucceeded && argoSyncedToGitops && managerSourceMatchesExpected;
  const runtimeAligned = runtimeBlockers.length === 0 && argoSyncedToGitops && managerSourceMatchesExpected;
  const ciEvidenceMissing = pipelineRunName !== null && pipelineRunStatus.exists !== true;
  const mirrorAlreadySynced = mirrorPayload.readReady === true
    && mirrorPayload.writeReady === true
    && sourceCommit !== null
    && mirrorSourceCommit === sourceCommit
    && expectedGitopsRevision !== null;
  const runtimeAlignment = {
    pipelineSucceeded,
    argoRevision: stringOrNull(argo.revision),
    argoSyncedToGitops,
    managerSourceCommit: stringOrNull(manager.sourceCommit),
    managerSourceMatchesExpected,
    runtimeAligned,
  };
  const statusFullCommand = agentRunControlPlaneStatusCommand(spec, options, true);
  const triggerCurrentCommand = `bun scripts/cli.ts agentrun control-plane trigger-current --node ${spec.nodeId} --lane ${spec.lane} --confirm`;
  const nextAction = aligned
    ? { code: "none", summary: "lane aligned; no action required", command: null }
    : ciEvidenceMissing && runtimeAligned && mirrorAlreadySynced
      ? { code: "ci-evidence-missing", summary: "runtime and git mirror are aligned, but the expected PipelineRun evidence is missing; rerun trigger-current to recreate CI evidence", command: triggerCurrentCommand }
      : sourceBranchAdvanced
        ? { code: "target-superseded", summary: "target commit is no longer the branch tip; trigger-current against latest source before closeout", command: triggerCurrentCommand }
        : ciBlockers.length > 0
          ? { code: "ci-blocked", summary: `CI evidence is blocked: ${ciBlockers.join(", ")}`, command: statusFullCommand }
          : runtimeBlockers.length > 0
            ? { code: "runtime-blocked", summary: `runtime alignment is blocked: ${runtimeBlockers.join(", ")}`, command: statusFullCommand }
            : { code: "inspect-full-status", summary: "alignment is inconclusive; inspect full status details", command: statusFullCommand };
  const compactSourceStatus = {
    workspaceExists: sourcePayload.workspaceExists ?? false,
    workspaceClean: sourcePayload.workspaceClean ?? null,
    branch: sourcePayload.branch ?? null,
    remoteBranchExists: sourcePayload.remoteBranchExists ?? false,
    remoteBranchCommit: sourcePayload.remoteBranchCommit ?? null,
    workspaceDetached: sourceWorktreeDetached,
  };
  const compactGitMirrorStatus = {
    readReady: mirrorPayload.readReady ?? false,
    writeReady: mirrorPayload.writeReady ?? false,
    cachePvcExists: mirrorPayload.cachePvcExists ?? false,
    sourceCommit: mirrorSourceCommit,
    gitopsCommit: expectedGitopsRevision,
    alreadySynced: mirrorAlreadySynced,
  };
  const compactCiStatus = {
    namespaceExists: runtimePayload.ciNamespaceExists ?? false,
    serviceAccountExists: runtimePayload.serviceAccountExists ?? false,
    pipelineExists: pipeline.exists ?? false,
    pipelineRun: {
      name: pipelineRunName,
      exists: pipelineRunStatus.exists ?? false,
      status: pipelineRunStatus.status ?? null,
      reason: pipelineRunStatus.reason ?? null,
      sourceCommit: pipelineRunSourceCommit,
    },
    evidenceMissing: ciEvidenceMissing,
    blockers: ciBlockers,
  };
  const compactArgoStatus = {
    exists: argo.exists ?? false,
    application: argo.application ?? null,
    revision: stringOrNull(argo.revision),
    syncStatus: argo.syncStatus ?? null,
    healthStatus: argo.healthStatus ?? null,
    syncedToGitops: argoSyncedToGitops,
  };
  const compactRuntimeStatus = {
    namespaceExists: runtimePayload.runtimeNamespaceExists ?? false,
    manager: {
      deploymentExists: manager.deploymentExists ?? false,
      serviceExists: manager.serviceExists ?? false,
      sourceCommit: stringOrNull(manager.sourceCommit),
      sourceMatchesExpected: managerSourceMatchesExpected,
    },
    databaseSecretPresent: database.secretPresent ?? null,
    secretsReady: secrets.ready ?? null,
    localPostgresAbsent: localPostgres.absent ?? null,
    blockers: runtimeBlockers,
  };
  const detailedSummary = {
    aligned,
    runtimeAligned,
    ciEvidenceMissing,
    mirrorAlreadySynced,
    blockers,
    warnings,
    sourceCommit,
    expectedPipelineRun: pipelineRunName,
    expectedGitopsRevision,
    runtimeAlignment,
    branchDrift,
    source: {
      workspaceExists: sourcePayload.workspaceExists ?? false,
      workspaceClean: sourcePayload.workspaceClean ?? null,
      branch: sourcePayload.branch ?? null,
      workspaceDetached: sourceWorktreeDetached,
      localHead: sourcePayload.localHead ?? null,
      remoteBranchExists: sourcePayload.remoteBranchExists ?? false,
      remoteBranchCommit: sourcePayload.remoteBranchCommit ?? null,
    },
    gitMirror: {
      readReady: mirrorPayload.readReady ?? false,
      writeReady: mirrorPayload.writeReady ?? false,
      cachePvcExists: mirrorPayload.cachePvcExists ?? false,
      repositoryCount: Array.isArray(mirrorPayload.repositories) ? mirrorPayload.repositories.length : null,
      sourceCommit: mirrorSourceCommit,
      gitopsCommit: expectedGitopsRevision,
      alreadySynced: mirrorAlreadySynced,
    },
    ci: {
      namespaceExists: runtimePayload.ciNamespaceExists ?? false,
      serviceAccountExists: runtimePayload.serviceAccountExists ?? false,
      pipeline,
      pipelineRun: pipelineRunStatus,
      evidenceMissing: ciEvidenceMissing,
      blockers: ciBlockers,
    },
    argo,
    runtime: {
      namespaceExists: runtimePayload.runtimeNamespaceExists ?? false,
      manager: {
        deploymentExists: manager.deploymentExists ?? false,
        serviceExists: manager.serviceExists ?? false,
        deployment: manager.deployment ?? null,
        service: manager.service ?? null,
        image: manager.image ?? null,
        sourceCommit: stringOrNull(manager.sourceCommit),
        sourceMatchesExpected: managerSourceMatchesExpected,
      },
      database,
      secrets: compactLaneSecretsStatus(secrets),
      localPostgres,
    },
    nextAction,
  };
  const commanderSummary = {
    aligned,
    runtimeAligned,
    ciEvidenceMissing,
    mirrorAlreadySynced,
    blockers,
    warnings,
    sourceCommit,
    expectedPipelineRun: pipelineRunName,
    expectedGitopsRevision,
    runtimeAlignment,
    branchDrift,
    source: compactSourceStatus,
    gitMirror: compactGitMirrorStatus,
    ci: compactCiStatus,
    argo: compactArgoStatus,
    runtime: compactRuntimeStatus,
    nextAction,
  };
  const result: Record<string, unknown> = {
    ok: sourceProbe.value.exitCode === 0 && runtimeProbe.value.exitCode === 0 && mirrorProbe.value.exitCode === 0 && blockers.length === 0,
    command: "agentrun control-plane status",
    mode: "yaml-declared-node-lane",
    configPath: target.configPath,
    target: options.full || options.raw ? agentRunLaneSummary(spec) : compactAgentRunLaneStatusTarget(spec),
    summary: options.full || options.raw ? detailedSummary : commanderSummary,
    alignment: {
      aligned,
      runtimeAligned,
      ciEvidenceMissing,
      mirrorAlreadySynced,
      blockers,
      warnings,
      sourceCommit,
      expectedPipelineRun: pipelineRunName,
      expectedGitopsRevision,
      runtimeAlignment,
      branchDrift,
    },
    timings: {
      sourceMs: sourceProbe.elapsedMs,
      runtimeMs: runtimeProbe.elapsedMs,
      gitMirrorMs: mirrorProbe.elapsedMs,
      totalMs: sourceProbe.elapsedMs + Math.max(runtimeProbe.elapsedMs, mirrorProbe.elapsedMs),
    },
    disclosure: {
      output: options.full || options.raw ? "full" : "compact-summary",
      full: options.full,
      raw: options.raw,
      omittedWhenCompact: options.full || options.raw ? [] : ["full target YAML summary", "detailed source/runtime/gitMirror objects", "capture stdout/stderr tails for successful probes"],
      fullCommand: statusFullCommand,
    },
    next: {
      action: nextAction,
      plan: `bun scripts/cli.ts agentrun control-plane plan --node ${spec.nodeId} --lane ${spec.lane}`,
      postgresStatus: spec.database.configRef ? `bun scripts/cli.ts platform-db postgres status --config ${spec.database.configRef}` : null,
      postgresApply: spec.database.configRef ? `bun scripts/cli.ts platform-db postgres apply --config ${spec.database.configRef} --confirm` : null,
      secretSync: `bun scripts/cli.ts agentrun control-plane secret-sync --node ${spec.nodeId} --lane ${spec.lane} --confirm`,
      restart: `bun scripts/cli.ts agentrun control-plane restart --node ${spec.nodeId} --lane ${spec.lane} --confirm`,
      statusFull: statusFullCommand,
      triggerCurrent: ciEvidenceMissing || sourceBranchAdvanced ? triggerCurrentCommand : null,
      triggerLatest: sourceBranchAdvanced ? `bun scripts/cli.ts agentrun control-plane trigger-current --node ${spec.nodeId} --lane ${spec.lane} --confirm` : null,
    },
    valuesPrinted: false,
  };
  if (options.full || options.raw || sourceProbe.value.exitCode !== 0 || runtimeProbe.value.exitCode !== 0 || mirrorProbe.value.exitCode !== 0) {
    result.captures = {
      source: compactCapture(sourceProbe.value, { full: options.full || options.raw || sourceProbe.value.exitCode !== 0 }),
      runtime: compactCapture(runtimeProbe.value, { full: options.full || options.raw || runtimeProbe.value.exitCode !== 0 }),
      gitMirror: compactCapture(mirrorProbe.value, { full: options.full || options.raw || mirrorProbe.value.exitCode !== 0 }),
    };
  }
  if (options.full || options.raw) {
    result.source = sourcePayload;
    result.runtime = runtimePayload;
    result.gitMirror = mirrorPayload;
  }
  return result;
}

function agentRunControlPlaneStatusCommand(spec: AgentRunLaneSpec, options: Pick<StatusOptions, "sourceCommit" | "pipelineRun">, full: boolean): string {
  return [
    "bun scripts/cli.ts agentrun control-plane status",
    `--node ${spec.nodeId}`,
    `--lane ${spec.lane}`,
    options.pipelineRun === null ? null : `--pipeline-run ${options.pipelineRun}`,
    options.sourceCommit === null ? null : `--source-commit ${options.sourceCommit}`,
    full ? "--full" : null,
  ].filter(Boolean).join(" ");
}

function renderAgentRunControlPlaneStatusSummary(result: Record<string, unknown>): RenderedCliResult {
  const summary = record(result.summary);
  const target = record(result.target);
  const node = record(target.node);
  const runtimeTarget = record(target.runtime);
  const ciTarget = record(target.ci);
  const source = record(summary.source);
  const gitMirror = record(summary.gitMirror);
  const ci = record(summary.ci);
  const ciRun = record(ci.pipelineRun);
  const argo = record(summary.argo);
  const runtime = record(summary.runtime);
  const runtimeManager = record(runtime.manager);
  const nextAction = record(summary.nextAction);
  const next = record(result.next);
  const disclosure = record(result.disclosure);
  const timings = record(result.timings);
  const blockers = Array.isArray(summary.blockers) ? summary.blockers.map(String) : [];
  const warnings = Array.isArray(summary.warnings) ? summary.warnings.map(String) : [];
  const lines = [
    "AGENTRUN CONTROL-PLANE STATUS",
    renderTable(
      ["NODE", "LANE", "NAMESPACE", "SOURCE", "PIPELINE", "ALIGNED", "RUNTIME", "BLOCKERS"],
      [[
        displayValue(node.id ?? target.node ?? "-"),
        displayValue(target.lane ?? "-"),
        displayValue(runtimeTarget.namespace ?? "-"),
        shortSha(summary.sourceCommit),
        displayValue(summary.expectedPipelineRun ?? "-"),
        yesNo(summary.aligned),
        yesNo(summary.runtimeAligned),
        blockers.length === 0 ? "-" : blockers.join(","),
      ]],
    ),
    "",
    renderTable(
      ["COMPONENT", "STATUS", "DETAIL"],
      [
        ["source", yesNo(source.workspaceClean), `branch=${displayValue(source.branch)} commit=${shortSha(source.remoteBranchCommit)} detached=${yesNo(source.workspaceDetached)}`],
        ["git-mirror", yesNo(gitMirror.alreadySynced), `read=${yesNo(gitMirror.readReady)} write=${yesNo(gitMirror.writeReady)} gitops=${shortSha(gitMirror.gitopsCommit)}`],
        ["ci", yesNo(ciRun.status === "True"), `run=${displayValue(ciRun.name)} status=${displayValue(ciRun.status)} reason=${displayValue(ciRun.reason)} evidenceMissing=${yesNo(ci.evidenceMissing)}`],
        ["argo", yesNo(argo.syncedToGitops), `sync=${displayValue(argo.syncStatus)} health=${displayValue(argo.healthStatus)} revision=${shortSha(argo.revision)}`],
        ["runtime", yesNo(runtimeManager.sourceMatchesExpected), `manager=${shortSha(runtimeManager.sourceCommit)} secrets=${yesNo(runtime.secretsReady)} dbSecret=${yesNo(runtime.databaseSecretPresent)} localPgAbsent=${yesNo(runtime.localPostgresAbsent)}`],
      ],
    ),
    "",
    warnings.length === 0 ? "WARNINGS\n-" : ["WARNINGS", ...warnings.map((warning) => `- ${warning}`)].join("\n"),
    "",
    "NEXT",
    `  action: ${displayValue(nextAction.summary ?? "-")}`,
    nextAction.command ? `  run: ${displayValue(nextAction.command)}` : null,
    `  full: ${displayValue(next.statusFull ?? disclosure.fullCommand ?? "bun scripts/cli.ts agentrun control-plane status --full")}`,
    "",
    `TIMINGS source=${displayValue(timings.sourceMs)}ms runtime=${displayValue(timings.runtimeMs)}ms gitMirror=${displayValue(timings.gitMirrorMs)}ms total=${displayValue(timings.totalMs)}ms`,
  ].filter((line): line is string => line !== null);
  return renderedCliResult(result.ok !== false, "agentrun control-plane status", `${lines.join("\n")}\n`);
}

function yesNo(value: unknown): string {
  if (value === true) return "yes";
  if (value === false) return "no";
  if (value === null || value === undefined) return "-";
  return displayValue(value);
}

function shortSha(value: unknown): string {
  const text = displayValue(value);
  if (/^[0-9a-f]{40}$/u.test(text)) return text.slice(0, 12);
  return text;
}

function compactLaneSecretsStatus(secrets: Record<string, unknown>): Record<string, unknown> {
  const items = Array.isArray(secrets.items) ? secrets.items.filter((item): item is Record<string, unknown> => typeof item === "object" && item !== null && !Array.isArray(item)) : [];
  const missing = items
    .filter((item) => item.present !== true || item.keyPresent !== true)
    .map((item) => ({
      namespace: item.namespace ?? null,
      name: item.name ?? null,
      key: item.key ?? null,
      present: item.present ?? false,
      keyPresent: item.keyPresent ?? false,
    }));
  return {
    ready: secrets.ready ?? false,
    count: secrets.count ?? items.length,
    missingCount: missing.length,
    missing,
    valuesPrinted: false,
  };
}

function compactAgentRunLaneStatusTarget(spec: AgentRunLaneSpec): Record<string, unknown> {
  return {
    node: {
      id: spec.nodeId,
      route: spec.nodeRoute,
      kubeRoute: spec.nodeKubeRoute,
    },
    lane: spec.lane,
    version: spec.version,
    source: {
      repository: spec.source.repository,
      branch: spec.source.branch,
    },
    runtime: {
      namespace: spec.runtime.namespace,
      managerDeployment: spec.runtime.managerDeployment,
      managerService: spec.runtime.managerService,
    },
    ci: {
      namespace: spec.ci.namespace,
      pipeline: spec.ci.pipeline,
      pipelineRunPrefix: spec.ci.pipelineRunPrefix,
    },
    gitops: {
      branch: spec.gitops.branch,
      argoApplication: spec.gitops.argoApplication,
    },
    gitMirror: {
      namespace: spec.gitMirror.namespace,
      readService: spec.gitMirror.readService,
      writeService: spec.gitMirror.writeService,
      repositoryCount: spec.gitMirror.repositories.length,
    },
    database: {
      mode: spec.database.mode,
      provider: spec.database.provider,
      configRef: spec.database.configRef,
      localPostgresExpectedAbsent: spec.database.localPostgresExpectedAbsent,
      valuesPrinted: false,
    },
    secretCount: spec.secrets.length,
    valuesPrinted: false,
  };
}

async function restartYamlLane(config: UniDeskConfig, options: LaneConfirmOptions): Promise<Record<string, unknown>> {
  const { configPath, spec } = resolveAgentRunLaneTarget(options);
  const plan = {
    node: spec.nodeId,
    kubeRoute: spec.nodeKubeRoute,
    lane: spec.lane,
    namespace: spec.runtime.namespace,
    deployment: spec.runtime.managerDeployment,
    annotation: "kubectl.kubernetes.io/restartedAt",
    reason: "reload-lane-secrets-or-runtime-env",
    valuesPrinted: false,
  };
  if (options.dryRun || !options.confirm) {
    return {
      ok: true,
      command: "agentrun control-plane restart",
      mode: "dry-run",
      mutation: false,
      configPath,
      target: agentRunLaneSummary(spec),
      plan,
      next: {
        confirm: `bun scripts/cli.ts agentrun control-plane restart --node ${spec.nodeId} --lane ${spec.lane} --confirm`,
        status: `bun scripts/cli.ts agentrun control-plane status --node ${spec.nodeId} --lane ${spec.lane}`,
      },
      valuesPrinted: false,
    };
  }
  const result = await capture(config, spec.nodeKubeRoute, ["sh", "--", restartYamlLaneScript(spec)]);
  const payload = captureJsonPayload(result);
  return {
    ok: result.exitCode === 0 && payload.ok !== false,
    command: "agentrun control-plane restart",
    mode: "confirmed-rollout-restart",
    mutation: true,
    configPath,
    target: agentRunLaneSummary(spec),
    plan,
    result: payload,
    capture: compactCapture(result, { full: result.exitCode !== 0, stdoutTailChars: 4000, stderrTailChars: 4000 }),
    next: {
      status: `bun scripts/cli.ts agentrun control-plane status --node ${spec.nodeId} --lane ${spec.lane}`,
    },
    valuesPrinted: false,
  };
}

async function secretSync(config: UniDeskConfig, options: SecretSyncOptions): Promise<Record<string, unknown>> {
  const { configPath, spec } = resolveAgentRunLaneTarget(options);
  const sources = collectLaneSecretSources(spec);
  if (sources.length === 0) {
    return {
      ok: false,
      command: "agentrun control-plane secret-sync",
      mode: "yaml-declared-node-lane",
      configPath,
      target: agentRunLaneSummary(spec),
      degradedReason: "lane-secret-sources-not-declared",
      valuesPrinted: false,
    };
  }
  const values = sources.map((source) => ({ spec: source, value: readSecretSourceValue(spec, source) }));
  const plan = values.map(({ spec: item, value }) => ({
    id: item.id,
    namespace: item.targetRef.namespace,
    secret: item.targetRef.name,
    key: item.targetRef.key,
    sourceRef: item.sourceRef,
    sourceMode: item.sourceMode,
    sourceKey: item.sourceKey,
    sourcePath: value.redactedPath,
    fingerprint: value.fingerprint,
    valueBytes: value.valueBytes,
    valuesPrinted: false,
  }));
  if (options.dryRun || !options.confirm) {
    return {
      ok: true,
      command: "agentrun control-plane secret-sync",
      mode: "dry-run",
      mutation: false,
      configPath,
      target: agentRunLaneSummary(spec),
      plan: { secretCount: plan.length, items: plan, valuesPrinted: false },
      next: {
        confirm: `bun scripts/cli.ts agentrun control-plane secret-sync --node ${spec.nodeId} --lane ${spec.lane} --confirm`,
        status: `bun scripts/cli.ts agentrun control-plane status --node ${spec.nodeId} --lane ${spec.lane}`,
      },
      valuesPrinted: false,
    };
  }
  const result = await capture(config, spec.nodeKubeRoute, ["sh", "--", secretSyncScript(spec, values.map(({ spec: item, value }) => ({ targetRef: item.targetRef, value: value.value })))]);
  const payload = captureJsonPayload(result);
  return {
    ok: result.exitCode === 0 && payload.ok !== false,
    command: "agentrun control-plane secret-sync",
    mode: "confirmed-sync",
    mutation: true,
    configPath,
    target: agentRunLaneSummary(spec),
    plan: { secretCount: plan.length, items: plan, valuesPrinted: false },
    result: payload,
    capture: compactCapture(result, { full: result.exitCode !== 0, stdoutTailChars: 3000, stderrTailChars: 3000 }),
    next: {
      status: `bun scripts/cli.ts agentrun control-plane status --node ${spec.nodeId} --lane ${spec.lane}`,
    },
    valuesPrinted: false,
  };
}

async function exposeAgentRun(_config: UniDeskConfig, options: ConfirmOptions): Promise<Record<string, unknown>> {
  const clientConfig = readAgentRunClientConfig();
  const exposure = clientConfig.publicExposure;
  if (!exposure?.enabled) {
    return {
      ok: true,
      command: "agentrun control-plane expose",
      action: "disabled-by-yaml",
      publicExposure: exposureSummary(exposure),
      valuesPrinted: false,
    };
  }
  if (options.dryRun) {
    return {
      ok: true,
      command: "agentrun control-plane expose",
      dryRun: true,
      mutation: false,
      publicExposure: exposureSummary(exposure),
      plan: {
        masterFrps: {
          action: "ensure-allow-port",
          configPath: exposure.masterFrps.configPath,
          containerName: exposure.masterFrps.containerName,
          remotePort: exposure.remotePort,
        },
        masterCaddy: {
          action: "ensure-https-vhost",
          domain: exposure.masterCaddy.domain,
          configPath: exposure.masterCaddy.configPath,
          serviceName: exposure.masterCaddy.serviceName,
          upstreamBaseUrl: exposure.masterCaddy.upstreamBaseUrl,
          responseHeaderTimeoutSeconds: exposure.masterCaddy.responseHeaderTimeoutSeconds,
        },
      },
      next: { confirm: "bun scripts/cli.ts agentrun control-plane expose --confirm" },
      valuesPrinted: false,
    };
  }
  const masterFrps = applyAgentRunMasterFrpsAllowPort(exposure);
  const masterCaddy = applyAgentRunMasterCaddySite(exposure);
  const ok = masterFrps.ok === true && masterCaddy.ok === true;
  return {
    ok,
    command: "agentrun control-plane expose",
    mutation: true,
    publicExposure: exposureSummary(exposure),
    masterFrps,
    masterCaddy,
    validation: {
      publicProbe: `curl -fsS ${exposure.publicBaseUrl.replace(/\/+$/u, "")}/health/readiness`,
      directClient: "bun scripts/cli.ts agentrun get tasks --queue commander -o json",
      valuesPrinted: false,
    },
    valuesPrinted: false,
  };
}

function exposureSummary(exposure: AgentRunPublicExposure | null | undefined): Record<string, unknown> {
  if (!exposure) return { enabled: false, valuesPrinted: false };
  return {
    enabled: exposure.enabled,
    proxyName: exposure.proxyName,
    remotePort: exposure.remotePort,
    publicBaseUrl: exposure.publicBaseUrl,
    masterBaseUrl: exposure.masterBaseUrl,
    frps: {
      configPath: exposure.masterFrps.configPath,
      containerName: exposure.masterFrps.containerName,
    },
    caddy: {
      enabled: exposure.masterCaddy.enabled,
      domain: exposure.masterCaddy.domain,
      configPath: exposure.masterCaddy.configPath,
      serviceName: exposure.masterCaddy.serviceName,
      upstreamBaseUrl: exposure.masterCaddy.upstreamBaseUrl,
      responseHeaderTimeoutSeconds: exposure.masterCaddy.responseHeaderTimeoutSeconds,
    },
    valuesPrinted: false,
  };
}

function applyAgentRunMasterFrpsAllowPort(exposure: AgentRunPublicExposure): Record<string, unknown> {
  const pathValue = exposure.masterFrps.configPath;
  const port = exposure.remotePort;
  const container = exposure.masterFrps.containerName;
  if (!existsSync(pathValue)) return { ok: false, error: "master-frps-config-missing", path: pathValue, valuesPrinted: false };
  const before = readFileSync(pathValue, "utf8");
  const alreadyAllowed = frpsAllowPortExists(before, port);
  let backupPath: string | null = null;
  let action = "kept-existing";
  if (!alreadyAllowed) {
    const stamp = new Date().toISOString().replace(/[-:]/gu, "").replace(/\..*$/u, "Z");
    backupPath = `${pathValue}.bak-agentrun-${stamp}`;
    copyFileSync(pathValue, backupPath);
    writeFileSync(pathValue, `${before.replace(/\s*$/u, "")}\n\n[[allowPorts]]\nstart = ${port}\nend = ${port}\n`, "utf8");
    chmodSync(pathValue, statSync(backupPath).mode & 0o777);
    action = "added-allow-port";
  }
  const restart = alreadyAllowed ? null : spawnSync("docker", ["restart", container], { encoding: "utf8" });
  const inspect = spawnSync("docker", ["inspect", "-f", "{{.State.Running}}", container], { encoding: "utf8" });
  const ok = alreadyAllowed || (restart?.status === 0 && inspect.status === 0 && String(inspect.stdout).trim() === "true");
  return {
    ok,
    action,
    path: pathValue,
    backupPath,
    remotePort: port,
    containerName: container,
    restart: restart === null ? null : { exitCode: restart.status, stdoutTail: String(restart.stdout).slice(-1000), stderrTail: String(restart.stderr).slice(-1000) },
    inspect: { exitCode: inspect.status, running: String(inspect.stdout).trim() === "true", stderrTail: String(inspect.stderr).slice(-1000) },
    valuesPrinted: false,
  };
}

function applyAgentRunMasterCaddySite(exposure: AgentRunPublicExposure): Record<string, unknown> {
  const caddy = exposure.masterCaddy;
  if (!caddy.enabled) return { ok: true, action: "disabled-by-yaml", valuesPrinted: false };
  const pathValue = caddy.configPath;
  if (!existsSync(pathValue)) return { ok: false, error: "master-caddy-config-missing", path: pathValue, valuesPrinted: false };
  const desiredBlock = renderAgentRunCaddySiteBlock(caddy.domain, caddy.upstreamBaseUrl, caddy.responseHeaderTimeoutSeconds);
  const applied = applyLocalCaddyManagedSite({
    serviceId: "agentrun",
    markerName: "agentrun",
    configPath: pathValue,
    serviceName: caddy.serviceName,
    siteBlock: desiredBlock,
    legacySiteDomain: caddy.domain,
  });
  return {
    ...applied,
    domain: caddy.domain,
    upstreamBaseUrl: caddy.upstreamBaseUrl,
    responseHeaderTimeoutSeconds: caddy.responseHeaderTimeoutSeconds,
    valuesPrinted: false,
  };
}

function renderAgentRunCaddySiteBlock(domain: string, upstreamBaseUrl: string, responseHeaderTimeoutSeconds: number): string {
  const upstream = new URL(upstreamBaseUrl);
  const upstreamHost = `${upstream.hostname}${upstream.port ? `:${upstream.port}` : ""}`;
  return `${domain} {
    encode zstd gzip
    reverse_proxy ${upstreamHost} {
        header_up Host {host}
        header_up X-Real-IP {remote_host}
        transport http {
            dial_timeout 5s
            response_header_timeout ${responseHeaderTimeoutSeconds}s
        }
    }
}`;
}

function frpsAllowPortExists(toml: string, port: number): boolean {
  const sections = toml.split(/(?=\[\[allowPorts\]\])/u);
  return sections.some((section) => {
    if (!section.includes("[[allowPorts]]")) return false;
    const start = section.match(/^\s*start\s*=\s*(\d+)\s*$/mu);
    const end = section.match(/^\s*end\s*=\s*(\d+)\s*$/mu);
    return Number(start?.[1]) === port && Number(end?.[1]) === port;
  });
}

async function triggerCurrent(config: UniDeskConfig, options: TriggerOptions): Promise<Record<string, unknown>> {
  return await triggerCurrentYamlLane(config, options, resolveAgentRunLaneTarget(options));
}

async function triggerCurrentYamlLane(config: UniDeskConfig, options: TriggerOptions, target: { configPath: string; spec: AgentRunLaneSpec }): Promise<Record<string, unknown>> {
  const spec = target.spec;
  const probe = await capture(config, spec.nodeRoute, ["sh", "--", yamlLaneSourceBootstrapProbeScript(spec)]);
  const source = captureJsonPayload(probe);
  const sourceCommit = stringOrNull(source.sourceCommit);
  const remoteBranchExists = source.remoteBranchExists === true;
  const pipelineRun = sourceCommit !== null && isGitSha(sourceCommit) ? agentRunPipelineRunName(spec, sourceCommit) : null;
  const placeholderImage = sourceCommit === null ? null : placeholderAgentRunImage(spec, sourceCommit);
  const renderedFiles = placeholderImage === null ? [] : renderAgentRunGitopsFiles(spec, { sourceCommit, image: placeholderImage });
  const plan = {
    node: spec.nodeId,
    lane: spec.lane,
    version: spec.version,
    source: {
      workspace: spec.source.workspace,
      remote: spec.source.remote,
      branch: spec.source.branch,
      bootstrapFromBranch: spec.source.bootstrapFromBranch,
      bootstrapTimeoutSeconds: spec.source.bootstrapTimeoutSeconds,
      bootstrapPollSeconds: spec.source.bootstrapPollSeconds,
      remoteBranchExists,
      sourceCommit,
    },
    deploymentFormat: spec.deployment.format,
    deploymentTruth: "config/agentrun.yaml",
    removedServiceDeployJson: true,
    pipelineRun,
    imageBuild: {
      repository: `${spec.ci.registryPrefix}/${spec.deployment.manager.imageBuild.repository}`,
      containerfile: spec.deployment.manager.imageBuild.containerfile,
      buildArgNames: Object.keys(spec.deployment.manager.imageBuild.buildArgs).sort(),
      timeoutSeconds: spec.deployment.manager.imageBuild.timeoutSeconds,
      pollSeconds: spec.deployment.manager.imageBuild.pollSeconds,
      proxyConfigured: spec.deployment.manager.imageBuild.httpProxy !== null || spec.deployment.manager.imageBuild.httpsProxy !== null,
    },
    gitops: {
      branch: spec.gitops.branch,
      path: spec.gitops.path,
      renderedFileCount: renderedFiles.length,
      renderedFilesDigest: renderedFiles.length === 0 ? null : renderedFilesDigest(renderedFiles),
    },
    valuesPrinted: false,
  };
  if (options.dryRun || !options.confirm) {
    return {
      ok: true,
      command: "agentrun control-plane trigger-current",
      mode: "dry-run",
      mutation: false,
      configPath: target.configPath,
      target: agentRunLaneSummary(spec),
      plan,
      sourceProbe: compactCapture(probe, { full: probe.exitCode !== 0, stdoutTailChars: 3000, stderrTailChars: 3000 }),
      next: {
        confirm: `bun scripts/cli.ts agentrun control-plane trigger-current --node ${spec.nodeId} --lane ${spec.lane} --confirm`,
        status: `bun scripts/cli.ts agentrun control-plane status --node ${spec.nodeId} --lane ${spec.lane}`,
      },
      valuesPrinted: false,
    };
  }
  if (options.wait) {
    return await triggerCurrentYamlLaneConfirmed(config, spec, target.configPath, true);
  }
  return startAsyncAgentRunJob(
    `agentrun_${spec.lane}_trigger_current`,
    ["bun", "scripts/cli.ts", "agentrun", "control-plane", "trigger-current", "--node", spec.nodeId, "--lane", spec.lane, "--confirm", "--wait"],
    `Run AgentRun ${spec.version} YAML-only trigger-current on ${spec.nodeId}`,
  );
}

async function triggerCurrentYamlLaneConfirmed(config: UniDeskConfig, spec: AgentRunLaneSpec, configPath: string, waited: boolean): Promise<Record<string, unknown>> {
  const result = await triggerCurrentYamlLaneConfirmedSteps(config, spec, configPath, waited);
  const restore = await capture(config, spec.nodeRoute, ["sh", "--", yamlLaneSourceRestoreScript(spec)]);
  const restorePayload = captureJsonPayload(restore);
  const restoreOk = restore.exitCode === 0 && restorePayload.ok === true;
  const existingWarnings = Array.isArray(result.warnings) ? result.warnings.filter((item): item is string => typeof item === "string") : [];
  return {
    ...result,
    warnings: restoreOk ? existingWarnings : Array.from(new Set([...existingWarnings, "source-worktree-restore-failed"])),
    sourceWorkspaceRestore: restorePayload,
    sourceWorkspaceRestoreCapture: compactCapture(restore, { full: !restoreOk, stdoutTailChars: 3000, stderrTailChars: 3000 }),
    valuesPrinted: false,
  };
}

async function triggerCurrentYamlLaneConfirmedSteps(config: UniDeskConfig, spec: AgentRunLaneSpec, configPath: string, waited: boolean): Promise<Record<string, unknown>> {
  progressEvent("agentrun.yaml-lane.source-bootstrap.progress", {
    node: spec.nodeId,
    lane: spec.lane,
    status: "submitting",
  });
  const bootstrapSubmit = await capture(config, spec.nodeRoute, ["sh", "--", yamlLaneSourceBootstrapSubmitScript(spec)]);
  const bootstrapSubmitPayload = captureJsonPayload(bootstrapSubmit);
  if (bootstrapSubmit.exitCode !== 0 || bootstrapSubmitPayload.ok === false) {
    return {
      ok: false,
      command: "agentrun control-plane trigger-current",
      mode: waited ? "confirmed-waited" : "confirmed-trigger",
      configPath,
      target: agentRunLaneSummary(spec),
      phase: "source-bootstrap-submit",
      degradedReason: "yaml-lane-source-bootstrap-submit-failed",
      result: bootstrapSubmitPayload,
      capture: compactCapture(bootstrapSubmit, { full: true, stdoutTailChars: 5000, stderrTailChars: 5000 }),
      valuesPrinted: false,
    };
  }
  const bootstrap = await waitForYamlLaneSourceBootstrap(config, spec, stringOrNull(bootstrapSubmitPayload.jobId));
  const bootstrapPayload = bootstrap.payload;
  const sourceCommit = stringOrNull(bootstrapPayload.sourceCommit);
  if (bootstrap.ok !== true || sourceCommit === null || !isGitSha(sourceCommit)) {
    return {
      ok: false,
      command: "agentrun control-plane trigger-current",
      mode: waited ? "confirmed-waited" : "confirmed-trigger",
      configPath,
      target: agentRunLaneSummary(spec),
      phase: "source-bootstrap",
      degradedReason: "yaml-lane-source-bootstrap-failed",
      result: bootstrapPayload,
      bootstrapStatus: bootstrap,
      valuesPrinted: false,
    };
  }
  const buildSubmit = await capture(config, spec.nodeRoute, ["sh", "--", yamlLaneBuildImageSubmitScript(spec, sourceCommit)]);
  const buildSubmitPayload = captureJsonPayload(buildSubmit);
  if (buildSubmit.exitCode !== 0 || buildSubmitPayload.ok === false) {
    return {
      ok: false,
      command: "agentrun control-plane trigger-current",
      mode: waited ? "confirmed-waited" : "confirmed-trigger",
      configPath,
      target: agentRunLaneSummary(spec),
      phase: "image-build-submit",
      sourceCommit,
      degradedReason: "yaml-lane-image-build-submit-failed",
      sourceBootstrap: bootstrapPayload,
      result: buildSubmitPayload,
      capture: compactCapture(buildSubmit, { full: true, stdoutTailChars: 5000, stderrTailChars: 5000 }),
      valuesPrinted: false,
    };
  }
  const build = await waitForYamlLaneBuildImage(config, spec, sourceCommit, stringOrNull(buildSubmitPayload.jobId));
  const buildPayload = build.payload;
  const digest = stringOrNull(buildPayload.digest);
  const envIdentity = stringOrNull(buildPayload.envIdentity);
  if (build.ok !== true || digest === null || envIdentity === null) {
    return {
      ok: false,
      command: "agentrun control-plane trigger-current",
      mode: waited ? "confirmed-waited" : "confirmed-trigger",
      configPath,
      target: agentRunLaneSummary(spec),
      phase: "image-build",
      sourceCommit,
      degradedReason: "yaml-lane-image-build-failed",
      sourceBootstrap: bootstrapPayload,
      buildSubmit: buildSubmitPayload,
      result: buildPayload,
      buildStatus: build,
      valuesPrinted: false,
    };
  }
  const image = agentRunImageArtifact(spec, { sourceCommit, envIdentity, digest, status: stringOrNull(buildPayload.status) ?? "built" });
  const renderedFiles = renderAgentRunGitopsFiles(spec, { sourceCommit, image });
  const mirrorPrePublish = await runYamlLaneGitMirrorSyncJob(config, spec);
  if (mirrorPrePublish.ok !== true) {
    return {
      ok: false,
      command: "agentrun control-plane trigger-current",
      mode: waited ? "confirmed-waited" : "confirmed-trigger",
      configPath,
      target: agentRunLaneSummary(spec),
      phase: "git-mirror-prepublish-sync",
      sourceCommit,
      image,
      degradedReason: "yaml-lane-git-mirror-prepublish-sync-failed",
      sourceBootstrap: bootstrapPayload,
      imageBuild: buildPayload,
      result: mirrorPrePublish,
      valuesPrinted: false,
    };
  }
  progressEvent("agentrun.yaml-lane.gitops-publish.progress", {
    node: spec.nodeId,
    lane: spec.lane,
    sourceCommit,
    status: "submitting",
  });
  const gitops = await runYamlLaneGitopsPublishJob(config, spec, sourceCommit, renderedFiles);
  const gitopsPayload = gitops.payload;
  if (gitops.ok !== true || gitopsPayload.ok === false) {
    return {
      ok: false,
      command: "agentrun control-plane trigger-current",
      mode: waited ? "confirmed-waited" : "confirmed-trigger",
      configPath,
      target: agentRunLaneSummary(spec),
      phase: "gitops-publish",
      sourceCommit,
      image,
      degradedReason: "yaml-lane-gitops-publish-failed",
      sourceBootstrap: bootstrapPayload,
      imageBuild: buildPayload,
      gitMirrorPrePublish: mirrorPrePublish,
      result: gitopsPayload,
      gitopsPublishStatus: gitops,
      valuesPrinted: false,
    };
  }
  const mirrorFlush = await runYamlLaneGitMirrorFlushJob(config, spec);
  if (mirrorFlush.ok !== true) {
    return {
      ok: false,
      command: "agentrun control-plane trigger-current",
      mode: waited ? "confirmed-waited" : "confirmed-trigger",
      configPath,
      target: agentRunLaneSummary(spec),
      phase: "git-mirror-flush",
      sourceCommit,
      image,
      gitops: gitopsPayload,
      gitMirrorPrePublish: mirrorPrePublish,
      degradedReason: "yaml-lane-git-mirror-flush-failed",
      result: mirrorFlush,
      valuesPrinted: false,
    };
  }
  const pipelineRun = agentRunPipelineRunName(spec, sourceCommit);
  const created = await capture(config, spec.nodeKubeRoute, ["sh", "--", yamlLanePipelineRunCreateScript(spec, sourceCommit, pipelineRun)]);
  const createPayload = captureJsonPayload(created);
  return {
    ok: created.exitCode === 0 && createPayload.ok !== false,
    command: "agentrun control-plane trigger-current",
    mode: waited ? "confirmed-waited" : "confirmed-trigger",
    mutation: true,
    configPath,
    target: agentRunLaneSummary(spec),
    sourceCommit,
    pipelineRun,
    image,
    sourceBootstrap: bootstrapPayload,
    imageBuildSubmit: buildSubmitPayload,
    imageBuild: buildPayload,
    renderedFiles: {
      count: renderedFiles.length,
      digest: renderedFilesDigest(renderedFiles),
    },
    gitops: gitopsPayload,
    gitMirrorPrePublish: mirrorPrePublish,
    gitMirror: mirrorFlush,
    created: createPayload,
    capture: compactCapture(created, { full: created.exitCode !== 0, stdoutTailChars: 4000, stderrTailChars: 4000 }),
    next: {
      status: `bun scripts/cli.ts agentrun control-plane status --node ${spec.nodeId} --lane ${spec.lane}`,
      statusByPipelineRun: `bun scripts/cli.ts agentrun control-plane status --node ${spec.nodeId} --lane ${spec.lane} --pipeline-run ${pipelineRun} --full`,
    },
    valuesPrinted: false,
  };
}

async function refresh(config: UniDeskConfig, options: RefreshOptions): Promise<Record<string, unknown>> {
  return await refreshYamlLane(config, options);
}

async function refreshYamlLane(config: UniDeskConfig, options: RefreshOptions): Promise<Record<string, unknown>> {
  const { configPath, spec } = resolveAgentRunLaneTarget(options);
  const plan = {
    node: spec.nodeId,
    lane: spec.lane,
    version: spec.version,
    argoNamespace: spec.gitops.argoNamespace,
    argoApplication: spec.gitops.argoApplication,
    gitopsBranch: spec.gitops.branch,
    mutation: "argocd-hard-refresh",
    valuesPrinted: false,
  };
  if (options.dryRun || !options.confirm) {
    return {
      ok: true,
      command: "agentrun control-plane refresh",
      mode: "dry-run",
      mutation: false,
      configPath,
      target: agentRunLaneSummary(spec),
      plan,
      next: {
        confirm: `bun scripts/cli.ts agentrun control-plane refresh --node ${spec.nodeId} --lane ${spec.lane} --confirm`,
        status: `bun scripts/cli.ts agentrun control-plane status --node ${spec.nodeId} --lane ${spec.lane}`,
      },
      valuesPrinted: false,
    };
  }
  const refreshed = await capture(config, spec.nodeKubeRoute, ["sh", "--", refreshYamlLaneScript(spec)]);
  const payload = captureJsonPayload(refreshed);
  return {
    ok: refreshed.exitCode === 0 && payload.ok !== false,
    command: "agentrun control-plane refresh",
    mode: "confirmed-yaml-lane",
    mutation: true,
    configPath,
    target: agentRunLaneSummary(spec),
    plan,
    result: payload,
    refreshed: compactCapture(refreshed, { full: refreshed.exitCode !== 0, stdoutTailChars: 3000, stderrTailChars: 3000 }),
    next: {
      status: `bun scripts/cli.ts agentrun control-plane status --node ${spec.nodeId} --lane ${spec.lane}`,
    },
    valuesPrinted: false,
  };
}

async function cleanupRunners(config: UniDeskConfig, options: CleanupRunnersOptions): Promise<Record<string, unknown>> {
  const { configPath, spec } = resolveAgentRunLaneTarget(options);
  const result = await capture(config, spec.nodeKubeRoute, ["sh", "--", cleanupRunnersScript(options, spec)]);
  const payload = captureJsonPayload(result);
  const ok = result.exitCode === 0 && payload.ok !== false;
  const base = {
    ...payload,
    ok,
    command: "agentrun control-plane cleanup-runners",
    configPath,
    target: agentRunLaneSummary(spec),
    mode: options.dryRun || !options.confirm ? "dry-run" : "confirmed-cleanup",
    namespace: spec.runtime.namespace,
    retention: spec.deployment.runner.retention,
    probe: compactCapture(result, { full: result.exitCode !== 0, stdoutTailChars: 3000, stderrTailChars: 3000 }),
  };
  if (options.dryRun || !options.confirm) {
    return {
      ...base,
      dryRun: true,
      mutation: false,
      next: {
        confirm: `bun scripts/cli.ts agentrun control-plane cleanup-runners --node ${spec.nodeId} --lane ${spec.lane}${options.forceActive ? " --force-active" : ""} --confirm`,
      },
    };
  }
  return {
    ...base,
    dryRun: false,
    mutation: true,
    followUp: {
      dryRun: `bun scripts/cli.ts agentrun control-plane cleanup-runners --node ${spec.nodeId} --lane ${spec.lane}${options.forceActive ? " --force-active" : ""} --dry-run`,
      status: `bun scripts/cli.ts agentrun control-plane status --node ${spec.nodeId} --lane ${spec.lane}`,
    },
  };
}

async function cleanupRuns(config: UniDeskConfig, options: CleanupRunsOptions): Promise<Record<string, unknown>> {
  const { configPath, spec } = resolveAgentRunLaneTarget(options);
  const result = await capture(config, spec.nodeKubeRoute, ["sh", "--", cleanupRunsScript(options, spec.ci.namespace, spec.ci.pipelineRunPrefix)]);
  const payload = captureJsonPayload(result);
  const ok = result.exitCode === 0 && payload.ok !== false;
  const base = {
    ...payload,
    ok,
    command: "agentrun control-plane cleanup-runs",
    configPath,
    target: agentRunLaneSummary(spec),
    mode: options.dryRun || !options.confirm ? "dry-run" : "confirmed-cleanup",
    namespace: spec.ci.namespace,
    minAgeMinutes: options.minAgeMinutes,
    limit: options.limit,
    probe: compactCapture(result, { full: result.exitCode !== 0, stdoutTailChars: 3000, stderrTailChars: 3000 }),
  };
  if (options.dryRun || !options.confirm) {
    return {
      ...base,
      dryRun: true,
      mutation: false,
      next: {
        confirm: `bun scripts/cli.ts agentrun control-plane cleanup-runs --node ${spec.nodeId} --lane ${spec.lane} --min-age-minutes ${options.minAgeMinutes} --limit ${options.limit} --confirm`,
      },
    };
  }
  return {
    ...base,
    dryRun: false,
    mutation: true,
    followUp: {
      status: `bun scripts/cli.ts agentrun control-plane status --node ${spec.nodeId} --lane ${spec.lane}`,
      releasedPvs: `bun scripts/cli.ts agentrun control-plane cleanup-released-pvs --node ${spec.nodeId} --lane ${spec.lane} --limit ${options.limit} --dry-run`,
      diskPressure: `trans ${spec.nodeKubeRoute} kubectl get node -o jsonpath='{range .items[*]}{.metadata.name}{\"\\t\"}{range .status.conditions[*]}{.type}{\"=\"}{.status}{\" \"}{.reason}{\";\"}{end}{\"\\n\"}{end}'`,
    },
  };
}

async function cleanupReleasedPvs(config: UniDeskConfig, options: CleanupReleasedPvOptions): Promise<Record<string, unknown>> {
  const { configPath, spec } = resolveAgentRunLaneTarget(options);
  const result = await capture(config, spec.nodeKubeRoute, ["sh", "--", cleanupReleasedPvsScript(options, spec.ci.namespace)]);
  const payload = captureJsonPayload(result);
  const ok = result.exitCode === 0 && payload.ok !== false;
  const base = {
    ...payload,
    ok,
    command: "agentrun control-plane cleanup-released-pvs",
    configPath,
    target: agentRunLaneSummary(spec),
    mode: options.dryRun || !options.confirm ? "dry-run" : "confirmed-cleanup",
    namespace: spec.ci.namespace,
    limit: options.limit,
    probe: compactCapture(result, { full: result.exitCode !== 0, stdoutTailChars: 3000, stderrTailChars: 3000 }),
  };
  if (options.dryRun || !options.confirm) {
    return {
      ...base,
      dryRun: true,
      mutation: false,
      next: {
        confirm: `bun scripts/cli.ts agentrun control-plane cleanup-released-pvs --node ${spec.nodeId} --lane ${spec.lane} --limit ${options.limit} --confirm`,
      },
    };
  }
  return {
    ...base,
    dryRun: false,
    mutation: true,
    followUp: {
      cleanupRuns: `bun scripts/cli.ts agentrun control-plane cleanup-runs --node ${spec.nodeId} --lane ${spec.lane} --min-age-minutes 30 --limit ${options.limit} --dry-run`,
      diskPressure: `trans ${spec.nodeKubeRoute} kubectl get node -o jsonpath='{range .items[*]}{.metadata.name}{\"\\t\"}{range .status.conditions[*]}{.type}{\"=\"}{.status}{\" \"}{.reason}{\";\"}{end}{\"\\n\"}{end}'`,
    },
  };
}

function cleanupRunnersScript(options: CleanupRunnersOptions, spec: AgentRunLaneSpec): string {
  const retention = spec.deployment.runner.retention;
  const matchLabelsB64 = Buffer.from(JSON.stringify(retention.selectors.matchLabels), "utf8").toString("base64");
  const jobNamePrefixesB64 = Buffer.from(JSON.stringify(retention.selectors.jobNamePrefixes), "utf8").toString("base64");
  return [
    "set -eu",
    `namespace=${shQuote(spec.runtime.namespace)}`,
    `manager_deployment=${shQuote(spec.runtime.managerDeployment)}`,
    `max_runners=${String(retention.maxRunners)}`,
    `cleanup_order=${shQuote(retention.cleanupOrder)}`,
    `active_heartbeat_max_age_ms=${String(retention.activeHeartbeatMaxAgeMs)}`,
    `age_based_cleanup_enabled=${retention.ageBasedCleanup.enabled ? "true" : "false"}`,
    `age_based_max_age_hours=${retention.ageBasedCleanup.maxAgeHours === null ? "" : String(retention.ageBasedCleanup.maxAgeHours)}`,
    `timeout_seconds=${String(options.timeoutSeconds)}`,
    `force_active=${options.forceActive ? "true" : "false"}`,
    `match_labels_json_b64=${shQuote(matchLabelsB64)}`,
    `job_name_prefixes_json_b64=${shQuote(jobNamePrefixesB64)}`,
    "match_labels_json=$(printf '%s' \"$match_labels_json_b64\" | base64 -d)",
    "job_name_prefixes_json=$(printf '%s' \"$job_name_prefixes_json_b64\" | base64 -d)",
    "tmp_dir=$(mktemp -d)",
    "trap 'rm -rf \"$tmp_dir\"' EXIT",
    "kubectl -n \"$namespace\" get job -o json > \"$tmp_dir/jobs.json\"",
    "kubectl -n \"$namespace\" get pod -o json > \"$tmp_dir/pods.json\"",
    "facts_exit=0",
    "set +e",
    "kubectl -n \"$namespace\" exec -i deploy/\"$manager_deployment\" -- env RETENTION_NAMESPACE=\"$namespace\" sh -lc 'cat >/tmp/agentrun-runner-retention.mjs && bun /tmp/agentrun-runner-retention.mjs' > \"$tmp_dir/runner-facts.json\" 2> \"$tmp_dir/runner-facts.err\" <<'NODE'",
    cleanupRunnersFactsNodeScript(),
    "NODE",
    "facts_exit=$?",
    "set -e",
    "if [ \"$facts_exit\" -ne 0 ]; then",
    "  printf '%s\\n' '{\"ok\":false,\"items\":[],\"failureKind\":\"manager-facts-unavailable\",\"valuesPrinted\":false}' > \"$tmp_dir/runner-facts.json\"",
    "fi",
    "MATCH_LABELS_JSON=\"$match_labels_json\" JOB_NAME_PREFIXES_JSON=\"$job_name_prefixes_json\" MAX_RUNNERS=\"$max_runners\" CLEANUP_ORDER=\"$cleanup_order\" ACTIVE_HEARTBEAT_MAX_AGE_MS=\"$active_heartbeat_max_age_ms\" AGE_BASED_CLEANUP_ENABLED=\"$age_based_cleanup_enabled\" AGE_BASED_MAX_AGE_HOURS=\"$age_based_max_age_hours\" FORCE_ACTIVE=\"$force_active\" FACTS_EXIT=\"$facts_exit\" TMP_DIR=\"$tmp_dir\" NAMESPACE=\"$namespace\" node <<'NODE' > \"$tmp_dir/plan.json\"",
    cleanupRunnersPlanNodeScript(),
    "NODE",
    "if [ " + shQuote(options.confirm && !options.dryRun ? "true" : "false") + " != true ]; then",
    "  cat \"$tmp_dir/plan.json\"",
    "  exit 0",
    "fi",
    "node -e 'const fs=require(\"node:fs\"); const plan=JSON.parse(fs.readFileSync(process.argv[1],\"utf8\")); const names=Array.isArray(plan.selectedRunnerJobs)?plan.selectedRunnerJobs:[]; fs.writeFileSync(process.argv[2], names.join(\"\\n\") + (names.length>0?\"\\n\":\"\"));' \"$tmp_dir/plan.json\" \"$tmp_dir/selected-jobs.txt\"",
    "delete_exit=0",
    "if [ -s \"$tmp_dir/selected-jobs.txt\" ]; then",
    "  xargs -r kubectl -n \"$namespace\" delete job --ignore-not-found=true --wait=true --timeout=\"${timeout_seconds}s\" < \"$tmp_dir/selected-jobs.txt\" > \"$tmp_dir/delete.out\" 2> \"$tmp_dir/delete.err\" || delete_exit=$?",
    "else",
    "  : > \"$tmp_dir/delete.out\"",
    "  : > \"$tmp_dir/delete.err\"",
    "fi",
    "kubectl -n \"$namespace\" get job -o json > \"$tmp_dir/jobs-after.json\"",
    "kubectl -n \"$namespace\" get pod -o json > \"$tmp_dir/pods-after.json\"",
    "DELETE_EXIT=\"$delete_exit\" TMP_DIR=\"$tmp_dir\" node <<'NODE'",
    cleanupRunnersFinalizeNodeScript(),
    "NODE",
  ].join("\n");
}

function cleanupRunsScript(options: CleanupRunsOptions, namespace: string, pipelineRunPrefix: string): string {
  return [
    "set -eu",
    `namespace=${shQuote(namespace)}`,
    `pipeline_run_prefix=${shQuote(pipelineRunPrefix)}`,
    `min_age_minutes=${String(options.minAgeMinutes)}`,
    `limit=${String(options.limit)}`,
    `timeout_seconds=${String(options.timeoutSeconds)}`,
    "tmp_dir=$(mktemp -d)",
    "trap 'rm -rf \"$tmp_dir\"' EXIT",
    "kubectl -n \"$namespace\" get pipelinerun -o json > \"$tmp_dir/pipelineruns.json\"",
    "kubectl -n \"$namespace\" get pvc -o json > \"$tmp_dir/pvcs.json\"",
    "kubectl get pv -o json > \"$tmp_dir/pvs.json\"",
    "kubectl -n \"$namespace\" get pod -o json > \"$tmp_dir/pods.json\"",
    "NAMESPACE=\"$namespace\" PIPELINE_RUN_PREFIX=\"$pipeline_run_prefix\" MIN_AGE_MINUTES=\"$min_age_minutes\" LIMIT=\"$limit\" TMP_DIR=\"$tmp_dir\" node <<'NODE' > \"$tmp_dir/plan.json\"",
    cleanupRunsPlanNodeScript(),
    "NODE",
    "if [ " + shQuote(options.confirm && !options.dryRun ? "true" : "false") + " != true ]; then",
    "  cat \"$tmp_dir/plan.json\"",
    "  exit 0",
    "fi",
    "node -e 'const fs=require(\"node:fs\"); const plan=JSON.parse(fs.readFileSync(process.argv[1],\"utf8\")); const names=Array.isArray(plan.selectedPipelineRuns)?plan.selectedPipelineRuns:[]; fs.writeFileSync(process.argv[2], names.join(\"\\n\") + (names.length>0?\"\\n\":\"\"));' \"$tmp_dir/plan.json\" \"$tmp_dir/selected-names.txt\"",
    "delete_exit=0",
    "if [ -s \"$tmp_dir/selected-names.txt\" ]; then",
    "  xargs -r kubectl -n \"$namespace\" delete pipelinerun --ignore-not-found=true --wait=true --timeout=\"${timeout_seconds}s\" < \"$tmp_dir/selected-names.txt\" > \"$tmp_dir/delete.out\" 2> \"$tmp_dir/delete.err\" || delete_exit=$?",
    "else",
    "  : > \"$tmp_dir/delete.out\"",
    "  : > \"$tmp_dir/delete.err\"",
    "fi",
    "kubectl -n \"$namespace\" get pvc -o json > \"$tmp_dir/pvcs-after.json\"",
    "DELETE_EXIT=\"$delete_exit\" TMP_DIR=\"$tmp_dir\" node <<'NODE'",
    cleanupRunsFinalizeNodeScript(),
    "NODE",
  ].join("\n");
}

function cleanupReleasedPvsScript(options: CleanupReleasedPvOptions, namespace: string): string {
  return [
    "set -eu",
    `namespace=${shQuote(namespace)}`,
    `limit=${String(options.limit)}`,
    `timeout_seconds=${String(options.timeoutSeconds)}`,
    "tmp_dir=$(mktemp -d)",
    "trap 'rm -rf \"$tmp_dir\"' EXIT",
    "kubectl get pv -o json > \"$tmp_dir/pvs.json\"",
    "NAMESPACE=\"$namespace\" LIMIT=\"$limit\" TMP_DIR=\"$tmp_dir\" node <<'NODE' > \"$tmp_dir/plan.json\"",
    cleanupReleasedPvsPlanNodeScript(),
    "NODE",
    "if [ " + shQuote(options.confirm && !options.dryRun ? "true" : "false") + " != true ]; then",
    "  cat \"$tmp_dir/plan.json\"",
    "  exit 0",
    "fi",
    "node -e 'const fs=require(\"node:fs\"); const plan=JSON.parse(fs.readFileSync(process.argv[1],\"utf8\")); const names=Array.isArray(plan.selectedPersistentVolumes)?plan.selectedPersistentVolumes:[]; fs.writeFileSync(process.argv[2], names.join(\"\\n\") + (names.length>0?\"\\n\":\"\"));' \"$tmp_dir/plan.json\" \"$tmp_dir/selected-pvs.txt\"",
    "delete_exit=0",
    "if [ -s \"$tmp_dir/selected-pvs.txt\" ]; then",
    "  xargs -r kubectl delete pv --ignore-not-found=true --wait=true --timeout=\"${timeout_seconds}s\" < \"$tmp_dir/selected-pvs.txt\" > \"$tmp_dir/delete.out\" 2> \"$tmp_dir/delete.err\" || delete_exit=$?",
    "else",
    "  : > \"$tmp_dir/delete.out\"",
    "  : > \"$tmp_dir/delete.err\"",
    "fi",
    "kubectl get pv -o json > \"$tmp_dir/pvs-after.json\"",
    "DELETE_EXIT=\"$delete_exit\" TMP_DIR=\"$tmp_dir\" node <<'NODE'",
    cleanupReleasedPvsFinalizeNodeScript(),
    "NODE",
  ].join("\n");
}

function yamlLaneSourceStatusScript(spec: AgentRunLaneSpec): string {
  return [
    "set +e",
    `expected_workspace=${shQuote(spec.source.workspace)}`,
    `source_branch=${shQuote(spec.source.branch)}`,
    "workspace_exists=false",
    "workspace_clean=null",
    "local_head=null",
    "branch=null",
    "remote_url=null",
    "remote_branch_exists=false",
    "remote_branch_commit=null",
    "status_short=''",
    "if [ -d .git ] || git rev-parse --show-toplevel >/dev/null 2>&1; then",
    "  actual_workspace=$(pwd)",
    "  workspace_exists=true",
    "  branch=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || true)",
    "  remote_url=$(git remote get-url origin 2>/dev/null || true)",
    "  local_head=$(git rev-parse HEAD 2>/dev/null || true)",
    "  status_short=$(git status --short 2>/dev/null || true)",
    "  if [ -z \"$status_short\" ]; then workspace_clean=true; else workspace_clean=false; fi",
    "  git fetch origin \"$source_branch\" >/dev/null 2>&1 || true",
    "  remote_branch_commit=$(git rev-parse \"refs/remotes/origin/$source_branch\" 2>/dev/null || true)",
    "  if [ -n \"$remote_branch_commit\" ]; then remote_branch_exists=true; fi",
    "else",
    "  actual_workspace=$(pwd)",
    "fi",
    "export expected_workspace source_branch workspace_exists workspace_clean local_head branch remote_url remote_branch_exists remote_branch_commit status_short actual_workspace",
    "node <<'NODE'",
    "function nullable(value) { return value && value !== 'null' ? value : null; }",
    "function booleanValue(value) { if (value === 'true') return true; if (value === 'false') return false; return null; }",
    "const env = process.env;",
    "console.log(JSON.stringify({",
    "  ok: env.workspace_exists === 'true',",
    "  expectedWorkspace: env.expected_workspace,",
    "  actualWorkspace: env.actual_workspace || null,",
    "  workspaceExists: env.workspace_exists === 'true',",
    "  workspaceClean: booleanValue(env.workspace_clean),",
    "  branch: nullable(env.branch),",
    "  remoteUrl: nullable(env.remote_url),",
    "  localHead: nullable(env.local_head),",
    "  remoteBranch: env.source_branch,",
    "  remoteBranchExists: env.remote_branch_exists === 'true',",
    "  remoteBranchCommit: nullable(env.remote_branch_commit),",
    "  statusShort: nullable(env.status_short),",
    "  valuesPrinted: false",
    "}));",
    "NODE",
  ].join("\n");
}

function yamlLaneRuntimeStatusScript(spec: AgentRunLaneSpec, pipelineRun: string | null): string {
  return [
    "set +e",
    `runtime_namespace=${shQuote(spec.runtime.namespace)}`,
    `ci_namespace=${shQuote(spec.ci.namespace)}`,
    `pipeline_name=${shQuote(spec.ci.pipeline)}`,
    `pipeline_run=${pipelineRun === null ? "''" : shQuote(pipelineRun)}`,
    `service_account=${shQuote(spec.ci.serviceAccountName)}`,
    `argo_namespace=${shQuote(spec.gitops.argoNamespace)}`,
    `argo_application=${shQuote(spec.gitops.argoApplication)}`,
    `manager_deployment=${shQuote(spec.runtime.managerDeployment)}`,
    `manager_service=${shQuote(spec.runtime.managerService)}`,
    `database_secret=${shQuote(spec.database.secretRef.name)}`,
    `database_key=${shQuote(spec.database.secretRef.key)}`,
    `secrets_json=${shQuote(JSON.stringify(collectLaneSecretSources(spec).map((item) => item.targetRef)))}`,
    "export runtime_namespace ci_namespace pipeline_name pipeline_run service_account argo_namespace argo_application manager_deployment manager_service database_secret database_key secrets_json",
    "tmp_dir=$(mktemp -d)",
    "trap 'rm -rf \"$tmp_dir\"' EXIT",
    "kubectl get ns \"$runtime_namespace\" -o json > \"$tmp_dir/runtime-ns.json\" 2>/dev/null",
    "runtime_ns_exit=$?",
    "kubectl get ns \"$ci_namespace\" -o json > \"$tmp_dir/ci-ns.json\" 2>/dev/null",
    "ci_ns_exit=$?",
    "kubectl -n \"$ci_namespace\" get pipeline \"$pipeline_name\" -o json > \"$tmp_dir/pipeline.json\" 2>/dev/null",
    "pipeline_exit=$?",
    "kubectl -n \"$ci_namespace\" get serviceaccount \"$service_account\" -o json > \"$tmp_dir/serviceaccount.json\" 2>/dev/null",
    "sa_exit=$?",
    "if [ -n \"$pipeline_run\" ]; then kubectl -n \"$ci_namespace\" get pipelinerun \"$pipeline_run\" -o json > \"$tmp_dir/pipelinerun.json\" 2>/dev/null; pr_exit=$?; else pr_exit=2; fi",
    "kubectl -n \"$argo_namespace\" get application \"$argo_application\" -o json > \"$tmp_dir/argo.json\" 2>/dev/null",
    "argo_exit=$?",
    "kubectl -n \"$runtime_namespace\" get deploy \"$manager_deployment\" -o json > \"$tmp_dir/manager-deploy.json\" 2>/dev/null",
    "manager_deploy_exit=$?",
    "kubectl -n \"$runtime_namespace\" get svc \"$manager_service\" -o json > \"$tmp_dir/manager-svc.json\" 2>/dev/null",
    "manager_svc_exit=$?",
    "kubectl -n \"$runtime_namespace\" get secret \"$database_secret\" -o json > \"$tmp_dir/db-secret.json\" 2>/dev/null",
    "db_secret_exit=$?",
    "SECRET_REFS_JSON=\"$secrets_json\" NODE_TMP=\"$tmp_dir\" node <<'NODE' > \"$tmp_dir/secrets.json\"",
    "const fs = require('node:fs');",
    "const cp = require('node:child_process');",
    "const refs = JSON.parse(process.env.SECRET_REFS_JSON || '[]');",
    "const result = [];",
    "for (const ref of refs) {",
    "  const out = cp.spawnSync('kubectl', ['-n', ref.namespace, 'get', 'secret', ref.name, '-o', 'json'], { encoding: 'utf8' });",
    "  let keyPresent = false;",
    "  if (out.status === 0) {",
    "    try { keyPresent = Object.prototype.hasOwnProperty.call((JSON.parse(out.stdout).data || {}), ref.key); } catch {}",
    "  }",
    "  result.push({ namespace: ref.namespace, name: ref.name, key: ref.key, present: out.status === 0, keyPresent, valuesPrinted: false });",
    "}",
    "console.log(JSON.stringify({ ready: result.every((item) => item.present && item.keyPresent), count: result.length, items: result, valuesPrinted: false }));",
    "NODE",
    "kubectl -n \"$runtime_namespace\" get deploy,sts,svc,secret -o name > \"$tmp_dir/runtime-names.txt\" 2>/dev/null",
    "NODE_TMP=\"$tmp_dir\" RUNTIME_NS_EXIT=\"$runtime_ns_exit\" CI_NS_EXIT=\"$ci_ns_exit\" PIPELINE_EXIT=\"$pipeline_exit\" SERVICE_ACCOUNT_EXIT=\"$sa_exit\" PIPELINERUN_EXIT=\"$pr_exit\" ARGO_EXIT=\"$argo_exit\" MANAGER_DEPLOY_EXIT=\"$manager_deploy_exit\" MANAGER_SVC_EXIT=\"$manager_svc_exit\" DB_SECRET_EXIT=\"$db_secret_exit\" node <<'NODE'",
    "const fs = require('node:fs');",
    "const path = require('node:path');",
    "const dir = process.env.NODE_TMP;",
    "function readJson(name) { try { return JSON.parse(fs.readFileSync(path.join(dir, name), 'utf8')); } catch { return null; } }",
    "function exists(exitName) { return process.env[exitName] === '0'; }",
    "function condition(obj) { return obj?.status?.conditions?.[0] || null; }",
    "function envValue(deploy, name) { return deploy?.spec?.template?.spec?.containers?.[0]?.env?.find((entry) => entry.name === name)?.value || null; }",
    "function pipelineRunParam(obj, name) { return (obj?.spec?.params || []).find((entry) => entry.name === name)?.value || null; }",
    "const pipelineRun = readJson('pipelinerun.json');",
    "const argo = readJson('argo.json');",
    "const managerDeploy = readJson('manager-deploy.json');",
    "const managerSvc = readJson('manager-svc.json');",
    "const dbSecret = readJson('db-secret.json');",
    "const secrets = readJson('secrets.json') || { ready: true, count: 0, items: [], valuesPrinted: false };",
    "let names = ''; try { names = fs.readFileSync(path.join(dir, 'runtime-names.txt'), 'utf8'); } catch {}",
    "const c = condition(pipelineRun);",
    "console.log(JSON.stringify({",
    "  ok: exists('RUNTIME_NS_EXIT') && exists('CI_NS_EXIT'),",
    "  runtimeNamespaceExists: exists('RUNTIME_NS_EXIT'),",
    "  ciNamespaceExists: exists('CI_NS_EXIT'),",
    "  serviceAccountExists: exists('SERVICE_ACCOUNT_EXIT'),",
    "  pipeline: { exists: exists('PIPELINE_EXIT'), name: process.env.pipeline_name },",
    "  pipelineRun: { exists: exists('PIPELINERUN_EXIT'), name: process.env.pipeline_run || null, status: c?.status || null, reason: c?.reason || null, sourceCommit: pipelineRunParam(pipelineRun, 'revision'), startTime: pipelineRun?.status?.startTime || null, completionTime: pipelineRun?.status?.completionTime || null },",
    "  argo: { exists: exists('ARGO_EXIT'), namespace: process.env.argo_namespace, application: process.env.argo_application, revision: argo?.status?.sync?.revision || null, syncStatus: argo?.status?.sync?.status || null, healthStatus: argo?.status?.health?.status || null },",
    "  manager: { deploymentExists: exists('MANAGER_DEPLOY_EXIT'), serviceExists: exists('MANAGER_SVC_EXIT'), deployment: process.env.manager_deployment, service: process.env.manager_service, image: managerDeploy?.spec?.template?.spec?.containers?.[0]?.image || null, sourceCommit: envValue(managerDeploy, 'AGENTRUN_SOURCE_COMMIT'), servicePorts: Array.isArray(managerSvc?.spec?.ports) ? managerSvc.spec.ports.map((port) => ({ name: port.name || null, port: port.port || null, targetPort: port.targetPort || null })) : [] },",
    "  database: { secretPresent: exists('DB_SECRET_EXIT'), secretName: process.env.database_secret, key: process.env.database_key, keyPresent: Boolean(dbSecret?.data && Object.prototype.hasOwnProperty.call(dbSecret.data, process.env.database_key || '')) , valuesPrinted: false },",
    "  secrets,",
    "  localPostgres: { absent: !/postgres/i.test(names), matchingObjects: names.split(/\\r?\\n/).filter((line) => /postgres/i.test(line)).slice(0, 20) },",
    "  valuesPrinted: false",
    "}));",
    "NODE",
  ].join("\n");
}

function yamlLaneSourceBootstrapProbeScript(spec: AgentRunLaneSpec): string {
  return [
    "set +e",
    `workspace=${shQuote(spec.source.workspace)}`,
    `remote=${shQuote(spec.source.remote)}`,
    `branch=${shQuote(spec.source.branch)}`,
    "workspace_exists=false",
    "remote_branch_exists=false",
    "source_commit=null",
    "if [ -d \"$workspace/.git\" ]; then",
    "  workspace_exists=true",
    "  cd \"$workspace\"",
    "  remote_branch=$(git ls-remote --heads \"$remote\" \"$branch\" 2>/dev/null | awk '{print $1}' | head -n 1)",
    "  if [ -n \"$remote_branch\" ]; then remote_branch_exists=true; source_commit=\"$remote_branch\"; else source_commit=$(git rev-parse HEAD 2>/dev/null || printf null); fi",
    "else",
    "  remote_branch=$(git ls-remote --heads \"$remote\" \"$branch\" 2>/dev/null | awk '{print $1}' | head -n 1)",
    "  if [ -n \"$remote_branch\" ]; then remote_branch_exists=true; source_commit=\"$remote_branch\"; fi",
    "fi",
    "export workspace_exists remote_branch_exists source_commit",
    "node <<'NODE'",
    "console.log(JSON.stringify({ ok: true, workspaceExists: process.env.workspace_exists === 'true', remoteBranchExists: process.env.remote_branch_exists === 'true', sourceCommit: process.env.source_commit === 'null' ? null : process.env.source_commit, valuesPrinted: false }));",
    "NODE",
  ].join("\n");
}

function yamlLaneSourceBootstrapSubmitScript(spec: AgentRunLaneSpec): string {
  const bootstrap = spec.source.bootstrapFromBranch ?? spec.source.branch;
  const stateDir = `/tmp/unidesk-agentrun-source-${spec.nodeId}-${spec.lane}`;
  return [
    "set -eu",
    `workspace=${shQuote(spec.source.workspace)}`,
    `remote=${shQuote(spec.source.remote)}`,
    `branch=${shQuote(spec.source.branch)}`,
    `bootstrap_branch=${shQuote(bootstrap)}`,
    `state_dir=${shQuote(stateDir)}`,
    "mkdir -p \"$state_dir\" \"$(dirname \"$workspace\")\"",
    "job_id=\"source-bootstrap-$(date +%s)-$$\"",
    "status_file=\"$state_dir/$job_id.json\"",
    "stdout_file=\"$state_dir/$job_id.stdout.log\"",
    "stderr_file=\"$state_dir/$job_id.stderr.log\"",
    "cat > \"$status_file\" <<EOF",
    "{\"ok\":false,\"status\":\"running\",\"jobId\":\"$job_id\",\"workspace\":\"$workspace\",\"branch\":\"$branch\",\"valuesPrinted\":false}",
    "EOF",
    "(",
    "  set -eu",
    "  write_failed_status() { code=$?; if [ \"$code\" -ne 0 ]; then tail_text=$(tail -n 60 \"$stderr_file\" 2>/dev/null | sed 's/\"/\\\\\"/g' | tr '\\n' ' ' | cut -c1-3000); CODE=\"$code\" ERROR_TAIL=\"$tail_text\" JOB_ID=\"$job_id\" WORKSPACE=\"$workspace\" BRANCH=\"$branch\" node <<'NODE' > \"$status_file\"",
    "const code = Number(process.env.CODE || 1);",
    "console.log(JSON.stringify({ ok: false, status: 'failed', exitCode: code, jobId: process.env.JOB_ID, workspace: process.env.WORKSPACE, branch: process.env.BRANCH, errorTail: process.env.ERROR_TAIL || null, valuesPrinted: false }));",
    "NODE",
    "  fi; exit \"$code\"; }",
    "  trap write_failed_status EXIT",
    "  if [ -d \"$workspace/.git\" ] && git -C \"$workspace\" rev-parse --git-dir >/dev/null 2>&1; then",
    "    :",
    "  else",
    "    rm -rf \"$workspace\"",
    "    git clone --no-checkout \"$remote\" \"$workspace\"",
    "  fi",
    "  cd \"$workspace\"",
    "  git remote set-url origin \"$remote\" || git remote add origin \"$remote\"",
    "  git fetch origin \"$bootstrap_branch\" \"$branch\" || git fetch origin \"$bootstrap_branch\"",
    "  if git rev-parse --verify \"refs/remotes/origin/$branch^{commit}\" >/dev/null 2>&1; then",
    "    git checkout -B \"$branch\" \"refs/remotes/origin/$branch\"",
    "  else",
    "    git checkout -B \"$branch\" \"refs/remotes/origin/$bootstrap_branch\"",
    "  fi",
    "  if [ -f deploy/deploy.json ]; then rm deploy/deploy.json; fi",
    "  git add -A deploy/deploy.json 2>/dev/null || true",
    "  if ! git diff --quiet --cached -- deploy/deploy.json 2>/dev/null; then",
    "    git -c user.email=agentrun@unidesk.local -c user.name='UniDesk AgentRun Ops' commit -m 'chore: remove service deploy json truth'",
    "  fi",
    "  git push -u origin \"$branch\"",
    "  source_commit=$(git rev-parse HEAD)",
    "  status_short=$(git status --short)",
    "  SOURCE_COMMIT=\"$source_commit\" STATUS_SHORT=\"$status_short\" JOB_ID=\"$job_id\" WORKSPACE=\"$workspace\" BRANCH=\"$branch\" node <<'NODE' > \"$status_file\"",
    "console.log(JSON.stringify({ ok: process.env.STATUS_SHORT === '', status: 'succeeded', jobId: process.env.JOB_ID, workspace: process.env.WORKSPACE, branch: process.env.BRANCH, sourceCommit: process.env.SOURCE_COMMIT, workspaceClean: process.env.STATUS_SHORT === '', statusShort: process.env.STATUS_SHORT || null, removedServiceDeployJson: true, valuesPrinted: false }));",
    "NODE",
    "  trap - EXIT",
    ") >\"$stdout_file\" 2>\"$stderr_file\" &",
    "pid=$!",
    "JOB_PID=\"$pid\" JOB_ID=\"$job_id\" STATUS_FILE=\"$status_file\" STDOUT_FILE=\"$stdout_file\" STDERR_FILE=\"$stderr_file\" node <<'NODE'",
    "console.log(JSON.stringify({ ok: true, status: 'submitted', jobId: process.env.JOB_ID, pid: Number(process.env.JOB_PID), statusFile: process.env.STATUS_FILE, stdoutFile: process.env.STDOUT_FILE, stderrFile: process.env.STDERR_FILE, valuesPrinted: false }));",
    "NODE",
  ].join("\n");
}

async function waitForYamlLaneSourceBootstrap(config: UniDeskConfig, spec: AgentRunLaneSpec, jobId: string | null): Promise<Record<string, unknown> & { ok: boolean; payload: Record<string, unknown> }> {
  if (jobId === null) return { ok: false, payload: { ok: false, degradedReason: "source-bootstrap-job-id-missing", valuesPrinted: false } };
  const startedAt = Date.now();
  const timeoutMs = spec.source.bootstrapTimeoutSeconds * 1000;
  const pollMs = spec.source.bootstrapPollSeconds * 1000;
  let lastPayload: Record<string, unknown> = {};
  let polls = 0;
  while (Date.now() - startedAt < timeoutMs) {
    polls += 1;
    const probe = await capture(config, spec.nodeRoute, ["sh", "--", yamlLaneSourceBootstrapStatusScript(spec, jobId)]);
    const payload = captureJsonPayload(probe);
    lastPayload = payload;
    progressEvent("agentrun.yaml-lane.source-bootstrap.progress", {
      node: spec.nodeId,
      lane: spec.lane,
      jobId,
      polls,
      status: stringOrNull(payload.status) ?? "unknown",
      sourceCommit: stringOrNull(payload.sourceCommit),
      elapsedMs: Date.now() - startedAt,
    });
    if (payload.status === "succeeded" && stringOrNull(payload.sourceCommit) !== null) return { ok: payload.ok === true, payload, polls, elapsedMs: Date.now() - startedAt };
    if (payload.status === "failed") return { ok: false, payload, polls, elapsedMs: Date.now() - startedAt };
    await sleep(pollMs);
  }
  return { ok: false, payload: { ...lastPayload, ok: false, status: "timeout", degradedReason: "source-bootstrap-timeout", valuesPrinted: false }, polls, elapsedMs: Date.now() - startedAt };
}

function yamlLaneSourceBootstrapStatusScript(spec: AgentRunLaneSpec, jobId: string): string {
  const stateDir = `/tmp/unidesk-agentrun-source-${spec.nodeId}-${spec.lane}`;
  return [
    "set +e",
    `status_file=${shQuote(`${stateDir}/${jobId}.json`)}`,
    "if [ -f \"$status_file\" ]; then cat \"$status_file\"; else printf '{\"ok\":false,\"status\":\"missing\",\"valuesPrinted\":false}\\n'; fi",
  ].join("\n");
}

function yamlLaneSourceRestoreScript(spec: AgentRunLaneSpec): string {
  return [
    "set +e",
    `workspace=${shQuote(spec.source.workspace)}`,
    `branch=${shQuote(spec.source.branch)}`,
    "tmp_dir=$(mktemp -d)",
    "trap 'rm -rf \"$tmp_dir\"' EXIT",
    "workspace_exists=false",
    "if git -C \"$workspace\" rev-parse --git-dir >/dev/null 2>&1; then workspace_exists=true; fi",
    "if [ \"$workspace_exists\" != true ]; then",
    "  WORKSPACE=\"$workspace\" BRANCH=\"$branch\" node <<'NODE'",
    "console.log(JSON.stringify({ ok: false, status: 'skipped', failureKind: 'source-worktree-missing', workspace: process.env.WORKSPACE, branch: process.env.BRANCH, valuesPrinted: false }));",
    "NODE",
    "  exit 0",
    "fi",
    "before_branch=$(git -C \"$workspace\" rev-parse --abbrev-ref HEAD 2>/dev/null || true)",
    "before_head=$(git -C \"$workspace\" rev-parse HEAD 2>/dev/null || true)",
    "status_short=$(git -C \"$workspace\" status --short 2>/dev/null || true)",
    "if [ -n \"$status_short\" ]; then",
    "  WORKSPACE=\"$workspace\" BRANCH=\"$branch\" BEFORE_BRANCH=\"$before_branch\" BEFORE_HEAD=\"$before_head\" STATUS_SHORT=\"$status_short\" node <<'NODE'",
    "console.log(JSON.stringify({ ok: false, status: 'skipped', failureKind: 'source-worktree-dirty', workspace: process.env.WORKSPACE, branch: process.env.BRANCH, before: { branch: process.env.BEFORE_BRANCH || null, head: process.env.BEFORE_HEAD || null, detached: process.env.BEFORE_BRANCH === 'HEAD' }, statusShort: process.env.STATUS_SHORT || null, valuesPrinted: false }));",
    "NODE",
    "  exit 0",
    "fi",
    "git -C \"$workspace\" fetch origin \"$branch\" > \"$tmp_dir/fetch.out\" 2> \"$tmp_dir/fetch.err\"",
    "fetch_exit=$?",
    "remote_branch_commit=$(git -C \"$workspace\" rev-parse \"refs/remotes/origin/$branch\" 2>/dev/null || true)",
    "checkout_exit=1",
    "if [ \"$fetch_exit\" -eq 0 ] && [ -n \"$remote_branch_commit\" ]; then",
    "  git -C \"$workspace\" checkout -B \"$branch\" \"refs/remotes/origin/$branch\" > \"$tmp_dir/checkout.out\" 2> \"$tmp_dir/checkout.err\"",
    "  checkout_exit=$?",
    "else",
    "  : > \"$tmp_dir/checkout.out\"",
    "  : > \"$tmp_dir/checkout.err\"",
    "fi",
    "after_branch=$(git -C \"$workspace\" rev-parse --abbrev-ref HEAD 2>/dev/null || true)",
    "after_head=$(git -C \"$workspace\" rev-parse HEAD 2>/dev/null || true)",
    "after_status_short=$(git -C \"$workspace\" status --short 2>/dev/null || true)",
    "fetch_err=$(tail -n 20 \"$tmp_dir/fetch.err\" 2>/dev/null | tr '\\n' ' ' | cut -c1-1200)",
    "checkout_err=$(tail -n 20 \"$tmp_dir/checkout.err\" 2>/dev/null | tr '\\n' ' ' | cut -c1-1200)",
    "WORKSPACE=\"$workspace\" BRANCH=\"$branch\" BEFORE_BRANCH=\"$before_branch\" BEFORE_HEAD=\"$before_head\" FETCH_EXIT=\"$fetch_exit\" CHECKOUT_EXIT=\"$checkout_exit\" REMOTE_BRANCH_COMMIT=\"$remote_branch_commit\" AFTER_BRANCH=\"$after_branch\" AFTER_HEAD=\"$after_head\" AFTER_STATUS_SHORT=\"$after_status_short\" FETCH_ERR=\"$fetch_err\" CHECKOUT_ERR=\"$checkout_err\" node <<'NODE'",
    "const fetchExit = Number(process.env.FETCH_EXIT || '1');",
    "const checkoutExit = Number(process.env.CHECKOUT_EXIT || '1');",
    "const afterClean = !process.env.AFTER_STATUS_SHORT;",
    "const ok = fetchExit === 0 && checkoutExit === 0 && afterClean && process.env.AFTER_BRANCH === process.env.BRANCH;",
    "let failureKind = null;",
    "if (fetchExit !== 0) failureKind = 'source-branch-fetch-failed';",
    "else if (!process.env.REMOTE_BRANCH_COMMIT) failureKind = 'source-branch-missing';",
    "else if (checkoutExit !== 0) failureKind = 'source-branch-checkout-failed';",
    "else if (!afterClean) failureKind = 'source-worktree-dirty-after-restore';",
    "else if (process.env.AFTER_BRANCH !== process.env.BRANCH) failureKind = 'source-worktree-branch-mismatch';",
    "console.log(JSON.stringify({",
    "  ok,",
    "  status: ok ? 'restored' : 'failed',",
    "  failureKind,",
    "  workspace: process.env.WORKSPACE,",
    "  branch: process.env.BRANCH,",
    "  before: { branch: process.env.BEFORE_BRANCH || null, head: process.env.BEFORE_HEAD || null, detached: process.env.BEFORE_BRANCH === 'HEAD' },",
    "  after: { branch: process.env.AFTER_BRANCH || null, head: process.env.AFTER_HEAD || null, clean: afterClean },",
    "  remoteBranchCommit: process.env.REMOTE_BRANCH_COMMIT || null,",
    "  fetch: { exitCode: fetchExit, stderrTail: process.env.FETCH_ERR || null },",
    "  checkout: { exitCode: checkoutExit, stderrTail: process.env.CHECKOUT_ERR || null },",
    "  valuesPrinted: false",
    "}));",
    "NODE",
  ].join("\n");
}

function yamlLaneBuildImageSubmitScript(spec: AgentRunLaneSpec, sourceCommit: string): string {
  const build = spec.deployment.manager.imageBuild;
  const noProxy = build.noProxy.join(",");
  const imageRepository = `${spec.ci.registryPrefix}/${build.repository}`;
  const stateDir = `/tmp/unidesk-agentrun-build-${spec.nodeId}-${spec.lane}`;
  const buildArgs = Object.entries(build.buildArgs)
    .sort(([left], [right]) => left.localeCompare(right))
    .map(([key, value]) => `${key}=${value}`);
  const script = [
    "set -eu",
    `workspace=${shQuote(spec.source.workspace)}`,
    `source_commit=${shQuote(sourceCommit)}`,
    `state_dir=${shQuote(stateDir)}`,
    `containerfile=${shQuote(build.containerfile)}`,
    `context_dir=${shQuote(build.context)}`,
    `image_repository=${shQuote(imageRepository)}`,
    `network=${shQuote(build.network)}`,
    `http_proxy_value=${build.httpProxy === null ? "''" : shQuote(build.httpProxy)}`,
    `https_proxy_value=${build.httpsProxy === null ? "''" : shQuote(build.httpsProxy)}`,
    `no_proxy_value=${shQuote(noProxy)}`,
    `env_identity_files=${shQuote(JSON.stringify(build.envIdentityFiles))}`,
    `build_args_json=${shQuote(JSON.stringify(buildArgs))}`,
    "mkdir -p \"$state_dir\"",
    "cd \"$workspace\"",
    "git checkout \"$source_commit\"",
    "env_identity=$(ENV_IDENTITY_FILES=\"$env_identity_files\" BUILD_ARGS_JSON=\"$build_args_json\" node <<'NODE'",
    "const { createHash } = require('node:crypto');",
    "const { readFileSync, existsSync } = require('node:fs');",
    "const files = JSON.parse(process.env.ENV_IDENTITY_FILES || '[]');",
    "const buildArgs = JSON.parse(process.env.BUILD_ARGS_JSON || '[]');",
    "const hash = createHash('sha256');",
    "for (const item of buildArgs) { hash.update('build-arg'); hash.update('\\0'); hash.update(item); hash.update('\\0'); }",
    "for (const file of files) { hash.update(file); hash.update('\\0'); if (existsSync(file)) hash.update(readFileSync(file)); hash.update('\\0'); }",
    "process.stdout.write(hash.digest('hex').slice(0, 24));",
    "NODE",
    ")",
    "source_short=$(printf '%s' \"$source_commit\" | cut -c1-12)",
    "job_id=\"$source_short-$env_identity\"",
    "status_file=\"$state_dir/$job_id.json\"",
    "stdout_file=\"$state_dir/$job_id.stdout.log\"",
    "stderr_file=\"$state_dir/$job_id.stderr.log\"",
    "cat > \"$status_file\" <<EOF",
    "{\"ok\":false,\"status\":\"running\",\"jobId\":\"$job_id\",\"sourceCommit\":\"$source_commit\",\"envIdentity\":\"$env_identity\",\"image\":\"$image_repository:$env_identity\",\"valuesPrinted\":false}",
    "EOF",
    "(",
    "  set -eu",
    "  write_failed_status() { code=$?; if [ \"$code\" -ne 0 ]; then tail_text=$(tail -n 40 \"$stderr_file\" 2>/dev/null | sed 's/\"/\\\\\"/g' | tr '\\n' ' ' | cut -c1-2000); CODE=\"$code\" ERROR_TAIL=\"$tail_text\" JOB_ID=\"$job_id\" SOURCE_COMMIT=\"$source_commit\" ENV_IDENTITY=\"$env_identity\" IMAGE_REPOSITORY=\"$image_repository\" node <<'NODE' > \"$status_file\"",
    "const code = Number(process.env.CODE || 1);",
    "console.log(JSON.stringify({ ok: false, status: 'failed', exitCode: code, jobId: process.env.JOB_ID, sourceCommit: process.env.SOURCE_COMMIT, envIdentity: process.env.ENV_IDENTITY, image: `${process.env.IMAGE_REPOSITORY}:${process.env.ENV_IDENTITY}`, errorTail: process.env.ERROR_TAIL || null, valuesPrinted: false }));",
    "NODE",
    "  fi; exit \"$code\"; }",
    "  trap write_failed_status EXIT",
    "  cd \"$workspace\"",
    "  image=\"$image_repository:$env_identity\"",
    "  args=\"--network $network\"",
    "  if [ -n \"$http_proxy_value\" ]; then args=\"$args --build-arg HTTP_PROXY=$http_proxy_value --build-arg http_proxy=$http_proxy_value\"; fi",
    "  if [ -n \"$https_proxy_value\" ]; then args=\"$args --build-arg HTTPS_PROXY=$https_proxy_value --build-arg https_proxy=$https_proxy_value\"; fi",
    "  if [ -n \"$no_proxy_value\" ]; then args=\"$args --build-arg NO_PROXY=$no_proxy_value --build-arg no_proxy=$no_proxy_value\"; fi",
    "  build_arg_values=$(BUILD_ARGS_JSON=\"$build_args_json\" node <<'NODE'",
    "const values = JSON.parse(process.env.BUILD_ARGS_JSON || '[]');",
    "for (const value of values) console.log(value);",
    "NODE",
    "  )",
    "  while IFS= read -r build_arg_value; do [ -n \"$build_arg_value\" ] && args=\"$args --build-arg $build_arg_value\"; done <<EOF",
    "$build_arg_values",
    "EOF",
    "  if docker image inspect \"$image\" >/dev/null 2>&1; then build_status=reused; else docker build $args -f \"$containerfile\" -t \"$image\" \"$context_dir\"; build_status=built; fi",
    "  manifest_accept='application/vnd.oci.image.index.v1+json, application/vnd.oci.image.manifest.v1+json, application/vnd.docker.distribution.manifest.v2+json'",
    "  fetch_manifest_digest() {",
    "    ref=\"$1\"",
    "    attempt=1",
    "    max_attempts=30",
    "    while [ \"$attempt\" -le \"$max_attempts\" ]; do",
    "      headers=$(mktemp)",
    "      if curl -fsSI -H \"Accept: $manifest_accept\" \"http://127.0.0.1:5000/v2/${image_repository#127.0.0.1:5000/}/manifests/$ref\" >\"$headers\"; then",
    "        found_digest=$(awk -F': ' 'tolower($1)==\"docker-content-digest\"{print $2}' \"$headers\" | tr -d '\\r' | head -n 1)",
    "        rm -f \"$headers\"",
    "        if [ -n \"$found_digest\" ]; then printf '%s' \"$found_digest\"; return 0; fi",
    "      else",
    "        rm -f \"$headers\"",
    "      fi",
    "      printf '{\"event\":\"agentrun-registry-manifest-probe\",\"status\":\"retrying\",\"ref\":\"%s\",\"attempt\":\"%s/%s\"}\\n' \"$ref\" \"$attempt\" \"$max_attempts\" >&2",
    "      sleep 1",
    "      attempt=$((attempt + 1))",
    "    done",
    "    printf '{\"event\":\"agentrun-registry-manifest-probe\",\"status\":\"exhausted\",\"ref\":\"%s\",\"attempt\":\"%s/%s\"}\\n' \"$ref\" \"$max_attempts\" \"$max_attempts\" >&2",
    "    return 1",
    "  }",
    "  docker push \"$image\"",
    "  digest=$(fetch_manifest_digest \"$env_identity\" || true)",
    "  if [ -n \"$digest\" ]; then verified_digest=$(fetch_manifest_digest \"$digest\" || true); if [ \"$verified_digest\" != \"$digest\" ]; then digest=; fi; fi",
    "  STATUS=\"$build_status\" DIGEST=\"$digest\" JOB_ID=\"$job_id\" SOURCE_COMMIT=\"$source_commit\" ENV_IDENTITY=\"$env_identity\" IMAGE_REPOSITORY=\"$image_repository\" node <<'NODE' > \"$status_file\"",
    "const digest = process.env.DIGEST || null;",
    "console.log(JSON.stringify({ ok: Boolean(digest), status: process.env.STATUS || 'built', jobId: process.env.JOB_ID, sourceCommit: process.env.SOURCE_COMMIT, envIdentity: process.env.ENV_IDENTITY, image: `${process.env.IMAGE_REPOSITORY}:${process.env.ENV_IDENTITY}`, digest, repositoryDigest: digest ? `${process.env.IMAGE_REPOSITORY}@${digest}` : null, valuesPrinted: false }));",
    "NODE",
    "  trap - EXIT",
    ") >\"$stdout_file\" 2>\"$stderr_file\" &",
    "pid=$!",
    "JOB_PID=\"$pid\" JOB_ID=\"$job_id\" STATUS_FILE=\"$status_file\" STDOUT_FILE=\"$stdout_file\" STDERR_FILE=\"$stderr_file\" node <<'NODE'",
    "console.log(JSON.stringify({ ok: true, status: 'submitted', jobId: process.env.JOB_ID, pid: Number(process.env.JOB_PID), statusFile: process.env.STATUS_FILE, stdoutFile: process.env.STDOUT_FILE, stderrFile: process.env.STDERR_FILE, valuesPrinted: false }));",
    "NODE",
  ].join("\n");
  return script;
}

async function waitForYamlLaneBuildImage(config: UniDeskConfig, spec: AgentRunLaneSpec, sourceCommit: string, jobId: string | null): Promise<Record<string, unknown> & { ok: boolean; payload: Record<string, unknown> }> {
  if (jobId === null) return { ok: false, payload: { ok: false, degradedReason: "build-job-id-missing", valuesPrinted: false } };
  const startedAt = Date.now();
  const timeoutMs = Math.max(60, spec.deployment.manager.imageBuild.timeoutSeconds) * 1000;
  let lastPayload: Record<string, unknown> = {};
  let polls = 0;
  while (Date.now() - startedAt < timeoutMs) {
    polls += 1;
    const probe = await capture(config, spec.nodeRoute, ["sh", "--", yamlLaneBuildImageStatusScript(spec, jobId)]);
    const payload = captureJsonPayload(probe);
    lastPayload = payload;
    progressEvent("agentrun.yaml-lane.image-build.progress", {
      node: spec.nodeId,
      lane: spec.lane,
      sourceCommit,
      jobId,
      polls,
      status: stringOrNull(payload.status) ?? "unknown",
      elapsedMs: Date.now() - startedAt,
    });
    if (payload.ok === true && stringOrNull(payload.digest) !== null) return { ok: true, payload, polls, elapsedMs: Date.now() - startedAt };
    if (payload.status === "failed") return { ok: false, payload, polls, elapsedMs: Date.now() - startedAt };
    await sleep(spec.deployment.manager.imageBuild.pollSeconds * 1000);
  }
  return { ok: false, payload: { ...lastPayload, ok: false, status: "timeout", degradedReason: "image-build-timeout", valuesPrinted: false }, polls, elapsedMs: Date.now() - startedAt };
}

function yamlLaneBuildImageStatusScript(spec: AgentRunLaneSpec, jobId: string): string {
  const stateDir = `/tmp/unidesk-agentrun-build-${spec.nodeId}-${spec.lane}`;
  return [
    "set +e",
    `status_file=${shQuote(`${stateDir}/${jobId}.json`)}`,
    `stdout_file=${shQuote(`${stateDir}/${jobId}.stdout.log`)}`,
    `stderr_file=${shQuote(`${stateDir}/${jobId}.stderr.log`)}`,
    "if [ -f \"$status_file\" ]; then cat \"$status_file\"; else printf '{\"ok\":false,\"status\":\"missing\",\"valuesPrinted\":false}\\n'; fi",
    "if [ -f \"$stderr_file\" ] && tail -n 20 \"$stderr_file\" | grep -Eq 'ERROR|error|failed|denied'; then :; fi",
  ].join("\n");
}

async function runYamlLaneGitopsPublishJob(config: UniDeskConfig, spec: AgentRunLaneSpec, sourceCommit: string, files: readonly { path: string; content: string }[]): Promise<Record<string, unknown> & { ok: boolean; payload: Record<string, unknown> }> {
  const jobName = `gitops-publish-${spec.nodeId.toLowerCase()}-${spec.lane}-${Date.now().toString(36)}`.slice(0, 63);
  const manifest = yamlLaneGitopsPublishJobManifest(spec, files, jobName);
  const created = await capture(config, spec.nodeKubeRoute, ["sh", "--", createYamlLaneJobScript(spec.gitMirror.namespace, jobName, manifest)]);
  if (created.exitCode !== 0) {
    return {
      ok: false,
      payload: { ok: false, status: "create-failed", jobName, degradedReason: "gitops-publish-job-create-failed", valuesPrinted: false },
      jobName,
      sourceCommit,
      phase: "create-job",
      capture: compactCapture(created, { full: true, stdoutTailChars: 5000, stderrTailChars: 5000 }),
      valuesPrinted: false,
    };
  }
  const startedAt = Date.now();
  const timeoutMs = 300_000;
  let polls = 0;
  let lastPayload: Record<string, unknown> = {};
  let lastProbe: SshCaptureResult | null = null;
  while (Date.now() - startedAt < timeoutMs) {
    polls += 1;
    lastProbe = await capture(config, spec.nodeKubeRoute, ["sh", "--", yamlLaneJobProbeScript(spec.gitMirror.namespace, jobName)]);
    const probePayload = captureJsonPayload(lastProbe);
    const publishPayload = yamlLaneGitopsPublishPayloadFromProbe(probePayload);
    if (Object.keys(publishPayload).length > 0) lastPayload = publishPayload;
    progressEvent("agentrun.yaml-lane.gitops-publish.progress", {
      node: spec.nodeId,
      lane: spec.lane,
      sourceCommit,
      jobName,
      polls,
      status: stringOrNull(publishPayload.status) ?? (probePayload.succeeded === true ? "succeeded" : probePayload.failed === true ? "failed" : "running"),
      gitopsCommit: stringOrNull(publishPayload.gitopsCommit),
      elapsedMs: Date.now() - startedAt,
    });
    if (probePayload.succeeded === true) {
      if (publishPayload.ok === true && stringOrNull(publishPayload.gitopsCommit) !== null) {
        return { ok: true, payload: publishPayload, jobName, polls, elapsedMs: Date.now() - startedAt, probe: compactCapture(lastProbe), valuesPrinted: false };
      }
      return {
        ok: false,
        payload: { ...publishPayload, ok: false, status: stringOrNull(publishPayload.status) ?? "succeeded-without-result", degradedReason: "gitops-publish-result-missing", jobName, valuesPrinted: false },
        jobName,
        polls,
        elapsedMs: Date.now() - startedAt,
        probe: compactCapture(lastProbe, { full: true, stdoutTailChars: 5000, stderrTailChars: 5000 }),
        valuesPrinted: false,
      };
    }
    if (probePayload.failed === true) {
      const payload = Object.keys(publishPayload).length > 0 ? publishPayload : { ok: false, status: "failed", degradedReason: "gitops-publish-job-failed", jobName, valuesPrinted: false };
      return {
        ok: false,
        payload,
        jobName,
        polls,
        elapsedMs: Date.now() - startedAt,
        probe: compactCapture(lastProbe, { full: true, stdoutTailChars: 5000, stderrTailChars: 5000 }),
        valuesPrinted: false,
      };
    }
    await sleep(5_000);
  }
  return {
    ok: false,
    payload: { ...lastPayload, ok: false, status: "timeout", degradedReason: "gitops-publish-job-timeout", jobName, valuesPrinted: false },
    jobName,
    polls,
    elapsedMs: Date.now() - startedAt,
    probe: lastProbe === null ? null : compactCapture(lastProbe, { full: true, stdoutTailChars: 5000, stderrTailChars: 5000 }),
    valuesPrinted: false,
  };
}

function yamlLaneGitopsPublishPayloadFromProbe(probePayload: Record<string, unknown>): Record<string, unknown> {
  const logsTail = stringOrNull(probePayload.logsTail);
  if (logsTail === null) return {};
  const lines = logsTail.split(/\r?\n/u).map((line) => line.trim()).filter(Boolean);
  for (let index = lines.length - 1; index >= 0; index -= 1) {
    const line = lines[index];
    if (!line.startsWith("{") || !line.endsWith("}")) continue;
    try {
      const parsed = JSON.parse(line) as unknown;
      const payload = record(parsed);
      if (payload.ok === true || payload.ok === false) return payload;
    } catch {
      continue;
    }
  }
  return {};
}

function yamlLaneGitopsPublishJobManifest(spec: AgentRunLaneSpec, files: readonly { path: string; content: string }[], name: string): Record<string, unknown> {
  return {
    apiVersion: "batch/v1",
    kind: "Job",
    metadata: {
      name,
      namespace: spec.gitMirror.namespace,
      labels: {
        "app.kubernetes.io/name": "gitops-publish",
        "app.kubernetes.io/part-of": "agentrun",
        "agentrun.pikastech.local/lane": spec.version,
        "agentrun.pikastech.local/node": spec.nodeId,
        "agentrun.pikastech.local/component": "gitops-publish",
      },
    },
    spec: {
      backoffLimit: 0,
      activeDeadlineSeconds: 600,
      ttlSecondsAfterFinished: 3600,
      template: {
        metadata: {
          labels: {
            "app.kubernetes.io/name": "gitops-publish",
            "app.kubernetes.io/part-of": "agentrun",
            "agentrun.pikastech.local/lane": spec.version,
            "agentrun.pikastech.local/node": spec.nodeId,
            "agentrun.pikastech.local/component": "gitops-publish",
          },
        },
        spec: {
          restartPolicy: "Never",
          volumes: [yamlLaneGitMirrorCacheVolume(spec)],
          containers: [{
            name: "publish",
            image: spec.gitMirror.toolsImage,
            imagePullPolicy: "IfNotPresent",
            command: ["/bin/sh", "-ec", yamlLaneGitopsPublishShell(spec, files, name)],
            volumeMounts: [{ name: "cache", mountPath: "/cache" }],
          }],
        },
      },
    },
  };
}

function yamlLaneGitopsPublishShell(spec: AgentRunLaneSpec, files: readonly { path: string; content: string }[], jobName: string): string {
  const filesB64 = Buffer.from(JSON.stringify(files.map((file) => ({
    path: file.path,
    contentBase64: Buffer.from(file.content, "utf8").toString("base64"),
  }))), "utf8").toString("base64");
  return [
    "set -eu",
    `repository=${shQuote(spec.source.repository)}`,
    `gitops_branch=${shQuote(spec.gitops.branch)}`,
    `gitops_root=${shQuote(spec.deployment.gitopsRoot)}`,
    `artifact_catalog=${shQuote(spec.deployment.artifactCatalogPath)}`,
    `files_b64=${shQuote(filesB64)}`,
    `job_name=${shQuote(jobName)}`,
    "remote=\"/cache/${repository}.git\"",
    "remote_mode=git-mirror-cache-volume",
    "publish_worktree=\"/tmp/$job_name\"",
    "write_failed_status() { code=$?; if [ \"$code\" -ne 0 ]; then printf '%s\\n' \"{\\\"ok\\\":false,\\\"status\\\":\\\"failed\\\",\\\"exitCode\\\":$code,\\\"jobName\\\":\\\"$job_name\\\",\\\"publishWorkspace\\\":\\\"$publish_worktree\\\",\\\"gitopsBranch\\\":\\\"$gitops_branch\\\",\\\"publishRemoteMode\\\":\\\"$remote_mode\\\",\\\"valuesPrinted\\\":false}\"; fi; exit \"$code\"; }",
    "trap write_failed_status EXIT",
    "rm -rf \"$publish_worktree\"",
    "git clone --no-checkout \"$remote\" \"$publish_worktree\"",
    "cd \"$publish_worktree\"",
    "git fetch origin \"$gitops_branch\" || true",
    "if git rev-parse --verify \"refs/remotes/origin/$gitops_branch^{commit}\" >/dev/null 2>&1; then",
    "  git checkout -B \"$gitops_branch\" \"refs/remotes/origin/$gitops_branch\"",
    "else",
    "  git checkout --orphan \"$gitops_branch\"",
    "  git rm -rf . >/dev/null 2>&1 || true",
    "fi",
    "git rm -rf --ignore-unmatch \"$gitops_root\" \"$artifact_catalog\" source.json >/dev/null 2>&1 || true",
    "rm -rf \"$gitops_root\" \"$artifact_catalog\" source.json",
    "FILES_B64=\"$files_b64\" node <<'NODE'",
    "const fs = require('node:fs');",
    "const path = require('node:path');",
    "const files = JSON.parse(Buffer.from(process.env.FILES_B64 || '', 'base64').toString('utf8'));",
    "for (const file of files) {",
    "  const target = path.resolve(process.cwd(), file.path);",
    "  if (!target.startsWith(process.cwd() + path.sep)) throw new Error(`refuse path outside workspace: ${file.path}`);",
    "  fs.mkdirSync(path.dirname(target), { recursive: true });",
    "  fs.writeFileSync(target, Buffer.from(file.contentBase64, 'base64'));",
    "}",
    "NODE",
    "git add source.json \"$artifact_catalog\" \"$gitops_root\"",
    "if git diff --quiet --cached; then changed=false; else changed=true; git -c user.email=agentrun@unidesk.local -c user.name='UniDesk AgentRun Ops' commit -m \"deploy: render AgentRun ${gitops_branch} from UniDesk YAML\"; fi",
    "git push -u origin \"$gitops_branch\"",
    "gitops_commit=$(git rev-parse HEAD)",
    "CHANGED=\"$changed\" GITOPS_BRANCH=\"$gitops_branch\" GITOPS_COMMIT=\"$gitops_commit\" FILE_COUNT=\"" + String(files.length) + "\" JOB_NAME=\"$job_name\" PUBLISH_REMOTE_MODE=\"$remote_mode\" node <<'NODE'",
    "console.log(JSON.stringify({ ok: true, status: 'succeeded', jobName: process.env.JOB_NAME, changed: process.env.CHANGED === 'true', gitopsBranch: process.env.GITOPS_BRANCH, gitopsCommit: process.env.GITOPS_COMMIT, publishRemoteMode: process.env.PUBLISH_REMOTE_MODE || null, fileCount: Number(process.env.FILE_COUNT || 0), valuesPrinted: false }));",
    "NODE",
    "trap - EXIT",
  ].join("\n");
}

const AGENTRUN_GIT_MIRROR_RETRY_MAX_ATTEMPTS = 5;
const AGENTRUN_GIT_MIRROR_RETRYABLE_PATTERN =
  /(kex_exchange_identification|connection closed by remote host|connection closed by unknown|could not read from remote repository|ssh\.github\.com|github\.com|fetch-pack|early eof|econnreset|read econnreset|proxy-connect|tunnel socket error)/i;

function agentRunGitMirrorRetryDelayMs(attempt: number): number {
  return Math.min(15_000, 1_000 * Math.pow(2, Math.max(0, attempt - 1)));
}

function agentRunGitMirrorFailureText(value: unknown): string {
  try {
    return JSON.stringify(value);
  } catch {
    return String(value);
  }
}

function agentRunGitMirrorRetryableFailure(
  spec: AgentRunLaneSpec,
  action: "sync" | "flush",
  attempt: number,
  value: unknown,
): Record<string, unknown> | null {
  const text = agentRunGitMirrorFailureText(value);
  if (!AGENTRUN_GIT_MIRROR_RETRYABLE_PATTERN.test(text)) return null;
  const retryExhausted = attempt >= AGENTRUN_GIT_MIRROR_RETRY_MAX_ATTEMPTS;
  const retryBackoffMs = retryExhausted ? 0 : agentRunGitMirrorRetryDelayMs(attempt);
  return {
    retryable: true,
    retryAttempt: attempt,
    retryMaxAttempts: AGENTRUN_GIT_MIRROR_RETRY_MAX_ATTEMPTS,
    retryLabel: `${attempt}/${AGENTRUN_GIT_MIRROR_RETRY_MAX_ATTEMPTS}`,
    retryExhausted,
    retryBackoffMs,
    backoffPolicy: "exponential",
    failureKind: "git-mirror-upstream-transient",
    upstream: "git-mirror-ssh",
    action,
    node: spec.nodeId,
    lane: spec.lane,
    message: retryExhausted
      ? "AgentRun git-mirror upstream transient failure exhausted retries; stopping instead of continuing silently."
      : "AgentRun git-mirror upstream transient failure; retrying with exponential backoff.",
    next: retryExhausted
      ? { stopped: true, reason: "retry-exhausted" }
      : {
          retry: `bun scripts/cli.ts agentrun git-mirror ${action} --node ${spec.nodeId} --lane ${spec.lane} --confirm --wait`,
          delayMs: retryBackoffMs,
        },
    valuesPrinted: false,
  };
}

function agentRunGitMirrorRetrySummary(attempts: Record<string, unknown>[]): Record<string, unknown> {
  const last = attempts.length > 0 ? record(attempts[attempts.length - 1]) : {};
  return {
    policy: "exponential",
    maxAttempts: AGENTRUN_GIT_MIRROR_RETRY_MAX_ATTEMPTS,
    attempts,
    exhausted: last.retryExhausted === true,
    stopped: last.retryExhausted === true,
    valuesPrinted: false,
  };
}

async function runYamlLaneGitMirrorSyncJob(config: UniDeskConfig, spec: AgentRunLaneSpec): Promise<Record<string, unknown>> {
  return await runYamlLaneGitMirrorJob(config, spec, "sync");
}

async function runYamlLaneGitMirrorFlushJob(config: UniDeskConfig, spec: AgentRunLaneSpec): Promise<Record<string, unknown>> {
  return await runYamlLaneGitMirrorJob(config, spec, "flush");
}

async function runYamlLaneGitMirrorJob(config: UniDeskConfig, spec: AgentRunLaneSpec, action: "sync" | "flush"): Promise<Record<string, unknown>> {
  const attempts: Record<string, unknown>[] = [];
  for (let attempt = 1; attempt <= AGENTRUN_GIT_MIRROR_RETRY_MAX_ATTEMPTS; attempt += 1) {
    const jobPrefix = action === "sync" ? spec.gitMirror.syncJobPrefix : spec.gitMirror.flushJobPrefix;
    const jobName = `${jobPrefix}-${Date.now().toString(36)}-${attempt}`.slice(0, 63);
    const manifest = yamlLaneGitMirrorJobManifest(spec, action, jobName);
    const created = await capture(config, spec.nodeKubeRoute, ["sh", "--", createYamlLaneJobScript(spec.gitMirror.namespace, jobName, manifest)]);
    if (created.exitCode !== 0) {
      const result = { ok: false, phase: "create-job", jobName, capture: compactCapture(created, { full: true, stdoutTailChars: 4000, stderrTailChars: 4000 }), valuesPrinted: false };
      const retryableFailure = agentRunGitMirrorRetryableFailure(spec, action, attempt, result);
      attempts.push({ attempt, retryLabel: `${attempt}/${AGENTRUN_GIT_MIRROR_RETRY_MAX_ATTEMPTS}`, jobName, ok: false, phase: "create-job", retryableFailure, retryExhausted: retryableFailure !== null && record(retryableFailure).retryExhausted === true });
      if (retryableFailure !== null && record(retryableFailure).retryExhausted !== true) {
        progressEvent("agentrun.yaml-lane.git-mirror.retry", retryableFailure);
        await sleep(agentRunGitMirrorRetryDelayMs(attempt));
        continue;
      }
      return { ...result, retryableFailure, retry: agentRunGitMirrorRetrySummary(attempts) };
    }
    const startedAt = Date.now();
    let polls = 0;
    let lastProbe: SshCaptureResult | null = null;
    while (Date.now() - startedAt < 300_000) {
      polls += 1;
      lastProbe = await capture(config, spec.nodeKubeRoute, ["sh", "--", yamlLaneJobProbeScript(spec.gitMirror.namespace, jobName)]);
      const payload = captureJsonPayload(lastProbe);
      progressEvent("agentrun.yaml-lane.git-mirror.progress", {
        node: spec.nodeId,
        lane: spec.lane,
        action,
        jobName,
        polls,
        retryAttempt: attempt,
        retryMaxAttempts: AGENTRUN_GIT_MIRROR_RETRY_MAX_ATTEMPTS,
        retryLabel: `${attempt}/${AGENTRUN_GIT_MIRROR_RETRY_MAX_ATTEMPTS}`,
        succeeded: payload.succeeded === true,
        failed: payload.failed === true,
        elapsedMs: Date.now() - startedAt,
      });
      if (payload.succeeded === true) {
        attempts.push({ attempt, retryLabel: `${attempt}/${AGENTRUN_GIT_MIRROR_RETRY_MAX_ATTEMPTS}`, jobName, ok: true, polls, elapsedMs: Date.now() - startedAt });
        return { ok: true, jobName, polls, elapsedMs: Date.now() - startedAt, result: payload, retry: agentRunGitMirrorRetrySummary(attempts), valuesPrinted: false };
      }
      if (payload.failed === true) {
        const result = { ok: false, jobName, polls, elapsedMs: Date.now() - startedAt, result: payload, capture: compactCapture(lastProbe, { full: true, stdoutTailChars: 5000, stderrTailChars: 3000 }), valuesPrinted: false };
        const retryableFailure = agentRunGitMirrorRetryableFailure(spec, action, attempt, result);
        attempts.push({ attempt, retryLabel: `${attempt}/${AGENTRUN_GIT_MIRROR_RETRY_MAX_ATTEMPTS}`, jobName, ok: false, polls, elapsedMs: Date.now() - startedAt, retryableFailure, retryExhausted: retryableFailure !== null && record(retryableFailure).retryExhausted === true });
        if (retryableFailure !== null && record(retryableFailure).retryExhausted !== true) {
          progressEvent("agentrun.yaml-lane.git-mirror.retry", retryableFailure);
          await sleep(agentRunGitMirrorRetryDelayMs(attempt));
          break;
        }
        return { ...result, retryableFailure, retry: agentRunGitMirrorRetrySummary(attempts) };
      }
      await sleep(5_000);
    }
    if (attempts.length > 0 && record(attempts[attempts.length - 1]).jobName === jobName) continue;
    const degradedReason = `git-mirror-${action}-job-timeout`;
    const result = { ok: false, jobName, polls, elapsedMs: Date.now() - startedAt, degradedReason, capture: lastProbe === null ? null : compactCapture(lastProbe, { full: true, stdoutTailChars: 5000, stderrTailChars: 3000 }), valuesPrinted: false };
    const retryableFailure = agentRunGitMirrorRetryableFailure(spec, action, attempt, result);
    attempts.push({ attempt, retryLabel: `${attempt}/${AGENTRUN_GIT_MIRROR_RETRY_MAX_ATTEMPTS}`, jobName, ok: false, polls, elapsedMs: Date.now() - startedAt, degradedReason, retryableFailure, retryExhausted: retryableFailure !== null && record(retryableFailure).retryExhausted === true });
    if (retryableFailure !== null && record(retryableFailure).retryExhausted !== true) {
      progressEvent("agentrun.yaml-lane.git-mirror.retry", retryableFailure);
      await sleep(agentRunGitMirrorRetryDelayMs(attempt));
      continue;
    }
    return { ...result, retryableFailure, retry: agentRunGitMirrorRetrySummary(attempts) };
  }
  return { ok: false, degradedReason: `git-mirror-${action}-retry-loop-exhausted`, retry: agentRunGitMirrorRetrySummary(attempts), valuesPrinted: false };
}

function yamlLanePipelineRunCreateScript(spec: AgentRunLaneSpec, sourceCommit: string, pipelineRun: string): string {
  const manifest = {
    apiVersion: "tekton.dev/v1",
    kind: "PipelineRun",
    metadata: {
      name: pipelineRun,
      namespace: spec.ci.namespace,
      labels: {
        "app.kubernetes.io/part-of": "agentrun",
        "agentrun.pikastech.local/lane": spec.version,
        "agentrun.pikastech.local/node": spec.nodeId,
        "agentrun.pikastech.local/source-commit": sourceCommit,
        "agentrun.pikastech.local/trigger": "unidesk-yaml-only",
      },
    },
    spec: {
      pipelineRef: { name: spec.ci.pipeline },
      taskRunTemplate: {
        serviceAccountName: spec.ci.serviceAccountName,
        podTemplate: { hostNetwork: true, dnsPolicy: "ClusterFirstWithHostNet", securityContext: { fsGroup: 1000 } },
      },
      params: [
        { name: "git-url", value: spec.source.remote },
        { name: "git-read-url", value: spec.gitMirror.readUrl },
        { name: "git-write-url", value: spec.gitMirror.writeUrl },
        { name: "source-branch", value: spec.source.branch },
        { name: "gitops-branch", value: spec.gitops.branch },
        { name: "revision", value: sourceCommit },
        { name: "registry-prefix", value: spec.ci.registryPrefix },
        { name: "tools-image", value: spec.ci.toolsImage },
      ],
      workspaces: [
        { name: "source", volumeClaimTemplate: { spec: { accessModes: ["ReadWriteOnce"], resources: { requests: { storage: "4Gi" } } } } },
        { name: "git-ssh", secret: { secretName: spec.gitMirror.sshSecretName } },
      ],
    },
  };
  const manifestB64 = Buffer.from(JSON.stringify(manifest), "utf8").toString("base64");
  return [
    "set -eu",
    `namespace=${shQuote(spec.ci.namespace)}`,
    `pipeline_run=${shQuote(pipelineRun)}`,
    `manifest_b64=${shQuote(manifestB64)}`,
    "tmp=$(mktemp)",
    "trap 'rm -f \"$tmp\"' EXIT",
    "printf '%s' \"$manifest_b64\" | base64 -d > \"$tmp\"",
    "existing_status=$(kubectl -n \"$namespace\" get pipelinerun \"$pipeline_run\" -o 'jsonpath={.status.conditions[0].status}' 2>/dev/null || true)",
    "if [ \"$existing_status\" = False ]; then kubectl -n \"$namespace\" delete pipelinerun \"$pipeline_run\" --ignore-not-found=true --wait=false >/dev/null 2>&1 || true; fi",
    "if kubectl -n \"$namespace\" get pipelinerun \"$pipeline_run\" >/dev/null 2>&1; then created=false; else kubectl create -f \"$tmp\"; created=true; fi",
    "status=$(kubectl -n \"$namespace\" get pipelinerun \"$pipeline_run\" -o 'jsonpath={.status.conditions[0].status}' 2>/dev/null || true)",
    "CREATED=\"$created\" STATUS=\"$status\" PIPELINE_RUN=\"$pipeline_run\" node <<'NODE'",
    "console.log(JSON.stringify({ ok: true, pipelineRun: process.env.PIPELINE_RUN, created: process.env.CREATED === 'true', status: process.env.STATUS || null, valuesPrinted: false }));",
    "NODE",
  ].join("\n");
}

function createYamlLaneJobScript(namespace: string, jobName: string, manifest: Record<string, unknown>): string {
  const manifestB64 = Buffer.from(JSON.stringify(manifest), "utf8").toString("base64");
  return [
    "set -eu",
    `namespace=${shQuote(namespace)}`,
    `job=${shQuote(jobName)}`,
    `manifest_b64=${shQuote(manifestB64)}`,
    "tmp=$(mktemp)",
    "trap 'rm -f \"$tmp\"' EXIT",
    "printf '%s' \"$manifest_b64\" | base64 -d > \"$tmp\"",
    "kubectl -n \"$namespace\" delete job \"$job\" --ignore-not-found=true --wait=false >/dev/null 2>&1 || true",
    "kubectl create -f \"$tmp\"",
    "JOB=\"$job\" node <<'NODE'",
    "console.log(JSON.stringify({ ok: true, jobName: process.env.JOB, valuesPrinted: false }));",
    "NODE",
  ].join("\n");
}

function yamlLaneJobProbeScript(namespace: string, jobName: string): string {
  return [
    "set +e",
    `namespace=${shQuote(namespace)}`,
    `job=${shQuote(jobName)}`,
    "kubectl -n \"$namespace\" get job \"$job\" -o json > /tmp/agentrun-job.json 2>/dev/null",
    "job_exit=$?",
    "kubectl -n \"$namespace\" logs \"job/$job\" --tail=120 > /tmp/agentrun-job.log 2>/dev/null",
    "JOB_EXIT=\"$job_exit\" JOB=\"$job\" node <<'NODE'",
    "const fs = require('node:fs');",
    "let job = null; try { job = JSON.parse(fs.readFileSync('/tmp/agentrun-job.json', 'utf8')); } catch {}",
    "let log = ''; try { log = fs.readFileSync('/tmp/agentrun-job.log', 'utf8'); } catch {}",
    "const succeeded = Number(job?.status?.succeeded || 0) > 0;",
    "const failed = Number(job?.status?.failed || 0) > 0;",
    "console.log(JSON.stringify({ ok: process.env.JOB_EXIT === '0', jobName: process.env.JOB, succeeded, failed, active: job?.status?.active || 0, logsTail: log.slice(-4000), valuesPrinted: false }));",
    "NODE",
  ].join("\n");
}

function yamlLaneGitMirrorCacheVolume(spec: AgentRunLaneSpec): Record<string, unknown> {
  if (spec.gitMirror.cacheHostPath !== null) {
    return { name: "cache", hostPath: { path: spec.gitMirror.cacheHostPath, type: "DirectoryOrCreate" } };
  }
  return { name: "cache", persistentVolumeClaim: { claimName: spec.gitMirror.cachePvc } };
}

function yamlLaneGitMirrorJobManifest(spec: AgentRunLaneSpec, action: "sync" | "flush", name: string): Record<string, unknown> {
  const proxyHostNeedsHostNetwork = spec.gitMirror.githubProxy.host === "127.0.0.1" || spec.gitMirror.githubProxy.host === "localhost";
  return {
    apiVersion: "batch/v1",
    kind: "Job",
    metadata: {
      name,
      namespace: spec.gitMirror.namespace,
      labels: {
        "app.kubernetes.io/name": "git-mirror",
        "app.kubernetes.io/part-of": "agentrun",
        "agentrun.pikastech.local/lane": spec.version,
        "agentrun.pikastech.local/node": spec.nodeId,
        "agentrun.pikastech.local/component": action,
      },
    },
    spec: {
      backoffLimit: 0,
      activeDeadlineSeconds: 600,
      ttlSecondsAfterFinished: 3600,
      template: {
        metadata: {
          labels: {
            "app.kubernetes.io/name": "git-mirror",
            "app.kubernetes.io/part-of": "agentrun",
            "agentrun.pikastech.local/lane": spec.version,
            "agentrun.pikastech.local/node": spec.nodeId,
            "agentrun.pikastech.local/component": action,
          },
        },
        spec: {
          restartPolicy: "Never",
          ...(proxyHostNeedsHostNetwork ? { hostNetwork: true, dnsPolicy: "ClusterFirstWithHostNet" } : {}),
          volumes: [
            yamlLaneGitMirrorCacheVolume(spec),
            { name: "git-ssh", secret: { secretName: spec.gitMirror.sshSecretName, defaultMode: 0o400 } },
          ],
          containers: [{
            name: action,
            image: spec.gitMirror.toolsImage,
            imagePullPolicy: "IfNotPresent",
            command: ["/bin/sh", "-ec", action === "sync" ? yamlLaneGitMirrorSyncShell(spec) : yamlLaneGitMirrorFlushShell(spec)],
            volumeMounts: [
              { name: "cache", mountPath: "/cache" },
              { name: "git-ssh", mountPath: "/git-ssh", readOnly: true },
            ],
          }],
        },
      },
    },
  };
}

function yamlLaneGitMirrorSshSetupShellLines(spec: AgentRunLaneSpec): string[] {
  const proxyHost = spec.gitMirror.githubProxy.host;
  const proxyPort = spec.gitMirror.githubProxy.port;
  const proxyUrl = `http://${proxyHost}:${proxyPort}`;
  const proxySummary = `agentrun git-mirror-egress-proxy node=${spec.nodeId} lane=${spec.lane} host=${proxyHost} port=${proxyPort} ssh=GIT_SSH-wrapper source=yaml`;
  const proxyCommand = `ProxyCommand=node /tmp/agentrun-github-proxy-connect.cjs ${proxyHost} ${proxyPort} %h %p`;
  return [
    "mkdir -p /root/.ssh",
    "cp /git-ssh/ssh-privatekey /root/.ssh/id_rsa",
    "chmod 0400 /root/.ssh/id_rsa",
    `printf '%s\\n' ${shQuote(proxySummary)} >&2`,
    "cat > /tmp/agentrun-github-proxy-connect.cjs <<'NODE_PROXY'",
    "#!/usr/bin/env node",
    "const net = require('node:net');",
    "const [proxyHost, proxyPortRaw, targetHost, targetPortRaw] = process.argv.slice(2);",
    "const proxyPort = Number.parseInt(proxyPortRaw || '', 10);",
    "const targetPort = Number.parseInt(targetPortRaw || '', 10);",
    "if (!proxyHost || !Number.isInteger(proxyPort) || !targetHost || !Number.isInteger(targetPort)) {",
    "  console.error('agentrun git-mirror proxy-connect: invalid ProxyCommand arguments');",
    "  process.exit(64);",
    "}",
    "let settled = false;",
    "let tunnelEstablished = false;",
    "function finish(code, message) {",
    "  if (settled) return;",
    "  settled = true;",
    "  if (message) console.error('agentrun git-mirror proxy-connect: ' + message);",
    "  process.exit(code);",
    "}",
    "const socket = net.createConnection({ host: proxyHost, port: proxyPort });",
    "let buffer = Buffer.alloc(0);",
    "socket.setTimeout(15000, () => { socket.destroy(); finish(65, 'timeout connecting via ' + proxyHost + ':' + proxyPort + ' to ' + targetHost + ':' + targetPort); });",
    "socket.on('connect', () => socket.write('CONNECT ' + targetHost + ':' + targetPort + ' HTTP/1.1\\r\\nHost: ' + targetHost + ':' + targetPort + '\\r\\nProxy-Connection: Keep-Alive\\r\\n\\r\\n'));",
    "socket.on('error', (error) => finish(tunnelEstablished ? 69 : 66, (tunnelEstablished ? 'tunnel socket error: ' : 'tcp error connecting to proxy: ') + (error && error.message ? error.message : String(error))));",
    "socket.on('close', () => { if (!tunnelEstablished) finish(68, 'proxy closed before CONNECT completed via ' + proxyHost + ':' + proxyPort + ' to ' + targetHost + ':' + targetPort); else finish(0); });",
    "function onData(chunk) {",
    "  buffer = Buffer.concat([buffer, chunk]);",
    "  const headerEnd = buffer.indexOf('\\r\\n\\r\\n');",
    "  if (headerEnd === -1 && buffer.length < 8192) return;",
    "  if (headerEnd === -1) { socket.destroy(); finish(68, 'proxy response header exceeded 8192 bytes before CONNECT status via ' + proxyHost + ':' + proxyPort + ' to ' + targetHost + ':' + targetPort); return; }",
    "  const head = buffer.slice(0, headerEnd + 4).toString('latin1');",
    "  const statusLine = head.split('\\r\\n', 1)[0] || '';",
    "  const statusCode = Number.parseInt(statusLine.split(' ')[1] || '', 10);",
    "  if (!statusLine.startsWith('HTTP/1.') || !Number.isInteger(statusCode) || statusCode < 200 || statusCode > 299) {",
    "    const safeStatus = statusLine.replace(/[^\\x20-\\x7e]/g, '?').slice(0, 160);",
    "    socket.destroy();",
    "    finish(67, 'proxy CONNECT failed via ' + proxyHost + ':' + proxyPort + ' to ' + targetHost + ':' + targetPort + ': ' + safeStatus);",
    "    return;",
    "  }",
    "  socket.off('data', onData);",
    "  socket.setTimeout(0);",
    "  tunnelEstablished = true;",
    "  const rest = buffer.slice(headerEnd + 4);",
    "  if (rest.length) process.stdout.write(rest);",
    "  process.stdin.on('error', () => {});",
    "  process.stdout.on('error', () => {});",
    "  process.stdin.pipe(socket);",
    "  socket.pipe(process.stdout);",
    "}",
    "socket.on('data', onData);",
    "NODE_PROXY",
    "chmod 0700 /tmp/agentrun-github-proxy-connect.cjs",
    "cat > /tmp/agentrun-git-ssh-proxy.sh <<'SH_PROXY'",
    "#!/bin/sh",
    `exec ssh -i /root/.ssh/id_rsa -o IdentitiesOnly=yes -o BatchMode=yes -o StrictHostKeyChecking=accept-new -o UserKnownHostsFile=/root/.ssh/known_hosts -o ConnectTimeout=15 -o ServerAliveInterval=5 -o ServerAliveCountMax=1 -o ${shQuote(proxyCommand)} "$@"`,
    "SH_PROXY",
    "chmod 0700 /tmp/agentrun-git-ssh-proxy.sh",
    `export HTTP_PROXY=${shQuote(proxyUrl)}`,
    `export HTTPS_PROXY=${shQuote(proxyUrl)}`,
    `export ALL_PROXY=${shQuote(proxyUrl)}`,
    `export http_proxy=${shQuote(proxyUrl)}`,
    `export https_proxy=${shQuote(proxyUrl)}`,
    `export all_proxy=${shQuote(proxyUrl)}`,
    "export GIT_SSH=/tmp/agentrun-git-ssh-proxy.sh",
    "unset GIT_SSH_COMMAND",
  ];
}

function yamlLaneGitMirrorSyncShell(spec: AgentRunLaneSpec): string {
  return [
    "set -eu",
    ...yamlLaneGitMirrorSshSetupShellLines(spec),
    `repository=${shQuote(spec.source.repository)}`,
    `source_branch=${shQuote(spec.source.branch)}`,
    `gitops_branch=${shQuote(spec.gitops.branch)}`,
    "repo=\"/cache/${repository}.git\"",
    "remote=\"ssh://git@ssh.github.com:443/${repository}.git\"",
    "mkdir -p \"$(dirname \"$repo\")\"",
    "if [ -d \"$repo/objects\" ] && [ -f \"$repo/HEAD\" ]; then",
    "  git --git-dir=\"$repo\" remote set-url origin \"$remote\" || git --git-dir=\"$repo\" remote add origin \"$remote\"",
    "else",
    "  rm -rf \"$repo\"",
    "  git init --bare \"$repo\"",
    "  git --git-dir=\"$repo\" remote add origin \"$remote\"",
    "fi",
    "git --git-dir=\"$repo\" config uploadpack.allowReachableSHA1InWant true",
    "git --git-dir=\"$repo\" config uploadpack.allowAnySHA1InWant true",
    "git --git-dir=\"$repo\" config http.uploadpack true",
    "git --git-dir=\"$repo\" config http.receivepack true",
    "timeout 240 git --git-dir=\"$repo\" fetch origin \"+refs/heads/${source_branch}:refs/mirror-stage/heads/${source_branch}\"",
    "source_sha=$(git --git-dir=\"$repo\" rev-parse --verify \"refs/mirror-stage/heads/${source_branch}^{commit}\")",
    "git --git-dir=\"$repo\" update-ref \"refs/heads/${source_branch}\" \"$source_sha\"",
    "timeout 240 git --git-dir=\"$repo\" fetch origin \"+refs/heads/${gitops_branch}:refs/mirror-stage/heads/${gitops_branch}\"",
    "gitops_sha=$(git --git-dir=\"$repo\" rev-parse --verify \"refs/mirror-stage/heads/${gitops_branch}^{commit}\")",
    "git --git-dir=\"$repo\" update-ref \"refs/heads/${gitops_branch}\" \"$gitops_sha\"",
    "git --git-dir=\"$repo\" update-server-info",
    "SOURCE_SHA=\"$source_sha\" GITOPS_SHA=\"$gitops_sha\" node <<'NODE'",
    "console.log(JSON.stringify({ ok: true, localSource: process.env.SOURCE_SHA, localGitops: process.env.GITOPS_SHA, valuesPrinted: false }));",
    "NODE",
  ].join("\n");
}

function yamlLaneGitMirrorFlushShell(spec: AgentRunLaneSpec): string {
  return [
    "set -eu",
    ...yamlLaneGitMirrorSshSetupShellLines(spec),
    `repository=${shQuote(spec.source.repository)}`,
    `gitops_branch=${shQuote(spec.gitops.branch)}`,
    "repo=\"/cache/${repository}.git\"",
    "remote=\"ssh://git@ssh.github.com:443/${repository}.git\"",
    "test -d \"$repo\"",
    "git --git-dir=\"$repo\" remote set-url origin \"$remote\" || git --git-dir=\"$repo\" remote add origin \"$remote\"",
    "local_gitops=$(git --git-dir=\"$repo\" rev-parse --verify \"refs/heads/${gitops_branch}^{commit}\" 2>/dev/null || true)",
    "if [ -n \"$local_gitops\" ]; then",
    "  git --git-dir=\"$repo\" -c remote.origin.mirror=false push origin \"refs/heads/${gitops_branch}:refs/heads/${gitops_branch}\"",
    "  git --git-dir=\"$repo\" fetch origin \"+refs/heads/${gitops_branch}:refs/mirror-stage/heads/${gitops_branch}\"",
    "fi",
    "github_gitops=$(git --git-dir=\"$repo\" rev-parse --verify \"refs/mirror-stage/heads/${gitops_branch}^{commit}\" 2>/dev/null || true)",
    "pending=false; if [ -n \"$local_gitops\" ] && { [ -z \"$github_gitops\" ] || [ \"$local_gitops\" != \"$github_gitops\" ]; }; then pending=true; fi",
    "LOCAL_GITOPS=\"$local_gitops\" GITHUB_GITOPS=\"$github_gitops\" PENDING=\"$pending\" node <<'NODE'",
    "console.log(JSON.stringify({ ok: process.env.PENDING !== 'true', localGitops: process.env.LOCAL_GITOPS || null, githubGitops: process.env.GITHUB_GITOPS || null, pendingFlush: process.env.PENDING === 'true', valuesPrinted: false }));",
    "NODE",
  ].join("\n");
}

function yamlLaneGitMirrorStatusScript(spec: AgentRunLaneSpec): string {
  return [
    "set +e",
    `namespace=${shQuote(spec.gitMirror.namespace)}`,
    `read_deployment=${shQuote(spec.gitMirror.readDeployment)}`,
    `read_service=${shQuote(spec.gitMirror.readService)}`,
    `write_service=${shQuote(spec.gitMirror.writeService)}`,
    `cache_pvc=${shQuote(spec.gitMirror.cachePvc)}`,
    `repository=${shQuote(spec.source.repository)}`,
    `source_branch=${shQuote(spec.source.branch)}`,
    `gitops_branch=${shQuote(spec.gitops.branch)}`,
    `repositories_json=${shQuote(JSON.stringify(spec.gitMirror.repositories))}`,
    "kubectl -n \"$namespace\" get svc \"$read_service\" -o json >/tmp/agentrun-gitmirror-read.json 2>/dev/null",
    "read_exit=$?",
    "kubectl -n \"$namespace\" get svc \"$write_service\" -o json >/tmp/agentrun-gitmirror-write.json 2>/dev/null",
    "write_exit=$?",
    "kubectl -n \"$namespace\" get pvc \"$cache_pvc\" -o json >/tmp/agentrun-gitmirror-cache.json 2>/dev/null",
    "cache_exit=$?",
    "kubectl -n \"$namespace\" get deploy,svc,pvc -o name > /tmp/agentrun-gitmirror-names.txt 2>/dev/null",
    "repo_path=\"/cache/${repository}.git\"",
    "rm -f /tmp/agentrun-gitmirror-refs.txt",
    "if [ \"$read_exit\" -eq 0 ]; then",
    "  kubectl -n \"$namespace\" exec deploy/\"$read_deployment\" -- sh -lc 'repo_path=\"$1\"; source_branch=\"$2\"; gitops_branch=\"$3\"; printf \"sourceCommit=\"; git --git-dir=\"$repo_path\" rev-parse \"refs/heads/$source_branch\" 2>/dev/null || true; printf \"gitopsCommit=\"; git --git-dir=\"$repo_path\" rev-parse \"refs/heads/$gitops_branch\" 2>/dev/null || true' sh \"$repo_path\" \"$source_branch\" \"$gitops_branch\" > /tmp/agentrun-gitmirror-refs.txt 2>/dev/null",
    "fi",
    "NAMESPACE=\"$namespace\" READ_EXIT=\"$read_exit\" WRITE_EXIT=\"$write_exit\" CACHE_EXIT=\"$cache_exit\" REPOSITORY=\"$repository\" SOURCE_BRANCH=\"$source_branch\" GITOPS_BRANCH=\"$gitops_branch\" REPOSITORIES_JSON=\"$repositories_json\" node <<'NODE'",
    "const fs = require('node:fs');",
    "const repositories = JSON.parse(process.env.REPOSITORIES_JSON || '[]');",
    "let names = ''; try { names = fs.readFileSync('/tmp/agentrun-gitmirror-names.txt', 'utf8'); } catch {}",
    "let refs = ''; try { refs = fs.readFileSync('/tmp/agentrun-gitmirror-refs.txt', 'utf8'); } catch {}",
    "const refValue = (key) => refs.split(/\\r?\\n/).find((line) => line.startsWith(`${key}=`))?.slice(key.length + 1).trim() || null;",
    "const readReady = process.env.READ_EXIT === '0';",
    "const writeReady = process.env.WRITE_EXIT === '0';",
    "const cachePvcExists = process.env.CACHE_EXIT === '0';",
    "console.log(JSON.stringify({",
    "  ok: readReady && writeReady && cachePvcExists,",
    "  namespace: process.env.NAMESPACE,",
    "  readReady,",
    "  writeReady,",
    "  cachePvcExists,",
    "  resources: names.split(/\\r?\\n/).filter(Boolean).slice(0, 40),",
    "  repository: process.env.REPOSITORY,",
    "  sourceBranch: process.env.SOURCE_BRANCH,",
    "  gitopsBranch: process.env.GITOPS_BRANCH,",
    "  sourceCommit: refValue('sourceCommit'),",
    "  gitopsCommit: refValue('gitopsCommit'),",
    "  repositories,",
    "  valuesPrinted: false",
    "}));",
    "NODE",
  ].join("\n");
}

type LaneSecretSource = {
  id: string;
  sourceRef: string;
  sourceMode: "env" | "file";
  sourceKey: string | null;
  targetRef: { namespace: string; name: string; key: string };
};

function readSecretSourceValue(spec: AgentRunLaneSpec, source: LaneSecretSource): { redactedPath: string; value: string; valueBytes: number; fingerprint: string } {
  const { sourceRef } = source;
  if (sourceRef.includes("..")) throw new Error(`secret sourceRef must not contain ..: ${sourceRef}`);
  const sourcePath = sourceRef.startsWith("/")
    ? sourceRef
    : join(resolveSecretSourceRoot(spec), ...sourceRef.split("/"));
  if (!existsSync(sourcePath)) throw new Error(`secret source ${sourceRef} is missing`);
  let value: string;
  if (source.sourceMode === "file") {
    value = readFileSync(sourcePath, "utf8");
  } else {
    if (source.sourceKey === null) throw new Error(`secret source ${sourceRef} is missing sourceKey`);
    const values = parseEnvFile(readFileSync(sourcePath, "utf8"));
    const envValue = values.get(source.sourceKey);
    if (envValue === undefined || envValue.length === 0) throw new Error(`secret source ${sourceRef} is missing required key ${source.sourceKey}`);
    value = envValue;
  }
  if (value.length === 0) throw new Error(`secret source ${sourceRef} is empty`);
  return {
    redactedPath: sourceRef.startsWith("/") ? redactAbsoluteSecretPath(sourceRef) : `.state/secrets/${sourceRef}`,
    value,
    valueBytes: Buffer.byteLength(value, "utf8"),
    fingerprint: sha256Fingerprint(value),
  };
}

function redactAbsoluteSecretPath(sourceRef: string): string {
  const parts = sourceRef.split("/").filter(Boolean);
  return parts.length === 0 ? "/" : `/${parts.slice(0, -1).join("/")}/<redacted>`;
}

function resolveSecretSourceRoot(spec: AgentRunLaneSpec): string {
  if (spec.database.configRef === null) return rootPath(".state", "secrets");
  const configPath = spec.database.configRef.startsWith("/") ? spec.database.configRef : rootPath(spec.database.configRef);
  const configRoot = record(Bun.YAML.parse(readFileSync(configPath, "utf8")) as unknown);
  const secrets = record(configRoot.secrets);
  const root = stringOrNull(secrets.root);
  if (root === null || !root.startsWith("/") || root.includes("..")) throw new Error(`${spec.database.configRef}.secrets.root must be an absolute path without ..`);
  return root;
}

function parseEnvFile(text: string): Map<string, string> {
  const result = new Map<string, string>();
  for (const rawLine of text.split(/\r?\n/u)) {
    let line = rawLine.trim();
    if (line.length === 0 || line.startsWith("#")) continue;
    if (line.startsWith("export ")) line = line.slice("export ".length).trim();
    const index = line.indexOf("=");
    if (index <= 0) continue;
    const key = line.slice(0, index).trim();
    let value = line.slice(index + 1).trim();
    if ((value.startsWith('"') && value.endsWith('"')) || (value.startsWith("'") && value.endsWith("'"))) {
      value = value.slice(1, -1);
    }
    result.set(key, value);
  }
  return result;
}

function collectLaneSecretSources(spec: AgentRunLaneSpec): LaneSecretSource[] {
  const result: LaneSecretSource[] = [];
  if (spec.database.secretSourceRef !== null) {
    result.push({
      id: "database",
      sourceRef: spec.database.secretSourceRef,
      sourceMode: "env",
      sourceKey: spec.database.secretRef.key,
      targetRef: { namespace: spec.runtime.namespace, name: spec.database.secretRef.name, key: spec.database.secretRef.key },
    });
  }
  for (const secret of spec.secrets) {
    result.push({
      id: secret.id,
      sourceRef: secret.sourceRef,
      sourceMode: secret.sourceMode,
      sourceKey: secret.sourceKey,
      targetRef: secret.targetRef,
    });
  }
  const seen = new Set<string>();
  return result.filter((item) => {
    const key = `${item.targetRef.namespace}/${item.targetRef.name}/${item.targetRef.key}`;
    if (seen.has(key)) return false;
    seen.add(key);
    return true;
  });
}

function secretSyncScript(_spec: AgentRunLaneSpec, values: Array<{ targetRef: { namespace: string; name: string; key: string }; value: string }>): string {
  const encoded = Buffer.from(JSON.stringify(values.map((item) => ({
    targetRef: item.targetRef,
    valueBase64: Buffer.from(item.value, "utf8").toString("base64"),
  }))), "utf8").toString("base64");
  return [
    "set -eu",
    `payload_b64=${shQuote(encoded)}`,
    "tmp_dir=$(mktemp -d)",
    "trap 'rm -rf \"$tmp_dir\"' EXIT",
    "payload_json=\"$tmp_dir/payload.json\"",
    "printf '%s' \"$payload_b64\" | base64 -d > \"$payload_json\"",
    "PAYLOAD_JSON=\"$payload_json\" TMP_DIR=\"$tmp_dir\" node <<'NODE'",
    "const fs = require('node:fs');",
    "const cp = require('node:child_process');",
    "const crypto = require('node:crypto');",
    "const items = JSON.parse(fs.readFileSync(process.env.PAYLOAD_JSON, 'utf8'));",
    "const results = [];",
    "const groups = new Map();",
    "function run(argv, input) {",
    "  const out = cp.spawnSync(argv[0], argv.slice(1), { input, encoding: 'utf8' });",
    "  if (out.status !== 0) throw new Error(`${argv.join(' ')} failed: ${out.stderr || out.stdout}`);",
    "  return out;",
    "}",
    "function tryRun(argv) {",
    "  return cp.spawnSync(argv[0], argv.slice(1), { encoding: 'utf8' });",
    "}",
    "for (let index = 0; index < items.length; index += 1) {",
    "  const item = items[index];",
    "  const ref = item.targetRef;",
    "  const groupKey = `${ref.namespace}\\u0000${ref.name}`;",
    "  if (!groups.has(groupKey)) groups.set(groupKey, { namespace: ref.namespace, name: ref.name, items: [] });",
    "  groups.get(groupKey).items.push({ key: ref.key, valueBase64: item.valueBase64 });",
    "}",
    "for (const group of groups.values()) {",
    "  const ns = run(['kubectl', 'create', 'namespace', group.namespace, '--dry-run=client', '-o', 'yaml']).stdout;",
    "  run(['kubectl', 'apply', '--server-side', '--field-manager=unidesk-agentrun-secret-sync', '-f', '-'], ns);",
    "  const existing = tryRun(['kubectl', '-n', group.namespace, 'get', 'secret', group.name]);",
    "  if (existing.status !== 0) run(['kubectl', '-n', group.namespace, 'create', 'secret', 'generic', group.name]);",
    "  const patch = { data: {} };",
    "  for (const entry of group.items) patch.data[entry.key] = entry.valueBase64;",
    "  const patchFile = `${process.env.TMP_DIR}/${group.namespace}-${group.name}-patch.json`;",
    "  fs.writeFileSync(patchFile, JSON.stringify(patch));",
    "  run(['kubectl', '-n', group.namespace, 'patch', 'secret', group.name, '--type=merge', `--patch-file=${patchFile}`]);",
    "  const fetched = JSON.parse(run(['kubectl', '-n', group.namespace, 'get', 'secret', group.name, '-o', 'json']).stdout);",
    "  for (const entry of group.items) {",
    "    const raw = fetched.data?.[entry.key] || '';",
    "    const decoded = raw ? Buffer.from(raw, 'base64') : Buffer.alloc(0);",
    "    results.push({ namespace: group.namespace, secret: group.name, key: entry.key, ok: raw.length > 0, valueBytes: decoded.length, fingerprint: raw ? 'sha256:' + crypto.createHash('sha256').update(decoded).digest('hex') : null, valuesPrinted: false });",
    "  }",
    "}",
    "console.log(JSON.stringify({ ok: results.every((item) => item.ok), secretCount: results.length, items: results, valuesPrinted: false }));",
    "NODE",
  ].join("\n");
}

function restartYamlLaneScript(spec: AgentRunLaneSpec): string {
  return [
    "set +e",
    `namespace=${shQuote(spec.runtime.namespace)}`,
    `deployment=${shQuote(spec.runtime.managerDeployment)}`,
    "ts=$(date -u +%Y-%m-%dT%H:%M:%SZ)",
    "kubectl -n \"$namespace\" patch deployment \"$deployment\" --type='merge' -p \"{\\\"spec\\\":{\\\"template\\\":{\\\"metadata\\\":{\\\"annotations\\\":{\\\"kubectl.kubernetes.io/restartedAt\\\":\\\"$ts\\\"}}}}}\" >/tmp/agentrun-restart-patch.out 2>/tmp/agentrun-restart-patch.err",
    "patch_rc=$?",
    "if [ \"$patch_rc\" -eq 0 ]; then",
    "  kubectl -n \"$namespace\" rollout status deployment/\"$deployment\" --timeout=180s >/tmp/agentrun-rollout-status.out 2>/tmp/agentrun-rollout-status.err",
    "  rollout_rc=$?",
    "else",
    "  rollout_rc=$patch_rc",
    "fi",
    "pods_json=$(kubectl -n \"$namespace\" get pod -l app.kubernetes.io/name=agentrun-mgr -o json 2>/dev/null || printf '{}')",
    "deployment_json=$(kubectl -n \"$namespace\" get deployment \"$deployment\" -o json 2>/dev/null || printf '{}')",
    "patch_err=$(cat /tmp/agentrun-restart-patch.err 2>/dev/null || true)",
    "rollout_err=$(cat /tmp/agentrun-rollout-status.err 2>/dev/null || true)",
    "PODS_JSON=\"$pods_json\" DEPLOYMENT_JSON=\"$deployment_json\" PATCH_RC=\"$patch_rc\" ROLLOUT_RC=\"$rollout_rc\" TS=\"$ts\" PATCH_ERR=\"$patch_err\" ROLLOUT_ERR=\"$rollout_err\" node <<'NODE'",
    "const pods = JSON.parse(process.env.PODS_JSON || '{}');",
    "const deployment = JSON.parse(process.env.DEPLOYMENT_JSON || '{}');",
    "const conditions = Array.isArray(deployment.status?.conditions) ? deployment.status.conditions : [];",
    "const items = Array.isArray(pods.items) ? pods.items : [];",
    "const compactError = (value) => String(value || '').replace(/\\s+/g, ' ').trim().slice(0, 500) || null;",
    "console.log(JSON.stringify({",
    "  ok: process.env.PATCH_RC === '0' && process.env.ROLLOUT_RC === '0',",
    "  restartedAt: process.env.TS,",
    "  patch: { exitCode: Number(process.env.PATCH_RC || '1'), error: compactError(process.env.PATCH_ERR) },",
    "  rollout: { exitCode: Number(process.env.ROLLOUT_RC || '1'), error: compactError(process.env.ROLLOUT_ERR) },",
    "  readyReplicas: deployment.status?.readyReplicas ?? null,",
    "  replicas: deployment.status?.replicas ?? null,",
    "  conditions: conditions.map((item) => ({ type: item.type, status: item.status, reason: item.reason ?? null })),",
    "  pods: items.map((pod) => ({",
    "    name: pod.metadata?.name ?? null,",
    "    phase: pod.status?.phase ?? null,",
    "    ready: (pod.status?.containerStatuses ?? []).map((item) => item.ready),",
    "    restarts: (pod.status?.containerStatuses ?? []).map((item) => item.restartCount),",
    "    waiting: (pod.status?.containerStatuses ?? []).map((item) => item.state?.waiting?.reason ?? null),",
    "  })),",
    "  valuesPrinted: false",
    "}));",
    "NODE",
    "exit \"$rollout_rc\"",
  ].join("\n");
}

function applyYamlScript(yaml: string, fieldManager: string, dryRun: boolean): string {
  const encoded = Buffer.from(yaml, "utf8").toString("base64");
  return [
    "set -eu",
    `manifest_b64=${shQuote(encoded)}`,
    `field_manager=${shQuote(fieldManager)}`,
    `dry_run=${dryRun ? "true" : "false"}`,
    "tmp_dir=$(mktemp -d)",
    "trap 'rm -rf \"$tmp_dir\"' EXIT",
    "manifest=\"$tmp_dir/manifest.yaml\"",
    "printf '%s' \"$manifest_b64\" | base64 -d > \"$manifest\"",
    "args=\"--server-side --force-conflicts --field-manager=$field_manager\"",
    "if [ \"$dry_run\" = true ]; then args=\"$args --dry-run=server\"; fi",
    "set +e",
    "kubectl apply $args -f \"$manifest\" > \"$tmp_dir/apply.out\" 2> \"$tmp_dir/apply.err\"",
    "apply_exit=$?",
    "set -e",
    "APPLY_EXIT=\"$apply_exit\" APPLY_OUT=\"$tmp_dir/apply.out\" APPLY_ERR=\"$tmp_dir/apply.err\" MANIFEST=\"$manifest\" node <<'NODE'",
    "const fs = require('node:fs');",
    "const crypto = require('node:crypto');",
    "const out = fs.readFileSync(process.env.APPLY_OUT, 'utf8');",
    "const err = fs.readFileSync(process.env.APPLY_ERR, 'utf8');",
    "const manifest = fs.readFileSync(process.env.MANIFEST, 'utf8');",
    "const resources = out.split(/\\r?\\n/).map((line) => line.trim()).filter(Boolean).slice(0, 80);",
    "console.log(JSON.stringify({ ok: process.env.APPLY_EXIT === '0', exitCode: Number(process.env.APPLY_EXIT), resourceCount: resources.length, resources, manifestBytes: Buffer.byteLength(manifest, 'utf8'), manifestDigest: 'sha256:' + crypto.createHash('sha256').update(manifest).digest('hex'), stderrTail: err.slice(-3000), valuesPrinted: false }));",
    "NODE",
    "exit \"$apply_exit\"",
  ].join("\n");
}

function manifestObjectRef(object: Record<string, unknown>): Record<string, unknown> {
  const metadata = record(object.metadata);
  return {
    apiVersion: stringOrNull(object.apiVersion),
    kind: stringOrNull(object.kind),
    namespace: stringOrNull(metadata.namespace),
    name: stringOrNull(metadata.name),
  };
}

function cleanupRunnersFactsNodeScript(): string {
  return String.raw`
function iso(value) {
  if (value instanceof Date) return value.toISOString();
  if (typeof value === "string" && value.length > 0) {
    const ms = Date.parse(value);
    return Number.isFinite(ms) ? new Date(ms).toISOString() : null;
  }
  return null;
}

try {
  const { Pool } = await import("pg");
  const namespace = process.env.RETENTION_NAMESPACE || process.env.AGENTRUN_RUNTIME_NAMESPACE || "";
  const pool = new Pool({ connectionString: process.env.DATABASE_URL });
  const sql = [
    "SELECT",
    "  j.id, j.run_id, j.command_id, j.attempt_id, j.runner_id, j.namespace, j.job_name, j.created_at, j.updated_at,",
    "  r.registered_at AS runner_registered_at, r.heartbeat_at AS runner_heartbeat_at,",
    "  rr.status AS run_status, rr.terminal_status AS run_terminal_status, rr.failure_kind AS run_failure_kind, rr.updated_at AS run_updated_at",
    "FROM agentrun_runner_jobs j",
    "LEFT JOIN agentrun_runners r ON r.id = j.runner_id",
    "LEFT JOIN agentrun_runs rr ON rr.id = j.run_id",
    "WHERE j.namespace = $1",
    "ORDER BY COALESCE(r.heartbeat_at, j.updated_at, j.created_at) ASC",
  ].join("\n");
  const result = await pool.query(sql, [namespace]);
  await pool.end();
  console.log(JSON.stringify({
    ok: true,
    itemCount: result.rows.length,
    items: result.rows.map((row) => ({
      id: row.id,
      runId: row.run_id,
      commandId: row.command_id,
      attemptId: row.attempt_id,
      runnerId: row.runner_id,
      namespace: row.namespace,
      jobName: row.job_name,
      runnerJobCreatedAt: iso(row.created_at),
      runnerJobUpdatedAt: iso(row.updated_at),
      runnerRegisteredAt: iso(row.runner_registered_at),
      runnerHeartbeatAt: iso(row.runner_heartbeat_at),
      runStatus: row.run_status || null,
      runTerminalStatus: row.run_terminal_status || null,
      runFailureKind: row.run_failure_kind || null,
      runUpdatedAt: iso(row.run_updated_at),
      valuesPrinted: false,
    })),
    valuesPrinted: false,
  }));
} catch (error) {
  console.log(JSON.stringify({
    ok: false,
    itemCount: 0,
    items: [],
    failureKind: "manager-runner-facts-query-failed",
    message: error instanceof Error ? error.message : String(error),
    valuesPrinted: false,
  }));
}
`;
}

function cleanupRunnersPlanNodeScript(): string {
  return String.raw`
const fs = require("node:fs");
const path = require("node:path");
const tmp = process.env.TMP_DIR;
const namespace = process.env.NAMESPACE;
const maxRunners = Number(process.env.MAX_RUNNERS || 0);
const cleanupOrder = process.env.CLEANUP_ORDER || "";
const activeHeartbeatMaxAgeMs = Number(process.env.ACTIVE_HEARTBEAT_MAX_AGE_MS || 0);
const ageBasedCleanupEnabled = process.env.AGE_BASED_CLEANUP_ENABLED === "true";
const ageBasedMaxAgeHours = process.env.AGE_BASED_MAX_AGE_HOURS ? Number(process.env.AGE_BASED_MAX_AGE_HOURS) : null;
const forceActive = process.env.FORCE_ACTIVE === "true";
const matchLabels = JSON.parse(process.env.MATCH_LABELS_JSON || "{}");
const jobNamePrefixes = JSON.parse(process.env.JOB_NAME_PREFIXES_JSON || "[]");
const now = Date.now();

function readJson(name) {
  return JSON.parse(fs.readFileSync(path.join(tmp, name), "utf8"));
}

function dateMs(value) {
  const ms = Date.parse(value || "");
  return Number.isFinite(ms) ? ms : null;
}

function ageMs(value) {
  const ms = dateMs(value);
  return ms === null ? null : Math.max(0, now - ms);
}

function labelsOf(item) {
  return item?.metadata?.labels && typeof item.metadata.labels === "object" ? item.metadata.labels : {};
}

function annotationsOf(item) {
  return item?.metadata?.annotations && typeof item.metadata.annotations === "object" ? item.metadata.annotations : {};
}

function matchesLabels(labels) {
  return Object.entries(matchLabels).every(([key, value]) => labels?.[key] === value);
}

function matchesPrefix(name) {
  return jobNamePrefixes.length === 0 || jobNamePrefixes.some((prefix) => name === prefix || name.startsWith(prefix + "-"));
}

function terminalRunStatus(value) {
  return value === "completed" || value === "failed" || value === "blocked" || value === "cancelled";
}

function jobCondition(job, type) {
  const conditions = Array.isArray(job?.status?.conditions) ? job.status.conditions : [];
  return conditions.find((entry) => entry?.type === type && entry?.status === "True") || null;
}

function isTerminalJob(job) {
  return jobCondition(job, "Complete") !== null || jobCondition(job, "Failed") !== null || Number(job?.status?.succeeded || 0) > 0 || Number(job?.status?.failed || 0) > 0;
}

function isTerminalPod(pod) {
  const phase = pod?.status?.phase || "";
  return phase === "Succeeded" || phase === "Failed";
}

function jobNameForPod(pod) {
  const labels = labelsOf(pod);
  if (typeof labels["job-name"] === "string") return labels["job-name"];
  const owner = (Array.isArray(pod?.metadata?.ownerReferences) ? pod.metadata.ownerReferences : []).find((entry) => entry?.kind === "Job" && typeof entry?.name === "string");
  return owner?.name || null;
}

function preferredLastActiveAt(fact, job) {
  return fact?.runnerHeartbeatAt
    || fact?.runUpdatedAt
    || fact?.runnerJobUpdatedAt
    || job?.status?.completionTime
    || job?.status?.startTime
    || job?.metadata?.creationTimestamp
    || null;
}

function sortOldestLastActive(left, right) {
  const leftMs = dateMs(left.lastActiveAt) ?? dateMs(left.createdAt) ?? Number.MAX_SAFE_INTEGER;
  const rightMs = dateMs(right.lastActiveAt) ?? dateMs(right.createdAt) ?? Number.MAX_SAFE_INTEGER;
  if (leftMs !== rightMs) return leftMs - rightMs;
  return String(left.name).localeCompare(String(right.name));
}

function countNonTerminalPods(pods) {
  return pods.filter((pod) => !isTerminalPod(pod)).length;
}

const jobs = readJson("jobs.json");
const pods = readJson("pods.json");
const facts = readJson("runner-facts.json");
const factItems = Array.isArray(facts.items) ? facts.items : [];
const factByJob = new Map(factItems.map((item) => [item.jobName, item]));
const allPods = Array.isArray(pods.items) ? pods.items : [];
const podsByJob = new Map();
for (const pod of allPods) {
  const jobName = jobNameForPod(pod);
  if (!jobName) continue;
  const entry = podsByJob.get(jobName) || [];
  entry.push(pod);
  podsByJob.set(jobName, entry);
}

const matchedJobs = (Array.isArray(jobs.items) ? jobs.items : [])
  .map((job) => {
    const name = job?.metadata?.name || "";
    return { job, name, labels: labelsOf(job), annotations: annotationsOf(job) };
  })
  .filter((item) => item.name && matchesLabels(item.labels) && matchesPrefix(item.name));

const runnerJobs = matchedJobs.map(({ job, name, labels, annotations }) => {
  const fact = factByJob.get(name) || null;
  const jobPods = podsByJob.get(name) || [];
  const nonTerminalPods = jobPods.filter((pod) => !isTerminalPod(pod));
  const terminatingPods = nonTerminalPods.filter((pod) => typeof pod?.metadata?.deletionTimestamp === "string");
  const terminal = isTerminalJob(job) || terminalRunStatus(fact?.runStatus) || terminalRunStatus(fact?.runTerminalStatus);
  const heartbeatAgeMs = ageMs(fact?.runnerHeartbeatAt);
  const heartbeatFresh = heartbeatAgeMs !== null && heartbeatAgeMs <= activeHeartbeatMaxAgeMs;
  const hasActivePod = Number(job?.status?.active || 0) > 0 || nonTerminalPods.length > 0;
  const lastActiveAt = preferredLastActiveAt(fact, job);
  let inactive = false;
  let protectedActive = false;
  let classification = "unknown";
  if (terminal) {
    inactive = true;
    classification = "terminal";
  } else if (heartbeatFresh) {
    protectedActive = true;
    classification = "active-fresh-heartbeat";
  } else if (heartbeatAgeMs !== null) {
    inactive = true;
    classification = "inactive-stale-heartbeat";
  } else if (terminatingPods.length > 0 && nonTerminalPods.length === terminatingPods.length) {
    inactive = true;
    classification = "inactive-terminating";
  } else if (hasActivePod) {
    protectedActive = true;
    classification = facts.ok === true ? "active-no-heartbeat-row" : "active-unverified-manager-facts";
  } else {
    inactive = true;
    classification = "inactive-no-active-pod";
  }
  return {
    name,
    namespace,
    createdAt: job?.metadata?.creationTimestamp || null,
    lastActiveAt,
    lastActiveAgeMs: ageMs(lastActiveAt),
    lastActiveSource: fact?.runnerHeartbeatAt ? "runner-heartbeat" : fact?.runUpdatedAt ? "run-updated" : fact?.runnerJobUpdatedAt ? "runner-job-updated" : job?.status?.completionTime ? "job-completion" : job?.status?.startTime ? "job-start" : "job-created",
    runId: annotations["agentrun.pikastech.local/run-id"] || fact?.runId || null,
    commandId: annotations["agentrun.pikastech.local/command-id"] || fact?.commandId || null,
    runnerJobId: fact?.id || null,
    runnerId: fact?.runnerId || null,
    runStatus: fact?.runStatus || null,
    runTerminalStatus: fact?.runTerminalStatus || null,
    jobStatus: {
      active: Number(job?.status?.active || 0),
      succeeded: Number(job?.status?.succeeded || 0),
      failed: Number(job?.status?.failed || 0),
      ready: Number(job?.status?.ready || 0),
      terminating: Number(job?.status?.terminating || 0),
    },
    podCount: jobPods.length,
    nonTerminalPodCount: nonTerminalPods.length,
    terminatingPodCount: terminatingPods.length,
    inactive,
    protectedActive,
    classification,
    labels,
    valuesPrinted: false,
  };
});

const runnerJobCount = runnerJobs.length;
const inactiveCandidates = runnerJobs.filter((item) => item.inactive).sort(sortOldestLastActive);
const overLimitCount = Math.max(0, runnerJobCount - maxRunners);
const selectedByName = new Map();
const selectionReasons = new Map();
for (const item of inactiveCandidates.slice(0, overLimitCount)) {
  selectedByName.set(item.name, item);
  selectionReasons.set(item.name, "over-max-runners");
}
if (ageBasedCleanupEnabled && ageBasedMaxAgeHours !== null) {
  const maxAgeMs = ageBasedMaxAgeHours * 3600 * 1000;
  for (const item of inactiveCandidates) {
    const itemAgeMs = item.lastActiveAgeMs;
    if (itemAgeMs !== null && itemAgeMs >= maxAgeMs) {
      selectedByName.set(item.name, item);
      if (!selectionReasons.has(item.name)) selectionReasons.set(item.name, "age-based-cleanup");
    }
  }
}
if (forceActive) {
  for (const item of runnerJobs) {
    selectedByName.set(item.name, item);
    selectionReasons.set(item.name, item.protectedActive ? "force-active-runner-cleanup" : "force-runner-cleanup");
  }
}

const selectionPool = forceActive ? runnerJobs : inactiveCandidates;
const selected = selectionPool
  .filter((item) => selectedByName.has(item.name))
  .map((item) => ({ ...item, selectionReason: selectionReasons.get(item.name) || "selected" }));
const matchedPodNames = new Set(runnerJobs.map((item) => item.name));
const matchedPods = allPods.filter((pod) => {
  const jobName = jobNameForPod(pod);
  return jobName !== null && matchedPodNames.has(jobName);
});
const remainingAfterSelection = runnerJobCount - selected.length;
console.log(JSON.stringify({
  ok: true,
  planKind: "agentrun-runtime-runner-retention",
  generatedAt: new Date(now).toISOString(),
  namespace,
  criteria: {
    maxRunners,
    cleanupOrder,
    activeHeartbeatMaxAgeMs,
    forceActive,
    selectors: { matchLabels, jobNamePrefixes },
    ageBasedCleanup: { enabled: ageBasedCleanupEnabled, maxAgeHours: ageBasedMaxAgeHours },
  },
  managerFacts: {
    ok: facts.ok === true,
    factCount: factItems.length,
    factsExit: Number(process.env.FACTS_EXIT || 0),
    failureKind: facts.failureKind || null,
    message: facts.ok === true ? null : facts.message || null,
    valuesPrinted: false,
  },
  runnerJobCount,
  nonTerminalRunnerPodCount: countNonTerminalPods(matchedPods),
  overLimitCount,
  inactiveCandidateCount: inactiveCandidates.length,
  protectedActiveRunnerCount: runnerJobs.filter((item) => item.protectedActive).length,
  activeRunRisk: remainingAfterSelection > maxRunners,
  remainingRunnerJobCountAfterSelection: remainingAfterSelection,
  runnerJobs: runnerJobs.sort(sortOldestLastActive),
  candidates: inactiveCandidates,
  selected,
  selectedRunnerJobs: selected.map((item) => item.name),
  selectedRunnerJobCount: selected.length,
  valuesPrinted: false,
}));
`;
}

function cleanupRunnersFinalizeNodeScript(): string {
  return String.raw`
const fs = require("node:fs");
const path = require("node:path");
const tmp = process.env.TMP_DIR;
const deleteExit = Number(process.env.DELETE_EXIT || 0);
const plan = JSON.parse(fs.readFileSync(path.join(tmp, "plan.json"), "utf8"));
const jobsAfter = JSON.parse(fs.readFileSync(path.join(tmp, "jobs-after.json"), "utf8"));
const podsAfter = JSON.parse(fs.readFileSync(path.join(tmp, "pods-after.json"), "utf8"));
const matchLabels = plan.criteria?.selectors?.matchLabels || {};
const jobNamePrefixes = plan.criteria?.selectors?.jobNamePrefixes || [];

function labelsOf(item) {
  return item?.metadata?.labels && typeof item.metadata.labels === "object" ? item.metadata.labels : {};
}

function matchesLabels(labels) {
  return Object.entries(matchLabels).every(([key, value]) => labels?.[key] === value);
}

function matchesPrefix(name) {
  return jobNamePrefixes.length === 0 || jobNamePrefixes.some((prefix) => name === prefix || name.startsWith(prefix + "-"));
}

function isTerminalPod(pod) {
  const phase = pod?.status?.phase || "";
  return phase === "Succeeded" || phase === "Failed";
}

function jobNameForPod(pod) {
  const labels = labelsOf(pod);
  if (typeof labels["job-name"] === "string") return labels["job-name"];
  const owner = (Array.isArray(pod?.metadata?.ownerReferences) ? pod.metadata.ownerReferences : []).find((entry) => entry?.kind === "Job" && typeof entry?.name === "string");
  return owner?.name || null;
}

function tail(name) {
  try {
    const text = fs.readFileSync(path.join(tmp, name), "utf8");
    return text.length > 3000 ? text.slice(-3000) : text;
  } catch {
    return "";
  }
}

const selected = new Set(Array.isArray(plan.selectedRunnerJobs) ? plan.selectedRunnerJobs : []);
const remainingJobs = (Array.isArray(jobsAfter.items) ? jobsAfter.items : [])
  .map((job) => ({ name: job?.metadata?.name || "", labels: labelsOf(job) }))
  .filter((item) => item.name && matchesLabels(item.labels) && matchesPrefix(item.name));
const remainingJobNames = new Set(remainingJobs.map((item) => item.name));
const matchedPods = (Array.isArray(podsAfter.items) ? podsAfter.items : []).filter((pod) => {
  const jobName = jobNameForPod(pod);
  return jobName !== null && remainingJobNames.has(jobName);
});
const remainingSelectedRunnerJobs = Array.from(selected).filter((name) => remainingJobNames.has(name));
const deletedRunnerJobs = Array.from(selected).filter((name) => !remainingJobNames.has(name));
console.log(JSON.stringify({
  ...plan,
  ok: deleteExit === 0,
  deletion: { exitCode: deleteExit, stdoutTail: tail("delete.out"), stderrTail: tail("delete.err") },
  deletedRunnerJobs,
  deletedRunnerJobCount: deletedRunnerJobs.length,
  remainingSelectedRunnerJobs,
  remainingSelectedRunnerJobCount: remainingSelectedRunnerJobs.length,
  after: {
    runnerJobCount: remainingJobs.length,
    nonTerminalRunnerPodCount: matchedPods.filter((pod) => !isTerminalPod(pod)).length,
    overLimitCount: Math.max(0, remainingJobs.length - Number(plan.criteria?.maxRunners || 0)),
  },
  valuesPrinted: false,
}));
`;
}

function cleanupRunsPlanNodeScript(): string {
  return String.raw`
const fs = require("node:fs");
const path = require("node:path");
const cp = require("node:child_process");
const tmp = process.env.TMP_DIR;
const namespace = process.env.NAMESPACE;
const pipelineRunPrefix = process.env.PIPELINE_RUN_PREFIX || "";
const minAgeMinutes = Number(process.env.MIN_AGE_MINUTES || 60);
const limit = Number(process.env.LIMIT || 20);
const now = Date.now();

function readJson(name) {
  return JSON.parse(fs.readFileSync(path.join(tmp, name), "utf8"));
}

function conditionOf(item) {
  const conditions = Array.isArray(item?.status?.conditions) ? item.status.conditions : [];
  return conditions.find((entry) => entry.type === "Succeeded") || conditions[0] || {};
}

function ageMinutes(createdAt) {
  const createdMs = Date.parse(createdAt || "");
  return Number.isFinite(createdMs) ? Math.floor((now - createdMs) / 60000) : null;
}

function localPathOf(pv) {
  return pv?.spec?.local?.path || pv?.spec?.hostPath?.path || null;
}

function duBytes(hostPath) {
  if (typeof hostPath !== "string" || !hostPath.startsWith("/var/lib/rancher/k3s/storage/")) return null;
  try {
    const out = cp.execFileSync("du", ["-sB1", hostPath], { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] });
    const bytes = Number(String(out).trim().split(/\s+/)[0]);
    return Number.isFinite(bytes) ? bytes : null;
  } catch {
    return null;
  }
}

function formatBytes(bytes) {
  if (!Number.isFinite(bytes)) return null;
  const units = ["B", "KiB", "MiB", "GiB", "TiB"];
  let value = bytes;
  let unit = 0;
  while (value >= 1024 && unit < units.length - 1) {
    value /= 1024;
    unit += 1;
  }
  return value.toFixed(unit === 0 ? 0 : 1) + units[unit];
}

const pipelineRuns = readJson("pipelineruns.json");
const pvcs = readJson("pvcs.json");
const pvs = readJson("pvs.json");
const pods = readJson("pods.json");
const pvByName = new Map((Array.isArray(pvs.items) ? pvs.items : []).map((item) => [item?.metadata?.name, item]));
const activeClaimPods = new Map();
for (const pod of Array.isArray(pods.items) ? pods.items : []) {
  const phase = pod?.status?.phase || "";
  if (phase === "Succeeded" || phase === "Failed") continue;
  for (const volume of Array.isArray(pod?.spec?.volumes) ? pod.spec.volumes : []) {
    const claimName = volume?.persistentVolumeClaim?.claimName;
    if (!claimName) continue;
    const entry = activeClaimPods.get(claimName) || [];
    entry.push(pod?.metadata?.name || null);
    activeClaimPods.set(claimName, entry.filter(Boolean));
  }
}

const pvcsByOwner = new Map();
for (const pvc of Array.isArray(pvcs.items) ? pvcs.items : []) {
  const owner = (Array.isArray(pvc?.metadata?.ownerReferences) ? pvc.metadata.ownerReferences : []).find((entry) => entry.kind === "PipelineRun");
  if (!owner?.name) continue;
  const entry = pvcsByOwner.get(owner.name) || [];
  entry.push(pvc);
  pvcsByOwner.set(owner.name, entry);
}

const allPipelineRuns = (Array.isArray(pipelineRuns.items) ? pipelineRuns.items : [])
  .map((item) => {
    const condition = conditionOf(item);
    return {
      name: item?.metadata?.name || "",
      createdAt: item?.metadata?.creationTimestamp || null,
      ageMinutes: ageMinutes(item?.metadata?.creationTimestamp),
      status: condition.status || null,
      reason: condition.reason || null,
    };
  })
  .filter((item) => pipelineRunPrefix.length === 0 || item.name.startsWith(pipelineRunPrefix + "-"));

const protectedActivePipelineRuns = allPipelineRuns
  .filter((item) => item.status !== "True" && item.status !== "False")
  .sort((a, b) => String(a.createdAt).localeCompare(String(b.createdAt)));
const protectedLatestPipelineRun = allPipelineRuns
  .filter((item) => item.status === "True" || item.status === "False")
  .sort((a, b) => String(b.createdAt).localeCompare(String(a.createdAt)))[0]?.name || null;

const candidates = allPipelineRuns
  .filter((item) => item.status === "True" || item.status === "False")
  .filter((item) => typeof item.ageMinutes === "number" && item.ageMinutes >= minAgeMinutes)
  .sort((a, b) => String(a.createdAt).localeCompare(String(b.createdAt)))
  .slice(0, limit)
  .map((item) => {
    const owned = pvcsByOwner.get(item.name) || [];
    const activeMountPods = owned.flatMap((pvc) => activeClaimPods.get(pvc?.metadata?.name) || []);
    const protectedLatest = item.name === protectedLatestPipelineRun;
    return {
      ...item,
      selected: activeMountPods.length === 0 && !protectedLatest,
      selectedReason: protectedLatest ? "protected-latest-pipelinerun" : activeMountPods.length === 0 ? "terminal-and-unmounted" : "owned-pvc-active-mounted",
      ownedPvcCount: owned.length,
      activeMountPods,
    };
  });

const selectedPipelineRuns = candidates.filter((item) => item.selected).map((item) => item.name);
const selectedSet = new Set(selectedPipelineRuns);
const ownedPvcs = [];
const protectedOwnedPvcs = [];
for (const [owner, items] of pvcsByOwner.entries()) {
  if (!selectedSet.has(owner) && !candidates.some((item) => item.name === owner)) continue;
  for (const pvc of items) {
    const volume = pvc?.spec?.volumeName || null;
    const pv = volume ? pvByName.get(volume) : null;
    const hostPath = localPathOf(pv);
    const activeMountPods = activeClaimPods.get(pvc?.metadata?.name) || [];
    const entry = {
      name: pvc?.metadata?.name || null,
      volume,
      phase: pvc?.status?.phase || null,
      ownerKind: "PipelineRun",
      owner,
      storageClass: pv?.spec?.storageClassName || null,
      reclaimPolicy: pv?.spec?.persistentVolumeReclaimPolicy || null,
      hostPath,
      estimatedBytes: duBytes(hostPath),
      activeMountPods,
    };
    if (selectedSet.has(owner)) ownedPvcs.push(entry);
    else protectedOwnedPvcs.push(entry);
  }
}

const estimatedReclaimBytes = ownedPvcs.reduce((sum, item) => sum + (Number.isFinite(item.estimatedBytes) ? item.estimatedBytes : 0), 0);
console.log(JSON.stringify({
  ok: true,
  planKind: "agentrun-ci-completed-pipelinerun-workspace-retention",
  generatedAt: new Date().toISOString(),
  namespace,
  criteria: { prefix: pipelineRunPrefix + "-", terminalStatuses: ["True", "False"], minAgeMinutes, limit },
  candidates,
  candidateCount: candidates.length,
  protectedActivePipelineRuns,
  protectedActivePipelineRunCount: protectedActivePipelineRuns.length,
  protectedLatestPipelineRun,
  selectedPipelineRuns,
  selectedPipelineRunCount: selectedPipelineRuns.length,
  ownedPvcs,
  ownedPvcCount: ownedPvcs.length,
  protectedOwnedPvcs,
  protectedOwnedPvcCount: protectedOwnedPvcs.length,
  estimatedReclaimBytes,
  estimatedReclaimHuman: formatBytes(estimatedReclaimBytes),
}));
`;
}

function cleanupRunsFinalizeNodeScript(): string {
  return String.raw`
const fs = require("node:fs");
const path = require("node:path");
const tmp = process.env.TMP_DIR;
const deleteExit = Number(process.env.DELETE_EXIT || 0);
const plan = JSON.parse(fs.readFileSync(path.join(tmp, "plan.json"), "utf8"));
const pvcsAfter = JSON.parse(fs.readFileSync(path.join(tmp, "pvcs-after.json"), "utf8"));
const selected = new Set(Array.isArray(plan.selectedPipelineRuns) ? plan.selectedPipelineRuns : []);
const remainingOwnedPvcs = (Array.isArray(pvcsAfter.items) ? pvcsAfter.items : [])
  .map((pvc) => {
    const owner = (Array.isArray(pvc?.metadata?.ownerReferences) ? pvc.metadata.ownerReferences : []).find((entry) => entry.kind === "PipelineRun");
    return {
      name: pvc?.metadata?.name || null,
      volume: pvc?.spec?.volumeName || null,
      phase: pvc?.status?.phase || null,
      ownerKind: owner?.kind || null,
      owner: owner?.name || null,
    };
  })
  .filter((item) => item.owner && selected.has(item.owner));

function tail(name) {
  try {
    const text = fs.readFileSync(path.join(tmp, name), "utf8");
    return text.length > 3000 ? text.slice(-3000) : text;
  } catch {
    return "";
  }
}

console.log(JSON.stringify({
  ...plan,
  ok: deleteExit === 0,
  deletedPipelineRuns: Array.from(selected),
  deletedPipelineRunCount: selected.size,
  deletion: { exitCode: deleteExit, stdoutTail: tail("delete.out"), stderrTail: tail("delete.err") },
  remainingOwnedPvcs,
  remainingOwnedPvcCount: remainingOwnedPvcs.length,
}));
`;
}

function cleanupReleasedPvsPlanNodeScript(): string {
  return String.raw`
const fs = require("node:fs");
const path = require("node:path");
const cp = require("node:child_process");
const tmp = process.env.TMP_DIR;
const namespace = process.env.NAMESPACE;
const limit = Number(process.env.LIMIT || 20);

function readJson(name) {
  return JSON.parse(fs.readFileSync(path.join(tmp, name), "utf8"));
}

function localPathOf(pv) {
  return pv?.spec?.local?.path || pv?.spec?.hostPath?.path || null;
}

function duBytes(hostPath) {
  if (typeof hostPath !== "string" || !hostPath.startsWith("/var/lib/rancher/k3s/storage/")) return null;
  try {
    const out = cp.execFileSync("du", ["-sB1", hostPath], { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] });
    const bytes = Number(String(out).trim().split(/\s+/)[0]);
    return Number.isFinite(bytes) ? bytes : null;
  } catch {
    return null;
  }
}

function formatBytes(bytes) {
  if (!Number.isFinite(bytes)) return null;
  const units = ["B", "KiB", "MiB", "GiB", "TiB"];
  let value = bytes;
  let unit = 0;
  while (value >= 1024 && unit < units.length - 1) {
    value /= 1024;
    unit += 1;
  }
  return value.toFixed(unit === 0 ? 0 : 1) + units[unit];
}

const pvs = readJson("pvs.json");
const candidates = (Array.isArray(pvs.items) ? pvs.items : [])
  .map((pv) => {
    const hostPath = localPathOf(pv);
    return {
      name: pv?.metadata?.name || "",
      createdAt: pv?.metadata?.creationTimestamp || null,
      phase: pv?.status?.phase || null,
      storageClass: pv?.spec?.storageClassName || null,
      reclaimPolicy: pv?.spec?.persistentVolumeReclaimPolicy || null,
      claimNamespace: pv?.spec?.claimRef?.namespace || null,
      claimName: pv?.spec?.claimRef?.name || null,
      capacity: pv?.spec?.capacity?.storage || null,
      hostPath,
      estimatedBytes: duBytes(hostPath),
    };
  })
  .filter((item) => item.phase === "Released")
  .filter((item) => item.storageClass === "local-path" && item.reclaimPolicy === "Delete")
  .filter((item) => item.claimNamespace === namespace)
  .sort((a, b) => String(a.createdAt).localeCompare(String(b.createdAt)))
  .slice(0, limit);

const selectedPersistentVolumes = candidates.map((item) => item.name);
const estimatedReclaimBytes = candidates.reduce((sum, item) => sum + (Number.isFinite(item.estimatedBytes) ? item.estimatedBytes : 0), 0);
console.log(JSON.stringify({
  ok: true,
  planKind: "agentrun-ci-released-local-path-pv-retention",
  generatedAt: new Date().toISOString(),
  namespace,
  criteria: { phase: "Released", storageClass: "local-path", reclaimPolicy: "Delete", claimNamespace: namespace, limit },
  candidates,
  candidateCount: candidates.length,
  selectedPersistentVolumes,
  selectedPersistentVolumeCount: selectedPersistentVolumes.length,
  estimatedReclaimBytes,
  estimatedReclaimHuman: formatBytes(estimatedReclaimBytes),
}));
`;
}

function cleanupReleasedPvsFinalizeNodeScript(): string {
  return String.raw`
const fs = require("node:fs");
const path = require("node:path");
const tmp = process.env.TMP_DIR;
const deleteExit = Number(process.env.DELETE_EXIT || 0);
const plan = JSON.parse(fs.readFileSync(path.join(tmp, "plan.json"), "utf8"));
const pvsAfter = JSON.parse(fs.readFileSync(path.join(tmp, "pvs-after.json"), "utf8"));
const selected = new Set(Array.isArray(plan.selectedPersistentVolumes) ? plan.selectedPersistentVolumes : []);
const remainingPersistentVolumes = (Array.isArray(pvsAfter.items) ? pvsAfter.items : [])
  .filter((pv) => selected.has(pv?.metadata?.name))
  .map((pv) => ({ name: pv?.metadata?.name || null, phase: pv?.status?.phase || null, claimNamespace: pv?.spec?.claimRef?.namespace || null, claimName: pv?.spec?.claimRef?.name || null }));

function tail(name) {
  try {
    const text = fs.readFileSync(path.join(tmp, name), "utf8");
    return text.length > 3000 ? text.slice(-3000) : text;
  } catch {
    return "";
  }
}

console.log(JSON.stringify({
  ...plan,
  ok: deleteExit === 0,
  deletedPersistentVolumes: Array.from(selected),
  deletedPersistentVolumeCount: selected.size,
  deletion: { exitCode: deleteExit, stdoutTail: tail("delete.out"), stderrTail: tail("delete.err") },
  remainingPersistentVolumes,
  remainingPersistentVolumeCount: remainingPersistentVolumes.length,
}));
`;
}

function refreshYamlLaneScript(spec: AgentRunLaneSpec): string {
  return [
    "set -eu",
    `namespace=${shQuote(spec.gitops.argoNamespace)}`,
    `application=${shQuote(spec.gitops.argoApplication)}`,
    "kubectl -n \"$namespace\" annotate application \"$application\" argocd.argoproj.io/refresh=hard --overwrite >/tmp/agentrun-refresh-output.txt",
    "kubectl -n \"$namespace\" get application \"$application\" -o json >/tmp/agentrun-refresh-app.json",
    "NAMESPACE=\"$namespace\" APPLICATION=\"$application\" node <<'NODE'",
    "const fs = require('node:fs');",
    "let app = {};",
    "try { app = JSON.parse(fs.readFileSync('/tmp/agentrun-refresh-app.json', 'utf8')); } catch {}",
    "console.log(JSON.stringify({",
    "  ok: true,",
    "  namespace: process.env.NAMESPACE,",
    "  application: process.env.APPLICATION,",
    "  revision: app.status?.sync?.revision ?? null,",
    "  syncStatus: app.status?.sync?.status ?? null,",
    "  healthStatus: app.status?.health?.status ?? null,",
    "  observedAt: new Date().toISOString(),",
    "  valuesPrinted: false",
    "}));",
    "NODE",
  ].join("\n");
}

async function gitMirrorStatus(config: UniDeskConfig, options: GitMirrorStatusOptions = { full: false, raw: false, node: null, lane: null }): Promise<Record<string, unknown>> {
  const target = resolveAgentRunLaneTarget(options);
  const spec = target.spec;
  const observation = await readGitMirrorStatus(config, target);
  const summary = observation.summary;
  return {
    ok: observation.ok,
    command: "agentrun git-mirror status",
    mode: "yaml-declared-node-lane",
    configPath: target.configPath,
    target: agentRunLaneSummary(spec),
    namespace: spec.gitMirror.namespace,
    readUrl: spec.gitMirror.readUrl,
    writeUrl: spec.gitMirror.writeUrl,
    summary,
    ...(options.raw ? { raw: observation.raw } : {}),
    probe: compactCapture(observation.result, { full: options.full || options.raw, stdoutTailChars: 6000, stderrTailChars: 3000 }),
    disclosure: {
      defaultView: "compact-low-noise",
      full: options.full,
      raw: options.raw,
      rawOmitted: !options.raw,
      probeTailOmitted: !(options.full || options.raw),
      expandWith: `bun scripts/cli.ts agentrun git-mirror status --node ${spec.nodeId} --lane ${spec.lane} --full`,
      rawWith: `bun scripts/cli.ts agentrun git-mirror status --node ${spec.nodeId} --lane ${spec.lane} --raw`,
    },
    next: {
      sync: `bun scripts/cli.ts agentrun git-mirror sync --node ${spec.nodeId} --lane ${spec.lane} --confirm`,
      flush: summary.pendingFlush === true ? `bun scripts/cli.ts agentrun git-mirror flush --node ${spec.nodeId} --lane ${spec.lane} --confirm` : null,
    },
  };
}

async function readGitMirrorStatus(config: UniDeskConfig, target: { configPath: string; spec: AgentRunLaneSpec }): Promise<Record<string, unknown> & { result: SshCaptureResult; raw: string; summary: Record<string, unknown> }> {
  const spec = target.spec;
  const result = await capture(config, spec.nodeKubeRoute, ["sh", "--", yamlLaneGitMirrorStatusScript(spec)]);
  const raw = result.stdout;
  const summary = captureJsonPayload(result);
  return {
    ok: result.exitCode === 0 && summary.ok !== false,
    configPath: target.configPath,
    target: agentRunLaneSummary(spec),
    namespace: spec.gitMirror.namespace,
    readUrl: spec.gitMirror.readUrl,
    writeUrl: spec.gitMirror.writeUrl,
    raw,
    summary,
    result,
  };
}

async function runGitMirrorJob(config: UniDeskConfig, action: "sync" | "flush", options: GitMirrorOptions): Promise<Record<string, unknown>> {
  const { configPath, spec } = resolveAgentRunLaneTarget(options);
  const previewJobName = `${action === "sync" ? spec.gitMirror.syncJobPrefix : spec.gitMirror.flushJobPrefix}-${Date.now().toString(36)}`.slice(0, 63);
  const previewManifest = yamlLaneGitMirrorJobManifest(spec, action, previewJobName);
  const command = `agentrun git-mirror ${action}`;
  if (options.dryRun || !options.confirm) {
    return {
      ok: true,
      command,
      mode: "yaml-declared-node-lane",
      configPath,
      target: agentRunLaneSummary(spec),
      dryRun: true,
      namespace: spec.gitMirror.namespace,
      jobName: previewJobName,
      manifest: previewManifest,
      next: { confirm: `bun scripts/cli.ts ${command} --node ${spec.nodeId} --lane ${spec.lane} --confirm` },
    };
  }
  if (!options.wait) {
    const jobName = previewJobName;
    const manifest = yamlLaneGitMirrorJobManifest(spec, action, jobName);
    const created = await capture(config, spec.nodeKubeRoute, ["sh", "--", createYamlLaneJobScript(spec.gitMirror.namespace, jobName, manifest)]);
    const status = await gitMirrorStatus(config, { full: false, raw: false, node: spec.nodeId, lane: spec.lane });
    return {
      ok: created.exitCode === 0,
      command,
      mode: created.exitCode === 0 ? "submitted" : "create-failed",
      configPath,
      target: agentRunLaneSummary(spec),
      dryRun: false,
      namespace: spec.gitMirror.namespace,
      jobName,
      result: compactCapture(created),
      status,
      next: {
        status: `bun scripts/cli.ts agentrun git-mirror status --node ${spec.nodeId} --lane ${spec.lane}`,
        wait: `bun scripts/cli.ts agentrun git-mirror ${action} --node ${spec.nodeId} --lane ${spec.lane} --confirm --wait`,
      },
    };
  }
  const attempts: Record<string, unknown>[] = [];
  let lastCreated: SshCaptureResult | null = null;
  let lastWait: Record<string, unknown> | null = null;
  for (let attempt = 1; attempt <= AGENTRUN_GIT_MIRROR_RETRY_MAX_ATTEMPTS; attempt += 1) {
    const jobName = `${action === "sync" ? spec.gitMirror.syncJobPrefix : spec.gitMirror.flushJobPrefix}-${Date.now().toString(36)}-${attempt}`.slice(0, 63);
    const manifest = yamlLaneGitMirrorJobManifest(spec, action, jobName);
    const created = await capture(config, spec.nodeKubeRoute, ["sh", "--", createYamlLaneJobScript(spec.gitMirror.namespace, jobName, manifest)]);
    lastCreated = created;
    if (created.exitCode !== 0) {
      const result = { phase: "create-job", capture: compactCapture(created, { full: true, stdoutTailChars: 4000, stderrTailChars: 4000 }) };
      const retryableFailure = agentRunGitMirrorRetryableFailure(spec, action, attempt, result);
      attempts.push({ attempt, retryLabel: `${attempt}/${AGENTRUN_GIT_MIRROR_RETRY_MAX_ATTEMPTS}`, jobName, ok: false, phase: "create-job", retryableFailure, retryExhausted: retryableFailure !== null && record(retryableFailure).retryExhausted === true });
      if (retryableFailure !== null && record(retryableFailure).retryExhausted !== true) {
        progressEvent(`agentrun.git-mirror.${action}.retry`, retryableFailure);
        await sleep(agentRunGitMirrorRetryDelayMs(attempt));
        continue;
      }
      const status = await gitMirrorStatus(config, { full: false, raw: false, node: spec.nodeId, lane: spec.lane });
      return {
        ok: false,
        command,
        mode: "create-failed",
        configPath,
        target: agentRunLaneSummary(spec),
        dryRun: false,
        namespace: spec.gitMirror.namespace,
        jobName,
        result: compactCapture(created),
        retryableFailure,
        retry: agentRunGitMirrorRetrySummary(attempts),
        status,
        next: {
          status: `bun scripts/cli.ts agentrun git-mirror status --node ${spec.nodeId} --lane ${spec.lane}`,
          wait: `bun scripts/cli.ts agentrun git-mirror ${action} --node ${spec.nodeId} --lane ${spec.lane} --confirm --wait`,
        },
      };
    }
    const wait = await waitForGitMirrorJob(config, spec, action, jobName, options.timeoutSeconds);
    lastWait = wait;
    if (wait.ok === true) {
      attempts.push({ attempt, retryLabel: `${attempt}/${AGENTRUN_GIT_MIRROR_RETRY_MAX_ATTEMPTS}`, jobName, ok: true, wait });
      const status = await gitMirrorStatus(config, { full: false, raw: false, node: spec.nodeId, lane: spec.lane });
      return {
        ok: true,
        command,
        mode: "waited",
        configPath,
        target: agentRunLaneSummary(spec),
        dryRun: false,
        namespace: spec.gitMirror.namespace,
        jobName,
        result: compactCapture(created),
        wait,
        retry: agentRunGitMirrorRetrySummary(attempts),
        status,
        next: {
          status: `bun scripts/cli.ts agentrun git-mirror status --node ${spec.nodeId} --lane ${spec.lane}`,
          flush: action === "sync" && status.summary && record(status.summary).pendingFlush === true ? `bun scripts/cli.ts agentrun git-mirror flush --node ${spec.nodeId} --lane ${spec.lane} --confirm` : null,
        },
      };
    }
    const retryableFailure = agentRunGitMirrorRetryableFailure(spec, action, attempt, wait);
    attempts.push({ attempt, retryLabel: `${attempt}/${AGENTRUN_GIT_MIRROR_RETRY_MAX_ATTEMPTS}`, jobName, ok: false, wait, retryableFailure, retryExhausted: retryableFailure !== null && record(retryableFailure).retryExhausted === true });
    if (retryableFailure !== null && record(retryableFailure).retryExhausted !== true) {
      progressEvent(`agentrun.git-mirror.${action}.retry`, retryableFailure);
      await sleep(agentRunGitMirrorRetryDelayMs(attempt));
      continue;
    }
    const status = await gitMirrorStatus(config, { full: false, raw: false, node: spec.nodeId, lane: spec.lane });
    return {
      ok: false,
      command,
      mode: "waited",
      configPath,
      target: agentRunLaneSummary(spec),
      dryRun: false,
      namespace: spec.gitMirror.namespace,
      jobName,
      result: compactCapture(created),
      wait,
      retryableFailure,
      retry: agentRunGitMirrorRetrySummary(attempts),
      status,
      next: {
        status: `bun scripts/cli.ts agentrun git-mirror status --node ${spec.nodeId} --lane ${spec.lane}`,
        wait: `bun scripts/cli.ts agentrun git-mirror ${action} --node ${spec.nodeId} --lane ${spec.lane} --confirm --wait`,
      },
    };
  }
  const status = await gitMirrorStatus(config, { full: false, raw: false, node: spec.nodeId, lane: spec.lane });
  return {
    ok: false,
    command,
    mode: "retry-exhausted",
    configPath,
    target: agentRunLaneSummary(spec),
    dryRun: false,
    namespace: spec.gitMirror.namespace,
    result: lastCreated === null ? null : compactCapture(lastCreated),
    wait: lastWait,
    retry: agentRunGitMirrorRetrySummary(attempts),
    status,
    next: { status: `bun scripts/cli.ts agentrun git-mirror status --node ${spec.nodeId} --lane ${spec.lane}` },
  };
}

async function waitForGitMirrorJob(config: UniDeskConfig, spec: AgentRunLaneSpec, action: "sync" | "flush", jobName: string, timeoutSeconds: number): Promise<Record<string, unknown>> {
  const startedAtMs = Date.now();
  let lastProbe: SshCaptureResult | null = null;
  let polls = 0;
  while (Date.now() - startedAtMs <= timeoutSeconds * 1000) {
    polls += 1;
    lastProbe = await capture(config, spec.nodeKubeRoute, ["sh", "--", yamlLaneJobProbeScript(spec.gitMirror.namespace, jobName)]);
    const summary = captureJsonPayload(lastProbe);
    process.stderr.write(`${JSON.stringify({
      event: `agentrun.git-mirror.${action}.progress`,
      at: new Date().toISOString(),
      stage: "k8s-job",
      node: spec.nodeId,
      lane: spec.lane,
      status: summary.succeeded === true ? "succeeded" : summary.failed === true ? "failed" : "running",
      jobName,
      polls,
      elapsedMs: Date.now() - startedAtMs,
    })}\n`);
    if (summary.succeeded === true) {
      return {
        ok: true,
        action,
        jobName,
        polls,
        elapsedMs: Date.now() - startedAtMs,
        summary,
        probe: compactCapture(lastProbe),
      };
    }
    if (summary.failed === true) {
      return {
        ok: false,
        action,
        jobName,
        polls,
        elapsedMs: Date.now() - startedAtMs,
        degradedReason: "git-mirror-job-failed",
        summary,
        probe: compactCapture(lastProbe),
      };
    }
    await sleep(5_000);
  }
  return {
    ok: false,
    action,
    jobName,
    polls,
    elapsedMs: Date.now() - startedAtMs,
    degradedReason: "git-mirror-job-timeout",
    probe: lastProbe ? compactCapture(lastProbe) : null,
  };
}

function startAsyncAgentRunJob(name: string, command: string[], note: string): Record<string, unknown> {
  const job = startJob(name, command, note);
  const statusCommand = `bun scripts/cli.ts job status ${job.id} --tail-bytes 12000`;
  return {
    ok: true,
    mode: "async-job",
    job,
    statusCommand,
    tailCommand: `tail -f ${job.stdoutFile}`,
    next: {
      status: statusCommand,
      tail: `tail -f ${job.stdoutFile}`,
    },
  };
}

async function runAgentRunRestCompatCommand(config: UniDeskConfig | null, group: AgentRunRestCompatGroup, args: string[], canonicalArgs: string[]): Promise<Record<string, unknown>> {
  try {
    return await withAgentRunRestTarget(resolveAgentRunRestTarget(config, parseAgentRunRestTargetOptions(args)), async () => {
      return await runAgentRunRestCommand(config, group, stripAgentRunLaneTargetArgs(args));
    });
  } catch (error) {
    if (error instanceof AgentRunRestError) return error.toPayload(`agentrun ${canonicalArgs.join(" ")}`.trim());
    throw error;
  }
}

async function runAgentRunRestCommand(config: UniDeskConfig | null, group: AgentRunRestCompatGroup, args: string[]): Promise<Record<string, unknown>> {
  void config;
  const compatGroup = group === "aipods" ? "aipod-specs" : group;
  const [action, id] = args;
  if (compatGroup === "queue") return await runAgentRunQueueRest(action, id, args);
  if (compatGroup === "sessions") return await runAgentRunSessionsRest(action, id, args);
  if (compatGroup === "runs") return await runAgentRunRunsRest(action, id, args);
  if (compatGroup === "commands") return await runAgentRunCommandsRest(action, id, args);
  if (compatGroup === "runner") return await runAgentRunRunnerRest(action, id, args);
  if (compatGroup === "aipod-specs") return await runAgentRunAipodSpecsRest(action, id, args);
  throw new AgentRunRestError("unsupported-version", `unsupported AgentRun REST compatibility group: ${group}`);
}

function parseAgentRunRestTargetOptions(args: string[]): AgentRunRestTargetOptions {
  return {
    node: agentRunOption(args, "node"),
    lane: agentRunOption(args, "lane"),
  };
}

function stripAgentRunLaneTargetArgs(args: string[]): string[] {
  const result: string[] = [];
  for (let index = 0; index < args.length; index += 1) {
    const arg = args[index] ?? "";
    if (arg === "--node" || arg === "--lane") {
      index += 1;
      continue;
    }
    if (arg.startsWith("--node=") || arg.startsWith("--lane=")) continue;
    result.push(arg);
  }
  return result;
}

async function runAgentRunQueueRest(action: string | undefined, id: string | undefined, args: string[]): Promise<Record<string, unknown>> {
  if (action === "list") return await agentRunRestRequest("agentrun queue list", "GET", `/api/v1/queue/tasks${agentRunQuery(args, ["queue", "state", "cursor", "limit", "updated-after"])}`);
  if (action === "commander") return await agentRunRestRequest("agentrun queue commander", "GET", `/api/v1/queue/commander${agentRunQuery(args, ["queue", "reader-id"])}`);
  if (action === "stats") return await agentRunRestRequest("agentrun queue stats", "GET", `/api/v1/queue/stats${agentRunQuery(args, ["queue"])}`);
  if (action === "show" && id) return await agentRunRestRequest("agentrun queue show", "GET", `/api/v1/queue/tasks/${encodeURIComponent(id)}`);
  if (action === "submit") return await submitQueueTaskRest(args);
  if (action === "dispatch" && id) return await mutateQueueTaskRest("queue-dispatch", id, "dispatch", queueDispatchBodyFromArgs(args), args);
  if (action === "read" && id) return await mutateQueueTaskRest("queue-read", id, "read", { readerId: agentRunOption(args, "reader-id") ?? "cli" }, args);
  if (action === "cancel" && id) return await mutateQueueTaskRest("queue-cancel", id, "cancel", cancelBodyFromArgs(args), args);
  if (action === "refresh" && id) return await mutateQueueTaskRest("queue-refresh", id, "refresh", {}, args);
  throw new AgentRunRestError("validation-failed", `unsupported queue command: ${[action, id].filter(Boolean).join(" ") || "(empty)"}`);
}

async function runAgentRunSessionsRest(action: string | undefined, id: string | undefined, args: string[]): Promise<Record<string, unknown>> {
  if (action === "ps") return await agentRunRestRequest("agentrun sessions ps", "GET", `/api/v1/sessions${agentRunQuery(args, ["state", "profile", "backend-profile", "reader-id", "cursor", "limit"])}`);
  if (action === "show" && id) return await agentRunRestRequest("agentrun sessions show", "GET", `/api/v1/sessions/${encodeURIComponent(id)}${agentRunQuery(args, ["reader-id"])}`);
  if ((action === "trace" || action === "output") && id) return await agentRunRestRequest(`agentrun sessions ${action}`, "GET", `/api/v1/sessions/${encodeURIComponent(id)}/${action}${agentRunQuery(args, ["after-seq", "limit", "run-id"])}`);
  if (action === "read" && id) {
    const body = { readerId: agentRunOption(args, "reader-id") ?? "cli" };
    if (agentRunHasFlag(args, "dry-run")) return agentRunDryRunPlan("session-read", `/api/v1/sessions/${encodeURIComponent(id)}/read`, body, `bun scripts/cli.ts agentrun sessions read ${id} --reader-id ${body.readerId}`);
    return await agentRunRestRequest("agentrun sessions read", "POST", `/api/v1/sessions/${encodeURIComponent(id)}/read`, body);
  }
  if (action === "cancel" && id) {
    const body = { action: "cancel", ...cancelBodyFromArgs(args) };
    if (agentRunHasFlag(args, "dry-run")) return agentRunDryRunPlan("session-cancel", `/api/v1/sessions/${encodeURIComponent(id)}/control`, body, `bun scripts/cli.ts agentrun sessions cancel ${id}`);
    return await agentRunRestRequest("agentrun sessions cancel", "POST", `/api/v1/sessions/${encodeURIComponent(id)}/control`, body);
  }
  if (action === "send" && id) return await sessionSendRest(id, args);
  throw new AgentRunRestError("validation-failed", `unsupported sessions command: ${[action, id].filter(Boolean).join(" ") || "(empty)"}`);
}

async function runAgentRunRunsRest(action: string | undefined, id: string | undefined, args: string[]): Promise<Record<string, unknown>> {
  if (action === "create") return await agentRunRestRequest("agentrun runs create", "POST", "/api/v1/runs", await requiredJsonBody(args, "runs create"));
  if (action === "show" && id) return await agentRunRestRequest("agentrun runs show", "GET", `/api/v1/runs/${encodeURIComponent(id)}`);
  if (action === "events" && id) return await agentRunRestRequest("agentrun runs events", "GET", `/api/v1/runs/${encodeURIComponent(id)}/events${agentRunQuery(args, ["after-seq", "limit"])}`);
  if (action === "result" && id) return await agentRunRestRequest("agentrun runs result", "GET", `/api/v1/runs/${encodeURIComponent(id)}/result${agentRunQuery(args, ["command-id", "command"])}`);
  if (action === "cancel" && id) return await agentRunRestRequest("agentrun runs cancel", "POST", `/api/v1/runs/${encodeURIComponent(id)}/cancel`, cancelBodyFromArgs(args));
  throw new AgentRunRestError("validation-failed", `unsupported runs command: ${[action, id].filter(Boolean).join(" ") || "(empty)"}`);
}

async function runAgentRunCommandsRest(action: string | undefined, id: string | undefined, args: string[]): Promise<Record<string, unknown>> {
  if (action === "create" && id) {
    const body = await optionalJsonBody(args);
    if (!body.type) body.type = agentRunOption(args, "type") ?? "turn";
    const idempotencyKey = agentRunOption(args, "idempotency-key");
    if (idempotencyKey) body.idempotencyKey = idempotencyKey;
    return await agentRunRestRequest("agentrun commands create", "POST", `/api/v1/runs/${encodeURIComponent(id)}/commands`, body);
  }
  if (action === "show" && id) {
    const runId = requiredAgentRunOption(args, ["run-id", "run"], "commands show requires --run-id");
    return await agentRunRestRequest("agentrun commands show", "GET", `/api/v1/runs/${encodeURIComponent(runId)}/commands/${encodeURIComponent(id)}`);
  }
  if (action === "result" && id) {
    const runId = requiredAgentRunOption(args, ["run-id", "run"], "commands result requires --run-id");
    return await agentRunRestRequest("agentrun commands result", "GET", `/api/v1/runs/${encodeURIComponent(runId)}/commands/${encodeURIComponent(id)}/result`);
  }
  if (action === "cancel" && id) return await agentRunRestRequest("agentrun commands cancel", "POST", `/api/v1/commands/${encodeURIComponent(id)}/cancel`, cancelBodyFromArgs(args));
  throw new AgentRunRestError("validation-failed", `unsupported commands command: ${[action, id].filter(Boolean).join(" ") || "(empty)"}`);
}

async function runAgentRunRunnerRest(action: string | undefined, id: string | undefined, args: string[]): Promise<Record<string, unknown>> {
  if (action === "jobs") {
    const runId = requiredAgentRunOption(args, ["run-id", "run"], "runner jobs requires --run-id");
    return await agentRunRestRequest("agentrun runner jobs", "GET", `/api/v1/runs/${encodeURIComponent(runId)}/runner-jobs${agentRunQuery(args, ["command-id", "command"])}`);
  }
  if (action === "job-status") {
    const runId = requiredAgentRunOption(args, ["run-id", "run"], "runner job-status requires --run-id");
    const runnerJobId = id ?? agentRunOption(args, "runner-job-id");
    if (!runnerJobId) return await agentRunRestRequest("agentrun runner job-status", "GET", `/api/v1/runs/${encodeURIComponent(runId)}/runner-jobs${agentRunQuery(args, ["command-id", "command"])}`);
    return await agentRunRestRequest("agentrun runner job-status", "GET", `/api/v1/runs/${encodeURIComponent(runId)}/runner-jobs/${encodeURIComponent(runnerJobId)}`);
  }
  if (action === "job") {
    const runId = requiredAgentRunOption(args, ["run-id", "run"], "runner job requires --run-id");
    const body = queueDispatchBodyFromArgs(args);
    const commandId = requiredAgentRunOption(args, ["command-id", "command"], "runner job requires --command-id");
    body.commandId = commandId;
    if (agentRunHasFlag(args, "dry-run")) return agentRunDryRunPlan("runner-job", `/api/v1/runs/${encodeURIComponent(runId)}/runner-jobs`, body, `bun scripts/cli.ts agentrun runner job --run-id ${runId} --command-id ${commandId}`);
    return await agentRunRestRequest("agentrun runner job", "POST", `/api/v1/runs/${encodeURIComponent(runId)}/runner-jobs`, body);
  }
  throw new AgentRunRestError("validation-failed", `unsupported runner command: ${[action, id].filter(Boolean).join(" ") || "(empty)"}`);
}

async function runAgentRunAipodSpecsRest(action: string | undefined, id: string | undefined, args: string[]): Promise<Record<string, unknown>> {
  if (action === "list") return await agentRunRestRequest("agentrun aipod-specs list", "GET", "/api/v1/aipod-specs");
  if (action === "show" && id) return await agentRunRestRequest("agentrun aipod-specs show", "GET", `/api/v1/aipod-specs/${encodeURIComponent(id)}`);
  if (action === "render" && id) return await agentRunRestRequest("agentrun aipod-specs render", "POST", `/api/v1/aipod-specs/${encodeURIComponent(id)}/render`, await aipodRenderInputFromArgs(args, 2));
  if (action === "apply" || action === "set") {
    const yaml = readYamlInputFromArgs(args);
    const pathValue = id ? `/api/v1/aipod-specs/${encodeURIComponent(id)}` : "/api/v1/aipod-specs";
    const method: AgentRunHttpMethod = id ? "PUT" : "POST";
    const body = { yaml };
    if (agentRunHasFlag(args, "dry-run")) return agentRunDryRunPlan("aipod-spec-apply", pathValue, { yamlBytes: Buffer.byteLength(yaml, "utf8") }, `bun scripts/cli.ts agentrun aipod-specs apply${id ? ` ${id}` : ""} --yaml-stdin`, method);
    return await agentRunRestRequest("agentrun aipod-specs apply", method, pathValue, body);
  }
  if ((action === "delete" || action === "rm") && id) return await agentRunRestRequest("agentrun aipod-specs delete", "DELETE", `/api/v1/aipod-specs/${encodeURIComponent(id)}`);
  throw new AgentRunRestError("validation-failed", `unsupported aipod-specs command: ${[action, id].filter(Boolean).join(" ") || "(empty)"}`);
}

async function submitQueueTaskRest(args: string[]): Promise<Record<string, unknown>> {
  const aipod = agentRunOption(args, "aipod") ?? agentRunOption(args, "aipod-spec");
  if (aipod) {
    const rendered = await agentRunRestRequest("agentrun aipod-specs render", "POST", `/api/v1/aipod-specs/${encodeURIComponent(aipod)}/render`, await aipodRenderInputFromArgs(args, 2));
    const body = record(record(innerData(rendered)).queueTask);
    if (Object.keys(body).length === 0) throw new AgentRunRestError("schema-mismatch", `aipod-spec ${aipod} render did not return queueTask`);
    if (agentRunHasFlag(args, "dry-run")) return agentRunDryRunPlan("queue-submit", "/api/v1/queue/tasks", body, queueSubmitConfirmCommand(args, aipod), "POST", { jsonInput: { source: "aipod-spec", aipod, valuesPrinted: false } });
    return await agentRunRestRequest("agentrun queue submit", "POST", "/api/v1/queue/tasks", body);
  }
  const body = await requiredJsonBody(args, "queue submit");
  const idempotencyKey = agentRunOption(args, "idempotency-key");
  if (idempotencyKey) body.idempotencyKey = idempotencyKey;
  if (agentRunHasFlag(args, "dry-run")) return agentRunDryRunPlan("queue-submit", "/api/v1/queue/tasks", body, queueSubmitConfirmCommand(args), "POST", { jsonInput: jsonInputDisclosureFromArgs(args) });
  return await agentRunRestRequest("agentrun queue submit", "POST", "/api/v1/queue/tasks", body);
}

async function mutateQueueTaskRest(action: string, taskId: string, suffix: string, body: Record<string, unknown>, args: string[]): Promise<Record<string, unknown>> {
  const pathValue = `/api/v1/queue/tasks/${encodeURIComponent(taskId)}/${suffix}`;
  if (agentRunHasFlag(args, "dry-run")) return agentRunDryRunPlan(action, pathValue, body, `bun scripts/cli.ts agentrun queue ${suffix} ${taskId}`);
  return await agentRunRestRequest(`agentrun queue ${suffix}`, "POST", pathValue, body);
}

async function sessionSendRest(sessionId: string, args: string[]): Promise<Record<string, unknown>> {
  const aipod = agentRunOption(args, "aipod") ?? agentRunOption(args, "aipod-spec");
  if (aipod) return await sessionSendWithAipodRest(sessionId, aipod, args);
  const input = await optionalJsonBody(args);
  const prompt = optionalPromptFromArgs(args, 2);
  const sendBody = await sessionSendBodyFromRunInput(sessionId, args, input, sessionSendPayloadFromInput(input, prompt));
  const response = await agentRunRestRequest("agentrun sessions send", "POST", `/api/v1/sessions/${encodeURIComponent(sessionId)}/send`, sendBody);
  return { ok: response.ok !== false, command: "agentrun sessions send", data: innerData(response), bridge: response.bridge };
}

function sessionSendPayloadFromInput(input: Record<string, unknown>, prompt: string | null): Record<string, unknown> {
  const payload = record(input.payload);
  if (Object.keys(payload).length > 0) return payload;
  const text = prompt ?? stringOrNull(input.prompt) ?? stringOrNull(input.message) ?? stringOrNull(input.text);
  if (text === null) throw new AgentRunRestError("validation-failed", "send requires payload or non-empty prompt/message/text; use --prompt-stdin, --prompt-file, --prompt, a trailing prompt, or JSON payload");
  return { prompt: text };
}

async function sessionSendBodyFromRunInput(sessionId: string, args: string[], input: Record<string, unknown>, payload: Record<string, unknown>): Promise<Record<string, unknown>> {
  const fullSendBody = isExplicitSessionSendBody(input);
  const runInput = fullSendBody ? record(input.run ?? input.runBase) : input;
  const runBody = await sessionRunBodyFromArgs(sessionId, args, runInput);
  const runnerDefaults = fullSendBody ? record(input.runnerJob) : {};
  const runnerJob = await sessionRunnerJobBody(args, runnerDefaults);
  const body: Record<string, unknown> = fullSendBody ? { ...input } : {};
  body.run = runBody;
  body.payload = record(input.payload);
  if (Object.keys(record(body.payload)).length === 0) body.payload = payload;
  body.createRunnerJob = agentRunHasFlag(args, "no-runner-job") ? false : input.createRunnerJob !== false;
  body.runnerJob = runnerJob;
  body.dryRun = agentRunHasFlag(args, "dry-run");
  const commandIdempotencyKey = agentRunOption(args, "command-idempotency-key") ?? agentRunOption(args, "idempotency-key");
  if (commandIdempotencyKey) body.commandIdempotencyKey = commandIdempotencyKey;
  return body;
}

function isExplicitSessionSendBody(input: Record<string, unknown>): boolean {
  return isRecord(input.run)
    || isRecord(input.runBase)
    || isRecord(input.payload)
    || isRecord(input.runnerJob)
    || input.createRunnerJob !== undefined
    || input.commandIdempotencyKey !== undefined;
}

async function sessionRunBodyFromArgs(sessionId: string, args: string[], input: Record<string, unknown>): Promise<Record<string, unknown>> {
  const existing = await fetchAgentRunSessionOrNull(sessionId, args);
  const sessionPolicy = readAgentRunClientConfig().client.sessionPolicy;
  const profile = agentRunOption(args, "profile")
    ?? agentRunOption(args, "backend-profile")
    ?? stringOrNull(input.backendProfile)
    ?? stringOrNull(existing?.backendProfile)
    ?? sessionPolicy.backendProfile;
  const body: Record<string, unknown> = { ...input };
  body.tenantId = agentRunOption(args, "tenant-id") ?? stringOrNull(body.tenantId) ?? stringOrNull(existing?.tenantId) ?? sessionPolicy.tenantId;
  body.projectId = agentRunOption(args, "project-id") ?? stringOrNull(body.projectId) ?? stringOrNull(existing?.projectId) ?? sessionPolicy.projectId;
  body.providerId = agentRunOption(args, "provider-id") ?? stringOrNull(body.providerId) ?? stringOrNull(existing?.providerId) ?? sessionPolicy.providerId;
  body.backendProfile = profile;
  body.workspaceRef = jsonObjectOption(args, "workspace-json") ?? record(body.workspaceRef);
  if (Object.keys(record(body.workspaceRef)).length === 0) body.workspaceRef = cloneJsonRecord(sessionPolicy.workspaceRef);
  body.executionPolicy = jsonObjectOption(args, "execution-policy-json") ?? record(body.executionPolicy);
  if (Object.keys(record(body.executionPolicy)).length === 0) body.executionPolicy = defaultAgentRunExecutionPolicy(profile, sessionPolicy);
  const inheritedSessionRef = existing === null ? {} : {
    conversationId: existing.conversationId,
    threadId: existing.threadId,
    metadata: existing.metadata,
  };
  const sessionRef = { ...inheritedSessionRef, ...record(body.sessionRef) };
  const metadata = { ...record(inheritedSessionRef.metadata), ...record(sessionRef.metadata) };
  const title = agentRunOption(args, "title");
  if (title) metadata.title = title;
  body.sessionRef = { ...sessionRef, sessionId, metadata };
  return body;
}

async function sessionSendWithAipodRest(sessionId: string, aipod: string, args: string[]): Promise<Record<string, unknown>> {
  const rendered = await agentRunRestRequest("agentrun aipod-specs render", "POST", `/api/v1/aipod-specs/${encodeURIComponent(aipod)}/render`, await aipodRenderInputFromArgs(args, 2, { sessionId }));
  const renderedData = record(innerData(rendered));
  const task = record(renderedData.queueTask);
  if (Object.keys(task).length === 0) throw new AgentRunRestError("schema-mismatch", `aipod-spec ${aipod} render did not return queueTask`);
  const sessionRef = record(task.sessionRef);
  const metadata = record(sessionRef.metadata);
  const title = agentRunOption(args, "title") ?? stringOrNull(task.title);
  if (title) metadata.title = title;
  const sessionPolicy = readAgentRunClientConfig().client.sessionPolicy;
  const backendProfile = stringOrNull(task.backendProfile) ?? sessionPolicy.backendProfile;
  const executionPolicy = record(task.executionPolicy);
  const runBody: Record<string, unknown> = {
    tenantId: stringOrNull(task.tenantId) ?? sessionPolicy.tenantId,
    projectId: stringOrNull(task.projectId) ?? sessionPolicy.projectId,
    providerId: stringOrNull(task.providerId) ?? sessionPolicy.providerId,
    backendProfile,
    workspaceRef: task.workspaceRef ?? cloneJsonRecord(sessionPolicy.workspaceRef),
    sessionRef: { ...sessionRef, sessionId, metadata },
    executionPolicy: Object.keys(executionPolicy).length === 0 ? defaultAgentRunExecutionPolicy(backendProfile, sessionPolicy) : executionPolicy,
    resourceBundleRef: task.resourceBundleRef,
    traceSink: { kind: "aipod-session", aipod, sessionId, valuesPrinted: false },
  };
  const runnerDefaults = record(record(renderedData.dispatchDefaults).runnerJob);
  const sendBody: Record<string, unknown> = {
    run: runBody,
    payload: task.payload,
    createRunnerJob: !agentRunHasFlag(args, "no-runner-job"),
    runnerJob: await sessionRunnerJobBody(args, runnerDefaults),
    dryRun: agentRunHasFlag(args, "dry-run"),
  };
  const commandIdempotencyKey = agentRunOption(args, "command-idempotency-key") ?? agentRunOption(args, "idempotency-key");
  if (commandIdempotencyKey) sendBody.commandIdempotencyKey = commandIdempotencyKey;
  const response = await agentRunRestRequest("agentrun sessions send", "POST", `/api/v1/sessions/${encodeURIComponent(sessionId)}/send`, sendBody);
  const data = record(innerData(response));
  return { ok: response.ok !== false, command: "agentrun sessions send", data: { ...data, aipod, profile: String(task.backendProfile ?? ""), valuesPrinted: false }, bridge: response.bridge };
}

async function fetchAgentRunSessionOrNull(sessionId: string, args: string[]): Promise<Record<string, unknown> | null> {
  try {
    return record(innerData(await agentRunRestRequest("agentrun sessions show", "GET", `/api/v1/sessions/${encodeURIComponent(sessionId)}${agentRunQuery(args, ["reader-id"])}`)));
  } catch (error) {
    if (error instanceof AgentRunRestError && error.httpStatus === 404) return null;
    throw error;
  }
}

async function sessionRunnerJobBody(args: string[], defaults: Record<string, unknown> = {}): Promise<Record<string, unknown>> {
  const runnerBody = { ...defaults, ...(await optionalRunnerJsonBody(args)) };
  copyAgentRunOptions(args, runnerBody, ["image", "namespace", "attempt-id", "runner-id", "source-commit", "service-account-name"]);
  const managerUrl = agentRunOption(args, "runner-manager-url");
  if (managerUrl !== null) runnerBody.managerUrl = managerUrl;
  const runnerIdempotencyKey = agentRunOption(args, "runner-idempotency-key");
  if (runnerIdempotencyKey !== null) runnerBody.idempotencyKey = runnerIdempotencyKey;
  return runnerBody;
}

async function agentRunRestRequest(command: string, method: AgentRunHttpMethod, pathValue: string, body?: unknown): Promise<Record<string, unknown>> {
  const clientConfig = readAgentRunClientConfig();
  if (activeAgentRunRestTarget !== null) return await agentRunLaneRestRequest(command, method, pathValue, body, clientConfig, activeAgentRunRestTarget);
  const auth = resolveAgentRunAuth(clientConfig);
  const bridgeBase = agentRunRestBridgeMetadata(clientConfig, auth, method, pathValue);
  const startedAt = Date.now();
  const controller = new AbortController();
  const timeout = setTimeout(() => controller.abort(), clientConfig.manager.timeoutMs);
  let response: Response;
  try {
    const headers: Record<string, string> = {
      [clientConfig.auth.header]: `${clientConfig.auth.scheme} ${auth.value}`,
    };
    const init: RequestInit = { method, headers, signal: controller.signal };
    if (body !== undefined) {
      headers["content-type"] = "application/json";
      init.body = JSON.stringify(body);
    }
    response = await fetch(new URL(pathValue, clientConfig.manager.baseUrl), init);
  } catch (error) {
    const timedOut = isAbortLikeError(error);
    throw new AgentRunRestError(timedOut ? "agentrun-timeout" : "agentrun-connect-failed", timedOut ? `AgentRun server request timed out for ${method} ${pathValue} after ${clientConfig.manager.timeoutMs}ms` : `AgentRun server connection failed for ${method} ${pathValue}: ${error instanceof Error ? error.message : String(error)}`, { bridge: { ...bridgeBase, elapsedMs: Date.now() - startedAt } });
  } finally {
    clearTimeout(timeout);
  }
  const text = await response.text();
  const bridge = { ...bridgeBase, httpStatus: response.status, elapsedMs: Date.now() - startedAt };
  if (text.trim().length === 0) throw new AgentRunRestError("schema-mismatch", `AgentRun server returned an empty response for ${method} ${pathValue}`, { bridge, httpStatus: response.status });
  let envelope: Record<string, unknown>;
  try {
    envelope = record(JSON.parse(text) as unknown);
  } catch {
    throw new AgentRunRestError("schema-mismatch", `AgentRun server returned non-JSON response for ${method} ${pathValue}`, { bridge, httpStatus: response.status });
  }
  if (response.status === 401 || response.status === 403) throw new AgentRunRestError("auth-failed", stringOrNull(envelope.message) ?? "AgentRun API key was rejected", { bridge, httpStatus: response.status, details: safeAgentRunEnvelope(envelope) });
  if (!response.ok) {
    const details = response.status === 404
      ? addAgentRunNotFoundLookupHint(safeAgentRunEnvelope(envelope), clientConfig, method, pathValue, null)
      : safeAgentRunEnvelope(envelope);
    throw new AgentRunRestError(response.status === 404 ? "not-found" : "validation-failed", stringOrNull(envelope.message) ?? `AgentRun request failed with HTTP ${response.status}`, { bridge, httpStatus: response.status, details });
  }
  if (envelope.ok !== true) {
    const failureKind = normalizeAgentRunFailureKind(stringOrNull(envelope.failureKind), response.status);
    throw new AgentRunRestError(failureKind, stringOrNull(envelope.message) ?? `AgentRun request failed for ${method} ${pathValue}`, { bridge, httpStatus: response.status, details: safeAgentRunEnvelope(envelope) });
  }
  return {
    ok: true,
    command,
    data: envelope.data ?? null,
    bridge,
  };
}

function isAbortLikeError(error: unknown): boolean {
  if (!(error instanceof Error)) return false;
  return error.name === "AbortError" || /abort|timed out|timeout/iu.test(error.message);
}

async function agentRunLaneRestRequest(command: string, method: AgentRunHttpMethod, pathValue: string, body: unknown, clientConfig: AgentRunClientConfig, target: AgentRunRestTarget): Promise<Record<string, unknown>> {
  const bridgeBase = agentRunLaneRestBridgeMetadata(clientConfig, target, method, pathValue);
  const startedAt = Date.now();
  const proxyBaseUrl = `http://127.0.0.1:${target.spec.runtime.managerPort}`;
  const request = {
    method,
    path: pathValue,
    body: body ?? null,
    baseUrl: proxyBaseUrl,
    serviceBaseUrl: target.spec.runtime.internalBaseUrl,
    timeoutMs: clientConfig.manager.timeoutMs,
    authEnv: clientConfig.auth.env,
    header: clientConfig.auth.header,
    scheme: clientConfig.auth.scheme,
    valuesPrinted: false,
  };
  const captureResult = await capture(target.config, target.spec.nodeKubeRoute, ["sh", "--", agentRunLaneRestProxyScript(target.spec, request)]);
  const captureSummary = compactCapture(captureResult, { full: false, stdoutTailChars: 1200, stderrTailChars: 2000 });
  const bridge = { ...bridgeBase, elapsedMs: Date.now() - startedAt, capture: captureSummary };
  if (captureResult.exitCode !== 0) {
    throw new AgentRunRestError("agentrun-proxy-exec-failed", `AgentRun lane ${target.spec.nodeId}/${target.spec.lane} manager proxy execution failed for ${method} ${pathValue}`, { bridge });
  }
  const proxy = captureJsonPayload(captureResult);
  if (proxy.ok !== true) {
    const proxyFailureKind = stringOrNull(proxy.failureKind);
    const failureKind = classifyAgentRunProxyFailureKind(proxyFailureKind);
    throw new AgentRunRestError(failureKind, stringOrNull(proxy.message) ?? `AgentRun lane ${target.spec.nodeId}/${target.spec.lane} manager proxy failed`, { bridge: { ...bridge, proxy }, details: pickCompact(proxy, ["ok", "failureKind", "message", "elapsedMs", "path", "baseUrl", "valuesPrinted"]) });
  }
  const httpStatus = nonNegativeIntegerOrNull(proxy.httpStatus) ?? 0;
  const text = stringOrNull(proxy.text) ?? "";
  const responseBridge = { ...bridge, httpStatus, proxyElapsedMs: nonNegativeIntegerOrNull(proxy.elapsedMs) };
  if (text.trim().length === 0) throw new AgentRunRestError("schema-mismatch", `AgentRun server returned an empty response for ${method} ${pathValue}`, { bridge: responseBridge, httpStatus });
  let envelope: Record<string, unknown>;
  try {
    envelope = record(JSON.parse(text) as unknown);
  } catch {
    throw new AgentRunRestError("schema-mismatch", `AgentRun server returned non-JSON response for ${method} ${pathValue}`, { bridge: responseBridge, httpStatus });
  }
  if (httpStatus === 401 || httpStatus === 403) throw new AgentRunRestError("auth-failed", stringOrNull(envelope.message) ?? "AgentRun API key was rejected", { bridge: responseBridge, httpStatus, details: safeAgentRunEnvelope(envelope) });
  if (httpStatus < 200 || httpStatus >= 300) {
    const details = httpStatus === 404
      ? addAgentRunNotFoundLookupHint(safeAgentRunEnvelope(envelope), clientConfig, method, pathValue, target)
      : safeAgentRunEnvelope(envelope);
    throw new AgentRunRestError(httpStatus === 404 ? "not-found" : "validation-failed", stringOrNull(envelope.message) ?? `AgentRun request failed with HTTP ${httpStatus}`, { bridge: responseBridge, httpStatus, details });
  }
  if (envelope.ok !== true) {
    const failureKind = normalizeAgentRunFailureKind(stringOrNull(envelope.failureKind), httpStatus);
    throw new AgentRunRestError(failureKind, stringOrNull(envelope.message) ?? `AgentRun request failed for ${method} ${pathValue}`, { bridge: responseBridge, httpStatus, details: safeAgentRunEnvelope(envelope) });
  }
  return {
    ok: true,
    command,
    data: envelope.data ?? null,
    bridge: responseBridge,
  };
}

function agentRunLaneRestProxyScript(spec: AgentRunLaneSpec, request: Record<string, unknown>): string {
  const requestB64 = Buffer.from(JSON.stringify(request), "utf8").toString("base64");
  const evalScript = String.raw`
const startedAt = Date.now();
let input = {};
let method = "GET";
let path = "/";
let baseUrl = "http://127.0.0.1:8080";
let timeoutMs = 15000;
try {
  input = JSON.parse(Buffer.from(process.env.AGENTRUN_LANE_REST_REQUEST_B64 || "", "base64").toString("utf8"));
  method = String(input.method || "GET");
  path = String(input.path || "/");
  baseUrl = String(input.baseUrl || "http://127.0.0.1:8080");
  timeoutMs = Number(input.timeoutMs || 15000);
  const headers = {};
  const authEnv = String(input.authEnv || "HWLAB_API_KEY");
  const apiKey = process.env[authEnv] || process.env.AGENTRUN_API_KEY || process.env.HWLAB_API_KEY || "";
  if (apiKey && input.header && input.scheme) headers[String(input.header)] = String(input.scheme) + " " + apiKey;
  let body = undefined;
  if (input.body !== null && input.body !== undefined) {
    headers["content-type"] = "application/json";
    body = JSON.stringify(input.body);
  }
  const controller = new AbortController();
  const timeout = setTimeout(() => controller.abort(), timeoutMs);
  let response;
  try {
    response = await fetch(new URL(path, baseUrl).toString(), {
      method,
      headers,
      body,
      signal: controller.signal,
    });
  } finally {
    clearTimeout(timeout);
  }
  const text = await response.text();
  console.log(JSON.stringify({ ok: true, httpStatus: response.status, statusText: response.statusText, text, elapsedMs: Date.now() - startedAt, valuesPrinted: false }));
} catch (error) {
  const name = error instanceof Error ? error.name : "";
  const message = error instanceof Error ? error.message : String(error);
  const timedOut = name === "AbortError" || /abort|timed out|timeout/iu.test(message);
  console.log(JSON.stringify({ ok: false, failureKind: timedOut ? "manager-pod-fetch-timeout" : "manager-pod-fetch-failed", message: timedOut ? "AgentRun manager request timed out for " + method + " " + path + " after " + timeoutMs + "ms" : message, elapsedMs: Date.now() - startedAt, path, baseUrl, valuesPrinted: false }));
}
`;
  return [
    "set -eu",
    `namespace=${shQuote(spec.runtime.namespace)}`,
    `deployment=${shQuote(spec.runtime.managerDeployment)}`,
    `request_b64=${shQuote(requestB64)}`,
    `kubectl -n "$namespace" exec deploy/"$deployment" -- env AGENTRUN_LANE_REST_REQUEST_B64="$request_b64" bun --eval ${shQuote(evalScript)}`,
  ].join("\n");
}

function resolveAgentRunRestTarget(config: UniDeskConfig | null, options: AgentRunRestTargetOptions): AgentRunRestTarget | null {
  if (options.node === null && options.lane === null) return null;
  if (config === null) throw new AgentRunRestError("validation-failed", "--node/--lane resource queries require UniDesk config");
  const { configPath, spec } = resolveAgentRunLaneTarget(options);
  return { config, configPath, spec };
}

async function withAgentRunRestTarget<T>(target: AgentRunRestTarget | null, action: () => Promise<T>): Promise<T> {
  const previous = activeAgentRunRestTarget;
  activeAgentRunRestTarget = target;
  try {
    return await action();
  } finally {
    activeAgentRunRestTarget = previous;
  }
}

function renderAgentRunRestError(command: string, error: AgentRunRestError, options: AgentRunResourceOptions): RenderedCliResult {
  const payload = error.toPayload(command);
  if (options.raw || options.output === "json" || options.output === "yaml") return renderMachine(command, payload, options.output === "yaml" ? "yaml" : "json", false);
  const laneHint = record(record(payload.agentrun).laneAwareLookup);
  const currentEndpoint = record(laneHint.currentEndpoint);
  const nextCommands = Array.isArray(laneHint.nextCommands)
    ? laneHint.nextCommands.filter((value): value is string => typeof value === "string" && value.length > 0).slice(0, 4)
    : [];
  const hintLines = Object.keys(laneHint).length === 0
    ? []
    : [
        "",
        "Lane lookup hint:",
        `  Current baseUrl: ${String(currentEndpoint.baseUrl ?? "(unknown)")}`,
        `  Config: ${String(currentEndpoint.configPath ?? "(unknown)")}`,
        `  ${String(laneHint.summary ?? "The resource was not found on the currently configured AgentRun manager endpoint.")}`,
      ];
  const nextLines = nextCommands.length > 0
    ? nextCommands
    : [
        "Check config/agentrun.yaml manager.baseUrl and the AgentRun API route.",
        "Verify HWLAB_API_KEY is present in env or in the configured auth.file without printing the key.",
      ];
  return renderedCliResult(false, command, [
    `Error: ${payload.failureKind}`,
    String(payload.message ?? ""),
    ...hintLines,
    "",
    "Next:",
    ...nextLines.map((line) => `  ${line}`),
  ].join("\n"));
}

class AgentRunRestError extends Error {
  readonly failureKind: AgentRunFailureKind;
  readonly bridge: Record<string, unknown> | null;
  readonly httpStatus: number | null;
  readonly details: Record<string, unknown> | null;

  constructor(failureKind: AgentRunFailureKind, message: string, options: { bridge?: Record<string, unknown>; httpStatus?: number; details?: Record<string, unknown> } = {}) {
    super(message);
    this.name = "AgentRunRestError";
    this.failureKind = failureKind;
    this.bridge = options.bridge ?? null;
    this.httpStatus = options.httpStatus ?? null;
    this.details = options.details ?? null;
  }

  toPayload(command: string): Record<string, unknown> {
    const transport = stringOrNull(this.bridge?.mode) ?? "direct-http";
    return {
      ok: false,
      command,
      failureKind: this.failureKind,
      message: this.message,
      transport,
      clientRole: "render-only",
      ...(this.httpStatus === null ? {} : { httpStatus: this.httpStatus }),
      ...(this.bridge === null ? {} : { bridge: this.bridge }),
      ...(this.details === null ? {} : { agentrun: this.details }),
      valuesPrinted: false,
    };
  }
}

function readAgentRunClientConfig(env: NodeJS.ProcessEnv = process.env): AgentRunClientConfig {
  const configPath = env.AGENTRUN_CLIENT_CONFIG ?? rootPath("config", "agentrun.yaml");
  if (!existsSync(configPath)) throw new AgentRunRestError("validation-failed", `AgentRun client config not found: ${configPath}`);
  try {
    const parsed = parseAgentRunClientConfigYaml(readFileSync(configPath, "utf8"), configPath);
    return { ...parsed, sourcePath: configPath };
  } catch (error) {
    if (error instanceof AgentRunRestError) throw error;
    throw new AgentRunRestError("validation-failed", `AgentRun client config invalid: ${error instanceof Error ? error.message : String(error)}`, {
      bridge: { mode: "direct-http", clientRole: "render-only", configPath },
    });
  }
}

export function parseAgentRunClientConfigYaml(raw: string, sourcePath = "config/agentrun.yaml"): AgentRunClientConfig {
  const input = record(Bun.YAML.parse(raw) as unknown);
  validateAgentRunConfigEnvelope(input, sourcePath);
  const manager = record(input.manager);
  const auth = record(input.auth);
  const client = record(input.client);
  const baseUrl = stringFieldFromRecord(manager, "baseUrl", "manager");
  try {
    const parsed = new URL(baseUrl);
    if (parsed.protocol !== "http:" && parsed.protocol !== "https:") throw new Error("invalid protocol");
  } catch {
    throw new Error(`${sourcePath}: manager.baseUrl must be an http(s) URL`);
  }
  const timeoutMs = numberFieldFromRecord(manager, "timeoutMs", "manager", { min: 1, max: 60_000 });
  const header = stringFieldFromRecord(auth, "header", "auth");
  const scheme = stringFieldFromRecord(auth, "scheme", "auth");
  if (header.toLowerCase() !== "authorization") throw new Error(`${sourcePath}: auth.header must be Authorization`);
  if (scheme !== "Bearer") throw new Error(`${sourcePath}: auth.scheme must be Bearer`);
  const role = stringFieldFromRecord(client, "role", "client");
  const transport = stringFieldFromRecord(client, "transport", "client");
  if (role !== "render-only") throw new Error(`${sourcePath}: client.role must be render-only`);
  if (transport !== "direct-http") throw new Error(`${sourcePath}: client.transport must be direct-http`);
  const sessionPolicy = readAgentRunSessionPolicyConfig(client, sourcePath);
  const publicExposure = readAgentRunPublicExposureConfig(input.publicExposure, baseUrl.replace(/\/+$/u, "/"), sourcePath);
  return {
    sourcePath,
    manager: {
      baseUrl: baseUrl.replace(/\/+$/u, "/"),
      timeoutMs,
    },
    auth: {
      env: stringFieldFromRecord(auth, "env", "auth"),
      file: stringFieldFromRecord(auth, "file", "auth"),
      header,
      scheme,
    },
    client: {
      role,
      transport,
      sessionPolicy,
    },
    publicExposure,
  };
}

function readAgentRunSessionPolicyConfig(client: Record<string, unknown>, sourcePath: string): AgentRunSessionPolicyConfig {
  const pathValue = "client.sessionPolicy";
  const sessionPolicy = record(client.sessionPolicy);
  const workspaceRef = record(sessionPolicy.workspaceRef);
  const executionPolicy = record(sessionPolicy.executionPolicy);
  const secretScope = record(executionPolicy.secretScope);
  stringFieldFromRecord(workspaceRef, "kind", `${pathValue}.workspaceRef`);
  stringFieldFromRecord(executionPolicy, "sandbox", `${pathValue}.executionPolicy`);
  stringFieldFromRecord(executionPolicy, "approval", `${pathValue}.executionPolicy`);
  positiveIntegerFieldFromRecord(executionPolicy, "timeoutMs", `${pathValue}.executionPolicy`);
  stringFieldFromRecord(executionPolicy, "network", `${pathValue}.executionPolicy`);
  booleanFieldFromRecord(secretScope, "allowCredentialEcho", `${pathValue}.executionPolicy.secretScope`);
  return {
    sourcePath,
    tenantId: stringFieldFromRecord(sessionPolicy, "tenantId", pathValue),
    projectId: stringFieldFromRecord(sessionPolicy, "projectId", pathValue),
    providerId: stringFieldFromRecord(sessionPolicy, "providerId", pathValue),
    backendProfile: stringFieldFromRecord(sessionPolicy, "backendProfile", pathValue),
    workspaceRef: cloneJsonRecord(workspaceRef),
    executionPolicy: cloneJsonRecord(executionPolicy),
  };
}

function validateAgentRunConfigEnvelope(input: Record<string, unknown>, sourcePath: string): void {
  if (input.version !== 1) throw new Error(`${sourcePath}: version must be 1`);
  if (input.kind !== "AgentRunConfig") throw new Error(`${sourcePath}: kind must be AgentRunConfig`);
  const metadata = record(input.metadata);
  if (stringFieldFromRecord(metadata, "name", "metadata") !== "agentrun") throw new Error(`${sourcePath}: metadata.name must be agentrun`);
}

function readAgentRunPublicExposureConfig(value: unknown, managerBaseUrl: string, sourcePath: string): AgentRunPublicExposure | null {
  if (value === undefined || value === null) return null;
  const exposure = record(value);
  if (exposure.enabled !== true) return null;
  const proxyName = stringFieldFromRecord(exposure, "proxyName", "publicExposure");
  if (!/^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$/u.test(proxyName)) throw new Error(`${sourcePath}: publicExposure.proxyName must be a DNS label`);
  const remotePort = numberFieldFromRecord(exposure, "remotePort", "publicExposure", { min: 1, max: 65_535 });
  const publicBaseUrl = normalizedHttpUrl(stringFieldFromRecord(exposure, "publicBaseUrl", "publicExposure"), `${sourcePath}: publicExposure.publicBaseUrl`);
  const masterBaseUrl = normalizedHttpUrl(stringFieldFromRecord(exposure, "masterBaseUrl", "publicExposure"), `${sourcePath}: publicExposure.masterBaseUrl`);
  if (!publicBaseUrl.startsWith("https://")) throw new Error(`${sourcePath}: publicExposure.publicBaseUrl must use https://`);
  if (publicBaseUrl !== managerBaseUrl) throw new Error(`${sourcePath}: manager.baseUrl must match publicExposure.publicBaseUrl`);
  if (!masterBaseUrl.startsWith(`http://127.0.0.1:${remotePort}`)) throw new Error(`${sourcePath}: publicExposure.masterBaseUrl must point to http://127.0.0.1:${remotePort}`);
  const masterFrps = record(exposure.masterFrps);
  const masterCaddy = record(exposure.masterCaddy);
  const caddyEnabled = masterCaddy.enabled === true;
  const domain = stringFieldFromRecord(masterCaddy, "domain", "publicExposure.masterCaddy");
  if (!/^[a-z0-9.-]+$/u.test(domain) || !domain.endsWith(".nip.io")) throw new Error(`${sourcePath}: publicExposure.masterCaddy.domain must be a nip.io hostname`);
  const caddyUpstreamBaseUrl = normalizedHttpUrl(stringFieldFromRecord(masterCaddy, "upstreamBaseUrl", "publicExposure.masterCaddy"), `${sourcePath}: publicExposure.masterCaddy.upstreamBaseUrl`);
  if (caddyUpstreamBaseUrl !== masterBaseUrl) throw new Error(`${sourcePath}: publicExposure.masterCaddy.upstreamBaseUrl must match publicExposure.masterBaseUrl`);
  return {
    enabled: true,
    proxyName,
    remotePort,
    publicBaseUrl,
    masterBaseUrl,
    masterFrps: {
      configPath: absolutePathField(masterFrps, "configPath", "publicExposure.masterFrps", sourcePath),
      containerName: stringFieldFromRecord(masterFrps, "containerName", "publicExposure.masterFrps"),
    },
    masterCaddy: {
      enabled: caddyEnabled,
      domain,
      configPath: absolutePathField(masterCaddy, "configPath", "publicExposure.masterCaddy", sourcePath),
      serviceName: stringFieldFromRecord(masterCaddy, "serviceName", "publicExposure.masterCaddy"),
      upstreamBaseUrl: caddyUpstreamBaseUrl,
      responseHeaderTimeoutSeconds: numberFieldFromRecord(masterCaddy, "responseHeaderTimeoutSeconds", "publicExposure.masterCaddy", { min: 1, max: 600 }),
    },
  };
}

function normalizedHttpUrl(value: string, label: string): string {
  let url: URL;
  try {
    url = new URL(value);
  } catch {
    throw new Error(`${label} must be an http(s) URL`);
  }
  if (url.protocol !== "http:" && url.protocol !== "https:") throw new Error(`${label} must be an http(s) URL`);
  return value.replace(/\/+$/u, "/");
}

function absolutePathField(obj: Record<string, unknown>, key: string, pathValue: string, sourcePath: string): string {
  const value = stringFieldFromRecord(obj, key, pathValue);
  if (!value.startsWith("/")) throw new Error(`${sourcePath}: ${pathValue}.${key} must be an absolute path`);
  return value;
}

export function resolveAgentRunAuth(config: AgentRunClientConfig, env: NodeJS.ProcessEnv = process.env): AgentRunResolvedAuth {
  const envValue = env[config.auth.env]?.trim();
  if (envValue) return { source: "env", value: envValue };
  if (existsSync(config.auth.file)) {
    const fromFile = readEnvValueFromFile(config.auth.file, config.auth.env);
    if (fromFile !== null) return { source: "file", value: fromFile };
  }
  throw new AgentRunRestError("auth-missing", `${config.auth.env} is required for direct AgentRun REST access`, {
    bridge: {
      mode: "direct-http",
      clientRole: "render-only",
      configPath: config.sourcePath,
      auth: { env: config.auth.env, file: config.auth.file, source: "missing", header: config.auth.header, scheme: config.auth.scheme, valuesPrinted: false },
    },
  });
}

function readEnvValueFromFile(pathValue: string, envName: string): string | null {
  const text = readFileSync(pathValue, "utf8");
  for (const line of text.split(/\r?\n/u)) {
    const trimmed = line.trim();
    if (trimmed.length === 0 || trimmed.startsWith("#")) continue;
    const normalized = trimmed.startsWith("export ") ? trimmed.slice("export ".length).trim() : trimmed;
    const index = normalized.indexOf("=");
    if (index <= 0) continue;
    if (normalized.slice(0, index).trim() !== envName) continue;
    const raw = normalized.slice(index + 1).trim();
    const value = raw.replace(/^['"]|['"]$/gu, "");
    return value.length > 0 ? value : null;
  }
  return null;
}

function agentRunRestBridgeMetadata(config: AgentRunClientConfig, auth: AgentRunResolvedAuth, method: AgentRunHttpMethod, pathValue: string): Record<string, unknown> {
  return {
    mode: "direct-http",
    clientRole: "render-only",
    compatibility: "no-hwlab-runtime-proxy-no-ssh-official-cli",
    configPath: config.sourcePath,
    baseUrl: config.manager.baseUrl,
    request: { method, path: pathValue, timeoutMs: config.manager.timeoutMs },
    auth: { env: config.auth.env, file: config.auth.file, source: auth.source, header: config.auth.header, scheme: config.auth.scheme, valuesPrinted: false },
  };
}

function agentRunLaneRestBridgeMetadata(config: AgentRunClientConfig, target: AgentRunRestTarget, method: AgentRunHttpMethod, pathValue: string): Record<string, unknown> {
  return {
    mode: "lane-k8s-service-proxy",
    clientRole: "render-only",
    configPath: config.sourcePath,
    laneConfigPath: target.configPath,
    node: target.spec.nodeId,
    lane: target.spec.lane,
    kubeRoute: target.spec.nodeKubeRoute,
    namespace: target.spec.runtime.namespace,
    managerDeployment: target.spec.runtime.managerDeployment,
    baseUrl: target.spec.runtime.internalBaseUrl,
    request: { method, path: pathValue, timeoutMs: config.manager.timeoutMs },
    auth: { source: "manager-pod-env", env: config.auth.env, fallbackEnv: "AGENTRUN_API_KEY", header: config.auth.header, scheme: config.auth.scheme, valuesPrinted: false },
    valuesPrinted: false,
  };
}

function addAgentRunNotFoundLookupHint(details: Record<string, unknown>, config: AgentRunClientConfig, method: AgentRunHttpMethod, pathValue: string, target: AgentRunRestTarget | null): Record<string, unknown> {
  const resource = agentRunResourceFromPath(pathValue);
  const laneConfig = readAgentRunLaneLookupConfig(config.sourcePath);
  const candidateLanes = laneConfig?.lanes ?? [];
  const nextCommands = candidateLanes
    .filter((lane) => typeof lane.node === "string" && lane.node.length > 0 && typeof lane.lane === "string" && lane.lane.length > 0)
    .slice(0, 4)
    .map((lane) => `bun scripts/cli.ts agentrun control-plane status --node ${lane.node} --lane ${lane.lane}`);
  return {
    ...details,
    laneAwareLookup: {
      kind: "agentrun-resource-not-found-on-current-endpoint",
      summary: resource === null
        ? "The request returned 404 on the currently configured AgentRun manager endpoint; a resource from another lane will not be visible through this baseUrl."
        : `${resource.kind}/${resource.id} returned 404 on the currently configured AgentRun manager endpoint; if it was created on another lane, inspect that lane before treating the resource as lost.`,
      request: {
        method,
        path: pathValue,
        ...(resource === null ? {} : { resource }),
      },
      currentEndpoint: {
        transport: target === null ? "direct-http" : "lane-k8s-service-proxy",
        baseUrl: target === null ? config.manager.baseUrl : target.spec.runtime.internalBaseUrl,
        configPath: config.sourcePath,
        defaultNode: laneConfig?.defaultNode ?? null,
        defaultLane: laneConfig?.defaultLane ?? null,
        selectedNode: target?.spec.nodeId ?? null,
        selectedLane: target?.spec.lane ?? null,
      },
      candidateLanes,
      nextCommands,
      note: target === null
        ? "Pass --node <node> --lane <lane> to query a YAML-declared non-default AgentRun lane."
        : "The resource was not found on the selected AgentRun lane; verify the run/session id and the HWLAB runtime lane that created it.",
      valuesPrinted: false,
    },
  };
}

function agentRunResourceFromPath(pathValue: string): Record<string, string> | null {
  const run = pathValue.match(/\/runs\/([^/?#]+)/u);
  if (run?.[1] !== undefined) return { kind: "run", id: decodeURIComponent(run[1]) };
  const session = pathValue.match(/\/sessions\/([^/?#]+)/u);
  if (session?.[1] !== undefined) return { kind: "session", id: decodeURIComponent(session[1]) };
  const command = pathValue.match(/\/commands\/([^/?#]+)/u);
  if (command?.[1] !== undefined) return { kind: "command", id: decodeURIComponent(command[1]) };
  const task = pathValue.match(/\/queue\/tasks\/([^/?#]+)/u);
  if (task?.[1] !== undefined) return { kind: "task", id: decodeURIComponent(task[1]) };
  return null;
}

function readAgentRunLaneLookupConfig(configPath: string): { defaultNode: string | null; defaultLane: string | null; lanes: Record<string, unknown>[] } | null {
  try {
    const raw = readFileSync(configPath, "utf8");
    const parsed = record(Bun.YAML.parse(raw) as unknown);
    const controlPlane = record(parsed.controlPlane);
    const defaultTarget = record(controlPlane.default);
    const lanes = record(controlPlane.lanes);
    return {
      defaultNode: stringOrNull(defaultTarget.node),
      defaultLane: stringOrNull(defaultTarget.lane),
      lanes: Object.entries(lanes).map(([laneName, rawLane]) => {
        const lane = record(rawLane);
        const runtime = record(lane.runtime);
        return {
          lane: laneName,
          node: stringOrNull(lane.node) ?? stringOrNull(lane.nodeId),
          version: stringOrNull(lane.version),
          namespace: stringOrNull(runtime.namespace),
          internalBaseUrl: stringOrNull(runtime.internalBaseUrl),
          isDefault: laneName === stringOrNull(defaultTarget.lane),
        };
      }),
    };
  } catch {
    return null;
  }
}

function agentRunDryRunPlan(action: string, pathValue: string, body: Record<string, unknown>, confirmCommand: string, method: AgentRunHttpMethod = "POST", extra: Record<string, unknown> = {}): Record<string, unknown> {
  return {
    ok: true,
    action,
    dryRun: true,
    mutation: false,
    transport: "direct-http",
    clientRole: "render-only",
    request: {
      method,
      path: pathValue,
      bodyKeys: Object.keys(body),
      valuesPrinted: false,
    },
    ...extra,
    next: { confirm: confirmCommand },
    valuesPrinted: false,
  };
}

function agentRunQuery(args: string[], names: string[]): string {
  const params = new URLSearchParams();
  const keyMap: Record<string, string> = {
    "after-seq": "afterSeq",
    "backend-profile": "backendProfile",
    "command": "commandId",
    "command-id": "commandId",
    "reader-id": "readerId",
    "run-id": "runId",
    "updated-after": "updatedAfter",
  };
  for (const name of names) {
    const value = agentRunOption(args, name);
    if (value !== null) params.set(keyMap[name] ?? name, value);
  }
  const query = params.toString();
  return query.length > 0 ? `?${query}` : "";
}

function agentRunOption(args: string[], name: string): string | null {
  const flag = `--${name}`;
  for (let index = 0; index < args.length; index += 1) {
    const arg = args[index] ?? "";
    if (arg === flag) {
      const value = args[index + 1];
      if (value === undefined || value.startsWith("--")) throw new AgentRunRestError("validation-failed", `${flag} requires a value`);
      return value;
    }
    if (arg.startsWith(`${flag}=`)) return arg.slice(flag.length + 1);
  }
  return null;
}

function requiredAgentRunOption(args: string[], names: string[], message: string): string {
  for (const name of names) {
    const value = agentRunOption(args, name);
    if (value !== null) return value;
  }
  throw new AgentRunRestError("validation-failed", message);
}

function agentRunHasFlag(args: string[], name: string): boolean {
  const flag = `--${name}`;
  return args.includes(flag) || args.some((arg) => arg.startsWith(`${flag}=`));
}

async function requiredJsonBody(args: string[], context: string): Promise<Record<string, unknown>> {
  const body = await optionalJsonBody(args);
  if (Object.keys(body).length === 0) throw new AgentRunRestError("validation-failed", `${context} requires --json-stdin or --json-file <path>`);
  return body;
}

async function optionalJsonBody(args: string[]): Promise<Record<string, unknown>> {
  const raw = readJsonTextFromArgs(args, "json");
  if (raw === null) return {};
  return record(JSON.parse(raw) as unknown);
}

async function optionalRunnerJsonBody(args: string[]): Promise<Record<string, unknown>> {
  const raw = readJsonTextFromArgs(args, "runner-json");
  if (raw === null) return {};
  return record(JSON.parse(raw) as unknown);
}

function readJsonTextFromArgs(args: string[], prefix: "json" | "runner-json"): string | null {
  if (agentRunHasFlag(args, `${prefix}-stdin`)) return readFileSync(0, "utf8");
  const file = agentRunOption(args, `${prefix}-file`);
  if (file !== null) return file === "-" ? readFileSync(0, "utf8") : readFileSync(file, "utf8");
  return null;
}

function readYamlInputFromArgs(args: string[]): string {
  if (agentRunHasFlag(args, "yaml-stdin")) return readFileSync(0, "utf8");
  const file = agentRunOption(args, "yaml-file");
  if (file !== null) return file === "-" ? readFileSync(0, "utf8") : readFileSync(file, "utf8");
  throw new AgentRunRestError("validation-failed", "aipod-spec YAML input is required; use --yaml-stdin or --yaml-file <file>");
}

async function aipodRenderInputFromArgs(args: string[], trailingPromptStart: number, overrides: Record<string, unknown> = {}): Promise<Record<string, unknown>> {
  const input = await optionalJsonBody(args);
  const prompt = optionalPromptFromArgs(args, trailingPromptStart);
  if (prompt !== null) input.prompt = prompt;
  copyAgentRunOptions(args, input, ["tenant-id", "project-id", "queue", "lane", "title", "provider-id", "idempotency-key", "session-id"]);
  const profile = agentRunOption(args, "profile") ?? agentRunOption(args, "backend-profile");
  if (profile) input.backendProfile = profile;
  const priority = agentRunOption(args, "priority");
  if (priority) input.priority = Number(priority);
  const workspaceRef = jsonObjectOption(args, "workspace-json");
  if (workspaceRef !== null) input.workspaceRef = workspaceRef;
  return { ...input, ...overrides };
}

function readPromptFromArgs(args: string[], trailingStart: number): string {
  const prompt = optionalPromptFromArgs(args, trailingStart);
  if (prompt === null) throw new AgentRunRestError("validation-failed", "prompt is required; use --prompt-stdin, --prompt-file, --prompt, or a trailing prompt");
  return prompt;
}

function optionalPromptFromArgs(args: string[], trailingStart: number): string | null {
  if (agentRunHasFlag(args, "prompt-stdin") || agentRunHasFlag(args, "stdin")) return readFileSync(0, "utf8");
  const promptFile = agentRunOption(args, "prompt-file");
  if (promptFile !== null) return promptFile === "-" ? readFileSync(0, "utf8") : readFileSync(promptFile, "utf8");
  const prompt = agentRunOption(args, "prompt");
  if (prompt !== null) return prompt;
  const trailing = args.slice(trailingStart).filter((arg) => !arg.startsWith("-"));
  return trailing.length > 0 ? trailing.join(" ") : null;
}

function queueDispatchBodyFromArgs(args: string[]): Record<string, unknown> {
  const body = recordFromMaybeJson(args);
  copyAgentRunOptions(args, body, ["idempotency-key", "image", "namespace", "attempt-id", "runner-id", "source-commit", "service-account-name"]);
  const managerUrl = agentRunOption(args, "runner-manager-url");
  if (managerUrl) body.managerUrl = managerUrl;
  return body;
}

function recordFromMaybeJson(args: string[]): Record<string, unknown> {
  const raw = readJsonTextFromArgs(args, "json");
  if (raw === null) return {};
  return record(JSON.parse(raw) as unknown);
}

function cancelBodyFromArgs(args: string[]): Record<string, unknown> {
  const reason = agentRunOption(args, "reason");
  return reason === null ? {} : { reason };
}

function copyAgentRunOptions(args: string[], target: Record<string, unknown>, flagNames: string[]): void {
  for (const flagName of flagNames) {
    const value = agentRunOption(args, flagName);
    if (value === null) continue;
    target[camelCaseFlag(flagName)] = value;
  }
}

function camelCaseFlag(flagName: string): string {
  return flagName.replace(/-([a-z])/gu, (_, letter: string) => String(letter).toUpperCase());
}

function jsonObjectOption(args: string[], flagName: string): Record<string, unknown> | null {
  const value = agentRunOption(args, flagName);
  if (value === null) return null;
  return record(JSON.parse(value) as unknown);
}

function queueSubmitConfirmCommand(args: string[], aipod?: string): string {
  const dryRunless = args.filter((arg) => arg !== "--dry-run").join(" ");
  return `bun scripts/cli.ts agentrun queue submit${aipod ? ` --aipod ${aipod}` : ""}${dryRunless.length > 0 ? ` ${dryRunless}` : ""}`.trim();
}

function jsonInputDisclosureFromArgs(args: string[]): Record<string, unknown> {
  return {
    source: agentRunHasFlag(args, "json-stdin") ? "stdin" : agentRunOption(args, "json-file") ?? "<task.json>",
    valuesPrinted: false,
  };
}

function defaultAgentRunExecutionPolicy(profile: string, sessionPolicy: AgentRunSessionPolicyConfig = readAgentRunClientConfig().client.sessionPolicy): Record<string, unknown> {
  const { spec } = resolveAgentRunLaneTarget({});
  const credentials = agentRunProviderCredentialRefs(spec, profile);
  if (credentials.length === 0) {
    throw new AgentRunRestError("validation-failed", `config/agentrun.yaml has no providerCredential Secret binding for backendProfile=${profile} on default lane ${spec.nodeId}/${spec.lane}`);
  }
  const providerCredentials = credentials.map((credential) => {
    if (credential.secretRef.namespace !== spec.runtime.namespace) {
      throw new AgentRunRestError("validation-failed", `providerCredential ${profile} Secret ${credential.secretRef.name} is in namespace ${credential.secretRef.namespace}, expected default lane namespace ${spec.runtime.namespace}`);
    }
    return {
      profile: credential.profile,
      secretRef: {
        name: credential.secretRef.name,
        keys: credential.secretRef.keys,
      },
    };
  });
  const basePolicy = cloneJsonRecord(sessionPolicy.executionPolicy);
  const secretScope = record(basePolicy.secretScope);
  return {
    ...basePolicy,
    secretScope: {
      ...secretScope,
      providerCredentials,
    },
  };
}

function renderAgentRunSessionPolicyExplanation(): string {
  const config = readAgentRunClientConfig();
  const { spec } = resolveAgentRunLaneTarget({});
  const sessionPolicy = config.client.sessionPolicy;
  const credentials = agentRunProviderCredentialRefs(spec, sessionPolicy.backendProfile);
  const execution = defaultAgentRunExecutionPolicy(sessionPolicy.backendProfile, sessionPolicy);
  const credentialSources = credentials.map((credential) => ({
    profile: credential.profile,
    secretRef: credential.secretRef,
    valuesPrinted: false,
  }));
  return [
    "KIND: session-policy",
    `CONFIG: ${config.sourcePath}`,
    `DEFAULT LANE: ${spec.nodeId}/${spec.lane}`,
    `DEFAULTS: tenantId=${sessionPolicy.tenantId} projectId=${sessionPolicy.projectId} providerId=${sessionPolicy.providerId} backendProfile=${sessionPolicy.backendProfile}`,
    `WORKSPACE: ${JSON.stringify(sessionPolicy.workspaceRef)}`,
    `EXECUTION: ${JSON.stringify(execution)}`,
    `PROVIDER CREDENTIAL SOURCES: ${JSON.stringify(credentialSources)}`,
    "VALUES: secret payloads are not printed",
  ].join("\n");
}

function safeAgentRunEnvelope(envelope: Record<string, unknown>): Record<string, unknown> {
  return pickCompact(envelope, ["ok", "failureKind", "message", "code", "details", "valuesPrinted"]);
}

function normalizeAgentRunFailureKind(raw: string | null, httpStatus: number): AgentRunFailureKind {
  if (raw === "agentrun-unreachable") return "agentrun-connect-failed";
  if (raw === "auth-missing" || raw === "auth-failed" || raw === "agentrun-connect-failed" || raw === "agentrun-proxy-exec-failed" || raw === "agentrun-manager-fetch-failed" || raw === "agentrun-timeout" || raw === "schema-mismatch" || raw === "unsupported-version" || raw === "validation-failed" || raw === "not-found") return raw;
  if (httpStatus === 401 || httpStatus === 403) return "auth-failed";
  if (httpStatus === 404) return "not-found";
  return raw === "schema-invalid" ? "validation-failed" : "validation-failed";
}

function classifyAgentRunProxyFailureKind(raw: string | null): AgentRunFailureKind {
  if (raw === "manager-pod-fetch-timeout" || raw === "agentrun-timeout") return "agentrun-timeout";
  if (raw === "manager-pod-fetch-failed") return "agentrun-manager-fetch-failed";
  const normalized = normalizeAgentRunFailureKind(raw, 0);
  return normalized === "validation-failed" ? "agentrun-proxy-exec-failed" : normalized;
}

function stringFieldFromRecord(obj: Record<string, unknown>, key: string, pathValue: string): string {
  const value = obj[key];
  if (typeof value !== "string" || value.trim().length === 0) throw new Error(`${pathValue}.${key} must be a non-empty string`);
  return value.trim();
}

function numberFieldFromRecord(obj: Record<string, unknown>, key: string, pathValue: string, bounds: { min: number; max: number }): number {
  const value = obj[key];
  if (typeof value !== "number" || !Number.isFinite(value) || value < bounds.min || value > bounds.max) throw new Error(`${pathValue}.${key} must be a number between ${bounds.min} and ${bounds.max}`);
  return value;
}

function positiveIntegerFieldFromRecord(obj: Record<string, unknown>, key: string, pathValue: string): number {
  const value = obj[key];
  if (!Number.isInteger(value) || Number(value) <= 0) throw new Error(`${pathValue}.${key} must be a positive integer`);
  return Number(value);
}

function booleanFieldFromRecord(obj: Record<string, unknown>, key: string, pathValue: string): boolean {
  const value = obj[key];
  if (typeof value !== "boolean") throw new Error(`${pathValue}.${key} must be a boolean`);
  return value;
}

function cloneJsonRecord(value: Record<string, unknown>): Record<string, unknown> {
  return JSON.parse(JSON.stringify(value)) as Record<string, unknown>;
}

interface AgentRunClientConfig {
  sourcePath: string;
  manager: {
    baseUrl: string;
    timeoutMs: number;
  };
  auth: {
    env: string;
    file: string;
    header: string;
    scheme: string;
  };
  client: {
    role: string;
    transport: string;
    sessionPolicy: AgentRunSessionPolicyConfig;
  };
  publicExposure: AgentRunPublicExposure | null;
}

interface AgentRunSessionPolicyConfig {
  sourcePath: string;
  tenantId: string;
  projectId: string;
  providerId: string;
  backendProfile: string;
  workspaceRef: Record<string, unknown>;
  executionPolicy: Record<string, unknown>;
}

interface AgentRunPublicExposure {
  enabled: true;
  proxyName: string;
  remotePort: number;
  publicBaseUrl: string;
  masterBaseUrl: string;
  masterFrps: {
    configPath: string;
    containerName: string;
  };
  masterCaddy: {
    enabled: boolean;
    domain: string;
    configPath: string;
    serviceName: string;
    upstreamBaseUrl: string;
    responseHeaderTimeoutSeconds: number;
  };
}

interface AgentRunResolvedAuth {
  source: "env" | "file";
  value: string;
}

type AgentRunHttpMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
type AgentRunFailureKind = "auth-missing" | "auth-failed" | "agentrun-connect-failed" | "agentrun-proxy-exec-failed" | "agentrun-manager-fetch-failed" | "agentrun-timeout" | "schema-mismatch" | "unsupported-version" | "validation-failed" | "not-found";

type AgentRunRestCompatGroup = "queue" | "sessions" | "aipod-specs" | "aipods" | "runs" | "commands" | "runner";
type AgentRunResourceVerb = "get" | "describe" | "events" | "logs" | "result" | "ack" | "cancel" | "dispatch" | "create" | "apply" | "send" | "explain";
type AgentRunResourceKind = "task" | "run" | "command" | "runnerjob" | "session" | "aipodspec";
type AgentRunOutputMode = "human" | "wide" | "name" | "json" | "yaml";

interface AgentRunResourceRef {
  kind: AgentRunResourceKind;
  name: string;
}

interface AgentRunResourceOptions {
  output: AgentRunOutputMode;
  full: boolean;
  raw: boolean;
  debug: boolean;
  limit: number;
  queue: string | null;
  state: string | null;
  unread: boolean;
  readerId: string;
  taskId: string | null;
  runId: string | null;
  commandId: string | null;
  sessionId: string | null;
  afterSeq: number | null;
  tail: number | null;
  fullText: boolean;
  reason: string | null;
  dryRun: boolean;
  file: string | null;
  aipod: string | null;
  idempotencyKey: string | null;
  promptStdin: boolean;
  node: string | null;
  lane: string | null;
  passthroughArgs: string[];
}

interface AgentRunRestTargetOptions {
  node: string | null;
  lane: string | null;
}

interface AgentRunRestTarget {
  config: UniDeskConfig;
  configPath: string;
  spec: AgentRunLaneSpec;
}

let activeAgentRunRestTarget: AgentRunRestTarget | null = null;

type AgentRunBridgeCaptureBackend = "local-backend-core-broker" | "remote-frontend-websocket";

interface LocalBackendCoreStatus {
  dockerExecutable: boolean;
  backendCoreContainer: boolean;
  error: string | null;
}

interface AgentRunBridgeCapturePlan {
  backend: AgentRunBridgeCaptureBackend;
  route: string;
  reason: string;
  remoteHost: string | null;
  localBackendCore: LocalBackendCoreStatus;
}

type AgentRunBridgeCaptureResult = SshCaptureResult & { bridgeExecution?: AgentRunBridgeCapturePlan };

let localBackendCoreStatusCache: LocalBackendCoreStatus | null = null;

async function capture(config: UniDeskConfig, target: string, args: string[]): Promise<AgentRunBridgeCaptureResult> {
  const plan = agentRunBridgeCapturePlan(config, target);
  if (plan.backend === "remote-frontend-websocket" && plan.remoteHost !== null) {
    return await captureRemote(config, plan, target, args);
  }
  const local = attachBridgeExecution(await runSshCommandCapture(config, target, args), plan);
  const fallbackHost = agentRunBridgeRemoteHost(config);
  if (local.exitCode !== 0 && fallbackHost !== null && bridgeExecutionFailureKind(local)?.degradedReason === "capture-backend-unavailable") {
    const fallbackPlan: AgentRunBridgeCapturePlan = {
      ...plan,
      backend: "remote-frontend-websocket",
      remoteHost: fallbackHost,
      reason: "local-capture-backend-unavailable",
    };
    return await captureRemote(config, fallbackPlan, target, args);
  }
  return local;
}

async function captureRemote(config: UniDeskConfig, plan: AgentRunBridgeCapturePlan, target: string, args: string[]): Promise<AgentRunBridgeCaptureResult> {
  if (plan.remoteHost === null) return attachBridgeExecution(remoteBridgeCaptureFailure(new Error("remote host is not configured")), plan);
  try {
    return attachBridgeExecution(await runRemoteSshCommandCapture(config, plan.remoteHost, target, args), plan);
  } catch (error) {
    return attachBridgeExecution(remoteBridgeCaptureFailure(error), plan);
  }
}

function remoteBridgeCaptureFailure(error: unknown): SshCaptureResult {
  const message = error instanceof Error ? `${error.name}: ${error.message}` : String(error);
  return {
    exitCode: 255,
    stdout: "",
    stderr: `unidesk remote frontend ssh bridge failed: ${message}\n`,
  };
}

function attachBridgeExecution(result: SshCaptureResult, plan: AgentRunBridgeCapturePlan): AgentRunBridgeCaptureResult {
  return { ...result, bridgeExecution: plan };
}

function agentRunBridgeCapturePlan(config: UniDeskConfig, target: string, env: NodeJS.ProcessEnv = process.env): AgentRunBridgeCapturePlan {
  const localBackendCore = detectLocalBackendCoreStatus();
  const remoteHost = agentRunBridgeRemoteHost(config, env);
  const runnerEnv = isAgentRunRunnerEnvironment(env);
  if (runnerEnv && remoteHost !== null) {
    return { backend: "remote-frontend-websocket", route: target, reason: "runner-environment", remoteHost, localBackendCore };
  }
  if (!localBackendCore.backendCoreContainer && remoteHost !== null) {
    return { backend: "remote-frontend-websocket", route: target, reason: "local-backend-core-unavailable", remoteHost, localBackendCore };
  }
  return { backend: "local-backend-core-broker", route: target, reason: "main-server-local-backend-core", remoteHost: null, localBackendCore };
}

function detectLocalBackendCoreStatus(): LocalBackendCoreStatus {
  if (localBackendCoreStatusCache !== null) return localBackendCoreStatusCache;
  const result = spawnSync("docker", ["ps", "--format", "{{.Names}}"], { encoding: "utf8", timeout: 2000 });
  if (result.error !== undefined) {
    localBackendCoreStatusCache = {
      dockerExecutable: false,
      backendCoreContainer: false,
      error: result.error.message,
    };
    return localBackendCoreStatusCache;
  }
  const output = `${result.stdout ?? ""}\n${result.stderr ?? ""}`.trim();
  localBackendCoreStatusCache = {
    dockerExecutable: result.status === 0,
    backendCoreContainer: result.status === 0 && String(result.stdout ?? "").split(/\r?\n/u).includes("unidesk-backend-core"),
    error: result.status === 0 ? null : output || `docker ps exited ${result.status ?? "unknown"}`,
  };
  return localBackendCoreStatusCache;
}

function isAgentRunRunnerEnvironment(env: NodeJS.ProcessEnv): boolean {
  return Boolean(
    env.AGENTRUN_BOOT_MODE
      || env.AGENTRUN_RUN_ID
      || env.AGENTRUN_K8S_JOB_NAME
      || env.CODE_QUEUE_SERVICE_ROLE
      || env.CODE_QUEUE_INSTANCE_ID
      || env.KUBERNETES_SERVICE_HOST,
  );
}

function agentRunBridgeRemoteHost(config: UniDeskConfig, env: NodeJS.ProcessEnv = process.env): string | null {
  return normalizeRemoteHostHint(env.UNIDESK_MAIN_SERVER_IP)
    ?? normalizeRemoteHostHint(env.UNIDESK_MAIN_SERVER_HOST)
    ?? normalizeRemoteHostHint(env.CODE_QUEUE_DEV_CONTAINER_MASTER_HOST)
    ?? normalizeRemoteHostHint(config.network.publicHost);
}

function normalizeRemoteHostHint(raw: string | undefined): string | null {
  const value = raw?.trim() ?? "";
  if (value.length === 0 || value === "localhost" || value === "127.0.0.1" || value === "::1") return null;
  return value.replace(/\/+$/u, "");
}

function captureBridgeMetadata(result: SshCaptureResult): Record<string, unknown> | null {
  const bridgeExecution = (result as AgentRunBridgeCaptureResult).bridgeExecution;
  if (bridgeExecution === undefined) return null;
  return {
    backend: bridgeExecution.backend,
    route: bridgeExecution.route,
    reason: bridgeExecution.reason,
    remoteHost: bridgeExecution.remoteHost,
    localBackendCore: bridgeExecution.localBackendCore,
  };
}

function bridgeExecutionFailureKind(result: SshCaptureResult): { degradedReason: string; failureKind: string; recoveryActions: string[] } | null {
  if (result.exitCode === 0) return null;
  const stderr = result.stderr;
  if (/No such container: unidesk-backend-core|failed to start broker|Executable not found.*"docker"|docker: not found|Cannot connect to the Docker daemon/iu.test(stderr)) {
    return {
      degradedReason: "capture-backend-unavailable",
      failureKind: "bridge-execution-environment",
      recoveryActions: [
        "Run the same command from a healthy UniDesk main-server CLI, or provide UNIDESK_MAIN_SERVER_IP/UNIDESK_MAIN_SERVER_HOST so the bridge can use the frontend WebSocket SSH backend.",
        "For AgentRun runner jobs, request the unidesk-ssh tool credential SecretRef instead of embedding secret values in prompts or payloads.",
        "After restoring the bridge backend, retry the same bun scripts/cli.ts agentrun ... command; do not use direct kubectl or GitHub API bypasses.",
      ],
    };
  }
  if (/frontend login failed|remote frontend ssh bridge|websocket error|timed out waiting for provider session|route-not-allowed/iu.test(stderr)) {
    return {
      degradedReason: "bridge-execution-environment-unavailable",
      failureKind: "bridge-execution-environment",
      recoveryActions: [
        "Verify the UniDesk frontend/backend-core SSH bridge is reachable from this runner and that UNIDESK_MAIN_SERVER_IP or UNIDESK_MAIN_SERVER_HOST points at the main server.",
        "Verify scoped UNIDESK_SSH_CLIENT_TOKEN route allowlist includes the requested AgentRun route, without printing token values.",
        "Retry with the same bun scripts/cli.ts agentrun ... command after the controlled bridge path is restored.",
      ],
    };
  }
  return null;
}

function compactCapture(result: SshCaptureResult, options: { full?: boolean; stdoutTailChars?: number; stderrTailChars?: number } = {}): Record<string, unknown> {
  const stdoutTailChars = options.stdoutTailChars ?? 8000;
  const stderrTailChars = options.stderrTailChars ?? 4000;
  const full = options.full ?? true;
  const payload: Record<string, unknown> = {
    exitCode: result.exitCode,
    stdoutBytes: Buffer.byteLength(result.stdout, "utf8"),
    stderrBytes: Buffer.byteLength(result.stderr, "utf8"),
    stdoutTailOmitted: !full && result.exitCode === 0,
    stderrTailOmitted: !full && result.exitCode === 0,
  };
  const bridgeExecution = captureBridgeMetadata(result);
  if (bridgeExecution !== null) payload.bridgeExecution = bridgeExecution;
  const failureKind = bridgeExecutionFailureKind(result);
  if (failureKind !== null) {
    payload.degradedReason = failureKind.degradedReason;
    payload.failureKind = failureKind.failureKind;
    payload.recoveryActions = failureKind.recoveryActions;
  }
  if (full || result.exitCode !== 0) {
    payload.stdoutTail = tail(result.stdout, stdoutTailChars);
    payload.stderrTail = tail(result.stderr, stderrTailChars);
    payload.stdoutTruncated = result.stdout.length > stdoutTailChars;
    payload.stderrTruncated = result.stderr.length > stderrTailChars;
  }
  return payload;
}

async function timedStatusStage<T>(stage: string, action: () => Promise<T>): Promise<TimedValue<T>> {
  const startedAtMs = Date.now();
  progressEvent("agentrun.control-plane.status.progress", { stage, status: "started" });
  try {
    const value = await action();
    const exitCode = isCaptureResult(value) ? value.exitCode : typeof record(value).ok === "boolean" && record(value).ok !== true ? 1 : 0;
    progressEvent("agentrun.control-plane.status.progress", {
      stage,
      status: exitCode === 0 ? "succeeded" : "failed",
      exitCode,
      elapsedMs: Date.now() - startedAtMs,
    });
    return { value, elapsedMs: Date.now() - startedAtMs };
  } catch (error) {
    progressEvent("agentrun.control-plane.status.progress", {
      stage,
      status: "failed",
      elapsedMs: Date.now() - startedAtMs,
      error: error instanceof Error ? error.message : String(error),
    });
    throw error;
  }
}

function progressEvent(event: string, payload: Record<string, unknown>): void {
  const stage = displayValue(payload.stage ?? event);
  const status = displayValue(payload.status ?? "-");
  const details = [
    payload.exitCode === undefined ? null : `exit=${displayValue(payload.exitCode)}`,
    payload.elapsedMs === undefined ? null : `elapsed=${displayValue(payload.elapsedMs)}ms`,
    payload.error === undefined ? null : `error=${truncateOneLine(displayValue(payload.error), 160)}`,
  ].filter((item): item is string => item !== null);
  process.stderr.write(`status ${stage} ${status}${details.length === 0 ? "" : ` ${details.join(" ")}`}\n`);
}

function isCaptureResult(value: unknown): value is SshCaptureResult {
  return typeof value === "object" && value !== null && "exitCode" in value && typeof (value as { exitCode?: unknown }).exitCode === "number";
}

function isAgentRunPipelineRunName(value: string): boolean {
  return /^agentrun-v[0-9]+-ci-[0-9a-f]{12,40}(?:-[a-z0-9-]+)?$/u.test(value);
}

function captureJsonPayload(result: SshCaptureResult): Record<string, unknown> {
  const trimmed = result.stdout.trim();
  if (trimmed.length === 0) return {};
  try {
    return record(JSON.parse(trimmed) as unknown);
  } catch {
    const lastJsonLine = trimmed.split(/\r?\n/u).reverse().find((line) => line.trim().startsWith("{") && line.trim().endsWith("}"));
    if (lastJsonLine === undefined) return {};
    try {
      return record(JSON.parse(lastJsonLine) as unknown);
    } catch {
      return {};
    }
  }
}

function record(value: unknown): Record<string, unknown> {
  return typeof value === "object" && value !== null && !Array.isArray(value) ? value as Record<string, unknown> : {};
}

function stringOrNull(value: unknown): string | null {
  return typeof value === "string" && value.length > 0 ? value : null;
}

function nonNegativeIntegerOrNull(value: unknown): number | null {
  if (typeof value === "number" && Number.isInteger(value) && value >= 0) return value;
  if (typeof value === "string" && /^\d+$/u.test(value)) return Number(value);
  return null;
}

function isGitSha(value: string): boolean {
  return /^[0-9a-f]{40}$/u.test(value);
}

function tail(text: string, maxChars: number): string {
  return text.length > maxChars ? text.slice(-maxChars) : text;
}

function sleep(ms: number): Promise<void> {
  return new Promise((resolve) => setTimeout(resolve, ms));
}

function shQuote(value: string): string {
  return `'${value.replace(/'/gu, "'\\''")}'`;
}

function unsupported(args: string[]): RenderedCliResult {
  const command = `agentrun ${args.join(" ")}`.trim();
  return renderedCliResult(false, command, [
    `Error: unsupported AgentRun command: ${command}`,
    "",
    "Supported resource commands:",
    "  agentrun get|describe|events|logs|result|ack|cancel|dispatch|create|apply|send",
    "",
    "Compatibility bridge groups:",
    "  agentrun aipod-specs|queue|runs|commands|runner|sessions",
    "",
    "Operations:",
    "  agentrun control-plane status|trigger-current|refresh",
    "  agentrun git-mirror status|sync|flush",
  ].join("\n"));
}
