docguard-cli 0.9.7__tar.gz → 0.9.8__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.9.8/.github/workflows/release.yml +78 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/PKG-INFO +75 -2
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/README.md +74 -1
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/SECURITY.md +3 -3
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/cli/validators/metadata-sync.mjs +9 -2
- docguard_cli-0.9.8/examples/01-express-api/README.md +3 -0
- docguard_cli-0.9.8/examples/01-express-api/package.json +12 -0
- docguard_cli-0.9.8/examples/01-express-api/server.js +37 -0
- docguard_cli-0.9.8/examples/02-python-flask/README.md +24 -0
- docguard_cli-0.9.8/examples/02-python-flask/app.py +50 -0
- docguard_cli-0.9.8/examples/02-python-flask/docs-canonical/ARCHITECTURE.md +26 -0
- docguard_cli-0.9.8/examples/02-python-flask/requirements.txt +1 -0
- docguard_cli-0.9.8/examples/03-spec-kit-project/CHANGELOG.md +9 -0
- docguard_cli-0.9.8/examples/03-spec-kit-project/README.md +35 -0
- docguard_cli-0.9.8/examples/03-spec-kit-project/docs-canonical/ARCHITECTURE.md +40 -0
- docguard_cli-0.9.8/examples/03-spec-kit-project/docs-canonical/TEST-SPEC.md +28 -0
- docguard_cli-0.9.8/examples/03-spec-kit-project/package.json +10 -0
- docguard_cli-0.9.8/examples/03-spec-kit-project/src/index.js +50 -0
- docguard_cli-0.9.8/examples/03-spec-kit-project/tests/basic.test.js +23 -0
- docguard_cli-0.9.8/examples/README.md +44 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/extensions/spec-kit-docguard/extension.yml +1 -1
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/package.json +1 -1
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/pyproject.toml +1 -1
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/.agent/commands/speckit.analyze.md +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/.agent/commands/speckit.checklist.md +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/.agent/commands/speckit.clarify.md +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/.agent/commands/speckit.constitution.md +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/.agent/commands/speckit.implement.md +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/.agent/commands/speckit.plan.md +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/.agent/commands/speckit.specify.md +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/.agent/commands/speckit.tasks.md +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/.agent/commands/speckit.taskstoissues.md +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/.agent/skills/docguard-fix/SKILL.md +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/.agent/skills/docguard-guard/SKILL.md +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/.agent/skills/docguard-review/SKILL.md +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/.agent/skills/docguard-score/SKILL.md +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/.agent/skills/speckit-analyze/SKILL.md +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/.agent/skills/speckit-checklist/SKILL.md +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/.agent/skills/speckit-clarify/SKILL.md +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/.agent/skills/speckit-constitution/SKILL.md +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/.agent/skills/speckit-implement/SKILL.md +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/.agent/skills/speckit-plan/SKILL.md +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/.agent/skills/speckit-specify/SKILL.md +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/.agent/skills/speckit-tasks/SKILL.md +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/.agent/skills/speckit-taskstoissues/SKILL.md +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/.docguard.json +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/.docguardignore +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/.github/workflows/ci.yml +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/.github/workflows/spec-kit-extension.yml +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/.gitignore +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/.npmignore +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/.specify/init-options.json +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/.specify/memory/constitution.md +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/.specify/scripts/bash/check-prerequisites.sh +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/.specify/scripts/bash/common.sh +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/.specify/scripts/bash/create-new-feature.sh +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/.specify/scripts/bash/setup-plan.sh +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/.specify/scripts/bash/update-agent-context.sh +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/.specify/templates/agent-file-template.md +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/.specify/templates/checklist-template.md +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/.specify/templates/constitution-template.md +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/.specify/templates/plan-template.md +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/.specify/templates/spec-template.md +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/.specify/templates/tasks-template.md +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/AGENTS.md +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/CHANGELOG.md +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/CODE_OF_CONDUCT.md +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/COMPARISONS.md +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/CONTRIBUTING.md +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/DRIFT-LOG.md +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/LICENSE +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/PHILOSOPHY.md +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/ROADMAP.md +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/STANDARD.md +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/SUPPORT.md +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/action.yml +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/cli/commands/agents.mjs +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/cli/commands/badge.mjs +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/cli/commands/ci.mjs +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/cli/commands/diagnose.mjs +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/cli/commands/diff.mjs +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/cli/commands/fix.mjs +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/cli/commands/generate.mjs +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/cli/commands/guard.mjs +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/cli/commands/hooks.mjs +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/cli/commands/init.mjs +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/cli/commands/llms.mjs +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/cli/commands/publish.mjs +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/cli/commands/score.mjs +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/cli/commands/setup.mjs +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/cli/commands/trace.mjs +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/cli/commands/watch.mjs +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/cli/docguard.mjs +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/cli/ensure-skills.mjs +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/cli/scanners/doc-tools.mjs +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/cli/scanners/routes.mjs +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/cli/scanners/schemas.mjs +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/cli/scanners/speckit.mjs +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/cli/shared.mjs +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/cli/validators/architecture.mjs +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/cli/validators/changelog.mjs +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/cli/validators/doc-quality.mjs +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/cli/validators/docs-coverage.mjs +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/cli/validators/docs-diff.mjs +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/cli/validators/docs-sync.mjs +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/cli/validators/drift.mjs +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/cli/validators/environment.mjs +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/cli/validators/freshness.mjs +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/cli/validators/metrics-consistency.mjs +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/cli/validators/schema-sync.mjs +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/cli/validators/security.mjs +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/cli/validators/structure.mjs +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/cli/validators/test-spec.mjs +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/cli/validators/todo-tracking.mjs +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/cli/validators/traceability.mjs +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/commands/docguard.fix.md +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/commands/docguard.guard.md +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/commands/docguard.review.md +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/commands/docguard.score.md +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/configs/fastify.json +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/configs/generic.json +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/configs/nextjs.json +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/configs/python.json +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/docguard_cli/__init__.py +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/docguard_cli/wrapper.py +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/docs/ai-integration.md +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/docs/commands.md +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/docs/configuration.md +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/docs/faq.md +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/docs/installation.md +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/docs/profiles.md +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/docs/quickstart.md +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/docs-canonical/ARCHITECTURE.md +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/docs-canonical/DATA-MODEL.md +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/docs-canonical/ENVIRONMENT.md +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/docs-canonical/SECURITY.md +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/docs-canonical/TEST-SPEC.md +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/extensions/spec-kit-docguard/LICENSE +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/extensions/spec-kit-docguard/README.md +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/extensions/spec-kit-docguard/commands/diagnose.md +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/extensions/spec-kit-docguard/commands/generate.md +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/extensions/spec-kit-docguard/commands/guard.md +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/extensions/spec-kit-docguard/commands/init.md +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/extensions/spec-kit-docguard/commands/score.md +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/extensions/spec-kit-docguard/commands/trace.md +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/extensions/spec-kit-docguard/scripts/bash/common.sh +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/extensions/spec-kit-docguard/scripts/bash/docguard-check-docs.sh +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/extensions/spec-kit-docguard/scripts/bash/docguard-init-doc.sh +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/extensions/spec-kit-docguard/scripts/bash/docguard-suggest-fix.sh +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/extensions/spec-kit-docguard/skills/docguard-fix/SKILL.md +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/extensions/spec-kit-docguard/skills/docguard-guard/SKILL.md +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/extensions/spec-kit-docguard/skills/docguard-review/SKILL.md +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/extensions/spec-kit-docguard/skills/docguard-score/SKILL.md +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/extensions/spec-kit-docguard/templates/extensions.yml +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/templates/ADR.md.template +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/templates/AGENTS.md.template +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/templates/ARCHITECTURE.md.template +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/templates/CHANGELOG.md.template +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/templates/CURRENT-STATE.md.template +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/templates/DATA-MODEL.md.template +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/templates/DEPLOYMENT.md.template +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/templates/DRIFT-LOG.md.template +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/templates/ENVIRONMENT.md.template +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/templates/KNOWN-GOTCHAS.md.template +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/templates/REQUIREMENTS.md.template +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/templates/ROADMAP.md.template +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/templates/RUNBOOKS.md.template +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/templates/SECURITY.md.template +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/templates/TEST-SPEC.md.template +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/templates/TROUBLESHOOTING.md.template +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/templates/VENDOR-BUGS.md.template +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/templates/ci/github-actions.yml +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/templates/commands/docguard.fix.md +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/templates/commands/docguard.guard.md +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/templates/commands/docguard.init.md +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/templates/commands/docguard.review.md +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/templates/commands/docguard.update.md +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/tests/commands.test.mjs +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/vscode-extension/.vscodeignore +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/vscode-extension/README.md +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/vscode-extension/extension.js +0 -0
- {docguard_cli-0.9.7 → docguard_cli-0.9.8}/vscode-extension/package.json +0 -0
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
name: Publish to npm + PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
|
+
|
|
7
|
+
permissions:
|
|
8
|
+
contents: read
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
# ── Run tests first ──
|
|
12
|
+
test:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
strategy:
|
|
15
|
+
matrix:
|
|
16
|
+
node-version: [18, 20, 22]
|
|
17
|
+
steps:
|
|
18
|
+
- uses: actions/checkout@v4
|
|
19
|
+
with:
|
|
20
|
+
fetch-depth: 0
|
|
21
|
+
- uses: actions/setup-node@v4
|
|
22
|
+
with:
|
|
23
|
+
node-version: ${{ matrix.node-version }}
|
|
24
|
+
- name: Run Tests
|
|
25
|
+
run: npm test
|
|
26
|
+
- name: Guard (self-check)
|
|
27
|
+
run: node cli/docguard.mjs guard || [ $? -eq 2 ]
|
|
28
|
+
|
|
29
|
+
# ── Publish to npm ──
|
|
30
|
+
publish-npm:
|
|
31
|
+
needs: test
|
|
32
|
+
runs-on: ubuntu-latest
|
|
33
|
+
steps:
|
|
34
|
+
- uses: actions/checkout@v4
|
|
35
|
+
- uses: actions/setup-node@v4
|
|
36
|
+
with:
|
|
37
|
+
node-version: 20
|
|
38
|
+
registry-url: 'https://registry.npmjs.org'
|
|
39
|
+
|
|
40
|
+
- name: Sync version from tag
|
|
41
|
+
run: |
|
|
42
|
+
VERSION="${GITHUB_REF_NAME#v}"
|
|
43
|
+
npm version "$VERSION" --no-git-tag-version --allow-same-version
|
|
44
|
+
echo "Publishing version $VERSION"
|
|
45
|
+
|
|
46
|
+
- name: Publish
|
|
47
|
+
run: npm publish
|
|
48
|
+
env:
|
|
49
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
50
|
+
|
|
51
|
+
# ── Publish to PyPI ──
|
|
52
|
+
publish-pypi:
|
|
53
|
+
needs: test
|
|
54
|
+
runs-on: ubuntu-latest
|
|
55
|
+
steps:
|
|
56
|
+
- uses: actions/checkout@v4
|
|
57
|
+
- uses: actions/setup-python@v5
|
|
58
|
+
with:
|
|
59
|
+
python-version: '3.12'
|
|
60
|
+
|
|
61
|
+
- name: Sync version from tag
|
|
62
|
+
run: |
|
|
63
|
+
VERSION="${GITHUB_REF_NAME#v}"
|
|
64
|
+
sed -i "s/^version = \".*\"/version = \"$VERSION\"/" pyproject.toml
|
|
65
|
+
echo "Publishing version $VERSION"
|
|
66
|
+
grep 'version' pyproject.toml
|
|
67
|
+
|
|
68
|
+
- name: Install build tools
|
|
69
|
+
run: pip install build twine
|
|
70
|
+
|
|
71
|
+
- name: Build
|
|
72
|
+
run: python -m build
|
|
73
|
+
|
|
74
|
+
- name: Publish
|
|
75
|
+
run: python -m twine upload dist/*
|
|
76
|
+
env:
|
|
77
|
+
TWINE_USERNAME: __token__
|
|
78
|
+
TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: docguard-cli
|
|
3
|
-
Version: 0.9.
|
|
3
|
+
Version: 0.9.8
|
|
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
|
|
@@ -46,6 +46,8 @@ Description-Content-Type: text/markdown
|
|
|
46
46
|
- [Templates](#-templates)
|
|
47
47
|
- [AI Agent Support](#-ai-agent-support)
|
|
48
48
|
- [Slash Commands](#-slash-commands)
|
|
49
|
+
- [Examples](#-examples)
|
|
50
|
+
- [Testing](#-testing)
|
|
49
51
|
- [CI/CD Integration](#%EF%B8%8F-cicd-integration)
|
|
50
52
|
- [File Structure](#-file-structure)
|
|
51
53
|
- [Configuration](#%EF%B8%8F-configuration)
|
|
@@ -68,6 +70,39 @@ DocGuard is an official [GitHub Spec Kit](https://github.com/github/spec-kit) co
|
|
|
68
70
|
|
|
69
71
|
📖 **[Philosophy](PHILOSOPHY.md)** · 📋 **[CDD Standard](STANDARD.md)** · ⚖️ **[Comparisons](COMPARISONS.md)** · 🗺️ **[Roadmap](ROADMAP.md)**
|
|
70
72
|
|
|
73
|
+
### Architecture
|
|
74
|
+
|
|
75
|
+
```mermaid
|
|
76
|
+
graph TD
|
|
77
|
+
CLI["CLI Entry<br/>docguard.mjs"] --> Commands["Commands (15)"]
|
|
78
|
+
Commands --> guard["guard"]
|
|
79
|
+
Commands --> generate["generate"]
|
|
80
|
+
Commands --> score["score"]
|
|
81
|
+
Commands --> diagnose["diagnose"]
|
|
82
|
+
Commands --> setup["setup wizard"]
|
|
83
|
+
Commands --> other["diff · init · fix · trace<br/>agents · hooks · badge · ci · watch"]
|
|
84
|
+
|
|
85
|
+
guard --> Validators["Validators (19)"]
|
|
86
|
+
generate --> Scanners["Scanners (4)<br/>routes · schemas · doc-tools · speckit"]
|
|
87
|
+
score --> Scoring["Weighted Scoring<br/>8 categories"]
|
|
88
|
+
diagnose --> Validators
|
|
89
|
+
diagnose --> AIPrompts["AI-Ready<br/>Fix Prompts"]
|
|
90
|
+
|
|
91
|
+
Validators --> Output["Output"]
|
|
92
|
+
Scanners --> Output
|
|
93
|
+
Scoring --> Output
|
|
94
|
+
Output --> Terminal["Terminal"]
|
|
95
|
+
Output --> JSON["JSON"]
|
|
96
|
+
Output --> Badge["Badge"]
|
|
97
|
+
|
|
98
|
+
style CLI fill:#2d5016,color:#fff
|
|
99
|
+
style Validators fill:#1a3a5c,color:#fff
|
|
100
|
+
style Scanners fill:#1a3a5c,color:#fff
|
|
101
|
+
style Output fill:#5c3a1a,color:#fff
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
> **Distribution**: Node.js core (npm) · Python wrapper (PyPI) · GitHub Action (`action.yml`) · Spec Kit Extension (ZIP)
|
|
105
|
+
|
|
71
106
|
---
|
|
72
107
|
|
|
73
108
|
## ⚡ Quick Start
|
|
@@ -359,6 +394,44 @@ For advanced users and CI/CD pipelines, DocGuard includes bash scripts with `--j
|
|
|
359
394
|
|
|
360
395
|
---
|
|
361
396
|
|
|
397
|
+
## 📁 Examples
|
|
398
|
+
|
|
399
|
+
Three real-world projects to see DocGuard in action:
|
|
400
|
+
|
|
401
|
+
| Example | Scenario | What You'll See |
|
|
402
|
+
|---------|----------|----------------|
|
|
403
|
+
| [01-express-api](examples/01-express-api/) | Node.js API with **zero docs** | Cold-start: `generate` → instant coverage |
|
|
404
|
+
| [02-python-flask](examples/02-python-flask/) | Python app with **drifted docs** | Drift detection: catch when docs lie |
|
|
405
|
+
| [03-spec-kit-project](examples/03-spec-kit-project/) | Full CDD + Spec Kit | Gold standard: what maturity looks like |
|
|
406
|
+
|
|
407
|
+
See [examples/README.md](examples/README.md) for step-by-step instructions.
|
|
408
|
+
|
|
409
|
+
---
|
|
410
|
+
|
|
411
|
+
## 🧪 Testing
|
|
412
|
+
|
|
413
|
+
### Test Suite
|
|
414
|
+
|
|
415
|
+
```bash
|
|
416
|
+
npm test # 33 tests across 18 describe blocks
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
Covers all 15 CLI commands, project type detection, compliance profiles, JSON output format, and help completeness.
|
|
420
|
+
|
|
421
|
+
### CI Matrix
|
|
422
|
+
|
|
423
|
+
| Node.js | OS | Status |
|
|
424
|
+
|---------|-----|--------|
|
|
425
|
+
| 18 | ubuntu-latest | ✅ |
|
|
426
|
+
| 20 | ubuntu-latest | ✅ |
|
|
427
|
+
| 22 | ubuntu-latest | ✅ |
|
|
428
|
+
|
|
429
|
+
### Self-Validation (Dogfooding)
|
|
430
|
+
|
|
431
|
+
DocGuard runs its own `guard`, `score`, `diff`, `diagnose`, and `badge` commands against itself in CI — ensuring the tool passes its own checks.
|
|
432
|
+
|
|
433
|
+
---
|
|
434
|
+
|
|
362
435
|
## ⚙️ CI/CD Integration
|
|
363
436
|
|
|
364
437
|
### GitHub Actions
|
|
@@ -386,7 +459,7 @@ npx docguard-cli hooks --type pre-commit
|
|
|
386
459
|
### GitHub Marketplace
|
|
387
460
|
|
|
388
461
|
```yaml
|
|
389
|
-
- uses: raccioly/docguard@v0.9.
|
|
462
|
+
- uses: raccioly/docguard@v0.9.7
|
|
390
463
|
with:
|
|
391
464
|
command: guard
|
|
392
465
|
fail-on-warning: true
|
|
@@ -22,6 +22,8 @@
|
|
|
22
22
|
- [Templates](#-templates)
|
|
23
23
|
- [AI Agent Support](#-ai-agent-support)
|
|
24
24
|
- [Slash Commands](#-slash-commands)
|
|
25
|
+
- [Examples](#-examples)
|
|
26
|
+
- [Testing](#-testing)
|
|
25
27
|
- [CI/CD Integration](#%EF%B8%8F-cicd-integration)
|
|
26
28
|
- [File Structure](#-file-structure)
|
|
27
29
|
- [Configuration](#%EF%B8%8F-configuration)
|
|
@@ -44,6 +46,39 @@ DocGuard is an official [GitHub Spec Kit](https://github.com/github/spec-kit) co
|
|
|
44
46
|
|
|
45
47
|
📖 **[Philosophy](PHILOSOPHY.md)** · 📋 **[CDD Standard](STANDARD.md)** · ⚖️ **[Comparisons](COMPARISONS.md)** · 🗺️ **[Roadmap](ROADMAP.md)**
|
|
46
48
|
|
|
49
|
+
### Architecture
|
|
50
|
+
|
|
51
|
+
```mermaid
|
|
52
|
+
graph TD
|
|
53
|
+
CLI["CLI Entry<br/>docguard.mjs"] --> Commands["Commands (15)"]
|
|
54
|
+
Commands --> guard["guard"]
|
|
55
|
+
Commands --> generate["generate"]
|
|
56
|
+
Commands --> score["score"]
|
|
57
|
+
Commands --> diagnose["diagnose"]
|
|
58
|
+
Commands --> setup["setup wizard"]
|
|
59
|
+
Commands --> other["diff · init · fix · trace<br/>agents · hooks · badge · ci · watch"]
|
|
60
|
+
|
|
61
|
+
guard --> Validators["Validators (19)"]
|
|
62
|
+
generate --> Scanners["Scanners (4)<br/>routes · schemas · doc-tools · speckit"]
|
|
63
|
+
score --> Scoring["Weighted Scoring<br/>8 categories"]
|
|
64
|
+
diagnose --> Validators
|
|
65
|
+
diagnose --> AIPrompts["AI-Ready<br/>Fix Prompts"]
|
|
66
|
+
|
|
67
|
+
Validators --> Output["Output"]
|
|
68
|
+
Scanners --> Output
|
|
69
|
+
Scoring --> Output
|
|
70
|
+
Output --> Terminal["Terminal"]
|
|
71
|
+
Output --> JSON["JSON"]
|
|
72
|
+
Output --> Badge["Badge"]
|
|
73
|
+
|
|
74
|
+
style CLI fill:#2d5016,color:#fff
|
|
75
|
+
style Validators fill:#1a3a5c,color:#fff
|
|
76
|
+
style Scanners fill:#1a3a5c,color:#fff
|
|
77
|
+
style Output fill:#5c3a1a,color:#fff
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
> **Distribution**: Node.js core (npm) · Python wrapper (PyPI) · GitHub Action (`action.yml`) · Spec Kit Extension (ZIP)
|
|
81
|
+
|
|
47
82
|
---
|
|
48
83
|
|
|
49
84
|
## ⚡ Quick Start
|
|
@@ -335,6 +370,44 @@ For advanced users and CI/CD pipelines, DocGuard includes bash scripts with `--j
|
|
|
335
370
|
|
|
336
371
|
---
|
|
337
372
|
|
|
373
|
+
## 📁 Examples
|
|
374
|
+
|
|
375
|
+
Three real-world projects to see DocGuard in action:
|
|
376
|
+
|
|
377
|
+
| Example | Scenario | What You'll See |
|
|
378
|
+
|---------|----------|----------------|
|
|
379
|
+
| [01-express-api](examples/01-express-api/) | Node.js API with **zero docs** | Cold-start: `generate` → instant coverage |
|
|
380
|
+
| [02-python-flask](examples/02-python-flask/) | Python app with **drifted docs** | Drift detection: catch when docs lie |
|
|
381
|
+
| [03-spec-kit-project](examples/03-spec-kit-project/) | Full CDD + Spec Kit | Gold standard: what maturity looks like |
|
|
382
|
+
|
|
383
|
+
See [examples/README.md](examples/README.md) for step-by-step instructions.
|
|
384
|
+
|
|
385
|
+
---
|
|
386
|
+
|
|
387
|
+
## 🧪 Testing
|
|
388
|
+
|
|
389
|
+
### Test Suite
|
|
390
|
+
|
|
391
|
+
```bash
|
|
392
|
+
npm test # 33 tests across 18 describe blocks
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
Covers all 15 CLI commands, project type detection, compliance profiles, JSON output format, and help completeness.
|
|
396
|
+
|
|
397
|
+
### CI Matrix
|
|
398
|
+
|
|
399
|
+
| Node.js | OS | Status |
|
|
400
|
+
|---------|-----|--------|
|
|
401
|
+
| 18 | ubuntu-latest | ✅ |
|
|
402
|
+
| 20 | ubuntu-latest | ✅ |
|
|
403
|
+
| 22 | ubuntu-latest | ✅ |
|
|
404
|
+
|
|
405
|
+
### Self-Validation (Dogfooding)
|
|
406
|
+
|
|
407
|
+
DocGuard runs its own `guard`, `score`, `diff`, `diagnose`, and `badge` commands against itself in CI — ensuring the tool passes its own checks.
|
|
408
|
+
|
|
409
|
+
---
|
|
410
|
+
|
|
338
411
|
## ⚙️ CI/CD Integration
|
|
339
412
|
|
|
340
413
|
### GitHub Actions
|
|
@@ -362,7 +435,7 @@ npx docguard-cli hooks --type pre-commit
|
|
|
362
435
|
### GitHub Marketplace
|
|
363
436
|
|
|
364
437
|
```yaml
|
|
365
|
-
- uses: raccioly/docguard@v0.9.
|
|
438
|
+
- uses: raccioly/docguard@v0.9.7
|
|
366
439
|
with:
|
|
367
440
|
command: guard
|
|
368
441
|
fail-on-warning: true
|
|
@@ -4,15 +4,15 @@
|
|
|
4
4
|
|
|
5
5
|
| Version | Supported |
|
|
6
6
|
|---------|-----------|
|
|
7
|
-
| 0.
|
|
8
|
-
| < 0.
|
|
7
|
+
| 0.9.x | ✅ Current |
|
|
8
|
+
| < 0.9 | ❌ Not supported |
|
|
9
9
|
|
|
10
10
|
## Reporting a Vulnerability
|
|
11
11
|
|
|
12
12
|
If you discover a security vulnerability in DocGuard, please report it responsibly:
|
|
13
13
|
|
|
14
14
|
1. **Do NOT** open a public GitHub issue for security vulnerabilities
|
|
15
|
-
2. **
|
|
15
|
+
2. **Report via** [GitHub Security Advisories](https://github.com/raccioly/docguard/security/advisories/new) (private, preferred)
|
|
16
16
|
3. Include:
|
|
17
17
|
- Description of the vulnerability
|
|
18
18
|
- Steps to reproduce
|
|
@@ -40,6 +40,7 @@ export function validateMetadataSync(projectDir, config) {
|
|
|
40
40
|
const vParts = currentVersion.split('.');
|
|
41
41
|
const major = parseInt(vParts[0], 10);
|
|
42
42
|
const minor = parseInt(vParts[1], 10);
|
|
43
|
+
const patch = parseInt(vParts[2], 10);
|
|
43
44
|
|
|
44
45
|
// ── Check 1: extension.yml version sync ──
|
|
45
46
|
const extFiles = findExtensionYmls(projectDir);
|
|
@@ -101,9 +102,15 @@ export function validateMetadataSync(projectDir, config) {
|
|
|
101
102
|
const fParts = foundVersion.split('.');
|
|
102
103
|
const fMajor = parseInt(fParts[0], 10);
|
|
103
104
|
const fMinor = parseInt(fParts[1], 10);
|
|
105
|
+
const fPatch = parseInt(fParts[2], 10);
|
|
104
106
|
|
|
105
|
-
// Only flag if same major but older
|
|
106
|
-
|
|
107
|
+
// Only flag if same major but older version (same package, stale ref)
|
|
108
|
+
const isOlder = fMajor === major && (
|
|
109
|
+
fMinor < minor ||
|
|
110
|
+
(fMinor === minor && fPatch < patch)
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
if (isOlder && foundVersion !== currentVersion) {
|
|
107
114
|
total++;
|
|
108
115
|
warnings.push(
|
|
109
116
|
`${relPath} references "v${foundVersion}" in an actionable context (URL/install/declaration) but current version is "${currentVersion}"`
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "express-api-example",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "A simple Express API — intentionally undocumented for DocGuard demo",
|
|
5
|
+
"main": "server.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"start": "node server.js"
|
|
8
|
+
},
|
|
9
|
+
"dependencies": {
|
|
10
|
+
"express": "^4.18.0"
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
const express = require('express');
|
|
2
|
+
const app = express();
|
|
3
|
+
const PORT = process.env.PORT || 3000;
|
|
4
|
+
|
|
5
|
+
app.use(express.json());
|
|
6
|
+
|
|
7
|
+
// Health check
|
|
8
|
+
app.get('/health', (req, res) => {
|
|
9
|
+
res.json({ status: 'ok', uptime: process.uptime() });
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
// List users
|
|
13
|
+
app.get('/api/users', (req, res) => {
|
|
14
|
+
res.json([
|
|
15
|
+
{ id: 1, name: 'Alice', role: 'admin' },
|
|
16
|
+
{ id: 2, name: 'Bob', role: 'user' },
|
|
17
|
+
]);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
// Create user
|
|
21
|
+
app.post('/api/users', (req, res) => {
|
|
22
|
+
const { name, role } = req.body;
|
|
23
|
+
if (!name) return res.status(400).json({ error: 'Name is required' });
|
|
24
|
+
res.status(201).json({ id: Date.now(), name, role: role || 'user' });
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
// Get user by ID
|
|
28
|
+
app.get('/api/users/:id', (req, res) => {
|
|
29
|
+
const id = parseInt(req.params.id);
|
|
30
|
+
if (id === 1) return res.json({ id: 1, name: 'Alice', role: 'admin' });
|
|
31
|
+
if (id === 2) return res.json({ id: 2, name: 'Bob', role: 'user' });
|
|
32
|
+
res.status(404).json({ error: 'User not found' });
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
app.listen(PORT, () => {
|
|
36
|
+
console.log(`Server running on port ${PORT}`);
|
|
37
|
+
});
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Product Catalog API
|
|
2
|
+
|
|
3
|
+
A Flask-based REST API for managing products. Provides **3 endpoints** for product listing and retrieval.
|
|
4
|
+
|
|
5
|
+
## Stack
|
|
6
|
+
|
|
7
|
+
- Python 3.10+
|
|
8
|
+
- Flask
|
|
9
|
+
- **SQLite** for local storage
|
|
10
|
+
|
|
11
|
+
## Endpoints
|
|
12
|
+
|
|
13
|
+
| Method | Path | Description |
|
|
14
|
+
|--------|------|-------------|
|
|
15
|
+
| GET | /health | Health check |
|
|
16
|
+
| GET | /api/products | List all products |
|
|
17
|
+
| GET | /api/products/:id | Get product by ID |
|
|
18
|
+
|
|
19
|
+
## Running
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
pip install -r requirements.txt
|
|
23
|
+
python app.py
|
|
24
|
+
```
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
from flask import Flask, request, jsonify
|
|
2
|
+
import os
|
|
3
|
+
|
|
4
|
+
app = Flask(__name__)
|
|
5
|
+
|
|
6
|
+
# Database connection — uses PostgreSQL via psycopg2
|
|
7
|
+
DATABASE_URL = os.environ.get('DATABASE_URL', 'postgresql://localhost:5432/myapp')
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@app.route('/health')
|
|
11
|
+
def health():
|
|
12
|
+
return jsonify({'status': 'healthy', 'database': 'postgresql'})
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@app.route('/api/products')
|
|
16
|
+
def list_products():
|
|
17
|
+
"""List all products with optional category filter."""
|
|
18
|
+
category = request.args.get('category')
|
|
19
|
+
return jsonify([
|
|
20
|
+
{'id': 1, 'name': 'Widget', 'price': 9.99, 'category': 'tools'},
|
|
21
|
+
{'id': 2, 'name': 'Gadget', 'price': 19.99, 'category': 'electronics'},
|
|
22
|
+
])
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
@app.route('/api/products/<int:product_id>')
|
|
26
|
+
def get_product(product_id):
|
|
27
|
+
"""Get a single product by ID."""
|
|
28
|
+
return jsonify({'id': product_id, 'name': 'Widget', 'price': 9.99})
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
@app.route('/api/products', methods=['POST'])
|
|
32
|
+
def create_product():
|
|
33
|
+
"""Create a new product."""
|
|
34
|
+
data = request.get_json()
|
|
35
|
+
if not data or 'name' not in data:
|
|
36
|
+
return jsonify({'error': 'Product name is required'}), 400
|
|
37
|
+
return jsonify({'id': 100, **data}), 201
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
@app.route('/api/orders', methods=['POST'])
|
|
41
|
+
def create_order():
|
|
42
|
+
"""Place a new order — with inventory check."""
|
|
43
|
+
data = request.get_json()
|
|
44
|
+
if not data or 'product_id' not in data:
|
|
45
|
+
return jsonify({'error': 'Product ID is required'}), 400
|
|
46
|
+
return jsonify({'order_id': 500, 'status': 'confirmed'}), 201
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
if __name__ == '__main__':
|
|
50
|
+
app.run(debug=True, port=5000)
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Architecture
|
|
2
|
+
|
|
3
|
+
## System Overview
|
|
4
|
+
|
|
5
|
+
Product Catalog API — a simple Flask application.
|
|
6
|
+
|
|
7
|
+
## Tech Stack
|
|
8
|
+
|
|
9
|
+
- **Runtime**: Python 3.10+
|
|
10
|
+
- **Framework**: Flask
|
|
11
|
+
- **Database**: SQLite (local development)
|
|
12
|
+
- **Deployment**: Docker
|
|
13
|
+
|
|
14
|
+
## Components
|
|
15
|
+
|
|
16
|
+
| Component | Purpose |
|
|
17
|
+
|-----------|---------|
|
|
18
|
+
| app.py | Main Flask application |
|
|
19
|
+
| models.py | Database models |
|
|
20
|
+
|
|
21
|
+
## Data Flow
|
|
22
|
+
|
|
23
|
+
1. Client sends HTTP request
|
|
24
|
+
2. Flask routes to handler
|
|
25
|
+
3. Handler queries SQLite database
|
|
26
|
+
4. Response returned as JSON
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
flask>=3.0
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Task Tracker
|
|
2
|
+
|
|
3
|
+
A lightweight task management CLI built with Canonical-Driven Development (CDD).
|
|
4
|
+
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
node src/index.js add "Review pull request"
|
|
9
|
+
node src/index.js list
|
|
10
|
+
node src/index.js done 1
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Features
|
|
14
|
+
|
|
15
|
+
- Add, list, and complete tasks
|
|
16
|
+
- JSON file-based storage
|
|
17
|
+
- Status filtering (pending, done)
|
|
18
|
+
|
|
19
|
+
## Documentation
|
|
20
|
+
|
|
21
|
+
All canonical documentation lives in `docs-canonical/`:
|
|
22
|
+
|
|
23
|
+
| Document | Purpose |
|
|
24
|
+
|----------|---------|
|
|
25
|
+
| ARCHITECTURE.md | System design and components |
|
|
26
|
+
| TEST-SPEC.md | Test requirements and coverage |
|
|
27
|
+
|
|
28
|
+
## CDD Compliance
|
|
29
|
+
|
|
30
|
+
This project uses [DocGuard](https://github.com/raccioly/docguard) for documentation enforcement:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npx docguard-cli guard # Validate docs
|
|
34
|
+
npx docguard-cli score # Check maturity
|
|
35
|
+
```
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Architecture
|
|
2
|
+
|
|
3
|
+
## System Overview
|
|
4
|
+
|
|
5
|
+
Task Tracker is a CLI application for managing tasks via a JSON file store.
|
|
6
|
+
|
|
7
|
+
## Tech Stack
|
|
8
|
+
|
|
9
|
+
- **Language**: JavaScript (Node.js 18+)
|
|
10
|
+
- **Storage**: JSON file (`tasks.json`)
|
|
11
|
+
- **Testing**: `node:test` (built-in)
|
|
12
|
+
- **Dependencies**: Zero — pure Node.js built-ins only
|
|
13
|
+
|
|
14
|
+
## Components
|
|
15
|
+
|
|
16
|
+
| Component | File | Purpose |
|
|
17
|
+
|-----------|------|---------|
|
|
18
|
+
| CLI Entry | `src/index.js` | Command parsing and dispatch |
|
|
19
|
+
| Task Store | `tasks.json` | Persistent task storage |
|
|
20
|
+
|
|
21
|
+
## Layer Boundaries
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
CLI Arguments → Command Dispatch → File I/O → JSON Storage
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Data Flow
|
|
28
|
+
|
|
29
|
+
### Adding a Task
|
|
30
|
+
1. User runs `node src/index.js add "Task title"`
|
|
31
|
+
2. CLI parses command and arguments
|
|
32
|
+
3. `addTask()` loads existing tasks from `tasks.json`
|
|
33
|
+
4. New task appended with auto-incremented ID
|
|
34
|
+
5. Tasks array saved back to `tasks.json`
|
|
35
|
+
|
|
36
|
+
### Completing a Task
|
|
37
|
+
1. User runs `node src/index.js done <id>`
|
|
38
|
+
2. `completeTask()` loads tasks, finds by ID
|
|
39
|
+
3. Status changed to `done`, timestamp added
|
|
40
|
+
4. Updated array saved to file
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Test Specification
|
|
2
|
+
|
|
3
|
+
## Test Strategy
|
|
4
|
+
|
|
5
|
+
All tests use Node.js built-in test runner (`node:test`).
|
|
6
|
+
|
|
7
|
+
## Test Categories
|
|
8
|
+
|
|
9
|
+
### Unit Tests
|
|
10
|
+
|
|
11
|
+
| Test | File | What It Verifies |
|
|
12
|
+
|------|------|-----------------|
|
|
13
|
+
| Add task | `tests/basic.test.js` | Task creation with correct fields |
|
|
14
|
+
| List tasks | `tests/basic.test.js` | Retrieval of all tasks |
|
|
15
|
+
| Complete task | `tests/basic.test.js` | Status transition to done |
|
|
16
|
+
|
|
17
|
+
### Integration Tests
|
|
18
|
+
|
|
19
|
+
| Test | What It Verifies |
|
|
20
|
+
|------|-----------------|
|
|
21
|
+
| CLI add | Running `node src/index.js add` produces correct output |
|
|
22
|
+
| CLI list | Running `node src/index.js list` shows tasks |
|
|
23
|
+
|
|
24
|
+
## Running Tests
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
npm test
|
|
28
|
+
```
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
const { readFileSync, writeFileSync, existsSync } = require('fs');
|
|
2
|
+
const { resolve } = require('path');
|
|
3
|
+
|
|
4
|
+
const TASKS_FILE = resolve(__dirname, '../tasks.json');
|
|
5
|
+
|
|
6
|
+
function loadTasks() {
|
|
7
|
+
if (!existsSync(TASKS_FILE)) return [];
|
|
8
|
+
return JSON.parse(readFileSync(TASKS_FILE, 'utf-8'));
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function saveTasks(tasks) {
|
|
12
|
+
writeFileSync(TASKS_FILE, JSON.stringify(tasks, null, 2) + '\n', 'utf-8');
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function addTask(title) {
|
|
16
|
+
const tasks = loadTasks();
|
|
17
|
+
const task = { id: tasks.length + 1, title, status: 'pending', created: new Date().toISOString() };
|
|
18
|
+
tasks.push(task);
|
|
19
|
+
saveTasks(tasks);
|
|
20
|
+
console.log(`Added: [${task.id}] ${title}`);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function listTasks(filter) {
|
|
24
|
+
const tasks = loadTasks();
|
|
25
|
+
const filtered = filter ? tasks.filter(t => t.status === filter) : tasks;
|
|
26
|
+
if (filtered.length === 0) return console.log('No tasks found.');
|
|
27
|
+
for (const t of filtered) {
|
|
28
|
+
const mark = t.status === 'done' ? '✅' : '⬜';
|
|
29
|
+
console.log(` ${mark} [${t.id}] ${t.title}`);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function completeTask(id) {
|
|
34
|
+
const tasks = loadTasks();
|
|
35
|
+
const task = tasks.find(t => t.id === parseInt(id));
|
|
36
|
+
if (!task) return console.log(`Task ${id} not found.`);
|
|
37
|
+
task.status = 'done';
|
|
38
|
+
task.completed = new Date().toISOString();
|
|
39
|
+
saveTasks(tasks);
|
|
40
|
+
console.log(`Done: [${task.id}] ${task.title}`);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const [,, cmd, ...args] = process.argv;
|
|
44
|
+
|
|
45
|
+
switch (cmd) {
|
|
46
|
+
case 'add': addTask(args.join(' ')); break;
|
|
47
|
+
case 'list': listTasks(args[0]); break;
|
|
48
|
+
case 'done': completeTask(args[0]); break;
|
|
49
|
+
default: console.log('Usage: node src/index.js <add|list|done> [args]');
|
|
50
|
+
}
|