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.
- package/CLAUDE.md +176 -2
- package/README.md +22 -0
- package/bin/specweave.js +18 -1
- package/dist/src/cli/commands/cache.d.ts +17 -0
- package/dist/src/cli/commands/cache.d.ts.map +1 -0
- package/dist/src/cli/commands/cache.js +126 -0
- package/dist/src/cli/commands/cache.js.map +1 -0
- package/dist/src/cli/commands/init.js +1 -1
- package/dist/src/cli/commands/init.js.map +1 -1
- package/dist/src/cli/commands/plan/increment-detector.js +2 -2
- package/dist/src/cli/commands/plan/increment-detector.js.map +1 -1
- package/dist/src/cli/commands/sync-spec-commits.js +1 -1
- package/dist/src/cli/commands/sync-spec-commits.js.map +1 -1
- package/dist/src/cli/commands/sync-specs.js +2 -2
- package/dist/src/cli/commands/sync-specs.js.map +1 -1
- package/dist/src/cli/helpers/github/increment-profile-selector.js +1 -1
- package/dist/src/cli/helpers/github/increment-profile-selector.js.map +1 -1
- package/dist/src/cli/workers/living-docs-worker.js +66 -1
- package/dist/src/cli/workers/living-docs-worker.js.map +1 -1
- package/dist/src/config/types.d.ts +203 -1208
- package/dist/src/config/types.d.ts.map +1 -1
- package/dist/src/core/discrepancy/increment-generator.d.ts.map +1 -1
- package/dist/src/core/discrepancy/increment-generator.js +5 -2
- package/dist/src/core/discrepancy/increment-generator.js.map +1 -1
- package/dist/src/core/increment/duplicate-detector.js +2 -2
- package/dist/src/core/increment/duplicate-detector.js.map +1 -1
- package/dist/src/core/increment/increment-archiver.d.ts +24 -0
- package/dist/src/core/increment/increment-archiver.d.ts.map +1 -1
- package/dist/src/core/increment/increment-archiver.js +59 -2
- package/dist/src/core/increment/increment-archiver.js.map +1 -1
- package/dist/src/core/increment/increment-status.js +2 -2
- package/dist/src/core/increment/increment-status.js.map +1 -1
- package/dist/src/core/increment/increment-utils.d.ts +85 -0
- package/dist/src/core/increment/increment-utils.d.ts.map +1 -1
- package/dist/src/core/increment/increment-utils.js +102 -4
- package/dist/src/core/increment/increment-utils.js.map +1 -1
- package/dist/src/core/increment/metadata-validator.js +1 -1
- package/dist/src/core/increment/metadata-validator.js.map +1 -1
- package/dist/src/core/living-docs/feature-id-manager.js +1 -1
- package/dist/src/core/living-docs/feature-id-manager.js.map +1 -1
- package/dist/src/core/living-docs/hierarchy-mapper.js +3 -3
- package/dist/src/core/living-docs/hierarchy-mapper.js.map +1 -1
- package/dist/src/core/living-docs/intelligent-analyzer/architecture-generator.d.ts +18 -0
- package/dist/src/core/living-docs/intelligent-analyzer/architecture-generator.d.ts.map +1 -0
- package/dist/src/core/living-docs/intelligent-analyzer/architecture-generator.js +247 -0
- package/dist/src/core/living-docs/intelligent-analyzer/architecture-generator.js.map +1 -0
- package/dist/src/core/living-docs/intelligent-analyzer/deep-repo-analyzer.d.ts +15 -0
- package/dist/src/core/living-docs/intelligent-analyzer/deep-repo-analyzer.d.ts.map +1 -0
- package/dist/src/core/living-docs/intelligent-analyzer/deep-repo-analyzer.js +138 -0
- package/dist/src/core/living-docs/intelligent-analyzer/deep-repo-analyzer.js.map +1 -0
- package/dist/src/core/living-docs/intelligent-analyzer/file-sampler.d.ts +24 -0
- package/dist/src/core/living-docs/intelligent-analyzer/file-sampler.d.ts.map +1 -0
- package/dist/src/core/living-docs/intelligent-analyzer/file-sampler.js +198 -0
- package/dist/src/core/living-docs/intelligent-analyzer/file-sampler.js.map +1 -0
- package/dist/src/core/living-docs/intelligent-analyzer/inconsistency-detector.d.ts +17 -0
- package/dist/src/core/living-docs/intelligent-analyzer/inconsistency-detector.d.ts.map +1 -0
- package/dist/src/core/living-docs/intelligent-analyzer/inconsistency-detector.js +241 -0
- package/dist/src/core/living-docs/intelligent-analyzer/inconsistency-detector.js.map +1 -0
- package/dist/src/core/living-docs/intelligent-analyzer/index.d.ts +28 -0
- package/dist/src/core/living-docs/intelligent-analyzer/index.d.ts.map +1 -0
- package/dist/src/core/living-docs/intelligent-analyzer/index.js +197 -0
- package/dist/src/core/living-docs/intelligent-analyzer/index.js.map +1 -0
- package/dist/src/core/living-docs/intelligent-analyzer/organization-synthesizer.d.ts +18 -0
- package/dist/src/core/living-docs/intelligent-analyzer/organization-synthesizer.d.ts.map +1 -0
- package/dist/src/core/living-docs/intelligent-analyzer/organization-synthesizer.js +154 -0
- package/dist/src/core/living-docs/intelligent-analyzer/organization-synthesizer.js.map +1 -0
- package/dist/src/core/living-docs/intelligent-analyzer/strategy-generator.d.ts +42 -0
- package/dist/src/core/living-docs/intelligent-analyzer/strategy-generator.d.ts.map +1 -0
- package/dist/src/core/living-docs/intelligent-analyzer/strategy-generator.js +343 -0
- package/dist/src/core/living-docs/intelligent-analyzer/strategy-generator.js.map +1 -0
- package/dist/src/core/living-docs/intelligent-analyzer/types.d.ts +146 -0
- package/dist/src/core/living-docs/intelligent-analyzer/types.d.ts.map +1 -0
- package/dist/src/core/living-docs/intelligent-analyzer/types.js +7 -0
- package/dist/src/core/living-docs/intelligent-analyzer/types.js.map +1 -0
- package/dist/src/core/living-docs/living-docs-sync.d.ts +5 -0
- package/dist/src/core/living-docs/living-docs-sync.d.ts.map +1 -1
- package/dist/src/core/living-docs/living-docs-sync.js +36 -2
- package/dist/src/core/living-docs/living-docs-sync.js.map +1 -1
- package/dist/src/core/sync/spec-increment-mapper.js +3 -3
- package/dist/src/core/sync/spec-increment-mapper.js.map +1 -1
- package/dist/src/importers/item-converter.d.ts +25 -0
- package/dist/src/importers/item-converter.d.ts.map +1 -1
- package/dist/src/importers/item-converter.js +135 -5
- package/dist/src/importers/item-converter.js.map +1 -1
- package/dist/src/init/architecture/types.d.ts +33 -140
- package/dist/src/init/architecture/types.d.ts.map +1 -1
- package/dist/src/init/compliance/types.d.ts +30 -27
- package/dist/src/init/compliance/types.d.ts.map +1 -1
- package/dist/src/init/repo/types.d.ts +11 -34
- package/dist/src/init/repo/types.d.ts.map +1 -1
- package/dist/src/init/research/src/config/types.d.ts +15 -82
- package/dist/src/init/research/src/config/types.d.ts.map +1 -1
- package/dist/src/init/research/types.d.ts +38 -93
- package/dist/src/init/research/types.d.ts.map +1 -1
- package/dist/src/init/team/types.d.ts +4 -42
- package/dist/src/init/team/types.d.ts.map +1 -1
- package/dist/src/types/dashboard-cache.d.ts +181 -0
- package/dist/src/types/dashboard-cache.d.ts.map +1 -0
- package/dist/src/types/dashboard-cache.js +65 -0
- package/dist/src/types/dashboard-cache.js.map +1 -0
- package/dist/src/utils/docs-validator.d.ts +131 -0
- package/dist/src/utils/docs-validator.d.ts.map +1 -0
- package/dist/src/utils/docs-validator.js +529 -0
- package/dist/src/utils/docs-validator.js.map +1 -0
- package/dist/src/utils/feature-id-collision.js +1 -1
- package/dist/src/utils/feature-id-collision.js.map +1 -1
- package/dist/src/utils/html-to-mdx.d.ts +1 -0
- package/dist/src/utils/html-to-mdx.d.ts.map +1 -1
- package/dist/src/utils/html-to-mdx.js +43 -5
- package/dist/src/utils/html-to-mdx.js.map +1 -1
- package/package.json +1 -1
- package/plugins/specweave/agents/pm/AGENT.md +10 -7
- package/plugins/specweave/commands/specweave-archive-features.md +5 -7
- package/plugins/specweave/commands/specweave-archive.md +2 -1
- package/plugins/specweave/commands/specweave-do.md +35 -1
- package/plugins/specweave/commands/specweave-done.md +96 -0
- package/plugins/specweave/commands/specweave-import-external.md +45 -18
- package/plugins/specweave/commands/specweave-increment.md +331 -33
- package/plugins/specweave/commands/specweave-jobs.md +2 -2
- package/plugins/specweave/commands/specweave-progress.md +4 -4
- package/plugins/specweave/commands/specweave-restore-feature.md +5 -4
- package/plugins/specweave/commands/specweave-sync-docs.md +1 -1
- package/plugins/specweave/commands/specweave-sync-specs.md +216 -322
- package/plugins/specweave/commands/specweave-validate-features.md +13 -8
- package/plugins/specweave/hooks/docs-changed.sh.backup +79 -0
- package/plugins/specweave/hooks/hooks.json +33 -4
- package/plugins/specweave/hooks/human-input-required.sh.backup +75 -0
- package/plugins/specweave/hooks/lib/common-setup.sh +375 -0
- package/plugins/specweave/hooks/lib/crash-prevention.sh +336 -0
- package/plugins/specweave/hooks/post-first-increment.sh.backup +61 -0
- package/plugins/specweave/hooks/post-increment-change.sh.backup +98 -0
- package/plugins/specweave/hooks/post-increment-completion.sh.backup +231 -0
- package/plugins/specweave/hooks/post-increment-planning.sh.backup +1048 -0
- package/plugins/specweave/hooks/post-increment-status-change.sh.backup +147 -0
- package/plugins/specweave/hooks/post-spec-update.sh.backup +158 -0
- package/plugins/specweave/hooks/post-task-completion.sh +4 -23
- package/plugins/specweave/hooks/post-user-story-complete.sh.backup +179 -0
- package/plugins/specweave/hooks/pre-command-deduplication.sh +1 -6
- package/plugins/specweave/hooks/pre-command-deduplication.sh.backup +83 -0
- package/plugins/specweave/hooks/pre-implementation.sh.backup +67 -0
- package/plugins/specweave/hooks/pre-task-completion.sh +8 -37
- package/plugins/specweave/hooks/pre-task-completion.sh.backup +194 -0
- package/plugins/specweave/hooks/pre-tool-use.sh +2 -11
- package/plugins/specweave/hooks/pre-tool-use.sh.backup +133 -0
- package/plugins/specweave/hooks/universal/dispatcher.mjs +135 -42
- package/plugins/specweave/hooks/universal/fail-fast-wrapper.sh +183 -0
- package/plugins/specweave/hooks/user-prompt-submit.sh +140 -38
- package/plugins/specweave/hooks/user-prompt-submit.sh.backup +386 -0
- package/plugins/specweave/hooks/v2/dispatchers/post-tool-use.sh +12 -0
- package/plugins/specweave/hooks/v2/dispatchers/session-start.sh +89 -0
- package/plugins/specweave/hooks/v2/guards/bash-file-guard.sh +211 -0
- package/plugins/specweave/hooks/v2/guards/bash-file-guard.test.sh +163 -0
- package/plugins/specweave/hooks/v2/guards/completion-guard.sh +26 -28
- package/plugins/specweave/hooks/v2/guards/features-folder-guard.sh +50 -0
- package/plugins/specweave/lib/vendor/core/increment/duplicate-detector.js +2 -2
- package/plugins/specweave/lib/vendor/core/increment/duplicate-detector.js.map +1 -1
- package/plugins/specweave/scripts/README.md +166 -0
- package/plugins/specweave/scripts/cleanup-state.sh +142 -0
- package/plugins/specweave/scripts/force-kill.sh +142 -0
- package/plugins/specweave/scripts/jobs.js +171 -0
- package/plugins/specweave/scripts/progress.js +170 -0
- package/plugins/specweave/scripts/read-costs.sh +132 -0
- package/plugins/specweave/scripts/read-jobs.sh +324 -0
- package/plugins/specweave/scripts/read-progress.sh +185 -0
- package/plugins/specweave/scripts/read-status.sh +146 -0
- package/plugins/specweave/scripts/read-workflow.sh +173 -0
- package/plugins/specweave/scripts/rebuild-dashboard-cache.sh +327 -0
- package/plugins/specweave/scripts/session-watchdog.sh +192 -0
- package/plugins/specweave/scripts/status.js +154 -0
- package/plugins/specweave/scripts/update-dashboard-cache.sh +281 -0
- package/plugins/specweave/skills/increment-planner/SKILL.md +333 -24
- package/plugins/specweave/skills/increment-planner/templates/spec-multi-project.md +17 -9
- package/plugins/specweave/skills/increment-planner/templates/spec-single-project.md +6 -2
- package/plugins/specweave/skills/instant-status/SKILL.md +70 -0
- package/plugins/specweave-ado/hooks/post-living-docs-update.sh.backup +353 -0
- package/plugins/specweave-ado/hooks/post-task-completion.sh.backup +172 -0
- package/plugins/specweave-ado/lib/enhanced-ado-sync.js +170 -0
- package/plugins/specweave-docs/commands/build.md +32 -4
- package/plugins/specweave-docs/commands/preview.md +43 -1
- package/plugins/specweave-docs/commands/validate.md +250 -0
- package/plugins/specweave-github/hooks/.specweave/logs/hooks-debug.log +1262 -0
- package/plugins/specweave-github/hooks/post-task-completion.sh.backup +258 -0
- package/plugins/specweave-github/lib/enhanced-github-sync.js +220 -0
- package/plugins/specweave-jira/hooks/post-task-completion.sh.backup +172 -0
- package/plugins/specweave-jira/lib/enhanced-jira-sync.js +134 -0
- package/plugins/specweave-release/hooks/.specweave/logs/dora-tracking.log +1254 -0
- package/plugins/specweave-release/hooks/post-task-completion.sh.backup +110 -0
- package/plugins/specweave/hooks/post-edit-spec.sh +0 -265
- package/plugins/specweave/hooks/post-write-spec.sh +0 -267
- package/plugins/specweave/hooks/pre-edit-spec.sh +0 -151
- 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
|