specweave 0.17.1 → 0.17.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/specweave.js +16 -16
- package/dist/plugins/specweave-github/lib/github-spec-sync.d.ts +109 -6
- package/dist/plugins/specweave-github/lib/github-spec-sync.d.ts.map +1 -1
- package/dist/plugins/specweave-github/lib/github-spec-sync.js +435 -49
- package/dist/plugins/specweave-github/lib/github-spec-sync.js.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/github-multi-repo.d.ts +10 -2
- package/dist/src/cli/helpers/issue-tracker/github-multi-repo.d.ts.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/github-multi-repo.js +28 -14
- package/dist/src/cli/helpers/issue-tracker/github-multi-repo.js.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/github.d.ts.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/github.js +10 -1
- package/dist/src/cli/helpers/issue-tracker/github.js.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/index.d.ts.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/index.js +20 -0
- package/dist/src/cli/helpers/issue-tracker/index.js.map +1 -1
- package/dist/src/core/project-manager.d.ts +25 -21
- package/dist/src/core/project-manager.d.ts.map +1 -1
- package/dist/src/core/project-manager.js +41 -51
- package/dist/src/core/project-manager.js.map +1 -1
- package/dist/src/core/repo-structure/folder-detector.d.ts +19 -0
- package/dist/src/core/repo-structure/folder-detector.d.ts.map +1 -0
- package/dist/src/core/repo-structure/folder-detector.js +95 -0
- package/dist/src/core/repo-structure/folder-detector.js.map +1 -0
- package/dist/src/core/repo-structure/repo-structure-manager.d.ts +4 -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 +41 -27
- package/dist/src/core/repo-structure/repo-structure-manager.js.map +1 -1
- package/dist/src/core/types/spec-metadata.d.ts +34 -1
- package/dist/src/core/types/spec-metadata.d.ts.map +1 -1
- package/dist/src/core/types/sync-profile.d.ts +30 -0
- 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/utils/project-validator.d.ts +27 -0
- package/dist/src/utils/project-validator.d.ts.map +1 -0
- package/dist/src/utils/project-validator.js +68 -0
- package/dist/src/utils/project-validator.js.map +1 -0
- package/package.json +1 -1
- package/plugins/specweave/lib/hooks/git-diff-analyzer.js +129 -213
- package/plugins/specweave/lib/hooks/invoke-translator-skill.js +146 -192
- package/plugins/specweave/lib/hooks/prepare-reflection-context.js +103 -116
- package/plugins/specweave/lib/hooks/reflection-config-loader.js +85 -125
- package/plugins/specweave/lib/hooks/reflection-parser.js +267 -385
- package/plugins/specweave/lib/hooks/reflection-prompt-builder.js +169 -226
- package/plugins/specweave/lib/hooks/reflection-storage.js +223 -297
- package/plugins/specweave/lib/hooks/run-self-reflection.js +120 -191
- package/plugins/specweave/lib/hooks/translate-file.js +239 -300
- package/plugins/specweave/lib/hooks/translate-living-docs.js +88 -144
- package/plugins/specweave/lib/hooks/types/reflection-types.js +57 -72
- package/plugins/specweave/lib/hooks/update-tasks-md.js +117 -179
- package/plugins/specweave-ado/lib/ado-board-resolver.js +135 -205
- package/plugins/specweave-ado/lib/ado-client-v2.js +405 -449
- package/plugins/specweave-ado/lib/ado-hierarchical-sync.js +223 -335
- package/plugins/specweave-ado/lib/ado-spec-commit-sync.js +173 -194
- package/plugins/specweave-ado/lib/ado-spec-sync.js +380 -414
- package/plugins/specweave-ado/lib/conflict-resolver.ts +1 -1
- package/plugins/specweave-ado/lib/project-selector.js +168 -196
- package/plugins/specweave-github/MULTI-PROJECT-SYNC-ARCHITECTURE.md +658 -0
- package/plugins/specweave-github/SYNC-ARCHITECTURE-FIX-SUMMARY.md +302 -0
- package/plugins/specweave-github/hooks/post-task-completion.sh +55 -157
- package/plugins/specweave-github/lib/cli-sync-increment-changes.js +9 -20
- package/plugins/specweave-github/lib/github-board-resolver.js +69 -115
- package/plugins/specweave-github/lib/github-client-v2.js +400 -389
- package/plugins/specweave-github/lib/github-client.js +246 -280
- package/plugins/specweave-github/lib/github-hierarchical-sync.js +168 -251
- package/plugins/specweave-github/lib/github-spec-commit-sync.js +171 -194
- package/plugins/specweave-github/lib/github-spec-sync.js +742 -418
- package/plugins/specweave-github/lib/github-spec-sync.ts +597 -61
- package/plugins/specweave-github/lib/index.js +11 -10
- package/plugins/specweave-github/lib/repo-selector.js +174 -201
- package/plugins/specweave-github/lib/subtask-sync.js +132 -125
- package/plugins/specweave-github/lib/task-parser.js +191 -207
- package/plugins/specweave-github/lib/task-sync.js +344 -296
- package/plugins/specweave-github/lib/types.js +0 -5
- package/plugins/specweave-github/skills/github-sync/SKILL.md +234 -242
- package/plugins/specweave-jira/lib/jira-board-resolver.js +50 -79
- package/plugins/specweave-jira/lib/jira-hierarchical-sync.js +119 -191
- package/plugins/specweave-jira/lib/jira-spec-commit-sync.js +241 -263
- package/plugins/specweave-jira/lib/jira-spec-sync.js +366 -405
- package/plugins/specweave-jira/lib/project-selector.js +172 -201
- package/plugins/specweave-jira/lib/reorganization-detector.js +202 -237
- package/plugins/specweave-jira/lib/setup-wizard.js +162 -204
- package/dist/adapters/adapter-base.d.ts +0 -71
- package/dist/adapters/adapter-base.d.ts.map +0 -1
- package/dist/adapters/adapter-base.js +0 -139
- package/dist/adapters/adapter-base.js.map +0 -1
- package/dist/adapters/adapter-interface.d.ts +0 -149
- package/dist/adapters/adapter-interface.d.ts.map +0 -1
- package/dist/adapters/adapter-interface.js +0 -8
- package/dist/adapters/adapter-interface.js.map +0 -1
- package/dist/adapters/adapter-loader.d.ts +0 -91
- package/dist/adapters/adapter-loader.d.ts.map +0 -1
- package/dist/adapters/adapter-loader.js +0 -238
- package/dist/adapters/adapter-loader.js.map +0 -1
- package/dist/adapters/agents-md-generator.d.ts +0 -48
- package/dist/adapters/agents-md-generator.d.ts.map +0 -1
- package/dist/adapters/agents-md-generator.js +0 -193
- package/dist/adapters/agents-md-generator.js.map +0 -1
- package/dist/adapters/claude/adapter.d.ts +0 -128
- package/dist/adapters/claude/adapter.d.ts.map +0 -1
- package/dist/adapters/claude/adapter.js +0 -415
- package/dist/adapters/claude/adapter.js.map +0 -1
- package/dist/adapters/claude-md-generator.d.ts +0 -78
- package/dist/adapters/claude-md-generator.d.ts.map +0 -1
- package/dist/adapters/claude-md-generator.js +0 -307
- package/dist/adapters/claude-md-generator.js.map +0 -1
- package/dist/adapters/codex/adapter.d.ts +0 -50
- package/dist/adapters/codex/adapter.d.ts.map +0 -1
- package/dist/adapters/codex/adapter.js +0 -316
- package/dist/adapters/codex/adapter.js.map +0 -1
- package/dist/adapters/cursor/adapter.d.ts +0 -98
- package/dist/adapters/cursor/adapter.d.ts.map +0 -1
- package/dist/adapters/cursor/adapter.js +0 -406
- package/dist/adapters/cursor/adapter.js.map +0 -1
- package/dist/adapters/doc-generator.d.ts +0 -69
- package/dist/adapters/doc-generator.d.ts.map +0 -1
- package/dist/adapters/doc-generator.js +0 -247
- package/dist/adapters/doc-generator.js.map +0 -1
- package/dist/adapters/gemini/adapter.d.ts +0 -50
- package/dist/adapters/gemini/adapter.d.ts.map +0 -1
- package/dist/adapters/gemini/adapter.js +0 -281
- package/dist/adapters/gemini/adapter.js.map +0 -1
- package/dist/adapters/generic/adapter.d.ts +0 -86
- package/dist/adapters/generic/adapter.d.ts.map +0 -1
- package/dist/adapters/generic/adapter.js +0 -338
- package/dist/adapters/generic/adapter.js.map +0 -1
- package/dist/cli/commands/abandon.d.ts +0 -13
- package/dist/cli/commands/abandon.d.ts.map +0 -1
- package/dist/cli/commands/abandon.js +0 -15
- package/dist/cli/commands/abandon.js.map +0 -1
- package/dist/cli/commands/check-discipline.d.ts +0 -16
- package/dist/cli/commands/check-discipline.d.ts.map +0 -1
- package/dist/cli/commands/check-discipline.js +0 -79
- package/dist/cli/commands/check-discipline.js.map +0 -1
- package/dist/cli/commands/import-docs.d.ts +0 -21
- package/dist/cli/commands/import-docs.d.ts.map +0 -1
- package/dist/cli/commands/import-docs.js +0 -146
- package/dist/cli/commands/import-docs.js.map +0 -1
- package/dist/cli/commands/init-multiproject.d.ts +0 -11
- package/dist/cli/commands/init-multiproject.d.ts.map +0 -1
- package/dist/cli/commands/init-multiproject.js +0 -202
- package/dist/cli/commands/init-multiproject.js.map +0 -1
- package/dist/cli/commands/init.d.ts +0 -10
- package/dist/cli/commands/init.d.ts.map +0 -1
- package/dist/cli/commands/init.js +0 -1328
- package/dist/cli/commands/init.js.map +0 -1
- package/dist/cli/commands/install.d.ts +0 -9
- package/dist/cli/commands/install.d.ts.map +0 -1
- package/dist/cli/commands/install.js +0 -127
- package/dist/cli/commands/install.js.map +0 -1
- package/dist/cli/commands/list.d.ts +0 -8
- package/dist/cli/commands/list.d.ts.map +0 -1
- package/dist/cli/commands/list.js +0 -119
- package/dist/cli/commands/list.js.map +0 -1
- package/dist/cli/commands/migrate-to-multiproject.d.ts +0 -37
- package/dist/cli/commands/migrate-to-multiproject.d.ts.map +0 -1
- package/dist/cli/commands/migrate-to-multiproject.js +0 -189
- package/dist/cli/commands/migrate-to-multiproject.js.map +0 -1
- package/dist/cli/commands/migrate-to-profiles.d.ts +0 -25
- package/dist/cli/commands/migrate-to-profiles.d.ts.map +0 -1
- package/dist/cli/commands/migrate-to-profiles.js +0 -348
- package/dist/cli/commands/migrate-to-profiles.js.map +0 -1
- package/dist/cli/commands/pause.d.ts +0 -13
- package/dist/cli/commands/pause.d.ts.map +0 -1
- package/dist/cli/commands/pause.js +0 -15
- package/dist/cli/commands/pause.js.map +0 -1
- package/dist/cli/commands/qa.d.ts +0 -54
- package/dist/cli/commands/qa.d.ts.map +0 -1
- package/dist/cli/commands/qa.js +0 -98
- package/dist/cli/commands/qa.js.map +0 -1
- package/dist/cli/commands/resume.d.ts +0 -12
- package/dist/cli/commands/resume.d.ts.map +0 -1
- package/dist/cli/commands/resume.js +0 -14
- package/dist/cli/commands/resume.js.map +0 -1
- package/dist/cli/commands/revert-wip-limit.js +0 -60
- package/dist/cli/commands/status-line.d.ts +0 -14
- package/dist/cli/commands/status-line.d.ts.map +0 -1
- package/dist/cli/commands/status-line.js +0 -75
- package/dist/cli/commands/status-line.js.map +0 -1
- package/dist/cli/commands/status.d.ts +0 -12
- package/dist/cli/commands/status.d.ts.map +0 -1
- package/dist/cli/commands/status.js +0 -23
- package/dist/cli/commands/status.js.map +0 -1
- package/dist/cli/commands/switch-project.d.ts +0 -13
- package/dist/cli/commands/switch-project.d.ts.map +0 -1
- package/dist/cli/commands/switch-project.js +0 -91
- package/dist/cli/commands/switch-project.js.map +0 -1
- package/dist/cli/commands/sync-spec-commits.d.ts +0 -9
- package/dist/cli/commands/sync-spec-commits.d.ts.map +0 -1
- package/dist/cli/commands/sync-spec-commits.js +0 -186
- package/dist/cli/commands/sync-spec-commits.js.map +0 -1
- package/dist/cli/commands/validate-jira.d.ts +0 -35
- package/dist/cli/commands/validate-jira.d.ts.map +0 -1
- package/dist/cli/commands/validate-jira.js +0 -112
- package/dist/cli/commands/validate-jira.js.map +0 -1
- package/dist/cli/commands/validate-plugins.d.ts +0 -41
- package/dist/cli/commands/validate-plugins.d.ts.map +0 -1
- package/dist/cli/commands/validate-plugins.js +0 -171
- package/dist/cli/commands/validate-plugins.js.map +0 -1
- package/dist/cli/helpers/github/increment-profile-selector.d.ts +0 -47
- package/dist/cli/helpers/github/increment-profile-selector.d.ts.map +0 -1
- package/dist/cli/helpers/github/increment-profile-selector.js +0 -186
- package/dist/cli/helpers/github/increment-profile-selector.js.map +0 -1
- package/dist/cli/helpers/github/profile-manager.d.ts +0 -119
- package/dist/cli/helpers/github/profile-manager.d.ts.map +0 -1
- package/dist/cli/helpers/github/profile-manager.js +0 -311
- package/dist/cli/helpers/github/profile-manager.js.map +0 -1
- package/dist/cli/helpers/issue-tracker/ado.d.ts +0 -57
- package/dist/cli/helpers/issue-tracker/ado.d.ts.map +0 -1
- package/dist/cli/helpers/issue-tracker/ado.js +0 -243
- package/dist/cli/helpers/issue-tracker/ado.js.map +0 -1
- package/dist/cli/helpers/issue-tracker/github-multi-repo.d.ts +0 -86
- package/dist/cli/helpers/issue-tracker/github-multi-repo.d.ts.map +0 -1
- package/dist/cli/helpers/issue-tracker/github-multi-repo.js +0 -417
- package/dist/cli/helpers/issue-tracker/github-multi-repo.js.map +0 -1
- package/dist/cli/helpers/issue-tracker/github.d.ts +0 -80
- package/dist/cli/helpers/issue-tracker/github.d.ts.map +0 -1
- package/dist/cli/helpers/issue-tracker/github.js +0 -324
- package/dist/cli/helpers/issue-tracker/github.js.map +0 -1
- package/dist/cli/helpers/issue-tracker/index.d.ts +0 -22
- package/dist/cli/helpers/issue-tracker/index.d.ts.map +0 -1
- package/dist/cli/helpers/issue-tracker/index.js +0 -562
- package/dist/cli/helpers/issue-tracker/index.js.map +0 -1
- package/dist/cli/helpers/issue-tracker/jira.d.ts +0 -61
- package/dist/cli/helpers/issue-tracker/jira.d.ts.map +0 -1
- package/dist/cli/helpers/issue-tracker/jira.js +0 -404
- package/dist/cli/helpers/issue-tracker/jira.js.map +0 -1
- package/dist/cli/helpers/issue-tracker/types.d.ts +0 -108
- package/dist/cli/helpers/issue-tracker/types.d.ts.map +0 -1
- package/dist/cli/helpers/issue-tracker/types.js +0 -16
- package/dist/cli/helpers/issue-tracker/types.js.map +0 -1
- package/dist/cli/helpers/issue-tracker/utils.d.ts +0 -120
- package/dist/cli/helpers/issue-tracker/utils.d.ts.map +0 -1
- package/dist/cli/helpers/issue-tracker/utils.js +0 -293
- package/dist/cli/helpers/issue-tracker/utils.js.map +0 -1
- package/dist/core/agent-model-manager.d.ts +0 -52
- package/dist/core/agent-model-manager.d.ts.map +0 -1
- package/dist/core/agent-model-manager.js +0 -120
- package/dist/core/agent-model-manager.js.map +0 -1
- package/dist/core/brownfield/analyzer.d.ts +0 -86
- package/dist/core/brownfield/analyzer.d.ts.map +0 -1
- package/dist/core/brownfield/analyzer.js +0 -365
- package/dist/core/brownfield/analyzer.js.map +0 -1
- package/dist/core/brownfield/importer.d.ts +0 -76
- package/dist/core/brownfield/importer.d.ts.map +0 -1
- package/dist/core/brownfield/importer.js +0 -287
- package/dist/core/brownfield/importer.js.map +0 -1
- package/dist/core/comment-builder.d.ts +0 -57
- package/dist/core/comment-builder.d.ts.map +0 -1
- package/dist/core/comment-builder.js +0 -239
- package/dist/core/comment-builder.js.map +0 -1
- package/dist/core/config-manager.d.ts +0 -47
- package/dist/core/config-manager.d.ts.map +0 -1
- package/dist/core/config-manager.js +0 -136
- package/dist/core/config-manager.js.map +0 -1
- package/dist/core/cost-tracker.d.ts +0 -108
- package/dist/core/cost-tracker.d.ts.map +0 -1
- package/dist/core/cost-tracker.js +0 -281
- package/dist/core/cost-tracker.js.map +0 -1
- package/dist/core/credentials-manager.d.ts +0 -107
- package/dist/core/credentials-manager.d.ts.map +0 -1
- package/dist/core/credentials-manager.js +0 -457
- package/dist/core/credentials-manager.js.map +0 -1
- package/dist/core/i18n/language-detector.d.ts +0 -29
- package/dist/core/i18n/language-detector.d.ts.map +0 -1
- package/dist/core/i18n/language-detector.js +0 -143
- package/dist/core/i18n/language-detector.js.map +0 -1
- package/dist/core/i18n/language-manager.d.ts +0 -101
- package/dist/core/i18n/language-manager.d.ts.map +0 -1
- package/dist/core/i18n/language-manager.js +0 -232
- package/dist/core/i18n/language-manager.js.map +0 -1
- package/dist/core/i18n/language-registry.d.ts +0 -44
- package/dist/core/i18n/language-registry.d.ts.map +0 -1
- package/dist/core/i18n/language-registry.js +0 -234
- package/dist/core/i18n/language-registry.js.map +0 -1
- package/dist/core/i18n/locale-manager.d.ts +0 -62
- package/dist/core/i18n/locale-manager.d.ts.map +0 -1
- package/dist/core/i18n/locale-manager.js +0 -137
- package/dist/core/i18n/locale-manager.js.map +0 -1
- package/dist/core/i18n/system-prompt-injector.d.ts +0 -33
- package/dist/core/i18n/system-prompt-injector.d.ts.map +0 -1
- package/dist/core/i18n/system-prompt-injector.js +0 -131
- package/dist/core/i18n/system-prompt-injector.js.map +0 -1
- package/dist/core/i18n/types.d.ts +0 -151
- package/dist/core/i18n/types.d.ts.map +0 -1
- package/dist/core/i18n/types.js +0 -11
- package/dist/core/i18n/types.js.map +0 -1
- package/dist/core/increment/active-increment-manager.d.ts +0 -79
- package/dist/core/increment/active-increment-manager.d.ts.map +0 -1
- package/dist/core/increment/active-increment-manager.js +0 -153
- package/dist/core/increment/active-increment-manager.js.map +0 -1
- package/dist/core/increment/discipline-checker.d.ts +0 -60
- package/dist/core/increment/discipline-checker.d.ts.map +0 -1
- package/dist/core/increment/discipline-checker.js +0 -274
- package/dist/core/increment/discipline-checker.js.map +0 -1
- package/dist/core/increment/limits.d.ts +0 -68
- package/dist/core/increment/limits.d.ts.map +0 -1
- package/dist/core/increment/limits.js +0 -224
- package/dist/core/increment/limits.js.map +0 -1
- package/dist/core/increment/metadata-manager.d.ts +0 -116
- package/dist/core/increment/metadata-manager.d.ts.map +0 -1
- package/dist/core/increment/metadata-manager.js.map +0 -1
- package/dist/core/increment/metadata-validator.d.ts +0 -33
- package/dist/core/increment/metadata-validator.d.ts.map +0 -1
- package/dist/core/increment/metadata-validator.js +0 -147
- package/dist/core/increment/metadata-validator.js.map +0 -1
- package/dist/core/increment/status-commands.d.ts +0 -43
- package/dist/core/increment/status-commands.d.ts.map +0 -1
- package/dist/core/increment/status-commands.js +0 -277
- package/dist/core/increment/status-commands.js.map +0 -1
- package/dist/core/increment/types.d.ts +0 -88
- package/dist/core/increment/types.d.ts.map +0 -1
- package/dist/core/increment/types.js +0 -8
- package/dist/core/increment/types.js.map +0 -1
- package/dist/core/increment-status.d.ts +0 -72
- package/dist/core/increment-status.d.ts.map +0 -1
- package/dist/core/increment-status.js +0 -227
- package/dist/core/increment-status.js.map +0 -1
- package/dist/core/model-selector.d.ts +0 -57
- package/dist/core/model-selector.d.ts.map +0 -1
- package/dist/core/model-selector.js +0 -115
- package/dist/core/model-selector.js.map +0 -1
- package/dist/core/phase-detector.d.ts +0 -62
- package/dist/core/phase-detector.d.ts.map +0 -1
- package/dist/core/phase-detector.js +0 -229
- package/dist/core/phase-detector.js.map +0 -1
- package/dist/core/plugin-loader.d.ts +0 -131
- package/dist/core/plugin-loader.d.ts.map +0 -1
- package/dist/core/plugin-loader.js +0 -421
- package/dist/core/plugin-loader.js.map +0 -1
- package/dist/core/project-manager.d.ts +0 -127
- package/dist/core/project-manager.d.ts.map +0 -1
- package/dist/core/project-manager.js +0 -524
- package/dist/core/project-manager.js.map +0 -1
- package/dist/core/project-structure-detector.d.ts +0 -92
- package/dist/core/project-structure-detector.d.ts.map +0 -1
- package/dist/core/project-structure-detector.js +0 -289
- package/dist/core/project-structure-detector.js.map +0 -1
- package/dist/core/qa/qa-runner.d.ts +0 -16
- package/dist/core/qa/qa-runner.d.ts.map +0 -1
- package/dist/core/qa/qa-runner.js +0 -422
- package/dist/core/qa/qa-runner.js.map +0 -1
- package/dist/core/qa/quality-gate-decider.d.ts +0 -53
- package/dist/core/qa/quality-gate-decider.d.ts.map +0 -1
- package/dist/core/qa/quality-gate-decider.js +0 -268
- package/dist/core/qa/quality-gate-decider.js.map +0 -1
- package/dist/core/qa/risk-calculator.d.ts +0 -126
- package/dist/core/qa/risk-calculator.d.ts.map +0 -1
- package/dist/core/qa/risk-calculator.js +0 -247
- package/dist/core/qa/risk-calculator.js.map +0 -1
- package/dist/core/qa/types.d.ts +0 -315
- package/dist/core/qa/types.d.ts.map +0 -1
- package/dist/core/qa/types.js +0 -8
- package/dist/core/qa/types.js.map +0 -1
- package/dist/core/repo-structure/repo-structure-manager.d.ts +0 -82
- package/dist/core/repo-structure/repo-structure-manager.d.ts.map +0 -1
- package/dist/core/repo-structure/repo-structure-manager.js +0 -581
- package/dist/core/repo-structure/repo-structure-manager.js.map +0 -1
- package/dist/core/rfc-generator-v2.d.ts +0 -149
- package/dist/core/rfc-generator-v2.d.ts.map +0 -1
- package/dist/core/rfc-generator-v2.js +0 -399
- package/dist/core/rfc-generator-v2.js.map +0 -1
- package/dist/core/spec-task-mapper.d.ts +0 -71
- package/dist/core/spec-task-mapper.d.ts.map +0 -1
- package/dist/core/spec-task-mapper.js +0 -208
- package/dist/core/spec-task-mapper.js.map +0 -1
- package/dist/core/specs/spec-metadata-manager.d.ts +0 -70
- package/dist/core/specs/spec-metadata-manager.d.ts.map +0 -1
- package/dist/core/specs/spec-metadata-manager.js +0 -371
- package/dist/core/specs/spec-metadata-manager.js.map +0 -1
- package/dist/core/specs/spec-parser.d.ts +0 -66
- package/dist/core/specs/spec-parser.d.ts.map +0 -1
- package/dist/core/specs/spec-parser.js +0 -276
- package/dist/core/specs/spec-parser.js.map +0 -1
- package/dist/core/status-line/status-line-manager.d.ts +0 -62
- package/dist/core/status-line/status-line-manager.d.ts.map +0 -1
- package/dist/core/status-line/status-line-manager.js +0 -169
- package/dist/core/status-line/status-line-manager.js.map +0 -1
- package/dist/core/status-line/types.d.ts +0 -50
- package/dist/core/status-line/types.d.ts.map +0 -1
- package/dist/core/status-line/types.js +0 -17
- package/dist/core/status-line/types.js.map +0 -1
- package/dist/core/sync/bidirectional-engine.d.ts +0 -110
- package/dist/core/sync/bidirectional-engine.d.ts.map +0 -1
- package/dist/core/sync/bidirectional-engine.js +0 -356
- package/dist/core/sync/bidirectional-engine.js.map +0 -1
- package/dist/core/sync/folder-mapper.d.ts +0 -71
- package/dist/core/sync/folder-mapper.d.ts.map +0 -1
- package/dist/core/sync/folder-mapper.js +0 -203
- package/dist/core/sync/folder-mapper.js.map +0 -1
- package/dist/core/sync/profile-manager.d.ts +0 -72
- package/dist/core/sync/profile-manager.d.ts.map +0 -1
- package/dist/core/sync/profile-manager.js +0 -338
- package/dist/core/sync/profile-manager.js.map +0 -1
- package/dist/core/sync/profile-selector.d.ts +0 -52
- package/dist/core/sync/profile-selector.d.ts.map +0 -1
- package/dist/core/sync/profile-selector.js +0 -179
- package/dist/core/sync/profile-selector.js.map +0 -1
- package/dist/core/sync/profile-validator.d.ts +0 -52
- package/dist/core/sync/profile-validator.d.ts.map +0 -1
- package/dist/core/sync/profile-validator.js +0 -170
- package/dist/core/sync/profile-validator.js.map +0 -1
- package/dist/core/sync/project-context.d.ts +0 -81
- package/dist/core/sync/project-context.d.ts.map +0 -1
- package/dist/core/sync/project-context.js +0 -354
- package/dist/core/sync/project-context.js.map +0 -1
- package/dist/core/sync/rate-limiter.d.ts +0 -116
- package/dist/core/sync/rate-limiter.d.ts.map +0 -1
- package/dist/core/sync/rate-limiter.js +0 -308
- package/dist/core/sync/rate-limiter.js.map +0 -1
- package/dist/core/sync/time-range-selector.d.ts +0 -48
- package/dist/core/sync/time-range-selector.d.ts.map +0 -1
- package/dist/core/sync/time-range-selector.js +0 -224
- package/dist/core/sync/time-range-selector.js.map +0 -1
- package/dist/core/types/config.d.ts +0 -90
- package/dist/core/types/config.d.ts.map +0 -1
- package/dist/core/types/config.js +0 -44
- package/dist/core/types/config.js.map +0 -1
- package/dist/core/types/increment-metadata.d.ts +0 -120
- package/dist/core/types/increment-metadata.d.ts.map +0 -1
- package/dist/core/types/increment-metadata.js +0 -138
- package/dist/core/types/increment-metadata.js.map +0 -1
- package/dist/core/types/plugin.d.ts +0 -283
- package/dist/core/types/plugin.d.ts.map +0 -1
- package/dist/core/types/plugin.js +0 -49
- package/dist/core/types/plugin.js.map +0 -1
- package/dist/core/types/spec-metadata.d.ts +0 -229
- package/dist/core/types/spec-metadata.d.ts.map +0 -1
- package/dist/core/types/spec-metadata.js +0 -14
- package/dist/core/types/spec-metadata.js.map +0 -1
- package/dist/core/types/sync-profile.d.ts +0 -349
- package/dist/core/types/sync-profile.d.ts.map +0 -1
- package/dist/core/types/sync-profile.js +0 -79
- package/dist/core/types/sync-profile.js.map +0 -1
- package/dist/hooks/lib/git-diff-analyzer.d.ts +0 -89
- package/dist/hooks/lib/git-diff-analyzer.d.ts.map +0 -1
- package/dist/hooks/lib/git-diff-analyzer.js +0 -226
- package/dist/hooks/lib/git-diff-analyzer.js.map +0 -1
- package/dist/hooks/lib/invoke-translator-skill.d.ts +0 -60
- package/dist/hooks/lib/invoke-translator-skill.d.ts.map +0 -1
- package/dist/hooks/lib/invoke-translator-skill.js +0 -201
- package/dist/hooks/lib/invoke-translator-skill.js.map +0 -1
- package/dist/hooks/lib/prepare-reflection-context.d.ts +0 -42
- package/dist/hooks/lib/prepare-reflection-context.d.ts.map +0 -1
- package/dist/hooks/lib/prepare-reflection-context.js +0 -123
- package/dist/hooks/lib/prepare-reflection-context.js.map +0 -1
- package/dist/hooks/lib/reflection-config-loader.d.ts +0 -45
- package/dist/hooks/lib/reflection-config-loader.d.ts.map +0 -1
- package/dist/hooks/lib/reflection-config-loader.js +0 -132
- package/dist/hooks/lib/reflection-config-loader.js.map +0 -1
- package/dist/hooks/lib/reflection-parser.d.ts +0 -33
- package/dist/hooks/lib/reflection-parser.d.ts.map +0 -1
- package/dist/hooks/lib/reflection-parser.js +0 -419
- package/dist/hooks/lib/reflection-parser.js.map +0 -1
- package/dist/hooks/lib/reflection-prompt-builder.d.ts +0 -56
- package/dist/hooks/lib/reflection-prompt-builder.d.ts.map +0 -1
- package/dist/hooks/lib/reflection-prompt-builder.js +0 -239
- package/dist/hooks/lib/reflection-prompt-builder.js.map +0 -1
- package/dist/hooks/lib/reflection-storage.d.ts +0 -64
- package/dist/hooks/lib/reflection-storage.d.ts.map +0 -1
- package/dist/hooks/lib/reflection-storage.js +0 -305
- package/dist/hooks/lib/reflection-storage.js.map +0 -1
- package/dist/hooks/lib/run-self-reflection.d.ts +0 -43
- package/dist/hooks/lib/run-self-reflection.d.ts.map +0 -1
- package/dist/hooks/lib/run-self-reflection.js +0 -203
- package/dist/hooks/lib/run-self-reflection.js.map +0 -1
- package/dist/hooks/lib/sync-living-docs.d.ts +0 -27
- package/dist/hooks/lib/sync-living-docs.d.ts.map +0 -1
- package/dist/hooks/lib/sync-living-docs.js +0 -116
- package/dist/hooks/lib/sync-living-docs.js.map +0 -1
- package/dist/hooks/lib/translate-file.d.ts +0 -59
- package/dist/hooks/lib/translate-file.d.ts.map +0 -1
- package/dist/hooks/lib/translate-file.js +0 -350
- package/dist/hooks/lib/translate-file.js.map +0 -1
- package/dist/hooks/lib/translate-living-docs.d.ts +0 -13
- package/dist/hooks/lib/translate-living-docs.d.ts.map +0 -1
- package/dist/hooks/lib/translate-living-docs.js +0 -175
- package/dist/hooks/lib/translate-living-docs.js.map +0 -1
- package/dist/hooks/lib/types/reflection-types.d.ts +0 -164
- package/dist/hooks/lib/types/reflection-types.d.ts.map +0 -1
- package/dist/hooks/lib/types/reflection-types.js +0 -73
- package/dist/hooks/lib/types/reflection-types.js.map +0 -1
- package/dist/hooks/lib/update-tasks-md.d.ts +0 -29
- package/dist/hooks/lib/update-tasks-md.d.ts.map +0 -1
- package/dist/hooks/lib/update-tasks-md.js +0 -203
- package/dist/hooks/lib/update-tasks-md.js.map +0 -1
- package/dist/integrations/ado/ado-client.d.ts +0 -127
- package/dist/integrations/ado/ado-client.d.ts.map +0 -1
- package/dist/integrations/ado/ado-client.js +0 -416
- package/dist/integrations/ado/ado-client.js.map +0 -1
- package/dist/integrations/jira/jira-client.d.ts +0 -139
- package/dist/integrations/jira/jira-client.d.ts.map +0 -1
- package/dist/integrations/jira/jira-client.js +0 -386
- package/dist/integrations/jira/jira-client.js.map +0 -1
- package/dist/integrations/jira/jira-incremental-mapper.d.ts +0 -75
- package/dist/integrations/jira/jira-incremental-mapper.d.ts.map +0 -1
- package/dist/integrations/jira/jira-incremental-mapper.js +0 -474
- package/dist/integrations/jira/jira-incremental-mapper.js.map +0 -1
- package/dist/integrations/jira/jira-mapper.d.ts +0 -105
- package/dist/integrations/jira/jira-mapper.d.ts.map +0 -1
- package/dist/integrations/jira/jira-mapper.js +0 -494
- package/dist/integrations/jira/jira-mapper.js.map +0 -1
- package/dist/metrics/calculators/change-failure-rate.d.ts +0 -22
- package/dist/metrics/calculators/change-failure-rate.d.ts.map +0 -1
- package/dist/metrics/calculators/change-failure-rate.js +0 -70
- package/dist/metrics/calculators/change-failure-rate.js.map +0 -1
- package/dist/metrics/calculators/deployment-frequency.d.ts +0 -20
- package/dist/metrics/calculators/deployment-frequency.d.ts.map +0 -1
- package/dist/metrics/calculators/deployment-frequency.js +0 -61
- package/dist/metrics/calculators/deployment-frequency.js.map +0 -1
- package/dist/metrics/calculators/lead-time.d.ts +0 -22
- package/dist/metrics/calculators/lead-time.d.ts.map +0 -1
- package/dist/metrics/calculators/lead-time.js +0 -82
- package/dist/metrics/calculators/lead-time.js.map +0 -1
- package/dist/metrics/calculators/mttr.d.ts +0 -21
- package/dist/metrics/calculators/mttr.d.ts.map +0 -1
- package/dist/metrics/calculators/mttr.js +0 -60
- package/dist/metrics/calculators/mttr.js.map +0 -1
- package/dist/metrics/dora-calculator.d.ts +0 -28
- package/dist/metrics/dora-calculator.d.ts.map +0 -1
- package/dist/metrics/dora-calculator.js +0 -117
- package/dist/metrics/dora-calculator.js.map +0 -1
- package/dist/metrics/github-client.d.ts +0 -51
- package/dist/metrics/github-client.d.ts.map +0 -1
- package/dist/metrics/github-client.js +0 -133
- package/dist/metrics/github-client.js.map +0 -1
- package/dist/metrics/report-generator.d.ts +0 -17
- package/dist/metrics/report-generator.d.ts.map +0 -1
- package/dist/metrics/report-generator.js +0 -403
- package/dist/metrics/report-generator.js.map +0 -1
- package/dist/metrics/types.d.ts +0 -112
- package/dist/metrics/types.d.ts.map +0 -1
- package/dist/metrics/types.js +0 -10
- package/dist/metrics/types.js.map +0 -1
- package/dist/metrics/utils/percentile.d.ts +0 -25
- package/dist/metrics/utils/percentile.d.ts.map +0 -1
- package/dist/metrics/utils/percentile.js +0 -46
- package/dist/metrics/utils/percentile.js.map +0 -1
- package/dist/metrics/utils/tier-classifier.d.ts +0 -61
- package/dist/metrics/utils/tier-classifier.d.ts.map +0 -1
- package/dist/metrics/utils/tier-classifier.js +0 -100
- package/dist/metrics/utils/tier-classifier.js.map +0 -1
- package/dist/plugins/specweave-ado/lib/ado-board-resolver.d.ts +0 -94
- package/dist/plugins/specweave-ado/lib/ado-board-resolver.d.ts.map +0 -1
- package/dist/plugins/specweave-ado/lib/ado-board-resolver.js +0 -219
- package/dist/plugins/specweave-ado/lib/ado-board-resolver.js.map +0 -1
- package/dist/plugins/specweave-ado/lib/ado-hierarchical-sync.d.ts +0 -40
- package/dist/plugins/specweave-ado/lib/ado-hierarchical-sync.d.ts.map +0 -1
- package/dist/plugins/specweave-ado/lib/ado-hierarchical-sync.js +0 -370
- package/dist/plugins/specweave-ado/lib/ado-hierarchical-sync.js.map +0 -1
- package/dist/plugins/specweave-ado/lib/ado-multi-project-sync.d.ts +0 -149
- package/dist/plugins/specweave-ado/lib/ado-multi-project-sync.d.ts.map +0 -1
- package/dist/plugins/specweave-ado/lib/ado-multi-project-sync.js +0 -517
- package/dist/plugins/specweave-ado/lib/ado-multi-project-sync.js.map +0 -1
- package/dist/plugins/specweave-ado/lib/ado-project-detector.d.ts +0 -72
- package/dist/plugins/specweave-ado/lib/ado-project-detector.d.ts.map +0 -1
- package/dist/plugins/specweave-ado/lib/ado-project-detector.js +0 -416
- package/dist/plugins/specweave-ado/lib/ado-project-detector.js.map +0 -1
- package/dist/plugins/specweave-ado/lib/conflict-resolver.d.ts +0 -99
- package/dist/plugins/specweave-ado/lib/conflict-resolver.d.ts.map +0 -1
- package/dist/plugins/specweave-ado/lib/conflict-resolver.js +0 -331
- package/dist/plugins/specweave-ado/lib/conflict-resolver.js.map +0 -1
- package/dist/plugins/specweave-ado/lib/project-selector.d.ts +0 -42
- package/dist/plugins/specweave-ado/lib/project-selector.d.ts.map +0 -1
- package/dist/plugins/specweave-ado/lib/project-selector.js +0 -211
- package/dist/plugins/specweave-ado/lib/project-selector.js.map +0 -1
- package/dist/plugins/specweave-github/lib/github-board-resolver.d.ts +0 -54
- package/dist/plugins/specweave-github/lib/github-board-resolver.d.ts.map +0 -1
- package/dist/plugins/specweave-github/lib/github-board-resolver.js +0 -122
- package/dist/plugins/specweave-github/lib/github-board-resolver.js.map +0 -1
- package/dist/plugins/specweave-github/lib/github-hierarchical-sync.d.ts +0 -29
- package/dist/plugins/specweave-github/lib/github-hierarchical-sync.d.ts.map +0 -1
- package/dist/plugins/specweave-github/lib/github-hierarchical-sync.js +0 -268
- package/dist/plugins/specweave-github/lib/github-hierarchical-sync.js.map +0 -1
- package/dist/plugins/specweave-github/lib/github-multi-project-sync.d.ts +0 -126
- package/dist/plugins/specweave-github/lib/github-multi-project-sync.d.ts.map +0 -1
- package/dist/plugins/specweave-github/lib/github-multi-project-sync.js +0 -420
- package/dist/plugins/specweave-github/lib/github-multi-project-sync.js.map +0 -1
- package/dist/plugins/specweave-github/lib/repo-selector.d.ts +0 -49
- package/dist/plugins/specweave-github/lib/repo-selector.d.ts.map +0 -1
- package/dist/plugins/specweave-github/lib/repo-selector.js +0 -216
- package/dist/plugins/specweave-github/lib/repo-selector.js.map +0 -1
- package/dist/plugins/specweave-jira/lib/jira-board-resolver.d.ts +0 -50
- package/dist/plugins/specweave-jira/lib/jira-board-resolver.d.ts.map +0 -1
- package/dist/plugins/specweave-jira/lib/jira-board-resolver.js +0 -84
- package/dist/plugins/specweave-jira/lib/jira-board-resolver.js.map +0 -1
- package/dist/plugins/specweave-jira/lib/jira-hierarchical-sync.d.ts +0 -33
- package/dist/plugins/specweave-jira/lib/jira-hierarchical-sync.d.ts.map +0 -1
- package/dist/plugins/specweave-jira/lib/jira-hierarchical-sync.js +0 -206
- package/dist/plugins/specweave-jira/lib/jira-hierarchical-sync.js.map +0 -1
- package/dist/plugins/specweave-jira/lib/jira-multi-project-sync.d.ts +0 -95
- package/dist/plugins/specweave-jira/lib/jira-multi-project-sync.d.ts.map +0 -1
- package/dist/plugins/specweave-jira/lib/jira-multi-project-sync.js +0 -301
- package/dist/plugins/specweave-jira/lib/jira-multi-project-sync.js.map +0 -1
- package/dist/plugins/specweave-jira/lib/project-selector.d.ts +0 -42
- package/dist/plugins/specweave-jira/lib/project-selector.d.ts.map +0 -1
- package/dist/plugins/specweave-jira/lib/project-selector.js +0 -216
- package/dist/plugins/specweave-jira/lib/project-selector.js.map +0 -1
- package/dist/project-mapper.js +0 -272
- package/dist/scripts/split-spec-by-project.js +0 -105
- package/dist/spec-splitter.js +0 -283
- package/dist/src/core/agent-model-manager.d.ts +0 -52
- package/dist/src/core/agent-model-manager.d.ts.map +0 -1
- package/dist/src/core/agent-model-manager.js +0 -120
- package/dist/src/core/agent-model-manager.js.map +0 -1
- package/dist/src/core/model-selector.d.ts +0 -57
- package/dist/src/core/model-selector.d.ts.map +0 -1
- package/dist/src/core/model-selector.js +0 -115
- package/dist/src/core/model-selector.js.map +0 -1
- package/dist/src/core/phase-detector.d.ts +0 -62
- package/dist/src/core/phase-detector.d.ts.map +0 -1
- package/dist/src/core/phase-detector.js +0 -229
- package/dist/src/core/phase-detector.js.map +0 -1
- package/dist/src/hooks/lib/git-diff-analyzer.d.ts +0 -89
- package/dist/src/hooks/lib/git-diff-analyzer.d.ts.map +0 -1
- package/dist/src/hooks/lib/git-diff-analyzer.js +0 -226
- package/dist/src/hooks/lib/git-diff-analyzer.js.map +0 -1
- package/dist/src/hooks/lib/invoke-translator-skill.d.ts +0 -60
- package/dist/src/hooks/lib/invoke-translator-skill.d.ts.map +0 -1
- package/dist/src/hooks/lib/invoke-translator-skill.js +0 -201
- package/dist/src/hooks/lib/invoke-translator-skill.js.map +0 -1
- package/dist/src/hooks/lib/prepare-reflection-context.d.ts +0 -42
- package/dist/src/hooks/lib/prepare-reflection-context.d.ts.map +0 -1
- package/dist/src/hooks/lib/prepare-reflection-context.js +0 -123
- package/dist/src/hooks/lib/prepare-reflection-context.js.map +0 -1
- package/dist/src/hooks/lib/reflection-config-loader.d.ts +0 -45
- package/dist/src/hooks/lib/reflection-config-loader.d.ts.map +0 -1
- package/dist/src/hooks/lib/reflection-config-loader.js +0 -132
- package/dist/src/hooks/lib/reflection-config-loader.js.map +0 -1
- package/dist/src/hooks/lib/reflection-parser.d.ts +0 -33
- package/dist/src/hooks/lib/reflection-parser.d.ts.map +0 -1
- package/dist/src/hooks/lib/reflection-parser.js +0 -419
- package/dist/src/hooks/lib/reflection-parser.js.map +0 -1
- package/dist/src/hooks/lib/reflection-prompt-builder.d.ts +0 -56
- package/dist/src/hooks/lib/reflection-prompt-builder.d.ts.map +0 -1
- package/dist/src/hooks/lib/reflection-prompt-builder.js +0 -239
- package/dist/src/hooks/lib/reflection-prompt-builder.js.map +0 -1
- package/dist/src/hooks/lib/reflection-storage.d.ts +0 -64
- package/dist/src/hooks/lib/reflection-storage.d.ts.map +0 -1
- package/dist/src/hooks/lib/reflection-storage.js +0 -305
- package/dist/src/hooks/lib/reflection-storage.js.map +0 -1
- package/dist/src/hooks/lib/run-self-reflection.d.ts +0 -43
- package/dist/src/hooks/lib/run-self-reflection.d.ts.map +0 -1
- package/dist/src/hooks/lib/run-self-reflection.js +0 -203
- package/dist/src/hooks/lib/run-self-reflection.js.map +0 -1
- package/dist/src/hooks/lib/sync-living-docs.d.ts +0 -27
- package/dist/src/hooks/lib/sync-living-docs.d.ts.map +0 -1
- package/dist/src/hooks/lib/sync-living-docs.js +0 -116
- package/dist/src/hooks/lib/sync-living-docs.js.map +0 -1
- package/dist/src/hooks/lib/translate-file.d.ts +0 -59
- package/dist/src/hooks/lib/translate-file.d.ts.map +0 -1
- package/dist/src/hooks/lib/translate-file.js +0 -350
- package/dist/src/hooks/lib/translate-file.js.map +0 -1
- package/dist/src/hooks/lib/translate-living-docs.d.ts +0 -13
- package/dist/src/hooks/lib/translate-living-docs.d.ts.map +0 -1
- package/dist/src/hooks/lib/translate-living-docs.js +0 -175
- package/dist/src/hooks/lib/translate-living-docs.js.map +0 -1
- package/dist/src/hooks/lib/types/reflection-types.d.ts +0 -164
- package/dist/src/hooks/lib/types/reflection-types.d.ts.map +0 -1
- package/dist/src/hooks/lib/types/reflection-types.js +0 -73
- package/dist/src/hooks/lib/types/reflection-types.js.map +0 -1
- package/dist/src/hooks/lib/update-tasks-md.d.ts +0 -29
- package/dist/src/hooks/lib/update-tasks-md.d.ts.map +0 -1
- package/dist/src/hooks/lib/update-tasks-md.js +0 -203
- package/dist/src/hooks/lib/update-tasks-md.js.map +0 -1
- package/dist/testing/test-generator.d.ts +0 -117
- package/dist/testing/test-generator.d.ts.map +0 -1
- package/dist/testing/test-generator.js +0 -370
- package/dist/testing/test-generator.js.map +0 -1
- package/dist/types/cost-tracking.d.ts +0 -43
- package/dist/types/cost-tracking.d.ts.map +0 -1
- package/dist/types/cost-tracking.js +0 -8
- package/dist/types/cost-tracking.js.map +0 -1
- package/dist/types/model-selection.d.ts +0 -53
- package/dist/types/model-selection.d.ts.map +0 -1
- package/dist/types/model-selection.js +0 -12
- package/dist/types/model-selection.js.map +0 -1
- package/dist/utils/agents-md-compiler.d.ts +0 -68
- package/dist/utils/agents-md-compiler.d.ts.map +0 -1
- package/dist/utils/agents-md-compiler.js +0 -420
- package/dist/utils/agents-md-compiler.js.map +0 -1
- package/dist/utils/auth-helpers.d.ts +0 -58
- package/dist/utils/auth-helpers.d.ts.map +0 -1
- package/dist/utils/auth-helpers.js +0 -108
- package/dist/utils/auth-helpers.js.map +0 -1
- package/dist/utils/auto-install.d.ts +0 -47
- package/dist/utils/auto-install.d.ts.map +0 -1
- package/dist/utils/auto-install.js +0 -211
- package/dist/utils/auto-install.js.map +0 -1
- package/dist/utils/claude-cli-detector.d.ts +0 -75
- package/dist/utils/claude-cli-detector.d.ts.map +0 -1
- package/dist/utils/claude-cli-detector.js +0 -285
- package/dist/utils/claude-cli-detector.js.map +0 -1
- package/dist/utils/cost-reporter.d.ts +0 -58
- package/dist/utils/cost-reporter.d.ts.map +0 -1
- package/dist/utils/cost-reporter.js +0 -224
- package/dist/utils/cost-reporter.js.map +0 -1
- package/dist/utils/docs-preview/config-generator.d.ts +0 -46
- package/dist/utils/docs-preview/config-generator.d.ts.map +0 -1
- package/dist/utils/docs-preview/config-generator.js +0 -377
- package/dist/utils/docs-preview/config-generator.js.map +0 -1
- package/dist/utils/docs-preview/docusaurus-setup.d.ts +0 -38
- package/dist/utils/docs-preview/docusaurus-setup.d.ts.map +0 -1
- package/dist/utils/docs-preview/docusaurus-setup.js +0 -177
- package/dist/utils/docs-preview/docusaurus-setup.js.map +0 -1
- package/dist/utils/docs-preview/index.d.ts +0 -7
- package/dist/utils/docs-preview/index.d.ts.map +0 -1
- package/dist/utils/docs-preview/index.js +0 -7
- package/dist/utils/docs-preview/index.js.map +0 -1
- package/dist/utils/docs-preview/package-installer.d.ts +0 -42
- package/dist/utils/docs-preview/package-installer.d.ts.map +0 -1
- package/dist/utils/docs-preview/package-installer.js +0 -182
- package/dist/utils/docs-preview/package-installer.js.map +0 -1
- package/dist/utils/docs-preview/server-manager.d.ts +0 -30
- package/dist/utils/docs-preview/server-manager.d.ts.map +0 -1
- package/dist/utils/docs-preview/server-manager.js +0 -212
- package/dist/utils/docs-preview/server-manager.js.map +0 -1
- package/dist/utils/docs-preview/sidebar-builder.d.ts +0 -32
- package/dist/utils/docs-preview/sidebar-builder.d.ts.map +0 -1
- package/dist/utils/docs-preview/sidebar-builder.js +0 -202
- package/dist/utils/docs-preview/sidebar-builder.js.map +0 -1
- package/dist/utils/docs-preview/types.d.ts +0 -57
- package/dist/utils/docs-preview/types.d.ts.map +0 -1
- package/dist/utils/docs-preview/types.js +0 -2
- package/dist/utils/docs-preview/types.js.map +0 -1
- package/dist/utils/env-file.d.ts +0 -88
- package/dist/utils/env-file.d.ts.map +0 -1
- package/dist/utils/env-file.js +0 -180
- package/dist/utils/env-file.js.map +0 -1
- package/dist/utils/env-multi-project-parser.d.ts +0 -220
- package/dist/utils/env-multi-project-parser.d.ts.map +0 -1
- package/dist/utils/env-multi-project-parser.js +0 -401
- package/dist/utils/env-multi-project-parser.js.map +0 -1
- package/dist/utils/esm-helpers.d.ts +0 -50
- package/dist/utils/esm-helpers.d.ts.map +0 -1
- package/dist/utils/esm-helpers.js +0 -57
- package/dist/utils/esm-helpers.js.map +0 -1
- package/dist/utils/execFileNoThrow.d.ts +0 -99
- package/dist/utils/execFileNoThrow.d.ts.map +0 -1
- package/dist/utils/execFileNoThrow.js +0 -137
- package/dist/utils/execFileNoThrow.js.map +0 -1
- package/dist/utils/external-resource-validator.d.ts +0 -102
- package/dist/utils/external-resource-validator.d.ts.map +0 -1
- package/dist/utils/external-resource-validator.js +0 -504
- package/dist/utils/external-resource-validator.js.map +0 -1
- package/dist/utils/generate-skills-index.d.ts +0 -24
- package/dist/utils/generate-skills-index.d.ts.map +0 -1
- package/dist/utils/generate-skills-index.js +0 -410
- package/dist/utils/generate-skills-index.js.map +0 -1
- package/dist/utils/git-detector.d.ts +0 -84
- package/dist/utils/git-detector.d.ts.map +0 -1
- package/dist/utils/git-detector.js +0 -233
- package/dist/utils/git-detector.js.map +0 -1
- package/dist/utils/git-utils.d.ts +0 -74
- package/dist/utils/git-utils.d.ts.map +0 -1
- package/dist/utils/git-utils.js +0 -272
- package/dist/utils/git-utils.js.map +0 -1
- package/dist/utils/model-selection.d.ts +0 -75
- package/dist/utils/model-selection.d.ts.map +0 -1
- package/dist/utils/model-selection.js +0 -204
- package/dist/utils/model-selection.js.map +0 -1
- package/dist/utils/plugin-validator.d.ts +0 -161
- package/dist/utils/plugin-validator.d.ts.map +0 -1
- package/dist/utils/plugin-validator.js +0 -558
- package/dist/utils/plugin-validator.js.map +0 -1
- package/dist/utils/pricing-constants.d.ts +0 -70
- package/dist/utils/pricing-constants.d.ts.map +0 -1
- package/dist/utils/pricing-constants.js +0 -71
- package/dist/utils/pricing-constants.js.map +0 -1
- package/dist/utils/project-detection.d.ts +0 -141
- package/dist/utils/project-detection.d.ts.map +0 -1
- package/dist/utils/project-detection.js +0 -321
- package/dist/utils/project-detection.js.map +0 -1
- package/dist/utils/project-mapper.d.ts +0 -92
- package/dist/utils/project-mapper.d.ts.map +0 -1
- package/dist/utils/project-mapper.js +0 -276
- package/dist/utils/project-mapper.js.map +0 -1
- package/dist/utils/spec-splitter.d.ts +0 -75
- package/dist/utils/spec-splitter.d.ts.map +0 -1
- package/dist/utils/spec-splitter.js +0 -332
- package/dist/utils/spec-splitter.js.map +0 -1
- package/dist/utils/string-utils.d.ts +0 -40
- package/dist/utils/string-utils.d.ts.map +0 -1
- package/dist/utils/string-utils.js +0 -58
- package/dist/utils/string-utils.js.map +0 -1
- package/dist/utils/translation.d.ts +0 -187
- package/dist/utils/translation.d.ts.map +0 -1
- package/dist/utils/translation.js +0 -414
- package/dist/utils/translation.js.map +0 -1
- /package/dist/{locales → src/locales}/de/.gitkeep +0 -0
- /package/dist/{locales → src/locales}/de/cli.json +0 -0
- /package/dist/{locales → src/locales}/en/cli.json +0 -0
- /package/dist/{locales → src/locales}/en/errors.json +0 -0
- /package/dist/{locales → src/locales}/en/templates.json +0 -0
- /package/dist/{locales → src/locales}/es/.gitkeep +0 -0
- /package/dist/{locales → src/locales}/es/cli.json +0 -0
- /package/dist/{locales → src/locales}/fr/.gitkeep +0 -0
- /package/dist/{locales → src/locales}/fr/cli.json +0 -0
- /package/dist/{locales → src/locales}/ja/.gitkeep +0 -0
- /package/dist/{locales → src/locales}/ja/cli.json +0 -0
- /package/dist/{locales → src/locales}/ko/.gitkeep +0 -0
- /package/dist/{locales → src/locales}/ko/cli.json +0 -0
- /package/dist/{locales → src/locales}/pt/.gitkeep +0 -0
- /package/dist/{locales → src/locales}/pt/cli.json +0 -0
- /package/dist/{locales → src/locales}/ru/.gitkeep +0 -0
- /package/dist/{locales → src/locales}/ru/cli.json +0 -0
- /package/dist/{locales → src/locales}/zh/.gitkeep +0 -0
- /package/dist/{locales → src/locales}/zh/cli.json +0 -0
|
@@ -1,165 +1,246 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
1
|
+
import { SpecMetadataManager } from "../../../src/core/specs/spec-metadata-manager.js";
|
|
2
|
+
import { SpecParser } from "../../../src/core/specs/spec-parser.js";
|
|
3
|
+
import { execFileNoThrow } from "../../../src/utils/execFileNoThrow.js";
|
|
4
|
+
import { ProjectContextManager } from "../../../src/core/sync/project-context.js";
|
|
5
|
+
class GitHubSpecSync {
|
|
6
|
+
constructor(projectRoot = process.cwd()) {
|
|
7
|
+
this.projectRoot = projectRoot;
|
|
8
|
+
this.specManager = new SpecMetadataManager(projectRoot);
|
|
9
|
+
this.projectContextManager = new ProjectContextManager(projectRoot);
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Detect project from spec file path
|
|
13
|
+
*
|
|
14
|
+
* Spec path format: .specweave/docs/internal/specs/{project-id}/spec-*.md
|
|
15
|
+
* OR (single project): .specweave/docs/internal/specs/spec-*.md
|
|
16
|
+
*/
|
|
17
|
+
async detectProjectFromSpecPath(specFilePath) {
|
|
18
|
+
const specPathMatch = specFilePath.match(/\.specweave\/docs\/internal\/specs\/([^/]+)\//);
|
|
19
|
+
if (specPathMatch) {
|
|
20
|
+
const projectId = specPathMatch[1];
|
|
21
|
+
const project = await this.projectContextManager.getProject(projectId);
|
|
22
|
+
return project ? projectId : null;
|
|
21
23
|
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
success: false,
|
|
33
|
-
specId,
|
|
34
|
-
provider: 'github',
|
|
35
|
-
error: `Spec ${specId} not found`
|
|
36
|
-
};
|
|
37
|
-
}
|
|
38
|
-
// 2. Detect repository
|
|
39
|
-
const repoInfo = await this.detectRepo();
|
|
40
|
-
if (!repoInfo) {
|
|
41
|
-
return {
|
|
42
|
-
success: false,
|
|
43
|
-
specId,
|
|
44
|
-
provider: 'github',
|
|
45
|
-
error: 'Could not detect GitHub repository'
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
|
-
const { owner, repo } = repoInfo;
|
|
49
|
-
// 3. Check if spec already linked to GitHub Project
|
|
50
|
-
const existingLink = spec.metadata.externalLinks?.github;
|
|
51
|
-
let project;
|
|
52
|
-
if (existingLink?.projectId) {
|
|
53
|
-
// UPDATE existing project
|
|
54
|
-
console.log(` Found existing GitHub Project #${existingLink.projectId}`);
|
|
55
|
-
project = await this.updateGitHubProject(owner, repo, existingLink.projectId, spec);
|
|
56
|
-
}
|
|
57
|
-
else {
|
|
58
|
-
// CREATE new project
|
|
59
|
-
console.log(' Creating new GitHub Project...');
|
|
60
|
-
project = await this.createGitHubProject(owner, repo, spec);
|
|
61
|
-
// Link spec to project
|
|
62
|
-
await this.specManager.linkToExternal(specId, 'github', {
|
|
63
|
-
id: project.id,
|
|
64
|
-
url: project.url,
|
|
65
|
-
owner,
|
|
66
|
-
repo
|
|
67
|
-
});
|
|
68
|
-
}
|
|
69
|
-
// 4. Sync user stories as issues/cards
|
|
70
|
-
const changes = await this.syncUserStories(owner, repo, project.number, spec);
|
|
71
|
-
console.log('✅ Sync complete!');
|
|
72
|
-
return {
|
|
73
|
-
success: true,
|
|
74
|
-
specId,
|
|
75
|
-
provider: 'github',
|
|
76
|
-
externalId: project.id.toString(),
|
|
77
|
-
url: project.url,
|
|
78
|
-
changes
|
|
79
|
-
};
|
|
80
|
-
}
|
|
81
|
-
catch (error) {
|
|
82
|
-
console.error('❌ Error syncing to GitHub:', error);
|
|
83
|
-
return {
|
|
84
|
-
success: false,
|
|
85
|
-
specId,
|
|
86
|
-
provider: 'github',
|
|
87
|
-
error: error instanceof Error ? error.message : 'Unknown error'
|
|
88
|
-
};
|
|
89
|
-
}
|
|
24
|
+
return "default";
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Get GitHub configuration for a project
|
|
28
|
+
*/
|
|
29
|
+
async getGitHubConfigForProject(projectId) {
|
|
30
|
+
const config = await this.projectContextManager.load();
|
|
31
|
+
const project = await this.projectContextManager.getProject(projectId);
|
|
32
|
+
if (!project) {
|
|
33
|
+
return null;
|
|
90
34
|
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
specId,
|
|
150
|
-
provider: 'github',
|
|
151
|
-
error: error instanceof Error ? error.message : 'Unknown error'
|
|
152
|
-
};
|
|
35
|
+
const profileId = project.defaultSyncProfile || config.activeProfile;
|
|
36
|
+
if (!profileId) {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
const profile = config.profiles?.[profileId];
|
|
40
|
+
if (!profile || profile.provider !== "github") {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
const githubConfig = profile.config;
|
|
44
|
+
return {
|
|
45
|
+
projectId,
|
|
46
|
+
strategy: githubConfig.githubStrategy || "project-per-spec",
|
|
47
|
+
owner: githubConfig.owner || "",
|
|
48
|
+
repo: githubConfig.repo || githubConfig.repos && githubConfig.repos[0] || "",
|
|
49
|
+
teamBoardId: githubConfig.teamBoardId
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Sync spec to GitHub Project (CREATE or UPDATE)
|
|
54
|
+
*
|
|
55
|
+
* MULTI-PROJECT ARCHITECTURE:
|
|
56
|
+
* - Detects which project the spec belongs to
|
|
57
|
+
* - Routes to correct GitHub repo based on project config
|
|
58
|
+
* - Supports multiple sync strategies
|
|
59
|
+
*/
|
|
60
|
+
async syncSpecToGitHub(specId) {
|
|
61
|
+
console.log(`
|
|
62
|
+
\u{1F504} Syncing spec ${specId} to GitHub Project...`);
|
|
63
|
+
try {
|
|
64
|
+
const spec = await this.specManager.loadSpec(specId);
|
|
65
|
+
if (!spec) {
|
|
66
|
+
return {
|
|
67
|
+
success: false,
|
|
68
|
+
specId,
|
|
69
|
+
provider: "github",
|
|
70
|
+
error: `Spec ${specId} not found`
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
const projectId = await this.detectProjectFromSpecPath(spec.filePath);
|
|
74
|
+
if (!projectId) {
|
|
75
|
+
return {
|
|
76
|
+
success: false,
|
|
77
|
+
specId,
|
|
78
|
+
provider: "github",
|
|
79
|
+
error: "Could not determine project for spec"
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
console.log(` \u{1F4E6} Detected project: ${projectId}`);
|
|
83
|
+
const githubConfig = await this.getGitHubConfigForProject(projectId);
|
|
84
|
+
if (!githubConfig) {
|
|
85
|
+
const repoInfo = await this.detectRepo();
|
|
86
|
+
if (!repoInfo) {
|
|
87
|
+
return {
|
|
88
|
+
success: false,
|
|
89
|
+
specId,
|
|
90
|
+
provider: "github",
|
|
91
|
+
error: `No GitHub configuration found for project '${projectId}'`
|
|
92
|
+
};
|
|
153
93
|
}
|
|
94
|
+
githubConfig.owner = repoInfo.owner;
|
|
95
|
+
githubConfig.repo = repoInfo.repo;
|
|
96
|
+
githubConfig.strategy = "project-per-spec";
|
|
97
|
+
}
|
|
98
|
+
console.log(` \u{1F3AF} Strategy: ${githubConfig.strategy}`);
|
|
99
|
+
console.log(` \u{1F517} Repository: ${githubConfig.owner}/${githubConfig.repo}`);
|
|
100
|
+
const { owner, repo, strategy } = githubConfig;
|
|
101
|
+
return await this.syncWithStrategy(spec, owner, repo, strategy, githubConfig);
|
|
102
|
+
} catch (error) {
|
|
103
|
+
console.error("\u274C Error syncing to GitHub:", error);
|
|
104
|
+
return {
|
|
105
|
+
success: false,
|
|
106
|
+
specId,
|
|
107
|
+
provider: "github",
|
|
108
|
+
error: error instanceof Error ? error.message : "Unknown error"
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Sync spec using specified strategy
|
|
114
|
+
*/
|
|
115
|
+
async syncWithStrategy(spec, owner, repo, strategy, config) {
|
|
116
|
+
const specId = spec.metadata.id;
|
|
117
|
+
switch (strategy) {
|
|
118
|
+
case "project-per-spec":
|
|
119
|
+
return await this.syncProjectPerSpec(spec, owner, repo);
|
|
120
|
+
case "team-board":
|
|
121
|
+
return await this.syncTeamBoard(spec, owner, repo, config.teamBoardId);
|
|
122
|
+
case "centralized":
|
|
123
|
+
return await this.syncCentralized(spec, owner, repo);
|
|
124
|
+
case "distributed":
|
|
125
|
+
return await this.syncDistributed(spec, config);
|
|
126
|
+
default:
|
|
127
|
+
return await this.syncProjectPerSpec(spec, owner, repo);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Strategy 1: Project-per-Spec (DEFAULT)
|
|
132
|
+
* - One GitHub Project per spec
|
|
133
|
+
* - Current behavior, no changes needed
|
|
134
|
+
*/
|
|
135
|
+
async syncProjectPerSpec(spec, owner, repo) {
|
|
136
|
+
const specId = spec.metadata.id;
|
|
137
|
+
try {
|
|
138
|
+
const existingLink = spec.metadata.externalLinks?.github;
|
|
139
|
+
let project;
|
|
140
|
+
if (existingLink?.projectId) {
|
|
141
|
+
console.log(` Found existing GitHub Project #${existingLink.projectId}`);
|
|
142
|
+
project = await this.updateGitHubProject(
|
|
143
|
+
owner,
|
|
144
|
+
repo,
|
|
145
|
+
existingLink.projectId,
|
|
146
|
+
spec
|
|
147
|
+
);
|
|
148
|
+
} else {
|
|
149
|
+
console.log(" Creating new GitHub Project...");
|
|
150
|
+
project = await this.createGitHubProject(owner, repo, spec);
|
|
151
|
+
await this.specManager.linkToExternal(specId, "github", {
|
|
152
|
+
id: project.id,
|
|
153
|
+
url: project.url,
|
|
154
|
+
owner,
|
|
155
|
+
repo
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
const changes = await this.syncUserStories(owner, repo, project.number, spec);
|
|
159
|
+
console.log("\u2705 Sync complete!");
|
|
160
|
+
return {
|
|
161
|
+
success: true,
|
|
162
|
+
specId,
|
|
163
|
+
provider: "github",
|
|
164
|
+
externalId: project.id.toString(),
|
|
165
|
+
url: project.url,
|
|
166
|
+
changes
|
|
167
|
+
};
|
|
168
|
+
} catch (error) {
|
|
169
|
+
console.error("\u274C Error syncing to GitHub:", error);
|
|
170
|
+
return {
|
|
171
|
+
success: false,
|
|
172
|
+
specId,
|
|
173
|
+
provider: "github",
|
|
174
|
+
error: error instanceof Error ? error.message : "Unknown error"
|
|
175
|
+
};
|
|
154
176
|
}
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Sync FROM GitHub Project to spec (bidirectional)
|
|
180
|
+
*/
|
|
181
|
+
async syncFromGitHub(specId) {
|
|
182
|
+
console.log(`
|
|
183
|
+
\u{1F504} Syncing FROM GitHub to spec ${specId}...`);
|
|
184
|
+
try {
|
|
185
|
+
const spec = await this.specManager.loadSpec(specId);
|
|
186
|
+
if (!spec) {
|
|
187
|
+
return {
|
|
188
|
+
success: false,
|
|
189
|
+
specId,
|
|
190
|
+
provider: "github",
|
|
191
|
+
error: `Spec ${specId} not found`
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
const githubLink = spec.metadata.externalLinks?.github;
|
|
195
|
+
if (!githubLink?.projectId) {
|
|
196
|
+
return {
|
|
197
|
+
success: false,
|
|
198
|
+
specId,
|
|
199
|
+
provider: "github",
|
|
200
|
+
error: "Spec not linked to GitHub Project"
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
const { owner, repo } = await this.detectRepo() || { owner: "", repo: "" };
|
|
204
|
+
const project = await this.fetchGitHubProject(owner, repo, githubLink.projectId);
|
|
205
|
+
const conflicts = await this.detectConflicts(spec, project);
|
|
206
|
+
if (conflicts.length === 0) {
|
|
207
|
+
console.log("\u2705 No conflicts - spec and GitHub in sync");
|
|
208
|
+
return {
|
|
209
|
+
success: true,
|
|
210
|
+
specId,
|
|
211
|
+
provider: "github",
|
|
212
|
+
externalId: project.id.toString(),
|
|
213
|
+
url: project.url
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
console.log(`\u26A0\uFE0F Detected ${conflicts.length} conflict(s)`);
|
|
217
|
+
await this.resolveConflicts(spec, conflicts);
|
|
218
|
+
console.log("\u2705 Sync FROM GitHub complete!");
|
|
219
|
+
return {
|
|
220
|
+
success: true,
|
|
221
|
+
specId,
|
|
222
|
+
provider: "github",
|
|
223
|
+
externalId: project.id.toString(),
|
|
224
|
+
url: project.url,
|
|
225
|
+
conflicts
|
|
226
|
+
};
|
|
227
|
+
} catch (error) {
|
|
228
|
+
console.error("\u274C Error syncing FROM GitHub:", error);
|
|
229
|
+
return {
|
|
230
|
+
success: false,
|
|
231
|
+
specId,
|
|
232
|
+
provider: "github",
|
|
233
|
+
error: error instanceof Error ? error.message : "Unknown error"
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Create new GitHub Project for spec
|
|
239
|
+
*/
|
|
240
|
+
async createGitHubProject(owner, repo, spec) {
|
|
241
|
+
const projectTitle = `[${spec.metadata.id.toUpperCase()}] ${spec.metadata.title}`;
|
|
242
|
+
const projectBody = this.generateProjectDescription(spec);
|
|
243
|
+
const query = `
|
|
163
244
|
mutation CreateProject($ownerId: ID!, $title: String!, $body: String!) {
|
|
164
245
|
createProjectV2(input: {
|
|
165
246
|
ownerId: $ownerId,
|
|
@@ -175,33 +256,31 @@ export class GitHubSpecSync {
|
|
|
175
256
|
}
|
|
176
257
|
}
|
|
177
258
|
`;
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
// Use GraphQL to update project
|
|
204
|
-
const query = `
|
|
259
|
+
const ownerId = await this.getOwnerId(owner);
|
|
260
|
+
const result = await this.executeGraphQL(query, {
|
|
261
|
+
ownerId,
|
|
262
|
+
title: projectTitle,
|
|
263
|
+
body: projectBody
|
|
264
|
+
});
|
|
265
|
+
const project = result.data.createProjectV2.projectV2;
|
|
266
|
+
console.log(` \u2705 Created GitHub Project #${project.number}: ${project.url}`);
|
|
267
|
+
return {
|
|
268
|
+
id: parseInt(project.id, 10),
|
|
269
|
+
title: project.title,
|
|
270
|
+
number: project.number,
|
|
271
|
+
url: project.url,
|
|
272
|
+
state: "open",
|
|
273
|
+
owner,
|
|
274
|
+
repo
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Update existing GitHub Project
|
|
279
|
+
*/
|
|
280
|
+
async updateGitHubProject(owner, repo, projectId, spec) {
|
|
281
|
+
const projectTitle = `[${spec.metadata.id.toUpperCase()}] ${spec.metadata.title}`;
|
|
282
|
+
const projectBody = this.generateProjectDescription(spec);
|
|
283
|
+
const query = `
|
|
205
284
|
mutation UpdateProject($projectId: ID!, $title: String, $body: String) {
|
|
206
285
|
updateProjectV2(input: {
|
|
207
286
|
projectId: $projectId,
|
|
@@ -217,73 +296,30 @@ export class GitHubSpecSync {
|
|
|
217
296
|
}
|
|
218
297
|
}
|
|
219
298
|
`;
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
if (!spec.metadata.userStories || spec.metadata.userStories.length === 0) {
|
|
245
|
-
console.log(' ℹ️ No user stories to sync');
|
|
246
|
-
return { created, updated, deleted };
|
|
247
|
-
}
|
|
248
|
-
console.log(` Syncing ${spec.metadata.userStories.length} user stories...`);
|
|
249
|
-
for (const us of spec.metadata.userStories) {
|
|
250
|
-
// Create or update issue for each user story
|
|
251
|
-
const issueTitle = `[${us.id}] ${us.title}`;
|
|
252
|
-
const issueBody = this.generateIssueBody(us);
|
|
253
|
-
// Check if issue already exists (by title pattern)
|
|
254
|
-
const existingIssue = await this.findIssueByTitle(owner, repo, us.id);
|
|
255
|
-
if (existingIssue) {
|
|
256
|
-
// UPDATE existing issue
|
|
257
|
-
await this.updateIssue(owner, repo, existingIssue.number, {
|
|
258
|
-
title: issueTitle,
|
|
259
|
-
body: issueBody,
|
|
260
|
-
state: us.status === 'done' ? 'closed' : 'open'
|
|
261
|
-
});
|
|
262
|
-
updated.push(us.id);
|
|
263
|
-
console.log(` ✅ Updated ${us.id}`);
|
|
264
|
-
}
|
|
265
|
-
else {
|
|
266
|
-
// CREATE new issue
|
|
267
|
-
const newIssue = await this.createIssue(owner, repo, {
|
|
268
|
-
title: issueTitle,
|
|
269
|
-
body: issueBody,
|
|
270
|
-
labels: ['user-story', `spec:${spec.metadata.id}`, `priority:${us.priority}`]
|
|
271
|
-
});
|
|
272
|
-
created.push(us.id);
|
|
273
|
-
console.log(` ✅ Created ${us.id} → Issue #${newIssue.number}`);
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
return { created, updated, deleted };
|
|
277
|
-
}
|
|
278
|
-
/**
|
|
279
|
-
* Generate project description from spec
|
|
280
|
-
*/
|
|
281
|
-
generateProjectDescription(spec) {
|
|
282
|
-
const progress = spec.metadata.progress;
|
|
283
|
-
const progressText = progress
|
|
284
|
-
? `**Progress**: ${progress.percentComplete}% (${progress.completedUserStories}/${progress.totalUserStories} user stories)`
|
|
285
|
-
: '**Progress**: N/A';
|
|
286
|
-
return `
|
|
299
|
+
const result = await this.executeGraphQL(query, {
|
|
300
|
+
projectId: projectId.toString(),
|
|
301
|
+
title: projectTitle,
|
|
302
|
+
body: projectBody
|
|
303
|
+
});
|
|
304
|
+
const project = result.data.updateProjectV2.projectV2;
|
|
305
|
+
console.log(` \u2705 Updated GitHub Project #${project.number}`);
|
|
306
|
+
return {
|
|
307
|
+
id: projectId,
|
|
308
|
+
title: project.title,
|
|
309
|
+
number: project.number,
|
|
310
|
+
url: project.url,
|
|
311
|
+
state: "open",
|
|
312
|
+
owner,
|
|
313
|
+
repo
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* Generate project description from spec
|
|
318
|
+
*/
|
|
319
|
+
generateProjectDescription(spec) {
|
|
320
|
+
const progress = spec.metadata.progress;
|
|
321
|
+
const progressText = progress ? `**Progress**: ${progress.percentComplete}% (${progress.completedUserStories}/${progress.totalUserStories} user stories)` : "**Progress**: N/A";
|
|
322
|
+
return `
|
|
287
323
|
# ${spec.metadata.title}
|
|
288
324
|
|
|
289
325
|
**Spec ID**: ${spec.metadata.id}
|
|
@@ -303,18 +339,16 @@ ${spec.metadata.userStories?.length || 0} user stories tracked in this project.
|
|
|
303
339
|
|
|
304
340
|
---
|
|
305
341
|
|
|
306
|
-
|
|
307
|
-
Last updated: ${new Date().toISOString()}
|
|
342
|
+
\u{1F916} **Auto-synced from SpecWeave**
|
|
343
|
+
Last updated: ${(/* @__PURE__ */ new Date()).toISOString()}
|
|
308
344
|
`.trim();
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
.join('\n');
|
|
317
|
-
return `
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* Generate issue body from user story
|
|
348
|
+
*/
|
|
349
|
+
generateIssueBody(us) {
|
|
350
|
+
const acList = us.acceptanceCriteria.map((ac) => `- [${ac.status === "done" ? "x" : " "}] ${ac.description}`).join("\n");
|
|
351
|
+
return `
|
|
318
352
|
## User Story
|
|
319
353
|
|
|
320
354
|
${us.title}
|
|
@@ -328,178 +362,468 @@ ${acList}
|
|
|
328
362
|
**Priority**: ${us.priority}
|
|
329
363
|
**Status**: ${us.status}
|
|
330
364
|
|
|
331
|
-
|
|
365
|
+
\u{1F916} **Auto-synced from SpecWeave**
|
|
332
366
|
`.trim();
|
|
367
|
+
}
|
|
368
|
+
/**
|
|
369
|
+
* Detect conflicts between spec and GitHub
|
|
370
|
+
*/
|
|
371
|
+
async detectConflicts(spec, project) {
|
|
372
|
+
const conflicts = [];
|
|
373
|
+
const expectedTitle = `[${spec.metadata.id.toUpperCase()}] ${spec.metadata.title}`;
|
|
374
|
+
if (project.title !== expectedTitle) {
|
|
375
|
+
conflicts.push({
|
|
376
|
+
type: "metadata",
|
|
377
|
+
field: "title",
|
|
378
|
+
localValue: spec.metadata.title,
|
|
379
|
+
remoteValue: project.title,
|
|
380
|
+
resolution: "remote-wins",
|
|
381
|
+
description: "Project title differs from spec title"
|
|
382
|
+
});
|
|
333
383
|
}
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
resolution: 'remote-wins',
|
|
348
|
-
description: 'Project title differs from spec title'
|
|
349
|
-
});
|
|
350
|
-
}
|
|
351
|
-
// TODO: Compare user stories and their statuses
|
|
352
|
-
return conflicts;
|
|
353
|
-
}
|
|
354
|
-
/**
|
|
355
|
-
* Resolve conflicts
|
|
356
|
-
*/
|
|
357
|
-
async resolveConflicts(spec, conflicts) {
|
|
358
|
-
for (const conflict of conflicts) {
|
|
359
|
-
if (conflict.resolution === 'remote-wins') {
|
|
360
|
-
console.log(` 🔄 Resolving: ${conflict.description} (GitHub wins)`);
|
|
361
|
-
// Update spec metadata from GitHub
|
|
362
|
-
if (conflict.field === 'title') {
|
|
363
|
-
await this.specManager.saveMetadata(spec.metadata.id, {
|
|
364
|
-
title: conflict.remoteValue
|
|
365
|
-
});
|
|
366
|
-
}
|
|
367
|
-
}
|
|
384
|
+
return conflicts;
|
|
385
|
+
}
|
|
386
|
+
/**
|
|
387
|
+
* Resolve conflicts
|
|
388
|
+
*/
|
|
389
|
+
async resolveConflicts(spec, conflicts) {
|
|
390
|
+
for (const conflict of conflicts) {
|
|
391
|
+
if (conflict.resolution === "remote-wins") {
|
|
392
|
+
console.log(` \u{1F504} Resolving: ${conflict.description} (GitHub wins)`);
|
|
393
|
+
if (conflict.field === "title") {
|
|
394
|
+
await this.specManager.saveMetadata(spec.metadata.id, {
|
|
395
|
+
title: conflict.remoteValue
|
|
396
|
+
});
|
|
368
397
|
}
|
|
398
|
+
}
|
|
369
399
|
}
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
return JSON.parse(result.stdout);
|
|
400
|
+
}
|
|
401
|
+
/**
|
|
402
|
+
* Execute GraphQL query against GitHub API
|
|
403
|
+
*/
|
|
404
|
+
async executeGraphQL(query, variables) {
|
|
405
|
+
const result = await execFileNoThrow("gh", [
|
|
406
|
+
"api",
|
|
407
|
+
"graphql",
|
|
408
|
+
"-f",
|
|
409
|
+
`query=${query}`,
|
|
410
|
+
...Object.entries(variables).flatMap(([key, value]) => ["-F", `${key}=${value}`])
|
|
411
|
+
]);
|
|
412
|
+
if (result.error) {
|
|
413
|
+
throw new Error(`GraphQL query failed: ${result.error}`);
|
|
385
414
|
}
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
415
|
+
return JSON.parse(result.stdout);
|
|
416
|
+
}
|
|
417
|
+
/**
|
|
418
|
+
* Get owner ID (user or organization)
|
|
419
|
+
*/
|
|
420
|
+
async getOwnerId(owner) {
|
|
421
|
+
const query = `
|
|
391
422
|
query GetOwner($login: String!) {
|
|
392
423
|
repositoryOwner(login: $login) {
|
|
393
424
|
id
|
|
394
425
|
}
|
|
395
426
|
}
|
|
396
427
|
`;
|
|
397
|
-
|
|
398
|
-
|
|
428
|
+
const result = await this.executeGraphQL(query, { login: owner });
|
|
429
|
+
return result.data.repositoryOwner.id;
|
|
430
|
+
}
|
|
431
|
+
/**
|
|
432
|
+
* Fetch GitHub Project details
|
|
433
|
+
*/
|
|
434
|
+
async fetchGitHubProject(owner, repo, projectId) {
|
|
435
|
+
return {
|
|
436
|
+
id: projectId,
|
|
437
|
+
title: "Project Title",
|
|
438
|
+
number: 1,
|
|
439
|
+
url: "https://github.com/...",
|
|
440
|
+
state: "open",
|
|
441
|
+
owner,
|
|
442
|
+
repo
|
|
443
|
+
};
|
|
444
|
+
}
|
|
445
|
+
/**
|
|
446
|
+
* Find issue by title pattern
|
|
447
|
+
*/
|
|
448
|
+
async findIssueByTitle(owner, repo, usId) {
|
|
449
|
+
const result = await execFileNoThrow("gh", [
|
|
450
|
+
"issue",
|
|
451
|
+
"list",
|
|
452
|
+
"--repo",
|
|
453
|
+
`${owner}/${repo}`,
|
|
454
|
+
"--search",
|
|
455
|
+
`"[${usId}]" in:title`,
|
|
456
|
+
"--json",
|
|
457
|
+
"number,title,body,state,labels",
|
|
458
|
+
"--limit",
|
|
459
|
+
"1"
|
|
460
|
+
]);
|
|
461
|
+
if (result.error || !result.stdout) {
|
|
462
|
+
return null;
|
|
399
463
|
}
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
464
|
+
const issues = JSON.parse(result.stdout);
|
|
465
|
+
return issues.length > 0 ? issues[0] : null;
|
|
466
|
+
}
|
|
467
|
+
/**
|
|
468
|
+
* Create GitHub issue
|
|
469
|
+
*/
|
|
470
|
+
async createIssue(owner, repo, issue) {
|
|
471
|
+
const result = await execFileNoThrow("gh", [
|
|
472
|
+
"issue",
|
|
473
|
+
"create",
|
|
474
|
+
"--repo",
|
|
475
|
+
`${owner}/${repo}`,
|
|
476
|
+
"--title",
|
|
477
|
+
issue.title,
|
|
478
|
+
"--body",
|
|
479
|
+
issue.body,
|
|
480
|
+
"--label",
|
|
481
|
+
issue.labels.join(","),
|
|
482
|
+
"--json",
|
|
483
|
+
"number,title,body,state"
|
|
484
|
+
]);
|
|
485
|
+
if (result.error) {
|
|
486
|
+
throw new Error(`Failed to create issue: ${result.error}`);
|
|
414
487
|
}
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
'--search',
|
|
425
|
-
`"[${usId}]" in:title`,
|
|
426
|
-
'--json',
|
|
427
|
-
'number,title,body,state,labels',
|
|
428
|
-
'--limit',
|
|
429
|
-
'1'
|
|
430
|
-
]);
|
|
431
|
-
if (result.error || !result.stdout) {
|
|
432
|
-
return null;
|
|
433
|
-
}
|
|
434
|
-
const issues = JSON.parse(result.stdout);
|
|
435
|
-
return issues.length > 0 ? issues[0] : null;
|
|
488
|
+
return JSON.parse(result.stdout);
|
|
489
|
+
}
|
|
490
|
+
/**
|
|
491
|
+
* Update GitHub issue
|
|
492
|
+
*/
|
|
493
|
+
async updateIssue(owner, repo, issueNumber, updates) {
|
|
494
|
+
const args = ["issue", "edit", issueNumber.toString(), "--repo", `${owner}/${repo}`];
|
|
495
|
+
if (updates.title) {
|
|
496
|
+
args.push("--title", updates.title);
|
|
436
497
|
}
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
*/
|
|
440
|
-
async createIssue(owner, repo, issue) {
|
|
441
|
-
const result = await execFileNoThrow('gh', [
|
|
442
|
-
'issue',
|
|
443
|
-
'create',
|
|
444
|
-
'--repo',
|
|
445
|
-
`${owner}/${repo}`,
|
|
446
|
-
'--title',
|
|
447
|
-
issue.title,
|
|
448
|
-
'--body',
|
|
449
|
-
issue.body,
|
|
450
|
-
'--label',
|
|
451
|
-
issue.labels.join(','),
|
|
452
|
-
'--json',
|
|
453
|
-
'number,title,body,state'
|
|
454
|
-
]);
|
|
455
|
-
if (result.error) {
|
|
456
|
-
throw new Error(`Failed to create issue: ${result.error}`);
|
|
457
|
-
}
|
|
458
|
-
return JSON.parse(result.stdout);
|
|
498
|
+
if (updates.body) {
|
|
499
|
+
args.push("--body", updates.body);
|
|
459
500
|
}
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
501
|
+
if (updates.state === "closed") {
|
|
502
|
+
args.push("--state", "closed");
|
|
503
|
+
} else if (updates.state === "open") {
|
|
504
|
+
args.push("--state", "open");
|
|
505
|
+
}
|
|
506
|
+
const result = await execFileNoThrow("gh", args);
|
|
507
|
+
if (result.error) {
|
|
508
|
+
throw new Error(`Failed to update issue #${issueNumber}: ${result.error}`);
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
/**
|
|
512
|
+
* Strategy 2: Team-Board
|
|
513
|
+
* - One GitHub Project per team (aggregates multiple specs)
|
|
514
|
+
* - All specs from the same team/project sync to same board
|
|
515
|
+
*/
|
|
516
|
+
async syncTeamBoard(spec, owner, repo, teamBoardId) {
|
|
517
|
+
const specId = spec.metadata.id;
|
|
518
|
+
try {
|
|
519
|
+
console.log(" \u{1F4CB} Using team-board strategy (aggregated)");
|
|
520
|
+
if (!teamBoardId) {
|
|
521
|
+
const projectId = await this.detectProjectFromSpecPath(spec.filePath);
|
|
522
|
+
const project = await this.projectContextManager.getProject(projectId || "default");
|
|
523
|
+
const teamName = project?.team || "Team";
|
|
524
|
+
const teamProject = await this.createGitHubProject(owner, repo, {
|
|
525
|
+
...spec,
|
|
526
|
+
metadata: {
|
|
527
|
+
...spec.metadata,
|
|
528
|
+
title: `${teamName} Board`
|
|
529
|
+
}
|
|
530
|
+
});
|
|
531
|
+
teamBoardId = teamProject.id;
|
|
532
|
+
console.log(` \u2705 Created team board: ${teamName} Board (#${teamBoardId})`);
|
|
533
|
+
}
|
|
534
|
+
const changes = await this.syncUserStories(owner, repo, teamBoardId, spec);
|
|
535
|
+
return {
|
|
536
|
+
success: true,
|
|
537
|
+
specId,
|
|
538
|
+
provider: "github",
|
|
539
|
+
externalId: teamBoardId.toString(),
|
|
540
|
+
url: `https://github.com/orgs/${owner}/projects/${teamBoardId}`,
|
|
541
|
+
changes
|
|
542
|
+
};
|
|
543
|
+
} catch (error) {
|
|
544
|
+
console.error("\u274C Error syncing to team board:", error);
|
|
545
|
+
return {
|
|
546
|
+
success: false,
|
|
547
|
+
specId,
|
|
548
|
+
provider: "github",
|
|
549
|
+
error: error instanceof Error ? error.message : "Unknown error"
|
|
550
|
+
};
|
|
481
551
|
}
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
552
|
+
}
|
|
553
|
+
/**
|
|
554
|
+
* Strategy 3: Centralized
|
|
555
|
+
* - Parent repo tracks all specs (multi-repo pattern)
|
|
556
|
+
* - Issues created in parent repo with tags for child repos
|
|
557
|
+
*/
|
|
558
|
+
async syncCentralized(spec, parentOwner, parentRepo) {
|
|
559
|
+
const specId = spec.metadata.id;
|
|
560
|
+
try {
|
|
561
|
+
console.log(" \u{1F3E2} Using centralized strategy (parent repo tracks all)");
|
|
562
|
+
const project = await this.createGitHubProject(parentOwner, parentRepo, spec);
|
|
563
|
+
const projectId = await this.detectProjectFromSpecPath(spec.filePath);
|
|
564
|
+
const projectContext = await this.projectContextManager.getProject(projectId || "default");
|
|
565
|
+
const changes = await this.syncUserStories(
|
|
566
|
+
parentOwner,
|
|
567
|
+
parentRepo,
|
|
568
|
+
project.number,
|
|
569
|
+
spec,
|
|
570
|
+
projectContext?.name ? [`project:${projectContext.name}`] : []
|
|
571
|
+
);
|
|
572
|
+
console.log(` \u2705 Synced to parent repo: ${parentOwner}/${parentRepo}`);
|
|
573
|
+
return {
|
|
574
|
+
success: true,
|
|
575
|
+
specId,
|
|
576
|
+
provider: "github",
|
|
577
|
+
externalId: project.id.toString(),
|
|
578
|
+
url: project.url,
|
|
579
|
+
changes
|
|
580
|
+
};
|
|
581
|
+
} catch (error) {
|
|
582
|
+
console.error("\u274C Error syncing centralized:", error);
|
|
583
|
+
return {
|
|
584
|
+
success: false,
|
|
585
|
+
specId,
|
|
586
|
+
provider: "github",
|
|
587
|
+
error: error instanceof Error ? error.message : "Unknown error"
|
|
588
|
+
};
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
/**
|
|
592
|
+
* Strategy 4: Distributed
|
|
593
|
+
* - Each team syncs to their repo (microservices)
|
|
594
|
+
* - Cross-team specs create issues in multiple repos
|
|
595
|
+
*/
|
|
596
|
+
async syncDistributed(spec, config) {
|
|
597
|
+
const specId = spec.metadata.id;
|
|
598
|
+
try {
|
|
599
|
+
console.log(" \u{1F310} Using distributed strategy (per-team repos)");
|
|
600
|
+
const projectId = config.projectId;
|
|
601
|
+
const projectContext = await this.projectContextManager.getProject(projectId);
|
|
602
|
+
if (!projectContext) {
|
|
603
|
+
throw new Error(`Project context not found for ${projectId}`);
|
|
604
|
+
}
|
|
605
|
+
const isCrossTeam = this.isCrossTeamSpec(spec);
|
|
606
|
+
if (isCrossTeam) {
|
|
607
|
+
console.log(" \u{1F517} Cross-team spec detected, syncing to multiple repos");
|
|
608
|
+
return await this.syncCrossTeamSpec(spec, projectId);
|
|
609
|
+
}
|
|
610
|
+
return await this.syncProjectPerSpec(spec, config.owner, config.repo);
|
|
611
|
+
} catch (error) {
|
|
612
|
+
console.error("\u274C Error syncing distributed:", error);
|
|
613
|
+
return {
|
|
614
|
+
success: false,
|
|
615
|
+
specId,
|
|
616
|
+
provider: "github",
|
|
617
|
+
error: error instanceof Error ? error.message : "Unknown error"
|
|
618
|
+
};
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
/**
|
|
622
|
+
* Check if spec is cross-team (touches multiple projects)
|
|
623
|
+
*
|
|
624
|
+
* Detection heuristics:
|
|
625
|
+
* - Spec title contains keywords like "integration", "cross-team", "shared"
|
|
626
|
+
* - User stories reference multiple projects/teams
|
|
627
|
+
* - Tags include multiple project names
|
|
628
|
+
*/
|
|
629
|
+
isCrossTeamSpec(spec) {
|
|
630
|
+
const crossTeamKeywords = [
|
|
631
|
+
"integration",
|
|
632
|
+
"cross-team",
|
|
633
|
+
"cross-project",
|
|
634
|
+
"shared",
|
|
635
|
+
"common",
|
|
636
|
+
"auth",
|
|
637
|
+
// Auth often touches frontend + backend
|
|
638
|
+
"api-contract",
|
|
639
|
+
"sync"
|
|
640
|
+
];
|
|
641
|
+
const title = spec.metadata.title.toLowerCase();
|
|
642
|
+
const hasCrossTeamKeyword = crossTeamKeywords.some(
|
|
643
|
+
(keyword) => title.includes(keyword)
|
|
644
|
+
);
|
|
645
|
+
const tags = spec.metadata.tags || [];
|
|
646
|
+
const projectTags = tags.filter((tag) => tag.startsWith("project:"));
|
|
647
|
+
const hasMultipleProjects = projectTags.length > 1;
|
|
648
|
+
return hasCrossTeamKeyword || hasMultipleProjects;
|
|
649
|
+
}
|
|
650
|
+
/**
|
|
651
|
+
* Sync cross-team spec to multiple repositories
|
|
652
|
+
*
|
|
653
|
+
* Creates issues in multiple repos:
|
|
654
|
+
* - Frontend repo gets frontend-specific user stories
|
|
655
|
+
* - Backend repo gets backend-specific user stories
|
|
656
|
+
* - Shared stories get created in both with cross-links
|
|
657
|
+
*/
|
|
658
|
+
async syncCrossTeamSpec(spec, projectId) {
|
|
659
|
+
const specId = spec.metadata.id;
|
|
660
|
+
try {
|
|
661
|
+
const config = await this.projectContextManager.load();
|
|
662
|
+
const relatedProfiles = await this.detectRelatedProfiles(spec, config);
|
|
663
|
+
if (relatedProfiles.length === 0) {
|
|
664
|
+
throw new Error("No related profiles found for cross-team spec");
|
|
665
|
+
}
|
|
666
|
+
console.log(` \u{1F4C2} Syncing to ${relatedProfiles.length} repositories:`);
|
|
667
|
+
const allChanges = {
|
|
668
|
+
created: [],
|
|
669
|
+
updated: [],
|
|
670
|
+
deleted: []
|
|
671
|
+
};
|
|
672
|
+
for (const profile of relatedProfiles) {
|
|
673
|
+
const githubConfig = profile.config;
|
|
674
|
+
console.log(` \u2192 ${githubConfig.owner}/${githubConfig.repo}`);
|
|
675
|
+
const relevantStories = this.filterRelevantUserStories(
|
|
676
|
+
spec,
|
|
677
|
+
profile.projectContext?.name || ""
|
|
678
|
+
);
|
|
679
|
+
if (relevantStories.length === 0) {
|
|
680
|
+
console.log(` \u2139\uFE0F No relevant stories, skipping`);
|
|
681
|
+
continue;
|
|
489
682
|
}
|
|
490
|
-
const
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
683
|
+
const project = await this.createGitHubProject(
|
|
684
|
+
githubConfig.owner || "",
|
|
685
|
+
githubConfig.repo || "",
|
|
686
|
+
{
|
|
687
|
+
...spec,
|
|
688
|
+
metadata: {
|
|
689
|
+
...spec.metadata,
|
|
690
|
+
userStories: relevantStories
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
);
|
|
694
|
+
const changes = await this.syncUserStories(
|
|
695
|
+
githubConfig.owner || "",
|
|
696
|
+
githubConfig.repo || "",
|
|
697
|
+
project.number,
|
|
698
|
+
{ ...spec, metadata: { ...spec.metadata, userStories: relevantStories } }
|
|
699
|
+
);
|
|
700
|
+
allChanges.created.push(...changes.created);
|
|
701
|
+
allChanges.updated.push(...changes.updated);
|
|
702
|
+
allChanges.deleted.push(...changes.deleted);
|
|
703
|
+
}
|
|
704
|
+
console.log(" \u2705 Cross-team sync complete!");
|
|
705
|
+
return {
|
|
706
|
+
success: true,
|
|
707
|
+
specId,
|
|
708
|
+
provider: "github",
|
|
709
|
+
externalId: "cross-team",
|
|
710
|
+
url: "multiple-repos",
|
|
711
|
+
changes: allChanges
|
|
712
|
+
};
|
|
713
|
+
} catch (error) {
|
|
714
|
+
console.error("\u274C Error syncing cross-team spec:", error);
|
|
715
|
+
return {
|
|
716
|
+
success: false,
|
|
717
|
+
specId,
|
|
718
|
+
provider: "github",
|
|
719
|
+
error: error instanceof Error ? error.message : "Unknown error"
|
|
720
|
+
};
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
/**
|
|
724
|
+
* Detect related profiles for cross-team spec
|
|
725
|
+
*/
|
|
726
|
+
async detectRelatedProfiles(spec, config) {
|
|
727
|
+
const profiles = [];
|
|
728
|
+
const tags = spec.metadata.tags || [];
|
|
729
|
+
const projectTags = tags.filter((tag) => tag.startsWith("project:")).map((tag) => tag.replace("project:", ""));
|
|
730
|
+
for (const projectId of projectTags) {
|
|
731
|
+
const project = await this.projectContextManager.getProject(projectId);
|
|
732
|
+
if (project && project.defaultSyncProfile) {
|
|
733
|
+
const profile = config.profiles?.[project.defaultSyncProfile];
|
|
734
|
+
if (profile && profile.provider === "github") {
|
|
735
|
+
profiles.push({
|
|
736
|
+
...profile,
|
|
737
|
+
projectContext: project
|
|
738
|
+
});
|
|
501
739
|
}
|
|
502
|
-
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
return profiles;
|
|
743
|
+
}
|
|
744
|
+
/**
|
|
745
|
+
* Filter user stories relevant to a specific project
|
|
746
|
+
*
|
|
747
|
+
* Heuristics:
|
|
748
|
+
* - Story title/description contains project keywords
|
|
749
|
+
* - Story tags include project name
|
|
750
|
+
* - Story implementation references project folder
|
|
751
|
+
*/
|
|
752
|
+
filterRelevantUserStories(spec, projectName) {
|
|
753
|
+
if (!spec.metadata.userStories) {
|
|
754
|
+
return [];
|
|
755
|
+
}
|
|
756
|
+
const projectKeywords = projectName.toLowerCase().split(/[-_\s]/);
|
|
757
|
+
return spec.metadata.userStories.filter((story) => {
|
|
758
|
+
const storyText = `${story.title} ${story.description || ""}`.toLowerCase();
|
|
759
|
+
const mentionsProject = projectKeywords.some(
|
|
760
|
+
(keyword) => storyText.includes(keyword)
|
|
761
|
+
);
|
|
762
|
+
const isShared = !storyText.match(/\b(frontend|backend|mobile|infra|platform)\b/);
|
|
763
|
+
return mentionsProject || isShared;
|
|
764
|
+
});
|
|
765
|
+
}
|
|
766
|
+
/**
|
|
767
|
+
* Enhanced syncUserStories with optional extra labels
|
|
768
|
+
*/
|
|
769
|
+
async syncUserStories(owner, repo, projectNumber, spec, extraLabels = []) {
|
|
770
|
+
const created = [];
|
|
771
|
+
const updated = [];
|
|
772
|
+
const deleted = [];
|
|
773
|
+
if (!spec.metadata.userStories || spec.metadata.userStories.length === 0) {
|
|
774
|
+
console.log(" \u2139\uFE0F No user stories to sync");
|
|
775
|
+
return { created, updated, deleted };
|
|
776
|
+
}
|
|
777
|
+
console.log(` Syncing ${spec.metadata.userStories.length} user stories...`);
|
|
778
|
+
for (const us of spec.metadata.userStories) {
|
|
779
|
+
const issueTitle = `[${us.id}] ${us.title}`;
|
|
780
|
+
const issueBody = this.generateIssueBody(us);
|
|
781
|
+
const existingIssue = await this.findIssueByTitle(owner, repo, us.id);
|
|
782
|
+
const labels = [
|
|
783
|
+
"user-story",
|
|
784
|
+
`spec:${spec.metadata.id}`,
|
|
785
|
+
`priority:${us.priority}`,
|
|
786
|
+
...extraLabels
|
|
787
|
+
];
|
|
788
|
+
if (existingIssue) {
|
|
789
|
+
await this.updateIssue(owner, repo, existingIssue.number, {
|
|
790
|
+
title: issueTitle,
|
|
791
|
+
body: issueBody,
|
|
792
|
+
state: us.status === "done" ? "closed" : "open"
|
|
793
|
+
});
|
|
794
|
+
updated.push(us.id);
|
|
795
|
+
console.log(` \u2705 Updated ${us.id}`);
|
|
796
|
+
} else {
|
|
797
|
+
const newIssue = await this.createIssue(owner, repo, {
|
|
798
|
+
title: issueTitle,
|
|
799
|
+
body: issueBody,
|
|
800
|
+
labels
|
|
801
|
+
});
|
|
802
|
+
created.push(us.id);
|
|
803
|
+
console.log(` \u2705 Created ${us.id} \u2192 Issue #${newIssue.number}`);
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
return { created, updated, deleted };
|
|
807
|
+
}
|
|
808
|
+
/**
|
|
809
|
+
* Detect GitHub repository from git remote
|
|
810
|
+
*/
|
|
811
|
+
async detectRepo() {
|
|
812
|
+
const result = await execFileNoThrow("git", ["remote", "get-url", "origin"]);
|
|
813
|
+
if (result.error || !result.stdout) {
|
|
814
|
+
return null;
|
|
815
|
+
}
|
|
816
|
+
const remoteUrl = result.stdout.trim();
|
|
817
|
+
const httpsMatch = remoteUrl.match(/github\.com[/:]([\w-]+)\/([\w-]+?)(\.git)?$/);
|
|
818
|
+
if (httpsMatch) {
|
|
819
|
+
return {
|
|
820
|
+
owner: httpsMatch[1],
|
|
821
|
+
repo: httpsMatch[2]
|
|
822
|
+
};
|
|
503
823
|
}
|
|
824
|
+
return null;
|
|
825
|
+
}
|
|
504
826
|
}
|
|
505
|
-
|
|
827
|
+
export {
|
|
828
|
+
GitHubSpecSync
|
|
829
|
+
};
|