@shrkcrft/inspector 0.1.0-alpha.1
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/LICENSE +21 -0
- package/README.md +15 -0
- package/dist/acceptance-replay.d.ts +63 -0
- package/dist/acceptance-replay.d.ts.map +1 -0
- package/dist/acceptance-replay.js +240 -0
- package/dist/action-hint-diagnostics.d.ts +32 -0
- package/dist/action-hint-diagnostics.d.ts.map +1 -0
- package/dist/action-hint-diagnostics.js +133 -0
- package/dist/adoption-check.d.ts +28 -0
- package/dist/adoption-check.d.ts.map +1 -0
- package/dist/adoption-check.js +181 -0
- package/dist/adoption-checkpoint.d.ts +97 -0
- package/dist/adoption-checkpoint.d.ts.map +1 -0
- package/dist/adoption-checkpoint.js +209 -0
- package/dist/adoption-merge-preview.d.ts +28 -0
- package/dist/adoption-merge-preview.d.ts.map +1 -0
- package/dist/adoption-merge-preview.js +254 -0
- package/dist/adoption-report-renderer.d.ts +33 -0
- package/dist/adoption-report-renderer.d.ts.map +1 -0
- package/dist/adoption-report-renderer.js +257 -0
- package/dist/adoption-state.d.ts +100 -0
- package/dist/adoption-state.d.ts.map +1 -0
- package/dist/adoption-state.js +296 -0
- package/dist/adoption-three-way.d.ts +46 -0
- package/dist/adoption-three-way.d.ts.map +1 -0
- package/dist/adoption-three-way.js +181 -0
- package/dist/agent-brief.d.ts +77 -0
- package/dist/agent-brief.d.ts.map +1 -0
- package/dist/agent-brief.js +490 -0
- package/dist/agent-contract-gate.d.ts +108 -0
- package/dist/agent-contract-gate.d.ts.map +1 -0
- package/dist/agent-contract-gate.js +412 -0
- package/dist/agent-contract-templates.d.ts +63 -0
- package/dist/agent-contract-templates.d.ts.map +1 -0
- package/dist/agent-contract-templates.js +346 -0
- package/dist/agent-contract.d.ts +65 -0
- package/dist/agent-contract.d.ts.map +1 -0
- package/dist/agent-contract.js +555 -0
- package/dist/agent-handoff.d.ts +123 -0
- package/dist/agent-handoff.d.ts.map +1 -0
- package/dist/agent-handoff.js +470 -0
- package/dist/agent-instructions.d.ts +2 -0
- package/dist/agent-instructions.d.ts.map +1 -0
- package/dist/agent-instructions.js +21 -0
- package/dist/agent-orchestration.d.ts +61 -0
- package/dist/agent-orchestration.d.ts.map +1 -0
- package/dist/agent-orchestration.js +285 -0
- package/dist/agent-task-prep.d.ts +31 -0
- package/dist/agent-task-prep.d.ts.map +1 -0
- package/dist/agent-task-prep.js +73 -0
- package/dist/ai-readiness.d.ts +30 -0
- package/dist/ai-readiness.d.ts.map +1 -0
- package/dist/ai-readiness.js +279 -0
- package/dist/api-report.d.ts +51 -0
- package/dist/api-report.d.ts.map +1 -0
- package/dist/api-report.js +254 -0
- package/dist/apply-dispatch-trace.d.ts +93 -0
- package/dist/apply-dispatch-trace.d.ts.map +1 -0
- package/dist/apply-dispatch-trace.js +283 -0
- package/dist/apply-gate-result.d.ts +52 -0
- package/dist/apply-gate-result.d.ts.map +1 -0
- package/dist/apply-gate-result.js +44 -0
- package/dist/architecture-map.d.ts +118 -0
- package/dist/architecture-map.d.ts.map +1 -0
- package/dist/architecture-map.js +543 -0
- package/dist/area-explore.d.ts +75 -0
- package/dist/area-explore.d.ts.map +1 -0
- package/dist/area-explore.js +438 -0
- package/dist/area-map.d.ts +57 -0
- package/dist/area-map.d.ts.map +1 -0
- package/dist/area-map.js +214 -0
- package/dist/asset-provenance.d.ts +123 -0
- package/dist/asset-provenance.d.ts.map +1 -0
- package/dist/asset-provenance.js +209 -0
- package/dist/barrel-operations.d.ts +45 -0
- package/dist/barrel-operations.d.ts.map +1 -0
- package/dist/barrel-operations.js +159 -0
- package/dist/boundaries-changed-only.d.ts +62 -0
- package/dist/boundaries-changed-only.d.ts.map +1 -0
- package/dist/boundaries-changed-only.js +97 -0
- package/dist/boundary-suggestions.d.ts +20 -0
- package/dist/boundary-suggestions.d.ts.map +1 -0
- package/dist/boundary-suggestions.js +51 -0
- package/dist/bundle-diff.d.ts +98 -0
- package/dist/bundle-diff.d.ts.map +1 -0
- package/dist/bundle-diff.js +531 -0
- package/dist/bundle-replay.d.ts +68 -0
- package/dist/bundle-replay.d.ts.map +1 -0
- package/dist/bundle-replay.js +273 -0
- package/dist/bundle-validate-html.d.ts +11 -0
- package/dist/bundle-validate-html.d.ts.map +1 -0
- package/dist/bundle-validate-html.js +60 -0
- package/dist/change-intent.d.ts +36 -0
- package/dist/change-intent.d.ts.map +1 -0
- package/dist/change-intent.js +259 -0
- package/dist/changed-preflight.d.ts +59 -0
- package/dist/changed-preflight.d.ts.map +1 -0
- package/dist/changed-preflight.js +358 -0
- package/dist/changed-scope.d.ts +112 -0
- package/dist/changed-scope.d.ts.map +1 -0
- package/dist/changed-scope.js +172 -0
- package/dist/changes-summary.d.ts +87 -0
- package/dist/changes-summary.d.ts.map +1 -0
- package/dist/changes-summary.js +323 -0
- package/dist/check-result-v1.d.ts +90 -0
- package/dist/check-result-v1.d.ts.map +1 -0
- package/dist/check-result-v1.js +335 -0
- package/dist/ci-integrity-report.d.ts +38 -0
- package/dist/ci-integrity-report.d.ts.map +1 -0
- package/dist/ci-integrity-report.js +324 -0
- package/dist/ci-permissions-fix.d.ts +38 -0
- package/dist/ci-permissions-fix.d.ts.map +1 -0
- package/dist/ci-permissions-fix.js +382 -0
- package/dist/ci-permissions.d.ts +51 -0
- package/dist/ci-permissions.d.ts.map +1 -0
- package/dist/ci-permissions.js +431 -0
- package/dist/ci-predict.d.ts +42 -0
- package/dist/ci-predict.d.ts.map +1 -0
- package/dist/ci-predict.js +300 -0
- package/dist/ci-scaffold.d.ts +47 -0
- package/dist/ci-scaffold.d.ts.map +1 -0
- package/dist/ci-scaffold.js +638 -0
- package/dist/codemod-assist.d.ts +97 -0
- package/dist/codemod-assist.d.ts.map +1 -0
- package/dist/codemod-assist.js +261 -0
- package/dist/command-recommender.d.ts +25 -0
- package/dist/command-recommender.d.ts.map +1 -0
- package/dist/command-recommender.js +145 -0
- package/dist/command-suggester.d.ts +61 -0
- package/dist/command-suggester.d.ts.map +1 -0
- package/dist/command-suggester.js +159 -0
- package/dist/command-taxonomy.d.ts +38 -0
- package/dist/command-taxonomy.d.ts.map +1 -0
- package/dist/command-taxonomy.js +164 -0
- package/dist/compliance-evidence.d.ts +58 -0
- package/dist/compliance-evidence.d.ts.map +1 -0
- package/dist/compliance-evidence.js +260 -0
- package/dist/compliance-profiles.d.ts +42 -0
- package/dist/compliance-profiles.d.ts.map +1 -0
- package/dist/compliance-profiles.js +171 -0
- package/dist/construct-adoption-diff.d.ts +55 -0
- package/dist/construct-adoption-diff.d.ts.map +1 -0
- package/dist/construct-adoption-diff.js +331 -0
- package/dist/construct-adoption.d.ts +71 -0
- package/dist/construct-adoption.d.ts.map +1 -0
- package/dist/construct-adoption.js +331 -0
- package/dist/construct-inference.d.ts +44 -0
- package/dist/construct-inference.d.ts.map +1 -0
- package/dist/construct-inference.js +391 -0
- package/dist/construct-registry.d.ts +32 -0
- package/dist/construct-registry.d.ts.map +1 -0
- package/dist/construct-registry.js +198 -0
- package/dist/contract-file-rule.d.ts +37 -0
- package/dist/contract-file-rule.d.ts.map +1 -0
- package/dist/contract-file-rule.js +99 -0
- package/dist/contract-template-registry.d.ts +28 -0
- package/dist/contract-template-registry.d.ts.map +1 -0
- package/dist/contract-template-registry.js +161 -0
- package/dist/contradictions.d.ts +52 -0
- package/dist/contradictions.d.ts.map +1 -0
- package/dist/contradictions.js +391 -0
- package/dist/convention-registry.d.ts +44 -0
- package/dist/convention-registry.d.ts.map +1 -0
- package/dist/convention-registry.js +195 -0
- package/dist/coverage-report.d.ts +25 -0
- package/dist/coverage-report.d.ts.map +1 -0
- package/dist/coverage-report.js +190 -0
- package/dist/custom-checks.d.ts +146 -0
- package/dist/custom-checks.d.ts.map +1 -0
- package/dist/custom-checks.js +260 -0
- package/dist/dashboard/dashboard-data.d.ts +59 -0
- package/dist/dashboard/dashboard-data.d.ts.map +1 -0
- package/dist/dashboard/dashboard-data.js +653 -0
- package/dist/dashboard-export.d.ts +67 -0
- package/dist/dashboard-export.d.ts.map +1 -0
- package/dist/dashboard-export.js +203 -0
- package/dist/decision-records.d.ts +47 -0
- package/dist/decision-records.d.ts.map +1 -0
- package/dist/decision-records.js +255 -0
- package/dist/demo-package.d.ts +49 -0
- package/dist/demo-package.d.ts.map +1 -0
- package/dist/demo-package.js +305 -0
- package/dist/demo-script.d.ts +25 -0
- package/dist/demo-script.d.ts.map +1 -0
- package/dist/demo-script.js +198 -0
- package/dist/demo-workflow.d.ts +28 -0
- package/dist/demo-workflow.d.ts.map +1 -0
- package/dist/demo-workflow.js +178 -0
- package/dist/dev-cycle.d.ts +41 -0
- package/dist/dev-cycle.d.ts.map +1 -0
- package/dist/dev-cycle.js +94 -0
- package/dist/dev-session-html.d.ts +13 -0
- package/dist/dev-session-html.d.ts.map +1 -0
- package/dist/dev-session-html.js +223 -0
- package/dist/dev-session-report.d.ts +11 -0
- package/dist/dev-session-report.d.ts.map +1 -0
- package/dist/dev-session-report.js +206 -0
- package/dist/dev-session.d.ts +257 -0
- package/dist/dev-session.d.ts.map +1 -0
- package/dist/dev-session.js +568 -0
- package/dist/diagnostics-suggest.d.ts +17 -0
- package/dist/diagnostics-suggest.d.ts.map +1 -0
- package/dist/diagnostics-suggest.js +69 -0
- package/dist/docs-check.d.ts +40 -0
- package/dist/docs-check.d.ts.map +1 -0
- package/dist/docs-check.js +221 -0
- package/dist/doctor-acknowledgements.d.ts +69 -0
- package/dist/doctor-acknowledgements.d.ts.map +1 -0
- package/dist/doctor-acknowledgements.js +150 -0
- package/dist/doctor-result.d.ts +51 -0
- package/dist/doctor-result.d.ts.map +1 -0
- package/dist/doctor-result.js +7 -0
- package/dist/doctor-suppressions.d.ts +91 -0
- package/dist/doctor-suppressions.d.ts.map +1 -0
- package/dist/doctor-suppressions.js +238 -0
- package/dist/drift-baseline.d.ts +29 -0
- package/dist/drift-baseline.d.ts.map +1 -0
- package/dist/drift-baseline.js +80 -0
- package/dist/drift.d.ts +38 -0
- package/dist/drift.d.ts.map +1 -0
- package/dist/drift.js +107 -0
- package/dist/entrypoint-matrix.d.ts +61 -0
- package/dist/entrypoint-matrix.d.ts.map +1 -0
- package/dist/entrypoint-matrix.js +221 -0
- package/dist/examples-check.d.ts +36 -0
- package/dist/examples-check.d.ts.map +1 -0
- package/dist/examples-check.js +168 -0
- package/dist/execution-graph.d.ts +98 -0
- package/dist/execution-graph.d.ts.map +1 -0
- package/dist/execution-graph.js +484 -0
- package/dist/export-bundle.d.ts +10 -0
- package/dist/export-bundle.d.ts.map +1 -0
- package/dist/export-bundle.js +90 -0
- package/dist/failure-diagnostics.d.ts +63 -0
- package/dist/failure-diagnostics.d.ts.map +1 -0
- package/dist/failure-diagnostics.js +243 -0
- package/dist/feature-bundle.d.ts +111 -0
- package/dist/feature-bundle.d.ts.map +1 -0
- package/dist/feature-bundle.js +211 -0
- package/dist/feedback-actions-v2.d.ts +65 -0
- package/dist/feedback-actions-v2.d.ts.map +1 -0
- package/dist/feedback-actions-v2.js +183 -0
- package/dist/feedback-ingestion.d.ts +96 -0
- package/dist/feedback-ingestion.d.ts.map +1 -0
- package/dist/feedback-ingestion.js +400 -0
- package/dist/fix-preview.d.ts +82 -0
- package/dist/fix-preview.d.ts.map +1 -0
- package/dist/fix-preview.js +365 -0
- package/dist/fuzzy-impact.d.ts +50 -0
- package/dist/fuzzy-impact.d.ts.map +1 -0
- package/dist/fuzzy-impact.js +446 -0
- package/dist/generated-code.d.ts +97 -0
- package/dist/generated-code.d.ts.map +1 -0
- package/dist/generated-code.js +395 -0
- package/dist/git-helpers.d.ts +38 -0
- package/dist/git-helpers.d.ts.map +1 -0
- package/dist/git-helpers.js +173 -0
- package/dist/golden-output.d.ts +33 -0
- package/dist/golden-output.d.ts.map +1 -0
- package/dist/golden-output.js +92 -0
- package/dist/grounding/build-grounding.d.ts +53 -0
- package/dist/grounding/build-grounding.d.ts.map +1 -0
- package/dist/grounding/build-grounding.js +51 -0
- package/dist/grounding/nx-projects.d.ts +29 -0
- package/dist/grounding/nx-projects.d.ts.map +1 -0
- package/dist/grounding/nx-projects.js +109 -0
- package/dist/grounding/validate-extracted-plan.d.ts +20 -0
- package/dist/grounding/validate-extracted-plan.d.ts.map +1 -0
- package/dist/grounding/validate-extracted-plan.js +127 -0
- package/dist/healing-plan.d.ts +33 -0
- package/dist/healing-plan.d.ts.map +1 -0
- package/dist/healing-plan.js +346 -0
- package/dist/helper-registry.d.ts +90 -0
- package/dist/helper-registry.d.ts.map +1 -0
- package/dist/helper-registry.js +529 -0
- package/dist/impact-analysis.d.ts +150 -0
- package/dist/impact-analysis.d.ts.map +1 -0
- package/dist/impact-analysis.js +697 -0
- package/dist/impact-graph-render.d.ts +51 -0
- package/dist/impact-graph-render.d.ts.map +1 -0
- package/dist/impact-graph-render.js +139 -0
- package/dist/impact-graph.d.ts +17 -0
- package/dist/impact-graph.d.ts.map +1 -0
- package/dist/impact-graph.js +119 -0
- package/dist/impact-render.d.ts +22 -0
- package/dist/impact-render.d.ts.map +1 -0
- package/dist/impact-render.js +422 -0
- package/dist/import-graph-analysis.d.ts +28 -0
- package/dist/import-graph-analysis.d.ts.map +1 -0
- package/dist/import-graph-analysis.js +193 -0
- package/dist/import-hygiene.d.ts +93 -0
- package/dist/import-hygiene.d.ts.map +1 -0
- package/dist/import-hygiene.js +366 -0
- package/dist/index.d.ts +224 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +234 -0
- package/dist/ingest-adoption.d.ts +50 -0
- package/dist/ingest-adoption.d.ts.map +1 -0
- package/dist/ingest-adoption.js +183 -0
- package/dist/ingest-apply.d.ts +80 -0
- package/dist/ingest-apply.d.ts.map +1 -0
- package/dist/ingest-apply.js +227 -0
- package/dist/ingest-body-extractor.d.ts +28 -0
- package/dist/ingest-body-extractor.d.ts.map +1 -0
- package/dist/ingest-body-extractor.js +129 -0
- package/dist/ingest-drafts.d.ts +16 -0
- package/dist/ingest-drafts.d.ts.map +1 -0
- package/dist/ingest-drafts.js +482 -0
- package/dist/inspector-cache.d.ts +41 -0
- package/dist/inspector-cache.d.ts.map +1 -0
- package/dist/inspector-cache.js +104 -0
- package/dist/install-smoke.d.ts +44 -0
- package/dist/install-smoke.d.ts.map +1 -0
- package/dist/install-smoke.js +31 -0
- package/dist/knowledge-authoring.d.ts +151 -0
- package/dist/knowledge-authoring.d.ts.map +1 -0
- package/dist/knowledge-authoring.js +586 -0
- package/dist/knowledge-graph.d.ts +76 -0
- package/dist/knowledge-graph.d.ts.map +1 -0
- package/dist/knowledge-graph.js +336 -0
- package/dist/knowledge-lint.d.ts +97 -0
- package/dist/knowledge-lint.d.ts.map +1 -0
- package/dist/knowledge-lint.js +302 -0
- package/dist/knowledge-rename.d.ts +38 -0
- package/dist/knowledge-rename.d.ts.map +1 -0
- package/dist/knowledge-rename.js +88 -0
- package/dist/knowledge-stale.d.ts +124 -0
- package/dist/knowledge-stale.d.ts.map +1 -0
- package/dist/knowledge-stale.js +892 -0
- package/dist/languages/command-inference.d.ts +27 -0
- package/dist/languages/command-inference.d.ts.map +1 -0
- package/dist/languages/command-inference.js +214 -0
- package/dist/languages/dependency-scan.d.ts +33 -0
- package/dist/languages/dependency-scan.d.ts.map +1 -0
- package/dist/languages/dependency-scan.js +343 -0
- package/dist/languages/index.d.ts +14 -0
- package/dist/languages/index.d.ts.map +1 -0
- package/dist/languages/index.js +13 -0
- package/dist/languages/language-boundaries.d.ts +30 -0
- package/dist/languages/language-boundaries.d.ts.map +1 -0
- package/dist/languages/language-boundaries.js +176 -0
- package/dist/languages/language-cache.d.ts +54 -0
- package/dist/languages/language-cache.d.ts.map +1 -0
- package/dist/languages/language-cache.js +236 -0
- package/dist/languages/language-detection.d.ts +30 -0
- package/dist/languages/language-detection.d.ts.map +1 -0
- package/dist/languages/language-detection.js +584 -0
- package/dist/languages/language-id.d.ts +15 -0
- package/dist/languages/language-id.d.ts.map +1 -0
- package/dist/languages/language-id.js +15 -0
- package/dist/languages/language-runner.d.ts +90 -0
- package/dist/languages/language-runner.d.ts.map +1 -0
- package/dist/languages/language-runner.js +346 -0
- package/dist/languages/polyglot-boundary.d.ts +80 -0
- package/dist/languages/polyglot-boundary.d.ts.map +1 -0
- package/dist/languages/polyglot-boundary.js +373 -0
- package/dist/languages/polyglot-ci.d.ts +25 -0
- package/dist/languages/polyglot-ci.d.ts.map +1 -0
- package/dist/languages/polyglot-ci.js +278 -0
- package/dist/languages/test-impact.d.ts +19 -0
- package/dist/languages/test-impact.d.ts.map +1 -0
- package/dist/languages/test-impact.js +157 -0
- package/dist/loader-diagnostics.d.ts +40 -0
- package/dist/loader-diagnostics.d.ts.map +1 -0
- package/dist/loader-diagnostics.js +49 -0
- package/dist/memory-diff.d.ts +60 -0
- package/dist/memory-diff.d.ts.map +1 -0
- package/dist/memory-diff.js +302 -0
- package/dist/migration-profile-registry.d.ts +26 -0
- package/dist/migration-profile-registry.d.ts.map +1 -0
- package/dist/migration-profile-registry.js +135 -0
- package/dist/migration-readiness.d.ts +101 -0
- package/dist/migration-readiness.d.ts.map +1 -0
- package/dist/migration-readiness.js +253 -0
- package/dist/monorepo-onboarding.d.ts +51 -0
- package/dist/monorepo-onboarding.d.ts.map +1 -0
- package/dist/monorepo-onboarding.js +235 -0
- package/dist/onboarding-adoption-diff.d.ts +53 -0
- package/dist/onboarding-adoption-diff.d.ts.map +1 -0
- package/dist/onboarding-adoption-diff.js +285 -0
- package/dist/onboarding-adoption.d.ts +136 -0
- package/dist/onboarding-adoption.d.ts.map +1 -0
- package/dist/onboarding-adoption.js +702 -0
- package/dist/onboarding-agent-import.d.ts +40 -0
- package/dist/onboarding-agent-import.d.ts.map +1 -0
- package/dist/onboarding-agent-import.js +114 -0
- package/dist/onboarding-diff.d.ts +39 -0
- package/dist/onboarding-diff.d.ts.map +1 -0
- package/dist/onboarding-diff.js +240 -0
- package/dist/onboarding-drafts-merge.d.ts +71 -0
- package/dist/onboarding-drafts-merge.d.ts.map +1 -0
- package/dist/onboarding-drafts-merge.js +174 -0
- package/dist/onboarding-drafts.d.ts +42 -0
- package/dist/onboarding-drafts.d.ts.map +1 -0
- package/dist/onboarding-drafts.js +268 -0
- package/dist/onboarding-report.d.ts +8 -0
- package/dist/onboarding-report.d.ts.map +1 -0
- package/dist/onboarding-report.js +239 -0
- package/dist/onboarding.d.ts +134 -0
- package/dist/onboarding.d.ts.map +1 -0
- package/dist/onboarding.js +729 -0
- package/dist/ownership.d.ts +38 -0
- package/dist/ownership.d.ts.map +1 -0
- package/dist/ownership.js +102 -0
- package/dist/pack-author-ux.d.ts +58 -0
- package/dist/pack-author-ux.d.ts.map +1 -0
- package/dist/pack-author-ux.js +219 -0
- package/dist/pack-author.d.ts +94 -0
- package/dist/pack-author.d.ts.map +1 -0
- package/dist/pack-author.js +208 -0
- package/dist/pack-compatibility.d.ts +21 -0
- package/dist/pack-compatibility.d.ts.map +1 -0
- package/dist/pack-compatibility.js +114 -0
- package/dist/pack-contributions-inventory.d.ts +121 -0
- package/dist/pack-contributions-inventory.d.ts.map +1 -0
- package/dist/pack-contributions-inventory.js +732 -0
- package/dist/pack-docs.d.ts +11 -0
- package/dist/pack-docs.d.ts.map +1 -0
- package/dist/pack-docs.js +101 -0
- package/dist/pack-doctor.d.ts +50 -0
- package/dist/pack-doctor.d.ts.map +1 -0
- package/dist/pack-doctor.js +302 -0
- package/dist/pack-helper-registry.d.ts +29 -0
- package/dist/pack-helper-registry.d.ts.map +1 -0
- package/dist/pack-helper-registry.js +144 -0
- package/dist/pack-pending.d.ts +68 -0
- package/dist/pack-pending.d.ts.map +1 -0
- package/dist/pack-pending.js +189 -0
- package/dist/pack-quality-score.d.ts +44 -0
- package/dist/pack-quality-score.d.ts.map +1 -0
- package/dist/pack-quality-score.js +155 -0
- package/dist/pack-release-check.d.ts +24 -0
- package/dist/pack-release-check.d.ts.map +1 -0
- package/dist/pack-release-check.js +258 -0
- package/dist/pack-signature-status.d.ts +72 -0
- package/dist/pack-signature-status.d.ts.map +1 -0
- package/dist/pack-signature-status.js +222 -0
- package/dist/pack-symbol-compat.d.ts +73 -0
- package/dist/pack-symbol-compat.d.ts.map +1 -0
- package/dist/pack-symbol-compat.js +519 -0
- package/dist/pack-test-runner.d.ts +59 -0
- package/dist/pack-test-runner.d.ts.map +1 -0
- package/dist/pack-test-runner.js +211 -0
- package/dist/pipeline-command-dictionary.d.ts +2 -0
- package/dist/pipeline-command-dictionary.d.ts.map +1 -0
- package/dist/pipeline-command-dictionary.js +20 -0
- package/dist/pipeline-lint.d.ts +30 -0
- package/dist/pipeline-lint.d.ts.map +1 -0
- package/dist/pipeline-lint.js +134 -0
- package/dist/plan-dependency-graph.d.ts +25 -0
- package/dist/plan-dependency-graph.d.ts.map +1 -0
- package/dist/plan-dependency-graph.js +195 -0
- package/dist/plan-review.d.ts +64 -0
- package/dist/plan-review.d.ts.map +1 -0
- package/dist/plan-review.js +242 -0
- package/dist/plan-simulation.d.ts +108 -0
- package/dist/plan-simulation.d.ts.map +1 -0
- package/dist/plan-simulation.js +767 -0
- package/dist/playbook-registry.d.ts +25 -0
- package/dist/playbook-registry.d.ts.map +1 -0
- package/dist/playbook-registry.js +148 -0
- package/dist/playbook-script.d.ts +60 -0
- package/dist/playbook-script.d.ts.map +1 -0
- package/dist/playbook-script.js +161 -0
- package/dist/plugin-lifecycle-profile-registry.d.ts +52 -0
- package/dist/plugin-lifecycle-profile-registry.d.ts.map +1 -0
- package/dist/plugin-lifecycle-profile-registry.js +202 -0
- package/dist/plugin-lifecycle.d.ts +132 -0
- package/dist/plugin-lifecycle.d.ts.map +1 -0
- package/dist/plugin-lifecycle.js +477 -0
- package/dist/policy-engine.d.ts +101 -0
- package/dist/policy-engine.d.ts.map +1 -0
- package/dist/policy-engine.js +321 -0
- package/dist/policy-override-audit.d.ts +18 -0
- package/dist/policy-override-audit.d.ts.map +1 -0
- package/dist/policy-override-audit.js +54 -0
- package/dist/policy-overrides.d.ts +35 -0
- package/dist/policy-overrides.d.ts.map +1 -0
- package/dist/policy-overrides.js +84 -0
- package/dist/policy-test.d.ts +83 -0
- package/dist/policy-test.d.ts.map +1 -0
- package/dist/policy-test.js +342 -0
- package/dist/pr-summary.d.ts +34 -0
- package/dist/pr-summary.d.ts.map +1 -0
- package/dist/pr-summary.js +220 -0
- package/dist/product-coherence.d.ts +21 -0
- package/dist/product-coherence.d.ts.map +1 -0
- package/dist/product-coherence.js +158 -0
- package/dist/profile-registry.d.ts +42 -0
- package/dist/profile-registry.d.ts.map +1 -0
- package/dist/profile-registry.js +104 -0
- package/dist/project-coupling-audit.d.ts +64 -0
- package/dist/project-coupling-audit.d.ts.map +1 -0
- package/dist/project-coupling-audit.js +282 -0
- package/dist/project-overview.d.ts +14 -0
- package/dist/project-overview.d.ts.map +1 -0
- package/dist/project-overview.js +27 -0
- package/dist/propose-knowledge.d.ts +64 -0
- package/dist/propose-knowledge.d.ts.map +1 -0
- package/dist/propose-knowledge.js +367 -0
- package/dist/quality-baseline.d.ts +123 -0
- package/dist/quality-baseline.d.ts.map +1 -0
- package/dist/quality-baseline.js +433 -0
- package/dist/quality-html.d.ts +7 -0
- package/dist/quality-html.d.ts.map +1 -0
- package/dist/quality-html.js +64 -0
- package/dist/quality-report.d.ts +49 -0
- package/dist/quality-report.d.ts.map +1 -0
- package/dist/quality-report.js +296 -0
- package/dist/query-resolver.d.ts +38 -0
- package/dist/query-resolver.d.ts.map +1 -0
- package/dist/query-resolver.js +163 -0
- package/dist/ranker-explainability.d.ts +91 -0
- package/dist/ranker-explainability.d.ts.map +1 -0
- package/dist/ranker-explainability.js +550 -0
- package/dist/reference-lookup.d.ts +8 -0
- package/dist/reference-lookup.d.ts.map +1 -0
- package/dist/reference-lookup.js +18 -0
- package/dist/registration-hint-registry.d.ts +55 -0
- package/dist/registration-hint-registry.d.ts.map +1 -0
- package/dist/registration-hint-registry.js +327 -0
- package/dist/registry-lifecycle.d.ts +47 -0
- package/dist/registry-lifecycle.d.ts.map +1 -0
- package/dist/registry-lifecycle.js +214 -0
- package/dist/release-readiness.d.ts +64 -0
- package/dist/release-readiness.d.ts.map +1 -0
- package/dist/release-readiness.js +456 -0
- package/dist/release-smoke.d.ts +138 -0
- package/dist/release-smoke.d.ts.map +1 -0
- package/dist/release-smoke.js +459 -0
- package/dist/release-train.d.ts +33 -0
- package/dist/release-train.d.ts.map +1 -0
- package/dist/release-train.js +104 -0
- package/dist/repo-memory.d.ts +95 -0
- package/dist/repo-memory.d.ts.map +1 -0
- package/dist/repo-memory.js +614 -0
- package/dist/report-site.d.ts +92 -0
- package/dist/report-site.d.ts.map +1 -0
- package/dist/report-site.js +658 -0
- package/dist/reposet.d.ts +56 -0
- package/dist/reposet.d.ts.map +1 -0
- package/dist/reposet.js +160 -0
- package/dist/repository-intelligence.d.ts +145 -0
- package/dist/repository-intelligence.d.ts.map +1 -0
- package/dist/repository-intelligence.js +729 -0
- package/dist/repository-knowledge-model.d.ts +218 -0
- package/dist/repository-knowledge-model.d.ts.map +1 -0
- package/dist/repository-knowledge-model.js +939 -0
- package/dist/repository-map.d.ts +72 -0
- package/dist/repository-map.d.ts.map +1 -0
- package/dist/repository-map.js +332 -0
- package/dist/repository-stats.d.ts +66 -0
- package/dist/repository-stats.d.ts.map +1 -0
- package/dist/repository-stats.js +329 -0
- package/dist/review-comment-renderer.d.ts +59 -0
- package/dist/review-comment-renderer.d.ts.map +1 -0
- package/dist/review-comment-renderer.js +181 -0
- package/dist/review-comment-v2.d.ts +9 -0
- package/dist/review-comment-v2.d.ts.map +1 -0
- package/dist/review-comment-v2.js +178 -0
- package/dist/review-html.d.ts +13 -0
- package/dist/review-html.d.ts.map +1 -0
- package/dist/review-html.js +79 -0
- package/dist/review-packet-v2.d.ts +29 -0
- package/dist/review-packet-v2.d.ts.map +1 -0
- package/dist/review-packet-v2.js +81 -0
- package/dist/review-packet-v3.d.ts +22 -0
- package/dist/review-packet-v3.d.ts.map +1 -0
- package/dist/review-packet-v3.js +181 -0
- package/dist/review-packet.d.ts +49 -0
- package/dist/review-packet.d.ts.map +1 -0
- package/dist/review-packet.js +129 -0
- package/dist/risk-signals.d.ts +28 -0
- package/dist/risk-signals.d.ts.map +1 -0
- package/dist/risk-signals.js +68 -0
- package/dist/role-views.d.ts +50 -0
- package/dist/role-views.d.ts.map +1 -0
- package/dist/role-views.js +334 -0
- package/dist/rounds.d.ts +52 -0
- package/dist/rounds.d.ts.map +1 -0
- package/dist/rounds.js +172 -0
- package/dist/rule-drift.d.ts +42 -0
- package/dist/rule-drift.d.ts.map +1 -0
- package/dist/rule-drift.js +148 -0
- package/dist/rule-quality.d.ts +73 -0
- package/dist/rule-quality.d.ts.map +1 -0
- package/dist/rule-quality.js +356 -0
- package/dist/rule-scaffold.d.ts +71 -0
- package/dist/rule-scaffold.d.ts.map +1 -0
- package/dist/rule-scaffold.js +258 -0
- package/dist/safety-audit-deep.d.ts +38 -0
- package/dist/safety-audit-deep.d.ts.map +1 -0
- package/dist/safety-audit-deep.js +162 -0
- package/dist/safety-audit.d.ts +91 -0
- package/dist/safety-audit.d.ts.map +1 -0
- package/dist/safety-audit.js +138 -0
- package/dist/safety-html.d.ts +7 -0
- package/dist/safety-html.d.ts.map +1 -0
- package/dist/safety-html.js +70 -0
- package/dist/scaffold-coverage.d.ts +46 -0
- package/dist/scaffold-coverage.d.ts.map +1 -0
- package/dist/scaffold-coverage.js +273 -0
- package/dist/scaffold-patterns.d.ts +38 -0
- package/dist/scaffold-patterns.d.ts.map +1 -0
- package/dist/scaffold-patterns.js +282 -0
- package/dist/schema-inventory.d.ts +55 -0
- package/dist/schema-inventory.d.ts.map +1 -0
- package/dist/schema-inventory.js +301 -0
- package/dist/search-index.d.ts +75 -0
- package/dist/search-index.d.ts.map +1 -0
- package/dist/search-index.js +531 -0
- package/dist/search-tuning-explain.d.ts +68 -0
- package/dist/search-tuning-explain.d.ts.map +1 -0
- package/dist/search-tuning-explain.js +207 -0
- package/dist/search-tuning-registry.d.ts +54 -0
- package/dist/search-tuning-registry.d.ts.map +1 -0
- package/dist/search-tuning-registry.js +303 -0
- package/dist/self-audit.d.ts +59 -0
- package/dist/self-audit.d.ts.map +1 -0
- package/dist/self-audit.js +192 -0
- package/dist/self-config-doctor-v2.d.ts +57 -0
- package/dist/self-config-doctor-v2.d.ts.map +1 -0
- package/dist/self-config-doctor-v2.js +653 -0
- package/dist/self-config-doctor.d.ts +47 -0
- package/dist/self-config-doctor.d.ts.map +1 -0
- package/dist/self-config-doctor.js +432 -0
- package/dist/sharkcraft-inspector.d.ts +73 -0
- package/dist/sharkcraft-inspector.d.ts.map +1 -0
- package/dist/sharkcraft-inspector.js +745 -0
- package/dist/spec/spec-cross-validate.d.ts +17 -0
- package/dist/spec/spec-cross-validate.d.ts.map +1 -0
- package/dist/spec/spec-cross-validate.js +53 -0
- package/dist/spec/spec-discovery.d.ts +27 -0
- package/dist/spec/spec-discovery.d.ts.map +1 -0
- package/dist/spec/spec-discovery.js +78 -0
- package/dist/spec/spec-review.d.ts +36 -0
- package/dist/spec/spec-review.d.ts.map +1 -0
- package/dist/spec/spec-review.js +37 -0
- package/dist/stability-map.d.ts +62 -0
- package/dist/stability-map.d.ts.map +1 -0
- package/dist/stability-map.js +404 -0
- package/dist/start-here.d.ts +49 -0
- package/dist/start-here.d.ts.map +1 -0
- package/dist/start-here.js +259 -0
- package/dist/surface-profile-detect.d.ts +42 -0
- package/dist/surface-profile-detect.d.ts.map +1 -0
- package/dist/surface-profile-detect.js +76 -0
- package/dist/symbol-index.d.ts +108 -0
- package/dist/symbol-index.d.ts.map +1 -0
- package/dist/symbol-index.js +483 -0
- package/dist/task-decompose.d.ts +38 -0
- package/dist/task-decompose.d.ts.map +1 -0
- package/dist/task-decompose.js +154 -0
- package/dist/task-packet.d.ts +104 -0
- package/dist/task-packet.d.ts.map +1 -0
- package/dist/task-packet.js +156 -0
- package/dist/task-ranker.d.ts +51 -0
- package/dist/task-ranker.d.ts.map +1 -0
- package/dist/task-ranker.js +410 -0
- package/dist/task-risk.d.ts +84 -0
- package/dist/task-risk.d.ts.map +1 -0
- package/dist/task-risk.js +731 -0
- package/dist/task-routing-hint-registry.d.ts +36 -0
- package/dist/task-routing-hint-registry.d.ts.map +1 -0
- package/dist/task-routing-hint-registry.js +186 -0
- package/dist/template-authoring.d.ts +113 -0
- package/dist/template-authoring.d.ts.map +1 -0
- package/dist/template-authoring.js +521 -0
- package/dist/template-body-inference-v2.d.ts +19 -0
- package/dist/template-body-inference-v2.d.ts.map +1 -0
- package/dist/template-body-inference-v2.js +468 -0
- package/dist/template-body-inference.d.ts +59 -0
- package/dist/template-body-inference.d.ts.map +1 -0
- package/dist/template-body-inference.js +277 -0
- package/dist/template-drift.d.ts +39 -0
- package/dist/template-drift.d.ts.map +1 -0
- package/dist/template-drift.js +353 -0
- package/dist/template-lint.d.ts +31 -0
- package/dist/template-lint.d.ts.map +1 -0
- package/dist/template-lint.js +113 -0
- package/dist/test-definitions.d.ts +41 -0
- package/dist/test-definitions.d.ts.map +1 -0
- package/dist/test-definitions.js +6 -0
- package/dist/test-impact.d.ts +30 -0
- package/dist/test-impact.d.ts.map +1 -0
- package/dist/test-impact.js +173 -0
- package/dist/test-runner.d.ts +87 -0
- package/dist/test-runner.d.ts.map +1 -0
- package/dist/test-runner.js +560 -0
- package/dist/uncertainty-report.d.ts +46 -0
- package/dist/uncertainty-report.d.ts.map +1 -0
- package/dist/uncertainty-report.js +108 -0
- package/dist/uncertainty.d.ts +38 -0
- package/dist/uncertainty.d.ts.map +1 -0
- package/dist/uncertainty.js +115 -0
- package/dist/universal-search.d.ts +64 -0
- package/dist/universal-search.d.ts.map +1 -0
- package/dist/universal-search.js +347 -0
- package/dist/upgrade-advisor.d.ts +22 -0
- package/dist/upgrade-advisor.d.ts.map +1 -0
- package/dist/upgrade-advisor.js +109 -0
- package/dist/why-file.d.ts +75 -0
- package/dist/why-file.d.ts.map +1 -0
- package/dist/why-file.js +202 -0
- package/dist/workflow-simulation.d.ts +46 -0
- package/dist/workflow-simulation.d.ts.map +1 -0
- package/dist/workflow-simulation.js +154 -0
- package/package.json +65 -0
|
@@ -0,0 +1,892 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Knowledge stale-check.
|
|
3
|
+
*
|
|
4
|
+
* Walks every knowledge entry's `references[]` + `anchors[]` and checks
|
|
5
|
+
* whether each target still resolves against the current workspace.
|
|
6
|
+
*
|
|
7
|
+
* Pure file-system + registry lookups — no network, no AST compilation.
|
|
8
|
+
* Symbol checks are deterministic best-effort text scans so the doctor
|
|
9
|
+
* stays cheap.
|
|
10
|
+
*
|
|
11
|
+
* Schema: sharkcraft.knowledge-stale/v1
|
|
12
|
+
*/
|
|
13
|
+
import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';
|
|
14
|
+
import * as nodePath from 'node:path';
|
|
15
|
+
import { HELPERS } from "./helper-registry.js";
|
|
16
|
+
import { resolveSymbolInFile, SymbolResolution } from "./symbol-index.js";
|
|
17
|
+
export const KNOWLEDGE_STALE_SCHEMA = 'sharkcraft.knowledge-stale/v1';
|
|
18
|
+
export var ReferenceCheckOutcome;
|
|
19
|
+
(function (ReferenceCheckOutcome) {
|
|
20
|
+
ReferenceCheckOutcome["Ok"] = "ok";
|
|
21
|
+
ReferenceCheckOutcome["Stale"] = "stale";
|
|
22
|
+
ReferenceCheckOutcome["Missing"] = "missing";
|
|
23
|
+
ReferenceCheckOutcome["Unknown"] = "unknown";
|
|
24
|
+
})(ReferenceCheckOutcome || (ReferenceCheckOutcome = {}));
|
|
25
|
+
export var SymbolConfidence;
|
|
26
|
+
(function (SymbolConfidence) {
|
|
27
|
+
SymbolConfidence["Exact"] = "exact";
|
|
28
|
+
SymbolConfidence["Probable"] = "probable";
|
|
29
|
+
SymbolConfidence["Missing"] = "missing";
|
|
30
|
+
SymbolConfidence["Unknown"] = "unknown";
|
|
31
|
+
})(SymbolConfidence || (SymbolConfidence = {}));
|
|
32
|
+
/**
|
|
33
|
+
* Rename detection strategy.
|
|
34
|
+
*
|
|
35
|
+
* - `strict` (default): emit `replaceWith.path` only when there is
|
|
36
|
+
* exactly one unambiguous candidate.
|
|
37
|
+
* - `wide`: also surface multiple candidates above a confidence
|
|
38
|
+
* threshold. When one candidate is meaningfully ahead of the second,
|
|
39
|
+
* it still auto-applies; otherwise the candidate list is returned
|
|
40
|
+
* without `path` so the user can disambiguate manually.
|
|
41
|
+
*/
|
|
42
|
+
export var RenameStrategy;
|
|
43
|
+
(function (RenameStrategy) {
|
|
44
|
+
RenameStrategy["Strict"] = "strict";
|
|
45
|
+
RenameStrategy["Wide"] = "wide";
|
|
46
|
+
})(RenameStrategy || (RenameStrategy = {}));
|
|
47
|
+
/**
|
|
48
|
+
* Wide-mode score thresholds. Tuned so a single-segment overlap
|
|
49
|
+
* (e.g. `packages/foo/<basename>`) registers as plausible, but two
|
|
50
|
+
* shared segments are required for confident auto-apply.
|
|
51
|
+
*/
|
|
52
|
+
const WIDE_MIN_SCORE = 0.34;
|
|
53
|
+
const WIDE_STRONG_SCORE = 0.66;
|
|
54
|
+
const WIDE_LEAD_GAP = 0.2;
|
|
55
|
+
function fileExists(projectRoot, rel) {
|
|
56
|
+
return existsSync(nodePath.join(projectRoot, rel));
|
|
57
|
+
}
|
|
58
|
+
function dirExists(projectRoot, rel) {
|
|
59
|
+
const full = nodePath.join(projectRoot, rel);
|
|
60
|
+
try {
|
|
61
|
+
return statSync(full).isDirectory();
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
function commandExistsInInspection(inspection, id) {
|
|
68
|
+
// Both `shrk` commands and pack-contributed commands live on the
|
|
69
|
+
// inspection. We do a permissive lookup against the recommendation
|
|
70
|
+
// catalog if available.
|
|
71
|
+
const commands = inspection.commandCatalog;
|
|
72
|
+
if (Array.isArray(commands)) {
|
|
73
|
+
if (commands.some((c) => c.id === id))
|
|
74
|
+
return true;
|
|
75
|
+
}
|
|
76
|
+
// Fallback — accept anything that looks like a valid `shrk` command.
|
|
77
|
+
return id.startsWith('shrk ') || id.startsWith('bun ');
|
|
78
|
+
}
|
|
79
|
+
function templateExists(inspection, id) {
|
|
80
|
+
return inspection.templates.some((t) => t.id === id);
|
|
81
|
+
}
|
|
82
|
+
function playbookExists(inspection, id) {
|
|
83
|
+
const inspectionAny = inspection;
|
|
84
|
+
const reg = inspectionAny.playbookRegistry;
|
|
85
|
+
if (reg && typeof reg.list === 'function') {
|
|
86
|
+
return (reg.list() ?? []).some((p) => p.id === id);
|
|
87
|
+
}
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
function constructExists(inspection, id) {
|
|
91
|
+
const inspectionAny = inspection;
|
|
92
|
+
const reg = inspectionAny.constructRegistry;
|
|
93
|
+
if (reg && typeof reg.list === 'function') {
|
|
94
|
+
return (reg.list() ?? []).some((c) => c.id === id);
|
|
95
|
+
}
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
function helperExists(id) {
|
|
99
|
+
return HELPERS.some((h) => h.id === id);
|
|
100
|
+
}
|
|
101
|
+
function policyExists(inspection, id) {
|
|
102
|
+
const inspectionAny = inspection;
|
|
103
|
+
const checks = inspectionAny.policyChecks;
|
|
104
|
+
if (Array.isArray(checks))
|
|
105
|
+
return checks.some((c) => c.id === id);
|
|
106
|
+
return false;
|
|
107
|
+
}
|
|
108
|
+
function boundaryRuleExists(inspection, id) {
|
|
109
|
+
const reg = inspection.boundaryRegistry;
|
|
110
|
+
if (reg && typeof reg.list === 'function')
|
|
111
|
+
return reg.list().some((b) => b.id === id);
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
function pathConventionExists(inspection, id) {
|
|
115
|
+
const svc = inspection.pathService;
|
|
116
|
+
if (svc && typeof svc.list === 'function') {
|
|
117
|
+
return svc.list().some((p) => p.id === id);
|
|
118
|
+
}
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
121
|
+
function packageExists(inspection, id) {
|
|
122
|
+
// Project packages live under `packages/<name>` for SharkCraft + many
|
|
123
|
+
// monorepos. Trust the inspection's package map if available, else
|
|
124
|
+
// fall back to a filesystem check.
|
|
125
|
+
const pkgs = inspection.packages;
|
|
126
|
+
if (Array.isArray(pkgs)) {
|
|
127
|
+
if (pkgs.some((p) => p.name === id))
|
|
128
|
+
return true;
|
|
129
|
+
}
|
|
130
|
+
// file lookup as a backstop
|
|
131
|
+
const rel = id.startsWith('@') ? id.split('/')[1] ?? '' : id;
|
|
132
|
+
return dirExists(inspection.projectRoot, `packages/${rel}`);
|
|
133
|
+
}
|
|
134
|
+
function checkSymbolReference(projectRoot, ref) {
|
|
135
|
+
const sym = ref.symbol ?? '';
|
|
136
|
+
if (!sym) {
|
|
137
|
+
return {
|
|
138
|
+
outcome: ReferenceCheckOutcome.Unknown,
|
|
139
|
+
confidence: SymbolConfidence.Unknown,
|
|
140
|
+
message: 'Symbol reference has no `symbol` field.',
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
const file = ref.path ? nodePath.join(projectRoot, ref.path) : null;
|
|
144
|
+
if (file) {
|
|
145
|
+
if (!existsSync(file)) {
|
|
146
|
+
return {
|
|
147
|
+
outcome: ReferenceCheckOutcome.Missing,
|
|
148
|
+
confidence: SymbolConfidence.Missing,
|
|
149
|
+
message: `Referenced file does not exist: ${ref.path}`,
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
// AST-backed resolution (falls back to text-scan if parse fails).
|
|
153
|
+
try {
|
|
154
|
+
const res = resolveSymbolInFile(file, sym);
|
|
155
|
+
switch (res.resolution) {
|
|
156
|
+
case SymbolResolution.ExactExport:
|
|
157
|
+
return {
|
|
158
|
+
outcome: ReferenceCheckOutcome.Ok,
|
|
159
|
+
confidence: SymbolConfidence.Exact,
|
|
160
|
+
message: res.message,
|
|
161
|
+
};
|
|
162
|
+
case SymbolResolution.ExactLocal:
|
|
163
|
+
case SymbolResolution.ExactReExport:
|
|
164
|
+
return {
|
|
165
|
+
outcome: ReferenceCheckOutcome.Ok,
|
|
166
|
+
confidence: SymbolConfidence.Exact,
|
|
167
|
+
message: res.message,
|
|
168
|
+
};
|
|
169
|
+
case SymbolResolution.ProbableText:
|
|
170
|
+
return {
|
|
171
|
+
outcome: ReferenceCheckOutcome.Ok,
|
|
172
|
+
confidence: SymbolConfidence.Probable,
|
|
173
|
+
message: res.message,
|
|
174
|
+
};
|
|
175
|
+
case SymbolResolution.Missing:
|
|
176
|
+
return {
|
|
177
|
+
outcome: ReferenceCheckOutcome.Stale,
|
|
178
|
+
confidence: SymbolConfidence.Missing,
|
|
179
|
+
message: res.message,
|
|
180
|
+
};
|
|
181
|
+
default:
|
|
182
|
+
return {
|
|
183
|
+
outcome: ReferenceCheckOutcome.Unknown,
|
|
184
|
+
confidence: SymbolConfidence.Unknown,
|
|
185
|
+
message: res.message,
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
catch {
|
|
190
|
+
// Fallback to text scan.
|
|
191
|
+
try {
|
|
192
|
+
const text = readFileSync(file, 'utf8');
|
|
193
|
+
const declRe = new RegExp(`(export\\s+(?:async\\s+)?(?:function|class|interface|enum|type|const|let|var)\\s+|class\\s+|function\\s+)${escapeRe(sym)}\\b`);
|
|
194
|
+
if (declRe.test(text)) {
|
|
195
|
+
return {
|
|
196
|
+
outcome: ReferenceCheckOutcome.Ok,
|
|
197
|
+
confidence: SymbolConfidence.Exact,
|
|
198
|
+
message: `Found declaration of \`${sym}\` in ${ref.path}.`,
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
if (text.includes(sym)) {
|
|
202
|
+
return {
|
|
203
|
+
outcome: ReferenceCheckOutcome.Ok,
|
|
204
|
+
confidence: SymbolConfidence.Probable,
|
|
205
|
+
message: `\`${sym}\` appears in ${ref.path}, but not as an exported declaration.`,
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
return {
|
|
209
|
+
outcome: ReferenceCheckOutcome.Stale,
|
|
210
|
+
confidence: SymbolConfidence.Missing,
|
|
211
|
+
message: `Symbol \`${sym}\` not found in ${ref.path}.`,
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
catch {
|
|
215
|
+
return {
|
|
216
|
+
outcome: ReferenceCheckOutcome.Unknown,
|
|
217
|
+
confidence: SymbolConfidence.Unknown,
|
|
218
|
+
message: `Failed to read ${ref.path}.`,
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
// No file pinned — best-effort confidence is `unknown`.
|
|
224
|
+
return {
|
|
225
|
+
outcome: ReferenceCheckOutcome.Unknown,
|
|
226
|
+
confidence: SymbolConfidence.Unknown,
|
|
227
|
+
message: `Symbol reference \`${sym}\` has no file pin; stale-check cannot verify.`,
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
function escapeRe(s) {
|
|
231
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
232
|
+
}
|
|
233
|
+
function checkReference(inspection, ref) {
|
|
234
|
+
const projectRoot = inspection.projectRoot;
|
|
235
|
+
switch (ref.kind) {
|
|
236
|
+
case 'file': {
|
|
237
|
+
if (!ref.path)
|
|
238
|
+
return missingField('file', 'path');
|
|
239
|
+
if (fileExists(projectRoot, ref.path)) {
|
|
240
|
+
return { outcome: ReferenceCheckOutcome.Ok, message: `File exists: ${ref.path}` };
|
|
241
|
+
}
|
|
242
|
+
return staleFile(ref.path);
|
|
243
|
+
}
|
|
244
|
+
case 'directory': {
|
|
245
|
+
if (!ref.path)
|
|
246
|
+
return missingField('directory', 'path');
|
|
247
|
+
if (dirExists(projectRoot, ref.path)) {
|
|
248
|
+
return { outcome: ReferenceCheckOutcome.Ok, message: `Directory exists: ${ref.path}` };
|
|
249
|
+
}
|
|
250
|
+
return {
|
|
251
|
+
outcome: ReferenceCheckOutcome.Stale,
|
|
252
|
+
message: `Directory missing: ${ref.path}`,
|
|
253
|
+
suggestion: 'Move the directory or update the knowledge reference.',
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
case 'symbol': {
|
|
257
|
+
const r = checkSymbolReference(projectRoot, ref);
|
|
258
|
+
return r;
|
|
259
|
+
}
|
|
260
|
+
case 'command': {
|
|
261
|
+
const id = ref.id ?? ref.command ?? '';
|
|
262
|
+
if (!id)
|
|
263
|
+
return missingField('command', 'id or command');
|
|
264
|
+
if (commandExistsInInspection(inspection, id)) {
|
|
265
|
+
return { outcome: ReferenceCheckOutcome.Ok, message: `Command available: ${id}` };
|
|
266
|
+
}
|
|
267
|
+
return {
|
|
268
|
+
outcome: ReferenceCheckOutcome.Stale,
|
|
269
|
+
message: `Command not registered: ${id}`,
|
|
270
|
+
suggestion: 'Register the command in the command catalog or update the reference.',
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
case 'template': {
|
|
274
|
+
if (!ref.id)
|
|
275
|
+
return missingField('template', 'id');
|
|
276
|
+
if (templateExists(inspection, ref.id)) {
|
|
277
|
+
return { outcome: ReferenceCheckOutcome.Ok, message: `Template exists: ${ref.id}` };
|
|
278
|
+
}
|
|
279
|
+
return staleId('template', ref.id);
|
|
280
|
+
}
|
|
281
|
+
case 'playbook': {
|
|
282
|
+
if (!ref.id)
|
|
283
|
+
return missingField('playbook', 'id');
|
|
284
|
+
if (playbookExists(inspection, ref.id)) {
|
|
285
|
+
return { outcome: ReferenceCheckOutcome.Ok, message: `Playbook exists: ${ref.id}` };
|
|
286
|
+
}
|
|
287
|
+
return staleId('playbook', ref.id);
|
|
288
|
+
}
|
|
289
|
+
case 'construct': {
|
|
290
|
+
if (!ref.id)
|
|
291
|
+
return missingField('construct', 'id');
|
|
292
|
+
if (constructExists(inspection, ref.id)) {
|
|
293
|
+
return { outcome: ReferenceCheckOutcome.Ok, message: `Construct exists: ${ref.id}` };
|
|
294
|
+
}
|
|
295
|
+
return staleId('construct', ref.id);
|
|
296
|
+
}
|
|
297
|
+
case 'helper': {
|
|
298
|
+
if (!ref.id)
|
|
299
|
+
return missingField('helper', 'id');
|
|
300
|
+
if (helperExists(ref.id)) {
|
|
301
|
+
return { outcome: ReferenceCheckOutcome.Ok, message: `Helper exists: ${ref.id}` };
|
|
302
|
+
}
|
|
303
|
+
return staleId('helper', ref.id);
|
|
304
|
+
}
|
|
305
|
+
case 'policy': {
|
|
306
|
+
if (!ref.id)
|
|
307
|
+
return missingField('policy', 'id');
|
|
308
|
+
if (policyExists(inspection, ref.id)) {
|
|
309
|
+
return { outcome: ReferenceCheckOutcome.Ok, message: `Policy exists: ${ref.id}` };
|
|
310
|
+
}
|
|
311
|
+
return staleId('policy', ref.id);
|
|
312
|
+
}
|
|
313
|
+
case 'boundary-rule': {
|
|
314
|
+
if (!ref.id)
|
|
315
|
+
return missingField('boundary-rule', 'id');
|
|
316
|
+
if (boundaryRuleExists(inspection, ref.id)) {
|
|
317
|
+
return { outcome: ReferenceCheckOutcome.Ok, message: `Boundary rule exists: ${ref.id}` };
|
|
318
|
+
}
|
|
319
|
+
return staleId('boundary-rule', ref.id);
|
|
320
|
+
}
|
|
321
|
+
case 'path-convention': {
|
|
322
|
+
if (!ref.id)
|
|
323
|
+
return missingField('path-convention', 'id');
|
|
324
|
+
if (pathConventionExists(inspection, ref.id)) {
|
|
325
|
+
return { outcome: ReferenceCheckOutcome.Ok, message: `Path convention exists: ${ref.id}` };
|
|
326
|
+
}
|
|
327
|
+
return staleId('path-convention', ref.id);
|
|
328
|
+
}
|
|
329
|
+
case 'package': {
|
|
330
|
+
if (!ref.id)
|
|
331
|
+
return missingField('package', 'id');
|
|
332
|
+
if (packageExists(inspection, ref.id)) {
|
|
333
|
+
return { outcome: ReferenceCheckOutcome.Ok, message: `Package exists: ${ref.id}` };
|
|
334
|
+
}
|
|
335
|
+
return staleId('package', ref.id);
|
|
336
|
+
}
|
|
337
|
+
case 'url': {
|
|
338
|
+
// We never fetch URLs. Mark them unknown unless we can resolve to a
|
|
339
|
+
// local docs file.
|
|
340
|
+
return {
|
|
341
|
+
outcome: ReferenceCheckOutcome.Unknown,
|
|
342
|
+
message: 'URL references are not verified (no network).',
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
function missingField(kind, field) {
|
|
348
|
+
return {
|
|
349
|
+
outcome: ReferenceCheckOutcome.Unknown,
|
|
350
|
+
message: `${kind} reference missing required field: ${field}`,
|
|
351
|
+
};
|
|
352
|
+
}
|
|
353
|
+
function staleFile(rel) {
|
|
354
|
+
return {
|
|
355
|
+
outcome: ReferenceCheckOutcome.Stale,
|
|
356
|
+
message: `File missing: ${rel}`,
|
|
357
|
+
suggestion: 'Restore the file or run `shrk knowledge rename-file <old> <new> --dry-run`.',
|
|
358
|
+
};
|
|
359
|
+
}
|
|
360
|
+
function staleId(kind, id) {
|
|
361
|
+
return {
|
|
362
|
+
outcome: ReferenceCheckOutcome.Stale,
|
|
363
|
+
message: `${kind} not found: ${id}`,
|
|
364
|
+
suggestion: 'Register the target or remove the reference.',
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
function entryTouchesChangedFiles(entry, changed) {
|
|
368
|
+
if (changed.length === 0)
|
|
369
|
+
return true;
|
|
370
|
+
const changedSet = new Set(changed.map((c) => c.split(/[\\/]/).join('/')));
|
|
371
|
+
for (const ref of entry.references ?? []) {
|
|
372
|
+
if (ref.path && changedSet.has(ref.path.split(/[\\/]/).join('/')))
|
|
373
|
+
return true;
|
|
374
|
+
}
|
|
375
|
+
for (const anchor of entry.anchors ?? []) {
|
|
376
|
+
if (anchor.path && changedSet.has(anchor.path.split(/[\\/]/).join('/')))
|
|
377
|
+
return true;
|
|
378
|
+
}
|
|
379
|
+
return false;
|
|
380
|
+
}
|
|
381
|
+
export function buildKnowledgeStaleReport(inspection, options = {}) {
|
|
382
|
+
const strategy = options.renameStrategy ?? RenameStrategy.Strict;
|
|
383
|
+
const referenceChecks = [];
|
|
384
|
+
const anchorChecks = [];
|
|
385
|
+
const counts = { ok: 0, stale: 0, missing: 0, unknown: 0 };
|
|
386
|
+
let totalReferences = 0;
|
|
387
|
+
let totalAnchors = 0;
|
|
388
|
+
// Lazy symbol → file index, built on first stale-symbol need.
|
|
389
|
+
let symbolIndex = null;
|
|
390
|
+
const getSymbolIndex = () => {
|
|
391
|
+
if (symbolIndex)
|
|
392
|
+
return symbolIndex;
|
|
393
|
+
symbolIndex = buildSymbolFileIndex(inspection.projectRoot);
|
|
394
|
+
return symbolIndex;
|
|
395
|
+
};
|
|
396
|
+
// Lazy basename → file path index, used for file-rename detection.
|
|
397
|
+
let fileBasenameIndex = null;
|
|
398
|
+
const getFileBasenameIndex = () => {
|
|
399
|
+
if (fileBasenameIndex)
|
|
400
|
+
return fileBasenameIndex;
|
|
401
|
+
fileBasenameIndex = buildBasenameFileIndex(inspection.projectRoot);
|
|
402
|
+
return fileBasenameIndex;
|
|
403
|
+
};
|
|
404
|
+
// Lazy basename → directory path index, used for dir-rename detection.
|
|
405
|
+
let dirBasenameIndex = null;
|
|
406
|
+
const getDirBasenameIndex = () => {
|
|
407
|
+
if (dirBasenameIndex)
|
|
408
|
+
return dirBasenameIndex;
|
|
409
|
+
dirBasenameIndex = buildBasenameDirIndex(inspection.projectRoot);
|
|
410
|
+
return dirBasenameIndex;
|
|
411
|
+
};
|
|
412
|
+
for (const entry of inspection.knowledgeEntries) {
|
|
413
|
+
if (options.changedFiles && !entryTouchesChangedFiles(entry, options.changedFiles)) {
|
|
414
|
+
continue;
|
|
415
|
+
}
|
|
416
|
+
for (const ref of entry.references ?? []) {
|
|
417
|
+
totalReferences += 1;
|
|
418
|
+
const result = checkReference(inspection, ref);
|
|
419
|
+
const outcome = result.outcome;
|
|
420
|
+
if (outcome === ReferenceCheckOutcome.Ok)
|
|
421
|
+
counts.ok += 1;
|
|
422
|
+
else if (outcome === ReferenceCheckOutcome.Stale)
|
|
423
|
+
counts.stale += 1;
|
|
424
|
+
else if (outcome === ReferenceCheckOutcome.Missing)
|
|
425
|
+
counts.missing += 1;
|
|
426
|
+
else
|
|
427
|
+
counts.unknown += 1;
|
|
428
|
+
const check = {
|
|
429
|
+
entryId: entry.id,
|
|
430
|
+
reference: ref,
|
|
431
|
+
outcome,
|
|
432
|
+
message: result.message,
|
|
433
|
+
...(result.confidence ? { symbolConfidence: result.confidence } : {}),
|
|
434
|
+
...(result.suggestion ? { suggestion: result.suggestion } : {}),
|
|
435
|
+
};
|
|
436
|
+
const isStaleOrMissing = outcome === ReferenceCheckOutcome.Stale || outcome === ReferenceCheckOutcome.Missing;
|
|
437
|
+
// Symbol rename detection. Strict mode: emit `replaceWith.path`
|
|
438
|
+
// only for the single unambiguous candidate. Wide mode also
|
|
439
|
+
// emits scored candidate lists for the multi-candidate cases that
|
|
440
|
+
// strict silently drops.
|
|
441
|
+
if (isStaleOrMissing && ref.kind === 'symbol' && ref.symbol) {
|
|
442
|
+
const all = (getSymbolIndex().get(ref.symbol) ?? []).filter((p) => p !== ref.path);
|
|
443
|
+
if (all.length === 1) {
|
|
444
|
+
check.replaceWith = {
|
|
445
|
+
path: all[0],
|
|
446
|
+
rationale: `\`${ref.symbol}\` is exported from \`${all[0]}\` — sole candidate.`,
|
|
447
|
+
strategy: RenameStrategy.Strict,
|
|
448
|
+
};
|
|
449
|
+
}
|
|
450
|
+
else if (strategy === RenameStrategy.Wide && all.length > 1) {
|
|
451
|
+
check.replaceWith = buildWideReplacement({
|
|
452
|
+
stalePath: ref.path ?? '',
|
|
453
|
+
paths: all,
|
|
454
|
+
kindLabel: `symbol \`${ref.symbol}\``,
|
|
455
|
+
});
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
// File rename detection (directory move, basename match).
|
|
459
|
+
if (isStaleOrMissing && ref.kind === 'file' && ref.path && !check.replaceWith) {
|
|
460
|
+
const indexed = getFileBasenameIndex();
|
|
461
|
+
const uniq = pickUniqueRenameCandidate(ref.path, indexed);
|
|
462
|
+
if (uniq) {
|
|
463
|
+
check.replaceWith = {
|
|
464
|
+
path: uniq,
|
|
465
|
+
rationale: `File basename \`${nodePath.basename(ref.path)}\` resolves uniquely to \`${uniq}\` (likely directory rename).`,
|
|
466
|
+
strategy: RenameStrategy.Strict,
|
|
467
|
+
};
|
|
468
|
+
}
|
|
469
|
+
else if (strategy === RenameStrategy.Wide) {
|
|
470
|
+
const all = (indexed.get(nodePath.basename(ref.path)) ?? []).filter((p) => p !== ref.path);
|
|
471
|
+
if (all.length > 0) {
|
|
472
|
+
check.replaceWith = buildWideReplacement({
|
|
473
|
+
stalePath: ref.path,
|
|
474
|
+
paths: all,
|
|
475
|
+
kindLabel: `file \`${nodePath.basename(ref.path)}\``,
|
|
476
|
+
});
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
// Directory rename detection.
|
|
481
|
+
if (isStaleOrMissing && ref.kind === 'directory' && ref.path && !check.replaceWith) {
|
|
482
|
+
const indexed = getDirBasenameIndex();
|
|
483
|
+
const uniq = pickUniqueRenameCandidate(ref.path, indexed);
|
|
484
|
+
if (uniq) {
|
|
485
|
+
check.replaceWith = {
|
|
486
|
+
path: uniq,
|
|
487
|
+
rationale: `Directory basename \`${nodePath.basename(ref.path)}\` resolves uniquely to \`${uniq}\`.`,
|
|
488
|
+
strategy: RenameStrategy.Strict,
|
|
489
|
+
};
|
|
490
|
+
}
|
|
491
|
+
else if (strategy === RenameStrategy.Wide) {
|
|
492
|
+
const all = (indexed.get(nodePath.basename(ref.path)) ?? []).filter((p) => p !== ref.path);
|
|
493
|
+
if (all.length > 0) {
|
|
494
|
+
check.replaceWith = buildWideReplacement({
|
|
495
|
+
stalePath: ref.path,
|
|
496
|
+
paths: all,
|
|
497
|
+
kindLabel: `directory \`${nodePath.basename(ref.path)}\``,
|
|
498
|
+
});
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
referenceChecks.push(check);
|
|
503
|
+
}
|
|
504
|
+
for (const anchor of entry.anchors ?? []) {
|
|
505
|
+
totalAnchors += 1;
|
|
506
|
+
const inspected = checkAnchor(inspection, anchor);
|
|
507
|
+
anchorChecks.push({
|
|
508
|
+
entryId: entry.id,
|
|
509
|
+
anchor,
|
|
510
|
+
outcome: inspected.outcome,
|
|
511
|
+
message: inspected.message,
|
|
512
|
+
});
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
// Content-similarity boost: when multiple wide replacements in the
|
|
516
|
+
// SAME entry name the same candidate path, raise that candidate's score
|
|
517
|
+
// for each occurrence. Captures the "directory was moved, all files
|
|
518
|
+
// followed" case where a single per-reference signal is weak but the
|
|
519
|
+
// aggregate is strong.
|
|
520
|
+
applyEntryCorroborationBoost(referenceChecks);
|
|
521
|
+
return {
|
|
522
|
+
schema: KNOWLEDGE_STALE_SCHEMA,
|
|
523
|
+
entries: inspection.knowledgeEntries.length,
|
|
524
|
+
totalReferences,
|
|
525
|
+
totalAnchors,
|
|
526
|
+
counts,
|
|
527
|
+
referenceChecks,
|
|
528
|
+
anchorChecks,
|
|
529
|
+
};
|
|
530
|
+
}
|
|
531
|
+
/**
|
|
532
|
+
* Score a list of candidate paths against the stale path by shared
|
|
533
|
+
* parent-directory segments. Normalises score into [0, 1] by the number
|
|
534
|
+
* of non-trivial segments in the stale path.
|
|
535
|
+
*/
|
|
536
|
+
function scoreByPathOverlap(stalePath, candidate) {
|
|
537
|
+
const normalise = (s) => s
|
|
538
|
+
.split(/[\\/]/)
|
|
539
|
+
.map((p) => p.trim())
|
|
540
|
+
.filter((p) => p.length > 0 && p !== '.');
|
|
541
|
+
const staleSegs = normalise(stalePath);
|
|
542
|
+
const staleBasename = staleSegs.length > 0 ? staleSegs[staleSegs.length - 1] : '';
|
|
543
|
+
const candSegs = normalise(candidate);
|
|
544
|
+
const staleDirs = new Set(staleSegs.filter((s) => s !== staleBasename));
|
|
545
|
+
let overlap = 0;
|
|
546
|
+
for (const s of candSegs) {
|
|
547
|
+
if (s === staleBasename)
|
|
548
|
+
continue;
|
|
549
|
+
if (staleDirs.has(s))
|
|
550
|
+
overlap += 1;
|
|
551
|
+
}
|
|
552
|
+
const denom = Math.max(staleDirs.size, 1);
|
|
553
|
+
return Math.min(1, overlap / denom);
|
|
554
|
+
}
|
|
555
|
+
function buildWideReplacement(args) {
|
|
556
|
+
const scored = args.paths
|
|
557
|
+
.map((p) => ({
|
|
558
|
+
path: p,
|
|
559
|
+
score: scoreByPathOverlap(args.stalePath, p),
|
|
560
|
+
rationale: `Path-overlap score ${scoreByPathOverlap(args.stalePath, p).toFixed(2)} vs stale \`${args.stalePath}\`.`,
|
|
561
|
+
}))
|
|
562
|
+
.filter((c) => c.score >= WIDE_MIN_SCORE)
|
|
563
|
+
.sort((a, b) => b.score - a.score);
|
|
564
|
+
if (scored.length === 0) {
|
|
565
|
+
return {
|
|
566
|
+
rationale: `Wide search for ${args.kindLabel} found ${args.paths.length} candidates, none above score threshold ${WIDE_MIN_SCORE}.`,
|
|
567
|
+
candidates: [],
|
|
568
|
+
strategy: RenameStrategy.Wide,
|
|
569
|
+
};
|
|
570
|
+
}
|
|
571
|
+
const top = scored[0];
|
|
572
|
+
const second = scored[1];
|
|
573
|
+
const clearWinner = top.score >= WIDE_STRONG_SCORE && (!second || top.score - second.score >= WIDE_LEAD_GAP);
|
|
574
|
+
if (clearWinner) {
|
|
575
|
+
return {
|
|
576
|
+
path: top.path,
|
|
577
|
+
rationale: `Wide auto-select: ${args.kindLabel} → ${top.path} (score ${top.score.toFixed(2)}, lead ${second ? (top.score - second.score).toFixed(2) : '∞'}).`,
|
|
578
|
+
candidates: scored,
|
|
579
|
+
strategy: RenameStrategy.Wide,
|
|
580
|
+
};
|
|
581
|
+
}
|
|
582
|
+
return {
|
|
583
|
+
rationale: `Wide search for ${args.kindLabel} surfaced ${scored.length} candidates; none clearly leads. Disambiguate manually.`,
|
|
584
|
+
candidates: scored,
|
|
585
|
+
strategy: RenameStrategy.Wide,
|
|
586
|
+
};
|
|
587
|
+
}
|
|
588
|
+
function applyEntryCorroborationBoost(checks) {
|
|
589
|
+
const byEntry = new Map();
|
|
590
|
+
for (const c of checks) {
|
|
591
|
+
if (!c.replaceWith?.candidates || c.replaceWith.candidates.length === 0)
|
|
592
|
+
continue;
|
|
593
|
+
let bucket = byEntry.get(c.entryId);
|
|
594
|
+
if (!bucket) {
|
|
595
|
+
bucket = [];
|
|
596
|
+
byEntry.set(c.entryId, bucket);
|
|
597
|
+
}
|
|
598
|
+
bucket.push(c);
|
|
599
|
+
}
|
|
600
|
+
for (const bucket of byEntry.values()) {
|
|
601
|
+
if (bucket.length < 2)
|
|
602
|
+
continue;
|
|
603
|
+
const pathCounts = new Map();
|
|
604
|
+
for (const c of bucket) {
|
|
605
|
+
for (const cand of c.replaceWith.candidates) {
|
|
606
|
+
if (!cand.path)
|
|
607
|
+
continue;
|
|
608
|
+
pathCounts.set(cand.path, (pathCounts.get(cand.path) ?? 0) + 1);
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
for (const c of bucket) {
|
|
612
|
+
const candidates = c.replaceWith.candidates ?? [];
|
|
613
|
+
const boosted = candidates
|
|
614
|
+
.map((cand) => {
|
|
615
|
+
if (!cand.path)
|
|
616
|
+
return cand;
|
|
617
|
+
const count = pathCounts.get(cand.path) ?? 0;
|
|
618
|
+
if (count < 2)
|
|
619
|
+
return cand;
|
|
620
|
+
const bumped = Math.min(1, cand.score + 0.15 * (count - 1));
|
|
621
|
+
return {
|
|
622
|
+
...cand,
|
|
623
|
+
score: bumped,
|
|
624
|
+
rationale: `${cand.rationale} (+entry-corroboration ×${count - 1})`,
|
|
625
|
+
};
|
|
626
|
+
})
|
|
627
|
+
.sort((a, b) => b.score - a.score);
|
|
628
|
+
const top = boosted[0];
|
|
629
|
+
const second = boosted[1];
|
|
630
|
+
const promote = top &&
|
|
631
|
+
top.path &&
|
|
632
|
+
top.score >= WIDE_STRONG_SCORE &&
|
|
633
|
+
(!second || top.score - second.score >= WIDE_LEAD_GAP);
|
|
634
|
+
c.replaceWith = {
|
|
635
|
+
...c.replaceWith,
|
|
636
|
+
candidates: boosted,
|
|
637
|
+
...(promote
|
|
638
|
+
? {
|
|
639
|
+
path: top.path,
|
|
640
|
+
rationale: `Wide + corroboration auto-select: ${top.path} (score ${top.score.toFixed(2)}).`,
|
|
641
|
+
}
|
|
642
|
+
: {}),
|
|
643
|
+
};
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
/**
|
|
648
|
+
* Build a `symbol-name → [files...]` index by scanning TS
|
|
649
|
+
* sources for top-level `export ... <symbol>` declarations.
|
|
650
|
+
*
|
|
651
|
+
* Pure regex scan (no AST). Designed to be cheap enough to run once
|
|
652
|
+
* per inspection — bounded by the number of TS files under
|
|
653
|
+
* `packages/` (the only reliable source roots in SharkCraft
|
|
654
|
+
* today). Skips `node_modules`, `dist`, `.sharkcraft`, and `*.d.ts`.
|
|
655
|
+
*
|
|
656
|
+
* Returns paths relative to `projectRoot` so they're directly
|
|
657
|
+
* pasteable into a `references[]` entry.
|
|
658
|
+
*/
|
|
659
|
+
function buildSymbolFileIndex(projectRoot) {
|
|
660
|
+
const index = new Map();
|
|
661
|
+
// Bounded BFS over known source roots. We explicitly stay out of
|
|
662
|
+
// node_modules / dist / .sharkcraft / examples / tools to avoid
|
|
663
|
+
// exploding the scan over the workspace.
|
|
664
|
+
const roots = ['packages'];
|
|
665
|
+
for (const root of roots) {
|
|
666
|
+
const abs = nodePath.join(projectRoot, root);
|
|
667
|
+
if (!existsSync(abs))
|
|
668
|
+
continue;
|
|
669
|
+
walkForSymbols(abs, projectRoot, index);
|
|
670
|
+
}
|
|
671
|
+
const out = new Map();
|
|
672
|
+
for (const [k, v] of index)
|
|
673
|
+
out.set(k, [...v]);
|
|
674
|
+
return out;
|
|
675
|
+
}
|
|
676
|
+
/**
|
|
677
|
+
* Build a `basename → [relative file paths...]` index over the same
|
|
678
|
+
* source roots `buildSymbolFileIndex` covers. Used to detect file
|
|
679
|
+
* renames (the common case when a directory is moved).
|
|
680
|
+
*/
|
|
681
|
+
function buildBasenameFileIndex(projectRoot) {
|
|
682
|
+
const index = new Map();
|
|
683
|
+
for (const root of ['packages', 'sharkcraft', 'docs', 'examples']) {
|
|
684
|
+
const abs = nodePath.join(projectRoot, root);
|
|
685
|
+
if (!existsSync(abs))
|
|
686
|
+
continue;
|
|
687
|
+
walkForBasenames(abs, projectRoot, index, /* dirs */ false);
|
|
688
|
+
}
|
|
689
|
+
const out = new Map();
|
|
690
|
+
for (const [k, v] of index)
|
|
691
|
+
out.set(k, [...v]);
|
|
692
|
+
return out;
|
|
693
|
+
}
|
|
694
|
+
/**
|
|
695
|
+
* Build a `basename → [relative directory paths...]` index over
|
|
696
|
+
* the same source roots. Used to detect directory renames.
|
|
697
|
+
*/
|
|
698
|
+
function buildBasenameDirIndex(projectRoot) {
|
|
699
|
+
const index = new Map();
|
|
700
|
+
for (const root of ['packages', 'sharkcraft', 'docs', 'examples']) {
|
|
701
|
+
const abs = nodePath.join(projectRoot, root);
|
|
702
|
+
if (!existsSync(abs))
|
|
703
|
+
continue;
|
|
704
|
+
walkForBasenames(abs, projectRoot, index, /* dirs */ true);
|
|
705
|
+
}
|
|
706
|
+
const out = new Map();
|
|
707
|
+
for (const [k, v] of index)
|
|
708
|
+
out.set(k, [...v]);
|
|
709
|
+
return out;
|
|
710
|
+
}
|
|
711
|
+
function walkForBasenames(dir, projectRoot, out, collectDirs) {
|
|
712
|
+
let entries;
|
|
713
|
+
try {
|
|
714
|
+
entries = readdirSync(dir);
|
|
715
|
+
}
|
|
716
|
+
catch {
|
|
717
|
+
return;
|
|
718
|
+
}
|
|
719
|
+
for (const e of entries) {
|
|
720
|
+
if (e === 'node_modules' || e === 'dist' || e === '.sharkcraft' || e.startsWith('.'))
|
|
721
|
+
continue;
|
|
722
|
+
const full = nodePath.join(dir, e);
|
|
723
|
+
let st;
|
|
724
|
+
try {
|
|
725
|
+
st = statSync(full);
|
|
726
|
+
}
|
|
727
|
+
catch {
|
|
728
|
+
continue;
|
|
729
|
+
}
|
|
730
|
+
const rel = nodePath.relative(projectRoot, full);
|
|
731
|
+
if (st.isDirectory()) {
|
|
732
|
+
if (collectDirs) {
|
|
733
|
+
const key = e;
|
|
734
|
+
let list = out.get(key);
|
|
735
|
+
if (!list) {
|
|
736
|
+
list = [];
|
|
737
|
+
out.set(key, list);
|
|
738
|
+
}
|
|
739
|
+
if (!list.includes(rel))
|
|
740
|
+
list.push(rel);
|
|
741
|
+
}
|
|
742
|
+
if (e === '__tests__' || e === 'fixtures')
|
|
743
|
+
continue;
|
|
744
|
+
walkForBasenames(full, projectRoot, out, collectDirs);
|
|
745
|
+
}
|
|
746
|
+
else if (st.isFile() && !collectDirs) {
|
|
747
|
+
// Skip auto-generated noise.
|
|
748
|
+
if (e.endsWith('.d.ts'))
|
|
749
|
+
continue;
|
|
750
|
+
const key = e;
|
|
751
|
+
let list = out.get(key);
|
|
752
|
+
if (!list) {
|
|
753
|
+
list = [];
|
|
754
|
+
out.set(key, list);
|
|
755
|
+
}
|
|
756
|
+
if (!list.includes(rel))
|
|
757
|
+
list.push(rel);
|
|
758
|
+
}
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
/**
|
|
762
|
+
* Given a stale reference path and a basename → candidates index,
|
|
763
|
+
* return a unique candidate iff:
|
|
764
|
+
* 1. The basename exists in the index.
|
|
765
|
+
* 2. Exactly one candidate matches.
|
|
766
|
+
* 3. That candidate is not the same path as the stale one.
|
|
767
|
+
* 4. The candidate shares ≥1 non-trivial parent-directory segment with
|
|
768
|
+
* the stale path (so we don't propose unrelated namesakes).
|
|
769
|
+
*/
|
|
770
|
+
function pickUniqueRenameCandidate(stalePath, index) {
|
|
771
|
+
const norm = stalePath.split(/[\\/]/).join('/').replace(/^\.\//, '');
|
|
772
|
+
const basename = nodePath.basename(norm);
|
|
773
|
+
if (!basename)
|
|
774
|
+
return null;
|
|
775
|
+
const candidates = (index.get(basename) ?? []).filter((c) => c !== norm);
|
|
776
|
+
if (candidates.length !== 1)
|
|
777
|
+
return null;
|
|
778
|
+
const candidate = candidates[0];
|
|
779
|
+
const staleSegments = new Set(norm.split('/').filter((s) => s.length > 0 && s !== basename));
|
|
780
|
+
const candidateSegments = candidate.split('/').filter((s) => s.length > 0 && s !== basename);
|
|
781
|
+
let overlap = 0;
|
|
782
|
+
for (const seg of candidateSegments) {
|
|
783
|
+
if (staleSegments.has(seg))
|
|
784
|
+
overlap++;
|
|
785
|
+
}
|
|
786
|
+
if (overlap < 1)
|
|
787
|
+
return null;
|
|
788
|
+
return candidate;
|
|
789
|
+
}
|
|
790
|
+
function walkForSymbols(dir, projectRoot, out) {
|
|
791
|
+
let entries;
|
|
792
|
+
try {
|
|
793
|
+
entries = readdirSync(dir);
|
|
794
|
+
}
|
|
795
|
+
catch {
|
|
796
|
+
return;
|
|
797
|
+
}
|
|
798
|
+
for (const e of entries) {
|
|
799
|
+
if (e === 'node_modules' || e === 'dist' || e === '.sharkcraft' || e.startsWith('.'))
|
|
800
|
+
continue;
|
|
801
|
+
const full = nodePath.join(dir, e);
|
|
802
|
+
let st;
|
|
803
|
+
try {
|
|
804
|
+
st = statSync(full);
|
|
805
|
+
}
|
|
806
|
+
catch {
|
|
807
|
+
continue;
|
|
808
|
+
}
|
|
809
|
+
if (st.isDirectory()) {
|
|
810
|
+
if (e === '__tests__' || e === 'fixtures')
|
|
811
|
+
continue;
|
|
812
|
+
walkForSymbols(full, projectRoot, out);
|
|
813
|
+
continue;
|
|
814
|
+
}
|
|
815
|
+
if (!st.isFile())
|
|
816
|
+
continue;
|
|
817
|
+
if (!/\.(ts|tsx)$/.test(e) || e.endsWith('.d.ts') || e.endsWith('.test.ts'))
|
|
818
|
+
continue;
|
|
819
|
+
let text;
|
|
820
|
+
try {
|
|
821
|
+
text = readFileSync(full, 'utf8');
|
|
822
|
+
}
|
|
823
|
+
catch {
|
|
824
|
+
continue;
|
|
825
|
+
}
|
|
826
|
+
const re = /^export\s+(?:async\s+)?(?:function|class|interface|enum|type|const|let|var)\s+([A-Z_a-z][A-Z_a-z0-9]*)\b/gm;
|
|
827
|
+
let m;
|
|
828
|
+
const rel = nodePath.relative(projectRoot, full);
|
|
829
|
+
while ((m = re.exec(text)) !== null) {
|
|
830
|
+
const name = m[1];
|
|
831
|
+
let list = out.get(name);
|
|
832
|
+
if (!list) {
|
|
833
|
+
list = [];
|
|
834
|
+
out.set(name, list);
|
|
835
|
+
}
|
|
836
|
+
if (!list.includes(rel))
|
|
837
|
+
list.push(rel);
|
|
838
|
+
}
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
function checkAnchor(inspection, anchor) {
|
|
842
|
+
switch (anchor.kind) {
|
|
843
|
+
case 'file':
|
|
844
|
+
if (!anchor.path) {
|
|
845
|
+
return { outcome: ReferenceCheckOutcome.Unknown, message: 'anchor has no path' };
|
|
846
|
+
}
|
|
847
|
+
if (fileExists(inspection.projectRoot, anchor.path)) {
|
|
848
|
+
return { outcome: ReferenceCheckOutcome.Ok, message: `anchor file exists: ${anchor.path}` };
|
|
849
|
+
}
|
|
850
|
+
return { outcome: ReferenceCheckOutcome.Stale, message: `anchor file missing: ${anchor.path}` };
|
|
851
|
+
case 'symbol':
|
|
852
|
+
return checkSymbolAnchor(inspection, anchor);
|
|
853
|
+
case 'command':
|
|
854
|
+
if (anchor.targetId && commandExistsInInspection(inspection, anchor.targetId)) {
|
|
855
|
+
return { outcome: ReferenceCheckOutcome.Ok, message: `command exists: ${anchor.targetId}` };
|
|
856
|
+
}
|
|
857
|
+
return { outcome: ReferenceCheckOutcome.Stale, message: `command anchor unresolved: ${anchor.targetId ?? '?'}` };
|
|
858
|
+
case 'construct':
|
|
859
|
+
if (anchor.targetId && constructExists(inspection, anchor.targetId)) {
|
|
860
|
+
return { outcome: ReferenceCheckOutcome.Ok, message: `construct exists: ${anchor.targetId}` };
|
|
861
|
+
}
|
|
862
|
+
return { outcome: ReferenceCheckOutcome.Stale, message: `construct anchor unresolved: ${anchor.targetId ?? '?'}` };
|
|
863
|
+
case 'template':
|
|
864
|
+
if (anchor.targetId && templateExists(inspection, anchor.targetId)) {
|
|
865
|
+
return { outcome: ReferenceCheckOutcome.Ok, message: `template exists: ${anchor.targetId}` };
|
|
866
|
+
}
|
|
867
|
+
return { outcome: ReferenceCheckOutcome.Stale, message: `template anchor unresolved: ${anchor.targetId ?? '?'}` };
|
|
868
|
+
case 'helper':
|
|
869
|
+
if (anchor.targetId && helperExists(anchor.targetId)) {
|
|
870
|
+
return { outcome: ReferenceCheckOutcome.Ok, message: `helper exists: ${anchor.targetId}` };
|
|
871
|
+
}
|
|
872
|
+
return { outcome: ReferenceCheckOutcome.Stale, message: `helper anchor unresolved: ${anchor.targetId ?? '?'}` };
|
|
873
|
+
case 'playbook':
|
|
874
|
+
if (anchor.targetId && playbookExists(inspection, anchor.targetId)) {
|
|
875
|
+
return { outcome: ReferenceCheckOutcome.Ok, message: `playbook exists: ${anchor.targetId}` };
|
|
876
|
+
}
|
|
877
|
+
return { outcome: ReferenceCheckOutcome.Stale, message: `playbook anchor unresolved: ${anchor.targetId ?? '?'}` };
|
|
878
|
+
case 'policy':
|
|
879
|
+
if (anchor.targetId && policyExists(inspection, anchor.targetId)) {
|
|
880
|
+
return { outcome: ReferenceCheckOutcome.Ok, message: `policy exists: ${anchor.targetId}` };
|
|
881
|
+
}
|
|
882
|
+
return { outcome: ReferenceCheckOutcome.Stale, message: `policy anchor unresolved: ${anchor.targetId ?? '?'}` };
|
|
883
|
+
}
|
|
884
|
+
}
|
|
885
|
+
function checkSymbolAnchor(inspection, anchor) {
|
|
886
|
+
const r = checkSymbolReference(inspection.projectRoot, {
|
|
887
|
+
kind: 'symbol',
|
|
888
|
+
symbol: anchor.symbol,
|
|
889
|
+
...(anchor.path ? { path: anchor.path } : {}),
|
|
890
|
+
});
|
|
891
|
+
return { outcome: r.outcome, message: r.message };
|
|
892
|
+
}
|