dw-kit 1.2.0 → 1.3.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/.claude/hooks/post-write.sh +64 -58
- package/.claude/hooks/pre-commit-gate.sh +96 -90
- package/.claude/hooks/privacy-block.sh +99 -94
- package/.claude/hooks/progress-ping.sh +53 -47
- package/.claude/hooks/safety-guard.sh +60 -54
- package/.claude/hooks/scout-block.sh +88 -82
- package/.claude/hooks/session-init.sh +91 -74
- package/.claude/hooks/stop-check.sh +88 -36
- package/.claude/hooks/telemetry-log.sh +34 -0
- package/.claude/rules/code-style.md +37 -37
- package/.claude/rules/commit-standards.md +37 -37
- package/.claude/rules/dw.md +136 -0
- package/.claude/settings.json +120 -99
- package/.claude/skills/dw-arch-review/SKILL.md +119 -119
- package/.claude/skills/dw-archive/SKILL.md +81 -81
- package/.claude/skills/dw-commit/SKILL.md +81 -81
- package/.claude/skills/dw-config-init/SKILL.md +91 -91
- package/.claude/skills/dw-config-validate/SKILL.md +75 -75
- package/.claude/skills/dw-dashboard/SKILL.md +209 -209
- package/.claude/skills/dw-debug/SKILL.md +97 -97
- package/.claude/skills/dw-decision/SKILL.md +116 -0
- package/.claude/skills/dw-docs-update/SKILL.md +125 -125
- package/.claude/skills/dw-estimate/SKILL.md +90 -90
- package/.claude/skills/dw-execute/SKILL.md +98 -98
- package/.claude/skills/dw-flow/SKILL.md +274 -274
- package/.claude/skills/dw-handoff/SKILL.md +81 -81
- package/.claude/skills/dw-kit-report/SKILL.md +152 -152
- package/.claude/skills/dw-log-work/SKILL.md +69 -69
- package/.claude/skills/dw-onboard/SKILL.md +201 -201
- package/.claude/skills/dw-plan/SKILL.md +125 -125
- package/.claude/skills/dw-prompt/SKILL.md +62 -62
- package/.claude/skills/dw-requirements/SKILL.md +98 -98
- package/.claude/skills/dw-research/SKILL.md +114 -114
- package/.claude/skills/dw-retroactive/SKILL.md +311 -311
- package/.claude/skills/dw-review/SKILL.md +66 -66
- package/.claude/skills/dw-rollback/SKILL.md +90 -90
- package/.claude/skills/dw-sprint-review/SKILL.md +99 -99
- package/.claude/skills/dw-task-init/SKILL.md +59 -59
- package/.claude/skills/dw-test-plan/SKILL.md +113 -113
- package/.claude/skills/dw-thinking/SKILL.md +70 -70
- package/.claude/skills/dw-upgrade/SKILL.md +72 -72
- package/.dw/config/dw.config.yml +82 -82
- package/.dw/core/PILLARS.md +122 -0
- package/.dw/core/templates/v2/spec.md +68 -0
- package/.dw/core/templates/v2/tracking.md +62 -0
- package/.dw/core/v14-evaluation-protocol.md +118 -0
- package/CLAUDE.md +42 -39
- package/MIGRATION-v1.3.md +201 -0
- package/README.md +43 -6
- package/package.json +86 -84
- package/src/cli.mjs +45 -9
- package/src/commands/dashboard.mjs +116 -0
- package/src/commands/doctor.mjs +165 -149
- package/src/commands/init.mjs +339 -332
- package/src/commands/metrics.mjs +165 -0
- package/src/commands/upgrade.mjs +297 -262
- package/src/lib/active-index.mjs +87 -0
- package/src/lib/copy.mjs +118 -110
- package/src/lib/cut-analysis.mjs +161 -0
- package/src/lib/telemetry.mjs +80 -0
- package/.claude/rules/dw-core.md +0 -100
- package/.claude/rules/dw-skills.md +0 -53
- package/.claude/rules/workflow-rules.md +0 -77
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
> An AI development workflow toolkit for teams using agentic IDEs (Claude Code, Cursor) — from idea to review-ready commits.
|
|
4
4
|
|
|
5
|
-
**v1.
|
|
5
|
+
**v1.3** · `npm install -g dw-kit` · [Docs](docs/README.md) · [Get started](docs/get-started.md) · [Cheatsheet](docs/cheatsheet.md) · [Migration v1.3](MIGRATION-v1.3.md) · [Changelog](CHANGELOG.md)
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
@@ -34,6 +34,14 @@ It’s designed for collaboration (Dev / Tech Lead / QA / PM) and keeps work aud
|
|
|
34
34
|
|
|
35
35
|
---
|
|
36
36
|
|
|
37
|
+
## Release notes
|
|
38
|
+
|
|
39
|
+
- v1.2.0 notes: [`CHANGELOG.md#v120--2026-04-09`](CHANGELOG.md#v120--2026-04-09)
|
|
40
|
+
- Full changelog: `CHANGELOG.md`
|
|
41
|
+
- Latest release notes: [GitHub Releases](https://github.com/dv-workflow/dv-workflow/releases)
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
37
45
|
## Install
|
|
38
46
|
|
|
39
47
|
```bash
|
|
@@ -53,7 +61,7 @@ dw init
|
|
|
53
61
|
Then in **Claude Code CLI**, run the full workflow:
|
|
54
62
|
|
|
55
63
|
```
|
|
56
|
-
/dw
|
|
64
|
+
/dw:flow your-task-or-anythings
|
|
57
65
|
```
|
|
58
66
|
|
|
59
67
|
---
|
|
@@ -61,18 +69,21 @@ Then in **Claude Code CLI**, run the full workflow:
|
|
|
61
69
|
Discover other skills:
|
|
62
70
|
|
|
63
71
|
```
|
|
64
|
-
/dw
|
|
65
|
-
/dw
|
|
72
|
+
/dw:prompt
|
|
73
|
+
/dw:thinking
|
|
74
|
+
/dw:decision
|
|
66
75
|
...
|
|
67
|
-
|
|
68
76
|
```
|
|
69
77
|
|
|
78
|
+
> **v1.3 note**: Slash commands switched from `/dw-*` to `/dw:*` (namespace convention). See [MIGRATION-v1.3.md](MIGRATION-v1.3.md).
|
|
79
|
+
|
|
70
80
|
---
|
|
71
81
|
|
|
72
82
|
## CLI commands
|
|
73
83
|
|
|
74
84
|
```bash
|
|
75
85
|
dw init # setup wizard / presets
|
|
86
|
+
dw init --solo # zero-config solo dev setup (v1.3)
|
|
76
87
|
dw validate # validate .dw/config/dw.config.yml
|
|
77
88
|
dw doctor # installation health check
|
|
78
89
|
dw upgrade # update toolkit files (override-aware)
|
|
@@ -80,6 +91,9 @@ dw upgrade --check # check for updates only
|
|
|
80
91
|
dw upgrade --dry-run # preview changes
|
|
81
92
|
dw prompt # build a well-structured task prompt (autocomplete + wizard)
|
|
82
93
|
dw prompt --text "..." # non-interactive: structure a description directly
|
|
94
|
+
dw active # regenerate .dw/tasks/ACTIVE.md index (v1.3)
|
|
95
|
+
dw metrics # inspect local telemetry (v1.3, opt-out via DW_NO_TELEMETRY=1)
|
|
96
|
+
dw dashboard # active tasks + ADRs + telemetry summary (v1.3)
|
|
83
97
|
dw claude-vn-fix # patch Claude CLI to fix Vietnamese IME (backup/restore)
|
|
84
98
|
```
|
|
85
99
|
|
|
@@ -109,11 +123,34 @@ workflow:
|
|
|
109
123
|
## What gets added to your repo?
|
|
110
124
|
|
|
111
125
|
```
|
|
112
|
-
.dw/
|
|
126
|
+
.dw/
|
|
127
|
+
core/ methodology + PILLARS.md
|
|
128
|
+
config/ dw.config.yml (+ optional .local.yml)
|
|
129
|
+
decisions/ ADRs (v1.3) — architectural decision records
|
|
130
|
+
tasks/ task docs + ACTIVE.md index (v1.3)
|
|
131
|
+
metrics/ local telemetry (v1.3, opt-out)
|
|
113
132
|
.claude/ # Claude Code: skills, hooks, agents, rules
|
|
114
133
|
CLAUDE.md # project context for the agent
|
|
115
134
|
```
|
|
116
135
|
|
|
117
136
|
---
|
|
118
137
|
|
|
138
|
+
## 5-pillar architecture (v1.3+)
|
|
139
|
+
|
|
140
|
+
dw-kit is a **context-first governance layer** on top of your AI agent — not a prescriptive workflow engine. Five pillars, verb-based:
|
|
141
|
+
|
|
142
|
+
| Pillar | Purpose | Examples |
|
|
143
|
+
|--------|---------|----------|
|
|
144
|
+
| **Guards** | Safety before action | `safety-guard`, `privacy-block`, `pre-commit-gate` |
|
|
145
|
+
| **Surfaces** | Make state visible | `ACTIVE.md`, `dw dashboard`, `project-map.md` |
|
|
146
|
+
| **Records** | Preserve memory | ADRs in `.dw/decisions/`, task docs |
|
|
147
|
+
| **Bridges** | Continuity across sessions/roles | `session-init`, auto-handoff in `tracking.md` |
|
|
148
|
+
| **Tunes** | Adapt to team shape | presets (`solo`, `team`, `enterprise`), config flags |
|
|
149
|
+
|
|
150
|
+
Full spec: [`.dw/core/PILLARS.md`](.dw/core/PILLARS.md)
|
|
151
|
+
|
|
152
|
+
**Design principle — obsolescence test**: Every feature must answer "will this be *more* valuable when AI is smarter?" If no → cut or defer.
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
119
156
|
Maintainer: [huygdv](mailto:huygdv19@gmail.com)
|
package/package.json
CHANGED
|
@@ -1,84 +1,86 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "dw-kit",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "AI development workflow toolkit — structured, quality-assured, team-ready. From requirements to dashboard.",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"bin": {
|
|
7
|
-
"dw": "bin/dw.mjs"
|
|
8
|
-
},
|
|
9
|
-
"files": [
|
|
10
|
-
"bin/",
|
|
11
|
-
"src/cli.mjs",
|
|
12
|
-
"src/commands/",
|
|
13
|
-
"src/lib/",
|
|
14
|
-
".dw/core/",
|
|
15
|
-
".dw/config/",
|
|
16
|
-
".dw/adapters/",
|
|
17
|
-
".claude/agents/",
|
|
18
|
-
".claude/hooks/",
|
|
19
|
-
".claude/rules/",
|
|
20
|
-
".claude/skills/dw-arch-review/",
|
|
21
|
-
".claude/skills/dw-archive/",
|
|
22
|
-
".claude/skills/dw-commit/",
|
|
23
|
-
".claude/skills/dw-config-init/",
|
|
24
|
-
".claude/skills/dw-config-validate/",
|
|
25
|
-
".claude/skills/dw-dashboard/",
|
|
26
|
-
".claude/skills/dw-debug/",
|
|
27
|
-
".claude/skills/dw-
|
|
28
|
-
".claude/skills/dw-
|
|
29
|
-
".claude/skills/dw-
|
|
30
|
-
".claude/skills/dw-
|
|
31
|
-
".claude/skills/dw-
|
|
32
|
-
".claude/skills/dw-
|
|
33
|
-
".claude/skills/dw-
|
|
34
|
-
".claude/skills/dw-
|
|
35
|
-
".claude/skills/dw-
|
|
36
|
-
".claude/skills/dw-
|
|
37
|
-
".claude/skills/dw-
|
|
38
|
-
".claude/skills/dw-
|
|
39
|
-
".claude/skills/dw-
|
|
40
|
-
".claude/skills/dw-
|
|
41
|
-
".claude/skills/dw-
|
|
42
|
-
".claude/skills/dw-
|
|
43
|
-
".claude/skills/dw-
|
|
44
|
-
".claude/skills/dw-
|
|
45
|
-
".claude/skills/dw-
|
|
46
|
-
".claude/skills/dw-
|
|
47
|
-
".claude/
|
|
48
|
-
".claude/
|
|
49
|
-
"
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
"test
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
"
|
|
63
|
-
"
|
|
64
|
-
"
|
|
65
|
-
"
|
|
66
|
-
"
|
|
67
|
-
"
|
|
68
|
-
"
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
"
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
"
|
|
81
|
-
"
|
|
82
|
-
"
|
|
83
|
-
|
|
84
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "dw-kit",
|
|
3
|
+
"version": "1.3.0",
|
|
4
|
+
"description": "AI development workflow toolkit — structured, quality-assured, team-ready. From requirements to dashboard.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"dw": "bin/dw.mjs"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"bin/",
|
|
11
|
+
"src/cli.mjs",
|
|
12
|
+
"src/commands/",
|
|
13
|
+
"src/lib/",
|
|
14
|
+
".dw/core/",
|
|
15
|
+
".dw/config/",
|
|
16
|
+
".dw/adapters/",
|
|
17
|
+
".claude/agents/",
|
|
18
|
+
".claude/hooks/",
|
|
19
|
+
".claude/rules/",
|
|
20
|
+
".claude/skills/dw-arch-review/",
|
|
21
|
+
".claude/skills/dw-archive/",
|
|
22
|
+
".claude/skills/dw-commit/",
|
|
23
|
+
".claude/skills/dw-config-init/",
|
|
24
|
+
".claude/skills/dw-config-validate/",
|
|
25
|
+
".claude/skills/dw-dashboard/",
|
|
26
|
+
".claude/skills/dw-debug/",
|
|
27
|
+
".claude/skills/dw-decision/",
|
|
28
|
+
".claude/skills/dw-docs-update/",
|
|
29
|
+
".claude/skills/dw-estimate/",
|
|
30
|
+
".claude/skills/dw-execute/",
|
|
31
|
+
".claude/skills/dw-flow/",
|
|
32
|
+
".claude/skills/dw-handoff/",
|
|
33
|
+
".claude/skills/dw-kit-report/",
|
|
34
|
+
".claude/skills/dw-log-work/",
|
|
35
|
+
".claude/skills/dw-onboard/",
|
|
36
|
+
".claude/skills/dw-plan/",
|
|
37
|
+
".claude/skills/dw-prompt/",
|
|
38
|
+
".claude/skills/dw-requirements/",
|
|
39
|
+
".claude/skills/dw-research/",
|
|
40
|
+
".claude/skills/dw-retroactive/",
|
|
41
|
+
".claude/skills/dw-review/",
|
|
42
|
+
".claude/skills/dw-rollback/",
|
|
43
|
+
".claude/skills/dw-sprint-review/",
|
|
44
|
+
".claude/skills/dw-task-init/",
|
|
45
|
+
".claude/skills/dw-test-plan/",
|
|
46
|
+
".claude/skills/dw-thinking/",
|
|
47
|
+
".claude/skills/dw-upgrade/",
|
|
48
|
+
".claude/templates/",
|
|
49
|
+
".claude/settings.json",
|
|
50
|
+
"CLAUDE.md",
|
|
51
|
+
"MIGRATION-v1.3.md"
|
|
52
|
+
],
|
|
53
|
+
"engines": {
|
|
54
|
+
"node": ">=18"
|
|
55
|
+
},
|
|
56
|
+
"scripts": {
|
|
57
|
+
"test": "node src/smoke-test.mjs",
|
|
58
|
+
"link": "npm link",
|
|
59
|
+
"test:e2e-local": "bash scripts/e2e-local-check.sh"
|
|
60
|
+
},
|
|
61
|
+
"keywords": [
|
|
62
|
+
"ai",
|
|
63
|
+
"workflow",
|
|
64
|
+
"claude",
|
|
65
|
+
"cursor",
|
|
66
|
+
"development",
|
|
67
|
+
"toolkit",
|
|
68
|
+
"tdd",
|
|
69
|
+
"code-review",
|
|
70
|
+
"agent"
|
|
71
|
+
],
|
|
72
|
+
"author": "huygdv <huygdv19@gmail.com>",
|
|
73
|
+
"license": "MIT",
|
|
74
|
+
"repository": {
|
|
75
|
+
"type": "git",
|
|
76
|
+
"url": "git+https://github.com/dv-workflow/dv-workflow.git"
|
|
77
|
+
},
|
|
78
|
+
"homepage": "https://github.com/dv-workflow/dv-workflow#readme",
|
|
79
|
+
"dependencies": {
|
|
80
|
+
"ajv": "^8.18.0",
|
|
81
|
+
"chalk": "^5.6.2",
|
|
82
|
+
"commander": "^14.0.3",
|
|
83
|
+
"enquirer": "^2.4.1",
|
|
84
|
+
"js-yaml": "^4.1.1"
|
|
85
|
+
}
|
|
86
|
+
}
|
package/src/cli.mjs
CHANGED
|
@@ -9,11 +9,14 @@ const __filename = fileURLToPath(import.meta.url);
|
|
|
9
9
|
const __dirname = dirname(__filename);
|
|
10
10
|
const require = createRequire(import.meta.url);
|
|
11
11
|
const pkg = require(join(__dirname, '..', 'package.json'));
|
|
12
|
+
const RELEASES_URL = 'https://github.com/dv-workflow/dv-workflow/releases';
|
|
12
13
|
|
|
13
14
|
export function run(argv) {
|
|
14
|
-
//
|
|
15
|
-
|
|
15
|
+
// Schedule fresh check in background (non-blocking).
|
|
16
|
+
// Notice is shown via process.on('exit') so it always appears AFTER command output,
|
|
17
|
+
// even when commands call process.exit() internally.
|
|
16
18
|
scheduleUpdateCheck(pkg.version);
|
|
19
|
+
const latestVersion = getUpdateNotice(pkg.version);
|
|
17
20
|
|
|
18
21
|
const program = new Command();
|
|
19
22
|
|
|
@@ -25,7 +28,8 @@ export function run(argv) {
|
|
|
25
28
|
program
|
|
26
29
|
.command('init')
|
|
27
30
|
.description('Setup dw-kit in current project (interactive wizard)')
|
|
28
|
-
.option('-p, --preset <name>', 'Use preset: solo-quick | small-team | enterprise')
|
|
31
|
+
.option('-p, --preset <name>', 'Use preset: solo | solo-quick | small-team | team | enterprise')
|
|
32
|
+
.option('--solo', 'Shortcut for --preset solo (zero-config setup)')
|
|
29
33
|
.option('-a, --adapter <platform>', 'Target platform: claude-cli | cursor | generic', 'claude-cli')
|
|
30
34
|
.option('-s, --silent', 'Non-interactive mode (reads DW_NAME, DW_DEPTH, DW_ROLES, DW_LANG env vars)')
|
|
31
35
|
.action(async (opts) => {
|
|
@@ -70,6 +74,33 @@ export function run(argv) {
|
|
|
70
74
|
await promptCommand(opts);
|
|
71
75
|
});
|
|
72
76
|
|
|
77
|
+
program
|
|
78
|
+
.command('metrics [sub]')
|
|
79
|
+
.description('Inspect local telemetry (show | cut-analysis | clear). Default: show')
|
|
80
|
+
.option('--since <date>', 'Filter events since ISO date (YYYY-MM-DD)')
|
|
81
|
+
.option('--skill <name>', 'Filter by skill name')
|
|
82
|
+
.action(async (sub, opts) => {
|
|
83
|
+
const { metricsCommand } = await import('./commands/metrics.mjs');
|
|
84
|
+
await metricsCommand({ sub, ...opts });
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
program
|
|
88
|
+
.command('active')
|
|
89
|
+
.description('Regenerate .dw/tasks/ACTIVE.md index')
|
|
90
|
+
.action(async () => {
|
|
91
|
+
const { writeActiveIndex } = await import('./lib/active-index.mjs');
|
|
92
|
+
const target = writeActiveIndex();
|
|
93
|
+
console.log(chalk.green('✓') + ` Wrote ${target}`);
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
program
|
|
97
|
+
.command('dashboard')
|
|
98
|
+
.description('Show team dashboard — active tasks, ADRs, telemetry summary, health')
|
|
99
|
+
.action(async (opts) => {
|
|
100
|
+
const { dashboardCommand } = await import('./commands/dashboard.mjs');
|
|
101
|
+
await dashboardCommand(opts);
|
|
102
|
+
});
|
|
103
|
+
|
|
73
104
|
program
|
|
74
105
|
.command('claude-vn-fix')
|
|
75
106
|
.description('Patch Claude CLI to fix Vietnamese IME (local, with backup/restore)')
|
|
@@ -81,12 +112,17 @@ export function run(argv) {
|
|
|
81
112
|
await claudeVnFixCommand(opts);
|
|
82
113
|
});
|
|
83
114
|
|
|
84
|
-
program.parse(argv);
|
|
85
|
-
|
|
86
115
|
if (latestVersion) {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
116
|
+
// Register notice to print AFTER the command completes (on clean exit only)
|
|
117
|
+
process.on('exit', (code) => {
|
|
118
|
+
if (code !== 0) return;
|
|
119
|
+
console.log();
|
|
120
|
+
console.log(chalk.yellow(` ↑ Update available`) + ` v${pkg.version} → ` + chalk.green.bold(`v${latestVersion}`));
|
|
121
|
+
console.log(` Run ` + chalk.cyan(`npm install -g dw-kit`) + ` to update`);
|
|
122
|
+
console.log(` Changelog: ` + chalk.cyan(`${RELEASES_URL}/tag/v${latestVersion}`));
|
|
123
|
+
console.log();
|
|
124
|
+
});
|
|
91
125
|
}
|
|
126
|
+
|
|
127
|
+
program.parse(argv);
|
|
92
128
|
}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { readEvents, summarize } from '../lib/telemetry.mjs';
|
|
2
|
+
import { generateActiveIndex } from '../lib/active-index.mjs';
|
|
3
|
+
import { existsSync, readdirSync, readFileSync } from 'node:fs';
|
|
4
|
+
import { join } from 'node:path';
|
|
5
|
+
import { banner, log, info, warn, ok } from '../lib/ui.mjs';
|
|
6
|
+
import chalk from 'chalk';
|
|
7
|
+
|
|
8
|
+
export async function dashboardCommand(opts) {
|
|
9
|
+
banner('dw-kit Dashboard');
|
|
10
|
+
|
|
11
|
+
const rootDir = process.cwd();
|
|
12
|
+
|
|
13
|
+
log(chalk.bold('📋 Active Tasks'));
|
|
14
|
+
log('');
|
|
15
|
+
const activeContent = generateActiveIndex(rootDir);
|
|
16
|
+
const taskLines = activeContent.split('\n').filter((l) => l.startsWith('- `'));
|
|
17
|
+
if (taskLines.length === 0) {
|
|
18
|
+
log(' (none)');
|
|
19
|
+
} else {
|
|
20
|
+
taskLines.forEach((l) => log(' ' + l));
|
|
21
|
+
}
|
|
22
|
+
log('');
|
|
23
|
+
|
|
24
|
+
log(chalk.bold('🗂️ Decisions (ADRs)'));
|
|
25
|
+
log('');
|
|
26
|
+
const decisionsDir = join(rootDir, '.dw/decisions');
|
|
27
|
+
if (existsSync(decisionsDir)) {
|
|
28
|
+
const adrs = readdirSync(decisionsDir).filter((f) => /^\d{4}-.*\.md$/.test(f));
|
|
29
|
+
if (adrs.length === 0) {
|
|
30
|
+
log(' (none)');
|
|
31
|
+
} else {
|
|
32
|
+
adrs.sort().forEach((f) => {
|
|
33
|
+
try {
|
|
34
|
+
const content = readFileSync(join(decisionsDir, f), 'utf8');
|
|
35
|
+
const statusMatch = content.match(/^status:\s*(.+)$/m);
|
|
36
|
+
const titleMatch = content.match(/^title:\s*(.+)$/m);
|
|
37
|
+
const status = statusMatch ? statusMatch[1].trim() : 'unknown';
|
|
38
|
+
const title = titleMatch ? titleMatch[1].trim() : f;
|
|
39
|
+
const statusColor =
|
|
40
|
+
status === 'Accepted'
|
|
41
|
+
? chalk.green
|
|
42
|
+
: status.startsWith('Proposed')
|
|
43
|
+
? chalk.yellow
|
|
44
|
+
: status === 'Deprecated'
|
|
45
|
+
? chalk.gray
|
|
46
|
+
: chalk.white;
|
|
47
|
+
log(` ${chalk.cyan(f.replace(/\.md$/, ''))} · ${statusColor(status)}`);
|
|
48
|
+
log(` ${chalk.dim(title)}`);
|
|
49
|
+
} catch {
|
|
50
|
+
log(` ${f} · (unreadable)`);
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
} else {
|
|
55
|
+
log(' (decisions layer not initialized — run `/dw:decision` to create first ADR)');
|
|
56
|
+
}
|
|
57
|
+
log('');
|
|
58
|
+
|
|
59
|
+
log(chalk.bold('📊 Telemetry Summary'));
|
|
60
|
+
log('');
|
|
61
|
+
if (process.env.DW_NO_TELEMETRY === '1') {
|
|
62
|
+
warn('Telemetry disabled (DW_NO_TELEMETRY=1)');
|
|
63
|
+
} else {
|
|
64
|
+
const events = readEvents(rootDir);
|
|
65
|
+
if (events.length === 0) {
|
|
66
|
+
log(' No events yet. Use dw-kit normally to populate.');
|
|
67
|
+
} else {
|
|
68
|
+
const s = summarize(events);
|
|
69
|
+
log(` Total events: ${s.totalEvents}`);
|
|
70
|
+
if (s.dateRange) {
|
|
71
|
+
log(` Range: ${s.dateRange.from.slice(0, 10)} → ${s.dateRange.to.slice(0, 10)}`);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const topSkills = Object.entries(s.bySkill)
|
|
75
|
+
.sort((a, b) => b[1] - a[1])
|
|
76
|
+
.slice(0, 5);
|
|
77
|
+
if (topSkills.length > 0) {
|
|
78
|
+
log('');
|
|
79
|
+
log(chalk.dim(' Top 5 skills:'));
|
|
80
|
+
topSkills.forEach(([n, c]) => log(` ${c.toString().padStart(4)}× /${n}`));
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const topHooks = Object.entries(s.byHook)
|
|
84
|
+
.sort((a, b) => b[1] - a[1])
|
|
85
|
+
.slice(0, 5);
|
|
86
|
+
if (topHooks.length > 0) {
|
|
87
|
+
log('');
|
|
88
|
+
log(chalk.dim(' Top 5 hooks:'));
|
|
89
|
+
topHooks.forEach(([n, c]) => log(` ${c.toString().padStart(4)}× ${n}`));
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
log('');
|
|
94
|
+
|
|
95
|
+
log(chalk.bold('🔧 Health'));
|
|
96
|
+
log('');
|
|
97
|
+
const checks = [
|
|
98
|
+
{ path: '.dw/config/dw.config.yml', label: 'Config' },
|
|
99
|
+
{ path: '.dw/tasks/ACTIVE.md', label: 'ACTIVE index' },
|
|
100
|
+
{ path: '.dw/decisions', label: 'Decisions layer' },
|
|
101
|
+
{ path: '.claude/hooks/privacy-block.sh', label: 'Privacy guard' },
|
|
102
|
+
{ path: '.claude/hooks/pre-commit-gate.sh', label: 'Commit gate' },
|
|
103
|
+
];
|
|
104
|
+
|
|
105
|
+
for (const c of checks) {
|
|
106
|
+
const full = join(rootDir, c.path);
|
|
107
|
+
if (existsSync(full)) {
|
|
108
|
+
ok(`${c.label}: ${c.path}`);
|
|
109
|
+
} else {
|
|
110
|
+
warn(`${c.label}: missing (${c.path})`);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
log('');
|
|
115
|
+
info('Run `dw metrics show` for detailed telemetry, `dw doctor` for full health check.');
|
|
116
|
+
}
|