specweave 1.0.511 → 1.0.512

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 (59) hide show
  1. package/dist/src/adapters/claude/README.md +2 -2
  2. package/dist/src/adapters/cursor/README.md +2 -2
  3. package/dist/src/adapters/generic/README.md +2 -2
  4. package/package.json +1 -1
  5. package/plugins/specweave/hooks/lib/common-setup.sh +1 -1
  6. package/plugins/specweave/hooks/lib/hook-errors.sh +2 -2
  7. package/plugins/specweave/hooks/lib/scheduler-startup.sh +3 -3
  8. package/plugins/specweave/hooks/lib/update-active-increment.sh +4 -4
  9. package/plugins/specweave/hooks/lib/update-status-line.sh +4 -4
  10. package/plugins/specweave/hooks/lib/validate-spec-status.sh +2 -2
  11. package/plugins/specweave/hooks/pre-compact.sh +2 -2
  12. package/plugins/specweave/hooks/startup-health-check.sh +1 -1
  13. package/plugins/specweave/hooks/stop-auto-v5.sh +3 -3
  14. package/plugins/specweave/hooks/stop-reflect.sh +3 -3
  15. package/plugins/specweave/hooks/stop-sync.sh +3 -3
  16. package/plugins/specweave/hooks/universal/fail-fast-wrapper.sh +2 -2
  17. package/plugins/specweave/hooks/user-prompt-submit.sh +1 -1
  18. package/plugins/specweave/hooks/v2/detectors/lifecycle-detector.sh +2 -2
  19. package/plugins/specweave/hooks/v2/detectors/us-completion-detector.sh +2 -2
  20. package/plugins/specweave/hooks/v2/dispatchers/post-tool-use-analytics.sh +2 -2
  21. package/plugins/specweave/hooks/v2/dispatchers/post-tool-use.sh +2 -2
  22. package/plugins/specweave/hooks/v2/dispatchers/pre-tool-use.sh +2 -2
  23. package/plugins/specweave/hooks/v2/dispatchers/session-start.sh +2 -2
  24. package/plugins/specweave/hooks/v2/guards/increment-existence-guard.sh +1 -1
  25. package/plugins/specweave/hooks/v2/guards/status-completion-guard.sh +1 -1
  26. package/plugins/specweave/hooks/v2/guards/task-ac-sync-guard.sh +2 -2
  27. package/plugins/specweave/hooks/v2/handlers/ac-sync-dispatcher.sh +1 -1
  28. package/plugins/specweave/hooks/v2/handlers/ac-validation-handler.sh +2 -2
  29. package/plugins/specweave/hooks/v2/handlers/github-sync-handler.sh +2 -2
  30. package/plugins/specweave/hooks/v2/handlers/living-docs-handler.sh +2 -2
  31. package/plugins/specweave/hooks/v2/handlers/living-specs-handler.sh +2 -2
  32. package/plugins/specweave/hooks/v2/handlers/project-bridge-handler.sh +2 -2
  33. package/plugins/specweave/hooks/v2/handlers/status-line-handler.sh +2 -2
  34. package/plugins/specweave/hooks/v2/handlers/status-update.sh +2 -2
  35. package/plugins/specweave/hooks/v2/handlers/universal-auto-create-dispatcher.sh +1 -1
  36. package/plugins/specweave/hooks/v2/integrations/ado-post-task.sh +1 -1
  37. package/plugins/specweave/hooks/v2/integrations/github-auto-create-handler.sh +2 -2
  38. package/plugins/specweave/hooks/v2/integrations/github-post-task.sh +1 -1
  39. package/plugins/specweave/hooks/v2/integrations/jira-post-task.sh +1 -1
  40. package/plugins/specweave/hooks/v2/queue/enqueue.sh +2 -2
  41. package/plugins/specweave/hooks/v2/session-end.sh +1 -1
  42. package/plugins/specweave/lib/external-sync/hooks-common.sh +2 -2
  43. package/plugins/specweave/scripts/analyze-standards.sh +2 -2
  44. package/plugins/specweave/scripts/cleanup-legacy-state.sh +2 -2
  45. package/plugins/specweave/scripts/cleanup-state.sh +2 -2
  46. package/plugins/specweave/scripts/heartbeat.sh +2 -2
  47. package/plugins/specweave/scripts/lsp-check.sh +1 -1
  48. package/plugins/specweave/scripts/lsp-warmup.sh +1 -1
  49. package/plugins/specweave/scripts/read-analytics.sh +2 -2
  50. package/plugins/specweave/scripts/read-costs.sh +2 -2
  51. package/plugins/specweave/scripts/read-grill-context.sh +2 -2
  52. package/plugins/specweave/scripts/read-jobs.sh +2 -2
  53. package/plugins/specweave/scripts/read-progress.sh +2 -2
  54. package/plugins/specweave/scripts/read-status.sh +2 -2
  55. package/plugins/specweave/scripts/read-workflow.sh +2 -2
  56. package/plugins/specweave/scripts/rebuild-dashboard-cache.sh +2 -2
  57. package/plugins/specweave/scripts/track-analytics.sh +2 -2
  58. package/plugins/specweave/scripts/update-dashboard-cache.sh +2 -2
  59. package/plugins/specweave/skills/team-lead/SKILL.md +17 -15
@@ -193,12 +193,12 @@ Skills are invoked explicitly via Skill tool or auto-activate based on keywords:
193
193
  ```typescript
194
194
  // Explicit invocation
195
195
  await Skill({
196
- skill: "frontend:architect",
196
+ skill: "sw:architect",
197
197
  args: "Design React component architecture for dashboard"
198
198
  });
199
199
 
200
200
  // Or via slash command
201
- /frontend:architect Design React component architecture
201
+ /sw:architect Design React component architecture
202
202
  ```
203
203
 
204
204
  Skills like PM and Architect auto-activate based on keywords. For explicit invocation, use the Skill tool.
@@ -105,8 +105,8 @@ User: "create increment for auth"
105
105
 
106
106
  **Claude Code (automatic)**:
107
107
  ```typescript
108
- Skill({ skill: "frontend:architect", args: "design components" })
109
- Frontend skill activates with specialized guidance
108
+ Skill({ skill: "sw:architect", args: "design components" })
109
+ Architect skill activates with specialized guidance
110
110
  ```
