vibe-forge 0.4.0 → 0.8.1

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 (129) hide show
  1. package/.claude/commands/clear-attention.md +63 -63
  2. package/.claude/commands/compact-context.md +52 -0
  3. package/.claude/commands/configure-vcs.md +102 -102
  4. package/.claude/commands/forge.md +218 -171
  5. package/.claude/commands/need-help.md +77 -77
  6. package/.claude/commands/update-status.md +64 -64
  7. package/.claude/commands/worker-loop.md +106 -106
  8. package/.claude/hooks/worker-loop.js +217 -187
  9. package/.claude/scripts/setup-worker-loop.sh +45 -45
  10. package/.claude/settings.json +89 -0
  11. package/LICENSE +21 -21
  12. package/README.md +253 -232
  13. package/agents/aegis/personality.md +303 -269
  14. package/agents/anvil/personality.md +278 -240
  15. package/agents/architect/personality.md +260 -234
  16. package/agents/crucible/personality.md +362 -309
  17. package/agents/crucible-x/personality.md +210 -0
  18. package/agents/ember/personality.md +293 -265
  19. package/agents/flux/personality.md +248 -0
  20. package/agents/furnace/personality.md +342 -291
  21. package/agents/herald/personality.md +249 -247
  22. package/agents/loki/personality.md +108 -0
  23. package/agents/oracle/personality.md +284 -0
  24. package/agents/pixel/personality.md +140 -0
  25. package/agents/planning-hub/personality.md +473 -251
  26. package/agents/scribe/personality.md +253 -251
  27. package/agents/slag/personality.md +268 -0
  28. package/agents/temper/personality.md +270 -0
  29. package/bin/cli.js +372 -325
  30. package/bin/dashboard/api/agents.js +333 -0
  31. package/bin/dashboard/api/dispatch.js +507 -0
  32. package/bin/dashboard/api/tasks.js +416 -0
  33. package/bin/dashboard/public/assets/index-BpHfsx1r.js +2 -0
  34. package/bin/dashboard/public/assets/index-QODv4Zn9.css +1 -0
  35. package/bin/dashboard/public/index.html +14 -0
  36. package/bin/dashboard/server.js +645 -0
  37. package/bin/forge-daemon.sh +477 -851
  38. package/bin/forge-setup.sh +661 -645
  39. package/bin/forge-spawn.sh +164 -164
  40. package/bin/forge.cmd +83 -83
  41. package/bin/forge.sh +566 -387
  42. package/bin/lib/agents.sh +177 -177
  43. package/bin/lib/check-aliases.js +50 -0
  44. package/bin/lib/colors.sh +44 -44
  45. package/bin/lib/config.sh +347 -313
  46. package/bin/lib/constants.sh +241 -206
  47. package/bin/lib/daemon/budgets.sh +107 -0
  48. package/bin/lib/daemon/dependencies.sh +146 -0
  49. package/bin/lib/daemon/display.sh +128 -0
  50. package/bin/lib/daemon/notifications.sh +273 -0
  51. package/bin/lib/daemon/routing.sh +93 -0
  52. package/bin/lib/daemon/state.sh +163 -0
  53. package/bin/lib/daemon/sync.sh +103 -0
  54. package/bin/lib/database.sh +357 -305
  55. package/bin/lib/frontmatter.js +106 -0
  56. package/bin/lib/heimdall-setup.js +113 -0
  57. package/bin/lib/heimdall.js +265 -0
  58. package/bin/lib/json.sh +264 -258
  59. package/bin/lib/terminal.js +452 -446
  60. package/bin/lib/util.sh +126 -126
  61. package/bin/lib/vcs.js +349 -349
  62. package/config/agent-manifest.yaml +237 -243
  63. package/config/agents.json +207 -132
  64. package/config/task-template.md +159 -87
  65. package/config/task-types.yaml +111 -106
  66. package/config/templates/handoff-template.md +40 -0
  67. package/context/agent-overrides/README.md +41 -0
  68. package/context/architecture.md +42 -0
  69. package/context/modern-conventions.md +129 -129
  70. package/context/project-context-template.md +122 -122
  71. package/docs/agents.md +473 -409
  72. package/docs/architecture.md +194 -162
  73. package/docs/commands.md +451 -388
  74. package/docs/security.md +195 -144
  75. package/package.json +77 -50
  76. package/.claude/settings.local.json +0 -33
  77. package/agents/forge-master/capabilities.md +0 -144
  78. package/agents/forge-master/context-template.md +0 -128
  79. package/agents/forge-master/personality.md +0 -138
  80. package/agents/sentinel/personality.md +0 -194
  81. package/context/forge-state.yaml +0 -19
  82. package/docs/TODO.md +0 -150
  83. package/docs/getting-started.md +0 -243
  84. package/docs/npm-publishing.md +0 -95
  85. package/docs/workflows/README.md +0 -32
  86. package/docs/workflows/azure-devops.md +0 -108
  87. package/docs/workflows/bitbucket.md +0 -104
  88. package/docs/workflows/git-only.md +0 -130
  89. package/docs/workflows/gitea.md +0 -168
  90. package/docs/workflows/github.md +0 -103
  91. package/docs/workflows/gitlab.md +0 -105
  92. package/docs/workflows.md +0 -454
  93. package/tasks/completed/ARCH-001-duplicate-agent-config.md +0 -121
  94. package/tasks/completed/ARCH-002-mixed-bash-node-implementation.md +0 -88
  95. package/tasks/completed/ARCH-003-worker-loop-hook-duplication.md +0 -77
  96. package/tasks/completed/ARCH-009-test-organization.md +0 -78
  97. package/tasks/completed/ARCH-011-jq-vs-nodejs-json.md +0 -94
  98. package/tasks/completed/ARCH-012-tmp-files-in-root.md +0 -71
  99. package/tasks/completed/ARCH-013-exit-code-constants.md +0 -65
  100. package/tasks/completed/ARCH-014-sed-incompatibility.md +0 -96
  101. package/tasks/completed/ARCH-015-docs-todo-tracking.md +0 -83
  102. package/tasks/completed/CLEAN-001.md +0 -38
  103. package/tasks/completed/CLEAN-003.md +0 -47
  104. package/tasks/completed/CLEAN-004.md +0 -56
  105. package/tasks/completed/CLEAN-005.md +0 -75
  106. package/tasks/completed/CLEAN-006.md +0 -47
  107. package/tasks/completed/CLEAN-007.md +0 -34
  108. package/tasks/completed/CLEAN-008.md +0 -49
  109. package/tasks/completed/CLEAN-012.md +0 -58
  110. package/tasks/completed/CLEAN-013.md +0 -45
  111. package/tasks/completed/SEC-001-sql-injection-fix.md +0 -58
  112. package/tasks/completed/SEC-002-notification-injection-fix.md +0 -45
  113. package/tasks/completed/SEC-003-eval-injection-fix.md +0 -54
  114. package/tasks/completed/SEC-004-pid-race-condition-fix.md +0 -49
  115. package/tasks/completed/SEC-005-worker-loop-path-fix.md +0 -51
  116. package/tasks/completed/SEC-006-eval-agent-names.md +0 -55
  117. package/tasks/completed/SEC-007-spawn-escaping.md +0 -67
  118. package/tasks/pending/ARCH-004-git-bash-detection-duplication.md +0 -72
  119. package/tasks/pending/ARCH-005-missing-src-directory.md +0 -95
  120. package/tasks/pending/ARCH-006-task-template-location.md +0 -64
  121. package/tasks/pending/ARCH-007-daemon-monolith.md +0 -91
  122. package/tasks/pending/ARCH-008-forge-master-vs-hub.md +0 -81
  123. package/tasks/pending/ARCH-010-missing-index-files.md +0 -84
  124. package/tasks/pending/CLEAN-002.md +0 -29
  125. package/tasks/pending/CLEAN-009.md +0 -31
  126. package/tasks/pending/CLEAN-010.md +0 -30
  127. package/tasks/pending/CLEAN-011.md +0 -30
  128. package/tasks/pending/CLEAN-014.md +0 -32
  129. package/tasks/review/task-001.md +0 -78
