@leanspec/ui 0.2.6-dev.20251125010539 → 0.2.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.next/standalone/node_modules/.pnpm/better-sqlite3@11.10.0/node_modules/better-sqlite3/build/Release/better_sqlite3.node +0 -0
- package/.next/standalone/packages/ui/.next/BUILD_ID +1 -1
- package/.next/standalone/packages/ui/.next/build-manifest.json +2 -2
- package/.next/standalone/packages/ui/.next/prerender-manifest.json +3 -3
- package/.next/standalone/packages/ui/.next/required-server-files.json +4 -4
- package/.next/standalone/packages/ui/.next/server/app/_global-error/page.js.nft.json +1 -1
- package/.next/standalone/packages/ui/.next/server/app/_global-error.html +2 -2
- package/.next/standalone/packages/ui/.next/server/app/_global-error.rsc +1 -1
- package/.next/standalone/packages/ui/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/packages/ui/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/.next/standalone/packages/ui/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/.next/standalone/packages/ui/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/packages/ui/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/.next/standalone/packages/ui/.next/server/app/_not-found.html +2 -2
- package/.next/standalone/packages/ui/.next/server/app/_not-found.rsc +1 -1
- package/.next/standalone/packages/ui/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/.next/standalone/packages/ui/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/.next/standalone/packages/ui/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/packages/ui/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/.next/standalone/packages/ui/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/packages/ui/.next/server/app/api/local-projects/[id]/route.js.nft.json +1 -1
- package/.next/standalone/packages/ui/.next/server/app/api/local-projects/discover/route.js.nft.json +1 -1
- package/.next/standalone/packages/ui/.next/server/app/api/local-projects/list-directory/route.js.nft.json +1 -1
- package/.next/standalone/packages/ui/.next/server/app/api/local-projects/route.js.nft.json +1 -1
- package/.next/standalone/packages/ui/.next/server/app/api/projects/[id]/route.js.nft.json +1 -1
- package/.next/standalone/packages/ui/.next/server/app/api/projects/[id]/specs/[spec]/route.js.nft.json +1 -1
- package/.next/standalone/packages/ui/.next/server/app/api/projects/[id]/specs/[spec]/status/route.js.nft.json +1 -1
- package/.next/standalone/packages/ui/.next/server/app/api/projects/[id]/specs/route.js.nft.json +1 -1
- package/.next/standalone/packages/ui/.next/server/app/api/projects/[id]/stats/route.js.nft.json +1 -1
- package/.next/standalone/packages/ui/.next/server/app/api/projects/route.js.nft.json +1 -1
- package/.next/standalone/packages/ui/.next/server/app/api/revalidate/route.js.nft.json +1 -1
- package/.next/standalone/packages/ui/.next/server/app/api/specs/[id]/dependency-graph/route.js.nft.json +1 -1
- package/.next/standalone/packages/ui/.next/server/app/api/specs/[id]/route.js.nft.json +1 -1
- package/.next/standalone/packages/ui/.next/server/app/api/specs/[id]/status/route.js.nft.json +1 -1
- package/.next/standalone/packages/ui/.next/server/app/api/specs/[id]/subspecs/[file]/route.js.nft.json +1 -1
- package/.next/standalone/packages/ui/.next/server/app/api/stats/route.js.nft.json +1 -1
- package/.next/standalone/packages/ui/.next/server/app/page.js.nft.json +1 -1
- package/.next/standalone/packages/ui/.next/server/app/projects/[projectId]/page.js.nft.json +1 -1
- package/.next/standalone/packages/ui/.next/server/app/projects/[projectId]/specs/[specId]/page.js.nft.json +1 -1
- package/.next/standalone/packages/ui/.next/server/app/projects/[projectId]/specs/page.js.nft.json +1 -1
- package/.next/standalone/packages/ui/.next/server/app/projects/page.js.nft.json +1 -1
- package/.next/standalone/packages/ui/.next/server/app/projects.html +2 -2
- package/.next/standalone/packages/ui/.next/server/app/projects.rsc +1 -1
- package/.next/standalone/packages/ui/.next/server/app/projects.segments/_full.segment.rsc +1 -1
- package/.next/standalone/packages/ui/.next/server/app/projects.segments/_index.segment.rsc +1 -1
- package/.next/standalone/packages/ui/.next/server/app/projects.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/packages/ui/.next/server/app/projects.segments/projects/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/packages/ui/.next/server/app/projects.segments/projects.segment.rsc +1 -1
- package/.next/standalone/packages/ui/.next/server/app/specs/[id]/page.js.nft.json +1 -1
- package/.next/standalone/packages/ui/.next/server/app/specs/page.js.nft.json +1 -1
- package/.next/standalone/packages/ui/.next/server/app/stats/page.js.nft.json +1 -1
- package/.next/standalone/packages/ui/.next/server/pages/404.html +2 -2
- package/.next/standalone/packages/ui/.next/server/pages/500.html +2 -2
- package/.next/standalone/packages/ui/.next/server/server-reference-manifest.js +1 -1
- package/.next/standalone/packages/ui/.next/server/server-reference-manifest.json +1 -1
- package/.next/standalone/packages/ui/dist/BUILD_ID +1 -0
- package/.next/standalone/packages/ui/dist/public/f864aa7e7061c0600e35cf3d879b27cf.txt +1 -0
- package/.next/standalone/packages/ui/dist/public/favicon.ico +0 -0
- package/.next/standalone/packages/ui/dist/public/file.svg +1 -0
- package/.next/standalone/packages/ui/dist/public/github-mark-white.svg +1 -0
- package/.next/standalone/packages/ui/dist/public/github-mark.svg +1 -0
- package/.next/standalone/packages/ui/dist/public/globe.svg +1 -0
- package/.next/standalone/packages/ui/dist/public/icon.svg +7 -0
- package/.next/standalone/packages/ui/dist/public/logo-dark-bg.svg +17 -0
- package/.next/standalone/packages/ui/dist/public/logo-with-bg.svg +17 -0
- package/.next/standalone/packages/ui/dist/public/logo.svg +17 -0
- package/.next/standalone/packages/ui/dist/public/next.svg +1 -0
- package/.next/standalone/packages/ui/dist/public/vercel.svg +1 -0
- package/.next/standalone/packages/ui/dist/public/window.svg +1 -0
- package/.next/standalone/packages/ui/dist/standalone/packages/web/README.md +196 -0
- package/.next/standalone/packages/ui/dist/standalone/packages/web/leanspec.db +0 -0
- package/.next/standalone/packages/ui/dist/standalone/packages/web/package.json +75 -0
- package/.next/standalone/packages/ui/dist/standalone/packages/web/server.js +44 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/014-complete-custom-frontmatter/README.md +175 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/016-github-action/README.md +317 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/017-vscode-extension/README.md +261 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/018-spec-validation/CLI-DESIGN.md +380 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/018-spec-validation/CONFIGURATION-EXAMPLES.md +230 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/018-spec-validation/CONFIGURATION.md +285 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/018-spec-validation/IMPLEMENTATION.md +358 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/018-spec-validation/README.md +303 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/018-spec-validation/TESTING.md +368 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/018-spec-validation/VALIDATION-RULES.md +327 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/024-pattern-aware-list-grouping/README.md +117 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/025-template-config-updates/README.md +73 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/026-init-pattern-selection/README.md +109 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/034-copilot-slash-commands/README.md +107 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/035-live-specs-showcase/ARCHITECTURE.md +244 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/035-live-specs-showcase/IMPLEMENTATION.md +429 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/035-live-specs-showcase/README.md +302 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/036-pm-integrations/README.md +158 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/043-official-launch-02/DEMO-AI-ASSISTED.md +359 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/043-official-launch-02/DEMO-FULL-LIFECYCLE.md +86 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/043-official-launch-02/DEMO-REAL-FEATURE.md +437 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/043-official-launch-02/DEMO-SCRIPT.md +365 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/043-official-launch-02/DOGFOODING-FINAL.md +203 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/043-official-launch-02/DOGFOODING-SESSION-2025-11-06.md +174 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/043-official-launch-02/DOGFOODING-SUMMARY.md +156 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/043-official-launch-02/IMPLEMENTATION.md +183 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/043-official-launch-02/MARKETING.md +229 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/043-official-launch-02/NEXT-STEPS-DEMO.md +243 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/043-official-launch-02/README.md +217 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/043-official-launch-02/SESSION-2025-11-06.md +166 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/043-official-launch-02/TESTING.md +126 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/045-unified-dashboard/ACTUAL-IMPLEMENTATION.md +108 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/045-unified-dashboard/DESIGN.md +382 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/045-unified-dashboard/IMPLEMENTATION.md +144 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/045-unified-dashboard/RATIONALE.md +146 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/045-unified-dashboard/README.md +208 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/045-unified-dashboard/TESTING.md +182 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/047-git-backfill-timestamps/README.md +314 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/048-spec-complexity-analysis/FINDINGS.md +113 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/048-spec-complexity-analysis/GUIDELINES.md +237 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/048-spec-complexity-analysis/README.md +149 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/049-leanspec-first-principles/ANALYSIS-COMPARISONS.md +175 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/049-leanspec-first-principles/ANALYSIS-CONSTRAINTS.md +254 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/049-leanspec-first-principles/FIRST-PRINCIPLES.md +376 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/049-leanspec-first-principles/OPERATIONALIZATION-ROADMAP.md +240 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/049-leanspec-first-principles/OPERATIONALIZATION-TOOLS.md +175 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/049-leanspec-first-principles/README.md +374 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/051-docs-system-prompt-principles/README.md +339 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/052-branding-assets/README.md +128 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/053-spec-assets-philosophy/README.md +97 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/054-validate-output-lint-style/DESIGN-DECISIONS.md +93 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/054-validate-output-lint-style/OUTPUT-FORMAT-SPEC.md +146 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/054-validate-output-lint-style/README.md +175 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/055-readme-redesign-ai-first/ANALYSIS-PART1.md +397 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/055-readme-redesign-ai-first/ANALYSIS-PART2.md +342 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/055-readme-redesign-ai-first/ANALYSIS.md +44 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/055-readme-redesign-ai-first/CHANGES.md +150 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/055-readme-redesign-ai-first/CONCERNS-ANALYSIS.md +351 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/055-readme-redesign-ai-first/DOCS-ALIGNMENT-ANALYSIS.md +238 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/055-readme-redesign-ai-first/README.md +280 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/055-readme-redesign-ai-first/REDESIGN-DRAFT.md +372 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/055-readme-redesign-ai-first/REDESIGN-REFINED.md +466 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/056-docs-site-accuracy-audit/AUDIT-RESULTS.md +178 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/056-docs-site-accuracy-audit/README.md +174 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/057-docs-validation-comprehensive/README.md +295 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/057-docs-validation-comprehensive/VALIDATION-RESULTS.md +487 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/058-docs-overview-polish/ANALYSIS.md +241 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/058-docs-overview-polish/DESIGN.md +279 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/058-docs-overview-polish/IMPLEMENTATION.md +642 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/058-docs-overview-polish/NOTES.md +125 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/058-docs-overview-polish/README.md +286 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/059-programmatic-spec-management/ARCHITECTURE.md +392 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/059-programmatic-spec-management/COMMANDS.md +1002 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/059-programmatic-spec-management/CONTEXT-ENGINEERING.md +411 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/059-programmatic-spec-management/IMPLEMENTATION.md +812 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/059-programmatic-spec-management/README.md +504 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/059-programmatic-spec-management/TESTING.md +724 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/060-core-concepts-coherence/README.md +125 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/061-ai-assisted-spec-writing/README.md +299 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/062-docs-info-architecture-v2/IMPLEMENTATION-PLAN.md +174 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/062-docs-info-architecture-v2/PAGE-SPECIFICATIONS.md +265 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/062-docs-info-architecture-v2/PROBLEM-ANALYSIS.md +36 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/062-docs-info-architecture-v2/README.md +243 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/062-docs-info-architecture-v2/SOLUTION-DESIGN.md +82 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/063-migration-from-existing-tools/DESIGN.md +338 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/063-migration-from-existing-tools/EXAMPLES.md +354 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/063-migration-from-existing-tools/IMPLEMENTATION.md +189 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/063-migration-from-existing-tools/README.md +119 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/064-docs-site-zh-translation/README.md +170 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/065-v03-planning/README.md +158 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/066-context-economy-thresholds-refinement/README.md +842 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/067-monorepo-core-extraction/README.md +358 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/068-live-specs-ux-enhancements/DESIGN.md +444 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/068-live-specs-ux-enhancements/README.md +357 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/069-token-counting-utils/README.md +551 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/070-mcp-token-counting-tool/README.md +372 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/071-simplified-token-validation/README.md +489 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/072-ai-agent-first-use-workflow/README.md +285 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/073-template-engine-agents-md/README.md +323 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/074-content-at-creation/README.md +136 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/075-intelligent-search-engine/README.md +399 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/076-programmatic-spec-relationships/README.md +301 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/077-archiving-strategy/README.md +235 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/078-sub-spec-template-system/README.md +303 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/079-cli-alphabetical-organization/README.md +196 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/080-mcp-server-modular-architecture/README.md +388 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/081-web-app-ux-redesign/README.md +824 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/082-web-realtime-sync-architecture/DATABASE.md +111 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/082-web-realtime-sync-architecture/DEPLOYMENT.md +69 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/082-web-realtime-sync-architecture/FILESYSTEM.md +77 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/082-web-realtime-sync-architecture/IMPLEMENTATION.md +184 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/082-web-realtime-sync-architecture/README.md +496 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/083-web-navigation-performance/README.md +490 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/084-sub-spec-visibility-in-tools/README.md +389 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/085-cli-relationship-commands/README.md +920 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/086-template-component-deduplication/README.md +146 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/087-cli-ui-command/README.md +607 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/088-core-concepts-terminology-only/README.md +104 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/089-sdd-practical-tutorials/README.md +124 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/090-leanspec-sdd-case-studies/README.md +129 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/091-chinese-localization-strategy/README.md +244 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/092-docs-site-submodule-migration/README.md +148 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/093-spec-detail-ui-improvements/README.md +54 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/archived/001-typescript-cli-migration/README.md +37 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/archived/002-template-system-redesign/README.md +60 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/archived/003-init-system-redesign/README.md +113 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/archived/004-existing-project-integration/README.md +69 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/archived/004-existing-project-integration/SUMMARY.md +112 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/archived/005-structured-frontmatter/README.md +229 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/archived/006-pm-visualization-tools/README.md +406 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/archived/007-system-prompt-updates/README.md +168 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/archived/008-commander-migration/README.md +174 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/archived/009-cli-ux-enhancement/README.md +212 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/archived/010-commands-refactor/README.md +249 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/archived/011-test-results/README.md +60 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/archived/011-test-results/TEST_SUMMARY.md +139 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/archived/012-sub-spec-files/README.md +722 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/archived/013-custom-spec-templates/README.md +413 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/archived/015-npm-publishing/README.md +255 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/archived/019-readme-improvement/README.md +252 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/archived/020-documentation-website/README.md +253 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/archived/021-docusaurus-vercel-migration/README.md +612 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/archived/022-flexible-folder-structure/README.md +794 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/archived/023-folder-structure-improvements/DESIGN.md +834 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/archived/023-folder-structure-improvements/README.md +255 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/archived/027-cli-ui-ux-optimization/README.md +454 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/archived/028-cli-ui-modernization/README.md +172 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/archived/029-visualization-improvements/IMPLEMENTATION.md +152 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/archived/029-visualization-improvements/README.md +95 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/archived/030-created-date-format-bug/README.md +87 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/archived/031-gantt-ux-improvements/README.md +230 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/archived/032-console-log-chalk-security/README.md +89 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/archived/033-mcp-server/README.md +89 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/archived/037-docs-overhaul/README.md +166 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/archived/038-flat-structure-migration/README.md +276 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/archived/038-mcp-frontmatter-bug-fix/README.md +122 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/archived/039-simplify-viewer-commands/README.md +198 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/archived/039-template-variable-sync/README.md +192 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/archived/040-spec-viewer-commands/README.md +171 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/archived/042-mcp-error-handling/README.md +200 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/archived/044-spec-relationships-clarity/README.md +317 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/archived/046-stats-dashboard-refactor/DESIGN.md +276 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/archived/046-stats-dashboard-refactor/IMPLEMENTATION.md +241 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/archived/046-stats-dashboard-refactor/README.md +139 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/archived/046-stats-dashboard-refactor/TESTING.md +328 -0
- package/.next/standalone/packages/ui/dist/standalone/specs/archived/050-tool-redesign-first-principles/README.md +400 -0
- package/.next/standalone/packages/ui/dist/static/chunks/0c19c69aa7625475.js +1 -0
- package/.next/standalone/packages/ui/dist/static/chunks/116800b03245a1e5.js +1 -0
- package/.next/standalone/packages/ui/dist/static/chunks/15843a3d7584e314.js +1 -0
- package/.next/standalone/packages/ui/dist/static/chunks/19e80edf527aef5c.js +1 -0
- package/.next/standalone/packages/ui/dist/static/chunks/465954d5af3284a9.js +1 -0
- package/.next/standalone/packages/ui/dist/static/chunks/5abeeb89f1412a80.js +3 -0
- package/.next/standalone/packages/ui/dist/static/chunks/5c2072ad938de8ed.js +1 -0
- package/.next/standalone/packages/ui/dist/static/chunks/6a05a93ec8fa7b83.js +1 -0
- package/.next/standalone/packages/ui/dist/static/chunks/778e42188e450b39.css +1 -0
- package/.next/standalone/packages/ui/dist/static/chunks/a02c1f50ff00204f.js +1 -0
- package/.next/standalone/packages/ui/dist/static/chunks/a45464b9776dd88e.js +1 -0
- package/.next/standalone/packages/ui/dist/static/chunks/a6dad97d9634a72d.js +1 -0
- package/.next/standalone/packages/ui/dist/static/chunks/b0ea0ac61604f843.js +1 -0
- package/.next/standalone/packages/ui/dist/static/chunks/c06e85b449720194.js +1 -0
- package/.next/standalone/packages/ui/dist/static/chunks/c557ac675be79771.js +1 -0
- package/.next/standalone/packages/ui/dist/static/chunks/cad005a57ffbb2d3.js +1 -0
- package/.next/standalone/packages/ui/dist/static/chunks/cdf6fe33bc65efbc.js +1 -0
- package/.next/standalone/packages/ui/dist/static/chunks/d12ed5dbe44caed7.js +1 -0
- package/.next/standalone/packages/ui/dist/static/chunks/d1ebe5c1a344f4ca.js +5 -0
- package/.next/standalone/packages/ui/dist/static/chunks/d42cf1682bc46652.js +1 -0
- package/.next/standalone/packages/ui/dist/static/chunks/dde5d8bddd7fbfcf.js +1 -0
- package/.next/standalone/packages/ui/dist/static/chunks/ebd89051637b9a47.js +4 -0
- package/.next/standalone/packages/ui/dist/static/chunks/ec82875d18b29f47.js +2 -0
- package/.next/standalone/packages/ui/dist/static/chunks/f0b701df9769bcc5.js +19 -0
- package/.next/standalone/packages/ui/dist/static/chunks/turbopack-1c09a99f4c9e28d3.js +3 -0
- package/.next/standalone/packages/ui/leanspec.db +0 -0
- package/.next/standalone/packages/ui/package.json +1 -1
- package/.next/standalone/packages/ui/server.js +1 -1
- package/.next/standalone/packages/ui/tsconfig.tsbuildinfo +1 -1
- package/.next/static/T_KGFP0pHt_xSaaYUJa3L/_buildManifest.js +11 -0
- package/.next/static/T_KGFP0pHt_xSaaYUJa3L/_clientMiddlewareManifest.json +1 -0
- package/.next/static/T_KGFP0pHt_xSaaYUJa3L/_ssgManifest.js +1 -0
- package/package.json +2 -2
- /package/.next/standalone/packages/ui/.next/static/{WJi9opx4ShY8zt8yBFo4r → T_KGFP0pHt_xSaaYUJa3L}/_buildManifest.js +0 -0
- /package/.next/standalone/packages/ui/.next/static/{WJi9opx4ShY8zt8yBFo4r → T_KGFP0pHt_xSaaYUJa3L}/_clientMiddlewareManifest.json +0 -0
- /package/.next/standalone/packages/ui/.next/static/{WJi9opx4ShY8zt8yBFo4r → T_KGFP0pHt_xSaaYUJa3L}/_ssgManifest.js +0 -0
- /package/.next/{static/WJi9opx4ShY8zt8yBFo4r → standalone/packages/ui/dist/static/4ZnYN1WbN4LGJQOwP6FkT}/_buildManifest.js +0 -0
- /package/.next/{static/WJi9opx4ShY8zt8yBFo4r → standalone/packages/ui/dist/static/4ZnYN1WbN4LGJQOwP6FkT}/_clientMiddlewareManifest.json +0 -0
- /package/.next/{static/WJi9opx4ShY8zt8yBFo4r → standalone/packages/ui/dist/static/4ZnYN1WbN4LGJQOwP6FkT}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,724 @@
|
|
|
1
|
+
# Testing Strategy
|
|
2
|
+
|
|
3
|
+
**Comprehensive validation for programmatic spec management**
|
|
4
|
+
|
|
5
|
+
## Testing Philosophy
|
|
6
|
+
|
|
7
|
+
### Principles
|
|
8
|
+
|
|
9
|
+
1. **Test behavior, not implementation** - Focus on what transforms do, not how
|
|
10
|
+
2. **Fast feedback loops** - Unit tests run in <1s, integration in <5s
|
|
11
|
+
3. **Confidence through coverage** - Target >85% code coverage
|
|
12
|
+
4. **Real-world scenarios** - Use actual specs from project
|
|
13
|
+
5. **Regression prevention** - Golden tests capture known-good transformations
|
|
14
|
+
|
|
15
|
+
### Test Pyramid
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
/\
|
|
19
|
+
/ \ E2E (5%)
|
|
20
|
+
/----\ Integration (25%)
|
|
21
|
+
/ \ Unit (70%)
|
|
22
|
+
/________\
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Unit Tests
|
|
26
|
+
|
|
27
|
+
### Parser Tests
|
|
28
|
+
|
|
29
|
+
**File**: `src/analysis/parser/parser.test.ts`
|
|
30
|
+
|
|
31
|
+
```typescript
|
|
32
|
+
describe('MarkdownParser', () => {
|
|
33
|
+
describe('parse', () => {
|
|
34
|
+
it('should parse basic markdown', () => {
|
|
35
|
+
const content = `# Title\n\nParagraph`;
|
|
36
|
+
const ast = parser.parse(content);
|
|
37
|
+
|
|
38
|
+
expect(ast.type).toBe('root');
|
|
39
|
+
expect(ast.children).toHaveLength(2);
|
|
40
|
+
expect(ast.children[0].type).toBe('heading');
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it('should parse frontmatter', () => {
|
|
44
|
+
const content = `---\nstatus: planned\n---\n\n# Title`;
|
|
45
|
+
const ast = parser.parse(content);
|
|
46
|
+
|
|
47
|
+
expect(ast.frontmatter).toBeDefined();
|
|
48
|
+
expect(ast.frontmatter.data.status).toBe('planned');
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('should track line positions', () => {
|
|
52
|
+
const content = `# H1\n\nParagraph\n\n## H2`;
|
|
53
|
+
const ast = parser.parse(content);
|
|
54
|
+
|
|
55
|
+
const h1 = ast.children[0] as HeadingNode;
|
|
56
|
+
const h2 = ast.children[2] as HeadingNode;
|
|
57
|
+
|
|
58
|
+
expect(h1.position.start.line).toBe(1);
|
|
59
|
+
expect(h2.position.start.line).toBe(5);
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
describe('stringify', () => {
|
|
64
|
+
it('should round-trip correctly', () => {
|
|
65
|
+
const content = readTestFixture('simple-spec.md');
|
|
66
|
+
const ast = parser.parse(content);
|
|
67
|
+
const output = parser.stringify(ast);
|
|
68
|
+
|
|
69
|
+
expect(output).toBe(content);
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Analyzer Tests
|
|
76
|
+
|
|
77
|
+
**File**: `src/analysis/analyzer/complexity.test.ts`
|
|
78
|
+
|
|
79
|
+
```typescript
|
|
80
|
+
describe('ComplexityAnalyzer', () => {
|
|
81
|
+
it('should detect lines exceeding limit', () => {
|
|
82
|
+
const spec = createSpec({ tokenCount: 1800 });
|
|
83
|
+
const result = analyzer.analyze(spec);
|
|
84
|
+
|
|
85
|
+
expect(result.exceedsLimit).toBe(true);
|
|
86
|
+
expect(result.tokenCount).toBe(1800);
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
it('should validate token thresholds correctly', () => {
|
|
90
|
+
const simple = createSpec({ tokenCount: 400, sections: 5 });
|
|
91
|
+
const complex = createSpec({ tokenCount: 8000, sections: 50, nesting: 5 });
|
|
92
|
+
|
|
93
|
+
const simpleResult = analyzer.analyze(simple);
|
|
94
|
+
const complexResult = analyzer.analyze(complex);
|
|
95
|
+
|
|
96
|
+
expect(simpleResult.exceedsTokenLimit).toBe(false);
|
|
97
|
+
expect(complexResult.exceedsTokenLimit).toBe(true);
|
|
98
|
+
|
|
99
|
+
expect(complexScore).toBeGreaterThan(simpleScore);
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
it('should identify concerns', () => {
|
|
103
|
+
const spec = createSpecWithSections([
|
|
104
|
+
'Overview',
|
|
105
|
+
'Design',
|
|
106
|
+
'Implementation',
|
|
107
|
+
'Testing'
|
|
108
|
+
]);
|
|
109
|
+
|
|
110
|
+
const concerns = analyzer.extractConcerns(spec);
|
|
111
|
+
|
|
112
|
+
expect(concerns).toHaveLength(4);
|
|
113
|
+
expect(concerns[0].name).toBe('Overview');
|
|
114
|
+
expect(concerns[1].name).toBe('Design & Architecture');
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
**File**: `src/analysis/analyzer/redundancy.test.ts`
|
|
120
|
+
|
|
121
|
+
```typescript
|
|
122
|
+
describe('RedundancyAnalyzer', () => {
|
|
123
|
+
it('should find exact duplicates', () => {
|
|
124
|
+
const spec = createSpecWithDuplicates();
|
|
125
|
+
const result = analyzer.detectRedundancy(spec);
|
|
126
|
+
|
|
127
|
+
expect(result.duplicates).toHaveLength(2);
|
|
128
|
+
expect(result.duplicates[0].similarity).toBe(1.0);
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
it('should find near-duplicates', () => {
|
|
132
|
+
const spec = createSpecWithSimilarSections();
|
|
133
|
+
const result = analyzer.detectRedundancy(spec);
|
|
134
|
+
|
|
135
|
+
const nearDupe = result.duplicates.find(d => d.similarity < 1.0);
|
|
136
|
+
expect(nearDupe).toBeDefined();
|
|
137
|
+
expect(nearDupe.similarity).toBeGreaterThan(0.85);
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
it('should calculate potential savings', () => {
|
|
141
|
+
const spec = createSpecWithRedundancy();
|
|
142
|
+
const result = analyzer.detectRedundancy(spec);
|
|
143
|
+
|
|
144
|
+
expect(result.totalLinesSaved).toBeGreaterThan(0);
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### Transformer Tests
|
|
150
|
+
|
|
151
|
+
**File**: `src/analysis/transformer/partition.test.ts`
|
|
152
|
+
|
|
153
|
+
```typescript
|
|
154
|
+
describe('PartitionTransformer', () => {
|
|
155
|
+
it('should split by concerns', () => {
|
|
156
|
+
const spec = loadFixture('spec-045-original.md');
|
|
157
|
+
const ast = parser.parse(spec);
|
|
158
|
+
|
|
159
|
+
const result = transformer.apply(ast, { strategy: 'concerns' });
|
|
160
|
+
|
|
161
|
+
expect(result.subSpecs).toHaveLength(5);
|
|
162
|
+
expect(result.subSpecs[0].name).toBe('README.md');
|
|
163
|
+
expect(result.subSpecs[1].name).toBe('DESIGN.md');
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
it('should update cross-references', () => {
|
|
167
|
+
const spec = loadFixture('spec-with-refs.md');
|
|
168
|
+
const ast = parser.parse(spec);
|
|
169
|
+
|
|
170
|
+
const result = transformer.apply(ast, { strategy: 'concerns' });
|
|
171
|
+
|
|
172
|
+
const readme = result.subSpecs.find(s => s.name === 'README.md');
|
|
173
|
+
const refs = findReferences(readme.ast);
|
|
174
|
+
|
|
175
|
+
// Internal ref becomes sub-spec ref
|
|
176
|
+
expect(refs).toContainEqual({
|
|
177
|
+
type: 'sub-spec',
|
|
178
|
+
url: './DESIGN.md#architecture'
|
|
179
|
+
});
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
it('should preserve all content', () => {
|
|
183
|
+
const spec = loadFixture('spec-045-original.md');
|
|
184
|
+
const ast = parser.parse(spec);
|
|
185
|
+
|
|
186
|
+
const originalLines = countLines(ast);
|
|
187
|
+
const result = transformer.apply(ast, { strategy: 'concerns' });
|
|
188
|
+
const totalLines = result.subSpecs.reduce(
|
|
189
|
+
(sum, s) => sum + countLines(s.ast),
|
|
190
|
+
0
|
|
191
|
+
);
|
|
192
|
+
|
|
193
|
+
// Allow small difference for added headers/footers
|
|
194
|
+
expect(totalLines).toBeGreaterThanOrEqual(originalLines);
|
|
195
|
+
expect(totalLines).toBeLessThan(originalLines * 1.1);
|
|
196
|
+
});
|
|
197
|
+
});
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
**File**: `src/analysis/transformer/compact.test.ts`
|
|
201
|
+
|
|
202
|
+
```typescript
|
|
203
|
+
describe('CompactionTransformer', () => {
|
|
204
|
+
it('should remove exact duplicates', () => {
|
|
205
|
+
const spec = createSpecWithDuplicates();
|
|
206
|
+
|
|
207
|
+
const result = transformer.apply(spec);
|
|
208
|
+
|
|
209
|
+
const duplicates = findDuplicateSections(result);
|
|
210
|
+
expect(duplicates).toHaveLength(0);
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
it('should preserve decision rationale', () => {
|
|
214
|
+
const spec = loadFixture('spec-with-rationale.md');
|
|
215
|
+
|
|
216
|
+
const originalRationale = extractRationale(spec);
|
|
217
|
+
const result = transformer.apply(spec);
|
|
218
|
+
const resultRationale = extractRationale(result);
|
|
219
|
+
|
|
220
|
+
expect(resultRationale).toEqual(originalRationale);
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
it('should reduce token count', () => {
|
|
224
|
+
const spec = loadFixture('verbose-spec.md');
|
|
225
|
+
const originalLines = countLines(spec);
|
|
226
|
+
|
|
227
|
+
const result = transformer.apply(spec);
|
|
228
|
+
const resultLines = countLines(result);
|
|
229
|
+
|
|
230
|
+
expect(resultLines).toBeLessThan(originalLines);
|
|
231
|
+
});
|
|
232
|
+
});
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
### Reference Manager Tests
|
|
236
|
+
|
|
237
|
+
**File**: `src/analysis/references/manager.test.ts`
|
|
238
|
+
|
|
239
|
+
```typescript
|
|
240
|
+
describe('ReferenceManager', () => {
|
|
241
|
+
it('should find all references', () => {
|
|
242
|
+
const spec = loadFixture('spec-with-refs.md');
|
|
243
|
+
const refs = manager.findReferences(spec);
|
|
244
|
+
|
|
245
|
+
expect(refs).toContainEqual({
|
|
246
|
+
type: 'internal',
|
|
247
|
+
url: '#design'
|
|
248
|
+
});
|
|
249
|
+
expect(refs).toContainEqual({
|
|
250
|
+
type: 'sub-spec',
|
|
251
|
+
url: './TESTING.md'
|
|
252
|
+
});
|
|
253
|
+
expect(refs).toContainEqual({
|
|
254
|
+
type: 'cross-spec',
|
|
255
|
+
url: '../012-sub-spec-files/'
|
|
256
|
+
});
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
it('should update references after split', () => {
|
|
260
|
+
const spec = loadFixture('spec-before-split.md');
|
|
261
|
+
const mapping = {
|
|
262
|
+
'#design': './DESIGN.md#design',
|
|
263
|
+
'#testing': './TESTING.md#testing'
|
|
264
|
+
};
|
|
265
|
+
|
|
266
|
+
const updated = manager.updateReferences(spec, mapping);
|
|
267
|
+
const refs = manager.findReferences(updated);
|
|
268
|
+
|
|
269
|
+
expect(refs.find(r => r.url === '#design')).toBeUndefined();
|
|
270
|
+
expect(refs.find(r => r.url === './DESIGN.md#design')).toBeDefined();
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
it('should validate references', () => {
|
|
274
|
+
const spec = loadFixture('spec-with-broken-refs.md');
|
|
275
|
+
const result = manager.validateReferences(spec);
|
|
276
|
+
|
|
277
|
+
expect(result.passed).toBe(false);
|
|
278
|
+
expect(result.errors).toContainEqual({
|
|
279
|
+
message: 'Broken reference: #nonexistent'
|
|
280
|
+
});
|
|
281
|
+
});
|
|
282
|
+
});
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
## Integration Tests
|
|
286
|
+
|
|
287
|
+
### CLI Integration
|
|
288
|
+
|
|
289
|
+
**File**: `src/__tests__/cli-integration.test.ts`
|
|
290
|
+
|
|
291
|
+
```typescript
|
|
292
|
+
describe('CLI Integration', () => {
|
|
293
|
+
beforeEach(() => {
|
|
294
|
+
setupTestProject();
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
afterEach(() => {
|
|
298
|
+
cleanupTestProject();
|
|
299
|
+
});
|
|
300
|
+
|
|
301
|
+
it('should analyze spec complexity', async () => {
|
|
302
|
+
const result = await runCLI('analyze 045 --json');
|
|
303
|
+
const data = JSON.parse(result.stdout);
|
|
304
|
+
|
|
305
|
+
expect(data.complexity.tokenCount).toBeGreaterThan(3500);
|
|
306
|
+
expect(data.concerns).toHaveLength(5);
|
|
307
|
+
});
|
|
308
|
+
|
|
309
|
+
it('should split spec into sub-specs', async () => {
|
|
310
|
+
await runCLI('split 045 --force');
|
|
311
|
+
|
|
312
|
+
expect(fileExists('specs/045/README.md')).toBe(true);
|
|
313
|
+
expect(fileExists('specs/045/DESIGN.md')).toBe(true);
|
|
314
|
+
expect(fileExists('specs/045/IMPLEMENTATION.md')).toBe(true);
|
|
315
|
+
|
|
316
|
+
// Validate all files
|
|
317
|
+
const result = await runCLI('validate 045');
|
|
318
|
+
expect(result.code).toBe(0);
|
|
319
|
+
});
|
|
320
|
+
|
|
321
|
+
it('should compact verbose spec', async () => {
|
|
322
|
+
const before = readFile('specs/018/README.md');
|
|
323
|
+
const beforeLines = before.split('\n').length;
|
|
324
|
+
|
|
325
|
+
await runCLI('compact 018 --force');
|
|
326
|
+
|
|
327
|
+
const after = readFile('specs/018/README.md');
|
|
328
|
+
const afterLines = after.split('\n').length;
|
|
329
|
+
|
|
330
|
+
expect(afterLines).toBeLessThan(beforeLines);
|
|
331
|
+
});
|
|
332
|
+
|
|
333
|
+
it('should rollback transformation', async () => {
|
|
334
|
+
const original = readFile('specs/045/README.md');
|
|
335
|
+
|
|
336
|
+
await runCLI('split 045 --force');
|
|
337
|
+
await runCLI('rollback 045');
|
|
338
|
+
|
|
339
|
+
const restored = readFile('specs/045/README.md');
|
|
340
|
+
expect(restored).toBe(original);
|
|
341
|
+
});
|
|
342
|
+
});
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
### Transformation Workflows
|
|
346
|
+
|
|
347
|
+
**File**: `src/__tests__/workflows.test.ts`
|
|
348
|
+
|
|
349
|
+
```typescript
|
|
350
|
+
describe('Transformation Workflows', () => {
|
|
351
|
+
it('should handle full split workflow', async () => {
|
|
352
|
+
// 1. Analyze
|
|
353
|
+
const analysis = await analyze('045');
|
|
354
|
+
expect(analysis.recommendations[0].strategy).toBe('partition');
|
|
355
|
+
|
|
356
|
+
// 2. Preview
|
|
357
|
+
const preview = await previewSplit('045');
|
|
358
|
+
expect(preview.subSpecs).toHaveLength(5);
|
|
359
|
+
|
|
360
|
+
// 3. Apply
|
|
361
|
+
const result = await applySplit('045');
|
|
362
|
+
expect(result.success).toBe(true);
|
|
363
|
+
|
|
364
|
+
// 4. Validate
|
|
365
|
+
const validation = await validate('045');
|
|
366
|
+
expect(validation.passed).toBe(true);
|
|
367
|
+
});
|
|
368
|
+
|
|
369
|
+
it('should handle compaction + split workflow', async () => {
|
|
370
|
+
// Spec is verbose AND oversized
|
|
371
|
+
const spec = '018';
|
|
372
|
+
|
|
373
|
+
// 1. Compact first
|
|
374
|
+
await compact(spec);
|
|
375
|
+
|
|
376
|
+
// 2. Check if still needs split
|
|
377
|
+
const analysis = await analyze(spec);
|
|
378
|
+
|
|
379
|
+
if (analysis.exceedsLimit) {
|
|
380
|
+
// 3. Split if needed
|
|
381
|
+
await split(spec);
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
// 4. All files should be under limit
|
|
385
|
+
const files = await listFiles(spec);
|
|
386
|
+
for (const file of files) {
|
|
387
|
+
const tokens = await getTokenCount(file);
|
|
388
|
+
expect(tokens).toBeLessThanOrEqual(3500);
|
|
389
|
+
}
|
|
390
|
+
});
|
|
391
|
+
});
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
## Golden Tests
|
|
395
|
+
|
|
396
|
+
### Purpose
|
|
397
|
+
Capture known-good transformations as regression tests.
|
|
398
|
+
|
|
399
|
+
### Structure
|
|
400
|
+
|
|
401
|
+
```
|
|
402
|
+
tests/golden/
|
|
403
|
+
split-045-unified-dashboard/
|
|
404
|
+
input.md # Original spec
|
|
405
|
+
expected/
|
|
406
|
+
README.md # Expected output
|
|
407
|
+
DESIGN.md
|
|
408
|
+
RATIONALE.md
|
|
409
|
+
IMPLEMENTATION.md
|
|
410
|
+
TESTING.md
|
|
411
|
+
compact-018-validation/
|
|
412
|
+
input.md
|
|
413
|
+
expected.md
|
|
414
|
+
compress-043-phases/
|
|
415
|
+
input.md
|
|
416
|
+
expected.md
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
### Test Implementation
|
|
420
|
+
|
|
421
|
+
```typescript
|
|
422
|
+
describe('Golden Tests', () => {
|
|
423
|
+
const goldenDir = path.join(__dirname, 'golden');
|
|
424
|
+
|
|
425
|
+
describe('split transformations', () => {
|
|
426
|
+
const testCases = fs.readdirSync(goldenDir)
|
|
427
|
+
.filter(name => name.startsWith('split-'));
|
|
428
|
+
|
|
429
|
+
testCases.forEach(testCase => {
|
|
430
|
+
it(`should match golden output: ${testCase}`, async () => {
|
|
431
|
+
const inputPath = path.join(goldenDir, testCase, 'input.md');
|
|
432
|
+
const expectedDir = path.join(goldenDir, testCase, 'expected');
|
|
433
|
+
|
|
434
|
+
const input = fs.readFileSync(inputPath, 'utf-8');
|
|
435
|
+
const ast = parser.parse(input);
|
|
436
|
+
|
|
437
|
+
const result = await transformer.apply(ast, { strategy: 'auto' });
|
|
438
|
+
|
|
439
|
+
// Compare each output file
|
|
440
|
+
for (const subSpec of result.subSpecs) {
|
|
441
|
+
const actualContent = parser.stringify(subSpec.ast);
|
|
442
|
+
const expectedPath = path.join(expectedDir, subSpec.name);
|
|
443
|
+
const expectedContent = fs.readFileSync(expectedPath, 'utf-8');
|
|
444
|
+
|
|
445
|
+
expect(actualContent).toBe(expectedContent);
|
|
446
|
+
}
|
|
447
|
+
});
|
|
448
|
+
});
|
|
449
|
+
});
|
|
450
|
+
|
|
451
|
+
describe('compact transformations', () => {
|
|
452
|
+
// Similar structure for compaction tests
|
|
453
|
+
});
|
|
454
|
+
});
|
|
455
|
+
```
|
|
456
|
+
|
|
457
|
+
### Updating Golden Tests
|
|
458
|
+
|
|
459
|
+
When intentionally changing transformation behavior:
|
|
460
|
+
|
|
461
|
+
```bash
|
|
462
|
+
# Update golden test expectations
|
|
463
|
+
$ npm run test:golden -- --update
|
|
464
|
+
|
|
465
|
+
# Or manually:
|
|
466
|
+
$ npm run transform:split -- tests/golden/split-045/input.md \
|
|
467
|
+
--output tests/golden/split-045/expected/
|
|
468
|
+
```
|
|
469
|
+
|
|
470
|
+
## Performance Tests
|
|
471
|
+
|
|
472
|
+
### Benchmarks
|
|
473
|
+
|
|
474
|
+
```typescript
|
|
475
|
+
describe('Performance', () => {
|
|
476
|
+
it('should parse large spec in <50ms', async () => {
|
|
477
|
+
const largeSpec = createSpec({ tokenCount: 8000 });
|
|
478
|
+
|
|
479
|
+
const start = performance.now();
|
|
480
|
+
const ast = parser.parse(largeSpec);
|
|
481
|
+
const duration = performance.now() - start;
|
|
482
|
+
|
|
483
|
+
expect(duration).toBeLessThan(50);
|
|
484
|
+
});
|
|
485
|
+
|
|
486
|
+
it('should analyze in <100ms', async () => {
|
|
487
|
+
const spec = loadFixture('spec-045.md');
|
|
488
|
+
|
|
489
|
+
const start = performance.now();
|
|
490
|
+
await analyzer.analyze(spec);
|
|
491
|
+
const duration = performance.now() - start;
|
|
492
|
+
|
|
493
|
+
expect(duration).toBeLessThan(100);
|
|
494
|
+
});
|
|
495
|
+
|
|
496
|
+
it('should split in <500ms', async () => {
|
|
497
|
+
const spec = loadFixture('spec-045.md');
|
|
498
|
+
|
|
499
|
+
const start = performance.now();
|
|
500
|
+
await transformer.apply(spec, { strategy: 'auto' });
|
|
501
|
+
const duration = performance.now() - start;
|
|
502
|
+
|
|
503
|
+
expect(duration).toBeLessThan(500);
|
|
504
|
+
});
|
|
505
|
+
|
|
506
|
+
it('should analyze all specs in <2s', async () => {
|
|
507
|
+
const specs = await loadAllSpecs();
|
|
508
|
+
|
|
509
|
+
const start = performance.now();
|
|
510
|
+
for (const spec of specs) {
|
|
511
|
+
await analyzer.analyze(spec);
|
|
512
|
+
}
|
|
513
|
+
const duration = performance.now() - start;
|
|
514
|
+
|
|
515
|
+
expect(duration).toBeLessThan(2000);
|
|
516
|
+
});
|
|
517
|
+
});
|
|
518
|
+
```
|
|
519
|
+
|
|
520
|
+
## E2E Tests
|
|
521
|
+
|
|
522
|
+
### Real-World Scenarios
|
|
523
|
+
|
|
524
|
+
```typescript
|
|
525
|
+
describe('E2E: Real-world usage', () => {
|
|
526
|
+
it('should handle oversized spec from creation to split', async () => {
|
|
527
|
+
// 1. Create new spec
|
|
528
|
+
await runCLI('create test-large-spec');
|
|
529
|
+
|
|
530
|
+
// 2. Add content (simulate writing)
|
|
531
|
+
const specPath = 'specs/060-test-large-spec/README.md';
|
|
532
|
+
fs.writeFileSync(specPath, generateLargeSpec(1200));
|
|
533
|
+
|
|
534
|
+
// 3. Validate (should warn)
|
|
535
|
+
const validation = await runCLI('validate 060');
|
|
536
|
+
expect(validation.stderr).toContain('exceeds 5,000 tokens');
|
|
537
|
+
|
|
538
|
+
// 4. Analyze
|
|
539
|
+
const analysis = await runCLI('analyze 060 --json');
|
|
540
|
+
expect(JSON.parse(analysis.stdout).recommendations[0].strategy)
|
|
541
|
+
.toBe('partition');
|
|
542
|
+
|
|
543
|
+
// 5. Split
|
|
544
|
+
await runCLI('split 060 --force');
|
|
545
|
+
|
|
546
|
+
// 6. Validate all sub-specs pass
|
|
547
|
+
const finalValidation = await runCLI('validate 060');
|
|
548
|
+
expect(finalValidation.code).toBe(0);
|
|
549
|
+
});
|
|
550
|
+
|
|
551
|
+
it('should handle spec evolution: create → grow → compact → split', async () => {
|
|
552
|
+
// Simulate natural spec evolution
|
|
553
|
+
|
|
554
|
+
// Phase 1: Create simple spec (200 lines)
|
|
555
|
+
await createSpec('test-evolution', { lines: 200 });
|
|
556
|
+
|
|
557
|
+
// Phase 2: Grows to 350 lines (warning zone)
|
|
558
|
+
await appendContent('test-evolution', 150);
|
|
559
|
+
const warning = await runCLI('validate test-evolution');
|
|
560
|
+
expect(warning.stderr).toContain('approaching limit');
|
|
561
|
+
|
|
562
|
+
// Phase 3: Compact to 280 lines
|
|
563
|
+
await runCLI('compact test-evolution --force');
|
|
564
|
+
const postCompact = await getTokenCount('test-evolution');
|
|
565
|
+
expect(postCompact).toBeLessThan(300);
|
|
566
|
+
|
|
567
|
+
// Phase 4: Grows to 500 lines (exceeds limit)
|
|
568
|
+
await appendContent('test-evolution', 220);
|
|
569
|
+
|
|
570
|
+
// Phase 5: Must split
|
|
571
|
+
await runCLI('split test-evolution --force');
|
|
572
|
+
|
|
573
|
+
// Phase 6: All sub-specs under limit
|
|
574
|
+
const files = await listFiles('test-evolution');
|
|
575
|
+
for (const file of files) {
|
|
576
|
+
const tokens = await getTokenCount(file);
|
|
577
|
+
expect(tokens).toBeLessThanOrEqual(3500);
|
|
578
|
+
}
|
|
579
|
+
});
|
|
580
|
+
});
|
|
581
|
+
```
|
|
582
|
+
|
|
583
|
+
## Test Utilities
|
|
584
|
+
|
|
585
|
+
### Test Helpers
|
|
586
|
+
|
|
587
|
+
```typescript
|
|
588
|
+
// tests/helpers.ts
|
|
589
|
+
|
|
590
|
+
export function createSpec(options: {
|
|
591
|
+
tokenCount?: number;
|
|
592
|
+
sections?: number;
|
|
593
|
+
nesting?: number;
|
|
594
|
+
}): string {
|
|
595
|
+
// Generate synthetic spec with specified properties
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
export function createSpecWithSections(sectionNames: string[]): string {
|
|
599
|
+
// Generate spec with specific sections
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
export function createSpecWithDuplicates(): string {
|
|
603
|
+
// Generate spec with intentional duplicates
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
export function loadFixture(name: string): string {
|
|
607
|
+
return fs.readFileSync(
|
|
608
|
+
path.join(__dirname, 'fixtures', name),
|
|
609
|
+
'utf-8'
|
|
610
|
+
);
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
export async function runCLI(command: string): Promise<{
|
|
614
|
+
code: number;
|
|
615
|
+
stdout: string;
|
|
616
|
+
stderr: string;
|
|
617
|
+
}> {
|
|
618
|
+
return new Promise((resolve) => {
|
|
619
|
+
exec(`npx lean-spec ${command}`, (error, stdout, stderr) => {
|
|
620
|
+
resolve({
|
|
621
|
+
code: error?.code ?? 0,
|
|
622
|
+
stdout,
|
|
623
|
+
stderr
|
|
624
|
+
});
|
|
625
|
+
});
|
|
626
|
+
});
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
export function countLines(ast: SpecAST | string): number {
|
|
630
|
+
if (typeof ast === 'string') {
|
|
631
|
+
return ast.split('\n').length;
|
|
632
|
+
}
|
|
633
|
+
// Count from AST
|
|
634
|
+
}
|
|
635
|
+
```
|
|
636
|
+
|
|
637
|
+
## Coverage Goals
|
|
638
|
+
|
|
639
|
+
### Targets
|
|
640
|
+
|
|
641
|
+
| Category | Target Coverage |
|
|
642
|
+
|----------|----------------|
|
|
643
|
+
| Overall | >85% |
|
|
644
|
+
| Parser | >90% |
|
|
645
|
+
| Analyzers | >85% |
|
|
646
|
+
| Transformers | >90% |
|
|
647
|
+
| CLI | >75% |
|
|
648
|
+
| Utilities | >80% |
|
|
649
|
+
|
|
650
|
+
### Measuring Coverage
|
|
651
|
+
|
|
652
|
+
```bash
|
|
653
|
+
# Run tests with coverage
|
|
654
|
+
$ npm run test:coverage
|
|
655
|
+
|
|
656
|
+
# View HTML report
|
|
657
|
+
$ open coverage/index.html
|
|
658
|
+
|
|
659
|
+
# CI check
|
|
660
|
+
$ npm run test:ci
|
|
661
|
+
# Fails if coverage <85%
|
|
662
|
+
```
|
|
663
|
+
|
|
664
|
+
## Continuous Integration
|
|
665
|
+
|
|
666
|
+
### GitHub Actions Workflow
|
|
667
|
+
|
|
668
|
+
```yaml
|
|
669
|
+
# .github/workflows/test.yml
|
|
670
|
+
name: Test
|
|
671
|
+
|
|
672
|
+
on: [push, pull_request]
|
|
673
|
+
|
|
674
|
+
jobs:
|
|
675
|
+
test:
|
|
676
|
+
runs-on: ubuntu-latest
|
|
677
|
+
steps:
|
|
678
|
+
- uses: actions/checkout@v2
|
|
679
|
+
- uses: actions/setup-node@v2
|
|
680
|
+
with:
|
|
681
|
+
node-version: '18'
|
|
682
|
+
|
|
683
|
+
- name: Install dependencies
|
|
684
|
+
run: npm ci
|
|
685
|
+
|
|
686
|
+
- name: Run unit tests
|
|
687
|
+
run: npm run test:unit
|
|
688
|
+
|
|
689
|
+
- name: Run integration tests
|
|
690
|
+
run: npm run test:integration
|
|
691
|
+
|
|
692
|
+
- name: Run golden tests
|
|
693
|
+
run: npm run test:golden
|
|
694
|
+
|
|
695
|
+
- name: Check coverage
|
|
696
|
+
run: npm run test:coverage
|
|
697
|
+
|
|
698
|
+
- name: Upload coverage
|
|
699
|
+
uses: codecov/codecov-action@v2
|
|
700
|
+
with:
|
|
701
|
+
file: ./coverage/coverage-final.json
|
|
702
|
+
```
|
|
703
|
+
|
|
704
|
+
## Test Fixtures
|
|
705
|
+
|
|
706
|
+
### Maintained Test Specs
|
|
707
|
+
|
|
708
|
+
Keep real-world test cases:
|
|
709
|
+
|
|
710
|
+
```
|
|
711
|
+
tests/fixtures/
|
|
712
|
+
simple-spec.md # Basic spec <200 lines
|
|
713
|
+
medium-spec.md # Spec at warning (350 lines)
|
|
714
|
+
large-spec.md # Spec exceeding limit (600 lines)
|
|
715
|
+
spec-with-concerns.md # Clear concern boundaries
|
|
716
|
+
spec-with-phases.md # Phase-based structure
|
|
717
|
+
spec-with-refs.md # Many cross-references
|
|
718
|
+
verbose-spec.md # Redundant content
|
|
719
|
+
malformed-spec.md # Invalid markdown
|
|
720
|
+
```
|
|
721
|
+
|
|
722
|
+
---
|
|
723
|
+
|
|
724
|
+
**Key Principle**: Comprehensive testing builds confidence. Test the happy path, edge cases, and failure modes. Fast tests enable rapid iteration.
|