111
111
 
112
112
  **Note**: In Claude Code, PM/Architect are SKILLS that auto-activate on keywords. For explicit invocation, use the Skill tool.
@@ -148,8 +148,8 @@ You manually execute the entire workflow!
148
148
 
149
149
  **Claude Code (automatic)**:
150
150
  ```typescript
151
- Skill({ skill: "frontend:architect", args: "design components" })
152
- Frontend skill activates and provides specialized guidance
151
+ Skill({ skill: "sw:architect", args: "design components" })
152
+ Architect skill activates and provides specialized guidance
153
153
  ```
154
154
 
155
155
  **Note**: In Claude Code, PM/Architect are SKILLS that auto-activate on keywords. For explicit invocation, use the Skill tool.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "specweave",
3
- "version": "1.0.511",
3
+ "version": "1.0.512",
4
4
  "description": "100+ domain-expert AI skills — PM, Architect, Frontend, QA, Security and more. Skills learn your team's patterns permanently. Spec-first planning, autonomous execution, multi-agent teams, synced to GitHub/JIRA. Claude Code, Cursor, Copilot & more.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -17,7 +17,7 @@ set +e # NEVER use set -e in hooks
17
17
  find_project_root() {
18
18
  local dir="${1:-$(pwd)}"
19
19
  while [[ "$dir" != "/" ]]; do
20
- if [[ -d "$dir/.specweave" ]]; then
20
+ if [[ -f "$dir/.specweave/config.json" ]]; then
21
21
  echo "$dir"
22
22
  return 0
23
23
  fi
@@ -26,7 +26,7 @@ HOOK_ERRORS_VERSION="1.0.0"
26
26
  _find_hook_project_root() {
27
27
  local dir="${1:-$PWD}"
28
28
  while [[ "$dir" != "/" ]]; do
29
- if [[ -d "$dir/.specweave" ]]; then
29
+ if [[ -f "$dir/.specweave/config.json" ]]; then
30
30
  echo "$dir"
31
31
  return 0
32
32
  fi
@@ -39,7 +39,7 @@ _find_hook_project_root() {
39
39
  _HOOK_PROJECT_ROOT=$(_find_hook_project_root)
40
40
 
41
41
  # Exit early if not a SpecWeave project (prevents .specweave pollution)
42
- if [[ -z "$_HOOK_PROJECT_ROOT" ]] || [[ ! -d "$_HOOK_PROJECT_ROOT/.specweave" ]]; then
42
+ if [[ -z "$_HOOK_PROJECT_ROOT" ]] || [[ ! -f "$_HOOK_PROJECT_ROOT/.specweave/config.json" ]]; then
43
43
  # Define no-op functions so sourcing scripts don't fail
44
44
  log_hook_warning() { :; }
45
45
  log_hook_error() { :; }
@@ -15,12 +15,12 @@ set +e
15
15
 
16
16
  # Find project root
17
17
  PROJECT_ROOT="$PWD"
18
- while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -d "$PROJECT_ROOT/.specweave" ]]; do
18
+ while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]]; do
19
19
  PROJECT_ROOT=$(dirname "$PROJECT_ROOT")
20
20
  done
21
21
 
22
- # Exit if no .specweave directory
23
- [[ ! -d "$PROJECT_ROOT/.specweave" ]] && exit 0
22
+ # Exit if no .specweave/config.json
23
+ [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]] && exit 0
24
24
 
25
25
  # Source resolve-package.sh for dynamic specweave path resolution
26
26
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
@@ -14,17 +14,17 @@ set +e
14
14
  # ============================================================================
15
15
  # PROJECT ROOT DETECTION (CRITICAL - must NOT fallback to pwd!)
16
16
  # ============================================================================
17
- if [[ -n "$SPECWEAVE_PROJECT_ROOT" ]] && [[ -d "$SPECWEAVE_PROJECT_ROOT/.specweave" ]]; then
17
+ if [[ -n "$SPECWEAVE_PROJECT_ROOT" ]] && [[ -f "$SPECWEAVE_PROJECT_ROOT/.specweave/config.json" ]]; then
18
18
  PROJECT_ROOT="$SPECWEAVE_PROJECT_ROOT"
19
19
  else
20
20
  PROJECT_ROOT="$PWD"
21
- while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -d "$PROJECT_ROOT/.specweave" ]]; do
21
+ while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]]; do
22
22
  PROJECT_ROOT=$(dirname "$PROJECT_ROOT")
23
23
  done
24
24
  fi
25
25
 
26
- # No .specweave? Exit BEFORE any mkdir (prevents .specweave pollution)
27
- [[ ! -d "$PROJECT_ROOT/.specweave" ]] && exit 0
26
+ # No .specweave/config.json? Exit BEFORE any mkdir (prevents .specweave pollution)
27
+ [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]] && exit 0
28
28
 
29
29
  STATE_DIR="$PROJECT_ROOT/.specweave/state"
30
30
  ACTIVE_FILE="$STATE_DIR/active-increment.json"
@@ -21,17 +21,17 @@ set +e
21
21
  # PROJECT ROOT (FAST - cached in env if available)
22
22
  # CRITICAL: Must NOT fallback to pwd (prevents .specweave pollution)
23
23
  # ============================================================================
24
- if [[ -n "$SPECWEAVE_PROJECT_ROOT" ]] && [[ -d "$SPECWEAVE_PROJECT_ROOT/.specweave" ]]; then
24
+ if [[ -n "$SPECWEAVE_PROJECT_ROOT" ]] && [[ -f "$SPECWEAVE_PROJECT_ROOT/.specweave/config.json" ]]; then
25
25
  PROJECT_ROOT="$SPECWEAVE_PROJECT_ROOT"
26
26
  else
27
27
  PROJECT_ROOT="$PWD"
28
- while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -d "$PROJECT_ROOT/.specweave" ]]; do
28
+ while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]]; do
29
29
  PROJECT_ROOT=$(dirname "$PROJECT_ROOT")
30
30
  done
31
31
  fi
32
32
 
33
- # No .specweave? Exit immediately BEFORE any variable init (prevents pollution)
34
- [[ ! -d "$PROJECT_ROOT/.specweave" ]] && exit 0
33
+ # No .specweave/config.json? Exit immediately BEFORE any variable init (prevents pollution)
34
+ [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]] && exit 0
35
35
 
