vibe-forge 0.8.1 → 0.8.2

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 (51) hide show
  1. package/.claude/commands/configure-vcs.md +102 -102
  2. package/.claude/commands/forge.md +218 -218
  3. package/.claude/hooks/worker-loop.js +220 -217
  4. package/.claude/settings.json +89 -89
  5. package/README.md +149 -191
  6. package/agents/aegis/personality.md +303 -303
  7. package/agents/anvil/personality.md +278 -278
  8. package/agents/architect/personality.md +260 -260
  9. package/agents/crucible/personality.md +362 -362
  10. package/agents/crucible-x/personality.md +210 -210
  11. package/agents/ember/personality.md +293 -293
  12. package/agents/flux/personality.md +248 -248
  13. package/agents/furnace/personality.md +342 -342
  14. package/agents/herald/personality.md +249 -249
  15. package/agents/oracle/personality.md +284 -284
  16. package/agents/pixel/personality.md +140 -140
  17. package/agents/planning-hub/personality.md +473 -473
  18. package/agents/scribe/personality.md +253 -253
  19. package/agents/slag/personality.md +268 -268
  20. package/agents/temper/personality.md +270 -270
  21. package/bin/cli.js +372 -372
  22. package/bin/forge-daemon.sh +477 -477
  23. package/bin/forge-setup.sh +662 -661
  24. package/bin/forge-spawn.sh +164 -164
  25. package/bin/forge.sh +566 -566
  26. package/docs/commands.md +8 -8
  27. package/package.json +77 -77
  28. package/{bin → src}/lib/agents.sh +177 -177
  29. package/{bin → src}/lib/check-aliases.js +50 -50
  30. package/{bin → src}/lib/colors.sh +45 -44
  31. package/{bin → src}/lib/config.sh +347 -347
  32. package/{bin → src}/lib/constants.sh +241 -241
  33. package/{bin → src}/lib/daemon/budgets.sh +107 -107
  34. package/{bin → src}/lib/daemon/dependencies.sh +146 -146
  35. package/{bin → src}/lib/daemon/display.sh +128 -128
  36. package/{bin → src}/lib/daemon/notifications.sh +273 -273
  37. package/{bin → src}/lib/daemon/routing.sh +93 -93
  38. package/{bin → src}/lib/daemon/state.sh +163 -163
  39. package/{bin → src}/lib/daemon/sync.sh +103 -103
  40. package/{bin → src}/lib/database.sh +357 -357
  41. package/{bin → src}/lib/frontmatter.js +106 -106
  42. package/{bin → src}/lib/heimdall-setup.js +113 -113
  43. package/{bin → src}/lib/heimdall.js +265 -265
  44. package/src/lib/index.sh +25 -0
  45. package/{bin → src}/lib/json.sh +264 -264
  46. package/{bin → src}/lib/terminal.js +452 -452
  47. package/{bin → src}/lib/util.sh +126 -126
  48. package/{bin → src}/lib/vcs.js +349 -349
  49. package/{context → templates}/project-context-template.md +122 -122
  50. package/config/task-template.md +0 -159
  51. package/config/templates/handoff-template.md +0 -40
