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,215 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: specweave-jira:status
|
|
3
|
+
description: Check JIRA sync status for SpecWeave increment
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# JIRA Status Command
|
|
7
|
+
|
|
8
|
+
**Usage**: `/specweave-jira:status <increment-id>`
|
|
9
|
+
|
|
10
|
+
**Purpose**: Display JIRA sync status and issue details for an increment
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Command Behavior
|
|
15
|
+
|
|
16
|
+
When user runs this command, Claude should:
|
|
17
|
+
|
|
18
|
+
### 1. Read Increment Metadata
|
|
19
|
+
|
|
20
|
+
```typescript
|
|
21
|
+
// Load increment metadata
|
|
22
|
+
const metadataPath = `.specweave/increments/${incrementId}/metadata.json`;
|
|
23
|
+
const metadata = JSON.parse(await fs.readFile(metadataPath, 'utf-8'));
|
|
24
|
+
|
|
25
|
+
// Check for linked JIRA issue (check both standard and legacy paths)
|
|
26
|
+
const jiraSync = metadata?.external_sync?.jira || metadata?.external_ids?.jira;
|
|
27
|
+
const issueKey = jiraSync?.issueKey || jiraSync?.epic;
|
|
28
|
+
|
|
29
|
+
if (!issueKey) {
|
|
30
|
+
console.log(`
|
|
31
|
+
⚠️ No JIRA issue linked
|
|
32
|
+
|
|
33
|
+
This increment is not linked to a JIRA issue.
|
|
34
|
+
Create one with: /specweave-jira:create ${incrementId}
|
|
35
|
+
`);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### 2. Resolve JIRA Profile
|
|
41
|
+
|
|
42
|
+
```typescript
|
|
43
|
+
// Priority: increment profile > global defaultProfile > activeProfile
|
|
44
|
+
let profileName = jiraSync?.profile;
|
|
45
|
+
if (!profileName) {
|
|
46
|
+
const config = JSON.parse(await fs.readFile('.specweave/config.json', 'utf-8'));
|
|
47
|
+
profileName = config?.sync?.defaultProfile ?? config?.sync?.activeProfile;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const profileConfig = config?.sync?.profiles?.[profileName];
|
|
51
|
+
const { domain, projectKey } = profileConfig?.config || {};
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### 3. Read Local Task Status
|
|
55
|
+
|
|
56
|
+
```typescript
|
|
57
|
+
// Check tasks.md for completion
|
|
58
|
+
const tasksPath = `.specweave/increments/${incrementId}/tasks.md`;
|
|
59
|
+
const tasksContent = await fs.readFile(tasksPath, 'utf-8');
|
|
60
|
+
|
|
61
|
+
const totalTasks = (tasksContent.match(/### T-\d+/g) || []).length;
|
|
62
|
+
const completedTasks = (tasksContent.match(/\[x\] completed/gi) || []).length;
|
|
63
|
+
const completion = totalTasks > 0 ? Math.round((completedTasks / totalTasks) * 100) : 0;
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### 4. Invoke JIRA Manager Agent (Optional - For Live Status)
|
|
67
|
+
|
|
68
|
+
```
|
|
69
|
+
Use Task tool with subagent_type: "specweave-jira:jira-manager:jira-manager"
|
|
70
|
+
|
|
71
|
+
Prompt: "Check JIRA sync status for increment {increment-id}.
|
|
72
|
+
|
|
73
|
+
Issue Key: {issueKey}
|
|
74
|
+
Profile: {profileName} (domain: {domain})
|
|
75
|
+
|
|
76
|
+
Steps:
|
|
77
|
+
1. GET issue from JIRA API: /rest/api/3/issue/{issueKey}
|
|
78
|
+
2. Extract: status, priority, assignee, sprint, story points
|
|
79
|
+
3. Compare local vs JIRA status
|
|
80
|
+
4. Detect any sync issues or drift
|
|
81
|
+
5. Display comprehensive status"
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### 5. Display Status
|
|
85
|
+
|
|
86
|
+
```
|
|
87
|
+
JIRA Sync Status
|
|
88
|
+
================
|
|
89
|
+
Increment: {increment-id}
|
|
90
|
+
Issue: {issueKey}
|
|
91
|
+
URL: https://{domain}/browse/{issueKey}
|
|
92
|
+
Status: {jiraStatus}
|
|
93
|
+
Completion: {completion}% ({completedTasks}/{totalTasks} tasks)
|
|
94
|
+
Last Synced: {lastSyncedAt} ({relativeTime})
|
|
95
|
+
Sync Enabled: ✅
|
|
96
|
+
|
|
97
|
+
Profile: {profileName}
|
|
98
|
+
Domain: {domain}
|
|
99
|
+
Project: {projectKey}
|
|
100
|
+
|
|
101
|
+
Next Sync: Automatic on task completion
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## Example Output
|
|
107
|
+
|
|
108
|
+
### Issue Linked
|
|
109
|
+
|
|
110
|
+
```
|
|
111
|
+
User: /specweave-jira:status 0005-payment-integration
|
|
112
|
+
|
|
113
|
+
Claude:
|
|
114
|
+
JIRA Sync Status
|
|
115
|
+
================
|
|
116
|
+
Increment: 0005-payment-integration
|
|
117
|
+
Issue: MYPROJ-123
|
|
118
|
+
URL: https://company.atlassian.net/browse/MYPROJ-123
|
|
119
|
+
Status: In Progress
|
|
120
|
+
Completion: 60% (6/10 tasks)
|
|
121
|
+
Last Synced: 2025-12-07 10:30:00 (5 minutes ago)
|
|
122
|
+
Sync Enabled: ✅
|
|
123
|
+
|
|
124
|
+
Profile: jira-my-project
|
|
125
|
+
Domain: company.atlassian.net
|
|
126
|
+
Project: MYPROJ
|
|
127
|
+
|
|
128
|
+
Priority: High
|
|
129
|
+
Assignee: john.doe
|
|
130
|
+
Sprint: Sprint 42
|
|
131
|
+
|
|
132
|
+
Next Sync: Automatic on task completion
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### No Issue Linked
|
|
136
|
+
|
|
137
|
+
```
|
|
138
|
+
User: /specweave-jira:status 0005
|
|
139
|
+
|
|
140
|
+
Claude:
|
|
141
|
+
JIRA Sync Status
|
|
142
|
+
================
|
|
143
|
+
Increment: 0005-payment-integration
|
|
144
|
+
|
|
145
|
+
⚠️ No JIRA issue linked
|
|
146
|
+
|
|
147
|
+
This increment is not linked to a JIRA issue.
|
|
148
|
+
Create one with: /specweave-jira:create 0005-payment-integration
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### Sync Issues Detected
|
|
152
|
+
|
|
153
|
+
```
|
|
154
|
+
User: /specweave-jira:status 0005
|
|
155
|
+
|
|
156
|
+
Claude:
|
|
157
|
+
JIRA Sync Status
|
|
158
|
+
================
|
|
159
|
+
Increment: 0005-payment-integration
|
|
160
|
+
Issue: MYPROJ-123
|
|
161
|
+
URL: https://company.atlassian.net/browse/MYPROJ-123
|
|
162
|
+
Status: In Progress
|
|
163
|
+
Completion: 60% (6/10 tasks)
|
|
164
|
+
Last Synced: 2025-12-05 10:30:00 (2 days ago)
|
|
165
|
+
Sync Enabled: ✅
|
|
166
|
+
|
|
167
|
+
⚠️ Sync Issues Detected:
|
|
168
|
+
- Local status: in_progress, JIRA status: Done
|
|
169
|
+
- Status drift detected - run /specweave-jira:pull to sync
|
|
170
|
+
|
|
171
|
+
Profile: jira-my-project
|
|
172
|
+
Domain: company.atlassian.net
|
|
173
|
+
Project: MYPROJ
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
## Status Information Displayed
|
|
179
|
+
|
|
180
|
+
| Field | Source | Description |
|
|
181
|
+
|-------|--------|-------------|
|
|
182
|
+
| Issue | metadata.json | JIRA issue key (e.g., PROJ-123) |
|
|
183
|
+
| URL | Constructed | Direct link to JIRA issue |
|
|
184
|
+
| Status | JIRA API | Current issue status |
|
|
185
|
+
| Completion | tasks.md | Local completion percentage |
|
|
186
|
+
| Last Synced | metadata.json | Timestamp of last sync |
|
|
187
|
+
| Profile | metadata/config | Which JIRA profile is used |
|
|
188
|
+
| Priority | JIRA API | Issue priority |
|
|
189
|
+
| Assignee | JIRA API | Current assignee |
|
|
190
|
+
| Sprint | JIRA API | Current sprint assignment |
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
## Drift Detection
|
|
195
|
+
|
|
196
|
+
The status command detects common sync issues:
|
|
197
|
+
|
|
198
|
+
| Issue | Detection | Resolution |
|
|
199
|
+
|-------|-----------|------------|
|
|
200
|
+
| Status drift | Local vs JIRA status mismatch | `/specweave-jira:pull` |
|
|
201
|
+
| Stale sync | Last synced > 24 hours ago | `/specweave-jira:sync` |
|
|
202
|
+
| Missing issue | Issue deleted in JIRA | `/specweave-jira:create` |
|
|
203
|
+
| Permission denied | canUpdateExternalItems=false | Read-only mode note |
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
207
|
+
## Related
|
|
208
|
+
|
|
209
|
+
| Command | Purpose |
|
|
210
|
+
|---------|---------|
|
|
211
|
+
| `/specweave-jira:pull` | Pull changes from JIRA |
|
|
212
|
+
| `/specweave-jira:push` | Push progress to JIRA |
|
|
213
|
+
| `/specweave-jira:sync` | Two-way sync |
|
|
214
|
+
| `/specweave-jira:create` | Create JIRA issue |
|
|
215
|
+
| `/specweave-jira:close` | Close issue when complete |
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# SpecWeave JIRA Sync Hook
|
|
4
|
+
# Runs after task completion to sync progress to JIRA Issues
|
|
5
|
+
#
|
|
6
|
+
# This hook is part of the specweave-jira plugin and handles:
|
|
7
|
+
# - Syncing task completion state to JIRA issues
|
|
8
|
+
# - Updating JIRA issue status based on increment progress
|
|
9
|
+
#
|
|
10
|
+
# Dependencies:
|
|
11
|
+
# - Node.js for running sync scripts
|
|
12
|
+
# - jq for JSON parsing
|
|
13
|
+
# - metadata.json must have .jira.issue field
|
|
14
|
+
# - JIRA API credentials in .env
|
|
15
|
+
|
|
16
|
+
set -e
|
|
17
|
+
|
|
18
|
+
# ============================================================================
|
|
19
|
+
# PROJECT ROOT DETECTION
|
|
20
|
+
# ============================================================================
|
|
21
|
+
|
|
22
|
+
# Find project root by searching upward for .specweave/ directory
|
|
23
|
+
find_project_root() {
|
|
24
|
+
local dir="$1"
|
|
25
|
+
while [ "$dir" != "/" ]; do
|
|
26
|
+
if [ -d "$dir/.specweave" ]; then
|
|
27
|
+
echo "$dir"
|
|
28
|
+
return 0
|
|
29
|
+
fi
|
|
30
|
+
dir="$(dirname "$dir")"
|
|
31
|
+
done
|
|
32
|
+
# Fallback: try current directory
|
|
33
|
+
if [ -d "$(pwd)/.specweave" ]; then
|
|
34
|
+
pwd
|
|
35
|
+
else
|
|
36
|
+
echo "$(pwd)"
|
|
37
|
+
fi
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
PROJECT_ROOT="$(find_project_root "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")"
|
|
41
|
+
cd "$PROJECT_ROOT" 2>/dev/null || true
|
|
42
|
+
|
|
43
|
+
# ============================================================================
|
|
44
|
+
# CONFIGURATION
|
|
45
|
+
# ============================================================================
|
|
46
|
+
|
|
47
|
+
LOGS_DIR=".specweave/logs"
|
|
48
|
+
DEBUG_LOG="$LOGS_DIR/hooks-debug.log"
|
|
49
|
+
|
|
50
|
+
mkdir -p "$LOGS_DIR" 2>/dev/null || true
|
|
51
|
+
|
|
52
|
+
# ============================================================================
|
|
53
|
+
# PRECONDITIONS CHECK
|
|
54
|
+
# ============================================================================
|
|
55
|
+
|
|
56
|
+
echo "[$(date)] [JIRA] 🔗 JIRA sync hook fired" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
57
|
+
|
|
58
|
+
# Detect current increment
|
|
59
|
+
CURRENT_INCREMENT=$(ls -td .specweave/increments/*/ 2>/dev/null | xargs -n1 basename | grep -v "_backlog" | grep -v "_archive" | grep -v "_working" | head -1)
|
|
60
|
+
|
|
61
|
+
if [ -z "$CURRENT_INCREMENT" ]; then
|
|
62
|
+
echo "[$(date)] [JIRA] ℹ️ No active increment, skipping JIRA sync" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
63
|
+
cat <<EOF
|
|
64
|
+
{
|
|
65
|
+
"continue": true
|
|
66
|
+
}
|
|
67
|
+
EOF
|
|
68
|
+
exit 0
|
|
69
|
+
fi
|
|
70
|
+
|
|
71
|
+
# Check for metadata.json
|
|
72
|
+
METADATA_FILE=".specweave/increments/$CURRENT_INCREMENT/metadata.json"
|
|
73
|
+
|
|
74
|
+
if [ ! -f "$METADATA_FILE" ]; then
|
|
75
|
+
echo "[$(date)] [JIRA] ℹ️ No metadata.json for $CURRENT_INCREMENT, skipping JIRA sync" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
76
|
+
cat <<EOF
|
|
77
|
+
{
|
|
78
|
+
"continue": true
|
|
79
|
+
}
|
|
80
|
+
EOF
|
|
81
|
+
exit 0
|
|
82
|
+
fi
|
|
83
|
+
|
|
84
|
+
# Check for JIRA issue link
|
|
85
|
+
if ! command -v jq &> /dev/null; then
|
|
86
|
+
echo "[$(date)] [JIRA] ⚠️ jq not found, skipping JIRA sync" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
87
|
+
cat <<EOF
|
|
88
|
+
{
|
|
89
|
+
"continue": true
|
|
90
|
+
}
|
|
91
|
+
EOF
|
|
92
|
+
exit 0
|
|
93
|
+
fi
|
|
94
|
+
|
|
95
|
+
JIRA_ISSUE=$(jq -r '.jira.issue // empty' "$METADATA_FILE" 2>/dev/null)
|
|
96
|
+
|
|
97
|
+
if [ -z "$JIRA_ISSUE" ]; then
|
|
98
|
+
echo "[$(date)] [JIRA] ℹ️ No JIRA issue linked to $CURRENT_INCREMENT, skipping sync" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
99
|
+
cat <<EOF
|
|
100
|
+
{
|
|
101
|
+
"continue": true
|
|
102
|
+
}
|
|
103
|
+
EOF
|
|
104
|
+
exit 0
|
|
105
|
+
fi
|
|
106
|
+
|
|
107
|
+
# Check for Node.js
|
|
108
|
+
if ! command -v node &> /dev/null; then
|
|
109
|
+
echo "[$(date)] [JIRA] ⚠️ Node.js not found, skipping JIRA sync" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
110
|
+
cat <<EOF
|
|
111
|
+
{
|
|
112
|
+
"continue": true
|
|
113
|
+
}
|
|
114
|
+
EOF
|
|
115
|
+
exit 0
|
|
116
|
+
fi
|
|
117
|
+
|
|
118
|
+
# Check for JIRA sync script
|
|
119
|
+
if [ ! -f "dist/commands/jira-sync.js" ]; then
|
|
120
|
+
echo "[$(date)] [JIRA] ⚠️ jira-sync.js not found, skipping JIRA sync" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
121
|
+
cat <<EOF
|
|
122
|
+
{
|
|
123
|
+
"continue": true
|
|
124
|
+
}
|
|
125
|
+
EOF
|
|
126
|
+
exit 0
|
|
127
|
+
fi
|
|
128
|
+
|
|
129
|
+
# ============================================================================
|
|
130
|
+
# JIRA SYNC LOGIC
|
|
131
|
+
# ============================================================================
|
|
132
|
+
|
|
133
|
+
echo "[$(date)] [JIRA] 🔄 Syncing to JIRA issue $JIRA_ISSUE" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
134
|
+
|
|
135
|
+
# Run JIRA sync command (non-blocking)
|
|
136
|
+
node dist/commands/jira-sync.js "$CURRENT_INCREMENT" 2>&1 | tee -a "$DEBUG_LOG" >/dev/null || {
|
|
137
|
+
echo "[$(date)] [JIRA] ⚠️ Failed to sync to JIRA (non-blocking)" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
echo "[$(date)] [JIRA] ✅ JIRA sync complete" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
141
|
+
|
|
142
|
+
# ============================================================================
|
|
143
|
+
# SPEC COMMIT SYNC (NEW!)
|
|
144
|
+
# ============================================================================
|
|
145
|
+
|
|
146
|
+
echo "[$(date)] [JIRA] 🔗 Checking for spec commit sync..." >> "$DEBUG_LOG" 2>/dev/null || true
|
|
147
|
+
|
|
148
|
+
# Call TypeScript CLI to sync commits
|
|
149
|
+
if command -v node &> /dev/null && [ -f "$PROJECT_ROOT/dist/cli/commands/sync-spec-commits.js" ]; then
|
|
150
|
+
echo "[$(date)] [JIRA] 🚀 Running spec commit sync..." >> "$DEBUG_LOG" 2>/dev/null || true
|
|
151
|
+
|
|
152
|
+
node "$PROJECT_ROOT/dist/cli/commands/sync-spec-commits.js" \
|
|
153
|
+
--increment "$PROJECT_ROOT/.specweave/increments/$CURRENT_INCREMENT" \
|
|
154
|
+
--provider jira \
|
|
155
|
+
2>&1 | tee -a "$DEBUG_LOG" >/dev/null || {
|
|
156
|
+
echo "[$(date)] [JIRA] ⚠️ Spec commit sync failed (non-blocking)" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
echo "[$(date)] [JIRA] ✅ Spec commit sync complete" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
160
|
+
else
|
|
161
|
+
echo "[$(date)] [JIRA] ℹ️ Spec commit sync not available (node or script not found)" >> "$DEBUG_LOG" 2>/dev/null || true
|
|
162
|
+
fi
|
|
163
|
+
|
|
164
|
+
# ============================================================================
|
|
165
|
+
# OUTPUT TO CLAUDE
|
|
166
|
+
# ============================================================================
|
|
167
|
+
|
|
168
|
+
cat <<EOF
|
|
169
|
+
{
|
|
170
|
+
"continue": true
|
|
171
|
+
}
|
|
172
|
+
EOF
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { EnhancedContentBuilder } from "../../../dist/src/core/sync/enhanced-content-builder.js";
|
|
2
|
+
import { SpecIncrementMapper } from "../../../dist/src/core/sync/spec-increment-mapper.js";
|
|
3
|
+
import { parseSpecContent } from "../../../dist/src/core/spec-content-sync.js";
|
|
4
|
+
import * as path from "path";
|
|
5
|
+
import * as fs from "fs/promises";
|
|
6
|
+
async function syncSpecToJiraWithEnhancedContent(options) {
|
|
7
|
+
const { specPath, domain, project, dryRun = false, verbose = false } = options;
|
|
8
|
+
try {
|
|
9
|
+
const baseSpec = await parseSpecContent(specPath);
|
|
10
|
+
if (!baseSpec) {
|
|
11
|
+
return {
|
|
12
|
+
success: false,
|
|
13
|
+
action: "error",
|
|
14
|
+
error: "Failed to parse spec content"
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
if (verbose) {
|
|
18
|
+
console.log(`\u{1F4C4} Parsed spec: ${baseSpec.identifier.compact}`);
|
|
19
|
+
}
|
|
20
|
+
const specId = baseSpec.identifier.full || baseSpec.identifier.compact;
|
|
21
|
+
const rootDir = await findSpecWeaveRoot(specPath);
|
|
22
|
+
const mapper = new SpecIncrementMapper(rootDir);
|
|
23
|
+
const mapping = await mapper.mapSpecToIncrements(specId);
|
|
24
|
+
if (verbose) {
|
|
25
|
+
console.log(`\u{1F517} Found ${mapping.increments.length} related increments`);
|
|
26
|
+
}
|
|
27
|
+
const taskMapping = buildTaskMapping(mapping.increments);
|
|
28
|
+
const architectureDocs = await findArchitectureDocs(rootDir, specId);
|
|
29
|
+
const enhancedSpec = {
|
|
30
|
+
...baseSpec,
|
|
31
|
+
summary: baseSpec.description,
|
|
32
|
+
taskMapping,
|
|
33
|
+
architectureDocs
|
|
34
|
+
};
|
|
35
|
+
const builder = new EnhancedContentBuilder();
|
|
36
|
+
const description = builder.buildExternalDescription(enhancedSpec);
|
|
37
|
+
if (verbose) {
|
|
38
|
+
console.log(`\u{1F4DD} Generated description: ${description.length} characters`);
|
|
39
|
+
}
|
|
40
|
+
if (dryRun) {
|
|
41
|
+
console.log("\u{1F50D} DRY RUN - Would create/update epic with:");
|
|
42
|
+
console.log(` Summary: ${baseSpec.title}`);
|
|
43
|
+
console.log(` Description length: ${description.length}`);
|
|
44
|
+
return {
|
|
45
|
+
success: true,
|
|
46
|
+
action: "no-change",
|
|
47
|
+
tasksLinked: taskMapping?.tasks.length || 0
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
if (!dryRun && (!domain || !project)) {
|
|
51
|
+
return {
|
|
52
|
+
success: false,
|
|
53
|
+
action: "error",
|
|
54
|
+
error: "JIRA domain/project not specified (required for actual sync)"
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
const result = {
|
|
58
|
+
success: true,
|
|
59
|
+
action: dryRun ? "no-change" : "created",
|
|
60
|
+
// Assume create if not dry run
|
|
61
|
+
tasksLinked: taskMapping?.tasks.length || 0
|
|
62
|
+
};
|
|
63
|
+
if (domain && project && !dryRun) {
|
|
64
|
+
result.epicKey = `SPEC-001`;
|
|
65
|
+
result.epicUrl = `https://${domain}/browse/SPEC-001`;
|
|
66
|
+
if (verbose) {
|
|
67
|
+
console.log(`\u26A0\uFE0F JIRA API integration not implemented in this file`);
|
|
68
|
+
console.log(` Use jira-spec-sync.ts for actual JIRA synchronization`);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return result;
|
|
72
|
+
} catch (error) {
|
|
73
|
+
return {
|
|
74
|
+
success: false,
|
|
75
|
+
action: "error",
|
|
76
|
+
error: error.message
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
async function findSpecWeaveRoot(specPath) {
|
|
81
|
+
let currentDir = path.dirname(specPath);
|
|
82
|
+
while (true) {
|
|
83
|
+
const specweaveDir = path.join(currentDir, ".specweave");
|
|
84
|
+
try {
|
|
85
|
+
await fs.access(specweaveDir);
|
|
86
|
+
return currentDir;
|
|
87
|
+
} catch {
|
|
88
|
+
const parentDir = path.dirname(currentDir);
|
|
89
|
+
if (parentDir === currentDir) {
|
|
90
|
+
throw new Error(".specweave directory not found");
|
|
91
|
+
}
|
|
92
|
+
currentDir = parentDir;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
function buildTaskMapping(increments) {
|
|
97
|
+
if (increments.length === 0) return void 0;
|
|
98
|
+
const firstIncrement = increments[0];
|
|
99
|
+
const tasks = firstIncrement.tasks.map((task) => ({
|
|
100
|
+
id: task.id,
|
|
101
|
+
title: task.title,
|
|
102
|
+
userStories: task.userStories
|
|
103
|
+
}));
|
|
104
|
+
return {
|
|
105
|
+
incrementId: firstIncrement.id,
|
|
106
|
+
tasks,
|
|
107
|
+
tasksUrl: `tasks.md`
|
|
108
|
+
// JIRA doesn't support external links in same way
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
async function findArchitectureDocs(rootDir, specId) {
|
|
112
|
+
const docs = [];
|
|
113
|
+
const archDir = path.join(rootDir, ".specweave/docs/internal/architecture");
|
|
114
|
+
try {
|
|
115
|
+
const adrDir = path.join(archDir, "adr");
|
|
116
|
+
try {
|
|
117
|
+
const adrs = await fs.readdir(adrDir);
|
|
118
|
+
const relatedAdrs = adrs.filter((file) => file.includes(specId.replace("spec-", "")));
|
|
119
|
+
for (const adr of relatedAdrs) {
|
|
120
|
+
docs.push({
|
|
121
|
+
type: "adr",
|
|
122
|
+
path: path.join(adrDir, adr),
|
|
123
|
+
title: adr.replace(".md", "").replace(/-/g, " ")
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
} catch {
|
|
127
|
+
}
|
|
128
|
+
} catch {
|
|
129
|
+
}
|
|
130
|
+
return docs;
|
|
131
|
+
}
|
|
132
|
+
export {
|
|
133
|
+
syncSpecToJiraWithEnhancedContent
|
|
134
|
+
};
|