36
36
  # ============================================================================
37
37
  # ULTRA-FAST EXITS
@@ -22,7 +22,7 @@ set +e # EMERGENCY FIX: Changed from set -euo pipefail to prevent Claude Code c
22
22
  find_project_root() {
23
23
  local dir="$PWD"
24
24
  while [[ "$dir" != "/" ]]; do
25
- if [[ -d "$dir/.specweave" ]]; then
25
+ if [[ -f "$dir/.specweave/config.json" ]]; then
26
26
  echo "$dir"
27
27
  return 0
28
28
  fi
@@ -35,7 +35,7 @@ find_project_root() {
35
35
  PROJECT_ROOT=$(find_project_root)
36
36
 
37
37
  # Exit early if not a SpecWeave project (prevents .specweave pollution)
38
- if [[ -z "$PROJECT_ROOT" ]] || [[ ! -d "$PROJECT_ROOT/.specweave" ]]; then
38
+ if [[ -z "$PROJECT_ROOT" ]] || [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]]; then
39
39
  echo "Not a SpecWeave project - skipping validation"
40
40
  exit 0
41
41
  fi
@@ -11,10 +11,10 @@ set +e
11
11
 
12
12
  # Find project root
13
13
  PROJECT_ROOT="$PWD"
14
- while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -d "$PROJECT_ROOT/.specweave" ]]; do
14
+ while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]]; do
15
15
  PROJECT_ROOT=$(dirname "$PROJECT_ROOT")
16
16
  done
17
- [[ ! -d "$PROJECT_ROOT/.specweave" ]] && echo '{"continue":true}' && exit 0
17
+ [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]] && echo '{"continue":true}' && exit 0
18
18
 
19
19
  STATE_DIR="$PROJECT_ROOT/.specweave/state"
20
20
  PRESSURE_FILE="$STATE_DIR/context-pressure.json"
@@ -9,7 +9,7 @@
9
9
  # Detect project root via walk-up
10
10
  _DIR="$PWD"
11
11
  _LIMIT=0
12
- while [ "$_DIR" != "/" ] && [ ! -d "$_DIR/.specweave" ] && [ $_LIMIT -lt 50 ]; do
12
+ while [ "$_DIR" != "/" ] && [ ! -f "$_DIR/.specweave/config.json" ] && [ $_LIMIT -lt 50 ]; do
13
13
  _DIR=$(dirname "$_DIR")
14
14
  _LIMIT=$((_LIMIT + 1))
15
15
  done
@@ -18,17 +18,17 @@ _get_duration_ms() {
18
18
  [ -z "${__STOP_AUTO_V5_SOURCED:-}" ] && cat > /dev/null
19
19
 
20
20
  # Project root detection (walk up to find .specweave/ — prevents pollution of subdirectories)
21
- if [[ -n "${PROJECT_ROOT:-}" ]] && [[ -d "$PROJECT_ROOT/.specweave" ]]; then
21
+ if [[ -n "${PROJECT_ROOT:-}" ]] && [[ -f "$PROJECT_ROOT/.specweave/config.json" ]]; then
22
22
  : # env var already set and valid
23
23
  else
24
24
  PROJECT_ROOT="$PWD"
25
- while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -d "$PROJECT_ROOT/.specweave" ]]; do
25
+ while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]]; do
26
26
  PROJECT_ROOT=$(dirname "$PROJECT_ROOT")
27
27
  done
28
28
  fi
29
29
 
30
30
  # Not a SpecWeave project — approve and exit (MUST be before any mkdir)
31
- if [[ ! -d "$PROJECT_ROOT/.specweave" ]]; then
31
+ if [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]]; then
32
32
  echo '{"decision":"approve"}'
33
33
  exit 0
34
34
  fi
@@ -26,17 +26,17 @@ INPUT=$(cat)
26
26
  TRANSCRIPT_PATH=$(echo "$INPUT" | jq -r '.transcript_path // ""' 2>/dev/null)
27
27
 
28
28
  # Project root detection (walk up to find .specweave/ — prevents pollution of subdirectories)
29
- if [[ -n "${PROJECT_ROOT:-}" ]] && [[ -d "$PROJECT_ROOT/.specweave" ]]; then
29
+ if [[ -n "${PROJECT_ROOT:-}" ]] && [[ -f "$PROJECT_ROOT/.specweave/config.json" ]]; then
30
30
  : # env var already set and valid
31
31
  else
32
32
  PROJECT_ROOT="$PWD"
33
- while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -d "$PROJECT_ROOT/.specweave" ]]; do
33
+ while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]]; do
34
34
  PROJECT_ROOT=$(dirname "$PROJECT_ROOT")
35
35
  done
36
36
  fi
37
37
 
38
38
  # Not a SpecWeave project — approve and exit (MUST be before any mkdir)
39
- if [[ ! -d "$PROJECT_ROOT/.specweave" ]]; then
39
+ if [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]]; then
40
40
  echo '{"decision":"approve"}'
41
41
  exit 0
42
42
  fi
@@ -22,11 +22,11 @@ set +e # Never fail
22
22
  INPUT=$(cat)
23
23
 
24
24
  # Project root detection (walk up to find .specweave/ — prevents pollution of subdirectories)
25
- if [[ -n "${PROJECT_ROOT:-}" ]] && [[ -d "$PROJECT_ROOT/.specweave" ]]; then
25
+ if [[ -n "${PROJECT_ROOT:-}" ]] && [[ -f "$PROJECT_ROOT/.specweave/config.json" ]]; then
26
26
  : # env var already set and valid
27
27
  else
28
28
  PROJECT_ROOT="$PWD"
29
- while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -d "$PROJECT_ROOT/.specweave" ]]; do
29
+ while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]]; do
30
30
  PROJECT_ROOT=$(dirname "$PROJECT_ROOT")
31
31
  done
32
32
  fi
@@ -38,7 +38,7 @@ silent_approve() {
38
38
  }
39
39
 
40
40
  # Not a SpecWeave project — approve and exit (MUST be before any mkdir)
