docguard-cli 0.11.0__tar.gz → 0.11.1__tar.gz
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.
- {docguard_cli-0.11.0/extensions/spec-kit-docguard → docguard_cli-0.11.1/.agent}/skills/docguard-fix/SKILL.md +2 -2
- {docguard_cli-0.11.0/extensions/spec-kit-docguard → docguard_cli-0.11.1/.agent}/skills/docguard-guard/SKILL.md +2 -2
- {docguard_cli-0.11.0/extensions/spec-kit-docguard → docguard_cli-0.11.1/.agent}/skills/docguard-review/SKILL.md +2 -2
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/.agent/skills/docguard-score/SKILL.md +2 -2
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/.agent/skills/docguard-sync/SKILL.md +1 -1
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/AGENTS.md +1 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/CHANGELOG.md +40 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/PKG-INFO +1 -1
- docguard_cli-0.11.1/cli/scanners/cdk.mjs +10 -0
- docguard_cli-0.11.1/cli/scanners/iac.mjs +235 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/cli/shared-ignore.mjs +29 -2
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/cli/shared-source.mjs +2 -1
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/cli/validators/docs-coverage.mjs +125 -6
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/cli/validators/docs-sync.mjs +49 -8
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/cli/validators/test-spec.mjs +129 -11
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/cli/validators/todo-tracking.mjs +55 -2
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/docs-canonical/ARCHITECTURE.md +10 -5
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/extensions/spec-kit-docguard/extension.yml +1 -1
- {docguard_cli-0.11.0/.agent → docguard_cli-0.11.1/extensions/spec-kit-docguard}/skills/docguard-fix/SKILL.md +2 -2
- {docguard_cli-0.11.0/.agent → docguard_cli-0.11.1/extensions/spec-kit-docguard}/skills/docguard-guard/SKILL.md +2 -2
- {docguard_cli-0.11.0/.agent → docguard_cli-0.11.1/extensions/spec-kit-docguard}/skills/docguard-review/SKILL.md +2 -2
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/extensions/spec-kit-docguard/skills/docguard-score/SKILL.md +2 -2
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/extensions/spec-kit-docguard/skills/docguard-sync/SKILL.md +1 -1
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/package.json +1 -1
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/pyproject.toml +1 -1
- docguard_cli-0.11.1/specs/003-v011-false-positives/plan.md +140 -0
- docguard_cli-0.11.1/specs/003-v011-false-positives/spec.md +191 -0
- docguard_cli-0.11.1/specs/003-v011-false-positives/tasks.md +156 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/templates/ARCHITECTURE.md.template +52 -0
- docguard_cli-0.11.1/tests/cdk-detection.test.mjs +292 -0
- docguard_cli-0.11.1/tests/docs-coverage.test.mjs +258 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/tests/docs-sync.test.mjs +116 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/tests/test-spec.test.mjs +108 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/tests/todo-tracking.test.mjs +44 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/tests/traceability.test.mjs +15 -9
- docguard_cli-0.11.0/tests/docs-coverage.test.mjs +0 -105
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/.agent/commands/speckit.analyze.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/.agent/commands/speckit.checklist.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/.agent/commands/speckit.clarify.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/.agent/commands/speckit.constitution.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/.agent/commands/speckit.implement.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/.agent/commands/speckit.plan.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/.agent/commands/speckit.specify.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/.agent/commands/speckit.tasks.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/.agent/commands/speckit.taskstoissues.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/.agent/skills/speckit-analyze/SKILL.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/.agent/skills/speckit-checklist/SKILL.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/.agent/skills/speckit-clarify/SKILL.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/.agent/skills/speckit-constitution/SKILL.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/.agent/skills/speckit-implement/SKILL.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/.agent/skills/speckit-plan/SKILL.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/.agent/skills/speckit-specify/SKILL.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/.agent/skills/speckit-tasks/SKILL.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/.agent/skills/speckit-taskstoissues/SKILL.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/.docguard.json +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/.docguardignore +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/.github/dependabot.yml +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/.github/scripts/patch-catalog.py +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/.github/workflows/ci.yml +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/.github/workflows/release.yml +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/.github/workflows/supply-chain.yml +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/.github/workflows/sync-speckit-catalog.yml +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/.gitignore +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/.jules/bolt.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/.jules/palette.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/.jules/sentinel.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/.npmignore +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/.npmrc +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/.specify/extensions/.cache/catalog-ebf165086500aab1-metadata.json +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/.specify/extensions/.cache/catalog-ebf165086500aab1.json +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/.specify/extensions/.cache/catalog-metadata.json +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/.specify/extensions/.cache/catalog.json +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/.specify/init-options.json +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/.specify/memory/constitution.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/.specify/scripts/bash/check-prerequisites.sh +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/.specify/scripts/bash/common.sh +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/.specify/scripts/bash/create-new-feature.sh +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/.specify/scripts/bash/setup-plan.sh +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/.specify/scripts/bash/update-agent-context.sh +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/.specify/templates/agent-file-template.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/.specify/templates/checklist-template.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/.specify/templates/constitution-template.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/.specify/templates/plan-template.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/.specify/templates/spec-template.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/.specify/templates/tasks-template.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/CODE_OF_CONDUCT.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/COMPARISONS.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/CONTRIBUTING.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/DRIFT-LOG.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/LICENSE +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/PHILOSOPHY.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/README.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/ROADMAP.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/SECURITY.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/STANDARD.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/SUPPLY-CHAIN-AUDIT.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/SUPPORT.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/action.yml +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/cli/commands/agents.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/cli/commands/badge.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/cli/commands/ci.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/cli/commands/diagnose.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/cli/commands/diff.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/cli/commands/fix.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/cli/commands/generate.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/cli/commands/guard.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/cli/commands/hooks.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/cli/commands/init.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/cli/commands/llms.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/cli/commands/publish.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/cli/commands/score.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/cli/commands/setup.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/cli/commands/sync.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/cli/commands/trace.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/cli/commands/watch.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/cli/docguard.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/cli/ensure-skills.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/cli/scanners/api-doc.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/cli/scanners/doc-tools.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/cli/scanners/frontend.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/cli/scanners/integrations.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/cli/scanners/memory-plan.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/cli/scanners/project-type.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/cli/scanners/routes.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/cli/scanners/schemas.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/cli/scanners/speckit.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/cli/shared.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/cli/validators/api-surface.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/cli/validators/architecture.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/cli/validators/changelog.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/cli/validators/doc-quality.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/cli/validators/docs-diff.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/cli/validators/drift.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/cli/validators/environment.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/cli/validators/freshness.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/cli/validators/metadata-sync.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/cli/validators/metrics-consistency.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/cli/validators/schema-sync.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/cli/validators/security.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/cli/validators/structure.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/cli/validators/traceability.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/cli/writers/api-reference.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/cli/writers/mechanical.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/cli/writers/sections.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/commands/docguard.fix.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/commands/docguard.guard.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/commands/docguard.review.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/commands/docguard.score.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/configs/fastify.json +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/configs/generic.json +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/configs/nextjs.json +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/configs/python.json +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/docguard_cli/__init__.py +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/docguard_cli/wrapper.py +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/docs/ai-integration.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/docs/commands.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/docs/configuration.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/docs/doc-sections.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/docs/faq.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/docs/installation.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/docs/profiles.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/docs/quickstart.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/docs-canonical/DATA-MODEL.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/docs-canonical/ENVIRONMENT.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/docs-canonical/SECURITY.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/docs-canonical/TEST-SPEC.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/examples/01-express-api/README.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/examples/01-express-api/package.json +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/examples/01-express-api/server.js +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/examples/02-python-flask/README.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/examples/02-python-flask/app.py +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/examples/02-python-flask/docs-canonical/ARCHITECTURE.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/examples/02-python-flask/requirements.txt +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/examples/03-spec-kit-project/CHANGELOG.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/examples/03-spec-kit-project/README.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/examples/03-spec-kit-project/docs-canonical/ARCHITECTURE.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/examples/03-spec-kit-project/docs-canonical/TEST-SPEC.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/examples/03-spec-kit-project/package.json +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/examples/03-spec-kit-project/src/index.js +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/examples/03-spec-kit-project/tests/basic.test.js +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/examples/README.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/extensions/spec-kit-docguard/LICENSE +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/extensions/spec-kit-docguard/README.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/extensions/spec-kit-docguard/commands/diagnose.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/extensions/spec-kit-docguard/commands/fix.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/extensions/spec-kit-docguard/commands/generate.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/extensions/spec-kit-docguard/commands/guard.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/extensions/spec-kit-docguard/commands/init.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/extensions/spec-kit-docguard/commands/score.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/extensions/spec-kit-docguard/commands/sync.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/extensions/spec-kit-docguard/commands/trace.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/extensions/spec-kit-docguard/scripts/bash/common.sh +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/extensions/spec-kit-docguard/scripts/bash/docguard-check-docs.sh +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/extensions/spec-kit-docguard/scripts/bash/docguard-init-doc.sh +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/extensions/spec-kit-docguard/scripts/bash/docguard-suggest-fix.sh +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/extensions/spec-kit-docguard/templates/extensions.yml +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/pr_description.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/specs/001-fix-ignore-validators/plan.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/specs/001-fix-ignore-validators/spec.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/specs/001-fix-ignore-validators/tasks.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/specs/002-fix-test-discovery/plan.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/specs/002-fix-test-discovery/spec.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/specs/002-fix-test-discovery/tasks.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/templates/ADR.md.template +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/templates/AGENTS.md.template +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/templates/CHANGELOG.md.template +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/templates/CURRENT-STATE.md.template +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/templates/DATA-MODEL.md.template +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/templates/DEPLOYMENT.md.template +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/templates/DRIFT-LOG.md.template +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/templates/ENVIRONMENT.md.template +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/templates/KNOWN-GOTCHAS.md.template +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/templates/REQUIREMENTS.md.template +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/templates/ROADMAP.md.template +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/templates/RUNBOOKS.md.template +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/templates/SECURITY.md.template +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/templates/TEST-SPEC.md.template +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/templates/TROUBLESHOOTING.md.template +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/templates/VENDOR-BUGS.md.template +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/templates/ci/github-actions.yml +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/templates/commands/docguard.fix.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/templates/commands/docguard.guard.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/templates/commands/docguard.init.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/templates/commands/docguard.review.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/templates/commands/docguard.update.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/test-draft.js +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/test-metrics.js +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/tests/api-doc.test.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/tests/api-surface.test.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/tests/api-write.test.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/tests/architecture.test.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/tests/backup-failure.test.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/tests/changelog.test.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/tests/commands.test.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/tests/doc-quality.test.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/tests/docs-diff.test.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/tests/drift.test.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/tests/environment.test.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/tests/freshness.test.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/tests/frontend-deep.test.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/tests/frontend.test.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/tests/guard-classify.test.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/tests/hooks.test.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/tests/i18n.test.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/tests/integrations.test.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/tests/mechanical.test.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/tests/memory-plan.test.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/tests/metadata-sync.test.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/tests/metrics-consistency.test.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/tests/monorepo-scanning.test.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/tests/multi-spec.test.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/tests/project-type.test.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/tests/routes-multilang.test.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/tests/schema-sync.test.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/tests/schemas-multilang.test.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/tests/schemas.test.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/tests/sections.test.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/tests/security.test.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/tests/shared-source.test.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/tests/structure.test.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/tests/sync.test.mjs +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/vscode-extension/.vscodeignore +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/vscode-extension/README.md +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/vscode-extension/extension.js +0 -0
- {docguard_cli-0.11.0 → docguard_cli-0.11.1}/vscode-extension/package.json +0 -0
|
@@ -6,10 +6,10 @@ description: AI-driven documentation repair with structured research workflow, t
|
|
|
6
6
|
compatibility: Requires DocGuard CLI installed (npm i -g docguard-cli or npx docguard-cli)
|
|
7
7
|
metadata:
|
|
8
8
|
author: docguard
|
|
9
|
-
version: 0.
|
|
9
|
+
version: 0.11.1
|
|
10
10
|
source: extensions/spec-kit-docguard/skills/docguard-fix
|
|
11
11
|
---
|
|
12
|
-
<!-- docguard:version: 0.
|
|
12
|
+
<!-- docguard:version: 0.11.1 -->
|
|
13
13
|
|
|
14
14
|
# DocGuard Fix Skill
|
|
15
15
|
|
|
@@ -7,10 +7,10 @@ description: Run DocGuard guard validation against Canonical-Driven Development
|
|
|
7
7
|
compatibility: Requires DocGuard CLI installed (npm i -g docguard-cli or npx docguard-cli)
|
|
8
8
|
metadata:
|
|
9
9
|
author: docguard
|
|
10
|
-
version: 0.
|
|
10
|
+
version: 0.11.1
|
|
11
11
|
source: extensions/spec-kit-docguard/skills/docguard-guard
|
|
12
12
|
---
|
|
13
|
-
<!-- docguard:version: 0.
|
|
13
|
+
<!-- docguard:version: 0.11.1 -->
|
|
14
14
|
|
|
15
15
|
# DocGuard Guard Skill
|
|
16
16
|
|
|
@@ -6,10 +6,10 @@ description: Cross-document consistency analysis and quality assessment. Perform
|
|
|
6
6
|
compatibility: Requires DocGuard CLI installed (npm i -g docguard-cli or npx docguard-cli)
|
|
7
7
|
metadata:
|
|
8
8
|
author: docguard
|
|
9
|
-
version: 0.
|
|
9
|
+
version: 0.11.1
|
|
10
10
|
source: extensions/spec-kit-docguard/skills/docguard-review
|
|
11
11
|
---
|
|
12
|
-
<!-- docguard:version: 0.
|
|
12
|
+
<!-- docguard:version: 0.11.1 -->
|
|
13
13
|
|
|
14
14
|
# DocGuard Review Skill
|
|
15
15
|
|
|
@@ -6,10 +6,10 @@ description: CDD maturity assessment with category-aware improvement roadmap. Ru
|
|
|
6
6
|
compatibility: Requires DocGuard CLI installed (npm i -g docguard-cli or npx docguard-cli)
|
|
7
7
|
metadata:
|
|
8
8
|
author: docguard
|
|
9
|
-
version: 0.
|
|
9
|
+
version: 0.11.1
|
|
10
10
|
source: extensions/spec-kit-docguard/skills/docguard-score
|
|
11
11
|
---
|
|
12
|
-
<!-- docguard:version: 0.
|
|
12
|
+
<!-- docguard:version: 0.11.1 -->
|
|
13
13
|
|
|
14
14
|
# DocGuard Score Skill
|
|
15
15
|
|
|
@@ -4,7 +4,7 @@ description: Keep canonical documentation ALWAYS UP TO DATE. Refreshes code-trut
|
|
|
4
4
|
compatibility: Requires DocGuard CLI installed (npm i -g docguard-cli or npx docguard-cli)
|
|
5
5
|
metadata:
|
|
6
6
|
author: docguard
|
|
7
|
-
version: 0.
|
|
7
|
+
version: 0.11.1
|
|
8
8
|
source: extensions/spec-kit-docguard/skills/docguard-sync
|
|
9
9
|
---
|
|
10
10
|
|
|
@@ -96,6 +96,7 @@ extensions/spec-kit-docguard/
|
|
|
96
96
|
|
|
97
97
|
## Rules
|
|
98
98
|
|
|
99
|
+
- **PR-first workflow — no direct-to-main commits.** Create a branch (`git checkout -b <type>/<slug>`), push, `gh pr create`, let CI run, self-review, squash-merge. Tag releases only after merge on `main`. The only acceptable direct-to-main: typo fixes in comments or README badge URLs.
|
|
99
100
|
- Never commit without updating CHANGELOG.md
|
|
100
101
|
- If code deviates from docs, add `// DRIFT: reason`
|
|
101
102
|
- Security rules in SECURITY.md are mandatory
|
|
@@ -7,6 +7,46 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.11.1] - 2026-05-25
|
|
11
|
+
|
|
12
|
+
Patch release addressing false positives surfaced by the v0.11.0 audit of the `wu-whatsappinbox` enterprise monorepo, generalized into a multi-tool IaC detector, plus several DocGuard self-audit improvements. Spec: `specs/003-v011-false-positives/`.
|
|
13
|
+
|
|
14
|
+
### Fixed
|
|
15
|
+
- **Docs-Sync no longer misclassifies frontend API clients as backend routes.** Dropped the ambiguous bare `'api'` from the route-directory convention list. `src/api/client.ts` (frontend axios) and similar are no longer scanned as Express/Next.js routes (FP-1). For Next.js App Router (`src/app/api`, `app/api`), only files matching the strict `route.{ts,tsx,js,jsx,mjs}` filename convention are counted — helper files in the same tree are skipped (FR-001, FR-002).
|
|
16
|
+
- **Test files are no longer flagged as undocumented services or routes.** The docs-sync route and service loops now skip paths under `__tests__/` and filenames matching `*.{test,spec}.{ts,tsx,js,jsx,mjs,py,java,go}` (FP-2, FR-003, FR-004). Eliminates ~7 spurious warnings per monorepo with co-located tests.
|
|
17
|
+
- **Build outputs no longer flagged as undocumented source.** Added `cdk.out`, `out`, `.nuxt`, `.claude` to the docs-coverage `IGNORE_DIRS` set (FP-3, FR-005).
|
|
18
|
+
- **`config.ignore` is now honored by Docs-Coverage's source-directory scan** (FP-3, FR-006 / IR-5). Closes a long-standing inconsistency where other validators respected the user's ignore but the source-dir scan did not. Patterns like `**/cdk.out/**` now match the directory itself as well as files inside it.
|
|
19
|
+
- **Worktree copies no longer double-counted.** `globMatch` in `cli/shared-ignore.mjs` now rejects paths under `.claude/worktrees/`, `.git/worktrees/`, and `.jj/` at any depth — same treatment as `node_modules` (FP-4, FR-007). Affects every Claude-Code project using parallel-agent worktrees.
|
|
20
|
+
- **Check 1 (config files) no longer flags build-cache dotdirs as undocumented configs.** Now skips directories — `.nuxt`, `.claude`, etc. are excluded by `IGNORE_DIRS` for the source-dir scan instead.
|
|
21
|
+
- **Check 1 (config files) now honors `config.ignore` too.** Originally fixed only for the source-directory scan; a follow-up audit reproduced the same FP-3 class with `.local` in `ignore` still being flagged. Both Docs-Coverage scans now call `shouldIgnore(entry, config) || shouldIgnore(entry + '/', config)`. Closes FR-015 (audit-confirmed gap).
|
|
22
|
+
- **Test-Spec validator parses multi-path Journey rows correctly.** Previously a Journey cell like `` `path/a.test.ts`, `path/b.test.ts` `` was stripped of all backticks then `existsSync()`d as one string — a 100% false-positive rate on multi-path rows. Now: split on commas outside backticks, strip backticks per segment, evaluate each independently. Row passes if ANY referenced file has evidence. Glob entries (`foo_*.test.ts`) are expanded; `(N suites)` / `(N tests)` annotations are accepted as the author's explicit coverage claim. Closes FP-6 and FR-016.
|
|
23
|
+
- **TODO-Tracking validator no longer false-positives on its own keyword list.** Previously the regex matched `TEMP(?!late|orar)` inside its own source. Two-part fix: (1) match restricted to text following a comment marker (`//`, `#`, `/*`, `<!--`, block `*`), (2) the validator skips its own source file (`cli/validators/todo-tracking.mjs`) since the docstring legitimately names the keywords.
|
|
24
|
+
- **TODO-Tracking validator no longer false-positives on test fixture strings.** Test files commonly contain `// TODO:` inside template literals (`writeFileSync(..., '// TODO:')`) that single-line heuristics can't distinguish from real comments. Test files are now skipped by default; opt back in with `config.todoTracking.includeTestFiles = true`.
|
|
25
|
+
- **Traceability validator's own fixtures no longer leak as orphan refs.** `tests/traceability.test.mjs` previously contained literal `REQ-001`/`REQ-002`/`REQ-003` strings that the validator scanned and reported as orphaned test references. Fixtures now build the IDs from parts so the validator's pattern doesn't match.
|
|
26
|
+
|
|
27
|
+
### Added
|
|
28
|
+
- **Multi-tool IaC detector + consolidated documentation reminder.** New `cli/scanners/iac.mjs` identifies projects shipping any of: **AWS CDK** (`cdk.json`), **Terraform** (`*.tf` files), **Pulumi** (`Pulumi.yaml`), **AWS SAM** (`template.yaml` with `AWS::Serverless::`), and **Serverless Framework** (`serverless.yml`). When an IaC project's ARCHITECTURE.md has no Infrastructure heading, DocGuard emits ONE actionable warning per detected tool naming the marker file location and the expected source layout — instead of multiple generic per-directory warnings (FR-009, FR-010, FR-011). The generic per-dir warnings inside IaC packages (`bin/`, `lib/`, `modules/`, `stacks/`, `constructs/`, `handlers/`, etc.) are suppressed in favor of these consolidated messages. The legacy `cli/scanners/cdk.mjs` is preserved as a thin re-export for backward compatibility.
|
|
29
|
+
- **`## Infrastructure (IaC)` section in `templates/ARCHITECTURE.md.template`.** New projects initialized via `docguard init` start with placeholder tables for AWS CDK, Terraform, and Pulumi/SAM/Serverless layouts plus a Deployment Pipeline subsection (FR-012). Explicitly skippable for non-IaC projects via a header comment.
|
|
30
|
+
- **`DEFAULT_IGNORE_DIRS`** exported from `cli/shared-ignore.mjs` — canonical shared ignore set covering build outputs (`dist`, `build`, `out`, `cdk.out`, `target`, `.gradle`), VCS internals (`.git`, `.jj`, `.hg`, `.svn`), package caches (`node_modules`, `vendor`, `.venv`, `__pycache__`), and framework synth outputs (`.next`, `.nuxt`, `.turbo`, `.vercel`, `.cache`, `.svelte-kit`) (FR-008). Added `target` (Rust/Java), `.gradle`, and `.svelte-kit` per the updated wu-whatsappinbox audit. Available for any future validator to import; existing per-validator `IGNORE_DIRS` sets are left in place (deferred migration).
|
|
31
|
+
|
|
32
|
+
### Changed
|
|
33
|
+
- **DocGuard package version bumped to 0.11.1** across `package.json` and all `extensions/spec-kit-docguard/` files (extension.yml + 5 SKILL.md files were referencing stale `v0.9.9`/`v0.10.0`).
|
|
34
|
+
- **`docs-canonical/ARCHITECTURE.md`** updated to add `cli/writers/` and `cli/shared-*.mjs` to the Component Map and Layer Boundaries — closes a real doc gap surfaced by dogfooding (the writers/ directory has shipped for several releases without being documented).
|
|
35
|
+
- **`specs/003-v011-false-positives/plan.md`** restructured to match the spec-kit `plan-template.md` shape (added Summary, Technical Context, Constitution Check, Project Structure sections). `tasks.md` rewritten with the spec-kit phased T### convention.
|
|
36
|
+
|
|
37
|
+
### Internal
|
|
38
|
+
- New test files: `tests/cdk-detection.test.mjs` (CDK + multi-tool IaC detector tests + `globMatch` worktree rejection + `DEFAULT_IGNORE_DIRS` shape). Existing test suites extended with regression cases for FP-1..FP-5, TODO-tracking false-positive guards, and IaC-tool detection across Terraform/Pulumi/SAM/Serverless. New tests are annotated with `// @req FR-NNN` / `// @req SC-NNN` comments for traceability. **Total: 329 tests passing (was 306, +23 new).**
|
|
39
|
+
- **DocGuard self-audit improvements**: ran `docguard guard` on the repo as part of this release. Warnings dropped from **57 → 15** across the session by fixing real drift (stale extension versions, missing `cli/writers/` mention, traceability gaps) and reducing self-referential false positives (TODO validator scanning its own keyword list).
|
|
40
|
+
- **Round 2 fixes after a second audit report**: FP-3 part B (`checkConfigFiles` honoring `config.ignore`), FP-6 (Test-Spec multi-path Journey row parsing with glob and `(N suites)` annotation support), additional `DEFAULT_IGNORE_DIRS` entries for Rust/Java/SvelteKit. **Total tests passing: 336** (was 306).
|
|
41
|
+
- No new NPM dependencies. Zero schema or config-file changes.
|
|
42
|
+
|
|
43
|
+
### Out of scope (deferred to v0.12)
|
|
44
|
+
- Feature requests IR-1..IR-4, IR-6..IR-8 (per-validator severity, `--diff-only`, draft-staleness warning, `sync --section`, `.docguardignore` template at init, extended Next.js detection, `routesGlob`/`servicesGlob` overrides). IR-5 (honor ignore in source-dir scan) shipped as part of this release alongside FP-3.
|
|
45
|
+
- Migrating all 17 modules that define their own `IGNORE_DIRS` constant to import `DEFAULT_IGNORE_DIRS` — mechanical, large diff, tracked separately.
|
|
46
|
+
- Multi-line string-literal detection in TODO-Tracking — current heuristic still false-positives on `// TODO:` inside multi-line template literals. Workaround: keep test files out of TODO scanning (now default) or use `config.todoIgnore` globs.
|
|
47
|
+
|
|
48
|
+
Credit: feedback from running v0.11.0 on the `wu-whatsappinbox` enterprise monorepo (audit score 98/100, 40 warnings).
|
|
49
|
+
|
|
10
50
|
## [0.11.0] - 2026-05-22
|
|
11
51
|
|
|
12
52
|
This release reshapes DocGuard from a documentation linter into an **AI-readable, always-current project memory builder** — for any language project, not just JS/web. The four-mode lifecycle (`generate → guard → sync → fix`) is now coherent end-to-end.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: docguard-cli
|
|
3
|
-
Version: 0.11.
|
|
3
|
+
Version: 0.11.1
|
|
4
4
|
Summary: The enforcement tool for Canonical-Driven Development (CDD). Audit, generate, and guard your project documentation. Zero dependencies.
|
|
5
5
|
Project-URL: Homepage, https://github.com/raccioly/docguard
|
|
6
6
|
Project-URL: Documentation, https://github.com/raccioly/docguard#readme
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CDK Detector — Re-export shim.
|
|
3
|
+
*
|
|
4
|
+
* The CDK-specific detector has been generalized into a multi-tool IaC
|
|
5
|
+
* detector at cli/scanners/iac.mjs covering CDK, Terraform, Pulumi, SAM,
|
|
6
|
+
* and Serverless Framework. This module re-exports the CDK-only API for
|
|
7
|
+
* backward compatibility. New code should import from iac.mjs directly.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
export { detectCDK, hasInfrastructureHeading } from './iac.mjs';
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* IaC Detector — Identifies Infrastructure-as-Code projects.
|
|
3
|
+
*
|
|
4
|
+
* IaC code is real production source that defines cloud infrastructure.
|
|
5
|
+
* It MUST be documented in ARCHITECTURE.md, not silently ignored. This
|
|
6
|
+
* detector identifies which IaC tool the project uses so docs-coverage
|
|
7
|
+
* can emit ONE consolidated actionable warning naming the actual layout
|
|
8
|
+
* (instead of multiple generic per-directory warnings).
|
|
9
|
+
*
|
|
10
|
+
* Supported tools:
|
|
11
|
+
* - AWS CDK → cdk.json marker file
|
|
12
|
+
* - Terraform → *.tf files in any non-ignored directory
|
|
13
|
+
* - Pulumi → Pulumi.yaml marker file
|
|
14
|
+
* - AWS SAM → template.yaml/yml with "AWS::Serverless::"
|
|
15
|
+
* - Serverless Fmw → serverless.yml/serverless.yaml/serverless.ts
|
|
16
|
+
*
|
|
17
|
+
* Zero NPM dependencies — pure Node.js built-ins only.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';
|
|
21
|
+
import { join, relative } from 'node:path';
|
|
22
|
+
import { DEFAULT_IGNORE_DIRS } from '../shared-ignore.mjs';
|
|
23
|
+
|
|
24
|
+
const MAX_DEPTH = 6;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Per-tool conventions: marker file/pattern + the directories that hold the
|
|
28
|
+
* actual IaC source. Used to construct the consolidated warning text.
|
|
29
|
+
*/
|
|
30
|
+
const TOOL_PROFILES = {
|
|
31
|
+
cdk: {
|
|
32
|
+
label: 'AWS CDK',
|
|
33
|
+
markerFile: 'cdk.json',
|
|
34
|
+
sourceDirs: ['bin/ (app entrypoint)', 'lib/stacks/', 'lib/constructs/'],
|
|
35
|
+
headingPattern: /^#+\s+(infrastructure|cdk|iac)\b/im,
|
|
36
|
+
},
|
|
37
|
+
terraform: {
|
|
38
|
+
label: 'Terraform',
|
|
39
|
+
markerFile: null, // any *.tf file
|
|
40
|
+
sourceDirs: ['*.tf (root module)', 'modules/ (reusable modules)', 'environments/ (per-env tfvars)'],
|
|
41
|
+
headingPattern: /^#+\s+(infrastructure|terraform|iac)\b/im,
|
|
42
|
+
},
|
|
43
|
+
pulumi: {
|
|
44
|
+
label: 'Pulumi',
|
|
45
|
+
markerFile: 'Pulumi.yaml',
|
|
46
|
+
sourceDirs: ['index.ts (main program)', 'stacks/', 'config/'],
|
|
47
|
+
headingPattern: /^#+\s+(infrastructure|pulumi|iac)\b/im,
|
|
48
|
+
},
|
|
49
|
+
sam: {
|
|
50
|
+
label: 'AWS SAM',
|
|
51
|
+
markerFile: 'template.yaml', // also template.yml — checked below
|
|
52
|
+
sourceDirs: ['template.yaml (SAM manifest)', 'src/ (Lambda handlers)', 'events/'],
|
|
53
|
+
headingPattern: /^#+\s+(infrastructure|sam|serverless|iac)\b/im,
|
|
54
|
+
},
|
|
55
|
+
serverless: {
|
|
56
|
+
label: 'Serverless Framework',
|
|
57
|
+
markerFile: 'serverless.yml', // also .yaml, .ts — checked below
|
|
58
|
+
sourceDirs: ['serverless.yml (manifest)', 'handlers/', 'src/'],
|
|
59
|
+
headingPattern: /^#+\s+(infrastructure|serverless|iac)\b/im,
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Detect every IaC tool used in the project. Walks the tree from projectDir
|
|
65
|
+
* looking for marker files, respecting DEFAULT_IGNORE_DIRS.
|
|
66
|
+
*
|
|
67
|
+
* @param {string} projectDir - Absolute path to project root
|
|
68
|
+
* @returns {{
|
|
69
|
+
* isIaC: boolean,
|
|
70
|
+
* tools: Array<{
|
|
71
|
+
* tool: string, // 'cdk' | 'terraform' | 'pulumi' | 'sam' | 'serverless'
|
|
72
|
+
* label: string, // 'AWS CDK' etc.
|
|
73
|
+
* markerPaths: string[], // relative paths to detected marker files
|
|
74
|
+
* packageDirs: string[], // relative dirs containing the markers
|
|
75
|
+
* sourceDirs: string[], // expected source layout per tool convention
|
|
76
|
+
* }>
|
|
77
|
+
* }}
|
|
78
|
+
*/
|
|
79
|
+
export function detectIaC(projectDir) {
|
|
80
|
+
const findings = {
|
|
81
|
+
cdk: { markerPaths: [], packageDirs: [] },
|
|
82
|
+
terraform: { markerPaths: [], packageDirs: [] },
|
|
83
|
+
pulumi: { markerPaths: [], packageDirs: [] },
|
|
84
|
+
sam: { markerPaths: [], packageDirs: [] },
|
|
85
|
+
serverless: { markerPaths: [], packageDirs: [] },
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
const recordFinding = (tool, fullPath) => {
|
|
89
|
+
const relPath = relative(projectDir, fullPath);
|
|
90
|
+
findings[tool].markerPaths.push(relPath);
|
|
91
|
+
const pkgDir = relative(projectDir, dirnameOf(fullPath)) || '.';
|
|
92
|
+
if (!findings[tool].packageDirs.includes(pkgDir)) {
|
|
93
|
+
findings[tool].packageDirs.push(pkgDir);
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
const walk = (dir, depth) => {
|
|
98
|
+
if (depth > MAX_DEPTH) return;
|
|
99
|
+
let entries;
|
|
100
|
+
try { entries = readdirSync(dir, { withFileTypes: true }); } catch { return; }
|
|
101
|
+
|
|
102
|
+
for (const e of entries) {
|
|
103
|
+
if (!e.isFile()) continue;
|
|
104
|
+
const full = join(dir, e.name);
|
|
105
|
+
|
|
106
|
+
// CDK
|
|
107
|
+
if (e.name === 'cdk.json') recordFinding('cdk', full);
|
|
108
|
+
|
|
109
|
+
// Terraform — any .tf file (we record one per directory, not per file)
|
|
110
|
+
if (e.name.endsWith('.tf')) {
|
|
111
|
+
const pkgDir = relative(projectDir, dir) || '.';
|
|
112
|
+
if (!findings.terraform.packageDirs.includes(pkgDir)) {
|
|
113
|
+
findings.terraform.markerPaths.push(relative(projectDir, full));
|
|
114
|
+
findings.terraform.packageDirs.push(pkgDir);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Pulumi
|
|
119
|
+
if (e.name === 'Pulumi.yaml' || e.name === 'Pulumi.yml') {
|
|
120
|
+
recordFinding('pulumi', full);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// SAM — template.yaml/yml WITH AWS::Serverless::
|
|
124
|
+
if (e.name === 'template.yaml' || e.name === 'template.yml') {
|
|
125
|
+
if (fileContains(full, 'AWS::Serverless::')) recordFinding('sam', full);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Serverless Framework
|
|
129
|
+
if (
|
|
130
|
+
e.name === 'serverless.yml' ||
|
|
131
|
+
e.name === 'serverless.yaml' ||
|
|
132
|
+
e.name === 'serverless.ts' ||
|
|
133
|
+
e.name === 'serverless.js'
|
|
134
|
+
) {
|
|
135
|
+
recordFinding('serverless', full);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
for (const e of entries) {
|
|
140
|
+
if (!e.isDirectory()) continue;
|
|
141
|
+
if (DEFAULT_IGNORE_DIRS.has(e.name)) continue;
|
|
142
|
+
if (e.name.startsWith('.')) continue;
|
|
143
|
+
walk(join(dir, e.name), depth + 1);
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
if (existsSync(projectDir)) {
|
|
148
|
+
try {
|
|
149
|
+
if (statSync(projectDir).isDirectory()) walk(projectDir, 0);
|
|
150
|
+
} catch { /* skip */ }
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const tools = [];
|
|
154
|
+
for (const [tool, data] of Object.entries(findings)) {
|
|
155
|
+
if (data.markerPaths.length > 0) {
|
|
156
|
+
tools.push({
|
|
157
|
+
tool,
|
|
158
|
+
label: TOOL_PROFILES[tool].label,
|
|
159
|
+
markerPaths: data.markerPaths,
|
|
160
|
+
packageDirs: data.packageDirs,
|
|
161
|
+
sourceDirs: TOOL_PROFILES[tool].sourceDirs,
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
return { isIaC: tools.length > 0, tools };
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Check whether ARCHITECTURE.md content includes an Infrastructure/CDK/IaC/
|
|
171
|
+
* Terraform/Pulumi/SAM heading at any level. Case-insensitive.
|
|
172
|
+
*
|
|
173
|
+
* @param {string} archContent - Full ARCHITECTURE.md content
|
|
174
|
+
* @returns {boolean}
|
|
175
|
+
*/
|
|
176
|
+
export function hasInfrastructureHeading(archContent) {
|
|
177
|
+
if (!archContent) return false;
|
|
178
|
+
return /^#+\s+(infrastructure|cdk|iac|terraform|pulumi|sam|serverless)\b/im.test(archContent);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Build the consolidated warning text for a detected IaC tool.
|
|
183
|
+
* One warning per tool — names the marker location and required content.
|
|
184
|
+
*/
|
|
185
|
+
export function buildIaCWarning(toolFinding) {
|
|
186
|
+
const primary = toolFinding.markerPaths[0];
|
|
187
|
+
const pkgDir = toolFinding.packageDirs[0];
|
|
188
|
+
const where = pkgDir === '.' ? '' : pkgDir + '/';
|
|
189
|
+
const sourceList = toolFinding.sourceDirs
|
|
190
|
+
.map(s => s.startsWith('*.') ? `${where}${s}` : `${where}${s}`)
|
|
191
|
+
.join(', ');
|
|
192
|
+
return `${toolFinding.label} detected at ${primary} — add an "Infrastructure" section to ` +
|
|
193
|
+
`ARCHITECTURE.md covering ${sourceList}`;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// ── Helpers ─────────────────────────────────────────────────────────────────
|
|
197
|
+
|
|
198
|
+
function dirnameOf(p) {
|
|
199
|
+
const i = p.lastIndexOf('/');
|
|
200
|
+
if (i < 0) {
|
|
201
|
+
const j = p.lastIndexOf('\\');
|
|
202
|
+
return j < 0 ? p : p.slice(0, j);
|
|
203
|
+
}
|
|
204
|
+
return p.slice(0, i);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
function fileContains(filePath, needle) {
|
|
208
|
+
try {
|
|
209
|
+
const content = readFileSync(filePath, 'utf-8');
|
|
210
|
+
return content.includes(needle);
|
|
211
|
+
} catch {
|
|
212
|
+
return false;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// ── Backwards-compatibility shim ────────────────────────────────────────────
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Legacy CDK-only API kept for callers that don't need multi-tool detection.
|
|
220
|
+
* Delegates to detectIaC and projects the CDK slice into the old shape.
|
|
221
|
+
*
|
|
222
|
+
* @deprecated Use detectIaC for new code.
|
|
223
|
+
*/
|
|
224
|
+
export function detectCDK(projectDir) {
|
|
225
|
+
const result = detectIaC(projectDir);
|
|
226
|
+
const cdk = result.tools.find(t => t.tool === 'cdk');
|
|
227
|
+
if (!cdk) {
|
|
228
|
+
return { isCDK: false, cdkJsonPaths: [], cdkPackageDirs: [] };
|
|
229
|
+
}
|
|
230
|
+
return {
|
|
231
|
+
isCDK: true,
|
|
232
|
+
cdkJsonPaths: cdk.markerPaths,
|
|
233
|
+
cdkPackageDirs: cdk.packageDirs,
|
|
234
|
+
};
|
|
235
|
+
}
|
|
@@ -15,6 +15,31 @@
|
|
|
15
15
|
* Zero NPM dependencies — pure Node.js built-ins only.
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
|
+
/**
|
|
19
|
+
* Canonical set of directory names that should never be scanned, regardless
|
|
20
|
+
* of validator. Build outputs, VCS internals, package caches, framework synth
|
|
21
|
+
* outputs. Validators MAY extend this with their own additions but SHOULD
|
|
22
|
+
* start from this base so behavior is consistent across the tool.
|
|
23
|
+
*/
|
|
24
|
+
export const DEFAULT_IGNORE_DIRS = new Set([
|
|
25
|
+
// Package managers
|
|
26
|
+
'node_modules', 'vendor', '.venv', '__pycache__',
|
|
27
|
+
// VCS
|
|
28
|
+
'.git', '.jj', '.hg', '.svn',
|
|
29
|
+
// Build outputs — JS/TS, Rust/Java, generic
|
|
30
|
+
'dist', 'build', 'out', 'coverage', 'target', '.gradle',
|
|
31
|
+
// Framework synth/cache
|
|
32
|
+
'.next', '.nuxt', '.turbo', '.vercel', '.cache', '.svelte-kit', 'cdk.out',
|
|
33
|
+
// OS
|
|
34
|
+
'.DS_Store',
|
|
35
|
+
]);
|
|
36
|
+
|
|
37
|
+
// Regex for paths that must always be rejected at any depth, regardless of
|
|
38
|
+
// the glob pattern matching them. These are duplicate file trees (worktrees)
|
|
39
|
+
// or runtime caches that should NEVER be treated as primary source.
|
|
40
|
+
const ALWAYS_REJECT_PATH_RE =
|
|
41
|
+
/(?:^|[/\\])(?:node_modules|\.claude[/\\]worktrees|\.git[/\\]worktrees|\.jj)(?:[/\\]|$)/;
|
|
42
|
+
|
|
18
43
|
/**
|
|
19
44
|
* Convert a glob pattern to a RegExp.
|
|
20
45
|
* Supports: * (any chars except /), ** (any path segments), . (literal dot).
|
|
@@ -111,8 +136,10 @@ function globToMatchRegex(pattern) {
|
|
|
111
136
|
export function globMatch(relPath, patterns) {
|
|
112
137
|
if (!relPath || !patterns || patterns.length === 0) return false;
|
|
113
138
|
|
|
114
|
-
// Always reject paths
|
|
115
|
-
|
|
139
|
+
// Always reject paths inside node_modules / worktree copies / .jj at any
|
|
140
|
+
// depth. A user's testPatterns like "**/*.test.ts" would otherwise match
|
|
141
|
+
// duplicate trees under .claude/worktrees and inflate test counts.
|
|
142
|
+
if (ALWAYS_REJECT_PATH_RE.test(relPath)) return false;
|
|
116
143
|
|
|
117
144
|
const regexes = patterns.map(p => globToMatchRegex(p));
|
|
118
145
|
return regexes.some(r => r.test(relPath));
|
|
@@ -18,8 +18,9 @@ import { resolve, join, dirname, relative, extname } from 'node:path';
|
|
|
18
18
|
import { shouldIgnore } from './shared-ignore.mjs';
|
|
19
19
|
|
|
20
20
|
const IGNORE_DIRS = new Set([
|
|
21
|
-
'node_modules', '.git', '.next', 'dist', 'build',
|
|
21
|
+
'node_modules', '.git', '.next', '.nuxt', 'dist', 'build', 'out',
|
|
22
22
|
'coverage', '.cache', '__pycache__', '.venv', 'vendor', '.turbo',
|
|
23
|
+
'cdk.out',
|
|
23
24
|
]);
|
|
24
25
|
|
|
25
26
|
const CODE_EXTENSIONS = new Set([
|
|
@@ -16,10 +16,14 @@
|
|
|
16
16
|
import { existsSync, readFileSync, readdirSync, statSync } from 'node:fs';
|
|
17
17
|
import { resolve, join, relative, basename, extname } from 'node:path';
|
|
18
18
|
import { resolveSourceRoots } from '../shared-source.mjs';
|
|
19
|
+
import { shouldIgnore } from '../shared-ignore.mjs';
|
|
20
|
+
import { detectIaC, hasInfrastructureHeading, buildIaCWarning } from '../scanners/iac.mjs';
|
|
19
21
|
|
|
20
22
|
const IGNORE_DIRS = new Set([
|
|
21
|
-
'node_modules', '.git', '.next', 'dist', 'build', '
|
|
22
|
-
'.cache', '__pycache__', '.venv', 'vendor',
|
|
23
|
+
'node_modules', '.git', '.next', '.nuxt', 'dist', 'build', 'out',
|
|
24
|
+
'coverage', '.cache', '__pycache__', '.venv', 'vendor',
|
|
25
|
+
'.turbo', '.vercel', '.svelte-kit', 'cdk.out', '.claude',
|
|
26
|
+
'target', '.gradle',
|
|
23
27
|
]);
|
|
24
28
|
|
|
25
29
|
// Dotfiles that are universally common and don't need documentation
|
|
@@ -50,8 +54,12 @@ export function validateDocsCoverage(projectDir, config) {
|
|
|
50
54
|
return { errors: [], warnings, passed: 0, total: 0 };
|
|
51
55
|
}
|
|
52
56
|
|
|
57
|
+
// IaC detection runs once and informs both Check 3 (suppression) and
|
|
58
|
+
// Check 6 (consolidated warning). One scan, two consumers.
|
|
59
|
+
const iac = detectIaC(projectDir);
|
|
60
|
+
|
|
53
61
|
// ── Check 1: Project-specific config/dotfiles referenced in docs ──
|
|
54
|
-
const configChecks = checkConfigFiles(projectDir, allDocContent);
|
|
62
|
+
const configChecks = checkConfigFiles(projectDir, allDocContent, config);
|
|
55
63
|
total += configChecks.total;
|
|
56
64
|
passed += configChecks.passed;
|
|
57
65
|
warnings.push(...configChecks.warnings);
|
|
@@ -63,7 +71,7 @@ export function validateDocsCoverage(projectDir, config) {
|
|
|
63
71
|
warnings.push(...binChecks.warnings);
|
|
64
72
|
|
|
65
73
|
// ── Check 3: Source directory structure matches ARCHITECTURE.md ──
|
|
66
|
-
const dirChecks = checkSourceDirs(projectDir, allDocContent, config);
|
|
74
|
+
const dirChecks = checkSourceDirs(projectDir, allDocContent, config, iac);
|
|
67
75
|
total += dirChecks.total;
|
|
68
76
|
passed += dirChecks.passed;
|
|
69
77
|
warnings.push(...dirChecks.warnings);
|
|
@@ -80,6 +88,12 @@ export function validateDocsCoverage(projectDir, config) {
|
|
|
80
88
|
passed += readmeChecks.passed;
|
|
81
89
|
warnings.push(...readmeChecks.warnings);
|
|
82
90
|
|
|
91
|
+
// ── Check 6: IaC-aware Infrastructure documentation ──
|
|
92
|
+
const iacChecks = checkIaCDocumentation(projectDir, iac);
|
|
93
|
+
total += iacChecks.total;
|
|
94
|
+
passed += iacChecks.passed;
|
|
95
|
+
warnings.push(...iacChecks.warnings);
|
|
96
|
+
|
|
83
97
|
return { errors: [], warnings, passed, total };
|
|
84
98
|
}
|
|
85
99
|
|
|
@@ -88,8 +102,10 @@ export function validateDocsCoverage(projectDir, config) {
|
|
|
88
102
|
/**
|
|
89
103
|
* Check 1: Project-specific config/dotfiles are mentioned in docs.
|
|
90
104
|
* Skips universally common files (.gitignore, .eslintrc, etc.).
|
|
105
|
+
* Honors config.ignore (FR-015 — applies user-configured ignore patterns
|
|
106
|
+
* consistently across all docs-coverage checks).
|
|
91
107
|
*/
|
|
92
|
-
function checkConfigFiles(projectDir, allDocContent) {
|
|
108
|
+
function checkConfigFiles(projectDir, allDocContent, config = {}) {
|
|
93
109
|
const warnings = [];
|
|
94
110
|
let passed = 0;
|
|
95
111
|
let total = 0;
|
|
@@ -111,6 +127,17 @@ function checkConfigFiles(projectDir, allDocContent) {
|
|
|
111
127
|
if (COMMON_DOTFILES.has(entry)) continue;
|
|
112
128
|
if (entry === 'tsconfig.json' || entry === 'package-lock.json') continue;
|
|
113
129
|
|
|
130
|
+
// Skip directories — this check is for configuration FILES, not dirs.
|
|
131
|
+
// Build-cache dotdirs (.nuxt, .next, .turbo, etc.) are handled by IGNORE_DIRS.
|
|
132
|
+
try {
|
|
133
|
+
if (statSync(join(projectDir, entry)).isDirectory()) continue;
|
|
134
|
+
} catch { continue; }
|
|
135
|
+
|
|
136
|
+
// Honor user-configured ignore patterns (FR-015 / IR-5).
|
|
137
|
+
// Same dual-form check as checkSourceDirs: relative path and trailing-slash
|
|
138
|
+
// form so dotfile-style patterns and dir-style patterns both apply.
|
|
139
|
+
if (shouldIgnore(entry, config) || shouldIgnore(entry + '/', config)) continue;
|
|
140
|
+
|
|
114
141
|
total++;
|
|
115
142
|
if (lowerDocContent.includes(entry.toLowerCase())) {
|
|
116
143
|
passed++;
|
|
@@ -160,8 +187,13 @@ function checkPackageBins(projectDir, allDocContent) {
|
|
|
160
187
|
|
|
161
188
|
/**
|
|
162
189
|
* Check 3: Source directories are referenced in ARCHITECTURE.md.
|
|
190
|
+
*
|
|
191
|
+
* Honors config.ignore (FR-006). When IaC is detected and the Infrastructure
|
|
192
|
+
* heading is missing, per-directory warnings inside the IaC package roots
|
|
193
|
+
* are suppressed — Check 6 emits one consolidated warning per IaC tool
|
|
194
|
+
* instead (FR-011).
|
|
163
195
|
*/
|
|
164
|
-
function checkSourceDirs(projectDir, allDocContent, config = {}) {
|
|
196
|
+
function checkSourceDirs(projectDir, allDocContent, config = {}, iac = { isIaC: false, tools: [] }) {
|
|
165
197
|
const warnings = [];
|
|
166
198
|
let passed = 0;
|
|
167
199
|
let total = 0;
|
|
@@ -173,6 +205,15 @@ function checkSourceDirs(projectDir, allDocContent, config = {}) {
|
|
|
173
205
|
try { archContent = readFileSync(archPath, 'utf-8'); } catch { return { warnings, passed, total }; }
|
|
174
206
|
|
|
175
207
|
const lowerArchContent = archContent.toLowerCase();
|
|
208
|
+
const infraDocumented = hasInfrastructureHeading(archContent);
|
|
209
|
+
|
|
210
|
+
// Only suppress per-dir warnings when IaC exists AND no Infrastructure
|
|
211
|
+
// heading is present — Check 6 will fire the consolidated message instead.
|
|
212
|
+
const suppressIaCDirs = iac.isIaC && !infraDocumented;
|
|
213
|
+
|
|
214
|
+
// Flatten every IaC tool's package dirs into a single Set for fast lookup.
|
|
215
|
+
const iacPackageDirs = [];
|
|
216
|
+
for (const tool of iac.tools) iacPackageDirs.push(...tool.packageDirs);
|
|
176
217
|
|
|
177
218
|
// Monorepo-aware: honor config.sourceRoot + workspaces instead of a hardcoded list.
|
|
178
219
|
for (const rootDir of resolveSourceRoots(projectDir, config)) {
|
|
@@ -189,6 +230,22 @@ function checkSourceDirs(projectDir, allDocContent, config = {}) {
|
|
|
189
230
|
|
|
190
231
|
if (IGNORE_DIRS.has(entry) || entry.startsWith('.') || entry === '__tests__' || entry === '__test__') continue;
|
|
191
232
|
|
|
233
|
+
const relPath = relative(projectDir, fullPath);
|
|
234
|
+
|
|
235
|
+
// Honor user-configured ignore patterns (FR-006 / IR-5).
|
|
236
|
+
// Patterns like `**/cdk.out/**` are written to match files INSIDE the
|
|
237
|
+
// directory; appending '/' lets us match the directory itself too.
|
|
238
|
+
if (shouldIgnore(relPath, config) || shouldIgnore(relPath + '/', config)) continue;
|
|
239
|
+
|
|
240
|
+
// Suppress per-dir warnings for IaC-relevant subdirs inside an IaC
|
|
241
|
+
// package — the consolidated Check 6 warning covers them. Includes CDK
|
|
242
|
+
// (bin/, lib/, stacks/, constructs/), Terraform (modules/, environments/),
|
|
243
|
+
// Pulumi (stacks/), SAM (events/, src/), Serverless (handlers/, src/).
|
|
244
|
+
if (suppressIaCDirs && isInsideIaCPackage(relPath, iacPackageDirs)
|
|
245
|
+
&& IAC_SUBDIR_NAMES.has(entry)) {
|
|
246
|
+
continue;
|
|
247
|
+
}
|
|
248
|
+
|
|
192
249
|
total++;
|
|
193
250
|
const searchName = entry.toLowerCase();
|
|
194
251
|
if (lowerArchContent.includes(searchName) || lowerArchContent.includes(root + '/' + entry)) {
|
|
@@ -204,6 +261,68 @@ function checkSourceDirs(projectDir, allDocContent, config = {}) {
|
|
|
204
261
|
return { warnings, passed, total };
|
|
205
262
|
}
|
|
206
263
|
|
|
264
|
+
/**
|
|
265
|
+
* Subdirectory names recognized as IaC-relevant across all supported tools.
|
|
266
|
+
* When IaC is detected and the Infrastructure heading is missing, these dirs
|
|
267
|
+
* inside the IaC package are suppressed from Check 3 to avoid double-warning.
|
|
268
|
+
*/
|
|
269
|
+
const IAC_SUBDIR_NAMES = new Set([
|
|
270
|
+
// CDK
|
|
271
|
+
'bin', 'lib', 'stacks', 'constructs',
|
|
272
|
+
// Terraform
|
|
273
|
+
'modules', 'environments',
|
|
274
|
+
// SAM / Serverless / Pulumi
|
|
275
|
+
'handlers', 'events', 'src',
|
|
276
|
+
]);
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* True if `relPath` is inside any of the IaC package directories.
|
|
280
|
+
* Both inputs are project-relative POSIX paths.
|
|
281
|
+
*/
|
|
282
|
+
function isInsideIaCPackage(relPath, packageDirs) {
|
|
283
|
+
if (!packageDirs || packageDirs.length === 0) return false;
|
|
284
|
+
const normalized = relPath.split('\\').join('/');
|
|
285
|
+
return packageDirs.some(pkgDir => {
|
|
286
|
+
const p = pkgDir === '.' ? '' : pkgDir.split('\\').join('/');
|
|
287
|
+
if (p === '') return true;
|
|
288
|
+
return normalized === p || normalized.startsWith(p + '/');
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Check 6: IaC projects should document their Infrastructure layer.
|
|
294
|
+
*
|
|
295
|
+
* Emits ONE consolidated warning per detected IaC tool when ARCHITECTURE.md
|
|
296
|
+
* has no Infrastructure heading. Suppresses the generic per-directory
|
|
297
|
+
* warnings that would otherwise fire for bin/, lib/, modules/, handlers/, etc.
|
|
298
|
+
*/
|
|
299
|
+
function checkIaCDocumentation(projectDir, iac) {
|
|
300
|
+
const warnings = [];
|
|
301
|
+
if (!iac || !iac.isIaC) return { warnings, passed: 0, total: 0 };
|
|
302
|
+
|
|
303
|
+
const archPath = resolve(projectDir, 'docs-canonical/ARCHITECTURE.md');
|
|
304
|
+
if (!existsSync(archPath)) {
|
|
305
|
+
// No ARCHITECTURE.md at all — structure validator will catch that.
|
|
306
|
+
// Don't double-warn here.
|
|
307
|
+
return { warnings, passed: 0, total: 0 };
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
let archContent;
|
|
311
|
+
try { archContent = readFileSync(archPath, 'utf-8'); } catch { return { warnings, passed: 0, total: 0 }; }
|
|
312
|
+
|
|
313
|
+
if (hasInfrastructureHeading(archContent)) {
|
|
314
|
+
// One pass per tool — counted as total per IaC tool present.
|
|
315
|
+
return { warnings, passed: iac.tools.length, total: iac.tools.length };
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
// One actionable warning per detected IaC tool. Most projects use one tool,
|
|
319
|
+
// but a multi-tool monorepo gets one targeted message each.
|
|
320
|
+
for (const tool of iac.tools) {
|
|
321
|
+
warnings.push(buildIaCWarning(tool));
|
|
322
|
+
}
|
|
323
|
+
return { warnings, passed: 0, total: iac.tools.length };
|
|
324
|
+
}
|
|
325
|
+
|
|
207
326
|
/**
|
|
208
327
|
* Check 4: Config files that code actually READS are documented.
|
|
209
328
|
*
|