## Summary Task cards now remove the overseer eye as soon as their workflow's effective oversight becomes `off`, instead of reusing an active value cached before the setting changed. The invalidation covers card remounts as well as mounted cards, and authoritative writes from the dashboard, agents, and configuration rollback reach the board through the existing project-scoped SSE stream. Older in-flight responses cannot restore the eye after a newer `off` value wins, while unrelated workflow-setting saves leave active indicators undisturbed. ## Validation - 99 focused dashboard regression tests passed across selected and aggregate cards, desktop and mobile, SSE delivery, and out-of-order responses - Core and dashboard typechecks passed - `pnpm lint` and `pnpm check:changesets` passed - `pnpm verify:fast` passed production builds and the CLI/server boot smoke <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Bug Fixes** - Planner-overseer eye badges now disappear immediately when workflow oversight is turned off. - Prevented stale or out-of-order updates from displaying incorrect oversight status. - Oversight indicators now remain hidden when the effective setting cannot be confirmed. - Live workflow setting changes now update task cards without requiring a page refresh. - **Documentation** - Clarified eye badge visibility rules, tooltip meaning, and active oversight states in the dashboard guide. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
58 lines
2.1 KiB
TypeScript
58 lines
2.1 KiB
TypeScript
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
import { updateWorkflowSettingValues } from "../legacy";
|
|
import {
|
|
__test_clearWorkflowSettingValuesRevisions,
|
|
getWorkflowSettingValuesRevision,
|
|
} from "../../utils/workflowSettingValuesEvents";
|
|
|
|
function response(ok: boolean, body: unknown, status = ok ? 200 : 500): Response {
|
|
return {
|
|
ok,
|
|
status,
|
|
statusText: ok ? "OK" : "Error",
|
|
headers: { get: () => "application/json" },
|
|
json: async () => body,
|
|
text: async () => JSON.stringify(body),
|
|
} as Response;
|
|
}
|
|
|
|
afterEach(() => {
|
|
vi.unstubAllGlobals();
|
|
__test_clearWorkflowSettingValuesRevisions();
|
|
});
|
|
|
|
describe("workflow setting value update invalidation", () => {
|
|
it("advances the matching workflow revision after a successful write", async () => {
|
|
vi.stubGlobal("fetch", vi.fn().mockResolvedValue(response(true, {
|
|
stored: { plannerOversightLevel: "off" },
|
|
effective: { plannerOversightLevel: "off" },
|
|
orphaned: [],
|
|
})));
|
|
|
|
await updateWorkflowSettingValues("builtin:coding", { plannerOversightLevel: "off" }, "project-1");
|
|
|
|
expect(getWorkflowSettingValuesRevision("builtin:coding", "project-1")).toBe(1);
|
|
expect(getWorkflowSettingValuesRevision("builtin:coding", "project-2")).toBe(0);
|
|
});
|
|
|
|
it("does not invalidate cards when the workflow write fails", async () => {
|
|
vi.stubGlobal("fetch", vi.fn().mockResolvedValue(response(false, { error: "failed" })));
|
|
|
|
await expect(updateWorkflowSettingValues("builtin:coding", { plannerOversightLevel: "off" }, "project-1")).rejects.toThrow();
|
|
|
|
expect(getWorkflowSettingValuesRevision("builtin:coding", "project-1")).toBe(0);
|
|
});
|
|
|
|
it("does not blink oversight UI for a successful unrelated setting write", async () => {
|
|
vi.stubGlobal("fetch", vi.fn().mockResolvedValue(response(true, {
|
|
stored: { planningFallbackThinkingLevel: "high" },
|
|
effective: { planningFallbackThinkingLevel: "high" },
|
|
orphaned: [],
|
|
})));
|
|
|
|
await updateWorkflowSettingValues("builtin:coding", { planningFallbackThinkingLevel: "high" }, "project-1");
|
|
|
|
expect(getWorkflowSettingValuesRevision("builtin:coding", "project-1")).toBe(0);
|
|
});
|
|
});
|