41
- [ ! -d "$PROJECT_ROOT/.specweave" ] && silent_approve
41
+ [ ! -f "$PROJECT_ROOT/.specweave/config.json" ] && silent_approve
42
42
 
43
43
  STATE_DIR="$PROJECT_ROOT/.specweave/state"
44
44
  QUEUE_DIR="$STATE_DIR/event-queue"
@@ -71,7 +71,7 @@ esac
71
71
  find_project_root() {
72
72
  local dir="$PWD"
73
73
  while [[ "$dir" != "/" ]]; do
74
- if [[ -d "$dir/.specweave" ]]; then
74
+ if [[ -f "$dir/.specweave/config.json" ]]; then
75
75
  echo "$dir"
76
76
  return 0
77
77
  fi
@@ -84,7 +84,7 @@ find_project_root() {
84
84
  PROJECT_ROOT=$(find_project_root)
85
85
 
86
86
  # Exit early if not a SpecWeave project (prevents .specweave pollution)
87
- if [[ -z "$PROJECT_ROOT" ]] || [[ ! -d "$PROJECT_ROOT/.specweave" ]]; then
87
+ if [[ -z "$PROJECT_ROOT" ]] || [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]]; then
88
88
  # Not a SpecWeave project - output success JSON and exit
89
89
  # UserPromptSubmit and Stop hooks need {"decision":"approve"}, others need {"continue":true}
90
90
  if [[ "$script_name" == stop-* ]] || [[ "$script_name" == user-prompt-submit* ]]; then
@@ -1675,7 +1675,7 @@ TDD_SOURCE=""
1675
1675
  TDD_MSG=""
1676
1676
 
1677
1677
  # Only check TDD if we're in a SpecWeave project (use resolved project root)
1678
- if [[ -n "$SW_PROJECT_ROOT" ]] && [[ -d "$SW_PROJECT_ROOT/.specweave" ]]; then
1678
+ if [[ -n "$SW_PROJECT_ROOT" ]] && [[ -f "$SW_PROJECT_ROOT/.specweave/config.json" ]]; then
1679
1679
 
1680
1680
  # Step 1: Check global config (LOWEST priority)
1681
1681
  if [[ -f "$SW_PROJECT_ROOT/.specweave/config.json" ]] && command -v jq >/dev/null 2>&1; then
@@ -15,10 +15,10 @@ INC_ID="${1:-}"
15
15
 
16
16
  # Find project root
17
17
  PROJECT_ROOT="$PWD"
18
- while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -d "$PROJECT_ROOT/.specweave" ]]; do
18
+ while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]]; do
19
19
  PROJECT_ROOT=$(dirname "$PROJECT_ROOT")
20
20
  done
21
- [[ ! -d "$PROJECT_ROOT/.specweave" ]] && exit 0
21
+ [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]] && exit 0
22
22
 
23
23
  STATE_DIR="$PROJECT_ROOT/.specweave/state"
24
24
  PREV_STATUS_FILE="$STATE_DIR/.prev-status-$INC_ID"
@@ -33,10 +33,10 @@ INC_ID="${1:-}"
33
33
 
34
34
  # Find project root
35
35
  PROJECT_ROOT="$PWD"
36
- while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -d "$PROJECT_ROOT/.specweave" ]]; do
36
+ while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]]; do
37
37
  PROJECT_ROOT=$(dirname "$PROJECT_ROOT")
38
38
  done
39
- [[ ! -d "$PROJECT_ROOT/.specweave" ]] && exit 0
39
+ [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]] && exit 0
40
40
 
41
41
  STATE_DIR="$PROJECT_ROOT/.specweave/state"
42
42
  TASKS_FILE="$PROJECT_ROOT/.specweave/increments/$INC_ID/tasks.md"
@@ -12,10 +12,10 @@ set +e
12
12
 
13
13
  # Project root detection
14
14
  PROJECT_ROOT="$PWD"
15
- while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -d "$PROJECT_ROOT/.specweave" ]]; do
15
+ while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]]; do
16
16
  PROJECT_ROOT=$(dirname "$PROJECT_ROOT")
17
17
  done
18
- [[ ! -d "$PROJECT_ROOT/.specweave" ]] && exit 0
18
+ [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]] && exit 0
19
19
 
20
20
  # Read stdin (tool result JSON)
21
21
  INPUT=""
@@ -39,10 +39,10 @@ HOOK_VERSION="1.0.148"
39
39
  # ============================================================================
40
40
 
41
41
  PROJECT_ROOT="$PWD"
42
- while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -d "$PROJECT_ROOT/.specweave" ]]; do
42
+ while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]]; do
43
43
  PROJECT_ROOT=$(dirname "$PROJECT_ROOT")
44
44
  done
45
- [[ ! -d "$PROJECT_ROOT/.specweave" ]] && exit 0
45
+ [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]] && exit 0
46
46
 
47
47
  STATE_DIR="$PROJECT_ROOT/.specweave/state"
48
48
 
@@ -22,11 +22,11 @@ INPUT=$(cat)
22
22
  # Detect project root via walk-up (cwd may not be root)
23
23
  _DIR="$PWD"
24
24
  _LIMIT=0
25
- while [[ "$_DIR" != "/" ]] && [[ ! -d "$_DIR/.specweave" ]] && [[ $_LIMIT -lt 50 ]]; do
25
+ while [[ "$_DIR" != "/" ]] && [[ ! -f "$_DIR/.specweave/config.json" ]] && [[ $_LIMIT -lt 50 ]]; do
26
26
  _DIR=$(dirname "$_DIR")
27
27
  _LIMIT=$((_LIMIT + 1))
28
28
  done
29
- [[ ! -d "$_DIR/.specweave" ]] && echo '{"decision":"allow"}' && exit 0
29
+ [[ ! -f "$_DIR/.specweave/config.json" ]] && echo '{"decision":"allow"}' && exit 0
30
30
 
31
31
  # Fast file_path check: skip non-increment files before jq (< 5ms)
32
32
  if ! echo "$INPUT" | grep -q '"file_path".*\.specweave/increments/'; then
@@ -16,10 +16,10 @@ set +e
16
16
 
17
17
  # Find project root
18
18
  PROJECT_ROOT="$PWD"
