specweave 0.24.1 → 0.24.8

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 (173) hide show
  1. package/CLAUDE.md +106 -0
  2. package/README.md +34 -0
  3. package/dist/src/cli/commands/init.d.ts.map +1 -1
  4. package/dist/src/cli/commands/init.js +80 -41
  5. package/dist/src/cli/commands/init.js.map +1 -1
  6. package/dist/src/cli/helpers/issue-tracker/github-multi-repo.d.ts +5 -2
  7. package/dist/src/cli/helpers/issue-tracker/github-multi-repo.d.ts.map +1 -1
  8. package/dist/src/cli/helpers/issue-tracker/github-multi-repo.js +72 -6
  9. package/dist/src/cli/helpers/issue-tracker/github-multi-repo.js.map +1 -1
  10. package/dist/src/cli/helpers/issue-tracker/github.d.ts +2 -1
  11. package/dist/src/cli/helpers/issue-tracker/github.d.ts.map +1 -1
  12. package/dist/src/cli/helpers/issue-tracker/github.js +4 -3
  13. package/dist/src/cli/helpers/issue-tracker/github.js.map +1 -1
  14. package/dist/src/cli/helpers/issue-tracker/index.d.ts.map +1 -1
  15. package/dist/src/cli/helpers/issue-tracker/index.js +26 -9
  16. package/dist/src/cli/helpers/issue-tracker/index.js.map +1 -1
  17. package/dist/src/cli/helpers/issue-tracker/types.d.ts +2 -1
  18. package/dist/src/cli/helpers/issue-tracker/types.d.ts.map +1 -1
  19. package/dist/src/cli/helpers/issue-tracker/types.js.map +1 -1
  20. package/dist/src/config/types.d.ts +24 -24
  21. package/dist/src/core/config/types.d.ts +25 -0
  22. package/dist/src/core/config/types.d.ts.map +1 -1
  23. package/dist/src/core/config/types.js +6 -0
  24. package/dist/src/core/config/types.js.map +1 -1
  25. package/dist/src/core/repo-structure/git-error-handler.d.ts +37 -0
  26. package/dist/src/core/repo-structure/git-error-handler.d.ts.map +1 -0
  27. package/dist/src/core/repo-structure/git-error-handler.js +214 -0
  28. package/dist/src/core/repo-structure/git-error-handler.js.map +1 -0
  29. package/dist/src/core/repo-structure/git-provider.d.ts +183 -0
  30. package/dist/src/core/repo-structure/git-provider.d.ts.map +1 -0
  31. package/dist/src/core/repo-structure/git-provider.js +57 -0
  32. package/dist/src/core/repo-structure/git-provider.js.map +1 -0
  33. package/dist/src/core/repo-structure/github-validator.d.ts +1 -0
  34. package/dist/src/core/repo-structure/github-validator.d.ts.map +1 -1
  35. package/dist/src/core/repo-structure/github-validator.js +35 -9
  36. package/dist/src/core/repo-structure/github-validator.js.map +1 -1
  37. package/dist/src/core/repo-structure/platform-registry.d.ts +114 -0
  38. package/dist/src/core/repo-structure/platform-registry.d.ts.map +1 -0
  39. package/dist/src/core/repo-structure/platform-registry.js +195 -0
  40. package/dist/src/core/repo-structure/platform-registry.js.map +1 -0
  41. package/dist/src/core/repo-structure/prompt-consolidator.d.ts +30 -0
  42. package/dist/src/core/repo-structure/prompt-consolidator.d.ts.map +1 -1
  43. package/dist/src/core/repo-structure/prompt-consolidator.js +69 -0
  44. package/dist/src/core/repo-structure/prompt-consolidator.js.map +1 -1
  45. package/dist/src/core/repo-structure/providers/bitbucket-provider.d.ts +54 -0
  46. package/dist/src/core/repo-structure/providers/bitbucket-provider.d.ts.map +1 -0
  47. package/dist/src/core/repo-structure/providers/bitbucket-provider.js +104 -0
  48. package/dist/src/core/repo-structure/providers/bitbucket-provider.js.map +1 -0
  49. package/dist/src/core/repo-structure/providers/github-provider.d.ts +53 -0
  50. package/dist/src/core/repo-structure/providers/github-provider.d.ts.map +1 -0
  51. package/dist/src/core/repo-structure/providers/github-provider.js +239 -0
  52. package/dist/src/core/repo-structure/providers/github-provider.js.map +1 -0
  53. package/dist/src/core/repo-structure/providers/gitlab-provider.d.ts +50 -0
  54. package/dist/src/core/repo-structure/providers/gitlab-provider.d.ts.map +1 -0
  55. package/dist/src/core/repo-structure/providers/gitlab-provider.js +97 -0
  56. package/dist/src/core/repo-structure/providers/gitlab-provider.js.map +1 -0
  57. package/dist/src/core/repo-structure/providers/index.d.ts +33 -0
  58. package/dist/src/core/repo-structure/providers/index.d.ts.map +1 -0
  59. package/dist/src/core/repo-structure/providers/index.js +60 -0
  60. package/dist/src/core/repo-structure/providers/index.js.map +1 -0
  61. package/dist/src/core/repo-structure/repo-bulk-discovery.d.ts +33 -0
  62. package/dist/src/core/repo-structure/repo-bulk-discovery.d.ts.map +1 -0
  63. package/dist/src/core/repo-structure/repo-bulk-discovery.js +275 -0
  64. package/dist/src/core/repo-structure/repo-bulk-discovery.js.map +1 -0
  65. package/dist/src/core/repo-structure/repo-structure-manager.d.ts +18 -2
  66. package/dist/src/core/repo-structure/repo-structure-manager.d.ts.map +1 -1
  67. package/dist/src/core/repo-structure/repo-structure-manager.js +303 -85
  68. package/dist/src/core/repo-structure/repo-structure-manager.js.map +1 -1
  69. package/dist/src/core/repo-structure/url-generator.d.ts +80 -0
  70. package/dist/src/core/repo-structure/url-generator.d.ts.map +1 -0
  71. package/dist/src/core/repo-structure/url-generator.js +110 -0
  72. package/dist/src/core/repo-structure/url-generator.js.map +1 -0
  73. package/dist/src/init/architecture/types.d.ts +6 -6
  74. package/dist/src/utils/plugin-validator.d.ts.map +1 -1
  75. package/dist/src/utils/plugin-validator.js +15 -14
  76. package/dist/src/utils/plugin-validator.js.map +1 -1
  77. package/package.json +4 -4
  78. package/plugins/specweave/.claude-plugin/plugin.json +4 -4
  79. package/plugins/specweave/agents/pm/AGENT.md +2 -0
  80. package/plugins/specweave/commands/specweave-do.md +0 -47
  81. package/plugins/specweave/commands/specweave-increment.md +0 -82
  82. package/plugins/specweave/commands/specweave-next.md +0 -47
  83. package/plugins/specweave/hooks/post-task-completion.sh +67 -6
  84. package/plugins/specweave/hooks/pre-edit-spec.sh +11 -0
  85. package/plugins/specweave/hooks/pre-task-completion.sh +69 -2
  86. package/plugins/specweave/hooks/pre-write-spec.sh +11 -0
  87. package/plugins/specweave/skills/increment-planner/SKILL.md +124 -4
  88. package/plugins/specweave-ado/lib/ado-multi-project-sync.js +0 -1
  89. package/plugins/specweave-jira/lib/enhanced-jira-sync.js +3 -3
  90. package/plugins/specweave/agents/pm/AGENT.md.bak +0 -1893
  91. package/plugins/specweave/hooks/docs-changed.sh.backup +0 -79
  92. package/plugins/specweave/hooks/human-input-required.sh.backup +0 -75
  93. package/plugins/specweave/hooks/lib/migrate-increment-work.sh.bak +0 -245
  94. package/plugins/specweave/hooks/lib/sync-spec-content.sh.bak +0 -149
  95. package/plugins/specweave/hooks/lib/validate-spec-status.sh.bak +0 -163
  96. package/plugins/specweave/hooks/post-first-increment.sh.backup +0 -61
  97. package/plugins/specweave/hooks/post-first-increment.sh.bak +0 -61
  98. package/plugins/specweave/hooks/post-increment-change.sh.backup +0 -98
  99. package/plugins/specweave/hooks/post-increment-completion.sh.backup +0 -231
  100. package/plugins/specweave/hooks/post-increment-planning.sh.backup +0 -1048
  101. package/plugins/specweave/hooks/post-increment-status-change.sh.backup +0 -147
  102. package/plugins/specweave/hooks/post-spec-update.sh.backup +0 -158
  103. package/plugins/specweave/hooks/post-spec-update.sh.bak +0 -158
  104. package/plugins/specweave/hooks/post-user-story-complete.sh.backup +0 -179
  105. package/plugins/specweave/hooks/post-user-story-complete.sh.bak +0 -179
  106. package/plugins/specweave/hooks/pre-command-deduplication.sh.backup +0 -83
  107. package/plugins/specweave/hooks/pre-command-deduplication.sh.bak +0 -83
  108. package/plugins/specweave/hooks/pre-implementation.sh.backup +0 -67
  109. package/plugins/specweave/hooks/pre-task-completion.sh.backup +0 -194
  110. package/plugins/specweave/hooks/pre-tool-use.sh.backup +0 -133
  111. package/plugins/specweave/hooks/user-prompt-submit.sh.backup +0 -386
  112. package/plugins/specweave/hooks/user-prompt-submit.sh.bak +0 -386
  113. package/plugins/specweave/lib/hooks/auto-transition.js.bak +0 -50
  114. package/plugins/specweave/lib/hooks/auto-transition.ts.bak +0 -84
  115. package/plugins/specweave/lib/hooks/git-diff-analyzer.d.js.bak +0 -0
  116. package/plugins/specweave/lib/hooks/git-diff-analyzer.d.ts.bak +0 -89
  117. package/plugins/specweave/lib/hooks/git-diff-analyzer.js.bak +0 -142
  118. package/plugins/specweave/lib/hooks/git-diff-analyzer.ts.bak +0 -269
  119. package/plugins/specweave/lib/hooks/invoke-translator-skill.d.js.bak +0 -0
  120. package/plugins/specweave/lib/hooks/invoke-translator-skill.d.ts.bak +0 -60
  121. package/plugins/specweave/lib/hooks/invoke-translator-skill.js.bak +0 -155
  122. package/plugins/specweave/lib/hooks/invoke-translator-skill.ts.bak +0 -264
  123. package/plugins/specweave/lib/hooks/prepare-reflection-context.d.js.bak +0 -0
  124. package/plugins/specweave/lib/hooks/prepare-reflection-context.d.ts.bak +0 -42
  125. package/plugins/specweave/lib/hooks/prepare-reflection-context.js.bak +0 -110
  126. package/plugins/specweave/lib/hooks/prepare-reflection-context.ts.bak +0 -178
  127. package/plugins/specweave/lib/hooks/reflection-config-loader.d.js.bak +0 -0
  128. package/plugins/specweave/lib/hooks/reflection-config-loader.d.ts.bak +0 -45
  129. package/plugins/specweave/lib/hooks/reflection-config-loader.js.bak +0 -92
  130. package/plugins/specweave/lib/hooks/reflection-config-loader.ts.bak +0 -156
  131. package/plugins/specweave/lib/hooks/reflection-parser.d.js.bak +0 -0
  132. package/plugins/specweave/lib/hooks/reflection-parser.d.ts.bak +0 -33
  133. package/plugins/specweave/lib/hooks/reflection-parser.js.bak +0 -301
  134. package/plugins/specweave/lib/hooks/reflection-parser.ts.bak +0 -484
  135. package/plugins/specweave/lib/hooks/reflection-prompt-builder.d.js.bak +0 -0
  136. package/plugins/specweave/lib/hooks/reflection-prompt-builder.d.ts.bak +0 -56
  137. package/plugins/specweave/lib/hooks/reflection-prompt-builder.js.bak +0 -182
  138. package/plugins/specweave/lib/hooks/reflection-prompt-builder.ts.bak +0 -306
  139. package/plugins/specweave/lib/hooks/reflection-storage.d.js.bak +0 -0
  140. package/plugins/specweave/lib/hooks/reflection-storage.d.ts.bak +0 -64
  141. package/plugins/specweave/lib/hooks/reflection-storage.js.bak +0 -231
  142. package/plugins/specweave/lib/hooks/reflection-storage.ts.bak +0 -369
  143. package/plugins/specweave/lib/hooks/run-self-reflection.d.js.bak +0 -0
  144. package/plugins/specweave/lib/hooks/run-self-reflection.d.ts.bak +0 -43
  145. package/plugins/specweave/lib/hooks/run-self-reflection.js.bak +0 -132
  146. package/plugins/specweave/lib/hooks/run-self-reflection.ts.bak +0 -258
  147. package/plugins/specweave/lib/hooks/sync-cache.js.bak +0 -294
  148. package/plugins/specweave/lib/hooks/sync-living-docs.d.js.bak +0 -1
  149. package/plugins/specweave/lib/hooks/sync-living-docs.d.ts.bak +0 -27
  150. package/plugins/specweave/lib/hooks/sync-living-docs.js.bak +0 -339
  151. package/plugins/specweave/lib/hooks/sync-us-tasks.js.bak +0 -476
  152. package/plugins/specweave/lib/hooks/translate-file.d.js.bak +0 -0
  153. package/plugins/specweave/lib/hooks/translate-file.d.ts.bak +0 -59
  154. package/plugins/specweave/lib/hooks/translate-file.js.bak +0 -289
  155. package/plugins/specweave/lib/hooks/translate-file.ts.bak +0 -428
  156. package/plugins/specweave/lib/hooks/translate-living-docs.d.js.bak +0 -0
  157. package/plugins/specweave/lib/hooks/translate-living-docs.d.ts.bak +0 -13
  158. package/plugins/specweave/lib/hooks/translate-living-docs.js.bak +0 -119
  159. package/plugins/specweave/lib/hooks/translate-living-docs.ts.bak +0 -224
  160. package/plugins/specweave/lib/hooks/update-ac-status.js.bak +0 -51
  161. package/plugins/specweave/lib/hooks/update-ac-status.ts.bak +0 -103
  162. package/plugins/specweave/lib/hooks/update-tasks-md.d.js.bak +0 -1
  163. package/plugins/specweave/lib/hooks/update-tasks-md.d.ts.bak +0 -29
  164. package/plugins/specweave/lib/hooks/update-tasks-md.js.bak +0 -296
  165. package/plugins/specweave/lib/hooks/update-tasks-md.ts.bak +0 -489
  166. package/plugins/specweave-ado/hooks/post-living-docs-update.sh.backup +0 -353
  167. package/plugins/specweave-ado/hooks/post-task-completion.sh.backup +0 -172
  168. package/plugins/specweave-ado/lib/enhanced-ado-sync.js +0 -170
  169. package/plugins/specweave-github/hooks/.specweave/logs/hooks-debug.log +0 -228
  170. package/plugins/specweave-github/hooks/post-task-completion.sh.backup +0 -258
  171. package/plugins/specweave-jira/hooks/post-task-completion.sh.backup +0 -172
  172. package/plugins/specweave-release/hooks/.specweave/logs/dora-tracking.log +0 -444
  173. package/plugins/specweave-release/hooks/post-task-completion.sh.backup +0 -110
