46e3899945
- Changes (#72): a file git reports `MM` whose working copy equals HEAD again (a staged change since undone on disk) is no longer listed — JetBrains' GitChangesCollector drops it the same way. Mode-only changes stay listed. statusCounts (the dirty-tree safety checks) is unchanged. - Chat (#73): Claude Code runs no hook before a folder is trusted, so a new pane's session has no row; the chat now says the session has not started, offers Open terminal, and asks before typing a message or /model //effort into the pane (an Enter would pick the trust prompt's "No, exit"). - Terminal: Safari + macOS's own Vietnamese Telex replaces the whole word on each key (insertReplacementText), which xterm.js ignores — only each word's first letter reached the pane. The edit is now sent as DELs + the new tail. - Also: Ctrl+V pastes a screenshot into the terminal as a file path; the folder browser fallback lists files for a file field (`files=1`); the macOS native picker opens in front of the browser; a hidden tab is marked while a chat waits or once a turn ended; chat live line shows running calls, turn time and tokens, and "Done in …".
59 lines
2.2 KiB
TypeScript
59 lines
2.2 KiB
TypeScript
/**
|
|
* @file ConversationView.notYet.test.tsx
|
|
* @description A live pane's new session has no row until its first hook:
|
|
* its 404 shows no "Session not found" (a replay still shows it) but says the
|
|
* session has not started — the CLI may be asking in the terminal, e.g. to
|
|
* trust the folder — offers the terminal, and tells the chat (`onNotStarted`).
|
|
* @author Nguyễn Ngọc Trí Vĩ <vinnt@smartgift.vn>
|
|
*/
|
|
|
|
import { fireEvent, render, screen, waitFor } from "@testing-library/react";
|
|
import { describe, expect, it, vi } from "vitest";
|
|
import { ConversationView } from "../ConversationView";
|
|
|
|
const transcript = vi.hoisted(() =>
|
|
vi.fn(async () => {
|
|
throw Object.assign(new Error("Session not found"), { code: "NOT_FOUND", status: 404 });
|
|
})
|
|
);
|
|
vi.mock("../../../lib/api", async (importOriginal) => {
|
|
const actual = await importOriginal<Record<string, unknown>>();
|
|
return {
|
|
...actual,
|
|
api: { sessions: { transcripts: vi.fn(async () => ({ transcripts: [] })), transcript } },
|
|
};
|
|
});
|
|
|
|
describe("ConversationView before a session's first hook", () => {
|
|
it("shows no error for a live pane", async () => {
|
|
render(<ConversationView sessionId="new" fill live />);
|
|
await waitFor(() => expect(transcript).toHaveBeenCalled());
|
|
await new Promise((r) => setTimeout(r, 0));
|
|
expect(screen.queryByText("Session not found")).toBeNull();
|
|
});
|
|
|
|
it("still reports it when not live", async () => {
|
|
render(<ConversationView sessionId="gone" fill />);
|
|
expect(await screen.findByText("Session not found")).toBeTruthy();
|
|
});
|
|
|
|
it("says the session has not started and offers the terminal (a trust prompt)", async () => {
|
|
const onOpenTerminal = vi.fn();
|
|
const onNotStarted = vi.fn();
|
|
render(
|
|
<ConversationView
|
|
sessionId="new"
|
|
fill
|
|
live
|
|
onOpenTerminal={onOpenTerminal}
|
|
onNotStarted={onNotStarted}
|
|
/>
|
|
);
|
|
expect(await screen.findByText("The session has not started yet.")).toBeTruthy();
|
|
expect(screen.queryByText("No conversation records found.")).toBeNull();
|
|
fireEvent.click(screen.getByText("Open terminal"));
|
|
expect(onOpenTerminal).toHaveBeenCalled();
|
|
expect(onNotStarted).toHaveBeenLastCalledWith(true);
|
|
});
|
|
});
|