specweave 0.22.14 → 0.23.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +178 -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 +46 -0
- 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 +5 -17
- package/dist/src/cli/helpers/issue-tracker/index.js.map +1 -1
- package/dist/src/config/types.d.ts +16 -16
- 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 +14 -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 +46 -0
- package/dist/src/core/living-docs/living-docs-sync.js.map +1 -1
- package/dist/src/core/repo-structure/repo-id-generator.d.ts +20 -0
- package/dist/src/core/repo-structure/repo-id-generator.d.ts.map +1 -1
- package/dist/src/core/repo-structure/repo-id-generator.js +44 -0
- package/dist/src/core/repo-structure/repo-id-generator.js.map +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 +5 -2
- package/dist/src/core/repo-structure/repo-structure-manager.js.map +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/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/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/import-coordinator.d.ts +15 -0
- package/dist/src/importers/import-coordinator.d.ts.map +1 -1
- package/dist/src/importers/import-coordinator.js +43 -1
- package/dist/src/importers/import-coordinator.js.map +1 -1
- package/dist/src/importers/item-converter.d.ts +5 -0
- package/dist/src/importers/item-converter.d.ts.map +1 -1
- package/dist/src/importers/item-converter.js +27 -2
- package/dist/src/importers/item-converter.js.map +1 -1
- 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/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/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 +20 -0
- package/plugins/specweave/commands/specweave-archive-features.md +11 -1
- package/plugins/specweave/commands/specweave-archive.md +51 -15
- package/plugins/specweave/commands/specweave-import-docs.md +88 -278
- package/plugins/specweave/commands/specweave-import-external.md +407 -0
- package/plugins/specweave/hooks/post-edit-spec.sh +94 -0
- package/plugins/specweave/hooks/post-increment-completion.sh +0 -0
- package/plugins/specweave/hooks/post-spec-update.sh +0 -0
- package/plugins/specweave/hooks/post-task-completion.sh +13 -3
- package/plugins/specweave/hooks/post-write-spec.sh +91 -0
- package/plugins/specweave/lib/hooks/auto-transition.js +1 -1
- package/plugins/specweave/lib/hooks/auto-transition.js.bak +50 -0
- package/plugins/specweave/lib/hooks/auto-transition.ts +1 -1
- package/plugins/specweave/lib/hooks/auto-transition.ts.bak +84 -0
- package/plugins/specweave/lib/hooks/git-diff-analyzer.d.js.bak +0 -0
- package/plugins/specweave/lib/hooks/git-diff-analyzer.d.ts.bak +89 -0
- package/plugins/specweave/lib/hooks/git-diff-analyzer.js.bak +142 -0
- package/plugins/specweave/lib/hooks/git-diff-analyzer.ts.bak +269 -0
- package/plugins/specweave/lib/hooks/invoke-translator-skill.d.js.bak +0 -0
- package/plugins/specweave/lib/hooks/invoke-translator-skill.d.ts.bak +60 -0
- package/plugins/specweave/lib/hooks/invoke-translator-skill.js +1 -1
- package/plugins/specweave/lib/hooks/invoke-translator-skill.js.bak +155 -0
- package/plugins/specweave/lib/hooks/invoke-translator-skill.ts +1 -1
- package/plugins/specweave/lib/hooks/invoke-translator-skill.ts.bak +264 -0
- package/plugins/specweave/lib/hooks/prepare-reflection-context.d.js.bak +0 -0
- package/plugins/specweave/lib/hooks/prepare-reflection-context.d.ts.bak +42 -0
- package/plugins/specweave/lib/hooks/prepare-reflection-context.js.bak +110 -0
- package/plugins/specweave/lib/hooks/prepare-reflection-context.ts.bak +178 -0
- package/plugins/specweave/lib/hooks/reflection-config-loader.d.js.bak +0 -0
- package/plugins/specweave/lib/hooks/reflection-config-loader.d.ts.bak +45 -0
- package/plugins/specweave/lib/hooks/reflection-config-loader.js.bak +92 -0
- package/plugins/specweave/lib/hooks/reflection-config-loader.ts.bak +156 -0
- package/plugins/specweave/lib/hooks/reflection-parser.d.js.bak +0 -0
- package/plugins/specweave/lib/hooks/reflection-parser.d.ts.bak +33 -0
- package/plugins/specweave/lib/hooks/reflection-parser.js.bak +301 -0
- package/plugins/specweave/lib/hooks/reflection-parser.ts.bak +484 -0
- package/plugins/specweave/lib/hooks/reflection-prompt-builder.d.js.bak +0 -0
- package/plugins/specweave/lib/hooks/reflection-prompt-builder.d.ts.bak +56 -0
- package/plugins/specweave/lib/hooks/reflection-prompt-builder.js.bak +182 -0
- package/plugins/specweave/lib/hooks/reflection-prompt-builder.ts.bak +306 -0
- package/plugins/specweave/lib/hooks/reflection-storage.d.js.bak +0 -0
- package/plugins/specweave/lib/hooks/reflection-storage.d.ts.bak +64 -0
- package/plugins/specweave/lib/hooks/reflection-storage.js.bak +231 -0
- package/plugins/specweave/lib/hooks/reflection-storage.ts.bak +369 -0
- package/plugins/specweave/lib/hooks/run-self-reflection.d.js.bak +0 -0
- package/plugins/specweave/lib/hooks/run-self-reflection.d.ts.bak +43 -0
- package/plugins/specweave/lib/hooks/run-self-reflection.js.bak +132 -0
- package/plugins/specweave/lib/hooks/run-self-reflection.ts.bak +258 -0
- package/plugins/specweave/lib/hooks/sync-cache.js.bak +294 -0
- package/plugins/specweave/lib/hooks/sync-living-docs.d.js.bak +1 -0
- package/plugins/specweave/lib/hooks/sync-living-docs.d.ts.bak +27 -0
- package/plugins/specweave/lib/hooks/sync-living-docs.js +35 -1
- package/plugins/specweave/lib/hooks/sync-living-docs.js.bak +339 -0
- package/plugins/specweave/lib/hooks/sync-us-tasks.js +179 -3
- package/plugins/specweave/lib/hooks/sync-us-tasks.js.bak +476 -0
- package/plugins/specweave/lib/hooks/translate-file.d.js.bak +0 -0
- package/plugins/specweave/lib/hooks/translate-file.d.ts.bak +59 -0
- package/plugins/specweave/lib/hooks/translate-file.js +1 -1
- package/plugins/specweave/lib/hooks/translate-file.js.bak +289 -0
- package/plugins/specweave/lib/hooks/translate-file.ts +1 -1
- package/plugins/specweave/lib/hooks/translate-file.ts.bak +428 -0
- package/plugins/specweave/lib/hooks/translate-living-docs.d.js.bak +0 -0
- package/plugins/specweave/lib/hooks/translate-living-docs.d.ts.bak +13 -0
- package/plugins/specweave/lib/hooks/translate-living-docs.js.bak +119 -0
- package/plugins/specweave/lib/hooks/translate-living-docs.ts.bak +224 -0
- package/plugins/specweave/lib/hooks/update-ac-status.js +1 -1
- package/plugins/specweave/lib/hooks/update-ac-status.js.bak +51 -0
- package/plugins/specweave/lib/hooks/update-ac-status.ts +1 -1
- package/plugins/specweave/lib/hooks/update-ac-status.ts.bak +103 -0
- package/plugins/specweave/lib/hooks/update-tasks-md.d.js.bak +1 -0
- package/plugins/specweave/lib/hooks/update-tasks-md.d.ts.bak +29 -0
- package/plugins/specweave/lib/hooks/update-tasks-md.js.bak +296 -0
- package/plugins/specweave/lib/hooks/update-tasks-md.ts.bak +489 -0
- 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-github/commands/specweave-github-update-user-story.md +1 -1
- package/plugins/specweave-github/skills/github-issue-standard/SKILL.md +1 -1
- package/plugins/specweave-release/hooks/.specweave/logs/dora-tracking.log +531 -0
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External Item Sync Service
|
|
3
|
+
*
|
|
4
|
+
* Handles synchronization with external tools (GitHub, JIRA, ADO) while
|
|
5
|
+
* preserving original item format and preventing unintended modifications.
|
|
6
|
+
*
|
|
7
|
+
* Key Features:
|
|
8
|
+
* - Comment-based updates for external items (format preservation)
|
|
9
|
+
* - Full sync for internal items (title, description, ACs)
|
|
10
|
+
* - Format preservation validation
|
|
11
|
+
* - External title immutability
|
|
12
|
+
*
|
|
13
|
+
* Part of increment 0047-us-task-linkage (T-034B)
|
|
14
|
+
*/
|
|
15
|
+
import fs from 'fs-extra';
|
|
16
|
+
import path from 'path';
|
|
17
|
+
import matter from 'gray-matter';
|
|
18
|
+
import { consoleLogger } from '../utils/logger.js';
|
|
19
|
+
import { FormatPreservationValidator } from '../validators/format-preservation-validator.js';
|
|
20
|
+
/**
|
|
21
|
+
* External Item Sync Service
|
|
22
|
+
*
|
|
23
|
+
* Routes sync operations based on format_preservation flag.
|
|
24
|
+
* External items (format_preservation=true) → comment-only sync
|
|
25
|
+
* Internal items (format_preservation=false) → full sync
|
|
26
|
+
*/
|
|
27
|
+
export class ExternalItemSyncService {
|
|
28
|
+
constructor(options = {}) {
|
|
29
|
+
this.logger = options.logger ?? consoleLogger;
|
|
30
|
+
this.validator = new FormatPreservationValidator({ logger: this.logger });
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Sync task completion to external tool
|
|
34
|
+
*
|
|
35
|
+
* Routes to comment-only or full sync based on format_preservation flag
|
|
36
|
+
*
|
|
37
|
+
* @param completionData - Task completion data
|
|
38
|
+
* @param options - Sync options
|
|
39
|
+
* @returns Sync result
|
|
40
|
+
*/
|
|
41
|
+
async syncTaskCompletion(completionData, options) {
|
|
42
|
+
try {
|
|
43
|
+
this.logger.log(` 🔄 Syncing task ${completionData.taskId} completion for ${completionData.usId}...`);
|
|
44
|
+
// Read format preservation flag from living docs
|
|
45
|
+
const formatPreservation = await this.getFormatPreservation(completionData.usId, completionData.featureId, options.projectRoot);
|
|
46
|
+
// Force full sync if requested (e.g., for internal items or testing)
|
|
47
|
+
if (options.forceFullSync) {
|
|
48
|
+
this.logger.log(` 📝 Full sync mode (force flag enabled)`);
|
|
49
|
+
return await this.fullSync(completionData, options);
|
|
50
|
+
}
|
|
51
|
+
// Route based on format_preservation flag
|
|
52
|
+
if (formatPreservation) {
|
|
53
|
+
this.logger.log(` 💬 Comment-only mode (format preservation enabled)`);
|
|
54
|
+
return await this.commentOnlySync(completionData, options);
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
this.logger.log(` 📝 Full sync mode (format preservation disabled)`);
|
|
58
|
+
return await this.fullSync(completionData, options);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
this.logger.error(` ❌ Sync failed for ${completionData.taskId}:`, error);
|
|
63
|
+
return {
|
|
64
|
+
success: false,
|
|
65
|
+
mode: 'skipped',
|
|
66
|
+
reason: 'Error during sync',
|
|
67
|
+
error: error.message
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Get format_preservation flag from living docs User Story file
|
|
73
|
+
*
|
|
74
|
+
* @param usId - User Story ID (e.g., "US-009")
|
|
75
|
+
* @param featureId - Feature ID (e.g., "FS-047")
|
|
76
|
+
* @param projectRoot - Project root directory
|
|
77
|
+
* @returns True if format preservation enabled
|
|
78
|
+
*/
|
|
79
|
+
async getFormatPreservation(usId, featureId, projectRoot) {
|
|
80
|
+
try {
|
|
81
|
+
// Find US file in living docs
|
|
82
|
+
const usFilePath = await this.findUSFile(projectRoot, featureId, usId);
|
|
83
|
+
if (!usFilePath) {
|
|
84
|
+
this.logger.warn(` ⚠️ Living docs file not found for ${usId}, defaulting to full sync`);
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
// Parse frontmatter
|
|
88
|
+
const content = await fs.readFile(usFilePath, 'utf-8');
|
|
89
|
+
const parsed = matter(content);
|
|
90
|
+
const frontmatter = parsed.data;
|
|
91
|
+
// Default to false (full sync) if not specified
|
|
92
|
+
return frontmatter.format_preservation === true;
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
this.logger.warn(` ⚠️ Failed to read format_preservation for ${usId}: ${error.message}`);
|
|
96
|
+
return false; // Default to full sync on error
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Find User Story file in living docs
|
|
101
|
+
*
|
|
102
|
+
* @param projectRoot - Project root
|
|
103
|
+
* @param featureId - Feature ID (e.g., "FS-047")
|
|
104
|
+
* @param usId - User Story ID (e.g., "US-009")
|
|
105
|
+
* @returns Path to US file or null if not found
|
|
106
|
+
*/
|
|
107
|
+
async findUSFile(projectRoot, featureId, usId) {
|
|
108
|
+
// Pattern: .specweave/docs/internal/specs/{project}/{feature}/us-{id}-*.md
|
|
109
|
+
const specsDir = path.join(projectRoot, '.specweave', 'docs', 'internal', 'specs');
|
|
110
|
+
// Search in all projects (default and multi-project)
|
|
111
|
+
const projectDirs = await this.getProjectDirs(specsDir);
|
|
112
|
+
for (const projectDir of projectDirs) {
|
|
113
|
+
const featureDir = path.join(projectDir, featureId);
|
|
114
|
+
if (!await fs.pathExists(featureDir))
|
|
115
|
+
continue;
|
|
116
|
+
const files = await fs.readdir(featureDir);
|
|
117
|
+
const usFile = files.find(f => f.toLowerCase().startsWith(`${usId.toLowerCase()}-`));
|
|
118
|
+
if (usFile) {
|
|
119
|
+
return path.join(featureDir, usFile);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Get all project directories in specs
|
|
126
|
+
*
|
|
127
|
+
* @param specsDir - Specs directory
|
|
128
|
+
* @returns Array of project directory paths
|
|
129
|
+
*/
|
|
130
|
+
async getProjectDirs(specsDir) {
|
|
131
|
+
if (!await fs.pathExists(specsDir)) {
|
|
132
|
+
return [];
|
|
133
|
+
}
|
|
134
|
+
const entries = await fs.readdir(specsDir, { withFileTypes: true });
|
|
135
|
+
const projectDirs = entries
|
|
136
|
+
.filter(e => e.isDirectory() && !e.name.startsWith('_'))
|
|
137
|
+
.map(e => path.join(specsDir, e.name));
|
|
138
|
+
return projectDirs;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Comment-only sync: Post completion update as comment
|
|
142
|
+
*
|
|
143
|
+
* Does NOT modify external item title, description, or acceptance criteria.
|
|
144
|
+
* Only posts a comment with task completion status.
|
|
145
|
+
*
|
|
146
|
+
* @param completionData - Task completion data
|
|
147
|
+
* @param options - Sync options
|
|
148
|
+
* @returns Sync result
|
|
149
|
+
*/
|
|
150
|
+
async commentOnlySync(completionData, options) {
|
|
151
|
+
// Format completion comment
|
|
152
|
+
const comment = this.formatCompletionComment(completionData);
|
|
153
|
+
if (options.dryRun) {
|
|
154
|
+
this.logger.log(` 🔍 [DRY RUN] Would post comment:\n${comment}`);
|
|
155
|
+
return {
|
|
156
|
+
success: true,
|
|
157
|
+
mode: 'comment-only',
|
|
158
|
+
reason: 'Format preservation enabled (external item)',
|
|
159
|
+
comment
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
// TODO: Integrate with external tool APIs (GitHub, JIRA, ADO)
|
|
163
|
+
// For now, just log the comment that would be posted
|
|
164
|
+
this.logger.log(` 💬 Comment to post:\n${comment}`);
|
|
165
|
+
return {
|
|
166
|
+
success: true,
|
|
167
|
+
mode: 'comment-only',
|
|
168
|
+
reason: 'Format preservation enabled (external item)',
|
|
169
|
+
comment
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Full sync: Update external item title, description, ACs
|
|
174
|
+
*
|
|
175
|
+
* Used for internal items or when format preservation disabled.
|
|
176
|
+
*
|
|
177
|
+
* @param completionData - Task completion data
|
|
178
|
+
* @param options - Sync options
|
|
179
|
+
* @returns Sync result
|
|
180
|
+
*/
|
|
181
|
+
async fullSync(completionData, options) {
|
|
182
|
+
const updatedFields = [];
|
|
183
|
+
// Validate sync operation (NEW - T-034C)
|
|
184
|
+
const formatPreservation = await this.getFormatPreservation(completionData.usId, completionData.featureId, options.projectRoot);
|
|
185
|
+
const syncOperation = {
|
|
186
|
+
usId: completionData.usId,
|
|
187
|
+
formatPreservation,
|
|
188
|
+
updates: ['title', 'description', 'acceptance_criteria'],
|
|
189
|
+
origin: formatPreservation ? 'external' : 'internal'
|
|
190
|
+
};
|
|
191
|
+
const validation = this.validator.validate(syncOperation);
|
|
192
|
+
if (!validation.valid) {
|
|
193
|
+
this.logger.error(` ❌ Full sync blocked by format preservation validation:`, validation.errors?.join(', '));
|
|
194
|
+
return {
|
|
195
|
+
success: false,
|
|
196
|
+
mode: 'skipped',
|
|
197
|
+
reason: 'Format preservation validation failed',
|
|
198
|
+
error: validation.errors?.join('; ')
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
if (options.dryRun) {
|
|
202
|
+
this.logger.log(` 🔍 [DRY RUN] Would perform full sync for ${completionData.usId}`);
|
|
203
|
+
return {
|
|
204
|
+
success: true,
|
|
205
|
+
mode: 'full-sync',
|
|
206
|
+
reason: 'Format preservation disabled (internal item)',
|
|
207
|
+
updatedFields: validation.allowedFields
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
// TODO: Implement full sync logic
|
|
211
|
+
// - Update external item title
|
|
212
|
+
// - Update external item description
|
|
213
|
+
// - Update acceptance criteria checkboxes
|
|
214
|
+
this.logger.log(` 📝 Full sync for ${completionData.usId} (not yet implemented)`);
|
|
215
|
+
return {
|
|
216
|
+
success: true,
|
|
217
|
+
mode: 'full-sync',
|
|
218
|
+
reason: 'Format preservation disabled (internal item)',
|
|
219
|
+
updatedFields: validation.allowedFields
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Format completion comment for external tool
|
|
224
|
+
*
|
|
225
|
+
* @param data - Task completion data
|
|
226
|
+
* @returns Formatted comment
|
|
227
|
+
*/
|
|
228
|
+
formatCompletionComment(data) {
|
|
229
|
+
const statusEmoji = data.status === 'completed' ? '✅' : '🔄';
|
|
230
|
+
return `${statusEmoji} **[${data.featureId}][${data.taskId}]** ${data.taskTitle}
|
|
231
|
+
|
|
232
|
+
**Status**: ${data.status}
|
|
233
|
+
**Acceptance Criteria Satisfied**: ${data.satisfiesACs.length > 0 ? data.satisfiesACs.join(', ') : 'None'}
|
|
234
|
+
**Progress**: ${data.completedTasks}/${data.totalTasks} tasks (${data.percentage}%)
|
|
235
|
+
${data.livingDocsUrl ? `**Living Docs**: [View spec](${data.livingDocsUrl})` : ''}
|
|
236
|
+
|
|
237
|
+
---
|
|
238
|
+
*Auto-posted by SpecWeave format preservation sync*`;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
//# sourceMappingURL=external-item-sync-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"external-item-sync-service.js","sourceRoot":"","sources":["../../../src/sync/external-item-sync-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Format Preservation Sync Service (T-034B)
|
|
3
|
+
*
|
|
4
|
+
* Routes sync to comment-only mode for external items (preserves original format)
|
|
5
|
+
* and full sync mode for internal items (allows title/description updates).
|
|
6
|
+
*
|
|
7
|
+
* Architecture:
|
|
8
|
+
* - External US (origin=external): Comment-only sync (no title/description changes)
|
|
9
|
+
* - Internal US (origin=internal): Full sync (title, description, status, comments)
|
|
10
|
+
*/
|
|
11
|
+
import { LivingDocsUSFile } from '../types/living-docs-us-file.js';
|
|
12
|
+
import { GitHubClientV2 } from '../../plugins/specweave-github/lib/github-client-v2.js';
|
|
13
|
+
import { JiraClient } from '../integrations/jira/jira-client.js';
|
|
14
|
+
import { AdoClient } from '../integrations/ado/ado-client.js';
|
|
15
|
+
import { Logger } from '../utils/logger.js';
|
|
16
|
+
export interface SyncConfig {
|
|
17
|
+
/** Allow updating external items from SpecWeave (Internal → External) */
|
|
18
|
+
canUpdateExternalItems?: boolean;
|
|
19
|
+
/** Allow upserting internal items from external tools (External → Internal) */
|
|
20
|
+
canUpsertInternalItems?: boolean;
|
|
21
|
+
/** Allow status updates (both directions) */
|
|
22
|
+
canUpdateStatus?: boolean;
|
|
23
|
+
}
|
|
24
|
+
export interface TaskCompletionInfo {
|
|
25
|
+
taskId: string;
|
|
26
|
+
title: string;
|
|
27
|
+
completed: boolean;
|
|
28
|
+
}
|
|
29
|
+
export interface ACCompletionInfo {
|
|
30
|
+
acId: string;
|
|
31
|
+
description: string;
|
|
32
|
+
satisfied: boolean;
|
|
33
|
+
}
|
|
34
|
+
export interface CompletionCommentData {
|
|
35
|
+
tasks: TaskCompletionInfo[];
|
|
36
|
+
acceptanceCriteria: ACCompletionInfo[];
|
|
37
|
+
progressPercentage: number;
|
|
38
|
+
livingDocsUrl?: string;
|
|
39
|
+
}
|
|
40
|
+
export declare class FormatPreservationSyncService {
|
|
41
|
+
private logger;
|
|
42
|
+
private config;
|
|
43
|
+
constructor(config?: SyncConfig, options?: {
|
|
44
|
+
logger?: Logger;
|
|
45
|
+
});
|
|
46
|
+
/**
|
|
47
|
+
* Sync User Story to external tool with origin-based routing
|
|
48
|
+
*
|
|
49
|
+
* - External US (origin=external) → Comment-only sync
|
|
50
|
+
* - Internal US (origin=internal) → Full sync
|
|
51
|
+
*/
|
|
52
|
+
syncUserStory(usFile: LivingDocsUSFile, completionData: CompletionCommentData, externalClient: GitHubClientV2 | JiraClient | AdoClient): Promise<void>;
|
|
53
|
+
/**
|
|
54
|
+
* Sync External US (Comment-only mode)
|
|
55
|
+
*
|
|
56
|
+
* Preserves original title/description, only adds completion comments
|
|
57
|
+
*/
|
|
58
|
+
private syncExternalUS;
|
|
59
|
+
/**
|
|
60
|
+
* Sync Internal US (Full sync mode)
|
|
61
|
+
*
|
|
62
|
+
* Allows updating title, description, status, and comments
|
|
63
|
+
*/
|
|
64
|
+
private syncInternalUS;
|
|
65
|
+
/**
|
|
66
|
+
* Build completion comment with task/AC progress
|
|
67
|
+
*
|
|
68
|
+
* Format:
|
|
69
|
+
* ## Progress Update
|
|
70
|
+
*
|
|
71
|
+
* ### Completed Tasks
|
|
72
|
+
* - ✅ [T-001] Task title
|
|
73
|
+
* - ✅ [T-002] Another task
|
|
74
|
+
*
|
|
75
|
+
* ### Acceptance Criteria
|
|
76
|
+
* - ✅ **AC-US1-01**: Criteria description
|
|
77
|
+
* - ✅ **AC-US1-02**: Another criteria
|
|
78
|
+
*
|
|
79
|
+
* **Progress**: 8/11 tasks completed (73%)
|
|
80
|
+
*
|
|
81
|
+
* [View Living Docs](url)
|
|
82
|
+
*/
|
|
83
|
+
buildCompletionComment(data: CompletionCommentData): string;
|
|
84
|
+
/**
|
|
85
|
+
* Extract issue number from external_id
|
|
86
|
+
* Examples: "GH-#123" → 123, "#456" → 456
|
|
87
|
+
*/
|
|
88
|
+
private extractIssueNumber;
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=format-preservation-sync.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format-preservation-sync.d.ts","sourceRoot":"","sources":["../../../src/sync/format-preservation-sync.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,gBAAgB,EAAa,MAAM,iCAAiC,CAAC;AAC9E,OAAO,EAAE,cAAc,EAAE,MAAM,wDAAwD,CAAC;AACxF,OAAO,EAAE,UAAU,EAAE,MAAM,qCAAqC,CAAC;AACjE,OAAO,EAAE,SAAS,EAAE,MAAM,mCAAmC,CAAC;AAC9D,OAAO,EAAE,MAAM,EAAiB,MAAM,oBAAoB,CAAC;AAE3D,MAAM,WAAW,UAAU;IACzB,yEAAyE;IACzE,sBAAsB,CAAC,EAAE,OAAO,CAAC;IAEjC,+EAA+E;IAC/E,sBAAsB,CAAC,EAAE,OAAO,CAAC;IAEjC,6CAA6C;IAC7C,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,kBAAkB,EAAE,CAAC;IAC5B,kBAAkB,EAAE,gBAAgB,EAAE,CAAC;IACvC,kBAAkB,EAAE,MAAM,CAAC;IAC3B,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,qBAAa,6BAA6B;IACxC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,MAAM,CAAa;gBAGzB,MAAM,GAAE,UAAe,EACvB,OAAO,GAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAA;KAAO;IAUnC;;;;;OAKG;IACG,aAAa,CACjB,MAAM,EAAE,gBAAgB,EACxB,cAAc,EAAE,qBAAqB,EACrC,cAAc,EAAE,cAAc,GAAG,UAAU,GAAG,SAAS,GACtD,OAAO,CAAC,IAAI,CAAC;IAchB;;;;OAIG;YACW,cAAc;IA+B5B;;;;OAIG;YACW,cAAc;IAuC5B;;;;;;;;;;;;;;;;;OAiBG;IACH,sBAAsB,CAAC,IAAI,EAAE,qBAAqB,GAAG,MAAM;IA0C3D;;;OAGG;IACH,OAAO,CAAC,kBAAkB;CAI3B"}
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Format Preservation Sync Service (T-034B)
|
|
3
|
+
*
|
|
4
|
+
* Routes sync to comment-only mode for external items (preserves original format)
|
|
5
|
+
* and full sync mode for internal items (allows title/description updates).
|
|
6
|
+
*
|
|
7
|
+
* Architecture:
|
|
8
|
+
* - External US (origin=external): Comment-only sync (no title/description changes)
|
|
9
|
+
* - Internal US (origin=internal): Full sync (title, description, status, comments)
|
|
10
|
+
*/
|
|
11
|
+
import { getOrigin } from '../types/living-docs-us-file.js';
|
|
12
|
+
import { GitHubClientV2 } from '../../plugins/specweave-github/lib/github-client-v2.js';
|
|
13
|
+
import { JiraClient } from '../integrations/jira/jira-client.js';
|
|
14
|
+
import { AdoClient } from '../integrations/ado/ado-client.js';
|
|
15
|
+
import { consoleLogger } from '../utils/logger.js';
|
|
16
|
+
export class FormatPreservationSyncService {
|
|
17
|
+
constructor(config = {}, options = {}) {
|
|
18
|
+
this.config = {
|
|
19
|
+
canUpdateExternalItems: config.canUpdateExternalItems ?? false,
|
|
20
|
+
canUpsertInternalItems: config.canUpsertInternalItems ?? false,
|
|
21
|
+
canUpdateStatus: config.canUpdateStatus ?? false
|
|
22
|
+
};
|
|
23
|
+
this.logger = options.logger ?? consoleLogger;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Sync User Story to external tool with origin-based routing
|
|
27
|
+
*
|
|
28
|
+
* - External US (origin=external) → Comment-only sync
|
|
29
|
+
* - Internal US (origin=internal) → Full sync
|
|
30
|
+
*/
|
|
31
|
+
async syncUserStory(usFile, completionData, externalClient) {
|
|
32
|
+
const origin = getOrigin(usFile);
|
|
33
|
+
this.logger.log(`📊 Syncing ${usFile.id} (origin: ${origin})`);
|
|
34
|
+
if (origin === 'external') {
|
|
35
|
+
// External US: Comment-only sync (preserves format)
|
|
36
|
+
await this.syncExternalUS(usFile, completionData, externalClient);
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
// Internal US: Full sync (allows updates)
|
|
40
|
+
await this.syncInternalUS(usFile, completionData, externalClient);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Sync External US (Comment-only mode)
|
|
45
|
+
*
|
|
46
|
+
* Preserves original title/description, only adds completion comments
|
|
47
|
+
*/
|
|
48
|
+
async syncExternalUS(usFile, completionData, externalClient) {
|
|
49
|
+
this.logger.log(` 💬 External US: Comment-only sync (format preserved)`);
|
|
50
|
+
// Build completion comment
|
|
51
|
+
const comment = this.buildCompletionComment(completionData);
|
|
52
|
+
// Post comment to external tool
|
|
53
|
+
if (externalClient instanceof GitHubClientV2) {
|
|
54
|
+
const issueNumber = this.extractIssueNumber(usFile.external_id || '');
|
|
55
|
+
await externalClient.addComment(issueNumber, comment);
|
|
56
|
+
}
|
|
57
|
+
else if (externalClient instanceof JiraClient) {
|
|
58
|
+
const issueKey = usFile.external_id || '';
|
|
59
|
+
await externalClient.addComment(issueKey, comment);
|
|
60
|
+
}
|
|
61
|
+
else if (externalClient instanceof AdoClient) {
|
|
62
|
+
const workItemId = parseInt(usFile.external_id || '0', 10);
|
|
63
|
+
await externalClient.addComment(workItemId, comment);
|
|
64
|
+
}
|
|
65
|
+
// Conditional status update (only if config allows)
|
|
66
|
+
if (this.config.canUpdateStatus) {
|
|
67
|
+
this.logger.log(` ✅ Status update enabled`);
|
|
68
|
+
// TODO: Implement status update logic
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
this.logger.log(` ⏭️ Status update skipped (canUpdateStatus=false)`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Sync Internal US (Full sync mode)
|
|
76
|
+
*
|
|
77
|
+
* Allows updating title, description, status, and comments
|
|
78
|
+
*/
|
|
79
|
+
async syncInternalUS(usFile, completionData, externalClient) {
|
|
80
|
+
this.logger.log(` 🔄 Internal US: Full sync (updates allowed)`);
|
|
81
|
+
// Full sync: Update title, description, comments, status
|
|
82
|
+
if (this.config.canUpdateExternalItems) {
|
|
83
|
+
this.logger.log(` ✅ External updates enabled`);
|
|
84
|
+
// Build completion comment
|
|
85
|
+
const comment = this.buildCompletionComment(completionData);
|
|
86
|
+
// Post comment
|
|
87
|
+
if (externalClient instanceof GitHubClientV2) {
|
|
88
|
+
const issueNumber = this.extractIssueNumber(usFile.external_id || '');
|
|
89
|
+
await externalClient.addComment(issueNumber, comment);
|
|
90
|
+
// Update title/description if needed
|
|
91
|
+
// TODO: Implement title/description update logic
|
|
92
|
+
}
|
|
93
|
+
else if (externalClient instanceof JiraClient) {
|
|
94
|
+
const issueKey = usFile.external_id || '';
|
|
95
|
+
await externalClient.addComment(issueKey, comment);
|
|
96
|
+
}
|
|
97
|
+
else if (externalClient instanceof AdoClient) {
|
|
98
|
+
const workItemId = parseInt(usFile.external_id || '0', 10);
|
|
99
|
+
await externalClient.addComment(workItemId, comment);
|
|
100
|
+
}
|
|
101
|
+
// Update status if allowed
|
|
102
|
+
if (this.config.canUpdateStatus) {
|
|
103
|
+
this.logger.log(` ✅ Status update enabled`);
|
|
104
|
+
// TODO: Implement status update logic
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
this.logger.log(` ⏭️ External updates skipped (canUpdateExternalItems=false)`);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Build completion comment with task/AC progress
|
|
113
|
+
*
|
|
114
|
+
* Format:
|
|
115
|
+
* ## Progress Update
|
|
116
|
+
*
|
|
117
|
+
* ### Completed Tasks
|
|
118
|
+
* - ✅ [T-001] Task title
|
|
119
|
+
* - ✅ [T-002] Another task
|
|
120
|
+
*
|
|
121
|
+
* ### Acceptance Criteria
|
|
122
|
+
* - ✅ **AC-US1-01**: Criteria description
|
|
123
|
+
* - ✅ **AC-US1-02**: Another criteria
|
|
124
|
+
*
|
|
125
|
+
* **Progress**: 8/11 tasks completed (73%)
|
|
126
|
+
*
|
|
127
|
+
* [View Living Docs](url)
|
|
128
|
+
*/
|
|
129
|
+
buildCompletionComment(data) {
|
|
130
|
+
const lines = [];
|
|
131
|
+
lines.push('## Progress Update');
|
|
132
|
+
lines.push('');
|
|
133
|
+
// Completed tasks
|
|
134
|
+
const completedTasks = data.tasks.filter(t => t.completed);
|
|
135
|
+
if (completedTasks.length > 0) {
|
|
136
|
+
lines.push('### Completed Tasks');
|
|
137
|
+
lines.push('');
|
|
138
|
+
for (const task of completedTasks) {
|
|
139
|
+
lines.push(`- ✅ [${task.taskId}] ${task.title}`);
|
|
140
|
+
}
|
|
141
|
+
lines.push('');
|
|
142
|
+
}
|
|
143
|
+
// Acceptance criteria
|
|
144
|
+
const satisfiedACs = data.acceptanceCriteria.filter(ac => ac.satisfied);
|
|
145
|
+
if (satisfiedACs.length > 0) {
|
|
146
|
+
lines.push('### Acceptance Criteria');
|
|
147
|
+
lines.push('');
|
|
148
|
+
for (const ac of satisfiedACs) {
|
|
149
|
+
lines.push(`- ✅ **${ac.acId}**: ${ac.description}`);
|
|
150
|
+
}
|
|
151
|
+
lines.push('');
|
|
152
|
+
}
|
|
153
|
+
// Progress summary
|
|
154
|
+
const totalTasks = data.tasks.length;
|
|
155
|
+
const completed = completedTasks.length;
|
|
156
|
+
lines.push(`**Progress**: ${completed}/${totalTasks} tasks completed (${data.progressPercentage}%)`);
|
|
157
|
+
lines.push('');
|
|
158
|
+
// Living docs link
|
|
159
|
+
if (data.livingDocsUrl) {
|
|
160
|
+
lines.push(`[View Living Docs](${data.livingDocsUrl})`);
|
|
161
|
+
}
|
|
162
|
+
return lines.join('\n');
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Extract issue number from external_id
|
|
166
|
+
* Examples: "GH-#123" → 123, "#456" → 456
|
|
167
|
+
*/
|
|
168
|
+
extractIssueNumber(externalId) {
|
|
169
|
+
const match = externalId.match(/#(\d+)/);
|
|
170
|
+
return match ? parseInt(match[1], 10) : 0;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
//# sourceMappingURL=format-preservation-sync.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format-preservation-sync.js","sourceRoot":"","sources":["../../../src/sync/format-preservation-sync.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sync Module Exports
|
|
3
|
+
*/
|
|
4
|
+
export { FormatPreservationSyncService } from './format-preservation-sync.js';
|
|
5
|
+
export { SyncCoordinator } from './sync-coordinator.js';
|
|
6
|
+
export type { SyncConfig, CompletionCommentData } from './format-preservation-sync.js';
|
|
7
|
+
export type { SyncCoordinatorOptions, SyncResult } from './sync-coordinator.js';
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/sync/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,6BAA6B,EAAE,MAAM,+BAA+B,CAAC;AAC9E,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAExD,YAAY,EAAE,UAAU,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACvF,YAAY,EAAE,sBAAsB,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/sync/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,6BAA6B,EAAE,MAAM,+BAA+B,CAAC;AAC9E,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sync Coordinator (T-034E)
|
|
3
|
+
*
|
|
4
|
+
* High-level coordinator that integrates FormatPreservationSyncService
|
|
5
|
+
* with living docs sync workflow. Called by post-task-completion hook.
|
|
6
|
+
*/
|
|
7
|
+
import { Logger } from '../utils/logger.js';
|
|
8
|
+
export interface SyncCoordinatorOptions {
|
|
9
|
+
projectRoot: string;
|
|
10
|
+
incrementId: string;
|
|
11
|
+
logger?: Logger;
|
|
12
|
+
}
|
|
13
|
+
export interface SyncResult {
|
|
14
|
+
success: boolean;
|
|
15
|
+
userStoriesSynced: number;
|
|
16
|
+
syncMode: 'comment-only' | 'full-sync' | 'read-only';
|
|
17
|
+
errors: string[];
|
|
18
|
+
}
|
|
19
|
+
export declare class SyncCoordinator {
|
|
20
|
+
private projectRoot;
|
|
21
|
+
private incrementId;
|
|
22
|
+
private logger;
|
|
23
|
+
constructor(options: SyncCoordinatorOptions);
|
|
24
|
+
/**
|
|
25
|
+
* Sync increment completion to external tools using format preservation
|
|
26
|
+
*/
|
|
27
|
+
syncIncrementCompletion(): Promise<SyncResult>;
|
|
28
|
+
/**
|
|
29
|
+
* Sync individual user story
|
|
30
|
+
*/
|
|
31
|
+
private syncUserStory;
|
|
32
|
+
/**
|
|
33
|
+
* Load completion data for user story
|
|
34
|
+
*/
|
|
35
|
+
private loadCompletionData;
|
|
36
|
+
/**
|
|
37
|
+
* Load user stories affected by this increment
|
|
38
|
+
*/
|
|
39
|
+
private loadUserStoriesForIncrement;
|
|
40
|
+
/**
|
|
41
|
+
* Load config
|
|
42
|
+
*/
|
|
43
|
+
private loadConfig;
|
|
44
|
+
/**
|
|
45
|
+
* Detect GitHub repository from config or git
|
|
46
|
+
*/
|
|
47
|
+
private detectGitHubRepo;
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=sync-coordinator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync-coordinator.d.ts","sourceRoot":"","sources":["../../../src/sync/sync-coordinator.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAQH,OAAO,EAAE,MAAM,EAAiB,MAAM,oBAAoB,CAAC;AAE3D,MAAM,WAAW,sBAAsB;IACrC,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,QAAQ,EAAE,cAAc,GAAG,WAAW,GAAG,WAAW,CAAC;IACrD,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,MAAM,CAAS;gBAEX,OAAO,EAAE,sBAAsB;IAM3C;;OAEG;IACG,uBAAuB,IAAI,OAAO,CAAC,UAAU,CAAC;IA4EpD;;OAEG;YACW,aAAa;IA8B3B;;OAEG;YACW,kBAAkB;IAmEhC;;OAEG;YACW,2BAA2B;IAqEzC;;OAEG;YACW,UAAU;IAWxB;;OAEG;YACW,gBAAgB;CAyB/B"}
|