@shrkcrft/cli 0.1.0-alpha.29 → 0.1.0-alpha.31
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/dist/asset-preview/apply-asset-preview.js +1 -1
- package/dist/authoring/authoring-kit.d.ts +9 -1
- package/dist/authoring/authoring-kit.d.ts.map +1 -1
- package/dist/authoring/authoring-kit.js +26 -13
- package/dist/bootstrap/unlinked-workspace-dependency.d.ts +11 -0
- package/dist/bootstrap/unlinked-workspace-dependency.d.ts.map +1 -0
- package/dist/bootstrap/unlinked-workspace-dependency.js +99 -0
- package/dist/command-registry.d.ts +100 -1
- package/dist/command-registry.d.ts.map +1 -1
- package/dist/command-registry.js +130 -3
- package/dist/commands/api-diff.command.d.ts.map +1 -1
- package/dist/commands/api-diff.command.js +12 -0
- package/dist/commands/apply.command.d.ts.map +1 -1
- package/dist/commands/apply.command.js +3 -0
- package/dist/commands/arch.command.d.ts.map +1 -1
- package/dist/commands/arch.command.js +26 -7
- package/dist/commands/architecture.command.d.ts.map +1 -1
- package/dist/commands/architecture.command.js +8 -2
- package/dist/commands/baseline.command.d.ts +76 -0
- package/dist/commands/baseline.command.d.ts.map +1 -1
- package/dist/commands/baseline.command.js +599 -75
- package/dist/commands/biome.command.d.ts.map +1 -1
- package/dist/commands/biome.command.js +20 -0
- package/dist/commands/boundaries.command.d.ts +9 -1
- package/dist/commands/boundaries.command.d.ts.map +1 -1
- package/dist/commands/boundaries.command.js +88 -20
- package/dist/commands/bundle.command.d.ts.map +1 -1
- package/dist/commands/bundle.command.js +57 -11
- package/dist/commands/cache-align.command.d.ts.map +1 -1
- package/dist/commands/cache-align.command.js +3 -1
- package/dist/commands/changelog-data.d.ts.map +1 -1
- package/dist/commands/changelog-data.js +164 -0
- package/dist/commands/changes.command.d.ts.map +1 -1
- package/dist/commands/changes.command.js +15 -0
- package/dist/commands/check.command.d.ts.map +1 -1
- package/dist/commands/check.command.js +1260 -324
- package/dist/commands/checks.command.d.ts.map +1 -1
- package/dist/commands/checks.command.js +188 -40
- package/dist/commands/ci.command.d.ts.map +1 -1
- package/dist/commands/ci.command.js +35 -2
- package/dist/commands/code-intel.command.d.ts.map +1 -1
- package/dist/commands/code-intel.command.js +8 -1
- package/dist/commands/command-catalog.d.ts +23 -1
- package/dist/commands/command-catalog.d.ts.map +1 -1
- package/dist/commands/command-catalog.js +152 -35
- package/dist/commands/commands.command.d.ts +21 -3
- package/dist/commands/commands.command.d.ts.map +1 -1
- package/dist/commands/commands.command.js +172 -27
- package/dist/commands/compress.command.d.ts.map +1 -1
- package/dist/commands/compress.command.js +4 -0
- package/dist/commands/constructs.command.d.ts.map +1 -1
- package/dist/commands/constructs.command.js +50 -12
- package/dist/commands/context.command.d.ts.map +1 -1
- package/dist/commands/context.command.js +40 -5
- package/dist/commands/contract-templates.command.d.ts.map +1 -1
- package/dist/commands/contract-templates.command.js +9 -1
- package/dist/commands/contract.command.d.ts.map +1 -1
- package/dist/commands/contract.command.js +35 -0
- package/dist/commands/conventions.command.d.ts.map +1 -1
- package/dist/commands/conventions.command.js +189 -29
- package/dist/commands/coverage.command.d.ts.map +1 -1
- package/dist/commands/coverage.command.js +9 -0
- package/dist/commands/daily.commands.d.ts +0 -1
- package/dist/commands/daily.commands.d.ts.map +1 -1
- package/dist/commands/daily.commands.js +12 -76
- package/dist/commands/dashboard.command.d.ts.map +1 -1
- package/dist/commands/dashboard.command.js +10 -0
- package/dist/commands/dev.command.d.ts.map +1 -1
- package/dist/commands/dev.command.js +45 -2
- package/dist/commands/diagnostics.command.d.ts +0 -2
- package/dist/commands/diagnostics.command.d.ts.map +1 -1
- package/dist/commands/diagnostics.command.js +5 -78
- package/dist/commands/diff-check.command.d.ts +6 -4
- package/dist/commands/diff-check.command.d.ts.map +1 -1
- package/dist/commands/diff-check.command.js +190 -103
- package/dist/commands/docs-references.command.d.ts +20 -0
- package/dist/commands/docs-references.command.d.ts.map +1 -0
- package/dist/commands/docs-references.command.js +520 -0
- package/dist/commands/doctor.command.d.ts.map +1 -1
- package/dist/commands/doctor.command.js +60 -5
- package/dist/commands/drift.command.d.ts.map +1 -1
- package/dist/commands/drift.command.js +17 -4
- package/dist/commands/eslint.command.d.ts.map +1 -1
- package/dist/commands/eslint.command.js +20 -0
- package/dist/commands/export.command.d.ts.map +1 -1
- package/dist/commands/export.command.js +23 -1
- package/dist/commands/feedback-dispatch.command.d.ts.map +1 -1
- package/dist/commands/feedback-dispatch.command.js +29 -0
- package/dist/commands/feedback.command.d.ts.map +1 -1
- package/dist/commands/feedback.command.js +6 -1
- package/dist/commands/finish.command.d.ts.map +1 -1
- package/dist/commands/finish.command.js +32 -8
- package/dist/commands/fix.command.d.ts.map +1 -1
- package/dist/commands/fix.command.js +19 -0
- package/dist/commands/gate.command.d.ts +6 -1
- package/dist/commands/gate.command.d.ts.map +1 -1
- package/dist/commands/gate.command.js +50 -124
- package/dist/commands/gates.command.d.ts +54 -0
- package/dist/commands/gates.command.d.ts.map +1 -1
- package/dist/commands/gates.command.js +1314 -64
- package/dist/commands/gen.command.d.ts.map +1 -1
- package/dist/commands/gen.command.js +4 -0
- package/dist/commands/generated.command.d.ts +62 -0
- package/dist/commands/generated.command.d.ts.map +1 -1
- package/dist/commands/generated.command.js +639 -156
- package/dist/commands/graph-code-subverbs.d.ts +15 -0
- package/dist/commands/graph-code-subverbs.d.ts.map +1 -1
- package/dist/commands/graph-code-subverbs.js +203 -25
- package/dist/commands/graph.command.d.ts.map +1 -1
- package/dist/commands/graph.command.js +79 -37
- package/dist/commands/help.command.d.ts +30 -6
- package/dist/commands/help.command.d.ts.map +1 -1
- package/dist/commands/help.command.js +323 -199
- package/dist/commands/helper.command.d.ts +1 -0
- package/dist/commands/helper.command.d.ts.map +1 -1
- package/dist/commands/helper.command.js +195 -56
- package/dist/commands/impact.command.d.ts.map +1 -1
- package/dist/commands/impact.command.js +115 -12
- package/dist/commands/infer.command.d.ts.map +1 -1
- package/dist/commands/infer.command.js +20 -45
- package/dist/commands/ingest.command.d.ts +0 -1
- package/dist/commands/ingest.command.d.ts.map +1 -1
- package/dist/commands/ingest.command.js +25 -41
- package/dist/commands/knowledge-author.command.d.ts +0 -3
- package/dist/commands/knowledge-author.command.d.ts.map +1 -1
- package/dist/commands/knowledge-author.command.js +10 -23
- package/dist/commands/knowledge.command.d.ts.map +1 -1
- package/dist/commands/knowledge.command.js +469 -129
- package/dist/commands/languages.command.d.ts.map +1 -1
- package/dist/commands/languages.command.js +27 -0
- package/dist/commands/lint.command.d.ts.map +1 -1
- package/dist/commands/lint.command.js +3 -0
- package/dist/commands/mcp.command.d.ts +18 -0
- package/dist/commands/mcp.command.d.ts.map +1 -1
- package/dist/commands/mcp.command.js +33 -8
- package/dist/commands/onboard.command.d.ts.map +1 -1
- package/dist/commands/onboard.command.js +20 -0
- package/dist/commands/owners.command.d.ts.map +1 -1
- package/dist/commands/owners.command.js +14 -2
- package/dist/commands/packs-new.d.ts +13 -1
- package/dist/commands/packs-new.d.ts.map +1 -1
- package/dist/commands/packs-new.js +500 -335
- package/dist/commands/packs.command.d.ts.map +1 -1
- package/dist/commands/packs.command.js +378 -36
- package/dist/commands/paths.command.d.ts.map +1 -1
- package/dist/commands/paths.command.js +9 -1
- package/dist/commands/pipelines.command.d.ts.map +1 -1
- package/dist/commands/pipelines.command.js +7 -1
- package/dist/commands/plan-check.command.d.ts.map +1 -1
- package/dist/commands/plan-check.command.js +3 -0
- package/dist/commands/plan.command.d.ts.map +1 -1
- package/dist/commands/plan.command.js +3 -0
- package/dist/commands/playbooks.command.d.ts.map +1 -1
- package/dist/commands/playbooks.command.js +7 -2
- package/dist/commands/policy-lint.command.d.ts +19 -2
- package/dist/commands/policy-lint.command.d.ts.map +1 -1
- package/dist/commands/policy-lint.command.js +224 -65
- package/dist/commands/policy.command.d.ts.map +1 -1
- package/dist/commands/policy.command.js +6 -1
- package/dist/commands/pr.command.d.ts.map +1 -1
- package/dist/commands/pr.command.js +14 -0
- package/dist/commands/presets.command.d.ts.map +1 -1
- package/dist/commands/presets.command.js +12 -27
- package/dist/commands/profiles.command.d.ts.map +1 -1
- package/dist/commands/profiles.command.js +94 -26
- package/dist/commands/provenance.command.js +1 -1
- package/dist/commands/quality.command.d.ts.map +1 -1
- package/dist/commands/quality.command.js +129 -33
- package/dist/commands/recommend.command.d.ts +20 -4
- package/dist/commands/recommend.command.d.ts.map +1 -1
- package/dist/commands/recommend.command.js +172 -278
- package/dist/commands/registrations.command.d.ts.map +1 -1
- package/dist/commands/registrations.command.js +138 -13
- package/dist/commands/registry-lifecycle-run.d.ts +14 -0
- package/dist/commands/registry-lifecycle-run.d.ts.map +1 -0
- package/dist/commands/registry-lifecycle-run.js +336 -0
- package/dist/commands/registry.command.d.ts.map +1 -1
- package/dist/commands/registry.command.js +235 -62
- package/dist/commands/release.command.d.ts.map +1 -1
- package/dist/commands/release.command.js +99 -20
- package/dist/commands/report.command.d.ts.map +1 -1
- package/dist/commands/report.command.js +38 -2
- package/dist/commands/reuse-coverage.command.d.ts +23 -0
- package/dist/commands/reuse-coverage.command.d.ts.map +1 -0
- package/dist/commands/reuse-coverage.command.js +536 -0
- package/dist/commands/reuse.command.d.ts +3 -18
- package/dist/commands/reuse.command.d.ts.map +1 -1
- package/dist/commands/reuse.command.js +395 -244
- package/dist/commands/review.command.d.ts.map +1 -1
- package/dist/commands/review.command.js +33 -1
- package/dist/commands/rounds.command.d.ts.map +1 -1
- package/dist/commands/rounds.command.js +5 -0
- package/dist/commands/safety.command.d.ts.map +1 -1
- package/dist/commands/safety.command.js +9 -0
- package/dist/commands/scaffolds.command.d.ts.map +1 -1
- package/dist/commands/scaffolds.command.js +97 -25
- package/dist/commands/search.command.d.ts +0 -8
- package/dist/commands/search.command.d.ts.map +1 -1
- package/dist/commands/search.command.js +136 -28
- package/dist/commands/self-config-xrefs.command.d.ts +24 -0
- package/dist/commands/self-config-xrefs.command.d.ts.map +1 -0
- package/dist/commands/self-config-xrefs.command.js +170 -0
- package/dist/commands/self-config.command.d.ts.map +1 -1
- package/dist/commands/self-config.command.js +261 -65
- package/dist/commands/smart-context.command.d.ts.map +1 -1
- package/dist/commands/smart-context.command.js +39 -3
- package/dist/commands/spec.command.d.ts.map +1 -1
- package/dist/commands/spec.command.js +3 -0
- package/dist/commands/stats.command.d.ts.map +1 -1
- package/dist/commands/stats.command.js +3 -0
- package/dist/commands/surface.command.d.ts +6 -1
- package/dist/commands/surface.command.d.ts.map +1 -1
- package/dist/commands/surface.command.js +256 -54
- package/dist/commands/task-context.command.js +1 -1
- package/dist/commands/task.command.d.ts.map +1 -1
- package/dist/commands/task.command.js +22 -1
- package/dist/commands/templates.command.d.ts +4 -0
- package/dist/commands/templates.command.d.ts.map +1 -1
- package/dist/commands/templates.command.js +109 -22
- package/dist/commands/test.command.d.ts.map +1 -1
- package/dist/commands/test.command.js +161 -33
- package/dist/commands/tests.command.d.ts.map +1 -1
- package/dist/commands/tests.command.js +29 -3
- package/dist/commands/trace.command.d.ts.map +1 -1
- package/dist/commands/trace.command.js +29 -4
- package/dist/commands/watch.command.d.ts.map +1 -1
- package/dist/commands/watch.command.js +3 -0
- package/dist/commands/why.command.d.ts.map +1 -1
- package/dist/commands/why.command.js +3 -0
- package/dist/commands/wiring.command.d.ts +18 -4
- package/dist/commands/wiring.command.d.ts.map +1 -1
- package/dist/commands/wiring.command.js +362 -74
- package/dist/dashboard/code-intelligence-data.js +4 -4
- package/dist/diff/deleted-orphan-coverage.d.ts +32 -0
- package/dist/diff/deleted-orphan-coverage.d.ts.map +1 -0
- package/dist/diff/deleted-orphan-coverage.js +107 -0
- package/dist/diff/deleted-orphan-scope-notes.d.ts +23 -0
- package/dist/diff/deleted-orphan-scope-notes.d.ts.map +1 -0
- package/dist/diff/deleted-orphan-scope-notes.js +49 -0
- package/dist/diff/deleted-orphans.d.ts +32 -0
- package/dist/diff/deleted-orphans.d.ts.map +1 -1
- package/dist/diff/deleted-orphans.js +42 -2
- package/dist/dispatch/closest-match.d.ts +15 -0
- package/dist/dispatch/closest-match.d.ts.map +1 -0
- package/dist/dispatch/closest-match.js +47 -0
- package/dist/dispatch/global-flags.d.ts +94 -0
- package/dist/dispatch/global-flags.d.ts.map +1 -0
- package/dist/dispatch/global-flags.js +123 -0
- package/dist/dispatch/guard-invocation-input.d.ts +24 -0
- package/dist/dispatch/guard-invocation-input.d.ts.map +1 -0
- package/dist/dispatch/guard-invocation-input.js +1 -0
- package/dist/dispatch/guard-invocation.d.ts +33 -0
- package/dist/dispatch/guard-invocation.d.ts.map +1 -0
- package/dist/dispatch/guard-invocation.js +183 -0
- package/dist/dispatch/help-intercept.d.ts +22 -0
- package/dist/dispatch/help-intercept.d.ts.map +1 -0
- package/dist/dispatch/help-intercept.js +42 -0
- package/dist/dispatch/i-declared-invocation.d.ts +17 -0
- package/dist/dispatch/i-declared-invocation.d.ts.map +1 -0
- package/dist/dispatch/i-declared-invocation.js +1 -0
- package/dist/dispatch/i-unknown-flag-refusal-input.d.ts +28 -0
- package/dist/dispatch/i-unknown-flag-refusal-input.d.ts.map +1 -0
- package/dist/dispatch/i-unknown-flag-refusal-input.js +1 -0
- package/dist/dispatch/invocation-rejection-kind.d.ts +15 -0
- package/dist/dispatch/invocation-rejection-kind.d.ts.map +1 -0
- package/dist/dispatch/invocation-rejection-kind.js +15 -0
- package/dist/dispatch/invocation-rejection.d.ts +18 -0
- package/dist/dispatch/invocation-rejection.d.ts.map +1 -0
- package/dist/dispatch/invocation-rejection.js +1 -0
- package/dist/dispatch/judge-invocation.d.ts +24 -0
- package/dist/dispatch/judge-invocation.d.ts.map +1 -0
- package/dist/dispatch/judge-invocation.js +50 -0
- package/dist/dispatch/positional-mode.d.ts +18 -0
- package/dist/dispatch/positional-mode.d.ts.map +1 -0
- package/dist/dispatch/positional-mode.js +18 -0
- package/dist/dispatch/read-tracking-map.d.ts +28 -0
- package/dist/dispatch/read-tracking-map.d.ts.map +1 -0
- package/dist/dispatch/read-tracking-map.js +58 -0
- package/dist/dispatch/refuse-sibling-valve-flags.d.ts +30 -0
- package/dist/dispatch/refuse-sibling-valve-flags.d.ts.map +1 -0
- package/dist/dispatch/refuse-sibling-valve-flags.js +65 -0
- package/dist/dispatch/subverb-spec.d.ts +26 -0
- package/dist/dispatch/subverb-spec.d.ts.map +1 -0
- package/dist/dispatch/subverb-spec.js +1 -0
- package/dist/dispatch/undocumented-flag-reads.d.ts +22 -0
- package/dist/dispatch/undocumented-flag-reads.d.ts.map +1 -0
- package/dist/dispatch/undocumented-flag-reads.js +283 -0
- package/dist/dispatch/unknown-flag-refusal-mode.d.ts +13 -0
- package/dist/dispatch/unknown-flag-refusal-mode.d.ts.map +1 -0
- package/dist/dispatch/unknown-flag-refusal-mode.js +13 -0
- package/dist/dispatch/unknown-flag-refusal.d.ts +22 -0
- package/dist/dispatch/unknown-flag-refusal.d.ts.map +1 -0
- package/dist/dispatch/unknown-flag-refusal.js +57 -0
- package/dist/dispatch/unread-flags.d.ts +152 -0
- package/dist/dispatch/unread-flags.d.ts.map +1 -0
- package/dist/dispatch/unread-flags.js +295 -0
- package/dist/dispatch/verdict-valve-flag.d.ts +21 -0
- package/dist/dispatch/verdict-valve-flag.d.ts.map +1 -0
- package/dist/dispatch/verdict-valve-flag.js +21 -0
- package/dist/dispatch/walk-declared-subverbs.d.ts +14 -0
- package/dist/dispatch/walk-declared-subverbs.d.ts.map +1 -0
- package/dist/dispatch/walk-declared-subverbs.js +28 -0
- package/dist/exit-codes.d.ts +41 -3
- package/dist/exit-codes.d.ts.map +1 -1
- package/dist/exit-codes.js +153 -14
- package/dist/finish/run-finish.d.ts +72 -5
- package/dist/finish/run-finish.d.ts.map +1 -1
- package/dist/finish/run-finish.js +453 -104
- package/dist/gates/accepted-empty-note.d.ts +10 -0
- package/dist/gates/accepted-empty-note.d.ts.map +1 -0
- package/dist/gates/accepted-empty-note.js +11 -0
- package/dist/gates/allow-empty.d.ts +25 -0
- package/dist/gates/allow-empty.d.ts.map +1 -0
- package/dist/gates/allow-empty.js +27 -0
- package/dist/gates/asset-doctor-failing-units.d.ts +16 -0
- package/dist/gates/asset-doctor-failing-units.d.ts.map +1 -0
- package/dist/gates/asset-doctor-failing-units.js +14 -0
- package/dist/gates/asset-doctor-failure-line.d.ts +16 -0
- package/dist/gates/asset-doctor-failure-line.d.ts.map +1 -0
- package/dist/gates/asset-doctor-failure-line.js +28 -0
- package/dist/gates/empty-rule-advice-lines.d.ts +15 -0
- package/dist/gates/empty-rule-advice-lines.d.ts.map +1 -0
- package/dist/gates/empty-rule-advice-lines.js +20 -0
- package/dist/gates/gate-envelope.d.ts +85 -8
- package/dist/gates/gate-envelope.d.ts.map +1 -1
- package/dist/gates/gate-envelope.js +56 -7
- package/dist/gates/gate-rule-globs.d.ts +67 -0
- package/dist/gates/gate-rule-globs.d.ts.map +1 -0
- package/dist/gates/gate-rule-globs.js +139 -0
- package/dist/gates/gate-rule-view.d.ts +25 -6
- package/dist/gates/gate-rule-view.d.ts.map +1 -1
- package/dist/gates/gate-rule-view.js +105 -77
- package/dist/gates/i-coverage-dead-glob.d.ts +19 -0
- package/dist/gates/i-coverage-dead-glob.d.ts.map +1 -0
- package/dist/gates/i-coverage-dead-glob.js +1 -0
- package/dist/gates/i-coverage-negation.d.ts +13 -0
- package/dist/gates/i-coverage-negation.d.ts.map +1 -0
- package/dist/gates/i-coverage-negation.js +1 -0
- package/dist/gates/i-registration-query-settle-input.d.ts +18 -0
- package/dist/gates/i-registration-query-settle-input.d.ts.map +1 -0
- package/dist/gates/i-registration-query-settle-input.js +1 -0
- package/dist/gates/i-unit-state-note-row.d.ts +16 -0
- package/dist/gates/i-unit-state-note-row.d.ts.map +1 -0
- package/dist/gates/i-unit-state-note-row.js +1 -0
- package/dist/gates/i-unit-state-notes.d.ts +32 -0
- package/dist/gates/i-unit-state-notes.d.ts.map +1 -0
- package/dist/gates/i-unit-state-notes.js +1 -0
- package/dist/gates/incomplete-registry-inventory.d.ts +19 -0
- package/dist/gates/incomplete-registry-inventory.d.ts.map +1 -0
- package/dist/gates/incomplete-registry-inventory.js +63 -0
- package/dist/gates/measure-registration-roles.d.ts +10 -0
- package/dist/gates/measure-registration-roles.d.ts.map +1 -0
- package/dist/gates/measure-registration-roles.js +9 -0
- package/dist/gates/plane-verdict.d.ts +14 -0
- package/dist/gates/plane-verdict.d.ts.map +1 -0
- package/dist/gates/plane-verdict.js +22 -0
- package/dist/gates/qualify-clean-for-units.d.ts +12 -0
- package/dist/gates/qualify-clean-for-units.d.ts.map +1 -0
- package/dist/gates/qualify-clean-for-units.js +18 -0
- package/dist/gates/registration-graph-verdict.d.ts +34 -0
- package/dist/gates/registration-graph-verdict.d.ts.map +1 -0
- package/dist/gates/registration-graph-verdict.js +70 -0
- package/dist/gates/registration-roles.d.ts +9 -0
- package/dist/gates/registration-roles.d.ts.map +1 -0
- package/dist/gates/registration-roles.js +1 -0
- package/dist/gates/registry-liveness.d.ts +11 -0
- package/dist/gates/registry-liveness.d.ts.map +1 -0
- package/dist/gates/registry-liveness.js +13 -0
- package/dist/gates/rule-coverage.d.ts +225 -4
- package/dist/gates/rule-coverage.d.ts.map +1 -1
- package/dist/gates/rule-coverage.js +610 -43
- package/dist/gates/run-gate-planes.d.ts +58 -0
- package/dist/gates/run-gate-planes.d.ts.map +1 -0
- package/dist/gates/run-gate-planes.js +403 -0
- package/dist/gates/scaffold-selftest.d.ts +56 -0
- package/dist/gates/scaffold-selftest.d.ts.map +1 -0
- package/dist/gates/scaffold-selftest.js +119 -0
- package/dist/gates/seam-rejected-rules.d.ts +28 -0
- package/dist/gates/seam-rejected-rules.d.ts.map +1 -0
- package/dist/gates/seam-rejected-rules.js +95 -0
- package/dist/gates/self-test-check.d.ts +29 -0
- package/dist/gates/self-test-check.d.ts.map +1 -0
- package/dist/gates/self-test-check.js +1 -0
- package/dist/gates/self-test-subject.d.ts +28 -0
- package/dist/gates/self-test-subject.d.ts.map +1 -0
- package/dist/gates/self-test-subject.js +1 -0
- package/dist/gates/self-test.d.ts +20 -0
- package/dist/gates/self-test.d.ts.map +1 -0
- package/dist/gates/self-test.js +82 -0
- package/dist/gates/settle-verdict.d.ts +14 -0
- package/dist/gates/settle-verdict.d.ts.map +1 -0
- package/dist/gates/settle-verdict.js +13 -0
- package/dist/gates/settled-verdict.d.ts +8 -0
- package/dist/gates/settled-verdict.d.ts.map +1 -0
- package/dist/gates/settled-verdict.js +1 -0
- package/dist/gates/template-registry-coverage.d.ts +18 -0
- package/dist/gates/template-registry-coverage.d.ts.map +1 -0
- package/dist/gates/template-registry-coverage.js +24 -0
- package/dist/gates/unit-state-notes.d.ts +40 -0
- package/dist/gates/unit-state-notes.d.ts.map +1 -0
- package/dist/gates/unit-state-notes.js +71 -0
- package/dist/gates/verdict-line.d.ts +18 -0
- package/dist/gates/verdict-line.d.ts.map +1 -0
- package/dist/gates/verdict-line.js +40 -0
- package/dist/graph/graph-reuse-lookup.d.ts +10 -0
- package/dist/graph/graph-reuse-lookup.d.ts.map +1 -0
- package/dist/graph/graph-reuse-lookup.js +41 -0
- package/dist/graph/index-behind-hint.d.ts +11 -0
- package/dist/graph/index-behind-hint.d.ts.map +1 -0
- package/dist/graph/index-behind-hint.js +27 -0
- package/dist/knowledge/knowledge-stale-gate-flags.d.ts +3 -0
- package/dist/knowledge/knowledge-stale-gate-flags.d.ts.map +1 -0
- package/dist/knowledge/knowledge-stale-gate-flags.js +1 -0
- package/dist/knowledge/knowledge-stale-gate-input.d.ts +3 -0
- package/dist/knowledge/knowledge-stale-gate-input.d.ts.map +1 -0
- package/dist/knowledge/knowledge-stale-gate-input.js +1 -0
- package/dist/knowledge/knowledge-stale-gate-result.d.ts +3 -0
- package/dist/knowledge/knowledge-stale-gate-result.d.ts.map +1 -0
- package/dist/knowledge/knowledge-stale-gate-result.js +1 -0
- package/dist/knowledge/knowledge-stale-gate.d.ts +10 -0
- package/dist/knowledge/knowledge-stale-gate.d.ts.map +1 -0
- package/dist/knowledge/knowledge-stale-gate.js +9 -0
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +204 -83
- package/dist/output/failure-hints.d.ts.map +1 -1
- package/dist/output/failure-hints.js +11 -9
- package/dist/output/rejected-entries-note.d.ts +57 -0
- package/dist/output/rejected-entries-note.d.ts.map +1 -0
- package/dist/output/rejected-entries-note.js +103 -0
- package/dist/output/stdout-is-pipe.d.ts +13 -0
- package/dist/output/stdout-is-pipe.d.ts.map +1 -0
- package/dist/output/stdout-is-pipe.js +21 -0
- package/dist/packs/stale-build-warning.d.ts +11 -0
- package/dist/packs/stale-build-warning.d.ts.map +1 -0
- package/dist/packs/stale-build-warning.js +23 -0
- package/dist/quality/run-quality.d.ts +123 -0
- package/dist/quality/run-quality.d.ts.map +1 -0
- package/dist/quality/run-quality.js +442 -0
- package/dist/schemas/json-schemas.d.ts +184 -3
- package/dist/schemas/json-schemas.d.ts.map +1 -1
- package/dist/schemas/json-schemas.js +113 -2
- package/dist/shrk.d.ts +3 -0
- package/dist/shrk.d.ts.map +1 -0
- package/dist/shrk.js +30 -0
- package/dist/surface/audience-applicability.d.ts +26 -0
- package/dist/surface/audience-applicability.d.ts.map +1 -0
- package/dist/surface/audience-applicability.js +60 -0
- package/dist/surface/catalog-command-safety.d.ts +18 -0
- package/dist/surface/catalog-command-safety.d.ts.map +1 -0
- package/dist/surface/catalog-command-safety.js +62 -0
- package/dist/surface/cli-command-resolver.d.ts +21 -0
- package/dist/surface/cli-command-resolver.d.ts.map +1 -0
- package/dist/surface/cli-command-resolver.js +87 -0
- package/dist/surface/command-dispatch-kind.d.ts +20 -0
- package/dist/surface/command-dispatch-kind.d.ts.map +1 -0
- package/dist/surface/command-dispatch-kind.js +20 -0
- package/dist/surface/command-index-entry.d.ts +40 -0
- package/dist/surface/command-index-entry.d.ts.map +1 -0
- package/dist/surface/command-index-entry.js +1 -0
- package/dist/surface/command-index.d.ts +77 -0
- package/dist/surface/command-index.d.ts.map +1 -0
- package/dist/surface/command-index.js +323 -0
- package/dist/surface/i-command-index.d.ts +22 -0
- package/dist/surface/i-command-index.d.ts.map +1 -0
- package/dist/surface/i-command-index.js +1 -0
- package/dist/surface/i-command-string-context.d.ts +20 -0
- package/dist/surface/i-command-string-context.d.ts.map +1 -0
- package/dist/surface/i-command-string-context.js +1 -0
- package/dist/surface/i-surface-denial.d.ts +13 -0
- package/dist/surface/i-surface-denial.d.ts.map +1 -0
- package/dist/surface/i-surface-denial.js +1 -0
- package/dist/surface/load-surface-context.d.ts +17 -1
- package/dist/surface/load-surface-context.d.ts.map +1 -1
- package/dist/surface/load-surface-context.js +48 -10
- package/dist/surface/not-enabled-error.d.ts +38 -4
- package/dist/surface/not-enabled-error.d.ts.map +1 -1
- package/dist/surface/not-enabled-error.js +96 -6
- package/dist/surface/profiles.d.ts +7 -0
- package/dist/surface/profiles.d.ts.map +1 -1
- package/dist/surface/resolve-command-string.d.ts +10 -0
- package/dist/surface/resolve-command-string.d.ts.map +1 -0
- package/dist/surface/resolve-command-string.js +572 -0
- package/dist/surface/surface-config-writer.d.ts +7 -2
- package/dist/surface/surface-config-writer.d.ts.map +1 -1
- package/dist/surface/surface-config-writer.js +25 -6
- package/dist/surface/surface-layer.d.ts +11 -0
- package/dist/surface/surface-layer.d.ts.map +1 -0
- package/dist/surface/surface-layer.js +11 -0
- package/dist/surface/surface-refusal-reason.d.ts +16 -0
- package/dist/surface/surface-refusal-reason.d.ts.map +1 -0
- package/dist/surface/surface-refusal-reason.js +16 -0
- package/dist/surface/surface-selector.d.ts +26 -0
- package/dist/surface/surface-selector.d.ts.map +1 -0
- package/dist/surface/surface-selector.js +42 -0
- package/dist/surface/surface-summary.d.ts +61 -18
- package/dist/surface/surface-summary.d.ts.map +1 -1
- package/dist/surface/surface-summary.js +147 -60
- package/dist/surface/tier.d.ts +85 -22
- package/dist/surface/tier.d.ts.map +1 -1
- package/dist/surface/tier.js +132 -30
- package/dist/usage/usage-log.d.ts +6 -1
- package/dist/usage/usage-log.d.ts.map +1 -1
- package/dist/usage/usage-log.js +7 -2
- package/dist/validation/run-validation-loop.d.ts +9 -0
- package/dist/validation/run-validation-loop.d.ts.map +1 -1
- package/dist/validation/run-validation-loop.js +14 -11
- package/dist/validation/typecheck-emitted.d.ts +8 -9
- package/dist/validation/typecheck-emitted.d.ts.map +1 -1
- package/dist/validation/typecheck-emitted.js +17 -97
- package/package.json +34 -34
|
@@ -1,19 +1,119 @@
|
|
|
1
1
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
2
2
|
import { join as nodePathJoin, resolve as nodePathResolve } from 'node:path';
|
|
3
|
-
import { buildAnchorUpdatePlan, buildKnowledgeStaleReport, buildRenameFilePlan, buildRenameSymbolPlan, inspectSharkcraft, ReferenceCheckOutcome, resolveChangedFiles, } from '@shrkcrft/inspector';
|
|
4
|
-
import { ALL_KNOWLEDGE_TYPES, formatEntryCompact, formatEntryFull, isKnowledgeType, projectKnowledgeEntryForJson, searchKnowledge, } from '@shrkcrft/knowledge';
|
|
5
|
-
import {
|
|
3
|
+
import { buildAnchorUpdatePlan, buildKnowledgeRefResolver, buildKnowledgeStaleReport, buildRenameFilePlan, buildRenameSymbolPlan, ContributionKind, describeInspectionDiscovery, inspectSharkcraft, KnowledgeAdvisoryCode, KnowledgeEntryVerdict, ReferenceAssetKind, ReferenceCheckOutcome, resolveChangedFiles, } from '@shrkcrft/inspector';
|
|
4
|
+
import { ALL_KNOWLEDGE_TYPES, formatEntryCompact, formatEntryFull, formatKnowledgeReference, isKnowledgeType, isValidVerifiedOn, parseStaleAfterDays, projectKnowledgeEntryForJson, searchKnowledge, } from '@shrkcrft/knowledge';
|
|
5
|
+
import { writeRejectedEntriesNote } from "../output/rejected-entries-note.js";
|
|
6
|
+
/** Every contribution kind the knowledge loader reads (knowledge, rules, paths, docs). */
|
|
7
|
+
const KNOWLEDGE_FAMILY_KINDS = [
|
|
8
|
+
ContributionKind.Knowledge,
|
|
9
|
+
ContributionKind.Rule,
|
|
10
|
+
ContributionKind.Path,
|
|
11
|
+
ContributionKind.PathConvention,
|
|
12
|
+
ContributionKind.Docs,
|
|
13
|
+
];
|
|
14
|
+
import { flagBool, flagNumber, flagString, flagList, requireInputSelector, resolveCwd, } from "../command-registry.js";
|
|
6
15
|
import { asJson, header } from "../output/format-output.js";
|
|
7
16
|
import { maybeRunInWatchMode } from "../output/watch-loop.js";
|
|
8
17
|
import { renderFailureHints, staleKnowledgeHints } from "../output/failure-hints.js";
|
|
9
|
-
|
|
18
|
+
import { ExitCode } from "../exit-codes.js";
|
|
19
|
+
import { ALLOW_EMPTY_FLAG, allowEmptyValve } from "../gates/allow-empty.js";
|
|
20
|
+
import { buildGateEnvelope } from "../gates/gate-envelope.js";
|
|
21
|
+
import { verdictLine } from "../gates/verdict-line.js";
|
|
22
|
+
import { evaluateKnowledgeStaleGate, formatPct, KNOWLEDGE_FAIL_ON_CATEGORIES, knowledgeStaleGateInput, knowledgeStaleWindowProblem, parseMinReferenced, } from "../knowledge/knowledge-stale-gate.js";
|
|
23
|
+
/** Unverifiable ids shown in text / markdown before the rest are summarised. */
|
|
24
|
+
const UNVERIFIABLE_SHOWN = 50;
|
|
25
|
+
/**
|
|
26
|
+
* The three buckets, with the unverifiable share — on the line where a bare
|
|
27
|
+
* `0 stale` used to sit, so a corpus checked a quarter of the way can never
|
|
28
|
+
* summarise as healthy.
|
|
29
|
+
*/
|
|
30
|
+
function bucketLine(r) {
|
|
31
|
+
const c = r.coverage;
|
|
32
|
+
const pct = c.entriesInScope > 0 ? formatPct(c.unverifiable / c.entriesInScope) : '0%';
|
|
33
|
+
return `entries in scope: ${c.entriesInScope} · verified: ${c.verified} · stale: ${c.stale} · unverifiable: ${c.unverifiable} (${pct})`;
|
|
34
|
+
}
|
|
35
|
+
/** Unverifiable entry ids grouped by the file that declares them — the file to edit. */
|
|
36
|
+
function unverifiableGroups(r) {
|
|
37
|
+
const by = new Map();
|
|
38
|
+
for (const v of r.entryVerdicts) {
|
|
39
|
+
if (v.verdict !== KnowledgeEntryVerdict.Unverifiable)
|
|
40
|
+
continue;
|
|
41
|
+
const list = by.get(v.source) ?? [];
|
|
42
|
+
list.push(v.entryId);
|
|
43
|
+
by.set(v.source, list);
|
|
44
|
+
}
|
|
45
|
+
return [...by.entries()].map(([source, ids]) => ({ source, ids }));
|
|
46
|
+
}
|
|
47
|
+
/** `sharkcraft/rules.ts (7): a, b, …` lines, capped across groups. */
|
|
48
|
+
function unverifiableLines(r, indent) {
|
|
49
|
+
const out = [];
|
|
50
|
+
let shown = 0;
|
|
51
|
+
for (const g of unverifiableGroups(r)) {
|
|
52
|
+
const room = UNVERIFIABLE_SHOWN - shown;
|
|
53
|
+
if (room <= 0)
|
|
54
|
+
break;
|
|
55
|
+
const ids = g.ids.slice(0, room);
|
|
56
|
+
shown += ids.length;
|
|
57
|
+
out.push(`${indent}${g.source} (${g.ids.length}): ${ids.join(', ')}${ids.length < g.ids.length ? ', …' : ''}`);
|
|
58
|
+
}
|
|
59
|
+
const rest = r.unverifiableIds.length - shown;
|
|
60
|
+
if (rest > 0)
|
|
61
|
+
out.push(`${indent}… ${rest} more (--json for all)`);
|
|
62
|
+
return out;
|
|
63
|
+
}
|
|
64
|
+
/** Load failures listed in text / markdown before the rest are summarised. */
|
|
65
|
+
const LOAD_FAILURES_SHOWN = 50;
|
|
66
|
+
/**
|
|
67
|
+
* `LOAD FAILED (N)` — the knowledge-bearing files whose entries never reached
|
|
68
|
+
* the corpus. Printed at ANY corpus size: a clean sweep of the rest is not a
|
|
69
|
+
* verdict over these.
|
|
70
|
+
*/
|
|
71
|
+
function loadFailureLines(d, indent) {
|
|
72
|
+
const failed = d.knowledgeLoadFailures;
|
|
73
|
+
if (failed.length === 0)
|
|
74
|
+
return [];
|
|
75
|
+
const out = [
|
|
76
|
+
`LOAD FAILED (${failed.length} of ${Math.max(d.knowledgeFilesAttempted, failed.length)} knowledge files) — their entries were never checked:`,
|
|
77
|
+
];
|
|
78
|
+
for (const f of failed.slice(0, LOAD_FAILURES_SHOWN)) {
|
|
79
|
+
out.push(`${indent}${f.status.toUpperCase().padEnd(14)}${f.kind.padEnd(10)}${f.file}${f.packName ? ` (pack ${f.packName})` : ''} — ${f.message}`);
|
|
80
|
+
}
|
|
81
|
+
if (failed.length > LOAD_FAILURES_SHOWN)
|
|
82
|
+
out.push(`${indent}… ${failed.length - LOAD_FAILURES_SHOWN} more (--json for all)`);
|
|
83
|
+
out.push('');
|
|
84
|
+
return out;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* The per-kind table. A kind the sweep never visited says so in words — a row
|
|
88
|
+
* of zeros cannot tell "clean" from "never looked".
|
|
89
|
+
*/
|
|
90
|
+
function kindTableLines(r) {
|
|
91
|
+
const cols = (b) => [b.scanned, b.zeroReferences, b.referencesChecked, b.verified, b.stale, b.unverifiable]
|
|
92
|
+
.map((n, i) => String(n).padStart(i === 0 ? 7 : i === 1 ? 10 : i === 2 ? 5 : i === 3 ? 9 : i === 4 ? 6 : 13))
|
|
93
|
+
.join('');
|
|
94
|
+
const row = (label, b, empty) => b.scanned === 0 ? ` ${label.padEnd(22)}${empty}` : ` ${label.padEnd(22)}${cols(b)}`;
|
|
95
|
+
const lines = [` ${'kind'.padEnd(22)}scanned zero-refs refs verified stale unverifiable`];
|
|
96
|
+
lines.push(row('knowledge', r.byAssetKind[ReferenceAssetKind.Knowledge], 'none in scope'));
|
|
97
|
+
for (const type of Object.keys(r.byEntryType).sort()) {
|
|
98
|
+
lines.push(row(` type:${type}`, r.byEntryType[type], 'none in scope'));
|
|
99
|
+
}
|
|
100
|
+
lines.push(row('boundary-rule', r.byAssetKind[ReferenceAssetKind.BoundaryRule], 'none declared'));
|
|
101
|
+
lines.push(r.policySweep.loaded
|
|
102
|
+
? row('policy', r.byAssetKind[ReferenceAssetKind.Policy], 'none declared')
|
|
103
|
+
: ` ${'policy'.padEnd(22)}not in sweep (policy registry not loaded)`);
|
|
104
|
+
return lines;
|
|
105
|
+
}
|
|
106
|
+
function refLabel(c) {
|
|
107
|
+
return formatKnowledgeReference(c.reference);
|
|
108
|
+
}
|
|
109
|
+
function renderStaleCheckMarkdown(p, verdict) {
|
|
10
110
|
const out = [];
|
|
11
111
|
out.push(`# Knowledge stale-check`);
|
|
12
112
|
out.push('');
|
|
13
|
-
out.push(`-
|
|
113
|
+
out.push(`- ${bucketLine(p)}`);
|
|
14
114
|
out.push(`- references: ${p.totalReferences}`);
|
|
15
115
|
out.push(`- anchors: ${p.totalAnchors}`);
|
|
16
|
-
out.push(`- counts: ok=${p.counts.ok}, stale=${p.counts.stale}, missing=${p.counts.missing}, unknown=${p.counts.unknown}`);
|
|
116
|
+
out.push(`- counts: ok=${p.counts.ok}, stale=${p.counts.stale}, missing=${p.counts.missing}, unknown=${p.counts.unknown}, invalid=${p.counts.invalid}`);
|
|
17
117
|
if (p.ci.ci || p.ci.strict || p.ci.failOn.length > 0) {
|
|
18
118
|
out.push(`- required failing: ${p.ci.totalRequiredFailing} (stale=${p.ci.requiredStale}, missing=${p.ci.requiredMissing})`);
|
|
19
119
|
}
|
|
@@ -21,34 +121,64 @@ function renderStaleCheckMarkdown(p) {
|
|
|
21
121
|
out.push(`- baseline (${p.baselineComparison.baseline}): new-stale=${p.baselineComparison.newStale}, new-missing=${p.baselineComparison.newMissing}, resolved=${p.baselineComparison.resolved}`);
|
|
22
122
|
}
|
|
23
123
|
out.push('');
|
|
124
|
+
out.push('```');
|
|
125
|
+
for (const line of kindTableLines(p))
|
|
126
|
+
out.push(line);
|
|
127
|
+
out.push('```');
|
|
128
|
+
const loadFailed = loadFailureLines(p.discovery, '- ').filter((l) => l !== '');
|
|
129
|
+
if (loadFailed.length > 0) {
|
|
130
|
+
out.push('');
|
|
131
|
+
out.push(`## ${loadFailed[0]}`);
|
|
132
|
+
for (const line of loadFailed.slice(1))
|
|
133
|
+
out.push(line);
|
|
134
|
+
}
|
|
135
|
+
if (p.coverage.unverifiable > 0) {
|
|
136
|
+
out.push('');
|
|
137
|
+
out.push(`## Unverifiable entries (${p.coverage.unverifiable}) — declare references[]`);
|
|
138
|
+
for (const line of unverifiableLines(p, '- '))
|
|
139
|
+
out.push(line);
|
|
140
|
+
}
|
|
141
|
+
out.push('');
|
|
24
142
|
out.push(`## Reference issues`);
|
|
25
|
-
for (const c of p.referenceChecks) {
|
|
143
|
+
for (const c of [...p.referenceChecks, ...p.assetReferenceChecks]) {
|
|
26
144
|
if (c.outcome === 'ok')
|
|
27
145
|
continue;
|
|
28
146
|
const req = c.reference.required ? ' **(required)**' : '';
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
if (p.ci.exitNonZero && p.ci.exitReason) {
|
|
32
|
-
out.push('');
|
|
33
|
-
out.push(`> FAIL: ${p.ci.exitReason}`);
|
|
147
|
+
const kind = c.assetKind ? ` [${c.implicit ? 'implicit ' : ''}${c.assetKind}]` : '';
|
|
148
|
+
out.push(`- **${c.outcome.toUpperCase()}**${req}${kind} \`${c.entryId}\` → \`${refLabel(c)}\` — ${c.message}`);
|
|
34
149
|
}
|
|
35
150
|
out.push('');
|
|
151
|
+
for (const line of verdict.split('\n'))
|
|
152
|
+
out.push(`> ${line}`);
|
|
153
|
+
out.push('');
|
|
36
154
|
return out.join('\n');
|
|
37
155
|
}
|
|
38
|
-
function renderStaleCheckHtml(p) {
|
|
156
|
+
function renderStaleCheckHtml(p, verdict) {
|
|
39
157
|
const esc = (s) => s.replace(/[&<>"']/g, (c) => ({ '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' }[c]));
|
|
40
158
|
const rows = [];
|
|
41
|
-
for (const c of p.referenceChecks) {
|
|
159
|
+
for (const c of [...p.referenceChecks, ...p.assetReferenceChecks]) {
|
|
42
160
|
if (c.outcome === 'ok')
|
|
43
161
|
continue;
|
|
44
|
-
rows.push(`<tr><td>${esc(c.outcome.toUpperCase())}</td><td>${c.reference.required ? '✓' : ''}</td><td>${esc(c.entryId)}</td><td>${esc(
|
|
162
|
+
rows.push(`<tr><td>${esc(c.outcome.toUpperCase())}</td><td>${c.reference.required ? '✓' : ''}</td><td>${esc(c.entryId)}</td><td>${esc(refLabel(c))}</td><td>${esc(c.message)}</td></tr>`);
|
|
45
163
|
}
|
|
164
|
+
const unverifiable = unverifiableLines(p, '').map((l) => `<li>${esc(l)}</li>`).join('');
|
|
165
|
+
const loadFailedLines = loadFailureLines(p.discovery, '').filter((l) => l !== '');
|
|
166
|
+
const loadFailed = loadFailedLines.length > 0
|
|
167
|
+
? `<h2>${esc(loadFailedLines[0])}</h2><ul>${loadFailedLines
|
|
168
|
+
.slice(1)
|
|
169
|
+
.map((l) => `<li>${esc(l)}</li>`)
|
|
170
|
+
.join('')}</ul>`
|
|
171
|
+
: '';
|
|
46
172
|
return `<!doctype html><meta charset="utf-8"><title>Knowledge stale-check</title>
|
|
47
173
|
<style>body{font:14px/1.4 sans-serif;margin:1rem}table{border-collapse:collapse;width:100%}td,th{border:1px solid #ccc;padding:.25rem .5rem;text-align:left}h1{margin-top:0}</style>
|
|
48
174
|
<h1>Knowledge stale-check</h1>
|
|
49
|
-
<p
|
|
175
|
+
<p>${esc(bucketLine(p))}</p>
|
|
176
|
+
<p>references=${p.totalReferences}, anchors=${p.totalAnchors}, ok=${p.counts.ok}, stale=${p.counts.stale}, missing=${p.counts.missing}, unknown=${p.counts.unknown}, invalid=${p.counts.invalid}</p>
|
|
177
|
+
<pre>${esc(kindTableLines(p).join('\n'))}</pre>
|
|
178
|
+
${loadFailed}
|
|
179
|
+
${unverifiable ? `<h2>Unverifiable entries (${p.coverage.unverifiable})</h2><ul>${unverifiable}</ul>` : ''}
|
|
50
180
|
<table><thead><tr><th>Outcome</th><th>Required</th><th>Entry</th><th>Reference</th><th>Message</th></tr></thead><tbody>${rows.join('')}</tbody></table>
|
|
51
|
-
|
|
181
|
+
<p style="font-weight:bold${p.exitCode === 0 ? '' : ';color:#a40000'}">${esc(verdict).replace(/\n/g, '<br>')}</p>
|
|
52
182
|
`;
|
|
53
183
|
}
|
|
54
184
|
/**
|
|
@@ -106,22 +236,43 @@ export const knowledgeListCommand = {
|
|
|
106
236
|
// and would strip pack entries whose fields are getters/non-enumerable.
|
|
107
237
|
entries.map(projectKnowledgeEntryForJson);
|
|
108
238
|
process.stdout.write(asJson(payload) + '\n');
|
|
239
|
+
await writeRejectedEntriesNote(inspection, KNOWLEDGE_FAMILY_KINDS, { json: true, next: 'shrk doctor' });
|
|
109
240
|
return 0;
|
|
110
241
|
}
|
|
242
|
+
if (inspection.knowledgeEntries.length === 0) {
|
|
243
|
+
// A query, not a gate — the exit stays 0 — but an empty corpus is almost
|
|
244
|
+
// always a wrong root, so say where discovery landed (as `knowledge lint`).
|
|
245
|
+
const d = describeInspectionDiscovery(inspection, resolveCwd(args));
|
|
246
|
+
process.stderr.write(`WARN loaded 0 knowledge entries from ${d.resolvedRoot} (sharkcraft/ folder: ${d.sharkcraftDir ?? 'missing'}` +
|
|
247
|
+
`${d.configError !== undefined ? `; config failed to load — ${d.configError}` : ''}).` +
|
|
248
|
+
`${d.configuredAncestor ? ` A configured ancestor exists: rerun with --cwd ${d.configuredAncestor}.` : ''}\n`);
|
|
249
|
+
}
|
|
250
|
+
// A knowledge file that never loaded makes the list PARTIAL — say which.
|
|
251
|
+
const failedLoads = describeInspectionDiscovery(inspection, resolveCwd(args)).knowledgeLoadFailures;
|
|
252
|
+
if (failedLoads.length > 0) {
|
|
253
|
+
process.stderr.write(`WARN ${failedLoads.length} knowledge file(s) never loaded — this list is partial: ${failedLoads
|
|
254
|
+
.map((f) => `${f.file} (${f.status})`)
|
|
255
|
+
.join(', ')}. Run \`shrk doctor\` for the error.\n`);
|
|
256
|
+
}
|
|
111
257
|
process.stdout.write(header(`Knowledge (${entries.length})`));
|
|
112
258
|
for (const e of entries)
|
|
113
259
|
process.stdout.write(formatEntryCompact(e) + '\n');
|
|
260
|
+
// An array member meant as an entry that the loader refused (no `content`,
|
|
261
|
+
// a reused id) is named (round 12, 12.1) — it used to vanish silently.
|
|
262
|
+
// Load failures are the partial-list WARN above — never said twice.
|
|
263
|
+
await writeRejectedEntriesNote(inspection, KNOWLEDGE_FAMILY_KINDS, { next: 'shrk doctor', loadFailures: false });
|
|
114
264
|
return 0;
|
|
115
265
|
},
|
|
116
266
|
};
|
|
117
267
|
export const knowledgeGetCommand = {
|
|
118
268
|
name: 'get',
|
|
119
|
-
description: 'Show full content of one knowledge entry.',
|
|
120
|
-
usage: 'shrk knowledge get <id> [--json]',
|
|
269
|
+
description: 'Show full content of one knowledge entry. A superseded entry opens with a banner naming its successor (resolved, with its title); `--follow` renders the current entry after it. Cross-reference ids print with the namespace they resolve into.',
|
|
270
|
+
usage: 'shrk knowledge get <id> [--follow] [--json]',
|
|
271
|
+
booleanFlags: new Set(['follow', 'json']),
|
|
121
272
|
async run(args) {
|
|
122
273
|
const id = args.positional[0];
|
|
123
274
|
if (!id) {
|
|
124
|
-
process.stderr.write('Usage: shrk knowledge get <id
|
|
275
|
+
process.stderr.write('Usage: shrk knowledge get <id> [--follow] [--json]\n');
|
|
125
276
|
return 2;
|
|
126
277
|
}
|
|
127
278
|
const inspection = await inspectSharkcraft({ cwd: resolveCwd(args) });
|
|
@@ -134,15 +285,69 @@ export const knowledgeGetCommand = {
|
|
|
134
285
|
process.stdout.write(asJson(entry) + '\n');
|
|
135
286
|
return 0;
|
|
136
287
|
}
|
|
137
|
-
|
|
288
|
+
// Warm first: a construct / playbook id is otherwise NOT VERIFIED, and a
|
|
289
|
+
// successor must be named with the registry that actually holds it.
|
|
290
|
+
await (await import("../surface/cli-command-resolver.js")).warmCliReferenceRegistries(inspection);
|
|
291
|
+
const resolveRef = buildKnowledgeRefResolver(inspection);
|
|
292
|
+
process.stdout.write(formatEntryFull(entry, { resolveRef }) + '\n');
|
|
293
|
+
if (flagBool(args, 'follow')) {
|
|
294
|
+
const followed = followSupersession(inspection.index, entry, inspection.knowledgeEntries.length);
|
|
295
|
+
if (followed.terminal) {
|
|
296
|
+
process.stdout.write(`\n--- following supersededBy: ${followed.path.join(' → ')} ---\n\n`);
|
|
297
|
+
process.stdout.write(formatEntryFull(followed.terminal, { resolveRef }) + '\n');
|
|
298
|
+
}
|
|
299
|
+
else {
|
|
300
|
+
process.stderr.write(`--follow: ${followed.reason}\n`);
|
|
301
|
+
}
|
|
302
|
+
}
|
|
138
303
|
return 0;
|
|
139
304
|
},
|
|
140
305
|
};
|
|
306
|
+
/**
|
|
307
|
+
* Walk `supersededBy` from `entry` to the ONE current entry, cycle-safe and
|
|
308
|
+
* bounded by the corpus size. Refuses (with the reason) on a fork, a successor
|
|
309
|
+
* that is not a knowledge entry, or a cycle — never guesses which branch.
|
|
310
|
+
*/
|
|
311
|
+
function followSupersession(index, entry, bound) {
|
|
312
|
+
const path = [entry.id];
|
|
313
|
+
const seen = new Set(path);
|
|
314
|
+
let cur = entry;
|
|
315
|
+
for (let step = 0; step <= bound; step += 1) {
|
|
316
|
+
const next = (cur.supersededBy ?? []).filter((s) => typeof s === 'string' && s.length > 0);
|
|
317
|
+
if (next.length === 0) {
|
|
318
|
+
return path.length > 1
|
|
319
|
+
? { terminal: cur, path }
|
|
320
|
+
: { path, reason: `"${entry.id}" is not superseded — nothing to follow.` };
|
|
321
|
+
}
|
|
322
|
+
if (next.length > 1) {
|
|
323
|
+
return { path, reason: `"${cur.id}" names ${next.length} successors (${next.join(', ')}) — pick one: shrk knowledge get <id>` };
|
|
324
|
+
}
|
|
325
|
+
const successor = index.get(next[0] ?? '');
|
|
326
|
+
if (!successor)
|
|
327
|
+
return { path, reason: `successor "${next[0]}" of "${cur.id}" is not a knowledge entry.` };
|
|
328
|
+
if (seen.has(successor.id)) {
|
|
329
|
+
return { path: [...path, successor.id], reason: `supersededBy forms a cycle (${[...path, successor.id].join(' → ')}) — no entry in it is current.` };
|
|
330
|
+
}
|
|
331
|
+
seen.add(successor.id);
|
|
332
|
+
path.push(successor.id);
|
|
333
|
+
cur = successor;
|
|
334
|
+
}
|
|
335
|
+
return { path, reason: 'the supersededBy chain is longer than the corpus.' };
|
|
336
|
+
}
|
|
141
337
|
export const knowledgeSearchCommand = {
|
|
142
338
|
name: 'search',
|
|
143
339
|
description: 'Search knowledge by query.',
|
|
144
340
|
usage: 'shrk knowledge search <query> [--type x,y] [--scope x,y] [--limit 10] [--json]',
|
|
145
341
|
async run(args) {
|
|
342
|
+
// No query and no filter is "you gave me nothing to search" — a usage
|
|
343
|
+
// error (3), never `Results (0)` at exit 0 (round 11 §1.2#5).
|
|
344
|
+
const noSelector = requireInputSelector(args, {
|
|
345
|
+
flags: ['type', 'scope', 'tag', 'appliesWhen'],
|
|
346
|
+
positional: true,
|
|
347
|
+
usage: 'shrk knowledge search <query> [--type x,y] [--scope x,y] [--limit 10] [--json]',
|
|
348
|
+
});
|
|
349
|
+
if (noSelector !== null)
|
|
350
|
+
return noSelector;
|
|
146
351
|
const query = args.positional.join(' ').trim();
|
|
147
352
|
const inspection = await inspectSharkcraft({ cwd: resolveCwd(args) });
|
|
148
353
|
const types = flagList(args, 'type');
|
|
@@ -191,33 +396,126 @@ function readChangedScopeOptionsForKnowledge(args, projectRoot) {
|
|
|
191
396
|
includeWorktree: changedOnly || !since,
|
|
192
397
|
};
|
|
193
398
|
}
|
|
399
|
+
/** Boolean flags of the stale-check — none of them may swallow a following token. */
|
|
400
|
+
const STALE_CHECK_BOOLEAN_FLAGS = new Set([
|
|
401
|
+
'json',
|
|
402
|
+
'ci',
|
|
403
|
+
'strict',
|
|
404
|
+
'report',
|
|
405
|
+
'changed-only',
|
|
406
|
+
'staged',
|
|
407
|
+
'watch',
|
|
408
|
+
'once',
|
|
409
|
+
'require-references',
|
|
410
|
+
ALLOW_EMPTY_FLAG,
|
|
411
|
+
]);
|
|
412
|
+
const STALE_CHECK_USAGE = 'shrk knowledge stale-check [--changed-only|--since <ref>|--staged|--files a,b,c] [--ci] [--strict] [--fail-on <category,...>] [--min-referenced <ratio|NN%>] [--require-references] [--allow-empty] [--stale-after <Nd|Nw|Nm|Ny> [--as-of YYYY-MM-DD]] [--baseline <file>] [--report] [--format text|markdown|html|json] [--output <path>] [--json] [--watch [--once] [--debounce N]]';
|
|
194
413
|
export const knowledgeStaleCheckCommand = {
|
|
195
414
|
name: 'stale-check',
|
|
196
|
-
description: '
|
|
197
|
-
usage:
|
|
415
|
+
description: 'Verify every knowledge entry against the workspace in three buckets — verified / stale / UNVERIFIABLE (no checkable reference). Strict by default: any unverifiable entry keeps the run at exit 2 unless accepted (--min-referenced). CI flags and `--watch [--once] [--debounce N]` supported. Read-only.',
|
|
416
|
+
usage: STALE_CHECK_USAGE,
|
|
417
|
+
booleanFlags: STALE_CHECK_BOOLEAN_FLAGS,
|
|
198
418
|
async run(args) {
|
|
199
|
-
|
|
200
|
-
if (watchExit !== null)
|
|
201
|
-
return watchExit;
|
|
202
|
-
return knowledgeStaleCheckImpl(args);
|
|
419
|
+
return runStaleCheck(args, 'knowledge stale-check');
|
|
203
420
|
},
|
|
204
421
|
};
|
|
205
|
-
async function
|
|
422
|
+
async function runStaleCheck(args, verb) {
|
|
423
|
+
const impl = (a) => knowledgeStaleCheckImpl(a, verb);
|
|
424
|
+
const watchExit = await maybeRunInWatchMode(args, impl);
|
|
425
|
+
if (watchExit !== null)
|
|
426
|
+
return watchExit;
|
|
427
|
+
return impl(args);
|
|
428
|
+
}
|
|
429
|
+
/** A malformed invocation: `3` (the gate never started) with the usage line. */
|
|
430
|
+
function staleCheckUsageError(message) {
|
|
431
|
+
process.stderr.write(`${message}\nUsage: ${STALE_CHECK_USAGE}\n`);
|
|
432
|
+
return ExitCode.UsageError;
|
|
433
|
+
}
|
|
434
|
+
async function knowledgeStaleCheckImpl(args, verb) {
|
|
206
435
|
const cwd = resolveCwd(args);
|
|
436
|
+
// ── Validate the request first: a bad flag value is `3`, never a verdict. ──
|
|
437
|
+
const failOnFlag = args.flags.get('fail-on');
|
|
438
|
+
if (failOnFlag === true) {
|
|
439
|
+
return staleCheckUsageError(`--fail-on needs a value: ${KNOWLEDGE_FAIL_ON_CATEGORIES.join(', ')}.`);
|
|
440
|
+
}
|
|
441
|
+
const failOnList = (typeof failOnFlag === 'string' ? failOnFlag : '')
|
|
442
|
+
.toLowerCase()
|
|
443
|
+
.split(',')
|
|
444
|
+
.map((s) => s.trim())
|
|
445
|
+
.filter(Boolean);
|
|
446
|
+
const unknownFailOn = failOnList.filter((c) => !KNOWLEDGE_FAIL_ON_CATEGORIES.includes(c));
|
|
447
|
+
if (unknownFailOn.length > 0) {
|
|
448
|
+
return staleCheckUsageError(`Unknown --fail-on value(s): ${unknownFailOn.join(', ')}. Valid: ${KNOWLEDGE_FAIL_ON_CATEGORIES.join(', ')}.`);
|
|
449
|
+
}
|
|
450
|
+
const minFlag = args.flags.get('min-referenced');
|
|
451
|
+
let minReferenced;
|
|
452
|
+
if (minFlag !== undefined) {
|
|
453
|
+
const ratio = typeof minFlag === 'string' ? parseMinReferenced(minFlag) : null;
|
|
454
|
+
if (ratio === null) {
|
|
455
|
+
return staleCheckUsageError(`--min-referenced takes a ratio 0..1 or a percentage (0.8, 80%) — got ${JSON.stringify(minFlag)}.`);
|
|
456
|
+
}
|
|
457
|
+
minReferenced = { ratio, acceptedBy: `--min-referenced ${minFlag}` };
|
|
458
|
+
}
|
|
459
|
+
const staleAfterFlag = args.flags.get('stale-after');
|
|
460
|
+
let staleAfterDays;
|
|
461
|
+
if (staleAfterFlag !== undefined) {
|
|
462
|
+
const days = typeof staleAfterFlag === 'string' ? parseStaleAfterDays(staleAfterFlag) : null;
|
|
463
|
+
if (days === null) {
|
|
464
|
+
return staleCheckUsageError(`--stale-after takes a duration such as 90d, 12w, 6m or 1y — got ${JSON.stringify(staleAfterFlag)}.`);
|
|
465
|
+
}
|
|
466
|
+
staleAfterDays = days;
|
|
467
|
+
}
|
|
468
|
+
const asOfFlag = args.flags.get('as-of');
|
|
469
|
+
if (asOfFlag !== undefined && (typeof asOfFlag !== 'string' || !isValidVerifiedOn(asOfFlag))) {
|
|
470
|
+
return staleCheckUsageError(`--as-of takes a date written YYYY-MM-DD — got ${JSON.stringify(asOfFlag)}.`);
|
|
471
|
+
}
|
|
472
|
+
const asOf = typeof asOfFlag === 'string' ? asOfFlag : undefined;
|
|
473
|
+
// A category that can never fire is a malformed request (the `--fail-on
|
|
474
|
+
// bogus` class): `aged` / `--as-of` measure against a --stale-after window.
|
|
475
|
+
// (The same check runs again below over `knowledgeCheck.failOn`.)
|
|
476
|
+
const windowProblem = knowledgeStaleWindowProblem(new Set(failOnList), false, staleAfterDays, asOf);
|
|
477
|
+
if (windowProblem)
|
|
478
|
+
return staleCheckUsageError(windowProblem);
|
|
207
479
|
const inspection = await inspectSharkcraft({ cwd });
|
|
480
|
+
// `command` references resolve against the live command index — injected
|
|
481
|
+
// here; without it they are NOT VERIFIED (never "Command available").
|
|
482
|
+
// The same call warms every async-filled registry (playbook / policy /
|
|
483
|
+
// construct / helper) before anything resolves.
|
|
484
|
+
await (await import("../surface/cli-command-resolver.js")).warmCliReferenceRegistries(inspection);
|
|
208
485
|
const scopeOpts = readChangedScopeOptionsForKnowledge(args, cwd);
|
|
209
486
|
const changedFiles = scopeOpts ? resolveChangedFiles(scopeOpts).files : undefined;
|
|
210
487
|
const report = buildKnowledgeStaleReport(inspection, {
|
|
211
488
|
...(changedFiles ? { changedFiles } : {}),
|
|
489
|
+
...(staleAfterDays !== undefined ? { staleAfterDays } : {}),
|
|
490
|
+
...(asOf ? { asOf } : {}),
|
|
212
491
|
});
|
|
213
|
-
// CI/preflight flags
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
const
|
|
217
|
-
const
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
492
|
+
// CI/preflight flags, folded over the config's `knowledgeCheck` block by
|
|
493
|
+
// THE input builder — `shrk quality` and release readiness build theirs
|
|
494
|
+
// there too, so a config-only request is one verdict on all three.
|
|
495
|
+
const discovery = describeInspectionDiscovery(inspection, cwd);
|
|
496
|
+
const gateInput = knowledgeStaleGateInput({
|
|
497
|
+
flags: {
|
|
498
|
+
ci: flagBool(args, 'ci'),
|
|
499
|
+
strict: flagBool(args, 'strict'),
|
|
500
|
+
failOn: failOnList,
|
|
501
|
+
...(minReferenced ? { minReferenced } : {}),
|
|
502
|
+
requireReferences: flagBool(args, 'require-references'),
|
|
503
|
+
emptyAcceptance: allowEmptyValve(args, report.coverage.entriesInScope),
|
|
504
|
+
...(staleAfterDays !== undefined ? { staleAfterDays } : {}),
|
|
505
|
+
...(asOf ? { asOf } : {}),
|
|
506
|
+
},
|
|
507
|
+
knowledgeCheck: inspection.config?.knowledgeCheck,
|
|
508
|
+
discovery,
|
|
509
|
+
scoped: changedFiles !== undefined,
|
|
510
|
+
});
|
|
511
|
+
// `knowledgeCheck.failOn: ['aged']` with no --stale-after window: a
|
|
512
|
+
// category that can never fire is a malformed request, never a verdict.
|
|
513
|
+
if (gateInput.usageProblem)
|
|
514
|
+
return staleCheckUsageError(gateInput.usageProblem);
|
|
515
|
+
const ci = gateInput.ci;
|
|
516
|
+
const strict = gateInput.strict;
|
|
517
|
+
const effectiveFailOn = [...gateInput.failOn];
|
|
518
|
+
const requireReferences = gateInput.requireReferences;
|
|
221
519
|
const baselineFile = flagString(args, 'baseline');
|
|
222
520
|
const wantReport = flagBool(args, 'report');
|
|
223
521
|
const formatRaw = (flagString(args, 'format') ?? '').toLowerCase();
|
|
@@ -225,58 +523,26 @@ async function knowledgeStaleCheckImpl(args) {
|
|
|
225
523
|
const wantMarkdown = formatRaw === 'markdown' || formatRaw === 'md';
|
|
226
524
|
const wantHtml = formatRaw === 'html';
|
|
227
525
|
const output = flagString(args, 'output');
|
|
228
|
-
//
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
526
|
+
// ── Settle first, render second. ──
|
|
527
|
+
const gate = evaluateKnowledgeStaleGate(report, gateInput);
|
|
528
|
+
const env = buildGateEnvelope(verb, gate.proposed, gate.rules, gate.runCoverage);
|
|
529
|
+
const exit = env.exit;
|
|
530
|
+
const { verified, entriesInScope } = report.coverage;
|
|
531
|
+
// Round 13: the ✓ line never contradicts a STALE row printed above it — a
|
|
532
|
+
// failing reference this mode waives (`required: false` under --ci, …) is
|
|
533
|
+
// named here and printed as an acceptance below it.
|
|
534
|
+
const entriesVerified = `${verified} of ${entriesInScope} knowledge ${entriesInScope === 1 ? 'entry' : 'entries'} verified`;
|
|
535
|
+
const verdict = verdictLine(env, gate.waived > 0
|
|
536
|
+
? `${entriesVerified} — ${gate.waived} failing reference(s) listed above do not block this mode (accepted below). ✓`
|
|
537
|
+
: `${entriesVerified} — no stale or missing references. ✓`, exit === ExitCode.NotVerified ? gate.notVerifiedLead : undefined);
|
|
538
|
+
const requiredStale = gate.requiredStale;
|
|
539
|
+
const requiredMissing = gate.requiredMissing;
|
|
240
540
|
const totalRequiredFailing = requiredStale + requiredMissing;
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
// CI mode — required failing refs are blocking. Optional refs warn only.
|
|
247
|
-
if (totalRequiredFailing > 0) {
|
|
248
|
-
exitNonZero = true;
|
|
249
|
-
exitReason = `${totalRequiredFailing} required references failing in --ci mode`;
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
else if (strict) {
|
|
253
|
-
// Strict — any stale/missing required ref fails. Same as CI essentially.
|
|
254
|
-
if (totalRequiredFailing > 0) {
|
|
255
|
-
exitNonZero = true;
|
|
256
|
-
exitReason = `${totalRequiredFailing} required references failing in --strict mode`;
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
else if (failOn.size > 0) {
|
|
260
|
-
if (considerFailOn('required') && totalRequiredFailing > 0) {
|
|
261
|
-
exitNonZero = true;
|
|
262
|
-
exitReason = `${totalRequiredFailing} required reference issues (--fail-on=required)`;
|
|
263
|
-
}
|
|
264
|
-
if (considerFailOn('stale') && report.counts.stale > 0) {
|
|
265
|
-
exitNonZero = true;
|
|
266
|
-
exitReason = `${report.counts.stale} stale references (--fail-on=stale)`;
|
|
267
|
-
}
|
|
268
|
-
if (considerFailOn('missing') && report.counts.missing > 0) {
|
|
269
|
-
exitNonZero = true;
|
|
270
|
-
exitReason = `${report.counts.missing} missing references (--fail-on=missing)`;
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
else {
|
|
274
|
-
// Default — non-CI: only the legacy "any missing or stale" condition fails.
|
|
275
|
-
if (report.counts.missing + report.counts.stale > 0) {
|
|
276
|
-
exitNonZero = true;
|
|
277
|
-
exitReason = `${report.counts.missing + report.counts.stale} stale or missing references (legacy default)`;
|
|
278
|
-
}
|
|
279
|
-
}
|
|
541
|
+
const exitReason = gate.reasons.length > 0
|
|
542
|
+
? gate.reasons.join('; ')
|
|
543
|
+
: exit === ExitCode.NotVerified
|
|
544
|
+
? `not verified — ${env.shortfalls[0] ?? 'nothing was proved'}`
|
|
545
|
+
: undefined;
|
|
280
546
|
// Baseline comparison (informational).
|
|
281
547
|
let baselineComparison;
|
|
282
548
|
if (baselineFile) {
|
|
@@ -335,14 +601,20 @@ async function knowledgeStaleCheckImpl(args) {
|
|
|
335
601
|
ci: {
|
|
336
602
|
ci,
|
|
337
603
|
strict,
|
|
338
|
-
|
|
604
|
+
// The EFFECTIVE categories (a --fail-on flag, else knowledgeCheck.failOn).
|
|
605
|
+
failOn: effectiveFailOn,
|
|
339
606
|
requiredStale,
|
|
340
607
|
requiredMissing,
|
|
341
608
|
totalRequiredFailing,
|
|
342
|
-
exitNonZero,
|
|
343
|
-
exitReason,
|
|
609
|
+
exitNonZero: exit !== ExitCode.VerifiedPass,
|
|
610
|
+
...(exitReason ? { exitReason } : {}),
|
|
611
|
+
...(gateInput.minReferenced ? { minReferenced: gateInput.minReferenced.ratio } : {}),
|
|
612
|
+
requireReferences,
|
|
344
613
|
},
|
|
345
|
-
baselineComparison,
|
|
614
|
+
...(baselineComparison ? { baselineComparison } : {}),
|
|
615
|
+
discovery,
|
|
616
|
+
exitCode: exit,
|
|
617
|
+
gate: env,
|
|
346
618
|
};
|
|
347
619
|
// Optional report file.
|
|
348
620
|
if (wantReport || output) {
|
|
@@ -358,59 +630,125 @@ async function knowledgeStaleCheckImpl(args) {
|
|
|
358
630
|
process.stdout.write(`Wrote report → ${outPath}\n`);
|
|
359
631
|
}
|
|
360
632
|
}
|
|
361
|
-
// Format-specific output.
|
|
633
|
+
// Format-specific output — every format returns the SETTLED exit.
|
|
362
634
|
if (wantJson) {
|
|
363
635
|
process.stdout.write(asJson(ciPayload) + '\n');
|
|
364
|
-
return
|
|
636
|
+
return exit;
|
|
365
637
|
}
|
|
366
638
|
if (wantMarkdown) {
|
|
367
|
-
process.stdout.write(renderStaleCheckMarkdown(ciPayload));
|
|
368
|
-
return
|
|
639
|
+
process.stdout.write(renderStaleCheckMarkdown(ciPayload, verdict));
|
|
640
|
+
return exit;
|
|
369
641
|
}
|
|
370
642
|
if (wantHtml) {
|
|
371
|
-
process.stdout.write(renderStaleCheckHtml(ciPayload));
|
|
372
|
-
return
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
643
|
+
process.stdout.write(renderStaleCheckHtml(ciPayload, verdict));
|
|
644
|
+
return exit;
|
|
645
|
+
}
|
|
646
|
+
writeStaleCheckText(ciPayload, {
|
|
647
|
+
verdict,
|
|
648
|
+
reasons: gate.reasons,
|
|
649
|
+
showRequired: ci || strict || effectiveFailOn.length > 0,
|
|
650
|
+
allowEmptyHint: exit === ExitCode.NotVerified && entriesInScope === 0 && !gate.discoveryFailed,
|
|
651
|
+
});
|
|
652
|
+
return exit;
|
|
653
|
+
}
|
|
654
|
+
/** Advisories printed in text before the rest are summarised. */
|
|
655
|
+
const ADVISORIES_SHOWN = 20;
|
|
656
|
+
/** Aged entries printed in text before the rest are summarised. */
|
|
657
|
+
const AGED_SHOWN = 50;
|
|
658
|
+
function writeStaleCheckText(p, o) {
|
|
659
|
+
const w = (s) => void process.stdout.write(s);
|
|
660
|
+
w(header('Knowledge stale-check'));
|
|
661
|
+
const d = p.discovery;
|
|
662
|
+
if (d.entriesLoaded === 0) {
|
|
663
|
+
// Name where discovery landed, so a wrong root is visible on the screen
|
|
664
|
+
// that refuses to pass.
|
|
665
|
+
w('Loaded 0 knowledge entries.\n');
|
|
666
|
+
w(` resolved root: ${d.resolvedRoot}${d.rootMarkers.length > 0 ? ` (${d.rootMarkers.join(', ')})` : ' (no root marker)'}\n`);
|
|
667
|
+
w(` sharkcraft/ folder: ${d.sharkcraftDir ?? 'missing'}\n`);
|
|
668
|
+
w(` config: ${d.configError !== undefined ? `failed to load — ${d.configError}` : (d.configFile ?? '(none)')}\n`);
|
|
669
|
+
if (d.configuredAncestor) {
|
|
670
|
+
w(` configured ancestor: ${d.configuredAncestor} — rerun with --cwd ${d.configuredAncestor}\n`);
|
|
671
|
+
}
|
|
672
|
+
w('\n');
|
|
673
|
+
}
|
|
674
|
+
for (const line of loadFailureLines(d, ' '))
|
|
675
|
+
w(`${line}\n`);
|
|
676
|
+
w(`${bucketLine(p)}\n`);
|
|
677
|
+
w(`references: ${p.totalReferences} · anchors: ${p.totalAnchors} · ok=${p.counts.ok} stale=${p.counts.stale} missing=${p.counts.missing} unknown=${p.counts.unknown} invalid=${p.counts.invalid}\n`);
|
|
678
|
+
const failures = Object.entries(p.failureCounts).filter(([, n]) => n > 0);
|
|
679
|
+
if (failures.length > 0)
|
|
680
|
+
w(`failures: ${failures.map(([k, n]) => `${k}=${n}`).join(' ')}\n`);
|
|
681
|
+
if (p.entriesInScope !== p.entries) {
|
|
682
|
+
w(`scope: ${p.entriesInScope} of ${p.entries} entries reference the changed files\n`);
|
|
683
|
+
}
|
|
684
|
+
if (o.showRequired) {
|
|
685
|
+
w(`required: stale=${p.ci.requiredStale} missing=${p.ci.requiredMissing} (total failing: ${p.ci.totalRequiredFailing})\n`);
|
|
686
|
+
}
|
|
687
|
+
if (p.baselineComparison) {
|
|
688
|
+
w(`baseline: new-stale=${p.baselineComparison.newStale} new-missing=${p.baselineComparison.newMissing} resolved=${p.baselineComparison.resolved}\n`);
|
|
689
|
+
}
|
|
690
|
+
if (p.age) {
|
|
691
|
+
w(`verifiedOn: ${p.age.aged.length} older than ${p.age.staleAfterDays}d, ${p.age.neverVerified.length} never verified (as of ${p.age.asOf})\n`);
|
|
692
|
+
}
|
|
693
|
+
w('\n');
|
|
694
|
+
for (const line of kindTableLines(p))
|
|
695
|
+
w(`${line}\n`);
|
|
696
|
+
if (p.coverage.unverifiable > 0) {
|
|
697
|
+
w(`\nUNVERIFIABLE (${p.coverage.unverifiable}) — never checked; declare references[] (or anchors[]):\n`);
|
|
698
|
+
for (const line of unverifiableLines(p, ' '))
|
|
699
|
+
w(`${line}\n`);
|
|
700
|
+
}
|
|
701
|
+
const issues = [...p.referenceChecks, ...p.assetReferenceChecks].filter((c) => c.outcome !== ReferenceCheckOutcome.Ok);
|
|
702
|
+
const badAnchors = p.anchorChecks.filter((c) => c.outcome !== ReferenceCheckOutcome.Ok);
|
|
703
|
+
if (issues.length + badAnchors.length > 0)
|
|
704
|
+
w('\n');
|
|
705
|
+
for (const c of issues) {
|
|
706
|
+
const tag = (c.implicit ? 'IMPLICIT' : c.outcome.toUpperCase()).padEnd(8);
|
|
389
707
|
const req = c.reference.required === true ? '[REQ] ' : ' ';
|
|
390
|
-
|
|
708
|
+
const kind = c.assetKind ? `[${c.assetKind}] ` : '';
|
|
709
|
+
w(` ${tag}${req}${kind}${c.entryId} → ${formatKnowledgeReference(c.reference)} — ${c.message}\n`);
|
|
710
|
+
if (c.expected !== undefined || c.actual !== undefined) {
|
|
711
|
+
w(` expected: ${String(c.expected ?? '?')} · actual: ${String(c.actual ?? '?')}\n`);
|
|
712
|
+
}
|
|
391
713
|
if (c.suggestion)
|
|
392
|
-
|
|
714
|
+
w(` ↳ ${c.suggestion}\n`);
|
|
393
715
|
}
|
|
394
|
-
for (const c of
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
716
|
+
for (const c of badAnchors) {
|
|
717
|
+
w(` ${c.outcome.toUpperCase().padEnd(8)}${c.entryId} anchor[${c.anchor.id}] (${c.anchor.kind}) — ${c.message}\n`);
|
|
718
|
+
}
|
|
719
|
+
// Implicit boundary references were listed with the issues above.
|
|
720
|
+
const advisories = p.advisories.filter((a) => a.code !== KnowledgeAdvisoryCode.ImplicitPathMissing);
|
|
721
|
+
if (advisories.length > 0) {
|
|
722
|
+
w(`\nAdvisories (${advisories.length}) — reported, never gating:\n`);
|
|
723
|
+
for (const a of advisories.slice(0, ADVISORIES_SHOWN))
|
|
724
|
+
w(` ${a.code} ${a.subjectId} — ${a.message}\n`);
|
|
725
|
+
if (advisories.length > ADVISORIES_SHOWN) {
|
|
726
|
+
w(` … ${advisories.length - ADVISORIES_SHOWN} more (--json for all)\n`);
|
|
727
|
+
}
|
|
399
728
|
}
|
|
400
|
-
if (
|
|
401
|
-
|
|
729
|
+
if (p.age && p.age.aged.length > 0) {
|
|
730
|
+
w(`\nAged — not verified within ${p.age.staleAfterDays}d (oldest first):\n`);
|
|
731
|
+
for (const a of p.age.aged.slice(0, AGED_SHOWN)) {
|
|
732
|
+
w(` ${a.entryId} verifiedOn ${a.verifiedOn} (${a.ageDays}d) ${a.source}\n`);
|
|
733
|
+
}
|
|
734
|
+
if (p.age.aged.length > AGED_SHOWN)
|
|
735
|
+
w(` … ${p.age.aged.length - AGED_SHOWN} more (--json for all)\n`);
|
|
402
736
|
}
|
|
403
|
-
if (
|
|
404
|
-
|
|
737
|
+
if (o.reasons.length > 0) {
|
|
738
|
+
w(`\nFAIL: ${o.reasons.join('; ')}\n`);
|
|
739
|
+
w(renderFailureHints(staleKnowledgeHints()));
|
|
405
740
|
}
|
|
406
|
-
|
|
741
|
+
if (o.allowEmptyHint)
|
|
742
|
+
w('\nPass --allow-empty to accept an empty scope explicitly.\n');
|
|
743
|
+
w(`\n${o.verdict}\n`);
|
|
407
744
|
}
|
|
408
745
|
export const knowledgeVerifyCommand = {
|
|
409
746
|
name: 'verify',
|
|
410
|
-
description: 'Alias for `knowledge stale-check
|
|
411
|
-
usage: '
|
|
747
|
+
description: 'Alias for `knowledge stale-check` — the same three-bucket verdict, flags and exit codes. Read-only.',
|
|
748
|
+
usage: STALE_CHECK_USAGE.replace('knowledge stale-check', 'knowledge verify'),
|
|
749
|
+
booleanFlags: STALE_CHECK_BOOLEAN_FLAGS,
|
|
412
750
|
run(args) {
|
|
413
|
-
return
|
|
751
|
+
return runStaleCheck(args, 'knowledge verify');
|
|
414
752
|
},
|
|
415
753
|
};
|
|
416
754
|
export const knowledgeReferencesCommand = {
|
|
@@ -447,7 +785,9 @@ export const knowledgeReferencesCommand = {
|
|
|
447
785
|
if (data.references.length > 0) {
|
|
448
786
|
process.stdout.write(`References (${data.references.length}):\n`);
|
|
449
787
|
for (const r of data.references) {
|
|
450
|
-
|
|
788
|
+
// One grammar: a pinned symbol renders `Name@path` (it used to render
|
|
789
|
+
// as its path, hiding the symbol it pins).
|
|
790
|
+
const target = formatKnowledgeReference(r).slice(r.kind.length + 1);
|
|
451
791
|
process.stdout.write(` • ${r.kind}: ${target}${r.required ? ' [required]' : ''}\n`);
|
|
452
792
|
}
|
|
453
793
|
}
|