dctracker 1.0.0__py3-none-any.whl

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 (87) hide show
  1. dct/__init__.py +6 -0
  2. dct/cli.py +1659 -0
  3. dct/config.py +150 -0
  4. dct/core/__init__.py +0 -0
  5. dct/core/analytics.py +382 -0
  6. dct/core/changelog.py +112 -0
  7. dct/core/checkpoints.py +205 -0
  8. dct/core/decisions.py +238 -0
  9. dct/core/engine.py +32 -0
  10. dct/core/handoff.py +151 -0
  11. dct/core/ids.py +25 -0
  12. dct/core/items.py +382 -0
  13. dct/core/plans/__init__.py +6 -0
  14. dct/core/plans/classify.py +94 -0
  15. dct/core/plans/crud.py +680 -0
  16. dct/core/plans/ingest.py +408 -0
  17. dct/core/plans/parser.py +312 -0
  18. dct/core/projects.py +298 -0
  19. dct/core/sprint.py +315 -0
  20. dct/core/sprints.py +601 -0
  21. dct/core/version.py +116 -0
  22. dct/db.py +558 -0
  23. dct/export.py +107 -0
  24. dct/hooks/check-changelog-on-stop.sh +49 -0
  25. dct/hooks/check-changelog.sh +143 -0
  26. dct/hooks/dct-plan-autoscan.sh +54 -0
  27. dct/hooks/dct-task-mirror.sh +62 -0
  28. dct/server.py +1812 -0
  29. dct/setup.py +258 -0
  30. dct/skills/clog/SKILL.md +73 -0
  31. dct/skills/commit/SKILL.md +153 -0
  32. dct/skills/dct-import/SKILL.md +329 -0
  33. dct/skills/dct-init/SKILL.md +289 -0
  34. dct/skills/handoff/SKILL.md +136 -0
  35. dct/skills/pickup/SKILL.md +115 -0
  36. dct/skills/plan-resolve-uncertain/SKILL.md +82 -0
  37. dct/skills/plan-status/SKILL.md +79 -0
  38. dct/skills/release/SKILL.md +281 -0
  39. dct/skills/track/SKILL.md +121 -0
  40. dct/skills/track-list/SKILL.md +134 -0
  41. dct/skills/track-resolve/SKILL.md +53 -0
  42. dct/skills/track-update/SKILL.md +109 -0
  43. dct/web/__init__.py +1 -0
  44. dct/web/app.py +83 -0
  45. dct/web/blueprints/__init__.py +5 -0
  46. dct/web/blueprints/analytics.py +34 -0
  47. dct/web/blueprints/changelog.py +40 -0
  48. dct/web/blueprints/decisions.py +23 -0
  49. dct/web/blueprints/events.py +69 -0
  50. dct/web/blueprints/handoffs.py +26 -0
  51. dct/web/blueprints/home.py +15 -0
  52. dct/web/blueprints/items.py +128 -0
  53. dct/web/blueprints/plans.py +53 -0
  54. dct/web/blueprints/projects.py +23 -0
  55. dct/web/blueprints/sprints.py +71 -0
  56. dct/web/changes.py +77 -0
  57. dct/web/serializers.py +109 -0
  58. dct/web/static/app.css +609 -0
  59. dct/web/static/app.js +62 -0
  60. dct/web/static/vendor/SOURCES.txt +10 -0
  61. dct/web/static/vendor/htmx.min.js +1 -0
  62. dct/web/static/vendor/uPlot.iife.min.js +2 -0
  63. dct/web/static/vendor/uPlot.min.css +1 -0
  64. dct/web/templates/analytics.html +63 -0
  65. dct/web/templates/base.html +106 -0
  66. dct/web/templates/changelog/list.html +23 -0
  67. dct/web/templates/decisions/list.html +22 -0
  68. dct/web/templates/handoffs/list.html +45 -0
  69. dct/web/templates/home.html +20 -0
  70. dct/web/templates/item_detail.html +91 -0
  71. dct/web/templates/items_list.html +44 -0
  72. dct/web/templates/partials/_bars.html +15 -0
  73. dct/web/templates/partials/_checkpoint_steps.html +22 -0
  74. dct/web/templates/partials/_items_table.html +23 -0
  75. dct/web/templates/partials/_plan_section.html +24 -0
  76. dct/web/templates/partials/_project_card.html +24 -0
  77. dct/web/templates/plans/detail.html +16 -0
  78. dct/web/templates/plans/list.html +15 -0
  79. dct/web/templates/project_home.html +51 -0
  80. dct/web/templates/sprints/detail.html +37 -0
  81. dct/web/templates/sprints/list.html +35 -0
  82. dctracker-1.0.0.dist-info/METADATA +357 -0
  83. dctracker-1.0.0.dist-info/RECORD +87 -0
  84. dctracker-1.0.0.dist-info/WHEEL +5 -0
  85. dctracker-1.0.0.dist-info/entry_points.txt +2 -0
  86. dctracker-1.0.0.dist-info/licenses/LICENSE +21 -0
  87. dctracker-1.0.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,136 @@
