dctracker 1.2.1__tar.gz → 1.4.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 (164) hide show
  1. {dctracker-1.2.1/dctracker.egg-info → dctracker-1.4.0}/PKG-INFO +17 -12
  2. {dctracker-1.2.1 → dctracker-1.4.0}/README.md +14 -9
  3. dctracker-1.4.0/dct/__init__.py +6 -0
  4. {dctracker-1.2.1 → dctracker-1.4.0}/dct/cli.py +322 -22
  5. {dctracker-1.2.1 → dctracker-1.4.0}/dct/core/analytics.py +13 -8
  6. {dctracker-1.2.1 → dctracker-1.4.0}/dct/core/changelog.py +4 -4
  7. {dctracker-1.2.1 → dctracker-1.4.0}/dct/core/checkpoints.py +101 -7
  8. {dctracker-1.2.1 → dctracker-1.4.0}/dct/core/decisions.py +41 -4
  9. {dctracker-1.2.1 → dctracker-1.4.0}/dct/core/engine.py +1 -1
  10. {dctracker-1.2.1 → dctracker-1.4.0}/dct/core/handoff.py +89 -33
  11. {dctracker-1.2.1 → dctracker-1.4.0}/dct/core/items.py +92 -44
  12. {dctracker-1.2.1 → dctracker-1.4.0}/dct/core/plans/crud.py +11 -11
  13. {dctracker-1.2.1 → dctracker-1.4.0}/dct/core/plans/parser.py +0 -1
  14. {dctracker-1.2.1 → dctracker-1.4.0}/dct/core/projects.py +7 -7
  15. {dctracker-1.2.1 → dctracker-1.4.0}/dct/core/provenance.py +4 -1
  16. dctracker-1.4.0/dct/core/sprint.py +508 -0
  17. {dctracker-1.2.1 → dctracker-1.4.0}/dct/core/sprints.py +371 -154
  18. {dctracker-1.2.1 → dctracker-1.4.0}/dct/db.py +57 -7
  19. {dctracker-1.2.1 → dctracker-1.4.0}/dct/export.py +2 -2
  20. {dctracker-1.2.1 → dctracker-1.4.0}/dct/integrations/claude.py +7 -5
  21. {dctracker-1.2.1 → dctracker-1.4.0}/dct/mcp/__init__.py +1 -1
  22. {dctracker-1.2.1 → dctracker-1.4.0}/dct/mcp/server.py +406 -140
  23. {dctracker-1.2.1 → dctracker-1.4.0}/dct/migrate.py +9 -7
  24. {dctracker-1.2.1 → dctracker-1.4.0}/dct/server.py +1 -1
  25. dctracker-1.4.0/dct/services/__init__.py +7 -0
  26. {dctracker-1.2.1 → dctracker-1.4.0}/dct/setup.py +1 -1
  27. dctracker-1.4.0/dct/skills/handoff/SKILL.md +188 -0
  28. dctracker-1.4.0/dct/skills/pickup/SKILL.md +147 -0
  29. {dctracker-1.2.1 → dctracker-1.4.0}/dct/skills/track-update/SKILL.md +6 -3
  30. {dctracker-1.2.1 → dctracker-1.4.0}/dct/update.py +1 -1
  31. {dctracker-1.2.1 → dctracker-1.4.0}/dct/web/app.py +1 -1
  32. {dctracker-1.2.1 → dctracker-1.4.0}/dct/web/blueprints/changelog.py +2 -2
  33. {dctracker-1.2.1 → dctracker-1.4.0}/dct/web/blueprints/decisions.py +2 -2
  34. {dctracker-1.2.1 → dctracker-1.4.0}/dct/web/blueprints/events.py +1 -1
  35. {dctracker-1.2.1 → dctracker-1.4.0}/dct/web/blueprints/handoffs.py +2 -2
  36. {dctracker-1.2.1 → dctracker-1.4.0}/dct/web/blueprints/items.py +5 -6
  37. {dctracker-1.2.1 → dctracker-1.4.0}/dct/web/blueprints/plans.py +3 -3
  38. {dctracker-1.2.1 → dctracker-1.4.0}/dct/web/blueprints/sprints.py +16 -6
  39. dctracker-1.4.0/dct/workflows/__init__.py +7 -0
  40. dctracker-1.4.0/dct/workflows/session.py +596 -0
  41. {dctracker-1.2.1 → dctracker-1.4.0/dctracker.egg-info}/PKG-INFO +17 -12
  42. {dctracker-1.2.1 → dctracker-1.4.0}/dctracker.egg-info/SOURCES.txt +8 -1
  43. {dctracker-1.2.1 → dctracker-1.4.0}/dctracker.egg-info/requires.txt +2 -2
  44. {dctracker-1.2.1 → dctracker-1.4.0}/pyproject.toml +14 -3
  45. {dctracker-1.2.1 → dctracker-1.4.0}/tests/test_adversarial.py +16 -5
  46. {dctracker-1.2.1 → dctracker-1.4.0}/tests/test_analytics.py +41 -34
  47. {dctracker-1.2.1 → dctracker-1.4.0}/tests/test_changelog.py +5 -1
  48. dctracker-1.4.0/tests/test_check_numbers.py +219 -0
  49. {dctracker-1.2.1 → dctracker-1.4.0}/tests/test_checkpoints.py +9 -4
  50. {dctracker-1.2.1 → dctracker-1.4.0}/tests/test_cli_sprints.py +1 -16
  51. {dctracker-1.2.1 → dctracker-1.4.0}/tests/test_cli_web.py +0 -1
  52. dctracker-1.4.0/tests/test_cli_workflows.py +616 -0
  53. {dctracker-1.2.1 → dctracker-1.4.0}/tests/test_config.py +1 -1
  54. {dctracker-1.2.1 → dctracker-1.4.0}/tests/test_engine.py +26 -1
  55. {dctracker-1.2.1 → dctracker-1.4.0}/tests/test_handoff.py +7 -3
  56. {dctracker-1.2.1 → dctracker-1.4.0}/tests/test_ids.py +1 -1
  57. {dctracker-1.2.1 → dctracker-1.4.0}/tests/test_items.py +8 -2
  58. {dctracker-1.2.1 → dctracker-1.4.0}/tests/test_migrate.py +1 -1
  59. {dctracker-1.2.1 → dctracker-1.4.0}/tests/test_migration.py +165 -13
  60. {dctracker-1.2.1 → dctracker-1.4.0}/tests/test_plan_ingest.py +5 -2
  61. {dctracker-1.2.1 → dctracker-1.4.0}/tests/test_plan_parser.py +0 -1
  62. {dctracker-1.2.1 → dctracker-1.4.0}/tests/test_projects.py +9 -3
  63. {dctracker-1.2.1 → dctracker-1.4.0}/tests/test_server_acks.py +5 -15
  64. {dctracker-1.2.1 → dctracker-1.4.0}/tests/test_server_alwaysload.py +28 -11
  65. {dctracker-1.2.1 → dctracker-1.4.0}/tests/test_server_handoff_view.py +30 -19
  66. dctracker-1.4.0/tests/test_server_protocol.py +99 -0
  67. dctracker-1.4.0/tests/test_server_wire.py +99 -0
  68. dctracker-1.4.0/tests/test_server_workflow_ops.py +527 -0
  69. dctracker-1.4.0/tests/test_sprint.py +310 -0
  70. {dctracker-1.2.1 → dctracker-1.4.0}/tests/test_sprints_crud.py +139 -35
  71. {dctracker-1.2.1 → dctracker-1.4.0}/tests/test_update.py +2 -4
  72. {dctracker-1.2.1 → dctracker-1.4.0}/tests/test_version.py +2 -3
  73. {dctracker-1.2.1 → dctracker-1.4.0}/tests/test_web_analytics.py +2 -2
  74. {dctracker-1.2.1 → dctracker-1.4.0}/tests/test_web_app.py +3 -1
  75. {dctracker-1.2.1 → dctracker-1.4.0}/tests/test_web_items.py +1 -1
  76. {dctracker-1.2.1 → dctracker-1.4.0}/tests/test_web_structural.py +5 -5
  77. {dctracker-1.2.1 → dctracker-1.4.0}/tests/test_windows_support.py +1 -3
  78. dctracker-1.4.0/tests/test_workflows.py +1287 -0
  79. dctracker-1.2.1/dct/__init__.py +0 -6
  80. dctracker-1.2.1/dct/core/sprint.py +0 -315
  81. dctracker-1.2.1/dct/services/__init__.py +0 -5
  82. dctracker-1.2.1/dct/skills/handoff/SKILL.md +0 -129
  83. dctracker-1.2.1/dct/skills/pickup/SKILL.md +0 -110
  84. dctracker-1.2.1/dct/workflows/__init__.py +0 -3
  85. dctracker-1.2.1/tests/test_sprint.py +0 -154
  86. {dctracker-1.2.1 → dctracker-1.4.0}/LICENSE +0 -0
  87. {dctracker-1.2.1 → dctracker-1.4.0}/MANIFEST.in +0 -0
  88. {dctracker-1.2.1 → dctracker-1.4.0}/dct/assets/__init__.py +0 -0
  89. {dctracker-1.2.1 → dctracker-1.4.0}/dct/config.py +0 -0
  90. {dctracker-1.2.1 → dctracker-1.4.0}/dct/core/__init__.py +0 -0
  91. {dctracker-1.2.1 → dctracker-1.4.0}/dct/core/ids.py +0 -0
  92. {dctracker-1.2.1 → dctracker-1.4.0}/dct/core/plans/__init__.py +0 -0
  93. {dctracker-1.2.1 → dctracker-1.4.0}/dct/core/plans/classify.py +0 -0
  94. {dctracker-1.2.1 → dctracker-1.4.0}/dct/core/plans/ingest.py +0 -0
  95. {dctracker-1.2.1 → dctracker-1.4.0}/dct/core/version.py +0 -0
  96. {dctracker-1.2.1 → dctracker-1.4.0}/dct/hooks/check-changelog-on-stop.sh +0 -0
  97. {dctracker-1.2.1 → dctracker-1.4.0}/dct/hooks/check-changelog.sh +0 -0
  98. {dctracker-1.2.1 → dctracker-1.4.0}/dct/hooks/dct-plan-autoscan.sh +0 -0
  99. {dctracker-1.2.1 → dctracker-1.4.0}/dct/hooks/dct-task-mirror.sh +0 -0
  100. {dctracker-1.2.1 → dctracker-1.4.0}/dct/integrations/__init__.py +0 -0
  101. {dctracker-1.2.1 → dctracker-1.4.0}/dct/paths.py +0 -0
  102. {dctracker-1.2.1 → dctracker-1.4.0}/dct/skills/clog/SKILL.md +0 -0
  103. {dctracker-1.2.1 → dctracker-1.4.0}/dct/skills/commit/SKILL.md +0 -0
  104. {dctracker-1.2.1 → dctracker-1.4.0}/dct/skills/dct-import/SKILL.md +0 -0
  105. {dctracker-1.2.1 → dctracker-1.4.0}/dct/skills/dct-init/SKILL.md +0 -0
  106. {dctracker-1.2.1 → dctracker-1.4.0}/dct/skills/plan-resolve-uncertain/SKILL.md +0 -0
  107. {dctracker-1.2.1 → dctracker-1.4.0}/dct/skills/plan-status/SKILL.md +0 -0
  108. {dctracker-1.2.1 → dctracker-1.4.0}/dct/skills/release/SKILL.md +0 -0
  109. {dctracker-1.2.1 → dctracker-1.4.0}/dct/skills/track/SKILL.md +0 -0
  110. {dctracker-1.2.1 → dctracker-1.4.0}/dct/skills/track-list/SKILL.md +0 -0
  111. {dctracker-1.2.1 → dctracker-1.4.0}/dct/skills/track-resolve/SKILL.md +0 -0
  112. {dctracker-1.2.1 → dctracker-1.4.0}/dct/web/__init__.py +0 -0
  113. {dctracker-1.2.1 → dctracker-1.4.0}/dct/web/blueprints/__init__.py +0 -0
  114. {dctracker-1.2.1 → dctracker-1.4.0}/dct/web/blueprints/analytics.py +0 -0
  115. {dctracker-1.2.1 → dctracker-1.4.0}/dct/web/blueprints/home.py +0 -0
  116. {dctracker-1.2.1 → dctracker-1.4.0}/dct/web/blueprints/projects.py +0 -0
  117. {dctracker-1.2.1 → dctracker-1.4.0}/dct/web/changes.py +9 -9
  118. {dctracker-1.2.1 → dctracker-1.4.0}/dct/web/serializers.py +0 -0
  119. {dctracker-1.2.1 → dctracker-1.4.0}/dct/web/static/app.css +0 -0
  120. {dctracker-1.2.1 → dctracker-1.4.0}/dct/web/static/app.js +0 -0
  121. {dctracker-1.2.1 → dctracker-1.4.0}/dct/web/static/vendor/SOURCES.txt +0 -0
  122. {dctracker-1.2.1 → dctracker-1.4.0}/dct/web/static/vendor/htmx.min.js +0 -0
  123. {dctracker-1.2.1 → dctracker-1.4.0}/dct/web/static/vendor/uPlot.iife.min.js +0 -0
  124. {dctracker-1.2.1 → dctracker-1.4.0}/dct/web/static/vendor/uPlot.min.css +0 -0
  125. {dctracker-1.2.1 → dctracker-1.4.0}/dct/web/templates/analytics.html +0 -0
  126. {dctracker-1.2.1 → dctracker-1.4.0}/dct/web/templates/base.html +0 -0
  127. {dctracker-1.2.1 → dctracker-1.4.0}/dct/web/templates/changelog/list.html +0 -0
  128. {dctracker-1.2.1 → dctracker-1.4.0}/dct/web/templates/decisions/list.html +0 -0
  129. {dctracker-1.2.1 → dctracker-1.4.0}/dct/web/templates/handoffs/list.html +0 -0
  130. {dctracker-1.2.1 → dctracker-1.4.0}/dct/web/templates/home.html +0 -0
  131. {dctracker-1.2.1 → dctracker-1.4.0}/dct/web/templates/item_detail.html +0 -0
  132. {dctracker-1.2.1 → dctracker-1.4.0}/dct/web/templates/items_list.html +0 -0
  133. {dctracker-1.2.1 → dctracker-1.4.0}/dct/web/templates/partials/_bars.html +0 -0
  134. {dctracker-1.2.1 → dctracker-1.4.0}/dct/web/templates/partials/_checkpoint_steps.html +0 -0
  135. {dctracker-1.2.1 → dctracker-1.4.0}/dct/web/templates/partials/_items_table.html +0 -0
  136. {dctracker-1.2.1 → dctracker-1.4.0}/dct/web/templates/partials/_plan_section.html +0 -0
  137. {dctracker-1.2.1 → dctracker-1.4.0}/dct/web/templates/partials/_project_card.html +0 -0
  138. {dctracker-1.2.1 → dctracker-1.4.0}/dct/web/templates/plans/detail.html +0 -0
  139. {dctracker-1.2.1 → dctracker-1.4.0}/dct/web/templates/plans/list.html +0 -0
  140. {dctracker-1.2.1 → dctracker-1.4.0}/dct/web/templates/project_home.html +0 -0
  141. {dctracker-1.2.1 → dctracker-1.4.0}/dct/web/templates/sprints/detail.html +0 -0
  142. {dctracker-1.2.1 → dctracker-1.4.0}/dct/web/templates/sprints/list.html +0 -0
  143. {dctracker-1.2.1 → dctracker-1.4.0}/dctracker.egg-info/dependency_links.txt +0 -0
  144. {dctracker-1.2.1 → dctracker-1.4.0}/dctracker.egg-info/entry_points.txt +0 -0
  145. {dctracker-1.2.1 → dctracker-1.4.0}/dctracker.egg-info/top_level.txt +0 -0
  146. {dctracker-1.2.1 → dctracker-1.4.0}/setup.cfg +0 -0
  147. {dctracker-1.2.1 → dctracker-1.4.0}/tests/test_changes.py +1 -1
  148. {dctracker-1.2.1 → dctracker-1.4.0}/tests/test_cli_prompts.py +0 -0
  149. {dctracker-1.2.1 → dctracker-1.4.0}/tests/test_decisions_crud.py +0 -0
  150. {dctracker-1.2.1 → dctracker-1.4.0}/tests/test_export.py +1 -1
  151. {dctracker-1.2.1 → dctracker-1.4.0}/tests/test_hook_bypass.py +0 -0
  152. {dctracker-1.2.1 → dctracker-1.4.0}/tests/test_hook_changelog_stop.py +0 -0
  153. {dctracker-1.2.1 → dctracker-1.4.0}/tests/test_hook_plan_autoscan.py +2 -2
  154. {dctracker-1.2.1 → dctracker-1.4.0}/tests/test_hook_task_mirror.py +0 -0
  155. {dctracker-1.2.1 → dctracker-1.4.0}/tests/test_ingest_dogfood.py +0 -0
  156. {dctracker-1.2.1 → dctracker-1.4.0}/tests/test_packaging.py +0 -0
  157. {dctracker-1.2.1 → dctracker-1.4.0}/tests/test_paths.py +0 -0
  158. {dctracker-1.2.1 → dctracker-1.4.0}/tests/test_plan_classify.py +0 -0
  159. {dctracker-1.2.1 → dctracker-1.4.0}/tests/test_plans_crud.py +0 -0
  160. {dctracker-1.2.1 → dctracker-1.4.0}/tests/test_provenance.py +1 -1
  161. {dctracker-1.2.1 → dctracker-1.4.0}/tests/test_restructure.py +0 -0
  162. {dctracker-1.2.1 → dctracker-1.4.0}/tests/test_setup.py +0 -0
  163. {dctracker-1.2.1 → dctracker-1.4.0}/tests/test_setup_wiring.py +0 -0
  164. {dctracker-1.2.1 → dctracker-1.4.0}/tests/test_web_views.py +1 -1
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dctracker
3
- Version: 1.2.1
3
+ Version: 1.4.0
4
4
  Summary: Deterministic Context Tracker (dct) — cross-project tracking, changelog, and release tooling for Claude Code.