19
- while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -d "$PROJECT_ROOT/.specweave" ]]; do
19
+ while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]]; do
20
20
  PROJECT_ROOT=$(dirname "$PROJECT_ROOT")
21
21
  done
22
- [[ ! -d "$PROJECT_ROOT/.specweave" ]] && exit 0
22
+ [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]] && exit 0
23
23
 
24
24
  # ============================================================================
25
25
  # SESSION CLEANUP: ALWAYS clear auto-mode.json (CRITICAL for session-scoped auto)
@@ -175,7 +175,7 @@ FOUND=false
175
175
  # Detect project root via walk-up
176
176
  _DIR="$PWD"
177
177
  _LIMIT=0
178
- while [[ "$_DIR" != "/" ]] && [[ ! -d "$_DIR/.specweave" ]] && [[ $_LIMIT -lt 50 ]]; do
178
+ while [[ "$_DIR" != "/" ]] && [[ ! -f "$_DIR/.specweave/config.json" ]] && [[ $_LIMIT -lt 50 ]]; do
179
179
  _DIR=$(dirname "$_DIR")
180
180
  _LIMIT=$((_LIMIT + 1))
181
181
  done
@@ -40,7 +40,7 @@ if echo "$NEW_STRING" | grep -qE '"status":\s*"completed"'; then
40
40
  # Detect project root via walk-up
41
41
  _DIR="$PWD"
42
42
  _LIMIT=0
43
- while [[ "$_DIR" != "/" ]] && [[ ! -d "$_DIR/.specweave" ]] && [[ $_LIMIT -lt 50 ]]; do
43
+ while [[ "$_DIR" != "/" ]] && [[ ! -f "$_DIR/.specweave/config.json" ]] && [[ $_LIMIT -lt 50 ]]; do
44
44
  _DIR=$(dirname "$_DIR")
45
45
  _LIMIT=$((_LIMIT + 1))
46
46
  done
@@ -37,7 +37,7 @@ HOOK_VERSION="1.0.43"
37
37
  find_project_root() {
38
38
  local dir="$PWD"
39
39
  while [[ "$dir" != "/" ]]; do
40
- if [[ -d "$dir/.specweave" ]]; then
40
+ if [[ -f "$dir/.specweave/config.json" ]]; then
41
41
  echo "$dir"
42
42
  return 0
43
43
  fi
@@ -49,7 +49,7 @@ find_project_root() {
49
49
 
50
50
  PROJECT_ROOT=$(find_project_root)
51
51
  [[ -z "$PROJECT_ROOT" ]] && exit 0
52
- [[ ! -d "$PROJECT_ROOT/.specweave" ]] && exit 0
52
+ [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]] && exit 0
53
53
 
54
54
  # ============================================================================
55
55
  # LOGGING INFRASTRUCTURE
@@ -32,7 +32,7 @@ fi
32
32
  find_project_root() {
33
33
  local dir="$1"
34
34
  while [ "$dir" != "/" ]; do
35
- if [ -d "$dir/.specweave" ]; then
35
+ if [ -f "$dir/.specweave/config.json" ]; then
36
36
  echo "$dir"
37
37
  return 0
38
38
  fi
@@ -13,10 +13,10 @@ INC_ID="${1:-}"
13
13
 
14
14
  # Find project root
15
15
  PROJECT_ROOT="$PWD"
16
- while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -d "$PROJECT_ROOT/.specweave" ]]; do
16
+ while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]]; do
17
17
  PROJECT_ROOT=$(dirname "$PROJECT_ROOT")
18
18
  done
19
- [[ ! -d "$PROJECT_ROOT/.specweave" ]] && exit 0
19
+ [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]] && exit 0
20
20
 
21
21
  INC_DIR="$PROJECT_ROOT/.specweave/increments/$INC_ID"
22
22
  TASKS_FILE="$INC_DIR/tasks.md"
@@ -42,10 +42,10 @@ fi
42
42
 
43
43
  # Find project root
44
44
  PROJECT_ROOT="$PWD"
45
- while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -d "$PROJECT_ROOT/.specweave" ]]; do
45
+ while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]]; do
46
46
  PROJECT_ROOT=$(dirname "$PROJECT_ROOT")
47
47
  done
48
- [[ ! -d "$PROJECT_ROOT/.specweave" ]] && exit 0
48
+ [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]] && exit 0
49
49
 
50
50
  CONFIG_FILE="$PROJECT_ROOT/.specweave/config.json"
51
51
  [[ ! -f "$CONFIG_FILE" ]] && exit 0
@@ -13,10 +13,10 @@ INC_ID="${1:-}"
13
13
 
14
14
  # Find project root
15
15
  PROJECT_ROOT="$PWD"
16
- while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -d "$PROJECT_ROOT/.specweave" ]]; do
16
+ while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]]; do
17
17
  PROJECT_ROOT=$(dirname "$PROJECT_ROOT")
18
18
  done
19
- [[ ! -d "$PROJECT_ROOT/.specweave" ]] && exit 0
19
+ [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]] && exit 0
20
20
 
21
21
  # Resolve specweave package location
22
22
  HANDLER_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
@@ -19,10 +19,10 @@ INC_ID="${2:-}"
19
19
 
20
20
  # Find project root
21
21
  PROJECT_ROOT="$PWD"
22
- while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -d "$PROJECT_ROOT/.specweave" ]]; do
22
+ while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]]; do
23
23
  PROJECT_ROOT=$(dirname "$PROJECT_ROOT")
24
24
  done
25
- [[ ! -d "$PROJECT_ROOT/.specweave" ]] && exit 0
25
+ [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]] && exit 0
26
26
 
27
27
  # Resolve specweave package location
28
28
  HANDLER_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
@@ -35,10 +35,10 @@ EVENT_DATA="${2:-}"
35
35
 
36
36
  # Find project root
37
37
  PROJECT_ROOT="$PWD"
38
- while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -d "$PROJECT_ROOT/.specweave" ]]; do
38
+ while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]]; do
39
39
  PROJECT_ROOT=$(dirname "$PROJECT_ROOT")
40
40
  done
41
- [[ ! -d "$PROJECT_ROOT/.specweave" ]] && exit 0
41
+ [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]] && exit 0
42
42
 
43
43
  # Resolve specweave package location
44
44
  HANDLER_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
