specweave 0.22.13 → 0.23.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 +2 -2
- package/CLAUDE.md +447 -52
- package/README.md +33 -10
- package/dist/plugins/specweave-github/lib/ThreeLayerSyncManager.d.ts +1 -1
- package/dist/plugins/specweave-github/lib/ThreeLayerSyncManager.js +1 -1
- package/dist/plugins/specweave-github/lib/enhanced-github-sync.js +1 -1
- package/dist/plugins/specweave-github/lib/enhanced-github-sync.js.map +1 -1
- package/dist/plugins/specweave-github/lib/github-spec-content-sync.d.ts.map +1 -1
- package/dist/plugins/specweave-github/lib/github-spec-content-sync.js +4 -1
- package/dist/plugins/specweave-github/lib/github-spec-content-sync.js.map +1 -1
- package/dist/plugins/specweave-github/lib/github-spec-sync.d.ts +1 -1
- package/dist/plugins/specweave-github/lib/github-spec-sync.js +1 -1
- package/dist/plugins/specweave-github/lib/github-sync-bidirectional.d.ts +9 -0
- package/dist/plugins/specweave-github/lib/github-sync-bidirectional.d.ts.map +1 -1
- package/dist/plugins/specweave-github/lib/github-sync-bidirectional.js +10 -1
- package/dist/plugins/specweave-github/lib/github-sync-bidirectional.js.map +1 -1
- package/dist/plugins/specweave-github/lib/progress-comment-builder.js +2 -2
- package/dist/plugins/specweave-github/lib/progress-comment-builder.js.map +1 -1
- package/dist/plugins/specweave-github/lib/types.d.ts +1 -1
- package/dist/src/cli/commands/import-external.d.ts +22 -0
- package/dist/src/cli/commands/import-external.d.ts.map +1 -0
- package/dist/src/cli/commands/import-external.js +282 -0
- package/dist/src/cli/commands/import-external.js.map +1 -0
- package/dist/src/cli/commands/init.d.ts.map +1 -1
- package/dist/src/cli/commands/init.js +359 -1
- package/dist/src/cli/commands/init.js.map +1 -1
- package/dist/src/cli/helpers/github-repo-selector.d.ts +59 -0
- package/dist/src/cli/helpers/github-repo-selector.d.ts.map +1 -0
- package/dist/src/cli/helpers/github-repo-selector.js +265 -0
- package/dist/src/cli/helpers/github-repo-selector.js.map +1 -0
- package/dist/src/cli/helpers/issue-tracker/index.d.ts.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/index.js +41 -24
- package/dist/src/cli/helpers/issue-tracker/index.js.map +1 -1
- package/dist/src/config/import-config.d.ts +69 -0
- package/dist/src/config/import-config.d.ts.map +1 -0
- package/dist/src/config/import-config.js +136 -0
- package/dist/src/config/import-config.js.map +1 -0
- package/dist/src/config/types.d.ts +26 -26
- package/dist/src/core/increment/ac-status-manager.d.ts.map +1 -1
- package/dist/src/core/increment/ac-status-manager.js +4 -2
- package/dist/src/core/increment/ac-status-manager.js.map +1 -1
- package/dist/src/core/increment/completion-validator.d.ts +30 -1
- package/dist/src/core/increment/completion-validator.d.ts.map +1 -1
- package/dist/src/core/increment/completion-validator.js +151 -3
- package/dist/src/core/increment/completion-validator.js.map +1 -1
- package/dist/src/core/increment/increment-archiver.d.ts +25 -0
- package/dist/src/core/increment/increment-archiver.d.ts.map +1 -1
- package/dist/src/core/increment/increment-archiver.js +130 -3
- package/dist/src/core/increment/increment-archiver.js.map +1 -1
- package/dist/src/core/living-docs/feature-archiver.d.ts +37 -0
- package/dist/src/core/living-docs/feature-archiver.d.ts.map +1 -1
- package/dist/src/core/living-docs/feature-archiver.js +262 -18
- package/dist/src/core/living-docs/feature-archiver.js.map +1 -1
- package/dist/src/core/living-docs/feature-id-manager.d.ts +17 -0
- package/dist/src/core/living-docs/feature-id-manager.d.ts.map +1 -1
- package/dist/src/core/living-docs/feature-id-manager.js +25 -0
- package/dist/src/core/living-docs/feature-id-manager.js.map +1 -1
- package/dist/src/core/living-docs/living-docs-sync.d.ts +16 -0
- package/dist/src/core/living-docs/living-docs-sync.d.ts.map +1 -1
- package/dist/src/core/living-docs/living-docs-sync.js +56 -1
- package/dist/src/core/living-docs/living-docs-sync.js.map +1 -1
- package/dist/src/core/living-docs/task-project-specific-generator.d.ts +2 -2
- package/dist/src/core/living-docs/task-project-specific-generator.js +2 -2
- package/dist/src/core/repo-structure/prompt-consolidator.d.ts +2 -2
- package/dist/src/core/repo-structure/prompt-consolidator.d.ts.map +1 -1
- package/dist/src/core/repo-structure/prompt-consolidator.js +3 -15
- package/dist/src/core/repo-structure/prompt-consolidator.js.map +1 -1
- package/dist/src/core/repo-structure/repo-structure-manager.d.ts +1 -1
- package/dist/src/core/repo-structure/repo-structure-manager.d.ts.map +1 -1
- package/dist/src/core/repo-structure/repo-structure-manager.js +3 -6
- package/dist/src/core/repo-structure/repo-structure-manager.js.map +1 -1
- package/dist/src/core/spec-content-sync.d.ts +4 -1
- package/dist/src/core/spec-content-sync.d.ts.map +1 -1
- package/dist/src/core/spec-content-sync.js +139 -4
- package/dist/src/core/spec-content-sync.js.map +1 -1
- package/dist/src/core/spec-task-mapper.d.ts.map +1 -1
- package/dist/src/core/spec-task-mapper.js +9 -8
- package/dist/src/core/spec-task-mapper.js.map +1 -1
- package/dist/src/core/status-line-validator.d.ts +63 -0
- package/dist/src/core/status-line-validator.d.ts.map +1 -0
- package/dist/src/core/status-line-validator.js +253 -0
- package/dist/src/core/status-line-validator.js.map +1 -0
- package/dist/src/core/sync/bidirectional-engine.d.ts +10 -1
- package/dist/src/core/sync/bidirectional-engine.d.ts.map +1 -1
- package/dist/src/core/sync/bidirectional-engine.js +10 -1
- package/dist/src/core/sync/bidirectional-engine.js.map +1 -1
- package/dist/src/core/sync/profile-manager.d.ts.map +1 -1
- package/dist/src/core/sync/profile-manager.js +3 -0
- package/dist/src/core/sync/profile-manager.js.map +1 -1
- package/dist/src/core/sync/project-context.d.ts.map +1 -1
- package/dist/src/core/sync/project-context.js +3 -0
- package/dist/src/core/sync/project-context.js.map +1 -1
- package/dist/src/core/sync/status-sync-engine.d.ts +1 -1
- package/dist/src/core/sync/status-sync-engine.js +1 -1
- package/dist/src/core/sync/sync-event-logger.d.ts +15 -1
- package/dist/src/core/sync/sync-event-logger.d.ts.map +1 -1
- package/dist/src/core/sync/sync-event-logger.js +39 -1
- package/dist/src/core/sync/sync-event-logger.js.map +1 -1
- package/dist/src/core/types/origin-metadata.d.ts +153 -0
- package/dist/src/core/types/origin-metadata.d.ts.map +1 -0
- package/dist/src/core/types/origin-metadata.js +166 -0
- package/dist/src/core/types/origin-metadata.js.map +1 -0
- package/dist/src/core/types/sync-config-validator.d.ts +57 -0
- package/dist/src/core/types/sync-config-validator.d.ts.map +1 -0
- package/dist/src/core/types/sync-config-validator.js +116 -0
- package/dist/src/core/types/sync-config-validator.js.map +1 -0
- package/dist/src/core/types/sync-profile.d.ts +8 -2
- package/dist/src/core/types/sync-profile.d.ts.map +1 -1
- package/dist/src/core/types/sync-profile.js.map +1 -1
- package/dist/src/core/types/sync-settings.d.ts +73 -0
- package/dist/src/core/types/sync-settings.d.ts.map +1 -0
- package/dist/src/core/types/sync-settings.js +90 -0
- package/dist/src/core/types/sync-settings.js.map +1 -0
- package/dist/src/core/utils/permission-checker.d.ts +100 -0
- package/dist/src/core/utils/permission-checker.d.ts.map +1 -0
- package/dist/src/core/utils/permission-checker.js +166 -0
- package/dist/src/core/utils/permission-checker.js.map +1 -0
- package/dist/src/generators/spec/spec-parser.js +3 -3
- package/dist/src/generators/spec/spec-parser.js.map +1 -1
- package/dist/src/generators/spec/task-parser.js +4 -4
- package/dist/src/generators/spec/task-parser.js.map +1 -1
- package/dist/src/id-generators/task-id-generator.d.ts +96 -0
- package/dist/src/id-generators/task-id-generator.d.ts.map +1 -0
- package/dist/src/id-generators/task-id-generator.js +143 -0
- package/dist/src/id-generators/task-id-generator.js.map +1 -0
- package/dist/src/id-generators/us-id-generator.d.ts +96 -0
- package/dist/src/id-generators/us-id-generator.d.ts.map +1 -0
- package/dist/src/id-generators/us-id-generator.js +143 -0
- package/dist/src/id-generators/us-id-generator.js.map +1 -0
- package/dist/src/importers/ado-importer.d.ts +43 -0
- package/dist/src/importers/ado-importer.d.ts.map +1 -0
- package/dist/src/importers/ado-importer.js +234 -0
- package/dist/src/importers/ado-importer.js.map +1 -0
- package/dist/src/importers/duplicate-detector.d.ts +107 -0
- package/dist/src/importers/duplicate-detector.d.ts.map +1 -0
- package/dist/src/importers/duplicate-detector.js +189 -0
- package/dist/src/importers/duplicate-detector.js.map +1 -0
- package/dist/src/importers/external-importer.d.ts +96 -0
- package/dist/src/importers/external-importer.d.ts.map +1 -0
- package/dist/src/importers/external-importer.js +13 -0
- package/dist/src/importers/external-importer.js.map +1 -0
- package/dist/src/importers/github-importer.d.ts +37 -0
- package/dist/src/importers/github-importer.d.ts.map +1 -0
- package/dist/src/importers/github-importer.js +161 -0
- package/dist/src/importers/github-importer.js.map +1 -0
- package/dist/src/importers/import-coordinator.d.ts +105 -0
- package/dist/src/importers/import-coordinator.d.ts.map +1 -0
- package/dist/src/importers/import-coordinator.js +224 -0
- package/dist/src/importers/import-coordinator.js.map +1 -0
- package/dist/src/importers/item-converter.d.ts +96 -0
- package/dist/src/importers/item-converter.d.ts.map +1 -0
- package/dist/src/importers/item-converter.js +246 -0
- package/dist/src/importers/item-converter.js.map +1 -0
- package/dist/src/importers/jira-importer.d.ts +42 -0
- package/dist/src/importers/jira-importer.d.ts.map +1 -0
- package/dist/src/importers/jira-importer.js +221 -0
- package/dist/src/importers/jira-importer.js.map +1 -0
- package/dist/src/importers/rate-limiter.d.ts +128 -0
- package/dist/src/importers/rate-limiter.d.ts.map +1 -0
- package/dist/src/importers/rate-limiter.js +200 -0
- package/dist/src/importers/rate-limiter.js.map +1 -0
- package/dist/src/init/compliance/types.d.ts +2 -2
- package/dist/src/init/repo/types.d.ts +2 -2
- package/dist/src/integrations/ado/ado-client.d.ts +6 -0
- package/dist/src/integrations/ado/ado-client.d.ts.map +1 -1
- package/dist/src/integrations/ado/ado-client.js +23 -0
- package/dist/src/integrations/ado/ado-client.js.map +1 -1
- package/dist/src/integrations/jira/jira-client.d.ts +6 -0
- package/dist/src/integrations/jira/jira-client.d.ts.map +1 -1
- package/dist/src/integrations/jira/jira-client.js +38 -0
- package/dist/src/integrations/jira/jira-client.js.map +1 -1
- package/dist/src/integrations/jira/jira-mapper.d.ts +1 -1
- package/dist/src/integrations/jira/jira-mapper.js +1 -1
- package/dist/src/living-docs/fs-id-allocator.d.ts +149 -0
- package/dist/src/living-docs/fs-id-allocator.d.ts.map +1 -0
- package/dist/src/living-docs/fs-id-allocator.js +325 -0
- package/dist/src/living-docs/fs-id-allocator.js.map +1 -0
- package/dist/src/living-docs/id-registry.d.ts +124 -0
- package/dist/src/living-docs/id-registry.d.ts.map +1 -0
- package/dist/src/living-docs/id-registry.js +230 -0
- package/dist/src/living-docs/id-registry.js.map +1 -0
- package/dist/src/progress/us-progress-tracker.d.ts +68 -0
- package/dist/src/progress/us-progress-tracker.d.ts.map +1 -0
- package/dist/src/progress/us-progress-tracker.js +120 -0
- package/dist/src/progress/us-progress-tracker.js.map +1 -0
- package/dist/src/sync/external-item-sync-service.d.ts +150 -0
- package/dist/src/sync/external-item-sync-service.d.ts.map +1 -0
- package/dist/src/sync/external-item-sync-service.js +241 -0
- package/dist/src/sync/external-item-sync-service.js.map +1 -0
- package/dist/src/sync/format-preservation-sync.d.ts +90 -0
- package/dist/src/sync/format-preservation-sync.d.ts.map +1 -0
- package/dist/src/sync/format-preservation-sync.js +173 -0
- package/dist/src/sync/format-preservation-sync.js.map +1 -0
- package/dist/src/sync/index.d.ts +8 -0
- package/dist/src/sync/index.d.ts.map +1 -0
- package/dist/src/sync/index.js +6 -0
- package/dist/src/sync/index.js.map +1 -0
- package/dist/src/sync/sync-coordinator.d.ts +49 -0
- package/dist/src/sync/sync-coordinator.d.ts.map +1 -0
- package/dist/src/sync/sync-coordinator.js +248 -0
- package/dist/src/sync/sync-coordinator.js.map +1 -0
- package/dist/src/sync/sync-metadata.d.ts +75 -0
- package/dist/src/sync/sync-metadata.d.ts.map +1 -0
- package/dist/src/sync/sync-metadata.js +100 -0
- package/dist/src/sync/sync-metadata.js.map +1 -0
- package/dist/src/types/living-docs-us-file.d.ts +63 -0
- package/dist/src/types/living-docs-us-file.d.ts.map +1 -0
- package/dist/src/types/living-docs-us-file.js +27 -0
- package/dist/src/types/living-docs-us-file.js.map +1 -0
- package/dist/src/validators/format-preservation-validator.d.ts +127 -0
- package/dist/src/validators/format-preservation-validator.d.ts.map +1 -0
- package/dist/src/validators/format-preservation-validator.js +187 -0
- package/dist/src/validators/format-preservation-validator.js.map +1 -0
- package/package.json +3 -2
- package/plugins/specweave/.claude-plugin/plugin.json +36 -2
- package/plugins/specweave/agents/architect/AGENT.md +11 -2
- package/plugins/specweave/agents/test-aware-planner/AGENT.md +81 -25
- package/plugins/specweave/commands/specweave-archive-features.md +11 -1
- package/plugins/specweave/commands/specweave-import-external.md +407 -0
- package/plugins/specweave/commands/specweave-progress.md +45 -97
- package/plugins/specweave/hooks/post-edit-spec.sh +41 -0
- package/plugins/specweave/hooks/post-increment-completion.sh +168 -26
- package/plugins/specweave/hooks/post-increment-planning.sh +148 -4
- package/plugins/specweave/hooks/post-spec-update.sh +0 -0
- package/plugins/specweave/hooks/post-task-completion.sh +75 -5
- package/plugins/specweave/hooks/post-write-spec.sh +37 -0
- package/plugins/specweave/lib/hooks/auto-transition.js +1 -1
- package/plugins/specweave/lib/hooks/auto-transition.ts +1 -1
- package/plugins/specweave/lib/hooks/invoke-translator-skill.js +1 -1
- package/plugins/specweave/lib/hooks/invoke-translator-skill.ts +1 -1
- package/plugins/specweave/lib/hooks/sync-cache.js +294 -0
- package/plugins/specweave/lib/hooks/sync-living-docs.js +67 -2
- package/plugins/specweave/lib/hooks/sync-us-tasks.js +200 -14
- package/plugins/specweave/lib/hooks/translate-file.js +1 -1
- package/plugins/specweave/lib/hooks/translate-file.ts +1 -1
- package/plugins/specweave/lib/hooks/update-ac-status.js +1 -1
- package/plugins/specweave/lib/hooks/update-ac-status.ts +1 -1
- package/plugins/specweave/lib/vendor/core/increment/ac-status-manager.d.ts +115 -0
- package/plugins/specweave/lib/vendor/core/increment/ac-status-manager.js +345 -0
- package/plugins/specweave/lib/vendor/core/increment/ac-status-manager.js.map +1 -0
- package/plugins/specweave/lib/vendor/core/increment/active-increment-manager.d.ts +106 -0
- package/plugins/specweave/lib/vendor/core/increment/active-increment-manager.js +220 -0
- package/plugins/specweave/lib/vendor/core/increment/active-increment-manager.js.map +1 -0
- package/plugins/specweave/lib/vendor/core/increment/auto-transition-manager.d.ts +60 -0
- package/plugins/specweave/lib/vendor/core/increment/auto-transition-manager.js +192 -0
- package/plugins/specweave/lib/vendor/core/increment/auto-transition-manager.js.map +1 -0
- package/plugins/specweave/lib/vendor/core/increment/duplicate-detector.d.ts +52 -0
- package/plugins/specweave/lib/vendor/core/increment/duplicate-detector.js +276 -0
- package/plugins/specweave/lib/vendor/core/increment/duplicate-detector.js.map +1 -0
- package/plugins/specweave/lib/vendor/core/increment/metadata-manager.d.ts +163 -0
- package/plugins/specweave/lib/vendor/core/increment/metadata-manager.js +541 -0
- package/plugins/specweave/lib/vendor/core/increment/metadata-manager.js.map +1 -0
- package/plugins/specweave/lib/vendor/core/types/increment-metadata.d.ts +157 -0
- package/plugins/specweave/lib/vendor/core/types/increment-metadata.js +191 -0
- package/plugins/specweave/lib/vendor/core/types/increment-metadata.js.map +1 -0
- package/plugins/specweave/lib/vendor/generators/spec/task-parser.d.ts +95 -0
- package/plugins/specweave/lib/vendor/generators/spec/task-parser.js +301 -0
- package/plugins/specweave/lib/vendor/generators/spec/task-parser.js.map +1 -0
- package/plugins/specweave/lib/vendor/utils/logger.d.ts +48 -0
- package/plugins/specweave/lib/vendor/utils/logger.js +53 -0
- package/plugins/specweave/lib/vendor/utils/logger.js.map +1 -0
- package/plugins/specweave/lib/vendor/utils/translation.d.ts +187 -0
- package/plugins/specweave/lib/vendor/utils/translation.js +414 -0
- package/plugins/specweave/lib/vendor/utils/translation.js.map +1 -0
- package/plugins/specweave-ado/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-ado/lib/ado-multi-project-sync.js +0 -1
- package/plugins/specweave-ado/lib/conflict-resolver.ts +1 -1
- package/plugins/specweave-alternatives/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-backend/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-confluent/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-cost-optimizer/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-diagrams/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-docs/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-docs-preview/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-figma/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-frontend/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-github/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-github/commands/specweave-github-update-user-story.md +1 -1
- package/plugins/specweave-github/hooks/post-task-completion.sh +37 -22
- package/plugins/specweave-github/lib/ThreeLayerSyncManager.ts +1 -1
- package/plugins/specweave-github/lib/enhanced-github-sync.js +1 -1
- package/plugins/specweave-github/lib/enhanced-github-sync.ts +1 -1
- package/plugins/specweave-github/lib/github-spec-content-sync.js +2 -1
- package/plugins/specweave-github/lib/github-spec-content-sync.ts +4 -1
- package/plugins/specweave-github/lib/github-spec-sync.js +1 -1
- package/plugins/specweave-github/lib/github-spec-sync.ts +1 -1
- package/plugins/specweave-github/lib/github-sync-bidirectional.js +1 -1
- package/plugins/specweave-github/lib/github-sync-bidirectional.ts +10 -1
- package/plugins/specweave-github/lib/progress-comment-builder.js +1 -1
- package/plugins/specweave-github/lib/progress-comment-builder.ts +2 -2
- package/plugins/specweave-github/lib/types.ts +1 -1
- package/plugins/specweave-github/skills/github-issue-standard/SKILL.md +1 -1
- package/plugins/specweave-infrastructure/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-jira/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-jira/lib/enhanced-jira-sync.js +3 -3
- package/plugins/specweave-kafka/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-kafka-streams/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-kubernetes/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-ml/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-mobile/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-n8n/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-payments/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-release/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-testing/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-tooling/.claude-plugin/plugin.json +1 -1
- package/plugins/specweave-ui/.claude-plugin/plugin.json +1 -1
- package/src/templates/.env.example +5 -0
- package/src/templates/config-permissions-guide.md +413 -0
- package/src/templates/config.json.template +68 -0
- package/src/templates/tasks.md.template +180 -201
- package/plugins/specweave-ado/lib/enhanced-ado-sync.js +0 -170
- package/plugins/specweave-release/hooks/.specweave/logs/dora-tracking.log +0 -5442
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ID Registry - Atomic Feature ID registration with collision detection
|
|
3
|
+
*
|
|
4
|
+
* Provides thread-safe ID registration using file-based locking to prevent
|
|
5
|
+
* race conditions during concurrent imports.
|
|
6
|
+
*
|
|
7
|
+
* Features:
|
|
8
|
+
* - File-based locking for atomic updates
|
|
9
|
+
* - Collision detection (checks both FS-XXX and FS-XXXE)
|
|
10
|
+
* - JSON-based persistent storage
|
|
11
|
+
* - Automatic lock cleanup with timeout
|
|
12
|
+
*/
|
|
13
|
+
import fs from 'fs-extra';
|
|
14
|
+
import path from 'path';
|
|
15
|
+
/**
|
|
16
|
+
* ID Registry with atomic file-based locking
|
|
17
|
+
*/
|
|
18
|
+
export class IDRegistry {
|
|
19
|
+
constructor(projectRoot) {
|
|
20
|
+
this.lockTimeout = 30000; // 30 seconds
|
|
21
|
+
this.retryDelay = 100; // 100ms
|
|
22
|
+
this.registryPath = path.join(projectRoot, '.specweave/.id-registry.json');
|
|
23
|
+
this.lockPath = path.join(projectRoot, '.specweave/.id-registry.lock');
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Register a new Feature ID atomically
|
|
27
|
+
*
|
|
28
|
+
* @param fsId - Feature ID to register (e.g., "FS-042E")
|
|
29
|
+
* @param entry - Registry entry metadata
|
|
30
|
+
* @throws Error if collision detected or lock acquisition fails
|
|
31
|
+
*/
|
|
32
|
+
async registerID(fsId, entry) {
|
|
33
|
+
// Acquire lock with timeout
|
|
34
|
+
await this.acquireLock();
|
|
35
|
+
try {
|
|
36
|
+
// Read current registry
|
|
37
|
+
const registry = await this.readRegistry();
|
|
38
|
+
// Check for collision (exact match or variant)
|
|
39
|
+
const collision = this.detectCollision(fsId, registry);
|
|
40
|
+
if (collision) {
|
|
41
|
+
throw new Error(`ID collision: ${fsId} conflicts with ${collision}`);
|
|
42
|
+
}
|
|
43
|
+
// Add new entry
|
|
44
|
+
registry.entries[fsId] = {
|
|
45
|
+
id: fsId,
|
|
46
|
+
...entry
|
|
47
|
+
};
|
|
48
|
+
registry.lastUpdated = new Date().toISOString();
|
|
49
|
+
registry.version++;
|
|
50
|
+
// Write atomically
|
|
51
|
+
await this.writeRegistry(registry);
|
|
52
|
+
}
|
|
53
|
+
finally {
|
|
54
|
+
// Always release lock
|
|
55
|
+
await this.releaseLock();
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Check if ID exists in registry
|
|
60
|
+
*
|
|
61
|
+
* @param fsId - Feature ID to check
|
|
62
|
+
* @returns True if ID is registered
|
|
63
|
+
*/
|
|
64
|
+
async hasID(fsId) {
|
|
65
|
+
const registry = await this.readRegistry();
|
|
66
|
+
return fsId in registry.entries;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Get registry entry
|
|
70
|
+
*
|
|
71
|
+
* @param fsId - Feature ID to retrieve
|
|
72
|
+
* @returns Registry entry or null if not found
|
|
73
|
+
*/
|
|
74
|
+
async getEntry(fsId) {
|
|
75
|
+
const registry = await this.readRegistry();
|
|
76
|
+
return registry.entries[fsId] || null;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Get all registered IDs
|
|
80
|
+
*
|
|
81
|
+
* @returns Array of all registered Feature IDs
|
|
82
|
+
*/
|
|
83
|
+
async getAllIDs() {
|
|
84
|
+
const registry = await this.readRegistry();
|
|
85
|
+
return Object.keys(registry.entries);
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Acquire lock file with timeout and retry
|
|
89
|
+
*
|
|
90
|
+
* @throws Error if lock cannot be acquired within timeout
|
|
91
|
+
*/
|
|
92
|
+
async acquireLock() {
|
|
93
|
+
const startTime = Date.now();
|
|
94
|
+
// Ensure lock directory exists
|
|
95
|
+
await fs.ensureDir(path.dirname(this.lockPath));
|
|
96
|
+
while (true) {
|
|
97
|
+
try {
|
|
98
|
+
// Try to create lock file exclusively
|
|
99
|
+
await fs.writeFile(this.lockPath, Date.now().toString(), { flag: 'wx' });
|
|
100
|
+
return; // Lock acquired
|
|
101
|
+
}
|
|
102
|
+
catch (error) {
|
|
103
|
+
if (error.code !== 'EEXIST') {
|
|
104
|
+
throw error; // Unexpected error
|
|
105
|
+
}
|
|
106
|
+
// Lock exists, check timeout
|
|
107
|
+
const elapsed = Date.now() - startTime;
|
|
108
|
+
if (elapsed > this.lockTimeout) {
|
|
109
|
+
// Check if lock is stale
|
|
110
|
+
const lockAge = await this.getLockAge();
|
|
111
|
+
if (lockAge > this.lockTimeout) {
|
|
112
|
+
// Stale lock, force remove
|
|
113
|
+
await fs.remove(this.lockPath);
|
|
114
|
+
continue; // Retry
|
|
115
|
+
}
|
|
116
|
+
throw new Error(`Lock acquisition timeout after ${elapsed}ms`);
|
|
117
|
+
}
|
|
118
|
+
// Wait and retry
|
|
119
|
+
await this.sleep(this.retryDelay);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Release lock file
|
|
125
|
+
*/
|
|
126
|
+
async releaseLock() {
|
|
127
|
+
try {
|
|
128
|
+
await fs.remove(this.lockPath);
|
|
129
|
+
}
|
|
130
|
+
catch (error) {
|
|
131
|
+
// Ignore if lock doesn't exist (already released)
|
|
132
|
+
if (error.code !== 'ENOENT') {
|
|
133
|
+
throw error;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Get lock file age in milliseconds
|
|
139
|
+
*
|
|
140
|
+
* @returns Lock age or Infinity if lock doesn't exist
|
|
141
|
+
*/
|
|
142
|
+
async getLockAge() {
|
|
143
|
+
try {
|
|
144
|
+
const lockContent = await fs.readFile(this.lockPath, 'utf-8');
|
|
145
|
+
const lockTime = parseInt(lockContent, 10);
|
|
146
|
+
return Date.now() - lockTime;
|
|
147
|
+
}
|
|
148
|
+
catch (error) {
|
|
149
|
+
return Infinity; // Lock doesn't exist
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Read registry from disk
|
|
154
|
+
*
|
|
155
|
+
* @returns Registry data
|
|
156
|
+
*/
|
|
157
|
+
async readRegistry() {
|
|
158
|
+
try {
|
|
159
|
+
const content = await fs.readFile(this.registryPath, 'utf-8');
|
|
160
|
+
return JSON.parse(content);
|
|
161
|
+
}
|
|
162
|
+
catch (error) {
|
|
163
|
+
if (error.code === 'ENOENT') {
|
|
164
|
+
// Registry doesn't exist, return empty
|
|
165
|
+
return {
|
|
166
|
+
entries: {},
|
|
167
|
+
lastUpdated: new Date().toISOString(),
|
|
168
|
+
version: 1
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
throw error;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Write registry to disk atomically
|
|
176
|
+
*
|
|
177
|
+
* @param registry - Registry data to write
|
|
178
|
+
*/
|
|
179
|
+
async writeRegistry(registry) {
|
|
180
|
+
await fs.ensureDir(path.dirname(this.registryPath));
|
|
181
|
+
// Write to temp file first
|
|
182
|
+
const tempPath = `${this.registryPath}.tmp`;
|
|
183
|
+
await fs.writeFile(tempPath, JSON.stringify(registry, null, 2));
|
|
184
|
+
// Atomic rename
|
|
185
|
+
await fs.rename(tempPath, this.registryPath);
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Detect ID collision (exact match or variant)
|
|
189
|
+
*
|
|
190
|
+
* @param fsId - ID to check (e.g., "FS-042E")
|
|
191
|
+
* @param registry - Current registry
|
|
192
|
+
* @returns Conflicting ID or null if no collision
|
|
193
|
+
*
|
|
194
|
+
* @example
|
|
195
|
+
* // Given registry: {FS-042: {...}}
|
|
196
|
+
* detectCollision('FS-042E', registry) // Returns: 'FS-042'
|
|
197
|
+
* detectCollision('FS-043', registry) // Returns: null
|
|
198
|
+
*/
|
|
199
|
+
detectCollision(fsId, registry) {
|
|
200
|
+
// Exact match
|
|
201
|
+
if (fsId in registry.entries) {
|
|
202
|
+
return fsId;
|
|
203
|
+
}
|
|
204
|
+
// Extract numeric part
|
|
205
|
+
const match = fsId.match(/^FS-(\d{3,})E?$/);
|
|
206
|
+
if (!match) {
|
|
207
|
+
throw new Error(`Invalid FS-ID format: ${fsId}`);
|
|
208
|
+
}
|
|
209
|
+
const number = parseInt(match[1], 10);
|
|
210
|
+
const internalId = `FS-${String(number).padStart(3, '0')}`;
|
|
211
|
+
const externalId = `FS-${String(number).padStart(3, '0')}E`;
|
|
212
|
+
// Check variant
|
|
213
|
+
if (internalId !== fsId && internalId in registry.entries) {
|
|
214
|
+
return internalId;
|
|
215
|
+
}
|
|
216
|
+
if (externalId !== fsId && externalId in registry.entries) {
|
|
217
|
+
return externalId;
|
|
218
|
+
}
|
|
219
|
+
return null; // No collision
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Sleep for specified milliseconds
|
|
223
|
+
*
|
|
224
|
+
* @param ms - Milliseconds to sleep
|
|
225
|
+
*/
|
|
226
|
+
sleep(ms) {
|
|
227
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
//# sourceMappingURL=id-registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"id-registry.js","sourceRoot":"","sources":["../../../src/living-docs/id-registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* User Story Progress Tracking
|
|
3
|
+
*
|
|
4
|
+
* Calculates task completion statistics grouped by User Story.
|
|
5
|
+
* Provides per-US and aggregate completion percentages.
|
|
6
|
+
*/
|
|
7
|
+
import { type Task, type TasksByUserStory } from '../generators/spec/task-parser.js';
|
|
8
|
+
/**
|
|
9
|
+
* Progress statistics for a single User Story
|
|
10
|
+
*/
|
|
11
|
+
export interface USProgress {
|
|
12
|
+
usId: string;
|
|
13
|
+
totalTasks: number;
|
|
14
|
+
completedTasks: number;
|
|
15
|
+
inProgressTasks: number;
|
|
16
|
+
pendingTasks: number;
|
|
17
|
+
percentage: number;
|
|
18
|
+
tasks: Task[];
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Aggregate progress across all User Stories
|
|
22
|
+
*/
|
|
23
|
+
export interface AggregateProgress {
|
|
24
|
+
totalTasks: number;
|
|
25
|
+
completedTasks: number;
|
|
26
|
+
inProgressTasks: number;
|
|
27
|
+
pendingTasks: number;
|
|
28
|
+
percentage: number;
|
|
29
|
+
byUserStory: Map<string, USProgress>;
|
|
30
|
+
orphanTasks: Task[];
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Calculate task completion statistics for a single User Story
|
|
34
|
+
*/
|
|
35
|
+
export declare function calculateUSProgress(usId: string, tasks: Task[]): USProgress;
|
|
36
|
+
/**
|
|
37
|
+
* Calculate aggregate progress across all User Stories
|
|
38
|
+
*/
|
|
39
|
+
export declare function calculateAggregateProgress(tasksByUS: TasksByUserStory): AggregateProgress;
|
|
40
|
+
/**
|
|
41
|
+
* Calculate progress from tasks.md file
|
|
42
|
+
*/
|
|
43
|
+
export declare function calculateProgressFromTasksFile(tasksPath: string): Promise<AggregateProgress>;
|
|
44
|
+
/**
|
|
45
|
+
* Format US progress as string
|
|
46
|
+
*/
|
|
47
|
+
export declare function formatUSProgress(progress: USProgress, includePercentage?: boolean): string;
|
|
48
|
+
/**
|
|
49
|
+
* Format aggregate progress as string
|
|
50
|
+
*/
|
|
51
|
+
export declare function formatAggregateProgress(progress: AggregateProgress): string;
|
|
52
|
+
/**
|
|
53
|
+
* Get progress bar visualization
|
|
54
|
+
*/
|
|
55
|
+
export declare function getProgressBar(percentage: number, width?: number): string;
|
|
56
|
+
/**
|
|
57
|
+
* Get color indicator based on percentage
|
|
58
|
+
*/
|
|
59
|
+
export declare function getProgressColor(percentage: number): 'green' | 'yellow' | 'red';
|
|
60
|
+
/**
|
|
61
|
+
* Sort User Stories by completion percentage (descending)
|
|
62
|
+
*/
|
|
63
|
+
export declare function sortUSByCompletion(progressMap: Map<string, USProgress>): USProgress[];
|
|
64
|
+
/**
|
|
65
|
+
* Sort User Stories by US-ID (ascending)
|
|
66
|
+
*/
|
|
67
|
+
export declare function sortUSByID(progressMap: Map<string, USProgress>): USProgress[];
|
|
68
|
+
//# sourceMappingURL=us-progress-tracker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"us-progress-tracker.d.ts","sourceRoot":"","sources":["../../../src/progress/us-progress-tracker.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAsC,KAAK,IAAI,EAAE,KAAK,gBAAgB,EAAmB,MAAM,mCAAmC,CAAC;AAE1I;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,IAAI,EAAE,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACrC,WAAW,EAAE,IAAI,EAAE,CAAC;CACrB;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,UAAU,CAmB3E;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CAAC,SAAS,EAAE,gBAAgB,GAAG,iBAAiB,CA0CzF;AAED;;GAEG;AACH,wBAAsB,8BAA8B,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAGlG;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,UAAU,EAAE,iBAAiB,GAAE,OAAc,GAAG,MAAM,CAGhG;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,iBAAiB,GAAG,MAAM,CAE3E;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,GAAE,MAAW,GAAG,MAAM,CAI7E;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,KAAK,CAI/E;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,GAAG,UAAU,EAAE,CAErF;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,GAAG,UAAU,EAAE,CAM7E"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* User Story Progress Tracking
|
|
3
|
+
*
|
|
4
|
+
* Calculates task completion statistics grouped by User Story.
|
|
5
|
+
* Provides per-US and aggregate completion percentages.
|
|
6
|
+
*/
|
|
7
|
+
import { parseTasksWithUSLinks } from '../generators/spec/task-parser.js';
|
|
8
|
+
/**
|
|
9
|
+
* Calculate task completion statistics for a single User Story
|
|
10
|
+
*/
|
|
11
|
+
export function calculateUSProgress(usId, tasks) {
|
|
12
|
+
const totalTasks = tasks.length;
|
|
13
|
+
const completedTasks = tasks.filter((t) => t.status === 'completed').length;
|
|
14
|
+
const inProgressTasks = tasks.filter((t) => t.status === 'in_progress').length;
|
|
15
|
+
const pendingTasks = tasks.filter((t) => t.status === 'pending' || t.status === 'transferred' || t.status === 'canceled').length;
|
|
16
|
+
const percentage = totalTasks > 0 ? Math.round((completedTasks / totalTasks) * 100) : 0;
|
|
17
|
+
return {
|
|
18
|
+
usId,
|
|
19
|
+
totalTasks,
|
|
20
|
+
completedTasks,
|
|
21
|
+
inProgressTasks,
|
|
22
|
+
pendingTasks,
|
|
23
|
+
percentage,
|
|
24
|
+
tasks,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Calculate aggregate progress across all User Stories
|
|
29
|
+
*/
|
|
30
|
+
export function calculateAggregateProgress(tasksByUS) {
|
|
31
|
+
const byUserStory = new Map();
|
|
32
|
+
let totalTasks = 0;
|
|
33
|
+
let completedTasks = 0;
|
|
34
|
+
let inProgressTasks = 0;
|
|
35
|
+
let pendingTasks = 0;
|
|
36
|
+
// Calculate per-US progress
|
|
37
|
+
for (const [usId, tasks] of Object.entries(tasksByUS)) {
|
|
38
|
+
if (usId === 'orphan' || usId === 'unknown')
|
|
39
|
+
continue; // Skip special keys
|
|
40
|
+
const usProgress = calculateUSProgress(usId, tasks);
|
|
41
|
+
byUserStory.set(usId, usProgress);
|
|
42
|
+
totalTasks += usProgress.totalTasks;
|
|
43
|
+
completedTasks += usProgress.completedTasks;
|
|
44
|
+
inProgressTasks += usProgress.inProgressTasks;
|
|
45
|
+
pendingTasks += usProgress.pendingTasks;
|
|
46
|
+
}
|
|
47
|
+
// Identify orphan tasks (tasks without userStory field)
|
|
48
|
+
const orphanTasks = tasksByUS['orphan'] || tasksByUS['unknown'] || [];
|
|
49
|
+
if (orphanTasks.length > 0) {
|
|
50
|
+
totalTasks += orphanTasks.length;
|
|
51
|
+
completedTasks += orphanTasks.filter((t) => t.status === 'completed').length;
|
|
52
|
+
inProgressTasks += orphanTasks.filter((t) => t.status === 'in_progress').length;
|
|
53
|
+
pendingTasks += orphanTasks.filter((t) => t.status === 'pending' || t.status === 'transferred' || t.status === 'canceled').length;
|
|
54
|
+
}
|
|
55
|
+
const percentage = totalTasks > 0 ? Math.round((completedTasks / totalTasks) * 100) : 0;
|
|
56
|
+
return {
|
|
57
|
+
totalTasks,
|
|
58
|
+
completedTasks,
|
|
59
|
+
inProgressTasks,
|
|
60
|
+
pendingTasks,
|
|
61
|
+
percentage,
|
|
62
|
+
byUserStory,
|
|
63
|
+
orphanTasks,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Calculate progress from tasks.md file
|
|
68
|
+
*/
|
|
69
|
+
export async function calculateProgressFromTasksFile(tasksPath) {
|
|
70
|
+
const tasksByUS = await parseTasksWithUSLinks(tasksPath);
|
|
71
|
+
return calculateAggregateProgress(tasksByUS);
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Format US progress as string
|
|
75
|
+
*/
|
|
76
|
+
export function formatUSProgress(progress, includePercentage = true) {
|
|
77
|
+
const percentStr = includePercentage ? ` (${progress.percentage}%)` : '';
|
|
78
|
+
return `${progress.usId}: ${progress.completedTasks}/${progress.totalTasks} tasks${percentStr}`;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Format aggregate progress as string
|
|
82
|
+
*/
|
|
83
|
+
export function formatAggregateProgress(progress) {
|
|
84
|
+
return `Overall: ${progress.completedTasks}/${progress.totalTasks} tasks (${progress.percentage}%)`;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Get progress bar visualization
|
|
88
|
+
*/
|
|
89
|
+
export function getProgressBar(percentage, width = 20) {
|
|
90
|
+
const filledChars = Math.round((percentage / 100) * width);
|
|
91
|
+
const emptyChars = width - filledChars;
|
|
92
|
+
return '█'.repeat(filledChars) + '░'.repeat(emptyChars);
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Get color indicator based on percentage
|
|
96
|
+
*/
|
|
97
|
+
export function getProgressColor(percentage) {
|
|
98
|
+
if (percentage >= 80)
|
|
99
|
+
return 'green';
|
|
100
|
+
if (percentage >= 50)
|
|
101
|
+
return 'yellow';
|
|
102
|
+
return 'red';
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Sort User Stories by completion percentage (descending)
|
|
106
|
+
*/
|
|
107
|
+
export function sortUSByCompletion(progressMap) {
|
|
108
|
+
return Array.from(progressMap.values()).sort((a, b) => b.percentage - a.percentage);
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Sort User Stories by US-ID (ascending)
|
|
112
|
+
*/
|
|
113
|
+
export function sortUSByID(progressMap) {
|
|
114
|
+
return Array.from(progressMap.values()).sort((a, b) => {
|
|
115
|
+
const aNum = parseInt(a.usId.replace('US-', ''));
|
|
116
|
+
const bNum = parseInt(b.usId.replace('US-', ''));
|
|
117
|
+
return aNum - bNum;
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=us-progress-tracker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"us-progress-tracker.js","sourceRoot":"","sources":["../../../src/progress/us-progress-tracker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External Item Sync Service
|
|
3
|
+
*
|
|
4
|
+
* Handles synchronization with external tools (GitHub, JIRA, ADO) while
|
|
5
|
+
* preserving original item format and preventing unintended modifications.
|
|
6
|
+
*
|
|
7
|
+
* Key Features:
|
|
8
|
+
* - Comment-based updates for external items (format preservation)
|
|
9
|
+
* - Full sync for internal items (title, description, ACs)
|
|
10
|
+
* - Format preservation validation
|
|
11
|
+
* - External title immutability
|
|
12
|
+
*
|
|
13
|
+
* Part of increment 0047-us-task-linkage (T-034B)
|
|
14
|
+
*/
|
|
15
|
+
import type { Logger } from '../utils/logger.js';
|
|
16
|
+
/**
|
|
17
|
+
* Task completion data for sync
|
|
18
|
+
*/
|
|
19
|
+
export interface TaskCompletionData {
|
|
20
|
+
/** Task ID (e.g., "T-034") */
|
|
21
|
+
taskId: string;
|
|
22
|
+
/** Feature ID (e.g., "FS-047") */
|
|
23
|
+
featureId: string;
|
|
24
|
+
/** User Story ID (e.g., "US-009") */
|
|
25
|
+
usId: string;
|
|
26
|
+
/** Acceptance criteria satisfied by this task */
|
|
27
|
+
satisfiesACs: string[];
|
|
28
|
+
/** Completed tasks count */
|
|
29
|
+
completedTasks: number;
|
|
30
|
+
/** Total tasks count */
|
|
31
|
+
totalTasks: number;
|
|
32
|
+
/** Completion percentage */
|
|
33
|
+
percentage: number;
|
|
34
|
+
/** Living docs URL */
|
|
35
|
+
livingDocsUrl?: string;
|
|
36
|
+
/** Task title */
|
|
37
|
+
taskTitle: string;
|
|
38
|
+
/** Task status */
|
|
39
|
+
status: 'completed' | 'in_progress' | 'pending';
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Sync options
|
|
43
|
+
*/
|
|
44
|
+
export interface SyncOptions {
|
|
45
|
+
/** Project root directory */
|
|
46
|
+
projectRoot: string;
|
|
47
|
+
/** External tool (github, jira, ado) */
|
|
48
|
+
externalTool?: 'github' | 'jira' | 'ado';
|
|
49
|
+
/** Force full sync (ignore format_preservation flag) */
|
|
50
|
+
forceFullSync?: boolean;
|
|
51
|
+
/** Dry run (don't actually sync, just log what would happen) */
|
|
52
|
+
dryRun?: boolean;
|
|
53
|
+
/** Logger instance */
|
|
54
|
+
logger?: Logger;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Sync result
|
|
58
|
+
*/
|
|
59
|
+
export interface SyncResult {
|
|
60
|
+
/** Success flag */
|
|
61
|
+
success: boolean;
|
|
62
|
+
/** Sync mode used */
|
|
63
|
+
mode: 'comment-only' | 'full-sync' | 'skipped';
|
|
64
|
+
/** Reason for mode selection */
|
|
65
|
+
reason: string;
|
|
66
|
+
/** Comment posted (if comment-only mode) */
|
|
67
|
+
comment?: string;
|
|
68
|
+
/** Fields updated (if full-sync mode) */
|
|
69
|
+
updatedFields?: string[];
|
|
70
|
+
/** Error message (if failed) */
|
|
71
|
+
error?: string;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* External Item Sync Service
|
|
75
|
+
*
|
|
76
|
+
* Routes sync operations based on format_preservation flag.
|
|
77
|
+
* External items (format_preservation=true) → comment-only sync
|
|
78
|
+
* Internal items (format_preservation=false) → full sync
|
|
79
|
+
*/
|
|
80
|
+
export declare class ExternalItemSyncService {
|
|
81
|
+
private logger;
|
|
82
|
+
private validator;
|
|
83
|
+
constructor(options?: {
|
|
84
|
+
logger?: Logger;
|
|
85
|
+
});
|
|
86
|
+
/**
|
|
87
|
+
* Sync task completion to external tool
|
|
88
|
+
*
|
|
89
|
+
* Routes to comment-only or full sync based on format_preservation flag
|
|
90
|
+
*
|
|
91
|
+
* @param completionData - Task completion data
|
|
92
|
+
* @param options - Sync options
|
|
93
|
+
* @returns Sync result
|
|
94
|
+
*/
|
|
95
|
+
syncTaskCompletion(completionData: TaskCompletionData, options: SyncOptions): Promise<SyncResult>;
|
|
96
|
+
/**
|
|
97
|
+
* Get format_preservation flag from living docs User Story file
|
|
98
|
+
*
|
|
99
|
+
* @param usId - User Story ID (e.g., "US-009")
|
|
100
|
+
* @param featureId - Feature ID (e.g., "FS-047")
|
|
101
|
+
* @param projectRoot - Project root directory
|
|
102
|
+
* @returns True if format preservation enabled
|
|
103
|
+
*/
|
|
104
|
+
private getFormatPreservation;
|
|
105
|
+
/**
|
|
106
|
+
* Find User Story file in living docs
|
|
107
|
+
*
|
|
108
|
+
* @param projectRoot - Project root
|
|
109
|
+
* @param featureId - Feature ID (e.g., "FS-047")
|
|
110
|
+
* @param usId - User Story ID (e.g., "US-009")
|
|
111
|
+
* @returns Path to US file or null if not found
|
|
112
|
+
*/
|
|
113
|
+
private findUSFile;
|
|
114
|
+
/**
|
|
115
|
+
* Get all project directories in specs
|
|
116
|
+
*
|
|
117
|
+
* @param specsDir - Specs directory
|
|
118
|
+
* @returns Array of project directory paths
|
|
119
|
+
*/
|
|
120
|
+
private getProjectDirs;
|
|
121
|
+
/**
|
|
122
|
+
* Comment-only sync: Post completion update as comment
|
|
123
|
+
*
|
|
124
|
+
* Does NOT modify external item title, description, or acceptance criteria.
|
|
125
|
+
* Only posts a comment with task completion status.
|
|
126
|
+
*
|
|
127
|
+
* @param completionData - Task completion data
|
|
128
|
+
* @param options - Sync options
|
|
129
|
+
* @returns Sync result
|
|
130
|
+
*/
|
|
131
|
+
private commentOnlySync;
|
|
132
|
+
/**
|
|
133
|
+
* Full sync: Update external item title, description, ACs
|
|
134
|
+
*
|
|
135
|
+
* Used for internal items or when format preservation disabled.
|
|
136
|
+
*
|
|
137
|
+
* @param completionData - Task completion data
|
|
138
|
+
* @param options - Sync options
|
|
139
|
+
* @returns Sync result
|
|
140
|
+
*/
|
|
141
|
+
private fullSync;
|
|
142
|
+
/**
|
|
143
|
+
* Format completion comment for external tool
|
|
144
|
+
*
|
|
145
|
+
* @param data - Task completion data
|
|
146
|
+
* @returns Formatted comment
|
|
147
|
+
*/
|
|
148
|
+
private formatCompletionComment;
|
|
149
|
+
}
|
|
150
|
+
//# sourceMappingURL=external-item-sync-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"external-item-sync-service.d.ts","sourceRoot":"","sources":["../../../src/sync/external-item-sync-service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAKH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAMjD;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,8BAA8B;IAC9B,MAAM,EAAE,MAAM,CAAC;IAEf,kCAAkC;IAClC,SAAS,EAAE,MAAM,CAAC;IAElB,qCAAqC;IACrC,IAAI,EAAE,MAAM,CAAC;IAEb,iDAAiD;IACjD,YAAY,EAAE,MAAM,EAAE,CAAC;IAEvB,4BAA4B;IAC5B,cAAc,EAAE,MAAM,CAAC;IAEvB,wBAAwB;IACxB,UAAU,EAAE,MAAM,CAAC;IAEnB,4BAA4B;IAC5B,UAAU,EAAE,MAAM,CAAC;IAEnB,sBAAsB;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB,iBAAiB;IACjB,SAAS,EAAE,MAAM,CAAC;IAElB,kBAAkB;IAClB,MAAM,EAAE,WAAW,GAAG,aAAa,GAAG,SAAS,CAAC;CACjD;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,6BAA6B;IAC7B,WAAW,EAAE,MAAM,CAAC;IAEpB,wCAAwC;IACxC,YAAY,CAAC,EAAE,QAAQ,GAAG,MAAM,GAAG,KAAK,CAAC;IAEzC,wDAAwD;IACxD,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB,gEAAgE;IAChE,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB,sBAAsB;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,mBAAmB;IACnB,OAAO,EAAE,OAAO,CAAC;IAEjB,qBAAqB;IACrB,IAAI,EAAE,cAAc,GAAG,WAAW,GAAG,SAAS,CAAC;IAE/C,gCAAgC;IAChC,MAAM,EAAE,MAAM,CAAC;IAEf,4CAA4C;IAC5C,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,yCAAyC;IACzC,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IAEzB,gCAAgC;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;GAMG;AACH,qBAAa,uBAAuB;IAClC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,SAAS,CAA8B;gBAEnC,OAAO,GAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAA;KAAO;IAK7C;;;;;;;;OAQG;IACG,kBAAkB,CACtB,cAAc,EAAE,kBAAkB,EAClC,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,UAAU,CAAC;IAoCtB;;;;;;;OAOG;YACW,qBAAqB;IA2BnC;;;;;;;OAOG;YACW,UAAU;IA2BxB;;;;;OAKG;YACW,cAAc;IAa5B;;;;;;;;;OASG;YACW,eAAe;IA6B7B;;;;;;;;OAQG;YACW,QAAQ;IAwDtB;;;;;OAKG;IACH,OAAO,CAAC,uBAAuB;CAahC"}
|