@thedecipherist/mdd 1.0.2 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +108 -7
- package/commands/mdd-audit.md +2 -2
- package/commands/mdd-branch-guard.sh +38 -0
- package/commands/mdd-build.md +1 -0
- package/commands/mdd-lifecycle.md +10 -6
- package/commands/mdd-manage.md +69 -3
- package/commands/mdd-ops.md +1 -0
- package/commands/mdd-plan.md +50 -0
- package/commands/mdd.md +78 -17
- package/dist/cli.js +15 -2
- package/dist/cli.js.map +1 -1
- package/dist/install.d.ts +2 -0
- package/dist/install.d.ts.map +1 -1
- package/dist/install.js +122 -3
- package/dist/install.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -86,7 +86,7 @@ MDD flips this. You write structured documentation first. Then Claude reads **on
|
|
|
86
86
|
MDD installs 7 Claude command files into `~/.claude/commands/`. The main router (`mdd.md`) reads your arguments and loads **only the mode file needed** - a `/mdd status` loads ~460 tokens instead of the full ~28,000.
|
|
87
87
|
|
|
88
88
|
```
|
|
89
|
-
mdd.md (~120 lines) Router - Steps 0/0a/0b, mode dispatch,
|
|
89
|
+
mdd.md (~120 lines) Router - Steps 0/0a/0b, mode dispatch, Branch Guard
|
|
90
90
|
mdd-build.md (~680 lines) BUILD MODE - Phases 0–7d
|
|
91
91
|
mdd-audit.md (~240 lines) AUDIT MODE - Phases A1–A7
|
|
92
92
|
mdd-manage.md (~340 lines) STATUS + NOTE + SCAN + UPDATE + DEPRECATE
|
|
@@ -109,12 +109,61 @@ mdd install # copies Claude commands to ~/.claude/commands/
|
|
|
109
109
|
After installation, `/mdd` is available in every Claude Code session globally - no per-project setup needed.
|
|
110
110
|
|
|
111
111
|
```bash
|
|
112
|
-
mdd update
|
|
113
|
-
mdd install --dir /custom/path
|
|
112
|
+
mdd update # update to latest installed version
|
|
113
|
+
mdd install --dir /custom/path # install to a custom directory (skips CLAUDE.md injection)
|
|
114
|
+
mdd install --install-local # install to .claude/commands/ + injects into ./CLAUDE.md
|
|
114
115
|
```
|
|
115
116
|
|
|
116
117
|
**Version safety:** `mdd install` compares `mdd_version` between the installed and available versions before overwriting. If you have a newer version installed, it won't silently downgrade.
|
|
117
118
|
|
|
119
|
+
### What `mdd install` sets up
|
|
120
|
+
|
|
121
|
+
| What | Where | Purpose |
|
|
122
|
+
|------|-------|---------|
|
|
123
|
+
| 7 command `.md` files | `~/.claude/commands/` | The `/mdd` slash command and all its modes |
|
|
124
|
+
| Branch Guard hook | `~/.claude/hooks/mdd-branch-guard.sh` | Blocks file writes on `main` in any MDD project |
|
|
125
|
+
| Hook registration | `~/.claude/settings.json` | Wires the hook to Claude Code's PreToolUse event |
|
|
126
|
+
| Guidance block | `~/.claude/CLAUDE.md` | Teaches Claude to suggest MDD automatically |
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## Branch Guard — Never Work on `main`
|
|
131
|
+
|
|
132
|
+
`mdd install` registers a **Claude Code `PreToolUse` hook** that fires before every file write (`Write`, `Edit`, `NotebookEdit`) in any project with a `.mdd/` directory. If the current branch is `main` or `master`, the hook blocks the operation:
|
|
133
|
+
|
|
134
|
+
```
|
|
135
|
+
⛔ MDD BRANCH GUARD
|
|
136
|
+
|
|
137
|
+
File modification is blocked on branch 'main'.
|
|
138
|
+
MDD never writes files directly on main or master.
|
|
139
|
+
|
|
140
|
+
Create a feature branch, then re-run your /mdd command:
|
|
141
|
+
|
|
142
|
+
git checkout -b feat/<feature-name>
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
**Why a hook and not just instructions?**
|
|
146
|
+
|
|
147
|
+
Instruction-based branch checks can be lost through Claude's context compaction (when a conversation grows very long, earlier context is summarised). A `PreToolUse` hook fires at the OS level on every tool call — it cannot be compacted away, forgotten, or bypassed by stale context.
|
|
148
|
+
|
|
149
|
+
**How it works end-to-end:**
|
|
150
|
+
|
|
151
|
+
1. MDD instructions enforce branch hygiene in every command file (Branch Guard in `mdd.md`, Phase 0 in `mdd-build.md`, Phase PE1 in `mdd-plan.md`).
|
|
152
|
+
2. The hook acts as a permanent failsafe. If Claude is about to write a file on `main`, the hook fires before the write happens, exits with code `2`, and the operation is blocked.
|
|
153
|
+
3. The hook is a no-op outside `.mdd` projects and on any non-`main`/`master` branch.
|
|
154
|
+
|
|
155
|
+
**MDD branch naming conventions:**
|
|
156
|
+
|
|
157
|
+
| Mode | Auto-created branch |
|
|
158
|
+
|------|---------------------|
|
|
159
|
+
| `/mdd <feature>` | `feat/<feature-slug>` |
|
|
160
|
+
| `/mdd audit` | `fix/mdd-audit-<YYYY-MM-DD>` |
|
|
161
|
+
| `/mdd plan-initiative` | `feat/init-<initiative-slug>` |
|
|
162
|
+
| `/mdd plan-wave` | `feat/<wave-slug>` |
|
|
163
|
+
| `/mdd plan-execute` | `feat/<wave-slug>` |
|
|
164
|
+
|
|
165
|
+
When on a clean `main`, MDD creates the branch automatically. When on `main` with uncommitted changes, MDD stops and offers to commit or stash first.
|
|
166
|
+
|
|
118
167
|
---
|
|
119
168
|
|
|
120
169
|
## Quick Start
|
|
@@ -138,7 +187,53 @@ npm install -g @thedecipherist/mdd && mdd install
|
|
|
138
187
|
|
|
139
188
|
---
|
|
140
189
|
|
|
141
|
-
##
|
|
190
|
+
## Claude Automatically Suggests MDD
|
|
191
|
+
|
|
192
|
+
`mdd install` injects a small guidance block into your `~/.claude/CLAUDE.md` (or the project `CLAUDE.md` for `--install-local`). From that point on, whenever Claude detects a `.mdd/` directory in the current project it automatically evaluates every implementation or infrastructure request and suggests the right MDD workflow — even if you didn't type `/mdd`.
|
|
193
|
+
|
|
194
|
+
**What Claude checks, in order:**
|
|
195
|
+
|
|
196
|
+
**1. Does it already exist?**
|
|
197
|
+
Claude scans `.mdd/.startup.md` — which lists every documented feature and ops runbook with their tags. If your prompt overlaps with something already documented, Claude flags it before you duplicate work:
|
|
198
|
+
|
|
199
|
+
> *"This looks related to `02-user-auth` in your MDD docs. Want to use `/mdd update 02` to modify it, or `/mdd audit 02` to review it first?"*
|
|
200
|
+
|
|
201
|
+
**2. Is it ops/infrastructure?**
|
|
202
|
+
Deploy procedures, CI/CD pipelines, commit hooks, Docker builds, cron jobs, DNS changes — anything operational gets flagged for a runbook instead of ad-hoc implementation:
|
|
203
|
+
|
|
204
|
+
> *"This sounds like an ops procedure. Want to document it as a repeatable runbook with `/mdd ops deploy to production`?"*
|
|
205
|
+
|
|
206
|
+
**3. Is it initiative-scale?**
|
|
207
|
+
Large requests touching three or more independent concerns get routed to initiative/wave planning instead of a single feature doc:
|
|
208
|
+
|
|
209
|
+
> *"This looks initiative-scale. Want to plan it with `/mdd plan-initiative`?"*
|
|
210
|
+
|
|
211
|
+
**4. Is it a single new feature?**
|
|
212
|
+
Everything else gets the standard build mode prompt:
|
|
213
|
+
|
|
214
|
+
> *"Want me to use `/mdd add payment processing` to build this with documentation and tests first?"*
|
|
215
|
+
|
|
216
|
+
Claude always **asks** — it never auto-invokes `/mdd`. If you say no, it proceeds with direct implementation as normal. The detection is also intentionally narrow: bug fixes, typo corrections, config tweaks, and one-off shell commands are never flagged.
|
|
217
|
+
|
|
218
|
+
**How it detects overlap without loading full docs:**
|
|
219
|
+
|
|
220
|
+
Every feature doc and ops runbook has a `tags:` field (4–8 domain-concept keywords). These tags are surfaced in `.mdd/.startup.md` — a compact session-context file that's already injected into every Claude conversation. Claude scans the tag list in milliseconds, with no full-document loading and no context bloat.
|
|
221
|
+
|
|
222
|
+
```
|
|
223
|
+
## Features Documented
|
|
224
|
+
- 01-project-scaffolding (complete) [typescript, express, project-setup, scaffolding]
|
|
225
|
+
- 02-user-auth (in_progress) [auth, jwt, login, sessions, middleware]
|
|
226
|
+
- 03-payment-flow (draft) [stripe, payments, checkout, webhooks]
|
|
227
|
+
|
|
228
|
+
## Ops Runbooks
|
|
229
|
+
- prod-deploy [deploy, dokploy, docker, eu-west, canary, health-check]
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
**The injection is idempotent.** Running `mdd install` or `mdd update` again never duplicates the block.
|
|
233
|
+
|
|
234
|
+
---
|
|
235
|
+
|
|
236
|
+
## All 22 Modes at a Glance
|
|
142
237
|
|
|
143
238
|
```
|
|
144
239
|
/mdd <feature description> Build Mode - Document, plan, and implement
|
|
@@ -146,6 +241,7 @@ npm install -g @thedecipherist/mdd && mdd install
|
|
|
146
241
|
/mdd status Overview: docs, tests, audit state, initiatives
|
|
147
242
|
/mdd scan Detect features whose source files changed
|
|
148
243
|
/mdd update <feature-id> Re-sync a feature doc after code changes
|
|
244
|
+
/mdd rebuild-tags [--force] Generate tags for all docs and rebuild .startup.md
|
|
149
245
|
/mdd note "text" Append a timestamped note to .mdd/.startup.md
|
|
150
246
|
/mdd note list Print the Notes section
|
|
151
247
|
/mdd note clear Wipe all notes (asks for confirmation)
|
|
@@ -235,6 +331,7 @@ last_synced: 2026-05-07
|
|
|
235
331
|
status: draft
|
|
236
332
|
phase: documentation
|
|
237
333
|
mdd_version: 8
|
|
334
|
+
tags: [auth, jwt, login, sessions, middleware]
|
|
238
335
|
known_issues: []
|
|
239
336
|
---
|
|
240
337
|
|
|
@@ -692,6 +789,7 @@ Every `.mdd/docs/<NN>-<feature-name>.md` file uses this YAML frontmatter:
|
|
|
692
789
|
| `status` | `draft` → `in_progress` → `complete` → `deprecated` |
|
|
693
790
|
| `phase` | Last completed phase name |
|
|
694
791
|
| `mdd_version` | Version of MDD that created/last updated this doc |
|
|
792
|
+
| `tags` | 4–8 domain-concept keywords surfaced in `.startup.md` so Claude can detect when a prompt relates to this feature (e.g. `[auth, jwt, login, sessions]`) |
|
|
695
793
|
| `known_issues` | Issues discovered during audits or implementation |
|
|
696
794
|
|
|
697
795
|
**`depends_on` rules:**
|
|
@@ -743,9 +841,12 @@ Generated: 2026-05-07 | Branch: feat/user-auth
|
|
|
743
841
|
Framework: Express + React | DB: PostgreSQL | Host: Dokploy
|
|
744
842
|
|
|
745
843
|
## Features Documented
|
|
746
|
-
01-project-scaffolding (complete)
|
|
747
|
-
02-user-auth (in_progress)
|
|
748
|
-
|
|
844
|
+
- 01-project-scaffolding (complete) [typescript, express, project-setup, scaffolding]
|
|
845
|
+
- 02-user-auth (in_progress) [auth, jwt, login, sessions, middleware]
|
|
846
|
+
- 03-payment-flow (draft) [stripe, payments, checkout, webhooks]
|
|
847
|
+
|
|
848
|
+
## Ops Runbooks
|
|
849
|
+
- prod-deploy [deploy, dokploy, docker, eu-west, canary, health-check]
|
|
749
850
|
|
|
750
851
|
## Last Audit
|
|
751
852
|
2026-05-01 - 20 findings, 17 fixed, 3 open
|
package/commands/mdd-audit.md
CHANGED
|
@@ -214,7 +214,7 @@ Estimated fix time: <N> hours (traditional) → <N> minutes (MDD)
|
|
|
214
214
|
Fix all now? (yes / review report first / fix only P1+P2)
|
|
215
215
|
```
|
|
216
216
|
|
|
217
|
-
**After the report is written**, trigger the `.mdd/.startup.md` rebuild (same logic as in Status Mode — rebuild auto-generated zone, preserve Notes zone) so the Last Audit block
|
|
217
|
+
**After the report is written**, run a tag pass before the startup rebuild: for any `.mdd/docs/*.md` or `.mdd/ops/*.md` file missing a `tags:` field, generate and write tags now (same logic as Phase RT2 in REBUILD-TAGS MODE). Docs that already have `tags:` are untouched. Then trigger the `.mdd/.startup.md` rebuild (same logic as in Status Mode — rebuild auto-generated zone, preserve Notes zone) so the Last Audit block and tag-enriched feature list are both current.
|
|
218
218
|
|
|
219
219
|
If user says yes (or selects a subset):
|
|
220
220
|
|
|
@@ -226,7 +226,7 @@ If user says yes (or selects a subset):
|
|
|
226
226
|
|
|
227
227
|
Report progress per finding. Update documentation `known_issues` to remove fixed items. Update `mdd_version` to current on every `.mdd/docs/*.md` file that is edited during fixes.
|
|
228
228
|
|
|
229
|
-
**After fixes are complete and results are written to `.mdd/audits/results-<date>.md`**, trigger the `.mdd/.startup.md` rebuild so the Last Audit block
|
|
229
|
+
**After fixes are complete and results are written to `.mdd/audits/results-<date>.md`**, run the same tag pass (generate missing tags for any doc still lacking them), then trigger the `.mdd/.startup.md` rebuild so the Last Audit block and tag list both reflect the final state.
|
|
230
230
|
|
|
231
231
|
---
|
|
232
232
|
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# MDD Branch Guard
|
|
3
|
+
# PreToolUse hook — blocks Write/Edit/NotebookEdit on main/master in MDD projects.
|
|
4
|
+
# Installed by: mdd install (into .claude/hooks/ or ~/.claude/hooks/)
|
|
5
|
+
|
|
6
|
+
# Only active in MDD projects
|
|
7
|
+
[ -d ".mdd" ] || exit 0
|
|
8
|
+
|
|
9
|
+
# Check current branch
|
|
10
|
+
BRANCH=$(git branch --show-current 2>/dev/null)
|
|
11
|
+
[ -z "$BRANCH" ] && exit 0
|
|
12
|
+
|
|
13
|
+
# Only block on main/master
|
|
14
|
+
[[ "$BRANCH" == "main" || "$BRANCH" == "master" ]] || exit 0
|
|
15
|
+
|
|
16
|
+
# Count uncommitted changes for context
|
|
17
|
+
CHANGES=$(git status --porcelain 2>/dev/null | wc -l | tr -d ' ')
|
|
18
|
+
|
|
19
|
+
echo ""
|
|
20
|
+
echo "⛔ MDD BRANCH GUARD"
|
|
21
|
+
echo ""
|
|
22
|
+
echo " File modification is blocked on branch '${BRANCH}'."
|
|
23
|
+
echo " MDD never writes files directly on main or master."
|
|
24
|
+
echo ""
|
|
25
|
+
if [ "$CHANGES" -gt 0 ]; then
|
|
26
|
+
echo " You have ${CHANGES} uncommitted change(s). Commit or stash first:"
|
|
27
|
+
echo ""
|
|
28
|
+
echo " git add -A && git commit -m 'wip: ...' && git checkout -b feat/<name>"
|
|
29
|
+
echo " — or —"
|
|
30
|
+
echo " git stash && git checkout -b feat/<name>"
|
|
31
|
+
else
|
|
32
|
+
echo " Create a feature branch, then re-run your /mdd command:"
|
|
33
|
+
echo ""
|
|
34
|
+
echo " git checkout -b feat/<feature-name>"
|
|
35
|
+
fi
|
|
36
|
+
echo ""
|
|
37
|
+
|
|
38
|
+
exit 2
|
package/commands/mdd-build.md
CHANGED
|
@@ -191,6 +191,7 @@ last_synced: <YYYY-MM-DD>
|
|
|
191
191
|
status: draft
|
|
192
192
|
phase: <last completed phase name, or "all" when fully built>
|
|
193
193
|
mdd_version: <read from mdd.md frontmatter mdd_version field>
|
|
194
|
+
tags: [<4-8 domain-concept keywords — systems touched, technology, feature names. NOT file paths>]
|
|
194
195
|
known_issues: []
|
|
195
196
|
---
|
|
196
197
|
|
|
@@ -61,6 +61,7 @@ Draft a complete feature doc following the Phase 3 template. Set:
|
|
|
61
61
|
- `last_synced: <today>`
|
|
62
62
|
- `status: draft` (since business intent may be incomplete)
|
|
63
63
|
- `phase: reverse-engineered`
|
|
64
|
+
- `tags: [...]` — infer 4–8 domain-concept keywords from the inferred purpose, routes, models, and source file names. NOT raw file paths — use the concept (e.g. `auth`, `api`, `stripe` not `src/handlers/stripe.ts`)
|
|
64
65
|
|
|
65
66
|
**In regenerate mode:** Show the existing doc alongside the new draft:
|
|
66
67
|
```
|
|
@@ -195,11 +196,11 @@ Batch-patches missing frontmatter fields (`last_synced`, `status`, `phase`) acro
|
|
|
195
196
|
```
|
|
196
197
|
📋 Upgrade Inventory
|
|
197
198
|
|
|
198
|
-
Doc | last_synced | status | phase
|
|
199
|
-
|
|
200
|
-
01-project-scaffolding | ❌ missing | ❌ | ❌
|
|
201
|
-
02-profile-system | ❌ missing | ✅ | ❌
|
|
202
|
-
03-database-layer | ✅ present | ✅ | ✅
|
|
199
|
+
Doc | last_synced | status | phase | tags
|
|
200
|
+
─────────────────────────────────|─────────────|────────|───────|──────
|
|
201
|
+
01-project-scaffolding | ❌ missing | ❌ | ❌ | ❌
|
|
202
|
+
02-profile-system | ❌ missing | ✅ | ❌ | ✅
|
|
203
|
+
03-database-layer | ✅ present | ✅ | ✅ | ❌
|
|
203
204
|
...
|
|
204
205
|
|
|
205
206
|
Docs needing upgrade: <N> of <total>
|
|
@@ -207,6 +208,7 @@ Fields to add:
|
|
|
207
208
|
last_synced — <N> docs
|
|
208
209
|
status — <N> docs
|
|
209
210
|
phase — <N> docs
|
|
211
|
+
tags — <N> docs (run /mdd rebuild-tags after upgrade to populate)
|
|
210
212
|
```
|
|
211
213
|
|
|
212
214
|
4. If 0 docs need upgrade → report "All docs are up to date. Nothing to patch." and stop.
|
|
@@ -307,11 +309,13 @@ data_flow: ...
|
|
|
307
309
|
last_synced: <new> ← insert here if missing
|
|
308
310
|
status: <new> ← insert here if missing
|
|
309
311
|
phase: <new> ← insert here if missing
|
|
312
|
+
mdd_version: <new> ← insert here if missing
|
|
313
|
+
tags: <new> ← insert here if missing (do not generate tags in upgrade — run /mdd rebuild-tags after)
|
|
310
314
|
known_issues: []
|
|
311
315
|
---
|
|
312
316
|
```
|
|
313
317
|
|
|
314
|
-
Insert new fields **before** `known_issues` to keep the canonical order.
|
|
318
|
+
Insert new fields **before** `known_issues` to keep the canonical order. **Do not attempt to generate tag values during upgrade** — tags require reading doc content to produce meaningful keywords. After running upgrade, run `/mdd rebuild-tags` to populate tags on any docs that need them.
|
|
315
319
|
|
|
316
320
|
Report progress as you go:
|
|
317
321
|
```
|
package/commands/mdd-manage.md
CHANGED
|
@@ -7,7 +7,7 @@ Quick overview of MDD state for the project:
|
|
|
7
7
|
3. **Scan `.mdd/jobs/`** — detect any active audit job (see below)
|
|
8
8
|
4. **Count tests** — `pnpm test:unit --reporter=json 2>/dev/null | jq '.numTotalTests'`
|
|
9
9
|
5. **Count known issues** — grep `known_issues` across all docs
|
|
10
|
-
6. **Read current mdd_version** — from `mdd.md` frontmatter (
|
|
10
|
+
6. **Read current mdd_version** — from `mdd.md` frontmatter. Check `.claude/commands/mdd.md` first (local install), then `~/.claude/commands/mdd.md` (global install). Use whichever exists.
|
|
11
11
|
7. **Scan all `.mdd/` files** — grep `mdd_version` from each, group by version number
|
|
12
12
|
8. **Scan `.mdd/initiatives/`** — count initiative files, group by status
|
|
13
13
|
9. **Scan `.mdd/waves/`** — count wave files, group by status; for each active wave count complete vs total features
|
|
@@ -63,8 +63,8 @@ After collecting status, rebuild the auto-generated zone of `.mdd/.startup.md`:
|
|
|
63
63
|
- `Generated: <YYYY-MM-DD>` (date only, no time)
|
|
64
64
|
- `Branch:` from `git branch --show-current`
|
|
65
65
|
- `Stack:` from `CLAUDE.md` or `claude-mastery-project.conf` if detectable, otherwise `(unknown)`
|
|
66
|
-
- `Features Documented:` sorted list of `.mdd/docs/*.md` filenames with status
|
|
67
|
-
- `Ops Runbooks:` sorted list of `.mdd/ops/*.md` filenames with
|
|
66
|
+
- `Features Documented:` sorted list of `.mdd/docs/*.md` filenames with status and tags — format: `- <id> (<status>) [tag1, tag2, ...]`. If `tags:` is missing from a doc, omit the bracket section for that entry.
|
|
67
|
+
- `Ops Runbooks:` sorted list of `.mdd/ops/*.md` filenames with tags — format: `- <slug> [tag1, tag2, ...]`. Omit section entirely if `.mdd/ops/` is empty.
|
|
68
68
|
- `Last Audit:` from the most recent `.mdd/audits/report-*.md` — extract findings/fixed/open counts
|
|
69
69
|
- `Rules Summary:` static block (does not change)
|
|
70
70
|
3. Write the rebuilt auto-generated section + `---` divider + preserved Notes section back to `.mdd/.startup.md`. Update `mdd_version` in the file's frontmatter to current.
|
|
@@ -338,3 +338,69 @@ Test files: <kept/deleted per user choice>
|
|
|
338
338
|
```
|
|
339
339
|
|
|
340
340
|
---
|
|
341
|
+
|
|
342
|
+
## REBUILD-TAGS MODE — `/mdd rebuild-tags [--force]`
|
|
343
|
+
|
|
344
|
+
Triggered when arguments start with `rebuild-tags`. Scans all feature docs and ops runbooks, generates `tags:` for any doc missing the field, then rebuilds `.startup.md`.
|
|
345
|
+
|
|
346
|
+
**Use case:** Migrating existing projects to the tag system. Safe to run multiple times — docs that already have `tags:` are skipped unless `--force` is passed.
|
|
347
|
+
|
|
348
|
+
### Phase RT1 — Inventory
|
|
349
|
+
|
|
350
|
+
1. Glob `.mdd/docs/*.md` (excluding `archive/`) and `.mdd/ops/*.md` (excluding `archive/`).
|
|
351
|
+
2. For each doc, check frontmatter for a `tags:` field.
|
|
352
|
+
3. Build an inventory table:
|
|
353
|
+
|
|
354
|
+
```
|
|
355
|
+
🏷️ Rebuild Tags — Inventory
|
|
356
|
+
|
|
357
|
+
Doc | Has tags?
|
|
358
|
+
─────────────────────────────────|──────────
|
|
359
|
+
01-docs-site | ❌ missing
|
|
360
|
+
02-dashboards-showcase | ❌ missing
|
|
361
|
+
03-install-local-flag | ✅ present
|
|
362
|
+
swarmk-dokploy (ops) | ❌ missing
|
|
363
|
+
|
|
364
|
+
Docs needing tags: <N> of <total>
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
If 0 docs need tags (and `--force` not passed) → report "All docs already have tags. `.startup.md` will be rebuilt." and jump to Phase RT3.
|
|
368
|
+
|
|
369
|
+
### Phase RT2 — Generate Tags
|
|
370
|
+
|
|
371
|
+
For each doc missing `tags:` (or all docs if `--force`):
|
|
372
|
+
|
|
373
|
+
1. Read the doc's frontmatter and `## Purpose` section (first paragraph only).
|
|
374
|
+
2. Generate 4–8 domain-concept keywords that identify what the doc is about:
|
|
375
|
+
- Use: title words, purpose concepts, platform/technology names, key system names, operation types
|
|
376
|
+
- Do NOT use: raw file paths, generic words like "feature" or "system", version numbers
|
|
377
|
+
- For ops docs: emphasise platform, services, environments, operation type (e.g. `deploy`, `dokploy`, `docker`, `canary`)
|
|
378
|
+
- For feature docs: emphasise domain concepts, technology, feature names (e.g. `auth`, `cli`, `install`, `flags`)
|
|
379
|
+
3. Write `tags:` to the doc frontmatter, inserting it **before** `known_issues:`.
|
|
380
|
+
4. Report one line per doc: `✅ 01-docs-site — tags: [github-pages, documentation, landing-page, user-guide]`
|
|
381
|
+
|
|
382
|
+
**`--force` behaviour:** Regenerate and overwrite `tags:` even on docs that already have them. Show old → new for each.
|
|
383
|
+
|
|
384
|
+
### Phase RT3 — Rebuild Startup
|
|
385
|
+
|
|
386
|
+
Trigger the `.mdd/.startup.md` rebuild (same logic as Status Mode — rebuild auto-generated zone, preserve Notes zone). The rebuilt startup now reflects tags on every feature and ops line.
|
|
387
|
+
|
|
388
|
+
### Phase RT4 — Report
|
|
389
|
+
|
|
390
|
+
```
|
|
391
|
+
✅ Rebuild Tags Complete
|
|
392
|
+
|
|
393
|
+
Feature docs processed: <N>
|
|
394
|
+
Ops runbooks processed: <N>
|
|
395
|
+
Tags generated: <N> docs
|
|
396
|
+
Tags skipped (present): <N> docs
|
|
397
|
+
|
|
398
|
+
.startup.md rebuilt with tag format:
|
|
399
|
+
- 01-docs-site (complete) [github-pages, documentation, landing-page, user-guide]
|
|
400
|
+
- 03-install-local-flag (complete) [cli, install, local-install, flags]
|
|
401
|
+
...
|
|
402
|
+
|
|
403
|
+
Run /mdd status to see the full updated startup snapshot.
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
---
|
package/commands/mdd-ops.md
CHANGED
package/commands/mdd-plan.md
CHANGED
|
@@ -2,6 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
Triggered when arguments start with `plan-initiative`. Creates a new initiative doc.
|
|
4
4
|
|
|
5
|
+
### Phase PI0 — Branch Guard
|
|
6
|
+
|
|
7
|
+
Run before any file creation:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
BRANCH=$(git branch --show-current)
|
|
11
|
+
DIRTY=$(git status --porcelain)
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
- **On `main` or `master` with uncommitted changes** → STOP. Show the Scenario A prompt from mdd.md Branch Guard.
|
|
15
|
+
- **On `main` or `master`, clean** → auto-branch to `feat/init-<initiative-slug>`. If the slug is not yet known (title not asked), use `feat/mdd-initiative` as a temporary name and rename the branch after the title is collected.
|
|
16
|
+
- **On a feature branch** → working dirty is fine. Proceed — initiative planning docs belong on whatever branch is current.
|
|
17
|
+
- **Never proceed on main.** Hard block.
|
|
18
|
+
|
|
5
19
|
### Phase PI1 — Mode choice
|
|
6
20
|
|
|
7
21
|
Ask the user:
|
|
@@ -86,6 +100,18 @@ Triggered when arguments start with `plan-wave`. Takes a wave slug (e.g. `auth-s
|
|
|
86
100
|
|
|
87
101
|
### Phase PW1 — Load and validate
|
|
88
102
|
|
|
103
|
+
**Step 0 — Branch guard:**
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
BRANCH=$(git branch --show-current)
|
|
107
|
+
DIRTY=$(git status --porcelain)
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
- **On `main` or `master` with uncommitted changes** → STOP. Show Scenario A from mdd.md Branch Guard.
|
|
111
|
+
- **On `main` or `master`, clean** → auto-branch to `feat/<wave-slug>`.
|
|
112
|
+
- **On a feature branch** → proceed (planning docs belong on this branch).
|
|
113
|
+
- **Never proceed on main.** Hard block.
|
|
114
|
+
|
|
89
115
|
1. Parse `<wave-slug>` from arguments — hard stop *"Wave slug required. Usage: /mdd plan-wave <wave-slug>"* if missing.
|
|
90
116
|
2. Derive initiative slug: everything before `-wave-N` (e.g. `auth-system-wave-2` → `auth-system`).
|
|
91
117
|
3. Read `initiatives/<initiative-slug>.md` fresh from disk — hard stop *"Initiative does not exist: `initiatives/<slug>.md`"* if not found.
|
|
@@ -160,6 +186,30 @@ Triggered when arguments start with `plan-execute`. Runs the full MDD build flow
|
|
|
160
186
|
|
|
161
187
|
### Phase PE1 — Load and validate
|
|
162
188
|
|
|
189
|
+
**Step 0 — Branch guard (runs before everything else):**
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
BRANCH=$(git branch --show-current)
|
|
193
|
+
DIRTY=$(git status --porcelain)
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
- **On `main` or `master` with uncommitted changes** → STOP. Show the Scenario A prompt from the Branch Guard in mdd.md. Do not proceed until resolved.
|
|
197
|
+
- **On `main` or `master`, clean** → auto-branch to `feat/<wave-slug>` immediately. Report: `✅ Branched to feat/<wave-slug>`.
|
|
198
|
+
- **On a feature branch that doesn't match `<wave-slug>`** → mismatch. Show:
|
|
199
|
+
```
|
|
200
|
+
⚠️ Branch mismatch for wave execution.
|
|
201
|
+
|
|
202
|
+
Current branch: <branch-name>
|
|
203
|
+
Expected: feat/<wave-slug>
|
|
204
|
+
|
|
205
|
+
MDD expects one wave per branch. What would you like to do?
|
|
206
|
+
(a) Commit, merge to main, and branch fresh to feat/<wave-slug>
|
|
207
|
+
(b) Continue on this branch (not recommended — mixes work)
|
|
208
|
+
(c) Abort
|
|
209
|
+
```
|
|
210
|
+
Follow the same (a)/(b)/(c) logic as mdd-build.md Phase 0.
|
|
211
|
+
- **Never proceed on main.** This is a hard block regardless of clean/dirty state.
|
|
212
|
+
|
|
163
213
|
1. Parse `<wave-slug>` — hard stop *"Wave does not exist"* if `waves/<wave-slug>.md` not found.
|
|
164
214
|
2. Read the wave doc.
|
|
165
215
|
3. Derive and read the parent initiative — hard stop if not found.
|
package/commands/mdd.md
CHANGED
|
@@ -53,6 +53,11 @@ Framework: (unknown) | DB: (unknown) | Host: (unknown)
|
|
|
53
53
|
|
|
54
54
|
## Features Documented
|
|
55
55
|
(none yet — run /mdd <feature> to create your first doc)
|
|
56
|
+
Format once populated: - <id> (<status>) [tag1, tag2, ...]
|
|
57
|
+
|
|
58
|
+
## Ops Runbooks
|
|
59
|
+
(none yet — run /mdd ops <description> to create one)
|
|
60
|
+
Format once populated: - <slug> [tag1, tag2, ...]
|
|
56
61
|
|
|
57
62
|
## Last Audit
|
|
58
63
|
(no audit run yet — run /mdd audit to generate findings)
|
|
@@ -99,44 +104,100 @@ The user's full arguments are: **$ARGUMENTS**
|
|
|
99
104
|
|
|
100
105
|
Parse these arguments to determine the mode. **Before doing anything else, read the appropriate mode file listed below.** The mode file contains the complete instructions for that mode. When mode file instructions reference `$ARGUMENTS`, treat it as the arguments stated above.
|
|
101
106
|
|
|
102
|
-
Find the MDD commands directory by checking
|
|
107
|
+
Find the MDD commands directory by checking in this order:
|
|
108
|
+
1. `.claude/commands/` in the current project (local install via `mdd install --install-local`)
|
|
109
|
+
2. `~/.claude/commands/` (global install via `npm install -g @thedecipherist/mdd && mdd install`)
|
|
110
|
+
|
|
111
|
+
Use whichever path contains `mdd-audit.md`. Store it as `$MDD_DIR` and use it for all mode file reads below.
|
|
103
112
|
|
|
104
113
|
- If arguments start with `audit` →
|
|
105
|
-
**Read
|
|
114
|
+
**Read `$MDD_DIR/mdd-audit.md` then follow its AUDIT MODE instructions.**
|
|
106
115
|
|
|
107
|
-
- If arguments start with `status`, `note`, `scan`, `update`, or `
|
|
108
|
-
**Read
|
|
116
|
+
- If arguments start with `status`, `note`, `scan`, `update`, `deprecate`, or `rebuild-tags` →
|
|
117
|
+
**Read `$MDD_DIR/mdd-manage.md` then follow the relevant mode instructions.**
|
|
109
118
|
|
|
110
119
|
- If arguments start with `reverse-engineer`, `reverse`, `graph`, or `upgrade` →
|
|
111
|
-
**Read
|
|
120
|
+
**Read `$MDD_DIR/mdd-lifecycle.md` then follow the relevant mode instructions.**
|
|
112
121
|
|
|
113
122
|
- If arguments start with `plan-` →
|
|
114
|
-
**Read
|
|
123
|
+
**Read `$MDD_DIR/mdd-plan.md` then follow the relevant PLAN mode instructions.**
|
|
115
124
|
|
|
116
125
|
- If arguments start with `ops`, `runop`, `update-op`, or `commands` →
|
|
117
|
-
**Read
|
|
126
|
+
**Read `$MDD_DIR/mdd-ops.md` then follow the relevant OPS/COMMANDS mode instructions.**
|
|
118
127
|
|
|
119
128
|
- If arguments are empty → ask the user what they want to do (build a feature, run an audit, check status, etc.)
|
|
120
129
|
|
|
121
|
-
- Otherwise → **Read
|
|
130
|
+
- Otherwise → **Read `$MDD_DIR/mdd-build.md` then follow BUILD MODE instructions.**
|
|
122
131
|
|
|
123
132
|
---
|
|
124
133
|
|
|
125
|
-
##
|
|
134
|
+
## Branch Guard (All Modes)
|
|
126
135
|
|
|
127
|
-
**
|
|
136
|
+
**This guard is mandatory. MDD never creates or modifies files directly on `main` or `master`. No exceptions — not even for documentation, planning, or ops files.**
|
|
128
137
|
|
|
129
|
-
|
|
138
|
+
**If the user already chose a worktree in Step 0, skip entirely** — the worktree has its own dedicated branch.
|
|
139
|
+
|
|
140
|
+
Otherwise, before creating or modifying any files, run:
|
|
130
141
|
|
|
131
142
|
```bash
|
|
132
|
-
git branch --show-current
|
|
143
|
+
BRANCH=$(git branch --show-current)
|
|
144
|
+
DIRTY=$(git status --porcelain)
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
### Scenario A — On `main` or `master`, working tree has uncommitted changes
|
|
150
|
+
|
|
151
|
+
**STOP. Do not create or modify any file.**
|
|
152
|
+
|
|
133
153
|
```
|
|
154
|
+
🚫 MDD Branch Guard — cannot proceed on main with uncommitted changes.
|
|
155
|
+
|
|
156
|
+
Branch: main
|
|
157
|
+
Dirty: <N> file(s) modified / untracked
|
|
158
|
+
|
|
159
|
+
MDD never works directly on main, and uncommitted changes must be
|
|
160
|
+
resolved before branching safely.
|
|
161
|
+
|
|
162
|
+
Choose:
|
|
163
|
+
(a) Commit now — stage all changes and commit, then MDD auto-branches
|
|
164
|
+
(b) Stash now — git stash, then MDD auto-branches
|
|
165
|
+
(c) Abort — handle git manually, then re-run /mdd
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
- **(a) Commit:** `git add -A`, generate a short conventional commit message from the changed files, commit, then proceed to Scenario B.
|
|
169
|
+
- **(b) Stash:** `git stash`, then proceed to Scenario B.
|
|
170
|
+
- **(c) Abort:** stop entirely — do not create any files.
|
|
171
|
+
|
|
172
|
+
---
|
|
173
|
+
|
|
174
|
+
### Scenario B — On `main` or `master`, clean working tree
|
|
175
|
+
|
|
176
|
+
Auto-branch immediately — no user prompt. Derive the branch name from the active mode:
|
|
177
|
+
|
|
178
|
+
| Mode | Branch name |
|
|
179
|
+
|------|-------------|
|
|
180
|
+
| Build (`/mdd <feature>`) | `feat/<feature-slug>` |
|
|
181
|
+
| Audit (`/mdd audit`) | `fix/mdd-audit-<YYYY-MM-DD>` |
|
|
182
|
+
| plan-initiative | `feat/init-<initiative-slug>` |
|
|
183
|
+
| plan-wave | `feat/<wave-slug>` |
|
|
184
|
+
| plan-execute | `feat/<wave-slug>` |
|
|
185
|
+
| Any other mode | `feat/<slug-from-arguments>` |
|
|
186
|
+
|
|
187
|
+
Run `git checkout -b <branch-name>` and report:
|
|
188
|
+
```
|
|
189
|
+
✅ Branched to <branch-name> — proceeding with MDD.
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
### Scenario C — Already on a feature or fix branch
|
|
195
|
+
|
|
196
|
+
Working tree dirty (in-progress changes) is **expected and fine** — that work belongs on this branch.
|
|
197
|
+
|
|
198
|
+
Each mode's Phase 0 handles mismatch detection (does the new task belong on this branch?). See mdd-build.md Phase 0 and mdd-plan.md for details.
|
|
134
199
|
|
|
135
|
-
**
|
|
136
|
-
- If on `main` or `master`:
|
|
137
|
-
- Build mode: `git checkout -b feat/<feature-name>`
|
|
138
|
-
- Audit mode: `git checkout -b fix/mdd-audit-<date>`
|
|
139
|
-
- If already on a feature branch: proceed
|
|
200
|
+
**One hard rule:** A branch starting with `fix/mdd-audit-` is an audit branch. Build and plan modes must not reuse it — fall through to Scenario B naming instead.
|
|
140
201
|
|
|
141
202
|
---
|
|
142
203
|
|
package/dist/cli.js
CHANGED
|
@@ -5,6 +5,7 @@ import { readFileSync } from 'fs';
|
|
|
5
5
|
import { fileURLToPath } from 'url';
|
|
6
6
|
import { join, dirname } from 'path';
|
|
7
7
|
import { cwd } from 'process';
|
|
8
|
+
import { homedir } from 'os';
|
|
8
9
|
const __filename = fileURLToPath(import.meta.url);
|
|
9
10
|
const __dirname = dirname(__filename);
|
|
10
11
|
const pkg = JSON.parse(readFileSync(join(__dirname, '../package.json'), 'utf-8'));
|
|
@@ -23,7 +24,13 @@ program
|
|
|
23
24
|
const dirExplicit = this.getOptionValueSource('dir') === 'cli';
|
|
24
25
|
const local = options.installLocal && !dirExplicit;
|
|
25
26
|
const effectiveDir = local ? join(cwd(), '.claude/commands') : options.dir;
|
|
26
|
-
|
|
27
|
+
const claudeMdPath = dirExplicit ? undefined
|
|
28
|
+
: local ? join(cwd(), 'CLAUDE.md')
|
|
29
|
+
: join(homedir(), '.claude', 'CLAUDE.md');
|
|
30
|
+
const settingsPath = dirExplicit ? undefined
|
|
31
|
+
: local ? join(cwd(), '.claude', 'settings.json')
|
|
32
|
+
: join(homedir(), '.claude', 'settings.json');
|
|
33
|
+
install({ dir: effectiveDir, force: options.force, local, claudeMdPath, settingsPath });
|
|
27
34
|
});
|
|
28
35
|
program
|
|
29
36
|
.command('update')
|
|
@@ -34,7 +41,13 @@ program
|
|
|
34
41
|
const dirExplicit = this.getOptionValueSource('dir') === 'cli';
|
|
35
42
|
const local = options.installLocal && !dirExplicit;
|
|
36
43
|
const effectiveDir = local ? join(cwd(), '.claude/commands') : options.dir;
|
|
37
|
-
|
|
44
|
+
const claudeMdPath = dirExplicit ? undefined
|
|
45
|
+
: local ? join(cwd(), 'CLAUDE.md')
|
|
46
|
+
: join(homedir(), '.claude', 'CLAUDE.md');
|
|
47
|
+
const settingsPath = dirExplicit ? undefined
|
|
48
|
+
: local ? join(cwd(), '.claude', 'settings.json')
|
|
49
|
+
: join(homedir(), '.claude', 'settings.json');
|
|
50
|
+
install({ dir: effectiveDir, force: true, local, claudeMdPath, settingsPath });
|
|
38
51
|
});
|
|
39
52
|
program.parse();
|
|
40
53
|
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACrC,OAAO,EAAE,GAAG,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/install.d.ts
CHANGED
package/dist/install.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../src/install.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../src/install.ts"],"names":[],"mappings":"AAQA,UAAU,cAAc;IACtB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAUD,wBAAgB,OAAO,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI,CAkGrD"}
|
package/dist/install.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import { copyFileSync, mkdirSync, existsSync, readdirSync, readFileSync } from 'fs';
|
|
2
|
-
import { join, resolve } from 'path';
|
|
1
|
+
import { copyFileSync, mkdirSync, existsSync, readdirSync, readFileSync, writeFileSync, appendFileSync, chmodSync } from 'fs';
|
|
2
|
+
import { join, resolve, dirname } from 'path';
|
|
3
3
|
import { homedir } from 'os';
|
|
4
4
|
import { fileURLToPath } from 'url';
|
|
5
|
-
import { dirname } from 'path';
|
|
6
5
|
const __filename = fileURLToPath(import.meta.url);
|
|
7
6
|
const __dirname = dirname(__filename);
|
|
8
7
|
export function install(options) {
|
|
@@ -76,6 +75,26 @@ export function install(options) {
|
|
|
76
75
|
if (options.local) {
|
|
77
76
|
console.log(' Tip: add .claude/commands/ to your .gitignore to keep these files out of git.\n');
|
|
78
77
|
}
|
|
78
|
+
if (options.claudeMdPath) {
|
|
79
|
+
const claudeResult = injectClaudeGuidance(resolve(options.claudeMdPath.replace('~', homedir())));
|
|
80
|
+
const icon = claudeResult.status === 'error' ? '✗' : claudeResult.status === 'skipped' ? '·' : '✓';
|
|
81
|
+
console.log(` ${icon} CLAUDE.md — ${claudeResult.message}`);
|
|
82
|
+
console.log('');
|
|
83
|
+
}
|
|
84
|
+
if (options.settingsPath) {
|
|
85
|
+
const hookScriptSrc = join(srcDir, 'mdd-branch-guard.sh');
|
|
86
|
+
const hooksDir = join(resolve(options.settingsPath.replace('~', homedir()), '..'), 'hooks');
|
|
87
|
+
const hookScriptDest = join(hooksDir, 'mdd-branch-guard.sh');
|
|
88
|
+
const hookResult = installHook({
|
|
89
|
+
hookScriptSrc,
|
|
90
|
+
hookScriptDest,
|
|
91
|
+
settingsPath: resolve(options.settingsPath.replace('~', homedir())),
|
|
92
|
+
local: options.local ?? false,
|
|
93
|
+
});
|
|
94
|
+
const icon = hookResult.status === 'error' ? '✗' : hookResult.status === 'skipped' ? '·' : '✓';
|
|
95
|
+
console.log(` ${icon} Branch Guard hook — ${hookResult.message}`);
|
|
96
|
+
console.log('');
|
|
97
|
+
}
|
|
79
98
|
console.log('Open Claude Code and run /mdd to get started.\n');
|
|
80
99
|
}
|
|
81
100
|
function getMddVersion(content) {
|
|
@@ -91,4 +110,104 @@ function getPackageVersion() {
|
|
|
91
110
|
return 'unknown';
|
|
92
111
|
}
|
|
93
112
|
}
|
|
113
|
+
const CLAUDE_GUIDANCE_MARKER = '## MDD — Manual-First Development';
|
|
114
|
+
const CLAUDE_GUIDANCE_BLOCK = `
|
|
115
|
+
## MDD — Manual-First Development
|
|
116
|
+
|
|
117
|
+
If a \`.mdd/\` directory exists in the current project, apply this logic whenever
|
|
118
|
+
the user asks you to implement, build, modify, deploy, or automate something —
|
|
119
|
+
and they have NOT used \`/mdd\` to initiate the request:
|
|
120
|
+
|
|
121
|
+
**Step 1 — Does it already exist?**
|
|
122
|
+
Scan \`.mdd/.startup.md\` (Features AND Ops Runbooks sections). Do any tags or
|
|
123
|
+
names match what the user is asking about?
|
|
124
|
+
→ Feature match: "This looks related to \`<NN>-<feature-name>\`. Want to use
|
|
125
|
+
\`/mdd update <NN>\` to modify it, or \`/mdd audit <NN>\` to review it first?"
|
|
126
|
+
→ Ops match: "You already have a \`<slug>\` runbook for this. Want to run it
|
|
127
|
+
with \`/mdd runop <slug>\` or update it with \`/mdd update-op <slug>\`?"
|
|
128
|
+
|
|
129
|
+
**Step 2 — What kind of request is it?**
|
|
130
|
+
|
|
131
|
+
Infrastructure or ops? (deploy, CI/CD, Docker, commit hooks, pipelines,
|
|
132
|
+
cron jobs, webhooks, DNS, SSL, rollback, health checks, server config)
|
|
133
|
+
→ "This sounds like an ops procedure. Want to document it as a repeatable
|
|
134
|
+
runbook with \`/mdd ops <description>\`?"
|
|
135
|
+
|
|
136
|
+
Feature work touching 3+ independent concerns?
|
|
137
|
+
→ "This looks initiative-scale. Want to plan it with \`/mdd plan-initiative\`?"
|
|
138
|
+
|
|
139
|
+
Single feature or bounded change?
|
|
140
|
+
→ "Want me to use \`/mdd <description>\` to build this with docs and tests first?"
|
|
141
|
+
|
|
142
|
+
Always ask — never auto-invoke. If the user says no, proceed as normal.
|
|
143
|
+
|
|
144
|
+
Skip entirely for: bug fixes, typos, config tweaks, single-line changes,
|
|
145
|
+
one-off shell commands.
|
|
146
|
+
`;
|
|
147
|
+
function installHook(opts) {
|
|
148
|
+
try {
|
|
149
|
+
// Install the hook script
|
|
150
|
+
mkdirSync(dirname(opts.hookScriptDest), { recursive: true });
|
|
151
|
+
copyFileSync(opts.hookScriptSrc, opts.hookScriptDest);
|
|
152
|
+
chmodSync(opts.hookScriptDest, 0o755);
|
|
153
|
+
// Derive hook command — local uses relative path, global uses $HOME
|
|
154
|
+
const hookCommand = opts.local
|
|
155
|
+
? 'bash .claude/hooks/mdd-branch-guard.sh'
|
|
156
|
+
: 'bash $HOME/.claude/hooks/mdd-branch-guard.sh';
|
|
157
|
+
const HOOK_MARKER = 'mdd-branch-guard';
|
|
158
|
+
// Read existing settings.json or start fresh
|
|
159
|
+
let settings = {};
|
|
160
|
+
if (existsSync(opts.settingsPath)) {
|
|
161
|
+
try {
|
|
162
|
+
settings = JSON.parse(readFileSync(opts.settingsPath, 'utf-8'));
|
|
163
|
+
}
|
|
164
|
+
catch {
|
|
165
|
+
// Unparseable settings — leave existing file alone to avoid corruption
|
|
166
|
+
return { status: 'error', message: `could not parse ${opts.settingsPath}` };
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
// Check if hook already registered
|
|
170
|
+
const hooksSection = settings['hooks'];
|
|
171
|
+
const preToolUse = (hooksSection?.['PreToolUse'] ?? []);
|
|
172
|
+
const alreadyInstalled = preToolUse.some(group => {
|
|
173
|
+
const hooks = group['hooks'];
|
|
174
|
+
return hooks?.some(h => String(h['command'] ?? '').includes(HOOK_MARKER));
|
|
175
|
+
});
|
|
176
|
+
if (alreadyInstalled) {
|
|
177
|
+
return { status: 'skipped', message: 'already registered in settings.json' };
|
|
178
|
+
}
|
|
179
|
+
// Merge hook entry into PreToolUse
|
|
180
|
+
const newEntry = {
|
|
181
|
+
matcher: 'Write|Edit|NotebookEdit',
|
|
182
|
+
hooks: [{ type: 'command', command: hookCommand }],
|
|
183
|
+
};
|
|
184
|
+
settings['hooks'] = {
|
|
185
|
+
...(hooksSection ?? {}),
|
|
186
|
+
PreToolUse: [...preToolUse, newEntry],
|
|
187
|
+
};
|
|
188
|
+
writeFileSync(opts.settingsPath, JSON.stringify(settings, null, 2) + '\n', 'utf-8');
|
|
189
|
+
return { status: 'installed', message: `hook registered in ${opts.settingsPath}` };
|
|
190
|
+
}
|
|
191
|
+
catch (err) {
|
|
192
|
+
return { status: 'error', message: String(err) };
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
function injectClaudeGuidance(claudeMdPath) {
|
|
196
|
+
try {
|
|
197
|
+
if (existsSync(claudeMdPath)) {
|
|
198
|
+
const existing = readFileSync(claudeMdPath, 'utf-8');
|
|
199
|
+
if (existing.includes(CLAUDE_GUIDANCE_MARKER)) {
|
|
200
|
+
return { status: 'skipped', message: 'guidance already present' };
|
|
201
|
+
}
|
|
202
|
+
appendFileSync(claudeMdPath, CLAUDE_GUIDANCE_BLOCK, 'utf-8');
|
|
203
|
+
}
|
|
204
|
+
else {
|
|
205
|
+
writeFileSync(claudeMdPath, CLAUDE_GUIDANCE_BLOCK.trimStart(), 'utf-8');
|
|
206
|
+
}
|
|
207
|
+
return { status: 'injected', message: 'guidance injected' };
|
|
208
|
+
}
|
|
209
|
+
catch (err) {
|
|
210
|
+
return { status: 'error', message: String(err) };
|
|
211
|
+
}
|
|
212
|
+
}
|
|
94
213
|
//# sourceMappingURL=install.js.map
|
package/dist/install.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"install.js","sourceRoot":"","sources":["../src/install.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"install.js","sourceRoot":"","sources":["../src/install.ts"],"names":[],"mappings":"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"}
|