@event4u/agent-config 14.12.0 → 14.14.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/.augment-plugin/marketplace.json +3 -3
- package/.augment-plugin/plugin.json +1 -1
- package/.claude-plugin/marketplace.json +1 -1
- package/CHANGELOG.md +118 -155
- package/CONTRIBUTING.md +38 -0
- package/CREDITS.md +135 -0
- package/NOTICE +13 -0
- package/README.md +8 -6
- package/dist/agent-src/commands/analyze/inbox.md +145 -2
- package/dist/agent-src/commands/feature/dev.md +7 -2
- package/dist/agent-src/commands/ghostwriter/write.md +5 -1
- package/dist/agent-src/commands/implement-ticket.md +1 -1
- package/dist/agent-src/commands/mission/upgrade.md +1 -1
- package/dist/agent-src/commands/orchestrate.md +2 -2
- package/dist/agent-src/commands/post-as/me.md +5 -1
- package/dist/agent-src/commands/pr/merge.md +19 -6
- package/dist/agent-src/commands/roadmap/process-full.md +19 -5
- package/dist/agent-src/commands/tdd/red.md +12 -2
- package/dist/agent-src/commands/work.md +1 -1
- package/dist/agent-src/contexts/communication/rules-auto/token-efficiency-mechanics.md +40 -0
- package/dist/agent-src/contexts/execution/auto-dispatch-classification.md +5 -2
- package/dist/agent-src/contexts/execution/autonomy-mechanics.md +21 -0
- package/dist/agent-src/contexts/execution/orchestration-telemetry.md +1 -0
- package/dist/agent-src/contexts/execution/subagent-response-contract.md +40 -0
- package/dist/agent-src/contexts/execution/subagent-steering.md +13 -1
- package/dist/agent-src/contexts/execution/terminal-states.md +96 -0
- package/dist/agent-src/rules/artifact-drafting-protocol.md +1 -1
- package/dist/agent-src/rules/broken-access-control.md +4 -0
- package/dist/agent-src/rules/code-comment-discipline.md +6 -0
- package/dist/agent-src/rules/code-provenance.md +4 -0
- package/dist/agent-src/rules/design-fidelity.md +1 -1
- package/dist/agent-src/rules/domain-safety-pii.md +4 -0
- package/dist/agent-src/rules/domain-safety-retention.md +4 -0
- package/dist/agent-src/rules/engineering-safety-floor.md +2 -0
- package/dist/agent-src/rules/external-code-graph-interop.md +14 -12
- package/dist/agent-src/rules/improve-before-implement.md +6 -8
- package/dist/agent-src/rules/laravel-routing.md +1 -1
- package/dist/agent-src/rules/lethal-trifecta-guard.md +4 -0
- package/dist/agent-src/rules/secret-vcs-guard.md +2 -0
- package/dist/agent-src/rules/security-sensitive-stop.md +2 -0
- package/dist/agent-src/rules/source-confidentiality.md +12 -34
- package/dist/agent-src/rules/symfony-routing.md +1 -1
- package/dist/agent-src/rules/token-efficiency.md +14 -0
- package/dist/agent-src/rules/tool-safety.md +4 -0
- package/dist/agent-src/rules/untrusted-input-defense.md +4 -0
- package/dist/agent-src/scripts/archive_completed_roadmaps.ts +252 -8
- package/dist/agent-src/scripts/guarded_baseline.ts +343 -0
- package/dist/agent-src/scripts/roadmap_set_step.ts +253 -0
- package/dist/agent-src/scripts/stub_queue.ts +82 -0
- package/dist/agent-src/scripts/stubs_due.ts +516 -0
- package/dist/agent-src/scripts/ticket_bundles.ts +84 -0
- package/dist/agent-src/scripts/update_roadmap_progress.ts +16 -12
- package/dist/agent-src/skills/brand-asset-generation/SKILL.md +17 -4
- package/dist/agent-src/skills/brand-audit/SKILL.md +33 -0
- package/dist/agent-src/skills/code-intelligence/SKILL.md +57 -0
- package/dist/agent-src/skills/database/SKILL.md +8 -0
- package/dist/agent-src/skills/dependency-upgrade/SKILL.md +27 -0
- package/dist/agent-src/skills/design-review/SKILL.md +1 -1
- package/dist/agent-src/skills/doc-coauthoring/SKILL.md +1 -1
- package/dist/agent-src/skills/existing-ui-audit/SKILL.md +17 -1
- package/dist/agent-src/skills/feature-planning/SKILL.md +9 -2
- package/dist/agent-src/skills/frontend-render-security/SKILL.md +44 -0
- package/dist/agent-src/skills/git-workflow/SKILL.md +1 -1
- package/dist/agent-src/skills/js-library-packaging/scripts/check_package_surface.ts +38 -4
- package/dist/agent-src/skills/judge-artifact-completeness/rubrics/ticket-quality-score.json +2 -2
- package/dist/agent-src/skills/laravel/SKILL.md +35 -0
- package/dist/agent-src/skills/laravel-migration/SKILL.md +57 -3
- package/dist/agent-src/skills/monorepo-workspace/SKILL.md +26 -0
- package/dist/agent-src/skills/playbook-authoring/SKILL.md +28 -1
- package/dist/agent-src/skills/react-shadcn-ui/SKILL.md +1 -1
- package/dist/agent-src/skills/skill-writing/references/procedure.md +5 -5
- package/dist/agent-src/skills/sql-writing/SKILL.md +7 -1
- package/dist/agent-src/skills/standards-from-config/SKILL.md +27 -4
- package/dist/agent-src/skills/supply-chain-intake/SKILL.md +11 -4
- package/dist/agent-src/skills/symfony-workflow/SKILL.md +35 -0
- package/dist/agent-src/skills/test-case-discovery/SKILL.md +85 -0
- package/dist/agent-src/skills/test-driven-development/SKILL.md +33 -9
- package/dist/agent-src/skills/testing-anti-patterns/SKILL.md +1 -1
- package/dist/agent-src/skills/testing-anti-patterns/process-anti-patterns.md +37 -0
- package/dist/agent-src/skills/ui-component-architect/SKILL.md +45 -2
- package/dist/agent-src/skills/upstream-contribute/SKILL.md +38 -1
- package/dist/agent-src/skills/verify-repair-loop/SKILL.md +9 -4
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
- package/dist/agent-src/templates/roadmaps.md +97 -3
- package/dist/agent-src/templates/scripts/check_memory.ts +258 -17
- package/dist/agent-src/templates/scripts/check_memory_proposal.ts +9 -3
- package/dist/agent-src/templates/scripts/memory_lookup.ts +86 -0
- package/dist/agent-src/templates/scripts/memory_signal.ts +44 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/backend/implement.ts +90 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/backend/index.ts +11 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/backend/test.ts +23 -1
- package/dist/agent-src/templates/scripts/work_engine/directives/backend/verify.ts +10 -1
- package/dist/agent-src/templates/scripts/work_engine/directives/mixed/stitch.ts +5 -1
- package/dist/agent-src/templates/scripts/work_engine/stack/runner.ts +102 -14
- package/dist/cli/commands/uiAudit.js +124 -5
- package/dist/cli/registry.js +2 -0
- package/dist/cli-delegate/{chunk-HYWSRNUX.js → chunk-2DK2VJWG.js} +3 -3
- package/dist/cli-delegate/{chunk-JCW7ZLHK.js → chunk-4FS4WRXP.js} +5 -0
- package/dist/cli-delegate/{chunk-OMIVVCG2.js → chunk-A4QJ6ENT.js} +24 -0
- package/dist/cli-delegate/{chunk-JJA2QEWA.js → chunk-AKJGUQNO.js} +466 -285
- package/dist/cli-delegate/{chunk-E46KPN6K.js → chunk-BTWUYDGN.js} +424 -363
- package/dist/cli-delegate/{chunk-K4FFODTS.js → chunk-ILMUPLGW.js} +1227 -316
- package/dist/cli-delegate/{chunk-FF7WAFMR.js → chunk-KPBWFOPZ.js} +5 -1
- package/dist/cli-delegate/cmd_adr_effective.js +102 -0
- package/dist/cli-delegate/cmd_conformance.js +80 -11
- package/dist/cli-delegate/cmd_doctor.js +3 -3
- package/dist/cli-delegate/cmd_export.js +3 -2
- package/dist/cli-delegate/cmd_fleet.js +2 -2
- package/dist/cli-delegate/cmd_handoff.js +1 -1
- package/dist/cli-delegate/cmd_preflight.js +2 -2
- package/dist/cli-delegate/cmd_prune.js +3 -2
- package/dist/cli-delegate/cmd_settings_get.js +1 -1
- package/dist/cli-delegate/cmd_settings_migrate.js +3 -2
- package/dist/cli-delegate/cmd_settings_set.js +2 -2
- package/dist/cli-delegate/cmd_sync.js +3 -2
- package/dist/cli-delegate/cmd_uninstall.js +3 -2
- package/dist/cli-delegate/cmd_validate.js +3 -2
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +58 -58
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +1 -1
- package/dist/discovery/dormancy-report.md +1 -1
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +2 -2
- package/dist/discovery/trust-report.md +1 -1
- package/dist/discovery/workspaces.json +2 -2
- package/dist/hooks/dispatch.js +2900 -1049
- package/dist/install/claudeRuleRewrite.js +254 -0
- package/dist/install/detect.js +29 -16
- package/dist/install/detect_php_shape.js +159 -0
- package/dist/install/install.mjs +634 -428
- package/dist/mcp/awesome-mcp-servers.row.md +1 -1
- package/dist/mcp/mcp-cloudflare-catalogue.json +1 -1
- package/dist/mcp/registry-manifest.json +3 -3
- package/dist/mcp/server.json +3 -3
- package/dist/mcp/server.mjs +4895 -2627
- package/dist/server/schemas/settings.js +3 -0
- package/dist/ui/assets/index-D0jaCRPM.js +29 -0
- package/dist/ui/index.html +1 -1
- package/docs/MIGRATION.md +1 -1
- package/docs/THIRD-PARTY-NOTICES.md +25 -0
- package/docs/contracts/provider-lifecycle.md +1 -1
- package/docs/contracts/settings-classes.md +10 -4
- package/docs/guidelines/agent-infra/5w2h-analysis.md +3 -3
- package/docs/guidelines/agent-infra/agent-interaction-and-decision-quality.md +1 -0
- package/docs/guidelines/agent-infra/artifact-drafting-protocol-mechanics.md +58 -3
- package/docs/guidelines/agent-infra/ask-when-uncertain-demos.md +2 -2
- package/docs/guidelines/agent-infra/asking-and-brevity-examples.md +3 -3
- package/docs/guidelines/agent-infra/break-glass-usage.md +7 -7
- package/docs/guidelines/agent-infra/carve-out-predicates.md +3 -3
- package/docs/guidelines/agent-infra/comparison-matrix.md +1 -1
- package/docs/guidelines/agent-infra/critical-thinking.md +4 -4
- package/docs/guidelines/agent-infra/direct-answers-demos.md +2 -2
- package/docs/guidelines/agent-infra/domain-eval-anti-pattern.md +1 -1
- package/docs/guidelines/agent-infra/engineering-memory-data-format.md +3 -3
- package/docs/guidelines/agent-infra/existence-question-verdicts.md +80 -0
- package/docs/guidelines/agent-infra/first-principles.md +2 -2
- package/docs/guidelines/agent-infra/framework-neutrality-patterns.md +2 -2
- package/docs/guidelines/agent-infra/guarded-baseline.md +39 -0
- package/docs/guidelines/agent-infra/inversion-thinking.md +5 -5
- package/docs/guidelines/agent-infra/language-and-tone-examples.md +1 -1
- package/docs/guidelines/agent-infra/layered-settings.md +10 -10
- package/docs/guidelines/agent-infra/memory-access.md +1 -1
- package/docs/guidelines/agent-infra/mental-models.md +3 -3
- package/docs/guidelines/agent-infra/reuse-verdict-mechanics.md +71 -0
- package/docs/guidelines/agent-infra/review-routing-data-format.md +7 -7
- package/docs/guidelines/agent-infra/roadmap-progress-mechanics.md +13 -7
- package/docs/guidelines/agent-infra/role-contracts.md +2 -2
- package/docs/guidelines/agent-infra/role-mode-router.md +3 -3
- package/docs/guidelines/agent-infra/rule-type-governance.md +2 -2
- package/docs/guidelines/agent-infra/scqa-framework.md +5 -5
- package/docs/guidelines/agent-infra/self-improvement-pipeline.md +6 -6
- package/docs/guidelines/agent-infra/simplicity-and-goal-demos.md +2 -2
- package/docs/guidelines/agent-infra/six-hats.md +3 -3
- package/docs/guidelines/agent-infra/skill-quality-checklist.md +6 -6
- package/docs/guidelines/agent-infra/source-confidentiality-mechanics.md +109 -0
- package/docs/guidelines/agent-infra/systems-thinking.md +1 -1
- package/docs/guidelines/agent-infra/verify-before-complete-demos.md +2 -2
- package/docs/guidelines/augment-portability-patterns.md +6 -4
- package/docs/guidelines/code-clarity.md +18 -0
- package/docs/guidelines/component-oriented-and-oop-development.md +3 -2
- package/docs/guidelines/cross-role-handoff.md +2 -2
- package/docs/guidelines/design-fidelity-mechanics.md +1 -1
- package/docs/guidelines/docs/readme-size-and-splitting.md +3 -3
- package/docs/guidelines/php/database.md +90 -7
- package/docs/guidelines/prompt-templates.md +7 -7
- package/llms.txt +2 -2
- package/package.json +5 -2
- package/src/agent-src/scripts/archive_completed_roadmaps.ts +252 -8
- package/src/agent-src/scripts/guarded_baseline.ts +343 -0
- package/src/agent-src/scripts/roadmap_set_step.ts +253 -0
- package/src/agent-src/scripts/stub_queue.ts +82 -0
- package/src/agent-src/scripts/stubs_due.ts +516 -0
- package/src/agent-src/scripts/ticket_bundles.ts +84 -0
- package/src/agent-src/scripts/update_roadmap_progress.ts +16 -12
- package/src/agent-src/templates/scripts/check_memory.ts +258 -17
- package/src/agent-src/templates/scripts/check_memory_proposal.ts +9 -3
- package/src/agent-src/templates/scripts/memory_lookup.ts +86 -0
- package/src/agent-src/templates/scripts/memory_signal.ts +44 -0
- package/src/agent-src/templates/scripts/work_engine/directives/backend/implement.ts +90 -0
- package/src/agent-src/templates/scripts/work_engine/directives/backend/index.ts +11 -0
- package/src/agent-src/templates/scripts/work_engine/directives/backend/test.ts +23 -1
- package/src/agent-src/templates/scripts/work_engine/directives/backend/verify.ts +10 -1
- package/src/agent-src/templates/scripts/work_engine/directives/mixed/stitch.ts +5 -1
- package/src/agent-src/templates/scripts/work_engine/stack/runner.ts +102 -14
- package/src/config/agent-settings.template.yml +32 -3
- package/src/config/assurance-capability-registry.json +21 -9
- package/src/config/canonical-terms.yml +119 -0
- package/src/config/capability-native-outcome-bars.json +81 -0
- package/src/config/ci-local-parity.yml +80 -0
- package/src/config/drafting-channels.yml +43 -0
- package/src/config/estate-count-budget.json +57 -36
- package/src/config/evaluator-budgets.json +14 -14
- package/src/config/gate-coverage.yml +729 -63
- package/src/config/gate-reachability-exemptions.json +21 -0
- package/src/config/gate-violation-baselines.json +42 -19
- package/src/config/harness-evolution-budget.json +25 -0
- package/src/config/lapsed-beta-baseline.json +96 -0
- package/src/config/memory-twin-verdicts.yml +129 -0
- package/src/config/metric-registry.yml +124 -0
- package/src/config/pack-size-budget.json +16 -15
- package/src/config/preamble-payload-budget.json +12 -4
- package/src/config/profiles/balanced.ini +27 -0
- package/src/config/profiles/full.ini +27 -0
- package/src/config/profiles/minimal.ini +27 -0
- package/src/config/publish-surface.json +9 -2
- package/src/config/routing-coverage-seed.json +16 -2
- package/src/config/rule-stub-ceilings.json +133 -112
- package/src/config/turnaround-budget.json +66 -0
- package/src/install/claudeRuleRewrite.ts +288 -0
- package/src/install/detect.ts +60 -17
- package/src/install/detect_php_shape.ts +191 -0
- package/src/scripts/_cli/cmd_doctor.ts +27 -112
- package/src/scripts/_dispatch.bash +23 -0
- package/src/scripts/_lib/activation_ladder.ts +255 -0
- package/src/scripts/_lib/activation_receipt_producer.ts +341 -0
- package/src/scripts/_lib/activation_states.ts +88 -0
- package/src/scripts/_lib/adherence_detectors.ts +143 -0
- package/src/scripts/_lib/adr_frontmatter.ts +26 -0
- package/src/scripts/_lib/arith_claims.ts +181 -0
- package/src/scripts/_lib/arm_ranking.ts +62 -0
- package/src/scripts/_lib/asset_delivery_ledger.ts +303 -0
- package/src/scripts/_lib/audit_field_provenance.ts +54 -0
- package/src/scripts/_lib/auto_dispatch.ts +32 -3
- package/src/scripts/_lib/bench_ab_size_claim.ts +98 -4
- package/src/scripts/_lib/benchmark_cache_fields.ts +158 -0
- package/src/scripts/_lib/candidate_pair_delta.ts +349 -0
- package/src/scripts/_lib/candidate_proposer.ts +402 -0
- package/src/scripts/_lib/candidate_record.ts +601 -0
- package/src/scripts/_lib/capture_rate.ts +319 -0
- package/src/scripts/_lib/carrier_status.ts +118 -0
- package/src/scripts/_lib/cascade_stage_enumeration.ts +92 -0
- package/src/scripts/_lib/collector_denominator.ts +771 -0
- package/src/scripts/_lib/collector_record.ts +340 -0
- package/src/scripts/_lib/collector_store.ts +664 -0
- package/src/scripts/_lib/collector_supervision.ts +827 -0
- package/src/scripts/_lib/concern_estate.ts +77 -0
- package/src/scripts/_lib/config_chain.ts +477 -0
- package/src/scripts/_lib/config_cost.ts +209 -0
- package/src/scripts/_lib/corpus_manifest.ts +726 -0
- package/src/scripts/_lib/council_settings_block.ts +6 -0
- package/src/scripts/_lib/curator_ops.ts +172 -0
- package/src/scripts/_lib/delivery_arm_experiment.ts +282 -0
- package/src/scripts/_lib/delivery_criticality.ts +126 -0
- package/src/scripts/_lib/doctor_runtime_checks.ts +70 -0
- package/src/scripts/_lib/empty_cycles.ts +88 -0
- package/src/scripts/_lib/estate_carrier_cases.ts +72 -0
- package/src/scripts/_lib/eval_publication.ts +354 -0
- package/src/scripts/_lib/evaluation_cascade.ts +452 -0
- package/src/scripts/_lib/evaluation_vector.ts +283 -0
- package/src/scripts/_lib/evaluator_promotion.ts +225 -0
- package/src/scripts/_lib/evidence_basis.ts +118 -0
- package/src/scripts/_lib/evolution_roi.ts +562 -0
- package/src/scripts/_lib/exec_evidence.ts +8 -0
- package/src/scripts/_lib/experience_card.ts +272 -0
- package/src/scripts/_lib/experience_report.ts +151 -0
- package/src/scripts/_lib/experiment_freeze.ts +112 -0
- package/src/scripts/_lib/generated_by.ts +66 -0
- package/src/scripts/_lib/harness_evolution_guards.ts +239 -0
- package/src/scripts/_lib/hook_effect_probe.ts +141 -0
- package/src/scripts/_lib/host_denominator.ts +687 -0
- package/src/scripts/_lib/host_projection_reach.ts +157 -0
- package/src/scripts/_lib/ignored_blocker.ts +148 -0
- package/src/scripts/_lib/install_reach_checks.ts +495 -0
- package/src/scripts/_lib/json_duplicate_keys.ts +150 -0
- package/src/scripts/_lib/judge_hygiene.ts +228 -0
- package/src/scripts/_lib/legacy_boundary_map.ts +228 -0
- package/src/scripts/_lib/lexical_shortlist.ts +215 -0
- package/src/scripts/_lib/llm_candidate_proposer.ts +461 -0
- package/src/scripts/_lib/llm_proposer_transport.ts +153 -0
- package/src/scripts/_lib/loop_guards.ts +299 -0
- package/src/scripts/_lib/loss_class.ts +129 -0
- package/src/scripts/_lib/machine_wake.ts +51 -0
- package/src/scripts/_lib/md_prose_lines.ts +177 -0
- package/src/scripts/_lib/minimality_tiebreak.ts +168 -0
- package/src/scripts/_lib/one_resolver_invariant.ts +449 -0
- package/src/scripts/_lib/orchestration_record.ts +253 -5
- package/src/scripts/_lib/outcome_envelope.ts +227 -0
- package/src/scripts/_lib/outcome_vocabularies.ts +125 -0
- package/src/scripts/_lib/paired_stats.ts +245 -0
- package/src/scripts/_lib/paired_verdict.ts +226 -0
- package/src/scripts/_lib/pathology_archive.ts +393 -0
- package/src/scripts/_lib/prefix_stable_surfaces.ts +123 -0
- package/src/scripts/_lib/privacy_class.ts +47 -0
- package/src/scripts/_lib/promotion_capability.ts +315 -0
- package/src/scripts/_lib/promotion_evidence.ts +414 -0
- package/src/scripts/_lib/promotion_review.ts +294 -0
- package/src/scripts/_lib/prompt_shape.ts +92 -0
- package/src/scripts/_lib/regression_neighbourhood.ts +259 -0
- package/src/scripts/_lib/release_highlights.ts +70 -1
- package/src/scripts/_lib/release_material.ts +125 -2
- package/src/scripts/_lib/repeated_failure.ts +105 -0
- package/src/scripts/_lib/repo_root.ts +111 -0
- package/src/scripts/_lib/review_skipped_record.ts +37 -0
- package/src/scripts/_lib/role_split.ts +338 -0
- package/src/scripts/_lib/routing_corpus.ts +307 -0
- package/src/scripts/_lib/routing_index_input.ts +104 -0
- package/src/scripts/_lib/rule_injection.ts +22 -1
- package/src/scripts/_lib/runtime_journal.ts +1499 -0
- package/src/scripts/_lib/runtime_wiring_checks.ts +430 -0
- package/src/scripts/_lib/semantic_noop.ts +167 -0
- package/src/scripts/_lib/skill_catalogue.ts +11 -1
- package/src/scripts/_lib/source_digest.ts +200 -0
- package/src/scripts/_lib/source_redact.ts +260 -0
- package/src/scripts/_lib/source_shape.ts +502 -0
- package/src/scripts/_lib/source_snapshot_dedup.ts +199 -0
- package/src/scripts/_lib/strip_comments.d.mts +8 -0
- package/src/scripts/_lib/strip_comments.mjs +65 -0
- package/src/scripts/_lib/test_red_state.ts +154 -0
- package/src/scripts/_lib/trigger_shift.ts +144 -0
- package/src/scripts/_lib/untrusted_content.ts +82 -7
- package/src/scripts/activation_receipt.ts +258 -0
- package/src/scripts/adoption_report.ts +1 -1
- package/src/scripts/adr/evidence_census.ts +1 -1
- package/src/scripts/adr/regenerate_index.ts +26 -2
- package/src/scripts/adr_cite_check.ts +164 -1
- package/src/scripts/ai_council/blind_review.ts +11 -1
- package/src/scripts/ai_council/clients.ts +4 -0
- package/src/scripts/ai_council/config.ts +3 -0
- package/src/scripts/ai_council/consensus.ts +28 -8
- package/src/scripts/ai_council/consensus_round.ts +226 -0
- package/src/scripts/ai_council/cross_exam.ts +128 -0
- package/src/scripts/ai_council/disagreement_signal.ts +338 -0
- package/src/scripts/ai_council/explain_route.ts +157 -0
- package/src/scripts/ai_council/information_gain.ts +293 -0
- package/src/scripts/ai_council/inline_findings.ts +340 -0
- package/src/scripts/ai_council/judge_position_bias.ts +197 -0
- package/src/scripts/ai_council/leakage_corpus.ts +385 -0
- package/src/scripts/ai_council/leakage_patterns.ts +453 -0
- package/src/scripts/ai_council/minority_retention.ts +171 -0
- package/src/scripts/ai_council/orchestrator.ts +16 -203
- package/src/scripts/ai_council/orchestrator_results.ts +23 -3
- package/src/scripts/ai_council/pricing.ts +106 -0
- package/src/scripts/ai_council/prompts.ts +74 -7
- package/src/scripts/ai_council/provider_leakage_bench.ts +327 -0
- package/src/scripts/ai_council/py_format.ts +14 -3
- package/src/scripts/ai_council/recouncil_guard.ts +293 -0
- package/src/scripts/ai_council/recouncil_savings.ts +299 -0
- package/src/scripts/ai_council/replay_route.ts +223 -0
- package/src/scripts/ai_council/response_record.ts +50 -0
- package/src/scripts/ai_council/reviewer_assignment.ts +279 -0
- package/src/scripts/ai_council/routing_training_row.ts +197 -0
- package/src/scripts/ai_council/synthesis_strategy.ts +159 -0
- package/src/scripts/ai_council/topology_bench_manifest.ts +860 -0
- package/src/scripts/ai_council/topology_vocabulary.ts +175 -0
- package/src/scripts/asset_delivery_ledger.ts +157 -0
- package/src/scripts/attest_artifact.ts +193 -0
- package/src/scripts/audit_auto_rules.ts +2 -1
- package/src/scripts/audit_command_surface.ts +1 -1
- package/src/scripts/audit_mcp_tools.ts +2 -2
- package/src/scripts/audit_skill_overlap_allowlist.json +6 -1
- package/src/scripts/audit_user_type_axis.ts +2 -1
- package/src/scripts/bench_ab_clone.ts +215 -10
- package/src/scripts/bench_ab_integrity.ts +119 -5
- package/src/scripts/bench_ab_v2_stats.ts +40 -213
- package/src/scripts/build_archive_index.ts +1 -1
- package/src/scripts/build_linear_digest.ts +1 -1
- package/src/scripts/build_proof.ts +11 -4
- package/src/scripts/build_rule_trigger_matrix.ts +1 -1
- package/src/scripts/build_source_digests.ts +157 -0
- package/src/scripts/cache_realization_report.ts +103 -0
- package/src/scripts/check_adr_frontmatter.ts +131 -10
- package/src/scripts/check_benchmark_report_fields.ts +207 -0
- package/src/scripts/check_beta_review_markers.ts +235 -6
- package/src/scripts/check_bundle_path_leakage.ts +34 -1
- package/src/scripts/check_claims.ts +576 -6
- package/src/scripts/check_composite_arming.ts +35 -0
- package/src/scripts/check_concern_admissions.ts +365 -0
- package/src/scripts/check_enforcement_coverage.ts +28 -0
- package/src/scripts/check_estate_count.ts +347 -25
- package/src/scripts/check_gate_reachability.ts +383 -0
- package/src/scripts/check_host_loadability.ts +104 -0
- package/src/scripts/check_loss_class_declared.ts +308 -0
- package/src/scripts/check_md_language.ts +15 -98
- package/src/scripts/check_memory_proposal.ts +18 -11
- package/src/scripts/check_no_currency_in_cost_surfaces.ts +225 -0
- package/src/scripts/check_no_external_sources.ts +281 -6
- package/src/scripts/check_pack_conformance_fixture.ts +11 -1
- package/src/scripts/check_pack_size.ts +59 -2
- package/src/scripts/check_preamble_payload_budget.ts +114 -3
- package/src/scripts/check_prefix_stable_mutation.ts +372 -0
- package/src/scripts/check_publish_surface.ts +10 -1
- package/src/scripts/check_references.ts +24 -1
- package/src/scripts/check_release_highlights.ts +96 -13
- package/src/scripts/check_roadmap_trackable.ts +17 -2
- package/src/scripts/check_rule_evidence_declaration.ts +316 -0
- package/src/scripts/check_rule_projection_integrity.ts +14 -4
- package/src/scripts/check_score_contract.ts +26 -3
- package/src/scripts/check_static_parity.ts +285 -0
- package/src/scripts/check_supervision_claim_atomicity.ts +498 -0
- package/src/scripts/check_suppression_hygiene.ts +15 -0
- package/src/scripts/ci_settle.ts +39 -2
- package/src/scripts/code_graph/build.ts +60 -3
- package/src/scripts/code_graph/extract.ts +44 -0
- package/src/scripts/code_graph/types.ts +24 -0
- package/src/scripts/collector_daemon.ts +714 -0
- package/src/scripts/config_cost_report.ts +302 -0
- package/src/scripts/consumer_matrix.ts +74 -1
- package/src/scripts/corpus_manifest.ts +235 -0
- package/src/scripts/cost/budget.mjs +10 -3
- package/src/scripts/cost/track.mjs +10 -3
- package/src/scripts/council_cli.ts +37 -54
- package/src/scripts/dispatch_r2_reviewer.ts +46 -5
- package/src/scripts/evolution_lab.ts +1153 -0
- package/src/scripts/external_sources_denylist.json +5 -18
- package/src/scripts/extract_audit_patterns.ts +21 -0
- package/src/scripts/fold_intake.ts +12 -1
- package/src/scripts/gen_discovery_baseline.ts +1 -1
- package/src/scripts/generate_capabilities_index.ts +12 -5
- package/src/scripts/generate_capability_matrix.ts +3 -3
- package/src/scripts/generate_command_flows.ts +2 -2
- package/src/scripts/generate_cookbook.ts +2 -2
- package/src/scripts/generate_index.ts +8 -1
- package/src/scripts/generate_knowledge_index.ts +2 -1
- package/src/scripts/generate_ownership_matrix.ts +2 -1
- package/src/scripts/generate_pack_manifests.ts +10 -2
- package/src/scripts/generate_role_experiences_catalog.ts +2 -2
- package/src/scripts/generate_settings_reference.ts +1 -1
- package/src/scripts/git_authorization_hook.ts +22 -1
- package/src/scripts/grade_target_readiness.ts +48 -5
- package/src/scripts/hook_effect_doctor.ts +261 -0
- package/src/scripts/hook_manifest.json +1 -1
- package/src/scripts/hook_manifest.yaml +125 -16
- package/src/scripts/hooks/block_speaking_inbox_dir.ts +271 -0
- package/src/scripts/hooks/block_unauthorized_git.ts +18 -0
- package/src/scripts/hooks/comment_discipline_hook.ts +146 -0
- package/src/scripts/hooks/concern_registry.ts +6 -0
- package/src/scripts/hooks/dispatch_hook.ts +32 -0
- package/src/scripts/hooks/journal_record_hook.ts +345 -0
- package/src/scripts/hooks/prepush_metadata_sources.sh +110 -0
- package/src/scripts/hooks/run_continuation_hook.ts +44 -9
- package/src/scripts/hooks/shims/install.sh +61 -0
- package/src/scripts/hooks/shims/php +101 -0
- package/src/scripts/hooks/suggestion_capture_hook.ts +10 -0
- package/src/scripts/hooks/turn_end_gate_hook.ts +9 -1
- package/src/scripts/hot_context_hook.ts +16 -0
- package/src/scripts/install-hooks.sh +20 -5
- package/src/scripts/install.ts +17 -35
- package/src/scripts/inventory_frontmatter.ts +2 -1
- package/src/scripts/language_mirror_hook.ts +14 -2
- package/src/scripts/lint_adr_sweep_routing.ts +12 -0
- package/src/scripts/lint_canonical_terms.ts +604 -0
- package/src/scripts/lint_carrier_integrity.ts +820 -0
- package/src/scripts/lint_code_comments.ts +643 -0
- package/src/scripts/lint_composition_review.ts +619 -0
- package/src/scripts/lint_consolidation_lineage.ts +666 -0
- package/src/scripts/lint_eval_specs.ts +593 -0
- package/src/scripts/lint_hook_manifest.ts +19 -0
- package/src/scripts/lint_host_portability.ts +373 -0
- package/src/scripts/lint_judge_prompt_expectation.ts +27 -1
- package/src/scripts/lint_memory_twin_parity.ts +335 -0
- package/src/scripts/lint_metric_consumers.ts +355 -0
- package/src/scripts/lint_plan_risk_register.ts +39 -19
- package/src/scripts/lint_promotion_paths.ts +779 -0
- package/src/scripts/lint_skill_descriptions.ts +18 -1
- package/src/scripts/lint_skill_frontmatter_safety.ts +58 -0
- package/src/scripts/lint_skill_link_reach.ts +252 -0
- package/src/scripts/lint_skill_trigger_corpus.ts +426 -23
- package/src/scripts/lint_ticket_buildable.ts +17 -1
- package/src/scripts/llm_propose.ts +256 -0
- package/src/scripts/mcp_server/consumer_tool_catalog.json +1 -1
- package/src/scripts/mcp_server/tool_catalog_source.ts +1 -1
- package/src/scripts/measure_delivery_sets.ts +361 -0
- package/src/scripts/measure_docs_dead_links.ts +348 -0
- package/src/scripts/measure_host_capture.ts +461 -0
- package/src/scripts/measure_routing_signal.ts +307 -0
- package/src/scripts/migration_status.ts +3 -3
- package/src/scripts/model_rule_injection.ts +76 -0
- package/src/scripts/orchestration_record.ts +14 -0
- package/src/scripts/preamble_byte_census.ts +139 -10
- package/src/scripts/prepack-check.mjs +4 -1
- package/src/scripts/probe_council_retention.ts +495 -0
- package/src/scripts/probe_turnaround.ts +384 -0
- package/src/scripts/probe_unblocked_ask.ts +279 -0
- package/src/scripts/release.ts +21 -37
- package/src/scripts/release_drill.ts +143 -0
- package/src/scripts/release_env.ts +35 -0
- package/src/scripts/release_publication.ts +84 -0
- package/src/scripts/render_benchmark_md.ts +1 -1
- package/src/scripts/rule_activation_census.ts +70 -9
- package/src/scripts/rule_backlinks.ts +1 -1
- package/src/scripts/run_lifecycle_suite.ts +208 -0
- package/src/scripts/run_skill_evals.ts +40 -0
- package/src/scripts/schemas/delivery-manifest.schema.json +43 -0
- package/src/scripts/schemas/drafting-channels.schema.json +43 -0
- package/src/scripts/schemas/evals.schema.json +24 -1
- package/src/scripts/schemas/rule.schema.json +52 -1
- package/src/scripts/schemas/skill.schema.json +17 -2
- package/src/scripts/skill_overlap.ts +7 -1
- package/src/scripts/skill_tools/run_block_d_eval.ts +8 -1
- package/src/scripts/skill_tools/score_skill_relevance.ts +84 -3
- package/src/scripts/skill_tools/suggest_skill_for_task.ts +8 -1
- package/src/scripts/skill_usage_report.ts +2 -1
- package/src/scripts/stubs_due.ts +211 -0
- package/src/scripts/sweep_source_surfaces.ts +678 -0
- package/src/scripts/sync_pr_branch.ts +3 -3
- package/src/scripts/trigger_eval_grandfather.json +202 -222
- package/src/scripts/utilization_report.ts +22 -2
- package/src/server/schemas/settings.ts +5 -0
- package/src/templates/marketing-copy.yml +1 -1
- package/dist/ui/assets/index-Cxgy63kz.js +0 -26
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
/**
|
|
3
|
+
* Dead relative links under `docs/`, split by whether the file SHIPS.
|
|
4
|
+
*
|
|
5
|
+
* `road-to-contract-review-deadlines` Phase 4.1. `check_references.ts` scans
|
|
6
|
+
* `dist/agent-src` and `agents` only, so `docs/` is green by exclusion rather
|
|
7
|
+
* than by being correct — the run reports thousands of `excluded_directory`
|
|
8
|
+
* skips and no other gate does general link validation there.
|
|
9
|
+
*
|
|
10
|
+
* The split is the point, not the total. A dead link in `docs/guidelines/` is
|
|
11
|
+
* shipped to consumers and is the only half that reaches anyone; a dead link in
|
|
12
|
+
* an internal analysis note costs a maintainer one confused minute. Reporting
|
|
13
|
+
* one number for both invites either an unreviewable 487-line sweep or nothing.
|
|
14
|
+
*
|
|
15
|
+
* A `.py` target is broken out separately because it is a MIGRATION LEFTOVER
|
|
16
|
+
* with a mechanical fix — the TypeScript port renamed the file, and the pointer
|
|
17
|
+
* did not follow. It is a class, not 152 independent defects.
|
|
18
|
+
*
|
|
19
|
+
* MEASUREMENT ONLY. This is deliberately not a `lint_*` / `check_*` gate: the
|
|
20
|
+
* scope decision (does `docs/` enter `check_references`?) is step 4.3 and is a
|
|
21
|
+
* maintainer call. A gate landed before that decision would pre-empt it.
|
|
22
|
+
*
|
|
23
|
+
* Usage:
|
|
24
|
+
* ./scripts-run src/scripts/measure_docs_dead_links
|
|
25
|
+
* ./scripts-run src/scripts/measure_docs_dead_links --format json
|
|
26
|
+
* ./scripts-run src/scripts/measure_docs_dead_links --list shipped
|
|
27
|
+
*/
|
|
28
|
+
import * as fs from 'node:fs';
|
|
29
|
+
import * as path from 'node:path';
|
|
30
|
+
import process from 'node:process';
|
|
31
|
+
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
32
|
+
|
|
33
|
+
const _HERE = fileURLToPath(import.meta.url);
|
|
34
|
+
const REPO_ROOT = path.resolve(path.dirname(_HERE), '..', '..');
|
|
35
|
+
|
|
36
|
+
/** Roots under `docs/` that `package.json:files[]` actually publishes. */
|
|
37
|
+
export const SHIPPED_DOCS_PREFIXES = [
|
|
38
|
+
'docs/guidelines/',
|
|
39
|
+
'docs/contracts/persona-schema.md',
|
|
40
|
+
'docs/contracts/provider-lifecycle.md',
|
|
41
|
+
'docs/contracts/settings-classes.md',
|
|
42
|
+
] as const;
|
|
43
|
+
|
|
44
|
+
/** Markdown inline links: `[text](target)`. Reference-style links are out of scope. */
|
|
45
|
+
const LINK_RE = /\[[^\]]*\]\(([^)\s]+)(?:\s+"[^"]*")?\)/g;
|
|
46
|
+
|
|
47
|
+
export type DeadClass = 'shipped' | 'internal';
|
|
48
|
+
|
|
49
|
+
export interface DeadLink {
|
|
50
|
+
file: string;
|
|
51
|
+
target: string;
|
|
52
|
+
resolved: string;
|
|
53
|
+
cls: DeadClass;
|
|
54
|
+
pyTarget: boolean;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export interface Measurement {
|
|
58
|
+
filesScanned: number;
|
|
59
|
+
linksScanned: number;
|
|
60
|
+
dead: DeadLink[];
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function walkMd(root: string, rel = ''): string[] {
|
|
64
|
+
const out: string[] = [];
|
|
65
|
+
const abs = path.join(root, rel);
|
|
66
|
+
for (const ent of fs.readdirSync(abs, { withFileTypes: true }).sort((a, b) => (a.name < b.name ? -1 : 1))) {
|
|
67
|
+
const r = rel === '' ? ent.name : `${rel}/${ent.name}`;
|
|
68
|
+
if (ent.isDirectory()) out.push(...walkMd(root, r));
|
|
69
|
+
else if (ent.name.endsWith('.md')) out.push(r);
|
|
70
|
+
}
|
|
71
|
+
return out;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function isShipped(file: string): boolean {
|
|
75
|
+
return SHIPPED_DOCS_PREFIXES.some((p) => (p.endsWith('/') ? file.startsWith(p) : file === p));
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* True for a link this measurement can decide. Anchors, URLs, mailto: and
|
|
80
|
+
* absolute paths are not relative file references and are skipped rather than
|
|
81
|
+
* counted as alive — counting an undecidable target as alive is the same
|
|
82
|
+
* false-green this whole roadmap is about.
|
|
83
|
+
*/
|
|
84
|
+
function isRelativeFileLink(target: string): boolean {
|
|
85
|
+
if (target === '' || target.startsWith('#')) return false;
|
|
86
|
+
// Prose placeholders, not links: a bare ellipsis inside a code-ish span, or
|
|
87
|
+
// an angle-bracket variable like `../<peer>/SKILL.md`. Counting them as dead
|
|
88
|
+
// would put un-fixable rows in a count whose whole purpose is to reach zero.
|
|
89
|
+
if (/^\.+$/.test(target)) return false;
|
|
90
|
+
if (target.includes('<') || target.includes('>')) return false;
|
|
91
|
+
if (/^[a-z][a-z0-9+.-]*:/i.test(target)) return false; // http:, https:, mailto:, …
|
|
92
|
+
if (target.startsWith('/')) return false;
|
|
93
|
+
return true;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export function measure(repoRoot: string = REPO_ROOT): Measurement {
|
|
97
|
+
const docsRoot = path.join(repoRoot, 'docs');
|
|
98
|
+
const files = walkMd(docsRoot);
|
|
99
|
+
const dead: DeadLink[] = [];
|
|
100
|
+
let linksScanned = 0;
|
|
101
|
+
|
|
102
|
+
for (const rel of files) {
|
|
103
|
+
const abs = path.join(docsRoot, rel);
|
|
104
|
+
const text = fs.readFileSync(abs, 'utf8');
|
|
105
|
+
LINK_RE.lastIndex = 0;
|
|
106
|
+
let m: RegExpExecArray | null;
|
|
107
|
+
while ((m = LINK_RE.exec(text)) !== null) {
|
|
108
|
+
const raw = m[1]!;
|
|
109
|
+
if (!isRelativeFileLink(raw)) continue;
|
|
110
|
+
linksScanned += 1;
|
|
111
|
+
const target = raw.split('#')[0]!;
|
|
112
|
+
if (target === '') continue; // pure anchor after the split
|
|
113
|
+
const resolved = path.normalize(path.join(path.dirname(abs), target));
|
|
114
|
+
if (fs.existsSync(resolved)) continue;
|
|
115
|
+
const file = `docs/${rel}`;
|
|
116
|
+
dead.push({
|
|
117
|
+
file,
|
|
118
|
+
target: raw,
|
|
119
|
+
resolved: path.relative(repoRoot, resolved),
|
|
120
|
+
cls: isShipped(file) ? 'shipped' : 'internal',
|
|
121
|
+
pyTarget: target.endsWith('.py'),
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return { filesScanned: files.length, linksScanned, dead };
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Repair a dead target by finding the ONE file in the tree it can only mean.
|
|
131
|
+
*
|
|
132
|
+
* The tail heuristic, and why it is safe: nearly every dead link here points at
|
|
133
|
+
* a container that MOVED — the retired uncondensed source tree after ADR-051
|
|
134
|
+
* flattened the source tree, or `../../rules/x.md` written from the wrong depth.
|
|
135
|
+
* The container changed; the tail did not. So the tail from a known segment
|
|
136
|
+
* onward (`rules/x.md`, `skills/x/SKILL.md`) still names the file uniquely.
|
|
137
|
+
*
|
|
138
|
+
* **Exactly one match, or no rewrite.** Ambiguity is reported, never guessed:
|
|
139
|
+
* a link silently repointed at the wrong one of two candidates is worse than a
|
|
140
|
+
* dead link, because a dead link is visible and a wrong one is not.
|
|
141
|
+
*/
|
|
142
|
+
const TAIL_SEGMENTS = ['rules/', 'skills/', 'commands/', 'contexts/', 'templates/', 'personas/', 'guidelines/', 'contracts/', 'scripts/', 'schemas/', 'tests/', 'golden/', 'decisions/'] as const;
|
|
143
|
+
|
|
144
|
+
function repoFileIndex(repoRoot: string): string[] {
|
|
145
|
+
const out: string[] = [];
|
|
146
|
+
const skip = new Set(['node_modules', '.git', 'dist', '.augment', '.claude', '.cursor', '.clinerules']);
|
|
147
|
+
const walk = (rel: string): void => {
|
|
148
|
+
for (const ent of fs.readdirSync(path.join(repoRoot, rel), { withFileTypes: true })) {
|
|
149
|
+
if (skip.has(ent.name)) continue;
|
|
150
|
+
const r = rel === '' ? ent.name : `${rel}/${ent.name}`;
|
|
151
|
+
if (ent.isDirectory()) walk(r);
|
|
152
|
+
else out.push(r);
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
walk('');
|
|
156
|
+
return out;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
export function resolveTail(target: string, index: readonly string[]): string | null {
|
|
160
|
+
const clean0 = target.split('#')[0]!;
|
|
161
|
+
// The migration class, handled first because it is a RENAME rather than a
|
|
162
|
+
// move: the TypeScript port changed the extension and the pointer did not
|
|
163
|
+
// follow. `scripts/x.py` -> `scripts/x.ts` is mechanical and unambiguous
|
|
164
|
+
// when the `.ts` file exists; when it does not, the file was deleted rather
|
|
165
|
+
// than ported and the link falls through to the tail search below.
|
|
166
|
+
const candidates = clean0.endsWith('.py')
|
|
167
|
+
? [
|
|
168
|
+
`${clean0.slice(0, -3)}.ts`,
|
|
169
|
+
// pytest's `test_x.py` became vitest's `x.test.ts` — a rename with
|
|
170
|
+
// a different SHAPE, not just a different extension, so it needs
|
|
171
|
+
// its own candidate rather than an extension swap.
|
|
172
|
+
clean0.replace(/(^|\/)test_([^/]+)\.py$/, '$1$2.test.ts'),
|
|
173
|
+
clean0,
|
|
174
|
+
]
|
|
175
|
+
: [clean0];
|
|
176
|
+
for (const clean of candidates) {
|
|
177
|
+
const hit = resolveOne(clean, index);
|
|
178
|
+
if (hit !== null) return hit;
|
|
179
|
+
}
|
|
180
|
+
return null;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
function resolveOne(clean: string, index: readonly string[]): string | null {
|
|
184
|
+
for (const seg of TAIL_SEGMENTS) {
|
|
185
|
+
const at = clean.lastIndexOf(seg);
|
|
186
|
+
if (at === -1) continue;
|
|
187
|
+
const tail = clean.slice(at);
|
|
188
|
+
const hits = index.filter((f) => f === tail || f.endsWith(`/${tail}`));
|
|
189
|
+
if (hits.length === 1) return hits[0]!;
|
|
190
|
+
if (hits.length > 1) {
|
|
191
|
+
// Tie-break on the ONE axis this repository has already settled:
|
|
192
|
+
// `src/` is the single source of truth and every other tree is a
|
|
193
|
+
// projection or an override (CLAUDE.md § Source of truth). So a tie
|
|
194
|
+
// between `src/rules/x.md` and `agents/overrides/rules/x.md` is not
|
|
195
|
+
// a real ambiguity — a doc pointing at the rule means the source.
|
|
196
|
+
// Any tie this does NOT break stays unresolved.
|
|
197
|
+
// Prefer the candidate the ORIGINAL target already named. A link
|
|
198
|
+
// reading `../../../src/scripts/memory_status.py` ties between
|
|
199
|
+
// `src/scripts/memory_status.ts` and
|
|
200
|
+
// `src/agent-src/templates/scripts/memory_status.ts` on the tail
|
|
201
|
+
// alone — but only one of them is what the author wrote, once the
|
|
202
|
+
// `../` prefix is dropped.
|
|
203
|
+
const normalized = clean.replace(/^(?:\.\.\/)+/, '');
|
|
204
|
+
const exact = hits.filter((f) => f === normalized);
|
|
205
|
+
if (exact.length === 1) return exact[0]!;
|
|
206
|
+
const inSrc = hits.filter((f) => f.startsWith('src/'));
|
|
207
|
+
if (inSrc.length === 1) return inSrc[0]!;
|
|
208
|
+
return null;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
// Last resort: the BASENAME alone, and only when the whole tree holds
|
|
212
|
+
// exactly one file with it. This is what catches a move that changed the
|
|
213
|
+
// directory as well as the name — `tests/test_condense.py` became
|
|
214
|
+
// `tests/scripts/condense.test.ts`, so neither the tail nor the extension
|
|
215
|
+
// swap alone reaches it. A basename with two homes stays unresolved: the
|
|
216
|
+
// uniqueness IS the safety property, not a convenience.
|
|
217
|
+
const base = clean.split('/').pop() ?? '';
|
|
218
|
+
if (base === '' || !base.includes('.')) return null;
|
|
219
|
+
const byBase = index.filter((f) => f.endsWith(`/${base}`) || f === base);
|
|
220
|
+
if (byBase.length === 1) return byBase[0]!;
|
|
221
|
+
const srcOrTests = byBase.filter((f) => f.startsWith('src/') || f.startsWith('tests/'));
|
|
222
|
+
if (srcOrTests.length === 1) return srcOrTests[0]!;
|
|
223
|
+
return null;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
interface FixResult {
|
|
227
|
+
rewritten: number;
|
|
228
|
+
files: number;
|
|
229
|
+
unresolved: DeadLink[];
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
export function applyFix(repoRoot: string, dead: readonly DeadLink[]): FixResult {
|
|
233
|
+
const index = repoFileIndex(repoRoot);
|
|
234
|
+
const byFile = new Map<string, DeadLink[]>();
|
|
235
|
+
for (const d of dead) {
|
|
236
|
+
const l = byFile.get(d.file) ?? [];
|
|
237
|
+
l.push(d);
|
|
238
|
+
byFile.set(d.file, l);
|
|
239
|
+
}
|
|
240
|
+
const unresolved: DeadLink[] = [];
|
|
241
|
+
let rewritten = 0;
|
|
242
|
+
let filesTouched = 0;
|
|
243
|
+
for (const [file, allLinks] of byFile) {
|
|
244
|
+
// One rewrite per DISTINCT target: the replacement is global within the
|
|
245
|
+
// file, so a target appearing twice would otherwise report one success
|
|
246
|
+
// and one phantom "unresolved" for a link that is already fixed.
|
|
247
|
+
const seen = new Set<string>();
|
|
248
|
+
const links = allLinks.filter((d) => (seen.has(d.target) ? false : (seen.add(d.target), true)));
|
|
249
|
+
const abs = path.join(repoRoot, file);
|
|
250
|
+
let text = fs.readFileSync(abs, 'utf8');
|
|
251
|
+
let changed = false;
|
|
252
|
+
for (const d of links) {
|
|
253
|
+
const resolvedRel = resolveTail(d.target, index);
|
|
254
|
+
if (resolvedRel === null) {
|
|
255
|
+
unresolved.push(d);
|
|
256
|
+
continue;
|
|
257
|
+
}
|
|
258
|
+
const anchor = d.target.includes('#') ? `#${d.target.split('#').slice(1).join('#')}` : '';
|
|
259
|
+
let next = path.relative(path.dirname(abs), path.join(repoRoot, resolvedRel));
|
|
260
|
+
if (!next.startsWith('.')) next = `./${next}`;
|
|
261
|
+
const replacement = `${next}${anchor}`;
|
|
262
|
+
if (replacement === d.target) {
|
|
263
|
+
unresolved.push(d);
|
|
264
|
+
continue;
|
|
265
|
+
}
|
|
266
|
+
const needle = `](${d.target})`;
|
|
267
|
+
if (!text.includes(needle)) {
|
|
268
|
+
unresolved.push(d);
|
|
269
|
+
continue;
|
|
270
|
+
}
|
|
271
|
+
text = text.split(needle).join(`](${replacement})`);
|
|
272
|
+
rewritten += 1;
|
|
273
|
+
changed = true;
|
|
274
|
+
}
|
|
275
|
+
if (changed) {
|
|
276
|
+
fs.writeFileSync(abs, text, 'utf8');
|
|
277
|
+
filesTouched += 1;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
return { rewritten, files: filesTouched, unresolved };
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
export function main(argv: string[] = process.argv.slice(2)): number {
|
|
284
|
+
if (argv.includes('-h') || argv.includes('--help')) {
|
|
285
|
+
process.stdout.write(
|
|
286
|
+
'usage: measure_docs_dead_links [--format json] [--list shipped|internal|py]\n' +
|
|
287
|
+
' [--fix shipped|py|all]\n' +
|
|
288
|
+
' --fix rewrites a dead target only when EXACTLY ONE file in the tree\n' +
|
|
289
|
+
' matches its path tail; ambiguity is reported, never guessed.\n',
|
|
290
|
+
);
|
|
291
|
+
return 0;
|
|
292
|
+
}
|
|
293
|
+
const asJson = argv.includes('--format') && argv[argv.indexOf('--format') + 1] === 'json';
|
|
294
|
+
const listIdx = argv.indexOf('--list');
|
|
295
|
+
const list = listIdx !== -1 ? argv[listIdx + 1] : null;
|
|
296
|
+
const fixIdx = argv.indexOf('--fix');
|
|
297
|
+
const fixScope = fixIdx !== -1 ? (argv[fixIdx + 1] ?? 'shipped') : null;
|
|
298
|
+
|
|
299
|
+
const r = measure();
|
|
300
|
+
|
|
301
|
+
if (fixScope !== null) {
|
|
302
|
+
const pool =
|
|
303
|
+
fixScope === 'shipped'
|
|
304
|
+
? r.dead.filter((d) => d.cls === 'shipped')
|
|
305
|
+
: fixScope === 'py'
|
|
306
|
+
? r.dead.filter((d) => d.pyTarget)
|
|
307
|
+
: r.dead;
|
|
308
|
+
const res = applyFix(REPO_ROOT, pool);
|
|
309
|
+
process.stdout.write(
|
|
310
|
+
`measure_docs_dead_links --fix ${fixScope}: rewrote ${String(res.rewritten)} link(s) in ` +
|
|
311
|
+
`${String(res.files)} file(s); ${String(res.unresolved.length)} left unresolved ` +
|
|
312
|
+
'(ambiguous or no unique candidate — never guessed).\n',
|
|
313
|
+
);
|
|
314
|
+
for (const d of res.unresolved.slice(0, 30)) {
|
|
315
|
+
process.stdout.write(` unresolved: ${d.file} -> ${d.target}\n`);
|
|
316
|
+
}
|
|
317
|
+
return 0;
|
|
318
|
+
}
|
|
319
|
+
const shipped = r.dead.filter((d) => d.cls === 'shipped');
|
|
320
|
+
const internal = r.dead.filter((d) => d.cls === 'internal');
|
|
321
|
+
const py = r.dead.filter((d) => d.pyTarget);
|
|
322
|
+
|
|
323
|
+
if (list !== null && list !== undefined) {
|
|
324
|
+
const pick = list === 'shipped' ? shipped : list === 'internal' ? internal : py;
|
|
325
|
+
for (const d of pick) process.stdout.write(`${d.file} -> ${d.target}\n`);
|
|
326
|
+
return 0;
|
|
327
|
+
}
|
|
328
|
+
if (asJson) {
|
|
329
|
+
process.stdout.write(
|
|
330
|
+
`${JSON.stringify({ filesScanned: r.filesScanned, linksScanned: r.linksScanned, total: r.dead.length, shipped: shipped.length, internal: internal.length, pyTarget: py.length }, null, 2)}\n`,
|
|
331
|
+
);
|
|
332
|
+
return 0;
|
|
333
|
+
}
|
|
334
|
+
process.stdout.write(
|
|
335
|
+
`docs/ dead relative links — ${r.dead.length} of ${r.linksScanned} link(s) across ${r.filesScanned} file(s)\n` +
|
|
336
|
+
` shipped ${String(shipped.length).padStart(4)} (package.json files[] publishes docs/guidelines/ plus three named contracts)\n` +
|
|
337
|
+
` internal ${String(internal.length).padStart(4)}\n` +
|
|
338
|
+
` .py target${String(py.length).padStart(5)} (migration leftovers; a subset of the two rows above, not a third bucket)\n`,
|
|
339
|
+
);
|
|
340
|
+
process.stdout.write(`scanned: ${r.filesScanned}\n`);
|
|
341
|
+
return 0;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
/* c8 ignore start */
|
|
345
|
+
if (process.argv[1] !== undefined && pathToFileURL(path.resolve(process.argv[1])).href === pathToFileURL(_HERE).href) {
|
|
346
|
+
process.exit(main());
|
|
347
|
+
}
|
|
348
|
+
/* c8 ignore stop */
|