@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,604 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
/**
|
|
3
|
+
* Canonical-terms lint — the house dialect, held by a ratchet.
|
|
4
|
+
*
|
|
5
|
+
* `src/config/canonical-terms.yml` records which side of nine measured spelling
|
|
6
|
+
* pairs this repository writes. Until this gate existed, nothing held that
|
|
7
|
+
* decision: the map was a document, and a document cannot stop the next commit
|
|
8
|
+
* from reintroducing `behaviour`. `road-to-canonical-terms` 2.2.
|
|
9
|
+
*
|
|
10
|
+
* ── What it reads, and what it deliberately does not ────────────────────────
|
|
11
|
+
* Prose only, under `src/` and `docs/` — the SHIPPED surface, which is the
|
|
12
|
+
* surface the map was decided on (22/78 American in `src/`; the British lead in
|
|
13
|
+
* the published aggregate is produced almost entirely by `agents/`, this
|
|
14
|
+
* repository's own working notes). Scanning `agents/` would judge roadmaps,
|
|
15
|
+
* evidence files and an archive nobody will edit again against a convention
|
|
16
|
+
* chosen for the shipped tree.
|
|
17
|
+
*
|
|
18
|
+
* Skipped, via the shared classifier in `_lib/md_prose_lines.ts` rather than a
|
|
19
|
+
* second copy of it: YAML frontmatter, fenced code, indented code, inline code
|
|
20
|
+
* spans, and any line carrying `<!-- canonical-terms: ignore -->`.
|
|
21
|
+
*
|
|
22
|
+
* ── Protected text ──────────────────────────────────────────────────────────
|
|
23
|
+
* Licence TITLES are exact external strings and are never rewritten — `MIT
|
|
24
|
+
* License`, `Apache License`, `GNU General Public License` and their family.
|
|
25
|
+
* The council was explicit on the limit of that carve-out: **proximity to a
|
|
26
|
+
* protected name does not exempt the surrounding prose.** So the exemption is
|
|
27
|
+
* span-scoped, not line-scoped — the title is blanked and the rest of the line
|
|
28
|
+
* is still read.
|
|
29
|
+
*
|
|
30
|
+
* URLs, link targets and paths are blanked for the same reason: `licence` in a
|
|
31
|
+
* URL is an address, not a word.
|
|
32
|
+
*
|
|
33
|
+
* ── Ratchet, not a hard zero ────────────────────────────────────────────────
|
|
34
|
+
* `sweep_authorised: false` in the map is a live constraint, not a formality:
|
|
35
|
+
* the AI council refused an unconditional ~5000-occurrence rewrite and required
|
|
36
|
+
* a classified inventory plus a bounded pilot first. So the corpus is NOT clean
|
|
37
|
+
* on day one, and a hard-zero gate would either fail `main` immediately or have
|
|
38
|
+
* to suppress the findings it exists to surface. `checkRatchet` records the
|
|
39
|
+
* remaining count; the gate fails only when it RISES. Lowering the baseline is
|
|
40
|
+
* a normal commit, raising it is a defect, and the entry expires so the number
|
|
41
|
+
* cannot harden into configuration.
|
|
42
|
+
*
|
|
43
|
+
* ── Inventory mode ──────────────────────────────────────────────────────────
|
|
44
|
+
* `--inventory` classifies every occurrence across a wider root set into the
|
|
45
|
+
* four categories the council named — repository-authored prose, protected
|
|
46
|
+
* exact text, generated or externally synchronised content, and ambiguous —
|
|
47
|
+
* and prints the table the migration is designed from. A frequency count cannot
|
|
48
|
+
* tell (a) from (b); that distinction is the whole point of the mode.
|
|
49
|
+
*
|
|
50
|
+
* Exit codes: 0 clean or within ratchet · 1 regression · 2 usage / dead scope.
|
|
51
|
+
*
|
|
52
|
+
* Usage:
|
|
53
|
+
* ./scripts-run src/scripts/lint_canonical_terms
|
|
54
|
+
* ./scripts-run src/scripts/lint_canonical_terms --inventory
|
|
55
|
+
* ./scripts-run src/scripts/lint_canonical_terms --inventory --format json
|
|
56
|
+
*/
|
|
57
|
+
import { execFileSync } from 'node:child_process';
|
|
58
|
+
import * as fs from 'node:fs';
|
|
59
|
+
import * as os from 'node:os';
|
|
60
|
+
import * as path from 'node:path';
|
|
61
|
+
import process from 'node:process';
|
|
62
|
+
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
63
|
+
|
|
64
|
+
import { parse as parseYaml } from 'yaml';
|
|
65
|
+
|
|
66
|
+
import { checkRatchet } from './_lib/gate_baseline.js';
|
|
67
|
+
import { GateLedger } from './_lib/gate_ledger.js';
|
|
68
|
+
import { runGateCli, runSelfTest } from './_lib/gate_self_test.js';
|
|
69
|
+
import { classifyMarkdownLines } from './_lib/md_prose_lines.js';
|
|
70
|
+
import { DeadScopeError, assertScanned } from './_lib/scan_scope.js';
|
|
71
|
+
|
|
72
|
+
const _HERE = fileURLToPath(import.meta.url);
|
|
73
|
+
const REPO_ROOT = path.resolve(path.dirname(_HERE), '..', '..');
|
|
74
|
+
|
|
75
|
+
/** Where the house dialect is recorded. */
|
|
76
|
+
export const MAP_REL = 'src/config/canonical-terms.yml';
|
|
77
|
+
|
|
78
|
+
/** The gate's enforcing scope — the shipped surface the map was decided on. */
|
|
79
|
+
export const GATE_ROOTS = ['src/', 'docs/'] as const;
|
|
80
|
+
|
|
81
|
+
/** The inventory's scope — everything the sweep would ever touch. */
|
|
82
|
+
export const INVENTORY_ROOTS = ['src/', 'docs/', 'agents/', 'dist/'] as const;
|
|
83
|
+
|
|
84
|
+
/** Per-line opt-out. */
|
|
85
|
+
const IGNORE_RE = /<!--\s*canonical-terms:\s*ignore\s*-->/i;
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Generated or externally synchronised trees. An occurrence here is category
|
|
89
|
+
* (c): rewriting it is a no-op that the next `task sync` reverts.
|
|
90
|
+
*/
|
|
91
|
+
const GENERATED_PREFIXES = [
|
|
92
|
+
'dist/',
|
|
93
|
+
'.augment/',
|
|
94
|
+
'.claude/',
|
|
95
|
+
'.cursor/',
|
|
96
|
+
'.clinerules/',
|
|
97
|
+
'node_modules/',
|
|
98
|
+
// The retired uncondensed source container ADR-051 abandoned is deliberately
|
|
99
|
+
// NOT listed. `check_no_new_legacy_path` refuses new references to it under
|
|
100
|
+
// src/, and no scan root here reaches it — so an entry would be a dead
|
|
101
|
+
// literal reintroducing a path this repository has spent a ratchet removing.
|
|
102
|
+
// Built by `src/scripts/build_proof.ts` from the Claims Ledger; editing it
|
|
103
|
+
// is a no-op that the next build reverts.
|
|
104
|
+
'docs/proof.md',
|
|
105
|
+
] as const;
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Immutable records. Repository-authored, but rewriting them edits history:
|
|
109
|
+
* an archived roadmap and a dated evidence file are what the repository SAID,
|
|
110
|
+
* and a sweep that changes them makes the record disagree with the measurement
|
|
111
|
+
* it published. Category (d) — a human decides, per file.
|
|
112
|
+
*/
|
|
113
|
+
const HISTORICAL_PREFIXES = [
|
|
114
|
+
'agents/roadmaps/archive/',
|
|
115
|
+
'agents/roadmaps/skipped/',
|
|
116
|
+
'agents/evidence/',
|
|
117
|
+
'docs/decisions/',
|
|
118
|
+
// Frozen changelog slices. `docs/archive/CHANGELOG-pre-*.md` is what the
|
|
119
|
+
// repository published at that version; rewriting it makes the record
|
|
120
|
+
// disagree with the release it describes.
|
|
121
|
+
'docs/archive/',
|
|
122
|
+
'CHANGELOG.md',
|
|
123
|
+
] as const;
|
|
124
|
+
|
|
125
|
+
/** Licence titles — exact external strings, never rewritten. */
|
|
126
|
+
const LICENCE_TITLE_RE =
|
|
127
|
+
/\b(?:MIT|Apache(?:\s+\d+(?:\.\d+)?)?|BSD(?:[- ]\d[- ]Clause)?|ISC|MPL|Mozilla\s+Public|GNU\s+(?:Lesser\s+|Affero\s+)?General\s+Public|Creative\s+Commons|Unlicense|EUPL|Eclipse\s+Public)\s+Licen[cs]e\b/gi;
|
|
128
|
+
|
|
129
|
+
/** Link targets, URLs and bare paths — addresses, not words. */
|
|
130
|
+
const ADDRESS_RE = /\]\([^)]*\)|<[^>\s]+>|\bhttps?:\/\/\S+|\b[\w./-]+\.(?:md|ts|js|json|ya?ml|py|sh|html)\b/g;
|
|
131
|
+
|
|
132
|
+
export type TermCategory = 'authored-prose' | 'protected-text' | 'generated' | 'ambiguous';
|
|
133
|
+
|
|
134
|
+
export interface TermPair {
|
|
135
|
+
canonical: string;
|
|
136
|
+
variant: string;
|
|
137
|
+
confidence: string;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export interface TermFinding {
|
|
141
|
+
file: string;
|
|
142
|
+
line: number;
|
|
143
|
+
variant: string;
|
|
144
|
+
canonical: string;
|
|
145
|
+
category: TermCategory;
|
|
146
|
+
context: string;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
interface CanonicalTermsMap {
|
|
150
|
+
sweep_authorised?: boolean;
|
|
151
|
+
terms?: { canonical?: string | null; variant?: string; confidence?: string }[];
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/** Read the decided pairs. Undecided entries (`canonical: null`) are skipped. */
|
|
155
|
+
export function loadPairs(repoRoot: string = REPO_ROOT, rel: string = MAP_REL): TermPair[] {
|
|
156
|
+
const raw = fs.readFileSync(path.join(repoRoot, rel), 'utf8');
|
|
157
|
+
const doc = parseYaml(raw) as CanonicalTermsMap;
|
|
158
|
+
const out: TermPair[] = [];
|
|
159
|
+
for (const t of doc.terms ?? []) {
|
|
160
|
+
if (t.canonical === null || t.canonical === undefined) continue;
|
|
161
|
+
if (typeof t.variant !== 'string' || t.variant === '') continue;
|
|
162
|
+
out.push({ canonical: t.canonical, variant: t.variant, confidence: t.confidence ?? 'unknown' });
|
|
163
|
+
}
|
|
164
|
+
return out;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
function escapeRegExp(s: string): string {
|
|
168
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Match the variant as a whole word, and also as the stem of its own
|
|
173
|
+
* inflections — `behaviour` must catch `behaviours` and `behavioural`, which is
|
|
174
|
+
* where a naive `\b…\b` silently under-reports. The leading boundary stays
|
|
175
|
+
* strict so `licence` does not fire inside `unlicenced-source`… it does, and
|
|
176
|
+
* that is correct: that is the variant.
|
|
177
|
+
*/
|
|
178
|
+
function variantRegExp(variant: string): RegExp {
|
|
179
|
+
return new RegExp(`(?<![\\p{L}\\p{N}_])${escapeRegExp(variant)}(?:s|es|d|al|ally|ing)?(?![\\p{L}\\p{N}_])`, 'giu');
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
function blankSpans(line: string, re: RegExp): string {
|
|
183
|
+
re.lastIndex = 0;
|
|
184
|
+
return line.replace(re, (m) => ' '.repeat(m.length));
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
function fileCategory(file: string): TermCategory | null {
|
|
188
|
+
if (GENERATED_PREFIXES.some((p) => file.startsWith(p))) return 'generated';
|
|
189
|
+
if (HISTORICAL_PREFIXES.some((p) => file.startsWith(p))) return 'ambiguous';
|
|
190
|
+
return null;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Classify every variant occurrence in one document.
|
|
195
|
+
*
|
|
196
|
+
* Pure over the content string, so the four states the roadmap's verify clause
|
|
197
|
+
* names — prose, fence, frontmatter, quoted licence title — are demonstrable
|
|
198
|
+
* from literals with no repo.
|
|
199
|
+
*/
|
|
200
|
+
export function scanContent(file: string, content: string, pairs: readonly TermPair[]): TermFinding[] {
|
|
201
|
+
const findings: TermFinding[] = [];
|
|
202
|
+
const forcedCategory = fileCategory(file);
|
|
203
|
+
|
|
204
|
+
for (const line of classifyMarkdownLines(content, { markers: [IGNORE_RE] })) {
|
|
205
|
+
if (line.kind !== 'prose') continue;
|
|
206
|
+
|
|
207
|
+
// `text` already has inline code spans blanked. Blank the protected
|
|
208
|
+
// spans on top, keeping the line length so a category decision made on
|
|
209
|
+
// the blanked text still lines up with the raw one.
|
|
210
|
+
const protectedBlanked = blankSpans(blankSpans(line.text, LICENCE_TITLE_RE), ADDRESS_RE);
|
|
211
|
+
|
|
212
|
+
for (const pair of pairs) {
|
|
213
|
+
const re = variantRegExp(pair.variant);
|
|
214
|
+
re.lastIndex = 0;
|
|
215
|
+
let m: RegExpExecArray | null;
|
|
216
|
+
while ((m = re.exec(line.text)) !== null) {
|
|
217
|
+
const at = m.index;
|
|
218
|
+
const survives = protectedBlanked.slice(at, at + m[0].length).trim() !== '';
|
|
219
|
+
const category: TermCategory = !survives
|
|
220
|
+
? 'protected-text'
|
|
221
|
+
: (forcedCategory ?? 'authored-prose');
|
|
222
|
+
findings.push({
|
|
223
|
+
file,
|
|
224
|
+
line: line.lineno,
|
|
225
|
+
variant: m[0],
|
|
226
|
+
canonical: pair.canonical,
|
|
227
|
+
category,
|
|
228
|
+
context: line.raw.trim(),
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
return findings;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Every markdown file under the given roots — TRACKED and UNTRACKED.
|
|
238
|
+
*
|
|
239
|
+
* `--others --exclude-standard` is load-bearing, not thoroughness. The gate's
|
|
240
|
+
* canary in `gate-coverage.yml` is create-only by contract, so it plants a NEW,
|
|
241
|
+
* untracked file; a plain `git ls-files` would not see it and the gate would
|
|
242
|
+
* report green on its own canary — the exact "gate that cannot fail" failure
|
|
243
|
+
* `check_gate_coverage --canary` exists to catch.
|
|
244
|
+
*/
|
|
245
|
+
function listMarkdown(repoRoot: string, roots: readonly string[]): string[] {
|
|
246
|
+
const patterns = [...roots.map((r) => `${r}**/*.md`), ...roots.map((r) => `${r}*.md`)];
|
|
247
|
+
const run = (args: string[]): string[] =>
|
|
248
|
+
execFileSync('git', args, { cwd: repoRoot, encoding: 'utf8', maxBuffer: 64 * 1024 * 1024 })
|
|
249
|
+
.split('\n')
|
|
250
|
+
.filter((l) => l.endsWith('.md'));
|
|
251
|
+
const tracked = run(['ls-files', '--', ...patterns]);
|
|
252
|
+
const untracked = run(['ls-files', '--others', '--exclude-standard', '--', ...patterns]);
|
|
253
|
+
return Array.from(new Set([...tracked, ...untracked])).sort();
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
export interface ScanResult {
|
|
257
|
+
findings: TermFinding[];
|
|
258
|
+
filesScanned: number;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/** Every `.md` under a plain directory — the fixture path, where there is no git index. */
|
|
262
|
+
function walkMarkdown(root: string): string[] {
|
|
263
|
+
const out: string[] = [];
|
|
264
|
+
const visit = (dir: string): void => {
|
|
265
|
+
for (const ent of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
266
|
+
const abs = path.join(dir, ent.name);
|
|
267
|
+
if (ent.isDirectory()) visit(abs);
|
|
268
|
+
else if (ent.name.endsWith('.md')) out.push(path.relative(root, abs));
|
|
269
|
+
}
|
|
270
|
+
};
|
|
271
|
+
visit(root);
|
|
272
|
+
return out.sort();
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* Scan a tree, accounting for every file through a {@link GateLedger}.
|
|
277
|
+
*
|
|
278
|
+
* The ledger is not decoration here. This gate `continue`s past unreadable
|
|
279
|
+
* files, and a `continue` with no record is precisely the silent-skip the
|
|
280
|
+
* ledger exists to make visible — a gate that read 1,400 of 1,577 files and
|
|
281
|
+
* printed a green checkmark is indistinguishable from one that read all of them.
|
|
282
|
+
*/
|
|
283
|
+
export function scanTree(
|
|
284
|
+
repoRoot: string,
|
|
285
|
+
roots: readonly string[],
|
|
286
|
+
pairs: readonly TermPair[],
|
|
287
|
+
ledger?: GateLedger,
|
|
288
|
+
): ScanResult {
|
|
289
|
+
const files = roots.length === 1 && roots[0] === '' ? walkMarkdown(repoRoot) : listMarkdown(repoRoot, roots);
|
|
290
|
+
ledger?.plan(files);
|
|
291
|
+
const findings: TermFinding[] = [];
|
|
292
|
+
for (const f of files) {
|
|
293
|
+
let content: string;
|
|
294
|
+
try {
|
|
295
|
+
content = fs.readFileSync(path.join(repoRoot, f), 'utf8');
|
|
296
|
+
} catch {
|
|
297
|
+
ledger?.skip(f, 'binary_content');
|
|
298
|
+
continue;
|
|
299
|
+
}
|
|
300
|
+
const hits = scanContent(f, content, pairs);
|
|
301
|
+
findings.push(...hits);
|
|
302
|
+
const actionable = hits.filter((h) => h.category === 'authored-prose');
|
|
303
|
+
if (actionable.length > 0) ledger?.fail(f, `${actionable.length} non-canonical occurrence(s)`);
|
|
304
|
+
else ledger?.complete(f);
|
|
305
|
+
}
|
|
306
|
+
return { findings, filesScanned: files.length };
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
function countBy(items: readonly { [k: string]: unknown }[], key: string): Record<string, number> {
|
|
310
|
+
const out: Record<string, number> = {};
|
|
311
|
+
for (const it of items) {
|
|
312
|
+
const k = String(it[key]);
|
|
313
|
+
out[k] = (out[k] ?? 0) + 1;
|
|
314
|
+
}
|
|
315
|
+
return out;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
function renderInventory(result: ScanResult, pairs: readonly TermPair[]): string {
|
|
319
|
+
const byCat = countBy(result.findings as unknown as Record<string, unknown>[], 'category');
|
|
320
|
+
const lines: string[] = [];
|
|
321
|
+
lines.push(`files scanned: ${result.filesScanned}`);
|
|
322
|
+
lines.push(`occurrences: ${result.findings.length}`);
|
|
323
|
+
lines.push('');
|
|
324
|
+
lines.push('| category | occurrences | what it means |');
|
|
325
|
+
lines.push('|---|---:|---|');
|
|
326
|
+
const meaning: Record<TermCategory, string> = {
|
|
327
|
+
'authored-prose': 'repository-authored prose, eligible for normalisation',
|
|
328
|
+
'protected-text': 'exact external text — licence titles, addresses, code spans',
|
|
329
|
+
generated: 'generated or externally synchronised; a rewrite is reverted by `task sync`',
|
|
330
|
+
ambiguous: 'immutable record (archive, evidence, ADRs, changelog) — a human decides per file',
|
|
331
|
+
};
|
|
332
|
+
for (const c of ['authored-prose', 'protected-text', 'generated', 'ambiguous'] as TermCategory[]) {
|
|
333
|
+
lines.push(`| ${c} | ${byCat[c] ?? 0} | ${meaning[c]} |`);
|
|
334
|
+
}
|
|
335
|
+
lines.push('');
|
|
336
|
+
lines.push('| pair | authored-prose | files | blast radius |');
|
|
337
|
+
lines.push('|---|---:|---:|---|');
|
|
338
|
+
for (const p of pairs) {
|
|
339
|
+
const hits = result.findings.filter((f) => f.canonical === p.canonical && f.category === 'authored-prose');
|
|
340
|
+
const files = new Set(hits.map((f) => f.file));
|
|
341
|
+
lines.push(`| \`${p.variant}\` → \`${p.canonical}\` | ${hits.length} | ${files.size} | ${files.size <= 5 ? 'small' : files.size <= 25 ? 'medium' : 'large'} |`);
|
|
342
|
+
}
|
|
343
|
+
return lines.join('\n');
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
|
|
347
|
+
/**
|
|
348
|
+
* Rewrite one matched token to the canonical side, preserving inflection and
|
|
349
|
+
* capitalization. `Sub-agents` → `Subagents`, `behavioural` → `behavioral`,
|
|
350
|
+
* `canonicalised` → `canonicalized`.
|
|
351
|
+
*
|
|
352
|
+
* The suffix is whatever the variant regex matched beyond the base, so the
|
|
353
|
+
* inflection set is defined in exactly one place ({@link variantRegExp}) and a
|
|
354
|
+
* new suffix added there is automatically handled here.
|
|
355
|
+
*/
|
|
356
|
+
export function canonicalizeToken(token: string, pair: TermPair): string {
|
|
357
|
+
const lower = token.toLowerCase();
|
|
358
|
+
const base = pair.variant.toLowerCase();
|
|
359
|
+
if (!lower.startsWith(base)) return token;
|
|
360
|
+
const suffix = lower.slice(base.length);
|
|
361
|
+
const replacement = pair.canonical + suffix;
|
|
362
|
+
if (token === token.toUpperCase() && token !== token.toLowerCase()) return replacement.toUpperCase();
|
|
363
|
+
if (token[0] === token[0]?.toUpperCase() && token[0] !== token[0]?.toLowerCase()) {
|
|
364
|
+
return replacement.charAt(0).toUpperCase() + replacement.slice(1);
|
|
365
|
+
}
|
|
366
|
+
return replacement;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
/**
|
|
370
|
+
* Apply the canonical side to the `authored-prose` occurrences of the selected
|
|
371
|
+
* pairs, and only those.
|
|
372
|
+
*
|
|
373
|
+
* The rewrite is driven by the SAME classification the gate reports, so a
|
|
374
|
+
* category the scanner protects is a category the sweep cannot touch — there is
|
|
375
|
+
* no second find-and-replace with its own idea of what a fence is. That is the
|
|
376
|
+
* property the council's "classified inventory, not a frequency count"
|
|
377
|
+
* condition was asking for.
|
|
378
|
+
*/
|
|
379
|
+
export function applyFix(
|
|
380
|
+
repoRoot: string,
|
|
381
|
+
findings: readonly TermFinding[],
|
|
382
|
+
pairs: readonly TermPair[],
|
|
383
|
+
): { files: number; occurrences: number } {
|
|
384
|
+
const byCanonical = new Map(pairs.map((p) => [p.canonical, p]));
|
|
385
|
+
const byFile = new Map<string, TermFinding[]>();
|
|
386
|
+
for (const f of findings) {
|
|
387
|
+
if (f.category !== 'authored-prose') continue;
|
|
388
|
+
const list = byFile.get(f.file) ?? [];
|
|
389
|
+
list.push(f);
|
|
390
|
+
byFile.set(f.file, list);
|
|
391
|
+
}
|
|
392
|
+
let occurrences = 0;
|
|
393
|
+
for (const [file, list] of byFile) {
|
|
394
|
+
const abs = path.join(repoRoot, file);
|
|
395
|
+
const lines = fs.readFileSync(abs, 'utf8').split('\n');
|
|
396
|
+
// Group per line so several hits on one line are rewritten together.
|
|
397
|
+
const lineNos = Array.from(new Set(list.map((f) => f.line)));
|
|
398
|
+
for (const lineNo of lineNos) {
|
|
399
|
+
const idx = lineNo - 1;
|
|
400
|
+
let text = lines[idx] ?? '';
|
|
401
|
+
for (const pair of new Set(list.filter((f) => f.line === lineNo).map((f) => byCanonical.get(f.canonical)!))) {
|
|
402
|
+
const re = variantRegExp(pair.variant);
|
|
403
|
+
text = text.replace(re, (tok) => canonicalizeToken(tok, pair));
|
|
404
|
+
}
|
|
405
|
+
if (text !== lines[idx]) {
|
|
406
|
+
occurrences += list.filter((f) => f.line === lineNo).length;
|
|
407
|
+
lines[idx] = text;
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
fs.writeFileSync(abs, lines.join('\n'), 'utf8');
|
|
411
|
+
}
|
|
412
|
+
return { files: byFile.size, occurrences };
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
|
|
416
|
+
/**
|
|
417
|
+
* Self-test — the gate proving it can still fail, on a fixture tree.
|
|
418
|
+
*
|
|
419
|
+
* The `--root` seam exists for exactly this: a fixture must never be judged
|
|
420
|
+
* against the repository's recorded debt, so `--root` bypasses the ratchet and
|
|
421
|
+
* uses the plain "any authored-prose occurrence is a failure" rule. The four
|
|
422
|
+
* cases are the four states the roadmap's verify clause names.
|
|
423
|
+
*/
|
|
424
|
+
export function selfTest(): number {
|
|
425
|
+
const tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'lct-selftest-'));
|
|
426
|
+
const write = (rel: string, body: string): string => {
|
|
427
|
+
const p = path.join(tmp, rel);
|
|
428
|
+
fs.mkdirSync(path.dirname(p), { recursive: true });
|
|
429
|
+
fs.writeFileSync(p, body, 'utf-8');
|
|
430
|
+
return path.dirname(p);
|
|
431
|
+
};
|
|
432
|
+
const run = (dir: string): number =>
|
|
433
|
+
runGateCli(REPO_ROOT, 'src/scripts/lint_canonical_terms.ts', ['--root', dir, '--quiet'], REPO_ROOT);
|
|
434
|
+
|
|
435
|
+
try {
|
|
436
|
+
return runSelfTest({
|
|
437
|
+
gate: 'lint_canonical_terms',
|
|
438
|
+
minCases: 4,
|
|
439
|
+
minRejectCases: 1,
|
|
440
|
+
cases: [
|
|
441
|
+
{
|
|
442
|
+
name: 'a non-canonical spelling in prose is rejected',
|
|
443
|
+
expect: 'reject',
|
|
444
|
+
run: () => run(write('prose/doc.md', 'The observed behaviour is wrong.\n')),
|
|
445
|
+
},
|
|
446
|
+
{
|
|
447
|
+
name: 'the same word inside a fence passes',
|
|
448
|
+
expect: 'accept',
|
|
449
|
+
run: () => run(write('fence/doc.md', 'Prose.\n\n```ts\n// behaviour\n```\n')),
|
|
450
|
+
},
|
|
451
|
+
{
|
|
452
|
+
name: 'the same word inside a frontmatter value passes',
|
|
453
|
+
expect: 'accept',
|
|
454
|
+
run: () => run(write('fm/doc.md', '---\ndescription: behaviour\n---\n\nProse.\n')),
|
|
455
|
+
},
|
|
456
|
+
{
|
|
457
|
+
name: 'the same word inside a quoted licence title passes',
|
|
458
|
+
expect: 'accept',
|
|
459
|
+
run: () => run(write('lic/doc.md', 'Shipped under the Mozilla Public Licence.\n')),
|
|
460
|
+
},
|
|
461
|
+
],
|
|
462
|
+
});
|
|
463
|
+
} finally {
|
|
464
|
+
fs.rmSync(tmp, { recursive: true, force: true });
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
export function main(argv: string[] = process.argv.slice(2)): number {
|
|
469
|
+
if (argv.includes('-h') || argv.includes('--help')) {
|
|
470
|
+
process.stdout.write(
|
|
471
|
+
'usage: lint_canonical_terms [--inventory] [--format {text,json}] [--quiet]\n' +
|
|
472
|
+
' Default: ratchet over authored prose under src/ and docs/.\n' +
|
|
473
|
+
' --inventory: classified occurrence table across src/, docs/, agents/ and dist/.\n' +
|
|
474
|
+
' --fix --pair <canonical>[,<canonical>]: rewrite authored-prose occurrences of\n' +
|
|
475
|
+
' the named pairs only. Refuses without --pair: the map carries\n' +
|
|
476
|
+
' `sweep_authorised: false`, so an unbounded sweep is not available here.\n' +
|
|
477
|
+
' --root <dir>: judge a fixture tree instead of the repo (no ratchet).\n' +
|
|
478
|
+
' --self-test: prove the gate can still fail.\n',
|
|
479
|
+
);
|
|
480
|
+
return 0;
|
|
481
|
+
}
|
|
482
|
+
if (argv.includes('--self-test')) return selfTest();
|
|
483
|
+
|
|
484
|
+
const rootIdx = argv.indexOf('--root');
|
|
485
|
+
const fixtureRoot = rootIdx !== -1 && rootIdx + 1 < argv.length ? (argv[rootIdx + 1] as string) : null;
|
|
486
|
+
|
|
487
|
+
const quiet = argv.includes('--quiet');
|
|
488
|
+
const asJson = argv.includes('--format=json') || (argv.includes('--format') && argv[argv.indexOf('--format') + 1] === 'json');
|
|
489
|
+
const inventory = argv.includes('--inventory');
|
|
490
|
+
const fix = argv.includes('--fix');
|
|
491
|
+
const pairArgIdx = argv.indexOf('--pair');
|
|
492
|
+
const selected =
|
|
493
|
+
pairArgIdx !== -1 && pairArgIdx + 1 < argv.length
|
|
494
|
+
? new Set((argv[pairArgIdx + 1] as string).split(',').map((s) => s.trim()).filter(Boolean))
|
|
495
|
+
: null;
|
|
496
|
+
|
|
497
|
+
if (fix && (selected === null || selected.size === 0)) {
|
|
498
|
+
process.stderr.write(
|
|
499
|
+
'lint_canonical_terms: --fix requires --pair. `sweep_authorised: false` in ' +
|
|
500
|
+
`${MAP_REL} means the corpus-wide sweep is not authorised; the pilot is bounded ` +
|
|
501
|
+
'by naming the pairs it may touch.\n',
|
|
502
|
+
);
|
|
503
|
+
return 2;
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
const pairs = loadPairs();
|
|
507
|
+
|
|
508
|
+
if (fixtureRoot !== null) {
|
|
509
|
+
// Fixture mode: no git index, no ratchet. Any authored-prose occurrence
|
|
510
|
+
// fails, which is what makes an accept/reject self-test meaningful.
|
|
511
|
+
const fixture = scanTree(path.resolve(fixtureRoot), [''], pairs);
|
|
512
|
+
const bad = fixture.findings.filter((f) => f.category === 'authored-prose');
|
|
513
|
+
if (!quiet) {
|
|
514
|
+
for (const f of bad) process.stderr.write(` ${f.file}:${f.line} \`${f.variant}\` -> \`${f.canonical}\`\n`);
|
|
515
|
+
process.stdout.write(`scanned: ${fixture.filesScanned}\n`);
|
|
516
|
+
}
|
|
517
|
+
return bad.length > 0 ? 1 : 0;
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
const roots = inventory ? INVENTORY_ROOTS : GATE_ROOTS;
|
|
521
|
+
const ledger = inventory ? undefined : new GateLedger('lint_canonical_terms');
|
|
522
|
+
const result = scanTree(REPO_ROOT, roots, pairs, ledger);
|
|
523
|
+
|
|
524
|
+
try {
|
|
525
|
+
assertScanned({
|
|
526
|
+
gate: 'lint_canonical_terms',
|
|
527
|
+
scanned: result.filesScanned,
|
|
528
|
+
units: 'markdown file(s)',
|
|
529
|
+
roots,
|
|
530
|
+
});
|
|
531
|
+
} catch (e) {
|
|
532
|
+
if (e instanceof DeadScopeError) {
|
|
533
|
+
process.stderr.write(`❌ ${e.message}\n`);
|
|
534
|
+
return 2;
|
|
535
|
+
}
|
|
536
|
+
throw e;
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
if (fix) {
|
|
540
|
+
const scoped = result.findings.filter((f) => selected!.has(f.canonical));
|
|
541
|
+
const applied = applyFix(REPO_ROOT, scoped, pairs);
|
|
542
|
+
process.stdout.write(
|
|
543
|
+
`lint_canonical_terms --fix: ${applied.occurrences} occurrence(s) in ${applied.files} file(s) ` +
|
|
544
|
+
`for pair(s) ${[...selected!].join(', ')}.\n`,
|
|
545
|
+
);
|
|
546
|
+
return 0;
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
if (inventory) {
|
|
550
|
+
if (asJson) {
|
|
551
|
+
process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
|
|
552
|
+
} else {
|
|
553
|
+
process.stdout.write(`${renderInventory(result, pairs)}\n`);
|
|
554
|
+
}
|
|
555
|
+
return 0;
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
const actionable = result.findings.filter((f) => f.category === 'authored-prose');
|
|
559
|
+
if (asJson) {
|
|
560
|
+
process.stdout.write(`${JSON.stringify({ findings: actionable, filesScanned: result.filesScanned }, null, 2)}\n`);
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
const verdict = checkRatchet({
|
|
564
|
+
gate: 'lint_canonical_terms',
|
|
565
|
+
actual: actionable.length,
|
|
566
|
+
repoRoot: REPO_ROOT,
|
|
567
|
+
});
|
|
568
|
+
|
|
569
|
+
if (!verdict.ok) {
|
|
570
|
+
ledger?.report();
|
|
571
|
+
// The machine-readable count is emitted on the RED path too. Rule 1 of
|
|
572
|
+
// the gate-coverage manifest asks for exactly one `scanned:` line, and a
|
|
573
|
+
// gate that publishes its coverage only when it passes cannot be caught
|
|
574
|
+
// going blind at the moment that matters most. This was missing when the
|
|
575
|
+
// gate landed, and `check_gate_coverage` reported it the first time the
|
|
576
|
+
// ratchet went red — which is the census working.
|
|
577
|
+
process.stdout.write(`scanned: ${result.filesScanned}\n`);
|
|
578
|
+
if (!quiet) {
|
|
579
|
+
for (const f of actionable.slice(0, 40)) {
|
|
580
|
+
process.stderr.write(` ${f.file}:${f.line} · \`${f.variant}\` → \`${f.canonical}\`\n`);
|
|
581
|
+
}
|
|
582
|
+
if (actionable.length > 40) process.stderr.write(` … and ${actionable.length - 40} more\n`);
|
|
583
|
+
}
|
|
584
|
+
process.stderr.write(`❌ ${verdict.message}\n`);
|
|
585
|
+
return 1;
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
ledger?.report(quiet ? () => undefined : undefined);
|
|
589
|
+
if (!quiet) {
|
|
590
|
+
process.stdout.write(`✅ ${verdict.message}\n`);
|
|
591
|
+
process.stdout.write(`scanned: ${result.filesScanned}\n`);
|
|
592
|
+
}
|
|
593
|
+
return 0;
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
/* c8 ignore start */
|
|
597
|
+
function isCliEntry(): boolean {
|
|
598
|
+
if (process.argv[1] === undefined) return false;
|
|
599
|
+
return pathToFileURL(path.resolve(process.argv[1])).href === pathToFileURL(_HERE).href;
|
|
600
|
+
}
|
|
601
|
+
if (isCliEntry()) {
|
|
602
|
+
process.exit(main());
|
|
603
|
+
}
|
|
604
|
+
/* c8 ignore stop */
|