feat(FN-3180): add dreams notification event and harden plugin setup sync
This merge lands four features: a new "dreams" notification event exposed through settings and docs (FN-3180), hardened plugin setup sync with test isolation improvements (FN-3573), and feedback-driven enhancements to the native shell connection manager (FN-3402). Core settings schema, the plugin AP Fusion-Task-Id: FN-3180
This commit is contained in:
@@ -243,6 +243,7 @@ const DEFAULT_NTFY_EVENTS: NtfyNotificationEvent[] = [
|
||||
"planning-awaiting-input",
|
||||
"gridlock",
|
||||
"fallback-used",
|
||||
"memory-dreams-processed",
|
||||
];
|
||||
|
||||
const NOTIFICATION_EVENT_OPTIONS: Array<{ event: NtfyNotificationEvent; label: string; description: string }> = [
|
||||
@@ -254,6 +255,7 @@ const NOTIFICATION_EVENT_OPTIONS: Array<{ event: NtfyNotificationEvent; label: s
|
||||
{ event: "planning-awaiting-input", label: "Planning needs input", description: "When planning mode is waiting for your response to continue" },
|
||||
{ event: "gridlock", label: "Pipeline gridlocked", description: "When all schedulable todo tasks are blocked and work cannot advance" },
|
||||
{ event: "fallback-used", label: "Fallback model used (recovered)", description: "When Fusion recovers from a retryable model failure by switching to a fallback model" },
|
||||
{ event: "memory-dreams-processed", label: "DREAMS.md entry added", description: "When manual dream processing writes a new entry to project or agent DREAMS.md" },
|
||||
];
|
||||
|
||||
/** Well-known experimental feature flags with display labels.
|
||||
|
||||
@@ -2578,16 +2578,18 @@ describe("SettingsModal", () => {
|
||||
expect(screen.getByRole("button", { name: /Test notification/ })).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("shows fallback-used event option for both providers", async () => {
|
||||
it("shows fallback-used and dreams events for both providers", async () => {
|
||||
mockFetchSettings.mockResolvedValueOnce({ ...defaultSettings, ntfyEnabled: true, ntfyTopic: "test-topic" });
|
||||
renderModal();
|
||||
await waitForSettingsModalReady();
|
||||
await openNotificationsSection();
|
||||
|
||||
expect(screen.getByLabelText("Fallback model used (recovered)")).toBeInTheDocument();
|
||||
expect(screen.getByLabelText("DREAMS.md entry added")).toBeInTheDocument();
|
||||
|
||||
await userEvent.click(screen.getByLabelText("Webhook notifications"));
|
||||
expect(screen.getAllByLabelText("Fallback model used (recovered)").length).toBeGreaterThan(0);
|
||||
expect(screen.getAllByLabelText("DREAMS.md entry added").length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
it("shows webhook fields when webhook provider is enabled", async () => {
|
||||
@@ -2668,10 +2670,12 @@ describe("SettingsModal", () => {
|
||||
const failed = screen.getByLabelText("Task failed") as HTMLInputElement;
|
||||
const merged = screen.getByLabelText("Task merged") as HTMLInputElement;
|
||||
const fallbackUsed = screen.getByLabelText("Fallback model used (recovered)") as HTMLInputElement;
|
||||
const dreamsProcessed = screen.getByLabelText("DREAMS.md entry added") as HTMLInputElement;
|
||||
expect(inReview.checked).toBe(true);
|
||||
expect(failed.checked).toBe(true);
|
||||
expect(merged.checked).toBe(false);
|
||||
expect(fallbackUsed.checked).toBe(false);
|
||||
expect(dreamsProcessed.checked).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ const defaultSettings = {
|
||||
defaultPresetBySize: {},
|
||||
ntfyEnabled: false,
|
||||
ntfyTopic: undefined,
|
||||
ntfyEvents: ["in-review", "merged", "failed", "awaiting-approval", "awaiting-user-review", "fallback-used"],
|
||||
ntfyEvents: ["in-review", "merged", "failed", "awaiting-approval", "awaiting-user-review", "fallback-used", "memory-dreams-processed"],
|
||||
webhookEnabled: false,
|
||||
webhookUrl: undefined,
|
||||
webhookFormat: undefined,
|
||||
|
||||
Reference in New Issue
Block a user