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,189 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Duplicate Detector
|
|
3
|
+
*
|
|
4
|
+
* Detects duplicate external items by scanning living docs for existing external IDs.
|
|
5
|
+
* Prevents re-importing items that have already been imported.
|
|
6
|
+
*/
|
|
7
|
+
import fs from 'fs-extra';
|
|
8
|
+
import path from 'path';
|
|
9
|
+
import matter from 'gray-matter';
|
|
10
|
+
import { glob } from 'glob';
|
|
11
|
+
/**
|
|
12
|
+
* Duplicate Detector
|
|
13
|
+
*
|
|
14
|
+
* Scans living docs US files for external_id metadata and provides
|
|
15
|
+
* duplicate detection functionality.
|
|
16
|
+
*/
|
|
17
|
+
export class DuplicateDetector {
|
|
18
|
+
constructor(options) {
|
|
19
|
+
this.cache = null;
|
|
20
|
+
this.options = {
|
|
21
|
+
enableCache: true,
|
|
22
|
+
...options,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Check if an external ID already exists in living docs
|
|
27
|
+
*
|
|
28
|
+
* @param externalId - External ID to check (e.g., "GH-#638", "JIRA-PROJ-123")
|
|
29
|
+
* @returns True if external ID exists (duplicate), false otherwise
|
|
30
|
+
*/
|
|
31
|
+
async checkExistingExternalId(externalId) {
|
|
32
|
+
const reference = await this.findExternalIdReference(externalId);
|
|
33
|
+
return reference !== null;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Find the User Story that contains a specific external ID
|
|
37
|
+
*
|
|
38
|
+
* @param externalId - External ID to search for
|
|
39
|
+
* @returns External ID reference if found, null otherwise
|
|
40
|
+
*/
|
|
41
|
+
async findExternalIdReference(externalId) {
|
|
42
|
+
// Build or use cache
|
|
43
|
+
const externalIdMap = await this.buildExternalIdMap();
|
|
44
|
+
// Normalize external ID for lookup
|
|
45
|
+
const normalizedId = this.normalizeExternalId(externalId);
|
|
46
|
+
return externalIdMap.get(normalizedId) || null;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Get all external IDs currently in living docs
|
|
50
|
+
*
|
|
51
|
+
* @returns Map of external ID to reference
|
|
52
|
+
*/
|
|
53
|
+
async getAllExternalIds() {
|
|
54
|
+
return this.buildExternalIdMap();
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Build map of external IDs to User Story references
|
|
58
|
+
*/
|
|
59
|
+
async buildExternalIdMap() {
|
|
60
|
+
// Return cached map if available
|
|
61
|
+
if (this.options.enableCache && this.cache) {
|
|
62
|
+
return this.cache;
|
|
63
|
+
}
|
|
64
|
+
const externalIdMap = new Map();
|
|
65
|
+
// Find all US markdown files in specs directory
|
|
66
|
+
const usFiles = await this.findUserStoryFiles();
|
|
67
|
+
// Scan each file for external_id metadata
|
|
68
|
+
for (const filePath of usFiles) {
|
|
69
|
+
const reference = await this.extractExternalIdFromFile(filePath);
|
|
70
|
+
if (reference) {
|
|
71
|
+
const normalizedId = this.normalizeExternalId(reference.externalId);
|
|
72
|
+
externalIdMap.set(normalizedId, reference);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
// Cache the map if enabled
|
|
76
|
+
if (this.options.enableCache) {
|
|
77
|
+
this.cache = externalIdMap;
|
|
78
|
+
}
|
|
79
|
+
return externalIdMap;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Find all User Story markdown files in specs directory
|
|
83
|
+
*/
|
|
84
|
+
async findUserStoryFiles() {
|
|
85
|
+
if (!fs.existsSync(this.options.specsDir)) {
|
|
86
|
+
return [];
|
|
87
|
+
}
|
|
88
|
+
// Match us-*.md files
|
|
89
|
+
const pattern = path.join(this.options.specsDir, 'us-*.md');
|
|
90
|
+
const files = await glob(pattern, { nodir: true });
|
|
91
|
+
return files;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Extract external_id from a User Story file
|
|
95
|
+
*
|
|
96
|
+
* @param filePath - Path to User Story markdown file
|
|
97
|
+
* @returns External ID reference if found, null otherwise
|
|
98
|
+
*/
|
|
99
|
+
async extractExternalIdFromFile(filePath) {
|
|
100
|
+
try {
|
|
101
|
+
const content = await fs.readFile(filePath, 'utf-8');
|
|
102
|
+
// Try to parse frontmatter
|
|
103
|
+
const parsed = matter(content);
|
|
104
|
+
// Check for external_id in frontmatter
|
|
105
|
+
if (parsed.data.external_id) {
|
|
106
|
+
return {
|
|
107
|
+
usId: this.extractUsIdFromFile(filePath, content),
|
|
108
|
+
filePath,
|
|
109
|
+
externalId: String(parsed.data.external_id),
|
|
110
|
+
platform: parsed.data.external_platform,
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
// Fallback: Parse external metadata section in content
|
|
114
|
+
const externalIdMatch = content.match(/^-\s+\*\*External ID\*\*:\s+(.+)$/m);
|
|
115
|
+
if (externalIdMatch) {
|
|
116
|
+
return {
|
|
117
|
+
usId: this.extractUsIdFromFile(filePath, content),
|
|
118
|
+
filePath,
|
|
119
|
+
externalId: externalIdMatch[1].trim(),
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
catch (error) {
|
|
125
|
+
// Skip files that can't be read
|
|
126
|
+
return null;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Extract US-ID from file name or content
|
|
131
|
+
*/
|
|
132
|
+
extractUsIdFromFile(filePath, content) {
|
|
133
|
+
// Try filename: us-001e-title.md → US-001E
|
|
134
|
+
const fileNameMatch = path.basename(filePath).match(/^us-(\d{3}e)/i);
|
|
135
|
+
if (fileNameMatch) {
|
|
136
|
+
return `US-${fileNameMatch[1].toUpperCase()}`;
|
|
137
|
+
}
|
|
138
|
+
// Try content: # US-001E: Title
|
|
139
|
+
const contentMatch = content.match(/^#\s+(US-\d{3}E):/m);
|
|
140
|
+
if (contentMatch) {
|
|
141
|
+
return contentMatch[1];
|
|
142
|
+
}
|
|
143
|
+
// Fallback: use filename
|
|
144
|
+
return path.basename(filePath, '.md');
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Normalize external ID for consistent comparison
|
|
148
|
+
*
|
|
149
|
+
* Examples:
|
|
150
|
+
* - "GH-#638" → "gh-638"
|
|
151
|
+
* - "GITHUB-638" → "gh-638"
|
|
152
|
+
* - "JIRA-PROJ-123" → "jira-proj-123"
|
|
153
|
+
*/
|
|
154
|
+
normalizeExternalId(externalId) {
|
|
155
|
+
return externalId
|
|
156
|
+
.toLowerCase()
|
|
157
|
+
.replace(/^github-/i, 'gh-')
|
|
158
|
+
.replace(/^gh-#/, 'gh-')
|
|
159
|
+
.replace(/^jira-/i, 'jira-')
|
|
160
|
+
.replace(/^ado-/i, 'ado-');
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Clear the cache (useful for testing or after imports)
|
|
164
|
+
*/
|
|
165
|
+
clearCache() {
|
|
166
|
+
this.cache = null;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Get cache statistics
|
|
170
|
+
*/
|
|
171
|
+
getCacheStats() {
|
|
172
|
+
return {
|
|
173
|
+
enabled: this.options.enableCache ?? true,
|
|
174
|
+
size: this.cache?.size ?? 0,
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Check if an external ID exists (convenience function)
|
|
180
|
+
*
|
|
181
|
+
* @param externalId - External ID to check
|
|
182
|
+
* @param specsDir - Living docs specs directory
|
|
183
|
+
* @returns True if duplicate exists
|
|
184
|
+
*/
|
|
185
|
+
export async function checkExistingExternalId(externalId, specsDir) {
|
|
186
|
+
const detector = new DuplicateDetector({ specsDir });
|
|
187
|
+
return detector.checkExistingExternalId(externalId);
|
|
188
|
+
}
|
|
189
|
+
//# sourceMappingURL=duplicate-detector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"duplicate-detector.js","sourceRoot":"","sources":["../../../src/importers/duplicate-detector.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External Importer Interface
|
|
3
|
+
*
|
|
4
|
+
* Abstraction layer for importing User Stories and tasks from external tools
|
|
5
|
+
* (GitHub, JIRA, Azure DevOps) into SpecWeave living docs.
|
|
6
|
+
*
|
|
7
|
+
* Supports:
|
|
8
|
+
* - Pagination for large datasets
|
|
9
|
+
* - Time range filtering
|
|
10
|
+
* - Platform-specific conversion
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* External item representation (platform-agnostic)
|
|
14
|
+
*/
|
|
15
|
+
export interface ExternalItem {
|
|
16
|
+
/** Platform-specific ID (e.g., "JIRA-123", "github#456") */
|
|
17
|
+
id: string;
|
|
18
|
+
/** Item type (user-story, epic, task, bug) */
|
|
19
|
+
type: 'user-story' | 'epic' | 'task' | 'bug' | 'feature';
|
|
20
|
+
/** Title/summary */
|
|
21
|
+
title: string;
|
|
22
|
+
/** Description/body */
|
|
23
|
+
description: string;
|
|
24
|
+
/** Status (open, in-progress, completed, closed) */
|
|
25
|
+
status: 'open' | 'in-progress' | 'completed' | 'closed';
|
|
26
|
+
/** Priority (P0-P4) */
|
|
27
|
+
priority?: 'P0' | 'P1' | 'P2' | 'P3' | 'P4';
|
|
28
|
+
/** Creation date */
|
|
29
|
+
createdAt: Date;
|
|
30
|
+
/** Last updated date */
|
|
31
|
+
updatedAt: Date;
|
|
32
|
+
/** External URL */
|
|
33
|
+
url: string;
|
|
34
|
+
/** Labels/tags */
|
|
35
|
+
labels: string[];
|
|
36
|
+
/** Acceptance criteria (extracted from description) */
|
|
37
|
+
acceptanceCriteria?: string[];
|
|
38
|
+
/** Child items (subtasks, linked issues) */
|
|
39
|
+
children?: ExternalItem[];
|
|
40
|
+
/** Parent ID (for hierarchical items) */
|
|
41
|
+
parentId?: string;
|
|
42
|
+
/** Platform this item came from */
|
|
43
|
+
platform: 'github' | 'jira' | 'ado';
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Import configuration
|
|
47
|
+
*/
|
|
48
|
+
export interface ImportConfig {
|
|
49
|
+
/** Time range in months (default: 3) */
|
|
50
|
+
timeRangeMonths?: number;
|
|
51
|
+
/** Include closed items (default: false) */
|
|
52
|
+
includeClosed?: boolean;
|
|
53
|
+
/** Filter by labels */
|
|
54
|
+
labels?: string[];
|
|
55
|
+
/** Filter by milestone/epic */
|
|
56
|
+
milestone?: string;
|
|
57
|
+
/** Maximum items to import (default: unlimited) */
|
|
58
|
+
maxItems?: number;
|
|
59
|
+
/** Include child items (subtasks) */
|
|
60
|
+
includeChildren?: boolean;
|
|
61
|
+
/** Page size for pagination (default: 100) */
|
|
62
|
+
pageSize?: number;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Importer interface
|
|
66
|
+
*/
|
|
67
|
+
export interface Importer {
|
|
68
|
+
/** Platform name */
|
|
69
|
+
readonly platform: 'github' | 'jira' | 'ado';
|
|
70
|
+
/**
|
|
71
|
+
* Import items from external platform
|
|
72
|
+
* @param config - Import configuration
|
|
73
|
+
* @returns Array of external items
|
|
74
|
+
*/
|
|
75
|
+
import(config?: ImportConfig): Promise<ExternalItem[]>;
|
|
76
|
+
/**
|
|
77
|
+
* Paginate through items (for large datasets)
|
|
78
|
+
* @param config - Import configuration
|
|
79
|
+
* @returns Async generator yielding items page by page
|
|
80
|
+
*/
|
|
81
|
+
paginate(config?: ImportConfig): AsyncGenerator<ExternalItem[], void, unknown>;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Import result
|
|
85
|
+
*/
|
|
86
|
+
export interface ImportResult {
|
|
87
|
+
/** Number of items imported */
|
|
88
|
+
count: number;
|
|
89
|
+
/** Imported items */
|
|
90
|
+
items: ExternalItem[];
|
|
91
|
+
/** Errors encountered during import */
|
|
92
|
+
errors: string[];
|
|
93
|
+
/** Platform */
|
|
94
|
+
platform: 'github' | 'jira' | 'ado';
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=external-importer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"external-importer.d.ts","sourceRoot":"","sources":["../../../src/importers/external-importer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,4DAA4D;IAC5D,EAAE,EAAE,MAAM,CAAC;IAEX,8CAA8C;IAC9C,IAAI,EAAE,YAAY,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,GAAG,SAAS,CAAC;IAEzD,oBAAoB;IACpB,KAAK,EAAE,MAAM,CAAC;IAEd,uBAAuB;IACvB,WAAW,EAAE,MAAM,CAAC;IAEpB,oDAAoD;IACpD,MAAM,EAAE,MAAM,GAAG,aAAa,GAAG,WAAW,GAAG,QAAQ,CAAC;IAExD,uBAAuB;IACvB,QAAQ,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IAE5C,oBAAoB;IACpB,SAAS,EAAE,IAAI,CAAC;IAEhB,wBAAwB;IACxB,SAAS,EAAE,IAAI,CAAC;IAEhB,mBAAmB;IACnB,GAAG,EAAE,MAAM,CAAC;IAEZ,kBAAkB;IAClB,MAAM,EAAE,MAAM,EAAE,CAAC;IAEjB,uDAAuD;IACvD,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;IAE9B,4CAA4C;IAC5C,QAAQ,CAAC,EAAE,YAAY,EAAE,CAAC;IAE1B,yCAAyC;IACzC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,mCAAmC;IACnC,QAAQ,EAAE,QAAQ,GAAG,MAAM,GAAG,KAAK,CAAC;CACrC;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,wCAAwC;IACxC,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB,4CAA4C;IAC5C,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB,uBAAuB;IACvB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAElB,+BAA+B;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,mDAAmD;IACnD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,qCAAqC;IACrC,eAAe,CAAC,EAAE,OAAO,CAAC;IAE1B,8CAA8C;IAC9C,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,oBAAoB;IACpB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,GAAG,KAAK,CAAC;IAE7C;;;;OAIG;IACH,MAAM,CAAC,MAAM,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;IAEvD;;;;OAIG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,YAAY,GAAG,cAAc,CAAC,YAAY,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;CAChF;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,+BAA+B;IAC/B,KAAK,EAAE,MAAM,CAAC;IAEd,qBAAqB;IACrB,KAAK,EAAE,YAAY,EAAE,CAAC;IAEtB,uCAAuC;IACvC,MAAM,EAAE,MAAM,EAAE,CAAC;IAEjB,eAAe;IACf,QAAQ,EAAE,QAAQ,GAAG,MAAM,GAAG,KAAK,CAAC;CACrC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External Importer Interface
|
|
3
|
+
*
|
|
4
|
+
* Abstraction layer for importing User Stories and tasks from external tools
|
|
5
|
+
* (GitHub, JIRA, Azure DevOps) into SpecWeave living docs.
|
|
6
|
+
*
|
|
7
|
+
* Supports:
|
|
8
|
+
* - Pagination for large datasets
|
|
9
|
+
* - Time range filtering
|
|
10
|
+
* - Platform-specific conversion
|
|
11
|
+
*/
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=external-importer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"external-importer.js","sourceRoot":"","sources":["../../../src/importers/external-importer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GitHub Importer
|
|
3
|
+
*
|
|
4
|
+
* Imports GitHub issues as External Items with pagination support.
|
|
5
|
+
* Handles rate limiting and converts GitHub-specific data to platform-agnostic format.
|
|
6
|
+
*/
|
|
7
|
+
import type { Importer, ExternalItem, ImportConfig } from './external-importer.js';
|
|
8
|
+
/**
|
|
9
|
+
* GitHub Importer Implementation
|
|
10
|
+
*/
|
|
11
|
+
export declare class GitHubImporter implements Importer {
|
|
12
|
+
readonly platform: "github";
|
|
13
|
+
private octokit;
|
|
14
|
+
private owner;
|
|
15
|
+
private repo;
|
|
16
|
+
constructor(owner: string, repo: string, token?: string);
|
|
17
|
+
/**
|
|
18
|
+
* Import all issues matching config
|
|
19
|
+
*/
|
|
20
|
+
import(config?: ImportConfig): Promise<ExternalItem[]>;
|
|
21
|
+
/**
|
|
22
|
+
* Paginate through issues (100 per page)
|
|
23
|
+
*/
|
|
24
|
+
paginate(config?: ImportConfig): AsyncGenerator<ExternalItem[], void, unknown>;
|
|
25
|
+
/**
|
|
26
|
+
* Convert GitHub issue to ExternalItem
|
|
27
|
+
*/
|
|
28
|
+
private convertToExternalItem;
|
|
29
|
+
/**
|
|
30
|
+
* Extract acceptance criteria from issue body
|
|
31
|
+
* Looks for patterns like:
|
|
32
|
+
* - [ ] AC-001: ...
|
|
33
|
+
* - Acceptance Criteria: ...
|
|
34
|
+
*/
|
|
35
|
+
private extractAcceptanceCriteria;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=github-importer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github-importer.d.ts","sourceRoot":"","sources":["../../../src/importers/github-importer.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAenF;;GAEG;AACH,qBAAa,cAAe,YAAW,QAAQ;IAC7C,QAAQ,CAAC,QAAQ,EAAG,QAAQ,CAAU;IACtC,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,IAAI,CAAS;gBAET,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM;IAQvD;;OAEG;IACG,MAAM,CAAC,MAAM,GAAE,YAAiB,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAUhE;;OAEG;IACI,QAAQ,CAAC,MAAM,GAAE,YAAiB,GAAG,cAAc,CAAC,YAAY,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC;IAkEzF;;OAEG;IACH,OAAO,CAAC,qBAAqB;IA8C7B;;;;;OAKG;IACH,OAAO,CAAC,yBAAyB;CA2BlC"}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GitHub Importer
|
|
3
|
+
*
|
|
4
|
+
* Imports GitHub issues as External Items with pagination support.
|
|
5
|
+
* Handles rate limiting and converts GitHub-specific data to platform-agnostic format.
|
|
6
|
+
*/
|
|
7
|
+
import { Octokit } from '@octokit/rest';
|
|
8
|
+
/**
|
|
9
|
+
* GitHub Importer Implementation
|
|
10
|
+
*/
|
|
11
|
+
export class GitHubImporter {
|
|
12
|
+
constructor(owner, repo, token) {
|
|
13
|
+
this.platform = 'github';
|
|
14
|
+
this.owner = owner;
|
|
15
|
+
this.repo = repo;
|
|
16
|
+
this.octokit = new Octokit({
|
|
17
|
+
auth: token || process.env.GITHUB_TOKEN,
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Import all issues matching config
|
|
22
|
+
*/
|
|
23
|
+
async import(config = {}) {
|
|
24
|
+
const items = [];
|
|
25
|
+
for await (const page of this.paginate(config)) {
|
|
26
|
+
items.push(...page);
|
|
27
|
+
}
|
|
28
|
+
return items;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Paginate through issues (100 per page)
|
|
32
|
+
*/
|
|
33
|
+
async *paginate(config = {}) {
|
|
34
|
+
const { timeRangeMonths = 3, includeClosed = false, labels = [], milestone, maxItems = Infinity, } = config;
|
|
35
|
+
// Calculate since date
|
|
36
|
+
const since = new Date();
|
|
37
|
+
since.setMonth(since.getMonth() - timeRangeMonths);
|
|
38
|
+
let page = 1;
|
|
39
|
+
let totalFetched = 0;
|
|
40
|
+
while (totalFetched < maxItems) {
|
|
41
|
+
try {
|
|
42
|
+
// Fetch page from GitHub API
|
|
43
|
+
const response = await this.octokit.issues.listForRepo({
|
|
44
|
+
owner: this.owner,
|
|
45
|
+
repo: this.repo,
|
|
46
|
+
state: includeClosed ? 'all' : 'open',
|
|
47
|
+
since: since.toISOString(),
|
|
48
|
+
labels: labels.join(','),
|
|
49
|
+
milestone: milestone,
|
|
50
|
+
per_page: 100,
|
|
51
|
+
page,
|
|
52
|
+
});
|
|
53
|
+
// Check rate limiting
|
|
54
|
+
const remaining = parseInt(response.headers['x-ratelimit-remaining'] || '0', 10);
|
|
55
|
+
if (remaining < 10) {
|
|
56
|
+
const resetTime = parseInt(response.headers['x-ratelimit-reset'] || '0', 10);
|
|
57
|
+
const resetDate = new Date(resetTime * 1000);
|
|
58
|
+
throw new Error(`GitHub rate limit approaching (${remaining} requests remaining). Resets at ${resetDate.toLocaleString()}`);
|
|
59
|
+
}
|
|
60
|
+
// Convert GitHub issues to ExternalItems
|
|
61
|
+
const items = response.data
|
|
62
|
+
.filter((issue) => !issue.pull_request) // Exclude pull requests
|
|
63
|
+
.map((issue) => this.convertToExternalItem(issue));
|
|
64
|
+
// Yield page
|
|
65
|
+
if (items.length > 0) {
|
|
66
|
+
yield items.slice(0, maxItems - totalFetched);
|
|
67
|
+
totalFetched += items.length;
|
|
68
|
+
}
|
|
69
|
+
// Check if we've reached the end
|
|
70
|
+
if (response.data.length < 100) {
|
|
71
|
+
break;
|
|
72
|
+
}
|
|
73
|
+
page++;
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
if (error.status === 403 && error.message.includes('rate limit')) {
|
|
77
|
+
throw new Error(`GitHub rate limit exceeded: ${error.message}`);
|
|
78
|
+
}
|
|
79
|
+
throw error;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Convert GitHub issue to ExternalItem
|
|
85
|
+
*/
|
|
86
|
+
convertToExternalItem(issue) {
|
|
87
|
+
// Extract type from labels
|
|
88
|
+
let type = 'task';
|
|
89
|
+
const labelNames = issue.labels.map((l) => l.name.toLowerCase());
|
|
90
|
+
if (labelNames.includes('user-story') || labelNames.includes('story')) {
|
|
91
|
+
type = 'user-story';
|
|
92
|
+
}
|
|
93
|
+
else if (labelNames.includes('epic')) {
|
|
94
|
+
type = 'epic';
|
|
95
|
+
}
|
|
96
|
+
else if (labelNames.includes('bug')) {
|
|
97
|
+
type = 'bug';
|
|
98
|
+
}
|
|
99
|
+
else if (labelNames.includes('feature')) {
|
|
100
|
+
type = 'feature';
|
|
101
|
+
}
|
|
102
|
+
// Extract priority from labels (P0, P1, P2, P3, P4)
|
|
103
|
+
const priorityLabel = labelNames.find((l) => /^p[0-4]$/i.test(l));
|
|
104
|
+
const priority = priorityLabel ? priorityLabel.toUpperCase() : undefined;
|
|
105
|
+
// Extract acceptance criteria from body
|
|
106
|
+
const acceptanceCriteria = this.extractAcceptanceCriteria(issue.body || '');
|
|
107
|
+
// Map GitHub state to ExternalItem status
|
|
108
|
+
let status = 'open';
|
|
109
|
+
if (issue.state === 'closed') {
|
|
110
|
+
status = 'completed';
|
|
111
|
+
}
|
|
112
|
+
else if (labelNames.includes('in-progress') || labelNames.includes('in progress')) {
|
|
113
|
+
status = 'in-progress';
|
|
114
|
+
}
|
|
115
|
+
return {
|
|
116
|
+
id: `github#${issue.number}`,
|
|
117
|
+
type,
|
|
118
|
+
title: issue.title,
|
|
119
|
+
description: issue.body || '',
|
|
120
|
+
status,
|
|
121
|
+
priority,
|
|
122
|
+
createdAt: new Date(issue.created_at),
|
|
123
|
+
updatedAt: new Date(issue.updated_at),
|
|
124
|
+
url: issue.html_url,
|
|
125
|
+
labels: issue.labels.map((l) => l.name),
|
|
126
|
+
acceptanceCriteria: acceptanceCriteria.length > 0 ? acceptanceCriteria : undefined,
|
|
127
|
+
platform: 'github',
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Extract acceptance criteria from issue body
|
|
132
|
+
* Looks for patterns like:
|
|
133
|
+
* - [ ] AC-001: ...
|
|
134
|
+
* - Acceptance Criteria: ...
|
|
135
|
+
*/
|
|
136
|
+
extractAcceptanceCriteria(body) {
|
|
137
|
+
const criteria = [];
|
|
138
|
+
// Pattern 1: Checkbox list items starting with "AC"
|
|
139
|
+
const acPattern = /^[\s-]*\[[ x]\]\s+(AC[-:]?\s*\d+:?\s*.+)$/gim;
|
|
140
|
+
const acMatches = body.matchAll(acPattern);
|
|
141
|
+
for (const match of acMatches) {
|
|
142
|
+
criteria.push(match[1].trim());
|
|
143
|
+
}
|
|
144
|
+
// Pattern 2: "Acceptance Criteria" section
|
|
145
|
+
const sectionPattern = /(?:^|\n)##?\s*Acceptance Criteria\s*\n([\s\S]*?)(?=\n##|\n---|\z)/i;
|
|
146
|
+
const sectionMatch = body.match(sectionPattern);
|
|
147
|
+
if (sectionMatch) {
|
|
148
|
+
const section = sectionMatch[1];
|
|
149
|
+
const itemPattern = /^[\s-]*[•*-]\s*(.+)$/gm;
|
|
150
|
+
const itemMatches = section.matchAll(itemPattern);
|
|
151
|
+
for (const match of itemMatches) {
|
|
152
|
+
const item = match[1].trim();
|
|
153
|
+
if (!criteria.some((c) => c.includes(item))) {
|
|
154
|
+
criteria.push(item);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
return criteria;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
//# sourceMappingURL=github-importer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github-importer.js","sourceRoot":"","sources":["../../../src/importers/github-importer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Import Coordinator
|
|
3
|
+
*
|
|
4
|
+
* Orchestrates multi-platform imports from GitHub, JIRA, and Azure DevOps.
|
|
5
|
+
* Handles parallel execution, progress tracking, and result aggregation.
|
|
6
|
+
*/
|
|
7
|
+
import type { ExternalItem, ImportConfig, ImportResult } from './external-importer.js';
|
|
8
|
+
import { type RateLimitInfo } from './rate-limiter.js';
|
|
9
|
+
export interface CoordinatorConfig {
|
|
10
|
+
/** Import from GitHub */
|
|
11
|
+
github?: {
|
|
12
|
+
owner: string;
|
|
13
|
+
repo: string;
|
|
14
|
+
token?: string;
|
|
15
|
+
};
|
|
16
|
+
/** Import from JIRA */
|
|
17
|
+
jira?: {
|
|
18
|
+
host: string;
|
|
19
|
+
email?: string;
|
|
20
|
+
apiToken?: string;
|
|
21
|
+
};
|
|
22
|
+
/** Import from Azure DevOps */
|
|
23
|
+
ado?: {
|
|
24
|
+
orgUrl: string;
|
|
25
|
+
project: string;
|
|
26
|
+
pat?: string;
|
|
27
|
+
};
|
|
28
|
+
/** Common import configuration */
|
|
29
|
+
importConfig?: ImportConfig;
|
|
30
|
+
/** Run imports in parallel (default: true) */
|
|
31
|
+
parallel?: boolean;
|
|
32
|
+
/** Progress callback */
|
|
33
|
+
onProgress?: (platform: string, count: number, total?: number) => void;
|
|
34
|
+
/** Project root for sync metadata (default: process.cwd()) */
|
|
35
|
+
projectRoot?: string;
|
|
36
|
+
/** Enable sync metadata tracking (default: true) */
|
|
37
|
+
enableSyncMetadata?: boolean;
|
|
38
|
+
/** Enable rate limiting (default: true) */
|
|
39
|
+
enableRateLimiting?: boolean;
|
|
40
|
+
/** Callback when rate limit warning */
|
|
41
|
+
onRateLimitWarning?: (platform: string, rateLimitInfo: RateLimitInfo) => void;
|
|
42
|
+
/** Callback when rate limit pause */
|
|
43
|
+
onRateLimitPause?: (platform: string, seconds: number) => void;
|
|
44
|
+
}
|
|
45
|
+
export interface CoordinatorResult {
|
|
46
|
+
/** Combined results from all platforms */
|
|
47
|
+
results: ImportResult[];
|
|
48
|
+
/** Total items imported across all platforms */
|
|
49
|
+
totalCount: number;
|
|
50
|
+
/** All imported items */
|
|
51
|
+
allItems: ExternalItem[];
|
|
52
|
+
/** Errors by platform */
|
|
53
|
+
errors: Record<string, string[]>;
|
|
54
|
+
/** Platforms that were imported from */
|
|
55
|
+
platforms: Array<'github' | 'jira' | 'ado'>;
|
|
56
|
+
/** Total items skipped as duplicates (if duplicate detection enabled) */
|
|
57
|
+
totalSkipped?: number;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Import Coordinator
|
|
61
|
+
*/
|
|
62
|
+
export declare class ImportCoordinator {
|
|
63
|
+
private importers;
|
|
64
|
+
private config;
|
|
65
|
+
private rateLimiter;
|
|
66
|
+
private projectRoot;
|
|
67
|
+
constructor(config: CoordinatorConfig);
|
|
68
|
+
/**
|
|
69
|
+
* Initialize importers based on configuration
|
|
70
|
+
*/
|
|
71
|
+
private initializeImporters;
|
|
72
|
+
/**
|
|
73
|
+
* Import from all configured platforms
|
|
74
|
+
*/
|
|
75
|
+
importAll(): Promise<CoordinatorResult>;
|
|
76
|
+
/**
|
|
77
|
+
* Import from platforms in parallel
|
|
78
|
+
*/
|
|
79
|
+
private importParallel;
|
|
80
|
+
/**
|
|
81
|
+
* Import from platforms sequentially
|
|
82
|
+
*/
|
|
83
|
+
private importSequential;
|
|
84
|
+
/**
|
|
85
|
+
* Import from a single platform with progress tracking
|
|
86
|
+
*/
|
|
87
|
+
private importFromPlatform;
|
|
88
|
+
/**
|
|
89
|
+
* Aggregate results from all platforms
|
|
90
|
+
*/
|
|
91
|
+
private aggregateResults;
|
|
92
|
+
/**
|
|
93
|
+
* Import from a specific platform only
|
|
94
|
+
*/
|
|
95
|
+
importFrom(platform: 'github' | 'jira' | 'ado'): Promise<ImportResult>;
|
|
96
|
+
/**
|
|
97
|
+
* Get list of configured platforms
|
|
98
|
+
*/
|
|
99
|
+
getConfiguredPlatforms(): Array<'github' | 'jira' | 'ado'>;
|
|
100
|
+
/**
|
|
101
|
+
* Check if a platform is configured
|
|
102
|
+
*/
|
|
103
|
+
isPlatformConfigured(platform: 'github' | 'jira' | 'ado'): boolean;
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=import-coordinator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"import-coordinator.d.ts","sourceRoot":"","sources":["../../../src/importers/import-coordinator.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAY,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAKjG,OAAO,EAAe,KAAK,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEpE,MAAM,WAAW,iBAAiB;IAChC,yBAAyB;IACzB,MAAM,CAAC,EAAE;QACP,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;IAEF,uBAAuB;IACvB,IAAI,CAAC,EAAE;QACL,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC;IAEF,+BAA+B;IAC/B,GAAG,CAAC,EAAE;QACJ,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,MAAM,CAAC;QAChB,GAAG,CAAC,EAAE,MAAM,CAAC;KACd,CAAC;IAEF,kCAAkC;IAClC,YAAY,CAAC,EAAE,YAAY,CAAC;IAE5B,8CAA8C;IAC9C,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB,wBAAwB;IACxB,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAEvE,8DAA8D;IAC9D,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,oDAAoD;IACpD,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAE7B,2CAA2C;IAC3C,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAE7B,uCAAuC;IACvC,kBAAkB,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,aAAa,EAAE,aAAa,KAAK,IAAI,CAAC;IAE9E,qCAAqC;IACrC,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CAChE;AAED,MAAM,WAAW,iBAAiB;IAChC,0CAA0C;IAC1C,OAAO,EAAE,YAAY,EAAE,CAAC;IAExB,gDAAgD;IAChD,UAAU,EAAE,MAAM,CAAC;IAEnB,yBAAyB;IACzB,QAAQ,EAAE,YAAY,EAAE,CAAC;IAEzB,yBAAyB;IACzB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAEjC,wCAAwC;IACxC,SAAS,EAAE,KAAK,CAAC,QAAQ,GAAG,MAAM,GAAG,KAAK,CAAC,CAAC;IAE5C,yEAAyE;IACzE,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,SAAS,CAAoC;IACrD,OAAO,CAAC,MAAM,CAAoB;IAClC,OAAO,CAAC,WAAW,CAA4B;IAC/C,OAAO,CAAC,WAAW,CAAS;gBAEhB,MAAM,EAAE,iBAAiB;IAiBrC;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAgD3B;;OAEG;IACG,SAAS,IAAI,OAAO,CAAC,iBAAiB,CAAC;IAU7C;;OAEG;YACW,cAAc;IAU5B;;OAEG;YACW,gBAAgB;IAkB9B;;OAEG;YACW,kBAAkB;IAyDhC;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAyCxB;;OAEG;IACG,UAAU,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,CAAC,YAAY,CAAC;IAU5E;;OAEG;IACH,sBAAsB,IAAI,KAAK,CAAC,QAAQ,GAAG,MAAM,GAAG,KAAK,CAAC;IAI1D;;OAEG;IACH,oBAAoB,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO;CAGnE"}
|