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
|
@@ -14,8 +14,13 @@ import { LanguageManager, isLanguageSupported, getSupportedLanguages } from '../
|
|
|
14
14
|
import { getLocaleManager } from '../../core/i18n/locale-manager.js';
|
|
15
15
|
import { consoleLogger } from '../../utils/logger.js';
|
|
16
16
|
import { generateInitialIncrement } from '../helpers/init/initial-increment-generator.js';
|
|
17
|
+
import { ImportCoordinator } from '../../importers/import-coordinator.js';
|
|
18
|
+
import { ItemConverter } from '../../importers/item-converter.js';
|
|
19
|
+
import { loadImportConfig } from '../../config/import-config.js';
|
|
17
20
|
const __dirname = getDirname(import.meta.url);
|
|
18
21
|
import { readEnvFile, parseEnvFile } from '../../utils/env-file.js';
|
|
22
|
+
import { selectRepositories } from '../helpers/github-repo-selector.js';
|
|
23
|
+
import { Octokit } from '@octokit/rest';
|
|
19
24
|
/**
|
|
20
25
|
* Detect if we're in the SpecWeave framework repository itself
|
|
21
26
|
* (development mode vs. user project mode)
|
|
@@ -1139,7 +1144,7 @@ export async function initCommand(projectName, options = {}) {
|
|
|
1139
1144
|
// No existing config - run setup
|
|
1140
1145
|
if (isFrameworkRepo) {
|
|
1141
1146
|
console.log(chalk.blue('\n🔍 Detected SpecWeave framework repository'));
|
|
1142
|
-
console.log(chalk.gray(' Recommended: Configure GitHub sync
|
|
1147
|
+
console.log(chalk.gray(' Recommended: Configure GitHub sync with full permissions (upsert, update, status)'));
|
|
1143
1148
|
console.log('');
|
|
1144
1149
|
}
|
|
1145
1150
|
await setupIssueTracker({
|
|
@@ -1168,6 +1173,27 @@ export async function initCommand(projectName, options = {}) {
|
|
|
1168
1173
|
console.error(chalk.yellow(`\n⚠️ Multi-project folder creation skipped: ${error.message}`));
|
|
1169
1174
|
}
|
|
1170
1175
|
}
|
|
1176
|
+
// 10.6.5 External Tool Import (T-025)
|
|
1177
|
+
// Import existing work items from GitHub, JIRA, or Azure DevOps
|
|
1178
|
+
// ONLY run if NOT continuing existing project (fresh start or new project)
|
|
1179
|
+
if (!continueExisting) {
|
|
1180
|
+
try {
|
|
1181
|
+
const importResult = await promptAndRunExternalImport(targetDir, isCI);
|
|
1182
|
+
if (importResult.totalCount > 0) {
|
|
1183
|
+
console.log(chalk.green(`\n✅ Imported ${importResult.totalCount} items from ${importResult.platforms.join(', ')}`));
|
|
1184
|
+
console.log(chalk.gray(' → Items saved to .specweave/docs/internal/specs/'));
|
|
1185
|
+
console.log('');
|
|
1186
|
+
}
|
|
1187
|
+
}
|
|
1188
|
+
catch (error) {
|
|
1189
|
+
// Non-critical - can import later manually
|
|
1190
|
+
if (process.env.DEBUG) {
|
|
1191
|
+
console.error(chalk.red(`\n❌ Import error: ${error.message}`));
|
|
1192
|
+
}
|
|
1193
|
+
console.log(chalk.yellow('\n⚠️ External tool import skipped (can run later)'));
|
|
1194
|
+
console.log(chalk.gray(' → Use: specweave import --from github'));
|
|
1195
|
+
}
|
|
1196
|
+
}
|
|
1171
1197
|
}
|
|
1172
1198
|
// 10.7 Testing Configuration (MOVED TO END - Better UX)
|
|
1173
1199
|
// Prompt for testing approach and coverage targets after all setup is complete
|
|
@@ -1334,6 +1360,338 @@ export async function initCommand(projectName, options = {}) {
|
|
|
1334
1360
|
process.exit(1);
|
|
1335
1361
|
}
|
|
1336
1362
|
}
|
|
1363
|
+
/**
|
|
1364
|
+
* Detect GitHub repository owner and name from git remote
|
|
1365
|
+
* Parses .git/config to extract GitHub remote URL
|
|
1366
|
+
*/
|
|
1367
|
+
function detectGitHubRemote(targetDir) {
|
|
1368
|
+
try {
|
|
1369
|
+
const gitConfigPath = path.join(targetDir, '.git', 'config');
|
|
1370
|
+
if (!fs.existsSync(gitConfigPath)) {
|
|
1371
|
+
return null;
|
|
1372
|
+
}
|
|
1373
|
+
const gitConfig = fs.readFileSync(gitConfigPath, 'utf-8');
|
|
1374
|
+
// Match GitHub remote URLs (both HTTPS and SSH)
|
|
1375
|
+
// HTTPS: https://github.com/owner/repo.git
|
|
1376
|
+
// SSH: git@github.com:owner/repo.git
|
|
1377
|
+
const httpsMatch = gitConfig.match(/https:\/\/github\.com\/([^/]+)\/([^/\s]+?)(?:\.git)?(?:\s|$)/);
|
|
1378
|
+
const sshMatch = gitConfig.match(/git@github\.com:([^/]+)\/([^/\s]+?)(?:\.git)?(?:\s|$)/);
|
|
1379
|
+
const match = httpsMatch || sshMatch;
|
|
1380
|
+
if (match) {
|
|
1381
|
+
return {
|
|
1382
|
+
owner: match[1],
|
|
1383
|
+
repo: match[2].replace(/\.git$/, '')
|
|
1384
|
+
};
|
|
1385
|
+
}
|
|
1386
|
+
return null;
|
|
1387
|
+
}
|
|
1388
|
+
catch (error) {
|
|
1389
|
+
return null;
|
|
1390
|
+
}
|
|
1391
|
+
}
|
|
1392
|
+
/**
|
|
1393
|
+
* Detect JIRA configuration from environment or .env file
|
|
1394
|
+
*/
|
|
1395
|
+
function detectJiraConfig(targetDir) {
|
|
1396
|
+
try {
|
|
1397
|
+
// Check environment variables first
|
|
1398
|
+
const envHost = process.env.JIRA_HOST;
|
|
1399
|
+
const envEmail = process.env.JIRA_EMAIL;
|
|
1400
|
+
const envToken = process.env.JIRA_API_TOKEN;
|
|
1401
|
+
if (envHost && envEmail && envToken) {
|
|
1402
|
+
return { host: envHost, email: envEmail, apiToken: envToken };
|
|
1403
|
+
}
|
|
1404
|
+
// Check .env file
|
|
1405
|
+
const envPath = path.join(targetDir, '.env');
|
|
1406
|
+
if (fs.existsSync(envPath)) {
|
|
1407
|
+
const envContent = fs.readFileSync(envPath, 'utf-8');
|
|
1408
|
+
const envVars = parseEnvFile(envContent);
|
|
1409
|
+
const fileHost = envVars.JIRA_HOST;
|
|
1410
|
+
const fileEmail = envVars.JIRA_EMAIL;
|
|
1411
|
+
const fileToken = envVars.JIRA_API_TOKEN;
|
|
1412
|
+
if (fileHost && fileEmail && fileToken) {
|
|
1413
|
+
return { host: fileHost, email: fileEmail, apiToken: fileToken };
|
|
1414
|
+
}
|
|
1415
|
+
}
|
|
1416
|
+
return null;
|
|
1417
|
+
}
|
|
1418
|
+
catch (error) {
|
|
1419
|
+
return null;
|
|
1420
|
+
}
|
|
1421
|
+
}
|
|
1422
|
+
/**
|
|
1423
|
+
* Detect Azure DevOps configuration from environment or .env file
|
|
1424
|
+
*/
|
|
1425
|
+
function detectADOConfig(targetDir) {
|
|
1426
|
+
try {
|
|
1427
|
+
// Check environment variables first
|
|
1428
|
+
const envOrgUrl = process.env.ADO_ORG_URL;
|
|
1429
|
+
const envProject = process.env.ADO_PROJECT;
|
|
1430
|
+
const envPat = process.env.ADO_PAT || process.env.AZURE_DEVOPS_PAT;
|
|
1431
|
+
if (envOrgUrl && envProject && envPat) {
|
|
1432
|
+
return { orgUrl: envOrgUrl, project: envProject, pat: envPat };
|
|
1433
|
+
}
|
|
1434
|
+
// Check .env file
|
|
1435
|
+
const envPath = path.join(targetDir, '.env');
|
|
1436
|
+
if (fs.existsSync(envPath)) {
|
|
1437
|
+
const envContent = fs.readFileSync(envPath, 'utf-8');
|
|
1438
|
+
const envVars = parseEnvFile(envContent);
|
|
1439
|
+
const fileOrgUrl = envVars.ADO_ORG_URL;
|
|
1440
|
+
const fileProject = envVars.ADO_PROJECT;
|
|
1441
|
+
const filePat = envVars.ADO_PAT || envVars.AZURE_DEVOPS_PAT;
|
|
1442
|
+
if (fileOrgUrl && fileProject && filePat) {
|
|
1443
|
+
return { orgUrl: fileOrgUrl, project: fileProject, pat: filePat };
|
|
1444
|
+
}
|
|
1445
|
+
}
|
|
1446
|
+
return null;
|
|
1447
|
+
}
|
|
1448
|
+
catch (error) {
|
|
1449
|
+
return null;
|
|
1450
|
+
}
|
|
1451
|
+
}
|
|
1452
|
+
/**
|
|
1453
|
+
* Prompt user and run external tool import
|
|
1454
|
+
* Detects GitHub/JIRA/ADO configuration and imports work items
|
|
1455
|
+
*/
|
|
1456
|
+
async function promptAndRunExternalImport(targetDir, isCI) {
|
|
1457
|
+
// Load import configuration (T-027)
|
|
1458
|
+
const importConfig = loadImportConfig(targetDir);
|
|
1459
|
+
// Check if import is disabled via config
|
|
1460
|
+
if (!importConfig.enabled) {
|
|
1461
|
+
return {
|
|
1462
|
+
results: [],
|
|
1463
|
+
totalCount: 0,
|
|
1464
|
+
allItems: [],
|
|
1465
|
+
errors: {},
|
|
1466
|
+
platforms: []
|
|
1467
|
+
};
|
|
1468
|
+
}
|
|
1469
|
+
// Detect available external tools
|
|
1470
|
+
const githubRemote = detectGitHubRemote(targetDir);
|
|
1471
|
+
const jiraConfig = detectJiraConfig(targetDir);
|
|
1472
|
+
const adoConfig = detectADOConfig(targetDir);
|
|
1473
|
+
const availableTools = [];
|
|
1474
|
+
if (githubRemote)
|
|
1475
|
+
availableTools.push('GitHub');
|
|
1476
|
+
if (jiraConfig)
|
|
1477
|
+
availableTools.push('JIRA');
|
|
1478
|
+
if (adoConfig)
|
|
1479
|
+
availableTools.push('Azure DevOps');
|
|
1480
|
+
// If no tools detected, skip import
|
|
1481
|
+
if (availableTools.length === 0) {
|
|
1482
|
+
return {
|
|
1483
|
+
results: [],
|
|
1484
|
+
totalCount: 0,
|
|
1485
|
+
allItems: [],
|
|
1486
|
+
errors: {},
|
|
1487
|
+
platforms: []
|
|
1488
|
+
};
|
|
1489
|
+
}
|
|
1490
|
+
console.log(chalk.blue('\n🔍 External Tool Detection'));
|
|
1491
|
+
console.log(chalk.gray(` Found: ${availableTools.join(', ')}`));
|
|
1492
|
+
console.log('');
|
|
1493
|
+
// In CI mode, skip import without prompting
|
|
1494
|
+
if (isCI) {
|
|
1495
|
+
console.log(chalk.gray(' → CI mode: Skipping import (can run manually later)\n'));
|
|
1496
|
+
return {
|
|
1497
|
+
results: [],
|
|
1498
|
+
totalCount: 0,
|
|
1499
|
+
allItems: [],
|
|
1500
|
+
errors: {},
|
|
1501
|
+
platforms: []
|
|
1502
|
+
};
|
|
1503
|
+
}
|
|
1504
|
+
// Prompt user to import
|
|
1505
|
+
const { shouldImport } = await inquirer.prompt([
|
|
1506
|
+
{
|
|
1507
|
+
type: 'confirm',
|
|
1508
|
+
name: 'shouldImport',
|
|
1509
|
+
message: `Import existing work items from ${availableTools.join(', ')}?`,
|
|
1510
|
+
default: false
|
|
1511
|
+
}
|
|
1512
|
+
]);
|
|
1513
|
+
if (!shouldImport) {
|
|
1514
|
+
console.log(chalk.gray(' ✓ Skipping import\n'));
|
|
1515
|
+
return {
|
|
1516
|
+
results: [],
|
|
1517
|
+
totalCount: 0,
|
|
1518
|
+
allItems: [],
|
|
1519
|
+
errors: {},
|
|
1520
|
+
platforms: []
|
|
1521
|
+
};
|
|
1522
|
+
}
|
|
1523
|
+
// US-011: Multi-Repo Selection for GitHub (if GitHub detected and token available)
|
|
1524
|
+
let repoSelectionConfig = null;
|
|
1525
|
+
if (githubRemote && process.env.GITHUB_TOKEN) {
|
|
1526
|
+
const { useMultiRepo } = await inquirer.prompt([
|
|
1527
|
+
{
|
|
1528
|
+
type: 'confirm',
|
|
1529
|
+
name: 'useMultiRepo',
|
|
1530
|
+
message: 'Do you want to import from multiple repositories?',
|
|
1531
|
+
default: false
|
|
1532
|
+
}
|
|
1533
|
+
]);
|
|
1534
|
+
if (useMultiRepo) {
|
|
1535
|
+
try {
|
|
1536
|
+
const octokit = new Octokit({ auth: process.env.GITHUB_TOKEN });
|
|
1537
|
+
repoSelectionConfig = await selectRepositories(octokit, process.env.GITHUB_TOKEN);
|
|
1538
|
+
if (repoSelectionConfig) {
|
|
1539
|
+
// Save to config.json for future imports
|
|
1540
|
+
const configPath = path.join(targetDir, '.specweave', 'config.json');
|
|
1541
|
+
let config = {};
|
|
1542
|
+
if (fs.existsSync(configPath)) {
|
|
1543
|
+
config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
|
|
1544
|
+
}
|
|
1545
|
+
if (!config.github) {
|
|
1546
|
+
config.github = {};
|
|
1547
|
+
}
|
|
1548
|
+
config.github.repositories = repoSelectionConfig.repositories;
|
|
1549
|
+
config.github.selectionStrategy = repoSelectionConfig.selectionStrategy;
|
|
1550
|
+
if (repoSelectionConfig.pattern) {
|
|
1551
|
+
config.github.pattern = repoSelectionConfig.pattern;
|
|
1552
|
+
}
|
|
1553
|
+
if (repoSelectionConfig.organizationName) {
|
|
1554
|
+
config.github.organizationName = repoSelectionConfig.organizationName;
|
|
1555
|
+
}
|
|
1556
|
+
fs.ensureDirSync(path.dirname(configPath));
|
|
1557
|
+
fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
|
|
1558
|
+
console.log(chalk.green(`✅ Repository selection saved to config.json\n`));
|
|
1559
|
+
}
|
|
1560
|
+
}
|
|
1561
|
+
catch (error) {
|
|
1562
|
+
console.error(chalk.yellow(`⚠️ Failed to select repositories: ${error instanceof Error ? error.message : String(error)}`));
|
|
1563
|
+
console.log(chalk.gray('Continuing with single repository import...\n'));
|
|
1564
|
+
}
|
|
1565
|
+
}
|
|
1566
|
+
}
|
|
1567
|
+
// Map config timeRangeMonths to closest prompt option
|
|
1568
|
+
let defaultTimeRange = 3; // Default to 3 months
|
|
1569
|
+
if (importConfig.timeRangeMonths === 1)
|
|
1570
|
+
defaultTimeRange = 1;
|
|
1571
|
+
else if (importConfig.timeRangeMonths <= 3)
|
|
1572
|
+
defaultTimeRange = 3;
|
|
1573
|
+
else if (importConfig.timeRangeMonths <= 6)
|
|
1574
|
+
defaultTimeRange = 6;
|
|
1575
|
+
else
|
|
1576
|
+
defaultTimeRange = 999;
|
|
1577
|
+
// Prompt for time range (with config default)
|
|
1578
|
+
const { timeRange } = await inquirer.prompt([
|
|
1579
|
+
{
|
|
1580
|
+
type: 'list',
|
|
1581
|
+
name: 'timeRange',
|
|
1582
|
+
message: 'How far back should we import?',
|
|
1583
|
+
choices: [
|
|
1584
|
+
{ name: '1 month (recent items only)', value: 1 },
|
|
1585
|
+
{ name: '3 months (recommended)', value: 3 },
|
|
1586
|
+
{ name: '6 months (comprehensive)', value: 6 },
|
|
1587
|
+
{ name: 'All time (warning: may be slow)', value: 999 }
|
|
1588
|
+
],
|
|
1589
|
+
default: defaultTimeRange
|
|
1590
|
+
}
|
|
1591
|
+
]);
|
|
1592
|
+
// Build coordinator configuration
|
|
1593
|
+
const coordinatorConfig = {
|
|
1594
|
+
importConfig: {
|
|
1595
|
+
timeRangeMonths: timeRange,
|
|
1596
|
+
includeClosed: false, // Only open/in-progress items
|
|
1597
|
+
pageSize: importConfig.pageSize // Use config page size (T-027)
|
|
1598
|
+
},
|
|
1599
|
+
parallel: true
|
|
1600
|
+
};
|
|
1601
|
+
// Add GitHub config if available
|
|
1602
|
+
if (githubRemote) {
|
|
1603
|
+
coordinatorConfig.github = {
|
|
1604
|
+
owner: githubRemote.owner,
|
|
1605
|
+
repo: githubRemote.repo,
|
|
1606
|
+
token: process.env.GITHUB_TOKEN
|
|
1607
|
+
};
|
|
1608
|
+
}
|
|
1609
|
+
// Add JIRA config if available
|
|
1610
|
+
if (jiraConfig) {
|
|
1611
|
+
coordinatorConfig.jira = {
|
|
1612
|
+
host: jiraConfig.host,
|
|
1613
|
+
email: jiraConfig.email,
|
|
1614
|
+
apiToken: jiraConfig.apiToken
|
|
1615
|
+
};
|
|
1616
|
+
}
|
|
1617
|
+
// Add ADO config if available
|
|
1618
|
+
if (adoConfig) {
|
|
1619
|
+
coordinatorConfig.ado = {
|
|
1620
|
+
orgUrl: adoConfig.orgUrl,
|
|
1621
|
+
project: adoConfig.project,
|
|
1622
|
+
pat: adoConfig.pat
|
|
1623
|
+
};
|
|
1624
|
+
}
|
|
1625
|
+
// Run import with progress tracking
|
|
1626
|
+
const spinner = ora('Importing items...').start();
|
|
1627
|
+
let totalImported = 0;
|
|
1628
|
+
coordinatorConfig.onProgress = (platform, count) => {
|
|
1629
|
+
spinner.text = `Importing from ${platform}... (${count} items)`;
|
|
1630
|
+
totalImported = count;
|
|
1631
|
+
};
|
|
1632
|
+
try {
|
|
1633
|
+
const coordinator = new ImportCoordinator(coordinatorConfig);
|
|
1634
|
+
const result = await coordinator.importAll();
|
|
1635
|
+
spinner.succeed(`Imported ${result.totalCount} items`);
|
|
1636
|
+
// Show breakdown by platform
|
|
1637
|
+
if (result.results.length > 0) {
|
|
1638
|
+
console.log('');
|
|
1639
|
+
result.results.forEach(platformResult => {
|
|
1640
|
+
console.log(chalk.gray(` ✓ ${platformResult.platform}: ${platformResult.count} items`));
|
|
1641
|
+
});
|
|
1642
|
+
}
|
|
1643
|
+
// Show errors if any
|
|
1644
|
+
if (Object.keys(result.errors).length > 0) {
|
|
1645
|
+
console.log('');
|
|
1646
|
+
console.log(chalk.yellow(' ⚠️ Some imports failed:'));
|
|
1647
|
+
Object.entries(result.errors).forEach(([platform, errors]) => {
|
|
1648
|
+
console.log(chalk.gray(` → ${platform}: ${errors.join(', ')}`));
|
|
1649
|
+
});
|
|
1650
|
+
}
|
|
1651
|
+
// Warn if many items detected
|
|
1652
|
+
if (result.totalCount > 100) {
|
|
1653
|
+
console.log('');
|
|
1654
|
+
console.log(chalk.yellow(` ⚠️ Imported ${result.totalCount} items (large dataset)`));
|
|
1655
|
+
console.log(chalk.gray(' → Consider using time range filters for faster imports'));
|
|
1656
|
+
}
|
|
1657
|
+
// Convert imported items to living docs User Stories
|
|
1658
|
+
// CRITICAL: This ONLY creates living docs, NOT increments
|
|
1659
|
+
if (result.totalCount > 0) {
|
|
1660
|
+
spinner.start('Converting to living docs...');
|
|
1661
|
+
try {
|
|
1662
|
+
const specsDir = path.join(targetDir, '.specweave', 'docs', 'internal', 'specs');
|
|
1663
|
+
const converter = new ItemConverter({ specsDir });
|
|
1664
|
+
const convertedStories = await converter.convertItems(result.allItems);
|
|
1665
|
+
spinner.succeed(`Converted ${convertedStories.length} User Stories to living docs`);
|
|
1666
|
+
console.log(chalk.gray(` → Living docs created with E suffix (US-001E, US-002E, ...)`));
|
|
1667
|
+
console.log(chalk.gray(` → Location: .specweave/docs/internal/specs/`));
|
|
1668
|
+
console.log('');
|
|
1669
|
+
// Validate that no increments were auto-created
|
|
1670
|
+
try {
|
|
1671
|
+
ItemConverter.validateNoIncrementsCreated(targetDir);
|
|
1672
|
+
}
|
|
1673
|
+
catch (validationError) {
|
|
1674
|
+
spinner.fail('Import validation failed');
|
|
1675
|
+
throw new Error(`CRITICAL ERROR: ${validationError.message}\n` +
|
|
1676
|
+
`This is a bug in the import system. Please report it.`);
|
|
1677
|
+
}
|
|
1678
|
+
console.log(chalk.blue(' 💡 Next steps:'));
|
|
1679
|
+
console.log(chalk.gray(' → Review imported User Stories in living docs'));
|
|
1680
|
+
console.log(chalk.gray(' → Create increments manually when ready: /specweave:increment "feature"'));
|
|
1681
|
+
console.log('');
|
|
1682
|
+
}
|
|
1683
|
+
catch (conversionError) {
|
|
1684
|
+
spinner.fail('Conversion to living docs failed');
|
|
1685
|
+
throw conversionError;
|
|
1686
|
+
}
|
|
1687
|
+
}
|
|
1688
|
+
return result;
|
|
1689
|
+
}
|
|
1690
|
+
catch (error) {
|
|
1691
|
+
spinner.fail('Import failed');
|
|
1692
|
+
throw error;
|
|
1693
|
+
}
|
|
1694
|
+
}
|
|
1337
1695
|
function createDirectoryStructure(targetDir, adapterName) {
|
|
1338
1696
|
const directories = [
|
|
1339
1697
|
// Core increment structure
|