anvil-dev-framework 0.1.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.
Files changed (190) hide show
  1. package/README.md +719 -0
  2. package/VERSION +1 -0
  3. package/docs/ANVIL-REPO-IMPLEMENTATION-PLAN.md +441 -0
  4. package/docs/FIRST-SKILL-TUTORIAL.md +408 -0
  5. package/docs/INSTALLATION-RETRO-NOTES.md +458 -0
  6. package/docs/INSTALLATION.md +984 -0
  7. package/docs/anvil-hud.md +469 -0
  8. package/docs/anvil-init.md +255 -0
  9. package/docs/anvil-state.md +210 -0
  10. package/docs/boris-cherny-ralph-wiggum-insights.md +608 -0
  11. package/docs/command-reference.md +2022 -0
  12. package/docs/hooks-tts.md +368 -0
  13. package/docs/implementation-guide.md +810 -0
  14. package/docs/linear-github-integration.md +247 -0
  15. package/docs/local-issues.md +677 -0
  16. package/docs/patterns/README.md +419 -0
  17. package/docs/planning-responsibilities.md +139 -0
  18. package/docs/session-workflow.md +573 -0
  19. package/docs/simplification-plan-template.md +297 -0
  20. package/docs/simplification-principles.md +129 -0
  21. package/docs/specifications/CCS-RALPH-INTEGRATION-DESIGN.md +633 -0
  22. package/docs/specifications/CCS-RESEARCH-REPORT.md +169 -0
  23. package/docs/specifications/PLAN-ANV-verification-ralph-wiggum.md +403 -0
  24. package/docs/specifications/PLAN-parallel-tracks-anvil-memory-ccs.md +494 -0
  25. package/docs/specifications/SPEC-ANV-VRW/component-01-verify.md +208 -0
  26. package/docs/specifications/SPEC-ANV-VRW/component-02-stop-gate.md +226 -0
  27. package/docs/specifications/SPEC-ANV-VRW/component-03-posttooluse.md +209 -0
  28. package/docs/specifications/SPEC-ANV-VRW/component-04-ralph-wiggum.md +604 -0
  29. package/docs/specifications/SPEC-ANV-VRW/component-05-atomic-actions.md +311 -0
  30. package/docs/specifications/SPEC-ANV-VRW/component-06-verify-subagent.md +264 -0
  31. package/docs/specifications/SPEC-ANV-VRW/component-07-claude-md.md +363 -0
  32. package/docs/specifications/SPEC-ANV-VRW/index.md +182 -0
  33. package/docs/specifications/SPEC-ANV-anvil-memory.md +573 -0
  34. package/docs/specifications/SPEC-ANV-context-checkpoints.md +781 -0
  35. package/docs/specifications/SPEC-ANV-verification-ralph-wiggum.md +789 -0
  36. package/docs/sync.md +122 -0
  37. package/global/CLAUDE.md +140 -0
  38. package/global/agents/verify-app.md +164 -0
  39. package/global/commands/anvil-settings.md +527 -0
  40. package/global/commands/anvil-sync.md +121 -0
  41. package/global/commands/change.md +197 -0
  42. package/global/commands/clarify.md +252 -0
  43. package/global/commands/cleanup.md +292 -0
  44. package/global/commands/commit-push-pr.md +207 -0
  45. package/global/commands/decay-review.md +127 -0
  46. package/global/commands/discover.md +158 -0
  47. package/global/commands/doc-coverage.md +122 -0
  48. package/global/commands/evidence.md +307 -0
  49. package/global/commands/explore.md +121 -0
  50. package/global/commands/force-exit.md +135 -0
  51. package/global/commands/handoff.md +191 -0
  52. package/global/commands/healthcheck.md +302 -0
  53. package/global/commands/hud.md +84 -0
  54. package/global/commands/insights.md +319 -0
  55. package/global/commands/linear-setup.md +184 -0
  56. package/global/commands/lint-fix.md +198 -0
  57. package/global/commands/orient.md +510 -0
  58. package/global/commands/plan.md +228 -0
  59. package/global/commands/ralph.md +346 -0
  60. package/global/commands/ready.md +182 -0
  61. package/global/commands/release.md +305 -0
  62. package/global/commands/retro.md +96 -0
  63. package/global/commands/shard.md +166 -0
  64. package/global/commands/spec.md +227 -0
  65. package/global/commands/sprint.md +184 -0
  66. package/global/commands/tasks.md +228 -0
  67. package/global/commands/test-and-commit.md +151 -0
  68. package/global/commands/validate.md +132 -0
  69. package/global/commands/verify.md +251 -0
  70. package/global/commands/weekly-review.md +156 -0
  71. package/global/hooks/__pycache__/ralph_context_monitor.cpython-314.pyc +0 -0
  72. package/global/hooks/__pycache__/statusline_agent_sync.cpython-314.pyc +0 -0
  73. package/global/hooks/anvil_memory_observe.ts +322 -0
  74. package/global/hooks/anvil_memory_session.ts +166 -0
  75. package/global/hooks/anvil_memory_stop.ts +187 -0
  76. package/global/hooks/parse_transcript.py +116 -0
  77. package/global/hooks/post_merge_cleanup.sh +132 -0
  78. package/global/hooks/post_tool_format.sh +215 -0
  79. package/global/hooks/ralph_context_monitor.py +240 -0
  80. package/global/hooks/ralph_stop.sh +502 -0
  81. package/global/hooks/statusline.sh +1110 -0
  82. package/global/hooks/statusline_agent_sync.py +224 -0
  83. package/global/hooks/stop_gate.sh +250 -0
  84. package/global/lib/.claude/anvil-state.json +21 -0
  85. package/global/lib/__pycache__/agent_registry.cpython-314.pyc +0 -0
  86. package/global/lib/__pycache__/claim_service.cpython-314.pyc +0 -0
  87. package/global/lib/__pycache__/coderabbit_service.cpython-314.pyc +0 -0
  88. package/global/lib/__pycache__/config_service.cpython-314.pyc +0 -0
  89. package/global/lib/__pycache__/coordination_service.cpython-314.pyc +0 -0
  90. package/global/lib/__pycache__/doc_coverage_service.cpython-314.pyc +0 -0
  91. package/global/lib/__pycache__/gate_logger.cpython-314.pyc +0 -0
  92. package/global/lib/__pycache__/github_service.cpython-314.pyc +0 -0
  93. package/global/lib/__pycache__/hygiene_service.cpython-314.pyc +0 -0
  94. package/global/lib/__pycache__/issue_models.cpython-314.pyc +0 -0
  95. package/global/lib/__pycache__/issue_provider.cpython-314.pyc +0 -0
  96. package/global/lib/__pycache__/linear_data_service.cpython-314.pyc +0 -0
  97. package/global/lib/__pycache__/linear_provider.cpython-314.pyc +0 -0
  98. package/global/lib/__pycache__/local_provider.cpython-314.pyc +0 -0
  99. package/global/lib/__pycache__/quality_service.cpython-314.pyc +0 -0
  100. package/global/lib/__pycache__/ralph_state.cpython-314.pyc +0 -0
  101. package/global/lib/__pycache__/state_manager.cpython-314.pyc +0 -0
  102. package/global/lib/__pycache__/transcript_parser.cpython-314.pyc +0 -0
  103. package/global/lib/__pycache__/verification_runner.cpython-314.pyc +0 -0
  104. package/global/lib/__pycache__/verify_iteration.cpython-314.pyc +0 -0
  105. package/global/lib/__pycache__/verify_subagent.cpython-314.pyc +0 -0
  106. package/global/lib/agent_registry.py +995 -0
  107. package/global/lib/anvil-state.sh +435 -0
  108. package/global/lib/claim_service.py +515 -0
  109. package/global/lib/coderabbit_service.py +314 -0
  110. package/global/lib/config_service.py +423 -0
  111. package/global/lib/coordination_service.py +331 -0
  112. package/global/lib/doc_coverage_service.py +1305 -0
  113. package/global/lib/gate_logger.py +316 -0
  114. package/global/lib/github_service.py +310 -0
  115. package/global/lib/handoff_generator.py +775 -0
  116. package/global/lib/hygiene_service.py +712 -0
  117. package/global/lib/issue_models.py +257 -0
  118. package/global/lib/issue_provider.py +339 -0
  119. package/global/lib/linear_data_service.py +210 -0
  120. package/global/lib/linear_provider.py +987 -0
  121. package/global/lib/linear_provider.py.backup +671 -0
  122. package/global/lib/local_provider.py +486 -0
  123. package/global/lib/orient_fast.py +457 -0
  124. package/global/lib/quality_service.py +470 -0
  125. package/global/lib/ralph_prompt_generator.py +563 -0
  126. package/global/lib/ralph_state.py +1202 -0
  127. package/global/lib/state_manager.py +417 -0
  128. package/global/lib/transcript_parser.py +597 -0
  129. package/global/lib/verification_runner.py +557 -0
  130. package/global/lib/verify_iteration.py +490 -0
  131. package/global/lib/verify_subagent.py +250 -0
  132. package/global/skills/README.md +155 -0
  133. package/global/skills/quality-gates/SKILL.md +252 -0
  134. package/global/skills/skill-template/SKILL.md +109 -0
  135. package/global/skills/testing-strategies/SKILL.md +337 -0
  136. package/global/templates/CHANGE-template.md +105 -0
  137. package/global/templates/HANDOFF-template.md +63 -0
  138. package/global/templates/PLAN-template.md +111 -0
  139. package/global/templates/SPEC-template.md +93 -0
  140. package/global/templates/ralph/PROMPT.md.template +89 -0
  141. package/global/templates/ralph/fix_plan.md.template +31 -0
  142. package/global/templates/ralph/progress.txt.template +23 -0
  143. package/global/tests/__pycache__/test_doc_coverage.cpython-314.pyc +0 -0
  144. package/global/tests/test_doc_coverage.py +520 -0
  145. package/global/tests/test_issue_models.py +299 -0
  146. package/global/tests/test_local_provider.py +323 -0
  147. package/global/tools/README.md +178 -0
  148. package/global/tools/__pycache__/anvil-hud.cpython-314.pyc +0 -0
  149. package/global/tools/anvil-hud.py +3622 -0
  150. package/global/tools/anvil-hud.py.bak +3318 -0
  151. package/global/tools/anvil-issue.py +432 -0
  152. package/global/tools/anvil-memory/CLAUDE.md +49 -0
  153. package/global/tools/anvil-memory/README.md +42 -0
  154. package/global/tools/anvil-memory/bun.lock +25 -0
  155. package/global/tools/anvil-memory/bunfig.toml +9 -0
  156. package/global/tools/anvil-memory/package.json +23 -0
  157. package/global/tools/anvil-memory/src/__tests__/ccs/context-monitor.test.ts +535 -0
  158. package/global/tools/anvil-memory/src/__tests__/ccs/edge-cases.test.ts +645 -0
  159. package/global/tools/anvil-memory/src/__tests__/ccs/fixtures.ts +363 -0
  160. package/global/tools/anvil-memory/src/__tests__/ccs/index.ts +8 -0
  161. package/global/tools/anvil-memory/src/__tests__/ccs/integration.test.ts +417 -0
  162. package/global/tools/anvil-memory/src/__tests__/ccs/prompt-generator.test.ts +571 -0
  163. package/global/tools/anvil-memory/src/__tests__/ccs/ralph-stop.test.ts +440 -0
  164. package/global/tools/anvil-memory/src/__tests__/ccs/test-utils.ts +252 -0
  165. package/global/tools/anvil-memory/src/__tests__/commands.test.ts +657 -0
  166. package/global/tools/anvil-memory/src/__tests__/db.test.ts +641 -0
  167. package/global/tools/anvil-memory/src/__tests__/hooks.test.ts +272 -0
  168. package/global/tools/anvil-memory/src/__tests__/performance.test.ts +427 -0
  169. package/global/tools/anvil-memory/src/__tests__/test-utils.ts +113 -0
  170. package/global/tools/anvil-memory/src/commands/checkpoint.ts +197 -0
  171. package/global/tools/anvil-memory/src/commands/get.ts +115 -0
  172. package/global/tools/anvil-memory/src/commands/init.ts +94 -0
  173. package/global/tools/anvil-memory/src/commands/observe.ts +163 -0
  174. package/global/tools/anvil-memory/src/commands/search.ts +112 -0
  175. package/global/tools/anvil-memory/src/db.ts +638 -0
  176. package/global/tools/anvil-memory/src/index.ts +205 -0
  177. package/global/tools/anvil-memory/src/types.ts +122 -0
  178. package/global/tools/anvil-memory/tsconfig.json +29 -0
  179. package/global/tools/ralph-loop.sh +359 -0
  180. package/package.json +45 -0
  181. package/scripts/anvil +822 -0
  182. package/scripts/extract_patterns.py +222 -0
  183. package/scripts/init-project.sh +541 -0
  184. package/scripts/install.sh +229 -0
  185. package/scripts/postinstall.js +41 -0
  186. package/scripts/rollback.sh +188 -0
  187. package/scripts/sync.sh +623 -0
  188. package/scripts/test-statusline.sh +248 -0
  189. package/scripts/update_claude_md.py +224 -0
  190. package/scripts/verify.sh +255 -0
