@aiwg/cli 2026.10.1 → 2026.10.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/agentic/code/providers/capability-matrix.yaml +270 -0
- package/agentic/code/providers/model-capabilities.v1.json +3183 -24
- package/bin/aiwg.mjs +135 -47
- package/dist/src/a2a/codecs.js +9 -0
- package/dist/src/agents/grounding/knowledge-base.js +54 -6
- package/dist/src/artifacts/browser-export.js +6 -0
- package/dist/src/artifacts/checksum-manifest.js +1 -0
- package/dist/src/artifacts/citation-parser.js +173 -92
- package/dist/src/artifacts/citation-table-schema.js +59 -0
- package/dist/src/artifacts/cli.js +57 -18
- package/dist/src/artifacts/corpus-tools/snapshot.js +1 -1
- package/dist/src/artifacts/corpus-tools/vision-extract.js +107 -15
- package/dist/src/artifacts/corpus-views/ref-parser.js +3 -1
- package/dist/src/artifacts/corpus-views/renderers.js +3 -3
- package/dist/src/artifacts/discovery-eval.js +6 -4
- package/dist/src/artifacts/fortemi-core-query-adapter.js +36 -3
- package/dist/src/artifacts/fortemi-core-sync.js +166 -40
- package/dist/src/artifacts/framework-capabilities.js +171 -0
- package/dist/src/artifacts/framework-index-paths.js +73 -0
- package/dist/src/artifacts/framework-source-digest.js +75 -0
- package/dist/src/artifacts/index-builder.js +285 -131
- package/dist/src/artifacts/index-files.js +132 -18
- package/dist/src/artifacts/index-preparation.js +65 -0
- package/dist/src/artifacts/index-refresh.js +576 -0
- package/dist/src/artifacts/index-worker.mjs +9 -0
- package/dist/src/artifacts/prebuilt-build-lock.js +47 -4
- package/dist/src/artifacts/prebuilt-deployment.js +46 -0
- package/dist/src/artifacts/prebuilt-relations.js +80 -0
- package/dist/src/artifacts/query-engine.js +410 -88
- package/dist/src/artifacts/relations-builder.js +168 -0
- package/dist/src/artifacts/relations.js +148 -0
- package/dist/src/artifacts/repair.js +9 -4
- package/dist/src/artifacts/stats.js +5 -2
- package/dist/src/artifacts/types.js +30 -10
- package/dist/src/artifacts/watcher.js +1 -1
- package/dist/src/auth/credential-store.js +2 -1
- package/dist/src/catalog/cli.d.mts +5 -0
- package/dist/src/channel/manager.d.mts +20 -0
- package/dist/src/channel/manager.mjs +78 -12
- package/dist/src/cli/child-process-result.js +40 -0
- package/dist/src/cli/command-log.js +2 -3
- package/dist/src/cli/env.js +38 -16
- package/dist/src/cli/flag-parsing.js +236 -0
- package/dist/src/cli/handlers/artifacts.js +3 -0
- package/dist/src/cli/handlers/auth.js +3 -0
- package/dist/src/cli/handlers/decision.js +218 -5
- package/dist/src/cli/handlers/diagnose.js +13 -5
- package/dist/src/cli/handlers/effect.js +4 -2
- package/dist/src/cli/handlers/evidence.js +3 -0
- package/dist/src/cli/handlers/feedback.js +14 -5
- package/dist/src/cli/handlers/help.js +1 -0
- package/dist/src/cli/handlers/index.js +3 -1
- package/dist/src/cli/handlers/init.js +248 -30
- package/dist/src/cli/handlers/lint.js +5 -0
- package/dist/src/cli/handlers/mc.js +23 -0
- package/dist/src/cli/handlers/models.js +169 -10
- package/dist/src/cli/handlers/ralph-launcher.js +2 -0
- package/dist/src/cli/handlers/ralph.js +3 -0
- package/dist/src/cli/handlers/refresh.js +28 -0
- package/dist/src/cli/handlers/regenerate.js +14 -0
- package/dist/src/cli/handlers/resource-versions.js +3 -0
- package/dist/src/cli/handlers/rules.js +195 -0
- package/dist/src/cli/handlers/run.js +4 -0
- package/dist/src/cli/handlers/runtime-info.js +25 -11
- package/dist/src/cli/handlers/script-runner.js +19 -8
- package/dist/src/cli/handlers/session.js +406 -62
- package/dist/src/cli/handlers/sessions.js +243 -76
- package/dist/src/cli/handlers/setup-manifest.js +474 -79
- package/dist/src/cli/handlers/setup.js +180 -39
- package/dist/src/cli/handlers/steward.js +11 -0
- package/dist/src/cli/handlers/subcommands.js +60 -3
- package/dist/src/cli/handlers/team.js +18 -8
- package/dist/src/cli/handlers/uhp.js +3 -0
- package/dist/src/cli/handlers/use.js +307 -55
- package/dist/src/cli/handlers/utilities.js +125 -26
- package/dist/src/cli/handlers/version.js +8 -0
- package/dist/src/cli/prompt-utils.js +72 -0
- package/dist/src/cli/provider-resolution.js +11 -0
- package/dist/src/cli/router.js +15 -1
- package/dist/src/cli/services/deployment-verification.js +19 -9
- package/dist/src/cli/services/provider-prepare-coordinator.js +24 -0
- package/dist/src/cli/skill-usage.js +2 -3
- package/dist/src/config/aiwg-config.js +349 -35
- package/dist/src/config/cli.js +256 -23
- package/dist/src/config/decision-config.js +106 -0
- package/dist/src/config/dispatch-thresholds-runtime.d.mts +8 -0
- package/dist/src/config/dispatch-thresholds-runtime.mjs +38 -0
- package/dist/src/config/gitignore.js +50 -0
- package/dist/src/config/index-graph-overrides.js +36 -0
- package/dist/src/config/project-artifacts-health.d.mts +37 -0
- package/dist/src/config/project-artifacts-health.mjs +14 -3
- package/dist/src/config/project-artifacts-runtime.d.mts +16 -0
- package/dist/src/config/user-config-dir.d.mts +9 -0
- package/dist/src/config/user-config.js +38 -11
- package/dist/src/config/user-registry.js +23 -15
- package/dist/src/config/user-state.js +7 -0
- package/dist/src/decision/adapters/jev.js +75 -27
- package/dist/src/decision/ask.js +203 -43
- package/dist/src/decision/context-live-qualification.js +2 -2
- package/dist/src/decision/driver.js +14 -7
- package/dist/src/decision/ensemble/aggregate.js +23 -10
- package/dist/src/decision/ensemble-study/multifact-study.js +6 -2
- package/dist/src/decision/entry.js +25 -6
- package/dist/src/decision/graph-live-qualification.js +1 -1
- package/dist/src/decision/graph-run.js +9 -0
- package/dist/src/decision/heldout/collector.js +15 -14
- package/dist/src/decision/heldout/contract.js +30 -7
- package/dist/src/decision/index.js +1 -0
- package/dist/src/decision/interop.js +60 -8
- package/dist/src/decision/jev-credentials.js +15 -1
- package/dist/src/decision/ledger.js +942 -0
- package/dist/src/decision/offload-activation.js +137 -0
- package/dist/src/decision/offload.js +550 -0
- package/dist/src/decision/qualification/load.js +4 -6
- package/dist/src/decision/savings.js +28 -0
- package/dist/src/decision/validate.js +6 -3
- package/dist/src/effects/dispatch-verifier.js +252 -0
- package/dist/src/effects/index.js +1 -0
- package/dist/src/effects/types.js +5 -1
- package/dist/src/effects/verifiers/git.js +2 -1
- package/dist/src/effects/verifiers/tracker.js +26 -14
- package/dist/src/extensions/commands/definitions.js +19 -0
- package/dist/src/extensions/project-local-remove.js +36 -1
- package/dist/src/features/installer.js +2 -2
- package/dist/src/flow/graph-metadata.js +5 -0
- package/dist/src/gates/providers/loader.js +64 -18
- package/dist/src/installation/manager-command.d.mts +18 -0
- package/dist/src/installation/manager-command.mjs +15 -3
- package/dist/src/installation/manager.d.mts +49 -0
- package/dist/src/installation/manager.mjs +95 -5
- package/dist/src/issues/cli.js +4 -4
- package/dist/src/issues/local.js +24 -5
- package/dist/src/jobs/runner.js +1 -1
- package/dist/src/lint/cli.js +27 -1
- package/dist/src/lint/loader.js +2 -1
- package/dist/src/lint/reporters.js +25 -1
- package/dist/src/lint/rule-activation.js +43 -0
- package/dist/src/lint/runner.js +137 -62
- package/dist/src/mcp/adapters/codex-runtime.js +366 -56
- package/dist/src/mcp/claude-install.d.mts +4 -0
- package/dist/src/mcp/claude-install.mjs +41 -0
- package/dist/src/mcp/cli.d.mts +1 -0
- package/dist/src/mcp/cli.mjs +620 -85
- package/dist/src/mcp/config-file.d.mts +28 -0
- package/dist/src/mcp/config-file.mjs +279 -0
- package/dist/src/mcp/config-layers.d.mts +36 -0
- package/dist/src/mcp/config-layers.mjs +348 -0
- package/dist/src/mcp/credentials.d.mts +51 -0
- package/dist/src/mcp/credentials.mjs +484 -0
- package/dist/src/mcp/grok-build-config.d.mts +6 -0
- package/dist/src/mcp/grok-build-config.mjs +17 -27
- package/dist/src/mcp/helpers.mjs +109 -4
- package/dist/src/mcp/muse-native-config.d.mts +13 -0
- package/dist/src/mcp/muse-native-config.mjs +1 -0
- package/dist/src/mcp/omp-config.d.mts +4 -0
- package/dist/src/mcp/omp-config.mjs +50 -29
- package/dist/src/mcp/profiles.js +97 -23
- package/dist/src/mcp/profiles.mjs +99 -27
- package/dist/src/mcp/registry.js +248 -131
- package/dist/src/mcp/registry.mjs +169 -100
- package/dist/src/mcp/server-config.d.mts +3 -0
- package/dist/src/mcp/server-config.mjs +89 -0
- package/dist/src/mcp/server.mjs +127 -82
- package/dist/src/mcp/test-simple.mjs +2 -1
- package/dist/src/mcp/toml-editor.d.mts +4 -0
- package/dist/src/mcp/toml-string.d.mts +1 -0
- package/dist/src/mcp/toml-string.mjs +9 -0
- package/dist/src/mcp/toml-strip-mcp.d.mts +1 -0
- package/dist/src/mcp/toml-strip-mcp.mjs +135 -0
- package/dist/src/mcp/tool-filters.d.mts +46 -0
- package/dist/src/mcp/tool-filters.mjs +357 -0
- package/dist/src/mcp/tools/agentic-sandbox.mjs +3 -1
- package/dist/src/mcp/tools/decision.mjs +22 -3
- package/dist/src/mcp/tools/discovery.mjs +62 -55
- package/dist/src/mcp/tools/orchestration.mjs +50 -2
- package/dist/src/mcp/tools/subsystems.mjs +39 -8
- package/dist/src/mcp/tools/worker-invoke.mjs +2856 -0
- package/dist/src/mcp/tools/worker-shell-control.mjs +289 -0
- package/dist/src/mcp/tools/worker-stdin-runtime.mjs +79 -0
- package/dist/src/memory/project-registry.js +2 -2
- package/dist/src/mission-protocol/codecs.js +647 -1
- package/dist/src/mission-protocol/types.js +110 -0
- package/dist/src/mission-protocol/worker-status.js +2 -0
- package/dist/src/models/config-loader.js +76 -14
- package/dist/src/models/grok-build-models.js +93 -41
- package/dist/src/models/model-capabilities.v1.json +3183 -24
- package/dist/src/models/model-discovery.js +931 -67
- package/dist/src/models/provider-policy.js +719 -11
- package/dist/src/models/qualification-digest.d.mts +2 -0
- package/dist/src/models/qualification-digest.mjs +17 -0
- package/dist/src/models/resolver.js +261 -0
- package/dist/src/models/worker-direct-readiness.js +550 -0
- package/dist/src/models/worker-dispatch-offer.js +169 -0
- package/dist/src/models/worker-health-readiness.js +144 -0
- package/dist/src/models/worker-installation.d.mts +39 -0
- package/dist/src/models/worker-installation.mjs +986 -0
- package/dist/src/models/wrapper-route.js +18 -0
- package/dist/src/ops/registry.js +9 -14
- package/dist/src/plugins/standalone-packager.js +4 -3
- package/dist/src/process/bounded-child-process.d.mts +84 -0
- package/dist/src/process/bounded-child-process.mjs +430 -0
- package/dist/src/process/cli-command.d.mts +16 -0
- package/dist/src/process/cli-command.mjs +75 -0
- package/dist/src/process/signal-child.d.mts +6 -0
- package/dist/src/process/signal-child.mjs +7 -0
- package/dist/src/providers/capability-matrix.js +8 -0
- package/dist/src/providers/capability-matrix.yaml +270 -0
- package/dist/src/providers/deployed-skill-roots.js +20 -0
- package/dist/src/providers/grok-build-acp.js +3 -2
- package/dist/src/providers/grok-build-headless.js +53 -23
- package/dist/src/providers/grok-build-inspect.js +1 -0
- package/dist/src/providers/omp-agent.d.mts +8 -0
- package/dist/src/providers/omp-diagnostics.d.mts +1 -0
- package/dist/src/providers/omp-paths.d.mts +13 -0
- package/dist/src/providers/provider-definitions.js +9 -1
- package/dist/src/providers/provider-definitions.mjs +9 -2
- package/dist/src/providers/skill-ownership.d.mts +9 -0
- package/dist/src/providers/skill-ownership.mjs +88 -0
- package/dist/src/rules/activation.d.mts +21 -0
- package/dist/src/rules/activation.mjs +62 -0
- package/dist/src/rules/inline-budget.d.mts +26 -0
- package/dist/src/rules/inline-budget.mjs +66 -0
- package/dist/src/rules/inventory.js +129 -0
- package/dist/src/rules/pin-state.js +73 -0
- package/dist/src/rules/pins.d.mts +14 -0
- package/dist/src/rules/pins.mjs +112 -0
- package/dist/src/rules/rule-frontmatter.schema.json +197 -0
- package/dist/src/serve/executor-registry.js +16 -24
- package/dist/src/serve/fleet-mission-conductor.js +9 -0
- package/dist/src/serve/mission-conductor.js +47 -12
- package/dist/src/serve/shared-host-scheduler.js +2 -0
- package/dist/src/serve/worker-invocation.js +558 -0
- package/dist/src/serve/worker-stdin-frame.d.mts +10 -0
- package/dist/src/serve/worker-stdin-frame.mjs +107 -0
- package/dist/src/sessions/adapter-registry.js +49 -0
- package/dist/src/sessions/adapters/claude.js +39 -54
- package/dist/src/sessions/adapters/codex.js +82 -67
- package/dist/src/sessions/adapters/copilot.js +4 -4
- package/dist/src/sessions/adapters/cursor.js +40 -57
- package/dist/src/sessions/adapters/deepseek-harness.js +15 -12
- package/dist/src/sessions/adapters/factory.js +31 -27
- package/dist/src/sessions/adapters/generic.js +43 -9
- package/dist/src/sessions/adapters/grok-build.js +11 -11
- package/dist/src/sessions/adapters/grokbot-locator.js +111 -0
- package/dist/src/sessions/adapters/grokbot.js +434 -24
- package/dist/src/sessions/adapters/hermes.js +27 -29
- package/dist/src/sessions/adapters/muse-workspace-scan.js +128 -0
- package/dist/src/sessions/adapters/muse.js +200 -104
- package/dist/src/sessions/adapters/omp.js +28 -14
- package/dist/src/sessions/adapters/openclaw.js +89 -79
- package/dist/src/sessions/adapters/opencode.js +27 -24
- package/dist/src/sessions/adapters/openhuman.js +18 -60
- package/dist/src/sessions/adapters/pi.js +30 -14
- package/dist/src/sessions/adapters/warp.js +3 -3
- package/dist/src/sessions/adapters/windsurf.js +19 -48
- package/dist/src/sessions/batch-contracts.js +25 -5
- package/dist/src/sessions/batch-import.js +72 -51
- package/dist/src/sessions/candidates.js +47 -11
- package/dist/src/sessions/contracts.js +75 -2
- package/dist/src/sessions/coverage-preflight.js +134 -0
- package/dist/src/sessions/discovery.js +3 -0
- package/dist/src/sessions/export-plan.js +4 -3
- package/dist/src/sessions/grok-build-cli.js +67 -5
- package/dist/src/sessions/import-exclusions.js +72 -0
- package/dist/src/sessions/import-lease.js +34 -18
- package/dist/src/sessions/import-limits.js +37 -0
- package/dist/src/sessions/importer.js +84 -46
- package/dist/src/sessions/index.js +2 -0
- package/dist/src/sessions/lifecycle.js +45 -0
- package/dist/src/sessions/policy.js +133 -25
- package/dist/src/sessions/readers.js +106 -53
- package/dist/src/sessions/refresh.js +106 -0
- package/dist/src/sessions/repository.js +199 -63
- package/dist/src/sessions/workspace-discovery.js +315 -88
- package/dist/src/sessions/workspace-matching.js +107 -0
- package/dist/src/skills/adapters/clawhub.js +10 -8
- package/dist/src/skills/adapters/openclaw.js +10 -7
- package/dist/src/skills/importer.js +1 -0
- package/dist/src/smiths/context-pipeline/aiwg-md.js +11 -0
- package/dist/src/smiths/context-pipeline/claude-hook.js +3 -26
- package/dist/src/smiths/context-pipeline/finalization.js +6 -5
- package/dist/src/smiths/context-pipeline/generator.js +21 -4
- package/dist/src/smiths/context-pipeline/parallelism-section.js +195 -14
- package/dist/src/smiths/context-pipeline/workspace-context.js +116 -9
- package/dist/src/smiths/hook-bridge/codex-translator.js +6 -5
- package/dist/src/smiths/mcpsmith/example.js +1 -1
- package/dist/src/smiths/mcpsmith/generator.js +1 -1
- package/dist/src/smiths/toolsmith/runtime-discovery.d.mts +10 -0
- package/dist/src/smiths/toolsmith/runtime-discovery.mjs +85 -31
- package/dist/src/storage/backends/fs.js +18 -76
- package/dist/src/storage/backends/logseq.js +68 -7
- package/dist/src/storage/backends/obsidian.js +1 -0
- package/dist/src/storage/fortemi-qualification-receipt.js +2 -2
- package/dist/src/testing/generators/test-code-generator.js +57 -30
- package/dist/src/tracker/forge-http.js +2 -1
- package/dist/src/uhp/client.js +11 -1
- package/dist/src/uhp/mission.js +5 -0
- package/dist/src/update/checker.d.mts +2 -0
- package/dist/src/update/checker.mjs +5 -5
- package/dist/src/update/notifier.mjs +54 -2
- package/dist/src/update/service.d.mts +22 -0
- package/dist/src/utils/contained-filesystem.d.mts +37 -0
- package/dist/src/utils/contained-filesystem.mjs +683 -0
- package/dist/src/utils/temporary-directory.js +36 -0
- package/dist/src/writing/example-generator.js +1 -1
- package/dist/src/writing/fidelity.js +18 -1
- package/package.json +32 -2
- package/schemas/mission-v1.schema.json +2429 -0
- package/schemas/models/model-catalog.v1.schema.json +301 -0
- package/schemas/models/model-config-compatibility.v1.schema.json +281 -0
- package/schemas/models/model-policy.v1.schema.json +14 -0
- package/schemas/models/provider-model-capabilities.v1.schema.json +1072 -0
- package/tools/_resolve-impl.mjs +39 -2
- package/tools/agents/deploy-agents.mjs +64 -23
- package/tools/agents/providers/base.mjs +153 -166
- package/tools/agents/providers/claude.mjs +8 -24
- package/tools/agents/providers/codex.mjs +18 -11
- package/tools/agents/providers/cursor.mjs +19 -18
- package/tools/agents/providers/grok-build.mjs +3 -1
- package/tools/agents/providers/grokbot.mjs +11 -12
- package/tools/agents/providers/hermes.mjs +62 -49
- package/tools/agents/providers/omp.mjs +5 -2
- package/tools/agents/providers/openclaw-translator.mjs +19 -5
- package/tools/agents/providers/openclaw.mjs +9 -4
- package/tools/agents/providers/pi.mjs +5 -0
- package/tools/agents/providers/provider-prepare-channel.mjs +5 -0
- package/tools/agents/providers/provider-prepare-coordinator.mjs +247 -0
- package/tools/agents/providers/provider-prepare-worker.mjs +84 -0
- package/tools/agents/providers/rule-delivery.mjs +1270 -0
- package/tools/agents/providers/warp.mjs +20 -26
- package/tools/cli/decision-offload-report.mjs +40 -0
- package/tools/cli/workspace-status.mjs +862 -0
- package/tools/plugin/package-plugins.mjs +186 -8
- package/tools/plugin/plugin-links.mjs +114 -0
- package/tools/providers/antigravity-transport.mjs +3 -1
- package/tools/providers/deepseek-harness-transport.mjs +360 -0
- package/tools/providers/omp-transport.mjs +194 -0
- package/tools/ralph-external/lib/claude-adapter.mjs +389 -0
- package/tools/ralph-external/lib/codex-adapter.mjs +432 -0
- package/tools/ralph-external/lib/consecutive-failure-circuit-breaker.mjs +1748 -0
- package/tools/ralph-external/lib/deepseek-harness-adapter.mjs +397 -0
- package/tools/ralph-external/lib/factory-adapter.mjs +503 -0
- package/tools/ralph-external/lib/launcher-recovery-evidence.mjs +55 -0
- package/tools/ralph-external/lib/muse-adapter.mjs +364 -0
- package/tools/ralph-external/lib/omp-adapter.mjs +315 -0
- package/tools/ralph-external/lib/opencode-adapter.mjs +575 -0
- package/tools/ralph-external/lib/openhuman-adapter.mjs +75 -0
- package/tools/ralph-external/lib/pi-adapter.mjs +329 -0
- package/tools/ralph-external/lib/provider-adapter.mjs +748 -0
- package/tools/ralph-external/lib/recovery-probe.mjs +72 -0
- package/tools/ralph-external/lib/session-environment.mjs +28 -0
- package/tools/ralph-external/lib/systemd-client.mjs +49 -0
- package/tools/ralph-external/lib/worker-health.mjs +439 -0
- package/tools/ralph-external/lib/worker-isolation.mjs +717 -0
- package/tools/ralph-external/lib/worker-overflow.mjs +50 -0
- package/tools/ralph-external/process-monitor.mjs +1017 -0
- package/tools/ralph-external/session-launcher.mjs +5057 -0
- package/tools/scripts/resource-preflight.mjs +541 -0
- package/tools/skills/deploy-skills-codex.mjs +2 -1
- package/vscode-extension/schemas/aiwg.config.v1.json +2916 -0
|
@@ -31,14 +31,33 @@ function formatDiagnostic(d) {
|
|
|
31
31
|
/**
|
|
32
32
|
* Format lint results in full detail
|
|
33
33
|
*/
|
|
34
|
+
function formatBudget(result) {
|
|
35
|
+
const report = result.inlineBudget;
|
|
36
|
+
if (!report)
|
|
37
|
+
return [];
|
|
38
|
+
return [
|
|
39
|
+
`Startup budget (${report.provider}): limit ${report.limit} tokens${report.disabled ? ' (guard disabled)' : ''}; selected ${report.selected_tokens} estimated tokens (${report.selected_bytes} bytes; ${report.estimate})`,
|
|
40
|
+
...report.contributors.map(file => ` ${file.path}: ${file.bytes} bytes (${file.estimated_tokens} estimated tokens)`),
|
|
41
|
+
];
|
|
42
|
+
}
|
|
34
43
|
function formatFull(result) {
|
|
35
44
|
const lines = [];
|
|
36
45
|
lines.push(`${BOLD}AIWG Lint${RESET}`);
|
|
37
46
|
lines.push(`Target: ${result.target}`);
|
|
38
47
|
lines.push(`Rulesets: ${result.rulesets.join(', ')}`);
|
|
39
48
|
lines.push(`Files checked: ${result.summary.filesChecked}`);
|
|
49
|
+
lines.push(...formatBudget(result));
|
|
40
50
|
lines.push(`Rules applied: ${result.summary.rulesApplied} of ${result.summary.rulesSelected}`);
|
|
41
51
|
lines.push('');
|
|
52
|
+
if (result.summary.coverageMessage)
|
|
53
|
+
lines.push(`! ${result.summary.coverageMessage}`);
|
|
54
|
+
if (result.ruleCoverage) {
|
|
55
|
+
lines.push('Rule coverage (files by rule):');
|
|
56
|
+
for (const [ruleId, files] of Object.entries(result.ruleCoverage)) {
|
|
57
|
+
lines.push(` ${ruleId}: ${files.length ? files.join(', ') : '(no files)'}`);
|
|
58
|
+
}
|
|
59
|
+
lines.push('');
|
|
60
|
+
}
|
|
42
61
|
// A target that excludes every rule produces the same clean output as a
|
|
43
62
|
// target that passes them, which is how 34 findings stayed invisible across a
|
|
44
63
|
// long session (#2555). Say so before the verdict.
|
|
@@ -92,9 +111,14 @@ function formatFull(result) {
|
|
|
92
111
|
* Format lint results as a summary (counts only)
|
|
93
112
|
*/
|
|
94
113
|
function formatSummary(result) {
|
|
95
|
-
const lines = [];
|
|
114
|
+
const lines = [...formatBudget(result)];
|
|
96
115
|
lines.push(`Lint: ${result.summary.filesChecked} files, ${result.summary.errors} errors, ${result.summary.warnings} warnings, ${result.summary.infos} info`);
|
|
97
116
|
lines.push(`Rules applied: ${result.summary.rulesApplied} of ${result.summary.rulesSelected}`);
|
|
117
|
+
if (result.summary.coverageMessage)
|
|
118
|
+
lines.push(`! ${result.summary.coverageMessage}`);
|
|
119
|
+
if (result.summary.inapplicableRules.length > 0) {
|
|
120
|
+
lines.push(`Inapplicable rules: ${result.summary.inapplicableRules.join(', ')}`);
|
|
121
|
+
}
|
|
98
122
|
if (result.summary.rulesSelected > 0 && result.summary.rulesApplied === 0) {
|
|
99
123
|
lines.push(`! No rule applies to this target — this is not a clean result (#2555).`);
|
|
100
124
|
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { loadLocalCapabilityEntries, resolveRuleBindingTarget } from '../artifacts/query-engine.js';
|
|
2
|
+
import { parseRuleFrontmatter, RULE_BINDING_TYPES } from '../rules/activation.mjs';
|
|
3
|
+
export const ruleActivationRuleset = {
|
|
4
|
+
id: 'rule-activation', name: 'Rule activation', framework: 'core', version: '1.0.0',
|
|
5
|
+
description: 'Validate rule and behavior activation contracts and exact indexed bindings',
|
|
6
|
+
rules: [{
|
|
7
|
+
id: 'rules/activation', name: 'Rule activation contract', severity: 'error',
|
|
8
|
+
description: 'Validate activation, summaries, paths, bindings, and migration fallback',
|
|
9
|
+
appliesTo: { glob: '**/{rules/**/*.md,behaviors/**/BEHAVIOR.md}' },
|
|
10
|
+
checks: [{ type: 'rule-activation' }],
|
|
11
|
+
}],
|
|
12
|
+
};
|
|
13
|
+
export function lintRuleActivation(content, file, projectRoot, entries) {
|
|
14
|
+
// Generated structural indexes are not authored rules.
|
|
15
|
+
if (/^(?:RULES-INDEX|RULES-ONDEMAND)\.md$/.test(file.split('/').pop()))
|
|
16
|
+
return [];
|
|
17
|
+
const result = parseRuleFrontmatter(content);
|
|
18
|
+
const diagnostics = result.diagnostics.map(item => ({
|
|
19
|
+
ruleId: 'rules/activation', ruleName: 'Rule activation contract',
|
|
20
|
+
file, severity: item.severity, message: item.message,
|
|
21
|
+
}));
|
|
22
|
+
if (!result.rule)
|
|
23
|
+
return diagnostics;
|
|
24
|
+
const bindings = result.rule.bound_to;
|
|
25
|
+
if (!Object.values(bindings).some(list => list.length > 0))
|
|
26
|
+
return diagnostics;
|
|
27
|
+
// Reuse existing artifact index ownership and show precedence. No title guessing,
|
|
28
|
+
// corpus directory resolver, or extra binding registry.
|
|
29
|
+
const indexed = entries ?? loadLocalCapabilityEntries(projectRoot);
|
|
30
|
+
for (const key of Object.keys(RULE_BINDING_TYPES)) {
|
|
31
|
+
for (const id of bindings[key]) {
|
|
32
|
+
try {
|
|
33
|
+
resolveRuleBindingTarget(indexed, RULE_BINDING_TYPES[key], id);
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
diagnostics.push({ ruleId: 'rules/activation', ruleName: 'Rule activation contract',
|
|
37
|
+
file, severity: 'error', message: error instanceof Error ? error.message : String(error) });
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return diagnostics;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=rule-activation.js.map
|
package/dist/src/lint/runner.js
CHANGED
|
@@ -7,27 +7,54 @@
|
|
|
7
7
|
* @issue #810
|
|
8
8
|
*/
|
|
9
9
|
import fs from 'fs';
|
|
10
|
-
import {
|
|
10
|
+
import { lintRuleActivation } from './rule-activation.js';
|
|
11
|
+
import { guardRulesInlineBudget } from '../rules/inline-budget.mjs';
|
|
12
|
+
import { dropGitignored } from '../config/gitignore.js';
|
|
11
13
|
import fsp from 'fs/promises';
|
|
12
14
|
import path from 'path';
|
|
13
15
|
import { glob } from 'glob';
|
|
14
16
|
import { minimatch } from 'minimatch';
|
|
17
|
+
import { parse } from 'yaml';
|
|
15
18
|
/**
|
|
16
19
|
* Parse YAML-style frontmatter from a markdown file
|
|
17
20
|
* Returns key-value pairs from the --- delimited block
|
|
18
21
|
*/
|
|
19
22
|
function parseFrontmatter(content) {
|
|
20
|
-
const match = content.match(/^---\n([\s\S]*?)\n
|
|
23
|
+
const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/);
|
|
21
24
|
if (!match)
|
|
22
25
|
return {};
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
try {
|
|
27
|
+
const parsed = parse(match[1]);
|
|
28
|
+
return parsed !== null && typeof parsed === 'object' && !Array.isArray(parsed)
|
|
29
|
+
? parsed
|
|
30
|
+
: {};
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
// Invalid YAML cannot supply required metadata.
|
|
34
|
+
return {};
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
function isPresent(value) {
|
|
38
|
+
if (value == null)
|
|
39
|
+
return false;
|
|
40
|
+
if (typeof value === 'string')
|
|
41
|
+
return value.trim().length > 0;
|
|
42
|
+
if (Array.isArray(value))
|
|
43
|
+
return value.length > 0;
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
/** Resolve project-relative metadata from the nearest repository/workspace marker. */
|
|
47
|
+
function findProjectRoot(targetDir) {
|
|
48
|
+
let dir = path.resolve(targetDir);
|
|
49
|
+
while (true) {
|
|
50
|
+
if (fs.existsSync(path.join(dir, '.git')) || fs.existsSync(path.join(dir, '.aiwg'))) {
|
|
51
|
+
return dir;
|
|
28
52
|
}
|
|
53
|
+
const parent = path.dirname(dir);
|
|
54
|
+
if (parent === dir)
|
|
55
|
+
return path.resolve(targetDir);
|
|
56
|
+
dir = parent;
|
|
29
57
|
}
|
|
30
|
-
return result;
|
|
31
58
|
}
|
|
32
59
|
const DEFAULT_REFERENCE_PATTERN = '\\bREF-\\d{3,}\\b';
|
|
33
60
|
/**
|
|
@@ -215,8 +242,9 @@ function buildReferenceIndex(allFiles) {
|
|
|
215
242
|
* Preserve support for references stored outside the lint target when a rule
|
|
216
243
|
* explicitly supplies basePath. Accept both exact and slugged filenames.
|
|
217
244
|
*/
|
|
218
|
-
function resolvesFromBasePath(refId, targetDir, basePath) {
|
|
245
|
+
function resolvesFromBasePath(refId, targetDir, basePath, projectRoot) {
|
|
219
246
|
const candidateDirs = new Set([
|
|
247
|
+
path.resolve(projectRoot, basePath),
|
|
220
248
|
path.resolve(targetDir, basePath),
|
|
221
249
|
path.resolve(process.cwd(), basePath),
|
|
222
250
|
]);
|
|
@@ -237,14 +265,14 @@ function resolvesFromBasePath(refId, targetDir, basePath) {
|
|
|
237
265
|
/**
|
|
238
266
|
* Run a single check against a file's content and frontmatter
|
|
239
267
|
*/
|
|
240
|
-
function runCheck(check, content, frontmatter, filePath, targetDir, allFiles, referenceIndex) {
|
|
268
|
+
function runCheck(check, content, frontmatter, filePath, targetDir, allFiles, referenceIndex, projectRoot) {
|
|
241
269
|
const diagnostics = [];
|
|
242
270
|
switch (check.type) {
|
|
243
271
|
case 'frontmatter-required': {
|
|
244
272
|
if (!check.fields)
|
|
245
273
|
break;
|
|
246
274
|
for (const field of check.fields) {
|
|
247
|
-
if (!frontmatter[field]
|
|
275
|
+
if (!isPresent(frontmatter[field])) {
|
|
248
276
|
diagnostics.push({
|
|
249
277
|
ruleId: '',
|
|
250
278
|
ruleName: '',
|
|
@@ -261,7 +289,7 @@ function runCheck(check, content, frontmatter, filePath, targetDir, allFiles, re
|
|
|
261
289
|
if (!check.field || !check.pattern)
|
|
262
290
|
break;
|
|
263
291
|
const value = frontmatter[check.field];
|
|
264
|
-
if (value && !new RegExp(check.pattern).test(value)) {
|
|
292
|
+
if (isPresent(value) && typeof value !== 'object' && !new RegExp(check.pattern).test(String(value))) {
|
|
265
293
|
diagnostics.push({
|
|
266
294
|
ruleId: '',
|
|
267
295
|
ruleName: '',
|
|
@@ -282,7 +310,9 @@ function runCheck(check, content, frontmatter, filePath, targetDir, allFiles, re
|
|
|
282
310
|
let match;
|
|
283
311
|
while ((match = regex.exec(lines[i])) !== null) {
|
|
284
312
|
const refId = match[0];
|
|
285
|
-
const
|
|
313
|
+
const basePaths = check.basePath
|
|
314
|
+
? [check.basePath]
|
|
315
|
+
: ['.aiwg/research/findings', 'findings', 'documentation/references', '.'];
|
|
286
316
|
// A corpus documents its deliberate gaps ("REF-2464 remains
|
|
287
317
|
// unallocated after deduplication"). Reading that sentence as a
|
|
288
318
|
// dangling reference left only two ways to silence an error: delete
|
|
@@ -290,7 +320,7 @@ function runCheck(check, content, frontmatter, filePath, targetDir, allFiles, re
|
|
|
290
320
|
// absent (#2555).
|
|
291
321
|
if (absence.some((re) => re.test(lines[i])))
|
|
292
322
|
continue;
|
|
293
|
-
if (!referenceIndex.has(refId) && !resolvesFromBasePath(refId, targetDir, basePath)) {
|
|
323
|
+
if (!referenceIndex.has(refId) && !basePaths.some(basePath => resolvesFromBasePath(refId, targetDir, basePath, projectRoot))) {
|
|
294
324
|
diagnostics.push({
|
|
295
325
|
ruleId: '',
|
|
296
326
|
ruleName: '',
|
|
@@ -376,9 +406,12 @@ function runCheck(check, content, frontmatter, filePath, targetDir, allFiles, re
|
|
|
376
406
|
if (!check.field)
|
|
377
407
|
break;
|
|
378
408
|
const refPath = frontmatter[check.field];
|
|
379
|
-
if (refPath) {
|
|
380
|
-
|
|
381
|
-
|
|
409
|
+
if (isPresent(refPath)) {
|
|
410
|
+
// Project-root-relative is canonical (#3145); target-relative paths
|
|
411
|
+
// written for the legacy layout keep resolving.
|
|
412
|
+
const found = typeof refPath === 'string' &&
|
|
413
|
+
[projectRoot, targetDir].some(base => fs.existsSync(path.resolve(base, refPath)));
|
|
414
|
+
if (!found) {
|
|
382
415
|
diagnostics.push({
|
|
383
416
|
ruleId: '',
|
|
384
417
|
ruleName: '',
|
|
@@ -398,7 +431,8 @@ function runCheck(check, content, frontmatter, filePath, targetDir, allFiles, re
|
|
|
398
431
|
if (!check.pattern)
|
|
399
432
|
break;
|
|
400
433
|
const basename = path.basename(filePath, '.md');
|
|
401
|
-
|
|
434
|
+
const match = basename.match(new RegExp(check.pattern));
|
|
435
|
+
if (!match) {
|
|
402
436
|
diagnostics.push({
|
|
403
437
|
ruleId: '',
|
|
404
438
|
ruleName: '',
|
|
@@ -408,6 +442,20 @@ function runCheck(check, content, frontmatter, filePath, targetDir, allFiles, re
|
|
|
408
442
|
fix: `Rename to match the pattern ${check.pattern}`,
|
|
409
443
|
});
|
|
410
444
|
}
|
|
445
|
+
else if (check.field && isPresent(frontmatter[check.field])) {
|
|
446
|
+
const identifier = match[1] ?? match[0];
|
|
447
|
+
const value = frontmatter[check.field];
|
|
448
|
+
if (value !== identifier) {
|
|
449
|
+
diagnostics.push({
|
|
450
|
+
ruleId: '',
|
|
451
|
+
ruleName: '',
|
|
452
|
+
severity: 'warn',
|
|
453
|
+
file: filePath,
|
|
454
|
+
message: `File identifier '${identifier}' does not match frontmatter field '${check.field}': ${String(value)}`,
|
|
455
|
+
fix: `Make the filename identifier and '${check.field}' field agree`,
|
|
456
|
+
});
|
|
457
|
+
}
|
|
458
|
+
}
|
|
411
459
|
break;
|
|
412
460
|
}
|
|
413
461
|
case 'cross-ref-bidirectional': {
|
|
@@ -473,15 +521,13 @@ export function ruleAppliesToFile(ruleGlob, file, targetDir) {
|
|
|
473
521
|
/**
|
|
474
522
|
* Run a single rule against all matching files in the target
|
|
475
523
|
*/
|
|
476
|
-
async function runRule(rule, targetDir, allFiles, referenceIndex) {
|
|
524
|
+
async function runRule(rule, targetDir, allFiles, referenceIndex, projectRoot, artifactEntries) {
|
|
477
525
|
const diagnostics = [];
|
|
478
|
-
RULE_APPLIED.delete(rule.id);
|
|
479
526
|
// Filter files matching the rule's glob
|
|
480
527
|
const ruleGlob = rule.appliesTo.glob;
|
|
481
528
|
const matchingFiles = allFiles.filter(f => ruleAppliesToFile(ruleGlob, f, targetDir));
|
|
482
529
|
if (matchingFiles.length === 0)
|
|
483
|
-
return diagnostics;
|
|
484
|
-
RULE_APPLIED.add(rule.id);
|
|
530
|
+
return { diagnostics, files: matchingFiles };
|
|
485
531
|
// Handle id-unique check at the ruleset level
|
|
486
532
|
const uniqueCheck = rule.checks.find(c => c.type === 'id-unique');
|
|
487
533
|
if (uniqueCheck) {
|
|
@@ -516,7 +562,11 @@ async function runRule(rule, targetDir, allFiles, referenceIndex) {
|
|
|
516
562
|
for (const check of rule.checks) {
|
|
517
563
|
if (check.type === 'id-unique')
|
|
518
564
|
continue; // Already handled
|
|
519
|
-
|
|
565
|
+
if (check.type === 'rule-activation') {
|
|
566
|
+
diagnostics.push(...lintRuleActivation(content, file, projectRoot, artifactEntries));
|
|
567
|
+
continue;
|
|
568
|
+
}
|
|
569
|
+
const checkDiagnostics = runCheck(check, content, frontmatter, file, targetDir, allFiles, referenceIndex, projectRoot);
|
|
520
570
|
for (const d of checkDiagnostics) {
|
|
521
571
|
d.ruleId = rule.id;
|
|
522
572
|
d.ruleName = rule.name;
|
|
@@ -525,10 +575,8 @@ async function runRule(rule, targetDir, allFiles, referenceIndex) {
|
|
|
525
575
|
}
|
|
526
576
|
}
|
|
527
577
|
}
|
|
528
|
-
return diagnostics;
|
|
578
|
+
return { diagnostics, files: matchingFiles };
|
|
529
579
|
}
|
|
530
|
-
/** Rule ids that selected at least one file in the current run (#2555). */
|
|
531
|
-
const RULE_APPLIED = new Set();
|
|
532
580
|
/**
|
|
533
581
|
* Collect all files under a target directory
|
|
534
582
|
*/
|
|
@@ -547,37 +595,6 @@ async function collectFiles(targetDir, recursive, respectGitignore = true) {
|
|
|
547
595
|
return [];
|
|
548
596
|
}
|
|
549
597
|
}
|
|
550
|
-
/**
|
|
551
|
-
* Drop files git ignores (#2555).
|
|
552
|
-
*
|
|
553
|
-
* Generated trees are regenerated, not authored: linting `indices/` reported an
|
|
554
|
-
* error in text that documents a deliberate gap. `git check-ignore` is asked
|
|
555
|
-
* once for the whole set so the semantics are git's own (negations, nested
|
|
556
|
-
* `.gitignore`, `core.excludesFile`) rather than a re-implementation. Outside a
|
|
557
|
-
* repository, or without git, every file is kept.
|
|
558
|
-
*/
|
|
559
|
-
function dropGitignored(targetDir, files) {
|
|
560
|
-
if (files.length === 0)
|
|
561
|
-
return files;
|
|
562
|
-
try {
|
|
563
|
-
const result = spawnSync('git', ['check-ignore', '--stdin'], {
|
|
564
|
-
cwd: targetDir,
|
|
565
|
-
input: `${files.join('\n')}\n`,
|
|
566
|
-
encoding: 'utf8',
|
|
567
|
-
});
|
|
568
|
-
// 0 = some paths ignored, 1 = none ignored, anything else = not a repo or
|
|
569
|
-
// git unavailable, in which case nothing is filtered.
|
|
570
|
-
if (result.error || (result.status !== 0 && result.status !== 1))
|
|
571
|
-
return files;
|
|
572
|
-
const ignored = new Set((result.stdout ?? '').split('\n').map((line) => line.trim()).filter(Boolean));
|
|
573
|
-
if (ignored.size === 0)
|
|
574
|
-
return files;
|
|
575
|
-
return files.filter((file) => !ignored.has(file));
|
|
576
|
-
}
|
|
577
|
-
catch {
|
|
578
|
-
return files;
|
|
579
|
-
}
|
|
580
|
-
}
|
|
581
598
|
/**
|
|
582
599
|
* Auto-detect which rulesets apply to a target path
|
|
583
600
|
*
|
|
@@ -602,27 +619,74 @@ function autoDetectRulesets(target, available) {
|
|
|
602
619
|
}
|
|
603
620
|
}
|
|
604
621
|
// If no auto-detection, return all available
|
|
605
|
-
return matches.length > 0
|
|
622
|
+
return matches.length > 0
|
|
623
|
+
? available.filter(ruleset => ruleset.id === 'rule-activation' || matches.includes(ruleset))
|
|
624
|
+
: available;
|
|
606
625
|
}
|
|
607
626
|
/**
|
|
608
627
|
* Run lint on a target path with specified or auto-detected rulesets
|
|
609
628
|
*/
|
|
610
629
|
export async function runLint(targetDir, rulesets, options = {}) {
|
|
611
630
|
const recursive = options.recursive ?? true;
|
|
612
|
-
const
|
|
631
|
+
const targetStat = await fsp.stat(targetDir).catch(() => null);
|
|
632
|
+
const scanDir = targetStat?.isFile() ? path.dirname(targetDir) : targetDir;
|
|
633
|
+
const projectRoot = findProjectRoot(scanDir);
|
|
634
|
+
const respectGitignore = options.respectGitignore ?? true;
|
|
635
|
+
let allFiles;
|
|
636
|
+
let targetMessage = '';
|
|
637
|
+
if (!targetStat) {
|
|
638
|
+
allFiles = [];
|
|
639
|
+
targetMessage = `Target does not exist or is inaccessible: ${targetDir}.`;
|
|
640
|
+
}
|
|
641
|
+
else if (targetStat.isFile()) {
|
|
642
|
+
const file = path.basename(targetDir);
|
|
643
|
+
if (!/\.(md|yaml|yml|json)$/.test(file)) {
|
|
644
|
+
allFiles = [];
|
|
645
|
+
targetMessage = `Unsupported file type: ${file}. Expected .md, .yaml, .yml or .json.`;
|
|
646
|
+
}
|
|
647
|
+
else {
|
|
648
|
+
allFiles = respectGitignore ? dropGitignored(scanDir, [file]) : [file];
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
else {
|
|
652
|
+
allFiles = await collectFiles(scanDir, recursive, respectGitignore);
|
|
653
|
+
}
|
|
613
654
|
const referenceIndex = buildReferenceIndex(allFiles);
|
|
614
655
|
const allDiagnostics = [];
|
|
615
656
|
const inapplicableRules = [];
|
|
657
|
+
const ruleCoverage = {};
|
|
616
658
|
let rulesSelected = 0;
|
|
617
659
|
for (const ruleset of rulesets) {
|
|
618
660
|
for (const rule of ruleset.rules) {
|
|
619
661
|
rulesSelected += 1;
|
|
620
|
-
const diagnostics = await runRule(rule,
|
|
621
|
-
|
|
662
|
+
const { diagnostics, files } = await runRule(rule, scanDir, allFiles, referenceIndex, projectRoot, options.artifactEntries);
|
|
663
|
+
ruleCoverage[rule.id] = files;
|
|
664
|
+
if (files.length === 0)
|
|
622
665
|
inapplicableRules.push(rule.id);
|
|
623
666
|
allDiagnostics.push(...diagnostics);
|
|
624
667
|
}
|
|
625
668
|
}
|
|
669
|
+
let budget;
|
|
670
|
+
if (options.startupBudget) {
|
|
671
|
+
try {
|
|
672
|
+
budget = guardRulesInlineBudget({
|
|
673
|
+
...options.startupBudget, reportOnly: options.ci ? false : (options.startupBudget.reportOnly ?? true),
|
|
674
|
+
});
|
|
675
|
+
}
|
|
676
|
+
catch (error) {
|
|
677
|
+
allDiagnostics.push({
|
|
678
|
+
ruleId: 'rules/inline-budget', ruleName: 'Rules inline budget', file: '(assembled startup)',
|
|
679
|
+
severity: 'error', message: error instanceof Error ? error.message : String(error),
|
|
680
|
+
});
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
if (budget) {
|
|
684
|
+
for (const item of budget.diagnostics)
|
|
685
|
+
allDiagnostics.push({
|
|
686
|
+
ruleId: 'rules/inline-budget', ruleName: 'Rules inline budget', file: '(assembled startup)',
|
|
687
|
+
severity: item.severity, message: item.message,
|
|
688
|
+
});
|
|
689
|
+
}
|
|
626
690
|
const errors = allDiagnostics.filter(d => d.severity === 'error').length;
|
|
627
691
|
const warnings = allDiagnostics.filter(d => d.severity === 'warn').length;
|
|
628
692
|
const infos = allDiagnostics.filter(d => d.severity === 'info').length;
|
|
@@ -634,10 +698,20 @@ export async function runLint(targetDir, rulesets, options = {}) {
|
|
|
634
698
|
passed = false;
|
|
635
699
|
if (failOn === 'info' && allDiagnostics.length > 0)
|
|
636
700
|
passed = false;
|
|
701
|
+
const rulesApplied = rulesSelected - inapplicableRules.length;
|
|
702
|
+
const coverageMessage = allFiles.length === 0
|
|
703
|
+
? `No files checked. ${targetMessage || 'The target is empty, contains no supported files, or all files are ignored.'}`
|
|
704
|
+
: rulesApplied === 0
|
|
705
|
+
? 'No rules applied. Check the target path and selected ruleset globs.'
|
|
706
|
+
: undefined;
|
|
707
|
+
if (options.ci && !options.allowEmpty && coverageMessage)
|
|
708
|
+
passed = false;
|
|
637
709
|
return {
|
|
638
710
|
target: targetDir,
|
|
639
711
|
rulesets: rulesets.map(r => r.id),
|
|
640
712
|
diagnostics: allDiagnostics,
|
|
713
|
+
...(budget ? { inlineBudget: budget.report } : {}),
|
|
714
|
+
ruleCoverage,
|
|
641
715
|
summary: {
|
|
642
716
|
filesChecked: allFiles.length,
|
|
643
717
|
errors,
|
|
@@ -647,8 +721,9 @@ export async function runLint(targetDir, rulesets, options = {}) {
|
|
|
647
721
|
// A run where no rule selected a file must never read the same as a clean
|
|
648
722
|
// run (#2555). Reporters surface this; callers can gate on it.
|
|
649
723
|
rulesSelected,
|
|
650
|
-
rulesApplied
|
|
724
|
+
rulesApplied,
|
|
651
725
|
inapplicableRules,
|
|
726
|
+
coverageMessage,
|
|
652
727
|
},
|
|
653
728
|
timestamp: new Date().toISOString(),
|
|
654
729
|
};
|