@@ -25,10 +25,10 @@ EVENT_DATA="${2:-}"
25
25
 
26
26
  # Find project root
27
27
  PROJECT_ROOT="$PWD"
28
- while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -d "$PROJECT_ROOT/.specweave" ]]; do
28
+ while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]]; do
29
29
  PROJECT_ROOT=$(dirname "$PROJECT_ROOT")
30
30
  done
31
- [[ ! -d "$PROJECT_ROOT/.specweave" ]] && exit 0
31
+ [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]] && exit 0
32
32
 
33
33
  STATE_DIR="$PROJECT_ROOT/.specweave/state"
34
34
  CACHE_FILE="$STATE_DIR/status-line.json"
@@ -14,10 +14,10 @@ INC_ID="${1:-}"
14
14
 
15
15
  # Find project root
16
16
  PROJECT_ROOT="$PWD"
17
- while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -d "$PROJECT_ROOT/.specweave" ]]; do
17
+ while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]]; do
18
18
  PROJECT_ROOT=$(dirname "$PROJECT_ROOT")
19
19
  done
20
- [[ ! -d "$PROJECT_ROOT/.specweave" ]] && exit 0
20
+ [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]] && exit 0
21
21
 
22
22
  STATE_DIR="$PROJECT_ROOT/.specweave/state"
23
23
  CACHE_FILE="$STATE_DIR/status-line.json"
@@ -19,7 +19,7 @@ set +e # Never crash Claude Code
19
19
  find_project_root() {
20
20
  local dir="$1"
21
21
  while [ "$dir" != "/" ]; do
22
- [ -d "$dir/.specweave" ] && echo "$dir" && return 0
22
+ [ -f "$dir/.specweave/config.json" ] && echo "$dir" && return 0
23
23
  dir="$(dirname "$dir")"
24
24
  done
25
25
  return 1
@@ -28,7 +28,7 @@ fi
28
28
  find_project_root() {
29
29
  local dir="$1"
30
30
  while [ "$dir" != "/" ]; do
31
- if [ -d "$dir/.specweave" ]; then
31
+ if [ -f "$dir/.specweave/config.json" ]; then
32
32
  echo "$dir"
33
33
  return 0
34
34
  fi
@@ -26,10 +26,10 @@ INC_ID="$1"
26
26
  [[ -z "$INC_ID" ]] && exit 0
27
27
 
28
28
  PROJECT_ROOT="$PWD"
29
- while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -d "$PROJECT_ROOT/.specweave" ]]; do
29
+ while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]]; do
30
30
  PROJECT_ROOT=$(dirname "$PROJECT_ROOT")
31
31
  done
32
- [[ ! -d "$PROJECT_ROOT/.specweave" ]] && exit 0
32
+ [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]] && exit 0
33
33
 
34
34
  SPEC_PATH="$PROJECT_ROOT/.specweave/increments/$INC_ID/spec.md"
35
35
  META_PATH="$PROJECT_ROOT/.specweave/increments/$INC_ID/metadata.json"
@@ -34,7 +34,7 @@ fi
34
34
  find_project_root() {
35
35
  local dir="$1"
36
36
  while [ "$dir" != "/" ]; do
37
- if [ -d "$dir/.specweave" ]; then
37
+ if [ -f "$dir/.specweave/config.json" ]; then
38
38
  echo "$dir"
39
39
  return 0
40
40
  fi
@@ -28,7 +28,7 @@ fi
28
28
  find_project_root() {
29
29
  local dir="$1"
30
30
  while [ "$dir" != "/" ]; do
31
- if [ -d "$dir/.specweave" ]; then
31
+ if [ -f "$dir/.specweave/config.json" ]; then
32
32
  echo "$dir"
33
33
  return 0
34
34
  fi
@@ -15,10 +15,10 @@ EVENT_DATA="${2:-}"
15
15
 
16
16
  # Find project root
17
17
  PROJECT_ROOT="$PWD"
18
- while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -d "$PROJECT_ROOT/.specweave" ]]; do
18
+ while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]]; do
19
19
  PROJECT_ROOT=$(dirname "$PROJECT_ROOT")
20
20
  done
21
- [[ ! -d "$PROJECT_ROOT/.specweave" ]] && exit 0
21
+ [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]] && exit 0
22
22
 
23
23
  QUEUE_DIR="$PROJECT_ROOT/.specweave/state/event-queue"
24
24
  PENDING_FILE="$QUEUE_DIR/pending.jsonl"
@@ -56,7 +56,7 @@ SPECWEAVE_PKG="$(resolve_specweave_package "$HOOK_DIR")"
56
56
  find_specweave_root() {
57
57
  local dir="$1"
58
58
  while [[ "$dir" != "/" ]]; do
59
- if [[ -d "$dir/.specweave" ]]; then
59
+ if [[ -f "$dir/.specweave/config.json" ]]; then
60
60
  echo "$dir"
61
61
  return 0
62
62
  fi
@@ -11,7 +11,7 @@
11
11
  # PROJECT ROOT DETECTION
12
12
  # =============================================================================
13
13
 
14
- # Find project root by looking for .specweave directory
14
+ # Find project root by looking for .specweave/config.json
15
15
  # Returns: Absolute path to project root, or empty string if not found
16
16
  find_project_root() {
17
17
  local current_dir="${1:-$(pwd)}"
@@ -19,7 +19,7 @@ find_project_root() {
19
19
  local depth=0
20
20
 
21
21
  while [ "$depth" -lt "$max_depth" ]; do
22
- if [ -d "$current_dir/.specweave" ]; then
22
+ if [ -f "$current_dir/.specweave/config.json" ]; then
23
23
  echo "$current_dir"
24
24
  return 0
25
25
  fi
@@ -9,11 +9,11 @@ set -e
9
9
 
10
10
  # Detect project root (where .specweave/ is located)
11
11
  PROJECT_ROOT="$(pwd)"
12
- while [[ ! -d "$PROJECT_ROOT/.specweave" ]] && [[ "$PROJECT_ROOT" != "/" ]]; do
12
+ while [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]] && [[ "$PROJECT_ROOT" != "/" ]]; do
13
13
  PROJECT_ROOT="$(dirname "$PROJECT_ROOT")"
14
14
  done
15
15
 
16
- if [[ ! -d "$PROJECT_ROOT/.specweave" ]]; then
16
+ if [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]]; then
17
17
  echo "❌ Error: Not in a SpecWeave project (no .specweave/ directory found)"
18
18
  exit 1
19
19
  fi
@@ -16,10 +16,10 @@ set +e
16
16
 
17
17
  # Find project root
18
18
  PROJECT_ROOT="$PWD"
19
- while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -d "$PROJECT_ROOT/.specweave" ]]; do
19
+ while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]]; do
20
20
  PROJECT_ROOT=$(dirname "$PROJECT_ROOT")
