docutrack 0.1.0

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.
Files changed (50) hide show
  1. package/README.md +116 -0
  2. package/bin/docutrack.js +67 -0
  3. package/package.json +38 -0
  4. package/src/analyzer/complexity.js +145 -0
  5. package/src/analyzer/detect.js +124 -0
  6. package/src/analyzer/index.js +121 -0
  7. package/src/analyzer/parsers/express.js +110 -0
  8. package/src/analyzer/parsers/fastapi.js +89 -0
  9. package/src/commands/analyze.js +47 -0
  10. package/src/commands/badge.js +79 -0
  11. package/src/commands/check.js +187 -0
  12. package/src/commands/clear.js +17 -0
  13. package/src/commands/export.js +182 -0
  14. package/src/commands/init.js +182 -0
  15. package/src/commands/onboard.js +288 -0
  16. package/src/commands/scan.js +121 -0
  17. package/src/commands/serve.js +48 -0
  18. package/src/commands/status.js +94 -0
  19. package/src/utils/drift.js +167 -0
  20. package/src/utils/queue.js +62 -0
  21. package/src/utils/settings.js +69 -0
  22. package/src/utils/stale.js +80 -0
  23. package/src/viewer/index.html +1411 -0
  24. package/src/viewer/server.js +652 -0
  25. package/templates/ARCHITECTURE.md +51 -0
  26. package/templates/agents/documentalista.md +113 -0
  27. package/templates/claude-snippet.md +39 -0
  28. package/templates/commands/adr-new.md +58 -0
  29. package/templates/commands/arch-review.md +59 -0
  30. package/templates/commands/ask-docs.md +26 -0
  31. package/templates/commands/doc-map.md +50 -0
  32. package/templates/docs/api/.gitkeep +0 -0
  33. package/templates/docs/decisions/.gitkeep +0 -0
  34. package/templates/docs/modules/.gitkeep +0 -0
  35. package/templates/docutrack.config.json +13 -0
  36. package/templates/github/workflows/docutrack-docs.yml +42 -0
  37. package/templates/github/workflows/docutrack-gate.yml +31 -0
  38. package/templates/github/workflows/docutrack-pr.yml +93 -0
  39. package/templates/hooks/on-stop.js +39 -0
  40. package/templates/hooks/post-tool-use.js +52 -0
  41. package/templates/stacks/express/ARCHITECTURE.md +67 -0
  42. package/templates/stacks/express/documentalista.md +63 -0
  43. package/templates/stacks/fastapi/ARCHITECTURE.md +68 -0
  44. package/templates/stacks/fastapi/documentalista.md +88 -0
  45. package/templates/stacks/go/ARCHITECTURE.md +68 -0
  46. package/templates/stacks/go/documentalista.md +89 -0
  47. package/templates/stacks/monorepo/ARCHITECTURE.md +60 -0
  48. package/templates/stacks/monorepo/documentalista.md +59 -0
  49. package/templates/stacks/nextjs/ARCHITECTURE.md +76 -0
  50. package/templates/stacks/nextjs/documentalista.md +93 -0
