import { execFileSync } from "node:child_process";
import { existsSync, mkdirSync, mkdtempSync, readFileSync, realpathSync, rmSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import { dirname, resolve } from "node:path";
import { afterEach, describe, expect, it } from "vitest";
import { createGoatChainBridge, resolveInitialGoatChainThread } from "../src/best-agent-native-bridge.ts";
import {
  createCliRuntime,
  hydrateDimSdkProviderSelection,
  readCliPersistedState,
  resolveCliStorageRoot,
} from "../src/runtime.ts";

const { nextTick, ref, watch } = await import("vue");
const { createTerminalApp } = await import("@simon_he/vue-tui");
const { createDimSdkRouter, DimSdkShell } = await import("../src/dimsdk/index.ts");
const { useChatStatus } = await import("../src/dimsdk/pages/ChatPage/logic/status.ts");

const tempRoots: string[] = [];
const FULL_REPO_REVIEW_PAGE_LIMIT = 25;

afterEach(() => {
  while (tempRoots.length > 0) {
    rmSync(tempRoots.pop() as string, { force: true, recursive: true });
  }
});

function createWorkspace(files: Readonly<Record<string, string>>): string {
  const workspaceRoot = mkdtempSync(`${tmpdir()}/best-agent-dimsdk-real-workspace-`);
  tempRoots.push(workspaceRoot);
  for (const [relativePath, content] of Object.entries(files)) {
    const filePath = resolve(workspaceRoot, relativePath);
    mkdirSync(dirname(filePath), { recursive: true });
    writeFileSync(filePath, content, "utf8");
  }
  return workspaceRoot;
}

function readRealProviderConfig(): Record<string, unknown> {
  const cliStatePath = resolve(process.cwd(), ".best-agent", "cli-state.json");
  if (!existsSync(cliStatePath)) {
    throw new Error(`Missing CLI state at ${cliStatePath}`);
  }
  const parsed = JSON.parse(readFileSync(cliStatePath, "utf8"));
  const providerConfig = parsed?.providerConfig;
  if (!providerConfig || typeof providerConfig !== "object") {
    throw new Error("cli-state.json does not contain providerConfig");
  }
  return providerConfig as Record<string, unknown>;
}

function listFullRepoReviewTargets(cwd: string): string[] {
  const output = execFileSync("git", ["ls-files"], {
    cwd,
    encoding: "utf8",
    maxBuffer: 16 * 1024 * 1024,
  });
  return output
    .split("\n")
    .map((line) => line.trim())
    .filter(Boolean)
    .map((line) => line.replace(/^\.\//, ""))
    .sort((left, right) => left.localeCompare(right));
}

async function flushApp(app: {
  scheduler: { flush: () => void };
}, ticks = 3): Promise<void> {
  for (let index = 0; index < ticks; index += 1) {
    await nextTick();
  }
  app.scheduler.flush();
}

async function sleep(ms: number): Promise<void> {
  await new Promise((resolvePromise) => setTimeout(resolvePromise, ms));
}

async function waitFor<T>(
  fn: () => T | null | undefined,
  message: string,
  advance: () => Promise<void> = () => nextTick(),
  tries = 80,
  debug?: () => string,
): Promise<T> {
  for (let index = 0; index < tries; index += 1) {
    const value = fn();
    if (value) {
      return value;
    }
    await advance();
  }
  const detail = debug?.();
  throw new Error(detail ? `${message}\n\n${detail}` : message);
}

function bottomSnapshotText(app: {
  terminal: { snapshot: () => { lines: string[] } };
}, lineCount = 10): string {
  const lines = app.terminal.snapshot().lines;
  return lines.slice(-lineCount).join("\n");
}

function snapshotText(app: {
  terminal: { snapshot: () => { lines: string[] } };
}): string {
  return app.terminal.snapshot().lines.join("\n");
}

function findLastTextCell(
  lines: readonly string[],
  text: string,
): { x: number; y: number } | null {
  const wanted = text.toLowerCase();
  for (let y = lines.length - 1; y >= 0; y -= 1) {
    const x = lines[y]?.toLowerCase().indexOf(wanted) ?? -1;
    if (x >= 0) {
      return { x, y };
    }
  }
  return null;
}

function keyCodeFor(key: string): string {
  if (key === "/") return "Slash";
  if (key === "@") return "Digit2";
  if (key === " ") return "Space";
  if (key === ".") return "Period";
  if (key === "-") return "Minus";
  if (key.length === 1 && /[a-z]/i.test(key)) return `Key${key.toUpperCase()}`;
  if (key.length === 1 && /\d/.test(key)) return `Digit${key}`;
  return key;
}

async function pressKey(
  app: {
    events: { dispatch: (event: unknown) => boolean | void };
    scheduler: { flush: () => void };
  },
  key: string,
  code = keyCodeFor(key),
): Promise<void> {
  app.events.dispatch({ type: "keydown", key, code } as const);
  await flushApp(app);
}

async function typeText(
  app: {
    events: { dispatch: (event: unknown) => boolean | void };
    scheduler: { flush: () => void };
  },
  text: string,
): Promise<void> {
  for (const character of text) {
    await pressKey(app, character);
  }
}

async function clickLastText(
  app: {
    events: { dispatch: (event: unknown) => boolean | void };
    scheduler: { flush: () => void };
    terminal: { snapshot: () => { lines: readonly string[] } };
  },
  text: string,
): Promise<void> {
  const cell = findLastTextCell(app.terminal.snapshot().lines, text);
  if (!cell) {
    throw new Error(`Unable to find last "${text}" in terminal snapshot:\n${snapshotText(app)}`);
  }
  const eventBase = { cellX: cell.x + 1, cellY: cell.y };
  app.events.dispatch({ type: "pointerdown", button: 0, ...eventBase } as const);
  app.events.dispatch({ type: "pointerup", button: 0, ...eventBase } as const);
  app.events.dispatch({ type: "click", ...eventBase } as const);
  await flushApp(app);
}

function latestAssistantJson(store: any): string {
  const messages = Array.isArray(store?.state?.messages) ? store.state.messages : [];
  const assistant = [...messages].reverse().find((message: any) => message?.role === "assistant");
  return assistant ? JSON.stringify(assistant) : "";
}

function latestAssistant(store: any): any | null {
  const messages = Array.isArray(store?.state?.messages) ? store.state.messages : [];
  return [...messages].reverse().find((message: any) => message?.role === "assistant") ?? null;
}

function normalizeReasoningText(text: string): string {
  return text.replace(/\s+/g, " ").trim();
}

async function waitForAsync<T>(
  fn: () => Promise<T | null | undefined>,
  message: string,
  advance: () => Promise<void> = () => nextTick(),
  tries = 80,
  debug?: () => Promise<string> | string,
): Promise<T> {
  for (let index = 0; index < tries; index += 1) {
    const value = await fn();
    if (value) {
      return value;
    }
    await advance();
  }
  const detail = debug ? await debug() : undefined;
  throw new Error(detail ? `${message}\n\n${detail}` : message);
}

async function mountRealShell(options: Readonly<{ cwd?: string }> = {}) {
  const workspaceCwd = options.cwd ?? process.cwd();
  const providerConfig = readRealProviderConfig();

  const storageRoot = resolveCliStorageRoot({
    cwd: workspaceCwd,
    storageRoot: mkdtempSync(`${tmpdir()}/best-agent-dimsdk-real-`),
  });
  tempRoots.push(storageRoot);
  writeFileSync(
    resolve(storageRoot, "cli-state.json"),
    `${JSON.stringify({ providerConfig }, null, 2)}\n`,
    "utf8",
  );

  const persistedState = readCliPersistedState(storageRoot);
  const runtime = await createCliRuntime({
    cwd: workspaceCwd,
    storageRoot,
  });
  const initialProviderConfig = runtime.getProviderConfig();
  const initialThread = await resolveInitialGoatChainThread(runtime, { latest: false });
  const bridge = createGoatChainBridge({ runtime });
  const initialMessages = initialThread ? await bridge.hydrateThread(initialThread.id) : [];
  let stopProviderSync: (() => void) | undefined;
  let storeRef: any;

  const app = createTerminalApp({
    cols: 120,
    rows: 36,
    component: DimSdkShell as never,
    props: {
      agent: bridge.agent,
      context: {
        cwd: workspaceCwd,
        env: {
          ...process.env,
          DIMCODE_VERSION: process.env.DIMCODE_VERSION ?? "0.0.0",
        },
        system:
          "You are best-agent running inside the DimSdk terminal UI. Keep answers concise, tool-grounded, and focused on the current workspace.",
      },
      onStoreCreated: (store: any) => {
        storeRef = store;
        bridge.attachStore(store);
        if (typeof store.setCwd === "function") {
          store.setCwd(workspaceCwd);
        }
        store.state.messages = initialMessages;
        store.state.sessionId = initialThread?.id ?? "";
        hydrateDimSdkProviderSelection(store.state, {
          persistedProviderState: persistedState?.dimsdk?.providerState,
          providerConfig: initialProviderConfig,
        });
        stopProviderSync?.();
        stopProviderSync = watch(
          () => [store.state.provider, store.state.config.model],
          () => {},
          { deep: true },
        );
      },
      sessions: bridge.sessions,
      toolRunner: async (call: { id?: string; name?: string }) => ({
        toolCallId: String(call?.id ?? "tool"),
        output: `Real provider acceptance does not re-run "${String(call?.name ?? "tool")}" locally from the TUI shell.`,
        status: "error" as const,
      }),
      uiForcedSkills: new Set<string>(),
    },
    defaultStyle: { bg: "black", fg: "whiteBright" },
  });

  app.app.use(createDimSdkRouter({ initialRoute: "home", mode: "cli" }) as never);
  app.mount();
  await flushApp(app, 6);

  return {
    app,
    dispose() {
      stopProviderSync?.();
      app.dispose();
    },
    runtime,
    storageRoot,
    store: storeRef,
  };
}

describe("dimsdk real provider e2e", () => {
  const itReal = process.env.BEST_AGENT_REAL_PROVIDER_TEST === "1" ? it : it.skip;
  const itLongReal = process.env.BEST_AGENT_REAL_PROVIDER_LONG_TEST === "1" ? it : it.skip;

  itReal(
    "sends a real message from the TUI shell using the configured provider",
    async () => {
      const previousDimcodeTest = process.env.DIMCODE_TEST;
      process.env.DIMCODE_TEST = "1";
      const mounted = await mountRealShell();
      try {
        const prompt = "What is two plus two? Reply with just the numeral.";
        const debugStatus = useChatStatus({
          store: mounted.store,
          ui: {
            style: (_tokens?: unknown, extra?: Record<string, unknown>) => extra ?? {},
            token: () => ({ fg: "whiteBright", bg: "black" }),
            capability: { level: 8 },
          } as any,
          uiMode: ref("agent") as any,
        });
        await typeText(mounted.app, prompt);
        await pressKey(mounted.app, "Enter", "Enter");

        await waitFor(
          () => {
            const assistantJson = latestAssistantJson(mounted.store);
            return assistantJson.includes("\"4\"") ? assistantJson : null;
          },
          "TUI shell did not receive the expected real-provider assistant reply.",
          async () => {
            await sleep(250);
            await flushApp(mounted.app, 6);
          },
          240,
        );

        expect(String(mounted.store.state.sessionId ?? "")).toMatch(/^thread_/);
        expect(latestAssistantJson(mounted.store)).toContain("\"4\"");
        const assistant = [...(mounted.store.state.messages ?? [])]
          .reverse()
          .find((message: any) => message?.role === "assistant");
        const thinkingParts = assistant?.parts?.filter((part: any) => part?.type === "thinking") ?? [];
        expect(
          thinkingParts.some((part: any) =>
            String(part?.content ?? "").includes("Drafting a response from the orchestrator runtime profile."),
          ),
        ).toBe(false);
        await waitFor(
          () => {
            const totalTokens = Number(mounted.store?.state?.usage?.total_tokens ?? 0);
            return Number.isFinite(totalTokens) && totalTokens > 0 ? totalTokens : null;
          },
          "TUI shell did not surface session token usage after the real-provider reply.",
          async () => {
            await sleep(250);
            await flushApp(mounted.app, 6);
          },
          80,
        );
        expect(Number(mounted.store.state.usage.total_tokens)).toBeGreaterThan(0);
        await waitFor(
          () => {
            const screen = mounted.app.terminal.snapshot().lines.join("\n");
            return screen.includes("tok") && !screen.includes(" 0 tok ") ? screen : null;
          },
          "TUI shell did not render non-zero visible token usage after the real-provider reply.",
          async () => {
            await sleep(250);
            await flushApp(mounted.app, 6);
          },
          80,
          () =>
            [
              `chromeVersion=${JSON.stringify(mounted.store?.state?.chromeVersion ?? null)}`,
              `messageCount=${JSON.stringify(Array.isArray(mounted.store?.state?.messages) ? mounted.store.state.messages.length : null)}`,
              `usage=${JSON.stringify(mounted.store?.state?.usage ?? null)}`,
              `lastRequestBudget=${JSON.stringify(mounted.store?.state?.lastRequestBudget ?? null)}`,
              `debugHeaderStats=${JSON.stringify(debugStatus.headerStatsDisplay.value)}`,
              `debugCtxPct=${JSON.stringify(debugStatus.ctxPct.value)}`,
              `debugCtxPctChip=${JSON.stringify(debugStatus.ctxPctChip.value)}`,
              mounted.app.terminal.snapshot().lines.join("\n"),
            ].join("\n\n"),
        );
        await waitFor(
          () => {
            const screen = mounted.app.terminal.snapshot().lines.join("\n");
            const bottom = bottomSnapshotText(mounted.app, 10);
            return !bottom.includes("--") ? screen : null;
          },
          "TUI shell did not render request budget/context usage after the real-provider reply.",
          async () => {
            await sleep(250);
            await flushApp(mounted.app, 6);
          },
          80,
          () =>
            [
              `chromeVersion=${JSON.stringify(mounted.store?.state?.chromeVersion ?? null)}`,
              `messageCount=${JSON.stringify(Array.isArray(mounted.store?.state?.messages) ? mounted.store.state.messages.length : null)}`,
              `usage=${JSON.stringify(mounted.store?.state?.usage ?? null)}`,
              `lastRequestBudget=${JSON.stringify(mounted.store?.state?.lastRequestBudget ?? null)}`,
              `debugHeaderStats=${JSON.stringify(debugStatus.headerStatsDisplay.value)}`,
              `debugCtxPct=${JSON.stringify(debugStatus.ctxPct.value)}`,
              `debugCtxPctChip=${JSON.stringify(debugStatus.ctxPctChip.value)}`,
              mounted.app.terminal.snapshot().lines.join("\n"),
            ].join("\n\n"),
        );
        expect(bottomSnapshotText(mounted.app)).not.toContain(prompt);
      } finally {
        mounted.dispose();
        await mounted.runtime.close();
        if (previousDimcodeTest == null) {
          delete process.env.DIMCODE_TEST;
        } else {
          process.env.DIMCODE_TEST = previousDimcodeTest;
        }
      }
    },
    180_000,
  );

  itReal(
    "renders real provider thinking when available and otherwise omits the draft placeholder",
    async () => {
      const workspaceRoot = createWorkspace({
        "README.md": "# Tiny Reasoning Repo\n\nUse this repo to verify real provider thinking rendering.\n",
        "package.json": `${JSON.stringify({
          name: "tiny-reasoning-repo",
          private: true,
          scripts: {
            test: "vitest run",
          },
        }, null, 2)}\n`,
        "src/math.ts": [
          "export function average(values: number[]): number {",
          "  if (values.length === 0) return 0;",
          "  return values.reduce((sum, value) => sum + value, 0) / values.length;",
          "}",
          "",
        ].join("\n"),
      });
      const providerConfig = readRealProviderConfig();
      const storageRoot = resolveCliStorageRoot({
        cwd: workspaceRoot,
        storageRoot: mkdtempSync(`${tmpdir()}/best-agent-dimsdk-real-thinking-`),
      });
      tempRoots.push(storageRoot);
      writeFileSync(
        resolve(storageRoot, "cli-state.json"),
        `${JSON.stringify({ providerConfig }, null, 2)}\n`,
        "utf8",
      );

      const runtime = await createCliRuntime({
        cwd: workspaceRoot,
        storageRoot,
        providerConfig: providerConfig as any,
      });

      try {
        const requiredMarkers = [
          "DONE_REAL_THINKING",
          "TEST_RUNNER | vitest",
          "EMPTY_AVERAGE | 0",
        ];
        const prompt = [
          "Inspect README.md, package.json, and src/math.ts using workspace tools before answering.",
          "Then reply with exactly these three lines:",
          "DONE_REAL_THINKING",
          "TEST_RUNNER | vitest",
          "EMPTY_AVERAGE | 0",
          "If you cannot complete that exactly, reply with ERROR_REAL_THINKING.",
        ].join(" ");

        const { thread } = await runtime.startThread({
          title: "real provider thinking acceptance",
        });

        const result = await runtime.runTurn({
          threadId: thread.id,
          prompt,
        });
        expect(result.turn.status).toBe("completed");

        const history = await runtime.getThreadHistory({
          threadId: thread.id,
          limit: 200,
        });
        expect(history.items.some((item) => item.kind === "error")).toBe(false);
        expect(
          history.items.some(
            (item) =>
              item.kind === "tool-call"
              && (item.toolName === "read-file" || item.toolName === "read-file-range"),
          ),
        ).toBe(true);

        const reasoningItems = history.items.filter(
          (item): item is Extract<(typeof history.items)[number], { kind: "reasoning"; summary: string; status?: string }> =>
            item.kind === "reasoning",
        );
        expect(reasoningItems.length).toBeGreaterThan(0);
        const hasVisibleReasoning = reasoningItems.some(
          (item) =>
            item.status !== "draft"
            && item.summary.trim().length > 0
            && item.summary !== "Drafting a response from the orchestrator runtime profile.",
        );

        const bridge = createGoatChainBridge({ runtime });
        const messages = await bridge.hydrateThread(thread.id);
        const assistant = [...messages].reverse().find((message: any) => {
          if (message?.role !== "assistant") {
            return false;
          }
          const serialized = JSON.stringify(message);
          return requiredMarkers.every((marker) => serialized.includes(marker));
        });
        expect(assistant).toBeTruthy();

        const thinkingParts = assistant?.parts?.filter((part: any) => part?.type === "thinking") ?? [];
        const visibleThinking = thinkingParts
          .map((part: any) => String(part?.content ?? "").trim())
          .filter(Boolean);
        const renderedThinking = visibleThinking.join("\n");

        expect(JSON.stringify(assistant)).toContain("DONE_REAL_THINKING");
        expect(JSON.stringify(assistant)).not.toContain("ERROR_REAL_THINKING");
        if (hasVisibleReasoning) {
          expect(visibleThinking.length).toBeGreaterThan(0);
          expect(renderedThinking).not.toContain("Drafting a response from the orchestrator runtime profile.");
        } else {
          expect(thinkingParts).toHaveLength(0);
        }
      } finally {
        await runtime.close();
      }
    },
    240_000,
  );

  itReal(
    "resumes a real-provider ask-user turn and continues into a read-file follow-up",
    async () => {
      const previousDimcodeTest = process.env.DIMCODE_TEST;
      process.env.DIMCODE_TEST = "1";
      const workspaceRoot = createWorkspace({
        "README.md": "# Ask User Acceptance\n\nASK_USER_READ_MARKER_789\n",
      });
      const mounted = await mountRealShell({ cwd: workspaceRoot });
      try {
        const prompt = [
          "Your next action must be exactly one ask-user tool call.",
          "Ask me to choose dinner with question text Choose dinner and options Soup and Noodles.",
          "Do not guess the answer and do not answer before using ask-user.",
          "After I answer, use read-file on README.md before replying.",
          "Then reply with exactly two lines:",
          "DONE_ASK_USER_READ | <chosen option>",
          "README_MARKER | ASK_USER_READ_MARKER_789",
          "If you cannot complete that exactly, reply with ERROR_ASK_USER_READ.",
        ].join(" ");

        await typeText(mounted.app, prompt);
        await pressKey(mounted.app, "Enter", "Enter");

        const paused = await waitFor(
          () => (mounted.store?.state?.paused?.kind === "ask_user" ? mounted.store.state.paused : null),
          "Real provider did not pause for ask-user.",
          async () => {
            await sleep(250);
            await flushApp(mounted.app, 6);
          },
          240,
          () =>
            [
              `sessionId=${JSON.stringify(mounted.store?.state?.sessionId ?? null)}`,
              `paused=${JSON.stringify(mounted.store?.state?.paused ?? null)}`,
              `assistant=${latestAssistantJson(mounted.store)}`,
              bottomSnapshotText(mounted.app, 18),
            ].join("\n\n"),
        );

        const options = paused.questions?.[0]?.options ?? [];
        const noodleLabel = options.find((option: any) =>
          String(option?.label ?? "").toLowerCase().includes("noodle"),
        )?.label ?? "Noodles";

        expect(JSON.stringify(paused)).toContain("ask_user");
        expect(snapshotText(mounted.app)).toContain("Soup");
        expect(snapshotText(mounted.app)).toContain(String(noodleLabel));

        await clickLastText(mounted.app, String(noodleLabel));
        if (mounted.store?.state?.paused?.kind === "ask_user")
          await clickLastText(mounted.app, "[Submit]");

        await waitFor(
          () => (mounted.store?.state?.runningAgentRound && !mounted.store?.state?.paused ? true : null),
          "Submitting the ask-user choice did not resume the real provider turn.",
          async () => {
            await sleep(100);
            await flushApp(mounted.app, 4);
          },
          120,
          () =>
            [
              `paused=${JSON.stringify(mounted.store?.state?.paused ?? null)}`,
              `running=${JSON.stringify(mounted.store?.state?.runningAgentRound ?? null)}`,
              snapshotText(mounted.app),
            ].join("\n\n"),
        );

        const assistantJson = await waitFor(
          () => {
            const json = latestAssistantJson(mounted.store);
            return json.includes("DONE_ASK_USER_READ |") && json.includes("README_MARKER | ASK_USER_READ_MARKER_789")
              ? json
              : null;
          },
          "Real provider ask-user turn did not finish after submitting the selected option.",
          async () => {
            await sleep(250);
            await flushApp(mounted.app, 6);
          },
          480,
          () =>
            [
              `paused=${JSON.stringify(mounted.store?.state?.paused ?? null)}`,
              `usage=${JSON.stringify(mounted.store?.state?.usage ?? null)}`,
              `assistant=${latestAssistantJson(mounted.store)}`,
              bottomSnapshotText(mounted.app, 18),
            ].join("\n\n"),
        );

        expect(assistantJson).toContain(`DONE_ASK_USER_READ | ${String(noodleLabel)}`);
        expect(assistantJson).toContain("README_MARKER | ASK_USER_READ_MARKER_789");
        expect(assistantJson).not.toContain("ERROR_ASK_USER_READ");
        expect(snapshotText(mounted.app)).not.toContain("Awaiting answers");
        await waitFor(
          () => (!mounted.store?.state?.runningAgentRound && !mounted.store?.state?.paused ? true : null),
          "Real provider ask-user turn did not settle after the follow-up reply.",
          async () => {
            await sleep(100);
            await flushApp(mounted.app, 4);
          },
          120,
        );

        const history = await mounted.runtime.getThreadHistory({
          threadId: String(mounted.store.state.sessionId),
          limit: 300,
        });
        expect(history.items.some((item) => item.kind === "error")).toBe(false);
        expect(
          history.items.some(
            (item) => item.kind === "tool-call" && item.toolName === "ask-user",
          ),
        ).toBe(true);
        expect(
          history.items.some(
            (item) => item.kind === "tool-result" && item.toolName === "ask-user",
          ),
        ).toBe(true);
        expect(
          history.items.some(
            (item) =>
              item.kind === "tool-call"
              && (item.toolName === "read-file" || item.toolName === "read-file-range"),
          ),
        ).toBe(true);
      } finally {
        mounted.dispose();
        await mounted.runtime.close();
        if (previousDimcodeTest == null) {
          delete process.env.DIMCODE_TEST;
        } else {
          process.env.DIMCODE_TEST = previousDimcodeTest;
        }
      }
    },
    300_000,
  );

  itReal(
    "resumes a real-provider single-select ask-user turn immediately when the option is clicked",
    async () => {
      const previousDimcodeTest = process.env.DIMCODE_TEST;
      process.env.DIMCODE_TEST = "1";
      const workspaceRoot = createWorkspace({
        "README.md": "# Ask User Click Acceptance\n\nASK_USER_CLICK_MARKER_456\n",
      });
      const mounted = await mountRealShell({ cwd: workspaceRoot });
      try {
        const prompt = [
          "Your next action must be exactly one ask-user tool call.",
          "Ask me to choose a city with question text Choose city and options Beijing and Shanghai.",
          "Do not guess the answer and do not answer before using ask-user.",
          "After I answer, use read-file on README.md before replying.",
          "Then reply with exactly two lines:",
          "DONE_ASK_USER_CLICK | <chosen option>",
          "README_MARKER | ASK_USER_CLICK_MARKER_456",
          "If you cannot complete that exactly, reply with ERROR_ASK_USER_CLICK.",
        ].join(" ");

        await typeText(mounted.app, prompt);
        await pressKey(mounted.app, "Enter", "Enter");

        const paused = await waitFor(
          () => (mounted.store?.state?.paused?.kind === "ask_user" ? mounted.store.state.paused : null),
          "Real provider did not pause for single-click ask-user.",
          async () => {
            await sleep(250);
            await flushApp(mounted.app, 6);
          },
          240,
          () =>
            [
              `sessionId=${JSON.stringify(mounted.store?.state?.sessionId ?? null)}`,
              `paused=${JSON.stringify(mounted.store?.state?.paused ?? null)}`,
              `assistant=${latestAssistantJson(mounted.store)}`,
              bottomSnapshotText(mounted.app, 18),
            ].join("\n\n"),
        );

        const options = paused.questions?.[0]?.options ?? [];
        const shanghaiLabel = options.find((option: any) =>
          String(option?.label ?? "").toLowerCase().includes("shanghai"),
        )?.label ?? "Shanghai";

        await clickLastText(mounted.app, String(shanghaiLabel));

        await waitFor(
          () => (mounted.store?.state?.runningAgentRound && !mounted.store?.state?.paused ? true : null),
          "Clicking the single-select ask-user option did not resume the real provider turn.",
          async () => {
            await sleep(100);
            await flushApp(mounted.app, 4);
          },
          120,
          () =>
            [
              `paused=${JSON.stringify(mounted.store?.state?.paused ?? null)}`,
              `running=${JSON.stringify(mounted.store?.state?.runningAgentRound ?? null)}`,
              snapshotText(mounted.app),
            ].join("\n\n"),
        );

        const assistantJson = await waitFor(
          () => {
            const json = latestAssistantJson(mounted.store);
            return json.includes("DONE_ASK_USER_CLICK |") && json.includes("README_MARKER | ASK_USER_CLICK_MARKER_456")
              ? json
              : null;
          },
          "Real provider single-click ask-user turn did not finish after choosing Shanghai.",
          async () => {
            await sleep(250);
            await flushApp(mounted.app, 6);
          },
          480,
          () =>
            [
              `paused=${JSON.stringify(mounted.store?.state?.paused ?? null)}`,
              `usage=${JSON.stringify(mounted.store?.state?.usage ?? null)}`,
              `assistant=${latestAssistantJson(mounted.store)}`,
              bottomSnapshotText(mounted.app, 18),
            ].join("\n\n"),
        );

        expect(assistantJson).toContain(`DONE_ASK_USER_CLICK | ${String(shanghaiLabel)}`);
        expect(assistantJson).toContain("README_MARKER | ASK_USER_CLICK_MARKER_456");
        expect(assistantJson).not.toContain("ERROR_ASK_USER_CLICK");
        expect(snapshotText(mounted.app)).not.toContain("Awaiting answers");
        await waitFor(
          () => (!mounted.store?.state?.runningAgentRound && !mounted.store?.state?.paused ? true : null),
          "Real provider single-click ask-user turn did not settle after the follow-up reply.",
          async () => {
            await sleep(100);
            await flushApp(mounted.app, 4);
          },
          120,
        );

        const history = await mounted.runtime.getThreadHistory({
          threadId: String(mounted.store.state.sessionId),
          limit: 300,
        });
        expect(history.items.some((item) => item.kind === "error")).toBe(false);
        expect(
          history.items.some(
            (item) => item.kind === "tool-call" && item.toolName === "ask-user",
          ),
        ).toBe(true);
        expect(
          history.items.some(
            (item) => item.kind === "tool-result" && item.toolName === "ask-user",
          ),
        ).toBe(true);
        expect(
          history.items.some(
            (item) =>
              item.kind === "tool-call"
              && (item.toolName === "read-file" || item.toolName === "read-file-range"),
          ),
        ).toBe(true);
      } finally {
        mounted.dispose();
        await mounted.runtime.close();
        if (previousDimcodeTest == null) {
          delete process.env.DIMCODE_TEST;
        } else {
          process.env.DIMCODE_TEST = previousDimcodeTest;
        }
      }
    },
    300_000,
  );

  itReal(
    "resumes a real-provider ask-user turn into native web-search without leaking strict decision JSON",
    async () => {
      const previousDimcodeTest = process.env.DIMCODE_TEST;
      process.env.DIMCODE_TEST = "1";
      const workspaceRoot = createWorkspace({
        "README.md": "# Ask User Web Search Acceptance\n\nASK_USER_WEB_SEARCH_MARKER_987\n",
      });
      const mounted = await mountRealShell({ cwd: workspaceRoot });
      try {
        const prompt = [
          "Your next action must be exactly one ask-user tool call.",
          "Ask me to choose a city with question text Choose city and options Beijing and Shanghai.",
          "Do not guess the answer and do not answer before using ask-user.",
          "After I answer, you must use the web-search tool to look up today's weather for the chosen city.",
          "Do not use shell.",
          "After the web-search tool finishes, reply with exactly two lines:",
          "DONE_ASK_USER_WEB_SEARCH | <chosen option>",
          "WEATHER_TOOL_USED | yes",
          "If you cannot complete that exactly, reply with ERROR_ASK_USER_WEB_SEARCH.",
        ].join(" ");

        await typeText(mounted.app, prompt);
        await pressKey(mounted.app, "Enter", "Enter");

        const paused = await waitFor(
          () => (mounted.store?.state?.paused?.kind === "ask_user" ? mounted.store.state.paused : null),
          "Real provider did not pause for ask-user in the web-search scenario.",
          async () => {
            await sleep(250);
            await flushApp(mounted.app, 6);
          },
          240,
          () =>
            [
              `sessionId=${JSON.stringify(mounted.store?.state?.sessionId ?? null)}`,
              `paused=${JSON.stringify(mounted.store?.state?.paused ?? null)}`,
              `assistant=${latestAssistantJson(mounted.store)}`,
              bottomSnapshotText(mounted.app, 18),
            ].join("\n\n"),
        );

        const options = paused.questions?.[0]?.options ?? [];
        const shanghaiLabel = options.find((option: any) =>
          String(option?.label ?? "").toLowerCase().includes("shanghai"),
        )?.label ?? "Shanghai";

        await clickLastText(mounted.app, String(shanghaiLabel));

        await waitFor(
          () => (mounted.store?.state?.runningAgentRound && !mounted.store?.state?.paused ? true : null),
          "Clicking the ask-user option did not resume the web-search scenario.",
          async () => {
            await sleep(100);
            await flushApp(mounted.app, 4);
          },
          120,
          () =>
            [
              `paused=${JSON.stringify(mounted.store?.state?.paused ?? null)}`,
              `running=${JSON.stringify(mounted.store?.state?.runningAgentRound ?? null)}`,
              snapshotText(mounted.app),
            ].join("\n\n"),
        );

        const assistantJson = await waitFor(
          () => {
            const json = latestAssistantJson(mounted.store);
            return json.includes("DONE_ASK_USER_WEB_SEARCH |") && json.includes("WEATHER_TOOL_USED | yes")
              ? json
              : null;
          },
          "Real provider ask-user web-search turn did not finish after choosing Shanghai.",
          async () => {
            await sleep(250);
            await flushApp(mounted.app, 6);
          },
          480,
          () =>
            [
              `paused=${JSON.stringify(mounted.store?.state?.paused ?? null)}`,
              `usage=${JSON.stringify(mounted.store?.state?.usage ?? null)}`,
              `assistant=${latestAssistantJson(mounted.store)}`,
              bottomSnapshotText(mounted.app, 18),
            ].join("\n\n"),
        );

        expect(assistantJson).toContain(`DONE_ASK_USER_WEB_SEARCH | ${String(shanghaiLabel)}`);
        expect(assistantJson).toContain("WEATHER_TOOL_USED | yes");
        expect(assistantJson).not.toContain("ERROR_ASK_USER_WEB_SEARCH");
        expect(snapshotText(mounted.app)).not.toContain('{"kind":"tool","toolName":"web-search"');

        await waitFor(
          () => (!mounted.store?.state?.runningAgentRound && !mounted.store?.state?.paused ? true : null),
          "Real provider ask-user web-search turn did not settle after the follow-up reply.",
          async () => {
            await sleep(100);
            await flushApp(mounted.app, 4);
          },
          120,
        );

        const history = await mounted.runtime.getThreadHistory({
          threadId: String(mounted.store.state.sessionId),
          limit: 300,
        });
        expect(history.items.some((item) => item.kind === "error")).toBe(false);
        expect(
          history.items.some(
            (item) => item.kind === "tool-call" && item.toolName === "ask-user",
          ),
        ).toBe(true);
        expect(
          history.items.some(
            (item) => item.kind === "tool-result" && item.toolName === "ask-user",
          ),
        ).toBe(true);
        expect(
          history.items.some(
            (item) => item.kind === "tool-call" && item.toolName === "web-search",
          ),
        ).toBe(true);
        expect(
          history.items.some(
            (item) => item.kind === "tool-result" && item.toolName === "web-search",
          ),
        ).toBe(true);
      } finally {
        mounted.dispose();
        await mounted.runtime.close();
        if (previousDimcodeTest == null) {
          delete process.env.DIMCODE_TEST;
        } else {
          process.env.DIMCODE_TEST = previousDimcodeTest;
        }
      }
    },
    300_000,
  );

  itReal(
    "keeps a live ask-user web-search visible on click, expands real thinking content, and rehydrates the same reasoning after reopen",
    async () => {
      const previousDimcodeTest = process.env.DIMCODE_TEST;
      process.env.DIMCODE_TEST = "1";
      const workspaceRoot = createWorkspace({
        "README.md": "# Ask User Web Tool Click Acceptance\n\nASK_USER_WEB_TOOL_CLICK_MARKER_321\n",
      });
      const mounted = await mountRealShell({ cwd: workspaceRoot });
      let mountedClosed = false;
      let threadId = "";

      try {
        const prompt = [
          "Your next action must be exactly one ask-user tool call.",
          "Ask me to choose a city with question text Choose city and options Beijing and Shanghai.",
          "Do not guess the answer and do not answer before using ask-user.",
          "After I answer, you must call web-search for today's weather in the chosen city.",
          "Do not use shell.",
          "Reply only after web-search has completed.",
          "Then reply with exactly two lines:",
          "DONE_ASK_USER_WEB_SEARCH_CLICK | <chosen option>",
          "WEB_SEARCH_USED | yes",
          "If you cannot complete that exactly, reply with ERROR_ASK_USER_WEB_SEARCH_CLICK.",
        ].join(" ");

        await typeText(mounted.app, prompt);
        await pressKey(mounted.app, "Enter", "Enter");

        const paused = await waitFor(
          () => (mounted.store?.state?.paused?.kind === "ask_user" ? mounted.store.state.paused : null),
          "Real provider did not pause for ask-user in the web-tool click scenario.",
          async () => {
            await sleep(250);
            await flushApp(mounted.app, 6);
          },
          240,
          () =>
            [
              `sessionId=${JSON.stringify(mounted.store?.state?.sessionId ?? null)}`,
              `paused=${JSON.stringify(mounted.store?.state?.paused ?? null)}`,
              `assistant=${latestAssistantJson(mounted.store)}`,
              bottomSnapshotText(mounted.app, 18),
            ].join("\n\n"),
        );

        const options = paused.questions?.[0]?.options ?? [];
        const shanghaiLabel = options.find((option: any) =>
          String(option?.label ?? "").toLowerCase().includes("shanghai"),
        )?.label ?? "Shanghai";

        await clickLastText(mounted.app, String(shanghaiLabel));

        await waitFor(
          () => (mounted.store?.state?.runningAgentRound && !mounted.store?.state?.paused ? true : null),
          "Clicking the ask-user option did not resume the web-tool click scenario.",
          async () => {
            await sleep(100);
            await flushApp(mounted.app, 4);
          },
          120,
          () =>
            [
              `paused=${JSON.stringify(mounted.store?.state?.paused ?? null)}`,
              `running=${JSON.stringify(mounted.store?.state?.runningAgentRound ?? null)}`,
              snapshotText(mounted.app),
            ].join("\n\n"),
        );

        const liveState = await waitFor(
          () => {
            if (!mounted.store?.state?.runningAgentRound) {
              return null;
            }
            const assistant = latestAssistant(mounted.store);
            if (!assistant) {
              return null;
            }
            const thinkingParts = (assistant.parts ?? []).filter((part: any) =>
              part?.type === "thinking" && normalizeReasoningText(String(part?.content ?? "")).length > 0,
            );
            if (thinkingParts.length === 0) {
              return null;
            }
            const toolCalls = (assistant.parts ?? []).filter((part: any) =>
              part?.type === "tool_call"
              && String(part?.call?.name ?? "") === "web-search",
            );
            if (toolCalls.length === 0) {
              return null;
            }
            const pendingToolCall
              = [...toolCalls].reverse().find((part: any) => {
                  const callId = String(part?.call?.id ?? "");
                  if (!callId) {
                    return false;
                  }
                  return !(assistant.parts ?? []).some((candidate: any) =>
                    candidate?.type === "tool_result"
                    && String(candidate?.result?.toolCallId ?? "") === callId,
                  );
                })
                ?? toolCalls[toolCalls.length - 1];
            const liveThinkingPart = thinkingParts[thinkingParts.length - 1];
            const thinkingText = String(liveThinkingPart?.content ?? "");
            const normalizedThinking = normalizeReasoningText(thinkingText);
            if (!normalizedThinking) {
              return null;
            }
            const toolName = String(pendingToolCall?.call?.name ?? "");
            const toolCallId = String(pendingToolCall?.call?.id ?? "");
            const thinkingPartId = String(liveThinkingPart?.partId ?? "");
            if (!toolName || !toolCallId || !thinkingPartId) {
              return null;
            }
            return {
              thinkingExcerpt: normalizedThinking.slice(0, Math.min(48, normalizedThinking.length)),
              thinkingPartId,
              toolCallId,
              toolName,
            };
          },
          "Real provider did not surface live thinking plus a clickable web-search before the reply finished.",
          async () => {
            await sleep(100);
            await flushApp(mounted.app, 4);
          },
          300,
          () =>
            [
              `running=${JSON.stringify(mounted.store?.state?.runningAgentRound ?? null)}`,
              `selectedToolCallId=${JSON.stringify(mounted.store?.state?.selectedToolCallId ?? null)}`,
              `assistant=${latestAssistantJson(mounted.store)}`,
              bottomSnapshotText(mounted.app, 18),
            ].join("\n\n"),
        );

        await clickLastText(mounted.app, liveState.toolName);

        await waitFor(
          () => {
            const assistant = latestAssistant(mounted.store);
            if (!assistant) {
              return null;
            }
            const snapshot = snapshotText(mounted.app);
            const hasToolCall = (assistant.parts ?? []).some((part: any) =>
              part?.type === "tool_call" && String(part?.call?.id ?? "") === liveState.toolCallId,
            );
            if (!hasToolCall || !snapshot.includes(liveState.toolName)) {
              return null;
            }
            if (!mounted.store.state.ui.expandToolCallsAndThinking) {
              return String(mounted.store?.state?.selectedToolCallId ?? "") === liveState.toolCallId
                ? snapshot
                : null;
            }
            return snapshot;
          },
          "Clicking a live web-search hid it instead of keeping the tool row visible.",
          async () => {
            await sleep(100);
            await flushApp(mounted.app, 4);
          },
          80,
          () =>
            [
              `selectedToolCallId=${JSON.stringify(mounted.store?.state?.selectedToolCallId ?? null)}`,
              `assistant=${latestAssistantJson(mounted.store)}`,
              snapshotText(mounted.app),
            ].join("\n\n"),
        );

        await clickLastText(mounted.app, "Thinking");

        await waitFor(
          () => {
            const assistant = latestAssistant(mounted.store);
            if (!assistant) {
              return null;
            }
            const matchingThinking = (assistant.parts ?? []).find((part: any) =>
              part?.type === "thinking"
              && String(part?.partId ?? "") === liveState.thinkingPartId
              && part?.collapsed === false
              && normalizeReasoningText(String(part?.content ?? "")).includes(liveState.thinkingExcerpt),
            );
            if (!matchingThinking) {
              return null;
            }
            const normalizedSnapshot = normalizeReasoningText(snapshotText(mounted.app));
            return normalizedSnapshot.includes(liveState.thinkingExcerpt)
              ? matchingThinking
              : null;
          },
          "Clicking Thinking did not reveal the real reasoning text for the live web-search turn.",
          async () => {
            await sleep(100);
            await flushApp(mounted.app, 4);
          },
          80,
          () =>
            [
              `assistant=${latestAssistantJson(mounted.store)}`,
              snapshotText(mounted.app),
            ].join("\n\n"),
        );

        const assistantJson = await waitFor(
          () => {
            const json = latestAssistantJson(mounted.store);
            return !mounted.store?.state?.runningAgentRound
              && !mounted.store?.state?.paused
              && json.includes("DONE_ASK_USER_WEB_SEARCH_CLICK |")
              && json.includes("WEB_SEARCH_USED | yes")
              ? json
              : null;
          },
          "Real provider web-search click scenario did not settle after the live click interactions.",
          async () => {
            await sleep(250);
            await flushApp(mounted.app, 6);
          },
          480,
          () =>
            [
              `running=${JSON.stringify(mounted.store?.state?.runningAgentRound ?? null)}`,
              `paused=${JSON.stringify(mounted.store?.state?.paused ?? null)}`,
              `assistant=${latestAssistantJson(mounted.store)}`,
              bottomSnapshotText(mounted.app, 18),
            ].join("\n\n"),
        );

        expect(assistantJson).toContain(`DONE_ASK_USER_WEB_SEARCH_CLICK | ${String(shanghaiLabel)}`);
        expect(assistantJson).toContain("WEB_SEARCH_USED | yes");
        expect(assistantJson).not.toContain("ERROR_ASK_USER_WEB_SEARCH_CLICK");

        threadId = String(mounted.store.state.sessionId ?? "");
        const liveAssistant = latestAssistant(mounted.store);
        const liveThinkingTexts = (liveAssistant?.parts ?? [])
          .filter((part: any) => part?.type === "thinking")
          .map((part: any) => normalizeReasoningText(String(part?.content ?? "")))
          .filter(Boolean);
        expect(
          (liveAssistant?.parts ?? [])
            .filter((part: any) => part?.type === "thinking")
            .every((part: any) => String(part?.partId ?? "").trim().length > 0),
        ).toBe(true);
        expect(liveThinkingTexts.length).toBeGreaterThan(0);

        const history = await mounted.runtime.getThreadHistory({
          threadId,
          limit: 400,
        });
        expect(
          history.items.some(
            (item) => item.kind === "tool-call" && item.toolName === "ask-user",
          ),
        ).toBe(true);
        expect(
          history.items.some(
            (item) => item.kind === "tool-call" && item.toolName === "web-search",
          ),
        ).toBe(true);

        mounted.dispose();
        await mounted.runtime.close();
        mountedClosed = true;

        const reopenedRuntime = await createCliRuntime({
          cwd: workspaceRoot,
          storageRoot: mounted.storageRoot,
        });
        try {
          const bridge = createGoatChainBridge({ runtime: reopenedRuntime });
          const messages = await bridge.hydrateThread(threadId as any);
          const reopenedAssistant = [...messages].reverse().find((message: any) =>
            message?.role === "assistant",
          );
          const hydratedThinkingTexts = (reopenedAssistant?.parts ?? [])
            .filter((part: any) => part?.type === "thinking")
            .map((part: any) => normalizeReasoningText(String(part?.content ?? "")))
            .filter(Boolean);
          expect(
            (reopenedAssistant?.parts ?? [])
              .filter((part: any) => part?.type === "thinking")
              .every((part: any) => String(part?.partId ?? "").trim().length > 0),
          ).toBe(true);

          expect(hydratedThinkingTexts.length).toBeGreaterThan(0);
          expect(
            hydratedThinkingTexts.some((text: string) =>
              liveThinkingTexts.some((liveText: string) => liveText.includes(text) || text.includes(liveText)),
            ),
          ).toBe(true);
        } finally {
          await reopenedRuntime.close();
        }
      } finally {
        if (!mountedClosed) {
          mounted.dispose();
          await mounted.runtime.close();
        }
        if (previousDimcodeTest == null) {
          delete process.env.DIMCODE_TEST;
        } else {
          process.env.DIMCODE_TEST = previousDimcodeTest;
        }
      }
    },
    360_000,
  );

  itReal(
    "keeps reasoning hydrate correct after a real-provider ask-user turn reopens",
    async () => {
      const previousDimcodeTest = process.env.DIMCODE_TEST;
      process.env.DIMCODE_TEST = "1";
      const workspaceRoot = createWorkspace({
        "README.md": "# Ask User Thinking Hydrate\n\nASK_USER_THINKING_HYDRATE_MARKER_654\n",
      });
      const mounted = await mountRealShell({ cwd: workspaceRoot });
      let threadId = "";
      let liveReasoningState = "";

      try {
        const prompt = [
          "Your next action must be exactly one ask-user tool call.",
          "Ask me to choose a city with question text Choose city and options Beijing and Shanghai.",
          "Do not guess the answer and do not answer before using ask-user.",
          "After I answer, use read-file on README.md before replying.",
          "Do not use shell.",
          "Then reply with exactly two lines:",
          "DONE_ASK_USER_THINKING_HYDRATE | <chosen option>",
          "README_MARKER | ASK_USER_THINKING_HYDRATE_MARKER_654",
          "If you cannot complete that exactly, reply with ERROR_ASK_USER_THINKING_HYDRATE.",
        ].join(" ");

        await typeText(mounted.app, prompt);
        await pressKey(mounted.app, "Enter", "Enter");

        const paused = await waitFor(
          () => (mounted.store?.state?.paused?.kind === "ask_user" ? mounted.store.state.paused : null),
          "Real provider did not pause for ask-user in the reasoning hydrate scenario.",
          async () => {
            await sleep(250);
            await flushApp(mounted.app, 6);
          },
          240,
          () =>
            [
              `sessionId=${JSON.stringify(mounted.store?.state?.sessionId ?? null)}`,
              `paused=${JSON.stringify(mounted.store?.state?.paused ?? null)}`,
              `assistant=${latestAssistantJson(mounted.store)}`,
              bottomSnapshotText(mounted.app, 18),
            ].join("\n\n"),
        );

        const options = paused.questions?.[0]?.options ?? [];
        const shanghaiLabel = options.find((option: any) =>
          String(option?.label ?? "").toLowerCase().includes("shanghai"),
        )?.label ?? "Shanghai";

        await clickLastText(mounted.app, String(shanghaiLabel));

        await waitFor(
          () => (mounted.store?.state?.runningAgentRound && !mounted.store?.state?.paused ? true : null),
          "Clicking the ask-user option did not resume the reasoning hydrate scenario.",
          async () => {
            await sleep(100);
            await flushApp(mounted.app, 4);
          },
          120,
          () =>
            [
              `paused=${JSON.stringify(mounted.store?.state?.paused ?? null)}`,
              `running=${JSON.stringify(mounted.store?.state?.runningAgentRound ?? null)}`,
              snapshotText(mounted.app),
            ].join("\n\n"),
        );

        const assistant = await waitFor(
          () => {
            const messages = Array.isArray(mounted.store?.state?.messages)
              ? mounted.store.state.messages
              : [];
            const candidate = [...messages].reverse().find((message: any) =>
              message?.role === "assistant"
              && JSON.stringify(message).includes("DONE_ASK_USER_THINKING_HYDRATE")
              && JSON.stringify(message).includes("ASK_USER_THINKING_HYDRATE_MARKER_654")
            );
            const hasReasoningInfo = candidate?.parts?.some(
              (part: any) => part?.type === "info" && typeof part?._reasoning === "string",
            );
            const runSettled
              = mounted.store?.state?.runningAgentRound === false
                && !mounted.store?.state?.paused;
            return candidate && hasReasoningInfo && runSettled ? candidate : null;
          },
          "Real provider ask-user reasoning hydrate scenario did not finish.",
          async () => {
            await sleep(250);
            await flushApp(mounted.app, 6);
          },
          480,
          () =>
            [
              `sessionId=${JSON.stringify(mounted.store?.state?.sessionId ?? null)}`,
              `paused=${JSON.stringify(mounted.store?.state?.paused ?? null)}`,
              `usage=${JSON.stringify(mounted.store?.state?.usage ?? null)}`,
              `assistant=${latestAssistantJson(mounted.store)}`,
              bottomSnapshotText(mounted.app, 18),
            ].join("\n\n"),
        ) as any;

        const assistantJson = JSON.stringify(assistant);
        const liveThinkingParts = assistant?.parts?.filter((part: any) => part?.type === "thinking") ?? [];
        const liveThinkingTexts = liveThinkingParts
          .map((part: any) => String(part?.content ?? "").trim())
          .filter(Boolean);
        const liveInfoPart = [...(assistant?.parts ?? [])]
          .reverse()
          .find((part: any) => part?.type === "info" && typeof part?._reasoning === "string");

        expect(assistantJson).toContain(`DONE_ASK_USER_THINKING_HYDRATE | ${String(shanghaiLabel)}`);
        expect(assistantJson).toContain("README_MARKER | ASK_USER_THINKING_HYDRATE_MARKER_654");
        expect(assistantJson).not.toContain("ERROR_ASK_USER_THINKING_HYDRATE");
        expect(snapshotText(mounted.app)).not.toContain("Awaiting answers");
        expect(["visible", "tokens_only", "none"]).toContain(liveInfoPart?._reasoning);

        threadId = String(mounted.store?.state?.sessionId ?? "");
        liveReasoningState = String(liveInfoPart?._reasoning ?? "");

        expect(threadId).toBeTruthy();
        if (liveReasoningState === "visible") {
          const normalizedLiveThinking = normalizeReasoningText(liveThinkingTexts.join("\n"));
          expect(normalizedLiveThinking.length).toBeGreaterThan(0);
          expect(normalizedLiveThinking).not.toContain(
            "Drafting a response from the orchestrator runtime profile.",
          );
        } else {
          expect(liveThinkingTexts).toHaveLength(0);
        }

        const history = await mounted.runtime.getThreadHistory({
          threadId,
          limit: 300,
        });
        expect(history.items.some((item) => item.kind === "error")).toBe(false);
        expect(
          history.items.some(
            (item) => item.kind === "tool-call" && item.toolName === "ask-user",
          ),
        ).toBe(true);
        expect(
          history.items.some(
            (item) => item.kind === "tool-result" && item.toolName === "ask-user",
          ),
        ).toBe(true);
        expect(
          history.items.some(
            (item) =>
              item.kind === "tool-call"
              && (item.toolName === "read-file" || item.toolName === "read-file-range"),
          ),
        ).toBe(true);

        const bridge = createGoatChainBridge({ runtime: mounted.runtime });
        await waitForAsync(
          async () => {
            const messages = await bridge.hydrateThread(threadId as any);
            const hydratedAssistant = [...messages].reverse().find((message: any) =>
              message?.role === "assistant"
              && JSON.stringify(message).includes("DONE_ASK_USER_THINKING_HYDRATE")
              && JSON.stringify(message).includes("ASK_USER_THINKING_HYDRATE_MARKER_654")
            ) as any;
            if (!hydratedAssistant) {
              return null;
            }
            const hydratedThinkingTexts
              = (hydratedAssistant?.parts ?? [])
                .filter((part: any) => part?.type === "thinking")
                .map((part: any) => String(part?.content ?? "").trim())
                .filter(Boolean);
            const hydratedInfoPart = [...(hydratedAssistant?.parts ?? [])]
              .reverse()
              .find((part: any) => part?.type === "info" && typeof part?._reasoning === "string");
            if (String(hydratedInfoPart?._reasoning ?? "") !== liveReasoningState) {
              return null;
            }
            if (liveReasoningState === "visible") {
              const normalizedHydratedThinking = normalizeReasoningText(
                hydratedThinkingTexts.join("\n"),
              );
              return normalizedHydratedThinking.length > 0
                && !normalizedHydratedThinking.includes(
                  "Drafting a response from the orchestrator runtime profile.",
                )
                ? true
                : null;
            }
            return hydratedThinkingTexts.length === 0 ? true : null;
          },
          "Persisted ask-user reasoning hydrate snapshot did not settle before reopen.",
          async () => {
            await sleep(250);
            await flushApp(mounted.app, 2);
          },
          80,
        );
      } finally {
        mounted.dispose();
        await mounted.runtime.close();
      }

      const reopenedRuntime = await createCliRuntime({
        cwd: workspaceRoot,
        storageRoot: mounted.storageRoot,
        providerConfig: readRealProviderConfig() as any,
      });

      try {
        const bridge = createGoatChainBridge({ runtime: reopenedRuntime });
        const messages = await bridge.hydrateThread(threadId as any);
        const assistant = [...messages].reverse().find((message: any) =>
          message?.role === "assistant"
          && JSON.stringify(message).includes("DONE_ASK_USER_THINKING_HYDRATE")
          && JSON.stringify(message).includes("ASK_USER_THINKING_HYDRATE_MARKER_654")
        ) as any;

        const hydratedThinkingParts = assistant?.parts?.filter((part: any) => part?.type === "thinking") ?? [];
        const hydratedThinkingTexts = hydratedThinkingParts
          .map((part: any) => String(part?.content ?? "").trim())
          .filter(Boolean);
        const hydratedInfoPart = [...(assistant?.parts ?? [])]
          .reverse()
          .find((part: any) => part?.type === "info" && typeof part?._reasoning === "string");

        expect(assistant).toBeTruthy();
        expect(hydratedInfoPart?._reasoning).toBe(liveReasoningState);
        if (liveReasoningState === "visible") {
          const normalizedHydratedThinking = normalizeReasoningText(
            hydratedThinkingTexts.join("\n"),
          );
          expect(normalizedHydratedThinking.length).toBeGreaterThan(0);
          expect(normalizedHydratedThinking).not.toContain(
            "Drafting a response from the orchestrator runtime profile.",
          );
        } else {
          expect(hydratedThinkingTexts).toHaveLength(0);
        }
      } finally {
        await reopenedRuntime.close();
        if (previousDimcodeTest == null) {
          delete process.env.DIMCODE_TEST;
        } else {
          process.env.DIMCODE_TEST = previousDimcodeTest;
        }
      }
    },
    300_000,
  );

  itReal(
    "preserves real provider reasoning render state across reopen after a tool-assisted turn",
    async () => {
      const previousDimcodeTest = process.env.DIMCODE_TEST;
      process.env.DIMCODE_TEST = "1";
      const workspaceRoot = createWorkspace({
        "README.md": "# Real TUI Thinking\n\nREAL_TUI_THINKING_MARKER_321\n",
      });
      const mounted = await mountRealShell({ cwd: workspaceRoot });
      let threadId = "";
      let liveReasoningState = "";

      try {
        const prompt = [
          "Inspect README.md using read-file or read-file-range before answering.",
          "Do not use shell.",
          "Reply with exactly two lines:",
          "DONE_REAL_TUI_THINKING",
          "README_MARKER | REAL_TUI_THINKING_MARKER_321",
          "If you cannot complete that exactly, reply with ERROR_REAL_TUI_THINKING.",
        ].join(" ");

        await typeText(mounted.app, prompt);
        await pressKey(mounted.app, "Enter", "Enter");

        const assistant = await waitFor(
          () => {
            const messages = Array.isArray(mounted.store?.state?.messages)
              ? mounted.store.state.messages
              : [];
            const candidate = [...messages].reverse().find((message: any) =>
              message?.role === "assistant"
              && JSON.stringify(message).includes("DONE_REAL_TUI_THINKING")
              && JSON.stringify(message).includes("REAL_TUI_THINKING_MARKER_321")
            );
            const hasReasoningInfo = candidate?.parts?.some(
              (part: any) => part?.type === "info" && typeof part?._reasoning === "string",
            );
            const runSettled
              = mounted.store?.state?.runningAgentRound === false
                && !mounted.store?.state?.paused;
            return candidate && hasReasoningInfo && runSettled ? candidate : null;
          },
          "Real provider TUI turn did not finish the reasoning persistence scenario.",
          async () => {
            await sleep(250);
            await flushApp(mounted.app, 6);
          },
          480,
          () =>
            [
              `sessionId=${JSON.stringify(mounted.store?.state?.sessionId ?? null)}`,
              `paused=${JSON.stringify(mounted.store?.state?.paused ?? null)}`,
              `usage=${JSON.stringify(mounted.store?.state?.usage ?? null)}`,
              `assistant=${latestAssistantJson(mounted.store)}`,
              bottomSnapshotText(mounted.app, 18),
            ].join("\n\n"),
        ) as any;

        const assistantJson = JSON.stringify(assistant);
        const liveThinkingParts = assistant?.parts?.filter((part: any) => part?.type === "thinking") ?? [];
        const liveInfoPart = [...(assistant?.parts ?? [])]
          .reverse()
          .find((part: any) => part?.type === "info" && typeof part?._reasoning === "string");
        const liveThinkingTexts = liveThinkingParts
          .map((part: any) => String(part?.content ?? "").trim())
          .filter(Boolean);

        expect(assistantJson).toContain("DONE_REAL_TUI_THINKING");
        expect(assistantJson).toContain("REAL_TUI_THINKING_MARKER_321");
        expect(assistantJson).not.toContain("ERROR_REAL_TUI_THINKING");
        expect(["visible", "tokens_only", "none"]).toContain(liveInfoPart?._reasoning);

        threadId = String(mounted.store?.state?.sessionId ?? "");
        liveReasoningState = String(liveInfoPart?._reasoning ?? "");

        expect(threadId).toBeTruthy();
        if (liveReasoningState === "visible") {
          const normalizedLiveThinking = normalizeReasoningText(liveThinkingTexts.join("\n"));
          expect(normalizedLiveThinking.length).toBeGreaterThan(0);
          expect(normalizedLiveThinking).not.toContain(
            "Drafting a response from the orchestrator runtime profile.",
          );
        } else {
          expect(liveThinkingTexts).toHaveLength(0);
        }

        const history = await mounted.runtime.getThreadHistory({
          threadId: threadId as any,
          limit: 300,
        });
        expect(history.items.some((item) => item.kind === "error")).toBe(false);
        expect(
          history.items.some(
            (item) =>
              item.kind === "tool-call"
              && (item.toolName === "read-file" || item.toolName === "read-file-range"),
          ),
        ).toBe(true);

        const bridge = createGoatChainBridge({ runtime: mounted.runtime });
        await waitForAsync(
          async () => {
            const messages = await bridge.hydrateThread(threadId as any);
            const hydratedAssistant = [...messages].reverse().find((message: any) =>
              message?.role === "assistant"
              && JSON.stringify(message).includes("DONE_REAL_TUI_THINKING")
              && JSON.stringify(message).includes("REAL_TUI_THINKING_MARKER_321")
            ) as any;
            if (!hydratedAssistant) {
              return null;
            }
            const hydratedThinkingTexts
              = (hydratedAssistant?.parts ?? [])
                .filter((part: any) => part?.type === "thinking")
                .map((part: any) => String(part?.content ?? "").trim())
                .filter(Boolean);
            const hydratedInfoPart = [...(hydratedAssistant?.parts ?? [])]
              .reverse()
              .find((part: any) => part?.type === "info" && typeof part?._reasoning === "string");
            if (String(hydratedInfoPart?._reasoning ?? "") !== liveReasoningState) {
              return null;
            }
            if (liveReasoningState === "visible") {
              const normalizedHydratedThinking = normalizeReasoningText(
                hydratedThinkingTexts.join("\n"),
              );
              return normalizedHydratedThinking.length > 0
                && !normalizedHydratedThinking.includes(
                  "Drafting a response from the orchestrator runtime profile.",
                )
                ? true
                : null;
            }
            return hydratedThinkingTexts.length === 0 ? true : null;
          },
          "Persisted real-provider reasoning snapshot did not settle before reopen.",
          async () => {
            await sleep(250);
            await flushApp(mounted.app, 2);
          },
          80,
        );
      } finally {
        mounted.dispose();
        await mounted.runtime.close();
      }

      const reopenedRuntime = await createCliRuntime({
        cwd: workspaceRoot,
        storageRoot: mounted.storageRoot,
        providerConfig: readRealProviderConfig() as any,
      });

      try {
        const bridge = createGoatChainBridge({ runtime: reopenedRuntime });
        const messages = await bridge.hydrateThread(threadId as any);
        const assistant = [...messages].reverse().find((message: any) =>
          message?.role === "assistant"
          && JSON.stringify(message).includes("DONE_REAL_TUI_THINKING")
          && JSON.stringify(message).includes("REAL_TUI_THINKING_MARKER_321")
        ) as any;

        const hydratedThinkingParts = assistant?.parts?.filter((part: any) => part?.type === "thinking") ?? [];
        const hydratedThinkingTexts = hydratedThinkingParts
          .map((part: any) => String(part?.content ?? "").trim())
          .filter(Boolean);
        const hydratedInfoPart = [...(assistant?.parts ?? [])]
          .reverse()
          .find((part: any) => part?.type === "info" && typeof part?._reasoning === "string");

        expect(assistant).toBeTruthy();
        expect(hydratedInfoPart?._reasoning).toBe(liveReasoningState);
        if (liveReasoningState === "visible") {
          const normalizedHydratedThinking = normalizeReasoningText(
            hydratedThinkingTexts.join("\n"),
          );
          expect(normalizedHydratedThinking.length).toBeGreaterThan(0);
          expect(normalizedHydratedThinking).not.toContain(
            "Drafting a response from the orchestrator runtime profile.",
          );
        } else {
          expect(hydratedThinkingTexts).toHaveLength(0);
        }
      } finally {
        await reopenedRuntime.close();
        if (previousDimcodeTest == null) {
          delete process.env.DIMCODE_TEST;
        } else {
          process.env.DIMCODE_TEST = previousDimcodeTest;
        }
      }
    },
    300_000,
  );

  itReal(
    "analyzes a small repository and reviews every file with a real provider request",
    async () => {
      const previousDimcodeTest = process.env.DIMCODE_TEST;
      process.env.DIMCODE_TEST = "1";
      const workspaceRoot = createWorkspace({
        "README.md": "# Tiny Math Repo\n\nA tiny demo repo for real-provider acceptance.\n",
        "package.json": `${JSON.stringify({
          name: "tiny-math-repo",
          private: true,
          scripts: {
            test: "vitest run",
          },
        }, null, 2)}\n`,
        "src/math.ts": [
          "export function divide(total: number, count: number): number {",
          "  return total / count;",
          "}",
          "",
          "export function average(values: number[]): number {",
          "  if (values.length === 0) return 0;",
          "  return divide(values.reduce((sum, value) => sum + value, 0), values.length);",
          "}",
          "",
        ].join("\n"),
        "src/format.ts": [
          "export function formatAverage(label: string, value: number): string {",
          "  return `${label}: ${value.toFixed(3)}`;",
          "}",
          "",
        ].join("\n"),
        "test/math.test.ts": [
          "import { describe, expect, it } from \"vitest\";",
          "import { average } from \"../src/math\";",
          "",
          "describe(\"average\", () => {",
          "  it(\"returns the mean of a small list\", () => {",
          "    expect(average([2, 4, 6])).toBe(4);",
          "  });",
          "});",
          "",
        ].join("\n"),
      });
      const mounted = await mountRealShell({ cwd: workspaceRoot });
      try {
        const expectedFiles = [
          "README.md",
          "package.json",
          "src/math.ts",
          "src/format.ts",
          "test/math.test.ts",
        ] as const;
        const requiredMarkers = [
          "DONE_REPO_REVIEW",
          ...expectedFiles.map((filePath) => `FILE REVIEW | ${filePath} |`),
        ];
        const prompt = [
          "Analyze this repository and review every file.",
          "Use tools to inspect the files before answering.",
          `The repo has exactly these files: ${expectedFiles.join(", ")}.`,
          "Reply with DONE_REPO_REVIEW on its own line, then one line per file in the format FILE REVIEW | <path> | <comment>.",
          "Do not skip any file. If you cannot finish, reply with ERROR_REPO_REVIEW.",
        ].join(" ");

        await typeText(mounted.app, prompt);
        await pressKey(mounted.app, "Enter", "Enter");

        const assistantJson = await waitFor(
          () => {
            const json = latestAssistantJson(mounted.store);
            return requiredMarkers.every((marker) => json.includes(marker)) ? json : null;
          },
          "TUI shell did not finish the real-provider repository review task.",
          async () => {
            await sleep(250);
            await flushApp(mounted.app, 6);
          },
          480,
          () =>
            [
              `sessionId=${JSON.stringify(mounted.store?.state?.sessionId ?? null)}`,
              `usage=${JSON.stringify(mounted.store?.state?.usage ?? null)}`,
              `assistant=${latestAssistantJson(mounted.store)}`,
              bottomSnapshotText(mounted.app, 16),
            ].join("\n\n"),
        );

        expect(assistantJson).toContain("DONE_REPO_REVIEW");
        expect(assistantJson).not.toContain("ERROR_REPO_REVIEW");
        expect(assistantJson).not.toContain("Turn failed.");
        expect(assistantJson).not.toContain("The operation was aborted due to timeout");
        for (const filePath of expectedFiles) {
          expect(assistantJson).toContain(`FILE REVIEW | ${filePath} |`);
        }

        await waitFor(
          () => {
            const totalTokens = Number(mounted.store?.state?.usage?.total_tokens ?? 0);
            return Number.isFinite(totalTokens) && totalTokens > 0 ? totalTokens : null;
          },
          "TUI shell did not surface token usage after the repository review task.",
          async () => {
            await sleep(250);
            await flushApp(mounted.app, 6);
          },
          120,
        );

        const history = await mounted.runtime.getThreadHistory({
          threadId: String(mounted.store.state.sessionId),
          limit: 200,
        });
        expect(
          history.items.some(
            (item) =>
              item.kind === "tool-call"
              && (item.toolName === "read-file" || item.toolName === "read-file-range" || item.toolName === "shell"),
          ),
        ).toBe(true);
        expect(history.items.some((item) => item.kind === "error")).toBe(false);
      } finally {
        mounted.dispose();
        await mounted.runtime.close();
        if (previousDimcodeTest == null) {
          delete process.env.DIMCODE_TEST;
        } else {
          process.env.DIMCODE_TEST = previousDimcodeTest;
        }
      }
    },
    300_000,
  );

  itReal(
    "uses the shell tool in a real provider turn and returns the workspace path",
    async () => {
      const workspaceRoot = createWorkspace({
        "README.md": "# Real shell acceptance\n",
      });
      const expectedWorkspacePath = realpathSync(workspaceRoot);
      const providerConfig = readRealProviderConfig();
      const storageRoot = resolveCliStorageRoot({
        cwd: workspaceRoot,
        storageRoot: mkdtempSync(`${tmpdir()}/best-agent-dimsdk-real-shell-`),
      });
      tempRoots.push(storageRoot);
      writeFileSync(
        resolve(storageRoot, "cli-state.json"),
        `${JSON.stringify({ providerConfig }, null, 2)}\n`,
        "utf8",
      );

      const runtime = await createCliRuntime({
        cwd: workspaceRoot,
        storageRoot,
        providerConfig: providerConfig as any,
      });

      try {
        const { thread } = await runtime.startThread({
          title: "real provider shell acceptance",
        });

        const result = await runtime.runTurn({
          threadId: thread.id,
          prompt: [
            "Use the shell tool and run pwd in the current workspace.",
            "Do not use read-file.",
            "Reply with exactly one line in this format:",
            `DONE_SHELL | ${expectedWorkspacePath}`,
            "If you cannot complete that, reply with ERROR_SHELL.",
          ].join(" "),
        });

        expect(result.turn.status).toBe("completed");

        const history = await runtime.getThreadHistory({
          threadId: thread.id,
          limit: 200,
        });
        expect(history.items.some((item) => item.kind === "error")).toBe(false);

        const finalMessage = [...history.items]
          .reverse()
          .find((item): item is Extract<(typeof history.items)[number], { kind: "message"; role: "agent" }> =>
            item.kind === "message" && item.role === "agent",
          );
        expect(finalMessage?.text ?? "").toContain(`DONE_SHELL | ${expectedWorkspacePath}`);
        expect(finalMessage?.text ?? "").not.toContain("ERROR_SHELL");
        expect(
          history.items.some(
            (item) =>
              item.kind === "tool-call"
              && item.toolName === "shell"
              && item.input.startsWith("pwd"),
          ),
        ).toBe(true);
        expect(
          history.items.some(
            (item) =>
              item.kind === "tool-result"
              && item.toolName === "shell"
              && realpathSync(item.output.trim()) === expectedWorkspacePath,
          ),
        ).toBe(true);
      } finally {
        await runtime.close();
      }
    },
    180_000,
  );

  itReal(
    "uses one batched read-file call in a real provider turn to inspect multiple files",
    async () => {
      const workspaceRoot = createWorkspace({
        "alpha.txt": "ALPHA_NEEDLE_123\n",
        "beta.txt": "BETA_NEEDLE_456\n",
      });
      const providerConfig = readRealProviderConfig();
      const storageRoot = resolveCliStorageRoot({
        cwd: workspaceRoot,
        storageRoot: mkdtempSync(`${tmpdir()}/best-agent-dimsdk-real-read-batch-`),
      });
      tempRoots.push(storageRoot);
      writeFileSync(
        resolve(storageRoot, "cli-state.json"),
        `${JSON.stringify({ providerConfig }, null, 2)}\n`,
        "utf8",
      );

      const runtime = await createCliRuntime({
        cwd: workspaceRoot,
        storageRoot,
        providerConfig: providerConfig as any,
      });

      try {
        const { thread } = await runtime.startThread({
          title: "real provider batched read-file acceptance",
        });

        const result = await runtime.runTurn({
          threadId: thread.id,
          prompt: [
            "First use workspace-files to confirm the tracked files in the current workspace.",
            "Then use the read-file tool exactly once with a path array containing alpha.txt and beta.txt.",
            "Do not use shell.",
            "Reply with exactly three lines:",
            "DONE_BATCH_READ",
            "ALPHA | ALPHA_NEEDLE_123",
            "BETA | BETA_NEEDLE_456",
            "If you cannot do that, reply with ERROR_BATCH_READ.",
          ].join(" "),
        });

        expect(result.turn.status).toBe("completed");

        const history = await runtime.getThreadHistory({
          threadId: thread.id,
          limit: 200,
        });
        expect(history.items.some((item) => item.kind === "error")).toBe(false);

        const finalMessage = [...history.items]
          .reverse()
          .find((item): item is Extract<(typeof history.items)[number], { kind: "message"; role: "agent" }> =>
            item.kind === "message" && item.role === "agent",
          );
        expect(finalMessage?.text ?? "").toContain("DONE_BATCH_READ");
        expect(finalMessage?.text ?? "").toContain("ALPHA | ALPHA_NEEDLE_123");
        expect(finalMessage?.text ?? "").toContain("BETA | BETA_NEEDLE_456");
        expect(finalMessage?.text ?? "").not.toContain("ERROR_BATCH_READ");
        expect(
          history.items.some(
            (item) =>
              item.kind === "tool-call"
              && item.toolName === "workspace-files",
          ),
        ).toBe(true);
        expect(
          history.items.filter(
            (item) =>
              item.kind === "tool-call"
              && item.toolName === "read-file"
              && item.input === JSON.stringify(["alpha.txt", "beta.txt"]),
          ),
        ).toHaveLength(1);
        expect(
          history.items.some(
            (item) =>
              item.kind === "tool-result"
              && item.toolName === "read-file"
              && item.output.includes("=== file: alpha.txt ===")
              && item.output.includes("ALPHA_NEEDLE_123")
              && item.output.includes("=== file: beta.txt ===")
              && item.output.includes("BETA_NEEDLE_456"),
          ),
        ).toBe(true);
      } finally {
        await runtime.close();
      }
    },
    180_000,
  );

  itLongReal(
    "reviews every file in the full repository in a long-running real-provider turn",
    async () => {
      const baseProviderConfig = readRealProviderConfig() as { timeoutMs?: unknown };
      const providerConfig = {
        ...baseProviderConfig,
        timeoutMs: Math.max(300_000, Number(baseProviderConfig.timeoutMs ?? 0)),
      };
      const storageRoot = resolveCliStorageRoot({
        cwd: process.cwd(),
        storageRoot: mkdtempSync(`${tmpdir()}/best-agent-dimsdk-real-long-`),
      });
      tempRoots.push(storageRoot);
      writeFileSync(
        resolve(storageRoot, "cli-state.json"),
        `${JSON.stringify({ providerConfig }, null, 2)}\n`,
        "utf8",
      );

      const runtime = await createCliRuntime({
        cwd: process.cwd(),
        storageRoot,
        providerConfig: providerConfig as any,
      });

      try {
        const targetFiles = listFullRepoReviewTargets(process.cwd());
        expect(targetFiles.length).toBeGreaterThan(500);

        const { thread } = await runtime.startThread({
          title: "full repo real-provider review",
        });

        const prompt = [
          "This is a long-running stability validation.",
          "Review every file in the current repository without delegating to child threads.",
          `There are exactly ${targetFiles.length} tracked repository files.`,
          `Use the workspace-files tool with limit ${FULL_REPO_REVIEW_PAGE_LIMIT} to paginate the tracked files in lexicographic order.`,
          "Keep progress in full-repo-progress.json. Use read-scratch if you need to recover progress after compaction, interruption, or uncertainty.",
          "When you call write-scratch or append-scratch, always send an object with path and content string fields.",
          `Initialize full-repo-progress.json with write-scratch as compact JSON like {"nextOffset":0,"limit":${FULL_REPO_REVIEW_PAGE_LIMIT}}.`,
          "Initialize full-repo-review.md with write-scratch.",
          "For each workspace-files page, prefer one batched read-file call that covers the whole page before using any single-file follow-up reads.",
          "For each page from workspace-files, inspect every listed file with read-file or read-file-range before reviewing it.",
          "After each reviewed batch, append the FILE REVIEW lines to full-repo-review.md with append-scratch, then overwrite full-repo-progress.json with the next offset.",
          "The report must start with DONE_FULL_REPO_REVIEW, then FILE COUNT | <count>, then exactly one line per file in lexicographic order using this format:",
          "FILE REVIEW | <relative path> | <short review>",
          "Do not skip files. Do not stop early. If the task cannot be completed, write ERROR_FULL_REPO_REVIEW instead.",
          "In the final assistant reply, output exactly three lines:",
          "DONE_FULL_REPO_REVIEW",
          "REPORT PATH | <absolute scratch path>",
          `FILE COUNT | ${targetFiles.length}`,
        ].join(" ");

        const result = await runtime.runTurn({
          threadId: thread.id,
          prompt,
        });
        expect(result.turn.status).toBe("completed");

        const history = await runtime.getThreadHistory({
          threadId: thread.id,
          limit: 10_000,
        });
        expect(history.hasMore).toBe(false);
        expect(history.items.some((item) => item.kind === "error")).toBe(false);

        const finalMessage = [...history.items]
          .reverse()
          .find((item): item is Extract<(typeof history.items)[number], { kind: "message"; role: "agent" }> =>
            item.kind === "message" && item.role === "agent",
          );
        expect(finalMessage?.text ?? "").toContain("DONE_FULL_REPO_REVIEW");
        expect(finalMessage?.text ?? "").toContain(`FILE COUNT | ${targetFiles.length}`);
        expect(finalMessage?.text ?? "").not.toContain("ERROR_FULL_REPO_REVIEW");

        const scratchWrite = [...history.items]
          .reverse()
          .find(
            (item): item is Extract<(typeof history.items)[number], { kind: "tool-result"; toolName: "write-scratch" }> =>
              item.kind === "tool-result"
              && item.toolName === "write-scratch"
              && item.output.trim().endsWith("/full-repo-review.md"),
          );
        expect(scratchWrite?.output).toBeTruthy();

        const reportText = readFileSync(String(scratchWrite?.output).trim(), "utf8");
        expect(reportText).toContain("DONE_FULL_REPO_REVIEW");
        expect(reportText).toContain(`FILE COUNT | ${targetFiles.length}`);
        expect(reportText).not.toContain("ERROR_FULL_REPO_REVIEW");

        const reportLines = reportText
          .split("\n")
          .filter((line) => line.startsWith("FILE REVIEW | "));
        expect(reportLines).toHaveLength(targetFiles.length);
        for (const filePath of targetFiles) {
          expect(reportText).toContain(`FILE REVIEW | ${filePath} |`);
        }

        const inspectionCalls = history.items.filter(
          (item) =>
            item.kind === "tool-call"
            && (item.toolName === "read-file" || item.toolName === "read-file-range"),
        );
        expect(inspectionCalls.length).toBeGreaterThan(20);
        expect(history.items.some((item) => item.kind === "tool-call" && item.toolName === "workspace-files")).toBe(true);
        expect(history.items.some((item) => item.kind === "tool-call" && item.toolName === "append-scratch")).toBe(true);
      } finally {
        await runtime.close();
      }
    },
    1_800_000,
  );
});
