specweave 0.32.0 → 0.32.3
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 +215 -2
- package/README.md +22 -0
- package/bin/specweave.js +52 -1
- package/dist/plugins/specweave-ado/lib/ado-duplicate-detector.d.ts +100 -0
- package/dist/plugins/specweave-ado/lib/ado-duplicate-detector.d.ts.map +1 -0
- package/dist/plugins/specweave-ado/lib/ado-duplicate-detector.js +291 -0
- package/dist/plugins/specweave-ado/lib/ado-duplicate-detector.js.map +1 -0
- package/dist/plugins/specweave-jira/lib/jira-duplicate-detector.d.ts +103 -0
- package/dist/plugins/specweave-jira/lib/jira-duplicate-detector.d.ts.map +1 -0
- package/dist/plugins/specweave-jira/lib/jira-duplicate-detector.js +310 -0
- package/dist/plugins/specweave-jira/lib/jira-duplicate-detector.js.map +1 -0
- package/dist/plugins/specweave-jira/lib/jira-permission-gate.d.ts +126 -0
- package/dist/plugins/specweave-jira/lib/jira-permission-gate.d.ts.map +1 -0
- package/dist/plugins/specweave-jira/lib/jira-permission-gate.js +207 -0
- package/dist/plugins/specweave-jira/lib/jira-permission-gate.js.map +1 -0
- package/dist/src/adapters/codex/README.md +1 -1
- package/dist/src/adapters/codex/adapter.js +1 -1
- package/dist/src/cli/commands/archive.d.ts +2 -0
- package/dist/src/cli/commands/archive.d.ts.map +1 -1
- package/dist/src/cli/commands/archive.js +33 -0
- package/dist/src/cli/commands/archive.js.map +1 -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/context.d.ts +92 -0
- package/dist/src/cli/commands/context.d.ts.map +1 -0
- package/dist/src/cli/commands/context.js +205 -0
- package/dist/src/cli/commands/context.js.map +1 -0
- package/dist/src/cli/commands/init.d.ts.map +1 -1
- package/dist/src/cli/commands/init.js +112 -70
- 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/helpers/init/external-import.d.ts +3 -0
- package/dist/src/cli/helpers/init/external-import.d.ts.map +1 -1
- package/dist/src/cli/helpers/init/external-import.js +17 -4
- package/dist/src/cli/helpers/init/external-import.js.map +1 -1
- package/dist/src/cli/helpers/init/index.d.ts +1 -0
- package/dist/src/cli/helpers/init/index.d.ts.map +1 -1
- package/dist/src/cli/helpers/init/index.js +2 -0
- package/dist/src/cli/helpers/init/index.js.map +1 -1
- package/dist/src/cli/helpers/init/jira-ado-auto-detect.d.ts +70 -0
- package/dist/src/cli/helpers/init/jira-ado-auto-detect.d.ts.map +1 -1
- package/dist/src/cli/helpers/init/jira-ado-auto-detect.js +214 -4
- package/dist/src/cli/helpers/init/jira-ado-auto-detect.js.map +1 -1
- package/dist/src/cli/helpers/init/living-docs-preflight.d.ts +4 -0
- package/dist/src/cli/helpers/init/living-docs-preflight.d.ts.map +1 -1
- package/dist/src/cli/helpers/init/living-docs-preflight.js +34 -3
- package/dist/src/cli/helpers/init/living-docs-preflight.js.map +1 -1
- package/dist/src/cli/helpers/init/testing-config.d.ts +3 -0
- package/dist/src/cli/helpers/init/testing-config.d.ts.map +1 -1
- package/dist/src/cli/helpers/init/testing-config.js +9 -2
- package/dist/src/cli/helpers/init/testing-config.js.map +1 -1
- package/dist/src/cli/helpers/init/translation-config.d.ts +3 -0
- package/dist/src/cli/helpers/init/translation-config.d.ts.map +1 -1
- package/dist/src/cli/helpers/init/translation-config.js +21 -4
- package/dist/src/cli/helpers/init/translation-config.js.map +1 -1
- package/dist/src/cli/helpers/init/wizard-navigation.d.ts +45 -0
- package/dist/src/cli/helpers/init/wizard-navigation.d.ts.map +1 -0
- package/dist/src/cli/helpers/init/wizard-navigation.js +97 -0
- package/dist/src/cli/helpers/init/wizard-navigation.js.map +1 -0
- 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 +49 -4
- package/dist/src/core/increment/increment-archiver.d.ts.map +1 -1
- package/dist/src/core/increment/increment-archiver.js +123 -22
- 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 +150 -0
- package/dist/src/core/increment/increment-utils.d.ts.map +1 -1
- package/dist/src/core/increment/increment-utils.js +216 -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-archiver.d.ts +4 -0
- package/dist/src/core/living-docs/feature-archiver.d.ts.map +1 -1
- package/dist/src/core/living-docs/feature-archiver.js +32 -10
- package/dist/src/core/living-docs/feature-archiver.js.map +1 -1
- package/dist/src/core/living-docs/feature-id-manager.d.ts.map +1 -1
- package/dist/src/core/living-docs/feature-id-manager.js +8 -4
- package/dist/src/core/living-docs/feature-id-manager.js.map +1 -1
- package/dist/src/core/living-docs/governance/ecosystem-detector.d.ts +38 -0
- package/dist/src/core/living-docs/governance/ecosystem-detector.d.ts.map +1 -0
- package/dist/src/core/living-docs/governance/ecosystem-detector.js +325 -0
- package/dist/src/core/living-docs/governance/ecosystem-detector.js.map +1 -0
- package/dist/src/core/living-docs/governance/frontend-standards-parser.d.ts +74 -0
- package/dist/src/core/living-docs/governance/frontend-standards-parser.d.ts.map +1 -0
- package/dist/src/core/living-docs/governance/frontend-standards-parser.js +366 -0
- package/dist/src/core/living-docs/governance/frontend-standards-parser.js.map +1 -0
- package/dist/src/core/living-docs/governance/go-standards-parser.d.ts +64 -0
- package/dist/src/core/living-docs/governance/go-standards-parser.d.ts.map +1 -0
- package/dist/src/core/living-docs/governance/go-standards-parser.js +229 -0
- package/dist/src/core/living-docs/governance/go-standards-parser.js.map +1 -0
- package/dist/src/core/living-docs/governance/index.d.ts +50 -0
- package/dist/src/core/living-docs/governance/index.d.ts.map +1 -0
- package/dist/src/core/living-docs/governance/index.js +56 -0
- package/dist/src/core/living-docs/governance/index.js.map +1 -0
- package/dist/src/core/living-docs/governance/java-standards-parser.d.ts +89 -0
- package/dist/src/core/living-docs/governance/java-standards-parser.d.ts.map +1 -0
- package/dist/src/core/living-docs/governance/java-standards-parser.js +356 -0
- package/dist/src/core/living-docs/governance/java-standards-parser.js.map +1 -0
- package/dist/src/core/living-docs/governance/python-standards-parser.d.ts +83 -0
- package/dist/src/core/living-docs/governance/python-standards-parser.d.ts.map +1 -0
- package/dist/src/core/living-docs/governance/python-standards-parser.js +347 -0
- package/dist/src/core/living-docs/governance/python-standards-parser.js.map +1 -0
- package/dist/src/core/living-docs/governance/standards-generator.d.ts +38 -0
- package/dist/src/core/living-docs/governance/standards-generator.d.ts.map +1 -0
- package/dist/src/core/living-docs/governance/standards-generator.js +476 -0
- package/dist/src/core/living-docs/governance/standards-generator.js.map +1 -0
- 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 +299 -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 +22 -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 +482 -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 +190 -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 +11 -3
- package/dist/src/core/living-docs/living-docs-sync.d.ts.map +1 -1
- package/dist/src/core/living-docs/living-docs-sync.js +53 -10
- package/dist/src/core/living-docs/living-docs-sync.js.map +1 -1
- package/dist/src/core/living-docs/module-analyzer.d.ts +22 -0
- package/dist/src/core/living-docs/module-analyzer.d.ts.map +1 -1
- package/dist/src/core/living-docs/module-analyzer.js +123 -19
- package/dist/src/core/living-docs/module-analyzer.js.map +1 -1
- package/dist/src/core/llm/provider-factory.js +2 -2
- package/dist/src/core/llm/provider-factory.js.map +1 -1
- package/dist/src/core/llm/providers/anthropic-provider.js +1 -1
- package/dist/src/core/llm/providers/bedrock-provider.d.ts.map +1 -1
- package/dist/src/core/llm/providers/bedrock-provider.js +8 -4
- package/dist/src/core/llm/providers/bedrock-provider.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/importers/jira-importer.d.ts +14 -0
- package/dist/src/importers/jira-importer.d.ts.map +1 -1
- package/dist/src/importers/jira-importer.js +75 -0
- package/dist/src/importers/jira-importer.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/integrations/jira/jira-token-provider.d.ts +93 -0
- package/dist/src/integrations/jira/jira-token-provider.d.ts.map +1 -0
- package/dist/src/integrations/jira/jira-token-provider.js +160 -0
- package/dist/src/integrations/jira/jira-token-provider.js.map +1 -0
- package/dist/src/sync/ado-reconciler.d.ts +92 -0
- package/dist/src/sync/ado-reconciler.d.ts.map +1 -0
- package/dist/src/sync/ado-reconciler.js +335 -0
- package/dist/src/sync/ado-reconciler.js.map +1 -0
- package/dist/src/sync/jira-reconciler.d.ts +106 -0
- package/dist/src/sync/jira-reconciler.d.ts.map +1 -0
- package/dist/src/sync/jira-reconciler.js +405 -0
- package/dist/src/sync/jira-reconciler.js.map +1 -0
- 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/types/model-selection.d.ts +6 -4
- package/dist/src/types/model-selection.d.ts.map +1 -1
- package/dist/src/types/model-selection.js +3 -1
- package/dist/src/types/model-selection.js.map +1 -1
- 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/external-tool-drift-detector.d.ts +1 -1
- package/dist/src/utils/external-tool-drift-detector.d.ts.map +1 -1
- package/dist/src/utils/external-tool-drift-detector.js +5 -4
- package/dist/src/utils/external-tool-drift-detector.js.map +1 -1
- 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/feature-id-derivation.d.ts +8 -3
- package/dist/src/utils/feature-id-derivation.d.ts.map +1 -1
- package/dist/src/utils/feature-id-derivation.js +14 -6
- package/dist/src/utils/feature-id-derivation.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/dist/src/utils/model-selection.d.ts +3 -4
- package/dist/src/utils/model-selection.d.ts.map +1 -1
- package/dist/src/utils/model-selection.js +3 -4
- package/dist/src/utils/model-selection.js.map +1 -1
- package/package.json +1 -1
- package/plugins/specweave/agents/code-standards-detective/AGENT.md +48 -0
- 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-costs.md +4 -4
- package/plugins/specweave/commands/specweave-do.md +44 -10
- package/plugins/specweave/commands/specweave-done.md +109 -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/commands/specweave-validate.md +27 -1
- package/plugins/specweave/hooks/docs-changed.sh.backup +79 -0
- package/plugins/specweave/hooks/hooks.json +43 -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/spec-project-validator.sh +80 -25
- 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/hooks/v2/guards/increment-duplicate-guard.sh +135 -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/code-standards-analyzer/SKILL.md +58 -6
- package/plugins/specweave/skills/increment-planner/SKILL.md +388 -48
- package/plugins/specweave/skills/increment-planner/templates/spec-multi-project.md +17 -7
- package/plugins/specweave/skills/increment-planner/templates/spec-single-project.md +6 -1
- package/plugins/specweave/skills/increment-planner/templates/tasks-multi-project.md +1 -1
- package/plugins/specweave/skills/increment-planner/templates/tasks-single-project.md +1 -1
- package/plugins/specweave/skills/instant-status/SKILL.md +70 -0
- package/plugins/specweave-ado/commands/cleanup-duplicates.md +212 -0
- package/plugins/specweave-ado/commands/reconcile.md +120 -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/ado-duplicate-detector.js +279 -0
- package/plugins/specweave-ado/lib/ado-duplicate-detector.ts +407 -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/agents/github-manager/AGENT.md +2 -2
- 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-infrastructure/skills/hetzner-provisioner/README.md +1 -1
- package/plugins/specweave-jira/agents/jira-manager/AGENT.md +1 -1
- package/plugins/specweave-jira/agents/jira-multi-project-mapper/AGENT.md +530 -0
- package/plugins/specweave-jira/agents/jira-sync-judge/AGENT.md +438 -0
- package/plugins/specweave-jira/commands/cleanup-duplicates.md +219 -0
- package/plugins/specweave-jira/commands/close.md +297 -0
- package/plugins/specweave-jira/commands/create.md +198 -0
- package/plugins/specweave-jira/commands/reconcile.md +123 -0
- package/plugins/specweave-jira/commands/status.md +215 -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-jira/lib/jira-duplicate-detector.js +296 -0
- package/plugins/specweave-jira/lib/jira-duplicate-detector.ts +434 -0
- package/plugins/specweave-jira/lib/jira-permission-gate.js +160 -0
- package/plugins/specweave-jira/lib/jira-permission-gate.ts +276 -0
- package/plugins/specweave-jira/lib/jira-profile-resolver.js +222 -0
- package/plugins/specweave-jira/lib/jira-profile-resolver.ts +427 -0
- package/plugins/specweave-jira/reference/jira-specweave-mapping.md +16 -11
- package/plugins/specweave-release/commands/specweave-release-npm.md +140 -14
- 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,297 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: specweave-jira:close
|
|
3
|
+
description: Close JIRA issue when increment complete
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Close JIRA Issue Command
|
|
7
|
+
|
|
8
|
+
**Usage**: `/specweave-jira:close <increment-id>`
|
|
9
|
+
|
|
10
|
+
**Purpose**: Close JIRA issue and add completion summary
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Command Behavior
|
|
15
|
+
|
|
16
|
+
When user runs this command, Claude should:
|
|
17
|
+
|
|
18
|
+
### 1. Check Permission Gate (MANDATORY FIRST STEP)
|
|
19
|
+
|
|
20
|
+
**Before ANY JIRA API calls**, check if status updates are allowed:
|
|
21
|
+
|
|
22
|
+
```typescript
|
|
23
|
+
// Read .specweave/config.json
|
|
24
|
+
const config = JSON.parse(await fs.readFile('.specweave/config.json', 'utf-8'));
|
|
25
|
+
const canUpdateExternal = config?.sync?.settings?.canUpdateExternalItems ?? false;
|
|
26
|
+
const canUpdateStatus = config?.sync?.settings?.canUpdateStatus ?? false;
|
|
27
|
+
|
|
28
|
+
// Close requires both permissions (write to close, status to change state)
|
|
29
|
+
if (!canUpdateExternal || !canUpdateStatus) {
|
|
30
|
+
const missing = [];
|
|
31
|
+
if (!canUpdateExternal) missing.push('canUpdateExternalItems');
|
|
32
|
+
if (!canUpdateStatus) missing.push('canUpdateStatus');
|
|
33
|
+
|
|
34
|
+
console.log(`
|
|
35
|
+
❌ Permission Denied
|
|
36
|
+
|
|
37
|
+
Closing JIRA issues requires these permissions:
|
|
38
|
+
${missing.map(p => ` - sync.settings.${p} = false (required: true)`).join('\n')}
|
|
39
|
+
|
|
40
|
+
To enable, update .specweave/config.json:
|
|
41
|
+
{
|
|
42
|
+
"sync": {
|
|
43
|
+
"settings": {
|
|
44
|
+
"canUpdateExternalItems": true,
|
|
45
|
+
"canUpdateStatus": true
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
`);
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### 2. Resolve JIRA Profile
|
|
55
|
+
|
|
56
|
+
Use the increment's stored profile or fall back to global defaultProfile/activeProfile:
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
// Load increment metadata
|
|
60
|
+
const metadataPath = `.specweave/increments/${incrementId}/metadata.json`;
|
|
61
|
+
const metadata = JSON.parse(await fs.readFile(metadataPath, 'utf-8'));
|
|
62
|
+
|
|
63
|
+
// Priority: increment profile > global defaultProfile > activeProfile
|
|
64
|
+
let profileName = metadata?.external_sync?.jira?.profile;
|
|
65
|
+
if (!profileName) {
|
|
66
|
+
profileName = config?.sync?.defaultProfile ?? config?.sync?.activeProfile;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Validate profile exists
|
|
70
|
+
const profileConfig = config?.sync?.profiles?.[profileName];
|
|
71
|
+
if (!profileConfig || profileConfig.provider !== 'jira') {
|
|
72
|
+
console.log(`❌ JIRA profile "${profileName}" not found`);
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const { domain, projectKey } = profileConfig.config;
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### 3. Validate Increment Completion
|
|
80
|
+
|
|
81
|
+
Before closing, verify the increment is actually complete:
|
|
82
|
+
|
|
83
|
+
```typescript
|
|
84
|
+
// Check tasks.md for completion
|
|
85
|
+
const tasksPath = `.specweave/increments/${incrementId}/tasks.md`;
|
|
86
|
+
const tasksContent = await fs.readFile(tasksPath, 'utf-8');
|
|
87
|
+
|
|
88
|
+
const totalTasks = (tasksContent.match(/### T-\d+/g) || []).length;
|
|
89
|
+
const completedTasks = (tasksContent.match(/\[x\] completed/gi) || []).length;
|
|
90
|
+
|
|
91
|
+
if (completedTasks < totalTasks) {
|
|
92
|
+
console.log(`
|
|
93
|
+
⚠️ Increment not complete
|
|
94
|
+
|
|
95
|
+
Tasks: ${completedTasks}/${totalTasks} completed
|
|
96
|
+
Cannot close JIRA issue until all tasks are done.
|
|
97
|
+
|
|
98
|
+
Complete remaining tasks first, then re-run this command.
|
|
99
|
+
`);
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### 4. Validate Issue Is Linked
|
|
105
|
+
|
|
106
|
+
```typescript
|
|
107
|
+
// Check for linked issue
|
|
108
|
+
const issueKey = metadata?.external_sync?.jira?.issueKey
|
|
109
|
+
|| metadata?.external_ids?.jira?.epic;
|
|
110
|
+
|
|
111
|
+
if (!issueKey) {
|
|
112
|
+
console.log(`
|
|
113
|
+
⚠️ No JIRA issue linked
|
|
114
|
+
|
|
115
|
+
This increment is not linked to a JIRA issue.
|
|
116
|
+
First create an issue with: /specweave-jira:create ${incrementId}
|
|
117
|
+
`);
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### 5. Invoke JIRA Manager Agent
|
|
123
|
+
|
|
124
|
+
```
|
|
125
|
+
Use Task tool with subagent_type: "specweave-jira:jira-manager:jira-manager"
|
|
126
|
+
|
|
127
|
+
Prompt: "Close JIRA issue for completed increment {increment-id}.
|
|
128
|
+
|
|
129
|
+
IMPORTANT:
|
|
130
|
+
- Permission verified: canUpdateExternalItems=true, canUpdateStatus=true
|
|
131
|
+
- Using profile: {profileName} (domain: {domain}, project: {projectKey})
|
|
132
|
+
- Issue key: {issueKey}
|
|
133
|
+
|
|
134
|
+
Steps:
|
|
135
|
+
1. Validate: All tasks in tasks.md complete
|
|
136
|
+
2. Generate: Completion summary (duration, deliverables)
|
|
137
|
+
3. Load issue key from metadata.json
|
|
138
|
+
4. GET available transitions from /rest/api/3/issue/{issueKey}/transitions
|
|
139
|
+
5. Find transition to 'Done' or 'Closed' status
|
|
140
|
+
6. POST transition: /rest/api/3/issue/{issueKey}/transitions
|
|
141
|
+
7. POST final comment with summary
|
|
142
|
+
8. Display: Closure confirmation with profile used"
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### 6. Display Result
|
|
146
|
+
|
|
147
|
+
```
|
|
148
|
+
✅ Closed JIRA Issue
|
|
149
|
+
|
|
150
|
+
Issue: {issueKey}
|
|
151
|
+
Profile: {profileName}
|
|
152
|
+
Domain: {domain}
|
|
153
|
+
Project: {projectKey}
|
|
154
|
+
|
|
155
|
+
Increment: {increment-id}
|
|
156
|
+
Status: 100% complete ({total}/{total} tasks)
|
|
157
|
+
Duration: {days} days
|
|
158
|
+
|
|
159
|
+
Summary posted to JIRA issue
|
|
160
|
+
URL: https://{domain}/browse/{issueKey}
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
## Permission Requirements
|
|
166
|
+
|
|
167
|
+
This command requires **both** permissions:
|
|
168
|
+
|
|
169
|
+
| Permission | Required | Purpose |
|
|
170
|
+
|------------|----------|---------|
|
|
171
|
+
| canUpdateExternalItems | true | Write to JIRA issue |
|
|
172
|
+
| canUpdateStatus | true | Transition issue state to Done/Closed |
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## Example Output
|
|
177
|
+
|
|
178
|
+
### Success
|
|
179
|
+
|
|
180
|
+
```
|
|
181
|
+
User: /specweave-jira:close 0005-payment-integration
|
|
182
|
+
|
|
183
|
+
Claude:
|
|
184
|
+
Checking permissions...
|
|
185
|
+
canUpdateExternalItems: true
|
|
186
|
+
canUpdateStatus: true
|
|
187
|
+
|
|
188
|
+
Resolving JIRA profile...
|
|
189
|
+
Using: jira-my-project (from increment)
|
|
190
|
+
Domain: company.atlassian.net
|
|
191
|
+
Project: MYPROJ
|
|
192
|
+
|
|
193
|
+
Validating completion...
|
|
194
|
+
Tasks: 10/10 complete
|
|
195
|
+
|
|
196
|
+
Closing issue...
|
|
197
|
+
|
|
198
|
+
✅ Closed JIRA Issue MYPROJ-123
|
|
199
|
+
|
|
200
|
+
Profile: jira-my-project
|
|
201
|
+
Increment: 0005-payment-integration
|
|
202
|
+
Status: 100% complete (10/10 tasks)
|
|
203
|
+
Duration: 3 days
|
|
204
|
+
|
|
205
|
+
Summary posted to JIRA issue
|
|
206
|
+
URL: https://company.atlassian.net/browse/MYPROJ-123
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### Permission Denied
|
|
210
|
+
|
|
211
|
+
```
|
|
212
|
+
User: /specweave-jira:close 0005
|
|
213
|
+
|
|
214
|
+
Claude:
|
|
215
|
+
Checking permissions...
|
|
216
|
+
canUpdateExternalItems: false
|
|
217
|
+
canUpdateStatus: false
|
|
218
|
+
|
|
219
|
+
❌ Permission Denied
|
|
220
|
+
|
|
221
|
+
Closing JIRA issues requires:
|
|
222
|
+
- sync.settings.canUpdateExternalItems = true
|
|
223
|
+
- sync.settings.canUpdateStatus = true
|
|
224
|
+
|
|
225
|
+
Update .specweave/config.json to enable these permissions.
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
### Incomplete Increment
|
|
229
|
+
|
|
230
|
+
```
|
|
231
|
+
User: /specweave-jira:close 0005
|
|
232
|
+
|
|
233
|
+
Claude:
|
|
234
|
+
Checking permissions...
|
|
235
|
+
canUpdateExternalItems: true
|
|
236
|
+
canUpdateStatus: true
|
|
237
|
+
|
|
238
|
+
Validating completion...
|
|
239
|
+
|
|
240
|
+
⚠️ Increment not complete
|
|
241
|
+
|
|
242
|
+
Tasks: 6/10 completed
|
|
243
|
+
Cannot close JIRA issue until all tasks are done.
|
|
244
|
+
|
|
245
|
+
Complete remaining tasks:
|
|
246
|
+
- T-007: Add refund functionality
|
|
247
|
+
- T-008: Implement subscriptions
|
|
248
|
+
- T-009: Add analytics
|
|
249
|
+
- T-010: Security audit
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
### No Issue Linked
|
|
253
|
+
|
|
254
|
+
```
|
|
255
|
+
User: /specweave-jira:close 0005
|
|
256
|
+
|
|
257
|
+
Claude:
|
|
258
|
+
Checking linked issue...
|
|
259
|
+
|
|
260
|
+
⚠️ No JIRA issue linked
|
|
261
|
+
|
|
262
|
+
This increment is not linked to a JIRA issue.
|
|
263
|
+
First create an issue with: /specweave-jira:create 0005
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
---
|
|
267
|
+
|
|
268
|
+
## Metadata Updates
|
|
269
|
+
|
|
270
|
+
After successful closure, the increment's `metadata.json` will be updated:
|
|
271
|
+
|
|
272
|
+
```json
|
|
273
|
+
{
|
|
274
|
+
"external_sync": {
|
|
275
|
+
"jira": {
|
|
276
|
+
"profile": "jira-my-project",
|
|
277
|
+
"issueKey": "MYPROJ-123",
|
|
278
|
+
"issueUrl": "https://company.atlassian.net/browse/MYPROJ-123",
|
|
279
|
+
"status": "Done",
|
|
280
|
+
"closedAt": "2025-12-07T04:30:00Z",
|
|
281
|
+
"lastSyncedAt": "2025-12-07T04:30:00Z"
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
---
|
|
288
|
+
|
|
289
|
+
## Related
|
|
290
|
+
|
|
291
|
+
| Command | Purpose |
|
|
292
|
+
|---------|---------|
|
|
293
|
+
| `/specweave-jira:pull` | Pull changes from JIRA |
|
|
294
|
+
| `/specweave-jira:push` | Push progress to JIRA |
|
|
295
|
+
| `/specweave-jira:sync` | Two-way sync |
|
|
296
|
+
| `/specweave-jira:create` | Create JIRA issue |
|
|
297
|
+
| `/specweave-jira:status` | Check sync status |
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: specweave-jira:create
|
|
3
|
+
description: Create JIRA issue from SpecWeave increment
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Create JIRA Issue Command
|
|
7
|
+
|
|
8
|
+
**Usage**: `/specweave-jira:create <increment-id>`
|
|
9
|
+
|
|
10
|
+
**Purpose**: Create an Epic or Story in JIRA from a SpecWeave increment
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Command Behavior
|
|
15
|
+
|
|
16
|
+
When user runs this command, Claude should:
|
|
17
|
+
|
|
18
|
+
### 1. Check Permission Gate (MANDATORY FIRST STEP)
|
|
19
|
+
|
|
20
|
+
**Before ANY JIRA API calls**, check if write operations are allowed:
|
|
21
|
+
|
|
22
|
+
```typescript
|
|
23
|
+
// Read .specweave/config.json
|
|
24
|
+
const config = JSON.parse(await fs.readFile('.specweave/config.json', 'utf-8'));
|
|
25
|
+
const canUpdateExternal = config?.sync?.settings?.canUpdateExternalItems ?? false;
|
|
26
|
+
|
|
27
|
+
if (!canUpdateExternal) {
|
|
28
|
+
// STOP HERE - Permission denied
|
|
29
|
+
console.log(`
|
|
30
|
+
❌ Permission Denied
|
|
31
|
+
|
|
32
|
+
JIRA write operations are disabled.
|
|
33
|
+
Setting: sync.settings.canUpdateExternalItems = false
|
|
34
|
+
|
|
35
|
+
To enable, update .specweave/config.json:
|
|
36
|
+
{
|
|
37
|
+
"sync": {
|
|
38
|
+
"settings": {
|
|
39
|
+
"canUpdateExternalItems": true
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
`);
|
|
44
|
+
return; // DO NOT proceed to create issue
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
If `canUpdateExternalItems` is `false`, display the error and **STOP**. Do not invoke the JIRA Manager agent.
|
|
49
|
+
|
|
50
|
+
### 2. Resolve JIRA Profile
|
|
51
|
+
|
|
52
|
+
Use the increment's stored profile or fall back to global defaultProfile/activeProfile:
|
|
53
|
+
|
|
54
|
+
```typescript
|
|
55
|
+
// Load increment metadata
|
|
56
|
+
const metadata = JSON.parse(await fs.readFile(
|
|
57
|
+
`.specweave/increments/${incrementId}/metadata.json`, 'utf-8'
|
|
58
|
+
));
|
|
59
|
+
|
|
60
|
+
// Check for increment-specific profile
|
|
61
|
+
let profileName = metadata?.external_sync?.jira?.profile;
|
|
62
|
+
|
|
63
|
+
// Fall back to global defaultProfile (v0.31.0+) or activeProfile (legacy)
|
|
64
|
+
if (!profileName) {
|
|
65
|
+
profileName = config?.sync?.defaultProfile ?? config?.sync?.activeProfile;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Get profile config
|
|
69
|
+
const profileConfig = config?.sync?.profiles?.[profileName];
|
|
70
|
+
if (!profileConfig || profileConfig.provider !== 'jira') {
|
|
71
|
+
console.log(`❌ Profile "${profileName}" not found or not a JIRA profile`);
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const { domain, projectKey } = profileConfig.config;
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### 3. Validate Prerequisites
|
|
79
|
+
|
|
80
|
+
- Check JIRA plugin installed
|
|
81
|
+
- Check JIRA_API_TOKEN and JIRA_EMAIL environment variables set
|
|
82
|
+
- Check JIRA profile has domain and projectKey
|
|
83
|
+
|
|
84
|
+
### 4. Invoke JIRA Manager Agent
|
|
85
|
+
|
|
86
|
+
```
|
|
87
|
+
Use Task tool with subagent_type: "specweave-jira:jira-manager:jira-manager"
|
|
88
|
+
|
|
89
|
+
Prompt: "Create JIRA issue for increment {increment-id}.
|
|
90
|
+
|
|
91
|
+
IMPORTANT: Permission already verified (canUpdateExternalItems=true).
|
|
92
|
+
Use profile: {profileName} (domain: {domain}, project: {projectKey})
|
|
93
|
+
|
|
94
|
+
Steps:
|
|
95
|
+
1. Read .specweave/increments/{increment-id}/spec.md
|
|
96
|
+
2. Extract title and description
|
|
97
|
+
3. Use JIRA domain: {domain}, project key: {projectKey}
|
|
98
|
+
4. Create Epic via JIRA REST API (POST /rest/api/3/issue)
|
|
99
|
+
5. Store issue key in increment metadata.json external_sync.jira.issueKey
|
|
100
|
+
6. Store profile name in metadata.json external_sync.jira.profile
|
|
101
|
+
7. Display: Issue Key, URL, and confirmation"
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### 5. Display Result
|
|
105
|
+
|
|
106
|
+
```
|
|
107
|
+
✅ Created JIRA Epic
|
|
108
|
+
|
|
109
|
+
Issue: PROJ-123
|
|
110
|
+
URL: https://{domain}/browse/PROJ-123
|
|
111
|
+
Profile: {profileName}
|
|
112
|
+
|
|
113
|
+
Linked to increment: {increment-id}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
## Permission Denied Output
|
|
119
|
+
|
|
120
|
+
If `canUpdateExternalItems` is false:
|
|
121
|
+
|
|
122
|
+
```
|
|
123
|
+
❌ Permission Denied: JIRA Write Operations Disabled
|
|
124
|
+
|
|
125
|
+
Your configuration prevents creating/updating JIRA issues.
|
|
126
|
+
|
|
127
|
+
Current setting:
|
|
128
|
+
sync.settings.canUpdateExternalItems = false
|
|
129
|
+
|
|
130
|
+
To enable JIRA writes:
|
|
131
|
+
1. Edit .specweave/config.json
|
|
132
|
+
2. Set sync.settings.canUpdateExternalItems to true
|
|
133
|
+
3. Re-run this command
|
|
134
|
+
|
|
135
|
+
This setting was configured during 'specweave init'.
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
## Example Usage
|
|
141
|
+
|
|
142
|
+
```
|
|
143
|
+
User: /specweave-jira:create 0005-payment-integration
|
|
144
|
+
|
|
145
|
+
# If permission granted:
|
|
146
|
+
Claude: Checking JIRA permissions...
|
|
147
|
+
✓ canUpdateExternalItems: true
|
|
148
|
+
|
|
149
|
+
Resolving JIRA profile...
|
|
150
|
+
✓ Using profile: jira-my-project (from increment)
|
|
151
|
+
✓ Domain: company.atlassian.net
|
|
152
|
+
✓ Project: MYPROJ
|
|
153
|
+
|
|
154
|
+
Creating issue...
|
|
155
|
+
[Invokes JIRA Manager Agent]
|
|
156
|
+
|
|
157
|
+
✅ Created JIRA Epic MYPROJ-123
|
|
158
|
+
URL: https://company.atlassian.net/browse/MYPROJ-123
|
|
159
|
+
|
|
160
|
+
# If permission denied:
|
|
161
|
+
Claude: Checking JIRA permissions...
|
|
162
|
+
❌ Permission Denied
|
|
163
|
+
|
|
164
|
+
sync.settings.canUpdateExternalItems = false
|
|
165
|
+
|
|
166
|
+
To enable: Edit .specweave/config.json and set canUpdateExternalItems to true
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
## Metadata Updates
|
|
172
|
+
|
|
173
|
+
After successful creation, the increment's `metadata.json` will be updated:
|
|
174
|
+
|
|
175
|
+
```json
|
|
176
|
+
{
|
|
177
|
+
"external_sync": {
|
|
178
|
+
"jira": {
|
|
179
|
+
"profile": "jira-my-project",
|
|
180
|
+
"issueKey": "MYPROJ-123",
|
|
181
|
+
"issueUrl": "https://company.atlassian.net/browse/MYPROJ-123",
|
|
182
|
+
"lastSyncedAt": "2025-12-07T04:30:00Z"
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
## Related
|
|
191
|
+
|
|
192
|
+
| Command | Purpose |
|
|
193
|
+
|---------|---------|
|
|
194
|
+
| `/specweave-jira:pull` | Pull changes from JIRA |
|
|
195
|
+
| `/specweave-jira:push` | Push progress to JIRA |
|
|
196
|
+
| `/specweave-jira:sync` | Two-way sync |
|
|
197
|
+
| `/specweave-jira:status` | Check sync status |
|
|
198
|
+
| `/specweave-jira:close` | Close issue when complete |
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: specweave-jira:reconcile
|
|
3
|
+
description: Reconcile JIRA issue states with increment statuses. Fixes drift by closing issues for completed increments and reopening issues for resumed increments.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# JIRA Status Reconciliation
|
|
7
|
+
|
|
8
|
+
Scan all increments and fix any drift between local metadata.json status and JIRA issue states.
|
|
9
|
+
|
|
10
|
+
## Usage
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
/specweave-jira:reconcile [options]
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Options
|
|
17
|
+
|
|
18
|
+
- `--dry-run`: Preview changes without making them
|
|
19
|
+
- `--verbose`: Show detailed output for each issue checked
|
|
20
|
+
|
|
21
|
+
## What It Does
|
|
22
|
+
|
|
23
|
+
1. **Scans** all non-archived increments
|
|
24
|
+
2. **Compares** metadata.json status with JIRA issue state
|
|
25
|
+
3. **Fixes** mismatches:
|
|
26
|
+
- `metadata=completed` + `JIRA=In Progress` → **Close** the issue (transition to Done)
|
|
27
|
+
- `metadata=in-progress` + `JIRA=Done` → **Reopen** the issue (transition to To Do)
|
|
28
|
+
|
|
29
|
+
## When to Use
|
|
30
|
+
|
|
31
|
+
- After manual metadata.json edits
|
|
32
|
+
- After git pulls that changed increment statuses
|
|
33
|
+
- When you notice open issues for completed work
|
|
34
|
+
- As a periodic health check
|
|
35
|
+
|
|
36
|
+
## Implementation
|
|
37
|
+
|
|
38
|
+
Run the reconciliation using the JiraReconciler:
|
|
39
|
+
|
|
40
|
+
```typescript
|
|
41
|
+
import { JiraReconciler } from '../../../src/sync/jira-reconciler.js';
|
|
42
|
+
|
|
43
|
+
const reconciler = new JiraReconciler({
|
|
44
|
+
projectRoot: process.cwd(),
|
|
45
|
+
dryRun: args.includes('--dry-run'),
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
const result = await reconciler.reconcile();
|
|
49
|
+
|
|
50
|
+
// Report results
|
|
51
|
+
console.log(`\nReconciliation complete:`);
|
|
52
|
+
console.log(` Scanned: ${result.scanned} increments`);
|
|
53
|
+
console.log(` Fixed: ${result.closed} closed, ${result.reopened} reopened`);
|
|
54
|
+
if (result.errors.length > 0) {
|
|
55
|
+
console.log(` Errors: ${result.errors.length}`);
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Example Output
|
|
60
|
+
|
|
61
|
+
```
|
|
62
|
+
📊 Scanning 5 increment(s) for JIRA state drift...
|
|
63
|
+
|
|
64
|
+
✅ Issue PROJ-123 (0056-plugin-fix/US-001): State matches (In Progress)
|
|
65
|
+
❌ Issue PROJ-130 (0066-import-wizard/US-003): In Progress but should be CLOSED (status=completed)
|
|
66
|
+
✅ Closed issue PROJ-130
|
|
67
|
+
❌ Issue PROJ-128 (0063-multi-repo/US-001): CLOSED but should be OPEN (status=in-progress)
|
|
68
|
+
✅ Reopened issue PROJ-128
|
|
69
|
+
|
|
70
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
71
|
+
📊 JIRA RECONCILIATION SUMMARY
|
|
72
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
73
|
+
Increments scanned: 5
|
|
74
|
+
Mismatches found: 2
|
|
75
|
+
Issues closed: 1
|
|
76
|
+
Issues reopened: 1
|
|
77
|
+
Errors: 0
|
|
78
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Dry Run Mode
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
/specweave-jira:reconcile --dry-run
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Shows what would be changed without making any modifications:
|
|
88
|
+
|
|
89
|
+
```
|
|
90
|
+
❌ Issue PROJ-130 (0066-import-wizard/US-003): In Progress but should be CLOSED
|
|
91
|
+
[DRY RUN] Would close issue PROJ-130
|
|
92
|
+
|
|
93
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
94
|
+
📊 JIRA RECONCILIATION SUMMARY
|
|
95
|
+
⚠️ DRY RUN - No changes were made
|
|
96
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## Requirements
|
|
100
|
+
|
|
101
|
+
- JIRA API token configured (`JIRA_API_TOKEN`)
|
|
102
|
+
- JIRA email configured (`JIRA_EMAIL`)
|
|
103
|
+
- JIRA domain configured (`JIRA_DOMAIN`)
|
|
104
|
+
- `sync.jira.enabled = true` in config.json
|
|
105
|
+
- `sync.settings.canUpdateExternalItems = true` in config.json
|
|
106
|
+
- `sync.settings.canUpdateStatus = true` in config.json
|
|
107
|
+
|
|
108
|
+
## JIRA Status Mapping
|
|
109
|
+
|
|
110
|
+
| SpecWeave Status | Expected JIRA Status |
|
|
111
|
+
|-----------------|---------------------|
|
|
112
|
+
| `completed` | Done, Closed, Resolved |
|
|
113
|
+
| `abandoned` | Won't Do, Closed |
|
|
114
|
+
| `in-progress` | In Progress, In Review |
|
|
115
|
+
| `active` | To Do, Open |
|
|
116
|
+
| `planning` | To Do |
|
|
117
|
+
|
|
118
|
+
## Related Commands
|
|
119
|
+
|
|
120
|
+
- `/specweave-jira:status`: View sync status for increments
|
|
121
|
+
- `/specweave-jira:sync`: Manual sync to JIRA
|
|
122
|
+
- `/specweave:done`: Close increment (triggers auto-close)
|
|
123
|
+
- `/specweave:resume`: Resume increment (now triggers auto-reopen)
|