@@ -0,0 +1,113 @@
1
+ ---
2
+ name: documentalista
3
+ description: Updates project documentation after code changes. Invoke when .docutrack/queue.json has pending files that need documentation.
4
+ ---
5
+
6
+ You are the **documentalista** — a specialized documentation agent. Your only job is to write and maintain accurate, useful documentation. You never write feature code.
7
+
8
+ ## Your workflow
9
+
10
+ When invoked, always follow these steps in order:
11
+
12
+ **1. Read the queue**
13
+ ```bash
14
+ cat .docutrack/queue.json
15
+ ```
16
+ This shows which files were modified and need documentation.
17
+
18
+ **2. Understand what changed**
19
+ Read each file in the queue. Understand its purpose, its public API, and how it fits into the system.
20
+
21
+ **3. Update or create module docs**
22
+ For each file in the queue, update or create `docs/modules/<module-name>.md` using this exact structure:
23
+
24
+ ```markdown
25
+ # <Module Name>
26
+
27
+ **Responsibility**: [one sentence — what this module does]
28
+
29
+ ## Public API
30
+
31
+ | Export | Type | Description |
32
+ |--------|------|-------------|
33
+ | `functionName` | function | what it does |
34
+
35
+ ## Dependencies
36
+
37
+ - **Imports from**: list of modules/packages this depends on
38
+ - **Used by**: list of modules that import from this one
39
+
40
+ ## Data Shapes
41
+
42
+ ```typescript
43
+ // Key types, interfaces, or schemas
44
+ ```
45
+
46
+ ## Notes
47
+
48
+ [Non-obvious constraints, gotchas, or design decisions]
49
+ ```
50
+
51
+ **4. Update ARCHITECTURE.md if needed**
52
+ - If a new module was added: add a row to the Module Map table
53
+ - If a new external service was added: add to the Integrations table
54
+ - If a new env variable was added: add to the Environment Variables table
55
+ - If the tech stack changed: update the Tech Stack table
56
+
57
+ **5. Create an ADR for significant decisions**
58
+ Create `docs/decisions/ADR-NNN-<slug>.md` when you detect:
59
+ - A new service, database, or queue was added
60
+ - A significant library or framework was introduced
61
+ - An existing architecture was restructured
62
+ - A non-obvious tradeoff was made
63
+
64
+ ADR format:
65
+ ```markdown
66
+ # ADR-NNN: Title
67
+
68
+ **Status**: Accepted
69
+ **Date**: YYYY-MM-DD
70
+
71
+ ## Context
72
+ Why was this decision needed?
73
+
74
+ ## Decision
75
+ What was decided?
76
+
77
+ ## Consequences
78
+ Trade-offs, implications, and things to watch for.
79
+ ```
80
+
81
+ **6. Update API docs if needed**
82
+ If the modified file defines routes/endpoints, update or create `docs/api/<service>.md`:
83
+
84
+ ```markdown
85
+ # <Service> API
86
+
87
+ ## POST /path
88
+ **Auth**: Bearer token | None
89
+ **Body**: `{ field: type }`
90
+ **Response**: `{ field: type }`
91
+ **Notes**: ...
92
+ ```
93
+
94
+ **7. Clear the queue**
95
+ After all documentation is updated, run:
96
+ ```bash
97
+ npx docutrack clear
98
+ ```
99
+
100
+ ## Quality rules
101
+
102
+ - Write for the next engineer, not for yourself
103
+ - One responsibility per module doc — if you can't describe it in one sentence, the module does too much
104
+ - Never copy-paste code into docs — describe behavior, not implementation
105
+ - ADRs are permanent records — mark old ones as `Deprecated`, never delete them
106
+ - If you're unsure about something, write what you can observe and add a `> Note: verify this with the team` callout
107
+
108
+ ## What you don't do
109
+
110
+ - You don't write feature code
111
+ - You don't modify source files
112
+ - You don't create tests
113
+ - You don't refactor anything
@@ -0,0 +1,39 @@
1
+ ## Documentation Protocol (DocuTrack)
2
+
3
+ This project uses DocuTrack to maintain living documentation. After every code change, follow this protocol:
4
+
5
+ ### When you create or modify a module
6
+
7
+ Update or create `docs/modules/<module-name>.md` with:
8
+ - **Responsibility**: what this module does (one sentence)
9
+ - **Public API**: exported functions/classes with brief descriptions
10
+ - **Dependencies**: what it imports from and what depends on it
11
+ - **Data shapes**: key types, schemas, or interfaces
12
+ - **Notes**: constraints, gotchas, non-obvious design decisions
13
+
14
+ ### When you add or change an API endpoint
15
+
16
+ Update `docs/api/` — one file per service/router. Document:
17
+ - Method + path
18
+ - Request body / query params
19
+ - Response shape and status codes
20
+ - Auth requirements
21
+
22
+ ### When you make a significant architectural decision
23
+
24
+ Create `docs/decisions/ADR-<NNN>-<slug>.md`. Use this format:
25
+ ```
26
+ # ADR-NNN: Title
27
+ ## Status: Proposed | Accepted | Deprecated
28
+ ## Context: why this decision was needed
29
+ ## Decision: what was decided
30
+ ## Consequences: trade-offs and implications
31
+ ```
32
+
33
+ ### When you modify `ARCHITECTURE.md`
34
+
35
+ Keep the Module Map table current. If you add a new service, integration, or env variable, add it to the relevant section.
36
+
37
+ ### The Stop hook will warn you
38
+
39
+ If you end the session with modified files and no doc update, the Stop hook prints a list of what needs attention. Clear the queue with `npx docutrack clear` only after documentation is updated.
@@ -0,0 +1,58 @@
1
+ ---
2
+ description: Create a new Architecture Decision Record (ADR) interactively
3
+ allowed-tools: Read, Write, Bash
4
+ ---
5
+
6
+ Guide the user through creating a new Architecture Decision Record.
7
+
8
+ **Step 1 — Find the next ADR number**
9
+ List files in `docs/decisions/`. Find the highest `ADR-NNN` number and increment by 1. If none exist, start at 001.
10
+
11
+ **Step 2 — Ask for the decision title**
12
+ Say: "What is the title of this architectural decision? (e.g., 'Use PostgreSQL for primary storage')"
13
+
14
+ Wait for the user's response.
15
+
16
+ **Step 3 — Ask for context**
17
+ Say: "What problem or situation made this decision necessary?"
18
+
19
+ Wait for the user's response.
20
+
21
+ **Step 4 — Ask for the decision**
22
+ Say: "What was decided? Be specific."
23
+
24
+ Wait for the user's response.
25
+
26
+ **Step 5 — Ask for consequences**
27
+ Say: "What are the trade-offs, implications, or things to watch for as a result of this decision?"
28
+
29
+ Wait for the user's response.
30
+
31
+ **Step 6 — Create the ADR file**
32
+
33
+ Create the file at `docs/decisions/ADR-<NNN>-<slug>.md` where:
34
+ - `<NNN>` is zero-padded to 3 digits (e.g., 001, 012, 123)
35
+ - `<slug>` is the title lowercased with spaces replaced by hyphens, max 40 chars
36
+
37
+ File content:
38
+ ```markdown
39
+ # ADR-<NNN>: <Title>
40
+
41
+ **Status**: Accepted
42
+ **Date**: <today's date as YYYY-MM-DD>
43
+
44
+ ## Context
45
+
46
+ <User's context answer>
47
+
48
+ ## Decision
49
+
50
+ <User's decision answer>
51
+
52
+ ## Consequences
53
+
54
+ <User's consequences answer>
55
+ ```
56
+
57
+ After creating the file, say:
58
+ "Created `docs/decisions/ADR-<NNN>-<slug>.md`. The ADR is now part of your living documentation and will appear in DocuTrack's Decisions section."
@@ -0,0 +1,59 @@
1
+ ---
2
+ description: Audit documentation coverage and surface stale, missing, or low-quality docs
3
+ allowed-tools: Read, Bash
4
+ ---
5
+
6
+ Run a documentation coverage audit. Follow these steps:
7
+
8
+ **Step 1 — Collect source files**
9
+ Run: `find src -name "*.js" -o -name "*.ts" -o -name "*.py" -o -name "*.go" 2>/dev/null | grep -v node_modules | grep -v ".test." | grep -v ".spec." | head -100`
10
+
11
+ If `src/` doesn't exist, try `lib/`, `app/`, or `pkg/`.
12
+
13
+ **Step 2 — Collect documented modules**
14
+ List all `.md` files in `docs/modules/`.
15
+
16
+ **Step 3 — Read the queue**
17
+ Read `.docutrack/queue.json` to see files waiting for documentation.
18
+
19
+ **Step 4 — Read module docs**
20
+ For each doc in `docs/modules/`, check:
21
+ - Does it have a non-empty **Responsibility** line?
22
+ - Does it have a **Public API** section with at least one entry?
23
+ - Does it have a **Dependencies** section?
24
+
25
+ Flag any doc that is missing these sections as "incomplete".
26
+
27
+ **Step 5 — Output the report**
28
+
29
+ ```
30
+ DocuTrack Coverage Report
31
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
32
+ Score: <N>% (<documented>/<total> source files)
33
+
34
+ ✓ DOCUMENTED (<N>)
35
+ <module>.md ── <responsibility in one sentence>
36
+
37
+ ✗ MISSING DOCS (<N>)
38
+ <file path> ── no documentation found
39
+
40
+ ⚠ INCOMPLETE DOCS (<N>)
41
+ <module>.md ── missing: <what's missing>
42
+
43
+ ⏱ PENDING IN QUEUE (<N>)
44
+ <file path> ── added <relative time>
45
+
46
+ RECOMMENDATIONS
47
+ 1. <highest priority action>
48
+ 2. <second priority action>
49
+ 3. <third priority action>
50
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
51
+ ```
52
+
53
+ Rules for scoring:
54
+ - Score = (documented source files) / (total source files) × 100
55
+ - A source file is "documented" if a `docs/modules/<name>.md` exists for it (matching by basename without extension)
56
+ - Round to nearest integer
57
+ - Score ≥ 80: ✓ healthy | 50–79: ⚠ needs work | < 50: ✗ critical
58
+
59
+ After the report, ask: "Want me to write the missing documentation now?"
@@ -0,0 +1,26 @@
1
+ ---
2
+ name: ask-docs
3
+ description: Ask a question about this codebase using the accumulated documentation.
4
+ ---
5
+
6
+ Answer the question: $ARGUMENTS
7
+
8
+ To answer, read and synthesize the following documentation sources:
9
+
10
+ 1. `ARCHITECTURE.md` — system overview, module map, integrations, env variables
11
+ 2. `docs/modules/` — all module docs (responsibility, public API, dependencies, data shapes)
12
+ 3. `docs/api/openapi.json` — API spec (endpoints, parameters, request/response shapes)
13
+ 4. `docs/decisions/` — ADRs explaining why things are the way they are
14
+ 5. `.docutrack/queue.json` — pending files (what's being actively worked on)
15
+
16
+ **How to answer:**
17
+ - Be direct and specific — reference exact module names, function names, and file paths
18
+ - If the answer spans multiple modules, explain the interaction clearly
19
+ - If documentation doesn't cover the question, say what IS documented and suggest where to look in the source
20
+ - For API questions, quote the exact endpoint path and method
21
+ - For architecture questions, reference the ADR if one exists
22
+
23
+ **Format:**
24
+ - Lead with a one-sentence direct answer
25
+ - Follow with supporting detail from the docs
26
+ - End with the most relevant file path(s) to read next if the user wants more depth
@@ -0,0 +1,50 @@
1
+ ---
2
+ description: Render a live map of the system — modules, API surface, integrations, and doc coverage
3
+ allowed-tools: Read, Bash
4
+ ---
5
+
6
+ Read the following files (skip gracefully if any don't exist):
7
+ 1. `ARCHITECTURE.md`
8
+ 2. All `.md` files in `docs/modules/`
9
+ 3. `docs/api/openapi.json`
10
+ 4. `.docutrack/queue.json`
11
+
12
+ Then output a formatted system map in this exact structure:
13
+
14
+ ```
15
+ ╔══════════════════════════════════════════════════════╗
16
+ ║ System Map — <project name> ║
17
+ ╚══════════════════════════════════════════════════════╝
18
+
19
+ OVERVIEW
20
+ <one-sentence system description from ARCHITECTURE.md>
21
+
22
+ MODULES (<N> documented)
23
+ ├── <module> — <responsibility>
24
+ ├── <module> — <responsibility>
25
+ └── <module> — <responsibility>
26
+
27
+ API SURFACE (<N> endpoints)
28
+ GET /path/one [tag]
29
+ POST /path/two [tag]
30
+ ...
31
+
32
+ INTEGRATIONS
33
+ <service> — <purpose>
34
+ ...
35
+
36
+ COVERAGE
37
+ Documented : <N> modules
38
+ Pending : <N> files need documentation
39
+ Score : <N>% [▓▓▓▓▓▓░░░░]
40
+
41
+ PENDING DOCUMENTATION
42
+ - <file> (added <timestamp>)
43
+ ```
44
+
45
+ Rules:
46
+ - Keep module names short — use the file basename without extension
47
+ - Show at most 20 API endpoints; if more exist, show the first 20 and append ` ... and N more`
48
+ - For the coverage bar, use ▓ for covered and ░ for uncovered (10 chars total)
49
+ - If a section has no data (no modules, no API, etc.), write ` (none yet)` under it
50
+ - Do not include markdown formatting — output plain text only
File without changes
File without changes
File without changes
@@ -0,0 +1,13 @@
1
+ {
2
+ "template": "express",
3
+ "minCoverage": 80,
4
+ "ignore": [
5
+ "**/*.test.js",
6
+ "**/*.spec.js",
7
+ "**/*.test.ts",
8
+ "**/*.spec.ts",
9
+ "src/migrations",
10
+ "src/seeds",
11
+ "src/__generated__"
12
+ ]
13
+ }
@@ -0,0 +1,42 @@
1
+ name: Deploy DocuTrack Docs
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ paths:
7
+ - 'docs/**'
8
+ - 'ARCHITECTURE.md'
9
+
10
+ permissions:
11
+ contents: read
12
+ pages: write
13
+ id-token: write
14
+
15
+ concurrency:
16
+ group: pages
17
+ cancel-in-progress: true
18
+
19
+ jobs:
20
+ deploy:
21
+ runs-on: ubuntu-latest
22
+ environment:
23
+ name: github-pages
24
+ url: ${{ steps.deploy.outputs.page_url }}
25
+ steps:
26
+ - uses: actions/checkout@v4
27
+
28
+ - uses: actions/setup-node@v4
29
+ with:
30
+ node-version: 20
31
+
32
+ - name: Build docs site
33
+ run: npx docutrack build --out ./dist
34
+
35
+ - uses: actions/configure-pages@v4
36
+
37
+ - uses: actions/upload-pages-artifact@v3
38
+ with:
39
+ path: ./dist
40
+
41
+ - id: deploy
42
+ uses: actions/deploy-pages@v4
@@ -0,0 +1,31 @@
1
+ name: DocuTrack Coverage Gate
2
+
3
+ on:
4
+ pull_request:
5
+ types: [opened, synchronize, reopened]
6
+
7
+ jobs:
8
+ coverage-gate:
9
+ runs-on: ubuntu-latest
10
+ steps:
11
+ - uses: actions/checkout@v4
12
+
13
+ - uses: actions/setup-node@v4
14
+ with:
15
+ node-version: 20
16
+
17
+ - name: Check documentation coverage
18
+ run: |
19
+ STATUS=$(npx docutrack status --json 2>/dev/null || echo '{"coverage":0}')
20
+ COVERAGE=$(echo $STATUS | node -e 'process.stdin.on("data",d=>process.stdout.write(""+JSON.parse(d).coverage))')
21
+ MIN=$(node -e "try{const c=require('./docutrack.config.json');process.stdout.write(''+c.minCoverage)}catch{process.stdout.write('80')}")
22
+
23
+ echo "Coverage: ${COVERAGE}% (minimum: ${MIN}%)"
24
+
25
+ if [ "$COVERAGE" -lt "$MIN" ]; then
26
+ echo "::error::Documentation coverage ${COVERAGE}% is below the minimum ${MIN}%."
27
+ echo "::error::Run /arch-review in your Claude Code session to generate missing docs."
28
+ exit 1
29
+ fi
30
+
31
+ echo "::notice::Documentation coverage ${COVERAGE}% meets the minimum ${MIN}%."
@@ -0,0 +1,93 @@
1
+ name: DocuTrack PR Check
2
+
3
+ on:
4
+ pull_request:
5
+ types: [opened, synchronize, reopened]
6
+
7
+ permissions:
8
+ contents: read
9
+ pull-requests: write
10
+
11
+ jobs:
12
+ doc-check:
13
+ runs-on: ubuntu-latest
14
+ steps:
15
+ - uses: actions/checkout@v4
16
+ with:
17
+ fetch-depth: 0
18
+
19
+ - uses: actions/setup-node@v4
20
+ with:
21
+ node-version: 20
22
+
23
+ - name: Get doc coverage
24
+ id: coverage
25
+ run: |
26
+ STATUS=$(npx docutrack status --json 2>/dev/null || echo '{"coverage":0,"pending":0,"staleCount":0,"docCount":0}')
27
+ echo "json=$STATUS" >> $GITHUB_OUTPUT
28
+ echo "coverage=$(echo $STATUS | node -e 'process.stdin.on("data",d=>process.stdout.write(JSON.parse(d).coverage+"%"))')" >> $GITHUB_OUTPUT
29
+
30
+ - name: Get changed doc files
31
+ id: changed
32
+ run: |
33
+ CHANGED=$(git diff --name-only origin/${{ github.base_ref }}...HEAD -- 'docs/**' 'ARCHITECTURE.md' | head -20)
34
+ echo "files<<EOF" >> $GITHUB_OUTPUT
35
+ echo "$CHANGED" >> $GITHUB_OUTPUT
36
+ echo "EOF" >> $GITHUB_OUTPUT
37
+
38
+ - name: Post PR comment
39
+ uses: actions/github-script@v7
40
+ with:
41
+ script: |
42
+ const status = JSON.parse('${{ steps.coverage.outputs.json }}')
43
+ const changedFiles = `${{ steps.changed.outputs.files }}`.trim()
44
+ const files = changedFiles ? changedFiles.split('\n').filter(Boolean) : []
45
+
46
+ const scoreEmoji = status.coverage >= 80 ? '✅' : status.coverage >= 50 ? '⚠️' : '❌'
47
+ const docLines = files.length
48
+ ? files.map(f => ` - \`${f}\``).join('\n')
49
+ : ' _No documentation changes in this PR_'
50
+
51
+ const body = [
52
+ '## 📋 DocuTrack Documentation Report',
53
+ '',
54
+ `| Metric | Value |`,
55
+ `|--------|-------|`,
56
+ `| Coverage | ${scoreEmoji} **${status.coverage}%** |`,
57
+ `| Doc files | ${status.docCount} |`,
58
+ `| Pending (undocumented) | ${status.pending} |`,
59
+ `| Stale docs | ${status.staleCount} |`,
60
+ '',
61
+ '### Documentation changes in this PR',
62
+ docLines,
63
+ '',
64
+ status.pending > 0
65
+ ? `> ⚠️ **${status.pending} file(s) were modified without documentation updates.** Consider running \`/arch-review\` to address them.`
66
+ : '> ✅ All modified files have documentation.',
67
+ '',
68
+ '<sub>Generated by [DocuTrack](https://github.com/your-org/docutrack)</sub>',
69
+ ].join('\n')
70
+
71
+ // Update existing comment if present, otherwise create new one
72
+ const { data: comments } = await github.rest.issues.listComments({
73
+ owner: context.repo.owner,
74
+ repo: context.repo.repo,
75
+ issue_number: context.issue.number,
76
+ })
77
+ const existing = comments.find(c => c.body.includes('DocuTrack Documentation Report'))
78
+
79
+ if (existing) {
80
+ await github.rest.issues.updateComment({
81
+ owner: context.repo.owner,
82
+ repo: context.repo.repo,
83
+ comment_id: existing.id,
84
+ body,
85
+ })
86
+ } else {
87
+ await github.rest.issues.createComment({
88
+ owner: context.repo.owner,
89
+ repo: context.repo.repo,
90
+ issue_number: context.issue.number,
91
+ body,
92
+ })
93
+ }
@@ -0,0 +1,39 @@
1
+ 'use strict'
2
+
3
+ // Stop hook — fires when the Claude Code session ends
4
+ // Warns if there are files modified without documentation updates
5
+
6
+ const fs = require('fs')
7
+ const path = require('path')
8
+
9
+ const QUEUE_PATH = path.join('.docutrack', 'queue.json')
10
+
11
+ if (!fs.existsSync(QUEUE_PATH)) process.exit(0)
12
+
13
+ let queue
14
+ try {
15
+ queue = JSON.parse(fs.readFileSync(QUEUE_PATH, 'utf8'))
16
+ } catch {
17
+ process.exit(0)
18
+ }
19
+
20
+ if (!queue.pending || queue.pending.length === 0) process.exit(0)
21
+
22
+ const count = queue.pending.length
23
+ const files = queue.pending.map(e => ` - ${e.file}`).join('\n')
24
+
25
+ console.log(`
26
+ ╔════════════════════════════════════════════════════╗
27
+ ║ DocuTrack: ${String(count).padEnd(3)} file(s) need documentation ║
28
+ ╚════════════════════════════════════════════════════╝
29
+
30
+ ${files}
31
+
32
+ To update the docs, tell the agent:
33
+ "Update the documentation for the files in .docutrack/queue.json"
34
+
35
+ To clear the queue manually:
36
+ npx docutrack clear
37
+ `)
38
+
39
+ process.exit(0)
@@ -0,0 +1,52 @@
1
+ 'use strict'
2
+
3
+ // PostToolUse hook — fires after every Write, Edit, or MultiEdit
4
+ // Adds the modified file to .docutrack/queue.json
5
+
6
+ const fs = require('fs')
7
+ const path = require('path')
8
+
9
+ let raw = ''
10
+ process.stdin.setEncoding('utf8')
11
+ process.stdin.on('data', chunk => { raw += chunk })
12
+ process.stdin.on('end', () => {
13
+ try {
14
+ const event = JSON.parse(raw)
15
+ const filePath = extractFilePath(event)
16
+ if (filePath) addToQueue(filePath)
17
+ } catch {
18
+ // Never crash the agent session over a hook error
19
+ }
20
+ process.exit(0)
21
+ })
22
+
23
+ function extractFilePath(event) {
24
+ const { tool_name, tool_input } = event
25
+ if (!tool_input) return null
26
+
27
+ if (tool_name === 'Write' || tool_name === 'Edit' || tool_name === 'MultiEdit') {
28
+ return tool_input.file_path || null
29
+ }
30
+ return null
31
+ }
32
+
33
+ function addToQueue(filePath) {
34
+ const normalized = filePath.replace(/\\/g, '/')
35
+ const ignored = [
36
+ 'docs/', '.docutrack/', '.claude/', 'node_modules/', '.git/',
37
+ ]
38
+ if (ignored.some(p => normalized.startsWith(p))) return
39
+
40
+ const queuePath = path.join('.docutrack', 'queue.json')
41
+ if (!fs.existsSync(path.dirname(queuePath))) return // not initialized
42
+
43
+ let queue = { pending: [], lastClear: null }
44
+ try {
45
+ queue = JSON.parse(fs.readFileSync(queuePath, 'utf8'))
46
+ } catch { /* start fresh */ }
47
+
48
+ if (queue.pending.some(e => e.file === normalized)) return
49
+
50
+ queue.pending.push({ file: normalized, addedAt: new Date().toISOString() })
51
+ fs.writeFileSync(queuePath, JSON.stringify(queue, null, 2))
52
+ }