specweave 0.33.2 → 0.33.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/CLAUDE.md +56 -0
- package/dist/plugins/specweave-ado/lib/per-us-sync.d.ts +120 -0
- package/dist/plugins/specweave-ado/lib/per-us-sync.d.ts.map +1 -0
- package/dist/plugins/specweave-ado/lib/per-us-sync.js +276 -0
- package/dist/plugins/specweave-ado/lib/per-us-sync.js.map +1 -0
- package/dist/plugins/specweave-github/lib/github-client-v2.d.ts +4 -1
- package/dist/plugins/specweave-github/lib/github-client-v2.d.ts.map +1 -1
- package/dist/plugins/specweave-github/lib/github-client-v2.js +13 -3
- package/dist/plugins/specweave-github/lib/github-client-v2.js.map +1 -1
- package/dist/plugins/specweave-github/lib/per-us-sync.d.ts +97 -0
- package/dist/plugins/specweave-github/lib/per-us-sync.d.ts.map +1 -0
- package/dist/plugins/specweave-github/lib/per-us-sync.js +274 -0
- package/dist/plugins/specweave-github/lib/per-us-sync.js.map +1 -0
- package/dist/plugins/specweave-jira/lib/per-us-sync.d.ts +113 -0
- package/dist/plugins/specweave-jira/lib/per-us-sync.d.ts.map +1 -0
- package/dist/plugins/specweave-jira/lib/per-us-sync.js +254 -0
- package/dist/plugins/specweave-jira/lib/per-us-sync.js.map +1 -0
- package/dist/src/core/config/config-manager.d.ts.map +1 -1
- package/dist/src/core/config/config-manager.js +58 -0
- package/dist/src/core/config/config-manager.js.map +1 -1
- package/dist/src/core/config/types.d.ts +80 -0
- package/dist/src/core/config/types.d.ts.map +1 -1
- package/dist/src/core/config/types.js.map +1 -1
- package/dist/src/core/living-docs/cross-project-sync.d.ts +87 -15
- package/dist/src/core/living-docs/cross-project-sync.d.ts.map +1 -1
- package/dist/src/core/living-docs/cross-project-sync.js +147 -28
- package/dist/src/core/living-docs/cross-project-sync.js.map +1 -1
- package/dist/src/core/living-docs/living-docs-sync.d.ts.map +1 -1
- package/dist/src/core/living-docs/living-docs-sync.js +26 -22
- package/dist/src/core/living-docs/living-docs-sync.js.map +1 -1
- package/dist/src/core/living-docs/types.d.ts +24 -3
- package/dist/src/core/living-docs/types.d.ts.map +1 -1
- package/dist/src/core/types/config.d.ts +79 -0
- package/dist/src/core/types/config.d.ts.map +1 -1
- package/dist/src/core/types/config.js.map +1 -1
- package/dist/src/sync/sync-coordinator.d.ts +20 -0
- package/dist/src/sync/sync-coordinator.d.ts.map +1 -1
- package/dist/src/sync/sync-coordinator.js +258 -33
- package/dist/src/sync/sync-coordinator.js.map +1 -1
- package/dist/src/utils/project-resolver.d.ts +156 -0
- package/dist/src/utils/project-resolver.d.ts.map +1 -0
- package/dist/src/utils/project-resolver.js +587 -0
- package/dist/src/utils/project-resolver.js.map +1 -0
- package/package.json +1 -1
- package/plugins/specweave/hooks/hooks.json +10 -0
- package/plugins/specweave/hooks/user-prompt-submit.sh +105 -3
- package/plugins/specweave/hooks/v2/guards/per-us-project-validator.sh +281 -0
- package/plugins/specweave/hooks/v2/handlers/living-specs-handler.sh +29 -0
- package/plugins/specweave-ado/lib/per-us-sync.js +247 -0
- package/plugins/specweave-ado/lib/per-us-sync.ts +410 -0
- package/plugins/specweave-github/lib/github-client-v2.js +10 -3
- package/plugins/specweave-github/lib/github-client-v2.ts +15 -3
- package/plugins/specweave-github/lib/per-us-sync.js +241 -0
- package/plugins/specweave-github/lib/per-us-sync.ts +375 -0
- package/plugins/specweave-jira/lib/per-us-sync.js +224 -0
- package/plugins/specweave-jira/lib/per-us-sync.ts +366 -0
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-US GitHub Sync (v0.34.0+)
|
|
3
|
+
*
|
|
4
|
+
* Syncs each User Story to its explicitly declared project's GitHub repo.
|
|
5
|
+
* Uses the **Project**: field in spec.md (NOT keyword-based classification).
|
|
6
|
+
*
|
|
7
|
+
* Key difference from multi-project-sync:
|
|
8
|
+
* - Multi-project sync uses keyword/heuristic classification
|
|
9
|
+
* - Per-US sync uses EXPLICIT **Project**: field from spec.md
|
|
10
|
+
*
|
|
11
|
+
* @module per-us-sync
|
|
12
|
+
* @since v0.34.0
|
|
13
|
+
*/
|
|
14
|
+
import type { UserStoryData } from '../../../src/core/living-docs/types.js';
|
|
15
|
+
import type { ProjectMappings } from '../../../src/core/types/config.js';
|
|
16
|
+
import type { USExternalRefsMap } from '../../../src/core/types/increment-metadata.js';
|
|
17
|
+
import { Logger } from '../../../src/utils/logger.js';
|
|
18
|
+
/**
|
|
19
|
+
* Result of syncing a single US to GitHub
|
|
20
|
+
*/
|
|
21
|
+
export interface USSyncResult {
|
|
22
|
+
usId: string;
|
|
23
|
+
projectId: string;
|
|
24
|
+
repo: string;
|
|
25
|
+
issueNumber: number;
|
|
26
|
+
url: string;
|
|
27
|
+
action: 'created' | 'updated' | 'skipped';
|
|
28
|
+
error?: string;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Result of syncing all USs in an increment
|
|
32
|
+
*/
|
|
33
|
+
export interface PerUSSyncResult {
|
|
34
|
+
success: boolean;
|
|
35
|
+
synced: USSyncResult[];
|
|
36
|
+
failed: USSyncResult[];
|
|
37
|
+
externalRefs: USExternalRefsMap;
|
|
38
|
+
summary: {
|
|
39
|
+
total: number;
|
|
40
|
+
created: number;
|
|
41
|
+
updated: number;
|
|
42
|
+
skipped: number;
|
|
43
|
+
failed: number;
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Options for per-US sync
|
|
48
|
+
*/
|
|
49
|
+
export interface PerUSSyncOptions {
|
|
50
|
+
dryRun?: boolean;
|
|
51
|
+
force?: boolean;
|
|
52
|
+
defaultProject?: string;
|
|
53
|
+
logger?: Logger;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Per-US GitHub Sync
|
|
57
|
+
*
|
|
58
|
+
* Syncs each US to its declared project's GitHub repository.
|
|
59
|
+
*/
|
|
60
|
+
export declare class PerUSGitHubSync {
|
|
61
|
+
private token;
|
|
62
|
+
private projectMappings;
|
|
63
|
+
private octokit;
|
|
64
|
+
private logger;
|
|
65
|
+
constructor(token: string, projectMappings: ProjectMappings, options?: {
|
|
66
|
+
logger?: Logger;
|
|
67
|
+
});
|
|
68
|
+
/**
|
|
69
|
+
* Sync all user stories to their respective GitHub repos
|
|
70
|
+
*
|
|
71
|
+
* @param userStories - User stories with explicit project fields
|
|
72
|
+
* @param featureId - Feature ID (e.g., "FS-137")
|
|
73
|
+
* @param options - Sync options
|
|
74
|
+
*/
|
|
75
|
+
syncUserStories(userStories: UserStoryData[], featureId: string, options?: PerUSSyncOptions): Promise<PerUSSyncResult>;
|
|
76
|
+
/**
|
|
77
|
+
* Sync a single user story to GitHub
|
|
78
|
+
*/
|
|
79
|
+
private syncUserStory;
|
|
80
|
+
/**
|
|
81
|
+
* Find existing issue by US ID in title
|
|
82
|
+
*/
|
|
83
|
+
private findExistingIssue;
|
|
84
|
+
/**
|
|
85
|
+
* Build issue body from user story
|
|
86
|
+
*/
|
|
87
|
+
private buildIssueBody;
|
|
88
|
+
/**
|
|
89
|
+
* Group user stories by their explicit project field
|
|
90
|
+
*/
|
|
91
|
+
private groupByProject;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Format per-US sync results for display
|
|
95
|
+
*/
|
|
96
|
+
export declare function formatPerUSSyncResults(result: PerUSSyncResult): string;
|
|
97
|
+
//# sourceMappingURL=per-us-sync.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"per-us-sync.d.ts","sourceRoot":"","sources":["../../../../plugins/specweave-github/lib/per-us-sync.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wCAAwC,CAAC;AAC5E,OAAO,KAAK,EAAE,eAAe,EAAiB,MAAM,mCAAmC,CAAC;AACxF,OAAO,KAAK,EAAiB,iBAAiB,EAAE,MAAM,+CAA+C,CAAC;AACtG,OAAO,EAAE,MAAM,EAAiB,MAAM,8BAA8B,CAAC;AAErE;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC;IAC1C,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,YAAY,EAAE,iBAAiB,CAAC;IAChC,OAAO,EAAE;QACP,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;GAIG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,eAAe,CAAkB;IACzC,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,MAAM,CAAS;gBAGrB,KAAK,EAAE,MAAM,EACb,eAAe,EAAE,eAAe,EAChC,OAAO,GAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAA;KAAO;IAQnC;;;;;;OAMG;IACG,eAAe,CACnB,WAAW,EAAE,aAAa,EAAE,EAC5B,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,gBAAqB,GAC7B,OAAO,CAAC,eAAe,CAAC;IAsF3B;;OAEG;YACW,aAAa;IAmE3B;;OAEG;YACW,iBAAiB;IAuB/B;;OAEG;IACH,OAAO,CAAC,cAAc;IAoCtB;;OAEG;IACH,OAAO,CAAC,cAAc;CAiBvB;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM,CAmCtE"}
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-US GitHub Sync (v0.34.0+)
|
|
3
|
+
*
|
|
4
|
+
* Syncs each User Story to its explicitly declared project's GitHub repo.
|
|
5
|
+
* Uses the **Project**: field in spec.md (NOT keyword-based classification).
|
|
6
|
+
*
|
|
7
|
+
* Key difference from multi-project-sync:
|
|
8
|
+
* - Multi-project sync uses keyword/heuristic classification
|
|
9
|
+
* - Per-US sync uses EXPLICIT **Project**: field from spec.md
|
|
10
|
+
*
|
|
11
|
+
* @module per-us-sync
|
|
12
|
+
* @since v0.34.0
|
|
13
|
+
*/
|
|
14
|
+
import { Octokit } from '@octokit/rest';
|
|
15
|
+
import { consoleLogger } from '../../../src/utils/logger.js';
|
|
16
|
+
/**
|
|
17
|
+
* Per-US GitHub Sync
|
|
18
|
+
*
|
|
19
|
+
* Syncs each US to its declared project's GitHub repository.
|
|
20
|
+
*/
|
|
21
|
+
export class PerUSGitHubSync {
|
|
22
|
+
constructor(token, projectMappings, options = {}) {
|
|
23
|
+
this.token = token;
|
|
24
|
+
this.projectMappings = projectMappings;
|
|
25
|
+
this.octokit = new Octokit({ auth: token });
|
|
26
|
+
this.logger = options.logger ?? consoleLogger;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Sync all user stories to their respective GitHub repos
|
|
30
|
+
*
|
|
31
|
+
* @param userStories - User stories with explicit project fields
|
|
32
|
+
* @param featureId - Feature ID (e.g., "FS-137")
|
|
33
|
+
* @param options - Sync options
|
|
34
|
+
*/
|
|
35
|
+
async syncUserStories(userStories, featureId, options = {}) {
|
|
36
|
+
const synced = [];
|
|
37
|
+
const failed = [];
|
|
38
|
+
const externalRefs = {};
|
|
39
|
+
// Group USs by their declared project
|
|
40
|
+
const groups = this.groupByProject(userStories, options.defaultProject);
|
|
41
|
+
this.logger.log(`📡 Per-US GitHub Sync: ${userStories.length} USs across ${groups.size} projects`);
|
|
42
|
+
for (const [projectId, stories] of groups) {
|
|
43
|
+
// Get GitHub mapping for this project
|
|
44
|
+
const mapping = this.projectMappings[projectId]?.github;
|
|
45
|
+
if (!mapping) {
|
|
46
|
+
// No GitHub mapping for this project
|
|
47
|
+
this.logger.warn(` ⚠️ No GitHub mapping for project "${projectId}" - skipping ${stories.length} USs`);
|
|
48
|
+
for (const story of stories) {
|
|
49
|
+
failed.push({
|
|
50
|
+
usId: story.id,
|
|
51
|
+
projectId,
|
|
52
|
+
repo: 'N/A',
|
|
53
|
+
issueNumber: 0,
|
|
54
|
+
url: '',
|
|
55
|
+
action: 'skipped',
|
|
56
|
+
error: `No GitHub mapping for project "${projectId}"`
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
// Sync each US to this project's repo
|
|
62
|
+
for (const story of stories) {
|
|
63
|
+
try {
|
|
64
|
+
const result = await this.syncUserStory(story, mapping, featureId, options);
|
|
65
|
+
synced.push({
|
|
66
|
+
...result,
|
|
67
|
+
projectId
|
|
68
|
+
});
|
|
69
|
+
// Build external ref
|
|
70
|
+
if (!options.dryRun && result.action !== 'skipped') {
|
|
71
|
+
externalRefs[story.id] = {
|
|
72
|
+
github: {
|
|
73
|
+
provider: 'github',
|
|
74
|
+
issueNumber: result.issueNumber,
|
|
75
|
+
url: result.url,
|
|
76
|
+
targetProject: projectId,
|
|
77
|
+
lastSynced: new Date().toISOString()
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
catch (error) {
|
|
83
|
+
failed.push({
|
|
84
|
+
usId: story.id,
|
|
85
|
+
projectId,
|
|
86
|
+
repo: `${mapping.owner}/${mapping.repo}`,
|
|
87
|
+
issueNumber: 0,
|
|
88
|
+
url: '',
|
|
89
|
+
action: 'skipped',
|
|
90
|
+
error: error instanceof Error ? error.message : String(error)
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
// Calculate summary
|
|
96
|
+
const created = synced.filter(r => r.action === 'created').length;
|
|
97
|
+
const updated = synced.filter(r => r.action === 'updated').length;
|
|
98
|
+
const skipped = synced.filter(r => r.action === 'skipped').length;
|
|
99
|
+
return {
|
|
100
|
+
success: failed.length === 0,
|
|
101
|
+
synced,
|
|
102
|
+
failed,
|
|
103
|
+
externalRefs,
|
|
104
|
+
summary: {
|
|
105
|
+
total: userStories.length,
|
|
106
|
+
created,
|
|
107
|
+
updated,
|
|
108
|
+
skipped,
|
|
109
|
+
failed: failed.length
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Sync a single user story to GitHub
|
|
115
|
+
*/
|
|
116
|
+
async syncUserStory(story, mapping, featureId, options) {
|
|
117
|
+
const title = `[${featureId}][${story.id}] ${story.title}`;
|
|
118
|
+
const body = this.buildIssueBody(story, featureId);
|
|
119
|
+
if (options.dryRun) {
|
|
120
|
+
this.logger.log(` 🔍 [DRY-RUN] Would sync ${story.id} to ${mapping.owner}/${mapping.repo}`);
|
|
121
|
+
return {
|
|
122
|
+
usId: story.id,
|
|
123
|
+
projectId: story.project || 'unknown',
|
|
124
|
+
repo: `${mapping.owner}/${mapping.repo}`,
|
|
125
|
+
issueNumber: 0,
|
|
126
|
+
url: '',
|
|
127
|
+
action: 'skipped'
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
// Check for existing issue
|
|
131
|
+
const existingIssue = await this.findExistingIssue(mapping, story.id);
|
|
132
|
+
if (existingIssue) {
|
|
133
|
+
// Update existing issue
|
|
134
|
+
const response = await this.octokit.issues.update({
|
|
135
|
+
owner: mapping.owner,
|
|
136
|
+
repo: mapping.repo,
|
|
137
|
+
issue_number: existingIssue.number,
|
|
138
|
+
title,
|
|
139
|
+
body
|
|
140
|
+
});
|
|
141
|
+
this.logger.log(` 🔄 Updated ${story.id} → ${mapping.owner}/${mapping.repo}#${response.data.number}`);
|
|
142
|
+
return {
|
|
143
|
+
usId: story.id,
|
|
144
|
+
projectId: story.project || 'unknown',
|
|
145
|
+
repo: `${mapping.owner}/${mapping.repo}`,
|
|
146
|
+
issueNumber: response.data.number,
|
|
147
|
+
url: response.data.html_url,
|
|
148
|
+
action: 'updated'
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
// Create new issue
|
|
153
|
+
const response = await this.octokit.issues.create({
|
|
154
|
+
owner: mapping.owner,
|
|
155
|
+
repo: mapping.repo,
|
|
156
|
+
title,
|
|
157
|
+
body,
|
|
158
|
+
labels: ['specweave', 'user-story']
|
|
159
|
+
});
|
|
160
|
+
this.logger.log(` ✅ Created ${story.id} → ${mapping.owner}/${mapping.repo}#${response.data.number}`);
|
|
161
|
+
return {
|
|
162
|
+
usId: story.id,
|
|
163
|
+
projectId: story.project || 'unknown',
|
|
164
|
+
repo: `${mapping.owner}/${mapping.repo}`,
|
|
165
|
+
issueNumber: response.data.number,
|
|
166
|
+
url: response.data.html_url,
|
|
167
|
+
action: 'created'
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Find existing issue by US ID in title
|
|
173
|
+
*/
|
|
174
|
+
async findExistingIssue(mapping, usId) {
|
|
175
|
+
try {
|
|
176
|
+
const response = await this.octokit.issues.listForRepo({
|
|
177
|
+
owner: mapping.owner,
|
|
178
|
+
repo: mapping.repo,
|
|
179
|
+
labels: 'specweave',
|
|
180
|
+
state: 'all',
|
|
181
|
+
per_page: 100
|
|
182
|
+
});
|
|
183
|
+
const existing = response.data.find(issue => issue.title.includes(`[${usId}]`));
|
|
184
|
+
return existing ? { number: existing.number } : null;
|
|
185
|
+
}
|
|
186
|
+
catch {
|
|
187
|
+
return null;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Build issue body from user story
|
|
192
|
+
*/
|
|
193
|
+
buildIssueBody(story, featureId) {
|
|
194
|
+
const lines = [];
|
|
195
|
+
lines.push(`# ${story.title}`);
|
|
196
|
+
lines.push('');
|
|
197
|
+
if (story.description) {
|
|
198
|
+
lines.push(story.description);
|
|
199
|
+
lines.push('');
|
|
200
|
+
}
|
|
201
|
+
if (story.acceptanceCriteria && story.acceptanceCriteria.length > 0) {
|
|
202
|
+
lines.push('## Acceptance Criteria');
|
|
203
|
+
lines.push('');
|
|
204
|
+
for (const ac of story.acceptanceCriteria) {
|
|
205
|
+
lines.push(`- [ ] ${ac}`);
|
|
206
|
+
}
|
|
207
|
+
lines.push('');
|
|
208
|
+
}
|
|
209
|
+
lines.push('---');
|
|
210
|
+
lines.push('');
|
|
211
|
+
lines.push(`**Feature**: ${featureId}`);
|
|
212
|
+
lines.push(`**User Story**: ${story.id}`);
|
|
213
|
+
if (story.project) {
|
|
214
|
+
lines.push(`**Project**: ${story.project}`);
|
|
215
|
+
}
|
|
216
|
+
if (story.board) {
|
|
217
|
+
lines.push(`**Board**: ${story.board}`);
|
|
218
|
+
}
|
|
219
|
+
lines.push('');
|
|
220
|
+
lines.push('🤖 Auto-generated by SpecWeave');
|
|
221
|
+
return lines.join('\n');
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Group user stories by their explicit project field
|
|
225
|
+
*/
|
|
226
|
+
groupByProject(userStories, defaultProject) {
|
|
227
|
+
const groups = new Map();
|
|
228
|
+
for (const story of userStories) {
|
|
229
|
+
const project = story.project || defaultProject || 'default';
|
|
230
|
+
if (!groups.has(project)) {
|
|
231
|
+
groups.set(project, []);
|
|
232
|
+
}
|
|
233
|
+
groups.get(project).push(story);
|
|
234
|
+
}
|
|
235
|
+
return groups;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Format per-US sync results for display
|
|
240
|
+
*/
|
|
241
|
+
export function formatPerUSSyncResults(result) {
|
|
242
|
+
const lines = [];
|
|
243
|
+
lines.push('');
|
|
244
|
+
lines.push('📊 Per-US GitHub Sync Results');
|
|
245
|
+
lines.push('');
|
|
246
|
+
// Group by project
|
|
247
|
+
const byProject = new Map();
|
|
248
|
+
for (const r of [...result.synced, ...result.failed]) {
|
|
249
|
+
const existing = byProject.get(r.projectId) || [];
|
|
250
|
+
existing.push(r);
|
|
251
|
+
byProject.set(r.projectId, existing);
|
|
252
|
+
}
|
|
253
|
+
for (const [projectId, results] of byProject) {
|
|
254
|
+
lines.push(`**${projectId}**:`);
|
|
255
|
+
for (const r of results) {
|
|
256
|
+
const icon = r.action === 'created' ? '✅' :
|
|
257
|
+
r.action === 'updated' ? '🔄' :
|
|
258
|
+
r.error ? '❌' : '⏭️';
|
|
259
|
+
if (r.issueNumber > 0) {
|
|
260
|
+
lines.push(` ${icon} ${r.usId} → ${r.repo}#${r.issueNumber}`);
|
|
261
|
+
}
|
|
262
|
+
else if (r.error) {
|
|
263
|
+
lines.push(` ${icon} ${r.usId}: ${r.error}`);
|
|
264
|
+
}
|
|
265
|
+
else {
|
|
266
|
+
lines.push(` ${icon} ${r.usId} (${r.action})`);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
lines.push('');
|
|
270
|
+
}
|
|
271
|
+
lines.push(`📈 Summary: ${result.summary.created} created, ${result.summary.updated} updated, ${result.summary.failed} failed`);
|
|
272
|
+
return lines.join('\n');
|
|
273
|
+
}
|
|
274
|
+
//# sourceMappingURL=per-us-sync.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"per-us-sync.js","sourceRoot":"","sources":["../../../../plugins/specweave-github/lib/per-us-sync.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-US JIRA Sync (v0.34.0+)
|
|
3
|
+
*
|
|
4
|
+
* Syncs each User Story to its explicitly declared project's JIRA project.
|
|
5
|
+
* Uses the **Project**: field in spec.md (NOT keyword-based classification).
|
|
6
|
+
*
|
|
7
|
+
* Key difference from multi-project-sync:
|
|
8
|
+
* - Multi-project sync uses keyword/heuristic classification
|
|
9
|
+
* - Per-US sync uses EXPLICIT **Project**: field from spec.md
|
|
10
|
+
*
|
|
11
|
+
* @module per-us-sync
|
|
12
|
+
* @since v0.34.0
|
|
13
|
+
*/
|
|
14
|
+
import type { UserStoryData } from '../../../src/core/living-docs/types.js';
|
|
15
|
+
import type { ProjectMappings } from '../../../src/core/types/config.js';
|
|
16
|
+
import type { USExternalRefsMap } from '../../../src/core/types/increment-metadata.js';
|
|
17
|
+
import { Logger } from '../../../src/utils/logger.js';
|
|
18
|
+
/**
|
|
19
|
+
* Result of syncing a single US to JIRA
|
|
20
|
+
*/
|
|
21
|
+
export interface USSyncResult {
|
|
22
|
+
usId: string;
|
|
23
|
+
projectId: string;
|
|
24
|
+
jiraProject: string;
|
|
25
|
+
issueKey: string;
|
|
26
|
+
url: string;
|
|
27
|
+
action: 'created' | 'updated' | 'skipped';
|
|
28
|
+
error?: string;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Result of syncing all USs in an increment
|
|
32
|
+
*/
|
|
33
|
+
export interface PerUSSyncResult {
|
|
34
|
+
success: boolean;
|
|
35
|
+
synced: USSyncResult[];
|
|
36
|
+
failed: USSyncResult[];
|
|
37
|
+
externalRefs: USExternalRefsMap;
|
|
38
|
+
summary: {
|
|
39
|
+
total: number;
|
|
40
|
+
created: number;
|
|
41
|
+
updated: number;
|
|
42
|
+
skipped: number;
|
|
43
|
+
failed: number;
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Options for per-US sync
|
|
48
|
+
*/
|
|
49
|
+
export interface PerUSSyncOptions {
|
|
50
|
+
dryRun?: boolean;
|
|
51
|
+
force?: boolean;
|
|
52
|
+
defaultProject?: string;
|
|
53
|
+
logger?: Logger;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* JIRA client interface (to be injected)
|
|
57
|
+
*/
|
|
58
|
+
export interface JiraClient {
|
|
59
|
+
createIssue(project: string, issueType: string, summary: string, description: string): Promise<{
|
|
60
|
+
key: string;
|
|
61
|
+
self: string;
|
|
62
|
+
}>;
|
|
63
|
+
updateIssue(issueKey: string, summary: string, description: string): Promise<void>;
|
|
64
|
+
searchIssues(jql: string): Promise<Array<{
|
|
65
|
+
key: string;
|
|
66
|
+
fields: {
|
|
67
|
+
summary: string;
|
|
68
|
+
};
|
|
69
|
+
}>>;
|
|
70
|
+
getIssueUrl(issueKey: string): string;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Per-US JIRA Sync
|
|
74
|
+
*
|
|
75
|
+
* Syncs each US to its declared project's JIRA project.
|
|
76
|
+
*/
|
|
77
|
+
export declare class PerUSJiraSync {
|
|
78
|
+
private projectMappings;
|
|
79
|
+
private jiraClient;
|
|
80
|
+
private logger;
|
|
81
|
+
constructor(jiraClient: JiraClient, projectMappings: ProjectMappings, options?: {
|
|
82
|
+
logger?: Logger;
|
|
83
|
+
});
|
|
84
|
+
/**
|
|
85
|
+
* Sync all user stories to their respective JIRA projects
|
|
86
|
+
*
|
|
87
|
+
* @param userStories - User stories with explicit project fields
|
|
88
|
+
* @param featureId - Feature ID (e.g., "FS-137")
|
|
89
|
+
* @param options - Sync options
|
|
90
|
+
*/
|
|
91
|
+
syncUserStories(userStories: UserStoryData[], featureId: string, options?: PerUSSyncOptions): Promise<PerUSSyncResult>;
|
|
92
|
+
/**
|
|
93
|
+
* Sync a single user story to JIRA
|
|
94
|
+
*/
|
|
95
|
+
private syncUserStory;
|
|
96
|
+
/**
|
|
97
|
+
* Find existing issue by US ID in summary
|
|
98
|
+
*/
|
|
99
|
+
private findExistingIssue;
|
|
100
|
+
/**
|
|
101
|
+
* Build issue description from user story
|
|
102
|
+
*/
|
|
103
|
+
private buildIssueDescription;
|
|
104
|
+
/**
|
|
105
|
+
* Group user stories by their explicit project field
|
|
106
|
+
*/
|
|
107
|
+
private groupByProject;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Format per-US sync results for display
|
|
111
|
+
*/
|
|
112
|
+
export declare function formatPerUSSyncResults(result: PerUSSyncResult): string;
|
|
113
|
+
//# sourceMappingURL=per-us-sync.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"per-us-sync.d.ts","sourceRoot":"","sources":["../../../../plugins/specweave-jira/lib/per-us-sync.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wCAAwC,CAAC;AAC5E,OAAO,KAAK,EAAE,eAAe,EAAe,MAAM,mCAAmC,CAAC;AACtF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,+CAA+C,CAAC;AACvF,OAAO,EAAE,MAAM,EAAiB,MAAM,8BAA8B,CAAC;AAErE;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC;IAC1C,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,YAAY,EAAE,iBAAiB,CAAC;IAChC,OAAO,EAAE;QACP,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC9H,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnF,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE;YAAE,OAAO,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,CAAC,CAAC,CAAC;IACxF,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC;CACvC;AAED;;;;GAIG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,eAAe,CAAkB;IACzC,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,MAAM,CAAS;gBAGrB,UAAU,EAAE,UAAU,EACtB,eAAe,EAAE,eAAe,EAChC,OAAO,GAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAA;KAAO;IAOnC;;;;;;OAMG;IACG,eAAe,CACnB,WAAW,EAAE,aAAa,EAAE,EAC5B,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,gBAAqB,GAC7B,OAAO,CAAC,eAAe,CAAC;IAsF3B;;OAEG;YACW,aAAa;IA4D3B;;OAEG;YACW,iBAAiB;IAc/B;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAoC7B;;OAEG;IACH,OAAO,CAAC,cAAc;CAiBvB;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM,CAmCtE"}
|