specweave 0.23.16 → 0.24.0
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-plugin/marketplace.json +93 -38
- package/CLAUDE.md +159 -11
- package/dist/plugins/specweave-github/lib/github-spec-content-sync.d.ts.map +1 -1
- package/dist/plugins/specweave-github/lib/github-spec-content-sync.js +57 -0
- package/dist/plugins/specweave-github/lib/github-spec-content-sync.js.map +1 -1
- package/dist/src/cli/commands/sync-spec-content.js +3 -0
- package/dist/src/cli/commands/sync-spec-content.js.map +1 -1
- package/dist/src/cli/helpers/ado-area-path-mapper.d.ts +89 -0
- package/dist/src/cli/helpers/ado-area-path-mapper.d.ts.map +1 -0
- package/dist/src/cli/helpers/ado-area-path-mapper.js +213 -0
- package/dist/src/cli/helpers/ado-area-path-mapper.js.map +1 -0
- package/dist/src/cli/helpers/issue-tracker/ado-auto-discover.d.ts +29 -0
- package/dist/src/cli/helpers/issue-tracker/ado-auto-discover.d.ts.map +1 -0
- package/dist/src/cli/helpers/issue-tracker/ado-auto-discover.js +109 -0
- package/dist/src/cli/helpers/issue-tracker/ado-auto-discover.js.map +1 -0
- package/dist/src/cli/helpers/issue-tracker/ado.d.ts +1 -0
- package/dist/src/cli/helpers/issue-tracker/ado.d.ts.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/ado.js +2 -0
- package/dist/src/cli/helpers/issue-tracker/ado.js.map +1 -1
- package/dist/src/cli/helpers/smart-filter.d.ts +83 -0
- package/dist/src/cli/helpers/smart-filter.d.ts.map +1 -0
- package/dist/src/cli/helpers/smart-filter.js +265 -0
- package/dist/src/cli/helpers/smart-filter.js.map +1 -0
- package/dist/src/core/progress/progress-tracker.d.ts +4 -1
- package/dist/src/core/progress/progress-tracker.d.ts.map +1 -1
- package/dist/src/core/progress/progress-tracker.js +33 -4
- package/dist/src/core/progress/progress-tracker.js.map +1 -1
- package/dist/src/core/qa/quality-gate-decider.d.ts +1 -1
- package/dist/src/core/qa/quality-gate-decider.js +2 -2
- package/dist/src/core/qa/quality-gate-decider.js.map +1 -1
- package/dist/src/core/qa/risk-calculator.d.ts +2 -2
- package/dist/src/core/qa/risk-calculator.js +2 -2
- package/dist/src/core/spec-content-sync.d.ts +1 -1
- package/dist/src/core/spec-content-sync.d.ts.map +1 -1
- package/dist/src/core/validators/ac-presence-validator.d.ts +56 -0
- package/dist/src/core/validators/ac-presence-validator.d.ts.map +1 -0
- package/dist/src/core/validators/ac-presence-validator.js +149 -0
- package/dist/src/core/validators/ac-presence-validator.js.map +1 -0
- package/dist/src/integrations/ado/ado-dependency-loader.d.ts +1 -1
- package/dist/src/integrations/ado/ado-dependency-loader.d.ts.map +1 -1
- package/dist/src/integrations/ado/ado-dependency-loader.js +39 -7
- package/dist/src/integrations/ado/ado-dependency-loader.js.map +1 -1
- package/dist/src/integrations/ado/area-path-mapper.d.ts +137 -0
- package/dist/src/integrations/ado/area-path-mapper.d.ts.map +1 -0
- package/dist/src/integrations/ado/area-path-mapper.js +267 -0
- package/dist/src/integrations/ado/area-path-mapper.js.map +1 -0
- package/dist/src/integrations/jira/filter-processor.d.ts +126 -0
- package/dist/src/integrations/jira/filter-processor.d.ts.map +1 -0
- package/dist/src/integrations/jira/filter-processor.js +207 -0
- package/dist/src/integrations/jira/filter-processor.js.map +1 -0
- package/dist/src/integrations/jira/jira-client.d.ts +13 -0
- package/dist/src/integrations/jira/jira-client.d.ts.map +1 -1
- package/dist/src/integrations/jira/jira-client.js +33 -0
- package/dist/src/integrations/jira/jira-client.js.map +1 -1
- package/dist/src/utils/ac-embedder.d.ts +63 -0
- package/dist/src/utils/ac-embedder.d.ts.map +1 -0
- package/dist/src/utils/ac-embedder.js +217 -0
- package/dist/src/utils/ac-embedder.js.map +1 -0
- package/dist/src/utils/env-manager.d.ts +86 -0
- package/dist/src/utils/env-manager.d.ts.map +1 -0
- package/dist/src/utils/env-manager.js +188 -0
- package/dist/src/utils/env-manager.js.map +1 -0
- package/package.json +1 -1
- package/plugins/specweave/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave/agents/AGENTS-INDEX.md +1 -1
- package/plugins/specweave/agents/increment-quality-judge-v2/AGENT.md +9 -9
- package/plugins/specweave/commands/specweave-do.md +37 -0
- package/plugins/specweave/commands/specweave-done.md +159 -0
- package/plugins/specweave/commands/specweave-embed-acs.md +446 -0
- package/plugins/specweave/commands/specweave-next.md +148 -3
- package/plugins/specweave/commands/specweave-qa.md +2 -2
- package/plugins/specweave/hooks/lib/migrate-increment-work.sh +1 -1
- package/plugins/specweave/hooks/lib/migrate-increment-work.sh.bak +245 -0
- package/plugins/specweave/hooks/lib/sync-spec-content.sh +2 -2
- package/plugins/specweave/hooks/lib/sync-spec-content.sh.bak +149 -0
- package/plugins/specweave/hooks/lib/update-status-line.sh +34 -4
- package/plugins/specweave/hooks/lib/validate-spec-status.sh +1 -1
- package/plugins/specweave/hooks/lib/validate-spec-status.sh.bak +163 -0
- package/plugins/specweave/hooks/post-first-increment.sh +1 -1
- package/plugins/specweave/hooks/post-first-increment.sh.bak +61 -0
- package/plugins/specweave/hooks/post-spec-update.sh +1 -1
- package/plugins/specweave/hooks/post-spec-update.sh.bak +158 -0
- package/plugins/specweave/hooks/post-user-story-complete.sh +1 -1
- package/plugins/specweave/hooks/post-user-story-complete.sh.bak +179 -0
- package/plugins/specweave/hooks/pre-command-deduplication.sh +1 -1
- package/plugins/specweave/hooks/pre-command-deduplication.sh.bak +83 -0
- package/plugins/specweave/hooks/pre-increment-start.sh +168 -0
- package/plugins/specweave/hooks/user-prompt-submit.sh +1 -1
- package/plugins/specweave/hooks/user-prompt-submit.sh.bak +386 -0
- package/plugins/specweave/skills/SKILLS-INDEX.md +1 -1
- package/plugins/specweave/skills/specweave-framework/SKILL.md +1 -1
- package/plugins/specweave-ado/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-ado/agents/ado-manager/AGENT.md +23 -0
- package/plugins/specweave-ado/agents/ado-multi-project-mapper/AGENT.md +23 -0
- package/plugins/specweave-ado/agents/ado-sync-judge/AGENT.md +23 -0
- package/plugins/specweave-ado/commands/specweave-ado-import-projects.md +331 -0
- package/plugins/specweave-alternatives/.claude-plugin/plugin.json +10 -0
- package/plugins/specweave-alternatives/commands/alternatives-analyze.md +336 -0
- package/plugins/specweave-alternatives/skills/architecture-alternatives/SKILL.md +651 -0
- package/plugins/specweave-alternatives/skills/bmad-method/SKILL.md +420 -0
- package/plugins/specweave-alternatives/skills/spec-kit-expert/SKILL.md +487 -0
- package/plugins/specweave-backend/agents/database-optimizer/AGENT.md +23 -0
- package/plugins/specweave-backend/commands/api-scaffold.md +80 -0
- package/plugins/specweave-backend/commands/crud-generate.md +109 -0
- package/plugins/specweave-backend/commands/migration-generate.md +139 -0
- package/plugins/specweave-confluent/agents/confluent-architect/AGENT.md +23 -0
- package/plugins/specweave-confluent/commands/connector-deploy.md +154 -0
- package/plugins/specweave-confluent/commands/ksqldb-query.md +179 -0
- package/plugins/specweave-confluent/commands/schema-register.md +123 -0
- package/plugins/specweave-core/.claude-plugin/plugin.json +21 -0
- package/plugins/specweave-core/commands/architecture-review.md +288 -0
- package/plugins/specweave-core/commands/code-review.md +213 -0
- package/plugins/specweave-core/commands/refactor-plan.md +249 -0
- package/plugins/specweave-core/skills/code-quality/SKILL.md +157 -0
- package/plugins/specweave-core/skills/design-patterns/SKILL.md +244 -0
- package/plugins/specweave-core/skills/software-architecture/SKILL.md +83 -0
- package/plugins/specweave-cost-optimizer/.claude-plugin/plugin.json +22 -0
- package/plugins/specweave-cost-optimizer/commands/cost-analyze.md +360 -0
- package/plugins/specweave-cost-optimizer/commands/cost-optimize.md +480 -0
- package/plugins/specweave-cost-optimizer/skills/aws-cost-expert/SKILL.md +416 -0
- package/plugins/specweave-cost-optimizer/skills/cloud-pricing/SKILL.md +325 -0
- package/plugins/specweave-cost-optimizer/skills/cost-optimization/SKILL.md +337 -0
- package/plugins/specweave-diagrams/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-diagrams/agents/diagrams-architect/AGENT.md +23 -0
- package/plugins/specweave-diagrams/commands/diagrams-generate.md +168 -0
- package/plugins/specweave-docs/.claude-plugin/plugin.json +10 -0
- package/plugins/specweave-docs/commands/docs-generate.md +441 -0
- package/plugins/specweave-docs/commands/docs-init.md +334 -0
- package/plugins/specweave-docs/skills/docusaurus/SKILL.md +581 -0
- package/plugins/specweave-docs/skills/spec-driven-brainstorming/SKILL.md +689 -0
- package/plugins/specweave-docs/skills/technical-writing/SKILL.md +1039 -0
- package/plugins/specweave-docs-preview/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-figma/.claude-plugin/plugin.json +23 -0
- package/plugins/specweave-figma/commands/figma-import.md +690 -0
- package/plugins/specweave-figma/commands/figma-to-react.md +834 -0
- package/plugins/specweave-figma/commands/figma-tokens.md +815 -0
- package/plugins/specweave-frontend/.claude-plugin/plugin.json +21 -0
- package/plugins/specweave-frontend/agents/frontend-architect/AGENT.md +387 -0
- package/plugins/specweave-frontend/agents/frontend-architect/README.md +385 -0
- package/plugins/specweave-frontend/agents/frontend-architect/examples.md +590 -0
- package/plugins/specweave-frontend/agents/frontend-architect/templates/component-template.tsx +152 -0
- package/plugins/specweave-frontend/agents/frontend-architect/templates/hook-template.ts +311 -0
- package/plugins/specweave-frontend/agents/frontend-architect/templates/page-template.tsx +228 -0
- package/plugins/specweave-frontend/commands/component-generate.md +510 -0
- package/plugins/specweave-frontend/commands/design-system-init.md +494 -0
- package/plugins/specweave-frontend/commands/frontend-scaffold.md +207 -0
- package/plugins/specweave-frontend/commands/nextjs-setup.md +396 -0
- package/plugins/specweave-frontend/skills/design-system-architect/SKILL.md +278 -0
- package/plugins/specweave-frontend/skills/frontend/SKILL.md +420 -0
- package/plugins/specweave-frontend/skills/nextjs/SKILL.md +546 -0
- package/plugins/specweave-github/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-github/agents/github-manager/AGENT.md +23 -0
- package/plugins/specweave-github/agents/github-task-splitter/AGENT.md +25 -0
- package/plugins/specweave-github/agents/user-story-updater/AGENT.md +25 -0
- package/plugins/specweave-github/hooks/.specweave/logs/hooks-debug.log +194 -0
- package/plugins/specweave-github/lib/github-spec-content-sync.js +49 -0
- package/plugins/specweave-github/lib/github-spec-content-sync.ts +67 -0
- package/plugins/specweave-infrastructure/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-infrastructure/agents/devops/AGENT.md +26 -0
- package/plugins/specweave-infrastructure/agents/network-engineer/AGENT.md +26 -0
- package/plugins/specweave-infrastructure/agents/observability-engineer/AGENT.md +26 -0
- package/plugins/specweave-infrastructure/agents/performance-engineer/AGENT.md +26 -0
- package/plugins/specweave-infrastructure/agents/sre/AGENT.md +26 -0
- package/plugins/specweave-jira/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-jira/agents/jira-manager/AGENT.md +26 -0
- package/plugins/specweave-jira/commands/import-projects.js +183 -0
- package/plugins/specweave-jira/commands/import-projects.md +97 -0
- package/plugins/specweave-jira/commands/import-projects.ts +288 -0
- package/plugins/specweave-jira/commands/specweave-jira-import-projects.md +298 -0
- package/plugins/specweave-kafka/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-kafka/agents/kafka-architect/AGENT.md +26 -0
- package/plugins/specweave-kafka/agents/kafka-devops/AGENT.md +26 -0
- package/plugins/specweave-kafka/agents/kafka-observability/AGENT.md +26 -0
- package/plugins/specweave-kafka-streams/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-kubernetes/agents/kubernetes-architect/AGENT.md +26 -0
- package/plugins/specweave-kubernetes/commands/cluster-setup.md +262 -0
- package/plugins/specweave-kubernetes/commands/deployment-generate.md +242 -0
- package/plugins/specweave-kubernetes/commands/helm-scaffold.md +333 -0
- package/plugins/specweave-ml/.claude-plugin/plugin.json +3 -3
- package/plugins/specweave-ml/agents/data-scientist/AGENT.md +26 -0
- package/plugins/specweave-ml/agents/ml-engineer/AGENT.md +26 -0
- package/plugins/specweave-ml/agents/mlops-engineer/AGENT.md +26 -0
- package/plugins/specweave-mobile/agents/mobile-architect/AGENT.md +26 -0
- package/plugins/specweave-mobile/commands/app-scaffold.md +233 -0
- package/plugins/specweave-mobile/commands/build-config.md +256 -0
- package/plugins/specweave-mobile/commands/screen-generate.md +289 -0
- package/plugins/specweave-n8n/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-payments/agents/payment-integration/AGENT.md +26 -0
- package/plugins/specweave-plugin-dev/.claude-plugin/plugin.json +20 -0
- package/plugins/specweave-plugin-dev/commands/plugin-create.md +333 -0
- package/plugins/specweave-plugin-dev/commands/plugin-publish.md +339 -0
- package/plugins/specweave-plugin-dev/commands/plugin-test.md +293 -0
- package/plugins/specweave-plugin-dev/skills/claude-sdk/SKILL.md +162 -0
- package/plugins/specweave-plugin-dev/skills/marketplace-publishing/SKILL.md +263 -0
- package/plugins/specweave-plugin-dev/skills/plugin-development/SKILL.md +316 -0
- package/plugins/specweave-release/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-release/agents/release-manager/AGENT.md +27 -0
- package/plugins/specweave-release/commands/specweave-release-npm.md +110 -0
- package/plugins/specweave-release/hooks/.specweave/logs/dora-tracking.log +168 -0
- package/plugins/specweave-testing/.claude-plugin/plugin.json +21 -0
- package/plugins/specweave-testing/agents/qa-engineer/AGENT.md +797 -0
- package/plugins/specweave-testing/agents/qa-engineer/README.md +443 -0
- package/plugins/specweave-testing/agents/qa-engineer/templates/playwright-e2e-test.ts +470 -0
- package/plugins/specweave-testing/agents/qa-engineer/templates/test-data-factory.ts +507 -0
- package/plugins/specweave-testing/agents/qa-engineer/templates/vitest-unit-test.ts +400 -0
- package/plugins/specweave-testing/agents/qa-engineer/test-strategies.md +726 -0
- package/plugins/specweave-testing/commands/e2e-setup.md +1081 -0
- package/plugins/specweave-testing/commands/test-coverage.md +979 -0
- package/plugins/specweave-testing/commands/test-generate.md +1156 -0
- package/plugins/specweave-testing/commands/test-init.md +409 -0
- package/plugins/specweave-testing/skills/e2e-playwright/SKILL.md +769 -0
- package/plugins/specweave-testing/skills/tdd-expert/SKILL.md +934 -0
- package/plugins/specweave-testing/skills/unit-testing-expert/SKILL.md +1011 -0
- package/plugins/specweave-tooling/.claude-plugin/plugin.json +22 -0
- package/plugins/specweave-tooling/commands/specweave-tooling-skill-create.md +691 -0
- package/plugins/specweave-tooling/commands/specweave-tooling-skill-package.md +751 -0
- package/plugins/specweave-tooling/commands/specweave-tooling-skill-validate.md +858 -0
- package/plugins/specweave-ui/.claude-plugin/plugin.json +10 -0
- package/plugins/specweave-ui/commands/ui-automate.md +199 -0
- package/plugins/specweave-ui/commands/ui-inspect.md +70 -0
- package/plugins/specweave-ui/skills/browser-automation/SKILL.md +314 -0
- package/plugins/specweave-ui/skills/ui-testing/SKILL.md +716 -0
- package/plugins/specweave-ui/skills/visual-regression/SKILL.md +728 -0
- package/plugins/specweave/commands/check-hooks.md +0 -257
- package/plugins/specweave/commands/specweave-archive-increments.md +0 -82
- package/plugins/specweave/skills/plugin-expert/SKILL.md +0 -340
- /package/plugins/specweave/{agents/code-reviewer.md → skills/code-reviewer/SKILL.md} +0 -0
|
@@ -0,0 +1,245 @@
|
|
|
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
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
# sync-spec-content.sh <spec-path>
|
|
16
16
|
#
|
|
17
17
|
|
|
18
|
-
set -euo pipefail
|
|
18
|
+
set +e # EMERGENCY FIX: Changed from set -euo pipefail to prevent Claude Code crashes
|
|
19
19
|
|
|
20
20
|
# Get script directory
|
|
21
21
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
@@ -131,7 +131,7 @@ echo ""
|
|
|
131
131
|
set +e
|
|
132
132
|
node "$SYNC_CLI" --spec "$SPEC_PATH" --provider "$PROVIDER"
|
|
133
133
|
SYNC_EXIT_CODE=$?
|
|
134
|
-
set -e
|
|
134
|
+
set +e # EMERGENCY FIX: Changed from set -e to prevent Claude Code crashes
|
|
135
135
|
|
|
136
136
|
if [ $SYNC_EXIT_CODE -eq 0 ]; then
|
|
137
137
|
echo ""
|
|
@@ -0,0 +1,149 @@
|
|
|
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
|
|
@@ -14,8 +14,12 @@
|
|
|
14
14
|
# 6. Write to cache
|
|
15
15
|
#
|
|
16
16
|
# Performance: 50-100ms (runs async, user doesn't wait)
|
|
17
|
+
#
|
|
18
|
+
# EMERGENCY FIX (v0.24.4): Changed from set -euo pipefail to set +e
|
|
19
|
+
# CRITICAL: Hooks MUST use set +e to prevent Claude Code crashes!
|
|
20
|
+
# See: CLAUDE.md section 9a - Hook Performance & Safety
|
|
17
21
|
|
|
18
|
-
set
|
|
22
|
+
set +e
|
|
19
23
|
|
|
20
24
|
# Find project root
|
|
21
25
|
find_project_root() {
|
|
@@ -149,8 +153,20 @@ INCREMENT_ID=$(echo "$CURRENT_INCREMENT" | grep -oE '^[0-9]{4}')
|
|
|
149
153
|
INCREMENT_NAME_ONLY=$(echo "$CURRENT_INCREMENT" | sed 's/^[0-9]\{4\}-//')
|
|
150
154
|
INCREMENT_NAME="$INCREMENT_ID-$INCREMENT_NAME_ONLY"
|
|
151
155
|
|
|
152
|
-
# Step 6: Write cache (
|
|
153
|
-
|
|
156
|
+
# Step 6: Write cache with atomic validation (v0.24.4 - prevents corruption)
|
|
157
|
+
TMP_CACHE_FILE="$PROJECT_ROOT/.specweave/state/.status-line-tmp.json"
|
|
158
|
+
|
|
159
|
+
# Validate all numeric inputs before jq (prevents jq failures)
|
|
160
|
+
[[ "$TOTAL_TASKS" =~ ^[0-9]+$ ]] || TOTAL_TASKS=0
|
|
161
|
+
[[ "$COMPLETED_TASKS" =~ ^[0-9]+$ ]] || COMPLETED_TASKS=0
|
|
162
|
+
[[ "$PERCENTAGE" =~ ^[0-9]+$ ]] || PERCENTAGE=0
|
|
163
|
+
[[ "$TOTAL_ACS" =~ ^[0-9]+$ ]] || TOTAL_ACS=0
|
|
164
|
+
[[ "$COMPLETED_ACS" =~ ^[0-9]+$ ]] || COMPLETED_ACS=0
|
|
165
|
+
[[ "$OPEN_ACS" =~ ^[0-9]+$ ]] || OPEN_ACS=0
|
|
166
|
+
[[ "$OPEN_COUNT" =~ ^[0-9]+$ ]] || OPEN_COUNT=0
|
|
167
|
+
|
|
168
|
+
# Generate cache to temp file first (atomic operation)
|
|
169
|
+
if jq -n \
|
|
154
170
|
--arg id "$CURRENT_INCREMENT" \
|
|
155
171
|
--arg name "$INCREMENT_NAME" \
|
|
156
172
|
--argjson completed "$COMPLETED_TASKS" \
|
|
@@ -171,6 +187,20 @@ jq -n \
|
|
|
171
187
|
},
|
|
172
188
|
openCount: $openCount,
|
|
173
189
|
lastUpdate: (now | strftime("%Y-%m-%dT%H:%M:%SZ"))
|
|
174
|
-
}' > "$
|
|
190
|
+
}' > "$TMP_CACHE_FILE" 2>/dev/null; then
|
|
191
|
+
|
|
192
|
+
# Validate generated JSON before replacing cache (corruption prevention)
|
|
193
|
+
if jq empty "$TMP_CACHE_FILE" 2>/dev/null; then
|
|
194
|
+
mv "$TMP_CACHE_FILE" "$CACHE_FILE"
|
|
195
|
+
else
|
|
196
|
+
# Invalid JSON generated - keep old cache
|
|
197
|
+
echo "[$(date)] ERROR: Generated invalid JSON, keeping old cache" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
198
|
+
rm -f "$TMP_CACHE_FILE"
|
|
199
|
+
fi
|
|
200
|
+
else
|
|
201
|
+
# jq generation failed - keep old cache
|
|
202
|
+
echo "[$(date)] ERROR: jq failed to generate status cache (exit $?)" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
203
|
+
rm -f "$TMP_CACHE_FILE"
|
|
204
|
+
fi
|
|
175
205
|
|
|
176
206
|
exit 0
|
|
@@ -0,0 +1,163 @@
|
|
|
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
|