From a47b1e5d78d626f8b480f1e90d3d64be2625ff6a Mon Sep 17 00:00:00 2001 From: gsxdsm Date: Tue, 5 May 2026 01:52:19 -0700 Subject: [PATCH] =?UTF-8?q?fix(FN-3469):=20correct=20lazy-loaded=20views?= =?UTF-8?q?=20count=20in=20AGENTS.md=20(13=E2=86=9215)=20and=20add=20regre?= =?UTF-8?q?ssion=20test?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AGENTS.md | 4 +- .../__tests__/lazy-loaded-views-docs.test.ts | 82 +++++++++++++++++++ 2 files changed, 84 insertions(+), 2 deletions(-) create mode 100644 packages/dashboard/app/__tests__/lazy-loaded-views-docs.test.ts diff --git a/AGENTS.md b/AGENTS.md index f3296dcea..b2d1f5ed7 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -550,10 +550,10 @@ The test config (`vitest.config.ts`) includes `test.css: { include: [/.+/] }` so ### Lazy-Loaded Heavy Views -These 13 views are lazy-loaded via `React.lazy()` to manage bundle size: +These 15 views are lazy-loaded via `React.lazy()` to manage bundle size: - `AgentsView`, `RoadmapsView`, `NodesView`, `ChatView`, `MemoryView` -- `DevServerView`, `InsightsView`, `DocumentsView`, `SkillsView` +- `DevServerView`, `InsightsView`, `DocumentsView`, `SkillsView`, `ResearchView`, `TodoView` - `SetupWizardModal`, `PluginManager`, `PiExtensionsManager`, `AgentDetailView` They are loaded in `App.tsx` / `AppModals.tsx` / `SettingsModal.tsx` / `AgentsView.tsx` with ``. diff --git a/packages/dashboard/app/__tests__/lazy-loaded-views-docs.test.ts b/packages/dashboard/app/__tests__/lazy-loaded-views-docs.test.ts new file mode 100644 index 000000000..3def036cc --- /dev/null +++ b/packages/dashboard/app/__tests__/lazy-loaded-views-docs.test.ts @@ -0,0 +1,82 @@ +import { describe, expect, it } from "vitest"; +import { readFileSync } from "node:fs"; +import { resolve } from "node:path"; + +const EXPECTED_DOCUMENTED_VIEWS = new Set([ + "AgentsView", + "RoadmapsView", + "NodesView", + "ChatView", + "MemoryView", + "DevServerView", + "InsightsView", + "DocumentsView", + "SkillsView", + "ResearchView", + "TodoView", + "SetupWizardModal", + "PluginManager", + "PiExtensionsManager", + "AgentDetailView", +]); + +const EXPECTED_APP_LEVEL_VIEWS = new Set([ + "AgentsView", + "DocumentsView", + "InsightsView", + "ResearchView", + "NodesView", + "ChatView", + "RoadmapsView", + "SkillsView", + "MemoryView", + "DevServerView", + "TodoView", +]); + +function extractLazyLoadedSection(agentsDoc: string): string { + const match = agentsDoc.match(/### Lazy-Loaded Heavy Views[\s\S]*?(?=\n### |\n---|$)/); + if (!match) { + throw new Error("Lazy-Loaded Heavy Views section not found in AGENTS.md"); + } + return match[0]; +} + +function extractBacktickedNamesFromBullets(section: string): string[] { + return section + .split("\n") + .filter((line) => line.trim().startsWith("- ")) + .flatMap((line) => [...line.matchAll(/`([^`]+)`/g)].map((m) => m[1])); +} + +function extractAppLazyViews(appSource: string): Set { + const matches = [...appSource.matchAll(/const\s+(\w+)\s*=\s*lazy\(/g)].map((m) => m[1]); + return new Set(matches.map((name) => (name === "_TodoView" ? "TodoView" : name))); +} + +describe("AGENTS lazy-loaded views inventory", () => { + it("documents the App-level lazy views accurately and keeps the curated 15-view list in sync", () => { + const agentsDoc = readFileSync(resolve(__dirname, "../../../../AGENTS.md"), "utf-8"); + const appSource = readFileSync(resolve(__dirname, "../App.tsx"), "utf-8"); + + const section = extractLazyLoadedSection(agentsDoc); + const countMatch = section.match(/These\s+(\d+)\s+views\s+are lazy-loaded/); + expect(countMatch).toBeTruthy(); + expect(Number(countMatch?.[1])).toBe(15); + + const documentedViews = extractBacktickedNamesFromBullets(section); + expect(new Set(documentedViews)).toEqual(EXPECTED_DOCUMENTED_VIEWS); + expect(documentedViews).toHaveLength(15); + + expect(section).toContain("`ResearchView`"); + expect(section).toContain("`TodoView`"); + expect((section.match(/`AgentDetailView`/g) ?? []).length).toBe(1); + + const appLevelViews = extractAppLazyViews(appSource); + expect(appLevelViews).toEqual(EXPECTED_APP_LEVEL_VIEWS); + + for (const view of appLevelViews) { + expect(EXPECTED_DOCUMENTED_VIEWS.has(view)).toBe(true); + } + }); +});