@mytechtoday/augment-extensions 0.2.0 → 0.5.0
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/README.md +614 -39
- package/augment-extensions/coding-standards/bash/README.md +196 -0
- package/augment-extensions/coding-standards/bash/module.json +163 -0
- package/augment-extensions/coding-standards/bash/rules/naming-conventions.md +336 -0
- package/augment-extensions/coding-standards/bash/rules/universal-standards.md +289 -0
- package/augment-extensions/coding-standards/css/README.md +40 -0
- package/augment-extensions/coding-standards/css/examples/css-examples.css +550 -0
- package/augment-extensions/coding-standards/css/module.json +44 -0
- package/augment-extensions/coding-standards/css/rules/css-modern-features.md +448 -0
- package/augment-extensions/coding-standards/css/rules/css-standards.md +492 -0
- package/augment-extensions/coding-standards/html/README.md +40 -0
- package/augment-extensions/coding-standards/html/examples/html-examples.html +267 -0
- package/augment-extensions/coding-standards/html/examples/responsive-layout.html +505 -0
- package/augment-extensions/coding-standards/html/module.json +44 -0
- package/augment-extensions/coding-standards/html/rules/html-standards.md +349 -0
- package/augment-extensions/coding-standards/html-css-js/README.md +194 -0
- package/augment-extensions/coding-standards/html-css-js/examples/async-examples.js +487 -0
- package/augment-extensions/coding-standards/html-css-js/examples/css-examples.css +550 -0
- package/augment-extensions/coding-standards/html-css-js/examples/dom-examples.js +667 -0
- package/augment-extensions/coding-standards/html-css-js/examples/html-examples.html +267 -0
- package/augment-extensions/coding-standards/html-css-js/examples/javascript-examples.js +612 -0
- package/augment-extensions/coding-standards/html-css-js/examples/responsive-layout.html +505 -0
- package/augment-extensions/coding-standards/html-css-js/module.json +48 -0
- package/augment-extensions/coding-standards/html-css-js/rules/async-patterns.md +515 -0
- package/augment-extensions/coding-standards/html-css-js/rules/css-modern-features.md +448 -0
- package/augment-extensions/coding-standards/html-css-js/rules/css-standards.md +492 -0
- package/augment-extensions/coding-standards/html-css-js/rules/dom-manipulation.md +439 -0
- package/augment-extensions/coding-standards/html-css-js/rules/html-standards.md +349 -0
- package/augment-extensions/coding-standards/html-css-js/rules/javascript-standards.md +486 -0
- package/augment-extensions/coding-standards/html-css-js/rules/performance.md +463 -0
- package/augment-extensions/coding-standards/html-css-js/rules/tooling.md +543 -0
- package/augment-extensions/coding-standards/js/README.md +46 -0
- package/augment-extensions/coding-standards/js/examples/async-examples.js +487 -0
- package/augment-extensions/coding-standards/js/examples/dom-examples.js +667 -0
- package/augment-extensions/coding-standards/js/examples/javascript-examples.js +612 -0
- package/augment-extensions/coding-standards/js/module.json +49 -0
- package/augment-extensions/coding-standards/js/rules/async-patterns.md +515 -0
- package/augment-extensions/coding-standards/js/rules/dom-manipulation.md +439 -0
- package/augment-extensions/coding-standards/js/rules/javascript-standards.md +486 -0
- package/augment-extensions/coding-standards/js/rules/performance.md +463 -0
- package/augment-extensions/coding-standards/js/rules/tooling.md +543 -0
- package/augment-extensions/coding-standards/php/README.md +248 -0
- package/augment-extensions/coding-standards/php/examples/api-endpoint-example.php +204 -0
- package/augment-extensions/coding-standards/php/examples/cli-command-example.php +206 -0
- package/augment-extensions/coding-standards/php/examples/legacy-refactoring-example.php +234 -0
- package/augment-extensions/coding-standards/php/examples/web-application-example.php +211 -0
- package/augment-extensions/coding-standards/php/examples/woocommerce-extension-example.php +215 -0
- package/augment-extensions/coding-standards/php/examples/wordpress-plugin-example.php +189 -0
- package/augment-extensions/coding-standards/php/module.json +166 -0
- package/augment-extensions/coding-standards/php/rules/api-development.md +480 -0
- package/augment-extensions/coding-standards/php/rules/category-configuration.md +332 -0
- package/augment-extensions/coding-standards/php/rules/cli-tools.md +472 -0
- package/augment-extensions/coding-standards/php/rules/cms-integration.md +561 -0
- package/augment-extensions/coding-standards/php/rules/code-quality.md +402 -0
- package/augment-extensions/coding-standards/php/rules/documentation.md +425 -0
- package/augment-extensions/coding-standards/php/rules/ecommerce.md +627 -0
- package/augment-extensions/coding-standards/php/rules/error-handling.md +336 -0
- package/augment-extensions/coding-standards/php/rules/legacy-migration.md +677 -0
- package/augment-extensions/coding-standards/php/rules/naming-conventions.md +279 -0
- package/augment-extensions/coding-standards/php/rules/performance.md +392 -0
- package/augment-extensions/coding-standards/php/rules/psr-standards.md +186 -0
- package/augment-extensions/coding-standards/php/rules/security.md +358 -0
- package/augment-extensions/coding-standards/php/rules/testing.md +403 -0
- package/augment-extensions/coding-standards/php/rules/type-declarations.md +331 -0
- package/augment-extensions/coding-standards/php/rules/web-applications.md +426 -0
- package/augment-extensions/coding-standards/powershell/README.md +154 -0
- package/augment-extensions/coding-standards/powershell/examples/admin-example.ps1 +272 -0
- package/augment-extensions/coding-standards/powershell/examples/automation-example.ps1 +173 -0
- package/augment-extensions/coding-standards/powershell/examples/cloud-example.ps1 +243 -0
- package/augment-extensions/coding-standards/powershell/examples/cross-platform-example.ps1 +297 -0
- package/augment-extensions/coding-standards/powershell/examples/dsc-example.ps1 +224 -0
- package/augment-extensions/coding-standards/powershell/examples/legacy-migration-example.ps1 +340 -0
- package/augment-extensions/coding-standards/powershell/examples/module-example.psm1 +255 -0
- package/augment-extensions/coding-standards/powershell/module.json +165 -0
- package/augment-extensions/coding-standards/powershell/rules/administrative-tools.md +439 -0
- package/augment-extensions/coding-standards/powershell/rules/automation-scripts.md +240 -0
- package/augment-extensions/coding-standards/powershell/rules/cloud-orchestration.md +384 -0
- package/augment-extensions/coding-standards/powershell/rules/configuration-schema.md +383 -0
- package/augment-extensions/coding-standards/powershell/rules/cross-platform-scripts.md +482 -0
- package/augment-extensions/coding-standards/powershell/rules/dsc-configurations.md +296 -0
- package/augment-extensions/coding-standards/powershell/rules/error-handling.md +314 -0
- package/augment-extensions/coding-standards/powershell/rules/legacy-migrations.md +466 -0
- package/augment-extensions/coding-standards/powershell/rules/modules-functions.md +244 -0
- package/augment-extensions/coding-standards/powershell/rules/naming-conventions.md +266 -0
- package/augment-extensions/coding-standards/powershell/rules/performance-optimization.md +209 -0
- package/augment-extensions/coding-standards/powershell/rules/security-practices.md +314 -0
- package/augment-extensions/coding-standards/powershell/rules/testing-guidelines.md +268 -0
- package/augment-extensions/coding-standards/powershell/rules/universal-standards.md +197 -0
- package/augment-extensions/coding-standards/python/README.md +12 -8
- package/augment-extensions/coding-standards/python/examples/best-practices.py +373 -0
- package/augment-extensions/coding-standards/python/module.json +8 -4
- package/augment-extensions/coding-standards/python/rules/async-patterns.md +884 -0
- package/augment-extensions/coding-standards/python/rules/documentation.md +831 -0
- package/augment-extensions/coding-standards/python/rules/error-handling.md +855 -68
- package/augment-extensions/coding-standards/python/rules/testing.md +409 -0
- package/augment-extensions/coding-standards/python/rules/tooling.md +446 -0
- package/augment-extensions/coding-standards/python/rules/type-hints.md +115 -50
- package/augment-extensions/collections/html-css-js/README.md +82 -0
- package/augment-extensions/collections/html-css-js/collection.json +41 -0
- package/augment-extensions/domain-rules/database/README.md +161 -0
- package/augment-extensions/domain-rules/database/examples/flat-database-example.md +793 -0
- package/augment-extensions/domain-rules/database/examples/hybrid-database-example.md +1132 -0
- package/augment-extensions/domain-rules/database/examples/nosql-document-example.md +868 -0
- package/augment-extensions/domain-rules/database/examples/nosql-graph-example.md +805 -0
- package/augment-extensions/domain-rules/database/examples/relational-schema-example.md +621 -0
- package/augment-extensions/domain-rules/database/examples/vector-database-example.md +965 -0
- package/augment-extensions/domain-rules/database/module.json +28 -0
- package/augment-extensions/domain-rules/database/rules/flat-databases.md +624 -0
- package/augment-extensions/domain-rules/database/rules/nosql-databases.md +588 -0
- package/augment-extensions/domain-rules/database/rules/nosql-document-stores.md +856 -0
- package/augment-extensions/domain-rules/database/rules/nosql-graph-databases.md +778 -0
- package/augment-extensions/domain-rules/database/rules/nosql-key-value-stores.md +963 -0
- package/augment-extensions/domain-rules/database/rules/performance-optimization.md +1076 -0
- package/augment-extensions/domain-rules/database/rules/relational-databases.md +697 -0
- package/augment-extensions/domain-rules/database/rules/relational-indexing.md +671 -0
- package/augment-extensions/domain-rules/database/rules/relational-query-optimization.md +607 -0
- package/augment-extensions/domain-rules/database/rules/relational-schema-design.md +907 -0
- package/augment-extensions/domain-rules/database/rules/relational-transactions.md +783 -0
- package/augment-extensions/domain-rules/database/rules/security-standards.md +980 -0
- package/augment-extensions/domain-rules/database/rules/universal-best-practices.md +485 -0
- package/augment-extensions/domain-rules/database/rules/vector-databases.md +521 -0
- package/augment-extensions/domain-rules/database/rules/vector-embeddings.md +858 -0
- package/augment-extensions/domain-rules/database/rules/vector-indexing.md +934 -0
- package/augment-extensions/domain-rules/design/color/themes/catppuccin-latte/README.md +23 -0
- package/augment-extensions/domain-rules/design/color/themes/catppuccin-latte/module.json +26 -0
- package/augment-extensions/domain-rules/design/color/themes/catppuccin-mocha/README.md +23 -0
- package/augment-extensions/domain-rules/design/color/themes/catppuccin-mocha/module.json +26 -0
- package/augment-extensions/domain-rules/design/color/themes/dracula/README.md +23 -0
- package/augment-extensions/domain-rules/design/color/themes/dracula/module.json +26 -0
- package/augment-extensions/domain-rules/design/color/themes/gruvbox-dark/README.md +23 -0
- package/augment-extensions/domain-rules/design/color/themes/gruvbox-dark/module.json +26 -0
- package/augment-extensions/domain-rules/design/color/themes/gruvbox-light/README.md +23 -0
- package/augment-extensions/domain-rules/design/color/themes/gruvbox-light/module.json +26 -0
- package/augment-extensions/domain-rules/design/color/themes/high-contrast/README.md +27 -0
- package/augment-extensions/domain-rules/design/color/themes/high-contrast/module.json +26 -0
- package/augment-extensions/domain-rules/design/color/themes/monokai/README.md +23 -0
- package/augment-extensions/domain-rules/design/color/themes/monokai/module.json +26 -0
- package/augment-extensions/domain-rules/design/color/themes/nord/README.md +23 -0
- package/augment-extensions/domain-rules/design/color/themes/nord/module.json +26 -0
- package/augment-extensions/domain-rules/design/color/themes/one-dark/README.md +23 -0
- package/augment-extensions/domain-rules/design/color/themes/one-dark/module.json +26 -0
- package/augment-extensions/domain-rules/design/color/themes/one-light/README.md +23 -0
- package/augment-extensions/domain-rules/design/color/themes/one-light/module.json +26 -0
- package/augment-extensions/domain-rules/design/color/themes/solarized-dark/README.md +23 -0
- package/augment-extensions/domain-rules/design/color/themes/solarized-dark/module.json +26 -0
- package/augment-extensions/domain-rules/design/color/themes/solarized-light/README.md +23 -0
- package/augment-extensions/domain-rules/design/color/themes/solarized-light/module.json +26 -0
- package/augment-extensions/domain-rules/design/color/themes/tokyo-night/README.md +23 -0
- package/augment-extensions/domain-rules/design/color/themes/tokyo-night/module.json +26 -0
- package/augment-extensions/domain-rules/marketing-standards/seo-sales-marketing/README.md +136 -0
- package/augment-extensions/domain-rules/marketing-standards/seo-sales-marketing/SCHEMA-VALIDATION-REPORT.md +216 -0
- package/augment-extensions/domain-rules/marketing-standards/seo-sales-marketing/examples/brand-kit-example.yaml +292 -0
- package/augment-extensions/domain-rules/marketing-standards/seo-sales-marketing/examples/campaign-brief-example.yaml +389 -0
- package/augment-extensions/domain-rules/marketing-standards/seo-sales-marketing/examples/content-calendar-example.yaml +643 -0
- package/augment-extensions/domain-rules/marketing-standards/seo-sales-marketing/examples/email-newsletter-example.md +376 -0
- package/augment-extensions/domain-rules/marketing-standards/seo-sales-marketing/examples/landing-page-example.md +934 -0
- package/augment-extensions/domain-rules/marketing-standards/seo-sales-marketing/examples/ppc-ad-copy-example.md +301 -0
- package/augment-extensions/domain-rules/marketing-standards/seo-sales-marketing/examples/seo-blog-post-example.md +347 -0
- package/augment-extensions/domain-rules/marketing-standards/seo-sales-marketing/examples/social-media-campaign-example.md +606 -0
- package/augment-extensions/domain-rules/marketing-standards/seo-sales-marketing/module.json +50 -0
- package/augment-extensions/domain-rules/marketing-standards/seo-sales-marketing/rules/affiliate-influencer-marketing.md +593 -0
- package/augment-extensions/domain-rules/marketing-standards/seo-sales-marketing/rules/asset-management.md +418 -0
- package/augment-extensions/domain-rules/marketing-standards/seo-sales-marketing/rules/brand-consistency.md +210 -0
- package/augment-extensions/domain-rules/marketing-standards/seo-sales-marketing/rules/content-marketing.md +337 -0
- package/augment-extensions/domain-rules/marketing-standards/seo-sales-marketing/rules/conversion-optimization.md +455 -0
- package/augment-extensions/domain-rules/marketing-standards/seo-sales-marketing/rules/direct-sales.md +499 -0
- package/augment-extensions/domain-rules/marketing-standards/seo-sales-marketing/rules/email-marketing.md +439 -0
- package/augment-extensions/domain-rules/marketing-standards/seo-sales-marketing/rules/legal-compliance.md +227 -0
- package/augment-extensions/domain-rules/marketing-standards/seo-sales-marketing/rules/ppc-advertising.md +569 -0
- package/augment-extensions/domain-rules/marketing-standards/seo-sales-marketing/rules/seo-optimization.md +470 -0
- package/augment-extensions/domain-rules/marketing-standards/seo-sales-marketing/rules/social-media-marketing.md +414 -0
- package/augment-extensions/domain-rules/marketing-standards/seo-sales-marketing/rules/universal-marketing.md +177 -0
- package/augment-extensions/domain-rules/marketing-standards/seo-sales-marketing/schemas/asset-inventory.schema.json +247 -0
- package/augment-extensions/domain-rules/marketing-standards/seo-sales-marketing/schemas/brand-kit.schema.json +326 -0
- package/augment-extensions/domain-rules/marketing-standards/seo-sales-marketing/schemas/campaign-brief.schema.json +342 -0
- package/augment-extensions/domain-rules/marketing-standards/seo-sales-marketing/schemas/color-palette.schema.json +223 -0
- package/augment-extensions/domain-rules/marketing-standards/seo-sales-marketing/schemas/content-template.schema.json +383 -0
- package/augment-extensions/domain-rules/mcp/README.md +150 -0
- package/augment-extensions/domain-rules/mcp/examples/compressed-example.md +522 -0
- package/augment-extensions/domain-rules/mcp/examples/graph-augmented-example.md +520 -0
- package/augment-extensions/domain-rules/mcp/examples/hybrid-example.md +570 -0
- package/augment-extensions/domain-rules/mcp/examples/state-based-example.md +427 -0
- package/augment-extensions/domain-rules/mcp/examples/token-based-example.md +435 -0
- package/augment-extensions/domain-rules/mcp/examples/vector-based-example.md +502 -0
- package/augment-extensions/domain-rules/mcp/module.json +49 -0
- package/augment-extensions/domain-rules/mcp/rules/compressed-mcp.md +595 -0
- package/augment-extensions/domain-rules/mcp/rules/configuration.md +345 -0
- package/augment-extensions/domain-rules/mcp/rules/graph-augmented-mcp.md +687 -0
- package/augment-extensions/domain-rules/mcp/rules/hybrid-mcp.md +636 -0
- package/augment-extensions/domain-rules/mcp/rules/state-based-mcp.md +484 -0
- package/augment-extensions/domain-rules/mcp/rules/testing-validation.md +360 -0
- package/augment-extensions/domain-rules/mcp/rules/token-based-mcp.md +393 -0
- package/augment-extensions/domain-rules/mcp/rules/universal-rules.md +194 -0
- package/augment-extensions/domain-rules/mcp/rules/vector-based-mcp.md +625 -0
- package/augment-extensions/workflows/beads/module.json +4 -3
- package/augment-extensions/workflows/beads-integration/IMPLEMENTATION-STATUS.md +145 -0
- package/augment-extensions/workflows/beads-integration/README.md +143 -0
- package/augment-extensions/workflows/beads-integration/config/defaults.json +32 -0
- package/augment-extensions/workflows/beads-integration/config/schema.json +140 -0
- package/augment-extensions/workflows/beads-integration/examples/basic-task-generation.md +293 -0
- package/augment-extensions/workflows/beads-integration/module.json +75 -0
- package/augment-extensions/workflows/beads-integration/rules/core-rules.md +219 -0
- package/augment-extensions/workflows/beads-integration/rules/effectiveness-standards.md +256 -0
- package/augment-extensions/workflows/beads-integration/rules/task-generation.md +607 -0
- package/augment-extensions/workflows/database/README.md +195 -0
- package/augment-extensions/workflows/database/ai-prompt-testing.md +295 -0
- package/augment-extensions/workflows/database/examples/migration-example.md +498 -0
- package/augment-extensions/workflows/database/examples/optimization-example.md +496 -0
- package/augment-extensions/workflows/database/examples/schema-design-example.md +444 -0
- package/augment-extensions/workflows/database/module.json +42 -0
- package/augment-extensions/workflows/database/rules/data-migration.md +249 -0
- package/augment-extensions/workflows/database/rules/documentation-standards.md +339 -0
- package/augment-extensions/workflows/database/rules/migration-workflow.md +352 -0
- package/augment-extensions/workflows/database/rules/optimization-workflow.md +435 -0
- package/augment-extensions/workflows/database/rules/schema-design-workflow.md +535 -0
- package/augment-extensions/workflows/database/rules/testing-patterns.md +305 -0
- package/augment-extensions/workflows/database/rules/workflow.md +458 -0
- package/augment-extensions/workflows/openspec/module.json +4 -3
- package/augment-extensions/writing-standards/screenplay/README.md +300 -0
- package/augment-extensions/writing-standards/screenplay/_templates/README.md +121 -0
- package/augment-extensions/writing-standards/screenplay/_templates/genre-template.md +153 -0
- package/augment-extensions/writing-standards/screenplay/_templates/style-template.md +243 -0
- package/augment-extensions/writing-standards/screenplay/_templates/theme-template.md +213 -0
- package/augment-extensions/writing-standards/screenplay/examples/aaa-hollywood-scene.fountain +164 -0
- package/augment-extensions/writing-standards/screenplay/examples/beat-sheet-example.yaml +95 -0
- package/augment-extensions/writing-standards/screenplay/examples/character-profile-example.yaml +116 -0
- package/augment-extensions/writing-standards/screenplay/examples/commercial-30sec.fountain +151 -0
- package/augment-extensions/writing-standards/screenplay/examples/independent-monologue.fountain +67 -0
- package/augment-extensions/writing-standards/screenplay/examples/news-segment.fountain +142 -0
- package/augment-extensions/writing-standards/screenplay/examples/plot-outline-example.yaml +184 -0
- package/augment-extensions/writing-standards/screenplay/examples/tv-episode-teaser.fountain +204 -0
- package/augment-extensions/writing-standards/screenplay/genres/README.md +181 -0
- package/augment-extensions/writing-standards/screenplay/genres/examples/.gitkeep +2 -0
- package/augment-extensions/writing-standards/screenplay/genres/module.json +70 -0
- package/augment-extensions/writing-standards/screenplay/genres/rules/.gitkeep +2 -0
- package/augment-extensions/writing-standards/screenplay/genres/rules/action.md +399 -0
- package/augment-extensions/writing-standards/screenplay/genres/rules/adventure.md +407 -0
- package/augment-extensions/writing-standards/screenplay/genres/rules/animation.md +293 -0
- package/augment-extensions/writing-standards/screenplay/genres/rules/biographical.md +293 -0
- package/augment-extensions/writing-standards/screenplay/genres/rules/comedy.md +401 -0
- package/augment-extensions/writing-standards/screenplay/genres/rules/documentary.md +293 -0
- package/augment-extensions/writing-standards/screenplay/genres/rules/drama.md +409 -0
- package/augment-extensions/writing-standards/screenplay/genres/rules/fantasy.md +293 -0
- package/augment-extensions/writing-standards/screenplay/genres/rules/historical.md +293 -0
- package/augment-extensions/writing-standards/screenplay/genres/rules/horror.md +268 -0
- package/augment-extensions/writing-standards/screenplay/genres/rules/musical.md +294 -0
- package/augment-extensions/writing-standards/screenplay/genres/rules/mystery.md +293 -0
- package/augment-extensions/writing-standards/screenplay/genres/rules/noir.md +294 -0
- package/augment-extensions/writing-standards/screenplay/genres/rules/romance.md +293 -0
- package/augment-extensions/writing-standards/screenplay/genres/rules/sci-fi.md +289 -0
- package/augment-extensions/writing-standards/screenplay/genres/rules/superhero.md +293 -0
- package/augment-extensions/writing-standards/screenplay/genres/rules/thriller.md +294 -0
- package/augment-extensions/writing-standards/screenplay/genres/rules/western.md +293 -0
- package/augment-extensions/writing-standards/screenplay/module.json +124 -0
- package/augment-extensions/writing-standards/screenplay/rules/aaa-hollywood-films.md +339 -0
- package/augment-extensions/writing-standards/screenplay/rules/ai-integration-testing.md +329 -0
- package/augment-extensions/writing-standards/screenplay/rules/character-development.md +169 -0
- package/augment-extensions/writing-standards/screenplay/rules/commercials.md +437 -0
- package/augment-extensions/writing-standards/screenplay/rules/dialogue-writing.md +263 -0
- package/augment-extensions/writing-standards/screenplay/rules/diversity-inclusion.md +261 -0
- package/augment-extensions/writing-standards/screenplay/rules/examples-guide.md +315 -0
- package/augment-extensions/writing-standards/screenplay/rules/formatting-validation.md +413 -0
- package/augment-extensions/writing-standards/screenplay/rules/fountain-format.md +372 -0
- package/augment-extensions/writing-standards/screenplay/rules/independent-films.md +374 -0
- package/augment-extensions/writing-standards/screenplay/rules/live-tv-productions.md +443 -0
- package/augment-extensions/writing-standards/screenplay/rules/narrative-structures.md +207 -0
- package/augment-extensions/writing-standards/screenplay/rules/news-broadcasts.md +444 -0
- package/augment-extensions/writing-standards/screenplay/rules/pacing-timing.md +331 -0
- package/augment-extensions/writing-standards/screenplay/rules/quality-review-checklist.md +334 -0
- package/augment-extensions/writing-standards/screenplay/rules/quick-reference.md +299 -0
- package/augment-extensions/writing-standards/screenplay/rules/screen-continuity.md +263 -0
- package/augment-extensions/writing-standards/screenplay/rules/streaming-content.md +412 -0
- package/augment-extensions/writing-standards/screenplay/rules/trope-management.md +370 -0
- package/augment-extensions/writing-standards/screenplay/rules/tv-series.md +374 -0
- package/augment-extensions/writing-standards/screenplay/rules/universal-formatting.md +339 -0
- package/augment-extensions/writing-standards/screenplay/rules/vscode-integration.md +277 -0
- package/augment-extensions/writing-standards/screenplay/rules/web-content.md +393 -0
- package/augment-extensions/writing-standards/screenplay/schemas/beat-sheet.json +332 -0
- package/augment-extensions/writing-standards/screenplay/schemas/character-profile.json +247 -0
- package/augment-extensions/writing-standards/screenplay/schemas/feature-selection.json +200 -0
- package/augment-extensions/writing-standards/screenplay/schemas/plot-outline.json +233 -0
- package/augment-extensions/writing-standards/screenplay/schemas/screenplay-config.json +245 -0
- package/augment-extensions/writing-standards/screenplay/schemas/trope-inventory.json +221 -0
- package/augment-extensions/writing-standards/screenplay/styles/README.md +159 -0
- package/augment-extensions/writing-standards/screenplay/styles/examples/.gitkeep +2 -0
- package/augment-extensions/writing-standards/screenplay/styles/examples/style-applications.md +1449 -0
- package/augment-extensions/writing-standards/screenplay/styles/module.json +64 -0
- package/augment-extensions/writing-standards/screenplay/styles/rules/.gitkeep +2 -0
- package/augment-extensions/writing-standards/screenplay/styles/rules/dialogue-centric.md +520 -0
- package/augment-extensions/writing-standards/screenplay/styles/rules/ensemble.md +499 -0
- package/augment-extensions/writing-standards/screenplay/styles/rules/epic.md +497 -0
- package/augment-extensions/writing-standards/screenplay/styles/rules/experimental.md +492 -0
- package/augment-extensions/writing-standards/screenplay/styles/rules/flashback.md +509 -0
- package/augment-extensions/writing-standards/screenplay/styles/rules/linear.md +490 -0
- package/augment-extensions/writing-standards/screenplay/styles/rules/minimalist.md +499 -0
- package/augment-extensions/writing-standards/screenplay/styles/rules/non-linear.md +501 -0
- package/augment-extensions/writing-standards/screenplay/styles/rules/poetic.md +499 -0
- package/augment-extensions/writing-standards/screenplay/styles/rules/realistic.md +498 -0
- package/augment-extensions/writing-standards/screenplay/styles/rules/satirical.md +499 -0
- package/augment-extensions/writing-standards/screenplay/styles/rules/surreal.md +508 -0
- package/augment-extensions/writing-standards/screenplay/styles/rules/voice-over.md +500 -0
- package/augment-extensions/writing-standards/screenplay/themes/README.md +158 -0
- package/augment-extensions/writing-standards/screenplay/themes/examples/.gitkeep +2 -0
- package/augment-extensions/writing-standards/screenplay/themes/examples/common-mistakes-and-fixes.md +643 -0
- package/augment-extensions/writing-standards/screenplay/themes/examples/complete-scene-example.md +311 -0
- package/augment-extensions/writing-standards/screenplay/themes/examples/individual-theme-examples.md +562 -0
- package/augment-extensions/writing-standards/screenplay/themes/examples/multi-theme-weaving.md +538 -0
- package/augment-extensions/writing-standards/screenplay/themes/examples/theme-application-guide.md +432 -0
- package/augment-extensions/writing-standards/screenplay/themes/examples/theme-integration-across-acts.md +637 -0
- package/augment-extensions/writing-standards/screenplay/themes/module.json +66 -0
- package/augment-extensions/writing-standards/screenplay/themes/rules/.gitkeep +2 -0
- package/augment-extensions/writing-standards/screenplay/themes/rules/ambition.md +458 -0
- package/augment-extensions/writing-standards/screenplay/themes/rules/betrayal.md +490 -0
- package/augment-extensions/writing-standards/screenplay/themes/rules/environment.md +458 -0
- package/augment-extensions/writing-standards/screenplay/themes/rules/fate.md +459 -0
- package/augment-extensions/writing-standards/screenplay/themes/rules/friendship.md +491 -0
- package/augment-extensions/writing-standards/screenplay/themes/rules/growth.md +491 -0
- package/augment-extensions/writing-standards/screenplay/themes/rules/identity.md +490 -0
- package/augment-extensions/writing-standards/screenplay/themes/rules/isolation.md +464 -0
- package/augment-extensions/writing-standards/screenplay/themes/rules/justice.md +461 -0
- package/augment-extensions/writing-standards/screenplay/themes/rules/love.md +489 -0
- package/augment-extensions/writing-standards/screenplay/themes/rules/power.md +494 -0
- package/augment-extensions/writing-standards/screenplay/themes/rules/redemption.md +483 -0
- package/augment-extensions/writing-standards/screenplay/themes/rules/revenge.md +489 -0
- package/augment-extensions/writing-standards/screenplay/themes/rules/survival.md +496 -0
- package/augment-extensions/writing-standards/screenplay/themes/rules/technology.md +463 -0
- package/cli/MODULES.md +302 -0
- package/cli/dist/cli.js +168 -10
- package/cli/dist/cli.js.map +1 -1
- package/cli/dist/commands/catalog.d.ts +13 -0
- package/cli/dist/commands/catalog.d.ts.map +1 -0
- package/cli/dist/commands/catalog.js +104 -0
- package/cli/dist/commands/catalog.js.map +1 -0
- package/cli/dist/commands/gui.d.ts +6 -0
- package/cli/dist/commands/gui.d.ts.map +1 -0
- package/cli/dist/commands/gui.js +211 -0
- package/cli/dist/commands/gui.js.map +1 -0
- package/cli/dist/commands/init.d.ts.map +1 -1
- package/cli/dist/commands/init.js +12 -0
- package/cli/dist/commands/init.js.map +1 -1
- package/cli/dist/commands/install-rules.d.ts +14 -0
- package/cli/dist/commands/install-rules.d.ts.map +1 -0
- package/cli/dist/commands/install-rules.js +127 -0
- package/cli/dist/commands/install-rules.js.map +1 -0
- package/cli/dist/commands/link.d.ts.map +1 -1
- package/cli/dist/commands/link.js +9 -11
- package/cli/dist/commands/link.js.map +1 -1
- package/cli/dist/commands/list.d.ts.map +1 -1
- package/cli/dist/commands/list.js +11 -28
- package/cli/dist/commands/list.js.map +1 -1
- package/cli/dist/commands/mcp.d.ts +48 -0
- package/cli/dist/commands/mcp.d.ts.map +1 -0
- package/cli/dist/commands/mcp.js +229 -0
- package/cli/dist/commands/mcp.js.map +1 -0
- package/cli/dist/commands/self-remove.d.ts +7 -0
- package/cli/dist/commands/self-remove.d.ts.map +1 -0
- package/cli/dist/commands/self-remove.js +179 -0
- package/cli/dist/commands/self-remove.js.map +1 -0
- package/cli/dist/commands/show.d.ts +19 -0
- package/cli/dist/commands/show.d.ts.map +1 -1
- package/cli/dist/commands/show.js +478 -63
- package/cli/dist/commands/show.js.map +1 -1
- package/cli/dist/commands/skill.d.ts +67 -0
- package/cli/dist/commands/skill.d.ts.map +1 -0
- package/cli/dist/commands/skill.js +513 -0
- package/cli/dist/commands/skill.js.map +1 -0
- package/cli/dist/commands/unlink.d.ts +6 -0
- package/cli/dist/commands/unlink.d.ts.map +1 -0
- package/cli/dist/commands/unlink.js +115 -0
- package/cli/dist/commands/unlink.js.map +1 -0
- package/cli/dist/commands/validate.d.ts +6 -0
- package/cli/dist/commands/validate.d.ts.map +1 -0
- package/cli/dist/commands/validate.js +159 -0
- package/cli/dist/commands/validate.js.map +1 -0
- package/cli/dist/types/gui.d.ts +62 -0
- package/cli/dist/types/gui.d.ts.map +1 -0
- package/cli/dist/types/gui.js +30 -0
- package/cli/dist/types/gui.js.map +1 -0
- package/cli/dist/utils/catalog-sync.d.ts +22 -0
- package/cli/dist/utils/catalog-sync.d.ts.map +1 -0
- package/cli/dist/utils/catalog-sync.js +157 -0
- package/cli/dist/utils/catalog-sync.js.map +1 -0
- package/cli/dist/utils/character-count.d.ts +56 -0
- package/cli/dist/utils/character-count.d.ts.map +1 -0
- package/cli/dist/utils/character-count.js +190 -0
- package/cli/dist/utils/character-count.js.map +1 -0
- package/cli/dist/utils/documentation-validator.d.ts +18 -0
- package/cli/dist/utils/documentation-validator.d.ts.map +1 -0
- package/cli/dist/utils/documentation-validator.js +233 -0
- package/cli/dist/utils/documentation-validator.js.map +1 -0
- package/cli/dist/utils/gui-helpers.d.ts +23 -0
- package/cli/dist/utils/gui-helpers.d.ts.map +1 -0
- package/cli/dist/utils/gui-helpers.js +159 -0
- package/cli/dist/utils/gui-helpers.js.map +1 -0
- package/cli/dist/utils/install-rules.d.ts +32 -0
- package/cli/dist/utils/install-rules.d.ts.map +1 -0
- package/cli/dist/utils/install-rules.js +375 -0
- package/cli/dist/utils/install-rules.js.map +1 -0
- package/cli/dist/utils/mcp-integration.d.ts +70 -0
- package/cli/dist/utils/mcp-integration.d.ts.map +1 -0
- package/cli/dist/utils/mcp-integration.js +292 -0
- package/cli/dist/utils/mcp-integration.js.map +1 -0
- package/cli/dist/utils/module-system.d.ts +232 -0
- package/cli/dist/utils/module-system.d.ts.map +1 -0
- package/cli/dist/utils/module-system.js +900 -0
- package/cli/dist/utils/module-system.js.map +1 -0
- package/cli/dist/utils/modules-catalog.d.ts +33 -0
- package/cli/dist/utils/modules-catalog.d.ts.map +1 -0
- package/cli/dist/utils/modules-catalog.js +163 -0
- package/cli/dist/utils/modules-catalog.js.map +1 -0
- package/cli/dist/utils/rule-install-hooks.d.ts +19 -0
- package/cli/dist/utils/rule-install-hooks.d.ts.map +1 -0
- package/cli/dist/utils/rule-install-hooks.js +224 -0
- package/cli/dist/utils/rule-install-hooks.js.map +1 -0
- package/cli/dist/utils/skill-system.d.ts +95 -0
- package/cli/dist/utils/skill-system.d.ts.map +1 -0
- package/cli/dist/utils/skill-system.js +313 -0
- package/cli/dist/utils/skill-system.js.map +1 -0
- package/modules.md +559 -105
- package/package.json +17 -6
|
@@ -0,0 +1,900 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.getModulesDir = getModulesDir;
|
|
37
|
+
exports.validateModuleMetadata = validateModuleMetadata;
|
|
38
|
+
exports.isValidSemanticVersion = isValidSemanticVersion;
|
|
39
|
+
exports.parseSemanticVersion = parseSemanticVersion;
|
|
40
|
+
exports.compareSemanticVersions = compareSemanticVersions;
|
|
41
|
+
exports.satisfiesVersionRange = satisfiesVersionRange;
|
|
42
|
+
exports.loadModule = loadModule;
|
|
43
|
+
exports.extractModuleMetadata = extractModuleMetadata;
|
|
44
|
+
exports.generateDefaultMetadata = generateDefaultMetadata;
|
|
45
|
+
exports.listModuleFiles = listModuleFiles;
|
|
46
|
+
exports.groupFilesByDirectory = groupFilesByDirectory;
|
|
47
|
+
exports.getFileStatistics = getFileStatistics;
|
|
48
|
+
exports.discoverModules = discoverModules;
|
|
49
|
+
exports.discoverCollections = discoverCollections;
|
|
50
|
+
exports.findModule = findModule;
|
|
51
|
+
exports.searchModules = searchModules;
|
|
52
|
+
exports.findModuleEnhanced = findModuleEnhanced;
|
|
53
|
+
exports.getModuleSuggestions = getModuleSuggestions;
|
|
54
|
+
exports.findCollection = findCollection;
|
|
55
|
+
exports.resolveCollection = resolveCollection;
|
|
56
|
+
exports.resolveCollectionByName = resolveCollectionByName;
|
|
57
|
+
exports.isCollection = isCollection;
|
|
58
|
+
exports.isModule = isModule;
|
|
59
|
+
exports.validateModuleStructure = validateModuleStructure;
|
|
60
|
+
exports.validateModuleCategory = validateModuleCategory;
|
|
61
|
+
exports.calculateModuleCharacterCount = calculateModuleCharacterCount;
|
|
62
|
+
exports.validateProjectAgnostic = validateProjectAgnostic;
|
|
63
|
+
const fs = __importStar(require("fs"));
|
|
64
|
+
const path = __importStar(require("path"));
|
|
65
|
+
/**
|
|
66
|
+
* Get the modules directory path
|
|
67
|
+
*/
|
|
68
|
+
function getModulesDir() {
|
|
69
|
+
return path.join(__dirname, '../../../augment-extensions');
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Validate module.json structure
|
|
73
|
+
*/
|
|
74
|
+
function validateModuleMetadata(metadata) {
|
|
75
|
+
const errors = [];
|
|
76
|
+
const warnings = [];
|
|
77
|
+
// Required fields
|
|
78
|
+
if (!metadata.name)
|
|
79
|
+
errors.push('Missing required field: name');
|
|
80
|
+
if (!metadata.version)
|
|
81
|
+
errors.push('Missing required field: version');
|
|
82
|
+
if (!metadata.displayName)
|
|
83
|
+
errors.push('Missing required field: displayName');
|
|
84
|
+
if (!metadata.description)
|
|
85
|
+
errors.push('Missing required field: description');
|
|
86
|
+
if (!metadata.type)
|
|
87
|
+
errors.push('Missing required field: type');
|
|
88
|
+
// Validate type
|
|
89
|
+
const validTypes = ['coding-standards', 'domain-rules', 'workflows', 'examples', 'marketing-standards', 'writing-standards', 'themes'];
|
|
90
|
+
if (metadata.type && !validTypes.includes(metadata.type)) {
|
|
91
|
+
errors.push(`Invalid type: ${metadata.type}. Must be one of: ${validTypes.join(', ')}`);
|
|
92
|
+
}
|
|
93
|
+
// Validate version format (semantic versioning)
|
|
94
|
+
if (metadata.version && !isValidSemanticVersion(metadata.version)) {
|
|
95
|
+
errors.push(`Invalid version format: ${metadata.version}. Must follow MAJOR.MINOR.PATCH`);
|
|
96
|
+
}
|
|
97
|
+
// Validate augment.characterCount if present
|
|
98
|
+
if (metadata.augment?.characterCount !== undefined) {
|
|
99
|
+
if (typeof metadata.augment.characterCount !== 'number' || metadata.augment.characterCount < 0) {
|
|
100
|
+
errors.push('augment.characterCount must be a positive number');
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
// Validate augment.priority if present
|
|
104
|
+
if (metadata.augment?.priority) {
|
|
105
|
+
const validPriorities = ['high', 'medium', 'low'];
|
|
106
|
+
if (!validPriorities.includes(metadata.augment.priority)) {
|
|
107
|
+
warnings.push(`Invalid priority: ${metadata.augment.priority}. Should be one of: ${validPriorities.join(', ')}`);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return {
|
|
111
|
+
valid: errors.length === 0,
|
|
112
|
+
errors,
|
|
113
|
+
warnings
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Validate semantic version format
|
|
118
|
+
* Supports: MAJOR.MINOR.PATCH[-prerelease][+build]
|
|
119
|
+
* Examples: 1.0.0, 1.0.0-alpha, 1.0.0-beta.1, 1.0.0+20130313144700, 1.0.0-beta+exp.sha.5114f85
|
|
120
|
+
*/
|
|
121
|
+
function isValidSemanticVersion(version) {
|
|
122
|
+
// Full semver pattern with optional pre-release and build metadata
|
|
123
|
+
const semverPattern = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/;
|
|
124
|
+
return semverPattern.test(version);
|
|
125
|
+
}
|
|
126
|
+
function parseSemanticVersion(version) {
|
|
127
|
+
if (!isValidSemanticVersion(version)) {
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
130
|
+
const match = version.match(/^(\d+)\.(\d+)\.(\d+)(?:-([0-9a-zA-Z-.]+))?(?:\+([0-9a-zA-Z-.]+))?$/);
|
|
131
|
+
if (!match) {
|
|
132
|
+
return null;
|
|
133
|
+
}
|
|
134
|
+
return {
|
|
135
|
+
major: parseInt(match[1], 10),
|
|
136
|
+
minor: parseInt(match[2], 10),
|
|
137
|
+
patch: parseInt(match[3], 10),
|
|
138
|
+
prerelease: match[4],
|
|
139
|
+
build: match[5]
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Compare two semantic versions
|
|
144
|
+
* Returns: -1 if v1 < v2, 0 if v1 === v2, 1 if v1 > v2
|
|
145
|
+
*/
|
|
146
|
+
function compareSemanticVersions(v1, v2) {
|
|
147
|
+
const parsed1 = parseSemanticVersion(v1);
|
|
148
|
+
const parsed2 = parseSemanticVersion(v2);
|
|
149
|
+
if (!parsed1 || !parsed2) {
|
|
150
|
+
throw new Error('Invalid semantic version format');
|
|
151
|
+
}
|
|
152
|
+
// Compare major, minor, patch
|
|
153
|
+
if (parsed1.major !== parsed2.major) {
|
|
154
|
+
return parsed1.major > parsed2.major ? 1 : -1;
|
|
155
|
+
}
|
|
156
|
+
if (parsed1.minor !== parsed2.minor) {
|
|
157
|
+
return parsed1.minor > parsed2.minor ? 1 : -1;
|
|
158
|
+
}
|
|
159
|
+
if (parsed1.patch !== parsed2.patch) {
|
|
160
|
+
return parsed1.patch > parsed2.patch ? 1 : -1;
|
|
161
|
+
}
|
|
162
|
+
// Handle pre-release versions
|
|
163
|
+
// Version without pre-release > version with pre-release
|
|
164
|
+
if (!parsed1.prerelease && parsed2.prerelease)
|
|
165
|
+
return 1;
|
|
166
|
+
if (parsed1.prerelease && !parsed2.prerelease)
|
|
167
|
+
return -1;
|
|
168
|
+
if (parsed1.prerelease && parsed2.prerelease) {
|
|
169
|
+
return parsed1.prerelease.localeCompare(parsed2.prerelease);
|
|
170
|
+
}
|
|
171
|
+
// Build metadata is ignored in version precedence
|
|
172
|
+
return 0;
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Check if version satisfies a range (simple implementation)
|
|
176
|
+
* Supports: ^1.0.0 (compatible), ~1.0.0 (patch), >=1.0.0, >1.0.0, <=1.0.0, <1.0.0, 1.0.0 (exact)
|
|
177
|
+
*/
|
|
178
|
+
function satisfiesVersionRange(version, range) {
|
|
179
|
+
const parsed = parseSemanticVersion(version);
|
|
180
|
+
if (!parsed)
|
|
181
|
+
return false;
|
|
182
|
+
// Exact match
|
|
183
|
+
if (!range.match(/^[~^<>=]/)) {
|
|
184
|
+
return version === range;
|
|
185
|
+
}
|
|
186
|
+
// Caret (^) - compatible with version
|
|
187
|
+
if (range.startsWith('^')) {
|
|
188
|
+
const rangeVersion = range.slice(1);
|
|
189
|
+
const rangeParsed = parseSemanticVersion(rangeVersion);
|
|
190
|
+
if (!rangeParsed)
|
|
191
|
+
return false;
|
|
192
|
+
if (parsed.major !== rangeParsed.major)
|
|
193
|
+
return false;
|
|
194
|
+
if (parsed.major === 0) {
|
|
195
|
+
// For 0.x.y, minor version must match
|
|
196
|
+
if (parsed.minor !== rangeParsed.minor)
|
|
197
|
+
return false;
|
|
198
|
+
}
|
|
199
|
+
return compareSemanticVersions(version, rangeVersion) >= 0;
|
|
200
|
+
}
|
|
201
|
+
// Tilde (~) - patch updates
|
|
202
|
+
if (range.startsWith('~')) {
|
|
203
|
+
const rangeVersion = range.slice(1);
|
|
204
|
+
const rangeParsed = parseSemanticVersion(rangeVersion);
|
|
205
|
+
if (!rangeParsed)
|
|
206
|
+
return false;
|
|
207
|
+
if (parsed.major !== rangeParsed.major || parsed.minor !== rangeParsed.minor) {
|
|
208
|
+
return false;
|
|
209
|
+
}
|
|
210
|
+
return compareSemanticVersions(version, rangeVersion) >= 0;
|
|
211
|
+
}
|
|
212
|
+
// Comparison operators
|
|
213
|
+
if (range.startsWith('>=')) {
|
|
214
|
+
return compareSemanticVersions(version, range.slice(2)) >= 0;
|
|
215
|
+
}
|
|
216
|
+
if (range.startsWith('>')) {
|
|
217
|
+
return compareSemanticVersions(version, range.slice(1)) > 0;
|
|
218
|
+
}
|
|
219
|
+
if (range.startsWith('<=')) {
|
|
220
|
+
return compareSemanticVersions(version, range.slice(2)) <= 0;
|
|
221
|
+
}
|
|
222
|
+
if (range.startsWith('<')) {
|
|
223
|
+
return compareSemanticVersions(version, range.slice(1)) < 0;
|
|
224
|
+
}
|
|
225
|
+
return false;
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Load module from path
|
|
229
|
+
*/
|
|
230
|
+
function loadModule(modulePath) {
|
|
231
|
+
const moduleJsonPath = path.join(modulePath, 'module.json');
|
|
232
|
+
if (!fs.existsSync(moduleJsonPath)) {
|
|
233
|
+
return null;
|
|
234
|
+
}
|
|
235
|
+
try {
|
|
236
|
+
const metadata = JSON.parse(fs.readFileSync(moduleJsonPath, 'utf-8'));
|
|
237
|
+
// Get rules
|
|
238
|
+
const rulesDir = path.join(modulePath, 'rules');
|
|
239
|
+
const rules = fs.existsSync(rulesDir)
|
|
240
|
+
? fs.readdirSync(rulesDir).filter(f => f.endsWith('.md'))
|
|
241
|
+
: [];
|
|
242
|
+
// Get examples
|
|
243
|
+
const examplesDir = path.join(modulePath, 'examples');
|
|
244
|
+
const examples = fs.existsSync(examplesDir)
|
|
245
|
+
? fs.readdirSync(examplesDir)
|
|
246
|
+
: [];
|
|
247
|
+
// Extract full name from path
|
|
248
|
+
const modulesDir = getModulesDir();
|
|
249
|
+
const relativePath = path.relative(modulesDir, modulePath);
|
|
250
|
+
const fullName = relativePath.replace(/\\/g, '/');
|
|
251
|
+
return {
|
|
252
|
+
metadata,
|
|
253
|
+
path: modulePath,
|
|
254
|
+
fullName,
|
|
255
|
+
rules,
|
|
256
|
+
examples
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
catch (error) {
|
|
260
|
+
return null;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Extract comprehensive metadata from a module
|
|
265
|
+
* Includes file counts, sizes, and last modified dates
|
|
266
|
+
*/
|
|
267
|
+
function extractModuleMetadata(modulePath) {
|
|
268
|
+
const moduleJsonPath = path.join(modulePath, 'module.json');
|
|
269
|
+
// Try to load module.json
|
|
270
|
+
let metadata;
|
|
271
|
+
if (fs.existsSync(moduleJsonPath)) {
|
|
272
|
+
try {
|
|
273
|
+
metadata = JSON.parse(fs.readFileSync(moduleJsonPath, 'utf-8'));
|
|
274
|
+
}
|
|
275
|
+
catch (error) {
|
|
276
|
+
// Invalid JSON - generate default metadata
|
|
277
|
+
metadata = generateDefaultMetadata(modulePath);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
else {
|
|
281
|
+
// Missing module.json - generate default metadata
|
|
282
|
+
metadata = generateDefaultMetadata(modulePath);
|
|
283
|
+
}
|
|
284
|
+
// Collect file statistics
|
|
285
|
+
const fileStats = collectFileStatistics(modulePath);
|
|
286
|
+
const sizeStats = calculateSizeStatistics(modulePath);
|
|
287
|
+
const lastModified = getLastModifiedDate(modulePath);
|
|
288
|
+
return {
|
|
289
|
+
...metadata,
|
|
290
|
+
files: fileStats,
|
|
291
|
+
size: sizeStats,
|
|
292
|
+
lastModified
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Generate default metadata for modules without module.json
|
|
297
|
+
*/
|
|
298
|
+
function generateDefaultMetadata(modulePath) {
|
|
299
|
+
const modulesDir = getModulesDir();
|
|
300
|
+
const relativePath = path.relative(modulesDir, modulePath);
|
|
301
|
+
const parts = relativePath.split(path.sep);
|
|
302
|
+
const category = parts[0];
|
|
303
|
+
const moduleName = parts[parts.length - 1];
|
|
304
|
+
return {
|
|
305
|
+
name: moduleName,
|
|
306
|
+
version: '0.0.0',
|
|
307
|
+
displayName: moduleName.split('-').map(w => w.charAt(0).toUpperCase() + w.slice(1)).join(' '),
|
|
308
|
+
description: `Module: ${moduleName}`,
|
|
309
|
+
type: ['coding-standards', 'domain-rules', 'workflows', 'examples', 'marketing-standards', 'writing-standards', 'themes'].includes(category)
|
|
310
|
+
? category
|
|
311
|
+
: 'examples',
|
|
312
|
+
augment: {
|
|
313
|
+
characterCount: 0,
|
|
314
|
+
priority: 'medium',
|
|
315
|
+
category: category
|
|
316
|
+
}
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* Collect file statistics for a module
|
|
321
|
+
*/
|
|
322
|
+
function collectFileStatistics(modulePath) {
|
|
323
|
+
let total = 0;
|
|
324
|
+
let rules = 0;
|
|
325
|
+
let examples = 0;
|
|
326
|
+
let other = 0;
|
|
327
|
+
function countFiles(dir, isRulesDir = false, isExamplesDir = false) {
|
|
328
|
+
if (!fs.existsSync(dir))
|
|
329
|
+
return;
|
|
330
|
+
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
331
|
+
for (const entry of entries) {
|
|
332
|
+
const fullPath = path.join(dir, entry.name);
|
|
333
|
+
if (entry.isDirectory()) {
|
|
334
|
+
const isRules = entry.name === 'rules';
|
|
335
|
+
const isExamples = entry.name === 'examples';
|
|
336
|
+
countFiles(fullPath, isRules, isExamples);
|
|
337
|
+
}
|
|
338
|
+
else if (entry.isFile()) {
|
|
339
|
+
total++;
|
|
340
|
+
if (isRulesDir) {
|
|
341
|
+
rules++;
|
|
342
|
+
}
|
|
343
|
+
else if (isExamplesDir) {
|
|
344
|
+
examples++;
|
|
345
|
+
}
|
|
346
|
+
else {
|
|
347
|
+
other++;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
countFiles(modulePath);
|
|
353
|
+
return { total, rules, examples, other };
|
|
354
|
+
}
|
|
355
|
+
/**
|
|
356
|
+
* Calculate size statistics for a module
|
|
357
|
+
*/
|
|
358
|
+
function calculateSizeStatistics(modulePath) {
|
|
359
|
+
let totalBytes = 0;
|
|
360
|
+
let totalCharacters = 0;
|
|
361
|
+
function calculateSize(dir) {
|
|
362
|
+
if (!fs.existsSync(dir))
|
|
363
|
+
return;
|
|
364
|
+
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
365
|
+
for (const entry of entries) {
|
|
366
|
+
const fullPath = path.join(dir, entry.name);
|
|
367
|
+
if (entry.isDirectory()) {
|
|
368
|
+
calculateSize(fullPath);
|
|
369
|
+
}
|
|
370
|
+
else if (entry.isFile()) {
|
|
371
|
+
const stats = fs.statSync(fullPath);
|
|
372
|
+
totalBytes += stats.size;
|
|
373
|
+
// Count characters for text files
|
|
374
|
+
if (entry.name.endsWith('.md') || entry.name.endsWith('.json') || entry.name.endsWith('.txt')) {
|
|
375
|
+
try {
|
|
376
|
+
const content = fs.readFileSync(fullPath, 'utf-8');
|
|
377
|
+
totalCharacters += content.length;
|
|
378
|
+
}
|
|
379
|
+
catch (error) {
|
|
380
|
+
// Skip binary files
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
calculateSize(modulePath);
|
|
387
|
+
return { totalBytes, totalCharacters };
|
|
388
|
+
}
|
|
389
|
+
/**
|
|
390
|
+
* Get the last modified date of a module (most recent file modification)
|
|
391
|
+
*/
|
|
392
|
+
function getLastModifiedDate(modulePath) {
|
|
393
|
+
let latestDate = new Date(0); // Epoch
|
|
394
|
+
function findLatestDate(dir) {
|
|
395
|
+
if (!fs.existsSync(dir))
|
|
396
|
+
return;
|
|
397
|
+
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
398
|
+
for (const entry of entries) {
|
|
399
|
+
const fullPath = path.join(dir, entry.name);
|
|
400
|
+
if (entry.isDirectory()) {
|
|
401
|
+
findLatestDate(fullPath);
|
|
402
|
+
}
|
|
403
|
+
else if (entry.isFile()) {
|
|
404
|
+
const stats = fs.statSync(fullPath);
|
|
405
|
+
if (stats.mtime > latestDate) {
|
|
406
|
+
latestDate = stats.mtime;
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
findLatestDate(modulePath);
|
|
412
|
+
return latestDate;
|
|
413
|
+
}
|
|
414
|
+
/**
|
|
415
|
+
* List all files in a module with metadata
|
|
416
|
+
*/
|
|
417
|
+
function listModuleFiles(modulePath, options = {}) {
|
|
418
|
+
const { recursive = true, filter, groupByDirectory = false } = options;
|
|
419
|
+
const files = [];
|
|
420
|
+
function scanDirectory(dir, baseDir = modulePath) {
|
|
421
|
+
if (!fs.existsSync(dir))
|
|
422
|
+
return;
|
|
423
|
+
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
424
|
+
for (const entry of entries) {
|
|
425
|
+
const fullPath = path.join(dir, entry.name);
|
|
426
|
+
const relativePath = path.relative(baseDir, fullPath);
|
|
427
|
+
if (entry.isDirectory()) {
|
|
428
|
+
if (recursive) {
|
|
429
|
+
scanDirectory(fullPath, baseDir);
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
else if (entry.isFile()) {
|
|
433
|
+
// Apply filter if specified
|
|
434
|
+
if (filter && !matchesFilter(entry.name, filter)) {
|
|
435
|
+
continue;
|
|
436
|
+
}
|
|
437
|
+
const stats = fs.statSync(fullPath);
|
|
438
|
+
const extension = path.extname(entry.name);
|
|
439
|
+
const directory = path.dirname(relativePath);
|
|
440
|
+
// Determine file type
|
|
441
|
+
let fileType = 'other';
|
|
442
|
+
if (directory.includes('rules')) {
|
|
443
|
+
fileType = 'rule';
|
|
444
|
+
}
|
|
445
|
+
else if (directory.includes('examples')) {
|
|
446
|
+
fileType = 'example';
|
|
447
|
+
}
|
|
448
|
+
else if (entry.name === 'module.json' || entry.name === 'collection.json') {
|
|
449
|
+
fileType = 'config';
|
|
450
|
+
}
|
|
451
|
+
else if (entry.name === 'README.md' || extension === '.md') {
|
|
452
|
+
fileType = 'documentation';
|
|
453
|
+
}
|
|
454
|
+
files.push({
|
|
455
|
+
name: entry.name,
|
|
456
|
+
path: fullPath,
|
|
457
|
+
relativePath,
|
|
458
|
+
size: stats.size,
|
|
459
|
+
modified: stats.mtime,
|
|
460
|
+
type: fileType,
|
|
461
|
+
extension,
|
|
462
|
+
directory
|
|
463
|
+
});
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
scanDirectory(modulePath);
|
|
468
|
+
// Sort files
|
|
469
|
+
if (groupByDirectory) {
|
|
470
|
+
files.sort((a, b) => {
|
|
471
|
+
// Sort by directory first, then by name
|
|
472
|
+
if (a.directory !== b.directory) {
|
|
473
|
+
return a.directory.localeCompare(b.directory);
|
|
474
|
+
}
|
|
475
|
+
return a.name.localeCompare(b.name);
|
|
476
|
+
});
|
|
477
|
+
}
|
|
478
|
+
else {
|
|
479
|
+
// Sort by name only
|
|
480
|
+
files.sort((a, b) => a.name.localeCompare(b.name));
|
|
481
|
+
}
|
|
482
|
+
return files;
|
|
483
|
+
}
|
|
484
|
+
/**
|
|
485
|
+
* Match file name against filter pattern (simple glob support)
|
|
486
|
+
*/
|
|
487
|
+
function matchesFilter(fileName, filter) {
|
|
488
|
+
// Convert glob pattern to regex
|
|
489
|
+
const regexPattern = filter
|
|
490
|
+
.replace(/\./g, '\\.') // Escape dots
|
|
491
|
+
.replace(/\*/g, '.*') // * matches any characters
|
|
492
|
+
.replace(/\?/g, '.'); // ? matches single character
|
|
493
|
+
const regex = new RegExp(`^${regexPattern}$`, 'i');
|
|
494
|
+
return regex.test(fileName);
|
|
495
|
+
}
|
|
496
|
+
/**
|
|
497
|
+
* Group files by directory
|
|
498
|
+
*/
|
|
499
|
+
function groupFilesByDirectory(files) {
|
|
500
|
+
const grouped = new Map();
|
|
501
|
+
for (const file of files) {
|
|
502
|
+
const dir = file.directory || '.';
|
|
503
|
+
if (!grouped.has(dir)) {
|
|
504
|
+
grouped.set(dir, []);
|
|
505
|
+
}
|
|
506
|
+
grouped.get(dir).push(file);
|
|
507
|
+
}
|
|
508
|
+
return grouped;
|
|
509
|
+
}
|
|
510
|
+
/**
|
|
511
|
+
* Get file statistics for a list of files
|
|
512
|
+
*/
|
|
513
|
+
function getFileStatistics(files) {
|
|
514
|
+
const byType = {
|
|
515
|
+
rule: 0,
|
|
516
|
+
example: 0,
|
|
517
|
+
config: 0,
|
|
518
|
+
documentation: 0,
|
|
519
|
+
other: 0
|
|
520
|
+
};
|
|
521
|
+
const byExtension = {};
|
|
522
|
+
let totalSize = 0;
|
|
523
|
+
for (const file of files) {
|
|
524
|
+
totalSize += file.size;
|
|
525
|
+
byType[file.type]++;
|
|
526
|
+
const ext = file.extension || 'no-extension';
|
|
527
|
+
byExtension[ext] = (byExtension[ext] || 0) + 1;
|
|
528
|
+
}
|
|
529
|
+
return {
|
|
530
|
+
totalFiles: files.length,
|
|
531
|
+
totalSize,
|
|
532
|
+
byType,
|
|
533
|
+
byExtension
|
|
534
|
+
};
|
|
535
|
+
}
|
|
536
|
+
/**
|
|
537
|
+
* Recursively find all module.json files in a directory
|
|
538
|
+
*/
|
|
539
|
+
function findModuleJsonFiles(dir) {
|
|
540
|
+
const results = [];
|
|
541
|
+
if (!fs.existsSync(dir)) {
|
|
542
|
+
return results;
|
|
543
|
+
}
|
|
544
|
+
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
545
|
+
for (const entry of entries) {
|
|
546
|
+
const fullPath = path.join(dir, entry.name);
|
|
547
|
+
if (entry.isDirectory()) {
|
|
548
|
+
// Recursively search subdirectories
|
|
549
|
+
results.push(...findModuleJsonFiles(fullPath));
|
|
550
|
+
}
|
|
551
|
+
else if (entry.isFile() && entry.name === 'module.json') {
|
|
552
|
+
// Found a module.json file - return its parent directory
|
|
553
|
+
results.push(dir);
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
return results;
|
|
557
|
+
}
|
|
558
|
+
/**
|
|
559
|
+
* Discover all modules in the modules directory
|
|
560
|
+
*/
|
|
561
|
+
function discoverModules() {
|
|
562
|
+
const modules = [];
|
|
563
|
+
const modulesDir = getModulesDir();
|
|
564
|
+
if (!fs.existsSync(modulesDir)) {
|
|
565
|
+
return modules;
|
|
566
|
+
}
|
|
567
|
+
// Recursively find all directories containing module.json files
|
|
568
|
+
const modulePaths = findModuleJsonFiles(modulesDir);
|
|
569
|
+
// Filter out collections directory
|
|
570
|
+
const filteredPaths = modulePaths.filter(p => !p.includes(path.join(modulesDir, 'collections')));
|
|
571
|
+
for (const modulePath of filteredPaths) {
|
|
572
|
+
const module = loadModule(modulePath);
|
|
573
|
+
if (module) {
|
|
574
|
+
modules.push(module);
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
return modules;
|
|
578
|
+
}
|
|
579
|
+
/**
|
|
580
|
+
* Discover all collections in the collections directory
|
|
581
|
+
*/
|
|
582
|
+
function discoverCollections() {
|
|
583
|
+
const collections = [];
|
|
584
|
+
const modulesDir = getModulesDir();
|
|
585
|
+
const collectionsDir = path.join(modulesDir, 'collections');
|
|
586
|
+
if (!fs.existsSync(collectionsDir)) {
|
|
587
|
+
return collections;
|
|
588
|
+
}
|
|
589
|
+
const collectionNames = fs.readdirSync(collectionsDir, { withFileTypes: true })
|
|
590
|
+
.filter(dirent => dirent.isDirectory())
|
|
591
|
+
.map(dirent => dirent.name);
|
|
592
|
+
for (const collectionName of collectionNames) {
|
|
593
|
+
const collectionPath = path.join(collectionsDir, collectionName);
|
|
594
|
+
const collectionJsonPath = path.join(collectionPath, 'collection.json');
|
|
595
|
+
if (fs.existsSync(collectionJsonPath)) {
|
|
596
|
+
try {
|
|
597
|
+
const metadata = JSON.parse(fs.readFileSync(collectionJsonPath, 'utf-8'));
|
|
598
|
+
collections.push({
|
|
599
|
+
metadata,
|
|
600
|
+
path: collectionPath,
|
|
601
|
+
fullName: `collections/${collectionName}`
|
|
602
|
+
});
|
|
603
|
+
}
|
|
604
|
+
catch (error) {
|
|
605
|
+
console.error(`Error loading collection ${collectionName}:`, error);
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
return collections;
|
|
610
|
+
}
|
|
611
|
+
/**
|
|
612
|
+
* Find module by name (supports both "category/module" and "module" formats)
|
|
613
|
+
*/
|
|
614
|
+
function findModule(moduleName) {
|
|
615
|
+
const modulesDir = getModulesDir();
|
|
616
|
+
// If moduleName includes category (e.g., "coding-standards/typescript")
|
|
617
|
+
if (moduleName.includes('/')) {
|
|
618
|
+
const modulePath = path.join(modulesDir, moduleName);
|
|
619
|
+
return loadModule(modulePath);
|
|
620
|
+
}
|
|
621
|
+
// Search all categories for the module
|
|
622
|
+
const modules = discoverModules();
|
|
623
|
+
return modules.find(m => m.fullName.endsWith(`/${moduleName}`)) || null;
|
|
624
|
+
}
|
|
625
|
+
function searchModules(searchTerm, options = {}) {
|
|
626
|
+
const { caseSensitive = false, exactMatch = false, category } = options;
|
|
627
|
+
const allModules = discoverModules();
|
|
628
|
+
const searchLower = caseSensitive ? searchTerm : searchTerm.toLowerCase();
|
|
629
|
+
return allModules.filter(module => {
|
|
630
|
+
const moduleName = caseSensitive ? module.fullName : module.fullName.toLowerCase();
|
|
631
|
+
const moduleShortName = caseSensitive ? module.metadata.name : module.metadata.name.toLowerCase();
|
|
632
|
+
// Filter by category if specified
|
|
633
|
+
if (category) {
|
|
634
|
+
const moduleCategory = module.fullName.split('/')[0];
|
|
635
|
+
if (moduleCategory !== category) {
|
|
636
|
+
return false;
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
// Exact match
|
|
640
|
+
if (exactMatch) {
|
|
641
|
+
return moduleName === searchLower || moduleShortName === searchLower;
|
|
642
|
+
}
|
|
643
|
+
// Partial match (contains search term)
|
|
644
|
+
return moduleName.includes(searchLower) ||
|
|
645
|
+
moduleShortName.includes(searchLower) ||
|
|
646
|
+
(module.metadata.displayName &&
|
|
647
|
+
(caseSensitive ? module.metadata.displayName : module.metadata.displayName.toLowerCase()).includes(searchLower));
|
|
648
|
+
});
|
|
649
|
+
}
|
|
650
|
+
/**
|
|
651
|
+
* Find module with enhanced discovery
|
|
652
|
+
* Tries exact match first, then falls back to fuzzy search
|
|
653
|
+
*/
|
|
654
|
+
function findModuleEnhanced(moduleName) {
|
|
655
|
+
// Try exact match first
|
|
656
|
+
let module = findModule(moduleName);
|
|
657
|
+
if (module) {
|
|
658
|
+
return module;
|
|
659
|
+
}
|
|
660
|
+
// Try case-insensitive search
|
|
661
|
+
const results = searchModules(moduleName, { caseSensitive: false, exactMatch: false });
|
|
662
|
+
// If exactly one result, return it
|
|
663
|
+
if (results.length === 1) {
|
|
664
|
+
return results[0];
|
|
665
|
+
}
|
|
666
|
+
// If multiple results, try to find exact match (case-insensitive)
|
|
667
|
+
const exactMatches = results.filter(m => m.fullName.toLowerCase() === moduleName.toLowerCase() ||
|
|
668
|
+
m.metadata.name.toLowerCase() === moduleName.toLowerCase());
|
|
669
|
+
if (exactMatches.length === 1) {
|
|
670
|
+
return exactMatches[0];
|
|
671
|
+
}
|
|
672
|
+
// No unique match found
|
|
673
|
+
return null;
|
|
674
|
+
}
|
|
675
|
+
/**
|
|
676
|
+
* Get module suggestions for a search term
|
|
677
|
+
* Returns up to maxSuggestions similar modules
|
|
678
|
+
*/
|
|
679
|
+
function getModuleSuggestions(searchTerm, maxSuggestions = 5) {
|
|
680
|
+
const results = searchModules(searchTerm, { caseSensitive: false, exactMatch: false });
|
|
681
|
+
// Sort by relevance (exact matches first, then by length)
|
|
682
|
+
results.sort((a, b) => {
|
|
683
|
+
const aName = a.fullName.toLowerCase();
|
|
684
|
+
const bName = b.fullName.toLowerCase();
|
|
685
|
+
const searchLower = searchTerm.toLowerCase();
|
|
686
|
+
// Exact match scores highest
|
|
687
|
+
if (aName === searchLower)
|
|
688
|
+
return -1;
|
|
689
|
+
if (bName === searchLower)
|
|
690
|
+
return 1;
|
|
691
|
+
// Starts with search term scores next
|
|
692
|
+
if (aName.startsWith(searchLower) && !bName.startsWith(searchLower))
|
|
693
|
+
return -1;
|
|
694
|
+
if (bName.startsWith(searchLower) && !aName.startsWith(searchLower))
|
|
695
|
+
return 1;
|
|
696
|
+
// Shorter names score higher (more specific)
|
|
697
|
+
return aName.length - bName.length;
|
|
698
|
+
});
|
|
699
|
+
return results.slice(0, maxSuggestions);
|
|
700
|
+
}
|
|
701
|
+
/**
|
|
702
|
+
* Find collection by name (supports both "collections/name" and "name" formats)
|
|
703
|
+
*/
|
|
704
|
+
function findCollection(collectionName) {
|
|
705
|
+
const modulesDir = getModulesDir();
|
|
706
|
+
const collectionsDir = path.join(modulesDir, 'collections');
|
|
707
|
+
// Remove "collections/" prefix if present
|
|
708
|
+
const name = collectionName.replace(/^collections\//, '');
|
|
709
|
+
const collectionPath = path.join(collectionsDir, name);
|
|
710
|
+
const collectionJsonPath = path.join(collectionPath, 'collection.json');
|
|
711
|
+
if (!fs.existsSync(collectionJsonPath)) {
|
|
712
|
+
return null;
|
|
713
|
+
}
|
|
714
|
+
try {
|
|
715
|
+
const metadata = JSON.parse(fs.readFileSync(collectionJsonPath, 'utf-8'));
|
|
716
|
+
return {
|
|
717
|
+
metadata,
|
|
718
|
+
path: collectionPath,
|
|
719
|
+
fullName: `collections/${name}`
|
|
720
|
+
};
|
|
721
|
+
}
|
|
722
|
+
catch (error) {
|
|
723
|
+
return null;
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
/**
|
|
727
|
+
* Resolve collection to its constituent modules
|
|
728
|
+
* Returns array of module IDs that are part of the collection
|
|
729
|
+
*/
|
|
730
|
+
function resolveCollection(collection) {
|
|
731
|
+
return collection.metadata.modules.map(m => m.id);
|
|
732
|
+
}
|
|
733
|
+
/**
|
|
734
|
+
* Resolve collection by name to its constituent modules
|
|
735
|
+
*/
|
|
736
|
+
function resolveCollectionByName(collectionName) {
|
|
737
|
+
const collection = findCollection(collectionName);
|
|
738
|
+
if (!collection) {
|
|
739
|
+
return null;
|
|
740
|
+
}
|
|
741
|
+
return resolveCollection(collection);
|
|
742
|
+
}
|
|
743
|
+
/**
|
|
744
|
+
* Check if a name refers to a collection
|
|
745
|
+
*/
|
|
746
|
+
function isCollection(name) {
|
|
747
|
+
return findCollection(name) !== null;
|
|
748
|
+
}
|
|
749
|
+
/**
|
|
750
|
+
* Check if a name refers to a module
|
|
751
|
+
*/
|
|
752
|
+
function isModule(name) {
|
|
753
|
+
return findModule(name) !== null;
|
|
754
|
+
}
|
|
755
|
+
/**
|
|
756
|
+
* Validate module structure
|
|
757
|
+
*/
|
|
758
|
+
function validateModuleStructure(modulePath) {
|
|
759
|
+
const errors = [];
|
|
760
|
+
const warnings = [];
|
|
761
|
+
// Check module.json exists
|
|
762
|
+
const moduleJsonPath = path.join(modulePath, 'module.json');
|
|
763
|
+
if (!fs.existsSync(moduleJsonPath)) {
|
|
764
|
+
errors.push('Missing required file: module.json');
|
|
765
|
+
return { valid: false, errors, warnings };
|
|
766
|
+
}
|
|
767
|
+
// Validate module.json content
|
|
768
|
+
try {
|
|
769
|
+
const metadata = JSON.parse(fs.readFileSync(moduleJsonPath, 'utf-8'));
|
|
770
|
+
const metadataValidation = validateModuleMetadata(metadata);
|
|
771
|
+
errors.push(...metadataValidation.errors);
|
|
772
|
+
warnings.push(...metadataValidation.warnings);
|
|
773
|
+
}
|
|
774
|
+
catch (error) {
|
|
775
|
+
errors.push(`Invalid JSON in module.json: ${error instanceof Error ? error.message : error}`);
|
|
776
|
+
return { valid: false, errors, warnings };
|
|
777
|
+
}
|
|
778
|
+
// Check README.md exists
|
|
779
|
+
const readmePath = path.join(modulePath, 'README.md');
|
|
780
|
+
if (!fs.existsSync(readmePath)) {
|
|
781
|
+
errors.push('Missing required file: README.md');
|
|
782
|
+
}
|
|
783
|
+
// Check rules directory exists
|
|
784
|
+
const rulesDir = path.join(modulePath, 'rules');
|
|
785
|
+
if (!fs.existsSync(rulesDir)) {
|
|
786
|
+
errors.push('Missing required directory: rules/');
|
|
787
|
+
}
|
|
788
|
+
else {
|
|
789
|
+
// Check that rules directory has at least one .md file
|
|
790
|
+
const ruleFiles = fs.readdirSync(rulesDir).filter(f => f.endsWith('.md'));
|
|
791
|
+
if (ruleFiles.length === 0) {
|
|
792
|
+
warnings.push('rules/ directory is empty - should contain at least one .md file');
|
|
793
|
+
}
|
|
794
|
+
}
|
|
795
|
+
// Check examples directory (optional, but warn if missing)
|
|
796
|
+
const examplesDir = path.join(modulePath, 'examples');
|
|
797
|
+
if (!fs.existsSync(examplesDir)) {
|
|
798
|
+
warnings.push('Optional directory missing: examples/');
|
|
799
|
+
}
|
|
800
|
+
return {
|
|
801
|
+
valid: errors.length === 0,
|
|
802
|
+
errors,
|
|
803
|
+
warnings
|
|
804
|
+
};
|
|
805
|
+
}
|
|
806
|
+
/**
|
|
807
|
+
* Validate module category matches directory structure
|
|
808
|
+
*/
|
|
809
|
+
function validateModuleCategory(module) {
|
|
810
|
+
const errors = [];
|
|
811
|
+
const warnings = [];
|
|
812
|
+
const modulesDir = getModulesDir();
|
|
813
|
+
const relativePath = path.relative(modulesDir, module.path);
|
|
814
|
+
const category = relativePath.split(path.sep)[0];
|
|
815
|
+
if (module.metadata.type !== category) {
|
|
816
|
+
errors.push(`Module type "${module.metadata.type}" does not match directory category "${category}"`);
|
|
817
|
+
}
|
|
818
|
+
return {
|
|
819
|
+
valid: errors.length === 0,
|
|
820
|
+
errors,
|
|
821
|
+
warnings
|
|
822
|
+
};
|
|
823
|
+
}
|
|
824
|
+
/**
|
|
825
|
+
* Calculate character count for a module
|
|
826
|
+
*/
|
|
827
|
+
function calculateModuleCharacterCount(modulePath) {
|
|
828
|
+
let totalChars = 0;
|
|
829
|
+
function countFilesRecursively(dir) {
|
|
830
|
+
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
831
|
+
for (const entry of entries) {
|
|
832
|
+
const fullPath = path.join(dir, entry.name);
|
|
833
|
+
if (entry.isDirectory()) {
|
|
834
|
+
countFilesRecursively(fullPath);
|
|
835
|
+
}
|
|
836
|
+
else if (entry.isFile()) {
|
|
837
|
+
const content = fs.readFileSync(fullPath, 'utf-8');
|
|
838
|
+
totalChars += content.length;
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
if (fs.existsSync(modulePath)) {
|
|
843
|
+
countFilesRecursively(modulePath);
|
|
844
|
+
}
|
|
845
|
+
return totalChars;
|
|
846
|
+
}
|
|
847
|
+
/**
|
|
848
|
+
* Validate module is project-agnostic (no hardcoded paths or URLs)
|
|
849
|
+
*/
|
|
850
|
+
function validateProjectAgnostic(modulePath) {
|
|
851
|
+
const errors = [];
|
|
852
|
+
const warnings = [];
|
|
853
|
+
// Patterns to detect project-specific content
|
|
854
|
+
const pathPatterns = [
|
|
855
|
+
/[A-Z]:\\/g, // Windows absolute paths (C:\, D:\, etc.)
|
|
856
|
+
/\/home\/[a-zA-Z0-9_-]+\//g, // Linux home paths
|
|
857
|
+
/\/Users\/[a-zA-Z0-9_-]+\//g, // macOS home paths
|
|
858
|
+
];
|
|
859
|
+
const urlPatterns = [
|
|
860
|
+
/https?:\/\/(?!github\.com|npmjs\.com|pypi\.org|crates\.io)[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g, // URLs (excluding common registries)
|
|
861
|
+
];
|
|
862
|
+
function scanFile(filePath) {
|
|
863
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
864
|
+
// Check for hardcoded paths
|
|
865
|
+
for (const pattern of pathPatterns) {
|
|
866
|
+
const matches = content.match(pattern);
|
|
867
|
+
if (matches) {
|
|
868
|
+
warnings.push(`Potential hardcoded path in ${path.basename(filePath)}: ${matches[0]}`);
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
// Check for project-specific URLs
|
|
872
|
+
for (const pattern of urlPatterns) {
|
|
873
|
+
const matches = content.match(pattern);
|
|
874
|
+
if (matches) {
|
|
875
|
+
warnings.push(`Potential project-specific URL in ${path.basename(filePath)}: ${matches[0]}`);
|
|
876
|
+
}
|
|
877
|
+
}
|
|
878
|
+
}
|
|
879
|
+
function scanDirectory(dir) {
|
|
880
|
+
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
881
|
+
for (const entry of entries) {
|
|
882
|
+
const fullPath = path.join(dir, entry.name);
|
|
883
|
+
if (entry.isDirectory()) {
|
|
884
|
+
scanDirectory(fullPath);
|
|
885
|
+
}
|
|
886
|
+
else if (entry.isFile() && (entry.name.endsWith('.md') || entry.name.endsWith('.json'))) {
|
|
887
|
+
scanFile(fullPath);
|
|
888
|
+
}
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
if (fs.existsSync(modulePath)) {
|
|
892
|
+
scanDirectory(modulePath);
|
|
893
|
+
}
|
|
894
|
+
return {
|
|
895
|
+
valid: errors.length === 0,
|
|
896
|
+
errors,
|
|
897
|
+
warnings
|
|
898
|
+
};
|
|
899
|
+
}
|
|
900
|
+
//# sourceMappingURL=module-system.js.map
|