21
21
  done
22
- [[ ! -d "$PROJECT_ROOT/.specweave" ]] && exit 0
22
+ [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]] && exit 0
23
23
 
24
24
  STATE_DIR="$PROJECT_ROOT/.specweave/state"
25
25
  QUEUE_DIR="$STATE_DIR/event-queue"
@@ -17,11 +17,11 @@
17
17
  set -e
18
18
 
19
19
  PROJECT_ROOT="$PWD"
20
- while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -d "$PROJECT_ROOT/.specweave" ]]; do
20
+ while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]]; do
21
21
  PROJECT_ROOT=$(dirname "$PROJECT_ROOT")
22
22
  done
23
23
 
24
- if [[ ! -d "$PROJECT_ROOT/.specweave" ]]; then
24
+ if [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]]; then
25
25
  echo "❌ No .specweave directory found. Are you in a SpecWeave project?"
26
26
  exit 1
27
27
  fi
@@ -22,11 +22,11 @@ set -euo pipefail
22
22
  # Project Root Detection (MUST BE FIRST)
23
23
  # ============================================================================
24
24
 
25
- # Find project root by searching upward for .specweave/ directory
25
+ # Find project root by searching upward for .specweave/config.json
26
26
  find_specweave_root() {
27
27
  local dir="$1"
28
28
  while [[ "$dir" != "/" ]]; do
29
- if [[ -d "$dir/.specweave" ]]; then
29
+ if [[ -f "$dir/.specweave/config.json" ]]; then
30
30
  echo "$dir"
31
31
  return 0
32
32
  fi
@@ -31,7 +31,7 @@ if [ -n "${ENABLE_LSP_TOOL:-}" ]; then
31
31
  LSP_ENV_READY="true"
32
32
  fi
33
33
 
34
- if [ -z "$PROJECT_ROOT" ] || [ ! -d "$PROJECT_ROOT/.specweave" ]; then
34
+ if [ -z "$PROJECT_ROOT" ] || [ ! -f "$PROJECT_ROOT/.specweave/config.json" ]; then
35
35
  exit 0 # Not a SpecWeave project
36
36
  fi
37
37
 
@@ -22,7 +22,7 @@ PROJECT_ROOT="$1"
22
22
  MODE="${2:-background}" # "background" (daemon) or "foreground" (one-shot)
23
23
 
24
24
  # Validate project root
25
- if [ -z "$PROJECT_ROOT" ] || [ ! -d "$PROJECT_ROOT/.specweave" ]; then
25
+ if [ -z "$PROJECT_ROOT" ] || [ ! -f "$PROJECT_ROOT/.specweave/config.json" ]; then
26
26
  exit 0 # Not a SpecWeave project
27
27
  fi
28
28
 
@@ -17,11 +17,11 @@ set +e
17
17
 
18
18
  # Find project root
19
19
  PROJECT_ROOT="$PWD"
20
- while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -d "$PROJECT_ROOT/.specweave" ]]; do
20
+ while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]]; do
21
21
  PROJECT_ROOT=$(dirname "$PROJECT_ROOT")
22
22
  done
23
23
 
24
- if [[ ! -d "$PROJECT_ROOT/.specweave" ]]; then
24
+ if [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]]; then
25
25
  echo "Not a SpecWeave project"
26
26
  exit 0
27
27
  fi
@@ -14,11 +14,11 @@ INCREMENT_ID="${1:-}"
14
14
 
15
15
  # Find project root
16
16
  PROJECT_ROOT="$PWD"
17
- while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -d "$PROJECT_ROOT/.specweave" ]]; do
17
+ while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]]; do
18
18
  PROJECT_ROOT=$(dirname "$PROJECT_ROOT")
19
19
  done
20
20
 
21
- if [[ ! -d "$PROJECT_ROOT/.specweave" ]]; then
21
+ if [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]]; then
22
22
  echo "No SpecWeave project found (missing .specweave/)"
23
23
  exit 0
24
24
  fi
@@ -18,11 +18,11 @@ INCREMENT_ID="${1:-}"
18
18
 
19
19
  # Find project root
20
20
  PROJECT_ROOT="$PWD"
21
- while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -d "$PROJECT_ROOT/.specweave" ]]; do
21
+ while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]]; do
22
22
  PROJECT_ROOT=$(dirname "$PROJECT_ROOT")
23
23
  done
24
24
 
25
- if [[ ! -d "$PROJECT_ROOT/.specweave" ]]; then
25
+ if [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]]; then
26
26
  echo "No SpecWeave project found (missing .specweave/)"
27
27
  exit 1
28
28
  fi
@@ -23,11 +23,11 @@ done
23
23
 
24
24
  # Find project root
25
25
  PROJECT_ROOT="$PWD"
26
- while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -d "$PROJECT_ROOT/.specweave" ]]; do
26
+ while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]]; do
27
27
  PROJECT_ROOT=$(dirname "$PROJECT_ROOT")
28
28
  done
29
29
 
30
- if [[ ! -d "$PROJECT_ROOT/.specweave" ]]; then
30
+ if [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]]; then
31
31
  echo "No SpecWeave project found (missing .specweave/)"
32
32
  exit 0
33
33
  fi
@@ -28,11 +28,11 @@ INCREMENT_ID="${1:-}"
28
28
 
29
29
  # Find project root
30
30
  PROJECT_ROOT="$PWD"
31
- while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -d "$PROJECT_ROOT/.specweave" ]]; do
31
+ while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]]; do
32
32
  PROJECT_ROOT=$(dirname "$PROJECT_ROOT")
33
33
  done
34
34
 