1
+ ---
2
+ name: handoff
3
+ description: |
4
+ End-of-session workflow — flag items as next-sprint and leave a handoff prompt
5
+ for the next session.
6
+ Use when: "handoff", "zakończ sesję", "do następnej sesji", "end session",
7
+ "hand off", "zrób handoff", "wrap up".
8
+ ---
9
+
10
+ # /handoff — Session Handoff
11
+
12
+ Finalize a coding session by (a) marking which items belong to the next sprint
13
+ and (b) optionally writing a prompt for the next session to pick up.
14
+
15
+ ## Workflow
16
+
17
+ ### Step 1: Detect project
18
+
19
+ Call `mcp__dct__list_projects` and match against CWD (longest path prefix).
20
+ If CWD is not a registered project, ask user via `AskUserQuestion`:
21
+ - question: "Which project is this handoff for?"
22
+ - options: list of registered project slugs + "Cancel"
23
+
24
+ ### Step 2: Offer scope tag
25
+
26
+ Ask via `AskUserQuestion`:
27
+ - question: "Optional scope tag for this handoff (helps disambiguate when multiple sessions run in parallel)?"
28
+ - options: "No scope", "sprint-v<next>", "refactor-<area>", "Other (type in)"
29
+ - If user picks "Other", follow up with free-text AskUserQuestion.
30
+
31
+ Remember the chosen `scope` (may be empty).
32
+
33
+ ### Step 3: Show current sprint + propose items
34
+
35
+ Call `mcp__dct__review_sprint(project, since="last_release")` to get:
36
+ - current `in_sprint` list (what's already flagged)
37
+ - `recent_activity` — items touched since last release
38
+ - `stale_in_progress` — items blocked or forgotten
39
+
40
+ **Empty project fallback** — if all sections are empty (no items at all in
41
+ the project, or everything is resolved), offer via `AskUserQuestion`:
42
+ - question: "Nothing to propose — project has no open or recent items. What now?"
43
+ - options: `"Skip sprint proposal — just write handoff prompt"` / `"Cancel /handoff"` / `"Run /track-list to browse state first"`.
44
+
45
+ Present a draft sprint proposal based on:
46
+ - All P1 open items (always)
47
+ - Top 3-5 P2 open items with existing checkpoints
48
+ - Any items currently in `recent_activity` that are still open
49
+
50
+ Ask via `AskUserQuestion`:
51
+ - question: "Which items go into the next sprint? (IDs, comma-separated, or 'keep current', or 'empty sprint')"
52
+ - options: the proposed list formatted as "22, 21, 6 (proposed)" | "Keep current sprint" | "Empty sprint" | "Custom list (type in)"
53
+ - On "Custom list" — follow up with free-text ids.
54
+
55
+ ### Step 4: Set sprint
56
+
57
+ Parse chosen ids. Call `mcp__dct__set_sprint(project, item_ids="22,21,6")`
58
+ (or with empty string for empty sprint, or skip this step if "Keep current").
59
+
60
+ ### Step 5: Optionally write handoff prompt
61
+
62
+ Ask via `AskUserQuestion`:
63
+ - question: "Write a prompt for the next session?"
64
+ - options:
65
+ - "Yes — I'll dictate" (user types freely)
66
+ - "Yes — auto-draft from sprint context" (assistant drafts, user confirms)
67
+ - "No"
68
+
69
+ On "Yes — auto-draft":
70
+ - Draft a 2-4 sentence prompt summarizing:
71
+ - What was just accomplished (from resolved items / recent changelog)
72
+ - What's next (first 1-2 sprint items with brief context)
73
+ - Any open design questions worth flagging
74
+ - Present draft, ask `AskUserQuestion` for confirmation:
75
+ - "Save this prompt? [Yes / Edit first / Skip]"
76
+
77
+ On "Yes — I'll dictate": prompt user for free-text input.
78
+
79
+ On "No": skip.
80
+
81
+ ### Step 6: Create handoff entry
82
+
83
+ If prompt was provided, call:
84
+ ```
85
+ mcp__dct__create_handoff(
86
+ project=<slug>,
87
+ prompt=<text>,
88
+ created_by=f"claude-{model_id} @ {project_slug} {isoformat_utc_now()}Z",
89
+ scope=<scope or "">,
90
+ )
91
+ ```
92
+
93
+ Remember the returned `id`.
94
+
95
+ ### Step 6b: CC task-list mirror cleanup (v0.4.0)
96
+
97
+ If the TaskCreate mirror hook (`dct/hooks/dct-task-mirror.sh`) is active, the
98
+ current session may have spawned a session-scoped item with checkpoints
99
+ mirrored from TaskCreate/TodoWrite calls. These items have the tag
100
+ `cc-task-list` and title `"CC task list — session <id>"`.
101
+
102
+ Probe: `mcp__dct__list_items(project=<slug>)` filtered for `tags` containing
103
+ `cc-task-list`. For each such item surface via `AskUserQuestion`:
104
+
105
+ question: f"Session item #{id} has N CC task-list checkpoints. What to do?"
106
+ header: "CC task list"
107
+ options:
108
+ - "Resolve — the todos were one-off, archive it"
109
+ → `resolve_item(id, status="resolved", resolution="session ephemeral, archived on /handoff")`
110
+ - "Promote N checkpoints to real items"
111
+ → for each cc-task checkpoint: `promote_checkpoint_to_item` (or user picks subset)
112
+ - "Keep — I'll revisit next session"
113
+ → leave as-is; next session's /pickup will surface it
114
+ - "Skip"
115
+
116
+ This keeps backlog clean — ephemeral harness-tasks don't accumulate as
117
+ permanent items across months of sessions.
118
+
119
+ ### Step 7: Report
120
+
121
+ ```
122
+ ✓ Handoff #N zapisany
123
+ Sprint: 3 itemy (#22, #21, #6)
124
+ Scope: sprint-v0.2
125
+ Prompt: "Zacznij od #22..." (142 chars)
126
+
127
+ Next session: /pickup
128
+ ```
129
+
130
+ ## Rules
131
+
132
+ - **Every user decision is an `AskUserQuestion` call.** No plain-text prompts.
133
+ - Never call `set_sprint` without user confirming the list.
134
+ - Never write a handoff prompt without user confirming content.
135
+ - `created_by` MUST be non-empty; include model id + project + UTC timestamp.
136
+ - On `set_sprint`, if replacing a non-empty sprint, surface the diff ("removing: #7; adding: #22") in the confirmation question.
@@ -0,0 +1,115 @@
1
+ ---
2
+ name: pickup
3
+ description: |
4
+ Start-of-session workflow — read last session's handoff, show current sprint,
5
+ and propose the first action.
6
+ Use when: "pickup", "gdzie byliśmy", "resume", "where were we", "start session",
7
+ "co robimy", "kontynuuj", "podejmij od",
8
+ "co dalej", "kontynuujmy", "wracam", "jestem z powrotem",
9
+ "dalej", "idziemy dalej", "next up", "what's next", "back to work".
10
+ ---
11
+
12
+ # /pickup — Session Resume
13
+
14
+ Open a new session by loading the previous session's handoff prompt + current
15
+ sprint state, then propose a concrete first action.
16
+
17
+ ## Workflow
18
+
19
+ ### Step 1: Detect project
20
+
21
+ `mcp__dct__list_projects` → match CWD (longest prefix).
22
+ If not registered, ask via `AskUserQuestion`:
23
+ - question: "Which project are we working on?"
24
+ - options: list of slugs + "Cancel"
25
+
26
+ ### Step 2: Fetch review
27
+
28
+ Call `mcp__dct__review_sprint(project, since="last_release")`.
29
+
30
+ Returns:
31
+ - `in_sprint` — currently flagged items
32
+ - `recent_activity` — items changed since anchor
33
+ - `stale_in_progress` — forgotten in-progress items
34
+ - `unconsumed_handoffs` — unread drafts from previous sessions
35
+
36
+ ### Step 3: Handle unconsumed handoffs
37
+
38
+ **If there are 0 handoffs** — skip to Step 4.
39
+
40
+ **If there is exactly 1 handoff**, present its prompt and ask via `AskUserQuestion`:
41
+ - question: "Handoff #N [scope: X] from <created_at> by <created_by>:\n\n<prompt>\n\nPick up this handoff?"
42
+ - options:
43
+ - "Yes — consume and follow it"
44
+ - "Yes — follow it but keep unconsumed (for audit)"
45
+ - "No — start fresh, discard this handoff"
46
+ - "Show other recent handoffs"
47
+
48
+ **If there are multiple**, ask via `AskUserQuestion`:
49
+ - question: "N handoffs waiting. Which to pick up?"
50
+ - options: one per handoff formatted `#N [scope] — <first 80 chars of prompt>` + "None — start fresh"
51
+
52
+ On picked handoff:
53
+ - "Yes — consume" → `mcp__dct__consume_handoff(id, consumed_by=<session_id>)`
54
+ - "keep unconsumed" → use prompt content, don't stamp consumed_at
55
+ - "start fresh" → optionally ask to `delete_handoff(id)` (soft) or just leave
56
+
57
+ ### Step 4: Show sprint
58
+
59
+ Present `in_sprint` as a compact table (use format from `review_sprint.in_sprint`).
60
+ Show summary: sprint_size, sprint_completion, handoffs_pending.
61
+
62
+ If sprint is empty BUT there are open items in the project, ask via `AskUserQuestion`:
63
+ - question: "Sprint is empty (but N items open). What next?"
64
+ - options:
65
+ - "Pick sprint items now — run /handoff style proposal"
66
+ - "Browse open items — /track-list"
67
+ - "Just start working — I'll tell you what"
68
+
69
+ If sprint is empty AND there are NO open items in the project, ask via `AskUserQuestion`:
70
+ - question: "Project is empty — nothing to pick up. What now?"
71
+ - options:
72
+ - "Create the first item — run /track"
73
+ - "Import existing tracking data — run /dct-import"
74
+ - "Exit — not the right project"
75
+
76
+ ### Step 5: Propose first action
77
+
78
+ Combine:
79
+ - Handoff prompt (if consumed) — primary intent
80
+ - First in_sprint item by priority — concrete entry point
81
+ - Any stale_in_progress — optional "unstick first" path
82
+
83
+ Present via `AskUserQuestion`:
84
+ - question: "First action for this session?"
85
+ - options:
86
+ - "Open #<first-sprint-item> and start on its checkpoints"
87
+ - "Review all sprint items first"
88
+ - "Look at stale in_progress first (#X)"
89
+ - "Something else — tell me what"
90
+
91
+ ### Step 6: Report and open context
92
+
93
+ Based on user choice, run the matching action:
94
+ - "Open #X" → `mcp__dct__get_item(X)` + show checkpoints as next-step plan
95
+ - "Review all" → full sprint listing
96
+ - "Stale first" → `mcp__dct__get_item(<stale>)`
97
+ - "Something else" → wait for user input
98
+
99
+ Report:
100
+ ```
101
+ ✓ Picked up handoff #N
102
+ Sprint: 3 items, 0/3 done
103
+ Starting: #22 — "Optimize MCP response format"
104
+ Plan: 4 pending checkpoints in this item
105
+ ```
106
+
107
+ ## Rules
108
+
109
+ - **Every decision is an `AskUserQuestion`.** No plain-text Y/N prompts.
110
+ - Don't auto-consume handoffs — user must approve (consume vs keep vs discard).
111
+ - On empty sprint + no handoffs, don't force-create a sprint — ask user what to do.
112
+ - Show resolved items from `review_sprint.recent_activity` only as context, not as
113
+ work candidates (they're done).
114
+ - `consumed_by` should mirror `/handoff`'s `created_by` format:
115
+ `claude-<model_id> @ <project_slug> <iso_utc>Z`.
@@ -0,0 +1,82 @@
1
+ ---
2
+ name: plan-resolve-uncertain
3
+ description: |
4
+ Batch-resolve plan sections flagged `section_type='uncertain'` during
5
+ import. Offers LLM classification (via `claude --print`) per section or
6
+ manual override. Use when: "plan-resolve-uncertain", "resolve uncertain",
7
+ "sklasyfikuj niejasne", "check uncertain sections", "fix section types",
8
+ "uncertain sections", "classify plan sections".
9
+ ---
10
+
11
+ # /plan-resolve-uncertain — Classify Uncertain Plan Sections
12
+
13
+ ## When to invoke
14
+
15
+ - After `/dct-import` reported `uncertain_remaining > 0`.
16
+ - `/pickup` surfaces uncertain sections and user accepts the follow-up.
17
+ - User explicitly asks to review / fix uncertain classifications.
18
+
19
+ ## Workflow
20
+
21
+ ### Step 1: Resolve project
22
+
23
+ Auto-detect from CWD. Confirm via `AskUserQuestion` if ambiguous.
24
+
25
+ ### Step 2: List uncertain sections
26
+
27
+ Use `mcp__dct__list_plan_sections(plan_id=X, ...)` with `section_type="uncertain"`
28
+ for each active plan, OR construct a direct query via the CLI
29
+ (`dct plan resolve-uncertain --dry-run` if available).
30
+
31
+ Present a compact table:
32
+ ```
33
+ plan depth heading
34
+ ───────────────── ───── ─────────────────────────────────────
35
+ v0.2-impl 2 Phase 0 — Shared foundations
36
+ v0.2-impl 3 Open questions for v0.2.1
37
+ roadmap 2 Amendments to Spec
38
+ ```
39
+
40
+ ### Step 3: Strategy choice
41
+
42
+ `AskUserQuestion`:
43
+ - "N uncertain sections. How to resolve?"
44
+ - Options:
45
+ - "Auto-classify all via Claude Haiku (≈ $0.001/each)" — default if user is OK with LLM cost
46
+ - "Review one-by-one (manual decision per section)"
47
+ - "Mark all as 'prose' (safe default for narrative sections)"
48
+ - "Skip — leave as uncertain"
49
+
50
+ ### Step 4a: Auto-classify
51
+
52
+ For each section:
53
+ - Call the classifier indirectly via `dct plan rescan <file> --resolve-uncertain`
54
+ OR invoke `classify_uncertain()` equivalent.
55
+ - On result: update via `mcp__dct__add_plan_section` isn't right (section exists);
56
+ use a targeted update path: an MCP helper not yet exposed — fall back to
57
+ manual `dct plan set-section-type <ulid> <type>` CLI if present.
58
+ - Aggregate: how many resolved, how many still uncertain.
59
+
60
+ ### Step 4b: Review one-by-one
61
+
62
+ Per section, `AskUserQuestion`:
63
+ - Question: "Section `<heading>` — what type?"
64
+ - Options: sprint, phase, task, block, milestone, decision, prose, changelog,
65
+ adr_section, reference, generic, (skip).
66
+ - Apply choice.
67
+
68
+ ### Step 4c: Mark all as prose
69
+
70
+ Blanket update — quick escape hatch when user has read through them and
71
+ concluded they are all narrative text.
72
+
73
+ ### Step 5: Report
74
+
75
+ `"Resolved N, remaining M uncertain. Review next session via /plan-status."`
76
+
77
+ ## Rules
78
+
79
+ - Never silently accept LLM output without user approval at the strategy step.
80
+ - Cost-aware — report estimated LLM cost upfront before running batch.
81
+ - Graceful fallback if `claude` CLI missing — fall back to manual mode.
82
+ - Idempotent — re-running the skill on already-resolved sections is a no-op.
@@ -0,0 +1,79 @@
1
+ ---
2
+ name: plan-status
3
+ description: |
4
+ Cross-plan progress dashboard for a project. Shows per-plan done/total
5
+ checkpoint counts, uncertain section count, and last-scanned timestamp.
6
+ Use when: "plan-status", "plan progress", "pokaż plany", "co zostało
7
+ w planach", "ile zrobione w planie X", "status planów", "how much of
8
+ the plan is done", "stan planów".
9
+ ---
10
+
11
+ # /plan-status — Cross-plan Progress Dashboard
12
+
13
+ ## When to invoke
14
+
15
+ - User asks about progress across plans in the current project.
16
+ - Session start / handoff — show high-level plan health alongside sprint review.
17
+ - Before making planning decisions (pick a plan with most pending work, etc.).
18
+
19
+ ## Workflow
20
+
21
+ ### Step 1: Resolve project
22
+
23
+ Auto-detect from CWD via `mcp__dct__list_projects()` + longest-prefix match.
24
+ If not registered, ask via `AskUserQuestion`.
25
+
26
+ ### Step 2: Fetch plans
27
+
28
+ `mcp__dct__list_plans(project=<slug>, status="active")` — returns `{cols, rows}`.
29
+
30
+ ### Step 3: Enrich each plan with progress
31
+
32
+ For each plan row, call `mcp__dct__get_plan(plan_id)` to get the `progress`
33
+ sub-dict and sections needing review.
34
+
35
+ ### Step 4: Render table
36
+
37
+ ```
38
+ # kind status progress uncertain last-scanned title
39
+ ── ────── ────── ──────── ───────── ──────────── ─────────────────────
40
+ 12 plan active 8/10 2 2026-04-17 Plans/roadmaps schema
41
+ 17 spec active 3/3 0 2026-04-15 …
42
+ 23 adr active — 0 2026-04-10 ADR-001: Use ULIDs
43
+ ```
44
+
45
+ `progress` format:
46
+ - Plans with checkpoints: `done/active` (rejected excluded).
47
+ - Plans with only sections and no checkpoints (specs, ADRs): show `—`.
48
+
49
+ `uncertain`: count of `plan_sections.needs_llm_review=TRUE`.
50
+
51
+ ### Step 5: Optional drill-down
52
+
53
+ Ask via `AskUserQuestion`:
54
+ - "Show details for a specific plan?"
55
+ - Options: one per plan (`#12 — Plans/roadmaps schema`), or "Done".
56
+ - On selection: `mcp__dct__get_plan(id)` full dump + structured section tree.
57
+
58
+ ## Rules
59
+
60
+ - Read-only — never modify plans / sections / checkpoints from this skill.
61
+ - Respect `format="structured"` default — pretty-print only at the final
62
+ rendering step, not in the MCP calls themselves.
63
+ - When no plans exist, emit a one-liner (`"No plans registered in <project>"`)
64
+ and stop — do not suggest creating one unprompted.
65
+
66
+ ## Example dialog
67
+
68
+ > User: "/plan-status"
69
+ >
70
+ > Claude:
71
+ > Project: dct (detected from CWD)
72
+ > Plans: 3 active, 0 completed, 0 archived.
73
+ >
74
+ > # kind status progress uncertain last-scanned title
75
+ > ── ───── ────── ──────── ───────── ──────────── ─────
76
+ > 12 plan active 6/10 0 2026-04-17 v0.2.0 implementation
77
+ > ...
78
+ >
79
+ > Any plan to drill into?