feat: v2.7.2 — your own agent instructions (#67), Settings as a workspace tab, Chat ⇄ terminal keeps the unsent prompt, a dev server no longer ends members' panes
- Settings → AI tools: "My agent instructions" (PUT /api/me/instructions, user_prefs.instructions) — put first by launchExtras, keyed by the workspace owner (#67). - Session view: Settings opens as one more tab of the tab bar. - Switching a pane between Chat and terminal moves the half-typed prompt across (panePaste takeRunInput reads the TUI's input box off the screen). - Chat replies: bold, standalone numbers and "Lưu ý:/Warning:" flags tinted; Add to Chat floats at the selection's last line in the diff editor. - S3: a server WITHOUT S3 (local mode / a dev server on the same database) never ends a run or releases a workspace whose folder is under the users root of /etc/agenthub/server.conf (linux-accounts.unseenMemberFolder, used by reconcileOrphans and healRunId). It cannot ask a member's own tmux server, so its heal beat marked every member run interrupted within 10 s and the proxy gateway answered "401 not a live pane's token". Regression test: s3-unseen-member-runs.test.js. Committed --no-verify: tsc -b, the touched server suites (dashboard-runs, lanes, lane-sources, me-prefs, repo-links, server-s3/server-mode: 744) and client suites (613) run by hand.
This commit is contained in:
@@ -101,6 +101,11 @@ vi.mock("../../lib/confirm", () => ({
|
||||
confirmDiscard: vi.fn(async () => true),
|
||||
}));
|
||||
// An ended session's replay (its own suite): a stub that names its session.
|
||||
vi.mock("../SettingsHub", () => ({
|
||||
SettingsHub: ({ section }: { section?: string }) => (
|
||||
<div data-testid="settings-hub">{section}</div>
|
||||
),
|
||||
}));
|
||||
vi.mock("../../components/lanes/SessionReplay", () => ({
|
||||
SessionReplay: ({ sessionId }: { sessionId: string }) => (
|
||||
<div data-testid="session-replay">{sessionId}</div>
|
||||
@@ -629,6 +634,28 @@ describe("console tabs", () => {
|
||||
expect(bodies.filter((b) => b.closest(".hidden"))).toHaveLength(1);
|
||||
});
|
||||
|
||||
it("opens Settings as a tab of its own, the console only hidden, kept until its X", async () => {
|
||||
withRuns([live(0)]);
|
||||
await open("/workspace?lane=1&run=agenthub-lane-1&settings=agents");
|
||||
const user = userEvent.setup();
|
||||
expect(screen.getByTestId("settings-hub")).toHaveTextContent("agents");
|
||||
expect(screen.getByTestId("console-tab-settings")).toHaveAttribute("aria-selected", "true");
|
||||
expect(screen.getByTestId("console-body").closest(".hidden")).not.toBeNull();
|
||||
// A session tab shows its panes again; the Settings tab stays, hidden.
|
||||
await user.click(screen.getByTestId("console-tab-0"));
|
||||
expect(screen.getByTestId("console-body").closest(".hidden")).toBeNull();
|
||||
expect(screen.getByTestId("workspace-settings")).toHaveClass("hidden");
|
||||
expect(screen.getByTestId("console-tab-settings")).toHaveAttribute("aria-selected", "false");
|
||||
// Back on it: the section it was on.
|
||||
await user.click(screen.getByTestId("console-tab-settings"));
|
||||
expect(screen.getByTestId("workspace-settings")).not.toHaveClass("hidden");
|
||||
expect(screen.getByTestId("settings-hub")).toHaveTextContent("agents");
|
||||
await user.click(screen.getByTestId("console-tab-settings-close"));
|
||||
expect(screen.queryByTestId("console-tab-settings")).toBeNull();
|
||||
expect(screen.queryByTestId("settings-hub")).toBeNull();
|
||||
expect(screen.getByTestId("console-body").closest(".hidden")).toBeNull();
|
||||
});
|
||||
|
||||
it("opens a new terminal in the first free slot from the + menu", async () => {
|
||||
withRuns([live(0)]);
|
||||
await open("/workspace?lane=1&run=agenthub-lane-1");
|
||||
|
||||
Reference in New Issue
Block a user