safeword 0.2.4 → 0.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (235) hide show
  1. package/dist/check-3NGQ4NR5.js +129 -0
  2. package/dist/check-3NGQ4NR5.js.map +1 -0
  3. package/dist/chunk-2XWIUEQK.js +190 -0
  4. package/dist/chunk-2XWIUEQK.js.map +1 -0
  5. package/dist/chunk-GZRQL3SX.js +146 -0
  6. package/dist/chunk-GZRQL3SX.js.map +1 -0
  7. package/dist/chunk-ORQHKDT2.js +10 -0
  8. package/dist/chunk-ORQHKDT2.js.map +1 -0
  9. package/dist/chunk-W66Z3C5H.js +21 -0
  10. package/dist/chunk-W66Z3C5H.js.map +1 -0
  11. package/dist/cli.d.ts +1 -0
  12. package/dist/cli.js +34 -0
  13. package/dist/cli.js.map +1 -0
  14. package/dist/diff-Y6QTAW4O.js +166 -0
  15. package/dist/diff-Y6QTAW4O.js.map +1 -0
  16. package/dist/index.d.ts +11 -0
  17. package/dist/index.js +7 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/reset-3ACTIYYE.js +143 -0
  20. package/dist/reset-3ACTIYYE.js.map +1 -0
  21. package/dist/setup-RR4M334C.js +266 -0
  22. package/dist/setup-RR4M334C.js.map +1 -0
  23. package/dist/upgrade-6AR3DHUV.js +134 -0
  24. package/dist/upgrade-6AR3DHUV.js.map +1 -0
  25. package/package.json +44 -19
  26. package/{.safeword → templates}/hooks/agents-md-check.sh +0 -0
  27. package/{.safeword → templates}/hooks/post-tool.sh +0 -0
  28. package/{.safeword → templates}/hooks/pre-commit.sh +0 -0
  29. package/.claude/commands/arch-review.md +0 -32
  30. package/.claude/commands/lint.md +0 -6
  31. package/.claude/commands/quality-review.md +0 -13
  32. package/.claude/commands/setup-linting.md +0 -6
  33. package/.claude/hooks/auto-lint.sh +0 -6
  34. package/.claude/hooks/auto-quality-review.sh +0 -170
  35. package/.claude/hooks/check-linting-sync.sh +0 -17
  36. package/.claude/hooks/inject-timestamp.sh +0 -6
  37. package/.claude/hooks/question-protocol.sh +0 -12
  38. package/.claude/hooks/run-linters.sh +0 -8
  39. package/.claude/hooks/run-quality-review.sh +0 -76
  40. package/.claude/hooks/version-check.sh +0 -10
  41. package/.claude/mcp/README.md +0 -96
  42. package/.claude/mcp/arcade.sample.json +0 -9
  43. package/.claude/mcp/context7.sample.json +0 -7
  44. package/.claude/mcp/playwright.sample.json +0 -7
  45. package/.claude/settings.json +0 -62
  46. package/.claude/skills/quality-reviewer/SKILL.md +0 -190
  47. package/.claude/skills/safeword-quality-reviewer/SKILL.md +0 -13
  48. package/.env.arcade.example +0 -4
  49. package/.env.example +0 -11
  50. package/.gitmodules +0 -4
  51. package/.safeword/SAFEWORD.md +0 -33
  52. package/.safeword/eslint/eslint-base.mjs +0 -101
  53. package/.safeword/guides/architecture-guide.md +0 -404
  54. package/.safeword/guides/code-philosophy.md +0 -174
  55. package/.safeword/guides/context-files-guide.md +0 -405
  56. package/.safeword/guides/data-architecture-guide.md +0 -183
  57. package/.safeword/guides/design-doc-guide.md +0 -165
  58. package/.safeword/guides/learning-extraction.md +0 -515
  59. package/.safeword/guides/llm-instruction-design.md +0 -239
  60. package/.safeword/guides/llm-prompting.md +0 -95
  61. package/.safeword/guides/tdd-best-practices.md +0 -570
  62. package/.safeword/guides/test-definitions-guide.md +0 -243
  63. package/.safeword/guides/testing-methodology.md +0 -573
  64. package/.safeword/guides/user-story-guide.md +0 -237
  65. package/.safeword/guides/zombie-process-cleanup.md +0 -214
  66. package/.safeword/planning/002-user-story-quality-evaluation.md +0 -1840
  67. package/.safeword/planning/003-langsmith-eval-setup-prompt.md +0 -363
  68. package/.safeword/planning/004-llm-eval-test-cases.md +0 -3226
  69. package/.safeword/planning/005-architecture-enforcement-system.md +0 -169
  70. package/.safeword/planning/006-reactive-fix-prevention-research.md +0 -135
  71. package/.safeword/planning/011-cli-ux-vision.md +0 -330
  72. package/.safeword/planning/012-project-structure-cleanup.md +0 -154
  73. package/.safeword/planning/README.md +0 -39
  74. package/.safeword/planning/automation-plan-v2.md +0 -1225
  75. package/.safeword/planning/automation-plan-v3.md +0 -1291
  76. package/.safeword/planning/automation-plan.md +0 -3058
  77. package/.safeword/planning/design/005-cli-implementation.md +0 -343
  78. package/.safeword/planning/design/013-cli-self-contained-templates.md +0 -596
  79. package/.safeword/planning/design/013a-eslint-plugin-suite.md +0 -256
  80. package/.safeword/planning/design/013b-implementation-snippets.md +0 -385
  81. package/.safeword/planning/design/013c-config-isolation-strategy.md +0 -242
  82. package/.safeword/planning/design/code-philosophy-improvements.md +0 -60
  83. package/.safeword/planning/mcp-analysis.md +0 -545
  84. package/.safeword/planning/phase2-subagents-vs-skills-analysis.md +0 -451
  85. package/.safeword/planning/settings-improvements.md +0 -970
  86. package/.safeword/planning/test-definitions/005-cli-implementation.md +0 -1301
  87. package/.safeword/planning/test-definitions/cli-self-contained-templates.md +0 -205
  88. package/.safeword/planning/user-stories/001-guides-review-user-stories.md +0 -1381
  89. package/.safeword/planning/user-stories/003-reactive-fix-prevention.md +0 -132
  90. package/.safeword/planning/user-stories/004-technical-constraints.md +0 -86
  91. package/.safeword/planning/user-stories/005-cli-implementation.md +0 -311
  92. package/.safeword/planning/user-stories/cli-self-contained-templates.md +0 -172
  93. package/.safeword/planning/versioned-distribution.md +0 -740
  94. package/.safeword/prompts/arch-review.md +0 -43
  95. package/.safeword/prompts/quality-review.md +0 -11
  96. package/.safeword/scripts/arch-review.sh +0 -235
  97. package/.safeword/scripts/check-linting-sync.sh +0 -58
  98. package/.safeword/scripts/setup-linting.sh +0 -559
  99. package/.safeword/templates/architecture-template.md +0 -136
  100. package/.safeword/templates/ci/architecture-check.yml +0 -79
  101. package/.safeword/templates/design-doc-template.md +0 -127
  102. package/.safeword/templates/test-definitions-feature.md +0 -100
  103. package/.safeword/templates/ticket-template.md +0 -74
  104. package/.safeword/templates/user-stories-template.md +0 -82
  105. package/.safeword/tickets/001-guides-review-user-stories.md +0 -83
  106. package/.safeword/tickets/002-architecture-enforcement.md +0 -211
  107. package/.safeword/tickets/003-reactive-fix-prevention.md +0 -57
  108. package/.safeword/tickets/004-technical-constraints-in-user-stories.md +0 -39
  109. package/.safeword/tickets/005-cli-implementation.md +0 -248
  110. package/.safeword/tickets/006-flesh-out-skills.md +0 -43
  111. package/.safeword/tickets/007-flesh-out-questioning.md +0 -44
  112. package/.safeword/tickets/008-upgrade-questioning.md +0 -58
  113. package/.safeword/tickets/009-naming-conventions.md +0 -41
  114. package/.safeword/tickets/010-safeword-md-cleanup.md +0 -34
  115. package/.safeword/tickets/011-cursor-setup.md +0 -86
  116. package/.safeword/tickets/README.md +0 -73
  117. package/.safeword/version +0 -1
  118. package/AGENTS.md +0 -59
  119. package/CLAUDE.md +0 -12
  120. package/README.md +0 -347
  121. package/docs/001-cli-implementation-plan.md +0 -856
  122. package/docs/elite-dx-implementation-plan.md +0 -1034
  123. package/framework/README.md +0 -131
  124. package/framework/mcp/README.md +0 -96
  125. package/framework/mcp/arcade.sample.json +0 -8
  126. package/framework/mcp/context7.sample.json +0 -6
  127. package/framework/mcp/playwright.sample.json +0 -6
  128. package/framework/scripts/arch-review.sh +0 -235
  129. package/framework/scripts/check-linting-sync.sh +0 -58
  130. package/framework/scripts/load-env.sh +0 -49
  131. package/framework/scripts/setup-claude.sh +0 -223
  132. package/framework/scripts/setup-linting.sh +0 -559
  133. package/framework/scripts/setup-quality.sh +0 -477
  134. package/framework/scripts/setup-safeword.sh +0 -550
  135. package/framework/templates/ci/architecture-check.yml +0 -78
  136. package/learnings/ai-sdk-v5-breaking-changes.md +0 -178
  137. package/learnings/e2e-test-zombie-processes.md +0 -231
  138. package/learnings/milkdown-crepe-editor-property.md +0 -96
  139. package/learnings/prosemirror-fragment-traversal.md +0 -119
  140. package/packages/cli/AGENTS.md +0 -1
  141. package/packages/cli/ARCHITECTURE.md +0 -279
  142. package/packages/cli/package.json +0 -51
  143. package/packages/cli/src/cli.ts +0 -63
  144. package/packages/cli/src/commands/check.ts +0 -166
  145. package/packages/cli/src/commands/diff.ts +0 -209
  146. package/packages/cli/src/commands/reset.ts +0 -190
  147. package/packages/cli/src/commands/setup.ts +0 -325
  148. package/packages/cli/src/commands/upgrade.ts +0 -163
  149. package/packages/cli/src/index.ts +0 -3
  150. package/packages/cli/src/templates/config.ts +0 -58
  151. package/packages/cli/src/templates/content.ts +0 -18
  152. package/packages/cli/src/templates/index.ts +0 -12
  153. package/packages/cli/src/utils/agents-md.ts +0 -66
  154. package/packages/cli/src/utils/fs.ts +0 -179
  155. package/packages/cli/src/utils/git.ts +0 -124
  156. package/packages/cli/src/utils/hooks.ts +0 -29
  157. package/packages/cli/src/utils/output.ts +0 -60
  158. package/packages/cli/src/utils/project-detector.test.ts +0 -185
  159. package/packages/cli/src/utils/project-detector.ts +0 -44
  160. package/packages/cli/src/utils/version.ts +0 -28
  161. package/packages/cli/src/version.ts +0 -6
  162. package/packages/cli/templates/SAFEWORD.md +0 -776
  163. package/packages/cli/templates/doc-templates/architecture-template.md +0 -136
  164. package/packages/cli/templates/doc-templates/design-doc-template.md +0 -134
  165. package/packages/cli/templates/doc-templates/test-definitions-feature.md +0 -131
  166. package/packages/cli/templates/doc-templates/ticket-template.md +0 -82
  167. package/packages/cli/templates/doc-templates/user-stories-template.md +0 -92
  168. package/packages/cli/templates/guides/architecture-guide.md +0 -423
  169. package/packages/cli/templates/guides/code-philosophy.md +0 -195
  170. package/packages/cli/templates/guides/context-files-guide.md +0 -457
  171. package/packages/cli/templates/guides/data-architecture-guide.md +0 -200
  172. package/packages/cli/templates/guides/design-doc-guide.md +0 -171
  173. package/packages/cli/templates/guides/learning-extraction.md +0 -552
  174. package/packages/cli/templates/guides/llm-instruction-design.md +0 -248
  175. package/packages/cli/templates/guides/llm-prompting.md +0 -102
  176. package/packages/cli/templates/guides/tdd-best-practices.md +0 -615
  177. package/packages/cli/templates/guides/test-definitions-guide.md +0 -334
  178. package/packages/cli/templates/guides/testing-methodology.md +0 -618
  179. package/packages/cli/templates/guides/user-story-guide.md +0 -256
  180. package/packages/cli/templates/guides/zombie-process-cleanup.md +0 -219
  181. package/packages/cli/templates/hooks/agents-md-check.sh +0 -27
  182. package/packages/cli/templates/hooks/post-tool.sh +0 -4
  183. package/packages/cli/templates/hooks/pre-commit.sh +0 -10
  184. package/packages/cli/templates/prompts/arch-review.md +0 -43
  185. package/packages/cli/templates/prompts/quality-review.md +0 -10
  186. package/packages/cli/templates/skills/safeword-quality-reviewer/SKILL.md +0 -207
  187. package/packages/cli/tests/commands/check.test.ts +0 -129
  188. package/packages/cli/tests/commands/cli.test.ts +0 -89
  189. package/packages/cli/tests/commands/diff.test.ts +0 -115
  190. package/packages/cli/tests/commands/reset.test.ts +0 -310
  191. package/packages/cli/tests/commands/self-healing.test.ts +0 -170
  192. package/packages/cli/tests/commands/setup-blocking.test.ts +0 -71
  193. package/packages/cli/tests/commands/setup-core.test.ts +0 -135
  194. package/packages/cli/tests/commands/setup-git.test.ts +0 -139
  195. package/packages/cli/tests/commands/setup-hooks.test.ts +0 -334
  196. package/packages/cli/tests/commands/setup-linting.test.ts +0 -189
  197. package/packages/cli/tests/commands/setup-noninteractive.test.ts +0 -80
  198. package/packages/cli/tests/commands/setup-templates.test.ts +0 -181
  199. package/packages/cli/tests/commands/upgrade.test.ts +0 -215
  200. package/packages/cli/tests/helpers.ts +0 -243
  201. package/packages/cli/tests/npm-package.test.ts +0 -83
  202. package/packages/cli/tests/technical-constraints.test.ts +0 -96
  203. package/packages/cli/tsconfig.json +0 -25
  204. package/packages/cli/tsup.config.ts +0 -11
  205. package/packages/cli/vitest.config.ts +0 -23
  206. package/promptfoo.yaml +0 -3270
  207. /package/{framework → templates}/SAFEWORD.md +0 -0
  208. /package/{packages/cli/templates → templates}/commands/arch-review.md +0 -0
  209. /package/{packages/cli/templates → templates}/commands/lint.md +0 -0
  210. /package/{packages/cli/templates → templates}/commands/quality-review.md +0 -0
  211. /package/{framework/templates → templates/doc-templates}/architecture-template.md +0 -0
  212. /package/{framework/templates → templates/doc-templates}/design-doc-template.md +0 -0
  213. /package/{framework/templates → templates/doc-templates}/test-definitions-feature.md +0 -0
  214. /package/{framework/templates → templates/doc-templates}/ticket-template.md +0 -0
  215. /package/{framework/templates → templates/doc-templates}/user-stories-template.md +0 -0
  216. /package/{framework → templates}/guides/architecture-guide.md +0 -0
  217. /package/{framework → templates}/guides/code-philosophy.md +0 -0
  218. /package/{framework → templates}/guides/context-files-guide.md +0 -0
  219. /package/{framework → templates}/guides/data-architecture-guide.md +0 -0
  220. /package/{framework → templates}/guides/design-doc-guide.md +0 -0
  221. /package/{framework → templates}/guides/learning-extraction.md +0 -0
  222. /package/{framework → templates}/guides/llm-instruction-design.md +0 -0
  223. /package/{framework → templates}/guides/llm-prompting.md +0 -0
  224. /package/{framework → templates}/guides/tdd-best-practices.md +0 -0
  225. /package/{framework → templates}/guides/test-definitions-guide.md +0 -0
  226. /package/{framework → templates}/guides/testing-methodology.md +0 -0
  227. /package/{framework → templates}/guides/user-story-guide.md +0 -0
  228. /package/{framework → templates}/guides/zombie-process-cleanup.md +0 -0
  229. /package/{packages/cli/templates → templates}/hooks/inject-timestamp.sh +0 -0
  230. /package/{packages/cli/templates → templates}/lib/common.sh +0 -0
  231. /package/{packages/cli/templates → templates}/lib/jq-fallback.sh +0 -0
  232. /package/{packages/cli/templates → templates}/markdownlint.jsonc +0 -0
  233. /package/{framework → templates}/prompts/arch-review.md +0 -0
  234. /package/{framework → templates}/prompts/quality-review.md +0 -0
  235. /package/{framework/skills/quality-reviewer → templates/skills/safeword-quality-reviewer}/SKILL.md +0 -0