5
5
  Author-email: fotodeveloper <dev@fotodeveloper.com>
6
6
  License-Expression: MIT
@@ -25,7 +25,7 @@ Requires-Dist: platformdirs>=4.9.6; sys_platform == "win32"
25
25
  Provides-Extra: pg
26
26
  Requires-Dist: psycopg[binary]; extra == "pg"
27
27
  Provides-Extra: mcp
28
- Requires-Dist: mcp[cli]; extra == "mcp"
28
+ Requires-Dist: mcp<3,>=2; extra == "mcp"
29
29
  Provides-Extra: web
30
30
  Requires-Dist: flask>=3.0; extra == "web"
31
31
  Requires-Dist: markdown>=3.5; extra == "web"
@@ -34,7 +34,7 @@ Requires-Dist: pytest; extra == "dev"
34
34
  Requires-Dist: pytest-cov; extra == "dev"
35
35
  Provides-Extra: all
36
36
  Requires-Dist: psycopg[binary]; extra == "all"
37
- Requires-Dist: mcp[cli]; extra == "all"
37
+ Requires-Dist: mcp<3,>=2; extra == "all"
38
38
  Requires-Dist: flask>=3.0; extra == "all"
39
39
  Requires-Dist: markdown>=3.5; extra == "all"
40
40
  Requires-Dist: pytest; extra == "all"
