specweave 0.6.7 ā 0.7.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/README.md +1 -1
- package/CLAUDE.md +920 -107
- package/README.md +143 -207
- package/bin/specweave.js +67 -0
- package/dist/adapters/adapter-interface.d.ts +11 -11
- package/dist/adapters/adapter-interface.d.ts.map +1 -1
- package/dist/adapters/adapter-interface.js +1 -1
- package/dist/adapters/adapter-loader.d.ts +1 -2
- package/dist/adapters/adapter-loader.d.ts.map +1 -1
- package/dist/adapters/adapter-loader.js +3 -6
- package/dist/adapters/adapter-loader.js.map +1 -1
- package/dist/adapters/agents-md-generator.d.ts +3 -3
- package/dist/adapters/agents-md-generator.js +3 -3
- package/dist/adapters/generic/adapter.d.ts +2 -2
- package/dist/adapters/generic/adapter.d.ts.map +1 -1
- package/dist/adapters/generic/adapter.js +28 -9
- package/dist/adapters/generic/adapter.js.map +1 -1
- package/dist/cli/commands/abandon.d.ts +13 -0
- package/dist/cli/commands/abandon.d.ts.map +1 -0
- package/dist/cli/commands/abandon.js +15 -0
- package/dist/cli/commands/abandon.js.map +1 -0
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +141 -40
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/pause.d.ts +13 -0
- package/dist/cli/commands/pause.d.ts.map +1 -0
- package/dist/cli/commands/pause.js +15 -0
- package/dist/cli/commands/pause.js.map +1 -0
- package/dist/cli/commands/qa.d.ts +54 -0
- package/dist/cli/commands/qa.d.ts.map +1 -0
- package/dist/cli/commands/qa.js +98 -0
- package/dist/cli/commands/qa.js.map +1 -0
- package/dist/cli/commands/resume.d.ts +12 -0
- package/dist/cli/commands/resume.d.ts.map +1 -0
- package/dist/cli/commands/resume.js +14 -0
- package/dist/cli/commands/resume.js.map +1 -0
- package/dist/cli/commands/status.d.ts +12 -0
- package/dist/cli/commands/status.d.ts.map +1 -0
- package/dist/cli/commands/status.js +23 -0
- package/dist/cli/commands/status.js.map +1 -0
- package/dist/cli/helpers/issue-tracker/ado.d.ts +57 -0
- package/dist/cli/helpers/issue-tracker/ado.d.ts.map +1 -0
- package/dist/cli/helpers/issue-tracker/ado.js +223 -0
- package/dist/cli/helpers/issue-tracker/ado.js.map +1 -0
- package/dist/cli/helpers/issue-tracker/github.d.ts +65 -0
- package/dist/cli/helpers/issue-tracker/github.d.ts.map +1 -0
- package/dist/cli/helpers/issue-tracker/github.js +284 -0
- package/dist/cli/helpers/issue-tracker/github.js.map +1 -0
- package/dist/cli/helpers/issue-tracker/index.d.ts +22 -0
- package/dist/cli/helpers/issue-tracker/index.d.ts.map +1 -0
- package/dist/cli/helpers/issue-tracker/index.js +270 -0
- package/dist/cli/helpers/issue-tracker/index.js.map +1 -0
- package/dist/cli/helpers/issue-tracker/jira.d.ts +61 -0
- package/dist/cli/helpers/issue-tracker/jira.d.ts.map +1 -0
- package/dist/cli/helpers/issue-tracker/jira.js +265 -0
- package/dist/cli/helpers/issue-tracker/jira.js.map +1 -0
- package/dist/cli/helpers/issue-tracker/types.d.ts +86 -0
- package/dist/cli/helpers/issue-tracker/types.d.ts.map +1 -0
- package/dist/cli/helpers/issue-tracker/types.js +16 -0
- package/dist/cli/helpers/issue-tracker/types.js.map +1 -0
- package/dist/cli/helpers/issue-tracker/utils.d.ts +103 -0
- package/dist/cli/helpers/issue-tracker/utils.d.ts.map +1 -0
- package/dist/cli/helpers/issue-tracker/utils.js +240 -0
- package/dist/cli/helpers/issue-tracker/utils.js.map +1 -0
- package/dist/core/increment/limits.d.ts +68 -0
- package/dist/core/increment/limits.d.ts.map +1 -0
- package/dist/core/increment/limits.js +224 -0
- package/dist/core/increment/limits.js.map +1 -0
- package/dist/core/increment/metadata-manager.d.ts +114 -0
- package/dist/core/increment/metadata-manager.d.ts.map +1 -0
- package/dist/core/increment/metadata-manager.js +320 -0
- package/dist/core/increment/metadata-manager.js.map +1 -0
- package/dist/core/increment/status-commands.d.ts +43 -0
- package/dist/core/increment/status-commands.d.ts.map +1 -0
- package/dist/core/increment/status-commands.js +277 -0
- package/dist/core/increment/status-commands.js.map +1 -0
- package/dist/core/plugin-detector.d.ts +1 -0
- package/dist/core/plugin-detector.d.ts.map +1 -1
- package/dist/core/plugin-detector.js +25 -0
- package/dist/core/plugin-detector.js.map +1 -1
- package/dist/core/qa/qa-runner.d.ts +16 -0
- package/dist/core/qa/qa-runner.d.ts.map +1 -0
- package/dist/core/qa/qa-runner.js +404 -0
- package/dist/core/qa/qa-runner.js.map +1 -0
- package/dist/core/qa/quality-gate-decider.d.ts +53 -0
- package/dist/core/qa/quality-gate-decider.d.ts.map +1 -0
- package/dist/core/qa/quality-gate-decider.js +268 -0
- package/dist/core/qa/quality-gate-decider.js.map +1 -0
- package/dist/core/qa/risk-calculator.d.ts +126 -0
- package/dist/core/qa/risk-calculator.d.ts.map +1 -0
- package/dist/core/qa/risk-calculator.js +247 -0
- package/dist/core/qa/risk-calculator.js.map +1 -0
- package/dist/core/qa/types.d.ts +315 -0
- package/dist/core/qa/types.d.ts.map +1 -0
- package/dist/core/qa/types.js +8 -0
- package/dist/core/qa/types.js.map +1 -0
- package/dist/core/types/config.d.ts +37 -2
- package/dist/core/types/config.d.ts.map +1 -1
- package/dist/core/types/config.js +16 -0
- package/dist/core/types/config.js.map +1 -1
- package/dist/core/types/increment-metadata.d.ts +120 -0
- package/dist/core/types/increment-metadata.d.ts.map +1 -0
- package/dist/core/types/increment-metadata.js +138 -0
- package/dist/core/types/increment-metadata.js.map +1 -0
- package/dist/hooks/lib/invoke-translator-skill.d.ts +60 -0
- package/dist/hooks/lib/invoke-translator-skill.d.ts.map +1 -0
- package/dist/hooks/lib/invoke-translator-skill.js +201 -0
- package/dist/hooks/lib/invoke-translator-skill.js.map +1 -0
- package/dist/hooks/lib/translate-file.d.ts +59 -0
- package/dist/hooks/lib/translate-file.d.ts.map +1 -0
- package/dist/hooks/lib/translate-file.js +350 -0
- package/dist/hooks/lib/translate-file.js.map +1 -0
- package/dist/locales/en/cli.json +3 -1
- package/dist/metrics/calculators/change-failure-rate.d.ts +22 -0
- package/dist/metrics/calculators/change-failure-rate.d.ts.map +1 -0
- package/dist/metrics/calculators/change-failure-rate.js +70 -0
- package/dist/metrics/calculators/change-failure-rate.js.map +1 -0
- package/dist/metrics/calculators/deployment-frequency.d.ts +20 -0
- package/dist/metrics/calculators/deployment-frequency.d.ts.map +1 -0
- package/dist/metrics/calculators/deployment-frequency.js +61 -0
- package/dist/metrics/calculators/deployment-frequency.js.map +1 -0
- package/dist/metrics/calculators/lead-time.d.ts +22 -0
- package/dist/metrics/calculators/lead-time.d.ts.map +1 -0
- package/dist/metrics/calculators/lead-time.js +82 -0
- package/dist/metrics/calculators/lead-time.js.map +1 -0
- package/dist/metrics/calculators/mttr.d.ts +21 -0
- package/dist/metrics/calculators/mttr.d.ts.map +1 -0
- package/dist/metrics/calculators/mttr.js +60 -0
- package/dist/metrics/calculators/mttr.js.map +1 -0
- package/dist/metrics/dora-calculator.d.ts +24 -0
- package/dist/metrics/dora-calculator.d.ts.map +1 -0
- package/dist/metrics/dora-calculator.js +104 -0
- package/dist/metrics/dora-calculator.js.map +1 -0
- package/dist/metrics/github-client.d.ts +51 -0
- package/dist/metrics/github-client.d.ts.map +1 -0
- package/dist/metrics/github-client.js +133 -0
- package/dist/metrics/github-client.js.map +1 -0
- package/dist/metrics/types.d.ts +112 -0
- package/dist/metrics/types.d.ts.map +1 -0
- package/dist/metrics/types.js +10 -0
- package/dist/metrics/types.js.map +1 -0
- package/dist/metrics/utils/percentile.d.ts +25 -0
- package/dist/metrics/utils/percentile.d.ts.map +1 -0
- package/dist/metrics/utils/percentile.js +46 -0
- package/dist/metrics/utils/percentile.js.map +1 -0
- package/dist/metrics/utils/tier-classifier.d.ts +61 -0
- package/dist/metrics/utils/tier-classifier.d.ts.map +1 -0
- package/dist/metrics/utils/tier-classifier.js +100 -0
- package/dist/metrics/utils/tier-classifier.js.map +1 -0
- package/dist/utils/auth-helpers.d.ts +58 -0
- package/dist/utils/auth-helpers.d.ts.map +1 -0
- package/dist/utils/auth-helpers.js +108 -0
- package/dist/utils/auth-helpers.js.map +1 -0
- package/dist/utils/env-file.d.ts +88 -0
- package/dist/utils/env-file.d.ts.map +1 -0
- package/dist/utils/env-file.js +180 -0
- package/dist/utils/env-file.js.map +1 -0
- package/dist/utils/plugin-detection.d.ts +50 -0
- package/dist/utils/plugin-detection.d.ts.map +1 -0
- package/dist/utils/plugin-detection.js +229 -0
- package/dist/utils/plugin-detection.js.map +1 -0
- package/dist/utils/secrets-loader.d.ts +88 -0
- package/dist/utils/secrets-loader.d.ts.map +1 -0
- package/dist/utils/secrets-loader.js +271 -0
- package/dist/utils/secrets-loader.js.map +1 -0
- package/dist/utils/translation.d.ts +187 -0
- package/dist/utils/translation.d.ts.map +1 -0
- package/dist/utils/translation.js +414 -0
- package/dist/utils/translation.js.map +1 -0
- package/package.json +28 -44
- package/plugins/specweave/.claude-plugin/plugin.json +3 -3
- package/plugins/specweave/agents/pm/AGENT.md +330 -54
- package/plugins/specweave/agents/test-aware-planner/AGENT.md +1035 -0
- package/plugins/specweave/agents/test-aware-planner/templates/README.md +118 -0
- package/plugins/specweave/agents/test-aware-planner/templates/task-non-testable.md.template +24 -0
- package/plugins/specweave/agents/test-aware-planner/templates/task-testable.md.template +53 -0
- package/plugins/specweave/agents/test-aware-planner/templates/tasks-frontmatter.md.template +11 -0
- package/plugins/specweave/commands/README.md +88 -163
- package/plugins/specweave/commands/specweave-abandon.md +314 -0
- package/plugins/specweave/commands/specweave-check-tests.md +546 -0
- package/plugins/specweave/commands/{do.md ā specweave-do.md} +5 -5
- package/plugins/specweave/commands/{done.md ā specweave-done.md} +2 -0
- package/plugins/specweave/commands/{increment.md ā specweave-increment.md} +231 -4
- package/plugins/specweave/commands/specweave-pause.md +189 -0
- package/plugins/specweave/commands/specweave-qa.md +245 -0
- package/plugins/specweave/commands/specweave-resume.md +216 -0
- package/plugins/specweave/commands/specweave-status.md +397 -0
- package/plugins/specweave/commands/specweave-sync-tasks.md +256 -0
- package/plugins/specweave/commands/{translate.md ā specweave-translate.md} +3 -3
- package/plugins/specweave/commands/specweave-update-scope.md +351 -0
- package/plugins/specweave/commands/{validate.md ā specweave-validate.md} +2 -0
- package/plugins/specweave/commands/specweave.md +21 -21
- package/plugins/specweave/hooks/docs-changed.sh +23 -3
- package/plugins/specweave/hooks/human-input-required.sh +23 -3
- package/plugins/specweave/hooks/post-increment-planning.sh +335 -0
- package/plugins/specweave/hooks/post-task-completion.sh +161 -1
- package/plugins/specweave/hooks/pre-implementation.sh +23 -3
- package/plugins/specweave/skills/SKILLS-INDEX.md +1 -1
- package/plugins/specweave/skills/brownfield-analyzer/SKILL.md +9 -9
- package/plugins/specweave/skills/increment-planner/SKILL.md +400 -212
- package/plugins/specweave/skills/increment-quality-judge-v2/SKILL.md +499 -0
- package/plugins/specweave/skills/plugin-detector/SKILL.md +114 -1
- package/plugins/specweave/skills/project-kickstarter/SKILL.md +74 -1
- package/plugins/specweave/skills/{rfc-generator ā spec-generator}/SKILL.md +22 -29
- package/plugins/specweave/skills/specweave-detector/SKILL.md +3 -3
- package/plugins/specweave/skills/specweave-framework/SKILL.md +2 -2
- package/plugins/specweave-ado/.claude-plugin/plugin.json +18 -4
- package/plugins/specweave-ado/agents/ado-manager/AGENT.md +426 -0
- package/plugins/specweave-ado/commands/close-workitem.md +52 -0
- package/plugins/specweave-ado/commands/create-workitem.md +53 -0
- package/plugins/specweave-ado/commands/status.md +53 -0
- package/plugins/specweave-ado/commands/sync.md +55 -0
- package/plugins/specweave-ado/lib/ado-client.ts +361 -0
- package/plugins/specweave-ado/reference/ado-specweave-mapping.md +552 -0
- package/plugins/specweave-ado/skills/ado-sync/SKILL.md +344 -193
- package/plugins/specweave-docs/skills/docusaurus/SKILL.md +73 -0
- package/plugins/specweave-github/agents/github-manager/AGENT.md +49 -0
- package/plugins/specweave-github/commands/{github-close-issue.md ā close-issue.md} +1 -1
- package/plugins/specweave-github/commands/{github-create-issue.md ā create-issue.md} +1 -1
- package/plugins/specweave-github/commands/{github-status.md ā status.md} +1 -1
- package/plugins/specweave-github/commands/{github-sync-tasks.md ā sync-tasks.md} +1 -1
- package/plugins/specweave-github/commands/{github-sync.md ā sync.md} +1 -1
- package/plugins/specweave-github/reference/github-specweave-mapping.md +377 -0
- package/plugins/specweave-github/skills/github-sync/SKILL.md +11 -3
- package/plugins/specweave-infrastructure/commands/{specweave.monitor-setup.md ā monitor-setup.md} +5 -0
- package/plugins/specweave-infrastructure/commands/{specweave.slo-implement.md ā slo-implement.md} +5 -0
- package/plugins/specweave-jira/agents/jira-manager/AGENT.md +380 -0
- package/plugins/specweave-jira/commands/{specweave.sync-jira.md ā sync.md} +1 -1
- package/plugins/specweave-jira/reference/jira-specweave-mapping.md +508 -0
- package/plugins/specweave-ml/commands/ml-deploy.md +1 -1
- package/plugins/specweave-ml/commands/ml-evaluate.md +1 -1
- package/plugins/specweave-ml/commands/ml-explain.md +1 -1
- package/plugins/specweave-ml/commands/{specweave.ml-pipeline.md ā ml-pipeline.md} +5 -0
- package/src/templates/AGENTS.md.template +652 -1
- package/src/templates/CLAUDE.md.template +36 -21
- package/src/templates/COMPLETION-REPORT.template.md +128 -0
- package/src/templates/README.md.template +17 -16
- package/src/templates/docs/README.md +11 -9
- package/src/templates/docs/spec-template.md +229 -0
- package/dist/adapters/copilot/adapter.d.ts +0 -86
- package/dist/adapters/copilot/adapter.d.ts.map +0 -1
- package/dist/adapters/copilot/adapter.js +0 -396
- package/dist/adapters/copilot/adapter.js.map +0 -1
- package/plugins/.specweave/logs/hooks-debug.log +0 -24
- package/plugins/.specweave/logs/last-hook-fire +0 -1
- package/plugins/.specweave/logs/last-todowrite-time +0 -1
- package/plugins/.specweave/logs/tasks.log +0 -6
- package/plugins/specweave/commands/inc.md +0 -85
- package/plugins/specweave/commands/list-increments.md +0 -180
- package/src/adapters/README.md +0 -311
- package/src/adapters/adapter-base.ts +0 -182
- package/src/adapters/adapter-interface.ts +0 -166
- package/src/adapters/adapter-loader.ts +0 -259
- package/src/adapters/agents-md-generator.ts +0 -228
- package/src/adapters/claude/README.md +0 -233
- package/src/adapters/claude/adapter.ts +0 -468
- package/src/adapters/claude-md-generator.ts +0 -377
- package/src/adapters/codex/README.md +0 -105
- package/src/adapters/codex/adapter.ts +0 -333
- package/src/adapters/copilot/README.md +0 -240
- package/src/adapters/copilot/adapter.ts +0 -444
- package/src/adapters/cursor/.cursor/context/docs-context.md +0 -62
- package/src/adapters/cursor/.cursor/context/increments-context.md +0 -71
- package/src/adapters/cursor/.cursor/context/strategy-context.md +0 -73
- package/src/adapters/cursor/.cursor/context/tests-context.md +0 -89
- package/src/adapters/cursor/README.md +0 -283
- package/src/adapters/cursor/adapter.ts +0 -451
- package/src/adapters/doc-generator.ts +0 -331
- package/src/adapters/gemini/README.md +0 -97
- package/src/adapters/gemini/adapter.ts +0 -298
- package/src/adapters/generic/README.md +0 -277
- package/src/adapters/generic/adapter.ts +0 -359
- package/src/adapters/registry.yaml +0 -187
- /package/plugins/specweave/commands/{costs.md ā specweave-costs.md} +0 -0
- /package/plugins/specweave/commands/{next.md ā specweave-next.md} +0 -0
- /package/plugins/specweave/commands/{progress.md ā specweave-progress.md} +0 -0
- /package/plugins/specweave/commands/{sync-docs.md ā specweave-sync-docs.md} +0 -0
- /package/plugins/specweave/commands/{tdd-cycle.md ā specweave-tdd-cycle.md} +0 -0
- /package/plugins/specweave/commands/{tdd-green.md ā specweave-tdd-green.md} +0 -0
- /package/plugins/specweave/commands/{tdd-red.md ā specweave-tdd-red.md} +0 -0
- /package/plugins/specweave/commands/{tdd-refactor.md ā specweave-tdd-refactor.md} +0 -0
|
@@ -43,11 +43,11 @@ This master command routes to SpecWeave increment lifecycle subcommands.
|
|
|
43
43
|
|
|
44
44
|
| Subcommand | Description | Example |
|
|
45
45
|
|------------|-------------|---------|
|
|
46
|
-
| **github
|
|
47
|
-
| **github
|
|
48
|
-
| **github
|
|
49
|
-
| **github
|
|
50
|
-
| **github
|
|
46
|
+
| **github:create-issue** | Create GitHub issue from increment | `/specweave-github:create-issue 0001` |
|
|
47
|
+
| **github:sync** | Bidirectional sync with GitHub | `/specweave-github:sync 0001` |
|
|
48
|
+
| **github:sync-tasks** | Sync tasks as GitHub sub-issues | `/specweave-github:sync-tasks 0001` |
|
|
49
|
+
| **github:close-issue** | Close GitHub issue | `/specweave-github:close-issue 0001` |
|
|
50
|
+
| **github:status** | Show GitHub sync status | `/specweave-github:status` |
|
|
51
51
|
|
|
52
52
|
---
|
|
53
53
|
|
|
@@ -73,11 +73,11 @@ subcommands:
|
|
|
73
73
|
sync-jira: .claude/commands/specweave:sync-jira.md
|
|
74
74
|
|
|
75
75
|
# GitHub Plugin Commands
|
|
76
|
-
github
|
|
77
|
-
github
|
|
78
|
-
github
|
|
79
|
-
github
|
|
80
|
-
github
|
|
76
|
+
github:create-issue: .claude/commands/specweave-github:create-issue.md
|
|
77
|
+
github:sync: .claude/commands/specweave-github:sync.md
|
|
78
|
+
github:sync-tasks: .claude/commands/specweave-github:sync-tasks.md
|
|
79
|
+
github:close-issue: .claude/commands/specweave-github:close-issue.md
|
|
80
|
+
github:status: .claude/commands/specweave-github:status.md
|
|
81
81
|
```
|
|
82
82
|
|
|
83
83
|
---
|
|
@@ -183,15 +183,15 @@ Available subcommands:
|
|
|
183
183
|
sync-docs - Sync documentation (review/update)
|
|
184
184
|
|
|
185
185
|
GitHub Plugin:
|
|
186
|
-
github
|
|
187
|
-
github
|
|
188
|
-
github
|
|
189
|
-
github
|
|
190
|
-
github
|
|
186
|
+
github:create-issue - Create GitHub issue from increment
|
|
187
|
+
github:sync - Bidirectional sync with GitHub
|
|
188
|
+
github:sync-tasks - Sync tasks as GitHub sub-issues
|
|
189
|
+
github:close-issue - Close GitHub issue
|
|
190
|
+
github:status - Show GitHub sync status
|
|
191
191
|
|
|
192
192
|
Usage: /specweave <subcommand> [arguments]
|
|
193
193
|
Example: /specweave inc "User authentication"
|
|
194
|
-
Example: /specweave
|
|
194
|
+
Example: /specweave-github:create-issue 0001
|
|
195
195
|
```
|
|
196
196
|
|
|
197
197
|
---
|
|
@@ -433,11 +433,11 @@ Project Setup:
|
|
|
433
433
|
sync-docs [mode] [id] - Sync documentation (review/update)
|
|
434
434
|
|
|
435
435
|
GitHub Plugin:
|
|
436
|
-
github
|
|
437
|
-
github
|
|
438
|
-
github
|
|
439
|
-
github
|
|
440
|
-
github
|
|
436
|
+
github:create-issue <id> - Create GitHub issue from increment
|
|
437
|
+
github:sync <id> - Bidirectional sync with GitHub
|
|
438
|
+
github:sync-tasks <id> - Sync tasks as GitHub sub-issues
|
|
439
|
+
github:close-issue <id> - Close GitHub issue
|
|
440
|
+
github:status - Show GitHub sync status
|
|
441
441
|
|
|
442
442
|
Examples:
|
|
443
443
|
/specweave inc "User authentication"
|
|
@@ -7,7 +7,26 @@
|
|
|
7
7
|
|
|
8
8
|
set -e
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
# Find project root by searching upward for .specweave/ directory
|
|
11
|
+
# Works regardless of where hook is installed (source or .claude/hooks/)
|
|
12
|
+
find_project_root() {
|
|
13
|
+
local dir="$1"
|
|
14
|
+
while [ "$dir" != "/" ]; do
|
|
15
|
+
if [ -d "$dir/.specweave" ]; then
|
|
16
|
+
echo "$dir"
|
|
17
|
+
return 0
|
|
18
|
+
fi
|
|
19
|
+
dir="$(dirname "$dir")"
|
|
20
|
+
done
|
|
21
|
+
# Fallback: try current directory
|
|
22
|
+
if [ -d "$(pwd)/.specweave" ]; then
|
|
23
|
+
pwd
|
|
24
|
+
else
|
|
25
|
+
echo "$(pwd)"
|
|
26
|
+
fi
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
PROJECT_ROOT="$(find_project_root "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")"
|
|
11
30
|
cd "$PROJECT_ROOT"
|
|
12
31
|
|
|
13
32
|
# Colors
|
|
@@ -54,6 +73,7 @@ if [ -n "$DOC_CHANGES" ]; then
|
|
|
54
73
|
esac
|
|
55
74
|
|
|
56
75
|
# Log to hooks log
|
|
57
|
-
|
|
58
|
-
|
|
76
|
+
LOGS_DIR=".specweave/logs"
|
|
77
|
+
mkdir -p "$LOGS_DIR"
|
|
78
|
+
echo "[$(date)] Documentation changed: $DOC_CHANGES" >> "$LOGS_DIR/hooks.log"
|
|
59
79
|
fi
|
|
@@ -10,7 +10,26 @@
|
|
|
10
10
|
|
|
11
11
|
set -e
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
# Find project root by searching upward for .specweave/ directory
|
|
14
|
+
# Works regardless of where hook is installed (source or .claude/hooks/)
|
|
15
|
+
find_project_root() {
|
|
16
|
+
local dir="$1"
|
|
17
|
+
while [ "$dir" != "/" ]; do
|
|
18
|
+
if [ -d "$dir/.specweave" ]; then
|
|
19
|
+
echo "$dir"
|
|
20
|
+
return 0
|
|
21
|
+
fi
|
|
22
|
+
dir="$(dirname "$dir")"
|
|
23
|
+
done
|
|
24
|
+
# Fallback: try current directory
|
|
25
|
+
if [ -d "$(pwd)/.specweave" ]; then
|
|
26
|
+
pwd
|
|
27
|
+
else
|
|
28
|
+
echo "$(pwd)"
|
|
29
|
+
fi
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
PROJECT_ROOT="$(find_project_root "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")"
|
|
14
33
|
cd "$PROJECT_ROOT"
|
|
15
34
|
|
|
16
35
|
# Get question/requirement (passed as argument or default)
|
|
@@ -37,8 +56,9 @@ play_sound() {
|
|
|
37
56
|
play_sound &
|
|
38
57
|
|
|
39
58
|
# 2. Log to main hooks log
|
|
40
|
-
|
|
41
|
-
|
|
59
|
+
LOGS_DIR=".specweave/logs"
|
|
60
|
+
mkdir -p "$LOGS_DIR"
|
|
61
|
+
echo "[$(date)] Human input required: $QUESTION" >> "$LOGS_DIR/hooks.log"
|
|
42
62
|
|
|
43
63
|
# 3. Log to current work context (if exists)
|
|
44
64
|
CURRENT_WORK=$(find .specweave/work -maxdepth 1 -type d -name "current-*" | head -1 || true)
|
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# SpecWeave Post-Increment-Planning Hook
|
|
4
|
+
# Runs automatically after /specweave:inc completes
|
|
5
|
+
#
|
|
6
|
+
# PURPOSE:
|
|
7
|
+
# Translates newly generated spec.md, plan.md, and tasks.md from target language
|
|
8
|
+
# back to English for maintainability.
|
|
9
|
+
#
|
|
10
|
+
# WHY THIS MATTERS:
|
|
11
|
+
# - User works in native language (great UX during planning)
|
|
12
|
+
# - Framework translates to English automatically (maintainable docs)
|
|
13
|
+
# - Cost: ~$0.01 per increment (using Haiku)
|
|
14
|
+
#
|
|
15
|
+
# WORKFLOW:
|
|
16
|
+
# 1. User runs: /specweave:inc "ŠŠ¾Š±Š°Š²ŠøŃŃ AI ŃŠ°Ń-боŃ" (in Russian)
|
|
17
|
+
# 2. PM agent generates spec.md in Russian (natural, user-friendly)
|
|
18
|
+
# 3. THIS HOOK fires automatically
|
|
19
|
+
# 4. Detects non-English content
|
|
20
|
+
# 5. Translates spec.md, plan.md, tasks.md to English
|
|
21
|
+
# 6. Files now in English (maintainable)
|
|
22
|
+
#
|
|
23
|
+
# @see .specweave/increments/0006-llm-native-i18n/reports/DESIGN-POST-GENERATION-TRANSLATION.md
|
|
24
|
+
|
|
25
|
+
set -e
|
|
26
|
+
|
|
27
|
+
# ============================================================================
|
|
28
|
+
# PROJECT ROOT DETECTION
|
|
29
|
+
# ============================================================================
|
|
30
|
+
|
|
31
|
+
# Find project root by searching upward for .specweave/ directory
|
|
32
|
+
find_project_root() {
|
|
33
|
+
local dir="$1"
|
|
34
|
+
while [ "$dir" != "/" ]; do
|
|
35
|
+
if [ -d "$dir/.specweave" ]; then
|
|
36
|
+
echo "$dir"
|
|
37
|
+
return 0
|
|
38
|
+
fi
|
|
39
|
+
dir="$(dirname "$dir")"
|
|
40
|
+
done
|
|
41
|
+
# Fallback: try current directory
|
|
42
|
+
if [ -d "$(pwd)/.specweave" ]; then
|
|
43
|
+
pwd
|
|
44
|
+
else
|
|
45
|
+
echo "$(pwd)"
|
|
46
|
+
fi
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
PROJECT_ROOT="$(find_project_root "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")"
|
|
50
|
+
cd "$PROJECT_ROOT" 2>/dev/null || true
|
|
51
|
+
|
|
52
|
+
# ============================================================================
|
|
53
|
+
# CONFIGURATION
|
|
54
|
+
# ============================================================================
|
|
55
|
+
|
|
56
|
+
# Translation settings (can be overridden by .specweave/config.json)
|
|
57
|
+
TRANSLATION_ENABLED=true
|
|
58
|
+
AUTO_TRANSLATE_INTERNAL_DOCS=true
|
|
59
|
+
TARGET_LANGUAGE="en" # Always translate TO English (for maintainability)
|
|
60
|
+
|
|
61
|
+
# Paths
|
|
62
|
+
SPECWEAVE_DIR=".specweave"
|
|
63
|
+
INCREMENTS_DIR="$SPECWEAVE_DIR/increments"
|
|
64
|
+
LOGS_DIR="$SPECWEAVE_DIR/logs"
|
|
65
|
+
CONFIG_FILE="$SPECWEAVE_DIR/config.json"
|
|
66
|
+
DEBUG_LOG="$LOGS_DIR/hooks-debug.log"
|
|
67
|
+
|
|
68
|
+
mkdir -p "$LOGS_DIR" 2>/dev/null || true
|
|
69
|
+
|
|
70
|
+
# ============================================================================
|
|
71
|
+
# LOGGING
|
|
72
|
+
# ============================================================================
|
|
73
|
+
|
|
74
|
+
log_debug() {
|
|
75
|
+
echo "[$(date '+%Y-%m-%d %H:%M:%S')] [post-increment-planning] $1" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
log_info() {
|
|
79
|
+
echo "$1"
|
|
80
|
+
log_debug "$1"
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
log_error() {
|
|
84
|
+
echo "ā $1" >&2
|
|
85
|
+
log_debug "ERROR: $1"
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
# ============================================================================
|
|
89
|
+
# CONFIGURATION LOADING
|
|
90
|
+
# ============================================================================
|
|
91
|
+
|
|
92
|
+
load_config() {
|
|
93
|
+
if [ ! -f "$CONFIG_FILE" ]; then
|
|
94
|
+
log_debug "No config file found, using defaults"
|
|
95
|
+
return
|
|
96
|
+
fi
|
|
97
|
+
|
|
98
|
+
# Check if translation is enabled in config
|
|
99
|
+
local translation_enabled=$(cat "$CONFIG_FILE" | grep -o '"enabled"[[:space:]]*:[[:space:]]*\(true\|false\)' | grep -o '\(true\|false\)' || echo "true")
|
|
100
|
+
|
|
101
|
+
if [ "$translation_enabled" = "false" ]; then
|
|
102
|
+
TRANSLATION_ENABLED=false
|
|
103
|
+
log_debug "Translation disabled in config"
|
|
104
|
+
fi
|
|
105
|
+
|
|
106
|
+
# Check if auto-translation of internal docs is enabled
|
|
107
|
+
local auto_translate=$(cat "$CONFIG_FILE" | grep -o '"autoTranslateInternalDocs"[[:space:]]*:[[:space:]]*\(true\|false\)' | grep -o '\(true\|false\)' || echo "true")
|
|
108
|
+
|
|
109
|
+
if [ "$auto_translate" = "false" ]; then
|
|
110
|
+
AUTO_TRANSLATE_INTERNAL_DOCS=false
|
|
111
|
+
log_debug "Auto-translation of internal docs disabled in config"
|
|
112
|
+
fi
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
# ============================================================================
|
|
116
|
+
# INCREMENT DETECTION
|
|
117
|
+
# ============================================================================
|
|
118
|
+
|
|
119
|
+
get_latest_increment() {
|
|
120
|
+
# Find the most recently modified increment directory (excluding _backlog)
|
|
121
|
+
local latest=$(find "$INCREMENTS_DIR" -maxdepth 1 -type d -name "[0-9][0-9][0-9][0-9]-*" ! -name "_backlog" -exec stat -f "%m %N" {} \; 2>/dev/null | sort -rn | head -1 | cut -d' ' -f2-)
|
|
122
|
+
|
|
123
|
+
if [ -z "$latest" ]; then
|
|
124
|
+
log_error "No increment directory found"
|
|
125
|
+
return 1
|
|
126
|
+
fi
|
|
127
|
+
|
|
128
|
+
echo "$latest"
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
# ============================================================================
|
|
132
|
+
# LANGUAGE DETECTION
|
|
133
|
+
# ============================================================================
|
|
134
|
+
|
|
135
|
+
detect_file_language() {
|
|
136
|
+
local file_path="$1"
|
|
137
|
+
|
|
138
|
+
if [ ! -f "$file_path" ]; then
|
|
139
|
+
echo "en" # Default to English if file doesn't exist
|
|
140
|
+
return
|
|
141
|
+
fi
|
|
142
|
+
|
|
143
|
+
# Count non-ASCII characters (Cyrillic, Chinese, etc.)
|
|
144
|
+
local total_chars=$(wc -c < "$file_path" | tr -d ' ')
|
|
145
|
+
local non_ascii_chars=$(LC_ALL=C grep -o '[^ -~]' "$file_path" 2>/dev/null | wc -l | tr -d ' ')
|
|
146
|
+
|
|
147
|
+
# If >10% non-ASCII, assume non-English
|
|
148
|
+
if [ "$total_chars" -gt 0 ]; then
|
|
149
|
+
local ratio=$((non_ascii_chars * 100 / total_chars))
|
|
150
|
+
if [ "$ratio" -gt 10 ]; then
|
|
151
|
+
echo "non-en"
|
|
152
|
+
return
|
|
153
|
+
fi
|
|
154
|
+
fi
|
|
155
|
+
|
|
156
|
+
echo "en"
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
# ============================================================================
|
|
160
|
+
# TRANSLATION EXECUTION
|
|
161
|
+
# ============================================================================
|
|
162
|
+
|
|
163
|
+
translate_file() {
|
|
164
|
+
local file_path="$1"
|
|
165
|
+
local file_name=$(basename "$file_path")
|
|
166
|
+
|
|
167
|
+
log_info " š Translating $file_name..."
|
|
168
|
+
|
|
169
|
+
# Call the translate-file.ts script
|
|
170
|
+
# In production, this would invoke the LLM via Task tool
|
|
171
|
+
# For now, we'll create a marker file to indicate translation is needed
|
|
172
|
+
|
|
173
|
+
if [ -f "$PROJECT_ROOT/dist/hooks/lib/translate-file.js" ]; then
|
|
174
|
+
# Production: Use compiled TypeScript
|
|
175
|
+
node "$PROJECT_ROOT/dist/hooks/lib/translate-file.js" "$file_path" --target-lang en --verbose 2>&1 | while read -r line; do
|
|
176
|
+
echo " $line"
|
|
177
|
+
done
|
|
178
|
+
|
|
179
|
+
if [ ${PIPESTATUS[0]} -eq 0 ]; then
|
|
180
|
+
log_info " ā
$file_name translated successfully"
|
|
181
|
+
return 0
|
|
182
|
+
else
|
|
183
|
+
log_error " ā ļø Translation failed for $file_name"
|
|
184
|
+
return 1
|
|
185
|
+
fi
|
|
186
|
+
else
|
|
187
|
+
# Development/Testing: Just mark the file
|
|
188
|
+
log_info " ā¹ļø Translation script not compiled (run 'npm run build')"
|
|
189
|
+
log_info " ā¹ļø In production, $file_name would be translated to English"
|
|
190
|
+
return 0
|
|
191
|
+
fi
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
# ============================================================================
|
|
195
|
+
# MAIN LOGIC
|
|
196
|
+
# ============================================================================
|
|
197
|
+
|
|
198
|
+
main() {
|
|
199
|
+
log_debug "=== POST-INCREMENT-PLANNING HOOK START ==="
|
|
200
|
+
|
|
201
|
+
# 1. Load configuration
|
|
202
|
+
load_config
|
|
203
|
+
|
|
204
|
+
if [ "$TRANSLATION_ENABLED" = "false" ]; then
|
|
205
|
+
log_debug "Translation disabled, exiting"
|
|
206
|
+
cat <<EOF
|
|
207
|
+
{
|
|
208
|
+
"continue": true,
|
|
209
|
+
"message": "Translation disabled in config"
|
|
210
|
+
}
|
|
211
|
+
EOF
|
|
212
|
+
exit 0
|
|
213
|
+
fi
|
|
214
|
+
|
|
215
|
+
if [ "$AUTO_TRANSLATE_INTERNAL_DOCS" = "false" ]; then
|
|
216
|
+
log_debug "Auto-translation of internal docs disabled, exiting"
|
|
217
|
+
cat <<EOF
|
|
218
|
+
{
|
|
219
|
+
"continue": true,
|
|
220
|
+
"message": "Auto-translation of internal docs disabled"
|
|
221
|
+
}
|
|
222
|
+
EOF
|
|
223
|
+
exit 0
|
|
224
|
+
fi
|
|
225
|
+
|
|
226
|
+
# 2. Get latest increment directory
|
|
227
|
+
local increment_dir=$(get_latest_increment)
|
|
228
|
+
|
|
229
|
+
if [ $? -ne 0 ] || [ -z "$increment_dir" ]; then
|
|
230
|
+
log_error "Could not find latest increment directory"
|
|
231
|
+
cat <<EOF
|
|
232
|
+
{
|
|
233
|
+
"continue": true,
|
|
234
|
+
"error": "No increment directory found"
|
|
235
|
+
}
|
|
236
|
+
EOF
|
|
237
|
+
exit 0
|
|
238
|
+
fi
|
|
239
|
+
|
|
240
|
+
local increment_id=$(basename "$increment_dir")
|
|
241
|
+
log_debug "Latest increment: $increment_id"
|
|
242
|
+
|
|
243
|
+
# 3. Check if files need translation
|
|
244
|
+
local spec_file="$increment_dir/spec.md"
|
|
245
|
+
local plan_file="$increment_dir/plan.md"
|
|
246
|
+
local tasks_file="$increment_dir/tasks.md"
|
|
247
|
+
|
|
248
|
+
local needs_translation=false
|
|
249
|
+
local files_to_translate=()
|
|
250
|
+
|
|
251
|
+
# Detect language of each file
|
|
252
|
+
if [ -f "$spec_file" ]; then
|
|
253
|
+
local spec_lang=$(detect_file_language "$spec_file")
|
|
254
|
+
if [ "$spec_lang" = "non-en" ]; then
|
|
255
|
+
needs_translation=true
|
|
256
|
+
files_to_translate+=("$spec_file")
|
|
257
|
+
fi
|
|
258
|
+
fi
|
|
259
|
+
|
|
260
|
+
if [ -f "$plan_file" ]; then
|
|
261
|
+
local plan_lang=$(detect_file_language "$plan_file")
|
|
262
|
+
if [ "$plan_lang" = "non-en" ]; then
|
|
263
|
+
needs_translation=true
|
|
264
|
+
files_to_translate+=("$plan_file")
|
|
265
|
+
fi
|
|
266
|
+
fi
|
|
267
|
+
|
|
268
|
+
if [ -f "$tasks_file" ]; then
|
|
269
|
+
local tasks_lang=$(detect_file_language "$tasks_file")
|
|
270
|
+
if [ "$tasks_lang" = "non-en" ]; then
|
|
271
|
+
needs_translation=true
|
|
272
|
+
files_to_translate+=("$tasks_file")
|
|
273
|
+
fi
|
|
274
|
+
fi
|
|
275
|
+
|
|
276
|
+
# 4. If no translation needed, exit early
|
|
277
|
+
if [ "$needs_translation" = "false" ] || [ ${#files_to_translate[@]} -eq 0 ]; then
|
|
278
|
+
log_info "ā
All increment files already in English, skipping translation"
|
|
279
|
+
cat <<EOF
|
|
280
|
+
{
|
|
281
|
+
"continue": true,
|
|
282
|
+
"message": "All files already in English"
|
|
283
|
+
}
|
|
284
|
+
EOF
|
|
285
|
+
exit 0
|
|
286
|
+
fi
|
|
287
|
+
|
|
288
|
+
# 5. Perform translation
|
|
289
|
+
log_info ""
|
|
290
|
+
log_info "š Detected non-English content in increment $increment_id"
|
|
291
|
+
log_info " Translating to English for maintainability..."
|
|
292
|
+
log_info ""
|
|
293
|
+
|
|
294
|
+
local success_count=0
|
|
295
|
+
local total_count=${#files_to_translate[@]}
|
|
296
|
+
|
|
297
|
+
for file in "${files_to_translate[@]}"; do
|
|
298
|
+
if translate_file "$file"; then
|
|
299
|
+
((success_count++))
|
|
300
|
+
fi
|
|
301
|
+
done
|
|
302
|
+
|
|
303
|
+
# 6. Summary
|
|
304
|
+
log_info ""
|
|
305
|
+
if [ "$success_count" -eq "$total_count" ]; then
|
|
306
|
+
log_info "ā
Translation complete! All $total_count file(s) now in English"
|
|
307
|
+
log_info " Cost: ~\$0.01 (using Haiku)"
|
|
308
|
+
log_info ""
|
|
309
|
+
|
|
310
|
+
cat <<EOF
|
|
311
|
+
{
|
|
312
|
+
"continue": true,
|
|
313
|
+
"message": "Translated $total_count file(s) to English",
|
|
314
|
+
"files": $(printf '%s\n' "${files_to_translate[@]}" | jq -R . | jq -s .)
|
|
315
|
+
}
|
|
316
|
+
EOF
|
|
317
|
+
else
|
|
318
|
+
log_error "Translation completed with errors: $success_count/$total_count files translated"
|
|
319
|
+
cat <<EOF
|
|
320
|
+
{
|
|
321
|
+
"continue": true,
|
|
322
|
+
"warning": "Translation partially failed: $success_count/$total_count files",
|
|
323
|
+
"files": $(printf '%s\n' "${files_to_translate[@]}" | jq -R . | jq -s .)
|
|
324
|
+
}
|
|
325
|
+
EOF
|
|
326
|
+
fi
|
|
327
|
+
|
|
328
|
+
log_debug "=== POST-INCREMENT-PLANNING HOOK END ==="
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
# Run main function
|
|
332
|
+
main
|
|
333
|
+
|
|
334
|
+
# Always return success (non-blocking hook)
|
|
335
|
+
exit 0
|
|
@@ -28,7 +28,26 @@
|
|
|
28
28
|
|
|
29
29
|
set -e
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
# Find project root by searching upward for .specweave/ directory
|
|
32
|
+
# Works regardless of where hook is installed (source or .claude/hooks/)
|
|
33
|
+
find_project_root() {
|
|
34
|
+
local dir="$1"
|
|
35
|
+
while [ "$dir" != "/" ]; do
|
|
36
|
+
if [ -d "$dir/.specweave" ]; then
|
|
37
|
+
echo "$dir"
|
|
38
|
+
return 0
|
|
39
|
+
fi
|
|
40
|
+
dir="$(dirname "$dir")"
|
|
41
|
+
done
|
|
42
|
+
# Fallback: try current directory
|
|
43
|
+
if [ -d "$(pwd)/.specweave" ]; then
|
|
44
|
+
pwd
|
|
45
|
+
else
|
|
46
|
+
echo "$(pwd)"
|
|
47
|
+
fi
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
PROJECT_ROOT="$(find_project_root "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")"
|
|
32
51
|
cd "$PROJECT_ROOT" 2>/dev/null || true
|
|
33
52
|
|
|
34
53
|
# ============================================================================
|
|
@@ -205,6 +224,147 @@ if command -v node &> /dev/null; then
|
|
|
205
224
|
fi
|
|
206
225
|
fi
|
|
207
226
|
|
|
227
|
+
# ============================================================================
|
|
228
|
+
# SYNC TO EXTERNAL TRACKERS (NEW in v0.7.0 - GitHub/Jira/ADO)
|
|
229
|
+
# ============================================================================
|
|
230
|
+
|
|
231
|
+
if [ -n "$CURRENT_INCREMENT" ]; then
|
|
232
|
+
echo "[$(date)] š Checking external tracker sync for $CURRENT_INCREMENT" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
233
|
+
|
|
234
|
+
# Check for metadata.json with GitHub/Jira issue link
|
|
235
|
+
METADATA_FILE=".specweave/increments/$CURRENT_INCREMENT/metadata.json"
|
|
236
|
+
|
|
237
|
+
if [ -f "$METADATA_FILE" ]; then
|
|
238
|
+
# Detect tracker type from metadata
|
|
239
|
+
GITHUB_ISSUE=$(jq -r '.github.issue // empty' "$METADATA_FILE" 2>/dev/null)
|
|
240
|
+
JIRA_ISSUE=$(jq -r '.jira.issue // empty' "$METADATA_FILE" 2>/dev/null)
|
|
241
|
+
ADO_ITEM=$(jq -r '.ado.item // empty' "$METADATA_FILE" 2>/dev/null)
|
|
242
|
+
|
|
243
|
+
# GitHub sync (if issue exists and gh CLI available)
|
|
244
|
+
if [ -n "$GITHUB_ISSUE" ] && command -v gh &> /dev/null; then
|
|
245
|
+
echo "[$(date)] š Syncing to GitHub issue #$GITHUB_ISSUE" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
246
|
+
|
|
247
|
+
# Run GitHub sync - Update CHECKBOXES in issue description
|
|
248
|
+
TASKS_FILE=".specweave/increments/$CURRENT_INCREMENT/tasks.md"
|
|
249
|
+
|
|
250
|
+
if [ -f "$TASKS_FILE" ]; then
|
|
251
|
+
echo "[$(date)] š Syncing task checkboxes to GitHub issue #$GITHUB_ISSUE" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
252
|
+
|
|
253
|
+
# Get list of completed tasks from tasks.md
|
|
254
|
+
# Find all "## T-XXX:" headers where the task has "[x]" checkbox
|
|
255
|
+
COMPLETED_TASK_IDS=$(awk '
|
|
256
|
+
/^## T-[0-9]+:/ {
|
|
257
|
+
task_id = $2
|
|
258
|
+
gsub(/:/, "", task_id)
|
|
259
|
+
current_task = task_id
|
|
260
|
+
task_title = substr($0, index($0, $3))
|
|
261
|
+
next
|
|
262
|
+
}
|
|
263
|
+
/^- \[x\]/ && current_task != "" {
|
|
264
|
+
# Found a completed checkbox under a task
|
|
265
|
+
print current_task
|
|
266
|
+
current_task = ""
|
|
267
|
+
}
|
|
268
|
+
' "$TASKS_FILE" 2>/dev/null)
|
|
269
|
+
|
|
270
|
+
echo "[$(date)] Completed tasks found: $COMPLETED_TASK_IDS" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
271
|
+
|
|
272
|
+
# Read current issue body
|
|
273
|
+
ISSUE_BODY=$(gh issue view "$GITHUB_ISSUE" --json body -q .body 2>/dev/null || echo "")
|
|
274
|
+
|
|
275
|
+
if [ -n "$ISSUE_BODY" ]; then
|
|
276
|
+
# Create temporary file for updated body
|
|
277
|
+
TEMP_BODY=$(mktemp)
|
|
278
|
+
echo "$ISSUE_BODY" > "$TEMP_BODY"
|
|
279
|
+
|
|
280
|
+
# Update checkboxes for completed tasks
|
|
281
|
+
# Pattern: "- [ ] task-name" -> "- [x] task-name"
|
|
282
|
+
for task_id in $COMPLETED_TASK_IDS; do
|
|
283
|
+
# Update checkbox for this task ID
|
|
284
|
+
# Look for patterns like "[ ] T-013:" or "[ ] CLAUDE.md updates" etc.
|
|
285
|
+
sed -i.bak "s/- \[ \] \(.*${task_id}.*\)/- [x] \1/g" "$TEMP_BODY" 2>/dev/null || true
|
|
286
|
+
sed -i.bak "s/- \[ \] \(.*T-0*${task_id#T-}[: ].*\)/- [x] \1/g" "$TEMP_BODY" 2>/dev/null || true
|
|
287
|
+
|
|
288
|
+
echo "[$(date)] Updated checkbox for task: $task_id" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
289
|
+
done
|
|
290
|
+
|
|
291
|
+
# Also update based on task names (more reliable)
|
|
292
|
+
# Check for common patterns in issue body
|
|
293
|
+
if grep -q "test-aware-planner" "$TASKS_FILE" && grep -q "\[x\]" "$TASKS_FILE"; then
|
|
294
|
+
sed -i.bak "s/- \[ \] \(.*test-aware-planner.*\)/- [x] \1/g" "$TEMP_BODY" 2>/dev/null || true
|
|
295
|
+
fi
|
|
296
|
+
if grep -q "PM.*increment-planner" "$TASKS_FILE" && grep -q "\[x\]" "$TASKS_FILE"; then
|
|
297
|
+
sed -i.bak "s/- \[ \] \(.*PM.*increment-planner.*\)/- [x] \1/g" "$TEMP_BODY" 2>/dev/null || true
|
|
298
|
+
sed -i.bak "s/- \[ \] \(.*Enhanced PM.*\)/- [x] \1/g" "$TEMP_BODY" 2>/dev/null || true
|
|
299
|
+
fi
|
|
300
|
+
if grep -q "CLAUDE.md" "$TASKS_FILE" && grep -q "\[x\]" "$TASKS_FILE"; then
|
|
301
|
+
sed -i.bak "s/- \[ \] \(.*CLAUDE\.md.*\)/- [x] \1/g" "$TEMP_BODY" 2>/dev/null || true
|
|
302
|
+
fi
|
|
303
|
+
|
|
304
|
+
# Read updated body
|
|
305
|
+
UPDATED_BODY=$(cat "$TEMP_BODY")
|
|
306
|
+
|
|
307
|
+
# Update issue with new body
|
|
308
|
+
gh issue edit "$GITHUB_ISSUE" --body "$UPDATED_BODY" 2>&1 | tee -a "$DEBUG_LOG" >/dev/null || {
|
|
309
|
+
echo "[$(date)] ā ļø Failed to update issue description (non-blocking)" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
# Cleanup
|
|
313
|
+
rm -f "$TEMP_BODY" "$TEMP_BODY.bak"
|
|
314
|
+
|
|
315
|
+
echo "[$(date)] ā
Issue description checkboxes updated" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
316
|
+
fi
|
|
317
|
+
|
|
318
|
+
# Calculate progress for comment
|
|
319
|
+
TOTAL_TASKS=$(grep -c "^## T-[0-9]" "$TASKS_FILE" 2>/dev/null || echo "0")
|
|
320
|
+
COMPLETED_TASKS=$(echo "$COMPLETED_TASK_IDS" | wc -w | tr -d ' ')
|
|
321
|
+
|
|
322
|
+
if [ "$TOTAL_TASKS" -gt 0 ]; then
|
|
323
|
+
PROGRESS_PCT=$((COMPLETED_TASKS * 100 / TOTAL_TASKS))
|
|
324
|
+
|
|
325
|
+
# Post progress comment
|
|
326
|
+
gh issue comment "$GITHUB_ISSUE" --body "**Progress Update**: $COMPLETED_TASKS/$TOTAL_TASKS tasks ($PROGRESS_PCT%)\n\nIncrement: \`$CURRENT_INCREMENT\`\n\n---\nš¤ Auto-updated by SpecWeave" 2>&1 | tee -a "$DEBUG_LOG" >/dev/null || {
|
|
327
|
+
echo "[$(date)] ā ļø Failed to comment on GitHub issue (non-blocking)" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
328
|
+
}
|
|
329
|
+
fi
|
|
330
|
+
else
|
|
331
|
+
echo "[$(date)] ā¹ļø tasks.md not found, skipping GitHub sync" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
332
|
+
fi
|
|
333
|
+
fi
|
|
334
|
+
|
|
335
|
+
# Jira sync (if issue exists)
|
|
336
|
+
if [ -n "$JIRA_ISSUE" ]; then
|
|
337
|
+
echo "[$(date)] š Syncing to Jira issue $JIRA_ISSUE" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
338
|
+
|
|
339
|
+
# Run Jira sync command (non-blocking)
|
|
340
|
+
if command -v node &> /dev/null && [ -f "dist/commands/jira-sync.js" ]; then
|
|
341
|
+
node dist/commands/jira-sync.js "$CURRENT_INCREMENT" 2>&1 | tee -a "$DEBUG_LOG" >/dev/null || {
|
|
342
|
+
echo "[$(date)] ā ļø Failed to sync to Jira (non-blocking)" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
343
|
+
}
|
|
344
|
+
fi
|
|
345
|
+
fi
|
|
346
|
+
|
|
347
|
+
# Azure DevOps sync (if work item exists)
|
|
348
|
+
if [ -n "$ADO_ITEM" ]; then
|
|
349
|
+
echo "[$(date)] š Syncing to Azure DevOps item $ADO_ITEM" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
350
|
+
|
|
351
|
+
# Run ADO sync command (non-blocking)
|
|
352
|
+
if command -v node &> /dev/null && [ -f "dist/commands/ado-sync.js" ]; then
|
|
353
|
+
node dist/commands/ado-sync.js "$CURRENT_INCREMENT" 2>&1 | tee -a "$DEBUG_LOG" >/dev/null || {
|
|
354
|
+
echo "[$(date)] ā ļø Failed to sync to Azure DevOps (non-blocking)" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
355
|
+
}
|
|
356
|
+
fi
|
|
357
|
+
fi
|
|
358
|
+
|
|
359
|
+
# Log if no external tracker configured
|
|
360
|
+
if [ -z "$GITHUB_ISSUE" ] && [ -z "$JIRA_ISSUE" ] && [ -z "$ADO_ITEM" ]; then
|
|
361
|
+
echo "[$(date)] ā¹ļø No external tracker configured for $CURRENT_INCREMENT (skipping sync)" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
362
|
+
fi
|
|
363
|
+
else
|
|
364
|
+
echo "[$(date)] ā¹ļø No metadata.json found for $CURRENT_INCREMENT (skipping tracker sync)" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
365
|
+
fi
|
|
366
|
+
fi
|
|
367
|
+
|
|
208
368
|
# ============================================================================
|
|
209
369
|
# PLAY SOUND (only if session is truly ending)
|
|
210
370
|
# ============================================================================
|