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.
- dct/__init__.py +6 -0
- dct/cli.py +1659 -0
- dct/config.py +150 -0
- dct/core/__init__.py +0 -0
- dct/core/analytics.py +382 -0
- dct/core/changelog.py +112 -0
- dct/core/checkpoints.py +205 -0
- dct/core/decisions.py +238 -0
- dct/core/engine.py +32 -0
- dct/core/handoff.py +151 -0
- dct/core/ids.py +25 -0
- dct/core/items.py +382 -0
- dct/core/plans/__init__.py +6 -0
- dct/core/plans/classify.py +94 -0
- dct/core/plans/crud.py +680 -0
- dct/core/plans/ingest.py +408 -0
- dct/core/plans/parser.py +312 -0
- dct/core/projects.py +298 -0
- dct/core/sprint.py +315 -0
- dct/core/sprints.py +601 -0
- dct/core/version.py +116 -0
- dct/db.py +558 -0
- dct/export.py +107 -0
- dct/hooks/check-changelog-on-stop.sh +49 -0
- dct/hooks/check-changelog.sh +143 -0
- dct/hooks/dct-plan-autoscan.sh +54 -0
- dct/hooks/dct-task-mirror.sh +62 -0
- dct/server.py +1812 -0
- dct/setup.py +258 -0
- dct/skills/clog/SKILL.md +73 -0
- dct/skills/commit/SKILL.md +153 -0
- dct/skills/dct-import/SKILL.md +329 -0
- dct/skills/dct-init/SKILL.md +289 -0
- dct/skills/handoff/SKILL.md +136 -0
- dct/skills/pickup/SKILL.md +115 -0
- dct/skills/plan-resolve-uncertain/SKILL.md +82 -0
- dct/skills/plan-status/SKILL.md +79 -0
- dct/skills/release/SKILL.md +281 -0
- dct/skills/track/SKILL.md +121 -0
- dct/skills/track-list/SKILL.md +134 -0
- dct/skills/track-resolve/SKILL.md +53 -0
- dct/skills/track-update/SKILL.md +109 -0
- dct/web/__init__.py +1 -0
- dct/web/app.py +83 -0
- dct/web/blueprints/__init__.py +5 -0
- dct/web/blueprints/analytics.py +34 -0
- dct/web/blueprints/changelog.py +40 -0
- dct/web/blueprints/decisions.py +23 -0
- dct/web/blueprints/events.py +69 -0
- dct/web/blueprints/handoffs.py +26 -0
- dct/web/blueprints/home.py +15 -0
- dct/web/blueprints/items.py +128 -0
- dct/web/blueprints/plans.py +53 -0
- dct/web/blueprints/projects.py +23 -0
- dct/web/blueprints/sprints.py +71 -0
- dct/web/changes.py +77 -0
- dct/web/serializers.py +109 -0
- dct/web/static/app.css +609 -0
- dct/web/static/app.js +62 -0
- dct/web/static/vendor/SOURCES.txt +10 -0
- dct/web/static/vendor/htmx.min.js +1 -0
- dct/web/static/vendor/uPlot.iife.min.js +2 -0
- dct/web/static/vendor/uPlot.min.css +1 -0
- dct/web/templates/analytics.html +63 -0
- dct/web/templates/base.html +106 -0
- dct/web/templates/changelog/list.html +23 -0
- dct/web/templates/decisions/list.html +22 -0
- dct/web/templates/handoffs/list.html +45 -0
- dct/web/templates/home.html +20 -0
- dct/web/templates/item_detail.html +91 -0
- dct/web/templates/items_list.html +44 -0
- dct/web/templates/partials/_bars.html +15 -0
- dct/web/templates/partials/_checkpoint_steps.html +22 -0
- dct/web/templates/partials/_items_table.html +23 -0
- dct/web/templates/partials/_plan_section.html +24 -0
- dct/web/templates/partials/_project_card.html +24 -0
- dct/web/templates/plans/detail.html +16 -0
- dct/web/templates/plans/list.html +15 -0
- dct/web/templates/project_home.html +51 -0
- dct/web/templates/sprints/detail.html +37 -0
- dct/web/templates/sprints/list.html +35 -0
- dctracker-1.0.0.dist-info/METADATA +357 -0
- dctracker-1.0.0.dist-info/RECORD +87 -0
- dctracker-1.0.0.dist-info/WHEEL +5 -0
- dctracker-1.0.0.dist-info/entry_points.txt +2 -0
- dctracker-1.0.0.dist-info/licenses/LICENSE +21 -0
- dctracker-1.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: dct-import
|
|
3
|
+
description: |
|
|
4
|
+
Import existing tracking data from markdown files into dct. Handles checkbox
|
|
5
|
+
TODOs, narrative sprints, custom issue formats (ORCH-N / BUG-N with field
|
|
6
|
+
blocks), plan-as-parent documents (1k+ line planning docs), Keep-a-Changelog
|
|
7
|
+
with or without [Unreleased], and conventional-commit style entries.
|
|
8
|
+
Use when: "dct-import", "importuj", "zaimportuj todos", "migruj dane",
|
|
9
|
+
"import tracking data", "import from markdown", "migrate to dct", "zmigruj",
|
|
10
|
+
"przenieś", "załaduj istniejące todo", "convert roadmap to dct",
|
|
11
|
+
"parse sprint doc", "import issue file".
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# /dct-import — Import Existing Tracking Data
|
|
15
|
+
|
|
16
|
+
## Two import paths (v0.2.0)
|
|
17
|
+
|
|
18
|
+
Markdown files fall into three buckets; each uses a different tool:
|
|
19
|
+
|
|
20
|
+
| Bucket | Files | Tool |
|
|
21
|
+
| ------------ | ----------------------------------------------------------- | ---------------------------------------- |
|
|
22
|
+
| **Plan-like**| plans, specs, ADRs, roadmaps, retros, backlogs | `mcp__dct__ingest_plan_file` (v0.2 pipeline) |
|
|
23
|
+
| **Issue-like**| ORCH-N / BUG-N custom-field files, TODOS with inline status | v0.1 items + checkpoints (see Pattern Catalog below) |
|
|
24
|
+
| **Changelog**| CHANGELOG.md, changelog.md, changelog_unreleased.md | `mcp__dct__add_changelog` |
|
|
25
|
+
|
|
26
|
+
The v0.2 pipeline handles ULID injection, `[x]` historical state, and
|
|
27
|
+
optional LLM classification of uncertain sections in one call — you don't
|
|
28
|
+
re-implement Pattern Catalog logic for plan-like files.
|
|
29
|
+
|
|
30
|
+
## Key principle
|
|
31
|
+
|
|
32
|
+
Claude proposes, user decides via `AskUserQuestion`. Never auto-create
|
|
33
|
+
without confirmation. Ambiguous entries are flagged and asked one-by-one.
|
|
34
|
+
|
|
35
|
+
## Workflow
|
|
36
|
+
|
|
37
|
+
### Step 1: Detect candidate files
|
|
38
|
+
|
|
39
|
+
Scan project root (and common subdirs) for typical tracking files. Apply
|
|
40
|
+
the stale-file skip list FIRST (see below) — do not even offer skipped
|
|
41
|
+
paths to the user.
|
|
42
|
+
|
|
43
|
+
Typical patterns (file name heuristic):
|
|
44
|
+
- **Plan-like** (→ `ingest_plan_file`):
|
|
45
|
+
- `docs/plans/*.md`, `docs/specs/*.md`, `docs/adr/*.md`, `docs/retros/*.md`
|
|
46
|
+
- `ROADMAP.md`, `TODOS.md`, `FUTURE.md`, `BACKLOG.md`
|
|
47
|
+
- `SPRINT*.md`, `PLAN*.md`
|
|
48
|
+
- **Issue-like** (→ v0.1 items path):
|
|
49
|
+
- `ISSUES.md`, `BUGS.md`, `*issues*.md`, `*orchestrator*.md`
|
|
50
|
+
- **Changelog** (→ `add_changelog`):
|
|
51
|
+
- `CHANGELOG.md`, `changelog.md`, `changelog_unreleased.md`
|
|
52
|
+
|
|
53
|
+
### Step 2: Classify each file by format
|
|
54
|
+
|
|
55
|
+
For each candidate, read the first ~60 lines and classify by content.
|
|
56
|
+
The Pattern Catalog below lists 10 known formats. A file may match multiple
|
|
57
|
+
(e.g. a plan with embedded checkboxes) — pick the dominant one, flag as
|
|
58
|
+
composite in Step 4.
|
|
59
|
+
|
|
60
|
+
### Step 3: Parse per-format
|
|
61
|
+
|
|
62
|
+
Apply the mapping rules from the Pattern Catalog. Build a draft table of
|
|
63
|
+
proposed imports BEFORE any DB write.
|
|
64
|
+
|
|
65
|
+
### Step 4: Present review — AskUserQuestion pipeline
|
|
66
|
+
|
|
67
|
+
First `AskUserQuestion`:
|
|
68
|
+
- question: "Found N files. Which to import?"
|
|
69
|
+
- options: one per file formatted `TODOS.md (304 lines) — checkbox TODOs`,
|
|
70
|
+
plus `"All detected files"`, `"Pick subset (I'll list)"`, `"Cancel"`.
|
|
71
|
+
- On subset: follow-up multi-select AskUserQuestion.
|
|
72
|
+
|
|
73
|
+
For each selected file, show the proposed table then `AskUserQuestion`:
|
|
74
|
+
- question: "Proceed with <file>? (N entries, M ambiguous)"
|
|
75
|
+
- options:
|
|
76
|
+
- `"Import all as shown"`
|
|
77
|
+
- `"Resolve ambiguities one-by-one"` — one AskUserQuestion per flagged row
|
|
78
|
+
- `"Edit first"` — free-text AskUserQuestion, parse corrections, re-show
|
|
79
|
+
- `"Skip this file"`
|
|
80
|
+
- `"Cancel import"`
|
|
81
|
+
|
|
82
|
+
### Step 5: Execute
|
|
83
|
+
|
|
84
|
+
**For plan-like files** (v0.2 pipeline):
|
|
85
|
+
- Call `mcp__dct__ingest_plan_file(file_path, project, auto_resolve_uncertain=true)`.
|
|
86
|
+
- The tool handles ULID injection, DB upsert, first-import `[x]` historical
|
|
87
|
+
state, and optional LLM classification in one call.
|
|
88
|
+
- This DOES modify the MD file by injecting `<!-- dct:plan/section/cp:<ULID> -->`
|
|
89
|
+
HTML comments — this is intentional; the anchors are the stable cross-cut
|
|
90
|
+
between file and DB. Original text / ordering / code blocks are preserved.
|
|
91
|
+
|
|
92
|
+
For each confirmed issue-like or changelog entry (legacy v0.1 path):
|
|
93
|
+
1. Items: `mcp__dct__create_item(...)` — **REMEMBER the returned `id`** per entry.
|
|
94
|
+
2. Parent + sub-tasks: after creating the parent item, loop
|
|
95
|
+
`mcp__dct__add_checkpoint(parent_id, text)` for each sub-task —
|
|
96
|
+
remember each checkpoint id. Mark already-done sub-tasks via
|
|
97
|
+
`complete_checkpoint(cp_id)` in a second pass.
|
|
98
|
+
3. Changelog entries: `mcp__dct__add_changelog(...)`.
|
|
99
|
+
4. Provenance: `mcp__dct__add_note(item_id, f"Imported from {filename} on {date}")`
|
|
100
|
+
for every item. This feeds the post-migration audit trail.
|
|
101
|
+
5. For issue-like / changelog: NEVER modify or delete the source markdown file.
|
|
102
|
+
|
|
103
|
+
### Step 6: Report
|
|
104
|
+
|
|
105
|
+
Per-file summary: counts by type / priority / done-vs-open. End with
|
|
106
|
+
"X items, Y checkpoints, Z changelog entries imported from N files".
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## Pattern Catalog
|
|
111
|
+
|
|
112
|
+
### Format A — TODOS.md (checkbox flat list)
|
|
113
|
+
|
|
114
|
+
```markdown
|
|
115
|
+
## P1 — Blockers
|
|
116
|
+
- [ ] Fix parser crash on empty files
|
|
117
|
+
- [x] Rotate session tokens ← already done
|
|
118
|
+
|
|
119
|
+
## P2 — Important
|
|
120
|
+
- [ ] Add progress bar
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Mapping:
|
|
124
|
+
- Section heading `## P1 — ...` → `priority="P1"` for items in that section
|
|
125
|
+
- `- [ ]` / `- [x]` → `status="open"` / `status="resolved"`
|
|
126
|
+
- `✅` or bare `**DONE**` or `STATUS: DONE` at entry end → equivalent to `[x]`
|
|
127
|
+
- Line after dash → `title` (strip bold markers, emoji, leading/trailing whitespace)
|
|
128
|
+
- `item_type` defaults to `todo` unless entry text matches type triggers
|
|
129
|
+
("bug", "crash", "error" → issue; "add X" → feature; etc.)
|
|
130
|
+
|
|
131
|
+
### Format B — Narrative sprint / ROADMAP
|
|
132
|
+
|
|
133
|
+
```markdown
|
|
134
|
+
## Sprint 3 — January push
|
|
135
|
+
|
|
136
|
+
Goal: ship the parser rewrite, close the 4 blocker bugs, validate perf.
|
|
137
|
+
|
|
138
|
+
- Parser rewrite from scratch (new AST, incremental indexing)
|
|
139
|
+
- Memory leak fix in watcher — blocking prod since Jan 4
|
|
140
|
+
- Cross-platform CI matrix
|
|
141
|
+
- Performance baseline vs v0.17
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Mapping (**plan-as-parent** strategy):
|
|
145
|
+
- Each `## Sprint N — <title>` or `## Sprint 0.5 — <title>` → ONE parent item:
|
|
146
|
+
`item_type="feature"`, `title="Sprint N — <title>"`, description includes the Goal line
|
|
147
|
+
- Each bullet under the sprint → `add_checkpoint(parent_id, bullet_text)`
|
|
148
|
+
- Completed sprint (all bullets done, or marked "Done"/"✅ Shipped"):
|
|
149
|
+
resolve parent + complete all checkpoints
|
|
150
|
+
- Recognize multilingual section markers: `## Sprint`, `## Iteration`,
|
|
151
|
+
`## Faza`, `## Etap`
|
|
152
|
+
|
|
153
|
+
### Format C — Custom issue format (ORCH-N, BUG-N)
|
|
154
|
+
|
|
155
|
+
```markdown
|
|
156
|
+
## ORCH-3 — Scheduler race on concurrent writes
|
|
157
|
+
|
|
158
|
+
**Where**: cmd/scheduler/dispatch.go:142
|
|
159
|
+
**Problem**: Two workers claim the same job when heartbeat skipped.
|
|
160
|
+
**Fix**: Add advisory lock around SELECT FOR UPDATE SKIP LOCKED.
|
|
161
|
+
**Severity**: P1
|
|
162
|
+
**Status**: open
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
Mapping:
|
|
166
|
+
- Heading → `title` (strip the ID prefix or capture it as tag)
|
|
167
|
+
- `**Where**:` → `source_file` (+ `source_lines` if line range present)
|
|
168
|
+
- `**Problem**:` + `**Fix**:` → merged into `description`
|
|
169
|
+
- `**Severity**:` → `priority` (P1/P2/P3)
|
|
170
|
+
- `**Status**:` → `status` (map "open"/"in progress"/"done"/"resolved")
|
|
171
|
+
- `item_type="issue"` (that's what this format represents)
|
|
172
|
+
- Prefix like `ORCH-3` → `tags=["orch"]` (derive bucket tag from prefix)
|
|
173
|
+
|
|
174
|
+
### Format D — Plan-as-parent (1.5k+ line planning doc)
|
|
175
|
+
|
|
176
|
+
Large planning documents (1.5k-2k+ lines) SHOULD NOT be flattened into
|
|
177
|
+
hundreds of items. Instead:
|
|
178
|
+
|
|
179
|
+
1. File → ONE parent item: `item_type="feature"`, title from file H1,
|
|
180
|
+
description = first prose section + link to file path.
|
|
181
|
+
2. Each `##` section → `add_checkpoint(parent_id, section_title)`.
|
|
182
|
+
3. Each checkbox WITHIN those sections → one more `add_checkpoint` (nested
|
|
183
|
+
via sort_order grouping, e.g. section 1 gets sort 10-19, section 2 gets 20-29).
|
|
184
|
+
4. If file has >7 `##` sections, ask user via `AskUserQuestion` whether
|
|
185
|
+
they prefer "one parent per section" (multiple items) instead.
|
|
186
|
+
|
|
187
|
+
### Format E — Keep-a-Changelog with [Unreleased]
|
|
188
|
+
|
|
189
|
+
Standard format:
|
|
190
|
+
```markdown
|
|
191
|
+
## [Unreleased]
|
|
192
|
+
### Added
|
|
193
|
+
- New Python parser support
|
|
194
|
+
|
|
195
|
+
### Fixed
|
|
196
|
+
- Memory leak in watcher
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
Mapping:
|
|
200
|
+
- `### Added/Changed/Fixed/Removed` → `category` directly
|
|
201
|
+
- Bullet → `entry`
|
|
202
|
+
- Only import `[Unreleased]` section by default (past versions already released)
|
|
203
|
+
|
|
204
|
+
### Format F — Keep-a-Changelog WITHOUT [Unreleased]
|
|
205
|
+
|
|
206
|
+
Some projects collapse everything into versioned sections and have no
|
|
207
|
+
`[Unreleased]`. Ask user via `AskUserQuestion`:
|
|
208
|
+
- question: "No [Unreleased] section found. Import all versions or skip?"
|
|
209
|
+
- options:
|
|
210
|
+
- `"Import latest version only (treat as unreleased)"`
|
|
211
|
+
- `"Import all versions, stamped with their versions"` — uses
|
|
212
|
+
`mcp__dct__add_changelog` then `release_changelog(version=X)` per version
|
|
213
|
+
- `"Skip changelog import"`
|
|
214
|
+
|
|
215
|
+
### Format G — Empty subsections
|
|
216
|
+
|
|
217
|
+
```markdown
|
|
218
|
+
## [Unreleased]
|
|
219
|
+
### Added
|
|
220
|
+
|
|
221
|
+
### Fixed
|
|
222
|
+
- Actually something here
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
Skip empty subsections gracefully — do not create placeholder items. If
|
|
226
|
+
ALL subsections under [Unreleased] are empty, treat the file as "no
|
|
227
|
+
unreleased content" and move on.
|
|
228
|
+
|
|
229
|
+
### Format H — FUTURE.md / IDEAS.md (prose or loose bullets)
|
|
230
|
+
|
|
231
|
+
```markdown
|
|
232
|
+
## Maybe someday
|
|
233
|
+
|
|
234
|
+
Would be cool to support Ruby parsers. The challenge is...
|
|
235
|
+
|
|
236
|
+
Another idea: plugin system for custom languages.
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
Mapping:
|
|
240
|
+
- Each H2/bullet → `item_type="idea"`, `priority="future"`
|
|
241
|
+
- Description = the prose underneath (first 500 chars)
|
|
242
|
+
|
|
243
|
+
### Format I — Conventional-commit style entries
|
|
244
|
+
|
|
245
|
+
```markdown
|
|
246
|
+
- feat(parser): add Python support
|
|
247
|
+
- fix(watcher): memory leak on large trees
|
|
248
|
+
- refactor(graph): extract schema builder
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
Mapping (useful when importing from git log turned into markdown):
|
|
252
|
+
- Prefix `feat:` / `feat(scope):` → `category="added"`, `component=<scope>`
|
|
253
|
+
- `fix:` → `category="fixed"`
|
|
254
|
+
- `refactor:` / `chore:` / `perf:` / `style:` → `category="changed"`
|
|
255
|
+
- `revert:` / `remove:` → `category="removed"`
|
|
256
|
+
- Text after `:` → `entry`
|
|
257
|
+
|
|
258
|
+
### Format J — No-changelog graceful case
|
|
259
|
+
|
|
260
|
+
If the project has NO changelog file, do NOT error. Report: `"No changelog
|
|
261
|
+
file found — skipping changelog import"` and continue with items only.
|
|
262
|
+
|
|
263
|
+
---
|
|
264
|
+
|
|
265
|
+
## Stale-file skip list
|
|
266
|
+
|
|
267
|
+
Skip these paths during Step 1 detection — do NOT offer them to the user.
|
|
268
|
+
Common sources of already-migrated / archival / generated content:
|
|
269
|
+
|
|
270
|
+
- `.cursor/plans/`, `.cursor/chats/` — Cursor working files
|
|
271
|
+
- `worktrees/`, `.git/worktrees/` — git worktree dirs
|
|
272
|
+
- `old_modules*`, `old-*`, `*-archive`, `archive/` — manual archives
|
|
273
|
+
- `node_modules/`, `target/`, `dist/`, `build/` — build outputs
|
|
274
|
+
- `.venv/`, `venv/`, `__pycache__/` — Python virtualenvs
|
|
275
|
+
- `.claude/`, `.gstack/` — plugin internals
|
|
276
|
+
- Any file matching `*.bak`, `*.old`, `*~`
|
|
277
|
+
|
|
278
|
+
User can override ("include archive/old-bugs.md anyway") via explicit path
|
|
279
|
+
in their /dct-import invocation.
|
|
280
|
+
|
|
281
|
+
---
|
|
282
|
+
|
|
283
|
+
## Edge case handling
|
|
284
|
+
|
|
285
|
+
### Bilingual / mixed-language titles
|
|
286
|
+
|
|
287
|
+
Polish, English, mixed — preserve as-is. Do not translate, do not strip
|
|
288
|
+
language markers. Example: `"Parser crashes / Parser się wywala"` stays
|
|
289
|
+
as the title unchanged.
|
|
290
|
+
|
|
291
|
+
### Composite files (plan + checkboxes + narrative)
|
|
292
|
+
|
|
293
|
+
When a file clearly mixes formats, pick the dominant one and note the
|
|
294
|
+
mixed nature in the user's review table ("composite: plan-as-parent with
|
|
295
|
+
embedded checkboxes"). Usually "plan-as-parent" wins for 500+ line docs.
|
|
296
|
+
|
|
297
|
+
### Done-status recognition
|
|
298
|
+
|
|
299
|
+
A sub-task is DONE when ANY of these hold:
|
|
300
|
+
- `[x]` or `[X]` prefix
|
|
301
|
+
- `✅` marker anywhere in the line
|
|
302
|
+
- Literal `**DONE**`, `STATUS: DONE`, `[DONE]`, `(done)`, `— done`
|
|
303
|
+
- Line struck through with `~~text~~`
|
|
304
|
+
|
|
305
|
+
### No sprint / no plan / no checkboxes
|
|
306
|
+
|
|
307
|
+
If the file is pure prose without structure, offer to import as a single
|
|
308
|
+
`item_type="idea"` with the file content as description (truncated to
|
|
309
|
+
~1000 chars with link to full file path).
|
|
310
|
+
|
|
311
|
+
---
|
|
312
|
+
|
|
313
|
+
## Rules
|
|
314
|
+
|
|
315
|
+
- **Every user decision is AskUserQuestion** — no plain-text prompts.
|
|
316
|
+
- **Plan-like files → `ingest_plan_file`** — v0.2 pipeline owns ULID injection
|
|
317
|
+
and first-import state semantics. Do not re-implement these inline.
|
|
318
|
+
- **Issue-like / changelog files → v0.1 items / changelog path** — unchanged,
|
|
319
|
+
uses Pattern Catalog below.
|
|
320
|
+
- **Plan-like ingest DOES modify source files** — it injects HTML-comment
|
|
321
|
+
ULID anchors. Users should know this (show diff option if they're unsure).
|
|
322
|
+
Other formats: NEVER modify source files.
|
|
323
|
+
- **Provenance notes are mandatory for v0.1 items** — every legacy-path
|
|
324
|
+
item gets `add_note("Imported from <file> on <date>")`. Plan-like entries
|
|
325
|
+
have `plans.source_file` + `plans.imported_at` which serve the same role.
|
|
326
|
+
- **Respect stale-file skip list** — do not even offer those to the user.
|
|
327
|
+
- **One file, one format** — pick dominant; note composites for the user.
|
|
328
|
+
- **Changelog missing is OK** — skip gracefully, never error out.
|
|
329
|
+
- **Ambiguities are NEVER silent** — always flag and ask.
|
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: dct-init
|
|
3
|
+
description: |
|
|
4
|
+
Initialize dct for the current project — dual-mode: runs global bootstrap if
|
|
5
|
+
missing, then registers the current directory as a dct project. Interactive
|
|
6
|
+
via AskUserQuestion for path / slug / name / version (with smart defaults from
|
|
7
|
+
detect_version). Also offers to inject `mcp__dct__*` into the Claude Code
|
|
8
|
+
permissions allowlist so daily MCP calls stop prompting.
|
|
9
|
+
Use when: "dct-init", "/dct-init", "zainicjalizuj dct", "setup dct here",
|
|
10
|
+
"add this project to dct", "register this project", "dodaj projekt do dct",
|
|
11
|
+
"skonfiguruj dct", "dct setup", "initialize dct", "bootstrap dct".
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# /dct-init — bootstrap or register
|
|
15
|
+
|
|
16
|
+
One entry point for dct setup. Replaces the split mental model of
|
|
17
|
+
`dct init` (global, once) + `dct project add` (per-project, manual).
|
|
18
|
+
|
|
19
|
+
## Workflow
|
|
20
|
+
|
|
21
|
+
### Step 1: Probe global bootstrap state
|
|
22
|
+
|
|
23
|
+
Check three things in parallel:
|
|
24
|
+
|
|
25
|
+
1. MCP registration: read `~/.claude.json`; does `mcpServers.dct` exist?
|
|
26
|
+
2. Skills: does `~/.claude/skills/track` exist (as symlink or dir)?
|
|
27
|
+
3. Hooks: does `~/.claude/hooks/dct-check-changelog.sh` exist?
|
|
28
|
+
|
|
29
|
+
Derive `bootstrap_complete` = all three present.
|
|
30
|
+
|
|
31
|
+
If NOT complete:
|
|
32
|
+
AskUserQuestion:
|
|
33
|
+
question: "Global dct bootstrap is incomplete. Run `dct init` now?"
|
|
34
|
+
header: "Bootstrap"
|
|
35
|
+
options:
|
|
36
|
+
- "Yes — run bootstrap (recommended)"
|
|
37
|
+
- "Abort — I'll fix it manually"
|
|
38
|
+
On "yes": Bash `dct init`, capture output, show summary. Re-probe after.
|
|
39
|
+
On "abort": print instructions and exit.
|
|
40
|
+
|
|
41
|
+
If complete: skip to Step 2.
|
|
42
|
+
|
|
43
|
+
### Step 2: Probe + offer MCP allowlist injection
|
|
44
|
+
|
|
45
|
+
Read `~/.claude/settings.json`. Check if `permissions.allow` contains
|
|
46
|
+
any entry matching `mcp__dct__*` (wildcard) or any individual
|
|
47
|
+
`mcp__dct__<tool>` entry.
|
|
48
|
+
|
|
49
|
+
If none present:
|
|
50
|
+
AskUserQuestion:
|
|
51
|
+
question: "dct MCP tools aren't on the Claude Code allow list — every call prompts. Add them?"
|
|
52
|
+
header: "Allowlist"
|
|
53
|
+
options:
|
|
54
|
+
- "Yes — global ~/.claude/settings.json (recommended)"
|
|
55
|
+
- "Yes — project-scope .claude/settings.local.json"
|
|
56
|
+
- "No — skip, I'll prompt-approve each time"
|
|
57
|
+
|
|
58
|
+
On "global": edit `~/.claude/settings.json`, append
|
|
59
|
+
`"mcp__dct__*"` to `permissions.allow` (preserve order; dedupe).
|
|
60
|
+
On "project": edit `.claude/settings.local.json` in the CWD
|
|
61
|
+
(create file if missing) with the same entry.
|
|
62
|
+
On "no": continue.
|
|
63
|
+
|
|
64
|
+
If already present: note "✓ allowlist already has dct entries" and continue.
|
|
65
|
+
|
|
66
|
+
### Step 2.5: Probe project-local CC artefacts for conflicts
|
|
67
|
+
|
|
68
|
+
Scan CWD for project-local CC artefacts that could conflict with or shadow
|
|
69
|
+
the global dct install. Read-only until Step 2.5b.
|
|
70
|
+
|
|
71
|
+
Check in parallel:
|
|
72
|
+
|
|
73
|
+
| Location | What to look for | Conflict when… |
|
|
74
|
+
|---|---|---|
|
|
75
|
+
| `./.claude/skills/<name>/SKILL.md` | names matching dct's skill list (track, track-list, clog, commit, release, dct-import, dct-init, handoff, pickup) | local skill **shadows** global — typically unintentional |
|
|
76
|
+
| `./.claude/hooks/*changelog*.sh` | project-local changelog hooks | duplicates global dct hook behavior |
|
|
77
|
+
| `./.claude/settings.json` `hooks` section | wires to local hooks | runs in addition to global ones |
|
|
78
|
+
| `./CLAUDE.md` / `./.claude/CLAUDE.md` | mentions of other trackers ("linear", "jira", "TODOS.md", "ISSUES.md") | project has an existing tracker — `/dct-import` may help migrate |
|
|
79
|
+
|
|
80
|
+
If zero conflicts: report "✓ No CC artefact conflicts with global dct" and continue.
|
|
81
|
+
|
|
82
|
+
For each conflict, ask via `AskUserQuestion`:
|
|
83
|
+
|
|
84
|
+
question: f"Conflict: {<describe>} (found at {<path>})"
|
|
85
|
+
header: "Conflict"
|
|
86
|
+
options:
|
|
87
|
+
- "Keep local, use it (ignore global)" — CC precedence already favors local, no action
|
|
88
|
+
- "Remove local (backup to <path>.bak) and use global dct" — rename file, keep backup
|
|
89
|
+
- "Integrate — wire local into dct workflow" — for hooks: add `exec <global-hook>` at end of local script; for CLAUDE.md: add a "[uses dct]" note and suggest /dct-import
|
|
90
|
+
- "Skip — decide later" — leave the conflict, proceed to Step 3
|
|
91
|
+
|
|
92
|
+
Each decision is recorded; at the end of Step 2.5, print a short summary:
|
|
93
|
+
"✓ Handled N conflicts: <list>" or "✓ No conflicts" if clean.
|
|
94
|
+
|
|
95
|
+
### Step 2.6: Probe version-sync script integration
|
|
96
|
+
|
|
97
|
+
dct's `/release` Step 6 runs `./scripts/dct-version-sync.sh <version>` if
|
|
98
|
+
present. We want every registered project to have a version-sync script so
|
|
99
|
+
`/release` can bump project files automatically.
|
|
100
|
+
|
|
101
|
+
Probe in order (first-match wins for the existence check):
|
|
102
|
+
|
|
103
|
+
1. `./scripts/dct-version-sync.sh` — if line 1 begins with `# dct-version-sync template v`, report "✓ version-sync already integrated" and continue. Otherwise treat as existing-but-unmarked → ask user whether to add sentinel.
|
|
104
|
+
2. `./scripts/*version*.sh` or `./scripts/*bump*.sh` or `./scripts/release.sh` — existing non-dct bump script.
|
|
105
|
+
3. `./Makefile` or `./justfile` or `./Taskfile.yml` with a `version:` / `bump:` / `release:` target.
|
|
106
|
+
4. None of the above — greenfield, no script.
|
|
107
|
+
|
|
108
|
+
Based on probe result, use `AskUserQuestion`:
|
|
109
|
+
|
|
110
|
+
**Case 1 — existing dct template (sentinel present)**: skip, already good.
|
|
111
|
+
|
|
112
|
+
**Case 2 — existing non-dct script**:
|
|
113
|
+
question: f"Found existing {script_path}. Integrate with dct?"
|
|
114
|
+
header: "Version sync"
|
|
115
|
+
options:
|
|
116
|
+
- "Wrap — generate scripts/dct-version-sync.sh that delegates to <script> $1 (recommended)"
|
|
117
|
+
- "Replace — overwrite with dct template (backup original to .bak)"
|
|
118
|
+
- "Keep standalone — /release will skip Step 6; user runs script manually"
|
|
119
|
+
- "Skip for now"
|
|
120
|
+
|
|
121
|
+
On "wrap": write minimal shim:
|
|
122
|
+
```bash
|
|
123
|
+
#!/usr/bin/env bash
|
|
124
|
+
# dct-version-sync template v1 (wraps <original-script>)
|
|
125
|
+
set -euo pipefail
|
|
126
|
+
exec "$(dirname "$0")/<original-script-name>" "$@"
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
On "replace": copy dct's `scripts/dct-version-sync.sh` template, uncomment
|
|
130
|
+
the block matching detected project kind (result of `detect_version` in
|
|
131
|
+
Step 4d: VERSION / pyproject.toml / package.json / Cargo.toml / tauri.conf.json).
|
|
132
|
+
|
|
133
|
+
**Case 3 — Makefile/justfile/Taskfile target**:
|
|
134
|
+
question: f"Found {tool} target {target_name}. Integrate with dct?"
|
|
135
|
+
header: "Version sync"
|
|
136
|
+
options:
|
|
137
|
+
- "Wrap — generate scripts/dct-version-sync.sh that calls `{tool} {target} $1` (recommended)"
|
|
138
|
+
- "Skip — /release will skip Step 6; user runs {tool} {target} manually"
|
|
139
|
+
|
|
140
|
+
**Case 4 — no script detected**:
|
|
141
|
+
question: "No version-sync script found. Generate template?"
|
|
142
|
+
header: "Version sync"
|
|
143
|
+
options:
|
|
144
|
+
- f"Generate scripts/dct-version-sync.sh with {detected_kind} block uncommented (recommended)"
|
|
145
|
+
- "Generate all blocks commented (pick manually later)"
|
|
146
|
+
- "Skip"
|
|
147
|
+
|
|
148
|
+
All generated scripts include the sentinel `# dct-version-sync template v1`
|
|
149
|
+
as line 1 (after shebang) so future `/dct-init` runs short-circuit via
|
|
150
|
+
Case 1 and do not regenerate.
|
|
151
|
+
|
|
152
|
+
### Step 3: Probe current project registration
|
|
153
|
+
|
|
154
|
+
Call `mcp__dct__list_projects`. Let `cwd = os.getcwd()`.
|
|
155
|
+
|
|
156
|
+
Match: for each project row, check if `cwd == row.path` or
|
|
157
|
+
`cwd.startswith(row.path + "/")`. Longest-prefix wins (use
|
|
158
|
+
`get_project_by_path` semantics).
|
|
159
|
+
|
|
160
|
+
If matched:
|
|
161
|
+
Print "✓ Already registered as `<slug>` — current_version=<v>, path=<path>".
|
|
162
|
+
Offer via AskUserQuestion:
|
|
163
|
+
question: "Project is already registered. What now?"
|
|
164
|
+
header: "Registered"
|
|
165
|
+
options:
|
|
166
|
+
- "Nothing — just confirm status"
|
|
167
|
+
- "Update version — call `dct project set-version`"
|
|
168
|
+
- "Show current items — /track-list"
|
|
169
|
+
Run matching action. Exit.
|
|
170
|
+
|
|
171
|
+
If no match: continue to Step 4.
|
|
172
|
+
|
|
173
|
+
### Step 4: Collect registration inputs
|
|
174
|
+
|
|
175
|
+
Derive defaults first (pure functions, no side effects):
|
|
176
|
+
- `default_path` = CWD
|
|
177
|
+
- `default_slug` = `basename(CWD)`, lowercased, non-alnum → `-`
|
|
178
|
+
- `default_name` = title-case of `default_slug` (split on `-`/`_`, capitalize)
|
|
179
|
+
- `(detected_version, source_file)` = `dct.core.version.detect_version(default_path)`
|
|
180
|
+
|
|
181
|
+
Ask sequentially (four AskUserQuestions bundled in one tool call when possible):
|
|
182
|
+
|
|
183
|
+
a) Path confirmation:
|
|
184
|
+
question: "Register dct project at this path?"
|
|
185
|
+
header: "Path"
|
|
186
|
+
options:
|
|
187
|
+
- f"Yes — {default_path} (recommended)"
|
|
188
|
+
- "Different path — I'll type it"
|
|
189
|
+
|
|
190
|
+
b) Slug:
|
|
191
|
+
question: "Project slug (short id used in CLI, URLs, queries)?"
|
|
192
|
+
header: "Slug"
|
|
193
|
+
options:
|
|
194
|
+
- f"{default_slug} (recommended)"
|
|
195
|
+
- "Other — type custom"
|
|
196
|
+
|
|
197
|
+
c) Name:
|
|
198
|
+
question: "Human-readable display name?"
|
|
199
|
+
header: "Name"
|
|
200
|
+
options:
|
|
201
|
+
- f"{default_name} (recommended)"
|
|
202
|
+
- "Other — type custom"
|
|
203
|
+
|
|
204
|
+
d) Version:
|
|
205
|
+
If `detected_version` is not None:
|
|
206
|
+
question: f"Starting version? (detected: {detected_version} from {source_file})"
|
|
207
|
+
header: "Version"
|
|
208
|
+
options:
|
|
209
|
+
- f"{detected_version} (detected, recommended)"
|
|
210
|
+
- "Type custom"
|
|
211
|
+
- "Leave NULL (set later via `dct project set-version`)"
|
|
212
|
+
Else:
|
|
213
|
+
question: "Starting version? (none detected)"
|
|
214
|
+
header: "Version"
|
|
215
|
+
options:
|
|
216
|
+
- "0.1.0 (alpha — recommended)"
|
|
217
|
+
- "0.0.1 (pre-alpha)"
|
|
218
|
+
- "1.0.0 (stable)"
|
|
219
|
+
- "Type custom"
|
|
220
|
+
|
|
221
|
+
For any "Other — type custom" / "Type custom", use the answer's free-text value.
|
|
222
|
+
|
|
223
|
+
### Step 5: Execute registration
|
|
224
|
+
|
|
225
|
+
Build command:
|
|
226
|
+
```
|
|
227
|
+
dct project add <slug> <path> --name "<name>" [--version <vX.Y.Z>]
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
Skip `--version` when user picked "Leave NULL".
|
|
231
|
+
|
|
232
|
+
Run via Bash. Verify with `mcp__dct__list_projects` — the new slug must appear.
|
|
233
|
+
|
|
234
|
+
### Step 6: Final report
|
|
235
|
+
|
|
236
|
+
```
|
|
237
|
+
✓ Bootstrap: mcpServers.dct OK, N skills installed, M hooks installed
|
|
238
|
+
✓ Allowlist: "mcp__dct__*" in ~/.claude/settings.json
|
|
239
|
+
✓ Project: <slug> registered at <path>, version <v>
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
### Step 7: Propose a concrete next action
|
|
243
|
+
|
|
244
|
+
Registration alone does nothing visible — the project's DB row is empty.
|
|
245
|
+
Offer the natural follow-up via `AskUserQuestion`:
|
|
246
|
+
|
|
247
|
+
question: "Project is registered. What next?"
|
|
248
|
+
header: "Next step"
|
|
249
|
+
options:
|
|
250
|
+
- "Import existing MD tracking — run /dct-import now"
|
|
251
|
+
→ delegate to the `/dct-import` skill (pass the freshly-registered
|
|
252
|
+
slug implicitly via CWD auto-detect — the skill takes over from
|
|
253
|
+
there with its own AskUserQuestion flow for file selection).
|
|
254
|
+
- "Create first item manually — run /track"
|
|
255
|
+
→ delegate to the `/track` skill.
|
|
256
|
+
- "Exit — I'll come back later"
|
|
257
|
+
→ print a one-liner hint listing both commands and stop.
|
|
258
|
+
|
|
259
|
+
**Why this matters**: without the follow-up prompt, users correctly
|
|
260
|
+
register their project and then bounce off a blank slate — the DB has a
|
|
261
|
+
projects row but nothing else, so `/pickup` returns empty, `/track-list`
|
|
262
|
+
returns empty, and it looks like dct "doesn't do anything". For projects
|
|
263
|
+
with pre-existing MD tracking (ROADMAP, TODOS, sprint docs, changelog),
|
|
264
|
+
`/dct-import` is almost always the right next move and should be
|
|
265
|
+
offered proactively, not discovered by hunting.
|
|
266
|
+
|
|
267
|
+
**Probe before offering**: if the project path contains plausible
|
|
268
|
+
tracking files (any of `ROADMAP.md`, `TODOS.md`, `BACKLOG.md`,
|
|
269
|
+
`SPRINT*.md`, `PLAN*.md`, `CHANGELOG.md`, `changelog.md`,
|
|
270
|
+
`docs/plans/*.md`, `docs/specs/*.md`), make the `/dct-import` option the
|
|
271
|
+
**recommended** choice. If none exist, demote it — the recommended
|
|
272
|
+
default becomes `/track` for a greenfield project.
|
|
273
|
+
|
|
274
|
+
## Rules
|
|
275
|
+
|
|
276
|
+
- **Every decision is AskUserQuestion.** Never plain Y/N via read.
|
|
277
|
+
- **Idempotent probes first.** Safe to re-run at any time — re-running
|
|
278
|
+
with everything in place reports ✓ for each check and exits.
|
|
279
|
+
- **Smart defaults, no free-text when avoidable.** The "Other — type
|
|
280
|
+
custom" escape hatch covers unusual cases but default path is one click.
|
|
281
|
+
- **Single source of truth for bootstrap.** Skill calls `dct init`
|
|
282
|
+
under the hood; never re-implements MCP/skill/hook installation.
|
|
283
|
+
- **Single source of truth for registration.** Skill calls
|
|
284
|
+
`dct project add`; never writes the DB directly.
|
|
285
|
+
- **Preserve existing allowlist order.** Append, don't sort; dedupe
|
|
286
|
+
before write.
|
|
287
|
+
- **No overwrite without confirmation.** If `mcpServers.dct` already
|
|
288
|
+
exists with different config, surface the conflict via AskUserQuestion
|
|
289
|
+
before touching it.
|