codesift-mcp 0.3.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 +215 -23
- package/dist/cache/hono-cache.d.ts +50 -0
- package/dist/cache/hono-cache.d.ts.map +1 -0
- package/dist/cache/hono-cache.js +132 -0
- package/dist/cache/hono-cache.js.map +1 -0
- package/dist/cli/help.d.ts.map +1 -1
- package/dist/cli/help.js +8 -6
- package/dist/cli/help.js.map +1 -1
- package/dist/cli/platform.d.ts.map +1 -1
- package/dist/cli/platform.js +12 -14
- package/dist/cli/platform.js.map +1 -1
- package/dist/cli/setup.d.ts +1 -1
- package/dist/cli/setup.d.ts.map +1 -1
- package/dist/cli/setup.js +27 -3
- package/dist/cli/setup.js.map +1 -1
- package/dist/formatters-shortening.d.ts +13 -0
- package/dist/formatters-shortening.d.ts.map +1 -1
- package/dist/formatters-shortening.js +131 -0
- package/dist/formatters-shortening.js.map +1 -1
- package/dist/formatters.d.ts +38 -0
- package/dist/formatters.d.ts.map +1 -1
- package/dist/formatters.js +521 -0
- package/dist/formatters.js.map +1 -1
- package/dist/instructions.d.ts +1 -1
- package/dist/instructions.d.ts.map +1 -1
- package/dist/instructions.js +39 -38
- package/dist/instructions.js.map +1 -1
- package/dist/lsp/lsp-servers.d.ts.map +1 -1
- package/dist/lsp/lsp-servers.js +5 -0
- package/dist/lsp/lsp-servers.js.map +1 -1
- package/dist/lsp/lsp-tools.d.ts.map +1 -1
- package/dist/lsp/lsp-tools.js +1 -0
- package/dist/lsp/lsp-tools.js.map +1 -1
- package/dist/parser/astro-template.d.ts +47 -0
- package/dist/parser/astro-template.d.ts.map +1 -0
- package/dist/parser/astro-template.js +171 -0
- package/dist/parser/astro-template.js.map +1 -0
- package/dist/parser/extractors/_shared.d.ts +4 -0
- package/dist/parser/extractors/_shared.d.ts.map +1 -1
- package/dist/parser/extractors/_shared.js +8 -0
- package/dist/parser/extractors/_shared.js.map +1 -1
- package/dist/parser/extractors/astro.d.ts +4 -5
- package/dist/parser/extractors/astro.d.ts.map +1 -1
- package/dist/parser/extractors/astro.js +102 -26
- package/dist/parser/extractors/astro.js.map +1 -1
- package/dist/parser/extractors/gradle-kts.d.ts +4 -0
- package/dist/parser/extractors/gradle-kts.d.ts.map +1 -0
- package/dist/parser/extractors/gradle-kts.js +246 -0
- package/dist/parser/extractors/gradle-kts.js.map +1 -0
- package/dist/parser/extractors/hono-inline-analyzer.d.ts +34 -0
- package/dist/parser/extractors/hono-inline-analyzer.d.ts.map +1 -0
- package/dist/parser/extractors/hono-inline-analyzer.js +465 -0
- package/dist/parser/extractors/hono-inline-analyzer.js.map +1 -0
- package/dist/parser/extractors/hono-model.d.ts +196 -0
- package/dist/parser/extractors/hono-model.d.ts.map +1 -0
- package/dist/parser/extractors/hono-model.js +10 -0
- package/dist/parser/extractors/hono-model.js.map +1 -0
- package/dist/parser/extractors/hono.d.ts +118 -0
- package/dist/parser/extractors/hono.d.ts.map +1 -0
- package/dist/parser/extractors/hono.js +1527 -0
- package/dist/parser/extractors/hono.js.map +1 -0
- package/dist/parser/extractors/kotlin.d.ts +4 -0
- package/dist/parser/extractors/kotlin.d.ts.map +1 -0
- package/dist/parser/extractors/kotlin.js +521 -0
- package/dist/parser/extractors/kotlin.js.map +1 -0
- package/dist/parser/extractors/php.d.ts +22 -0
- package/dist/parser/extractors/php.d.ts.map +1 -0
- package/dist/parser/extractors/php.js +334 -0
- package/dist/parser/extractors/php.js.map +1 -0
- package/dist/parser/extractors/python.d.ts.map +1 -1
- package/dist/parser/extractors/python.js +234 -11
- package/dist/parser/extractors/python.js.map +1 -1
- package/dist/parser/extractors/sql.d.ts +33 -0
- package/dist/parser/extractors/sql.d.ts.map +1 -0
- package/dist/parser/extractors/sql.js +506 -0
- package/dist/parser/extractors/sql.js.map +1 -0
- package/dist/parser/extractors/typescript.d.ts.map +1 -1
- package/dist/parser/extractors/typescript.js +209 -3
- package/dist/parser/extractors/typescript.js.map +1 -1
- package/dist/parser/languages/tree-sitter-javascript.wasm +0 -0
- package/dist/parser/languages/tree-sitter-kotlin.wasm +0 -0
- package/dist/parser/languages/tree-sitter-php.wasm +0 -0
- package/dist/parser/languages/tree-sitter-php_only.wasm +0 -0
- package/dist/parser/languages/tree-sitter-python.wasm +0 -0
- package/dist/parser/parse-cache.d.ts +39 -0
- package/dist/parser/parse-cache.d.ts.map +1 -0
- package/dist/parser/parse-cache.js +87 -0
- package/dist/parser/parse-cache.js.map +1 -0
- package/dist/parser/parser-manager.d.ts +32 -0
- package/dist/parser/parser-manager.d.ts.map +1 -1
- package/dist/parser/parser-manager.js +93 -3
- package/dist/parser/parser-manager.js.map +1 -1
- package/dist/parser/symbol-extractor.d.ts.map +1 -1
- package/dist/parser/symbol-extractor.js +16 -0
- package/dist/parser/symbol-extractor.js.map +1 -1
- package/dist/register-tools.d.ts +38 -2
- package/dist/register-tools.d.ts.map +1 -1
- package/dist/register-tools.js +2444 -195
- package/dist/register-tools.js.map +1 -1
- package/dist/search/reranker.js +1 -1
- package/dist/search/reranker.js.map +1 -1
- package/dist/search/tool-ranker.d.ts +90 -0
- package/dist/search/tool-ranker.d.ts.map +1 -0
- package/dist/search/tool-ranker.js +420 -0
- package/dist/search/tool-ranker.js.map +1 -0
- package/dist/server-helpers.d.ts.map +1 -1
- package/dist/server-helpers.js +11 -0
- package/dist/server-helpers.js.map +1 -1
- package/dist/server.js +47 -14
- package/dist/server.js.map +1 -1
- package/dist/storage/index-store.d.ts +15 -1
- package/dist/storage/index-store.d.ts.map +1 -1
- package/dist/storage/index-store.js +27 -1
- package/dist/storage/index-store.js.map +1 -1
- package/dist/storage/session-state.d.ts +1 -1
- package/dist/storage/session-state.d.ts.map +1 -1
- package/dist/storage/session-state.js +6 -4
- package/dist/storage/session-state.js.map +1 -1
- package/dist/storage/usage-tracker.d.ts.map +1 -1
- package/dist/storage/usage-tracker.js +4 -1
- package/dist/storage/usage-tracker.js.map +1 -1
- package/dist/tools/agent-config-tools.d.ts +24 -0
- package/dist/tools/agent-config-tools.d.ts.map +1 -0
- package/dist/tools/agent-config-tools.js +119 -0
- package/dist/tools/agent-config-tools.js.map +1 -0
- package/dist/tools/architecture-tools.d.ts +23 -0
- package/dist/tools/architecture-tools.d.ts.map +1 -0
- package/dist/tools/architecture-tools.js +140 -0
- package/dist/tools/architecture-tools.js.map +1 -0
- package/dist/tools/astro-actions.d.ts +54 -0
- package/dist/tools/astro-actions.d.ts.map +1 -0
- package/dist/tools/astro-actions.js +561 -0
- package/dist/tools/astro-actions.js.map +1 -0
- package/dist/tools/astro-audit.d.ts +87 -0
- package/dist/tools/astro-audit.d.ts.map +1 -0
- package/dist/tools/astro-audit.js +345 -0
- package/dist/tools/astro-audit.js.map +1 -0
- package/dist/tools/astro-config.d.ts +33 -0
- package/dist/tools/astro-config.d.ts.map +1 -0
- package/dist/tools/astro-config.js +260 -0
- package/dist/tools/astro-config.js.map +1 -0
- package/dist/tools/astro-content-collections.d.ts +44 -0
- package/dist/tools/astro-content-collections.d.ts.map +1 -0
- package/dist/tools/astro-content-collections.js +630 -0
- package/dist/tools/astro-content-collections.js.map +1 -0
- package/dist/tools/astro-islands.d.ts +63 -0
- package/dist/tools/astro-islands.d.ts.map +1 -0
- package/dist/tools/astro-islands.js +255 -0
- package/dist/tools/astro-islands.js.map +1 -0
- package/dist/tools/astro-migration.d.ts +31 -0
- package/dist/tools/astro-migration.d.ts.map +1 -0
- package/dist/tools/astro-migration.js +378 -0
- package/dist/tools/astro-migration.js.map +1 -0
- package/dist/tools/astro-routes.d.ts +49 -0
- package/dist/tools/astro-routes.d.ts.map +1 -0
- package/dist/tools/astro-routes.js +119 -0
- package/dist/tools/astro-routes.js.map +1 -0
- package/dist/tools/async-correctness.d.ts +26 -0
- package/dist/tools/async-correctness.d.ts.map +1 -0
- package/dist/tools/async-correctness.js +166 -0
- package/dist/tools/async-correctness.js.map +1 -0
- package/dist/tools/audit-tools.d.ts +38 -0
- package/dist/tools/audit-tools.d.ts.map +1 -0
- package/dist/tools/audit-tools.js +248 -0
- package/dist/tools/audit-tools.js.map +1 -0
- package/dist/tools/celery-tools.d.ts +38 -0
- package/dist/tools/celery-tools.d.ts.map +1 -0
- package/dist/tools/celery-tools.js +154 -0
- package/dist/tools/celery-tools.js.map +1 -0
- package/dist/tools/clone-tools.js +1 -1
- package/dist/tools/clone-tools.js.map +1 -1
- package/dist/tools/complexity-tools.d.ts +4 -0
- package/dist/tools/complexity-tools.d.ts.map +1 -1
- package/dist/tools/complexity-tools.js +78 -4
- package/dist/tools/complexity-tools.js.map +1 -1
- package/dist/tools/compose-tools.d.ts +60 -0
- package/dist/tools/compose-tools.d.ts.map +1 -0
- package/dist/tools/compose-tools.js +203 -0
- package/dist/tools/compose-tools.js.map +1 -0
- package/dist/tools/coupling-tools.d.ts +50 -0
- package/dist/tools/coupling-tools.d.ts.map +1 -0
- package/dist/tools/coupling-tools.js +262 -0
- package/dist/tools/coupling-tools.js.map +1 -0
- package/dist/tools/dependency-audit-tools.d.ts +65 -0
- package/dist/tools/dependency-audit-tools.d.ts.map +1 -0
- package/dist/tools/dependency-audit-tools.js +553 -0
- package/dist/tools/dependency-audit-tools.js.map +1 -0
- package/dist/tools/django-settings.d.ts +22 -0
- package/dist/tools/django-settings.d.ts.map +1 -0
- package/dist/tools/django-settings.js +301 -0
- package/dist/tools/django-settings.js.map +1 -0
- package/dist/tools/django-view-security-tools.d.ts +32 -0
- package/dist/tools/django-view-security-tools.d.ts.map +1 -0
- package/dist/tools/django-view-security-tools.js +184 -0
- package/dist/tools/django-view-security-tools.js.map +1 -0
- package/dist/tools/fastapi-depends.d.ts +63 -0
- package/dist/tools/fastapi-depends.d.ts.map +1 -0
- package/dist/tools/fastapi-depends.js +191 -0
- package/dist/tools/fastapi-depends.js.map +1 -0
- package/dist/tools/frequency-tools.js +1 -1
- package/dist/tools/frequency-tools.js.map +1 -1
- package/dist/tools/graph-tools.d.ts +8 -2
- package/dist/tools/graph-tools.d.ts.map +1 -1
- package/dist/tools/graph-tools.js +44 -3
- package/dist/tools/graph-tools.js.map +1 -1
- package/dist/tools/hilt-tools.d.ts +55 -0
- package/dist/tools/hilt-tools.d.ts.map +1 -0
- package/dist/tools/hilt-tools.js +258 -0
- package/dist/tools/hilt-tools.js.map +1 -0
- package/dist/tools/hono-analyze-app.d.ts +48 -0
- package/dist/tools/hono-analyze-app.d.ts.map +1 -0
- package/dist/tools/hono-analyze-app.js +94 -0
- package/dist/tools/hono-analyze-app.js.map +1 -0
- package/dist/tools/hono-api-contract.d.ts +22 -0
- package/dist/tools/hono-api-contract.d.ts.map +1 -0
- package/dist/tools/hono-api-contract.js +112 -0
- package/dist/tools/hono-api-contract.js.map +1 -0
- package/dist/tools/hono-conditional-middleware.d.ts +27 -0
- package/dist/tools/hono-conditional-middleware.d.ts.map +1 -0
- package/dist/tools/hono-conditional-middleware.js +62 -0
- package/dist/tools/hono-conditional-middleware.js.map +1 -0
- package/dist/tools/hono-context-flow.d.ts +24 -0
- package/dist/tools/hono-context-flow.d.ts.map +1 -0
- package/dist/tools/hono-context-flow.js +70 -0
- package/dist/tools/hono-context-flow.js.map +1 -0
- package/dist/tools/hono-dead-routes.d.ts +26 -0
- package/dist/tools/hono-dead-routes.d.ts.map +1 -0
- package/dist/tools/hono-dead-routes.js +102 -0
- package/dist/tools/hono-dead-routes.js.map +1 -0
- package/dist/tools/hono-entry-resolver.d.ts +27 -0
- package/dist/tools/hono-entry-resolver.d.ts.map +1 -0
- package/dist/tools/hono-entry-resolver.js +31 -0
- package/dist/tools/hono-entry-resolver.js.map +1 -0
- package/dist/tools/hono-env-regression.d.ts +29 -0
- package/dist/tools/hono-env-regression.d.ts.map +1 -0
- package/dist/tools/hono-env-regression.js +157 -0
- package/dist/tools/hono-env-regression.js.map +1 -0
- package/dist/tools/hono-inline-analyze.d.ts +31 -0
- package/dist/tools/hono-inline-analyze.d.ts.map +1 -0
- package/dist/tools/hono-inline-analyze.js +59 -0
- package/dist/tools/hono-inline-analyze.js.map +1 -0
- package/dist/tools/hono-middleware-chain.d.ts +40 -0
- package/dist/tools/hono-middleware-chain.d.ts.map +1 -0
- package/dist/tools/hono-middleware-chain.js +121 -0
- package/dist/tools/hono-middleware-chain.js.map +1 -0
- package/dist/tools/hono-modules.d.ts +22 -0
- package/dist/tools/hono-modules.d.ts.map +1 -0
- package/dist/tools/hono-modules.js +118 -0
- package/dist/tools/hono-modules.js.map +1 -0
- package/dist/tools/hono-response-types.d.ts +37 -0
- package/dist/tools/hono-response-types.d.ts.map +1 -0
- package/dist/tools/hono-response-types.js +76 -0
- package/dist/tools/hono-response-types.js.map +1 -0
- package/dist/tools/hono-rpc-types.d.ts +21 -0
- package/dist/tools/hono-rpc-types.d.ts.map +1 -0
- package/dist/tools/hono-rpc-types.js +49 -0
- package/dist/tools/hono-rpc-types.js.map +1 -0
- package/dist/tools/hono-security.d.ts +31 -0
- package/dist/tools/hono-security.d.ts.map +1 -0
- package/dist/tools/hono-security.js +269 -0
- package/dist/tools/hono-security.js.map +1 -0
- package/dist/tools/hono-visualize.d.ts +13 -0
- package/dist/tools/hono-visualize.d.ts.map +1 -0
- package/dist/tools/hono-visualize.js +64 -0
- package/dist/tools/hono-visualize.js.map +1 -0
- package/dist/tools/hotspot-tools.d.ts.map +1 -1
- package/dist/tools/hotspot-tools.js +9 -7
- package/dist/tools/hotspot-tools.js.map +1 -1
- package/dist/tools/index-tools.d.ts +17 -0
- package/dist/tools/index-tools.d.ts.map +1 -1
- package/dist/tools/index-tools.js +210 -10
- package/dist/tools/index-tools.js.map +1 -1
- package/dist/tools/kotlin-tools.d.ts +142 -0
- package/dist/tools/kotlin-tools.d.ts.map +1 -0
- package/dist/tools/kotlin-tools.js +572 -0
- package/dist/tools/kotlin-tools.js.map +1 -0
- package/dist/tools/legacy-hono-conventions.d.ts +14 -0
- package/dist/tools/legacy-hono-conventions.d.ts.map +1 -0
- package/dist/tools/legacy-hono-conventions.js +152 -0
- package/dist/tools/legacy-hono-conventions.js.map +1 -0
- package/dist/tools/migration-lint-tools.d.ts +26 -0
- package/dist/tools/migration-lint-tools.d.ts.map +1 -0
- package/dist/tools/migration-lint-tools.js +247 -0
- package/dist/tools/migration-lint-tools.js.map +1 -0
- package/dist/tools/model-tools.d.ts +30 -0
- package/dist/tools/model-tools.d.ts.map +1 -0
- package/dist/tools/model-tools.js +145 -0
- package/dist/tools/model-tools.js.map +1 -0
- package/dist/tools/nest-ext-tools.d.ts +207 -0
- package/dist/tools/nest-ext-tools.d.ts.map +1 -0
- package/dist/tools/nest-ext-tools.js +752 -0
- package/dist/tools/nest-ext-tools.js.map +1 -0
- package/dist/tools/nest-tools.d.ts +198 -0
- package/dist/tools/nest-tools.d.ts.map +1 -0
- package/dist/tools/nest-tools.js +1142 -0
- package/dist/tools/nest-tools.js.map +1 -0
- package/dist/tools/nextjs-api-contract-readers.d.ts +14 -0
- package/dist/tools/nextjs-api-contract-readers.d.ts.map +1 -0
- package/dist/tools/nextjs-api-contract-readers.js +204 -0
- package/dist/tools/nextjs-api-contract-readers.js.map +1 -0
- package/dist/tools/nextjs-api-contract-tools.d.ts +57 -0
- package/dist/tools/nextjs-api-contract-tools.d.ts.map +1 -0
- package/dist/tools/nextjs-api-contract-tools.js +144 -0
- package/dist/tools/nextjs-api-contract-tools.js.map +1 -0
- package/dist/tools/nextjs-boundary-tools.d.ts +39 -0
- package/dist/tools/nextjs-boundary-tools.d.ts.map +1 -0
- package/dist/tools/nextjs-boundary-tools.js +152 -0
- package/dist/tools/nextjs-boundary-tools.js.map +1 -0
- package/dist/tools/nextjs-component-readers.d.ts +101 -0
- package/dist/tools/nextjs-component-readers.d.ts.map +1 -0
- package/dist/tools/nextjs-component-readers.js +287 -0
- package/dist/tools/nextjs-component-readers.js.map +1 -0
- package/dist/tools/nextjs-component-tools.d.ts +51 -0
- package/dist/tools/nextjs-component-tools.d.ts.map +1 -0
- package/dist/tools/nextjs-component-tools.js +212 -0
- package/dist/tools/nextjs-component-tools.js.map +1 -0
- package/dist/tools/nextjs-data-flow-tools.d.ts +42 -0
- package/dist/tools/nextjs-data-flow-tools.d.ts.map +1 -0
- package/dist/tools/nextjs-data-flow-tools.js +158 -0
- package/dist/tools/nextjs-data-flow-tools.js.map +1 -0
- package/dist/tools/nextjs-framework-audit-tools.d.ts +60 -0
- package/dist/tools/nextjs-framework-audit-tools.d.ts.map +1 -0
- package/dist/tools/nextjs-framework-audit-tools.js +394 -0
- package/dist/tools/nextjs-framework-audit-tools.js.map +1 -0
- package/dist/tools/nextjs-link-tools.d.ts +41 -0
- package/dist/tools/nextjs-link-tools.d.ts.map +1 -0
- package/dist/tools/nextjs-link-tools.js +157 -0
- package/dist/tools/nextjs-link-tools.js.map +1 -0
- package/dist/tools/nextjs-metadata-tools.d.ts +74 -0
- package/dist/tools/nextjs-metadata-tools.d.ts.map +1 -0
- package/dist/tools/nextjs-metadata-tools.js +252 -0
- package/dist/tools/nextjs-metadata-tools.js.map +1 -0
- package/dist/tools/nextjs-middleware-coverage-tools.d.ts +41 -0
- package/dist/tools/nextjs-middleware-coverage-tools.d.ts.map +1 -0
- package/dist/tools/nextjs-middleware-coverage-tools.js +88 -0
- package/dist/tools/nextjs-middleware-coverage-tools.js.map +1 -0
- package/dist/tools/nextjs-route-readers.d.ts +81 -0
- package/dist/tools/nextjs-route-readers.d.ts.map +1 -0
- package/dist/tools/nextjs-route-readers.js +340 -0
- package/dist/tools/nextjs-route-readers.js.map +1 -0
- package/dist/tools/nextjs-route-tools.d.ts +36 -0
- package/dist/tools/nextjs-route-tools.d.ts.map +1 -0
- package/dist/tools/nextjs-route-tools.js +175 -0
- package/dist/tools/nextjs-route-tools.js.map +1 -0
- package/dist/tools/nextjs-security-readers.d.ts +22 -0
- package/dist/tools/nextjs-security-readers.d.ts.map +1 -0
- package/dist/tools/nextjs-security-readers.js +318 -0
- package/dist/tools/nextjs-security-readers.js.map +1 -0
- package/dist/tools/nextjs-security-scoring.d.ts +15 -0
- package/dist/tools/nextjs-security-scoring.d.ts.map +1 -0
- package/dist/tools/nextjs-security-scoring.js +65 -0
- package/dist/tools/nextjs-security-scoring.js.map +1 -0
- package/dist/tools/nextjs-security-tools.d.ts +75 -0
- package/dist/tools/nextjs-security-tools.d.ts.map +1 -0
- package/dist/tools/nextjs-security-tools.js +153 -0
- package/dist/tools/nextjs-security-tools.js.map +1 -0
- package/dist/tools/nextjs-tools.d.ts +15 -0
- package/dist/tools/nextjs-tools.d.ts.map +1 -0
- package/dist/tools/nextjs-tools.js +15 -0
- package/dist/tools/nextjs-tools.js.map +1 -0
- package/dist/tools/outline-tools.d.ts.map +1 -1
- package/dist/tools/outline-tools.js +20 -0
- package/dist/tools/outline-tools.js.map +1 -1
- package/dist/tools/pattern-tools.d.ts +8 -0
- package/dist/tools/pattern-tools.d.ts.map +1 -1
- package/dist/tools/pattern-tools.js +651 -3
- package/dist/tools/pattern-tools.js.map +1 -1
- package/dist/tools/perf-tools.d.ts +32 -0
- package/dist/tools/perf-tools.d.ts.map +1 -0
- package/dist/tools/perf-tools.js +227 -0
- package/dist/tools/perf-tools.js.map +1 -0
- package/dist/tools/php-tools.d.ts +185 -0
- package/dist/tools/php-tools.d.ts.map +1 -0
- package/dist/tools/php-tools.js +645 -0
- package/dist/tools/php-tools.js.map +1 -0
- package/dist/tools/plan-turn-tools.d.ts +89 -0
- package/dist/tools/plan-turn-tools.d.ts.map +1 -0
- package/dist/tools/plan-turn-tools.js +508 -0
- package/dist/tools/plan-turn-tools.js.map +1 -0
- package/dist/tools/prisma-schema-tools.d.ts +44 -0
- package/dist/tools/prisma-schema-tools.d.ts.map +1 -0
- package/dist/tools/prisma-schema-tools.js +358 -0
- package/dist/tools/prisma-schema-tools.js.map +1 -0
- package/dist/tools/project-tools.d.ts +116 -7
- package/dist/tools/project-tools.d.ts.map +1 -1
- package/dist/tools/project-tools.js +595 -218
- package/dist/tools/project-tools.js.map +1 -1
- package/dist/tools/pydantic-models.d.ts +46 -0
- package/dist/tools/pydantic-models.d.ts.map +1 -0
- package/dist/tools/pydantic-models.js +249 -0
- package/dist/tools/pydantic-models.js.map +1 -0
- package/dist/tools/pyproject-tools.d.ts +23 -0
- package/dist/tools/pyproject-tools.d.ts.map +1 -0
- package/dist/tools/pyproject-tools.js +133 -0
- package/dist/tools/pyproject-tools.js.map +1 -0
- package/dist/tools/pytest-tools.d.ts +20 -0
- package/dist/tools/pytest-tools.d.ts.map +1 -0
- package/dist/tools/pytest-tools.js +106 -0
- package/dist/tools/pytest-tools.js.map +1 -0
- package/dist/tools/python-audit.d.ts +40 -0
- package/dist/tools/python-audit.d.ts.map +1 -0
- package/dist/tools/python-audit.js +244 -0
- package/dist/tools/python-audit.js.map +1 -0
- package/dist/tools/python-callers.d.ts +28 -0
- package/dist/tools/python-callers.d.ts.map +1 -0
- package/dist/tools/python-callers.js +110 -0
- package/dist/tools/python-callers.js.map +1 -0
- package/dist/tools/python-circular-imports.d.ts +19 -0
- package/dist/tools/python-circular-imports.d.ts.map +1 -0
- package/dist/tools/python-circular-imports.js +126 -0
- package/dist/tools/python-circular-imports.js.map +1 -0
- package/dist/tools/python-constants-tools.d.ts +44 -0
- package/dist/tools/python-constants-tools.d.ts.map +1 -0
- package/dist/tools/python-constants-tools.js +525 -0
- package/dist/tools/python-constants-tools.js.map +1 -0
- package/dist/tools/python-deps-analyzer.d.ts +46 -0
- package/dist/tools/python-deps-analyzer.d.ts.map +1 -0
- package/dist/tools/python-deps-analyzer.js +227 -0
- package/dist/tools/python-deps-analyzer.js.map +1 -0
- package/dist/tools/query-tools.d.ts +23 -0
- package/dist/tools/query-tools.d.ts.map +1 -0
- package/dist/tools/query-tools.js +256 -0
- package/dist/tools/query-tools.js.map +1 -0
- package/dist/tools/react-tools.d.ts +263 -0
- package/dist/tools/react-tools.d.ts.map +1 -0
- package/dist/tools/react-tools.js +839 -0
- package/dist/tools/react-tools.js.map +1 -0
- package/dist/tools/report-tools.js +47 -0
- package/dist/tools/report-tools.js.map +1 -1
- package/dist/tools/review-diff-tools.d.ts +5 -4
- package/dist/tools/review-diff-tools.d.ts.map +1 -1
- package/dist/tools/review-diff-tools.js +157 -66
- package/dist/tools/review-diff-tools.js.map +1 -1
- package/dist/tools/room-tools.d.ts +36 -0
- package/dist/tools/room-tools.d.ts.map +1 -0
- package/dist/tools/room-tools.js +147 -0
- package/dist/tools/room-tools.js.map +1 -0
- package/dist/tools/route-tools.d.ts +27 -1
- package/dist/tools/route-tools.d.ts.map +1 -1
- package/dist/tools/route-tools.js +744 -18
- package/dist/tools/route-tools.js.map +1 -1
- package/dist/tools/ruff-tools.d.ts +32 -0
- package/dist/tools/ruff-tools.d.ts.map +1 -0
- package/dist/tools/ruff-tools.js +114 -0
- package/dist/tools/ruff-tools.js.map +1 -0
- package/dist/tools/search-ranker.d.ts.map +1 -1
- package/dist/tools/search-ranker.js +7 -0
- package/dist/tools/search-ranker.js.map +1 -1
- package/dist/tools/search-tools.d.ts +3 -2
- package/dist/tools/search-tools.d.ts.map +1 -1
- package/dist/tools/search-tools.js +16 -3
- package/dist/tools/search-tools.js.map +1 -1
- package/dist/tools/serialization-tools.d.ts +24 -0
- package/dist/tools/serialization-tools.d.ts.map +1 -0
- package/dist/tools/serialization-tools.js +156 -0
- package/dist/tools/serialization-tools.js.map +1 -0
- package/dist/tools/sql-tools.d.ts +274 -0
- package/dist/tools/sql-tools.d.ts.map +1 -0
- package/dist/tools/sql-tools.js +1160 -0
- package/dist/tools/sql-tools.js.map +1 -0
- package/dist/tools/status-tools.d.ts +10 -0
- package/dist/tools/status-tools.d.ts.map +1 -0
- package/dist/tools/status-tools.js +32 -0
- package/dist/tools/status-tools.js.map +1 -0
- package/dist/tools/symbol-tools.d.ts +19 -0
- package/dist/tools/symbol-tools.d.ts.map +1 -1
- package/dist/tools/symbol-tools.js +75 -4
- package/dist/tools/symbol-tools.js.map +1 -1
- package/dist/tools/taint-tools.d.ts +43 -0
- package/dist/tools/taint-tools.d.ts.map +1 -0
- package/dist/tools/taint-tools.js +922 -0
- package/dist/tools/taint-tools.js.map +1 -0
- package/dist/tools/test-impact-tools.d.ts +29 -0
- package/dist/tools/test-impact-tools.d.ts.map +1 -0
- package/dist/tools/test-impact-tools.js +156 -0
- package/dist/tools/test-impact-tools.js.map +1 -0
- package/dist/tools/typecheck-tools.d.ts +39 -0
- package/dist/tools/typecheck-tools.d.ts.map +1 -0
- package/dist/tools/typecheck-tools.js +191 -0
- package/dist/tools/typecheck-tools.js.map +1 -0
- package/dist/tools/wiring-tools.d.ts +19 -0
- package/dist/tools/wiring-tools.d.ts.map +1 -0
- package/dist/tools/wiring-tools.js +147 -0
- package/dist/tools/wiring-tools.js.map +1 -0
- package/dist/types.d.ts +9 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/framework-detect.d.ts +18 -2
- package/dist/utils/framework-detect.d.ts.map +1 -1
- package/dist/utils/framework-detect.js +150 -3
- package/dist/utils/framework-detect.js.map +1 -1
- package/dist/utils/import-graph.d.ts +42 -0
- package/dist/utils/import-graph.d.ts.map +1 -1
- package/dist/utils/import-graph.js +248 -9
- package/dist/utils/import-graph.js.map +1 -1
- package/dist/utils/language-detect.d.ts +21 -0
- package/dist/utils/language-detect.d.ts.map +1 -0
- package/dist/utils/language-detect.js +183 -0
- package/dist/utils/language-detect.js.map +1 -0
- package/dist/utils/nextjs-ast-readers.d.ts +44 -0
- package/dist/utils/nextjs-ast-readers.d.ts.map +1 -0
- package/dist/utils/nextjs-ast-readers.js +341 -0
- package/dist/utils/nextjs-ast-readers.js.map +1 -0
- package/dist/utils/nextjs-audit-cache.d.ts +51 -0
- package/dist/utils/nextjs-audit-cache.d.ts.map +1 -0
- package/dist/utils/nextjs-audit-cache.js +116 -0
- package/dist/utils/nextjs-audit-cache.js.map +1 -0
- package/dist/utils/nextjs-metadata-readers.d.ts +65 -0
- package/dist/utils/nextjs-metadata-readers.d.ts.map +1 -0
- package/dist/utils/nextjs-metadata-readers.js +447 -0
- package/dist/utils/nextjs-metadata-readers.js.map +1 -0
- package/dist/utils/nextjs.d.ts +42 -0
- package/dist/utils/nextjs.d.ts.map +1 -0
- package/dist/utils/nextjs.js +284 -0
- package/dist/utils/nextjs.js.map +1 -0
- package/dist/utils/python-import-resolver.d.ts +42 -0
- package/dist/utils/python-import-resolver.d.ts.map +1 -0
- package/dist/utils/python-import-resolver.js +101 -0
- package/dist/utils/python-import-resolver.js.map +1 -0
- package/dist/utils/python-imports.d.ts +28 -0
- package/dist/utils/python-imports.d.ts.map +1 -0
- package/dist/utils/python-imports.js +117 -0
- package/dist/utils/python-imports.js.map +1 -0
- package/dist/utils/react-alias.d.ts +15 -0
- package/dist/utils/react-alias.d.ts.map +1 -0
- package/dist/utils/react-alias.js +31 -0
- package/dist/utils/react-alias.js.map +1 -0
- package/dist/utils/test-file.d.ts.map +1 -1
- package/dist/utils/test-file.js +7 -0
- package/dist/utils/test-file.js.map +1 -1
- package/dist/utils/walk.d.ts +22 -0
- package/dist/utils/walk.d.ts.map +1 -1
- package/dist/utils/walk.js +70 -2
- package/dist/utils/walk.js.map +1 -1
- package/package.json +4 -3
- package/rules/codesift.md +71 -5
- package/rules/codesift.mdc +71 -5
- package/rules/codex.md +71 -5
- package/rules/gemini.md +71 -5
- package/src/parser/languages/tree-sitter-javascript.wasm +0 -0
- package/src/parser/languages/tree-sitter-kotlin.wasm +0 -0
- package/src/parser/languages/tree-sitter-php.wasm +0 -0
- package/src/parser/languages/tree-sitter-php_only.wasm +0 -0
- package/src/parser/languages/tree-sitter-python.wasm +0 -0
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Next.js client boundary analyzer (T4).
|
|
3
|
+
*
|
|
4
|
+
* Walks `app/**\/*.{tsx,jsx}` files marked with `"use client"` and computes
|
|
5
|
+
* a deterministic ranking score per file from cheap signals (LOC, import
|
|
6
|
+
* counts, dynamic imports, third-party imports). Per design D5 the score
|
|
7
|
+
* is signal-based — no actual bundle bytes are estimated.
|
|
8
|
+
*/
|
|
9
|
+
import { readFile } from "node:fs/promises";
|
|
10
|
+
import { join, relative } from "node:path";
|
|
11
|
+
import { discoverWorkspaces, scanDirective } from "../utils/nextjs.js";
|
|
12
|
+
import { cachedParseFile as parseFile } from "../utils/nextjs-audit-cache.js";
|
|
13
|
+
import { cachedWalkDirectory as walkDirectory } from "../utils/nextjs-audit-cache.js";
|
|
14
|
+
import { getCodeIndex } from "./index-tools.js";
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
// Pure helpers (Tasks 27, 28)
|
|
17
|
+
// ---------------------------------------------------------------------------
|
|
18
|
+
function isLocalImport(spec) {
|
|
19
|
+
return spec.startsWith("./") || spec.startsWith("../") || spec.startsWith("@/") || spec.startsWith("~/");
|
|
20
|
+
}
|
|
21
|
+
export function extractComponentSignals(_filePath, source, tree) {
|
|
22
|
+
const loc = source.split("\n").length;
|
|
23
|
+
let import_count = 0;
|
|
24
|
+
let dynamic_import_count = 0;
|
|
25
|
+
const third_party = new Set();
|
|
26
|
+
const root = tree.rootNode;
|
|
27
|
+
for (const imp of root.descendantsOfType("import_statement")) {
|
|
28
|
+
import_count++;
|
|
29
|
+
// The module source is a string literal child
|
|
30
|
+
for (const child of imp.namedChildren) {
|
|
31
|
+
if (child.type === "string") {
|
|
32
|
+
const frag = child.namedChildren.find((c) => c.type === "string_fragment");
|
|
33
|
+
const text = frag?.text ?? child.text.slice(1, -1);
|
|
34
|
+
if (!isLocalImport(text)) {
|
|
35
|
+
third_party.add(text);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
// Walk for dynamic(...) calls (next/dynamic) — treat as proxy for code-split modules.
|
|
41
|
+
for (const call of root.descendantsOfType("call_expression")) {
|
|
42
|
+
const fn = call.childForFieldName("function") ?? call.namedChild(0);
|
|
43
|
+
if (fn?.type === "identifier" && fn.text === "dynamic") {
|
|
44
|
+
dynamic_import_count++;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return {
|
|
48
|
+
loc,
|
|
49
|
+
import_count,
|
|
50
|
+
dynamic_import_count,
|
|
51
|
+
third_party_imports: [...third_party],
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
export function rankingScore(signals) {
|
|
55
|
+
// Formula per D5: loc + (imports * 20) + (dynamic * -30) + (third_party * 15)
|
|
56
|
+
return (signals.loc +
|
|
57
|
+
signals.import_count * 20 +
|
|
58
|
+
signals.dynamic_import_count * -30 +
|
|
59
|
+
signals.third_party_imports.length * 15);
|
|
60
|
+
}
|
|
61
|
+
// ---------------------------------------------------------------------------
|
|
62
|
+
// Orchestrator (Task 29)
|
|
63
|
+
// ---------------------------------------------------------------------------
|
|
64
|
+
const COMPONENT_EXTS = new Set([".tsx", ".jsx"]);
|
|
65
|
+
const PARSE_CONCURRENCY = 10;
|
|
66
|
+
const MAX_FILE_SIZE_BYTES = 2_097_152;
|
|
67
|
+
const DEFAULT_TOP_N = 20;
|
|
68
|
+
export async function nextjsBoundaryAnalyzer(repo, options) {
|
|
69
|
+
if (process.env.CODESIFT_DISABLE_TOOLS?.includes("nextjs_boundary_analyzer")) {
|
|
70
|
+
throw new Error("nextjs_boundary_analyzer is disabled via CODESIFT_DISABLE_TOOLS");
|
|
71
|
+
}
|
|
72
|
+
const index = await getCodeIndex(repo);
|
|
73
|
+
if (!index) {
|
|
74
|
+
throw new Error(`Repository not found: ${repo}. Run index_folder first.`);
|
|
75
|
+
}
|
|
76
|
+
const projectRoot = index.root;
|
|
77
|
+
let workspaces;
|
|
78
|
+
if (options?.workspace) {
|
|
79
|
+
workspaces = [join(projectRoot, options.workspace)];
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
const discovered = await discoverWorkspaces(projectRoot);
|
|
83
|
+
workspaces = discovered.length > 0 ? discovered.map((w) => w.root) : [projectRoot];
|
|
84
|
+
}
|
|
85
|
+
const top_n = options?.top_n ?? DEFAULT_TOP_N;
|
|
86
|
+
const allEntries = [];
|
|
87
|
+
const parse_failures = [];
|
|
88
|
+
const scan_errors = [];
|
|
89
|
+
const workspaces_scanned = [];
|
|
90
|
+
for (const workspace of workspaces) {
|
|
91
|
+
workspaces_scanned.push(workspace);
|
|
92
|
+
const candidates = [];
|
|
93
|
+
for (const dir of ["app", "src/app"]) {
|
|
94
|
+
const fullDir = join(workspace, dir);
|
|
95
|
+
try {
|
|
96
|
+
const walked = await walkDirectory(fullDir, {
|
|
97
|
+
followSymlinks: true,
|
|
98
|
+
fileFilter: (ext) => COMPONENT_EXTS.has(ext),
|
|
99
|
+
maxFileSize: MAX_FILE_SIZE_BYTES,
|
|
100
|
+
});
|
|
101
|
+
candidates.push(...walked);
|
|
102
|
+
}
|
|
103
|
+
catch (err) {
|
|
104
|
+
scan_errors.push(`${fullDir}: ${err instanceof Error ? err.message : String(err)}`);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
for (let i = 0; i < candidates.length; i += PARSE_CONCURRENCY) {
|
|
108
|
+
const chunk = candidates.slice(i, i + PARSE_CONCURRENCY);
|
|
109
|
+
const results = await Promise.all(chunk.map(async (filePath) => {
|
|
110
|
+
const rel = relative(projectRoot, filePath);
|
|
111
|
+
try {
|
|
112
|
+
const directive = await scanDirective(filePath);
|
|
113
|
+
if (directive !== "use client")
|
|
114
|
+
return null;
|
|
115
|
+
const source = await readFile(filePath, "utf8");
|
|
116
|
+
const tree = await parseFile(filePath, source);
|
|
117
|
+
if (!tree) {
|
|
118
|
+
parse_failures.push(rel);
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
const signals = extractComponentSignals(rel, source, tree);
|
|
122
|
+
const score = rankingScore(signals);
|
|
123
|
+
return { rank: 0, path: rel, signals, score };
|
|
124
|
+
}
|
|
125
|
+
catch (err) {
|
|
126
|
+
parse_failures.push(`${rel}: ${err instanceof Error ? err.message : String(err)}`);
|
|
127
|
+
return null;
|
|
128
|
+
}
|
|
129
|
+
}));
|
|
130
|
+
for (const r of results)
|
|
131
|
+
if (r)
|
|
132
|
+
allEntries.push(r);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
allEntries.sort((a, b) => b.score - a.score);
|
|
136
|
+
const top = allEntries.slice(0, top_n).map((e, i) => ({ ...e, rank: i + 1 }));
|
|
137
|
+
const total_client_loc = allEntries.reduce((sum, e) => sum + e.signals.loc, 0);
|
|
138
|
+
return {
|
|
139
|
+
entries: top,
|
|
140
|
+
client_count: allEntries.length,
|
|
141
|
+
total_client_loc,
|
|
142
|
+
largest_offender: top[0] ?? null,
|
|
143
|
+
workspaces_scanned,
|
|
144
|
+
parse_failures,
|
|
145
|
+
scan_errors,
|
|
146
|
+
limitations: [
|
|
147
|
+
"score is signal-based — no actual bundle bytes estimated",
|
|
148
|
+
"transitive client boundaries via barrel files not detected",
|
|
149
|
+
],
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
//# sourceMappingURL=nextjs-boundary-tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nextjs-boundary-tools.js","sourceRoot":"","sources":["../../src/tools/nextjs-boundary-tools.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Next.js component classifier readers: directive detection, signal walking,
|
|
3
|
+
* per-file classification logic, and the decision table.
|
|
4
|
+
*
|
|
5
|
+
* These readers are pure helpers with no orchestration logic. They are used by
|
|
6
|
+
* `nextjs-component-tools.ts` (orchestrator) and re-exported from it for
|
|
7
|
+
* backward compatibility with existing consumers and tests. Split follows the
|
|
8
|
+
* T2/T3 reader + orchestrator precedent.
|
|
9
|
+
*/
|
|
10
|
+
import type Parser from "web-tree-sitter";
|
|
11
|
+
export type ComponentClassification = "server" | "client_explicit" | "client_inferred" | "ambiguous";
|
|
12
|
+
export interface SignalLocation {
|
|
13
|
+
name: string;
|
|
14
|
+
line: number;
|
|
15
|
+
column: number;
|
|
16
|
+
}
|
|
17
|
+
export interface ComponentSignals {
|
|
18
|
+
hooks: string[];
|
|
19
|
+
event_handlers: string[];
|
|
20
|
+
browser_globals: string[];
|
|
21
|
+
dynamic_ssr_false: boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Precise source locations for each detected signal. Agents use this to
|
|
24
|
+
* jump directly to the fix site without re-parsing the file. Populated
|
|
25
|
+
* for hooks, event_handlers, and browser_globals. dynamic_ssr_false is
|
|
26
|
+
* file-level so no location is tracked.
|
|
27
|
+
*/
|
|
28
|
+
signal_locations: SignalLocation[];
|
|
29
|
+
}
|
|
30
|
+
export interface NextjsComponentEntry {
|
|
31
|
+
path: string;
|
|
32
|
+
classification: ComponentClassification;
|
|
33
|
+
directive: "use client" | "use server" | null;
|
|
34
|
+
signals: ComponentSignals;
|
|
35
|
+
violations: string[];
|
|
36
|
+
/**
|
|
37
|
+
* Actionable remediation text for classification violations.
|
|
38
|
+
* Set when the entry has `unnecessary_use_client` violation or
|
|
39
|
+
* `client_inferred` classification; omitted otherwise.
|
|
40
|
+
*/
|
|
41
|
+
suggested_fix?: string;
|
|
42
|
+
}
|
|
43
|
+
export interface NextjsComponentsCounts {
|
|
44
|
+
total: number;
|
|
45
|
+
server: number;
|
|
46
|
+
client_explicit: number;
|
|
47
|
+
client_inferred: number;
|
|
48
|
+
ambiguous: number;
|
|
49
|
+
unnecessary_use_client: number;
|
|
50
|
+
}
|
|
51
|
+
export declare const MAX_FILE_SIZE_BYTES = 2097152;
|
|
52
|
+
export declare const DEFAULT_MAX_FILES = 2000;
|
|
53
|
+
export declare const PARSE_CONCURRENCY = 10;
|
|
54
|
+
/** Hooks that are server-safe (or SSR-safe) and don't imply client component. */
|
|
55
|
+
export declare const CLIENT_HOOKS_EXCLUDE: Set<string>;
|
|
56
|
+
/** JSX event attributes that imply client component. */
|
|
57
|
+
export declare const EVENT_HANDLER_ATTRS: Set<string>;
|
|
58
|
+
/** Browser-only globals (detected in MemberExpressions like `window.foo`). */
|
|
59
|
+
export declare const BROWSER_GLOBALS: Set<string>;
|
|
60
|
+
export declare const HOOK_NAME_RE: RegExp;
|
|
61
|
+
/**
|
|
62
|
+
* Pure decision table for component classification. No I/O, no AST access.
|
|
63
|
+
*
|
|
64
|
+
* Rules (in priority order):
|
|
65
|
+
* - directive === "use client":
|
|
66
|
+
* has any signal -> client_explicit
|
|
67
|
+
* no signals -> client_explicit + violation "unnecessary_use_client"
|
|
68
|
+
* - directive === "use server" -> server
|
|
69
|
+
* - directive === null:
|
|
70
|
+
* has any signal -> client_inferred
|
|
71
|
+
* no signals -> server
|
|
72
|
+
*/
|
|
73
|
+
export declare function applyClassificationTable(directive: "use client" | "use server" | null, signals: ComponentSignals): {
|
|
74
|
+
classification: ComponentClassification;
|
|
75
|
+
violations: string[];
|
|
76
|
+
};
|
|
77
|
+
/**
|
|
78
|
+
* Walk the AST to collect client-component signals:
|
|
79
|
+
* - hooks — call_expression whose callee identifier matches /^use[A-Z]/
|
|
80
|
+
* - events — jsx_attribute property_identifier in EVENT_HANDLER_ATTRS
|
|
81
|
+
* - globals — member_expression object identifier in BROWSER_GLOBALS
|
|
82
|
+
* - next/dynamic({ ssr: false }) — import from "next/dynamic" + call with ssr:false
|
|
83
|
+
*/
|
|
84
|
+
export declare function detectSignals(tree: Parser.Tree, _source: string): ComponentSignals;
|
|
85
|
+
/**
|
|
86
|
+
* Confirm a file-level directive by inspecting `Program.body[0]`.
|
|
87
|
+
*
|
|
88
|
+
* Tree-sitter's tsx/typescript grammars expose top-level directive strings as
|
|
89
|
+
* an `expression_statement` whose first named child is a `string` literal
|
|
90
|
+
* (a `"use client"` or `"use server"` token). Any other shape — including a
|
|
91
|
+
* nested block, inline comment, or non-first statement — must return `null`.
|
|
92
|
+
*/
|
|
93
|
+
export declare function confirmDirectiveFromTree(tree: Parser.Tree): "use client" | "use server" | null;
|
|
94
|
+
/**
|
|
95
|
+
* Classify a single file. Returns a partial entry with the directive field
|
|
96
|
+
* populated. Signal detection + final classification are added by the
|
|
97
|
+
* orchestrator (Task 23) via `detectSignals` (Task 21) and
|
|
98
|
+
* `applyClassificationTable` (Task 22).
|
|
99
|
+
*/
|
|
100
|
+
export declare function classifyFile(filePath: string, repoRoot: string): Promise<NextjsComponentEntry>;
|
|
101
|
+
//# sourceMappingURL=nextjs-component-readers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nextjs-component-readers.d.ts","sourceRoot":"","sources":["../../src/tools/nextjs-component-readers.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,KAAK,MAAM,MAAM,iBAAiB,CAAC;AAQ1C,MAAM,MAAM,uBAAuB,GAC/B,QAAQ,GACR,iBAAiB,GACjB,iBAAiB,GACjB,WAAW,CAAC;AAEhB,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,iBAAiB,EAAE,OAAO,CAAC;IAC3B;;;;;OAKG;IACH,gBAAgB,EAAE,cAAc,EAAE,CAAC;CACpC;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,uBAAuB,CAAC;IACxC,SAAS,EAAE,YAAY,GAAG,YAAY,GAAG,IAAI,CAAC;IAC9C,OAAO,EAAE,gBAAgB,CAAC;IAC1B,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,sBAAsB,EAAE,MAAM,CAAC;CAChC;AAMD,eAAO,MAAM,mBAAmB,UAAY,CAAC;AAC7C,eAAO,MAAM,iBAAiB,OAAO,CAAC;AACtC,eAAO,MAAM,iBAAiB,KAAK,CAAC;AAEpC,iFAAiF;AACjF,eAAO,MAAM,oBAAoB,aAA6B,CAAC;AAE/D,wDAAwD;AACxD,eAAO,MAAM,mBAAmB,aAU9B,CAAC;AAEH,8EAA8E;AAC9E,eAAO,MAAM,eAAe,aAG1B,CAAC;AAEH,eAAO,MAAM,YAAY,QAAkB,CAAC;AAM5C;;;;;;;;;;;GAWG;AACH,wBAAgB,wBAAwB,CACtC,SAAS,EAAE,YAAY,GAAG,YAAY,GAAG,IAAI,EAC7C,OAAO,EAAE,gBAAgB,GACxB;IAAE,cAAc,EAAE,uBAAuB,CAAC;IAAC,UAAU,EAAE,MAAM,EAAE,CAAA;CAAE,CAqBnE;AAMD;;;;;;GAMG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,CAAC,IAAI,EACjB,OAAO,EAAE,MAAM,GACd,gBAAgB,CAiHlB;AAMD;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,MAAM,CAAC,IAAI,GAChB,YAAY,GAAG,YAAY,GAAG,IAAI,CAkBpC;AAED;;;;;GAKG;AACH,wBAAsB,YAAY,CAChC,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,oBAAoB,CAAC,CAqD/B"}
|
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Next.js component classifier readers: directive detection, signal walking,
|
|
3
|
+
* per-file classification logic, and the decision table.
|
|
4
|
+
*
|
|
5
|
+
* These readers are pure helpers with no orchestration logic. They are used by
|
|
6
|
+
* `nextjs-component-tools.ts` (orchestrator) and re-exported from it for
|
|
7
|
+
* backward compatibility with existing consumers and tests. Split follows the
|
|
8
|
+
* T2/T3 reader + orchestrator precedent.
|
|
9
|
+
*/
|
|
10
|
+
import { readFile } from "node:fs/promises";
|
|
11
|
+
import { relative } from "node:path";
|
|
12
|
+
import { cachedParseFile as parseFile } from "../utils/nextjs-audit-cache.js";
|
|
13
|
+
import { scanDirective } from "../utils/nextjs.js";
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
// Constants
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
export const MAX_FILE_SIZE_BYTES = 2_097_152; // 2 MB hard cap per file
|
|
18
|
+
export const DEFAULT_MAX_FILES = 2000;
|
|
19
|
+
export const PARSE_CONCURRENCY = 10;
|
|
20
|
+
/** Hooks that are server-safe (or SSR-safe) and don't imply client component. */
|
|
21
|
+
export const CLIENT_HOOKS_EXCLUDE = new Set(["useId"]);
|
|
22
|
+
/** JSX event attributes that imply client component. */
|
|
23
|
+
export const EVENT_HANDLER_ATTRS = new Set([
|
|
24
|
+
"onClick", "onChange", "onSubmit", "onInput", "onFocus", "onBlur",
|
|
25
|
+
"onKeyDown", "onKeyUp", "onKeyPress",
|
|
26
|
+
"onMouseDown", "onMouseUp", "onMouseMove", "onMouseEnter", "onMouseLeave", "onMouseOver", "onMouseOut",
|
|
27
|
+
"onTouchStart", "onTouchEnd", "onTouchMove",
|
|
28
|
+
"onDrag", "onDrop", "onDragOver", "onDragEnd", "onDragStart", "onDragLeave", "onDragEnter",
|
|
29
|
+
"onScroll", "onWheel",
|
|
30
|
+
"onAnimationStart", "onAnimationEnd", "onTransitionEnd",
|
|
31
|
+
"onLoad", "onError",
|
|
32
|
+
"onCopy", "onCut", "onPaste",
|
|
33
|
+
]);
|
|
34
|
+
/** Browser-only globals (detected in MemberExpressions like `window.foo`). */
|
|
35
|
+
export const BROWSER_GLOBALS = new Set([
|
|
36
|
+
"window", "document", "localStorage", "sessionStorage",
|
|
37
|
+
"navigator", "location", "history",
|
|
38
|
+
]);
|
|
39
|
+
export const HOOK_NAME_RE = /^use[A-Z]\w*$/;
|
|
40
|
+
// ---------------------------------------------------------------------------
|
|
41
|
+
// Classification decision table
|
|
42
|
+
// ---------------------------------------------------------------------------
|
|
43
|
+
/**
|
|
44
|
+
* Pure decision table for component classification. No I/O, no AST access.
|
|
45
|
+
*
|
|
46
|
+
* Rules (in priority order):
|
|
47
|
+
* - directive === "use client":
|
|
48
|
+
* has any signal -> client_explicit
|
|
49
|
+
* no signals -> client_explicit + violation "unnecessary_use_client"
|
|
50
|
+
* - directive === "use server" -> server
|
|
51
|
+
* - directive === null:
|
|
52
|
+
* has any signal -> client_inferred
|
|
53
|
+
* no signals -> server
|
|
54
|
+
*/
|
|
55
|
+
export function applyClassificationTable(directive, signals) {
|
|
56
|
+
const hasAnySignal = signals.hooks.length > 0 ||
|
|
57
|
+
signals.event_handlers.length > 0 ||
|
|
58
|
+
signals.browser_globals.length > 0 ||
|
|
59
|
+
signals.dynamic_ssr_false;
|
|
60
|
+
if (directive === "use client") {
|
|
61
|
+
return {
|
|
62
|
+
classification: "client_explicit",
|
|
63
|
+
violations: hasAnySignal ? [] : ["unnecessary_use_client"],
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
if (directive === "use server") {
|
|
67
|
+
return { classification: "server", violations: [] };
|
|
68
|
+
}
|
|
69
|
+
// directive === null
|
|
70
|
+
return {
|
|
71
|
+
classification: hasAnySignal ? "client_inferred" : "server",
|
|
72
|
+
violations: [],
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
// ---------------------------------------------------------------------------
|
|
76
|
+
// Signal detection (hooks, JSX event handlers, browser globals, next/dynamic)
|
|
77
|
+
// ---------------------------------------------------------------------------
|
|
78
|
+
/**
|
|
79
|
+
* Walk the AST to collect client-component signals:
|
|
80
|
+
* - hooks — call_expression whose callee identifier matches /^use[A-Z]/
|
|
81
|
+
* - events — jsx_attribute property_identifier in EVENT_HANDLER_ATTRS
|
|
82
|
+
* - globals — member_expression object identifier in BROWSER_GLOBALS
|
|
83
|
+
* - next/dynamic({ ssr: false }) — import from "next/dynamic" + call with ssr:false
|
|
84
|
+
*/
|
|
85
|
+
export function detectSignals(tree, _source) {
|
|
86
|
+
const hooks = new Set();
|
|
87
|
+
const event_handlers = new Set();
|
|
88
|
+
const browser_globals = new Set();
|
|
89
|
+
const signal_locations = [];
|
|
90
|
+
let dynamic_ssr_false = false;
|
|
91
|
+
const root = tree.rootNode;
|
|
92
|
+
// Hooks: call_expression with identifier callee matching /^use[A-Z]/
|
|
93
|
+
for (const call of root.descendantsOfType("call_expression")) {
|
|
94
|
+
const fn = call.childForFieldName("function") ?? call.namedChild(0);
|
|
95
|
+
if (fn?.type === "identifier") {
|
|
96
|
+
const name = fn.text;
|
|
97
|
+
if (HOOK_NAME_RE.test(name) && !CLIENT_HOOKS_EXCLUDE.has(name)) {
|
|
98
|
+
hooks.add(name);
|
|
99
|
+
signal_locations.push({
|
|
100
|
+
name,
|
|
101
|
+
line: fn.startPosition.row + 1,
|
|
102
|
+
column: fn.startPosition.column + 1,
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
// JSX event handlers
|
|
108
|
+
for (const attr of root.descendantsOfType("jsx_attribute")) {
|
|
109
|
+
const nameNode = attr.namedChild(0);
|
|
110
|
+
if (nameNode?.type === "property_identifier" || nameNode?.type === "identifier") {
|
|
111
|
+
const name = nameNode.text;
|
|
112
|
+
if (EVENT_HANDLER_ATTRS.has(name)) {
|
|
113
|
+
event_handlers.add(name);
|
|
114
|
+
signal_locations.push({
|
|
115
|
+
name,
|
|
116
|
+
line: nameNode.startPosition.row + 1,
|
|
117
|
+
column: nameNode.startPosition.column + 1,
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
// Browser globals via member_expression (e.g. window.location)
|
|
123
|
+
for (const mem of root.descendantsOfType("member_expression")) {
|
|
124
|
+
const obj = mem.childForFieldName("object") ?? mem.namedChild(0);
|
|
125
|
+
if (obj?.type === "identifier" && BROWSER_GLOBALS.has(obj.text)) {
|
|
126
|
+
browser_globals.add(obj.text);
|
|
127
|
+
signal_locations.push({
|
|
128
|
+
name: obj.text,
|
|
129
|
+
line: obj.startPosition.row + 1,
|
|
130
|
+
column: obj.startPosition.column + 1,
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
// next/dynamic with { ssr: false }
|
|
135
|
+
// Only trust if there's an import from "next/dynamic". We then look for any
|
|
136
|
+
// call expression with second argument containing { ssr: false }.
|
|
137
|
+
const importsNextDynamic = root
|
|
138
|
+
.descendantsOfType("import_statement")
|
|
139
|
+
.some((imp) => {
|
|
140
|
+
// The module source is a direct string child of import_statement
|
|
141
|
+
for (const child of imp.namedChildren) {
|
|
142
|
+
if (child.type === "string") {
|
|
143
|
+
const frag = child.namedChild(0);
|
|
144
|
+
const text = frag?.type === "string_fragment" ? frag.text : child.text.slice(1, -1);
|
|
145
|
+
if (text === "next/dynamic")
|
|
146
|
+
return true;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return false;
|
|
150
|
+
});
|
|
151
|
+
if (importsNextDynamic) {
|
|
152
|
+
for (const call of root.descendantsOfType("call_expression")) {
|
|
153
|
+
const fn = call.childForFieldName("function") ?? call.namedChild(0);
|
|
154
|
+
if (fn?.type !== "identifier" || fn.text !== "dynamic")
|
|
155
|
+
continue;
|
|
156
|
+
const args = call.childForFieldName("arguments") ?? call.namedChild(1);
|
|
157
|
+
if (!args)
|
|
158
|
+
continue;
|
|
159
|
+
// Find the second argument (an object with ssr: false)
|
|
160
|
+
const argChildren = args.namedChildren;
|
|
161
|
+
if (argChildren.length < 2)
|
|
162
|
+
continue;
|
|
163
|
+
const opts = argChildren[1];
|
|
164
|
+
if (!opts || opts.type !== "object")
|
|
165
|
+
continue;
|
|
166
|
+
// Iterate pairs that are direct named children of the options object.
|
|
167
|
+
for (const pair of opts.namedChildren) {
|
|
168
|
+
if (pair.type !== "pair")
|
|
169
|
+
continue;
|
|
170
|
+
const key = pair.childForFieldName("key") ?? pair.namedChild(0);
|
|
171
|
+
if (!key)
|
|
172
|
+
continue;
|
|
173
|
+
const keyText = key.type === "property_identifier" || key.type === "identifier"
|
|
174
|
+
? key.text
|
|
175
|
+
: key.type === "string"
|
|
176
|
+
? key.text.slice(1, -1)
|
|
177
|
+
: null;
|
|
178
|
+
if (keyText !== "ssr")
|
|
179
|
+
continue;
|
|
180
|
+
const value = pair.childForFieldName("value") ?? pair.namedChild(1);
|
|
181
|
+
if (value?.type === "false") {
|
|
182
|
+
dynamic_ssr_false = true;
|
|
183
|
+
break;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
return {
|
|
189
|
+
hooks: [...hooks],
|
|
190
|
+
event_handlers: [...event_handlers],
|
|
191
|
+
browser_globals: [...browser_globals],
|
|
192
|
+
dynamic_ssr_false,
|
|
193
|
+
signal_locations,
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
// ---------------------------------------------------------------------------
|
|
197
|
+
// Two-stage directive detection
|
|
198
|
+
// ---------------------------------------------------------------------------
|
|
199
|
+
/**
|
|
200
|
+
* Confirm a file-level directive by inspecting `Program.body[0]`.
|
|
201
|
+
*
|
|
202
|
+
* Tree-sitter's tsx/typescript grammars expose top-level directive strings as
|
|
203
|
+
* an `expression_statement` whose first named child is a `string` literal
|
|
204
|
+
* (a `"use client"` or `"use server"` token). Any other shape — including a
|
|
205
|
+
* nested block, inline comment, or non-first statement — must return `null`.
|
|
206
|
+
*/
|
|
207
|
+
export function confirmDirectiveFromTree(tree) {
|
|
208
|
+
const root = tree.rootNode;
|
|
209
|
+
const first = root.namedChildren[0];
|
|
210
|
+
if (!first)
|
|
211
|
+
return null;
|
|
212
|
+
if (first.type !== "expression_statement")
|
|
213
|
+
return null;
|
|
214
|
+
const exprChild = first.namedChildren[0];
|
|
215
|
+
if (!exprChild)
|
|
216
|
+
return null;
|
|
217
|
+
if (exprChild.type !== "string")
|
|
218
|
+
return null;
|
|
219
|
+
// tree-sitter `string` nodes have fragment children containing the text
|
|
220
|
+
// between the quotes. Strip the surrounding quotes via .text and compare.
|
|
221
|
+
const raw = exprChild.text;
|
|
222
|
+
if (raw.length < 3)
|
|
223
|
+
return null;
|
|
224
|
+
const inner = raw.slice(1, -1);
|
|
225
|
+
if (inner === "use client")
|
|
226
|
+
return "use client";
|
|
227
|
+
if (inner === "use server")
|
|
228
|
+
return "use server";
|
|
229
|
+
return null;
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Classify a single file. Returns a partial entry with the directive field
|
|
233
|
+
* populated. Signal detection + final classification are added by the
|
|
234
|
+
* orchestrator (Task 23) via `detectSignals` (Task 21) and
|
|
235
|
+
* `applyClassificationTable` (Task 22).
|
|
236
|
+
*/
|
|
237
|
+
export async function classifyFile(filePath, repoRoot) {
|
|
238
|
+
const relPath = relative(repoRoot, filePath);
|
|
239
|
+
const emptySignals = {
|
|
240
|
+
hooks: [],
|
|
241
|
+
event_handlers: [],
|
|
242
|
+
browser_globals: [],
|
|
243
|
+
dynamic_ssr_false: false,
|
|
244
|
+
};
|
|
245
|
+
// Stage 1: fast-reject via 512-byte window
|
|
246
|
+
const stage1 = await scanDirective(filePath);
|
|
247
|
+
// Stage 2: parse file via tree-sitter
|
|
248
|
+
let source;
|
|
249
|
+
try {
|
|
250
|
+
source = await readFile(filePath, "utf8");
|
|
251
|
+
}
|
|
252
|
+
catch {
|
|
253
|
+
return {
|
|
254
|
+
path: relPath,
|
|
255
|
+
classification: "ambiguous",
|
|
256
|
+
directive: null,
|
|
257
|
+
signals: emptySignals,
|
|
258
|
+
violations: [],
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
const tree = await parseFile(filePath, source);
|
|
262
|
+
if (!tree) {
|
|
263
|
+
return {
|
|
264
|
+
path: relPath,
|
|
265
|
+
classification: "ambiguous",
|
|
266
|
+
directive: null,
|
|
267
|
+
signals: emptySignals,
|
|
268
|
+
violations: [],
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
// Stage 3: confirm directive via AST (only if stage 1 matched)
|
|
272
|
+
let directive = null;
|
|
273
|
+
if (stage1 !== null) {
|
|
274
|
+
directive = confirmDirectiveFromTree(tree);
|
|
275
|
+
}
|
|
276
|
+
// Note: signal detection and final classification are layered in by
|
|
277
|
+
// Tasks 21-23. For now we return a stub classification — the orchestrator
|
|
278
|
+
// rebuilds this via detectSignals + applyClassificationTable.
|
|
279
|
+
return {
|
|
280
|
+
path: relPath,
|
|
281
|
+
classification: directive === "use client" ? "client_explicit" : "server",
|
|
282
|
+
directive,
|
|
283
|
+
signals: emptySignals,
|
|
284
|
+
violations: [],
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
//# sourceMappingURL=nextjs-component-readers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nextjs-component-readers.js","sourceRoot":"","sources":["../../src/tools/nextjs-component-readers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Next.js component classifier: AST-based Server/Client component detection.
|
|
3
|
+
*
|
|
4
|
+
* Uses a two-stage directive detection strategy:
|
|
5
|
+
* 1. Fast-reject: scan first 512 bytes for "use client"/"use server" substring
|
|
6
|
+
* 2. AST confirm: verify directive is `Program.body[0]` ExpressionStatement
|
|
7
|
+
*
|
|
8
|
+
* Then walks the AST for client-component signals (hooks, JSX event handlers,
|
|
9
|
+
* browser globals, `next/dynamic({ ssr: false })`) and classifies each file
|
|
10
|
+
* per the 8-row decision table.
|
|
11
|
+
*
|
|
12
|
+
* This file is the orchestrator. AST reader helpers (`applyClassificationTable`,
|
|
13
|
+
* `detectSignals`, `confirmDirectiveFromTree`, `classifyFile`) live in
|
|
14
|
+
* `nextjs-component-readers.ts` and are re-exported from here for backward
|
|
15
|
+
* compatibility.
|
|
16
|
+
*/
|
|
17
|
+
import type { NextjsComponentEntry, NextjsComponentsCounts } from "./nextjs-component-readers.js";
|
|
18
|
+
export { MAX_FILE_SIZE_BYTES, DEFAULT_MAX_FILES, PARSE_CONCURRENCY, CLIENT_HOOKS_EXCLUDE, EVENT_HANDLER_ATTRS, BROWSER_GLOBALS, HOOK_NAME_RE, applyClassificationTable, detectSignals, confirmDirectiveFromTree, classifyFile, } from "./nextjs-component-readers.js";
|
|
19
|
+
export type { ComponentClassification, SignalLocation, ComponentSignals, NextjsComponentEntry, NextjsComponentsCounts, } from "./nextjs-component-readers.js";
|
|
20
|
+
export interface NextjsComponentsResult {
|
|
21
|
+
files: NextjsComponentEntry[];
|
|
22
|
+
counts: NextjsComponentsCounts;
|
|
23
|
+
parse_failures: string[];
|
|
24
|
+
scan_errors: string[];
|
|
25
|
+
truncated: boolean;
|
|
26
|
+
truncated_at?: number;
|
|
27
|
+
workspaces_scanned: string[];
|
|
28
|
+
limitations: string[];
|
|
29
|
+
}
|
|
30
|
+
export interface AnalyzeNextjsComponentsOptions {
|
|
31
|
+
workspace?: string | undefined;
|
|
32
|
+
file_pattern?: string | undefined;
|
|
33
|
+
max_files?: number | undefined;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Analyze a Next.js repository for Server/Client component classification.
|
|
37
|
+
*
|
|
38
|
+
* Flow:
|
|
39
|
+
* 1. Kill switch check (`CODESIFT_DISABLE_TOOLS`)
|
|
40
|
+
* 2. Resolve project root via `getCodeIndex(repo).root`
|
|
41
|
+
* 3. Determine workspaces: explicit `workspace` param, `discoverWorkspaces()`,
|
|
42
|
+
* or single root.
|
|
43
|
+
* 4. For each workspace, walk `app/` for `.tsx`/`.jsx` files.
|
|
44
|
+
* 5. Process in batches of `PARSE_CONCURRENCY` — for each file:
|
|
45
|
+
* a. `classifyFile` for directive
|
|
46
|
+
* b. `detectSignals` on the parsed tree (re-parses — acceptable for v1)
|
|
47
|
+
* c. `applyClassificationTable` to finalize classification + violations
|
|
48
|
+
* 6. Aggregate counts; honor `max_files`.
|
|
49
|
+
*/
|
|
50
|
+
export declare function analyzeNextjsComponents(repo: string, options?: AnalyzeNextjsComponentsOptions): Promise<NextjsComponentsResult>;
|
|
51
|
+
//# sourceMappingURL=nextjs-component-tools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nextjs-component-tools.d.ts","sourceRoot":"","sources":["../../src/tools/nextjs-component-tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAgBH,OAAO,KAAK,EAEV,oBAAoB,EACpB,sBAAsB,EACvB,MAAM,+BAA+B,CAAC;AAGvC,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EACjB,iBAAiB,EACjB,oBAAoB,EACpB,mBAAmB,EACnB,eAAe,EACf,YAAY,EACZ,wBAAwB,EACxB,aAAa,EACb,wBAAwB,EACxB,YAAY,GACb,MAAM,+BAA+B,CAAC;AACvC,YAAY,EACV,uBAAuB,EACvB,cAAc,EACd,gBAAgB,EAChB,oBAAoB,EACpB,sBAAsB,GACvB,MAAM,+BAA+B,CAAC;AAMvC,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,oBAAoB,EAAE,CAAC;IAC9B,MAAM,EAAE,sBAAsB,CAAC;IAC/B,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,SAAS,EAAE,OAAO,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,8BAA8B;IAC7C,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAChC;AASD;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,uBAAuB,CAC3C,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,8BAA8B,GACvC,OAAO,CAAC,sBAAsB,CAAC,CA8GjC"}
|