@@ -1,856 +0,0 @@
1
- # Safeword CLI Implementation Plan
2
-
3
- **Goal:** Ship TypeScript CLI that replaces bash scripts with elite developer experience.
4
-
5
- **Strategy:** Project-local (committable, version-pinnable) with optional plugin wrapper in Phase 2.
6
-
7
- **Non-goal:** Don't try to be Superpowers. Stay focused on quality enforcement, not skill libraries.
8
-
9
- ---
10
-
11
- ## Phase 1: Core CLI (Ship This First)
12
-
13
- **Target:** v1.0.0 - Functional replacement for bash scripts with better UX
14
-
15
- ### 1.1 Project Setup
16
-
17
- **Create CLI package structure:**
18
-
19
- ```bash
20
- mkdir -p packages/cli/src/{commands,lib,templates}
21
- cd packages/cli
22
- npm init -y
23
- ```
24
-
25
- **Install dependencies:**
26
-
27
- ```bash
28
- # Core CLI
29
- npm install commander @clack/prompts
30
-
31
- # File operations
32
- npm install fs-extra globby
33
-
34
- # Utilities
35
- npm install picocolors execa
36
-
37
- # Dev dependencies
38
- npm install -D typescript @types/node @types/fs-extra tsx vitest
39
- ```
40
-
41
- **Why these choices:**
42
-
43
- - `commander` - Industry standard CLI framework
44
- - `@clack/prompts` - Modern, beautiful prompts (used by Astro/Vite)
45
- - `fs-extra` - Promise-based fs with extras (copy, ensureDir)
46
- - `execa` - Better child_process (run npm, git commands)
47
- - `tsx` - Fast TypeScript execution for dev/testing
48
-
49
- ---
50
-
51
- ### 1.2 Core Commands
52
-
53
- **Priority order (ship incrementally):**
54
-
55
- **1.2.1 `safeword init` (CRITICAL PATH)**
56
-
57
- **Purpose:** Replace `setup-safeword.sh` with interactive setup
58
-
59
- **Features:**
60
-
61
- ```bash
62
- safeword init # Interactive with prompts
63
- safeword init --yes # Accept all defaults
64
- safeword init --ci # Non-interactive (CI mode)
65
- safeword init --linting-only # Skip quality review
66
- safeword init --quality-only # Skip linting
67
- ```
68
-
69
- **Flow:**
70
-
71
- 1. Detect project type (Next.js, React, Electron, TypeScript, etc.)
72
- 2. Prompt for install mode (or use defaults in --yes/--ci)
73
- 3. Copy templates from npm package to `.safeword/` and `.claude/`
74
- 4. Install linting dependencies (biome or eslint+prettier)
75
- 5. Update `package.json` (add scripts, optionally add CLI to devDeps)
76
- 6. Register hooks in `.claude/settings.json`
77
- 7. Create/update `SAFEWORD.md` with .safeword/SAFEWORD.md reference
78
- 8. Run automatic verification (see 1.2.2)
79
- 9. Print success summary with next steps
80
-
81
- **Auto-detection logic:**
82
-
83
- ```typescript
84
- export async function detectProjectType(): Promise<ProjectType> {
85
- const hasFile = (path: string) => fs.existsSync(path);
86
- const pkgJson = await readPackageJson();
87
-
88
- // Check dependencies
89
- const deps = { ...pkgJson.dependencies, ...pkgJson.devDependencies };
90
-
91
- if (deps['@biomejs/biome']) return 'biome';
92
- if (deps['next']) return 'nextjs';
93
- if (deps['electron']) return 'electron';
94
- if (deps['astro']) return 'astro';
95
- if (deps['react']) return 'react';
96
- if (deps['typescript'] || hasFile('tsconfig.json')) return 'typescript';
97
-
98
- return 'minimal';
99
- }
100
- ```
101
-
102
- **Output (interactive mode):**
103
-
104
- ```
105
- $ safeword init
106
-
107
- ○ Detecting project type...
108
- ✓ Next.js with TypeScript
109
-
110
- ○ Install options:
111
- ○ Recommended (auto-linting + quality review)
112
- ○ Auto-linting only
113
- ○ Quality review only
114
-
115
- ◆ Choice
116
- │ ● Recommended (auto-linting + quality review)
117
-
118
-
119
- ○ Installing...
120
-
121
- ▲ Linting (biome, 15.2 MB)
122
- ▲ Quality review
123
- ▲ Guides (12 files)
124
-
125
- ✓ Configured in 4.2s
126
-
127
- ○ Verification
128
-
129
- Files:
130
- ✓ .safeword/SAFEWORD.md
131
- ✓ .safeword/guides/ (12 guides)
132
- ✓ .claude/hooks/ (3 hooks)
133
- ✓ .claude/settings.json
134
- ✓ SAFEWORD.md
135
-
136
- Hooks:
137
- ✓ PostToolUse → auto-lint.sh
138
- ✓ Stop → auto-quality-review.sh
139
-
140
- Linting:
141
- ✓ biome.jsonc configured
142
- ✓ npm run lint works
143
-
144
- ✓ All checks passed!
145
-
146
- ○ Next steps
147
-
148
- git add .safeword .claude SAFEWORD.md package.json
149
- git commit -m "Add safeword config"
150
-
151
- Try it: Ask Claude to create a file
152
- ```
153
-
154
- ---
155
-
156
- **1.2.2 `safeword verify` (CRITICAL PATH)**
157
-
158
- **Purpose:** Health check + auto-repair
159
-
160
- **Features:**
161
-
162
- ```bash
163
- safeword verify # Show status, exit 0/1
164
- safeword verify --auto-init # Init if not configured (teammate onboarding)
165
- safeword verify --repair # Fix broken hooks
166
- safeword verify --ci # CI mode (minimal output)
167
- ```
168
-
169
- **Checks:**
170
-
171
- 1. `.safeword/SAFEWORD.md` exists
172
- 2. `.safeword/guides/` exists (count files)
173
- 3. `.claude/hooks/` exists (verify scripts executable)
174
- 4. `.claude/settings.json` exists and valid JSON
175
- 5. Hooks registered (PostToolUse, Stop)
176
- 6. `SAFEWORD.md` or `CLAUDE.md` references `.safeword/SAFEWORD.md`
177
- 7. Linting configured (biome.jsonc or eslint.config.mjs exists)
178
- 8. npm scripts exist (`lint`, `format`)
179
-
180
- **Repair logic:**
181
-
182
- ```typescript
183
- async function repair() {
184
- // Re-register hooks if missing
185
- if (!hooksRegistered()) {
186
- await registerHooks();
187
- }
188
-
189
- // Fix executable permissions
190
- await fs.chmod('.claude/hooks/auto-lint.sh', 0o755);
191
- await fs.chmod('.claude/hooks/auto-quality-review.sh', 0o755);
192
-
193
- // Re-add SAFEWORD.md reference if missing
194
- if (!agentsHasReference()) {
195
- await addSafewordReference();
196
- }
197
- }
198
- ```
199
-
200
- **Use case (teammate onboarding):**
201
-
202
- ```json
203
- // package.json
204
- {
205
- "scripts": {
206
- "prepare": "safeword verify --silent || echo 'ℹ Run: npx safeword init'"
207
- }
208
- }
209
- ```
210
-
211
- Teammate runs `npm install` → `prepare` hook runs → Prints message if not configured.
212
-
213
- **Note:** Don't use `postinstall` (security red flag). Use `prepare` (runs in dev only).
214
-
215
- ---
216
-
217
- **1.2.3 `safeword --version` (CRITICAL PATH)**
218
-
219
- **Purpose:** Show CLI version
220
-
221
- ```bash
222
- safeword --version
223
- # 1.0.0
224
- ```
225
-
226
- **Implementation:**
227
-
228
- ```typescript
229
- // Read from package.json
230
- import { readFileSync } from 'fs';
231
- import { join } from 'path';
232
-
233
- const pkgPath = join(__dirname, '../package.json');
234
- const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
235
-
236
- program.version(pkg.version);
237
- ```
238
-
239
- ---
240
-
241
- **1.2.4 `safeword status` (NICE TO HAVE)**
242
-
243
- **Purpose:** Show detailed project state
244
-
245
- ```bash
246
- safeword status
247
- ```
248
-
249
- **Output:**
250
-
251
- ```
252
- Safeword Status
253
-
254
- Project: /Users/alex/projects/my-app
255
- Version: 1.0.0 (latest: 1.2.0 - run `safeword upgrade` to update)
256
-
257
- Components:
258
- ✓ Auto-linting (biome)
259
- ✓ Quality review hooks
260
- ✓ 12 guides in .safeword/
261
-
262
- Hooks:
263
- ✓ PostToolUse → auto-lint.sh (active)
264
- ✓ Stop → auto-quality-review.sh (active)
265
-
266
- Config:
267
- • enabled: true
268
- • ask_questions: true
269
- • linting_mode: biome
270
-
271
- To update: safeword upgrade
272
- ```
273
-
274
- **Data sources:**
275
-
276
- - `.safeword/version` file (created by init)
277
- - `.claude/settings.json` (hook registration)
278
- - `.auto-quality-review.config` (user preferences)
279
- - Check npm registry for latest version
280
-
281
- ---
282
-
283
- ### 1.3 Template Embedding
284
-
285
- **Strategy:** Embed all templates in npm package (no external downloads, no cache complexity)
286
-
287
- **Structure:**
288
-
289
- ```
290
- packages/cli/src/templates/
291
- ├── SAFEWORD.md # Core patterns (copied from framework/SAFEWORD.md)
292
- ├── guides/ # All guides
293
- │ ├── testing-methodology.md
294
- │ ├── code-philosophy.md
295
- │ ├── user-story-guide.md
296
- │ └── ... (all existing guides)
297
- ├── hooks/ # Hook scripts
298
- │ ├── auto-lint.sh
299
- │ ├── auto-quality-review.sh
300
- │ ├── run-linters.sh
301
- │ └── run-quality-review.sh
302
- └── config/ # Config file templates
303
- ├── eslint.config.mjs
304
- ├── biome.jsonc
305
- └── prettierrc
306
- ```
307
-
308
- **Copy operation:**
309
-
310
- ```typescript
311
- import { copy } from 'fs-extra';
312
- import { join } from 'path';
313
-
314
- export async function copyTemplates(projectDir: string) {
315
- const templatesDir = join(__dirname, '../templates');
316
- const targetDir = join(projectDir, '.safeword');
317
-
318
- // Copy everything
319
- await copy(templatesDir, targetDir);
320
-
321
- // Write version file
322
- const version = require('../package.json').version;
323
- await fs.writeFile(join(targetDir, 'version'), version);
324
- }
325
- ```
326
-
327
- **Why embed vs download:**
328
-
329
- - Templates are ~2MB total (tiny for npm)
330
- - Offline support (no network needed after npx download)
331
- - Simpler code (no cache management)
332
- - npm already caches packages in `~/.npm/_npx/`
333
-
334
- ---
335
-
336
- ### 1.4 Non-Interactive Mode (CI/CD)
337
-
338
- **Auto-detect non-interactive environments:**
339
-
340
- ```typescript
341
- const isCI =
342
- !process.stdin.isTTY || process.env.CI === 'true' || process.env.GITHUB_ACTIONS === 'true';
343
-
344
- if (isCI && !options.yes && !options.ci) {
345
- console.error('Error: Interactive prompts require TTY');
346
- console.error('Use --yes or --ci flag for non-interactive mode');
347
- process.exit(1);
348
- }
349
- ```
350
-
351
- **CI mode behavior:**
352
-
353
- ```bash
354
- safeword init --ci
355
-
356
- # No colors (plain text)
357
- # No progress bars
358
- # No prompts (use defaults)
359
- # Minimal output (errors + summary only)
360
- # Exit code 0 = success, 1 = failure
361
- ```
362
-
363
- **GitHub Actions example:**
364
-
365
- ```yaml
366
- name: Verify Safeword
367
- on: [push]
368
-
369
- jobs:
370
- verify:
371
- runs-on: ubuntu-latest
372
- steps:
373
- - uses: actions/checkout@v3
374
- - uses: actions/setup-node@v3
375
- - run: npm install
376
- - run: npx @safeword/cli verify --ci
377
- ```
378
-
379
- ---
380
-
381
- ### 1.5 Package Manager Detection
382
-
383
- **Problem:** Mutating `package.json` breaks yarn/pnpm lockfiles
384
-
385
- **Solution:** Detect package manager and use appropriate command
386
-
387
- ```typescript
388
- export async function detectPackageManager(): Promise<'npm' | 'yarn' | 'pnpm'> {
389
- if (await fs.pathExists('pnpm-lock.yaml')) return 'pnpm';
390
- if (await fs.pathExists('yarn.lock')) return 'yarn';
391
- return 'npm';
392
- }
393
-
394
- export async function runPackageManagerCommand(
395
- command: string,
396
- pkgManager: 'npm' | 'yarn' | 'pnpm',
397
- ) {
398
- const cmds = {
399
- npm: `npm ${command}`,
400
- yarn: `yarn ${command}`,
401
- pnpm: `pnpm ${command}`,
402
- };
403
-
404
- await execa(cmds[pkgManager], { shell: true });
405
- }
406
- ```
407
-
408
- **Ask before mutating package.json:**
409
-
410
- ```typescript
411
- if (!options.yes && !options.ci) {
412
- const { addToDeps } = await prompts({
413
- type: 'confirm',
414
- name: 'addToDeps',
415
- message: `Add @safeword/cli to devDependencies? (${pkgManager})`,
416
- initial: true,
417
- });
418
-
419
- if (addToDeps) {
420
- await addToPackageJson(pkgManager);
421
- }
422
- }
423
- ```
424
-
425
- ---
426
-
427
- ### 1.6 XDG Compliance (Global Learnings)
428
-
429
- **Follow XDG Base Directory spec:**
430
-
431
- ```typescript
432
- import { homedir } from 'os';
433
- import { join } from 'path';
434
-
435
- export function getGlobalLearningsDir(): string {
436
- const xdgDataHome = process.env.XDG_DATA_HOME || join(homedir(), '.local/share');
437
- return join(xdgDataHome, 'safeword/learnings');
438
- }
439
-
440
- export function getConfigDir(): string {
441
- const xdgConfigHome = process.env.XDG_CONFIG_HOME || join(homedir(), '.config');
442
- return join(xdgConfigHome, 'safeword');
443
- }
444
- ```
445
-
446
- **Structure:**
447
-
448
- ```
449
- ~/.local/share/safeword/
450
- └── .safeword/learnings/ # Project learnings
451
-
452
- ~/.config/safeword/
453
- └── config.json # CLI preferences (future)
454
- ```
455
-
456
- **Phase 1:** Only implement if adding `safeword learning add` command. Otherwise defer to Phase 2.
457
-
458
- ---
459
-
460
- ### 1.7 Testing Strategy
461
-
462
- **Unit tests (vitest):**
463
-
464
- ```typescript
465
- // tests/detect.test.ts
466
- import { describe, it, expect } from 'vitest';
467
- import { detectProjectType } from '../src/lib/detect';
468
-
469
- describe('detectProjectType', () => {
470
- it('detects Next.js projects', async () => {
471
- // Mock fs to return package.json with next dep
472
- const type = await detectProjectType();
473
- expect(type).toBe('nextjs');
474
- });
475
- });
476
- ```
477
-
478
- **Integration tests (mock fs):**
479
-
480
- ```typescript
481
- import { vol } from 'memfs';
482
- import { init } from '../src/commands/init';
483
-
484
- describe('safeword init', () => {
485
- beforeEach(() => {
486
- vol.reset();
487
- vol.fromJSON({
488
- '/project/package.json': JSON.stringify({ name: 'test' }),
489
- });
490
- });
491
-
492
- it('creates .safeword directory', async () => {
493
- await init({ yes: true });
494
- expect(vol.existsSync('/project/.safeword')).toBe(true);
495
- });
496
- });
497
- ```
498
-
499
- **Manual smoke test:**
500
-
501
- ```bash
502
- # In packages/cli
503
- npm link
504
-
505
- # In test project
506
- cd ~/test-project
507
- safeword init --yes
508
- safeword verify
509
- safeword status
510
- ```
511
-
512
- ---
513
-
514
- ## Phase 1 Checklist
515
-
516
- **Must have (blocking v1.0.0 release):**
517
-
518
- - [ ] `safeword init` with interactive prompts
519
- - [ ] `safeword init --yes` (non-interactive)
520
- - [ ] `safeword init --ci` (CI mode)
521
- - [ ] `safeword verify` (health check)
522
- - [ ] `safeword --version`
523
- - [ ] Auto-detect project type (Next.js, React, etc.)
524
- - [ ] Copy templates to `.safeword/` and `.claude/`
525
- - [ ] Install linting dependencies
526
- - [ ] Register hooks in `.claude/settings.json`
527
- - [ ] Create/update SAFEWORD.md reference
528
- - [ ] Automatic verification after init
529
- - [ ] Package manager detection (npm/yarn/pnpm)
530
- - [ ] Non-TTY detection (auto-enable --ci mode)
531
-
532
- **Nice to have (can ship after v1.0.0):**
533
-
534
- - [ ] `safeword status` (detailed health report)
535
- - [ ] `safeword verify --repair` (auto-fix broken hooks)
536
- - [ ] Unit tests (70%+ coverage)
537
- - [ ] Integration tests (smoke tests)
538
-
539
- **Defer to Phase 2:**
540
-
541
- - [ ] `safeword upgrade` (update templates)
542
- - [ ] `safeword learning add/list` (manage learnings)
543
- - [ ] Global learnings directory
544
- - [ ] Version migration tooling
545
- - [ ] Claude Code plugin wrapper
546
-
547
- ---
548
-
549
- ## Publishing (npm)
550
-
551
- **Package name:** `@safeword/cli`
552
-
553
- **package.json:**
554
-
555
- ```json
556
- {
557
- "name": "@safeword/cli",
558
- "version": "1.0.0",
559
- "description": "TDD workflows and quality patterns for Claude Code",
560
- "bin": {
561
- "safeword": "./dist/cli.js"
562
- },
563
- "files": ["dist/", "templates/"],
564
- "keywords": ["claude-code", "tdd", "quality", "linting", "hooks"],
565
- "repository": "github:TheMostlyGreat/safeword",
566
- "license": "MIT"
567
- }
568
- ```
569
-
570
- **Build:**
571
-
572
- ```json
573
- {
574
- "scripts": {
575
- "build": "tsc",
576
- "dev": "tsx src/cli.ts",
577
- "test": "vitest"
578
- }
579
- }
580
- ```
581
-
582
- **Publish:**
583
-
584
- ```bash
585
- npm run build
586
- npm publish --access public
587
- ```
588
-
589
- **Usage after publish:**
590
-
591
- ```bash
592
- npx @safeword/cli init # Download + run (cached)
593
- npm install -g @safeword/cli # Global install
594
- safeword init # Run globally
595
- ```
596
-
597
- ---
598
-
599
- ## Migration from Bash Scripts
600
-
601
- **Current state:**
602
-
603
- - `setup-safeword.sh` (270 lines)
604
- - `setup-linting.sh` (738 lines)
605
- - `setup-quality.sh` (531 lines)
606
-
607
- **Total:** ~1500 lines of bash
608
-
609
- **Target:** ~800 lines of TypeScript (more maintainable, testable, cross-platform)
610
-
611
- **Migration path:**
612
-
613
- 1. Ship CLI alongside bash scripts (backwards compatible)
614
- 2. Update README to recommend CLI
615
- 3. Mark bash scripts as deprecated (add warning banner)
616
- 4. Remove bash scripts in v2.0.0
617
-
618
- **Deprecation notice in bash scripts:**
619
-
620
- ```bash
621
- echo "⚠️ WARNING: Bash setup scripts are deprecated"
622
- echo " Use the new CLI instead: npx @safeword/cli init"
623
- echo " Bash scripts will be removed in v2.0.0"
624
- echo ""
625
- ```
626
-
627
- ---
628
-
629
- ## Documentation Updates
630
-
631
- **Update README.md:**
632
-
633
- ````markdown
634
- ## Quick Start
635
-
636
- **1. Install:**
637
-
638
- ```bash
639
- npx @safeword/cli init
640
- ```
641
- ````
642
-
643
- **2. Verify:**
644
-
645
- ```bash
646
- npx @safeword/cli verify
647
- ```
648
-
649
- **3. Commit:**
650
-
651
- ```bash
652
- git add .safeword .claude SAFEWORD.md package.json
653
- git commit -m "Add safeword config"
654
- ```
655
-
656
- ````
657
-
658
- **Add CLI reference docs:**
659
- ```markdown
660
- ## CLI Reference
661
-
662
- ### safeword init
663
- Initialize safeword in current project
664
-
665
- Options:
666
- --yes Accept all defaults
667
- --ci Non-interactive mode (CI/CD)
668
- --linting-only Skip quality review setup
669
- --quality-only Skip linting setup
670
-
671
- ### safeword verify
672
- Verify safeword configuration
673
-
674
- Options:
675
- --auto-init Auto-initialize if not configured
676
- --repair Fix broken hooks
677
- --ci CI mode (exit 0/1)
678
-
679
- ### safeword status
680
- Show detailed project status
681
-
682
- ### safeword --version
683
- Show CLI version
684
- ````
685
-
686
- ---
687
-
688
- ## Timeline Estimate
689
-
690
- **Week 1: Setup + Core Commands**
691
-
692
- - Day 1-2: Project setup, dependencies, TypeScript config
693
- - Day 3-4: `safeword init` command (basic functionality)
694
- - Day 5: `safeword verify` command
695
-
696
- **Week 2: Templates + Auto-Detection**
697
-
698
- - Day 1-2: Embed templates in package
699
- - Day 3-4: Project type detection logic
700
- - Day 5: Template copying + hook registration
701
-
702
- **Week 3: Polish + Testing**
703
-
704
- - Day 1-2: Interactive prompts (clack/prompts)
705
- - Day 3: CI mode, package manager detection
706
- - Day 4-5: Testing (unit + integration)
707
-
708
- **Week 4: Publish + Migrate**
709
-
710
- - Day 1: Build system, publish to npm
711
- - Day 2-3: Update README, add CLI docs
712
- - Day 4-5: Test in real projects, fix bugs
713
-
714
- **Total: 4 weeks to v1.0.0**
715
-
716
- ---
717
-
718
- ## Success Criteria
719
-
720
- **v1.0.0 is ready when:**
721
-
722
- 1. ✅ CLI fully replaces bash scripts (feature parity)
723
- 2. ✅ One-command setup works: `npx @safeword/cli init`
724
- 3. ✅ Verification catches broken configs: `safeword verify`
725
- 4. ✅ CI mode works in GitHub Actions
726
- 5. ✅ Published to npm as `@safeword/cli`
727
- 6. ✅ README updated with new install instructions
728
- 7. ✅ Tested in 3+ real projects (Next.js, React, TypeScript)
729
- 8. ✅ No critical bugs (linting works, hooks trigger)
730
-
731
- **Ship when these are green. Don't wait for perfect.**
732
-
733
- ---
734
-
735
- ## Phase 2: Advanced Features (Future)
736
-
737
- **Defer these until v1.0.0 shipped and validated:**
738
-
739
- - `safeword upgrade` - Update project templates
740
- - `safeword learning add/list` - Manage learnings
741
- - Version migration tooling (`safeword migrate`)
742
- - Claude Code plugin wrapper (`/safeword:init`)
743
- - Health monitoring (daily status reports)
744
- - Team analytics (hook usage stats)
745
-
746
- **Get feedback first. Don't over-engineer.**
747
-
748
- ---
749
-
750
- ## Anti-Patterns to Avoid
751
-
752
- **❌ Don't:**
753
-
754
- - Build version migration before v2.0.0 exists
755
- - Add cache management (npm already caches)
756
- - Convert guides to "skills" (terminology confusion)
757
- - Make it a Claude Code plugin (lose project-local benefits)
758
- - Use `postinstall` scripts (security red flag)
759
- - Support every edge case (ship fast, iterate)
760
-
761
- **✅ Do:**
762
-
763
- - Start with MVP (init + verify)
764
- - Ship incrementally (don't wait for perfect)
765
- - Test in real projects early
766
- - Get feedback before Phase 2
767
- - Keep it simple (no premature abstraction)
768
- - Follow XDG standards (if adding global state)
769
-
770
- ---
771
-
772
- ## Decision Log
773
-
774
- **Decisions made:**
775
-
776
- 1. ✅ TypeScript CLI (not bash) - Maintainability > speed
777
- 2. ✅ npx distribution (not curl) - Target audience has Node.js
778
- 3. ✅ Project-local (not plugin) - Team consistency + versioning
779
- 4. ✅ `@clack/prompts` (not inquirer) - Modern, actively maintained
780
- 5. ✅ Embed templates (not download) - Offline support
781
- 6. ✅ `prepare` script (not postinstall) - Security
782
- 7. ✅ XDG compliance (for global learnings) - Standards matter
783
-
784
- **Decisions deferred:**
785
-
786
- 1. ⏸ Claude Code plugin wrapper - Wait for v1.0.0 feedback
787
- 2. ⏸ Version migration tooling - Wait for v2.0.0
788
- 3. ⏸ Learning management - Wait for user demand
789
- 4. ⏸ Status command - Nice to have, not blocking
790
-
791
- **Questions to answer during implementation:**
792
-
793
- 1. Should `safeword verify --auto-init` run automatically on `npm install`?
794
- 2. Should we ask before mutating `package.json` in `--yes` mode?
795
- 3. Should `safeword status` check npm registry for updates (network call)?
796
- 4. How much output is too much in CI mode?
797
-
798
- ---
799
-
800
- ## Next Steps
801
-
802
- **Start here:**
803
-
804
- 1. **Create CLI package:**
805
-
806
- ```bash
807
- mkdir -p packages/cli/src/{commands,lib,templates}
808
- cd packages/cli
809
- npm init -y
810
- npm install commander @clack/prompts fs-extra picocolors execa
811
- npm install -D typescript @types/node tsx vitest
812
- ```
813
-
814
- 2. **Copy templates:**
815
-
816
- ```bash
817
- cp ../SAFEWORD.md src/templates/SAFEWORD.md
818
- cp -r ../guides src/templates/guides
819
- cp -r ../.claude/hooks src/templates/hooks
820
- ```
821
-
822
- 3. **Build `safeword init` skeleton:**
823
-
824
- ```typescript
825
- // src/cli.ts
826
- #!/usr/bin/env node
827
- import { Command } from 'commander';
828
- import { init } from './commands/init';
829
-
830
- const program = new Command();
831
-
832
- program
833
- .name('safeword')
834
- .version('1.0.0');
835
-
836
- program
837
- .command('init')
838
- .option('--yes', 'Accept all defaults')
839
- .option('--ci', 'Non-interactive mode')
840
- .action(init);
841
-
842
- program.parse();
843
- ```
844
-
845
- 4. **Test locally:**
846
-
847
- ```bash
848
- chmod +x src/cli.ts
849
- npm link
850
- cd ~/test-project
851
- safeword init --yes
852
- ```
853
-
854
- 5. **Iterate until it works, then ship.**
855
-
856
- **Don't overthink. Start coding.**