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.
- package/README.md +719 -0
- package/VERSION +1 -0
- package/docs/ANVIL-REPO-IMPLEMENTATION-PLAN.md +441 -0
- package/docs/FIRST-SKILL-TUTORIAL.md +408 -0
- package/docs/INSTALLATION-RETRO-NOTES.md +458 -0
- package/docs/INSTALLATION.md +984 -0
- package/docs/anvil-hud.md +469 -0
- package/docs/anvil-init.md +255 -0
- package/docs/anvil-state.md +210 -0
- package/docs/boris-cherny-ralph-wiggum-insights.md +608 -0
- package/docs/command-reference.md +2022 -0
- package/docs/hooks-tts.md +368 -0
- package/docs/implementation-guide.md +810 -0
- package/docs/linear-github-integration.md +247 -0
- package/docs/local-issues.md +677 -0
- package/docs/patterns/README.md +419 -0
- package/docs/planning-responsibilities.md +139 -0
- package/docs/session-workflow.md +573 -0
- package/docs/simplification-plan-template.md +297 -0
- package/docs/simplification-principles.md +129 -0
- package/docs/specifications/CCS-RALPH-INTEGRATION-DESIGN.md +633 -0
- package/docs/specifications/CCS-RESEARCH-REPORT.md +169 -0
- package/docs/specifications/PLAN-ANV-verification-ralph-wiggum.md +403 -0
- package/docs/specifications/PLAN-parallel-tracks-anvil-memory-ccs.md +494 -0
- package/docs/specifications/SPEC-ANV-VRW/component-01-verify.md +208 -0
- package/docs/specifications/SPEC-ANV-VRW/component-02-stop-gate.md +226 -0
- package/docs/specifications/SPEC-ANV-VRW/component-03-posttooluse.md +209 -0
- package/docs/specifications/SPEC-ANV-VRW/component-04-ralph-wiggum.md +604 -0
- package/docs/specifications/SPEC-ANV-VRW/component-05-atomic-actions.md +311 -0
- package/docs/specifications/SPEC-ANV-VRW/component-06-verify-subagent.md +264 -0
- package/docs/specifications/SPEC-ANV-VRW/component-07-claude-md.md +363 -0
- package/docs/specifications/SPEC-ANV-VRW/index.md +182 -0
- package/docs/specifications/SPEC-ANV-anvil-memory.md +573 -0
- package/docs/specifications/SPEC-ANV-context-checkpoints.md +781 -0
- package/docs/specifications/SPEC-ANV-verification-ralph-wiggum.md +789 -0
- package/docs/sync.md +122 -0
- package/global/CLAUDE.md +140 -0
- package/global/agents/verify-app.md +164 -0
- package/global/commands/anvil-settings.md +527 -0
- package/global/commands/anvil-sync.md +121 -0
- package/global/commands/change.md +197 -0
- package/global/commands/clarify.md +252 -0
- package/global/commands/cleanup.md +292 -0
- package/global/commands/commit-push-pr.md +207 -0
- package/global/commands/decay-review.md +127 -0
- package/global/commands/discover.md +158 -0
- package/global/commands/doc-coverage.md +122 -0
- package/global/commands/evidence.md +307 -0
- package/global/commands/explore.md +121 -0
- package/global/commands/force-exit.md +135 -0
- package/global/commands/handoff.md +191 -0
- package/global/commands/healthcheck.md +302 -0
- package/global/commands/hud.md +84 -0
- package/global/commands/insights.md +319 -0
- package/global/commands/linear-setup.md +184 -0
- package/global/commands/lint-fix.md +198 -0
- package/global/commands/orient.md +510 -0
- package/global/commands/plan.md +228 -0
- package/global/commands/ralph.md +346 -0
- package/global/commands/ready.md +182 -0
- package/global/commands/release.md +305 -0
- package/global/commands/retro.md +96 -0
- package/global/commands/shard.md +166 -0
- package/global/commands/spec.md +227 -0
- package/global/commands/sprint.md +184 -0
- package/global/commands/tasks.md +228 -0
- package/global/commands/test-and-commit.md +151 -0
- package/global/commands/validate.md +132 -0
- package/global/commands/verify.md +251 -0
- package/global/commands/weekly-review.md +156 -0
- package/global/hooks/__pycache__/ralph_context_monitor.cpython-314.pyc +0 -0
- package/global/hooks/__pycache__/statusline_agent_sync.cpython-314.pyc +0 -0
- package/global/hooks/anvil_memory_observe.ts +322 -0
- package/global/hooks/anvil_memory_session.ts +166 -0
- package/global/hooks/anvil_memory_stop.ts +187 -0
- package/global/hooks/parse_transcript.py +116 -0
- package/global/hooks/post_merge_cleanup.sh +132 -0
- package/global/hooks/post_tool_format.sh +215 -0
- package/global/hooks/ralph_context_monitor.py +240 -0
- package/global/hooks/ralph_stop.sh +502 -0
- package/global/hooks/statusline.sh +1110 -0
- package/global/hooks/statusline_agent_sync.py +224 -0
- package/global/hooks/stop_gate.sh +250 -0
- package/global/lib/.claude/anvil-state.json +21 -0
- package/global/lib/__pycache__/agent_registry.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/claim_service.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/coderabbit_service.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/config_service.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/coordination_service.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/doc_coverage_service.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/gate_logger.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/github_service.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/hygiene_service.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/issue_models.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/issue_provider.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/linear_data_service.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/linear_provider.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/local_provider.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/quality_service.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/ralph_state.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/state_manager.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/transcript_parser.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/verification_runner.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/verify_iteration.cpython-314.pyc +0 -0
- package/global/lib/__pycache__/verify_subagent.cpython-314.pyc +0 -0
- package/global/lib/agent_registry.py +995 -0
- package/global/lib/anvil-state.sh +435 -0
- package/global/lib/claim_service.py +515 -0
- package/global/lib/coderabbit_service.py +314 -0
- package/global/lib/config_service.py +423 -0
- package/global/lib/coordination_service.py +331 -0
- package/global/lib/doc_coverage_service.py +1305 -0
- package/global/lib/gate_logger.py +316 -0
- package/global/lib/github_service.py +310 -0
- package/global/lib/handoff_generator.py +775 -0
- package/global/lib/hygiene_service.py +712 -0
- package/global/lib/issue_models.py +257 -0
- package/global/lib/issue_provider.py +339 -0
- package/global/lib/linear_data_service.py +210 -0
- package/global/lib/linear_provider.py +987 -0
- package/global/lib/linear_provider.py.backup +671 -0
- package/global/lib/local_provider.py +486 -0
- package/global/lib/orient_fast.py +457 -0
- package/global/lib/quality_service.py +470 -0
- package/global/lib/ralph_prompt_generator.py +563 -0
- package/global/lib/ralph_state.py +1202 -0
- package/global/lib/state_manager.py +417 -0
- package/global/lib/transcript_parser.py +597 -0
- package/global/lib/verification_runner.py +557 -0
- package/global/lib/verify_iteration.py +490 -0
- package/global/lib/verify_subagent.py +250 -0
- package/global/skills/README.md +155 -0
- package/global/skills/quality-gates/SKILL.md +252 -0
- package/global/skills/skill-template/SKILL.md +109 -0
- package/global/skills/testing-strategies/SKILL.md +337 -0
- package/global/templates/CHANGE-template.md +105 -0
- package/global/templates/HANDOFF-template.md +63 -0
- package/global/templates/PLAN-template.md +111 -0
- package/global/templates/SPEC-template.md +93 -0
- package/global/templates/ralph/PROMPT.md.template +89 -0
- package/global/templates/ralph/fix_plan.md.template +31 -0
- package/global/templates/ralph/progress.txt.template +23 -0
- package/global/tests/__pycache__/test_doc_coverage.cpython-314.pyc +0 -0
- package/global/tests/test_doc_coverage.py +520 -0
- package/global/tests/test_issue_models.py +299 -0
- package/global/tests/test_local_provider.py +323 -0
- package/global/tools/README.md +178 -0
- package/global/tools/__pycache__/anvil-hud.cpython-314.pyc +0 -0
- package/global/tools/anvil-hud.py +3622 -0
- package/global/tools/anvil-hud.py.bak +3318 -0
- package/global/tools/anvil-issue.py +432 -0
- package/global/tools/anvil-memory/CLAUDE.md +49 -0
- package/global/tools/anvil-memory/README.md +42 -0
- package/global/tools/anvil-memory/bun.lock +25 -0
- package/global/tools/anvil-memory/bunfig.toml +9 -0
- package/global/tools/anvil-memory/package.json +23 -0
- package/global/tools/anvil-memory/src/__tests__/ccs/context-monitor.test.ts +535 -0
- package/global/tools/anvil-memory/src/__tests__/ccs/edge-cases.test.ts +645 -0
- package/global/tools/anvil-memory/src/__tests__/ccs/fixtures.ts +363 -0
- package/global/tools/anvil-memory/src/__tests__/ccs/index.ts +8 -0
- package/global/tools/anvil-memory/src/__tests__/ccs/integration.test.ts +417 -0
- package/global/tools/anvil-memory/src/__tests__/ccs/prompt-generator.test.ts +571 -0
- package/global/tools/anvil-memory/src/__tests__/ccs/ralph-stop.test.ts +440 -0
- package/global/tools/anvil-memory/src/__tests__/ccs/test-utils.ts +252 -0
- package/global/tools/anvil-memory/src/__tests__/commands.test.ts +657 -0
- package/global/tools/anvil-memory/src/__tests__/db.test.ts +641 -0
- package/global/tools/anvil-memory/src/__tests__/hooks.test.ts +272 -0
- package/global/tools/anvil-memory/src/__tests__/performance.test.ts +427 -0
- package/global/tools/anvil-memory/src/__tests__/test-utils.ts +113 -0
- package/global/tools/anvil-memory/src/commands/checkpoint.ts +197 -0
- package/global/tools/anvil-memory/src/commands/get.ts +115 -0
- package/global/tools/anvil-memory/src/commands/init.ts +94 -0
- package/global/tools/anvil-memory/src/commands/observe.ts +163 -0
- package/global/tools/anvil-memory/src/commands/search.ts +112 -0
- package/global/tools/anvil-memory/src/db.ts +638 -0
- package/global/tools/anvil-memory/src/index.ts +205 -0
- package/global/tools/anvil-memory/src/types.ts +122 -0
- package/global/tools/anvil-memory/tsconfig.json +29 -0
- package/global/tools/ralph-loop.sh +359 -0
- package/package.json +45 -0
- package/scripts/anvil +822 -0
- package/scripts/extract_patterns.py +222 -0
- package/scripts/init-project.sh +541 -0
- package/scripts/install.sh +229 -0
- package/scripts/postinstall.js +41 -0
- package/scripts/rollback.sh +188 -0
- package/scripts/sync.sh +623 -0
- package/scripts/test-statusline.sh +248 -0
- package/scripts/update_claude_md.py +224 -0
- 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 ""
|