@@ -1,661 +1,662 @@
1
- #!/usr/bin/env bash
2
- #
3
- # Vibe Forge - Setup Script
4
- # Initializes Vibe Forge for the current project
5
- #
6
- # Usage: ./forge-setup.sh [--non-interactive]
7
- #
8
-
9
- set -e
10
-
11
- SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
12
- FORGE_ROOT="$(dirname "$SCRIPT_DIR")"
13
-
14
- # =============================================================================
15
- # Load Shared Libraries
16
- # =============================================================================
17
-
18
- # shellcheck source=lib/colors.sh
19
- source "$SCRIPT_DIR/lib/colors.sh"
20
- # shellcheck source=lib/constants.sh
21
- source "$SCRIPT_DIR/lib/constants.sh"
22
- # shellcheck source=lib/json.sh
23
- source "$SCRIPT_DIR/lib/json.sh"
24
- # shellcheck source=lib/util.sh
25
- source "$SCRIPT_DIR/lib/util.sh"
26
-
27
- # Parse arguments
28
- NON_INTERACTIVE=false
29
- if [[ "$1" == "--non-interactive" ]]; then
30
- NON_INTERACTIVE=true
31
- fi
32
-
33
- echo ""
34
- log_header "🔥 Vibe Forge Setup"
35
- echo ""
36
-
37
- # =============================================================================
38
- # STEP 1: Detect Platform
39
- # =============================================================================
40
-
41
- detect_platform() {
42
- case "$(uname -s)" in
43
- MINGW*|MSYS*|CYGWIN*)
44
- PLATFORM="windows"
45
- ;;
46
- Darwin)
47
- PLATFORM="macos"
48
- ;;
49
- Linux)
50
- PLATFORM="linux"
51
- ;;
52
- *)
53
- PLATFORM="unknown"
54
- ;;
55
- esac
56
-
57
- log_info "Platform detected: $PLATFORM"
58
- }
59
-
60
- # =============================================================================
61
- # STEP 2: Find Git Bash (Windows only)
62
- # =============================================================================
63
-
64
- find_git_bash() {
65
- if [[ "$PLATFORM" != "windows" ]]; then
66
- GIT_BASH_PATH=""
67
- return 0
68
- fi
69
-
70
- echo ""
71
- echo "Searching for Git Bash..."
72
-
73
- GIT_BASH_PATH=""
74
-
75
- # Common installation paths
76
- local paths=(
77
- "C:/Program Files/Git/bin/bash.exe"
78
- "C:/Program Files (x86)/Git/bin/bash.exe"
79
- "D:/Program Files/Git/bin/bash.exe"
80
- "D:/applications/git/bin/bash.exe"
81
- "$LOCALAPPDATA/Programs/Git/bin/bash.exe"
82
- "$USERPROFILE/AppData/Local/Programs/Git/bin/bash.exe"
83
- )
84
-
85
- # Check common paths
86
- for path in "${paths[@]}"; do
87
- if [[ -f "$path" ]]; then
88
- GIT_BASH_PATH="$path"
89
- break
90
- fi
91
- done
92
-
93
- # Try deriving from `where git`
94
- if [[ -z "$GIT_BASH_PATH" ]]; then
95
- local git_path
96
- git_path=$(where git 2>/dev/null | head -1)
97
- if [[ -n "$git_path" ]]; then
98
- # Git is typically at .../Git/cmd/git.exe or .../Git/bin/git.exe
99
- local git_dir
100
- git_dir=$(dirname "$(dirname "$git_path")")
101
- if [[ -f "$git_dir/bin/bash.exe" ]]; then
102
- GIT_BASH_PATH="$git_dir/bin/bash.exe"
103
- fi
104
- fi
105
- fi
106
-
107
- if [[ -n "$GIT_BASH_PATH" ]]; then
108
- log_success "Found Git Bash: $GIT_BASH_PATH"
109
- return 0
110
- else
111
- log_error "Git Bash not found."
112
- echo ""
113
- echo "Git Bash is required for Claude Code on Windows."
114
- echo ""
115
- echo "Options:"
116
- echo " 1. Install via winget: winget install Git.Git"
117
- echo " 2. Download from: https://git-scm.com/downloads/win"
118
- echo ""
119
-
120
- if [[ "$NON_INTERACTIVE" == "false" ]]; then
121
- read -p "Auto-install via winget? (y/n): " choice
122
- if [[ "$choice" == "y" || "$choice" == "Y" ]]; then
123
- echo ""
124
- echo "Installing Git..."
125
- if winget install Git.Git; then
126
- echo ""
127
- log_success "Git installed. Please restart your terminal and run 'forge init' again."
128
- exit 0
129
- else
130
- log_error "Installation failed. Please install Git manually."
131
- exit $EXIT_DEPENDENCY_MISSING
132
- fi
133
- fi
134
- fi
135
-
136
- echo "Please install Git and run 'forge init' again."
137
- exit $EXIT_DEPENDENCY_MISSING
138
- fi
139
- }
140
-
141
- # =============================================================================
142
- # STEP 3: Check Claude Code
143
- # =============================================================================
144
-
145
- check_claude() {
146
- echo ""
147
- echo "Checking Claude Code installation..."
148
-
149
- if ! command -v claude &> /dev/null; then
150
- log_error "Claude Code not found."
151
- echo ""
152
- echo "Claude Code CLI is required. Install from:"
153
- echo " https://claude.ai/download"
154
- echo ""
155
- exit $EXIT_DEPENDENCY_MISSING
156
- fi
157
-
158
- log_success "Claude Code found"
159
- }
160
-
161
- # =============================================================================
162
- # STEP 4: Create Config
163
- # =============================================================================
164
-
165
- create_config() {
166
- echo ""
167
- echo "Creating configuration..."
168
-
169
- local config_dir="$FORGE_ROOT/.forge"
170
- mkdir -p "$config_dir"
171
-
172
- # Convert path for Windows compatibility
173
- local git_bash_escaped="${GIT_BASH_PATH//\\/\\\\}"
174
-
175
- cat > "$config_dir/config.json" << EOF
176
- {
177
- "platform": "$PLATFORM",
178
- "git_bash_path": "$git_bash_escaped",
179
- "forge_root": "$FORGE_ROOT",
180
- "initialized": "$(date -Iseconds)",
181
- "validated": false
182
- }
183
- EOF
184
-
185
- log_success "Config created: $config_dir/config.json"
186
- }
187
-
188
- # =============================================================================
189
- # STEP 5: Configure Version Control
190
- # =============================================================================
191
-
192
- configure_vcs() {
193
- echo ""
194
- echo "Version Control Configuration"
195
- echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
196
- echo ""
197
-
198
- # Auto-detect VCS
199
- local detected_vcs
200
- detected_vcs=$(node "$SCRIPT_DIR/lib/vcs.js" detect 2>/dev/null)
201
- local detected_type
202
- detected_type=$(echo "$detected_vcs" | node -e "const d=require('fs').readFileSync(0,'utf8');try{console.log(JSON.parse(d).type)}catch{console.log('none')}")
203
- local confidence
204
- confidence=$(echo "$detected_vcs" | node -e "const d=require('fs').readFileSync(0,'utf8');try{console.log(JSON.parse(d).confidence)}catch{console.log('low')}")
205
-
206
- if [[ "$detected_type" != "none" && "$confidence" != "low" ]]; then
207
- log_info "Detected: $detected_type (confidence: $confidence)"
208
- fi
209
-
210
- echo ""
211
- echo "Select your version control platform:"
212
- echo ""
213
- echo " 1. GitHub (recommended - uses gh CLI)"
214
- echo " 2. GitLab"
215
- echo " 3. Gitea (self-hosted - uses tea CLI)"
216
- echo " 4. Azure DevOps"
217
- echo " 5. Bitbucket"
218
- echo " 6. Git only (no platform)"
219
- echo " 7. None (no version control)"
220
- echo ""
221
-
222
- local vcs_choice="github"
223
-
224
- if [[ "$NON_INTERACTIVE" == "false" ]]; then
225
- # Set default based on detection
226
- local default_choice="1"
227
- case "$detected_type" in
228
- github) default_choice="1" ;;
229
- gitlab) default_choice="2" ;;
230
- gitea) default_choice="3" ;;
231
- azure-devops) default_choice="4" ;;
232
- bitbucket) default_choice="5" ;;
233
- git-only) default_choice="6" ;;
234
- none) default_choice="7" ;;
235
- esac
236
-
237
- read -p "VCS Platform [$default_choice]: " choice
238
- choice="${choice:-$default_choice}"
239
-
240
- case "$choice" in
241
- 1) vcs_choice="github" ;;
242
- 2) vcs_choice="gitlab" ;;
243
- 3) vcs_choice="gitea" ;;
244
- 4) vcs_choice="azure-devops" ;;
245
- 5) vcs_choice="bitbucket" ;;
246
- 6) vcs_choice="git-only" ;;
247
- 7) vcs_choice="none" ;;
248
- *) vcs_choice="github" ;;
249
- esac
250
- else
251
- # Non-interactive: use detected or default to github
252
- if [[ "$detected_type" != "none" ]]; then
253
- vcs_choice="$detected_type"
254
- fi
255
- fi
256
-
257
- # Initialize VCS folders and save config
258
- local init_result
259
- init_result=$(node "$SCRIPT_DIR/lib/vcs.js" init "$vcs_choice" "$FORGE_ROOT" 2>/dev/null)
260
-
261
- echo ""
262
- case "$vcs_choice" in
263
- "github")
264
- log_success "GitHub selected"
265
- echo " Branch workflow with PR via gh CLI"
266
- echo " Created: .github/workflows/"
267
- ;;
268
- "gitlab")
269
- log_success "GitLab selected"
270
- echo " Branch workflow with merge requests"
271
- echo " Created: .gitlab/"
272
- ;;
273
- "gitea")
274
- log_success "Gitea selected"
275
- echo " Branch workflow with PR via tea CLI"
276
- echo " Created: .gitea/workflows/"
277
- ;;
278
- "azure-devops")
279
- log_success "Azure DevOps selected"
280
- echo " Branch workflow with PR via az CLI"
281
- echo " Created: .azure/"
282
- ;;
283
- "bitbucket")
284
- log_success "Bitbucket selected"
285
- echo " Branch workflow with manual PRs"
286
- ;;
287
- "git-only")
288
- log_info "Git only (no platform)"
289
- echo " Branch workflow without PR automation"
290
- ;;
291
- "none")
292
- log_info "No version control"
293
- echo " Git workflow guidance will be skipped"
294
- ;;
295
- esac
296
-
297
- # Save to forge config
298
- VCS_TYPE="$vcs_choice"
299
- }
300
-
301
- # =============================================================================
302
- # STEP 6: Validate Setup
303
- # =============================================================================
304
-
305
- validate_setup() {
306
- echo ""
307
- echo "Validating setup..."
308
-
309
- local test_cmd="claude --version"
310
-
311
- if [[ "$PLATFORM" == "windows" && -n "$GIT_BASH_PATH" ]]; then
312
- # On Windows, test with the git bash path set
313
- export CLAUDE_CODE_GIT_BASH_PATH="$GIT_BASH_PATH"
314
- fi
315
-
316
- if $test_cmd &> /dev/null; then
317
- log_success "Claude Code working"
318
-
319
- # Update config to mark as validated
320
- local config_file="$FORGE_ROOT/.forge/config.json"
321
- if [[ -f "$config_file" ]]; then
322
- json_write_bool "$config_file" "validated" true
323
- fi
324
-
325
- return 0
326
- else
327
- log_error "Claude Code validation failed"
328
- return 1
329
- fi
330
- }
331
-
332
- # =============================================================================
333
- # STEP 6: Configure Terminal
334
- # =============================================================================
335
-
336
- configure_terminal() {
337
- echo ""
338
- echo "Terminal Configuration"
339
- echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
340
- echo ""
341
- echo "Select your terminal for auto-spawning worker agents:"
342
- echo ""
343
- echo " 1. Windows Terminal (recommended - uses wt)"
344
- echo " 2. Other / Manual (provides instructions)"
345
- echo ""
346
-
347
- local terminal_choice="manual"
348
-
349
- if [[ "$NON_INTERACTIVE" == "false" ]]; then
350
- read -p "Terminal [1/2]: " choice
351
- case "$choice" in
352
- 1) terminal_choice="windows-terminal" ;;
353
- *) terminal_choice="manual" ;;
354
- esac
355
- else
356
- terminal_choice="manual"
357
- fi
358
-
359
- # Save to config
360
- TERMINAL_TYPE="$terminal_choice"
361
-
362
- # Update config with terminal type
363
- local config_file="$FORGE_ROOT/.forge/config.json"
364
- if [[ -f "$config_file" ]]; then
365
- json_write "$config_file" "terminal_type" "$terminal_choice"
366
- fi
367
-
368
- echo ""
369
- case "$terminal_choice" in
370
- "windows-terminal")
371
- log_success "Windows Terminal selected"
372
- echo " Workers will auto-spawn in new tabs via wt"
373
- ;;
374
- *)
375
- log_info "Manual mode selected"
376
- echo " You'll receive instructions to start workers"
377
- ;;
378
- esac
379
- }
380
-
381
- # =============================================================================
382
- # STEP 7: Configure Daemon
383
- # =============================================================================
384
-
385
- configure_daemon() {
386
- echo ""
387
- echo "Daemon Configuration"
388
- echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
389
- echo ""
390
- echo "The Forge daemon monitors task folders and routes work automatically."
391
- echo "It runs in the background and keeps forge-state.yaml updated."
392
- echo ""
393
-
394
- local enable_daemon="y"
395
-
396
- if [[ "$NON_INTERACTIVE" == "false" ]]; then
397
- read -p "Enable daemon orchestration? (Y/n): " choice
398
- if [[ "$choice" == "n" || "$choice" == "N" ]]; then
399
- enable_daemon="n"
400
- fi
401
- fi
402
-
403
- # Update config with daemon preference
404
- local config_file="$FORGE_ROOT/.forge/config.json"
405
- if [[ -f "$config_file" ]]; then
406
- json_write_bool "$config_file" "daemon_enabled" "$( [[ "$enable_daemon" == "y" ]] && echo "true" || echo "false" )"
407
- fi
408
-
409
- if [[ "$enable_daemon" == "y" ]]; then
410
- echo ""
411
- log_success "Daemon enabled"
412
- echo ""
413
- echo "Starting daemon..."
414
- if ! "$SCRIPT_DIR/forge-daemon.sh" start; then
415
- log_warn "Daemon failed to start (sqlite3 may be missing)"
416
- echo " You can install sqlite3 and start it later with: forge daemon start"
417
- fi
418
- else
419
- echo ""
420
- log_info "Daemon disabled"
421
- echo " You can start it later with: forge daemon start"
422
- fi
423
- }
424
-
425
- # =============================================================================
426
- # STEP 7b: Configure Worker Loop (Persistent Mode)
427
- # =============================================================================
428
-
429
- configure_worker_loop() {
430
- echo ""
431
- echo "Worker Loop Configuration"
432
- echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
433
- echo ""
434
- echo "Worker Loop keeps agents running continuously."
435
- echo "When a worker finishes a task, it automatically checks for new work"
436
- echo "instead of exiting. Great for longer coding sessions."
437
- echo ""
438
-
439
- local enable_worker_loop="n"
440
-
441
- if [[ "$NON_INTERACTIVE" == "false" ]]; then
442
- read -p "Enable persistent worker mode? (y/N): " choice
443
- if [[ "$choice" == "y" || "$choice" == "Y" ]]; then
444
- enable_worker_loop="y"
445
- fi
446
- fi
447
-
448
- # Update config with worker loop preference
449
- local config_file="$FORGE_ROOT/.forge/config.json"
450
- if [[ -f "$config_file" ]]; then
451
- json_write_bool "$config_file" "worker_loop_enabled" "$( [[ "$enable_worker_loop" == "y" ]] && echo "true" || echo "false" )"
452
- fi
453
-
454
- if [[ "$enable_worker_loop" == "y" ]]; then
455
- echo ""
456
- log_success "Worker Loop enabled"
457
- echo " Workers will keep running and check for new tasks"
458
- else
459
- echo ""
460
- log_info "Worker Loop disabled"
461
- echo " Workers will exit after completing their tasks"
462
- echo " Enable later with: forge config worker-loop on"
463
- fi
464
- }
465
-
466
- # =============================================================================
467
- # STEP 8: Install Slash Command
468
- # =============================================================================
469
-
470
- install_slash_command() {
471
- echo ""
472
- echo "Installing /forge slash command..."
473
-
474
- # Parent project directory (one level up from _vibe-forge)
475
- local parent_dir
476
- parent_dir="$(dirname "$FORGE_ROOT")"
477
-
478
- local target_dir="$parent_dir/.claude/commands"
479
- local source_file="$FORGE_ROOT/.claude/commands/forge.md"
480
-
481
- # Create .claude/commands in parent project if it doesn't exist
482
- mkdir -p "$target_dir"
483
-
484
- # Copy the forge command
485
- if [[ -f "$source_file" ]]; then
486
- cp "$source_file" "$target_dir/forge.md"
487
- log_success "Slash command installed: $target_dir/forge.md"
488
- echo " Use /forge in Claude Code to access Vibe Forge"
489
- else
490
- log_warn "Could not find forge command template"
491
- echo " You may need to manually copy .claude/commands/forge.md"
492
- fi
493
- }
494
-
495
- # =============================================================================
496
- # STEP 9: Create Project Context
497
- # =============================================================================
498
-
499
- detect_project_info() {
500
- # Try to detect project name
501
- PROJECT_NAME=$(basename "$PWD")
502
-
503
- # Try to detect tech stack
504
- TECH_STACK=""
505
-
506
- if [[ -f "package.json" ]]; then
507
- TECH_STACK="Node.js"
508
- # Check for framework hints
509
- if grep -q '"react"' package.json 2>/dev/null; then
510
- TECH_STACK="React"
511
- elif grep -q '"vue"' package.json 2>/dev/null; then
512
- TECH_STACK="Vue"
513
- elif grep -q '"next"' package.json 2>/dev/null; then
514
- TECH_STACK="Next.js"
515
- elif grep -q '"svelte"' package.json 2>/dev/null; then
516
- TECH_STACK="Svelte"
517
- fi
518
- elif [[ -f "Cargo.toml" ]]; then
519
- TECH_STACK="Rust"
520
- elif [[ -f "go.mod" ]]; then
521
- TECH_STACK="Go"
522
- elif [[ -f "requirements.txt" ]] || [[ -f "pyproject.toml" ]]; then
523
- TECH_STACK="Python"
524
- elif [[ -f "pom.xml" ]] || [[ -f "build.gradle" ]]; then
525
- TECH_STACK="Java"
526
- elif [[ -f "*.csproj" ]] || [[ -f "*.sln" ]]; then
527
- TECH_STACK="C#/.NET"
528
- fi
529
- }
530
-
531
- create_project_context() {
532
- echo ""
533
- echo "Project Context Setup"
534
- echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
535
-
536
- detect_project_info
537
-
538
- local context_dir="$PWD/context"
539
- local context_file="$context_dir/project-context.md"
540
- local template_file="$FORGE_ROOT/context/project-context-template.md"
541
-
542
- mkdir -p "$context_dir"
543
- mkdir -p "$context_dir/agent-overrides"
544
-
545
- # Create architecture.md if missing
546
- if [[ ! -f "$context_dir/architecture.md" ]] && [[ -f "$FORGE_ROOT/context/architecture.md" ]]; then
547
- cp "$FORGE_ROOT/context/architecture.md" "$context_dir/architecture.md"
548
- fi
549
-
550
- # Create agent-overrides README if missing
551
- if [[ ! -f "$context_dir/agent-overrides/README.md" ]] && [[ -f "$FORGE_ROOT/context/agent-overrides/README.md" ]]; then
552
- cp "$FORGE_ROOT/context/agent-overrides/README.md" "$context_dir/agent-overrides/README.md"
553
- fi
554
-
555
- # Check if context already exists
556
- if [[ -f "$context_file" ]]; then
557
- log_info "Project context already exists"
558
- echo " $context_file"
559
- return 0
560
- fi
561
-
562
- echo ""
563
- log_info "Detected project: $PROJECT_NAME"
564
- if [[ -n "$TECH_STACK" ]]; then
565
- log_info "Detected stack: $TECH_STACK"
566
- fi
567
- echo ""
568
-
569
- if [[ "$NON_INTERACTIVE" == "false" ]]; then
570
- # Ask for project description
571
- read -p "Brief project description (or Enter to skip): " PROJECT_DESC
572
- fi
573
-
574
- # Create project context from template or generate minimal one
575
- if [[ -f "$template_file" ]]; then
576
- cp "$template_file" "$context_file"
577
-
578
- # Replace placeholders using cross-platform sed
579
- sed_inplace "s/\[Project Name\]/$PROJECT_NAME/g" "$context_file"
580
- sed_inplace "s/\[Your Name\]/Developer/g" "$context_file"
581
-
582
- if [[ -n "$TECH_STACK" ]]; then
583
- sed_inplace "s/\[e.g., React, Node.js, PostgreSQL\]/$TECH_STACK/g" "$context_file"
584
- fi
585
-
586
- if [[ -n "$PROJECT_DESC" ]]; then
587
- sed_inplace "s/\[Brief description of the project\]/$PROJECT_DESC/g" "$context_file"
588
- fi
589
- else
590
- # Generate minimal context
591
- cat > "$context_file" << EOF
592
- # Project Context
593
-
594
- ## Project: $PROJECT_NAME
595
-
596
- ${PROJECT_DESC:-A software project managed with Vibe Forge.}
597
-
598
- ## Tech Stack
599
- ${TECH_STACK:-To be determined}
600
-
601
- ## Key Patterns
602
- - Follow existing code conventions
603
- - Write tests for new features
604
- - Document public APIs
605
-
606
- ## Notes
607
- Edit this file to add project-specific context for the AI agents.
608
- EOF
609
- fi
610
-
611
- log_success "Project context created: $context_file"
612
- echo " Edit this file to add more project details."
613
- }
614
-
615
- # =============================================================================
616
- # STEP 10: Setup Complete
617
- # =============================================================================
618
-
619
- setup_complete() {
620
- echo ""
621
- log_header "🔥 Vibe Forge initialized!"
622
- echo ""
623
- echo "Ready to start! Open Claude Code in this project and run:"
624
- echo ""
625
- log_info "/forge Start the Planning Hub"
626
- log_info "/forge status Show status dashboard"
627
- log_info "/forge spawn anvil Spawn a worker agent"
628
- log_info "/forge help See all commands"
629
- echo ""
630
- echo "Optional: Edit context/project-context.md to add project details."
631
- echo " Edit context/architecture.md for architectural guardrails."
632
- echo " Add files to context/agent-overrides/ for per-agent rules."
633
- echo ""
634
- }
635
-
636
- # =============================================================================
637
- # Main
638
- # =============================================================================
639
-
640
- main() {
641
- detect_platform
642
- find_git_bash
643
- check_claude
644
- create_config
645
- configure_vcs
646
-
647
- if validate_setup; then
648
- configure_terminal
649
- configure_daemon
650
- configure_worker_loop
651
- install_slash_command
652
- create_project_context
653
- setup_complete
654
- else
655
- echo ""
656
- log_error "Setup incomplete. Please check the errors above."
657
- exit $EXIT_CONFIG_ERROR
658
- fi
659
- }
660
-
661
- main "$@"
1
+ #!/usr/bin/env bash
2
+ #
3
+ # Vibe Forge - Setup Script
4
+ # Initializes Vibe Forge for the current project
5
+ #
6
+ # Usage: ./forge-setup.sh [--non-interactive]
7
+ #
8
+
9
+ set -euo pipefail
10
+
11
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
12
+ FORGE_ROOT="$(dirname "$SCRIPT_DIR")"
13
+
14
+ # =============================================================================
15
+ # Load Shared Libraries
16
+ # =============================================================================
17
+
18
+ # shellcheck source=lib/colors.sh
19
+ source "$SCRIPT_DIR/../src/lib/colors.sh"
20
+ # shellcheck source=lib/constants.sh
21
+ source "$SCRIPT_DIR/../src/lib/constants.sh"
22
+ # shellcheck source=lib/json.sh
23
+ source "$SCRIPT_DIR/../src/lib/json.sh"
24
+ # shellcheck source=lib/util.sh
25
+ source "$SCRIPT_DIR/../src/lib/util.sh"
26
+
27
+ # Parse arguments
28
+ NON_INTERACTIVE=false
29
+ if [[ "${1:-}" == "--non-interactive" ]]; then
30
+ NON_INTERACTIVE=true
31
+ fi
32
+
33
+ echo ""
34
+ log_header "🔥 Vibe Forge Setup"
35
+ echo ""
36
+
37
+ # =============================================================================
38
+ # STEP 1: Detect Platform
39
+ # =============================================================================
40
+
41
+ detect_platform() {
42
+ case "$(uname -s)" in
43
+ MINGW*|MSYS*|CYGWIN*)
44
+ PLATFORM="windows"
45
+ ;;
46
+ Darwin)
47
+ PLATFORM="macos"
48
+ ;;
49
+ Linux)
50
+ PLATFORM="linux"
51
+ ;;
52
+ *)
53
+ PLATFORM="unknown"
54
+ ;;
55
+ esac
56
+
57
+ log_info "Platform detected: $PLATFORM"
58
+ }
59
+
60
+ # =============================================================================
61
+ # STEP 2: Find Git Bash (Windows only)
62
+ # =============================================================================
63
+
64
+ find_git_bash() {
65
+ if [[ "$PLATFORM" != "windows" ]]; then
66
+ GIT_BASH_PATH=""
67
+ return 0
68
+ fi
69
+
70
+ echo ""
71
+ echo "Searching for Git Bash..."
72
+
73
+ GIT_BASH_PATH=""
74
+
75
+ # Common installation paths
76
+ local paths=(
77
+ "C:/Program Files/Git/bin/bash.exe"
78
+ "C:/Program Files (x86)/Git/bin/bash.exe"
79
+ "D:/Program Files/Git/bin/bash.exe"
80
+ "D:/applications/git/bin/bash.exe"
81
+ "$LOCALAPPDATA/Programs/Git/bin/bash.exe"
82
+ "$USERPROFILE/AppData/Local/Programs/Git/bin/bash.exe"
83
+ )
84
+
85
+ # Check common paths
86
+ for path in "${paths[@]}"; do
87
+ if [[ -f "$path" ]]; then
88
+ GIT_BASH_PATH="$path"
89
+ break
90
+ fi
91
+ done
92
+
93
+ # Try deriving from `where git`
94
+ if [[ -z "$GIT_BASH_PATH" ]]; then
95
+ local git_path
96
+ git_path=$(where git 2>/dev/null | head -1)
97
+ if [[ -n "$git_path" ]]; then
98
+ # Git is typically at .../Git/cmd/git.exe or .../Git/bin/git.exe
99
+ local git_dir
100
+ git_dir=$(dirname "$(dirname "$git_path")")
101
+ if [[ -f "$git_dir/bin/bash.exe" ]]; then
102
+ GIT_BASH_PATH="$git_dir/bin/bash.exe"
103
+ fi
104
+ fi
105
+ fi
106
+
107
+ if [[ -n "$GIT_BASH_PATH" ]]; then
108
+ log_success "Found Git Bash: $GIT_BASH_PATH"
109
+ return 0
110
+ else
111
+ log_error "Git Bash not found."
112
+ echo ""
113
+ echo "Git Bash is required for Claude Code on Windows."
114
+ echo ""
115
+ echo "Options:"
116
+ echo " 1. Install via winget: winget install Git.Git"
117
+ echo " 2. Download from: https://git-scm.com/downloads/win"
118
+ echo ""
119
+
120
+ if [[ "$NON_INTERACTIVE" == "false" ]]; then
121
+ read -p "Auto-install via winget? (y/n): " choice
122
+ if [[ "$choice" == "y" || "$choice" == "Y" ]]; then
123
+ echo ""
124
+ echo "Installing Git..."
125
+ if winget install Git.Git; then
126
+ echo ""
127
+ log_success "Git installed. Please restart your terminal and run 'forge init' again."
128
+ exit 0
129
+ else
130
+ log_error "Installation failed. Please install Git manually."
131
+ exit $EXIT_DEPENDENCY_MISSING
132
+ fi
133
+ fi
134
+ fi
135
+
136
+ echo "Please install Git and run 'forge init' again."
137
+ exit $EXIT_DEPENDENCY_MISSING
138
+ fi
139
+ }
140
+
141
+ # =============================================================================
142
+ # STEP 3: Check Claude Code
143
+ # =============================================================================
144
+
145
+ check_claude() {
146
+ echo ""
147
+ echo "Checking Claude Code installation..."
148
+
149
+ if ! command -v claude &> /dev/null; then
150
+ log_error "Claude Code not found."
151
+ echo ""
152
+ echo "Claude Code CLI is required. Install from:"
153
+ echo " https://claude.ai/download"
154
+ echo ""
155
+ exit $EXIT_DEPENDENCY_MISSING
156
+ fi
157
+
158
+ log_success "Claude Code found"
159
+ }
160
+
161
+ # =============================================================================
162
+ # STEP 4: Create Config
163
+ # =============================================================================
164
+
165
+ create_config() {
166
+ echo ""
167
+ echo "Creating configuration..."
168
+
169
+ local config_dir="$FORGE_ROOT/.forge"
170
+ mkdir -p "$config_dir"
171
+
172
+ # Convert path for Windows compatibility
173
+ local git_bash_escaped="${GIT_BASH_PATH//\\/\\\\}"
174
+
175
+ cat > "$config_dir/config.json" << EOF
176
+ {
177
+ "platform": "$PLATFORM",
178
+ "git_bash_path": "$git_bash_escaped",
179
+ "forge_root": "$FORGE_ROOT",
180
+ "initialized": "$(date -Iseconds)",
181
+ "validated": false
182
+ }
183
+ EOF
184
+
185
+ log_success "Config created: $config_dir/config.json"
186
+ }
187
+
188
+ # =============================================================================
189
+ # STEP 5: Configure Version Control
190
+ # =============================================================================
191
+
192
+ configure_vcs() {
193
+ echo ""
194
+ echo "Version Control Configuration"
195
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
196
+ echo ""
197
+
198
+ # Auto-detect VCS
199
+ local detected_vcs
200
+ detected_vcs=$(node "$SCRIPT_DIR/../src/lib/vcs.js" detect 2>/dev/null)
201
+ local detected_type
202
+ detected_type=$(echo "$detected_vcs" | node -e "const d=require('fs').readFileSync(0,'utf8');try{console.log(JSON.parse(d).type)}catch{console.log('none')}")
203
+ local confidence
204
+ confidence=$(echo "$detected_vcs" | node -e "const d=require('fs').readFileSync(0,'utf8');try{console.log(JSON.parse(d).confidence)}catch{console.log('low')}")
205
+
206
+ if [[ "$detected_type" != "none" && "$confidence" != "low" ]]; then
207
+ log_info "Detected: $detected_type (confidence: $confidence)"
208
+ fi
209
+
210
+ echo ""
211
+ echo "Select your version control platform:"
212
+ echo ""
213
+ echo " 1. GitHub (recommended - uses gh CLI)"
214
+ echo " 2. GitLab"
215
+ echo " 3. Gitea (self-hosted - uses tea CLI)"
216
+ echo " 4. Azure DevOps"
217
+ echo " 5. Bitbucket"
218
+ echo " 6. Git only (no platform)"
219
+ echo " 7. None (no version control)"
220
+ echo ""
221
+
222
+ local vcs_choice="github"
223
+
224
+ if [[ "$NON_INTERACTIVE" == "false" ]]; then
225
+ # Set default based on detection
226
+ local default_choice="1"
227
+ case "$detected_type" in
228
+ github) default_choice="1" ;;
229
+ gitlab) default_choice="2" ;;
230
+ gitea) default_choice="3" ;;
231
+ azure-devops) default_choice="4" ;;
232
+ bitbucket) default_choice="5" ;;
233
+ git-only) default_choice="6" ;;
234
+ none) default_choice="7" ;;
235
+ esac
236
+
237
+ read -p "VCS Platform [$default_choice]: " choice
238
+ choice="${choice:-$default_choice}"
239
+
240
+ case "$choice" in
241
+ 1) vcs_choice="github" ;;
242
+ 2) vcs_choice="gitlab" ;;
243
+ 3) vcs_choice="gitea" ;;
244
+ 4) vcs_choice="azure-devops" ;;
245
+ 5) vcs_choice="bitbucket" ;;
246
+ 6) vcs_choice="git-only" ;;
247
+ 7) vcs_choice="none" ;;
248
+ *) vcs_choice="github" ;;
249
+ esac
250
+ else
251
+ # Non-interactive: use detected or default to github
252
+ if [[ "$detected_type" != "none" ]]; then
253
+ vcs_choice="$detected_type"
254
+ fi
255
+ fi
256
+
257
+ # Initialize VCS folders and save config
258
+ local init_result
259
+ init_result=$(node "$SCRIPT_DIR/../src/lib/vcs.js" init "$vcs_choice" "$FORGE_ROOT" 2>/dev/null)
260
+
261
+ echo ""
262
+ case "$vcs_choice" in
263
+ "github")
264
+ log_success "GitHub selected"
265
+ echo " Branch workflow with PR via gh CLI"
266
+ echo " Created: .github/workflows/"
267
+ ;;
268
+ "gitlab")
269
+ log_success "GitLab selected"
270
+ echo " Branch workflow with merge requests"
271
+ echo " Created: .gitlab/"
272
+ ;;
273
+ "gitea")
274
+ log_success "Gitea selected"
275
+ echo " Branch workflow with PR via tea CLI"
276
+ echo " Created: .gitea/workflows/"
277
+ ;;
278
+ "azure-devops")
279
+ log_success "Azure DevOps selected"
280
+ echo " Branch workflow with PR via az CLI"
281
+ echo " Created: .azure/"
282
+ ;;
283
+ "bitbucket")
284
+ log_success "Bitbucket selected"
285
+ echo " Branch workflow with manual PRs"
286
+ ;;
287
+ "git-only")
288
+ log_info "Git only (no platform)"
289
+ echo " Branch workflow without PR automation"
290
+ ;;
291
+ "none")
292
+ log_info "No version control"
293
+ echo " Git workflow guidance will be skipped"
294
+ ;;
295
+ esac
296
+
297
+ # Save to forge config
298
+ VCS_TYPE="$vcs_choice"
299
+ }
300
+
301
+ # =============================================================================
302
+ # STEP 6: Validate Setup
303
+ # =============================================================================
304
+
305
+ validate_setup() {
306
+ echo ""
307
+ echo "Validating setup..."
308
+
309
+ local test_cmd="claude --version"
310
+
311
+ if [[ "$PLATFORM" == "windows" && -n "$GIT_BASH_PATH" ]]; then
312
+ # On Windows, test with the git bash path set
313
+ export CLAUDE_CODE_GIT_BASH_PATH="$GIT_BASH_PATH"
314
+ fi
315
+
316
+ if $test_cmd &> /dev/null; then
317
+ log_success "Claude Code working"
318
+
319
+ # Update config to mark as validated
320
+ local config_file="$FORGE_ROOT/.forge/config.json"
321
+ if [[ -f "$config_file" ]]; then
322
+ json_write_bool "$config_file" "validated" true
323
+ fi
324
+
325
+ return 0
326
+ else
327
+ log_error "Claude Code validation failed"
328
+ return 1
329
+ fi
330
+ }
331
+
332
+ # =============================================================================
333
+ # STEP 6: Configure Terminal
334
+ # =============================================================================
335
+
336
+ configure_terminal() {
337
+ echo ""
338
+ echo "Terminal Configuration"
339
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
340
+ echo ""
341
+ echo "Select your terminal for auto-spawning worker agents:"
342
+ echo ""
343
+ echo " 1. Windows Terminal (recommended - uses wt)"
344
+ echo " 2. Other / Manual (provides instructions)"
345
+ echo ""
346
+
347
+ local terminal_choice="manual"
348
+
349
+ if [[ "$NON_INTERACTIVE" == "false" ]]; then
350
+ read -p "Terminal [1/2]: " choice
351
+ case "$choice" in
352
+ 1) terminal_choice="windows-terminal" ;;
353
+ *) terminal_choice="manual" ;;
354
+ esac
355
+ else
356
+ terminal_choice="manual"
357
+ fi
358
+
359
+ # Save to config
360
+ TERMINAL_TYPE="$terminal_choice"
361
+
362
+ # Update config with terminal type
363
+ local config_file="$FORGE_ROOT/.forge/config.json"
364
+ if [[ -f "$config_file" ]]; then
365
+ json_write "$config_file" "terminal_type" "$terminal_choice"
366
+ fi
367
+
368
+ echo ""
369
+ case "$terminal_choice" in
370
+ "windows-terminal")
371
+ log_success "Windows Terminal selected"
372
+ echo " Workers will auto-spawn in new tabs via wt"
373
+ ;;
374
+ *)
375
+ log_info "Manual mode selected"
376
+ echo " You'll receive instructions to start workers"
377
+ ;;
378
+ esac
379
+ }
380
+
381
+ # =============================================================================
382
+ # STEP 7: Configure Daemon
383
+ # =============================================================================
384
+
385
+ configure_daemon() {
386
+ echo ""
387
+ echo "Daemon Configuration"
388
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
389
+ echo ""
390
+ echo "The Forge daemon monitors task folders and routes work automatically."
391
+ echo "It runs in the background and keeps forge-state.yaml updated."
392
+ echo ""
393
+
394
+ local enable_daemon="y"
395
+
396
+ if [[ "$NON_INTERACTIVE" == "false" ]]; then
397
+ read -p "Enable daemon orchestration? (Y/n): " choice
398
+ if [[ "$choice" == "n" || "$choice" == "N" ]]; then
399
+ enable_daemon="n"
400
+ fi
401
+ fi
402
+
403
+ # Update config with daemon preference
404
+ local config_file="$FORGE_ROOT/.forge/config.json"
405
+ if [[ -f "$config_file" ]]; then
406
+ json_write_bool "$config_file" "daemon_enabled" "$( [[ "$enable_daemon" == "y" ]] && echo "true" || echo "false" )"
407
+ fi
408
+
409
+ if [[ "$enable_daemon" == "y" ]]; then
410
+ echo ""
411
+ log_success "Daemon enabled"
412
+ echo ""
413
+ echo "Starting daemon..."
414
+ if ! "$SCRIPT_DIR/forge-daemon.sh" start; then
415
+ log_warn "Daemon failed to start (sqlite3 may be missing)"
416
+ echo " You can install sqlite3 and start it later with: forge daemon start"
417
+ fi
418
+ else
419
+ echo ""
420
+ log_info "Daemon disabled"
421
+ echo " You can start it later with: forge daemon start"
422
+ fi
423
+ }
424
+
425
+ # =============================================================================
426
+ # STEP 7b: Configure Worker Loop (Persistent Mode)
427
+ # =============================================================================
428
+
429
+ configure_worker_loop() {
430
+ echo ""
431
+ echo "Worker Loop Configuration"
432
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
433
+ echo ""
434
+ echo "Worker Loop keeps agents running continuously."
435
+ echo "When a worker finishes a task, it automatically checks for new work"
436
+ echo "instead of exiting. Great for longer coding sessions."
437
+ echo ""
438
+
439
+ local enable_worker_loop="n"
440
+
441
+ if [[ "$NON_INTERACTIVE" == "false" ]]; then
442
+ read -p "Enable persistent worker mode? (y/N): " choice
443
+ if [[ "$choice" == "y" || "$choice" == "Y" ]]; then
444
+ enable_worker_loop="y"
445
+ fi
446
+ fi
447
+
448
+ # Update config with worker loop preference
449
+ local config_file="$FORGE_ROOT/.forge/config.json"
450
+ if [[ -f "$config_file" ]]; then
451
+ json_write_bool "$config_file" "worker_loop_enabled" "$( [[ "$enable_worker_loop" == "y" ]] && echo "true" || echo "false" )"
452
+ fi
453
+
454
+ if [[ "$enable_worker_loop" == "y" ]]; then
455
+ echo ""
456
+ log_success "Worker Loop enabled"
457
+ echo " Workers will keep running and check for new tasks"
458
+ else
459
+ echo ""
460
+ log_info "Worker Loop disabled"
461
+ echo " Workers will exit after completing their tasks"
462
+ echo " Enable later with: forge config worker-loop on"
463
+ fi
464
+ }
465
+
466
+ # =============================================================================
467
+ # STEP 8: Install Slash Command
468
+ # =============================================================================
469
+
470
+ install_slash_command() {
471
+ echo ""
472
+ echo "Installing /forge slash command..."
473
+
474
+ # Parent project directory (one level up from _vibe-forge)
475
+ local parent_dir
476
+ parent_dir="$(dirname "$FORGE_ROOT")"
477
+
478
+ local target_dir="$parent_dir/.claude/commands"
479
+ local source_file="$FORGE_ROOT/.claude/commands/forge.md"
480
+
481
+ # Create .claude/commands in parent project if it doesn't exist
482
+ mkdir -p "$target_dir"
483
+
484
+ # Copy the forge command
485
+ if [[ -f "$source_file" ]]; then
486
+ cp "$source_file" "$target_dir/forge.md"
487
+ log_success "Slash command installed: $target_dir/forge.md"
488
+ echo " Use /forge in Claude Code to access Vibe Forge"
489
+ else
490
+ log_warn "Could not find forge command template"
491
+ echo " You may need to manually copy .claude/commands/forge.md"
492
+ fi
493
+ }
494
+
495
+ # =============================================================================
496
+ # STEP 9: Create Project Context
497
+ # =============================================================================
498
+
499
+ detect_project_info() {
500
+ # Try to detect project name
501
+ PROJECT_NAME=$(basename "$PWD")
502
+
503
+ # Try to detect tech stack
504
+ TECH_STACK=""
505
+
506
+ if [[ -f "package.json" ]]; then
507
+ TECH_STACK="Node.js"
508
+ # Check for framework hints
509
+ if grep -q '"react"' package.json 2>/dev/null; then
510
+ TECH_STACK="React"
511
+ elif grep -q '"vue"' package.json 2>/dev/null; then
512
+ TECH_STACK="Vue"
513
+ elif grep -q '"next"' package.json 2>/dev/null; then
514
+ TECH_STACK="Next.js"
515
+ elif grep -q '"svelte"' package.json 2>/dev/null; then
516
+ TECH_STACK="Svelte"
517
+ fi
518
+ elif [[ -f "Cargo.toml" ]]; then
519
+ TECH_STACK="Rust"
520
+ elif [[ -f "go.mod" ]]; then
521
+ TECH_STACK="Go"
522
+ elif [[ -f "requirements.txt" ]] || [[ -f "pyproject.toml" ]]; then
523
+ TECH_STACK="Python"
524
+ elif [[ -f "pom.xml" ]] || [[ -f "build.gradle" ]]; then
525
+ TECH_STACK="Java"
526
+ elif [[ -f "*.csproj" ]] || [[ -f "*.sln" ]]; then
527
+ TECH_STACK="C#/.NET"
528
+ fi
529
+ }
530
+
531
+ create_project_context() {
532
+ echo ""
533
+ echo "Project Context Setup"
534
+ echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
535
+
536
+ detect_project_info
537
+
538
+ local context_dir="$PWD/context"
539
+ local context_file="$context_dir/project-context.md"
540
+ local template_file="$FORGE_ROOT/templates/project-context-template.md"
541
+
542
+ mkdir -p "$context_dir"
543
+ mkdir -p "$context_dir/agent-overrides"
544
+
545
+ # Create architecture.md if missing
546
+ if [[ ! -f "$context_dir/architecture.md" ]] && [[ -f "$FORGE_ROOT/context/architecture.md" ]]; then
547
+ cp "$FORGE_ROOT/context/architecture.md" "$context_dir/architecture.md"
548
+ fi
549
+
550
+ # Create agent-overrides README if missing
551
+ if [[ ! -f "$context_dir/agent-overrides/README.md" ]] && [[ -f "$FORGE_ROOT/context/agent-overrides/README.md" ]]; then
552
+ cp "$FORGE_ROOT/context/agent-overrides/README.md" "$context_dir/agent-overrides/README.md"
553
+ fi
554
+
555
+ # Check if context already exists
556
+ if [[ -f "$context_file" ]]; then
557
+ log_info "Project context already exists"
558
+ echo " $context_file"
559
+ return 0
560
+ fi
561
+
562
+ echo ""
563
+ log_info "Detected project: $PROJECT_NAME"
564
+ if [[ -n "$TECH_STACK" ]]; then
565
+ log_info "Detected stack: $TECH_STACK"
566
+ fi
567
+ echo ""
568
+
569
+ local PROJECT_DESC=""
570
+ if [[ "$NON_INTERACTIVE" == "false" ]]; then
571
+ # Ask for project description
572
+ read -p "Brief project description (or Enter to skip): " PROJECT_DESC
573
+ fi
574
+
575
+ # Create project context from template or generate minimal one
576
+ if [[ -f "$template_file" ]]; then
577
+ cp "$template_file" "$context_file"
578
+
579
+ # Replace placeholders using cross-platform sed
580
+ sed_inplace "s/\[Project Name\]/$PROJECT_NAME/g" "$context_file"
581
+ sed_inplace "s/\[Your Name\]/Developer/g" "$context_file"
582
+
583
+ if [[ -n "$TECH_STACK" ]]; then
584
+ sed_inplace "s/\[e.g., React, Node.js, PostgreSQL\]/$TECH_STACK/g" "$context_file"
585
+ fi
586
+
587
+ if [[ -n "$PROJECT_DESC" ]]; then
588
+ sed_inplace "s/\[Brief description of the project\]/$PROJECT_DESC/g" "$context_file"
589
+ fi
590
+ else
591
+ # Generate minimal context
592
+ cat > "$context_file" << EOF
593
+ # Project Context
594
+
595
+ ## Project: $PROJECT_NAME
596
+
597
+ ${PROJECT_DESC:-A software project managed with Vibe Forge.}
598
+
599
+ ## Tech Stack
600
+ ${TECH_STACK:-To be determined}
601
+
602
+ ## Key Patterns
603
+ - Follow existing code conventions
604
+ - Write tests for new features
605
+ - Document public APIs
606
+
607
+ ## Notes
608
+ Edit this file to add project-specific context for the AI agents.
609
+ EOF
610
+ fi
611
+
612
+ log_success "Project context created: $context_file"
613
+ echo " Edit this file to add more project details."
614
+ }
615
+
616
+ # =============================================================================
617
+ # STEP 10: Setup Complete
618
+ # =============================================================================
619
+
620
+ setup_complete() {
621
+ echo ""
622
+ log_header "🔥 Vibe Forge initialized!"
623
+ echo ""
624
+ echo "Ready to start! Open Claude Code in this project and run:"
625
+ echo ""
626
+ log_info "/forge Start the Planning Hub"
627
+ log_info "/forge status Show status dashboard"
628
+ log_info "/forge spawn anvil Spawn a worker agent"
629
+ log_info "/forge help See all commands"
630
+ echo ""
631
+ echo "Optional: Edit context/project-context.md to add project details."
632
+ echo " Edit context/architecture.md for architectural guardrails."
633
+ echo " Add files to context/agent-overrides/ for per-agent rules."
634
+ echo ""
635
+ }
636
+
637
+ # =============================================================================
638
+ # Main
639
+ # =============================================================================
640
+
641
+ main() {
642
+ detect_platform
643
+ find_git_bash
644
+ check_claude
645
+ create_config
646
+ configure_vcs
647
+
648
+ if validate_setup; then
649
+ configure_terminal
650
+ configure_daemon
651
+ configure_worker_loop
652
+ install_slash_command
653
+ create_project_context
654
+ setup_complete
655
+ else
656
+ echo ""
657
+ log_error "Setup incomplete. Please check the errors above."
658
+ exit $EXIT_CONFIG_ERROR
659
+ fi
660
+ }
661
+
662
+ main "$@"