specweave 0.32.0 → 0.32.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (191) hide show
  1. package/CLAUDE.md +176 -2
  2. package/README.md +22 -0
  3. package/bin/specweave.js +18 -1
  4. package/dist/src/cli/commands/cache.d.ts +17 -0
  5. package/dist/src/cli/commands/cache.d.ts.map +1 -0
  6. package/dist/src/cli/commands/cache.js +126 -0
  7. package/dist/src/cli/commands/cache.js.map +1 -0
  8. package/dist/src/cli/commands/init.js +1 -1
  9. package/dist/src/cli/commands/init.js.map +1 -1
  10. package/dist/src/cli/commands/plan/increment-detector.js +2 -2
  11. package/dist/src/cli/commands/plan/increment-detector.js.map +1 -1
  12. package/dist/src/cli/commands/sync-spec-commits.js +1 -1
  13. package/dist/src/cli/commands/sync-spec-commits.js.map +1 -1
  14. package/dist/src/cli/commands/sync-specs.js +2 -2
  15. package/dist/src/cli/commands/sync-specs.js.map +1 -1
  16. package/dist/src/cli/helpers/github/increment-profile-selector.js +1 -1
  17. package/dist/src/cli/helpers/github/increment-profile-selector.js.map +1 -1
  18. package/dist/src/cli/workers/living-docs-worker.js +66 -1
  19. package/dist/src/cli/workers/living-docs-worker.js.map +1 -1
  20. package/dist/src/config/types.d.ts +203 -1208
  21. package/dist/src/config/types.d.ts.map +1 -1
  22. package/dist/src/core/discrepancy/increment-generator.d.ts.map +1 -1
  23. package/dist/src/core/discrepancy/increment-generator.js +5 -2
  24. package/dist/src/core/discrepancy/increment-generator.js.map +1 -1
  25. package/dist/src/core/increment/duplicate-detector.js +2 -2
  26. package/dist/src/core/increment/duplicate-detector.js.map +1 -1
  27. package/dist/src/core/increment/increment-archiver.d.ts +24 -0
  28. package/dist/src/core/increment/increment-archiver.d.ts.map +1 -1
  29. package/dist/src/core/increment/increment-archiver.js +59 -2
  30. package/dist/src/core/increment/increment-archiver.js.map +1 -1
  31. package/dist/src/core/increment/increment-status.js +2 -2
  32. package/dist/src/core/increment/increment-status.js.map +1 -1
  33. package/dist/src/core/increment/increment-utils.d.ts +85 -0
  34. package/dist/src/core/increment/increment-utils.d.ts.map +1 -1
  35. package/dist/src/core/increment/increment-utils.js +102 -4
  36. package/dist/src/core/increment/increment-utils.js.map +1 -1
  37. package/dist/src/core/increment/metadata-validator.js +1 -1
  38. package/dist/src/core/increment/metadata-validator.js.map +1 -1
  39. package/dist/src/core/living-docs/feature-id-manager.js +1 -1
  40. package/dist/src/core/living-docs/feature-id-manager.js.map +1 -1
  41. package/dist/src/core/living-docs/hierarchy-mapper.js +3 -3
  42. package/dist/src/core/living-docs/hierarchy-mapper.js.map +1 -1
  43. package/dist/src/core/living-docs/intelligent-analyzer/architecture-generator.d.ts +18 -0
  44. package/dist/src/core/living-docs/intelligent-analyzer/architecture-generator.d.ts.map +1 -0
  45. package/dist/src/core/living-docs/intelligent-analyzer/architecture-generator.js +247 -0
  46. package/dist/src/core/living-docs/intelligent-analyzer/architecture-generator.js.map +1 -0
  47. package/dist/src/core/living-docs/intelligent-analyzer/deep-repo-analyzer.d.ts +15 -0
  48. package/dist/src/core/living-docs/intelligent-analyzer/deep-repo-analyzer.d.ts.map +1 -0
  49. package/dist/src/core/living-docs/intelligent-analyzer/deep-repo-analyzer.js +138 -0
  50. package/dist/src/core/living-docs/intelligent-analyzer/deep-repo-analyzer.js.map +1 -0
  51. package/dist/src/core/living-docs/intelligent-analyzer/file-sampler.d.ts +24 -0
  52. package/dist/src/core/living-docs/intelligent-analyzer/file-sampler.d.ts.map +1 -0
  53. package/dist/src/core/living-docs/intelligent-analyzer/file-sampler.js +198 -0
  54. package/dist/src/core/living-docs/intelligent-analyzer/file-sampler.js.map +1 -0
  55. package/dist/src/core/living-docs/intelligent-analyzer/inconsistency-detector.d.ts +17 -0
  56. package/dist/src/core/living-docs/intelligent-analyzer/inconsistency-detector.d.ts.map +1 -0
  57. package/dist/src/core/living-docs/intelligent-analyzer/inconsistency-detector.js +241 -0
  58. package/dist/src/core/living-docs/intelligent-analyzer/inconsistency-detector.js.map +1 -0
  59. package/dist/src/core/living-docs/intelligent-analyzer/index.d.ts +28 -0
  60. package/dist/src/core/living-docs/intelligent-analyzer/index.d.ts.map +1 -0
  61. package/dist/src/core/living-docs/intelligent-analyzer/index.js +197 -0
  62. package/dist/src/core/living-docs/intelligent-analyzer/index.js.map +1 -0
  63. package/dist/src/core/living-docs/intelligent-analyzer/organization-synthesizer.d.ts +18 -0
  64. package/dist/src/core/living-docs/intelligent-analyzer/organization-synthesizer.d.ts.map +1 -0
  65. package/dist/src/core/living-docs/intelligent-analyzer/organization-synthesizer.js +154 -0
  66. package/dist/src/core/living-docs/intelligent-analyzer/organization-synthesizer.js.map +1 -0
  67. package/dist/src/core/living-docs/intelligent-analyzer/strategy-generator.d.ts +42 -0
  68. package/dist/src/core/living-docs/intelligent-analyzer/strategy-generator.d.ts.map +1 -0
  69. package/dist/src/core/living-docs/intelligent-analyzer/strategy-generator.js +343 -0
  70. package/dist/src/core/living-docs/intelligent-analyzer/strategy-generator.js.map +1 -0
  71. package/dist/src/core/living-docs/intelligent-analyzer/types.d.ts +146 -0
  72. package/dist/src/core/living-docs/intelligent-analyzer/types.d.ts.map +1 -0
  73. package/dist/src/core/living-docs/intelligent-analyzer/types.js +7 -0
  74. package/dist/src/core/living-docs/intelligent-analyzer/types.js.map +1 -0
  75. package/dist/src/core/living-docs/living-docs-sync.d.ts +5 -0
  76. package/dist/src/core/living-docs/living-docs-sync.d.ts.map +1 -1
  77. package/dist/src/core/living-docs/living-docs-sync.js +36 -2
  78. package/dist/src/core/living-docs/living-docs-sync.js.map +1 -1
  79. package/dist/src/core/sync/spec-increment-mapper.js +3 -3
  80. package/dist/src/core/sync/spec-increment-mapper.js.map +1 -1
  81. package/dist/src/importers/item-converter.d.ts +25 -0
  82. package/dist/src/importers/item-converter.d.ts.map +1 -1
  83. package/dist/src/importers/item-converter.js +135 -5
  84. package/dist/src/importers/item-converter.js.map +1 -1
  85. package/dist/src/init/architecture/types.d.ts +33 -140
  86. package/dist/src/init/architecture/types.d.ts.map +1 -1
  87. package/dist/src/init/compliance/types.d.ts +30 -27
  88. package/dist/src/init/compliance/types.d.ts.map +1 -1
  89. package/dist/src/init/repo/types.d.ts +11 -34
  90. package/dist/src/init/repo/types.d.ts.map +1 -1
  91. package/dist/src/init/research/src/config/types.d.ts +15 -82
  92. package/dist/src/init/research/src/config/types.d.ts.map +1 -1
  93. package/dist/src/init/research/types.d.ts +38 -93
  94. package/dist/src/init/research/types.d.ts.map +1 -1
  95. package/dist/src/init/team/types.d.ts +4 -42
  96. package/dist/src/init/team/types.d.ts.map +1 -1
  97. package/dist/src/types/dashboard-cache.d.ts +181 -0
  98. package/dist/src/types/dashboard-cache.d.ts.map +1 -0
  99. package/dist/src/types/dashboard-cache.js +65 -0
  100. package/dist/src/types/dashboard-cache.js.map +1 -0
  101. package/dist/src/utils/docs-validator.d.ts +131 -0
  102. package/dist/src/utils/docs-validator.d.ts.map +1 -0
  103. package/dist/src/utils/docs-validator.js +529 -0
  104. package/dist/src/utils/docs-validator.js.map +1 -0
  105. package/dist/src/utils/feature-id-collision.js +1 -1
  106. package/dist/src/utils/feature-id-collision.js.map +1 -1
  107. package/dist/src/utils/html-to-mdx.d.ts +1 -0
  108. package/dist/src/utils/html-to-mdx.d.ts.map +1 -1
  109. package/dist/src/utils/html-to-mdx.js +43 -5
  110. package/dist/src/utils/html-to-mdx.js.map +1 -1
  111. package/package.json +1 -1
  112. package/plugins/specweave/agents/pm/AGENT.md +10 -7
  113. package/plugins/specweave/commands/specweave-archive-features.md +5 -7
  114. package/plugins/specweave/commands/specweave-archive.md +2 -1
  115. package/plugins/specweave/commands/specweave-do.md +35 -1
  116. package/plugins/specweave/commands/specweave-done.md +96 -0
  117. package/plugins/specweave/commands/specweave-import-external.md +45 -18
  118. package/plugins/specweave/commands/specweave-increment.md +331 -33
  119. package/plugins/specweave/commands/specweave-jobs.md +2 -2
  120. package/plugins/specweave/commands/specweave-progress.md +4 -4
  121. package/plugins/specweave/commands/specweave-restore-feature.md +5 -4
  122. package/plugins/specweave/commands/specweave-sync-docs.md +1 -1
  123. package/plugins/specweave/commands/specweave-sync-specs.md +216 -322
  124. package/plugins/specweave/commands/specweave-validate-features.md +13 -8
  125. package/plugins/specweave/hooks/docs-changed.sh.backup +79 -0
  126. package/plugins/specweave/hooks/hooks.json +33 -4
  127. package/plugins/specweave/hooks/human-input-required.sh.backup +75 -0
  128. package/plugins/specweave/hooks/lib/common-setup.sh +375 -0
  129. package/plugins/specweave/hooks/lib/crash-prevention.sh +336 -0
  130. package/plugins/specweave/hooks/post-first-increment.sh.backup +61 -0
  131. package/plugins/specweave/hooks/post-increment-change.sh.backup +98 -0
  132. package/plugins/specweave/hooks/post-increment-completion.sh.backup +231 -0
  133. package/plugins/specweave/hooks/post-increment-planning.sh.backup +1048 -0
  134. package/plugins/specweave/hooks/post-increment-status-change.sh.backup +147 -0
  135. package/plugins/specweave/hooks/post-spec-update.sh.backup +158 -0
  136. package/plugins/specweave/hooks/post-task-completion.sh +4 -23
  137. package/plugins/specweave/hooks/post-user-story-complete.sh.backup +179 -0
  138. package/plugins/specweave/hooks/pre-command-deduplication.sh +1 -6
  139. package/plugins/specweave/hooks/pre-command-deduplication.sh.backup +83 -0
  140. package/plugins/specweave/hooks/pre-implementation.sh.backup +67 -0
  141. package/plugins/specweave/hooks/pre-task-completion.sh +8 -37
  142. package/plugins/specweave/hooks/pre-task-completion.sh.backup +194 -0
  143. package/plugins/specweave/hooks/pre-tool-use.sh +2 -11
  144. package/plugins/specweave/hooks/pre-tool-use.sh.backup +133 -0
  145. package/plugins/specweave/hooks/universal/dispatcher.mjs +135 -42
  146. package/plugins/specweave/hooks/universal/fail-fast-wrapper.sh +183 -0
  147. package/plugins/specweave/hooks/user-prompt-submit.sh +140 -38
  148. package/plugins/specweave/hooks/user-prompt-submit.sh.backup +386 -0
  149. package/plugins/specweave/hooks/v2/dispatchers/post-tool-use.sh +12 -0
  150. package/plugins/specweave/hooks/v2/dispatchers/session-start.sh +89 -0
  151. package/plugins/specweave/hooks/v2/guards/bash-file-guard.sh +211 -0
  152. package/plugins/specweave/hooks/v2/guards/bash-file-guard.test.sh +163 -0
  153. package/plugins/specweave/hooks/v2/guards/completion-guard.sh +26 -28
  154. package/plugins/specweave/hooks/v2/guards/features-folder-guard.sh +50 -0
  155. package/plugins/specweave/lib/vendor/core/increment/duplicate-detector.js +2 -2
  156. package/plugins/specweave/lib/vendor/core/increment/duplicate-detector.js.map +1 -1
  157. package/plugins/specweave/scripts/README.md +166 -0
  158. package/plugins/specweave/scripts/cleanup-state.sh +142 -0
  159. package/plugins/specweave/scripts/force-kill.sh +142 -0
  160. package/plugins/specweave/scripts/jobs.js +171 -0
  161. package/plugins/specweave/scripts/progress.js +170 -0
  162. package/plugins/specweave/scripts/read-costs.sh +132 -0
  163. package/plugins/specweave/scripts/read-jobs.sh +324 -0
  164. package/plugins/specweave/scripts/read-progress.sh +185 -0
  165. package/plugins/specweave/scripts/read-status.sh +146 -0
  166. package/plugins/specweave/scripts/read-workflow.sh +173 -0
  167. package/plugins/specweave/scripts/rebuild-dashboard-cache.sh +327 -0
  168. package/plugins/specweave/scripts/session-watchdog.sh +192 -0
  169. package/plugins/specweave/scripts/status.js +154 -0
  170. package/plugins/specweave/scripts/update-dashboard-cache.sh +281 -0
  171. package/plugins/specweave/skills/increment-planner/SKILL.md +333 -24
  172. package/plugins/specweave/skills/increment-planner/templates/spec-multi-project.md +17 -9
  173. package/plugins/specweave/skills/increment-planner/templates/spec-single-project.md +6 -2
  174. package/plugins/specweave/skills/instant-status/SKILL.md +70 -0
  175. package/plugins/specweave-ado/hooks/post-living-docs-update.sh.backup +353 -0
  176. package/plugins/specweave-ado/hooks/post-task-completion.sh.backup +172 -0
  177. package/plugins/specweave-ado/lib/enhanced-ado-sync.js +170 -0
  178. package/plugins/specweave-docs/commands/build.md +32 -4
  179. package/plugins/specweave-docs/commands/preview.md +43 -1
  180. package/plugins/specweave-docs/commands/validate.md +250 -0
  181. package/plugins/specweave-github/hooks/.specweave/logs/hooks-debug.log +1262 -0
  182. package/plugins/specweave-github/hooks/post-task-completion.sh.backup +258 -0
  183. package/plugins/specweave-github/lib/enhanced-github-sync.js +220 -0
  184. package/plugins/specweave-jira/hooks/post-task-completion.sh.backup +172 -0
  185. package/plugins/specweave-jira/lib/enhanced-jira-sync.js +134 -0
  186. package/plugins/specweave-release/hooks/.specweave/logs/dora-tracking.log +1254 -0
  187. package/plugins/specweave-release/hooks/post-task-completion.sh.backup +110 -0
  188. package/plugins/specweave/hooks/post-edit-spec.sh +0 -265
  189. package/plugins/specweave/hooks/post-write-spec.sh +0 -267
  190. package/plugins/specweave/hooks/pre-edit-spec.sh +0 -151
  191. package/plugins/specweave/hooks/pre-write-spec.sh +0 -151
