docguard-cli 0.12.0__tar.gz → 0.13.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.12.0/extensions/spec-kit-docguard → docguard_cli-0.13.1/.agent}/skills/docguard-fix/SKILL.md +2 -2
- {docguard_cli-0.12.0/extensions/spec-kit-docguard → docguard_cli-0.13.1/.agent}/skills/docguard-guard/SKILL.md +3 -3
- {docguard_cli-0.12.0/extensions/spec-kit-docguard → docguard_cli-0.13.1/.agent}/skills/docguard-review/SKILL.md +2 -2
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/.agent/skills/docguard-score/SKILL.md +2 -2
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/.agent/skills/docguard-sync/SKILL.md +1 -1
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/AGENTS.md +1 -1
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/CHANGELOG.md +77 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/PKG-INFO +3 -3
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/README.md +2 -2
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/cli/commands/fix.mjs +55 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/cli/commands/guard.mjs +20 -3
- docguard_cli-0.13.1/cli/commands/impact.mjs +169 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/cli/commands/sync.mjs +50 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/cli/commands/trace.mjs +105 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/cli/docguard.mjs +13 -0
- docguard_cli-0.13.1/cli/shared-git.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/cli/validators/cross-reference.mjs +110 -8
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/cli/validators/docs-sync.mjs +15 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/cli/validators/freshness.mjs +31 -0
- docguard_cli-0.13.1/cli/validators/generated-staleness.mjs +152 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/cli/validators/structure.mjs +25 -15
- docguard_cli-0.13.1/cli/writers/fix-memory.mjs +133 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/cli/writers/mechanical.mjs +22 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/commands/docguard.guard.md +2 -2
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/docs/quickstart.md +1 -1
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/docs-canonical/CI-RECIPES.md +2 -2
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/extensions/spec-kit-docguard/commands/guard.md +1 -1
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/extensions/spec-kit-docguard/extension.yml +1 -1
- {docguard_cli-0.12.0/.agent → docguard_cli-0.13.1/extensions/spec-kit-docguard}/skills/docguard-fix/SKILL.md +2 -2
- {docguard_cli-0.12.0/.agent → docguard_cli-0.13.1/extensions/spec-kit-docguard}/skills/docguard-guard/SKILL.md +3 -3
- {docguard_cli-0.12.0/.agent → docguard_cli-0.13.1/extensions/spec-kit-docguard}/skills/docguard-review/SKILL.md +2 -2
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/extensions/spec-kit-docguard/skills/docguard-score/SKILL.md +2 -2
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/extensions/spec-kit-docguard/skills/docguard-sync/SKILL.md +1 -1
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/package.json +1 -1
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/pyproject.toml +1 -1
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/templates/commands/docguard.guard.md +2 -2
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/tests/changed-only.test.mjs +4 -1
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/tests/cross-reference.test.mjs +58 -0
- docguard_cli-0.13.1/tests/fix-memory.test.mjs +141 -0
- docguard_cli-0.13.1/tests/generated-staleness.test.mjs +144 -0
- docguard_cli-0.13.1/tests/guard-no-throw.test.mjs +119 -0
- docguard_cli-0.13.1/tests/impact.test.mjs +125 -0
- docguard_cli-0.13.1/tests/shared-git.test.mjs +190 -0
- docguard_cli-0.13.1/tests/sync-since.test.mjs +99 -0
- docguard_cli-0.13.1/tests/trace-reverse.test.mjs +96 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/.agent/commands/speckit.analyze.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/.agent/commands/speckit.checklist.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/.agent/commands/speckit.clarify.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/.agent/commands/speckit.constitution.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/.agent/commands/speckit.implement.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/.agent/commands/speckit.plan.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/.agent/commands/speckit.specify.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/.agent/commands/speckit.tasks.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/.agent/commands/speckit.taskstoissues.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/.agent/skills/speckit-analyze/SKILL.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/.agent/skills/speckit-checklist/SKILL.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/.agent/skills/speckit-clarify/SKILL.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/.agent/skills/speckit-constitution/SKILL.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/.agent/skills/speckit-implement/SKILL.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/.agent/skills/speckit-plan/SKILL.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/.agent/skills/speckit-specify/SKILL.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/.agent/skills/speckit-tasks/SKILL.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/.agent/skills/speckit-taskstoissues/SKILL.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/.docguard.json +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/.docguardignore +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/.github/dependabot.yml +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/.github/scripts/patch-catalog.py +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/.github/workflows/ci.yml +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/.github/workflows/release.yml +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/.github/workflows/supply-chain.yml +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/.github/workflows/sync-speckit-catalog.yml +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/.gitignore +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/.jules/bolt.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/.jules/palette.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/.jules/sentinel.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/.npmignore +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/.npmrc +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/.specify/extensions/.cache/catalog-ebf165086500aab1-metadata.json +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/.specify/extensions/.cache/catalog-ebf165086500aab1.json +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/.specify/extensions/.cache/catalog-metadata.json +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/.specify/extensions/.cache/catalog.json +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/.specify/init-options.json +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/.specify/memory/constitution.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/.specify/scripts/bash/check-prerequisites.sh +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/.specify/scripts/bash/common.sh +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/.specify/scripts/bash/create-new-feature.sh +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/.specify/scripts/bash/setup-plan.sh +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/.specify/scripts/bash/update-agent-context.sh +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/.specify/templates/agent-file-template.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/.specify/templates/checklist-template.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/.specify/templates/constitution-template.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/.specify/templates/plan-template.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/.specify/templates/spec-template.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/.specify/templates/tasks-template.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/CODE_OF_CONDUCT.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/COMPARISONS.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/CONTRIBUTING.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/DRIFT-LOG.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/LICENSE +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/PHILOSOPHY.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/ROADMAP.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/SECURITY.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/STANDARD.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/SUPPLY-CHAIN-AUDIT.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/SUPPORT.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/action.yml +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/cli/commands/agents.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/cli/commands/badge.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/cli/commands/ci.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/cli/commands/diagnose.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/cli/commands/diff.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/cli/commands/generate.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/cli/commands/hooks.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/cli/commands/init.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/cli/commands/llms.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/cli/commands/publish.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/cli/commands/score.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/cli/commands/setup.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/cli/commands/upgrade.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/cli/commands/watch.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/cli/ensure-skills.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/cli/scanners/api-doc.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/cli/scanners/cdk.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/cli/scanners/doc-tools.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/cli/scanners/frontend.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/cli/scanners/iac.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/cli/scanners/integrations.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/cli/scanners/memory-plan.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/cli/scanners/project-type.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/cli/scanners/routes.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/cli/scanners/schemas.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/cli/scanners/speckit.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/cli/shared-ignore.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/cli/shared-source.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/cli/shared.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/cli/validators/api-surface.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/cli/validators/architecture.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/cli/validators/changelog.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/cli/validators/doc-quality.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/cli/validators/docs-coverage.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/cli/validators/docs-diff.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/cli/validators/drift.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/cli/validators/environment.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/cli/validators/metadata-sync.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/cli/validators/metrics-consistency.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/cli/validators/schema-sync.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/cli/validators/security.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/cli/validators/test-spec.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/cli/validators/todo-tracking.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/cli/validators/traceability.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/cli/writers/api-reference.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/cli/writers/sections.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/commands/docguard.fix.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/commands/docguard.review.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/commands/docguard.score.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/configs/fastify.json +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/configs/generic.json +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/configs/nextjs.json +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/configs/python.json +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/docguard_cli/__init__.py +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/docguard_cli/wrapper.py +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/docs/ai-integration.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/docs/commands.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/docs/configuration.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/docs/doc-sections.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/docs/faq.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/docs/installation.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/docs/profiles.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/docs-canonical/ARCHITECTURE.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/docs-canonical/DATA-MODEL.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/docs-canonical/ENVIRONMENT.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/docs-canonical/SECURITY.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/docs-canonical/TEST-SPEC.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/examples/01-express-api/README.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/examples/01-express-api/package.json +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/examples/01-express-api/server.js +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/examples/02-python-flask/README.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/examples/02-python-flask/app.py +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/examples/02-python-flask/docs-canonical/ARCHITECTURE.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/examples/02-python-flask/requirements.txt +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/examples/03-spec-kit-project/CHANGELOG.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/examples/03-spec-kit-project/README.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/examples/03-spec-kit-project/docs-canonical/ARCHITECTURE.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/examples/03-spec-kit-project/docs-canonical/TEST-SPEC.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/examples/03-spec-kit-project/package.json +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/examples/03-spec-kit-project/src/index.js +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/examples/03-spec-kit-project/tests/basic.test.js +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/examples/README.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/extensions/spec-kit-docguard/LICENSE +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/extensions/spec-kit-docguard/README.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/extensions/spec-kit-docguard/commands/diagnose.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/extensions/spec-kit-docguard/commands/fix.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/extensions/spec-kit-docguard/commands/generate.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/extensions/spec-kit-docguard/commands/init.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/extensions/spec-kit-docguard/commands/score.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/extensions/spec-kit-docguard/commands/sync.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/extensions/spec-kit-docguard/commands/trace.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/extensions/spec-kit-docguard/scripts/bash/common.sh +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/extensions/spec-kit-docguard/scripts/bash/docguard-check-docs.sh +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/extensions/spec-kit-docguard/scripts/bash/docguard-init-doc.sh +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/extensions/spec-kit-docguard/scripts/bash/docguard-suggest-fix.sh +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/extensions/spec-kit-docguard/templates/extensions.yml +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/extensions/spec-kit-docguard/templates/github-workflows/docguard-autofix.yml +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/extensions/spec-kit-docguard/templates/github-workflows/docguard-guard.yml +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/pr_description.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/specs/001-fix-ignore-validators/plan.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/specs/001-fix-ignore-validators/spec.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/specs/001-fix-ignore-validators/tasks.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/specs/002-fix-test-discovery/plan.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/specs/002-fix-test-discovery/spec.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/specs/002-fix-test-discovery/tasks.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/specs/003-v011-false-positives/plan.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/specs/003-v011-false-positives/spec.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/specs/003-v011-false-positives/tasks.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/templates/ADR.md.template +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/templates/AGENTS.md.template +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/templates/ARCHITECTURE.md.template +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/templates/CHANGELOG.md.template +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/templates/CURRENT-STATE.md.template +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/templates/DATA-MODEL.md.template +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/templates/DEPLOYMENT.md.template +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/templates/DRIFT-LOG.md.template +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/templates/ENVIRONMENT.md.template +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/templates/KNOWN-GOTCHAS.md.template +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/templates/REQUIREMENTS.md.template +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/templates/ROADMAP.md.template +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/templates/RUNBOOKS.md.template +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/templates/SECURITY.md.template +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/templates/TEST-SPEC.md.template +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/templates/TROUBLESHOOTING.md.template +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/templates/VENDOR-BUGS.md.template +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/templates/ci/github-actions.yml +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/templates/commands/docguard.fix.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/templates/commands/docguard.init.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/templates/commands/docguard.review.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/templates/commands/docguard.update.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/test-draft.js +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/test-metrics.js +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/tests/api-doc.test.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/tests/api-surface.test.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/tests/api-write.test.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/tests/architecture.test.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/tests/backup-failure.test.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/tests/cdk-detection.test.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/tests/changelog.test.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/tests/commands.test.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/tests/doc-quality.test.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/tests/docguardignore.test.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/tests/docs-coverage.test.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/tests/docs-diff.test.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/tests/docs-sync.test.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/tests/drift.test.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/tests/environment.test.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/tests/freshness.test.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/tests/frontend-deep.test.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/tests/frontend.test.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/tests/guard-classify.test.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/tests/hooks.test.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/tests/i18n.test.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/tests/integrations.test.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/tests/mechanical.test.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/tests/memory-plan.test.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/tests/metadata-sync.test.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/tests/metrics-consistency.test.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/tests/monorepo-scanning.test.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/tests/multi-spec.test.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/tests/patch-0.11.2.test.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/tests/project-type.test.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/tests/routes-multilang.test.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/tests/schema-sync.test.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/tests/schemas-multilang.test.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/tests/schemas.test.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/tests/sections.test.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/tests/security.test.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/tests/severity.test.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/tests/shared-source.test.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/tests/structure.test.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/tests/sweep-nudge.test.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/tests/sync.test.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/tests/test-spec.test.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/tests/todo-tracking.test.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/tests/traceability.test.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/tests/upgrade.test.mjs +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/vscode-extension/.vscodeignore +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/vscode-extension/README.md +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.1}/vscode-extension/extension.js +0 -0
- {docguard_cli-0.12.0 → docguard_cli-0.13.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.13.1
|
|
10
10
|
source: extensions/spec-kit-docguard/skills/docguard-fix
|
|
11
11
|
---
|
|
12
|
-
<!-- docguard:version: 0.
|
|
12
|
+
<!-- docguard:version: 0.13.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.13.1
|
|
11
11
|
source: extensions/spec-kit-docguard/skills/docguard-guard
|
|
12
12
|
---
|
|
13
|
-
<!-- docguard:version: 0.
|
|
13
|
+
<!-- docguard:version: 0.13.1 -->
|
|
14
14
|
|
|
15
15
|
# DocGuard Guard Skill
|
|
16
16
|
|
|
@@ -139,7 +139,7 @@ For each finding, provide a **specific, actionable fix** — not "fix the issue"
|
|
|
139
139
|
|
|
140
140
|
Based on the triage results:
|
|
141
141
|
|
|
142
|
-
- **If all PASS**: "All
|
|
142
|
+
- **If all PASS**: "All 22 validators passed. Project is CDD-compliant. Ready to commit."
|
|
143
143
|
- **If only MEDIUM/LOW warnings**: "Non-blocking warnings found. Safe to commit, but consider running `/docguard.fix` for automated remediation."
|
|
144
144
|
- **If HIGH or CRITICAL failures**: "Blocking issues found. Fix these before committing. Suggest running `/docguard.fix --doc [most impactful doc]` next."
|
|
145
145
|
|
|
@@ -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.13.1
|
|
10
10
|
source: extensions/spec-kit-docguard/skills/docguard-review
|
|
11
11
|
---
|
|
12
|
-
<!-- docguard:version: 0.
|
|
12
|
+
<!-- docguard:version: 0.13.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.13.1
|
|
10
10
|
source: extensions/spec-kit-docguard/skills/docguard-score
|
|
11
11
|
---
|
|
12
|
-
<!-- docguard:version: 0.
|
|
12
|
+
<!-- docguard:version: 0.13.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.13.1
|
|
8
8
|
source: extensions/spec-kit-docguard/skills/docguard-sync
|
|
9
9
|
---
|
|
10
10
|
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
| Command | Purpose |
|
|
42
42
|
|---------|---------|
|
|
43
43
|
| `diagnose` | **Primary** — identify issues + generate AI fix prompts |
|
|
44
|
-
| `guard` | Validate project (CI gate) —
|
|
44
|
+
| `guard` | Validate project (CI gate) — 22 validators |
|
|
45
45
|
| `generate` | Reverse-engineer docs from code |
|
|
46
46
|
| `fix --doc <name>` | AI prompt for specific document |
|
|
47
47
|
| `score` | CDD maturity score (0-100) |
|
|
@@ -7,6 +7,83 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.13.1] - 2026-05-26
|
|
11
|
+
|
|
12
|
+
Patch + small feature release responding to the wu-whatsappinbox v0.12/v0.13
|
|
13
|
+
feedback. Fixes 2 bugs (B-5, B-6), ships 3 new features (S-7, S-11, S-12),
|
|
14
|
+
and adds a cross-cutting "no validator throws" safety net. **22 validators,
|
|
15
|
+
448 tests (was 434, +14 new).** New `docguard impact` command.
|
|
16
|
+
|
|
17
|
+
### Fixed
|
|
18
|
+
|
|
19
|
+
- **B-5: Freshness validator crashed with `getLastCommitDate is not defined`.** A wu-whatsappinbox install of v0.13.0 produced this ReferenceError despite all the imports being correct in source — we couldn't reproduce locally, but the user's report was clear. Fix: defensive dynamic import in `freshness.mjs` that falls back to the pre-v0.13 inline implementation if `../shared-git.mjs` ever fails to load. Worst-case behavior is now "rename detection silently disabled" instead of "validator crashes with useless message". Also added an inline fallback for the same defensive layering. Reported by wu-whatsappinbox.
|
|
20
|
+
- **B-6: Cross-Reference didn't URL-decode link target paths.** A markdown link like `[name](../WU%20Documentation/foo.md)` (where the directory has a space) was looked up with `existsSync('../WU%20Documentation/foo.md')` literally — the filesystem stores the decoded form. Now: `resolveTarget` tries BOTH the literal path (for paths that legitimately contain `%`) and the URL-decoded form. **Effect on wu-whatsappinbox: Cross-Reference went from 28/28 to 101/101 checks — 73 previously-broken refs now resolve correctly.** Reported by wu-whatsappinbox.
|
|
21
|
+
- **Cross-cutting safety net**: new `tests/guard-no-throw.test.mjs` runs guard against a fixture repo and asserts no validator leaks a ReferenceError / TypeError / "is not defined" / "is not a function" / "Cannot read properties of undefined" pattern into user-facing output. Found a *second* lurking bug while writing the test: Structure validator threw `Cannot read properties of undefined (reading 'some')` when `config.requiredFiles.agentFile` was missing — fixed with defensive array-or-string coercion + skip-when-missing for `changelog` too. This safety net runs in CI, catching the entire class of developer-error-leaks before release.
|
|
22
|
+
|
|
23
|
+
### Added
|
|
24
|
+
|
|
25
|
+
- **S-12: Cross-Reference suggests the closest anchor on near-miss.** When the validator flags a broken anchor, it now appends `(did you mean #athena-setup-aws-only?)` when a heading in the target doc is a close match. Two-pass matcher: (1) substring containment with ≥4-char minimum and ≥50% overlap to avoid spurious matches, (2) Levenshtein edit distance within a `max(3, len/5)` budget. **Three of the five wu user-fixes in v0.12.0 were "heading renamed, link not updated" — now deterministic-fixable from the warning text.** Reported by wu-whatsappinbox.
|
|
26
|
+
- **S-7: Draft-staleness check in Generated-Doc Staleness validator.** A `docguard:generated` doc with `status: draft` (either YAML frontmatter or `<!-- status: draft -->` inline marker) that hasn't been modified in `> draftStalenessDays` days (default 14) now warns. Catches forgotten skeletons that stall before the AI fills them in. Threshold configurable via `config.draftStalenessDays`. Validator returns N/A only when there's NOTHING to check (no source=code sections AND no draft docs). Reported by wu-whatsappinbox.
|
|
27
|
+
- **S-11: New `docguard impact` command.** After a commit (or before a PR), runs `git diff --name-only --since=<ref>` and shows which canonical doc sections reference any of the changed code files. Three match strategies (direct path / basename / backticked module name — same as L-2 trace --reverse). Highlights orphaned files (code that changed but no doc references it) so reviewers know what's undocumented. JSON mode emits `{ since, changedFiles, ignoredFiles, affectedDocs }` for CI bots. Designed as a post-commit hook companion to K-1's auto-fix Action. Reported by wu-whatsappinbox.
|
|
28
|
+
|
|
29
|
+
### Internal
|
|
30
|
+
|
|
31
|
+
- **+3 new test files**: `tests/guard-no-throw.test.mjs` (2 — cross-cutting safety), `tests/impact.test.mjs` (5 — S-11), plus 5 new test cases in `cross-reference.test.mjs` (S-12 + B-6) and `generated-staleness.test.mjs` (S-7). **Total: 434 → 448 tests (+14 new).**
|
|
32
|
+
- **New module**: `cli/commands/impact.mjs` (~140 lines).
|
|
33
|
+
- **Hardened**: `cli/validators/freshness.mjs` (defensive shared-git import), `cli/validators/structure.mjs` (defensive config-shape handling), `cli/validators/cross-reference.mjs` (URL-decode + anchor suggestion).
|
|
34
|
+
- **Dry-run on wu-whatsappinbox before push** (read-only): 670/674 PASS in 1.8s with all 22 validators. Cross-Reference jumped from 28/28 to **101/101 checks** — B-6 fix unlocked 73 previously-broken refs.
|
|
35
|
+
- No new NPM deps.
|
|
36
|
+
|
|
37
|
+
### Note on wu's v0.12 feedback
|
|
38
|
+
|
|
39
|
+
Several "still open" suggestions from the wu-whatsappinbox v0.12 feedback were already shipped:
|
|
40
|
+
|
|
41
|
+
- **S-2 (sweep-needed nudge)** → shipped in v0.12.0 as K-6.
|
|
42
|
+
- **S-3 (trace --reverse)** → shipped in v0.13.0 as L-2.
|
|
43
|
+
- **S-4 (`git log --follow`)** → shipped in v0.13.0 as L-3.
|
|
44
|
+
- **S-5 (.docguardignore at init)** → shipped in v0.12.0 as K-3.
|
|
45
|
+
- **S-6 (per-validator severity)** → shipped in v0.12.0 as K-4.
|
|
46
|
+
- **S-9 (pre-commit lite)** → shipped in v0.12.0 as K-5.
|
|
47
|
+
- **S-10 (`.docguard/fixed.json`)** → shipped in v0.13.0 as M-2.
|
|
48
|
+
|
|
49
|
+
Upgrade with `docguard upgrade --apply` (or `npm i -g docguard-cli@latest`) to get all of these. **The wu report header said v0.12.0 but the B-5 error pattern indicates an in-flight v0.13.0 install** — either way, this patch makes both versions resilient to the regression.
|
|
50
|
+
|
|
51
|
+
## [0.13.0] - 2026-05-26
|
|
52
|
+
|
|
53
|
+
Feature release — full backlog cleanup. **Phase L** (sync intelligence: 3 features), **Phase M** (bigger validators: 2 features), **Phase N** (polish: 2 fixes), and a new `shared-git.mjs` module that gives every git-touching validator rename-aware history. **22 validators total** (was 21). 434 tests, +34 from v0.12.
|
|
54
|
+
|
|
55
|
+
### Added
|
|
56
|
+
|
|
57
|
+
- **L-1 / S-1: `sync --since <ref>` surgical refresh.** `sync` now uses the git diff against the given ref to decide which code-truth doc sections actually need refreshing. Sections whose underlying source files weren't in the diff are explicitly skipped (with a `skipped` entry naming the section). When the diff contains no code files at all (e.g. PRs that touch only markdown), sync is a fast no-op. Saves wall-clock time on large monorepos.
|
|
58
|
+
- **L-2 / S-3: `trace --reverse <code-path>`.** Mirror of the forward trace — given a code file path, finds every canonical doc that references it. Three match strategies (direct path, basename, backticked module name) with a per-doc summary in text mode or full match list in JSON mode. Surfaces "is this file documented anywhere?" in one command.
|
|
59
|
+
- **L-3 / S-4: Rename detection via `git log --follow`.** New `cli/shared-git.mjs` module centralises every git-log call. All file-scoped queries now pass `--follow` so a `git mv` no longer resets the file's history. Freshness, Test-Spec, Traceability — anything that asks git "when was this file last touched?" — now answers correctly across renames.
|
|
60
|
+
- **M-1 / S-7: Generated-Doc Staleness validator** (22nd validator). New validator re-runs the memory-plan scanner and compares each `source=code` section's expected body against on-disk content. Flags sections where the doc and the scanner disagree — i.e. either code changed without `sync --write` running, or someone hand-edited a machine-owned section. Warning includes a "first drift at line N" hint that names the diff site.
|
|
61
|
+
- **M-2 / S-10: `.docguard/fixed.json` fix-history audit log.** Every mechanical fix `fix --write` applies is appended to a small JSON log under `.docguard/`. Entries are fingerprinted by `type+file+summary` and deduped (re-applying the same fix updates the timestamp instead of growing the file). Rolls over at 500 entries. New `docguard fix --history` command pretty-prints the log grouped by day. Also recorded: `appliedBy` (so K-1's `docguard-bot` auto-commits are distinguishable from human runs).
|
|
62
|
+
- **N-1: Per-file scoping of `--changed-only`.** The `--changed-only` lite mode now computes the actually-changed files (`git diff --name-only HEAD~1 HEAD`, configurable with `--since`) and passes them as `config.changedFiles` to validators that opt in. Docs-Sync is the first opt-in: routes and services outside the changed set are skipped entirely. On wu-whatsappinbox the Docs-Sync check count went from 101 → 21 in `--changed-only` mode.
|
|
63
|
+
- **N-2: 4 broken README anchors fixed** (caught by K-7's Cross-Reference validator). `[Commands](#-commands)` → `[Usage](#usage)`. `CONTRIBUTING.md` added to the validator's standard-docs lookup list (along with CODE_OF_CONDUCT.md, SECURITY.md, PHILOSOPHY.md, STANDARD.md, COMPARISONS.md) so cross-doc refs to those resolve.
|
|
64
|
+
|
|
65
|
+
### Changed
|
|
66
|
+
|
|
67
|
+
- **22 validators total** (was 21). Auto-fix bumped 6 doc references from "21 validators" → "22 validators" during the version bump.
|
|
68
|
+
- **Trace command** (existing) now honors `--reverse` to switch to the new reverse mode; the forward mode is unchanged.
|
|
69
|
+
- **`docguard guard` JSON output** for `--format json` no longer prints the banner or `ensureSkills` line — same headless fix as v0.12, extended to `trace --reverse --format json` and other JSON-mode commands.
|
|
70
|
+
|
|
71
|
+
### Internal
|
|
72
|
+
|
|
73
|
+
- **6 new test files**: `tests/shared-git.test.mjs` (11), `tests/sync-since.test.mjs` (3), `tests/trace-reverse.test.mjs` (5), `tests/generated-staleness.test.mjs` (4), `tests/fix-memory.test.mjs` (11), plus updates to `tests/changed-only.test.mjs`. **Total: 434 tests passing (was 400, +34 new).**
|
|
74
|
+
- **New modules**: `cli/shared-git.mjs` (centralized git plumbing with --follow), `cli/validators/generated-staleness.mjs` (M-1), `cli/writers/fix-memory.mjs` (M-2). New helpers exported from sync.mjs: section→file matcher table for surgical refresh.
|
|
75
|
+
- **Action / CLI dual-fix from v0.12** is now coordinated: K-1's auto-fix Action records to `.docguard/fixed.json` via `appliedBy: 'docguard-bot'`, giving teams a permanent record of which fixes the bot applied without diving into git history.
|
|
76
|
+
- **Dry-run on wu-whatsappinbox before push** (read-only): 670/674 PASS in 1.82s with all 22 validators. 4 warnings are stale "21 validators" references in wu's local docguard skill files — those auto-fix on the next `fix --write`.
|
|
77
|
+
- Bumped extension files via auto-fix (6 files: extension.yml + 5 SKILL.md).
|
|
78
|
+
- No new NPM dependencies. Still zero deps.
|
|
79
|
+
|
|
80
|
+
### Out of scope (deferred to v0.14)
|
|
81
|
+
|
|
82
|
+
- **Fix-history suppression**: M-2 currently records but doesn't suppress. v0.14 will let `fix --write` skip fixes that were applied + reverted (avoiding ping-pong loops).
|
|
83
|
+
- **More validators opt-into `config.changedFiles`**: N-1 only wires Docs-Sync. Environment and API-Surface could also benefit from path-level scoping.
|
|
84
|
+
- **`generate-staleness` per-section auto-fix**: M-1 only warns; a future enhancement could emit structured fixes that `sync --write` consumes.
|
|
85
|
+
- **`docguard upgrade --apply` for cross-machine teams**: currently in-place; could grow a "team-wide" mode that opens a PR.
|
|
86
|
+
|
|
10
87
|
## [0.12.0] - 2026-05-26
|
|
11
88
|
|
|
12
89
|
Feature release — Phase K (7 features). Schema bump to **0.5**. Adds the
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: docguard-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.13.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
|
|
@@ -41,7 +41,7 @@ Description-Content-Type: text/markdown
|
|
|
41
41
|
- [What is DocGuard?](#what-is-docguard)
|
|
42
42
|
- [Quick Start](#-quick-start)
|
|
43
43
|
- [Spec Kit Integration](#-spec-kit-integration)
|
|
44
|
-
- [
|
|
44
|
+
- [Usage](#usage)
|
|
45
45
|
- [Validators](#-validators)
|
|
46
46
|
- [Templates](#-templates)
|
|
47
47
|
- [AI Agent Support](#-ai-agent-support)
|
|
@@ -367,7 +367,7 @@ DocGuard provides AI agent slash commands for integrated workflows. Installed au
|
|
|
367
367
|
|
|
368
368
|
| Command | What It Does |
|
|
369
369
|
|:--------|:-------------|
|
|
370
|
-
| `/docguard.guard` | Run quality validation — check all
|
|
370
|
+
| `/docguard.guard` | Run quality validation — check all 22 validators |
|
|
371
371
|
| `/docguard.review` | Analyze doc quality and suggest improvements |
|
|
372
372
|
| `/docguard.fix` | Generate targeted fix prompts for specific issues |
|
|
373
373
|
| `/docguard.score` | Show CDD maturity score with category breakdown |
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
- [What is DocGuard?](#what-is-docguard)
|
|
18
18
|
- [Quick Start](#-quick-start)
|
|
19
19
|
- [Spec Kit Integration](#-spec-kit-integration)
|
|
20
|
-
- [
|
|
20
|
+
- [Usage](#usage)
|
|
21
21
|
- [Validators](#-validators)
|
|
22
22
|
- [Templates](#-templates)
|
|
23
23
|
- [AI Agent Support](#-ai-agent-support)
|
|
@@ -343,7 +343,7 @@ DocGuard provides AI agent slash commands for integrated workflows. Installed au
|
|
|
343
343
|
|
|
344
344
|
| Command | What It Does |
|
|
345
345
|
|:--------|:-------------|
|
|
346
|
-
| `/docguard.guard` | Run quality validation — check all
|
|
346
|
+
| `/docguard.guard` | Run quality validation — check all 22 validators |
|
|
347
347
|
| `/docguard.review` | Analyze doc quality and suggest improvements |
|
|
348
348
|
| `/docguard.fix` | Generate targeted fix prompts for specific issues |
|
|
349
349
|
| `/docguard.score` | Show CDD maturity score with category breakdown |
|
|
@@ -21,6 +21,7 @@ import { c } from '../shared.mjs';
|
|
|
21
21
|
import { computeApiSurfaceDrift } from '../validators/api-surface.mjs';
|
|
22
22
|
import { removeEndpoints, hasGeneratedMarker } from '../writers/api-reference.mjs';
|
|
23
23
|
import { applyMechanicalFixes } from '../writers/mechanical.mjs';
|
|
24
|
+
import { loadFixMemory } from '../writers/fix-memory.mjs';
|
|
24
25
|
import { runGuardInternal } from './guard.mjs';
|
|
25
26
|
|
|
26
27
|
const API_DOC = 'docs-canonical/API-REFERENCE.md';
|
|
@@ -281,6 +282,55 @@ export function applyAllMechanicalFixes(projectDir, config, { force = false } =
|
|
|
281
282
|
return { applied, skipped, total: fixes.length };
|
|
282
283
|
}
|
|
283
284
|
|
|
285
|
+
/**
|
|
286
|
+
* M-2 — `docguard fix --history` shows the audit log of mechanical fixes
|
|
287
|
+
* that have been applied to this project. Reads `.docguard/fixed.json`
|
|
288
|
+
* and pretty-prints (or emits JSON when --format json).
|
|
289
|
+
*/
|
|
290
|
+
function runHistoryMode(projectDir, flags) {
|
|
291
|
+
const mem = loadFixMemory(projectDir);
|
|
292
|
+
const isJson = flags.format === 'json';
|
|
293
|
+
|
|
294
|
+
if (isJson) {
|
|
295
|
+
console.log(JSON.stringify(mem, null, 2));
|
|
296
|
+
return;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
if (mem.entries.length === 0) {
|
|
300
|
+
console.log(`${c.bold}🗂 DocGuard Fix History${c.reset}`);
|
|
301
|
+
console.log(`${c.dim} No fixes recorded yet. Run \`docguard fix --write\` to start the audit log.${c.reset}`);
|
|
302
|
+
return;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
console.log(`${c.bold}🗂 DocGuard Fix History${c.reset} ${c.dim}(${mem.entries.length} entries, newest first)${c.reset}\n`);
|
|
306
|
+
|
|
307
|
+
// Group by date for readability
|
|
308
|
+
const byDate = new Map();
|
|
309
|
+
for (const e of mem.entries) {
|
|
310
|
+
const day = (e.appliedAt || '').slice(0, 10);
|
|
311
|
+
if (!byDate.has(day)) byDate.set(day, []);
|
|
312
|
+
byDate.get(day).push(e);
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
// Show the most recent N days (cap output at 20 entries)
|
|
316
|
+
let printed = 0;
|
|
317
|
+
for (const [day, dayEntries] of byDate) {
|
|
318
|
+
if (printed >= 20) break;
|
|
319
|
+
console.log(` ${c.cyan}${day}${c.reset} ${c.dim}(${dayEntries.length} fix${dayEntries.length > 1 ? 'es' : ''})${c.reset}`);
|
|
320
|
+
for (const e of dayEntries.slice(0, 5)) {
|
|
321
|
+
if (printed >= 20) break;
|
|
322
|
+
const time = (e.appliedAt || '').slice(11, 16);
|
|
323
|
+
console.log(` ${c.dim}${time}${c.reset} ${e.type} → ${c.cyan}${e.file}${c.reset} ${c.dim}${e.summary || ''}${c.reset}`);
|
|
324
|
+
printed++;
|
|
325
|
+
}
|
|
326
|
+
if (dayEntries.length > 5) console.log(` ${c.dim}... ${dayEntries.length - 5} more on this day${c.reset}`);
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
if (mem.entries.length > 20) {
|
|
330
|
+
console.log(`\n ${c.dim}... ${mem.entries.length - 20} older entries. Use ${c.cyan}--format json${c.dim} for the full log.${c.reset}`);
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
|
|
284
334
|
function runWriteMode(projectDir, config, flags) {
|
|
285
335
|
const isJson = flags.format === 'json';
|
|
286
336
|
const { applied, skipped, total } = applyAllMechanicalFixes(projectDir, config, { force: flags.force });
|
|
@@ -321,6 +371,11 @@ export function runFix(projectDir, config, flags) {
|
|
|
321
371
|
const autoFix = flags.auto || false;
|
|
322
372
|
const specificDoc = flags.doc || null;
|
|
323
373
|
|
|
374
|
+
// M-2: --history shows the audit trail of past mechanical fixes.
|
|
375
|
+
if (flags.history) {
|
|
376
|
+
return runHistoryMode(projectDir, flags);
|
|
377
|
+
}
|
|
378
|
+
|
|
324
379
|
// --write: deterministically APPLY mechanical fixes (no LLM). Currently:
|
|
325
380
|
// remove API-REFERENCE.md endpoints the OpenAPI spec confirms no longer exist.
|
|
326
381
|
if (flags.write) {
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
import { c, resolveSeverity } from '../shared.mjs';
|
|
11
11
|
import { detectAgentMode, isSpecKitInitialized } from '../ensure-skills.mjs';
|
|
12
12
|
import { checkUpgradeStatus } from './upgrade.mjs';
|
|
13
|
+
import { changedFilesSince, isGitRepo } from '../shared-git.mjs';
|
|
13
14
|
import { validateStructure, validateDocSections } from '../validators/structure.mjs';
|
|
14
15
|
import { validateDrift } from '../validators/drift.mjs';
|
|
15
16
|
import { validateChangelog } from '../validators/changelog.mjs';
|
|
@@ -27,6 +28,7 @@ import { validateMetricsConsistency } from '../validators/metrics-consistency.mj
|
|
|
27
28
|
import { validateDocsCoverage } from '../validators/docs-coverage.mjs';
|
|
28
29
|
import { validateDocQuality } from '../validators/doc-quality.mjs';
|
|
29
30
|
import { validateCrossReferences } from '../validators/cross-reference.mjs';
|
|
31
|
+
import { validateGeneratedStaleness } from '../validators/generated-staleness.mjs';
|
|
30
32
|
import { validateTodoTracking } from '../validators/todo-tracking.mjs';
|
|
31
33
|
import { validateSchemaSync } from '../validators/schema-sync.mjs';
|
|
32
34
|
import { validateSpecKitIntegration } from '../scanners/speckit.mjs';
|
|
@@ -103,6 +105,7 @@ export function runGuardInternal(projectDir, config) {
|
|
|
103
105
|
{ key: 'schemaSync', name: 'Schema-Sync', fn: () => validateSchemaSync(projectDir, config) },
|
|
104
106
|
{ key: 'specKit', name: 'Spec-Kit', fn: () => validateSpecKitIntegration(projectDir, config) },
|
|
105
107
|
{ key: 'crossReference', name: 'Cross-Reference', fn: () => validateCrossReferences(projectDir, config) },
|
|
108
|
+
{ key: 'generatedStaleness', name: 'Generated-Staleness', fn: () => validateGeneratedStaleness(projectDir, config) },
|
|
106
109
|
// Metrics-Consistency runs post-loop (needs guard results)
|
|
107
110
|
];
|
|
108
111
|
|
|
@@ -197,7 +200,7 @@ function liteValidatorsConfig() {
|
|
|
197
200
|
'structure', 'docsSync', 'drift', 'changelog', 'testSpec', 'environment',
|
|
198
201
|
'security', 'architecture', 'freshness', 'traceability', 'docsDiff',
|
|
199
202
|
'apiSurface', 'metadataSync', 'docsCoverage', 'docQuality', 'todoTracking',
|
|
200
|
-
'schemaSync', 'specKit', 'crossReference', 'metricsConsistency',
|
|
203
|
+
'schemaSync', 'specKit', 'crossReference', 'generatedStaleness', 'metricsConsistency',
|
|
201
204
|
];
|
|
202
205
|
const out = {};
|
|
203
206
|
for (const k of all) out[k] = CHANGED_ONLY_VALIDATORS.includes(k);
|
|
@@ -212,8 +215,22 @@ export function runGuard(projectDir, config, flags) {
|
|
|
212
215
|
// fast subset (Docs-Sync, Environment, API-Surface). Designed for husky/
|
|
213
216
|
// lefthook hooks; expects to finish in under 2 seconds.
|
|
214
217
|
if (flags.changedOnly) {
|
|
215
|
-
|
|
216
|
-
|
|
218
|
+
// Compute the set of changed files since the given ref (default HEAD~1 —
|
|
219
|
+
// the pre-commit common case: "files changed in this commit vs the last
|
|
220
|
+
// committed state"). Validators that opt into `config.changedFiles` can
|
|
221
|
+
// scope to this list; others run normally over the whole tree.
|
|
222
|
+
const ref = flags.since || 'HEAD~1';
|
|
223
|
+
const changed = isGitRepo(projectDir) ? changedFilesSince(projectDir, ref) : [];
|
|
224
|
+
config = {
|
|
225
|
+
...config,
|
|
226
|
+
validators: liteValidatorsConfig(),
|
|
227
|
+
changedFiles: changed,
|
|
228
|
+
changedSinceRef: ref,
|
|
229
|
+
};
|
|
230
|
+
const label = changed.length > 0
|
|
231
|
+
? `${changed.length} file(s) changed since ${ref}`
|
|
232
|
+
: `no changes since ${ref} — running all ${CHANGED_ONLY_VALIDATORS.length} lite validators on full tree`;
|
|
233
|
+
console.log(`${c.cyan}⚡ docguard guard --changed-only${c.reset} ${c.dim}(${label})${c.reset}\n`);
|
|
217
234
|
}
|
|
218
235
|
|
|
219
236
|
const data = runGuardInternal(projectDir, config);
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Impact Command — S-11
|
|
3
|
+
*
|
|
4
|
+
* After a commit (or before opening a PR), shows which canonical doc
|
|
5
|
+
* sections reference any file that changed since `--since` (default HEAD~1).
|
|
6
|
+
* Combines the L-2 reverse-trace logic with the changed-files diff so you
|
|
7
|
+
* get "you should re-read these doc sections" in one command.
|
|
8
|
+
*
|
|
9
|
+
* Use cases:
|
|
10
|
+
* - Post-commit hook: `docguard impact --since HEAD~1` runs after each
|
|
11
|
+
* commit and reminds the developer which docs to update.
|
|
12
|
+
* - PR prep: `docguard impact --since main` shows the doc surface area
|
|
13
|
+
* touched by the whole branch.
|
|
14
|
+
*
|
|
15
|
+
* JSON mode emits a structured `{ changedFiles, affectedDocs }` payload
|
|
16
|
+
* for CI integrations and PR-comment bots.
|
|
17
|
+
*
|
|
18
|
+
* @req SC-S11-001 — impact reports per-file → doc mappings
|
|
19
|
+
* @req SC-S11-002 — files with no doc references are listed as "no impact"
|
|
20
|
+
* @req SC-S11-003 — --format json emits parseable structured output
|
|
21
|
+
* @req SC-S11-004 — non-code files (.md, .json, etc.) are skipped from impact analysis
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
import { existsSync, readFileSync, readdirSync } from 'node:fs';
|
|
25
|
+
import { resolve, basename } from 'node:path';
|
|
26
|
+
|
|
27
|
+
import { c } from '../shared.mjs';
|
|
28
|
+
import { changedFilesSince, isGitRepo } from '../shared-git.mjs';
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* File extensions we consider "code" for the purposes of impact analysis.
|
|
32
|
+
* Match the set used by other validators (Docs-Sync, Freshness).
|
|
33
|
+
*/
|
|
34
|
+
const CODE_EXTENSIONS = /\.(ts|tsx|js|jsx|mjs|cjs|py|go|rs|java|kt|rb|php|cs|swift)$/;
|
|
35
|
+
|
|
36
|
+
function escapeRegex(s) {
|
|
37
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Find canonical doc references for a single file. Reuses the same three
|
|
42
|
+
* match strategies as trace --reverse for consistency: direct path,
|
|
43
|
+
* basename, backticked module name.
|
|
44
|
+
*/
|
|
45
|
+
function findReferences(file, docs) {
|
|
46
|
+
const refs = [];
|
|
47
|
+
const normalized = file.replace(/^\.\//, '');
|
|
48
|
+
const base = basename(normalized);
|
|
49
|
+
const stem = base.replace(/\.[^.]+$/, '');
|
|
50
|
+
const stemRe = new RegExp(`\`${escapeRegex(stem)}\``);
|
|
51
|
+
for (const [docName, lines] of docs) {
|
|
52
|
+
for (let i = 0; i < lines.length; i++) {
|
|
53
|
+
const line = lines[i];
|
|
54
|
+
let kind = null;
|
|
55
|
+
if (line.includes(normalized)) kind = 'path';
|
|
56
|
+
else if (line.includes(base)) kind = 'basename';
|
|
57
|
+
else if (stemRe.test(line)) kind = 'module';
|
|
58
|
+
if (kind) {
|
|
59
|
+
refs.push({ doc: docName, line: i + 1, kind });
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return refs;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export function runImpact(projectDir, _config, flags) {
|
|
67
|
+
const isJson = flags.format === 'json';
|
|
68
|
+
const since = flags.since || 'HEAD~1';
|
|
69
|
+
|
|
70
|
+
if (!isGitRepo(projectDir)) {
|
|
71
|
+
if (isJson) {
|
|
72
|
+
console.log(JSON.stringify({ since, error: 'not a git repository', changedFiles: [], affectedDocs: [] }, null, 2));
|
|
73
|
+
} else {
|
|
74
|
+
console.error(`${c.red}Not a git repository — impact requires git history.${c.reset}`);
|
|
75
|
+
}
|
|
76
|
+
process.exit(1);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const changed = changedFilesSince(projectDir, since);
|
|
80
|
+
// Filter to code files only — markdown/json/yaml changes don't have "doc
|
|
81
|
+
// impact" in the same sense; they ARE the docs (or config).
|
|
82
|
+
const codeChanged = changed.filter(f => CODE_EXTENSIONS.test(f));
|
|
83
|
+
|
|
84
|
+
// Index canonical docs once
|
|
85
|
+
const docsDir = resolve(projectDir, 'docs-canonical');
|
|
86
|
+
const docsIndex = new Map(); // docName → lines[]
|
|
87
|
+
if (existsSync(docsDir)) {
|
|
88
|
+
try {
|
|
89
|
+
for (const f of readdirSync(docsDir)) {
|
|
90
|
+
if (!f.endsWith('.md')) continue;
|
|
91
|
+
try {
|
|
92
|
+
const content = readFileSync(resolve(docsDir, f), 'utf-8');
|
|
93
|
+
docsIndex.set(f, content.split('\n'));
|
|
94
|
+
} catch { /* skip unreadable */ }
|
|
95
|
+
}
|
|
96
|
+
} catch { /* skip if dir unreadable */ }
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Compute per-file references
|
|
100
|
+
const fileImpact = []; // { file, references: [{doc, line, kind}] }
|
|
101
|
+
for (const f of codeChanged) {
|
|
102
|
+
fileImpact.push({ file: f, references: findReferences(f, docsIndex) });
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Roll up: which docs are affected, with all source files
|
|
106
|
+
const docMap = new Map(); // doc → Set<file>
|
|
107
|
+
for (const { file, references } of fileImpact) {
|
|
108
|
+
for (const r of references) {
|
|
109
|
+
if (!docMap.has(r.doc)) docMap.set(r.doc, new Set());
|
|
110
|
+
docMap.get(r.doc).add(file);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
const affectedDocs = Array.from(docMap.entries()).map(([doc, files]) => ({
|
|
114
|
+
doc,
|
|
115
|
+
files: Array.from(files),
|
|
116
|
+
}));
|
|
117
|
+
|
|
118
|
+
// ── JSON output ──
|
|
119
|
+
if (isJson) {
|
|
120
|
+
console.log(JSON.stringify({
|
|
121
|
+
since,
|
|
122
|
+
changedFiles: codeChanged,
|
|
123
|
+
ignoredFiles: changed.filter(f => !CODE_EXTENSIONS.test(f)),
|
|
124
|
+
affectedDocs,
|
|
125
|
+
timestamp: new Date().toISOString(),
|
|
126
|
+
}, null, 2));
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// ── Text output ──
|
|
131
|
+
console.log(`${c.bold}📊 DocGuard Impact${c.reset} ${c.dim}(since ${since})${c.reset}\n`);
|
|
132
|
+
|
|
133
|
+
if (changed.length === 0) {
|
|
134
|
+
console.log(` ${c.green}✅ No file changes since ${since}.${c.reset}`);
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
if (codeChanged.length === 0) {
|
|
138
|
+
console.log(` ${c.dim}No code files changed (${changed.length} non-code files: ${changed.slice(0, 3).join(', ')}${changed.length > 3 ? '…' : ''}).${c.reset}`);
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
console.log(` ${c.cyan}${codeChanged.length}${c.reset} code file(s) changed.\n`);
|
|
143
|
+
|
|
144
|
+
if (affectedDocs.length === 0) {
|
|
145
|
+
console.log(` ${c.yellow}⚠ No canonical docs reference any of the changed files.${c.reset}`);
|
|
146
|
+
console.log(` ${c.dim}This often means the changed code is undocumented. Consider:${c.reset}`);
|
|
147
|
+
console.log(` ${c.dim} - Running ${c.cyan}docguard generate --plan${c.dim} to add doc skeletons${c.reset}`);
|
|
148
|
+
console.log(` ${c.dim} - Reviewing whether the change belongs in an existing doc${c.reset}`);
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
console.log(` ${c.green}${affectedDocs.length}${c.reset} canonical doc(s) reference the changed files:\n`);
|
|
153
|
+
for (const { doc, files } of affectedDocs) {
|
|
154
|
+
console.log(` ${c.cyan}${doc}${c.reset} ${c.dim}(${files.length} file${files.length > 1 ? 's' : ''})${c.reset}`);
|
|
155
|
+
for (const f of files.slice(0, 5)) {
|
|
156
|
+
console.log(` ${c.dim}via${c.reset} ${f}`);
|
|
157
|
+
}
|
|
158
|
+
if (files.length > 5) console.log(` ${c.dim}... ${files.length - 5} more${c.reset}`);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// List code files with NO doc references — these may need new docs
|
|
162
|
+
const orphaned = fileImpact.filter(fi => fi.references.length === 0).map(fi => fi.file);
|
|
163
|
+
if (orphaned.length > 0) {
|
|
164
|
+
console.log(`\n ${c.yellow}${orphaned.length} changed file(s) have NO canonical doc reference:${c.reset}`);
|
|
165
|
+
for (const f of orphaned.slice(0, 5)) console.log(` ${c.dim}• ${f}${c.reset}`);
|
|
166
|
+
if (orphaned.length > 5) console.log(` ${c.dim}... ${orphaned.length - 5} more${c.reset}`);
|
|
167
|
+
console.log(` ${c.dim}These may be undocumented — review whether they belong in an existing doc.${c.reset}`);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
@@ -34,6 +34,48 @@ function gitChangedFiles(projectDir, since) {
|
|
|
34
34
|
return [...new Set([...committed, ...working])];
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
+
/**
|
|
38
|
+
* L-1: Map each `source: 'code'` section ID to a predicate that returns true
|
|
39
|
+
* when one of the changed file paths could plausibly affect it. Conservative
|
|
40
|
+
* by design — when in doubt we run the section's sync, never skip it.
|
|
41
|
+
*
|
|
42
|
+
* The predicates are matched against project-relative POSIX paths (the form
|
|
43
|
+
* `git diff --name-only` returns).
|
|
44
|
+
*/
|
|
45
|
+
const SECTION_FILE_MATCHERS = {
|
|
46
|
+
'tech-stack': (p) => /package\.json$|pyproject\.toml$|Cargo\.toml$|go\.mod$|pom\.xml$|Gemfile$/.test(p),
|
|
47
|
+
'frontend-modules': (p) => /(^|\/)(src\/)?(stores|hooks|contexts|features)\//.test(p),
|
|
48
|
+
'endpoints-table': (p) => /(^|\/)(routes|controllers|handlers|app\/api)\//.test(p)
|
|
49
|
+
|| /\.(yaml|yml|json)$/i.test(p) && /openapi|swagger/i.test(p),
|
|
50
|
+
'entities-table': (p) => /(^|\/)(models|schemas|entities)\//.test(p)
|
|
51
|
+
|| /\.prisma$/.test(p),
|
|
52
|
+
'relationships': (p) => /(^|\/)(models|schemas|entities)\//.test(p)
|
|
53
|
+
|| /\.prisma$/.test(p),
|
|
54
|
+
'screens-table': (p) => /(^|\/)(screens|pages|app)\//.test(p)
|
|
55
|
+
|| /\.(tsx|jsx)$/.test(p),
|
|
56
|
+
'flows': (p) => /(^|\/)(screens|pages|app|routes)\//.test(p),
|
|
57
|
+
'integrations-table':(p) => /package\.json$|pyproject\.toml$|requirements.*\.txt$|Cargo\.toml$/.test(p),
|
|
58
|
+
'features-table': (p) => /(^|\/)(features|domains)\//.test(p),
|
|
59
|
+
'features': (p) => /(^|\/)(features|domains)\//.test(p),
|
|
60
|
+
'env-vars-table': (p) => /\.env(\..+)?$|(^|\/)config\//.test(p)
|
|
61
|
+
|| /\.(ts|tsx|js|jsx|mjs|py|go|rs|java|kt|rb)$/.test(p), // any code may use env
|
|
62
|
+
'setup': (p) => /\.env(\..+)?$|(^|\/)config\//.test(p),
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Decide whether a given code-truth section should be re-synced based on the
|
|
67
|
+
* set of changed files. Returns true when:
|
|
68
|
+
* - changedFiles is null/empty (no scope info → sync everything), OR
|
|
69
|
+
* - any changed file matches the section's known source patterns, OR
|
|
70
|
+
* - the section has no matcher registered (unknown → conservative: sync)
|
|
71
|
+
*/
|
|
72
|
+
function sectionTouchedByChanges(sectionId, changedFiles) {
|
|
73
|
+
if (!changedFiles || changedFiles.length === 0) return true;
|
|
74
|
+
const matcher = SECTION_FILE_MATCHERS[sectionId];
|
|
75
|
+
if (!matcher) return true; // unknown section → don't accidentally skip it
|
|
76
|
+
return changedFiles.some(matcher);
|
|
77
|
+
}
|
|
78
|
+
|
|
37
79
|
export function runSync(projectDir, config, flags) {
|
|
38
80
|
const plan = buildMemoryPlan(projectDir, config);
|
|
39
81
|
const apply = !!flags.write;
|
|
@@ -63,6 +105,14 @@ export function runSync(projectDir, config, flags) {
|
|
|
63
105
|
const existing = getSection(content, sec.id);
|
|
64
106
|
if (!existing) continue; // sync refreshes sections that already exist
|
|
65
107
|
if (existing.body.trim() === String(sec.body).trim()) continue; // already current
|
|
108
|
+
// L-1: when --since is provided, only update sections whose underlying
|
|
109
|
+
// source files appear in the changed set. Avoids spurious updates when
|
|
110
|
+
// the section's CONTENT would naturally drift (e.g. timestamp-driven
|
|
111
|
+
// counters) but no real source file changed.
|
|
112
|
+
if (changed !== null && !sectionTouchedByChanges(sec.id, changed)) {
|
|
113
|
+
skipped.push({ doc: doc.path, reason: `section ${sec.id} unchanged since ${flags.since} (no underlying source files in diff)` });
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
66
116
|
codeSectionChanged = true;
|
|
67
117
|
updates.push({ doc: doc.path, section: sec.id, status: apply ? 'updated' : 'stale' });
|
|
68
118
|
if (apply) { content = replaceSection(content, sec.id, sec.body).content; docChanged = true; }
|