dctracker 1.0.0__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.
Files changed (130) hide show
  1. dctracker-1.0.0/LICENSE +21 -0
  2. dctracker-1.0.0/MANIFEST.in +7 -0
  3. dctracker-1.0.0/PKG-INFO +357 -0
  4. dctracker-1.0.0/README.md +315 -0
  5. dctracker-1.0.0/dct/__init__.py +6 -0
  6. dctracker-1.0.0/dct/cli.py +1659 -0
  7. dctracker-1.0.0/dct/config.py +150 -0
  8. dctracker-1.0.0/dct/core/__init__.py +0 -0
  9. dctracker-1.0.0/dct/core/analytics.py +382 -0
  10. dctracker-1.0.0/dct/core/changelog.py +112 -0
  11. dctracker-1.0.0/dct/core/checkpoints.py +205 -0
  12. dctracker-1.0.0/dct/core/decisions.py +238 -0
  13. dctracker-1.0.0/dct/core/engine.py +32 -0
  14. dctracker-1.0.0/dct/core/handoff.py +151 -0
  15. dctracker-1.0.0/dct/core/ids.py +25 -0
  16. dctracker-1.0.0/dct/core/items.py +382 -0
  17. dctracker-1.0.0/dct/core/plans/__init__.py +6 -0
  18. dctracker-1.0.0/dct/core/plans/classify.py +94 -0
  19. dctracker-1.0.0/dct/core/plans/crud.py +680 -0
  20. dctracker-1.0.0/dct/core/plans/ingest.py +408 -0
  21. dctracker-1.0.0/dct/core/plans/parser.py +312 -0
  22. dctracker-1.0.0/dct/core/projects.py +298 -0
  23. dctracker-1.0.0/dct/core/sprint.py +315 -0
  24. dctracker-1.0.0/dct/core/sprints.py +601 -0
  25. dctracker-1.0.0/dct/core/version.py +116 -0
  26. dctracker-1.0.0/dct/db.py +558 -0
  27. dctracker-1.0.0/dct/export.py +107 -0
  28. dctracker-1.0.0/dct/hooks/check-changelog-on-stop.sh +49 -0
  29. dctracker-1.0.0/dct/hooks/check-changelog.sh +143 -0
  30. dctracker-1.0.0/dct/hooks/dct-plan-autoscan.sh +54 -0
  31. dctracker-1.0.0/dct/hooks/dct-task-mirror.sh +62 -0
  32. dctracker-1.0.0/dct/server.py +1812 -0
  33. dctracker-1.0.0/dct/setup.py +258 -0
  34. dctracker-1.0.0/dct/skills/clog/SKILL.md +73 -0
  35. dctracker-1.0.0/dct/skills/commit/SKILL.md +153 -0
  36. dctracker-1.0.0/dct/skills/dct-import/SKILL.md +329 -0
  37. dctracker-1.0.0/dct/skills/dct-init/SKILL.md +289 -0
  38. dctracker-1.0.0/dct/skills/handoff/SKILL.md +136 -0
  39. dctracker-1.0.0/dct/skills/pickup/SKILL.md +115 -0
  40. dctracker-1.0.0/dct/skills/plan-resolve-uncertain/SKILL.md +82 -0
  41. dctracker-1.0.0/dct/skills/plan-status/SKILL.md +79 -0
  42. dctracker-1.0.0/dct/skills/release/SKILL.md +281 -0
  43. dctracker-1.0.0/dct/skills/track/SKILL.md +121 -0
  44. dctracker-1.0.0/dct/skills/track-list/SKILL.md +134 -0
  45. dctracker-1.0.0/dct/skills/track-resolve/SKILL.md +53 -0
  46. dctracker-1.0.0/dct/skills/track-update/SKILL.md +109 -0
  47. dctracker-1.0.0/dct/web/__init__.py +1 -0
  48. dctracker-1.0.0/dct/web/app.py +83 -0
  49. dctracker-1.0.0/dct/web/blueprints/__init__.py +5 -0
  50. dctracker-1.0.0/dct/web/blueprints/analytics.py +34 -0
  51. dctracker-1.0.0/dct/web/blueprints/changelog.py +40 -0
  52. dctracker-1.0.0/dct/web/blueprints/decisions.py +23 -0
  53. dctracker-1.0.0/dct/web/blueprints/events.py +69 -0
  54. dctracker-1.0.0/dct/web/blueprints/handoffs.py +26 -0
  55. dctracker-1.0.0/dct/web/blueprints/home.py +15 -0
  56. dctracker-1.0.0/dct/web/blueprints/items.py +128 -0
  57. dctracker-1.0.0/dct/web/blueprints/plans.py +53 -0
  58. dctracker-1.0.0/dct/web/blueprints/projects.py +23 -0
  59. dctracker-1.0.0/dct/web/blueprints/sprints.py +71 -0
  60. dctracker-1.0.0/dct/web/changes.py +77 -0
  61. dctracker-1.0.0/dct/web/serializers.py +109 -0
  62. dctracker-1.0.0/dct/web/static/app.css +609 -0
  63. dctracker-1.0.0/dct/web/static/app.js +62 -0
  64. dctracker-1.0.0/dct/web/static/vendor/SOURCES.txt +10 -0
  65. dctracker-1.0.0/dct/web/static/vendor/htmx.min.js +1 -0
  66. dctracker-1.0.0/dct/web/static/vendor/uPlot.iife.min.js +2 -0
  67. dctracker-1.0.0/dct/web/static/vendor/uPlot.min.css +1 -0
  68. dctracker-1.0.0/dct/web/templates/analytics.html +63 -0
  69. dctracker-1.0.0/dct/web/templates/base.html +106 -0
  70. dctracker-1.0.0/dct/web/templates/changelog/list.html +23 -0
  71. dctracker-1.0.0/dct/web/templates/decisions/list.html +22 -0
  72. dctracker-1.0.0/dct/web/templates/handoffs/list.html +45 -0
  73. dctracker-1.0.0/dct/web/templates/home.html +20 -0
  74. dctracker-1.0.0/dct/web/templates/item_detail.html +91 -0
  75. dctracker-1.0.0/dct/web/templates/items_list.html +44 -0
  76. dctracker-1.0.0/dct/web/templates/partials/_bars.html +15 -0
  77. dctracker-1.0.0/dct/web/templates/partials/_checkpoint_steps.html +22 -0
  78. dctracker-1.0.0/dct/web/templates/partials/_items_table.html +23 -0
  79. dctracker-1.0.0/dct/web/templates/partials/_plan_section.html +24 -0
  80. dctracker-1.0.0/dct/web/templates/partials/_project_card.html +24 -0
  81. dctracker-1.0.0/dct/web/templates/plans/detail.html +16 -0
  82. dctracker-1.0.0/dct/web/templates/plans/list.html +15 -0
  83. dctracker-1.0.0/dct/web/templates/project_home.html +51 -0
  84. dctracker-1.0.0/dct/web/templates/sprints/detail.html +37 -0
  85. dctracker-1.0.0/dct/web/templates/sprints/list.html +35 -0
  86. dctracker-1.0.0/dctracker.egg-info/PKG-INFO +357 -0
  87. dctracker-1.0.0/dctracker.egg-info/SOURCES.txt +128 -0
  88. dctracker-1.0.0/dctracker.egg-info/dependency_links.txt +1 -0
  89. dctracker-1.0.0/dctracker.egg-info/entry_points.txt +2 -0
  90. dctracker-1.0.0/dctracker.egg-info/requires.txt +24 -0
  91. dctracker-1.0.0/dctracker.egg-info/top_level.txt +1 -0
  92. dctracker-1.0.0/pyproject.toml +64 -0
  93. dctracker-1.0.0/setup.cfg +4 -0
  94. dctracker-1.0.0/tests/test_adversarial.py +437 -0
  95. dctracker-1.0.0/tests/test_analytics.py +357 -0
  96. dctracker-1.0.0/tests/test_changelog.py +102 -0
  97. dctracker-1.0.0/tests/test_changes.py +70 -0
  98. dctracker-1.0.0/tests/test_checkpoints.py +388 -0
  99. dctracker-1.0.0/tests/test_cli_prompts.py +53 -0
  100. dctracker-1.0.0/tests/test_cli_sprints.py +158 -0
  101. dctracker-1.0.0/tests/test_cli_web.py +103 -0
  102. dctracker-1.0.0/tests/test_config.py +55 -0
  103. dctracker-1.0.0/tests/test_decisions_crud.py +167 -0
  104. dctracker-1.0.0/tests/test_engine.py +49 -0
  105. dctracker-1.0.0/tests/test_export.py +157 -0
  106. dctracker-1.0.0/tests/test_handoff.py +159 -0
  107. dctracker-1.0.0/tests/test_hook_bypass.py +109 -0
  108. dctracker-1.0.0/tests/test_hook_plan_autoscan.py +103 -0
  109. dctracker-1.0.0/tests/test_hook_task_mirror.py +101 -0
  110. dctracker-1.0.0/tests/test_ids.py +68 -0
  111. dctracker-1.0.0/tests/test_ingest_dogfood.py +89 -0
  112. dctracker-1.0.0/tests/test_items.py +189 -0
  113. dctracker-1.0.0/tests/test_migration.py +366 -0
  114. dctracker-1.0.0/tests/test_packaging.py +91 -0
  115. dctracker-1.0.0/tests/test_plan_classify.py +166 -0
  116. dctracker-1.0.0/tests/test_plan_ingest.py +375 -0
  117. dctracker-1.0.0/tests/test_plan_parser.py +379 -0
  118. dctracker-1.0.0/tests/test_plans_crud.py +405 -0
  119. dctracker-1.0.0/tests/test_projects.py +380 -0
  120. dctracker-1.0.0/tests/test_server_alwaysload.py +47 -0
  121. dctracker-1.0.0/tests/test_setup.py +46 -0
  122. dctracker-1.0.0/tests/test_setup_wiring.py +242 -0
  123. dctracker-1.0.0/tests/test_sprint.py +154 -0
  124. dctracker-1.0.0/tests/test_sprints_crud.py +687 -0
  125. dctracker-1.0.0/tests/test_version.py +148 -0
  126. dctracker-1.0.0/tests/test_web_analytics.py +73 -0
  127. dctracker-1.0.0/tests/test_web_app.py +204 -0
  128. dctracker-1.0.0/tests/test_web_items.py +142 -0
  129. dctracker-1.0.0/tests/test_web_structural.py +125 -0
  130. dctracker-1.0.0/tests/test_web_views.py +52 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 fotodeveloper
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,7 @@
1
+ # Sdist contents — CI publishes via `python -m build` (sdist → wheel), so every
2
+ # packaged asset must be grafted here as well as declared in package-data.
3
+ graft dct/skills
4
+ graft dct/hooks
5
+ graft dct/web/templates
6
+ graft dct/web/static
7
+ global-exclude *.py[cod] .DS_Store
@@ -0,0 +1,357 @@
1
+ Metadata-Version: 2.4
2
+ Name: dctracker
3
+ Version: 1.0.0
4
+ Summary: Deterministic Context Tracker (dct) — cross-project tracking, changelog, and release tooling for Claude Code.
5
+ Author-email: fotodeveloper <dev@fotodeveloper.com>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://dctools.dev
8
+ Project-URL: Repository, https://github.com/fotodeveloper/dct
9
+ Project-URL: Changelog, https://github.com/fotodeveloper/dct/blob/main/changelog.md
10
+ Keywords: claude-code,mcp,tracking,changelog,sprints,developer-tools,cli
11
+ Classifier: Development Status :: 5 - Production/Stable
12
+ Classifier: Environment :: Console
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Classifier: Topic :: Software Development
19
+ Requires-Python: >=3.11
20
+ Description-Content-Type: text/markdown
21
+ License-File: LICENSE
22
+ Requires-Dist: sqlalchemy>=2.0
23
+ Requires-Dist: python-ulid>=2.0
24
+ Provides-Extra: pg
25
+ Requires-Dist: psycopg[binary]; extra == "pg"
26
+ Provides-Extra: mcp
27
+ Requires-Dist: mcp[cli]; extra == "mcp"
28
+ Provides-Extra: web
29
+ Requires-Dist: flask>=3.0; extra == "web"
30
+ Requires-Dist: markdown>=3.5; extra == "web"
31
+ Provides-Extra: dev
32
+ Requires-Dist: pytest; extra == "dev"
33
+ Requires-Dist: pytest-cov; extra == "dev"
34
+ Provides-Extra: all
35
+ Requires-Dist: psycopg[binary]; extra == "all"
36
+ Requires-Dist: mcp[cli]; extra == "all"
37
+ Requires-Dist: flask>=3.0; extra == "all"
38
+ Requires-Dist: markdown>=3.5; extra == "all"
39
+ Requires-Dist: pytest; extra == "all"
40
+ Requires-Dist: pytest-cov; extra == "all"
41
+ Dynamic: license-file
42
+
43
+ # dct — Deterministic Context Tracker
44
+
45
+ [![PyPI version](https://img.shields.io/pypi/v/dctracker.svg)](https://pypi.org/project/dctracker/)
46
+ [![Python 3.11+](https://img.shields.io/badge/python-3.11+-blue.svg)](https://www.python.org/downloads/)
47
+ [![CI](https://github.com/fotodeveloper/dct/actions/workflows/ci.yml/badge.svg)](https://github.com/fotodeveloper/dct/actions/workflows/ci.yml)
48
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
49
+
50
+ Persistent, queryable memory for AI coding assistants — your assistant reads facts from a database instead of guessing. One user-scoped database tracks issues, todos, changelog entries, plans, sprints, and decisions across all your projects. Built for [Claude Code](https://claude.com/claude-code) (skills, hooks, 48 MCP tools); the MCP server and CLI work with any MCP-capable assistant.
51
+
52
+ Part of the **dc tools** family ([dctools.dev](https://dctools.dev)) — *deterministic context* for AI-assisted development.
53
+
54
+ ## Why dct?
55
+
56
+ You have a dozen side projects. Every Claude Code session starts cold — the assistant has no memory of what you decided last week, which bug you were mid-fix on, or why you picked SQLite over Postgres. So you re-explain, or it guesses.
57
+
58
+ The usual trackers don't fill the gap. GitHub Issues and Jira are per-repo, heavyweight, and live behind an API your assistant can't casually read or write. `TODO.md` files rot the moment you stop grooming them, and you can't query "every P1 across all my repos" from a pile of markdown.
59
+
60
+ dct is built for exactly this:
61
+
62
+ - **One user-scoped database** across all your projects — one place to ask "what's open everywhere?". Local-first: SQLite by default — nothing leaves your machine — with first-class PostgreSQL support when you want a server-grade backend.
63
+ - **MCP-native** — the assistant reads and writes tracking directly, no copy-paste, no context loss.
64
+ - **Changelog-first releases** — entries accumulate as you work (your assistant writes them); release day is one command, not an afternoon of `git log` archaeology.
65
+ - **Append-only ledger** — notes, checkpoints, and handoffs are soft-deleted, never dropped. Nothing is lost.
66
+ - **Session handoffs** — end a session with a handoff prompt; the next one picks up exactly where you left off.
67
+
68
+ ## The session loop: `/handoff` → `/pickup`
69
+
70
+ The pair you will use most. AI coding sessions end; your context shouldn't.
71
+
72
+ **Ending a session — `/handoff`** flags the items you were working on as the
73
+ current sprint and stores a short prompt for whoever comes next (usually:
74
+ you, tomorrow). **Starting a session — `/pickup`** reads the newest unconsumed
75
+ handoff, shows the sprint with checkpoint progress, and proposes the first
76
+ action — so the session starts *in the middle of the work*, not from a cold
77
+ "what were we doing?". The sprint is the durable *what's-in-flight-right-now*
78
+ set: it survives between sessions and cleans itself up — resolving an item
79
+ drops it from the sprint automatically. Illustrative session start:
80
+
81
+ ```text
82
+ > /pickup
83
+ Handoff (2026-07-05, scope: sprint-15):
84
+ "Theme tokens are merged; wire the toggle into settings next.
85
+ The Safari session fix (#12) still awaits review."
86
+ Sprint: 3 items — #12 in_progress [2/4], #31 open, #7 open
87
+ Proposed first action: #12 — wire the theme toggle into settings.
88
+ ```
89
+
90
+ Handoffs are database rows, not files: several can coexist per project
91
+ (`scope` tags disambiguate parallel workstreams), consuming one preserves it
92
+ in the ledger, and an unconsumed one can be amended in place. Available as
93
+ skills in Claude Code, MCP tools, and the CLI — full catalogue in
94
+ [docs/mcp-tools.md](docs/mcp-tools.md).
95
+
96
+ ## The release loop: `/clog` → `/commit` → `/release`
97
+
98
+ The other daily loop. A changelog reconstructed from `git log` on release
99
+ day is archaeology — dct makes it a side effect of working. Each time a
100
+ change lands, your assistant records a one-line entry in the database (the
101
+ `/clog` skill, `add_changelog` over MCP, `dct clog add` in scripts); an
102
+ opt-in hook can even hold back `git commit` until the entry exists. By
103
+ release day the changelog is already written:
104
+
105
+ ```text
106
+ > /release
107
+ 15 unreleased entries → stamped as 1.1.0
108
+ changelog.md regenerated (Keep a Changelog format)
109
+ release: v1.1.0 committed, project version bumped
110
+ ```
111
+
112
+ One command stamps the version, exports [Keep a Changelog](https://keepachangelog.com)
113
+ markdown, and makes the release commit.
114
+
115
+ ## Features
116
+
117
+ - **Centralized tracking** — one database for all your projects
118
+ - **Hybrid changelog** — entries in DB, export to Keep a Changelog markdown at release; **opt-in enforcement** + **per-project changelog location** (repo root by default, or a subdir like `pkg/changelog.md`)
119
+ - **Plans, specs, roadmaps, ADRs** — index markdown plans with stable ULID anchors; state in DB, content stays in markdown
120
+ - **First-class sprints** — a named, goal-scoped *current work* set that survives across sessions and self-cleans as items resolve
121
+ - **Decision records** — ADRs, sprint amendments, inline plan decisions with multi-anchor linkage
122
+ - **LLM-assisted classification** — uncertain plan sections auto-resolved via `claude --print` (haiku by default)
123
+ - **Passive autoscan hook** — PostToolUse hook re-scans plan-like files in background on every edit
124
+ - **MCP server** — native Claude Code integration via FastMCP, 48 tools
125
+ - **CLI** — fast `dct` command for hooks and scripts
126
+ - **Skills** — Claude Code slash commands (`/track`, `/clog`, `/dct-import`, `/plan-status`, …)
127
+ - **Soft deletes** — ledger pattern, nothing is ever lost
128
+ - **DB portable** — SQLite (zero setup) or PostgreSQL
129
+
130
+ ## Installation
131
+
132
+ Pick one — whichever matches your Python workflow. The distribution is named **`dctracker`** (PyPI); the installed command is **`dct`**.
133
+
134
+ ```bash
135
+ # Option A: uv tool (recommended — isolated, upgradable, editable for dev)
136
+ uv tool install dctracker --with 'mcp[cli]' --with 'psycopg[binary]'
137
+ # Or from source (dev):
138
+ uv tool install --editable /path/to/dct --with 'mcp[cli]' --with 'psycopg[binary]'
139
+ # Or straight from GitHub, no clone (e.g. to try main before a release):
140
+ uv tool install 'dctracker[mcp,pg] @ git+https://github.com/fotodeveloper/dct'
141
+
142
+ # Option B: pipx (classic isolated install)
143
+ pipx install 'dctracker[mcp,pg]'
144
+
145
+ # Option C: uvx (zero-install, fetches per-invocation)
146
+ # In ~/.claude.json: { "command": "uvx", "args": ["--from", "dctracker[mcp,pg]", "dct", "server"] }
147
+
148
+ # Option D: pip into your venv (not recommended for global CLI)
149
+ pip install 'dctracker[mcp,pg]'
150
+ ```
151
+
152
+ After installation `dct` must be in PATH. Verify:
153
+
154
+ ```bash
155
+ dct --version # -> dct <version>
156
+ dct server --help
157
+ dct plan --help # plan subcommands
158
+ ```
159
+
160
+ ### First run
161
+
162
+ ```bash
163
+ dct init
164
+ ```
165
+
166
+ The interactive wizard walks through the one-time global bootstrap:
167
+
168
+ 1. **Database backend** — `sqlite` (default, zero setup at `~/.claude/dct.db`) or `postgresql` (you supply the URL). It test-connects before saving.
169
+ 2. **Register projects** — for each project it asks slug / path / name, then **auto-detects the version** from `VERSION`, `pyproject.toml`, `package.json`, `Cargo.toml`, or `src-tauri/tauri.conf.json`. If none matches, you get an interactive prompt (`0.0.1` / `0.1.0` / `1.0.0` shortcuts); in non-tty contexts it stores `current_version=NULL` and reminds you to set it later. Register more any time with `dct project add`.
170
+ 3. **MCP server** — registered at **user scope** in `~/.claude.json` (via `claude mcp add --scope user`, with a direct-edit fallback), so `/track`, `/clog`, `/release`, and the MCP tools are available in **every** Claude Code session, from any directory.
171
+ 4. **Skills + hooks** — symlinks the skills into `~/.claude/skills/` and the four hooks into `~/.claude/hooks/`. Both ship inside the package; with an editable/dev install the symlinks point at the repo, so a fix goes live without reinstall.
172
+ 5. **Hook wiring** — with your consent, merges the hooks into `~/.claude/settings.json`. The merge is idempotent, backs up the file before the first write, and never touches hooks you already have. Re-run any time with `dct hooks wire`.
173
+
174
+ `dct init` writes `~/.claude/dct.toml`, `~/.claude.json` (MCP entry), the skill/hook symlinks, and (opt-in) the settings.json wiring — see [docs/architecture.md](docs/architecture.md) for the full config reference and scope model.
175
+
176
+ ### Your first session
177
+
178
+ With `dct init` done, open any registered project in Claude Code and just talk:
179
+
180
+ ```text
181
+ > track this: parser crashes on empty frontmatter
182
+ Created issue #12 in myproj (P2, open)
183
+
184
+ > I fixed the frontmatter crash
185
+ Changelog entry added (unreleased) — issue #12 resolved
186
+
187
+ > /handoff
188
+ Sprint set (1 item); handoff prompt stored for the next session
189
+ ```
190
+
191
+ Tomorrow, `/pickup` resumes mid-work — that's the [session loop](#the-session-loop-handoff--pickup)
192
+ from the top of this page. When you're ready to ship, `/release` stamps the
193
+ accumulated changelog with a version. No forms, no context switch — tracking
194
+ happens in the conversation you're already having.
195
+
196
+ ### Troubleshooting
197
+
198
+ - **`dct: command not found` after install** — the install location isn't on your `PATH`. For `uv tool` / `pipx`, run their `ensurepath` helper (`uv tool update-shell` or `pipx ensurepath`) and restart the shell.
199
+ - **PostgreSQL connection fails at `dct init`** — either start your local Postgres and re-run, or just pick the **SQLite** default (the answer to the backend prompt) — it needs no server and works everywhere.
200
+ - **MCP tools don't show up in Claude Code** — the MCP server is a per-session subprocess, so newly registered tools (or a reinstall) appear only after you **restart the Claude Code session**. Start a fresh session and they'll be there.
201
+ - **Plans/decisions tools fail with `No module named 'ulid'`** — your installed tool environment predates the `python-ulid` dependency. Upgrade it: `uv tool upgrade dctracker` (or reinstall via your chosen option above).
202
+
203
+ ## Usage
204
+
205
+ ### CLI
206
+
207
+ ```bash
208
+ # Items
209
+ dct add myproj todo "Fix parser crash" --priority P1 --tags "parser,crash"
210
+ dct list # All open items, all projects
211
+ dct list myproj --priority P1 # P1 items in myproj
212
+ dct show 42 # Full item details with notes
213
+ dct update 42 --status in_progress
214
+ dct note 42 "Found root cause in tokenizer"
215
+ dct resolve 42 --resolution "Fixed in commit abc123"
216
+
217
+ # Changelog (project auto-detected from CWD; --project overrides)
218
+ dct clog add added "New Python parser support" --project myproj
219
+ dct clog list --project myproj --unreleased
220
+ dct clog count --project myproj # Used by hooks
221
+ dct clog release 1.1 --project myproj # Stamp unreleased → 1.1
222
+ dct clog export --project myproj --output changelog.md
223
+
224
+ # Projects
225
+ dct project add myproj /path/to/myproj --name "My Project" # Version auto-detected
226
+ dct project list
227
+ dct project detect # Print current project slug (for hooks)
228
+ dct project rename myproj --slug myproj2 --name "Rebranded" # Rename in-place, project_id stable
229
+ dct project set-version myproj 1.1 # Post-factum version fix
230
+ dct project changelog myproj off # Opt out of dct changelog enforcement
231
+ dct project changelog-path myproj docs/changelog.md # Changelog outside repo root; default: changelog.md
232
+
233
+ # Plans
234
+ dct plan rescan /path/to/docs/plans/2026-04-17-feature.md # Idempotent rescan; hook entrypoint
235
+ dct plan rescan $FILE --quiet --resolve-uncertain # Hook-mode flags
236
+
237
+ # Checkpoints (item-level)
238
+ dct checkpoint add 42 "Write parser"
239
+ dct checkpoint list 42
240
+ dct checkpoint done 3 # Mark CP #3 as done
241
+ dct checkpoint reject 4 # Scope-change, keep in ledger
242
+ ```
243
+
244
+ ## MCP Tools
245
+
246
+ dct ships **48 MCP tools**, registered at user scope so they're callable from any Claude Code session as `mcp__dct__<name>`. Zero-arg calls auto-detect the project from the session's working directory; pass `project=<slug>` to override. The daily drivers:
247
+
248
+ | Tool | Purpose |
249
+ |---|---|
250
+ | `create_item` | Create a tracked item (issue / todo / feature / idea / improvement) |
251
+ | `list_items` | List / search items in compact `{cols, rows}` form |
252
+ | `update_item` | Update fields on an existing item |
253
+ | `resolve_item` | Close an item (terminal status), with gate-checkpoint guard |
254
+ | `add_checkpoint` | Add an acceptance criterion to an item |
255
+ | `complete_checkpoint` | Mark a checkpoint done (real-time, never batched) |
256
+ | `add_changelog` | Add an unreleased changelog entry |
257
+ | `release_changelog` | Stamp unreleased entries with a version + bump `current_version` |
258
+ | `set_sprint` | Atomically replace the current sprint's membership |
259
+ | `create_handoff` | Leave a handoff draft for the next session |
260
+
261
+ Full categorized catalogue of all 48 tools: **[docs/mcp-tools.md](docs/mcp-tools.md)**.
262
+
263
+ ## Plans, Roadmaps & Decisions
264
+
265
+ dct extends the flat items model with **hierarchical plans**: markdown plan/spec/roadmap/ADR files stay the source of truth for content, while dct indexes their structure (sections, checkpoints, decisions) with stable **ULID anchors** and owns their state (done/pending/rejected). A PostToolUse hook rescans plan-like files in the background on every edit, injecting ULIDs and syncing the DB; uncertain section headings are classified by a headless `claude --print` call (haiku).
266
+
267
+ Full guide — concepts, ULID anchors, ingest pipeline, classification rules, and promotion to items/sprints: **[docs/plans.md](docs/plans.md)**.
268
+
269
+ ## Web viewer
270
+
271
+ `dct web` runs a localhost-only, **read-only** browser dashboard over all registered projects (items, sprints, plans, changelog, decisions, handoffs, plus Radar / Backlog-Health / Velocity analytics) with live SSE refresh. It binds `127.0.0.1` only — no auth, single-user. Install the optional extra first:
272
+
273
+ ```bash
274
+ uv tool install 'dctracker[web,mcp,pg]' # or: pipx install 'dctracker[web]' — adds flask + markdown
275
+ dct web start # start the daemon → prints http://localhost:8787
276
+ dct web start --open # open the browser after starting
277
+ dct web status # show pid + URL
278
+ dct web stop # SIGTERM the daemon
279
+ ```
280
+
281
+ If the preferred port (default `8787`) is busy, the daemon auto-selects the next free port (disable with `--no-fallback`). Configure defaults under `[web]` in `~/.claude/dct.toml`.
282
+
283
+ ![dct web viewer — read-only dashboard over all registered projects](docs/assets/web-viewer.png)
284
+
285
+ ## Integration with Claude Code
286
+
287
+ dct is designed to be driven by Claude Code. To teach your assistant *when* to reach for each skill and MCP tool across every project, copy the ready-made snippet into your personal `~/.claude/CLAUDE.md`: **[docs/CLAUDE.md-snippet.md](docs/CLAUDE.md-snippet.md)**.
288
+
289
+ ### Skills
290
+
291
+ | Skill | Purpose |
292
+ |---|---|
293
+ | `/track` | Create a tracked item |
294
+ | `/track-list` | List/search items |
295
+ | `/track-update` | Update item fields |
296
+ | `/track-resolve` | Resolve/close items |
297
+ | `/clog` | Add changelog entry |
298
+ | `/commit` | Conventional commit with version suffix + changelog gate |
299
+ | `/release` | Stamp changelog + bump version + generate `changelog.md` |
300
+ | `/pickup` | Session start — read handoff, show sprint, propose first action |
301
+ | `/handoff` | Session end — flag sprint items, write handoff prompt |
302
+ | `/dct-import` | Discover + multi-select + ingest plan-like markdown files |
303
+ | `/dct-init` | Bootstrap dct + register the current project (interactive) |
304
+ | `/plan-status` | Cross-plan progress dashboard |
305
+ | `/plan-resolve-uncertain` | Batch classify uncertain plan sections via haiku |
306
+
307
+ ## Global Hooks
308
+
309
+ `dct init` **symlinks** four hooks into `~/.claude/hooks/` (→ the packaged `dct/hooks/`; an editable/dev install keeps them live-editable from the repo) and — with your consent — **wires them into `~/.claude/settings.json` automatically**. The wiring is an idempotent merge: hooks you already have (dct or your own, in any placement) are never touched, and the file is backed up before the first write. Re-run any time:
310
+
311
+ ```bash
312
+ dct hooks wire # idempotent; safe after upgrades or manual edits
313
+ ```
314
+
315
+ | Hook | Event | Purpose |
316
+ |---|---|---|
317
+ | `dct-check-changelog.sh` | PreToolUse (`Bash`) | blocks `git commit` when app code changed but no unreleased changelog entry exists — opt-in per project via `dct project changelog <slug> on\|off` |
318
+ | `dct-check-changelog-on-stop.sh` | Stop | session-end reminder about pending unreleased entries (same opt-in gate) |
319
+ | `dct-plan-autoscan.sh` | PostToolUse (`Edit\|Write\|MultiEdit`) | background rescan of plan-like MD files; fire-and-forget |
320
+ | `dct-task-mirror.sh` | PreToolUse (`TodoWrite\|TaskCreate`) | mirrors Claude Code tasks into dct as `cc-task` checkpoints |
321
+
322
+ Manual wiring reference (full JSON) and the five rules every dct hook follows: [docs/hooks.md](docs/hooks.md).
323
+
324
+ ## Configuration
325
+
326
+ dct reads `~/.claude/dct.toml`. The minimal config is just the database URL:
327
+
328
+ ```toml
329
+ [database]
330
+ url = "sqlite:////Users/you/.claude/dct.db"
331
+ # or: url = "postgresql+psycopg://localhost:5432/dct"
332
+ ```
333
+
334
+ The `DCT_DATABASE_URL` environment variable overrides `[database].url`. For the full reference (`[plans]`, `[mirror]`, `[web]` sections), the database schema, MCP scope precedence, and project auto-detection mechanics, see **[docs/architecture.md](docs/architecture.md)**.
335
+
336
+ ## Testing
337
+
338
+ ```bash
339
+ .venv/bin/pytest -q # All tests (670)
340
+ .venv/bin/pytest tests/test_plan_parser.py -v # Parser only
341
+ .venv/bin/pytest tests/test_plan_ingest.py -v # Ingest + sticky-resolved semantics
342
+
343
+ # MCP server smoke (boot + tool list)
344
+ uv run --no-project --with 'mcp[cli]' --with sqlalchemy --with 'psycopg[binary]' \
345
+ python -c "import asyncio; from dct.server import mcp; \
346
+ print(len(asyncio.run(mcp.list_tools())), 'tools')"
347
+ ```
348
+
349
+ ## Contributing
350
+
351
+ Bug reports, feature ideas, and PRs are welcome — see
352
+ [CONTRIBUTING.md](CONTRIBUTING.md) for dev setup (uv venv + pytest), commit
353
+ conventions, and how to add MCP tools or skills.
354
+
355
+ ## License
356
+
357
+ MIT — see [LICENSE](LICENSE).