35
- if [[ ! -d "$PROJECT_ROOT/.specweave" ]]; then
35
+ if [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]]; then
36
36
  echo "No SpecWeave project found (missing .specweave/)"
37
37
  exit 0
38
38
  fi
@@ -12,11 +12,11 @@ set -e
12
12
 
13
13
  # Find project root
14
14
  PROJECT_ROOT="$PWD"
15
- while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -d "$PROJECT_ROOT/.specweave" ]]; do
15
+ while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]]; do
16
16
  PROJECT_ROOT=$(dirname "$PROJECT_ROOT")
17
17
  done
18
18
 
19
- if [[ ! -d "$PROJECT_ROOT/.specweave" ]]; then
19
+ if [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]]; then
20
20
  echo "No SpecWeave project found (missing .specweave/)"
21
21
  exit 0
22
22
  fi
@@ -14,11 +14,11 @@ INCREMENT_ID="${1:-}"
14
14
 
15
15
  # Find project root
16
16
  PROJECT_ROOT="$PWD"
17
- while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -d "$PROJECT_ROOT/.specweave" ]]; do
17
+ while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]]; do
18
18
  PROJECT_ROOT=$(dirname "$PROJECT_ROOT")
19
19
  done
20
20
 
21
- if [[ ! -d "$PROJECT_ROOT/.specweave" ]]; then
21
+ if [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]]; then
22
22
  echo "No SpecWeave project found (missing .specweave/)"
23
23
  exit 0
24
24
  fi
@@ -19,11 +19,11 @@ log() {
19
19
 
20
20
  # Find project root
21
21
  PROJECT_ROOT="$PWD"
22
- while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -d "$PROJECT_ROOT/.specweave" ]]; do
22
+ while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]]; do
23
23
  PROJECT_ROOT=$(dirname "$PROJECT_ROOT")
24
24
  done
25
25
 
26
- if [[ ! -d "$PROJECT_ROOT/.specweave" ]]; then
26
+ if [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]]; then
27
27
  echo "❌ No .specweave directory found"
28
28
  exit 1
29
29
  fi
@@ -13,11 +13,11 @@ set +e
13
13
 
14
14
  # Find project root
15
15
  PROJECT_ROOT="$PWD"
16
- while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -d "$PROJECT_ROOT/.specweave" ]]; do
16
+ while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]]; do
17
17
  PROJECT_ROOT=$(dirname "$PROJECT_ROOT")
18
18
  done
19
19
 
20
- [[ ! -d "$PROJECT_ROOT/.specweave" ]] && exit 0
20
+ [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]] && exit 0
21
21
 
22
22
  ANALYTICS_DIR="$PROJECT_ROOT/.specweave/state/analytics"
23
23
  EVENTS_FILE="$ANALYTICS_DIR/events.jsonl"
@@ -24,11 +24,11 @@ fi
24
24
 
25
25
  # Find project root
26
26
  PROJECT_ROOT="$PWD"
27
- while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -d "$PROJECT_ROOT/.specweave" ]]; do
27
+ while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]]; do
28
28
  PROJECT_ROOT=$(dirname "$PROJECT_ROOT")
29
29
  done
30
30
 
31
- if [[ ! -d "$PROJECT_ROOT/.specweave" ]]; then
31
+ if [[ ! -f "$PROJECT_ROOT/.specweave/config.json" ]]; then
32
32
  echo "❌ No .specweave directory found"
33
33
  exit 1
34
34
  fi
@@ -382,29 +382,31 @@ fi
382
382
 
383
383
  ### Multi-Repo Increment Placement (CRITICAL)
384
384
 
385
- **In umbrella projects with a `repositories/` folder, each agent MUST create its increment in its OWN repo's `.specweave/`:**
385
+ **When `umbrella.enabled: true` in config.json, ALL increments go in the umbrella root `.specweave/increments/` NOT in child repos.** Use the `project` field in metadata.json to route increments to the correct child repo context.
386
386
 
387
387
  ```
388
- # CORRECT: Each repo has its own .specweave/increments/
388
+ # CORRECT: All increments at umbrella root, tagged by project
389
389
  umbrella-project/
390
- ├── .specweave/config.json # Umbrella config ONLY
390
+ ├── .specweave/config.json
391
+ ├── .specweave/increments/
392
+ │ ├── 0001-domain-models/ # metadata.json: "project": "sw-ecom-domain"
393
+ │ ├── 0002-shared-types/ # metadata.json: "project": "sw-ecom-shared"
394
+ │ └── 0003-api-endpoints/ # metadata.json: "project": "sw-ecom-api"
391
395
  ├── repositories/
392
- │ ├── {ORG}/sw-ecom-domain/
393
- └── .specweave/increments/0001-domain-models/
394
- ├── {ORG}/sw-ecom-shared/
395
- │ │ └── .specweave/increments/0001-shared-types/
396
- │ └── {ORG}/sw-ecom-api/
397
- │ └── .specweave/increments/0001-api-endpoints/
398
-
399
- # WRONG: All agents dumping into umbrella root
396
+ │ ├── {ORG}/sw-ecom-domain/ # NO .specweave/increments/ here
397
+ ├── {ORG}/sw-ecom-shared/ # NO .specweave/increments/ here
398
+ └── {ORG}/sw-ecom-api/ # NO .specweave/increments/ here
399
+
400
+ # WRONG: Increments inside child repos
400
401
  umbrella-project/
401
- ├── .specweave/increments/0001-everything/ # WRONG!
402
+ ├── repositories/{ORG}/sw-ecom-domain/
403
+ │ └── .specweave/increments/0001-domain-models/ # WRONG!
402
404
  ```
403
405
 
404
406
  **Rules:**
405
- - Run `specweave init` in each repo if `.specweave/` doesn't exist
406
- - Each agent's working directory is its assigned repo inside `repositories/`
407
- - Never create `.specweave/increments/` in the umbrella root for multi-repo work
407
+ - NEVER create `.specweave/increments/` inside child repos under `repositories/`
408
+ - NEVER run `specweave init` in child repos the umbrella root owns all increments
409
+ - Each agent works on files inside its assigned repo in `repositories/`, but increments stay at umbrella root
408
410
  - Replace `{ORG}` with the actual organization discovered above
409
411
 
410
412
  ### Phase 1: Upstream Agents (Contracts First)