safeword 0.2.4 → 0.2.6
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/dist/check-3NGQ4NR5.js +129 -0
- package/dist/check-3NGQ4NR5.js.map +1 -0
- package/dist/chunk-2XWIUEQK.js +190 -0
- package/dist/chunk-2XWIUEQK.js.map +1 -0
- package/dist/chunk-GZRQL3SX.js +146 -0
- package/dist/chunk-GZRQL3SX.js.map +1 -0
- package/dist/chunk-ORQHKDT2.js +10 -0
- package/dist/chunk-ORQHKDT2.js.map +1 -0
- package/dist/chunk-W66Z3C5H.js +21 -0
- package/dist/chunk-W66Z3C5H.js.map +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +34 -0
- package/dist/cli.js.map +1 -0
- package/dist/diff-Y6QTAW4O.js +166 -0
- package/dist/diff-Y6QTAW4O.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/reset-3ACTIYYE.js +143 -0
- package/dist/reset-3ACTIYYE.js.map +1 -0
- package/dist/setup-AIL5RL45.js +276 -0
- package/dist/setup-AIL5RL45.js.map +1 -0
- package/dist/upgrade-6AR3DHUV.js +134 -0
- package/dist/upgrade-6AR3DHUV.js.map +1 -0
- package/package.json +44 -19
- package/{.safeword → templates}/hooks/agents-md-check.sh +0 -0
- package/{.safeword → templates}/hooks/post-tool.sh +0 -0
- package/{.safeword → templates}/hooks/pre-commit.sh +0 -0
- package/.claude/commands/arch-review.md +0 -32
- package/.claude/commands/lint.md +0 -6
- package/.claude/commands/quality-review.md +0 -13
- package/.claude/commands/setup-linting.md +0 -6
- package/.claude/hooks/auto-lint.sh +0 -6
- package/.claude/hooks/auto-quality-review.sh +0 -170
- package/.claude/hooks/check-linting-sync.sh +0 -17
- package/.claude/hooks/inject-timestamp.sh +0 -6
- package/.claude/hooks/question-protocol.sh +0 -12
- package/.claude/hooks/run-linters.sh +0 -8
- package/.claude/hooks/run-quality-review.sh +0 -76
- package/.claude/hooks/version-check.sh +0 -10
- package/.claude/mcp/README.md +0 -96
- package/.claude/mcp/arcade.sample.json +0 -9
- package/.claude/mcp/context7.sample.json +0 -7
- package/.claude/mcp/playwright.sample.json +0 -7
- package/.claude/settings.json +0 -62
- package/.claude/skills/quality-reviewer/SKILL.md +0 -190
- package/.claude/skills/safeword-quality-reviewer/SKILL.md +0 -13
- package/.env.arcade.example +0 -4
- package/.env.example +0 -11
- package/.gitmodules +0 -4
- package/.safeword/SAFEWORD.md +0 -33
- package/.safeword/eslint/eslint-base.mjs +0 -101
- package/.safeword/guides/architecture-guide.md +0 -404
- package/.safeword/guides/code-philosophy.md +0 -174
- package/.safeword/guides/context-files-guide.md +0 -405
- package/.safeword/guides/data-architecture-guide.md +0 -183
- package/.safeword/guides/design-doc-guide.md +0 -165
- package/.safeword/guides/learning-extraction.md +0 -515
- package/.safeword/guides/llm-instruction-design.md +0 -239
- package/.safeword/guides/llm-prompting.md +0 -95
- package/.safeword/guides/tdd-best-practices.md +0 -570
- package/.safeword/guides/test-definitions-guide.md +0 -243
- package/.safeword/guides/testing-methodology.md +0 -573
- package/.safeword/guides/user-story-guide.md +0 -237
- package/.safeword/guides/zombie-process-cleanup.md +0 -214
- package/.safeword/planning/002-user-story-quality-evaluation.md +0 -1840
- package/.safeword/planning/003-langsmith-eval-setup-prompt.md +0 -363
- package/.safeword/planning/004-llm-eval-test-cases.md +0 -3226
- package/.safeword/planning/005-architecture-enforcement-system.md +0 -169
- package/.safeword/planning/006-reactive-fix-prevention-research.md +0 -135
- package/.safeword/planning/011-cli-ux-vision.md +0 -330
- package/.safeword/planning/012-project-structure-cleanup.md +0 -154
- package/.safeword/planning/README.md +0 -39
- package/.safeword/planning/automation-plan-v2.md +0 -1225
- package/.safeword/planning/automation-plan-v3.md +0 -1291
- package/.safeword/planning/automation-plan.md +0 -3058
- package/.safeword/planning/design/005-cli-implementation.md +0 -343
- package/.safeword/planning/design/013-cli-self-contained-templates.md +0 -596
- package/.safeword/planning/design/013a-eslint-plugin-suite.md +0 -256
- package/.safeword/planning/design/013b-implementation-snippets.md +0 -385
- package/.safeword/planning/design/013c-config-isolation-strategy.md +0 -242
- package/.safeword/planning/design/code-philosophy-improvements.md +0 -60
- package/.safeword/planning/mcp-analysis.md +0 -545
- package/.safeword/planning/phase2-subagents-vs-skills-analysis.md +0 -451
- package/.safeword/planning/settings-improvements.md +0 -970
- package/.safeword/planning/test-definitions/005-cli-implementation.md +0 -1301
- package/.safeword/planning/test-definitions/cli-self-contained-templates.md +0 -205
- package/.safeword/planning/user-stories/001-guides-review-user-stories.md +0 -1381
- package/.safeword/planning/user-stories/003-reactive-fix-prevention.md +0 -132
- package/.safeword/planning/user-stories/004-technical-constraints.md +0 -86
- package/.safeword/planning/user-stories/005-cli-implementation.md +0 -311
- package/.safeword/planning/user-stories/cli-self-contained-templates.md +0 -172
- package/.safeword/planning/versioned-distribution.md +0 -740
- package/.safeword/prompts/arch-review.md +0 -43
- package/.safeword/prompts/quality-review.md +0 -11
- package/.safeword/scripts/arch-review.sh +0 -235
- package/.safeword/scripts/check-linting-sync.sh +0 -58
- package/.safeword/scripts/setup-linting.sh +0 -559
- package/.safeword/templates/architecture-template.md +0 -136
- package/.safeword/templates/ci/architecture-check.yml +0 -79
- package/.safeword/templates/design-doc-template.md +0 -127
- package/.safeword/templates/test-definitions-feature.md +0 -100
- package/.safeword/templates/ticket-template.md +0 -74
- package/.safeword/templates/user-stories-template.md +0 -82
- package/.safeword/tickets/001-guides-review-user-stories.md +0 -83
- package/.safeword/tickets/002-architecture-enforcement.md +0 -211
- package/.safeword/tickets/003-reactive-fix-prevention.md +0 -57
- package/.safeword/tickets/004-technical-constraints-in-user-stories.md +0 -39
- package/.safeword/tickets/005-cli-implementation.md +0 -248
- package/.safeword/tickets/006-flesh-out-skills.md +0 -43
- package/.safeword/tickets/007-flesh-out-questioning.md +0 -44
- package/.safeword/tickets/008-upgrade-questioning.md +0 -58
- package/.safeword/tickets/009-naming-conventions.md +0 -41
- package/.safeword/tickets/010-safeword-md-cleanup.md +0 -34
- package/.safeword/tickets/011-cursor-setup.md +0 -86
- package/.safeword/tickets/README.md +0 -73
- package/.safeword/version +0 -1
- package/AGENTS.md +0 -59
- package/CLAUDE.md +0 -12
- package/README.md +0 -347
- package/docs/001-cli-implementation-plan.md +0 -856
- package/docs/elite-dx-implementation-plan.md +0 -1034
- package/framework/README.md +0 -131
- package/framework/mcp/README.md +0 -96
- package/framework/mcp/arcade.sample.json +0 -8
- package/framework/mcp/context7.sample.json +0 -6
- package/framework/mcp/playwright.sample.json +0 -6
- package/framework/scripts/arch-review.sh +0 -235
- package/framework/scripts/check-linting-sync.sh +0 -58
- package/framework/scripts/load-env.sh +0 -49
- package/framework/scripts/setup-claude.sh +0 -223
- package/framework/scripts/setup-linting.sh +0 -559
- package/framework/scripts/setup-quality.sh +0 -477
- package/framework/scripts/setup-safeword.sh +0 -550
- package/framework/templates/ci/architecture-check.yml +0 -78
- package/learnings/ai-sdk-v5-breaking-changes.md +0 -178
- package/learnings/e2e-test-zombie-processes.md +0 -231
- package/learnings/milkdown-crepe-editor-property.md +0 -96
- package/learnings/prosemirror-fragment-traversal.md +0 -119
- package/packages/cli/AGENTS.md +0 -1
- package/packages/cli/ARCHITECTURE.md +0 -279
- package/packages/cli/package.json +0 -51
- package/packages/cli/src/cli.ts +0 -63
- package/packages/cli/src/commands/check.ts +0 -166
- package/packages/cli/src/commands/diff.ts +0 -209
- package/packages/cli/src/commands/reset.ts +0 -190
- package/packages/cli/src/commands/setup.ts +0 -325
- package/packages/cli/src/commands/upgrade.ts +0 -163
- package/packages/cli/src/index.ts +0 -3
- package/packages/cli/src/templates/config.ts +0 -58
- package/packages/cli/src/templates/content.ts +0 -18
- package/packages/cli/src/templates/index.ts +0 -12
- package/packages/cli/src/utils/agents-md.ts +0 -66
- package/packages/cli/src/utils/fs.ts +0 -179
- package/packages/cli/src/utils/git.ts +0 -124
- package/packages/cli/src/utils/hooks.ts +0 -29
- package/packages/cli/src/utils/output.ts +0 -60
- package/packages/cli/src/utils/project-detector.test.ts +0 -185
- package/packages/cli/src/utils/project-detector.ts +0 -44
- package/packages/cli/src/utils/version.ts +0 -28
- package/packages/cli/src/version.ts +0 -6
- package/packages/cli/templates/SAFEWORD.md +0 -776
- package/packages/cli/templates/doc-templates/architecture-template.md +0 -136
- package/packages/cli/templates/doc-templates/design-doc-template.md +0 -134
- package/packages/cli/templates/doc-templates/test-definitions-feature.md +0 -131
- package/packages/cli/templates/doc-templates/ticket-template.md +0 -82
- package/packages/cli/templates/doc-templates/user-stories-template.md +0 -92
- package/packages/cli/templates/guides/architecture-guide.md +0 -423
- package/packages/cli/templates/guides/code-philosophy.md +0 -195
- package/packages/cli/templates/guides/context-files-guide.md +0 -457
- package/packages/cli/templates/guides/data-architecture-guide.md +0 -200
- package/packages/cli/templates/guides/design-doc-guide.md +0 -171
- package/packages/cli/templates/guides/learning-extraction.md +0 -552
- package/packages/cli/templates/guides/llm-instruction-design.md +0 -248
- package/packages/cli/templates/guides/llm-prompting.md +0 -102
- package/packages/cli/templates/guides/tdd-best-practices.md +0 -615
- package/packages/cli/templates/guides/test-definitions-guide.md +0 -334
- package/packages/cli/templates/guides/testing-methodology.md +0 -618
- package/packages/cli/templates/guides/user-story-guide.md +0 -256
- package/packages/cli/templates/guides/zombie-process-cleanup.md +0 -219
- package/packages/cli/templates/hooks/agents-md-check.sh +0 -27
- package/packages/cli/templates/hooks/post-tool.sh +0 -4
- package/packages/cli/templates/hooks/pre-commit.sh +0 -10
- package/packages/cli/templates/prompts/arch-review.md +0 -43
- package/packages/cli/templates/prompts/quality-review.md +0 -10
- package/packages/cli/templates/skills/safeword-quality-reviewer/SKILL.md +0 -207
- package/packages/cli/tests/commands/check.test.ts +0 -129
- package/packages/cli/tests/commands/cli.test.ts +0 -89
- package/packages/cli/tests/commands/diff.test.ts +0 -115
- package/packages/cli/tests/commands/reset.test.ts +0 -310
- package/packages/cli/tests/commands/self-healing.test.ts +0 -170
- package/packages/cli/tests/commands/setup-blocking.test.ts +0 -71
- package/packages/cli/tests/commands/setup-core.test.ts +0 -135
- package/packages/cli/tests/commands/setup-git.test.ts +0 -139
- package/packages/cli/tests/commands/setup-hooks.test.ts +0 -334
- package/packages/cli/tests/commands/setup-linting.test.ts +0 -189
- package/packages/cli/tests/commands/setup-noninteractive.test.ts +0 -80
- package/packages/cli/tests/commands/setup-templates.test.ts +0 -181
- package/packages/cli/tests/commands/upgrade.test.ts +0 -215
- package/packages/cli/tests/helpers.ts +0 -243
- package/packages/cli/tests/npm-package.test.ts +0 -83
- package/packages/cli/tests/technical-constraints.test.ts +0 -96
- package/packages/cli/tsconfig.json +0 -25
- package/packages/cli/tsup.config.ts +0 -11
- package/packages/cli/vitest.config.ts +0 -23
- package/promptfoo.yaml +0 -3270
- /package/{framework → templates}/SAFEWORD.md +0 -0
- /package/{packages/cli/templates → templates}/commands/arch-review.md +0 -0
- /package/{packages/cli/templates → templates}/commands/lint.md +0 -0
- /package/{packages/cli/templates → templates}/commands/quality-review.md +0 -0
- /package/{framework/templates → templates/doc-templates}/architecture-template.md +0 -0
- /package/{framework/templates → templates/doc-templates}/design-doc-template.md +0 -0
- /package/{framework/templates → templates/doc-templates}/test-definitions-feature.md +0 -0
- /package/{framework/templates → templates/doc-templates}/ticket-template.md +0 -0
- /package/{framework/templates → templates/doc-templates}/user-stories-template.md +0 -0
- /package/{framework → templates}/guides/architecture-guide.md +0 -0
- /package/{framework → templates}/guides/code-philosophy.md +0 -0
- /package/{framework → templates}/guides/context-files-guide.md +0 -0
- /package/{framework → templates}/guides/data-architecture-guide.md +0 -0
- /package/{framework → templates}/guides/design-doc-guide.md +0 -0
- /package/{framework → templates}/guides/learning-extraction.md +0 -0
- /package/{framework → templates}/guides/llm-instruction-design.md +0 -0
- /package/{framework → templates}/guides/llm-prompting.md +0 -0
- /package/{framework → templates}/guides/tdd-best-practices.md +0 -0
- /package/{framework → templates}/guides/test-definitions-guide.md +0 -0
- /package/{framework → templates}/guides/testing-methodology.md +0 -0
- /package/{framework → templates}/guides/user-story-guide.md +0 -0
- /package/{framework → templates}/guides/zombie-process-cleanup.md +0 -0
- /package/{packages/cli/templates → templates}/hooks/inject-timestamp.sh +0 -0
- /package/{packages/cli/templates → templates}/lib/common.sh +0 -0
- /package/{packages/cli/templates → templates}/lib/jq-fallback.sh +0 -0
- /package/{packages/cli/templates → templates}/markdownlint.jsonc +0 -0
- /package/{framework → templates}/prompts/arch-review.md +0 -0
- /package/{framework → templates}/prompts/quality-review.md +0 -0
- /package/{framework/skills/quality-reviewer → templates/skills/safeword-quality-reviewer}/SKILL.md +0 -0
|
@@ -1,596 +0,0 @@
|
|
|
1
|
-
# CLI Self-Contained Templates
|
|
2
|
-
|
|
3
|
-
**Date:** 2025-11-28
|
|
4
|
-
**Status:** Planning
|
|
5
|
-
**Ticket:** TBD
|
|
6
|
-
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
## Problem & Goal
|
|
10
|
-
|
|
11
|
-
**Problem:** CLI embeds stub templates; full content (guides, SAFEWORD.md) lives in `framework/` and isn't bundled.
|
|
12
|
-
|
|
13
|
-
**Goal:** Make `npx safeword` fully self-contained by bundling all templates.
|
|
14
|
-
|
|
15
|
-
---
|
|
16
|
-
|
|
17
|
-
## Current State
|
|
18
|
-
|
|
19
|
-
```
|
|
20
|
-
packages/cli/
|
|
21
|
-
├── src/templates/
|
|
22
|
-
│ ├── content.ts # Hardcoded string constants (stubs only)
|
|
23
|
-
│ └── config.ts # ESLint configs
|
|
24
|
-
├── templates/
|
|
25
|
-
│ ├── doc-templates/
|
|
26
|
-
│ │ └── ticket-template.md
|
|
27
|
-
│ └── hooks/
|
|
28
|
-
│ └── inject-timestamp.sh
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
**Problems:**
|
|
32
|
-
- `SAFEWORD_MD` in content.ts is a 38-line stub, not the full 31KB file
|
|
33
|
-
- No guides copied to user projects
|
|
34
|
-
- No doc templates copied
|
|
35
|
-
- Maintaining markdown as escaped TS strings is error-prone
|
|
36
|
-
|
|
37
|
-
---
|
|
38
|
-
|
|
39
|
-
## Proposed Structure
|
|
40
|
-
|
|
41
|
-
```
|
|
42
|
-
packages/cli/
|
|
43
|
-
├── src/
|
|
44
|
-
│ ├── cli.ts # Entry point with shebang
|
|
45
|
-
│ ├── index.ts # Library exports
|
|
46
|
-
│ ├── version.ts
|
|
47
|
-
│ ├── commands/
|
|
48
|
-
│ │ ├── check.ts
|
|
49
|
-
│ │ ├── diff.ts
|
|
50
|
-
│ │ ├── reset.ts
|
|
51
|
-
│ │ ├── setup.ts
|
|
52
|
-
│ │ └── upgrade.ts
|
|
53
|
-
│ ├── utils/
|
|
54
|
-
│ │ ├── fs.ts
|
|
55
|
-
│ │ ├── git.ts
|
|
56
|
-
│ │ ├── output.ts
|
|
57
|
-
│ │ ├── project-detector.ts
|
|
58
|
-
│ │ ├── templates.ts # NEW: Template file reader
|
|
59
|
-
│ │ └── version.ts
|
|
60
|
-
│ └── config/ # RENAMED from src/templates/
|
|
61
|
-
│ ├── eslint.ts # ESLint config generation
|
|
62
|
-
│ ├── hooks.ts # SETTINGS_HOOKS for .claude/settings.json
|
|
63
|
-
│ └── index.ts
|
|
64
|
-
├── templates/
|
|
65
|
-
│ ├── README.md # Documents bundled assets
|
|
66
|
-
│ ├── safeword/ # → .safeword/ (no dot to avoid npm issues)
|
|
67
|
-
│ │ ├── SAFEWORD.md # Full 31KB version
|
|
68
|
-
│ │ ├── guides/ # 13 methodology guides
|
|
69
|
-
│ │ ├── doc-templates/ # 5 doc templates (renamed from templates/)
|
|
70
|
-
│ │ ├── prompts/ # 2 review prompts
|
|
71
|
-
│ │ ├── hooks/ # Claude Code hooks (registered in .claude/settings.json)
|
|
72
|
-
│ │ │ ├── session-verify-agents.sh # SessionStart: verify AGENTS.md
|
|
73
|
-
│ │ │ ├── session-version.sh # SessionStart: display version
|
|
74
|
-
│ │ │ ├── session-lint-check.sh # SessionStart: linting sync check
|
|
75
|
-
│ │ │ ├── prompt-timestamp.sh # UserPromptSubmit: inject timestamp
|
|
76
|
-
│ │ │ ├── prompt-questions.sh # UserPromptSubmit: guide questions
|
|
77
|
-
│ │ │ ├── stop-quality.sh # Stop: trigger quality review
|
|
78
|
-
│ │ │ └── post-tool-lint.sh # PostToolUse: auto-lint files
|
|
79
|
-
│ │ ├── lib/ # Shared scripts (called by hooks, not registered)
|
|
80
|
-
│ │ │ ├── _lib-quality-prompt.sh # Quality review prompt content
|
|
81
|
-
│ │ │ └── _lib-run-linters.sh # Prettier + ESLint runner
|
|
82
|
-
│ │ └── git/ # Git hooks (installed to .git/hooks/)
|
|
83
|
-
│ │ └── git-pre-commit.sh # Pre-commit linting
|
|
84
|
-
│ └── claude/ # → .claude/ (MUST be .claude/ per Claude Code docs)
|
|
85
|
-
│ ├── commands/ # Slash commands (must be in .claude/commands/)
|
|
86
|
-
│ │ ├── quality-review.md
|
|
87
|
-
│ │ ├── arch-review.md
|
|
88
|
-
│ │ └── lint.md
|
|
89
|
-
│ └── skills/ # Skills (must be in .claude/skills/)
|
|
90
|
-
│ └── quality-reviewer/
|
|
91
|
-
│ └── SKILL.md # Full skill with YAML frontmatter
|
|
92
|
-
│ # Note: MCP configs go in .mcp.json at project root, not in .claude/
|
|
93
|
-
├── tests/
|
|
94
|
-
├── dist/
|
|
95
|
-
├── ARCHITECTURE.md
|
|
96
|
-
├── package.json
|
|
97
|
-
├── tsconfig.json
|
|
98
|
-
├── tsup.config.ts
|
|
99
|
-
└── vitest.config.ts
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
**Key decisions:**
|
|
103
|
-
- Use `safeword/` and `claude/` (no dots) to avoid npm ignore issues, rename to `.safeword/` and `.claude/` at copy time
|
|
104
|
-
- Rename `templates/` → `doc-templates/` to avoid `templates/templates/` confusion
|
|
105
|
-
- **Hooks live in `.safeword/hooks/`** - scripts are stored here, referenced from `.claude/settings.json`
|
|
106
|
-
- **Commands MUST go to `.claude/commands/`** - Claude Code hardcodes this path
|
|
107
|
-
- **Skills MUST go to `.claude/skills/`** - Claude Code hardcodes this path
|
|
108
|
-
- **No CLAUDE.md creation** - Only update existing AGENTS.md or create minimal one with link
|
|
109
|
-
- **`learnings/` folder** - Created on setup, preserved on upgrade/reset (user content)
|
|
110
|
-
- **Merge settings.json** - Don't overwrite existing settings, merge hooks into existing file
|
|
111
|
-
- Use full skill file from `framework/skills/`, not the stub
|
|
112
|
-
- Don't bundle `framework/scripts/` - these are legacy bash scripts replaced by CLI
|
|
113
|
-
- Create empty planning/tickets/learnings directories programmatically
|
|
114
|
-
- Keep `src/config/hooks.ts` for `SETTINGS_HOOKS` constant (writes to `.claude/settings.json`)
|
|
115
|
-
- **ESM-only** - No CJS support needed for CLI targeting Node 18+
|
|
116
|
-
- **ESLint/Prettier always set up** - Core part of safeword, but preserve existing configs if present
|
|
117
|
-
|
|
118
|
-
---
|
|
119
|
-
|
|
120
|
-
## Files to Migrate
|
|
121
|
-
|
|
122
|
-
### To `.safeword/`
|
|
123
|
-
|
|
124
|
-
| From | To | Count |
|
|
125
|
-
|------|-----|-------|
|
|
126
|
-
| `framework/SAFEWORD.md` | `templates/safeword/SAFEWORD.md` | 1 |
|
|
127
|
-
| `framework/guides/*.md` | `templates/safeword/guides/` | 13 |
|
|
128
|
-
| `framework/templates/*.md` | `templates/safeword/doc-templates/` | 5 |
|
|
129
|
-
| `framework/prompts/*.md` | `templates/safeword/prompts/` | 2 |
|
|
130
|
-
|
|
131
|
-
### To `.safeword/hooks/`, `.safeword/lib/`, `.safeword/git/`
|
|
132
|
-
|
|
133
|
-
All hooks consolidated from legacy setup scripts with new naming convention:
|
|
134
|
-
|
|
135
|
-
| Source | Old Name | New Name | Location | Hook Event |
|
|
136
|
-
|--------|----------|----------|----------|------------|
|
|
137
|
-
| CLI existing | `agents-md-check.sh` | `session-verify-agents.sh` | `hooks/` | SessionStart |
|
|
138
|
-
| `setup-quality.sh` | `version-check.sh` | `session-version.sh` | `hooks/` | SessionStart |
|
|
139
|
-
| `setup-linting.sh` | `check-linting-sync.sh` | `session-lint-check.sh` | `hooks/` | SessionStart |
|
|
140
|
-
| `setup-safeword.sh` | `inject-timestamp.sh` | `prompt-timestamp.sh` | `hooks/` | UserPromptSubmit |
|
|
141
|
-
| `.claude/hooks/` | `question-protocol.sh` | `prompt-questions.sh` | `hooks/` | UserPromptSubmit |
|
|
142
|
-
| `setup-quality.sh` | `auto-quality-review.sh` | `stop-quality.sh` | `hooks/` | Stop |
|
|
143
|
-
| `setup-linting.sh` | `auto-lint.sh` | `post-tool-lint.sh` | `hooks/` | PostToolUse |
|
|
144
|
-
| `setup-quality.sh` | `run-quality-review.sh` | `_lib-quality-prompt.sh` | `lib/` | (shared) |
|
|
145
|
-
| `setup-linting.sh` | `run-linters.sh` | `_lib-run-linters.sh` | `lib/` | (shared) |
|
|
146
|
-
| CLI existing | `pre-commit.sh` | `git-pre-commit.sh` | `git/` | (git hook) |
|
|
147
|
-
|
|
148
|
-
### To `.claude/commands/` (must be .claude/ per Claude Code docs)
|
|
149
|
-
|
|
150
|
-
| Source | File | Purpose |
|
|
151
|
-
|--------|------|---------|
|
|
152
|
-
| `setup-quality.sh` | `quality-review.md` | Manual quality review trigger |
|
|
153
|
-
| existing | `arch-review.md` | Trigger architecture review |
|
|
154
|
-
| `setup-linting.sh` | `lint.md` | Run linting on all files |
|
|
155
|
-
|
|
156
|
-
### To `.claude/skills/`
|
|
157
|
-
|
|
158
|
-
| From | To |
|
|
159
|
-
|------|-----|
|
|
160
|
-
| `framework/skills/quality-reviewer/` | `templates/claude/skills/quality-reviewer/` |
|
|
161
|
-
|
|
162
|
-
**Not bundled:**
|
|
163
|
-
- `framework/scripts/` - Legacy bash scripts (replaced by CLI)
|
|
164
|
-
- `framework/README.md` - Documentation only
|
|
165
|
-
- Empty directory structures (created programmatically)
|
|
166
|
-
|
|
167
|
-
**Total:** 35 files (21 in `.safeword/` + 7 hooks + 2 lib + 1 git + 3 commands + 1 skill)
|
|
168
|
-
|
|
169
|
-
**Note:** Commands and skills MUST be in `.claude/` - Claude Code does not support custom paths.
|
|
170
|
-
**Note:** MCP configs go in `.mcp.json` at project root (not in `.claude/`).
|
|
171
|
-
|
|
172
|
-
---
|
|
173
|
-
|
|
174
|
-
## Hook System
|
|
175
|
-
|
|
176
|
-
**Architecture:** Scripts in `.safeword/hooks/` are registered in `.claude/settings.json`. Naming pattern: `{event}-{action}.sh`
|
|
177
|
-
|
|
178
|
-
### Directory Structure
|
|
179
|
-
|
|
180
|
-
```
|
|
181
|
-
.safeword/
|
|
182
|
-
├── hooks/ # Claude Code hooks (registered in settings.json)
|
|
183
|
-
│ ├── session-verify-agents.sh # SessionStart: verify AGENTS.md
|
|
184
|
-
│ ├── session-version.sh # SessionStart: display version
|
|
185
|
-
│ ├── session-lint-check.sh # SessionStart: linting sync check
|
|
186
|
-
│ ├── prompt-questions.sh # UserPromptSubmit: guide questions
|
|
187
|
-
│ ├── prompt-timestamp.sh # UserPromptSubmit: inject timestamp
|
|
188
|
-
│ ├── stop-quality.sh # Stop: trigger quality review
|
|
189
|
-
│ └── post-tool-lint.sh # PostToolUse: auto-lint (matcher supported)
|
|
190
|
-
├── lib/ # Shared scripts (not registered, called by hooks)
|
|
191
|
-
│ ├── _lib-quality-prompt.sh # Quality review prompt content
|
|
192
|
-
│ └── _lib-run-linters.sh # Prettier + ESLint runner
|
|
193
|
-
└── git/ # Git hooks (installed to .git/hooks/)
|
|
194
|
-
└── git-pre-commit.sh # Pre-commit linting
|
|
195
|
-
```
|
|
196
|
-
|
|
197
|
-
### SETTINGS_HOOKS (Canonical)
|
|
198
|
-
|
|
199
|
-
⚠️ **CRITICAL:** Current CLI uses incorrect flat format. Must use nested format with `_safeword: true` marker:
|
|
200
|
-
|
|
201
|
-
```typescript
|
|
202
|
-
// src/config/hooks.ts - writes to .claude/settings.json
|
|
203
|
-
export const SETTINGS_HOOKS = {
|
|
204
|
-
SessionStart: [
|
|
205
|
-
{ _safeword: true, hooks: [{ type: 'command', command: '$CLAUDE_PROJECT_DIR/.safeword/hooks/session-verify-agents.sh', timeout: 5000 }] },
|
|
206
|
-
{ _safeword: true, hooks: [{ type: 'command', command: '$CLAUDE_PROJECT_DIR/.safeword/hooks/session-version.sh', timeout: 5000 }] },
|
|
207
|
-
{ _safeword: true, hooks: [{ type: 'command', command: '$CLAUDE_PROJECT_DIR/.safeword/hooks/session-lint-check.sh', timeout: 5000 }] },
|
|
208
|
-
],
|
|
209
|
-
UserPromptSubmit: [
|
|
210
|
-
// Note: matcher not supported on UserPromptSubmit - runs on all prompts
|
|
211
|
-
{ _safeword: true, hooks: [{ type: 'command', command: '$CLAUDE_PROJECT_DIR/.safeword/hooks/prompt-questions.sh', timeout: 2000 }] },
|
|
212
|
-
{ _safeword: true, hooks: [{ type: 'command', command: '$CLAUDE_PROJECT_DIR/.safeword/hooks/prompt-timestamp.sh', timeout: 2000 }] },
|
|
213
|
-
],
|
|
214
|
-
Stop: [
|
|
215
|
-
{ _safeword: true, hooks: [{ type: 'command', command: '$CLAUDE_PROJECT_DIR/.safeword/hooks/stop-quality.sh', timeout: 120000 }] },
|
|
216
|
-
],
|
|
217
|
-
PostToolUse: [
|
|
218
|
-
// matcher IS supported on PostToolUse - filters by tool name
|
|
219
|
-
{ _safeword: true, matcher: 'Write|Edit|MultiEdit|NotebookEdit', hooks: [{ type: 'command', command: '$CLAUDE_PROJECT_DIR/.safeword/hooks/post-tool-lint.sh', timeout: 10000 }] },
|
|
220
|
-
],
|
|
221
|
-
};
|
|
222
|
-
```
|
|
223
|
-
|
|
224
|
-
---
|
|
225
|
-
|
|
226
|
-
## Claude Code Skills Configuration
|
|
227
|
-
|
|
228
|
-
**Current issue:** The skill installed by CLI (`safeword-quality-reviewer/SKILL.md`) is a 12-line stub missing YAML frontmatter.
|
|
229
|
-
|
|
230
|
-
**Required format per Claude Code docs:**
|
|
231
|
-
|
|
232
|
-
```yaml
|
|
233
|
-
---
|
|
234
|
-
name: safeword-quality-reviewer
|
|
235
|
-
description: Deep code quality review with web research. Use when user explicitly requests verification against latest docs, needs deeper analysis, or is working on projects without SAFEWORD.md/CLAUDE.md.
|
|
236
|
-
allowed-tools: '*'
|
|
237
|
-
---
|
|
238
|
-
|
|
239
|
-
# Quality Reviewer
|
|
240
|
-
|
|
241
|
-
[Full skill content - 208 lines from framework/skills/quality-reviewer/SKILL.md]
|
|
242
|
-
```
|
|
243
|
-
|
|
244
|
-
**Required YAML frontmatter fields:**
|
|
245
|
-
| Field | Required | Format |
|
|
246
|
-
|-------|----------|--------|
|
|
247
|
-
| `name` | Yes | Lowercase letters, numbers, hyphens only (max 64 chars) |
|
|
248
|
-
| `description` | Yes | What it does AND when Claude should use it (max 1024 chars) |
|
|
249
|
-
| `allowed-tools` | No | Comma-separated tool list or `'*'` for all |
|
|
250
|
-
|
|
251
|
-
**Implementation:** Copy the full `framework/skills/quality-reviewer/SKILL.md` (208 lines with proper frontmatter) to `templates/claude/skills/safeword-quality-reviewer/SKILL.md`.
|
|
252
|
-
|
|
253
|
-
---
|
|
254
|
-
|
|
255
|
-
## Claude Code Commands (Not Currently Installed)
|
|
256
|
-
|
|
257
|
-
The CLI currently does NOT install slash commands. Consider adding in future:
|
|
258
|
-
|
|
259
|
-
**Storage location:** `.claude/commands/`
|
|
260
|
-
|
|
261
|
-
**Potential commands to bundle:**
|
|
262
|
-
| Command | Purpose |
|
|
263
|
-
|---------|---------|
|
|
264
|
-
| `quality-review.md` | Trigger manual quality review |
|
|
265
|
-
| `arch-review.md` | Trigger architecture review |
|
|
266
|
-
|
|
267
|
-
**Format:**
|
|
268
|
-
```yaml
|
|
269
|
-
---
|
|
270
|
-
description: Brief command description
|
|
271
|
-
---
|
|
272
|
-
|
|
273
|
-
Command instructions...
|
|
274
|
-
```
|
|
275
|
-
|
|
276
|
-
**Decision:** Commands are optional for MVP. Focus on skills and hooks first.
|
|
277
|
-
|
|
278
|
-
---
|
|
279
|
-
|
|
280
|
-
## Package.json Updates
|
|
281
|
-
|
|
282
|
-
The current `package.json` needs these improvements per [2024/2025 npm best practices](https://snyk.io/blog/building-npm-package-compatible-with-esm-and-cjs-2024/):
|
|
283
|
-
|
|
284
|
-
### Current
|
|
285
|
-
```json
|
|
286
|
-
{
|
|
287
|
-
"name": "safeword",
|
|
288
|
-
"version": "0.1.0",
|
|
289
|
-
"type": "module",
|
|
290
|
-
"bin": {
|
|
291
|
-
"safeword": "./dist/cli.js"
|
|
292
|
-
},
|
|
293
|
-
"exports": {
|
|
294
|
-
".": {
|
|
295
|
-
"import": "./dist/index.js",
|
|
296
|
-
"types": "./dist/index.d.ts"
|
|
297
|
-
}
|
|
298
|
-
},
|
|
299
|
-
"files": ["dist", "templates"],
|
|
300
|
-
"engines": { "node": ">=18" }
|
|
301
|
-
}
|
|
302
|
-
```
|
|
303
|
-
|
|
304
|
-
### Updated
|
|
305
|
-
```json
|
|
306
|
-
{
|
|
307
|
-
"name": "safeword",
|
|
308
|
-
"version": "0.1.0",
|
|
309
|
-
"description": "CLI for setting up AI coding agent configurations",
|
|
310
|
-
"type": "module",
|
|
311
|
-
"bin": {
|
|
312
|
-
"safeword": "./dist/cli.js"
|
|
313
|
-
},
|
|
314
|
-
"exports": {
|
|
315
|
-
".": {
|
|
316
|
-
"types": "./dist/index.d.ts",
|
|
317
|
-
"import": "./dist/index.js"
|
|
318
|
-
}
|
|
319
|
-
},
|
|
320
|
-
"files": ["dist", "templates"],
|
|
321
|
-
"sideEffects": false,
|
|
322
|
-
"engines": { "node": ">=18" },
|
|
323
|
-
"repository": {
|
|
324
|
-
"type": "git",
|
|
325
|
-
"url": "https://github.com/your-org/safeword"
|
|
326
|
-
},
|
|
327
|
-
"homepage": "https://github.com/your-org/safeword#readme",
|
|
328
|
-
"bugs": {
|
|
329
|
-
"url": "https://github.com/your-org/safeword/issues"
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
|
-
```
|
|
333
|
-
|
|
334
|
-
**Changes:**
|
|
335
|
-
1. **`types` first in exports** - TypeScript resolution requires types condition before import
|
|
336
|
-
2. **`sideEffects: false`** - Enables tree-shaking for bundlers
|
|
337
|
-
3. **`repository`, `homepage`, `bugs`** - Proper npm registry display
|
|
338
|
-
|
|
339
|
-
---
|
|
340
|
-
|
|
341
|
-
## Implementation Snippets
|
|
342
|
-
|
|
343
|
-
See **[013b-implementation-snippets.md](./013b-implementation-snippets.md)** for all code examples:
|
|
344
|
-
- Template reader (`src/utils/templates.ts`)
|
|
345
|
-
- Setup/upgrade usage patterns
|
|
346
|
-
- Settings.json merge logic
|
|
347
|
-
- Linting setup (preserve existing)
|
|
348
|
-
- Error handling & rollback
|
|
349
|
-
- ESLint plugin installation
|
|
350
|
-
- MCP config setup & cleanup
|
|
351
|
-
- Hook output format (`hookSpecificOutput`)
|
|
352
|
-
- Slash command templates
|
|
353
|
-
- Testing examples (unit, integration, promptfoo)
|
|
354
|
-
|
|
355
|
-
---
|
|
356
|
-
|
|
357
|
-
## Migration Steps
|
|
358
|
-
|
|
359
|
-
> **Goal:** Bundle all templates into CLI, fix hooks format, verify all internal references work.
|
|
360
|
-
|
|
361
|
-
### 1.1 Structure Setup
|
|
362
|
-
1. [ ] Create `packages/cli/templates/safeword/` directory structure (no dot - npm ignores dotfiles)
|
|
363
|
-
2. [ ] Create `packages/cli/templates/claude/` directory structure
|
|
364
|
-
3. [ ] Create `packages/cli/templates/README.md` documenting the mapping:
|
|
365
|
-
- `templates/safeword/` → `.safeword/`
|
|
366
|
-
- `templates/claude/` → `.claude/`
|
|
367
|
-
|
|
368
|
-
### 1.2 Content Migration
|
|
369
|
-
4. [ ] Copy from `framework/`:
|
|
370
|
-
- `SAFEWORD.md` → `templates/safeword/SAFEWORD.md`
|
|
371
|
-
- `guides/` → `templates/safeword/guides/`
|
|
372
|
-
- `templates/` → `templates/safeword/doc-templates/`
|
|
373
|
-
- `prompts/` → `templates/safeword/prompts/`
|
|
374
|
-
5. [ ] Copy hooks to `templates/safeword/hooks/`:
|
|
375
|
-
- From `setup-safeword.sh`: extract `inject-timestamp.sh` (lines ~102-109)
|
|
376
|
-
- From `setup-quality.sh`: extract `auto-quality-review.sh` (lines ~74-252), `run-quality-review.sh` (lines ~256-334), `version-check.sh` (lines ~338-372)
|
|
377
|
-
- From `setup-linting.sh`: extract `auto-lint.sh` (lines ~459-466), `run-linters.sh` (lines ~447-456), `check-linting-sync.sh` (lines ~494-512)
|
|
378
|
-
- Copy existing: `.claude/hooks/question-protocol.sh`
|
|
379
|
-
- Copy existing: `.safeword/hooks/agents-md-check.sh`, `.safeword/hooks/pre-commit.sh`
|
|
380
|
-
6. [ ] Copy skill: `framework/skills/quality-reviewer/` → `templates/claude/skills/quality-reviewer/`
|
|
381
|
-
7. [ ] Copy commands to `templates/claude/commands/`:
|
|
382
|
-
- From `setup-quality.sh`: extract `/quality-review` command (lines ~341-350)
|
|
383
|
-
- From `setup-linting.sh`: extract `/lint` command
|
|
384
|
-
- Copy existing: `.claude/commands/arch-review.md`
|
|
385
|
-
8. [ ] Copy MCP configs: `framework/mcp/*.sample.json` → `templates/claude/mcp/`
|
|
386
|
-
9. [ ] Rename scripts during copy using new naming convention (see Hook System section)
|
|
387
|
-
10. [ ] Update internal `source` calls in hooks to use new lib paths:
|
|
388
|
-
- `source "$CLAUDE_PROJECT_DIR/.safeword/lib/_lib-quality-prompt.sh"`
|
|
389
|
-
- `source "$CLAUDE_PROJECT_DIR/.safeword/lib/_lib-run-linters.sh"`
|
|
390
|
-
|
|
391
|
-
### 1.3 Link & Import Verification
|
|
392
|
-
11. [ ] Audit all markdown files for internal links - update paths:
|
|
393
|
-
- `@./framework/` → `@./.safeword/`
|
|
394
|
-
- Relative links between guides
|
|
395
|
-
12. [ ] Audit hook scripts for path references:
|
|
396
|
-
- `$CLAUDE_PROJECT_DIR/.safeword/hooks/` paths
|
|
397
|
-
- `$CLAUDE_PROJECT_DIR/.safeword/prompts/` paths
|
|
398
|
-
- Calls between hooks (e.g., `stop-quality.sh` → `_lib-quality-prompt.sh`)
|
|
399
|
-
13. [ ] Audit skill files for path references
|
|
400
|
-
14. [ ] Verify all `source` or `bash` calls use correct paths
|
|
401
|
-
|
|
402
|
-
### 1.4 Code Updates
|
|
403
|
-
15. [ ] Create `src/utils/templates.ts` with file reading utilities
|
|
404
|
-
16. [ ] Rename `src/templates/` → `src/config/`
|
|
405
|
-
17. [ ] Update `SETTINGS_HOOKS` in `src/config/hooks.ts` (new names + nested format + timeouts)
|
|
406
|
-
18. [ ] Update `setup.ts` to use new template system
|
|
407
|
-
19. [ ] Update `upgrade.ts` to use new template system
|
|
408
|
-
20. [ ] Update setup/upgrade to create empty planning/tickets directories
|
|
409
|
-
21. [ ] Delete `src/config/content.ts` (move remaining content to templates)
|
|
410
|
-
|
|
411
|
-
### 1.5 Package Updates
|
|
412
|
-
22. [ ] Update `package.json`:
|
|
413
|
-
- `types` first in exports
|
|
414
|
-
- Add `sideEffects: false`
|
|
415
|
-
- Add `repository`, `homepage`, `bugs`
|
|
416
|
-
23. [ ] Create `packages/cli/README.md` with:
|
|
417
|
-
- Installation instructions (`npx safeword setup`)
|
|
418
|
-
- What it installs
|
|
419
|
-
- Commands reference
|
|
420
|
-
- Link to main project docs
|
|
421
|
-
|
|
422
|
-
### 1.6 Testing & Cleanup
|
|
423
|
-
24. [ ] Test: `cd packages/cli && npm run build && npm pack`
|
|
424
|
-
25. [ ] Test: `npm pack --dry-run` shows all templates
|
|
425
|
-
26. [ ] Test: Install in fresh project, verify:
|
|
426
|
-
- All files present in `.safeword/` and `.claude/`
|
|
427
|
-
- All hooks execute without path errors
|
|
428
|
-
- Hook-to-hook calls work (stop-quality → _lib-quality-prompt)
|
|
429
|
-
- Skills load correctly
|
|
430
|
-
- Commands work
|
|
431
|
-
- MCP configs present
|
|
432
|
-
27. [ ] Delete `framework/` directory
|
|
433
|
-
28. [ ] Update root `README.md` with project overview
|
|
434
|
-
29. [ ] Update `AGENTS.md` to remove framework/ references
|
|
435
|
-
|
|
436
|
-
---
|
|
437
|
-
|
|
438
|
-
## Verification
|
|
439
|
-
|
|
440
|
-
After migration, verify:
|
|
441
|
-
|
|
442
|
-
1. **Build works:** `npm run build` succeeds
|
|
443
|
-
2. **Package includes templates:** `npm pack --dry-run` shows templates
|
|
444
|
-
3. **Setup works:** `npx safeword setup` in fresh project installs all files
|
|
445
|
-
4. **Upgrade works:** `npx safeword upgrade` updates all files
|
|
446
|
-
5. **Guides present:** `.safeword/guides/` has 13 files
|
|
447
|
-
6. **Full SAFEWORD.md:** File is ~31KB, not stub
|
|
448
|
-
7. **Planning dirs created:** Empty planning/tickets structure exists
|
|
449
|
-
|
|
450
|
-
---
|
|
451
|
-
|
|
452
|
-
## Rollback
|
|
453
|
-
|
|
454
|
-
If issues arise, revert to string constants approach by:
|
|
455
|
-
1. Restore `src/templates/content.ts`
|
|
456
|
-
2. Remove `templates/.safeword/` and `templates/.claude/`
|
|
457
|
-
3. Revert `setup.ts` and `upgrade.ts` changes
|
|
458
|
-
|
|
459
|
-
---
|
|
460
|
-
|
|
461
|
-
## ESLint Plugin Suite
|
|
462
|
-
|
|
463
|
-
See **[013a-eslint-plugin-suite.md](./013a-eslint-plugin-suite.md)** for full details.
|
|
464
|
-
|
|
465
|
-
**Summary:**
|
|
466
|
-
- **Core (always):** SonarJS, Microsoft SDL (superset of eslint-plugin-security)
|
|
467
|
-
- **Auto-detected:** React, Next.js, Astro, Electron, Vitest, Playwright, Drizzle
|
|
468
|
-
- **Boundaries:** Auto-generates config when 3+ architecture dirs detected (warn severity)
|
|
469
|
-
- **Containers:** Hadolint (separate tool, added to pre-commit if Dockerfile exists)
|
|
470
|
-
|
|
471
|
-
---
|
|
472
|
-
|
|
473
|
-
## Markdown Linting
|
|
474
|
-
|
|
475
|
-
Safeword includes markdown linting for `.safeword/` documentation using `markdownlint-cli2`.
|
|
476
|
-
|
|
477
|
-
### Why markdownlint-cli2?
|
|
478
|
-
|
|
479
|
-
| Tool | Verdict |
|
|
480
|
-
|------|---------|
|
|
481
|
-
| `markdownlint-cli2` | ✅ **Chosen** - Industry standard, fast, simple config |
|
|
482
|
-
| `eslint-plugin-markdownlint` | ❌ Less mature, adds ESLint complexity |
|
|
483
|
-
| `remark-lint` | ❌ Overkill, slow AST parsing |
|
|
484
|
-
| `textlint` | ❌ Prose-focused, not needed |
|
|
485
|
-
|
|
486
|
-
### Scope
|
|
487
|
-
|
|
488
|
-
Markdown linting applies to safeword documentation only:
|
|
489
|
-
- `.safeword/**/*.md`
|
|
490
|
-
- `AGENTS.md`
|
|
491
|
-
- `CLAUDE.md` (if present)
|
|
492
|
-
|
|
493
|
-
**Not linted:** User's project markdown (README, docs/) - too opinionated for general use.
|
|
494
|
-
|
|
495
|
-
### Configuration
|
|
496
|
-
|
|
497
|
-
```jsonc
|
|
498
|
-
// .safeword/.markdownlint.jsonc (SAFEWORD OWNS)
|
|
499
|
-
{
|
|
500
|
-
"default": true,
|
|
501
|
-
"MD013": false, // Disable line length (docs have long lines)
|
|
502
|
-
"MD033": false, // Allow inline HTML (badges, details tags)
|
|
503
|
-
"MD041": false, // First line doesn't need to be h1
|
|
504
|
-
"MD024": { // Allow duplicate headings in different sections
|
|
505
|
-
"siblings_only": true
|
|
506
|
-
}
|
|
507
|
-
}
|
|
508
|
-
```
|
|
509
|
-
|
|
510
|
-
**Note:** Using `.jsonc` extension allows comments. Alternatively, use `.markdownlint.yaml`.
|
|
511
|
-
|
|
512
|
-
**Rationale for disabled rules:**
|
|
513
|
-
- **MD013 (line-length)**: AI-generated docs often have long lines; breaking them hurts readability
|
|
514
|
-
- **MD033 (no-inline-html)**: Badges, collapsible sections need HTML
|
|
515
|
-
- **MD041 (first-line-heading)**: SAFEWORD.md starts with frontmatter comment
|
|
516
|
-
|
|
517
|
-
### Integration
|
|
518
|
-
|
|
519
|
-
**Pre-commit hook** (in `git-pre-commit.sh`):
|
|
520
|
-
```bash
|
|
521
|
-
# Lint markdown in .safeword/
|
|
522
|
-
npx markdownlint-cli2 ".safeword/**/*.md" "AGENTS.md" --config .safeword/.markdownlint.jsonc
|
|
523
|
-
```
|
|
524
|
-
|
|
525
|
-
**npm script** (added to package.json):
|
|
526
|
-
```json
|
|
527
|
-
{
|
|
528
|
-
"scripts": {
|
|
529
|
-
"lint:md": "markdownlint-cli2 '.safeword/**/*.md' 'AGENTS.md' --config .safeword/.markdownlint.jsonc"
|
|
530
|
-
}
|
|
531
|
-
}
|
|
532
|
-
```
|
|
533
|
-
|
|
534
|
-
### Installation
|
|
535
|
-
|
|
536
|
-
Added to project devDependencies during `safeword init`:
|
|
537
|
-
```typescript
|
|
538
|
-
plugins.push('markdownlint-cli2');
|
|
539
|
-
```
|
|
540
|
-
|
|
541
|
-
---
|
|
542
|
-
|
|
543
|
-
## Config Isolation Strategy
|
|
544
|
-
|
|
545
|
-
See **[013c-config-isolation-strategy.md](./013c-config-isolation-strategy.md)** for full details.
|
|
546
|
-
|
|
547
|
-
**Summary:** Safeword keeps its configs separate from user customizations for clean upgrades:
|
|
548
|
-
- **ESLint:** User imports `.safeword/eslint.config.js` via `extends`
|
|
549
|
-
- **Prettier:** User spreads `.safeword/prettier.config.js`
|
|
550
|
-
- **Claude hooks:** Safeword hooks marked with `_safeword: true` for upgrade identification
|
|
551
|
-
- **package.json scripts:** Add if missing, never overwrite existing
|
|
552
|
-
|
|
553
|
-
---
|
|
554
|
-
|
|
555
|
-
## Design Decisions
|
|
556
|
-
|
|
557
|
-
See **[013b-implementation-snippets.md](./013b-implementation-snippets.md)** for code examples.
|
|
558
|
-
|
|
559
|
-
| Decision | Choice | Rationale |
|
|
560
|
-
|----------|--------|-----------|
|
|
561
|
-
| **Error handling** | Hybrid (fatal vs non-fatal) | Fatal for core (filesystem, package.json), warn for optional (boundaries, MCP) |
|
|
562
|
-
| **Rollback** | `withRollback()` + `.backup/` dirs | Atomic operations, restore on failure, delete backup on success |
|
|
563
|
-
| **ESLint plugins** | Project devDependencies | Not bundled with CLI; auto-detect package manager (npm/yarn/pnpm/bun) |
|
|
564
|
-
| **MCP configs** | `.mcp.json` at root | Auto-add free (Context7, Playwright), sample for API-key (Arcade) |
|
|
565
|
-
| **Hook output** | `hookSpecificOutput` JSON via `jq` | Required format per Claude Code docs; `safeword check` verifies jq installed |
|
|
566
|
-
| **Command frontmatter** | `description` + `allowed-tools` | Per Claude Code slash command docs |
|
|
567
|
-
| **Testing** | Unit + integration + snapshot + promptfoo | Vitest for code, promptfoo for LLM evals |
|
|
568
|
-
| **Reset cleanup** | Add MCP cleanup to `reset.ts` | Remove context7/playwright from `.mcp.json`, delete `.mcp.json.sample` |
|
|
569
|
-
|
|
570
|
-
### hookSpecificOutput Format
|
|
571
|
-
|
|
572
|
-
Hooks must output JSON with `jq` (not plain echo):
|
|
573
|
-
|
|
574
|
-
```bash
|
|
575
|
-
# Example: session-verify-agents.sh
|
|
576
|
-
jq -n '{"hookSpecificOutput": {"hookEventName": "SessionStart", "additionalContext": "AGENTS.md verified"}}'
|
|
577
|
-
# Or for errors:
|
|
578
|
-
jq -n '{"hookSpecificOutput": {"hookEventName": "SessionStart", "blockReason": "AGENTS.md not found"}}'
|
|
579
|
-
exit 2
|
|
580
|
-
```
|
|
581
|
-
|
|
582
|
-
### Key Implementation Notes
|
|
583
|
-
|
|
584
|
-
- **SafewordError class:** `new SafewordError(msg, fatal: boolean)` - fatal exits, non-fatal warns
|
|
585
|
-
- **Package manager detection:** Check for lock files (yarn.lock, pnpm-lock.yaml, bun.lockb)
|
|
586
|
-
- **MCP merge strategy:** Use `??=` to add servers without overwriting existing
|
|
587
|
-
|
|
588
|
-
---
|
|
589
|
-
|
|
590
|
-
## References
|
|
591
|
-
|
|
592
|
-
- [Claude Code Hooks Documentation](https://docs.anthropic.com/en/docs/claude-code/hooks)
|
|
593
|
-
- [Building npm packages compatible with ESM and CJS in 2024](https://snyk.io/blog/building-npm-package-compatible-with-esm-and-cjs-2024/)
|
|
594
|
-
- [TypeScript and NPM package.json exports the 2024 way](https://www.velopen.com/blog/typescript-npm-package-json-exports/)
|
|
595
|
-
- [Tutorial: publishing ESM-based npm packages with TypeScript](https://2ality.com/2025/02/typescript-esm-packages.html)
|
|
596
|
-
- [TypeScript ESM Publishing Documentation](https://www.typescriptlang.org/docs/handbook/esm-node.html)
|