feat(ai-tools): Settings → AI Tools, Default/Other lane picker, per-run bypass switch (#40 A1)
Settings → Dashboard gains an AI Tools section (installed tools with Enabled/Disabled and Set default, available ones with a homepage link, Refresh). useAiTools shares one catalog copy across the app and replaces LANE_TOOL_LABEL. The Add-lane modal picks Default (<tool>) or Other…; the router row reads Native (<tool>) and disables AI Router profiles for tools that cannot use one. The run form gives catalog tools resume and a red per-run Bypass permissions switch (Codex too). Claude Code / Codex settings tabs hide while that tool is disabled. The Workspace probes each lane tool's CLI fresh. Docs: CLAUDE.md tool/bypass rule, AGENTS.md, LANES.md, API.md, CLI.md, server/README.md, OpenAPI fragment + regenerated openapi.yaml.
This commit is contained in:
@@ -41,7 +41,7 @@ const lane = (id: number, title: string): LaneFixture => ({
|
||||
const h = vi.hoisted(() => {
|
||||
const nativeProfile = {
|
||||
name: "native",
|
||||
label: "Native (Claude / Codex)",
|
||||
label: "Native",
|
||||
builtin: true,
|
||||
baseUrl: "",
|
||||
hasKey: false,
|
||||
@@ -205,10 +205,10 @@ describe("Workspace — the lane Model picker across a lane switch", () => {
|
||||
const user = userEvent.setup();
|
||||
|
||||
await selectLane(user, "Lane A");
|
||||
expect(await screen.findByDisplayValue("Native (Claude / Codex)")).toBeInTheDocument();
|
||||
expect(await screen.findByDisplayValue("Native (Claude)")).toBeInTheDocument();
|
||||
|
||||
await selectLane(user, "Lane B");
|
||||
await user.selectOptions(screen.getByDisplayValue("Native (Claude / Codex)"), ["9router"]);
|
||||
await user.selectOptions(screen.getByDisplayValue("Native (Claude)"), ["9router"]);
|
||||
await waitFor(() => expect(routerApply).toHaveBeenCalledWith(2, "9router"));
|
||||
await settle();
|
||||
expect(screen.getByDisplayValue("9Router")).toBeInTheDocument();
|
||||
@@ -216,7 +216,7 @@ describe("Workspace — the lane Model picker across a lane switch", () => {
|
||||
// Back to the lane that was never switched. It is still native server-side,
|
||||
// so the picker must say so — the row is one instance shared by every lane.
|
||||
await selectLane(user, "Lane A");
|
||||
expect(screen.getByDisplayValue("Native (Claude / Codex)")).toBeInTheDocument();
|
||||
expect(screen.getByDisplayValue("Native (Claude)")).toBeInTheDocument();
|
||||
// And nothing may have been written to lane A on the way.
|
||||
expect(routerApply).not.toHaveBeenCalledWith(1, expect.anything());
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user