@@ -1,645 +1,661 @@
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
- "$SCRIPT_DIR/forge-daemon.sh" start
415
- else
416
- echo ""
417
- log_info "Daemon disabled"
418
- echo " You can start it later with: forge daemon start"
419
- fi
420
- }
421
-
422
- # =============================================================================
423
- # STEP 7b: Configure Worker Loop (Persistent Mode)
424
- # =============================================================================
425
-
426
- configure_worker_loop() {
427
- echo ""
428
- echo "Worker Loop Configuration"
429
- echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
430
- echo ""
431
- echo "Worker Loop keeps agents running continuously."
432
- echo "When a worker finishes a task, it automatically checks for new work"
433
- echo "instead of exiting. Great for longer coding sessions."
434
- echo ""
435
-
436
- local enable_worker_loop="n"
437
-
438
- if [[ "$NON_INTERACTIVE" == "false" ]]; then
439
- read -p "Enable persistent worker mode? (y/N): " choice
440
- if [[ "$choice" == "y" || "$choice" == "Y" ]]; then
441
- enable_worker_loop="y"
442
- fi
443
- fi
444
-
445
- # Update config with worker loop preference
446
- local config_file="$FORGE_ROOT/.forge/config.json"
447
- if [[ -f "$config_file" ]]; then
448
- json_write_bool "$config_file" "worker_loop_enabled" "$( [[ "$enable_worker_loop" == "y" ]] && echo "true" || echo "false" )"
449
- fi
450
-
451
- if [[ "$enable_worker_loop" == "y" ]]; then
452
- echo ""
453
- log_success "Worker Loop enabled"
454
- echo " Workers will keep running and check for new tasks"
455
- else
456
- echo ""
457
- log_info "Worker Loop disabled"
458
- echo " Workers will exit after completing their tasks"
459
- echo " Enable later with: forge config worker-loop on"
460
- fi
461
- }
462
-
463
- # =============================================================================
464
- # STEP 8: Install Slash Command
465
- # =============================================================================
466
-
467
- install_slash_command() {
468
- echo ""
469
- echo "Installing /forge slash command..."
470
-
471
- # Parent project directory (one level up from _vibe-forge)
472
- local parent_dir
473
- parent_dir="$(dirname "$FORGE_ROOT")"
474
-
475
- local target_dir="$parent_dir/.claude/commands"
476
- local source_file="$FORGE_ROOT/.claude/commands/forge.md"
477
-
478
- # Create .claude/commands in parent project if it doesn't exist
479
- mkdir -p "$target_dir"
480
-
481
- # Copy the forge command
482
- if [[ -f "$source_file" ]]; then
483
- cp "$source_file" "$target_dir/forge.md"
484
- log_success "Slash command installed: $target_dir/forge.md"
485
- echo " Use /forge in Claude Code to access Vibe Forge"
486
- else
487
- log_warn "Could not find forge command template"
488
- echo " You may need to manually copy .claude/commands/forge.md"
489
- fi
490
- }
491
-
492
- # =============================================================================
493
- # STEP 9: Create Project Context
494
- # =============================================================================
495
-
496
- detect_project_info() {
497
- # Try to detect project name
498
- PROJECT_NAME=$(basename "$PWD")
499
-
500
- # Try to detect tech stack
501
- TECH_STACK=""
502
-
503
- if [[ -f "package.json" ]]; then
504
- TECH_STACK="Node.js"
505
- # Check for framework hints
506
- if grep -q '"react"' package.json 2>/dev/null; then
507
- TECH_STACK="React"
508
- elif grep -q '"vue"' package.json 2>/dev/null; then
509
- TECH_STACK="Vue"
510
- elif grep -q '"next"' package.json 2>/dev/null; then
511
- TECH_STACK="Next.js"
512
- elif grep -q '"svelte"' package.json 2>/dev/null; then
513
- TECH_STACK="Svelte"
514
- fi
515
- elif [[ -f "Cargo.toml" ]]; then
516
- TECH_STACK="Rust"
517
- elif [[ -f "go.mod" ]]; then
518
- TECH_STACK="Go"
519
- elif [[ -f "requirements.txt" ]] || [[ -f "pyproject.toml" ]]; then
520
- TECH_STACK="Python"
521
- elif [[ -f "pom.xml" ]] || [[ -f "build.gradle" ]]; then
522
- TECH_STACK="Java"
523
- elif [[ -f "*.csproj" ]] || [[ -f "*.sln" ]]; then
524
- TECH_STACK="C#/.NET"
525
- fi
526
- }
527
-
528
- create_project_context() {
529
- echo ""
530
- echo "Project Context Setup"
531
- echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
532
-
533
- detect_project_info
534
-
535
- local context_dir="$PWD/context"
536
- local context_file="$context_dir/project-context.md"
537
- local template_file="$FORGE_ROOT/context/project-context-template.md"
538
-
539
- mkdir -p "$context_dir"
540
-
541
- # Check if context already exists
542
- if [[ -f "$context_file" ]]; then
543
- log_info "Project context already exists"
544
- echo " $context_file"
545
- return 0
546
- fi
547
-
548
- echo ""
549
- log_info "Detected project: $PROJECT_NAME"
550
- if [[ -n "$TECH_STACK" ]]; then
551
- log_info "Detected stack: $TECH_STACK"
552
- fi
553
- echo ""
554
-
555
- if [[ "$NON_INTERACTIVE" == "false" ]]; then
556
- # Ask for project description
557
- read -p "Brief project description (or Enter to skip): " PROJECT_DESC
558
- fi
559
-
560
- # Create project context from template or generate minimal one
561
- if [[ -f "$template_file" ]]; then
562
- cp "$template_file" "$context_file"
563
-
564
- # Replace placeholders using cross-platform sed
565
- sed_inplace "s/\[Project Name\]/$PROJECT_NAME/g" "$context_file"
566
- sed_inplace "s/\[Your Name\]/Developer/g" "$context_file"
567
-
568
- if [[ -n "$TECH_STACK" ]]; then
569
- sed_inplace "s/\[e.g., React, Node.js, PostgreSQL\]/$TECH_STACK/g" "$context_file"
570
- fi
571
-
572
- if [[ -n "$PROJECT_DESC" ]]; then
573
- sed_inplace "s/\[Brief description of the project\]/$PROJECT_DESC/g" "$context_file"
574
- fi
575
- else
576
- # Generate minimal context
577
- cat > "$context_file" << EOF
578
- # Project Context
579
-
580
- ## Project: $PROJECT_NAME
581
-
582
- ${PROJECT_DESC:-A software project managed with Vibe Forge.}
583
-
584
- ## Tech Stack
585
- ${TECH_STACK:-To be determined}
586
-
587
- ## Key Patterns
588
- - Follow existing code conventions
589
- - Write tests for new features
590
- - Document public APIs
591
-
592
- ## Notes
593
- Edit this file to add project-specific context for the AI agents.
594
- EOF
595
- fi
596
-
597
- log_success "Project context created: $context_file"
598
- echo " Edit this file to add more project details."
599
- }
600
-
601
- # =============================================================================
602
- # STEP 10: Setup Complete
603
- # =============================================================================
604
-
605
- setup_complete() {
606
- echo ""
607
- log_header "🔥 Vibe Forge initialized!"
608
- echo ""
609
- echo "Ready to start! Open Claude Code in this project and run:"
610
- echo ""
611
- log_info "/forge Start the Planning Hub"
612
- log_info "/forge status Show status dashboard"
613
- log_info "/forge spawn anvil Spawn a worker agent"
614
- log_info "/forge help See all commands"
615
- echo ""
616
- echo "Optional: Edit context/project-context.md to add more details."
617
- echo ""
618
- }
619
-
620
- # =============================================================================
621
- # Main
622
- # =============================================================================
623
-
624
- main() {
625
- detect_platform
626
- find_git_bash
627
- check_claude
628
- create_config
629
- configure_vcs
630
-
631
- if validate_setup; then
632
- configure_terminal
633
- configure_daemon
634
- configure_worker_loop
635
- install_slash_command
636
- create_project_context
637
- setup_complete
638
- else
639
- echo ""
640
- log_error "Setup incomplete. Please check the errors above."
641
- exit $EXIT_CONFIG_ERROR
642
- fi
643
- }
644
-
645
- 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 -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 "$@"