@@ -0,0 +1,541 @@
1
+ #!/bin/bash
2
+
3
+ #
4
+ # Anvil Development Framework - Project Initialization (ANV-5)
5
+ #
6
+ # This script initializes Anvil in a project directory with optional
7
+ # template selection, hook symlinks, and Linear integration.
8
+ #
9
+ # Usage:
10
+ # anvil init [directory] [options]
11
+ #
12
+ # Options:
13
+ # --template <type> Use template: nextjs, python, saas, generic (default: generic)
14
+ # --with-hooks Create symlinks to framework hooks and commands
15
+ # --with-linear Run /linear-setup after initialization
16
+ # --force Overwrite existing files (backs up to .claude/.backup/)
17
+ # --dry-run Show what would be done without making changes
18
+ # --help Show this help message
19
+ #
20
+
21
+ set -e
22
+
23
+ # Colors
24
+ RED='\033[0;31m'
25
+ GREEN='\033[0;32m'
26
+ YELLOW='\033[1;33m'
27
+ BLUE='\033[0;34m'
28
+ CYAN='\033[0;36m'
29
+ NC='\033[0m' # No Color
30
+
31
+ # Determine anvil directory (where this script lives)
32
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
33
+ ANVIL_DIR="$(dirname "$SCRIPT_DIR")"
34
+
35
+ # Default options
36
+ PROJECT_DIR=""
37
+ TEMPLATE="generic"
38
+ WITH_HOOKS=false
39
+ WITH_LINEAR=false
40
+ FORCE=false
41
+ DRY_RUN=false
42
+
43
+ # =============================================================================
44
+ # Argument Parsing
45
+ # =============================================================================
46
+
47
+ show_help() {
48
+ echo "Anvil Development Framework - Project Initialization"
49
+ echo ""
50
+ echo "Usage: anvil init [directory] [options]"
51
+ echo ""
52
+ echo "Options:"
53
+ echo " --template <type> Template to use: nextjs, python, saas, generic (default: generic)"
54
+ echo " --with-hooks Create symlinks to framework hooks and commands"
55
+ echo " --with-linear Run /linear-setup after initialization"
56
+ echo " --force Overwrite existing files (backs up to .claude/.backup/)"
57
+ echo " --dry-run Show what would be done without making changes"
58
+ echo " --help Show this help message"
59
+ echo ""
60
+ echo "Templates:"
61
+ echo " generic Basic template for any project type"
62
+ echo " nextjs Next.js + TypeScript + Supabase + Tailwind"
63
+ echo " python Python + FastAPI + SQLAlchemy"
64
+ echo " saas SaaS application (Next.js based)"
65
+ echo ""
66
+ echo "Examples:"
67
+ echo " anvil init # Initialize current directory"
68
+ echo " anvil init ./my-project # Initialize specific directory"
69
+ echo " anvil init --template nextjs # Use Next.js template"
70
+ echo " anvil init --with-hooks --with-linear # Full setup with hooks and Linear"
71
+ echo ""
72
+ exit 0
73
+ }
74
+
75
+ # Parse arguments
76
+ while [[ $# -gt 0 ]]; do
77
+ case $1 in
78
+ --template)
79
+ TEMPLATE="$2"
80
+ shift 2
81
+ ;;
82
+ --with-hooks)
83
+ WITH_HOOKS=true
84
+ shift
85
+ ;;
86
+ --with-linear)
87
+ WITH_LINEAR=true
88
+ shift
89
+ ;;
90
+ --force)
91
+ FORCE=true
92
+ shift
93
+ ;;
94
+ --dry-run)
95
+ DRY_RUN=true
96
+ shift
97
+ ;;
98
+ --help|-h)
99
+ show_help
100
+ ;;
101
+ -*)
102
+ echo -e "${RED}Error: Unknown option: $1${NC}"
103
+ echo "Run 'anvil init --help' for usage information."
104
+ exit 1
105
+ ;;
106
+ *)
107
+ # First non-option argument is the project directory
108
+ if [ -z "$PROJECT_DIR" ]; then
109
+ PROJECT_DIR="$1"
110
+ fi
111
+ shift
112
+ ;;
113
+ esac
114
+ done
115
+
116
+ # Default to current directory if not specified
117
+ if [ -z "$PROJECT_DIR" ]; then
118
+ PROJECT_DIR="$(pwd)"
119
+ fi
120
+
121
+ # Validate template
122
+ case $TEMPLATE in
123
+ generic|nextjs|python|saas)
124
+ ;;
125
+ *)
126
+ echo -e "${RED}Error: Unknown template: $TEMPLATE${NC}"
127
+ echo "Available templates: generic, nextjs, python, saas"
128
+ exit 1
129
+ ;;
130
+ esac
131
+
132
+ # Map template names to directories
133
+ get_template_dir() {
134
+ case $1 in
135
+ nextjs) echo "saas" ;; # nextjs uses saas template
136
+ python) echo "api-python" ;; # python uses api-python template
137
+ *) echo "$1" ;;
138
+ esac
139
+ }
140
+
141
+ TEMPLATE_DIR=$(get_template_dir "$TEMPLATE")
142
+
143
+ # =============================================================================
144
+ # Helper Functions
145
+ # =============================================================================
146
+
147
+ # Dry-run aware file operations
148
+ do_mkdir() {
149
+ if [ "$DRY_RUN" = true ]; then
150
+ echo -e " ${CYAN}[dry-run]${NC} mkdir -p $1"
151
+ else
152
+ mkdir -p "$1"
153
+ fi
154
+ }
155
+
156
+ do_cp() {
157
+ if [ "$DRY_RUN" = true ]; then
158
+ echo -e " ${CYAN}[dry-run]${NC} cp $1 → $2"
159
+ else
160
+ cp "$1" "$2"
161
+ fi
162
+ }
163
+
164
+ do_ln() {
165
+ if [ "$DRY_RUN" = true ]; then
166
+ echo -e " ${CYAN}[dry-run]${NC} ln -s $1 → $2"
167
+ else
168
+ ln -sf "$1" "$2"
169
+ fi
170
+ }
171
+
172
+ # Backup existing file before overwriting
173
+ backup_file() {
174
+ local file="$1"
175
+ if [ -f "$file" ] && [ "$FORCE" = true ]; then
176
+ local backup_dir="$PROJECT_DIR/.claude/.backup/$(date +%Y%m%d-%H%M%S)"
177
+ local rel_path="${file#$PROJECT_DIR/}"
178
+ local backup_path="$backup_dir/$rel_path"
179
+
180
+ if [ "$DRY_RUN" = true ]; then
181
+ echo -e " ${CYAN}[dry-run]${NC} backup $rel_path"
182
+ else
183
+ mkdir -p "$(dirname "$backup_path")"
184
+ cp "$file" "$backup_path"
185
+ echo -e " ${YELLOW}↪${NC} Backed up: $rel_path"
186
+ fi
187
+ fi
188
+ }
189
+
190
+ # Check if file should be written (new or force mode)
191
+ should_write() {
192
+ local file="$1"
193
+ if [ ! -f "$file" ]; then
194
+ return 0 # File doesn't exist, should write
195
+ elif [ "$FORCE" = true ]; then
196
+ backup_file "$file"
197
+ return 0 # Force mode, should write after backup
198
+ else
199
+ return 1 # File exists and no force
200
+ fi
201
+ }
202
+
203
+ # =============================================================================
204
+ # Main Script
205
+ # =============================================================================
206
+
207
+ # Banner
208
+ echo ""
209
+ echo -e "${BLUE}Anvil Project Initialization${NC}"
210
+ echo "══════════════════════════════"
211
+ if [ "$DRY_RUN" = true ]; then
212
+ echo -e "${CYAN}[DRY RUN MODE - No changes will be made]${NC}"
213
+ fi
214
+ echo ""
215
+
216
+ # Validate project directory
217
+ if [ ! -d "$PROJECT_DIR" ]; then
218
+ echo -e "${RED}Error: Directory does not exist: $PROJECT_DIR${NC}"
219
+ exit 1
220
+ fi
221
+
222
+ # Check if it's a git repo
223
+ if [ ! -d "$PROJECT_DIR/.git" ]; then
224
+ echo -e "${YELLOW}Warning: Not a git repository. Some features may not work.${NC}"
225
+ fi
226
+
227
+ echo -e "${BLUE}Initializing Anvil in: ${PROJECT_DIR}${NC}"
228
+ echo -e "${BLUE}Template: ${TEMPLATE}${NC}"
229
+ [ "$WITH_HOOKS" = true ] && echo -e "${BLUE}Hooks: enabled${NC}"
230
+ [ "$WITH_LINEAR" = true ] && echo -e "${BLUE}Linear: enabled${NC}"
231
+ echo ""
232
+
233
+ # Create .claude directory structure
234
+ echo -e "${BLUE}Creating directory structure...${NC}"
235
+ do_mkdir "$PROJECT_DIR/.claude"
236
+ do_mkdir "$PROJECT_DIR/.claude/specs/current"
237
+ do_mkdir "$PROJECT_DIR/.claude/specs/archive"
238
+ do_mkdir "$PROJECT_DIR/.claude/changes"
239
+ do_mkdir "$PROJECT_DIR/.claude/handoffs"
240
+ do_mkdir "$PROJECT_DIR/.claude/examples"
241
+ do_mkdir "$PROJECT_DIR/.claude/commands"
242
+
243
+ if [ "$DRY_RUN" = false ]; then
244
+ echo -e " ${GREEN}✓${NC} .claude/"
245
+ echo -e " ${GREEN}✓${NC} .claude/specs/current/"
246
+ echo -e " ${GREEN}✓${NC} .claude/specs/archive/"
247
+ echo -e " ${GREEN}✓${NC} .claude/changes/"
248
+ echo -e " ${GREEN}✓${NC} .claude/handoffs/"
249
+ echo -e " ${GREEN}✓${NC} .claude/examples/"
250
+ echo -e " ${GREEN}✓${NC} .claude/commands/"
251
+ fi
252
+
253
+ # Copy project templates
254
+ echo ""
255
+ echo -e "${BLUE}Installing project templates...${NC}"
256
+
257
+ # Check for template-specific CLAUDE.md first, fall back to generic
258
+ TEMPLATE_CLAUDE_MD=""
259
+ if [ -f "$ANVIL_DIR/project/templates/$TEMPLATE_DIR/CLAUDE.md" ]; then
260
+ TEMPLATE_CLAUDE_MD="$ANVIL_DIR/project/templates/$TEMPLATE_DIR/CLAUDE.md"
261
+ elif [ -f "$ANVIL_DIR/project/CLAUDE.md.template" ]; then
262
+ TEMPLATE_CLAUDE_MD="$ANVIL_DIR/project/CLAUDE.md.template"
263
+ fi
264
+
265
+ # CLAUDE.md
266
+ if [ -n "$TEMPLATE_CLAUDE_MD" ]; then
267
+ if should_write "$PROJECT_DIR/.claude/CLAUDE.md"; then
268
+ do_cp "$TEMPLATE_CLAUDE_MD" "$PROJECT_DIR/.claude/CLAUDE.md"
269
+ [ "$DRY_RUN" = false ] && echo -e " ${GREEN}✓${NC} CLAUDE.md (from $TEMPLATE template)"
270
+ else
271
+ echo -e " ${YELLOW}⊘${NC} CLAUDE.md (exists, use --force to overwrite)"
272
+ fi
273
+ fi
274
+
275
+ # constitution.md
276
+ if should_write "$PROJECT_DIR/.claude/constitution.md"; then
277
+ do_cp "$ANVIL_DIR/project/constitution.md.template" "$PROJECT_DIR/.claude/constitution.md"
278
+ [ "$DRY_RUN" = false ] && echo -e " ${GREEN}✓${NC} constitution.md"
279
+ else
280
+ echo -e " ${YELLOW}⊘${NC} constitution.md (exists)"
281
+ fi
282
+
283
+ # product.md
284
+ if should_write "$PROJECT_DIR/.claude/product.md"; then
285
+ do_cp "$ANVIL_DIR/project/product.md.template" "$PROJECT_DIR/.claude/product.md"
286
+ [ "$DRY_RUN" = false ] && echo -e " ${GREEN}✓${NC} product.md"
287
+ else
288
+ echo -e " ${YELLOW}⊘${NC} product.md (exists)"
289
+ fi
290
+
291
+ # linear.yaml (Linear team configuration)
292
+ if [ ! -f "$PROJECT_DIR/.claude/linear.yaml" ]; then
293
+ if [ -f "$ANVIL_DIR/project/linear.yaml.template" ]; then
294
+ do_cp "$ANVIL_DIR/project/linear.yaml.template" "$PROJECT_DIR/.claude/linear.yaml"
295
+ [ "$DRY_RUN" = false ] && echo -e " ${GREEN}✓${NC} linear.yaml (run /linear-setup to configure)"
296
+ fi
297
+ else
298
+ echo -e " ${YELLOW}⊘${NC} linear.yaml (exists)"
299
+ fi
300
+
301
+ # Copy commands
302
+ if [ -d "$ANVIL_DIR/project/commands" ]; then
303
+ for file in "$ANVIL_DIR/project/commands"/*.md; do
304
+ if [ -f "$file" ]; then
305
+ BASENAME=$(basename "$file")
306
+ if should_write "$PROJECT_DIR/.claude/commands/$BASENAME"; then
307
+ do_cp "$file" "$PROJECT_DIR/.claude/commands/$BASENAME"
308
+ [ "$DRY_RUN" = false ] && echo -e " ${GREEN}✓${NC} commands/$BASENAME"
309
+ fi
310
+ fi
311
+ done
312
+ fi
313
+
314
+ # Copy examples
315
+ if [ -d "$ANVIL_DIR/project/examples" ]; then
316
+ for file in "$ANVIL_DIR/project/examples"/*; do
317
+ if [ -f "$file" ]; then
318
+ BASENAME=$(basename "$file")
319
+ if should_write "$PROJECT_DIR/.claude/examples/$BASENAME"; then
320
+ do_cp "$file" "$PROJECT_DIR/.claude/examples/$BASENAME"
321
+ [ "$DRY_RUN" = false ] && echo -e " ${GREEN}✓${NC} examples/$BASENAME"
322
+ fi
323
+ fi
324
+ done
325
+ fi
326
+
327
+ # Install quality gate configs
328
+ echo ""
329
+ echo -e "${BLUE}Installing quality gate configurations...${NC}"
330
+
331
+ # .coderabbit.yaml
332
+ if [ -f "$ANVIL_DIR/quality-gates/.coderabbit.yaml" ]; then
333
+ if should_write "$PROJECT_DIR/.coderabbit.yaml"; then
334
+ do_cp "$ANVIL_DIR/quality-gates/.coderabbit.yaml" "$PROJECT_DIR/.coderabbit.yaml"
335
+ [ "$DRY_RUN" = false ] && echo -e " ${GREEN}✓${NC} .coderabbit.yaml"
336
+ else
337
+ echo -e " ${YELLOW}⊘${NC} .coderabbit.yaml (exists)"
338
+ fi
339
+ fi
340
+
341
+ # .pre-commit-config.yaml
342
+ if [ -f "$ANVIL_DIR/quality-gates/.pre-commit-config.yaml" ]; then
343
+ if should_write "$PROJECT_DIR/.pre-commit-config.yaml"; then
344
+ do_cp "$ANVIL_DIR/quality-gates/.pre-commit-config.yaml" "$PROJECT_DIR/.pre-commit-config.yaml"
345
+ [ "$DRY_RUN" = false ] && echo -e " ${GREEN}✓${NC} .pre-commit-config.yaml"
346
+ else
347
+ echo -e " ${YELLOW}⊘${NC} .pre-commit-config.yaml (exists)"
348
+ fi
349
+ fi
350
+
351
+ # Semgrep rules
352
+ if [ -d "$ANVIL_DIR/quality-gates/.semgrep" ]; then
353
+ do_mkdir "$PROJECT_DIR/.semgrep/rules"
354
+ for file in "$ANVIL_DIR/quality-gates/.semgrep/rules"/*.yaml; do
355
+ if [ -f "$file" ]; then
356
+ BASENAME=$(basename "$file")
357
+ if should_write "$PROJECT_DIR/.semgrep/rules/$BASENAME"; then
358
+ do_cp "$file" "$PROJECT_DIR/.semgrep/rules/$BASENAME"
359
+ [ "$DRY_RUN" = false ] && echo -e " ${GREEN}✓${NC} .semgrep/rules/$BASENAME"
360
+ fi
361
+ fi
362
+ done
363
+ fi
364
+
365
+ # Update .gitignore
366
+ echo ""
367
+ echo -e "${BLUE}Updating .gitignore...${NC}"
368
+ if [ "$DRY_RUN" = true ]; then
369
+ echo -e " ${CYAN}[dry-run]${NC} Would update .gitignore"
370
+ else
371
+ if [ -f "$PROJECT_DIR/.gitignore" ]; then
372
+ # Check if anvil entries already exist
373
+ if ! grep -q ".claude/handoffs/" "$PROJECT_DIR/.gitignore"; then
374
+ echo "" >> "$PROJECT_DIR/.gitignore"
375
+ echo "# Anvil Development Framework" >> "$PROJECT_DIR/.gitignore"
376
+ echo ".claude/handoffs/" >> "$PROJECT_DIR/.gitignore"
377
+ echo -e " ${GREEN}✓${NC} Added .claude/handoffs/ to .gitignore"
378
+ else
379
+ echo -e " ${YELLOW}⊘${NC} .gitignore already configured"
380
+ fi
381
+ else
382
+ echo "# Anvil Development Framework" > "$PROJECT_DIR/.gitignore"
383
+ echo ".claude/handoffs/" >> "$PROJECT_DIR/.gitignore"
384
+ echo -e " ${GREEN}✓${NC} Created .gitignore"
385
+ fi
386
+ fi
387
+
388
+ # Install pre-commit hooks
389
+ if [ "$DRY_RUN" = false ]; then
390
+ if command -v pre-commit &> /dev/null; then
391
+ if [ -f "$PROJECT_DIR/.pre-commit-config.yaml" ]; then
392
+ echo ""
393
+ echo -e "${BLUE}Installing pre-commit hooks...${NC}"
394
+ cd "$PROJECT_DIR" && pre-commit install
395
+ echo -e " ${GREEN}✓${NC} Pre-commit hooks installed"
396
+ fi
397
+ fi
398
+ else
399
+ if command -v pre-commit &> /dev/null; then
400
+ echo -e " ${CYAN}[dry-run]${NC} Would install pre-commit hooks"
401
+ fi
402
+ fi
403
+
404
+ # =============================================================================
405
+ # --with-hooks: Create symlinks to framework hooks and commands (ANV-14)
406
+ # =============================================================================
407
+ if [ "$WITH_HOOKS" = true ]; then
408
+ echo ""
409
+ echo -e "${BLUE}Creating framework symlinks...${NC}"
410
+
411
+ # Create hooks directory if it doesn't exist
412
+ do_mkdir "$PROJECT_DIR/.claude/hooks"
413
+
414
+ # Symlink global hooks
415
+ if [ -d "$ANVIL_DIR/global/hooks" ]; then
416
+ for hook in "$ANVIL_DIR/global/hooks"/*; do
417
+ if [ -f "$hook" ]; then
418
+ BASENAME=$(basename "$hook")
419
+ TARGET="$PROJECT_DIR/.claude/hooks/$BASENAME"
420
+ if [ ! -L "$TARGET" ] && [ ! -f "$TARGET" ]; then
421
+ do_ln "$hook" "$TARGET"
422
+ [ "$DRY_RUN" = false ] && echo -e " ${GREEN}✓${NC} hooks/$BASENAME → global/hooks/$BASENAME"
423
+ else
424
+ echo -e " ${YELLOW}⊘${NC} hooks/$BASENAME (exists)"
425
+ fi
426
+ fi
427
+ done
428
+ fi
429
+
430
+ # Symlink global commands
431
+ if [ -d "$ANVIL_DIR/global/commands" ]; then
432
+ for cmd in "$ANVIL_DIR/global/commands"/*.md; do
433
+ if [ -f "$cmd" ]; then
434
+ BASENAME=$(basename "$cmd")
435
+ TARGET="$PROJECT_DIR/.claude/commands/$BASENAME"
436
+ if [ ! -L "$TARGET" ] && [ ! -f "$TARGET" ]; then
437
+ do_ln "$cmd" "$TARGET"
438
+ [ "$DRY_RUN" = false ] && echo -e " ${GREEN}✓${NC} commands/$BASENAME → global/commands/$BASENAME"
439
+ else
440
+ echo -e " ${YELLOW}⊘${NC} commands/$BASENAME (exists)"
441
+ fi
442
+ fi
443
+ done
444
+ fi
445
+
446
+ # Symlink global lib
447
+ if [ -d "$ANVIL_DIR/global/lib" ]; then
448
+ do_mkdir "$PROJECT_DIR/.claude/lib"
449
+ for lib in "$ANVIL_DIR/global/lib"/*.py; do
450
+ if [ -f "$lib" ]; then
451
+ BASENAME=$(basename "$lib")
452
+ TARGET="$PROJECT_DIR/.claude/lib/$BASENAME"
453
+ if [ ! -L "$TARGET" ] && [ ! -f "$TARGET" ]; then
454
+ do_ln "$lib" "$TARGET"
455
+ [ "$DRY_RUN" = false ] && echo -e " ${GREEN}✓${NC} lib/$BASENAME → global/lib/$BASENAME"
456
+ fi
457
+ fi
458
+ done
459
+ fi
460
+
461
+ echo -e " ${GREEN}✓${NC} Framework symlinks created"
462
+ fi
463
+
464
+ # =============================================================================
465
+ # --with-linear: Trigger Linear setup (ANV-15)
466
+ # =============================================================================
467
+ if [ "$WITH_LINEAR" = true ]; then
468
+ echo ""
469
+ echo -e "${BLUE}Linear integration requested...${NC}"
470
+ if [ "$DRY_RUN" = true ]; then
471
+ echo -e " ${CYAN}[dry-run]${NC} Would prompt to run /linear-setup"
472
+ else
473
+ echo -e " ${YELLOW}→${NC} Run '/linear-setup' in Claude Code to configure Linear integration"
474
+ echo -e " ${YELLOW}→${NC} This will map your project to a Linear team"
475
+ fi
476
+ fi
477
+
478
+ # Create initial handoff
479
+ if [ "$DRY_RUN" = true ]; then
480
+ echo ""
481
+ echo -e " ${CYAN}[dry-run]${NC} Would create initial handoff file"
482
+ else
483
+ HANDOFF_FILE="$PROJECT_DIR/.claude/handoffs/$(date +%Y-%m-%d)-anvil-init.md"
484
+ cat > "$HANDOFF_FILE" << EOF
485
+ ---
486
+ session_date: $(date +%Y-%m-%d)
487
+ session_time: $(date +%H:%M)
488
+ branch: $(cd "$PROJECT_DIR" && git branch --show-current 2>/dev/null || echo "unknown")
489
+ template: $TEMPLATE
490
+ ---
491
+
492
+ # Session Handoff: Anvil Initialization
493
+
494
+ ## Session Summary
495
+ Initialized Anvil Development Framework in this project using the **$TEMPLATE** template.
496
+
497
+ ## Completed This Session
498
+ - Created .claude/ directory structure
499
+ - Installed CLAUDE.md, constitution.md, product.md templates
500
+ - Installed quality gate configurations
501
+ - Updated .gitignore
502
+ $([ "$WITH_HOOKS" = true ] && echo "- Created symlinks to framework hooks and commands")
503
+ $([ "$WITH_LINEAR" = true ] && echo "- Linear integration requested (run /linear-setup)")
504
+
505
+ ## Recommended Next Task
506
+ 1. Customize .claude/CLAUDE.md with project-specific details
507
+ 2. Update .claude/constitution.md with project principles
508
+ 3. Fill out .claude/product.md with product definition
509
+ 4. Create convention examples in .claude/examples/
510
+ $([ "$WITH_LINEAR" = true ] && echo "5. Run /linear-setup to configure Linear integration")
511
+
512
+ ## Critical Context for Next Session
513
+ - This is a fresh Anvil installation
514
+ - Templates need customization
515
+ - Quality gates are configured but may need project-specific rules
516
+ EOF
517
+ fi
518
+
519
+ echo ""
520
+ if [ "$DRY_RUN" = true ]; then
521
+ echo -e "${CYAN}════════════════════════════════════════${NC}"
522
+ echo -e "${CYAN} Dry run complete - no changes made${NC}"
523
+ echo -e "${CYAN}════════════════════════════════════════${NC}"
524
+ else
525
+ echo -e "${GREEN}════════════════════════════════════════${NC}"
526
+ echo -e "${GREEN} Anvil initialized successfully!${NC}"
527
+ echo -e "${GREEN}════════════════════════════════════════${NC}"
528
+ fi
529
+ echo ""
530
+ echo "Project configured at: $PROJECT_DIR/.claude/"
531
+ echo "Template: $TEMPLATE"
532
+ echo ""
533
+ echo "Next steps:"
534
+ echo " 1. Edit .claude/CLAUDE.md with your project details"
535
+ echo " 2. Review .claude/constitution.md principles"
536
+ echo " 3. Fill out .claude/product.md"
537
+ echo " 4. Add convention examples to .claude/examples/"
538
+ [ "$WITH_LINEAR" = true ] && echo " 5. Run /linear-setup to configure Linear"
539
+ echo ""
540
+ echo "To start using Anvil, open Claude Code and run /orient"
541
+ echo ""