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,559 +0,0 @@
1
- #!/bin/bash
2
- ################################################################################
3
- # Claude Code Linting Hook Setup Script
4
- #
5
- # Automatically detects project type and configures ESLint + Prettier.
6
- #
7
- # Architecture:
8
- # .safeword/eslint/eslint-base.mjs ← Auto-generated every run. Don't edit.
9
- # eslint.config.mjs ← Your config. Customize freely.
10
- #
11
- # Usage:
12
- # bash setup-linting.sh # Setup/update linting
13
- # bash setup-linting.sh --no-typescript # Skip TypeScript detection
14
- # bash setup-linting.sh --no-react # Skip React detection
15
- #
16
- # Auto-detection:
17
- # - TypeScript: tsconfig.json OR typescript in package.json
18
- # - React: react in package.json
19
- # - Astro: astro in package.json
20
- ################################################################################
21
-
22
- set -e
23
-
24
- VERSION="v3.1.0"
25
-
26
- # Parse arguments
27
- SKIP_TYPESCRIPT=false
28
- SKIP_REACT=false
29
- SKIP_ASTRO=false
30
-
31
- while [[ $# -gt 0 ]]; do
32
- case $1 in
33
- --no-typescript|--no-ts) SKIP_TYPESCRIPT=true; shift ;;
34
- --no-react) SKIP_REACT=true; shift ;;
35
- --no-astro) SKIP_ASTRO=true; shift ;;
36
- --help|-h)
37
- echo "Usage: bash setup-linting.sh [options]"
38
- echo ""
39
- echo "Options:"
40
- echo " --no-typescript Skip TypeScript even if detected"
41
- echo " --no-react Skip React even if detected"
42
- echo " --no-astro Skip Astro even if detected"
43
- echo ""
44
- echo "Files:"
45
- echo " $BASE_DIR/eslint-base.mjs - Auto-generated (updated every run)"
46
- echo " eslint.config.mjs - Your config (created once, never overwritten)"
47
- exit 0
48
- ;;
49
- *) echo "Unknown option: $1 (use --help for usage)"; exit 1 ;;
50
- esac
51
- done
52
-
53
- echo "================================="
54
- echo "Claude Code Linting Setup"
55
- echo "Version: $VERSION"
56
- echo "================================="
57
- echo ""
58
-
59
- PROJECT_ROOT="$(pwd)"
60
- echo "Setting up in: $PROJECT_ROOT"
61
- echo ""
62
-
63
- # ============================================================================
64
- # Step 1: Detect project type
65
- # ============================================================================
66
- echo "[1/5] Detecting project type..."
67
-
68
- HAS_TYPESCRIPT=false
69
- HAS_REACT=false
70
- HAS_ASTRO=false
71
-
72
- # Read dependencies from package.json
73
- if [ -f package.json ] && command -v jq &> /dev/null; then
74
- DEPS=$(jq -r '(.dependencies // {}), (.devDependencies // {}) | keys[]' package.json 2>/dev/null || echo "")
75
- elif [ -f package.json ]; then
76
- DEPS=$(grep -E '"[^"]+"\s*:' package.json | cut -d'"' -f2)
77
- else
78
- DEPS=""
79
- fi
80
-
81
- # TypeScript detection
82
- if [ "$SKIP_TYPESCRIPT" = false ]; then
83
- if [ -f tsconfig.json ] || echo "$DEPS" | grep -qx "typescript"; then
84
- HAS_TYPESCRIPT=true
85
- echo " ✓ TypeScript detected"
86
- fi
87
- fi
88
-
89
- # React detection
90
- if [ "$SKIP_REACT" = false ]; then
91
- if echo "$DEPS" | grep -qx "react"; then
92
- HAS_REACT=true
93
- echo " ✓ React detected"
94
- fi
95
- fi
96
-
97
- # Astro detection
98
- if [ "$SKIP_ASTRO" = false ]; then
99
- if echo "$DEPS" | grep -qx "astro"; then
100
- HAS_ASTRO=true
101
- echo " ✓ Astro detected"
102
- fi
103
- fi
104
-
105
- [ "$HAS_TYPESCRIPT" = false ] && [ "$HAS_REACT" = false ] && [ "$HAS_ASTRO" = false ] && echo " → JavaScript-only project"
106
- echo ""
107
-
108
- # ============================================================================
109
- # Step 2: Create package.json if needed
110
- # ============================================================================
111
- echo "[2/5] Checking package.json..."
112
-
113
- if [ ! -f package.json ]; then
114
- cat > package.json << 'EOF'
115
- {
116
- "name": "my-project",
117
- "version": "1.0.0",
118
- "type": "module",
119
- "scripts": {},
120
- "devDependencies": {}
121
- }
122
- EOF
123
- echo " ✓ Created package.json"
124
- else
125
- echo " ✓ package.json exists"
126
- fi
127
- echo ""
128
-
129
- # ============================================================================
130
- # Step 3: Install packages
131
- # ============================================================================
132
- echo "[3/5] Installing packages..."
133
-
134
- # Base packages (always installed)
135
- PACKAGES="eslint @eslint/js prettier eslint-config-prettier globals"
136
- PACKAGES+=" eslint-plugin-sonarjs @microsoft/eslint-plugin-sdl eslint-plugin-boundaries"
137
-
138
- # Conditional packages
139
- [ "$HAS_TYPESCRIPT" = true ] && PACKAGES+=" typescript-eslint"
140
- [ "$HAS_REACT" = true ] && PACKAGES+=" @eslint-react/eslint-plugin eslint-plugin-react-hooks eslint-plugin-react-perf"
141
- [ "$HAS_ASTRO" = true ] && PACKAGES+=" eslint-plugin-astro"
142
-
143
- echo " Installing: $PACKAGES"
144
- npm install --save-dev $PACKAGES --silent 2>&1 | grep -v "npm WARN" || true
145
- echo " ✓ Packages installed"
146
- echo ""
147
-
148
- # ============================================================================
149
- # Step 4: Generate ESLint configs
150
- # ============================================================================
151
- echo "[4/5] Generating ESLint configs..."
152
-
153
- mkdir -p .safeword
154
-
155
- # --- Always generate .safeword/eslint-base.mjs ---
156
- BASE_DIR=".safeword/eslint"
157
- mkdir -p "$BASE_DIR"
158
- echo " Generating $BASE_DIR/eslint-base.mjs..."
159
-
160
- # Build the file with prominent header
161
- cat > "$BASE_DIR/eslint-base.mjs" << 'HEADER'
162
- ////////////////////////////////////////////////////////////////////////////////
163
- //
164
- // ██████╗ ██████╗ ███╗ ██╗ ██████╗ ████████╗ ███████╗██████╗ ██╗████████╗
165
- // ██╔══██╗██╔═══██╗ ████╗ ██║██╔═══██╗╚══██╔══╝ ██╔════╝██╔══██╗██║╚══██╔══╝
166
- // ██║ ██║██║ ██║ ██╔██╗ ██║██║ ██║ ██║ █████╗ ██║ ██║██║ ██║
167
- // ██║ ██║██║ ██║ ██║╚██╗██║██║ ██║ ██║ ██╔══╝ ██║ ██║██║ ██║
168
- // ██████╔╝╚██████╔╝ ██║ ╚████║╚██████╔╝ ██║ ███████╗██████╔╝██║ ██║
169
- // ╚═════╝ ╚═════╝ ╚═╝ ╚═══╝ ╚═════╝ ╚═╝ ╚══════╝╚═════╝ ╚═╝ ╚═╝
170
- //
171
- // AUTO-GENERATED FILE - DO NOT EDIT
172
- //
173
- // This file is regenerated every time you run:
174
- // bash setup-linting.sh
175
- //
176
- // To customize ESLint rules, edit eslint.config.mjs instead.
177
- // Your customizations there are preserved across regenerations.
178
- //
179
- ////////////////////////////////////////////////////////////////////////////////
180
-
181
- import { globalIgnores } from 'eslint/config';
182
- import js from '@eslint/js';
183
- HEADER
184
-
185
- [ "$HAS_TYPESCRIPT" = true ] && echo "import tseslint from 'typescript-eslint';" >> "$BASE_DIR/eslint-base.mjs"
186
- [ "$HAS_REACT" = true ] && cat >> "$BASE_DIR/eslint-base.mjs" << 'REACT_IMPORTS'
187
- import reactPlugin from '@eslint-react/eslint-plugin';
188
- import reactHooks from 'eslint-plugin-react-hooks';
189
- import reactPerf from 'eslint-plugin-react-perf';
190
- REACT_IMPORTS
191
- [ "$HAS_ASTRO" = true ] && echo "import astroPlugin from 'eslint-plugin-astro';" >> "$BASE_DIR/eslint-base.mjs"
192
-
193
- cat >> "$BASE_DIR/eslint-base.mjs" << 'COMMON_IMPORTS'
194
- import sonarjs from 'eslint-plugin-sonarjs';
195
- import sdl from '@microsoft/eslint-plugin-sdl';
196
- import boundaries from 'eslint-plugin-boundaries';
197
- import prettier from 'eslint-config-prettier';
198
- import globals from 'globals';
199
-
200
- export default [
201
- globalIgnores([
202
- '**/node_modules/', '**/dist/', '**/build/', '**/.next/', '**/coverage/',
203
- '**/*.min.js', '**/package-lock.json', '**/yarn.lock', '**/pnpm-lock.yaml',
204
- ]),
205
-
206
- // Base JavaScript
207
- {
208
- name: 'safeword/base-js',
209
- files: ['**/*.{js,mjs,cjs}'],
210
- ...js.configs.recommended,
211
- languageOptions: {
212
- ecmaVersion: 'latest',
213
- sourceType: 'module',
214
- globals: { ...globals.browser, ...globals.node, ...globals.es2025 },
215
- },
216
- },
217
- COMMON_IMPORTS
218
-
219
- # TypeScript block
220
- [ "$HAS_TYPESCRIPT" = true ] && cat >> "$BASE_DIR/eslint-base.mjs" << 'TS_BLOCK'
221
-
222
- // TypeScript
223
- {
224
- name: 'safeword/typescript',
225
- files: ['**/*.{ts,tsx}'],
226
- languageOptions: {
227
- parser: tseslint.parser,
228
- },
229
- plugins: {
230
- '@typescript-eslint': tseslint.plugin,
231
- },
232
- rules: {
233
- ...tseslint.configs.recommended.rules,
234
- },
235
- },
236
- TS_BLOCK
237
-
238
- # React block
239
- [ "$HAS_REACT" = true ] && cat >> "$BASE_DIR/eslint-base.mjs" << 'REACT_BLOCK'
240
-
241
- // React
242
- {
243
- name: 'safeword/react',
244
- files: ['**/*.{jsx,tsx}'],
245
- ...reactPlugin.configs['recommended-typescript'],
246
- plugins: {
247
- 'react-hooks': reactHooks,
248
- 'react-perf': reactPerf,
249
- },
250
- languageOptions: {
251
- parserOptions: { ecmaFeatures: { jsx: true } },
252
- },
253
- rules: {
254
- ...reactHooks.configs.recommended.rules,
255
- 'react-perf/jsx-no-new-object-as-prop': 'warn',
256
- 'react-perf/jsx-no-new-array-as-prop': 'warn',
257
- 'react-perf/jsx-no-new-function-as-prop': 'warn',
258
- },
259
- },
260
- REACT_BLOCK
261
-
262
- # Astro block
263
- [ "$HAS_ASTRO" = true ] && cat >> "$BASE_DIR/eslint-base.mjs" << 'ASTRO_BLOCK'
264
-
265
- // Astro
266
- ...astroPlugin.configs.recommended,
267
- ASTRO_BLOCK
268
-
269
- # Determine file pattern for quality/security rules
270
- FILE_PATTERN="**/*.{js,mjs,cjs"
271
- [ "$HAS_TYPESCRIPT" = true ] && FILE_PATTERN+=",ts,tsx"
272
- [ "$HAS_REACT" = true ] && FILE_PATTERN+=",jsx"
273
- FILE_PATTERN+="}"
274
-
275
- cat >> "$BASE_DIR/eslint-base.mjs" << QUALITY_BLOCK
276
-
277
- // Code quality (SonarJS)
278
- {
279
- name: 'safeword/sonarjs',
280
- files: ['$FILE_PATTERN'],
281
- plugins: { sonarjs },
282
- rules: sonarjs.configs.recommended.rules,
283
- },
284
-
285
- // Security (Microsoft SDL)
286
- {
287
- name: 'safeword/security',
288
- files: ['$FILE_PATTERN'],
289
- plugins: { '@microsoft/sdl': sdl },
290
- rules: {
291
- '@microsoft/sdl/no-insecure-url': 'error',
292
- '@microsoft/sdl/no-inner-html': 'error',
293
- '@microsoft/sdl/no-document-write': 'error',
294
- '@microsoft/sdl/no-html-method': 'error',
295
- '@microsoft/sdl/no-insecure-random': 'error',
296
- '@microsoft/sdl/no-postmessage-star-origin': 'error',
297
- },
298
- },
299
-
300
- // Architecture boundaries (default layers - customize in eslint.config.mjs)
301
- {
302
- name: 'safeword/boundaries',
303
- files: ['src/**/*.{js,mjs,cjs,ts,tsx,jsx}'],
304
- plugins: { boundaries },
305
- settings: {
306
- 'boundaries/include': ['src/**/*'],
307
- 'boundaries/elements': [
308
- { type: 'app', pattern: 'src/app/**/*' },
309
- { type: 'domain', pattern: 'src/domain/**/*' },
310
- { type: 'infra', pattern: 'src/infra/**/*' },
311
- { type: 'shared', pattern: 'src/shared/**/*' },
312
- ],
313
- },
314
- rules: {
315
- 'boundaries/element-types': ['error', {
316
- default: 'disallow',
317
- rules: [
318
- { from: 'app', allow: ['domain', 'infra', 'shared'] },
319
- { from: 'domain', allow: ['shared'] },
320
- { from: 'infra', allow: ['domain', 'shared'] },
321
- { from: 'shared', allow: [] },
322
- ],
323
- }],
324
- },
325
- },
326
-
327
- // Prettier (must be last in base)
328
- {
329
- name: 'safeword/prettier',
330
- ...prettier,
331
- },
332
- ];
333
- QUALITY_BLOCK
334
-
335
- echo " ✓ Generated $BASE_DIR/eslint-base.mjs"
336
-
337
- # --- Create eslint.config.mjs only if it doesn't exist ---
338
- if [ -f eslint.config.mjs ]; then
339
- echo " ✓ eslint.config.mjs exists (your customizations preserved)"
340
- else
341
- cat > eslint.config.mjs << 'USER_CONFIG'
342
- /**
343
- * ESLint Configuration
344
- *
345
- * This file is YOURS to customize. It imports the auto-generated base config
346
- * and lets you add your own rules, override defaults, and customize boundaries.
347
- *
348
- * The base config (.safeword/eslint-base.mjs) auto-detects:
349
- * - TypeScript, React, Astro from package.json
350
- * - Regenerated automatically when you run setup-linting.sh
351
- */
352
- import base from './.safeword/eslint/eslint-base.mjs';
353
-
354
- export default [
355
- // Include all base configs (TypeScript, React, boundaries, security, etc.)
356
- ...base,
357
-
358
- // =========================================================================
359
- // YOUR CUSTOMIZATIONS BELOW
360
- // =========================================================================
361
-
362
- // Example: Override boundary rules for your project's layer structure
363
- // {
364
- // name: 'my-boundaries',
365
- // files: ['src/**/*'],
366
- // settings: {
367
- // 'boundaries/elements': [
368
- // { type: 'features', pattern: 'src/features/**/*' },
369
- // { type: 'pages', pattern: 'src/pages/**/*' },
370
- // { type: 'shared', pattern: 'src/shared/**/*' },
371
- // ],
372
- // },
373
- // rules: {
374
- // 'boundaries/element-types': ['error', {
375
- // default: 'disallow',
376
- // rules: [
377
- // { from: 'pages', allow: ['features', 'shared'] },
378
- // { from: 'features', allow: ['shared'] },
379
- // { from: 'shared', allow: [] },
380
- // ],
381
- // }],
382
- // },
383
- // },
384
-
385
- // Example: Add custom rules
386
- // {
387
- // name: 'my-rules',
388
- // rules: {
389
- // 'no-console': 'warn',
390
- // '@typescript-eslint/no-explicit-any': 'off',
391
- // },
392
- // },
393
- ];
394
- USER_CONFIG
395
- echo " ✓ Created eslint.config.mjs (customize this file)"
396
- fi
397
-
398
- echo ""
399
-
400
- # ============================================================================
401
- # Step 5: Create supporting files and hooks
402
- # ============================================================================
403
- echo "[5/5] Setting up hooks and configs..."
404
-
405
- # Prettier config
406
- if [ ! -f .prettierrc ] && [ ! -f .prettierrc.json ] && [ ! -f prettier.config.js ]; then
407
- cat > .prettierrc << 'EOF'
408
- {
409
- "printWidth": 100,
410
- "tabWidth": 2,
411
- "useTabs": false,
412
- "semi": true,
413
- "singleQuote": true,
414
- "trailingComma": "all",
415
- "bracketSpacing": true,
416
- "arrowParens": "avoid",
417
- "endOfLine": "lf"
418
- }
419
- EOF
420
- echo " ✓ Created .prettierrc"
421
- fi
422
-
423
- # Prettier ignore
424
- if [ ! -f .prettierignore ]; then
425
- cat > .prettierignore << 'EOF'
426
- node_modules
427
- dist
428
- build
429
- .next
430
- coverage
431
- *.min.js
432
- package-lock.json
433
- EOF
434
- echo " ✓ Created .prettierignore"
435
- fi
436
-
437
- # Add npm scripts
438
- if command -v jq &> /dev/null; then
439
- jq '.scripts.lint = "eslint ." | .scripts.format = "prettier --write ."' package.json > package.json.tmp
440
- mv package.json.tmp package.json
441
- echo " ✓ Added npm scripts (lint, format)"
442
- fi
443
-
444
- # Claude Code hooks
445
- mkdir -p .claude/hooks .claude/commands
446
-
447
- cat > .claude/hooks/run-linters.sh << 'EOF'
448
- #!/bin/bash
449
- # Shared Linting Script - runs Prettier + ESLint on files
450
- if [ -n "$CLAUDE_PROJECT_DIR" ]; then cd "$CLAUDE_PROJECT_DIR" || exit 1; fi
451
- for target in "$@"; do
452
- [ -e "$target" ] || continue
453
- npx prettier --write "$target" 2>&1 || true
454
- npx eslint --fix "$target" 2>&1 || true
455
- done
456
- EOF
457
- chmod +x .claude/hooks/run-linters.sh
458
-
459
- cat > .claude/hooks/auto-lint.sh << 'EOF'
460
- #!/bin/bash
461
- # PostToolUse hook - auto-lint changed files
462
- input=$(cat)
463
- file_path=$(echo "$input" | jq -r '.tool_input.file_path // .tool_input.notebook_path // empty')
464
- [ -n "$file_path" ] && [ -f "$file_path" ] && "$CLAUDE_PROJECT_DIR/.claude/hooks/run-linters.sh" "$file_path"
465
- exit 0
466
- EOF
467
- chmod +x .claude/hooks/auto-lint.sh
468
-
469
- cat > .claude/commands/lint.md << 'EOF'
470
- Run linting on all project files.
471
-
472
- Execute:
473
- ```bash
474
- bash .claude/hooks/run-linters.sh .
475
- ```
476
- EOF
477
-
478
- echo " ✓ Created Claude Code hooks"
479
-
480
- # Update settings.json
481
- if [ ! -f .claude/settings.json ]; then
482
- echo '{"hooks": {}}' > .claude/settings.json
483
- fi
484
-
485
- # Add PostToolUse hook for auto-linting
486
- if ! jq -e '.hooks.PostToolUse[]?.hooks[]? | select(.command == "$CLAUDE_PROJECT_DIR/.claude/hooks/auto-lint.sh")' .claude/settings.json > /dev/null 2>&1; then
487
- jq '.hooks.PostToolUse = (.hooks.PostToolUse // []) + [{"matcher": "Write|Edit|MultiEdit|NotebookEdit", "hooks": [{"type": "command", "command": "$CLAUDE_PROJECT_DIR/.claude/hooks/auto-lint.sh", "timeout": 15}]}]' \
488
- .claude/settings.json > .claude/settings.json.tmp
489
- mv .claude/settings.json.tmp .claude/settings.json
490
- echo " ✓ Added PostToolUse hook (auto-lint)"
491
- fi
492
-
493
- # Create and add SessionStart hook to detect framework changes
494
- cat > .claude/hooks/check-linting-sync.sh << 'EOF'
495
- #!/bin/bash
496
- # SessionStart hook - reminds user to re-run setup if frameworks changed
497
- [ ! -f ".safeword/eslint/eslint-base.mjs" ] || [ ! -f "package.json" ] && exit 0
498
- DEPS=$(jq -r '(.dependencies//{}),(.devDependencies//{}) | keys[]' package.json 2>/dev/null || grep -oE '"[^"]+":' package.json | tr -d '":')
499
- HAS_TS=false; HAS_REACT=false; HAS_ASTRO=false
500
- { [ -f "tsconfig.json" ] || echo "$DEPS" | grep -qx "typescript"; } && HAS_TS=true
501
- echo "$DEPS" | grep -qx "react" && HAS_REACT=true
502
- echo "$DEPS" | grep -qx "astro" && HAS_ASTRO=true
503
- CFG_TS=$(grep -q "typescript-eslint" .safeword/eslint/eslint-base.mjs && echo true || echo false)
504
- CFG_REACT=$(grep -q "@eslint-react" .safeword/eslint/eslint-base.mjs && echo true || echo false)
505
- CFG_ASTRO=$(grep -q "eslint-plugin-astro" .safeword/eslint/eslint-base.mjs && echo true || echo false)
506
- MSG=""
507
- [ "$HAS_TS" != "$CFG_TS" ] && MSG+="TypeScript "
508
- [ "$HAS_REACT" != "$CFG_REACT" ] && MSG+="React "
509
- [ "$HAS_ASTRO" != "$CFG_ASTRO" ] && MSG+="Astro "
510
- [ -n "$MSG" ] && echo "⚠️ ESLint config out of sync (${MSG% }changed). Run: bash .safeword/scripts/setup-linting.sh"
511
- exit 0
512
- EOF
513
- chmod +x .claude/hooks/check-linting-sync.sh
514
-
515
- if ! jq -e '.hooks.SessionStart[]?.hooks[]? | select(.command == "$CLAUDE_PROJECT_DIR/.claude/hooks/check-linting-sync.sh")' .claude/settings.json > /dev/null 2>&1; then
516
- jq '.hooks.SessionStart = (.hooks.SessionStart // []) + [{"hooks": [{"type": "command", "command": "$CLAUDE_PROJECT_DIR/.claude/hooks/check-linting-sync.sh"}]}]' \
517
- .claude/settings.json > .claude/settings.json.tmp
518
- mv .claude/settings.json.tmp .claude/settings.json
519
- echo " ✓ Added SessionStart hook (sync check)"
520
- fi
521
-
522
- # /setup-linting command
523
- cat > .claude/commands/setup-linting.md << 'EOF'
524
- Re-run SAFEWORD linting setup (auto-detects frameworks, regenerates base config).
525
-
526
- Execute:
527
- ```bash
528
- bash .safeword/scripts/setup-linting.sh
529
- ```
530
- EOF
531
- echo " ✓ Created /setup-linting command"
532
-
533
- echo ""
534
- echo "================================="
535
- echo "✓ Setup Complete!"
536
- echo "================================="
537
- echo ""
538
- echo "Files:"
539
- echo " .safeword/eslint/eslint-base.mjs - Auto-generated (DO NOT EDIT)"
540
- echo " eslint.config.mjs - Your config (customize freely)"
541
- echo ""
542
- echo "Detected:"
543
- [ "$HAS_TYPESCRIPT" = true ] && echo " ✓ TypeScript"
544
- [ "$HAS_REACT" = true ] && echo " ✓ React"
545
- [ "$HAS_ASTRO" = true ] && echo " ✓ Astro"
546
- [ "$HAS_TYPESCRIPT" = false ] && [ "$HAS_REACT" = false ] && [ "$HAS_ASTRO" = false ] && echo " → JavaScript only"
547
- echo ""
548
- echo "Included:"
549
- echo " • eslint-plugin-boundaries (architecture)"
550
- echo " • eslint-plugin-sonarjs (code quality)"
551
- echo " • @microsoft/eslint-plugin-sdl (security)"
552
- echo ""
553
- echo "Commands:"
554
- echo " npm run lint # Check all files"
555
- echo " npm run format # Format all files"
556
- echo ""
557
- echo "After adding/removing frameworks, just re-run:"
558
- echo " bash setup-linting.sh"
559
- echo ""