@@ -0,0 +1,185 @@
1
+ #!/usr/bin/env bash
2
+ # read-progress.sh - Pure bash reader for /specweave:progress
3
+ #
4
+ # Reads from pre-computed dashboard cache for <10ms response time.
5
+ # Falls back to Node.js script if jq is not available.
6
+ #
7
+ # Usage: bash read-progress.sh [incrementId]
8
+ #
9
+ # Compatible with bash 3.x (macOS default)
10
+
11
+ set -e
12
+
13
+ INCREMENT_ID="${1:-}"
14
+
15
+ # Find project root
16
+ PROJECT_ROOT="$PWD"
17
+ while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -d "$PROJECT_ROOT/.specweave" ]]; do
18
+ PROJECT_ROOT=$(dirname "$PROJECT_ROOT")
19
+ done
20
+
21
+ if [[ ! -d "$PROJECT_ROOT/.specweave" ]]; then
22
+ echo "No SpecWeave project found (missing .specweave/)"
23
+ exit 0
24
+ fi
25
+
26
+ CACHE_FILE="$PROJECT_ROOT/.specweave/state/dashboard.json"
27
+ SCRIPTS_DIR="$PROJECT_ROOT/plugins/specweave/scripts"
28
+
29
+ # Check if jq is available, fall back to Node if not
30
+ if ! command -v jq >/dev/null 2>&1; then
31
+ if [[ -f "$SCRIPTS_DIR/progress.js" ]]; then
32
+ echo "⚠️ Install jq for instant status commands: brew install jq"
33
+ exec node "$SCRIPTS_DIR/progress.js" "$@"
34
+ else
35
+ echo "❌ jq not found and no fallback script available"
36
+ exit 1
37
+ fi
38
+ fi
39
+
40
+ # If cache doesn't exist or is corrupted, rebuild it
41
+ NEED_REBUILD=false
42
+ if [[ ! -f "$CACHE_FILE" ]]; then
43
+ NEED_REBUILD=true
44
+ elif ! jq -e '.' "$CACHE_FILE" >/dev/null 2>&1; then
45
+ # Cache exists but is corrupted (invalid JSON)
46
+ NEED_REBUILD=true
47
+ fi
48
+
49
+ if [[ "$NEED_REBUILD" == "true" ]]; then
50
+ bash "$SCRIPTS_DIR/rebuild-dashboard-cache.sh" --quiet 2>/dev/null || true
51
+ fi
52
+
53
+ # If still no cache, fall back to Node
54
+ if [[ ! -f "$CACHE_FILE" ]] || ! jq -e '.' "$CACHE_FILE" >/dev/null 2>&1; then
55
+ exec node "$SCRIPTS_DIR/progress.js" "$@"
56
+ fi
57
+
58
+ # Helper: create progress bar
59
+ progress_bar() {
60
+ local pct="$1"
61
+ local width="${2:-20}"
62
+ local filled=$((pct * width / 100))
63
+ local empty=$((width - filled))
64
+
65
+ local bar="["
66
+ for ((i=0; i<filled; i++)); do bar+="█"; done
67
+ for ((i=0; i<empty; i++)); do bar+="░"; done
68
+ bar+="]"
69
+ echo "$bar"
70
+ }
71
+
72
+ # Helper: format status with icon
73
+ format_status() {
74
+ case "$1" in
75
+ active) echo "🔄 active" ;;
76
+ planning) echo "📝 planning" ;;
77
+ paused) echo "⏸️ paused" ;;
78
+ completed) echo "✅ completed" ;;
79
+ abandoned) echo "❌ abandoned" ;;
80
+ ready_for_review) echo "👀 ready for review" ;;
81
+ backlog) echo "📋 backlog" ;;
82
+ *) echo "$1" ;;
83
+ esac
84
+ }
85
+
86
+ # If specific increment requested
87
+ if [[ -n "$INCREMENT_ID" ]]; then
88
+ # Find increment (partial match)
89
+ FULL_ID=$(jq -r --arg id "$INCREMENT_ID" '
90
+ .increments | keys[] | select(. == $id or startswith($id))
91
+ ' "$CACHE_FILE" | head -1)
92
+
93
+ if [[ -z "$FULL_ID" ]]; then
94
+ echo "Increment not found: $INCREMENT_ID"
95
+ exit 1
96
+ fi
97
+
98
+ # Read increment data
99
+ INC_DATA=$(jq --arg id "$FULL_ID" '.increments[$id]' "$CACHE_FILE")
100
+ STATUS=$(echo "$INC_DATA" | jq -r '.status // "unknown"')
101
+ TYPE=$(echo "$INC_DATA" | jq -r '.type // "feature"')
102
+ TOTAL=$(echo "$INC_DATA" | jq -r '.tasks.total // 0')
103
+ COMPLETED=$(echo "$INC_DATA" | jq -r '.tasks.completed // 0')
104
+
105
+ if [[ "$TOTAL" -gt 0 ]]; then
106
+ PCT=$((COMPLETED * 100 / TOTAL))
107
+ else
108
+ PCT=0
109
+ fi
110
+
111
+ BAR=$(progress_bar "$PCT")
112
+ STATUS_FMT=$(format_status "$STATUS")
113
+
114
+ echo ""
115
+ echo "📊 Progress: $FULL_ID"
116
+ echo ""
117
+ echo "Status: $STATUS_FMT"
118
+ echo "Type: $TYPE"
119
+ echo "Tasks: $COMPLETED/$TOTAL ($PCT%)"
120
+ echo "Progress: $BAR"
121
+ exit 0
122
+ fi
123
+
124
+ # Show all active increments
125
+ echo ""
126
+ echo "📊 Increment Progress"
127
+ echo ""
128
+
129
+ # Get active increments
130
+ ACTIVE=$(jq -r '
131
+ .increments | to_entries[] |
132
+ select(.value.status == "active" or .value.status == "planning" or .value.status == "in-progress") |
133
+ "\(.key)|\(.value.tasks.completed)|\(.value.tasks.total)"
134
+ ' "$CACHE_FILE" 2>/dev/null)
135
+
136
+ ACTIVE_COUNT=0
137
+ if [[ -n "$ACTIVE" ]]; then
138
+ echo "🔄 Active:"
139
+ while IFS='|' read -r id completed total; do
140
+ [[ -z "$id" ]] && continue
141
+ ACTIVE_COUNT=$((ACTIVE_COUNT + 1))
142
+ if [[ "$total" -gt 0 ]]; then
143
+ pct=$((completed * 100 / total))
144
+ else
145
+ pct=0
146
+ fi
147
+ bar=$(progress_bar "$pct" 15)
148
+ echo " $id"
149
+ echo " $bar $completed/$total ($pct%)"
150
+ done <<< "$ACTIVE"
151
+ echo ""
152
+ fi
153
+
154
+ # Get paused increments
155
+ PAUSED=$(jq -r '
156
+ .increments | to_entries[] |
157
+ select(.value.status == "paused") |
158
+ "\(.key)|\(.value.tasks.completed)|\(.value.tasks.total)"
159
+ ' "$CACHE_FILE" 2>/dev/null)
160
+
161
+ if [[ -n "$PAUSED" ]]; then
162
+ PAUSED_COUNT=$(echo "$PAUSED" | wc -l | tr -d ' ')
163
+ echo "⏸️ Paused ($PAUSED_COUNT):"
164
+ while IFS='|' read -r id completed total; do
165
+ [[ -z "$id" ]] && continue
166
+ if [[ "$total" -gt 0 ]]; then
167
+ pct=$((completed * 100 / total))
168
+ else
169
+ pct=0
170
+ fi
171
+ echo " $id - $pct%"
172
+ done <<< "$PAUSED"
173
+ echo ""
174
+ fi
175
+
176
+ # If no active/paused
177
+ if [[ "$ACTIVE_COUNT" -eq 0 ]] && [[ -z "$PAUSED" ]]; then
178
+ echo "No active increments."
179
+ COMPLETED_COUNT=$(jq '.summary.completed // 0' "$CACHE_FILE")
180
+ if [[ "$COMPLETED_COUNT" -gt 0 ]]; then
181
+ echo "$COMPLETED_COUNT completed increment(s)."
182
+ fi
183
+ fi
184
+
185
+ echo "💡 For details: /specweave:progress <incrementId>"
@@ -0,0 +1,146 @@
1
+ #!/usr/bin/env bash
2
+ # read-status.sh - Pure bash reader for /specweave:status
3
+ #
4
+ # Reads from pre-computed dashboard cache for <10ms response time.
5
+ # Falls back to Node.js script if jq is not available.
6
+ #
7
+ # Usage: bash read-status.sh
8
+ #
9
+ # Compatible with bash 3.x (macOS default)
10
+
11
+ set -e
12
+
13
+ # Find project root
14
+ PROJECT_ROOT="$PWD"
15
+ while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -d "$PROJECT_ROOT/.specweave" ]]; do
16
+ PROJECT_ROOT=$(dirname "$PROJECT_ROOT")
17
+ done
18
+
19
+ if [[ ! -d "$PROJECT_ROOT/.specweave" ]]; then
20
+ echo "No SpecWeave project found (missing .specweave/)"
21
+ exit 0
22
+ fi
23
+
24
+ CACHE_FILE="$PROJECT_ROOT/.specweave/state/dashboard.json"
25
+ SCRIPTS_DIR="$PROJECT_ROOT/plugins/specweave/scripts"
26
+
27
+ # Check if jq is available, fall back to Node if not
28
+ if ! command -v jq >/dev/null 2>&1; then
29
+ if [[ -f "$SCRIPTS_DIR/status.js" ]]; then
30
+ echo "⚠️ Install jq for instant status commands: brew install jq"
31
+ exec node "$SCRIPTS_DIR/status.js" "$@"
32
+ else
33
+ echo "❌ jq not found and no fallback script available"
34
+ exit 1
35
+ fi
36
+ fi
37
+
38
+ # If cache doesn't exist or is corrupted, rebuild it
39
+ NEED_REBUILD=false
40
+ if [[ ! -f "$CACHE_FILE" ]]; then
41
+ NEED_REBUILD=true
42
+ elif ! jq -e '.' "$CACHE_FILE" >/dev/null 2>&1; then
43
+ # Cache exists but is corrupted (invalid JSON)
44
+ NEED_REBUILD=true
45
+ fi
46
+
47
+ if [[ "$NEED_REBUILD" == "true" ]]; then
48
+ bash "$SCRIPTS_DIR/rebuild-dashboard-cache.sh" --quiet 2>/dev/null || true
49
+ fi
50
+
51
+ # If still no cache, fall back to Node
52
+ if [[ ! -f "$CACHE_FILE" ]] || ! jq -e '.' "$CACHE_FILE" >/dev/null 2>&1; then
53
+ exec node "$SCRIPTS_DIR/status.js" "$@"
54
+ fi
55
+
56
+ echo ""
57
+ echo "📋 SpecWeave Status Overview"
58
+ echo ""
59
+
60
+ # Status display order and icons
61
+ declare -a STATUS_ORDER
62
+ STATUS_ORDER=("active" "planning" "in-progress" "ready_for_review" "paused" "backlog" "completed" "abandoned")
63
+
64
+ status_icon() {
65
+ case "$1" in
66
+ active) echo "🔄" ;;
67
+ planning) echo "📝" ;;
68
+ in-progress) echo "⚙️" ;;
69
+ ready_for_review) echo "👀" ;;
70
+ paused) echo "⏸️" ;;
71
+ backlog) echo "📋" ;;
72
+ completed) echo "✅" ;;
73
+ abandoned) echo "❌" ;;
74
+ *) echo "•" ;;
75
+ esac
76
+ }
77
+
78
+ HAS_OUTPUT=false
79
+
80
+ for status in "${STATUS_ORDER[@]}"; do
81
+ # Get increments with this status
82
+ ITEMS=$(jq -r --arg s "$status" '
83
+ .increments | to_entries[] |
84
+ select(.value.status == $s) | .key
85
+ ' "$CACHE_FILE" 2>/dev/null)
86
+
87
+ if [[ -n "$ITEMS" ]]; then
88
+ HAS_OUTPUT=true
89
+ COUNT=$(echo "$ITEMS" | wc -l | tr -d ' ')
90
+ ICON=$(status_icon "$status")
91
+ DISPLAY_STATUS="${status//_/ }"
92
+
93
+ echo "$ICON $DISPLAY_STATUS ($COUNT):"
94
+
95
+ # Show first 5
96
+ SHOWN=0
97
+ while read -r item; do
98
+ [[ -z "$item" ]] && continue
99
+ if [[ $SHOWN -lt 5 ]]; then
100
+ echo " $item"
101
+ SHOWN=$((SHOWN + 1))
102
+ fi
103
+ done <<< "$ITEMS"
104
+
105
+ if [[ $COUNT -gt 5 ]]; then
106
+ echo " ... and $((COUNT - 5)) more"
107
+ fi
108
+ echo ""
109
+ fi
110
+ done
111
+
112
+ if [[ "$HAS_OUTPUT" == "false" ]]; then
113
+ echo "No increments found."
114
+ fi
115
+
116
+ # Summary line
117
+ TOTAL=$(jq '.summary.total // 0' "$CACHE_FILE")
118
+ ACTIVE=$(jq '.summary.active // 0' "$CACHE_FILE")
119
+ COMPLETED=$(jq '.summary.completed // 0' "$CACHE_FILE")
120
+ ARCHIVED=$(jq '.summary.archived // 0' "$CACHE_FILE")
121
+
122
+ echo "────────────────────────────────────────"
123
+ echo "Total: $TOTAL increment(s) | Active: $ACTIVE | Completed: $COMPLETED | Archived: $ARCHIVED"
124
+
125
+ # Show cache age in debug mode
126
+ if [[ "${DEBUG:-}" == "1" ]] || [[ "${SPECWEAVE_DEBUG:-}" == "1" ]]; then
127
+ CACHE_MTIME=$(stat -f %m "$CACHE_FILE" 2>/dev/null || stat -c %Y "$CACHE_FILE" 2>/dev/null)
128
+ NOW=$(date +%s)
129
+ AGE_SECONDS=$((NOW - CACHE_MTIME))
130
+ if [[ $AGE_SECONDS -lt 60 ]]; then
131
+ AGE_STR="${AGE_SECONDS}s ago"
132
+ elif [[ $AGE_SECONDS -lt 3600 ]]; then
133
+ AGE_STR="$((AGE_SECONDS / 60))m ago"
134
+ else
135
+ AGE_STR="$((AGE_SECONDS / 3600))h ago"
136
+ fi
137
+ CACHE_VERSION=$(jq -r '.version // "?"' "$CACHE_FILE")
138
+ echo ""
139
+ echo "🔧 Debug: Cache v${CACHE_VERSION}, updated ${AGE_STR}"
140
+ fi
141
+
142
+ echo ""
143
+ echo "💡 Commands:"
144
+ echo " /specweave:progress Show task progress"
145
+ echo " /specweave:do Execute current tasks"
146
+ echo " /specweave:done <id> Close increment"
@@ -0,0 +1,173 @@
1
+ #!/usr/bin/env bash
2
+ # read-workflow.sh - Pure bash reader for /specweave:workflow
3
+ #
4
+ # Shows current phase, suggests next actions based on increment state.
5
+ # Reads from pre-computed dashboard cache for <10ms response time.
6
+ #
7
+ # Usage: bash read-workflow.sh [incrementId]
8
+ #
9
+ # Compatible with bash 3.x (macOS default)
10
+
11
+ set -e
12
+
13
+ INCREMENT_ID="${1:-}"
14
+
15
+ # Find project root
16
+ PROJECT_ROOT="$PWD"
17
+ while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -d "$PROJECT_ROOT/.specweave" ]]; do
18
+ PROJECT_ROOT=$(dirname "$PROJECT_ROOT")
19
+ done
20
+
21
+ if [[ ! -d "$PROJECT_ROOT/.specweave" ]]; then
22
+ echo "No SpecWeave project found (missing .specweave/)"
23
+ exit 0
24
+ fi
25
+
26
+ CACHE_FILE="$PROJECT_ROOT/.specweave/state/dashboard.json"
27
+ SCRIPTS_DIR="$(dirname "${BASH_SOURCE[0]}")"
28
+
29
+ # Check if jq is available
30
+ if ! command -v jq >/dev/null 2>&1; then
31
+ echo "❌ jq required for workflow command. Install with: brew install jq"
32
+ exit 1
33
+ fi
34
+
35
+ # If cache doesn't exist or is corrupted, rebuild it
36
+ NEED_REBUILD=false
37
+ if [[ ! -f "$CACHE_FILE" ]]; then
38
+ NEED_REBUILD=true
39
+ elif ! jq -e '.' "$CACHE_FILE" >/dev/null 2>&1; then
40
+ # Cache exists but is corrupted (invalid JSON)
41
+ NEED_REBUILD=true
42
+ fi
43
+
44
+ if [[ "$NEED_REBUILD" == "true" ]]; then
45
+ bash "$SCRIPTS_DIR/rebuild-dashboard-cache.sh" --quiet 2>/dev/null || true
46
+ fi
47
+
48
+ if [[ ! -f "$CACHE_FILE" ]] || ! jq -e '.' "$CACHE_FILE" >/dev/null 2>&1; then
49
+ echo "❌ Cache unavailable. Try: bash plugins/specweave/scripts/rebuild-dashboard-cache.sh"
50
+ exit 1
51
+ fi
52
+
53
+ echo ""
54
+ echo "📋 SpecWeave Workflow Navigator"
55
+ echo ""
56
+
57
+ # Get active increment (or use provided ID)
58
+ if [[ -n "$INCREMENT_ID" ]]; then
59
+ # Find full ID
60
+ ACTIVE_ID=$(jq -r --arg id "$INCREMENT_ID" '
61
+ .increments | keys[] | select(. == $id or startswith($id))
62
+ ' "$CACHE_FILE" | head -1)
63
+ else
64
+ # Find first active increment
65
+ ACTIVE_ID=$(jq -r '
66
+ .increments | to_entries[] |
67
+ select(.value.status == "active" or .value.status == "in-progress") |
68
+ .key
69
+ ' "$CACHE_FILE" 2>/dev/null | head -1)
70
+ fi
71
+
72
+ if [[ -z "$ACTIVE_ID" ]]; then
73
+ echo "📭 No Active Increment"
74
+ echo ""
75
+ echo "Ready to start something new!"
76
+ echo ""
77
+
78
+ # Check for backlog items
79
+ BACKLOG_COUNT=$(jq '.summary.backlog // 0' "$CACHE_FILE")
80
+ if [[ "$BACKLOG_COUNT" -gt 0 ]]; then
81
+ echo "📋 Backlog: $BACKLOG_COUNT item(s) waiting"
82
+ echo " Resume with: /specweave:resume <id>"
83
+ echo ""
84
+ fi
85
+
86
+ echo "💡 Suggestions:"
87
+ echo " • /specweave:increment \"feature name\" - Plan new work"
88
+ echo " • /specweave:status - View all increments"
89
+ exit 0
90
+ fi
91
+
92
+ # Get increment data
93
+ INC_DATA=$(jq --arg id "$ACTIVE_ID" '.increments[$id]' "$CACHE_FILE")
94
+ STATUS=$(echo "$INC_DATA" | jq -r '.status // "unknown"')
95
+ TYPE=$(echo "$INC_DATA" | jq -r '.type // "feature"')
96
+ TASKS_TOTAL=$(echo "$INC_DATA" | jq -r '.tasks.total // 0')
97
+ TASKS_COMPLETED=$(echo "$INC_DATA" | jq -r '.tasks.completed // 0')
98
+ ACS_TOTAL=$(echo "$INC_DATA" | jq -r '.acs.total // 0')
99
+ ACS_COMPLETED=$(echo "$INC_DATA" | jq -r '.acs.completed // 0')
100
+
101
+ # Calculate percentages
102
+ if [[ "$TASKS_TOTAL" -gt 0 ]]; then
103
+ TASK_PCT=$((TASKS_COMPLETED * 100 / TASKS_TOTAL))
104
+ else
105
+ TASK_PCT=0
106
+ fi
107
+
108
+ if [[ "$ACS_TOTAL" -gt 0 ]]; then
109
+ AC_PCT=$((ACS_COMPLETED * 100 / ACS_TOTAL))
110
+ else
111
+ AC_PCT=0
112
+ fi
113
+
114
+ # Determine phase and suggestions
115
+ PHASE=""
116
+ SUGGESTIONS=""
117
+
118
+ if [[ "$STATUS" == "backlog" ]] || [[ "$STATUS" == "planned" ]]; then
119
+ PHASE="📝 Planning"
120
+ SUGGESTIONS="• /specweave:do - Start implementation
121
+ • /specweave:plan - Generate plan.md and tasks.md"
122
+
123
+ elif [[ "$TASKS_COMPLETED" -eq 0 ]]; then
124
+ PHASE="🚀 Starting"
125
+ SUGGESTIONS="• /specweave:do - Execute first task
126
+ • /specweave:pause - Pause if not ready"
127
+
128
+ elif [[ "$TASK_PCT" -lt 50 ]]; then
129
+ PHASE="🔨 In Progress (Early)"
130
+ SUGGESTIONS="• /specweave:do - Continue implementation
131
+ • /specweave:progress - Check task details"
132
+
133
+ elif [[ "$TASK_PCT" -lt 100 ]]; then
134
+ PHASE="⚙️ In Progress (Late)"
135
+ SUGGESTIONS="• /specweave:do - Complete remaining tasks
136
+ • /specweave:validate - Early quality check"
137
+
138
+ elif [[ "$STATUS" == "ready_for_review" ]]; then
139
+ PHASE="👀 Review"
140
+ SUGGESTIONS="• /specweave:validate - Full validation
141
+ • /specweave:done - Close increment (PM approval)"
142
+
143
+ elif [[ "$TASKS_COMPLETED" -eq "$TASKS_TOTAL" ]]; then
144
+ PHASE="✅ Tasks Complete"
145
+ SUGGESTIONS="• /specweave:validate - Run quality checks
146
+ • /specweave:done - Close increment"
147
+
148
+ else
149
+ PHASE="❓ Unknown"
150
+ SUGGESTIONS="• /specweave:status - Check status"
151
+ fi
152
+
153
+ # Display
154
+ echo "📍 Current Increment: $ACTIVE_ID"
155
+ echo ""
156
+ echo "Status: $STATUS"
157
+ echo "Type: $TYPE"
158
+ echo "Phase: $PHASE"
159
+ echo ""
160
+ echo "Progress:"
161
+ echo " Tasks: $TASKS_COMPLETED/$TASKS_TOTAL ($TASK_PCT%)"
162
+ echo " ACs: $ACS_COMPLETED/$ACS_TOTAL ($AC_PCT%)"
163
+ echo ""
164
+ echo "💡 Next Actions:"
165
+ echo "$SUGGESTIONS"
166
+ echo ""
167
+
168
+ # Additional context
169
+ PAUSED_COUNT=$(jq '.summary.paused // 0' "$CACHE_FILE")
170
+ if [[ "$PAUSED_COUNT" -gt 0 ]]; then
171
+ echo "ℹ️ $PAUSED_COUNT paused increment(s) - /specweave:resume to continue"
172
+ echo ""
173
+ fi