@@ -1,79 +0,0 @@
1
- #!/bin/bash
2
-
3
- # SpecWeave Docs-Changed Hook
4
- # Runs after file changes are detected
5
- # Detects if documentation was changed during implementation
6
- # Triggers review workflow if needed
7
-
8
- set -e
9
-
10
- # Find project root by searching upward for .specweave/ directory
11
- # Works regardless of where hook is installed (source or .claude/hooks/)
12
- find_project_root() {
13
- local dir="$1"
14
- while [ "$dir" != "/" ]; do
15
- if [ -d "$dir/.specweave" ]; then
16
- echo "$dir"
17
- return 0
18
- fi
19
- dir="$(dirname "$dir")"
20
- done
21
- # Fallback: try current directory
22
- if [ -d "$(pwd)/.specweave" ]; then
23
- pwd
24
- else
25
- echo "$(pwd)"
26
- fi
27
- }
28
-
29
- PROJECT_ROOT="$(find_project_root "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")"
30
- cd "$PROJECT_ROOT"
31
-
32
- # Colors
33
- RED='\033[0;31m'
34
- YELLOW='\033[1;33m'
35
- NC='\033[0m'
36
-
37
- # Get changed files (git)
38
- if ! git rev-parse --git-dir > /dev/null 2>&1; then
39
- # Not a git repository, skip
40
- exit 0
41
- fi
42
-
43
- CHANGED_FILES=$(git diff --name-only HEAD 2>/dev/null || echo "")
44
-
45
- if [ -z "$CHANGED_FILES" ]; then
46
- # No changes
47
- exit 0
48
- fi
49
-
50
- # Check if any documentation files changed
51
- DOC_CHANGES=$(echo "$CHANGED_FILES" | grep -E '\.specweave/(docs|increments/.*/.*\.md)' || true)
52
-
53
- if [ -n "$DOC_CHANGES" ]; then
54
- echo -e "${RED}⚠️ Documentation changed during implementation${NC}"
55
- echo ""
56
- echo "📋 Files changed:"
57
- echo "$DOC_CHANGES" | sed 's/^/ /'
58
- echo ""
59
- echo -e "${YELLOW}🔔 Recommended actions:${NC}"
60
- echo " 1. Review documentation changes"
61
- echo " 2. Update tasks.md if architecture changed"
62
- echo " 3. Type /review-docs to see full impact"
63
- echo ""
64
-
65
- # Play notification sound
66
- case "$(uname -s)" in
67
- Darwin)
68
- afplay /System/Library/Sounds/Ping.aiff 2>/dev/null &
69
- ;;
70
- Linux)
71
- paplay /usr/share/sounds/freedesktop/stereo/dialog-warning.oga 2>/dev/null || true
72
- ;;
73
- esac
74
-
75
- # Log to hooks log
76
- LOGS_DIR=".specweave/logs"
77
- mkdir -p "$LOGS_DIR"
78
- echo "[$(date)] Documentation changed: $DOC_CHANGES" >> "$LOGS_DIR/hooks.log"
79
- fi
@@ -1,75 +0,0 @@
1
- #!/bin/bash
2
-
3
- # SpecWeave Human-Input-Required Hook
4
- # Runs when Claude needs clarification or approval
5
- #
6
- # Actions:
7
- # 1. Play notification sound (Ping.aiff)
8
- # 2. Log the question/requirement
9
- # 3. Record in current increment's work log (if applicable)
10
-
11
- set -e
12
-
13
- # Find project root by searching upward for .specweave/ directory
14
- # Works regardless of where hook is installed (source or .claude/hooks/)
15
- find_project_root() {
16
- local dir="$1"
17
- while [ "$dir" != "/" ]; do
18
- if [ -d "$dir/.specweave" ]; then
19
- echo "$dir"
20
- return 0
21
- fi
22
- dir="$(dirname "$dir")"
23
- done
24
- # Fallback: try current directory
25
- if [ -d "$(pwd)/.specweave" ]; then
26
- pwd
27
- else
28
- echo "$(pwd)"
29
- fi
30
- }
31
-
32
- PROJECT_ROOT="$(find_project_root "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")"
33
- cd "$PROJECT_ROOT"
34
-
35
- # Get question/requirement (passed as argument or default)
36
- QUESTION="${1:-User input required}"
37
-
38
- echo "❓ Human input required"
39
-
40
- # 1. Play notification sound (cross-platform)
41
- play_sound() {
42
- case "$(uname -s)" in
43
- Darwin)
44
- afplay /System/Library/Sounds/Ping.aiff 2>/dev/null &
45
- ;;
46
- Linux)
47
- paplay /usr/share/sounds/freedesktop/stereo/dialog-question.oga 2>/dev/null || \
48
- aplay /usr/share/sounds/alsa/Side_Left.wav 2>/dev/null || true
49
- ;;
50
- MINGW*|MSYS*|CYGWIN*)
51
- powershell -c "(New-Object Media.SoundPlayer 'C:\Windows\Media\notify.wav').PlaySync();" 2>/dev/null || true
52
- ;;
53
- esac
54
- }
55
-
56
- play_sound &
57
-
58
- # 2. Log to main hooks log
59
- LOGS_DIR=".specweave/logs"
60
- mkdir -p "$LOGS_DIR"
61
- echo "[$(date)] Human input required: $QUESTION" >> "$LOGS_DIR/hooks.log"
62
-
63
- # 3. Log to current work context (if exists)
64
- CURRENT_WORK=$(find .specweave/work -maxdepth 1 -type d -name "current-*" | head -1 || true)
65
-
66
- if [ -n "$CURRENT_WORK" ] && [ -d "$CURRENT_WORK" ]; then
67
- echo "" >> "$CURRENT_WORK/notes.md"
68
- echo "## Input Required ($(date +%Y-%m-%d\ %H:%M))" >> "$CURRENT_WORK/notes.md"
69
- echo "" >> "$CURRENT_WORK/notes.md"
70
- echo "$QUESTION" >> "$CURRENT_WORK/notes.md"
71
- echo "" >> "$CURRENT_WORK/notes.md"
72
- echo "📝 Logged to $CURRENT_WORK/notes.md"
73
- fi
74
-
75
- echo "✅ Hook complete"
@@ -1,245 +0,0 @@
1
- #!/bin/bash
2
-
3
- # SpecWeave Increment Work Migration Utility
4
- # Purpose: Smart migration options when WIP limit is reached
5
- #
6
- # Options:
7
- # 1. Transfer work (move incomplete tasks to new increment)
8
- # 2. Adjust WIP limit (temporarily allow 3 active)
9
- # 3. Force-close (mark as complete without transferring work)
10
-
11
- set -euo pipefail
12
-
13
- # ============================================================================
14
- # CONFIGURATION
15
- # ============================================================================
16
-
17
- SPECWEAVE_DIR="${SPECWEAVE_DIR:-.specweave}"
18
- CONFIG_FILE="$SPECWEAVE_DIR/config.json"
19
-
20
- # ============================================================================
21
- # HELPER FUNCTIONS
22
- # ============================================================================
23
-
24
- # Get incomplete tasks from increment
25
- get_incomplete_tasks() {
26
- local increment_id="$1"
27
- local tasks_file="$SPECWEAVE_DIR/increments/$increment_id/tasks.md"
28
-
29
- if [[ ! -f "$tasks_file" ]]; then
30
- echo ""
31
- return
32
- fi
33
-
34
- # Extract unchecked tasks (lines starting with "- [ ]")
35
- grep -E "^\s*-\s*\[ \]" "$tasks_file" 2>/dev/null || echo ""
36
- }
37
-
38
- # Count incomplete tasks
39
- count_incomplete_tasks() {
40
- local increment_id="$1"
41
- local tasks=$(get_incomplete_tasks "$increment_id")
42
-
43
- if [[ -z "$tasks" ]]; then
44
- echo "0"
45
- else
46
- echo "$tasks" | wc -l | xargs
47
- fi
48
- }
49
-
50
- # Transfer work from old increment to new increment
51
- transfer_work() {
52
- local source_increment="$1"
53
- local target_increment="$2"
54
-
55
- echo "🔄 Transferring incomplete work from $source_increment to $target_increment..."
56
-
57
- # Get incomplete tasks
58
- local incomplete_tasks=$(get_incomplete_tasks "$source_increment")
59
-
60
- if [[ -z "$incomplete_tasks" ]]; then
61
- echo "✅ No incomplete tasks to transfer"
62
- return 0
63
- fi
64
-
65
- local task_count=$(echo "$incomplete_tasks" | wc -l | xargs)
66
- echo " 📋 Found $task_count incomplete tasks"
67
-
68
- # Append to target increment's tasks.md
69
- local target_tasks="$SPECWEAVE_DIR/increments/$target_increment/tasks.md"
70
-
71
- if [[ ! -f "$target_tasks" ]]; then
72
- echo "❌ Target increment tasks.md not found: $target_tasks"
73
- return 1
74
- fi
75
-
76
- # Add separator and transferred tasks
77
- cat >> "$target_tasks" <<EOF
78
-
79
- ---
80
-
81
- ## 🔄 Transferred from $source_increment
82
-
83
- $incomplete_tasks
84
-
85
- EOF
86
-
87
- echo " ✅ Transferred $task_count tasks to $target_tasks"
88
-
89
- # Mark source increment as completed-with-work-transfer
90
- local source_metadata="$SPECWEAVE_DIR/increments/$source_increment/metadata.json"
91
-
92
- if [[ -f "$source_metadata" ]]; then
93
- node -e "
94
- const fs = require('fs');
95
- const path = '$source_metadata';
96
- const data = JSON.parse(fs.readFileSync(path, 'utf-8'));
97
- data.status = 'completed';
98
- data.completionNote = 'Work transferred to $target_increment';
99
- data.completedAt = new Date().toISOString();
100
- data.workTransferredTo = '$target_increment';
101
- fs.writeFileSync(path, JSON.stringify(data, null, 2));
102
- "
103
- echo " ✅ Updated $source_increment metadata (status: completed, work transferred)"
104
- fi
105
-
106
- # Update target increment metadata
107
- local target_metadata="$SPECWEAVE_DIR/increments/$target_increment/metadata.json"
108
-
109
- if [[ -f "$target_metadata" ]]; then
110
- node -e "
111
- const fs = require('fs');
112
- const path = '$target_metadata';
113
- const data = JSON.parse(fs.readFileSync(path, 'utf-8'));
114
- data.workTransferredFrom = data.workTransferredFrom || [];
115
- data.workTransferredFrom.push('$source_increment');
116
- fs.writeFileSync(path, JSON.stringify(data, null, 2));
117
- "
118
- echo " ✅ Updated $target_increment metadata (work received from $source_increment)"
119
- fi
120
-
121
- echo "✅ Work transfer complete!"
122
- return 0
123
- }
124
-
125
- # Adjust WIP limit temporarily
126
- adjust_wip_limit() {
127
- local new_limit="$1"
128
-
129
- echo "⚠️ Temporarily adjusting WIP limit to $new_limit..."
130
-
131
- if [[ ! -f "$CONFIG_FILE" ]]; then
132
- echo "❌ Config file not found: $CONFIG_FILE"
133
- return 1
134
- fi
135
-
136
- # Update config.json (create backup first)
137
- cp "$CONFIG_FILE" "$CONFIG_FILE.bak"
138
-
139
- node -e "
140
- const fs = require('fs');
141
- const path = '$CONFIG_FILE';
142
- const data = JSON.parse(fs.readFileSync(path, 'utf-8'));
143
-
144
- // Ensure limits object exists
145
- if (!data.limits) {
146
- data.limits = {};
147
- }
148
-
149
- // Store original limit
150
- if (!data.limits.originalHardCap) {
151
- data.limits.originalHardCap = data.limits.hardCap || 2;
152
- }
153
-
154
- // Set new limit
155
- data.limits.hardCap = parseInt('$new_limit', 10);
156
- data.limits.wipAdjustedAt = new Date().toISOString();
157
-
158
- fs.writeFileSync(path, JSON.stringify(data, null, 2));
159
- "
160
-
161
- echo " ✅ WIP limit adjusted to $new_limit"
162
- echo " ⚠️ Remember to revert after completing one increment!"
163
- echo " 💡 Run: specweave revert-wip-limit"
164
-
165
- return 0
166
- }
167
-
168
- # Force-close increment
169
- force_close() {
170
- local increment_id="$1"
171
-
172
- echo "⚠️ Force-closing $increment_id..."
173
-
174
- local metadata_file="$SPECWEAVE_DIR/increments/$increment_id/metadata.json"
175
-
176
- if [[ ! -f "$metadata_file" ]]; then
177
- echo "❌ Metadata file not found: $metadata_file"
178
- return 1
179
- fi
180
-
181
- node -e "
182
- const fs = require('fs');
183
- const path = '$metadata_file';
184
- const data = JSON.parse(fs.readFileSync(path, 'utf-8'));
185
- data.status = 'completed';
186
- data.completionNote = 'Force-closed to start new increment (WIP limit reached)';
187
- data.completedAt = new Date().toISOString();
188
- data.forceCloseReason = 'wip-limit-reached';
189
- fs.writeFileSync(path, JSON.stringify(data, null, 2));
190
- "
191
-
192
- echo " ✅ $increment_id marked as completed (force-closed)"
193
- echo " ⚠️ Incomplete work was not transferred!"
194
-
195
- return 0
196
- }
197
-
198
- # ============================================================================
199
- # MAIN CLI
200
- # ============================================================================
201
-
202
- case "${1:-}" in
203
- transfer)
204
- if [[ $# -ne 3 ]]; then
205
- echo "Usage: $0 transfer <source_increment> <target_increment>"
206
- exit 1
207
- fi
208
- transfer_work "$2" "$3"
209
- ;;
210
-
211
- adjust-wip)
212
- if [[ $# -ne 2 ]]; then
213
- echo "Usage: $0 adjust-wip <new_limit>"
214
- exit 1
215
- fi
216
- adjust_wip_limit "$2"
217
- ;;
218
-
219
- force-close)
220
- if [[ $# -ne 2 ]]; then
221
- echo "Usage: $0 force-close <increment_id>"
222
- exit 1
223
- fi
224
- force_close "$2"
225
- ;;
226
-
227
- count-incomplete)
228
- if [[ $# -ne 2 ]]; then
229
- echo "Usage: $0 count-incomplete <increment_id>"
230
- exit 1
231
- fi
232
- count_incomplete_tasks "$2"
233
- ;;
234
-
235
- *)
236
- echo "SpecWeave Increment Work Migration Utility"
237
- echo ""
238
- echo "Usage:"
239
- echo " $0 transfer <source> <target> # Transfer work from source to target"
240
- echo " $0 adjust-wip <limit> # Adjust WIP limit temporarily"
241
- echo " $0 force-close <increment> # Force-close increment"
242
- echo " $0 count-incomplete <increment> # Count incomplete tasks"
243
- exit 1
244
- ;;
245
- esac
@@ -1,149 +0,0 @@
1
- #!/bin/bash
2
- #
3
- # Sync Spec Content to External Tools
4
- #
5
- # This script automatically syncs spec CONTENT (title, description, user stories)
6
- # to external tools (GitHub Issues, JIRA Epics, Azure DevOps Features).
7
- #
8
- # CRITICAL: This does NOT sync STATUS - that's managed by external tools.
9
- #
10
- # Sync Direction:
11
- # - Title/Description/User Stories: SpecWeave → External Tool (we update)
12
- # - Status/State: External Tool → SpecWeave (we read)
13
- #
14
- # Usage:
15
- # sync-spec-content.sh <spec-path>
16
- #
17
-
18
- set -euo pipefail
19
-
20
- # Get script directory
21
- SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
22
- PROJECT_ROOT="$(cd "$SCRIPT_DIR/../../../.." && pwd)"
23
-
24
- # Input validation
25
- if [ $# -lt 1 ]; then
26
- echo "Usage: $0 <spec-path>" >&2
27
- exit 1
28
- fi
29
-
30
- SPEC_PATH="$1"
31
-
32
- # Validate spec file exists
33
- if [ ! -f "$SPEC_PATH" ]; then
34
- echo "❌ Spec file not found: $SPEC_PATH" >&2
35
- exit 1
36
- fi
37
-
38
- # Check if sync is enabled
39
- CONFIG_FILE="$PROJECT_ROOT/.specweave/config.json"
40
- if [ ! -f "$CONFIG_FILE" ]; then
41
- echo "ℹ️ No config file found, skipping spec content sync" >&2
42
- exit 0
43
- fi
44
-
45
- # Check if sync is enabled in config
46
- SYNC_ENABLED=$(node -p "
47
- try {
48
- const config = require('$CONFIG_FILE');
49
- config.sync?.enabled ?? false;
50
- } catch {
51
- false;
52
- }
53
- " 2>/dev/null || echo "false")
54
-
55
- if [ "$SYNC_ENABLED" != "true" ]; then
56
- echo "ℹ️ Sync disabled in config, skipping spec content sync" >&2
57
- exit 0
58
- fi
59
-
60
- # Check if spec content sync is enabled
61
- SPEC_SYNC_ENABLED=$(node -p "
62
- try {
63
- const config = require('$CONFIG_FILE');
64
- config.sync?.settings?.syncSpecContent ?? true;
65
- } catch {
66
- true;
67
- }
68
- " 2>/dev/null || echo "true")
69
-
70
- if [ "$SPEC_SYNC_ENABLED" != "true" ]; then
71
- echo "ℹ️ Spec content sync disabled in config" >&2
72
- exit 0
73
- fi
74
-
75
- # Get active provider
76
- ACTIVE_PROFILE=$(node -p "
77
- try {
78
- const config = require('$CONFIG_FILE');
79
- config.sync?.activeProfile ?? null;
80
- } catch {
81
- null;
82
- }
83
- " 2>/dev/null || echo "null")
84
-
85
- if [ "$ACTIVE_PROFILE" = "null" ]; then
86
- echo "ℹ️ No active sync profile, skipping spec content sync" >&2
87
- exit 0
88
- fi
89
-
90
- # Get provider from active profile
91
- PROVIDER=$(node -p "
92
- try {
93
- const config = require('$CONFIG_FILE');
94
- config.sync?.profiles?.['"$ACTIVE_PROFILE"']?.provider ?? null;
95
- } catch {
96
- null;
97
- }
98
- " 2>/dev/null || echo "null")
99
-
100
- if [ "$PROVIDER" = "null" ]; then
101
- echo "ℹ️ No provider configured for profile '$ACTIVE_PROFILE'" >&2
102
- exit 0
103
- fi
104
-
105
- # Validate provider
106
- if [[ ! "$PROVIDER" =~ ^(github|jira|ado)$ ]]; then
107
- echo "❌ Invalid provider: $PROVIDER (must be github, jira, or ado)" >&2
108
- exit 1
109
- fi
110
-
111
- # Check if sync CLI command exists
112
- SYNC_CLI="$PROJECT_ROOT/dist/src/cli/commands/sync-spec-content.js"
113
- if [ ! -f "$SYNC_CLI" ]; then
114
- echo "ℹ️ Sync CLI not built, skipping spec content sync" >&2
115
- echo " Run: npm run build" >&2
116
- exit 0
117
- fi
118
-
119
- # Check if Node.js is available
120
- if ! command -v node &> /dev/null; then
121
- echo "❌ Node.js not found, cannot sync spec content" >&2
122
- exit 1
123
- fi
124
-
125
- echo ""
126
- echo "🔄 Syncing spec content to $PROVIDER..."
127
- echo " Spec: $(basename "$SPEC_PATH")"
128
- echo ""
129
-
130
- # Run sync
131
- set +e
132
- node "$SYNC_CLI" --spec "$SPEC_PATH" --provider "$PROVIDER"
133
- SYNC_EXIT_CODE=$?
134
- set -e
135
-
136
- if [ $SYNC_EXIT_CODE -eq 0 ]; then
137
- echo ""
138
- echo "✅ Spec content synced successfully"
139
- echo ""
140
- else
141
- echo ""
142
- echo "⚠️ Spec content sync failed (exit code: $SYNC_EXIT_CODE)" >&2
143
- echo " This is non-blocking. You can sync manually later:" >&2
144
- echo " node dist/src/cli/commands/sync-spec-content.js --spec \"$SPEC_PATH\" --provider $PROVIDER" >&2
145
- echo ""
146
- # Non-blocking: continue execution even if sync fails
147
- fi
148
-
149
- exit 0
@@ -1,163 +0,0 @@
1
- #!/bin/bash
2
- #
3
- # validate-spec-status.sh
4
- #
5
- # Validates that spec.md status values match IncrementStatus enum.
6
- # Prevents vocabulary drift and ensures status line hook compatibility.
7
- #
8
- # Usage:
9
- # bash validate-spec-status.sh <increment-id>
10
- # bash validate-spec-status.sh --all # Validate all increments
11
- #
12
- # Exit codes:
13
- # 0 = Valid
14
- # 1 = Invalid status found
15
- # 2 = Error (file not found, etc.)
16
- #
17
- # Requires: bash 4.0+ (for associative arrays)
18
-
19
- set -euo pipefail
20
-
21
- # Find project root
22
- find_project_root() {
23
- local dir="$PWD"
24
- while [[ "$dir" != "/" ]]; do
25
- if [[ -d "$dir/.specweave" ]]; then
26
- echo "$dir"
27
- return 0
28
- fi
29
- dir=$(dirname "$dir")
30
- done
31
- echo "$PWD"
32
- }
33
-
34
- PROJECT_ROOT=$(find_project_root)
35
- INCREMENTS_DIR="$PROJECT_ROOT/.specweave/increments"
36
-
37
- # Valid IncrementStatus enum values (from src/core/types/increment-metadata.ts)
38
- VALID_STATUSES=("planning" "active" "backlog" "paused" "completed" "abandoned")
39
-
40
- # Get suggested correction for invalid status
41
- get_correction() {
42
- local status="$1"
43
- case "$status" in
44
- "planned") echo "planning" ;;
45
- "in-progress"|"in_progress") echo "active" ;;
46
- "done") echo "completed" ;;
47
- "cancelled"|"canceled") echo "abandoned" ;;
48
- *) echo "" ;;
49
- esac
50
- }
51
-
52
- # Validate a single spec file
53
- validate_spec() {
54
- local spec_file="$1"
55
- local increment_id=$(basename "$(dirname "$spec_file")")
56
-
57
- if [[ ! -f "$spec_file" ]]; then
58
- echo "❌ Error: spec.md not found for increment $increment_id"
59
- return 2
60
- fi
61
-
62
- # Extract status from YAML frontmatter
63
- local status=$(grep -m1 "^status:" "$spec_file" 2>/dev/null | cut -d: -f2 | tr -d ' "' || echo "")
64
-
65
- if [[ -z "$status" ]]; then
66
- echo "⚠️ Warning: No status field in $increment_id/spec.md"
67
- return 0 # Not an error, just a warning
68
- fi
69
-
70
- # Check if status is valid
71
- local is_valid=0
72
- for valid_status in "${VALID_STATUSES[@]}"; do
73
- if [[ "$status" == "$valid_status" ]]; then
74
- is_valid=1
75
- break
76
- fi
77
- done
78
-
79
- if [[ $is_valid -eq 1 ]]; then
80
- echo "✅ $increment_id: status '$status' is valid"
81
- return 0
82
- else
83
- # Invalid status found - suggest correction
84
- echo ""
85
- echo "❌ Invalid status in $increment_id/spec.md"
86
- echo " Found: '$status'"
87
- echo ""
88
-
89
- # Check if we have a suggested correction
90
- local correction=$(get_correction "$status")
91
- if [[ -n "$correction" ]]; then
92
- echo " 💡 Did you mean: '$correction'?"
93
- echo ""
94
- echo " Fix:"
95
- echo " sed -i '' 's/^status: $status/status: $correction/' $spec_file"
96
- else
97
- echo " Valid statuses: ${VALID_STATUSES[*]}"
98
- fi
99
- echo ""
100
-
101
- return 1
102
- fi
103
- }
104
-
105
- # Validate all increments
106
- validate_all() {
107
- local exit_code=0
108
- local total=0
109
- local valid=0
110
- local invalid=0
111
-
112
- echo "Validating all increments in $INCREMENTS_DIR"
113
- echo ""
114
-
115
- for spec_file in "$INCREMENTS_DIR"/*/spec.md; do
116
- if [[ -f "$spec_file" ]]; then
117
- total=$((total + 1))
118
- if validate_spec "$spec_file"; then
119
- valid=$((valid + 1))
120
- else
121
- invalid=$((invalid + 1))
122
- exit_code=1
123
- fi
124
- fi
125
- done
126
-
127
- echo ""
128
- echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
129
- echo "Summary: $total increments checked"
130
- echo " ✅ Valid: $valid"
131
- echo " ❌ Invalid: $invalid"
132
- echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
133
-
134
- if [[ $invalid -gt 0 ]]; then
135
- echo ""
136
- echo "⚠️ Please fix invalid status values to use official IncrementStatus enum."
137
- echo ""
138
- echo "Valid statuses:"
139
- for status in "${VALID_STATUSES[@]}"; do
140
- echo " - $status"
141
- done
142
- fi
143
-
144
- return $exit_code
145
- }
146
-
147
- # Main logic
148
- if [[ $# -eq 0 ]]; then
149
- echo "Usage: $0 <increment-id> | --all"
150
- echo ""
151
- echo "Examples:"
152
- echo " $0 0042-test-infrastructure-cleanup"
153
- echo " $0 --all"
154
- exit 2
155
- fi
156
-
157
- if [[ "$1" == "--all" ]]; then
158
- validate_all
159
- else
160
- INCREMENT_ID="$1"
161
- SPEC_FILE="$INCREMENTS_DIR/$INCREMENT_ID/spec.md"
162
- validate_spec "$SPEC_FILE"
163
- fi