@@ -48,7 +48,7 @@ Dynamic: license-file
48
48
  [![CI](https://github.com/fotodeveloper/dct/actions/workflows/ci.yml/badge.svg)](https://github.com/fotodeveloper/dct/actions/workflows/ci.yml)
49
49
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
50
50
 
51
- 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, 49 MCP tools); the MCP server and CLI work with any MCP-capable assistant.
51
+ 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, 52 MCP tools); the MCP server and CLI work with any MCP-capable assistant.
52
52
 
53
53
  Part of the **dc tools** family ([dctools.dev](https://dctools.dev)) — *deterministic context* for AI-assisted development.
54
54
 
@@ -122,7 +122,7 @@ markdown, and makes the release commit.
122
122
  - **Decision records** — ADRs, sprint amendments, inline plan decisions with multi-anchor linkage
123
123
  - **LLM-assisted classification** — uncertain plan sections auto-resolved via `claude --print` (haiku by default)
124
124
  - **Passive autoscan hook** — PostToolUse hook re-scans plan-like files in background on every edit
125
- - **MCP server** — native Claude Code integration via FastMCP, 49 tools
125
+ - **MCP server** — native Claude Code integration via the official MCP SDK
126
126
  - **CLI** — fast `dct` command for hooks and scripts
127
127
  - **Skills** — Claude Code slash commands (`/track`, `/clog`, `/dct-import`, `/plan-status`, …)
128
128
  - **Soft deletes** — ledger pattern, nothing is ever lost
@@ -134,9 +134,9 @@ Pick one — whichever matches your Python workflow. The distribution is named *
134
134
 
135
135
  ```bash
136
136
  # Option A: uv tool (recommended — isolated, upgradable, editable for dev)
137
- uv tool install dctracker --with 'mcp[cli]' --with 'psycopg[binary]'
137
+ uv tool install dctracker --with 'mcp' --with 'psycopg[binary]'
138
138
  # Or from source (dev):
139
- uv tool install --editable /path/to/dct --with 'mcp[cli]' --with 'psycopg[binary]'
139
+ uv tool install --editable /path/to/dct --with 'mcp' --with 'psycopg[binary]'
140
140
  # Or straight from GitHub, no clone (e.g. to try main before a release):
141
141
  uv tool install 'dctracker[mcp,pg] @ git+https://github.com/fotodeveloper/dct'
142
142
 
@@ -257,7 +257,12 @@ dct sprint create "Payments hardening" --code pay-1 --goal "Close the P1 backlog
257
257
  dct sprint show 3 # Details + linked items
258
258
  dct sprint activate 3 # Shortcuts: activate / complete / defer
259
259
 
260
- # Handoffs (amend an unconsumed handoff in place; creation is /handoff or MCP)
260
+ # Session edges (same composed ops the /pickup and /handoff skills use)
261
+ dct pickup # Snapshot: sprint, handoffs, gates, decisions
262
+ # (read-only — --consume defaults to never)
263
+ dct handoff create --prompt-file - --add-items 22,6 # Sprint change + handoff, one transaction
264
+ # --remove-items cuts scope, --items replaces;
265
+ # omit all three to leave the sprint untouched
261
266
  dct handoff update 12 --prompt "Wire the toggle into settings next"
262
267
 
263
268
  # Config
@@ -267,7 +272,7 @@ dct config path # Show resolved config/data locations
267
272
 
268
273
  ## MCP Tools
269
274
 
270
- dct ships **49 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. Write ops return a minimal ack (id + a few post-state scalars); fetch full context with `get_item(id)` / `get_handoff(id)`. Ten mid-session daily drivers are always resident (`alwaysLoad`); the rest of the catalogue loads on demand via ToolSearch:
275
+ dct ships **52 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. Write ops return a minimal ack (id + a few post-state scalars); fetch full context with `get_item(id)` / `get_handoff(id)`. Thirteen tools are always resident (`alwaysLoad`) — ten mid-session daily drivers plus the three composed workflow ops (`pickup_work`, `handoff_work`, `get_context_snapshot`); the rest of the catalogue loads on demand via ToolSearch:
271
276
 
272
277
  | Tool | Purpose |
273
278
  |---|---|
@@ -282,7 +287,7 @@ dct ships **49 MCP tools**, registered at user scope so they're callable from an
282
287
  | `reject_checkpoint` | Mark a checkpoint rejected (scope change) — ledger-preserving |
283
288
  | `add_changelog` | Add an unreleased changelog entry |
284
289
 
285
- Session-edge tools stay deferred: `get_handoff` (full handoff dict — untruncated prompt + context_summary), `create_handoff`, `set_sprint`, `release_changelog`, and more. Full categorized catalogue of all 49 tools: **[docs/mcp-tools.md](docs/mcp-tools.md)**.
290
+ Session-edge tools stay deferred: `get_handoff` (full handoff dict — untruncated prompt + context_summary), `create_handoff`, `set_sprint`, `release_changelog`, and more. Full categorized catalogue: **[docs/mcp-tools.md](docs/mcp-tools.md)**.
286
291
 
287
292
  ## Plans, Roadmaps & Decisions
288
293
 
@@ -360,12 +365,12 @@ The `DCT_DATABASE_URL` environment variable overrides `[database].url`. For the
360
365
  ## Testing
361
366
 
362
367
  ```bash
363
- .venv/bin/pytest -q # All tests (938)
368
+ .venv/bin/pytest -q # All tests
364
369
  .venv/bin/pytest tests/test_plan_parser.py -v # Parser only
365
370
  .venv/bin/pytest tests/test_plan_ingest.py -v # Ingest + sticky-resolved semantics
366
371
 
367
372
  # MCP server smoke (boot + tool list)
368
- uv run --no-project --with 'mcp[cli]' --with sqlalchemy --with 'psycopg[binary]' \
373
+ uv run --no-project --with 'mcp' --with sqlalchemy --with 'psycopg[binary]' \
369
374
  python -c "import asyncio; from dct.mcp.server import mcp; \
370
375
  print(len(asyncio.run(mcp.list_tools())), 'tools')"
371
376
  ```
@@ -5,7 +5,7 @@
5
5
  [![CI](https://github.com/fotodeveloper/dct/actions/workflows/ci.yml/badge.svg)](https://github.com/fotodeveloper/dct/actions/workflows/ci.yml)
6
6
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
7
7
 
8
- 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, 49 MCP tools); the MCP server and CLI work with any MCP-capable assistant.
8
+ 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, 52 MCP tools); the MCP server and CLI work with any MCP-capable assistant.
9
9
 
10
10
  Part of the **dc tools** family ([dctools.dev](https://dctools.dev)) — *deterministic context* for AI-assisted development.
11
11
 
@@ -79,7 +79,7 @@ markdown, and makes the release commit.
79
79
  - **Decision records** — ADRs, sprint amendments, inline plan decisions with multi-anchor linkage
80
80
  - **LLM-assisted classification** — uncertain plan sections auto-resolved via `claude --print` (haiku by default)
81
81
  - **Passive autoscan hook** — PostToolUse hook re-scans plan-like files in background on every edit
82
- - **MCP server** — native Claude Code integration via FastMCP, 49 tools
82
+ - **MCP server** — native Claude Code integration via the official MCP SDK
83
83
  - **CLI** — fast `dct` command for hooks and scripts
84
84
  - **Skills** — Claude Code slash commands (`/track`, `/clog`, `/dct-import`, `/plan-status`, …)
85
85
  - **Soft deletes** — ledger pattern, nothing is ever lost
@@ -91,9 +91,9 @@ Pick one — whichever matches your Python workflow. The distribution is named *
91
91
 
92
92
  ```bash
93
93
  # Option A: uv tool (recommended — isolated, upgradable, editable for dev)
94
- uv tool install dctracker --with 'mcp[cli]' --with 'psycopg[binary]'
94
+ uv tool install dctracker --with 'mcp' --with 'psycopg[binary]'
95
95
  # Or from source (dev):
96
- uv tool install --editable /path/to/dct --with 'mcp[cli]' --with 'psycopg[binary]'
96
+ uv tool install --editable /path/to/dct --with 'mcp' --with 'psycopg[binary]'
97
97
  # Or straight from GitHub, no clone (e.g. to try main before a release):
98
98
  uv tool install 'dctracker[mcp,pg] @ git+https://github.com/fotodeveloper/dct'
99
99
 
@@ -214,7 +214,12 @@ dct sprint create "Payments hardening" --code pay-1 --goal "Close the P1 backlog
214
214
  dct sprint show 3 # Details + linked items
215
215
  dct sprint activate 3 # Shortcuts: activate / complete / defer
216
216
 
217
- # Handoffs (amend an unconsumed handoff in place; creation is /handoff or MCP)
217
+ # Session edges (same composed ops the /pickup and /handoff skills use)
218
+ dct pickup # Snapshot: sprint, handoffs, gates, decisions
219
+ # (read-only — --consume defaults to never)
220
+ dct handoff create --prompt-file - --add-items 22,6 # Sprint change + handoff, one transaction
221
+ # --remove-items cuts scope, --items replaces;
222
+ # omit all three to leave the sprint untouched
218
223
  dct handoff update 12 --prompt "Wire the toggle into settings next"
219
224
 
220
225
  # Config
@@ -224,7 +229,7 @@ dct config path # Show resolved config/data locations
224
229
 
225
230
  ## MCP Tools
226
231
 
227
- dct ships **49 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. Write ops return a minimal ack (id + a few post-state scalars); fetch full context with `get_item(id)` / `get_handoff(id)`. Ten mid-session daily drivers are always resident (`alwaysLoad`); the rest of the catalogue loads on demand via ToolSearch:
232
+ dct ships **52 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. Write ops return a minimal ack (id + a few post-state scalars); fetch full context with `get_item(id)` / `get_handoff(id)`. Thirteen tools are always resident (`alwaysLoad`) — ten mid-session daily drivers plus the three composed workflow ops (`pickup_work`, `handoff_work`, `get_context_snapshot`); the rest of the catalogue loads on demand via ToolSearch:
228
233
 
229
234
  | Tool | Purpose |
230
235
  |---|---|
@@ -239,7 +244,7 @@ dct ships **49 MCP tools**, registered at user scope so they're callable from an
239
244
  | `reject_checkpoint` | Mark a checkpoint rejected (scope change) — ledger-preserving |
240
245
  | `add_changelog` | Add an unreleased changelog entry |
241
246
 
242
- Session-edge tools stay deferred: `get_handoff` (full handoff dict — untruncated prompt + context_summary), `create_handoff`, `set_sprint`, `release_changelog`, and more. Full categorized catalogue of all 49 tools: **[docs/mcp-tools.md](docs/mcp-tools.md)**.
247
+ Session-edge tools stay deferred: `get_handoff` (full handoff dict — untruncated prompt + context_summary), `create_handoff`, `set_sprint`, `release_changelog`, and more. Full categorized catalogue: **[docs/mcp-tools.md](docs/mcp-tools.md)**.
243
248
 
244
249
  ## Plans, Roadmaps & Decisions
245
250
 
@@ -317,12 +322,12 @@ The `DCT_DATABASE_URL` environment variable overrides `[database].url`. For the
317
322
  ## Testing
318
323
 
319
324
  ```bash
320
- .venv/bin/pytest -q # All tests (938)
325
+ .venv/bin/pytest -q # All tests
321
326
  .venv/bin/pytest tests/test_plan_parser.py -v # Parser only
322
327
  .venv/bin/pytest tests/test_plan_ingest.py -v # Ingest + sticky-resolved semantics
323
328
 
324
329
  # MCP server smoke (boot + tool list)
325
- uv run --no-project --with 'mcp[cli]' --with sqlalchemy --with 'psycopg[binary]' \
330
+ uv run --no-project --with 'mcp' --with sqlalchemy --with 'psycopg[binary]' \
326
331
  python -c "import asyncio; from dct.mcp.server import mcp; \
327
332
  print(len(asyncio.run(mcp.list_tools())), 'tools')"
328
333
  ```
@@ -0,0 +1,6 @@
1
+ from importlib.metadata import PackageNotFoundError, version
2
+
3
+ try:
4
+ __version__ = version("dctracker")
5
+ except PackageNotFoundError:
6
+ __version__ = "1.4.0"