specweave 1.0.30 → 1.0.32
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 +140 -1235
- package/bin/specweave.js +23 -0
- package/dist/plugins/specweave-github/lib/github-client-v2.d.ts +3 -0
- package/dist/plugins/specweave-github/lib/github-client-v2.d.ts.map +1 -1
- package/dist/plugins/specweave-github/lib/github-client-v2.js +39 -0
- package/dist/plugins/specweave-github/lib/github-client-v2.js.map +1 -1
- package/dist/src/cli/commands/set-sync-target.d.ts +41 -0
- package/dist/src/cli/commands/set-sync-target.d.ts.map +1 -0
- package/dist/src/cli/commands/set-sync-target.js +126 -0
- package/dist/src/cli/commands/set-sync-target.js.map +1 -0
- 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 +5 -8
- package/dist/src/cli/helpers/issue-tracker/github-multi-repo.js.map +1 -1
- package/dist/src/core/hooks/HookScanner.d.ts +32 -0
- package/dist/src/core/hooks/HookScanner.d.ts.map +1 -1
- package/dist/src/core/hooks/HookScanner.js +125 -1
- package/dist/src/core/hooks/HookScanner.js.map +1 -1
- package/dist/src/core/hooks/types.d.ts +10 -1
- package/dist/src/core/hooks/types.d.ts.map +1 -1
- package/dist/src/core/increment/metadata-manager.d.ts +67 -1
- package/dist/src/core/increment/metadata-manager.d.ts.map +1 -1
- package/dist/src/core/increment/metadata-manager.js +93 -0
- package/dist/src/core/increment/metadata-manager.js.map +1 -1
- package/dist/src/core/project/index.d.ts +21 -0
- package/dist/src/core/project/index.d.ts.map +1 -0
- package/dist/src/core/project/index.js +22 -0
- package/dist/src/core/project/index.js.map +1 -0
- package/dist/src/core/project/project-service.d.ts +122 -0
- package/dist/src/core/project/project-service.d.ts.map +1 -0
- package/dist/src/core/project/project-service.js +334 -0
- package/dist/src/core/project/project-service.js.map +1 -0
- package/dist/src/core/sync/external-tool-resolver.d.ts +171 -0
- package/dist/src/core/sync/external-tool-resolver.d.ts.map +1 -0
- package/dist/src/core/sync/external-tool-resolver.js +569 -0
- package/dist/src/core/sync/external-tool-resolver.js.map +1 -0
- package/dist/src/core/types/increment-metadata.d.ts +92 -0
- package/dist/src/core/types/increment-metadata.d.ts.map +1 -1
- package/dist/src/hooks/processor.d.ts +7 -3
- package/dist/src/hooks/processor.d.ts.map +1 -1
- package/dist/src/hooks/processor.js +11 -5
- package/dist/src/hooks/processor.js.map +1 -1
- package/package.json +1 -1
- package/plugins/specweave/hooks/hooks.json +0 -69
- package/plugins/specweave/hooks/v2/handlers/project-bridge-handler.sh +96 -0
- package/plugins/specweave/hooks/v2/queue/processor.sh +13 -5
- package/plugins/specweave/lib/hooks/project-bridge.js +76 -0
- package/plugins/specweave/lib/hooks/update-tasks-md.js +0 -0
- package/plugins/specweave/lib/hooks/us-completion-orchestrator.js +0 -0
- package/plugins/specweave/lib/vendor/core/increment/metadata-manager.d.ts +67 -1
- package/plugins/specweave/lib/vendor/core/increment/metadata-manager.js +93 -0
- package/plugins/specweave/lib/vendor/core/increment/metadata-manager.js.map +1 -1
- package/plugins/specweave/lib/vendor/core/types/increment-metadata.d.ts +92 -0
- package/plugins/specweave-github/lib/github-client-v2.js +39 -0
- package/plugins/specweave-github/lib/github-client-v2.ts +44 -0
- package/plugins/specweave/hooks/docs-changed.sh +0 -87
- package/plugins/specweave/hooks/human-input-required.sh +0 -83
- package/plugins/specweave/hooks/post-edit-write-consolidated.sh +0 -428
- package/plugins/specweave/hooks/post-first-increment.sh +0 -61
- package/plugins/specweave/hooks/post-increment-change.sh +0 -103
- package/plugins/specweave/hooks/post-increment-completion.sh +0 -513
- package/plugins/specweave/hooks/post-increment-planning.sh +0 -1204
- package/plugins/specweave/hooks/post-increment-status-change.sh +0 -243
- package/plugins/specweave/hooks/post-metadata-change.sh +0 -246
- package/plugins/specweave/hooks/post-spec-update.sh +0 -158
- package/plugins/specweave/hooks/post-task-completion.sh +0 -557
- package/plugins/specweave/hooks/post-task-edit.sh +0 -47
- package/plugins/specweave/hooks/post-user-story-complete.sh +0 -230
- package/plugins/specweave/hooks/pre-command-deduplication.sh +0 -68
- package/plugins/specweave/hooks/pre-edit-write-consolidated.sh +0 -225
- package/plugins/specweave/hooks/pre-implementation.sh +0 -75
- package/plugins/specweave/hooks/pre-increment-start.sh +0 -173
- package/plugins/specweave/hooks/pre-task-completion-edit.sh +0 -355
- package/plugins/specweave/hooks/pre-task-completion.sh +0 -269
- package/plugins/specweave/hooks/pre-tool-use.sh +0 -137
- package/plugins/specweave/hooks/session-start-reconcile.sh +0 -139
- package/plugins/specweave/hooks/shared/bulk-operation-detector.sh +0 -167
- package/plugins/specweave/hooks/test-pretooluse-env.sh +0 -72
- package/plugins/specweave/hooks/validate-increment-completion.sh +0 -113
- package/plugins/specweave/lib/hooks/consolidated-sync.js +0 -288
|
@@ -0,0 +1,569 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External Tool Resolver Service (v1.0.31+ - ADR-0211)
|
|
3
|
+
*
|
|
4
|
+
* Single source of truth for external tool selection.
|
|
5
|
+
* Resolves which sync profile an increment should use based on:
|
|
6
|
+
* 1. Explicit syncTarget in metadata (highest priority)
|
|
7
|
+
* 2. Project mapping from spec.md **Project**: field
|
|
8
|
+
* 3. Default profile from config (fallback)
|
|
9
|
+
*
|
|
10
|
+
* @module core/sync/external-tool-resolver
|
|
11
|
+
*/
|
|
12
|
+
import * as fs from '../../utils/fs-native.js';
|
|
13
|
+
import * as path from 'path';
|
|
14
|
+
import { consoleLogger } from '../../utils/logger.js';
|
|
15
|
+
/**
|
|
16
|
+
* External Tool Resolver
|
|
17
|
+
*
|
|
18
|
+
* Provides unified external tool selection logic.
|
|
19
|
+
* Use this service instead of scattered logic throughout the codebase.
|
|
20
|
+
*/
|
|
21
|
+
export class ExternalToolResolver {
|
|
22
|
+
constructor(projectRoot, options = {}) {
|
|
23
|
+
this.config = null;
|
|
24
|
+
this.projectRoot = projectRoot;
|
|
25
|
+
this.configPath = path.join(projectRoot, '.specweave', 'config.json');
|
|
26
|
+
this.logger = options.logger ?? consoleLogger;
|
|
27
|
+
}
|
|
28
|
+
// ==========================================================================
|
|
29
|
+
// Config Loading
|
|
30
|
+
// ==========================================================================
|
|
31
|
+
/**
|
|
32
|
+
* Load configuration from disk
|
|
33
|
+
*/
|
|
34
|
+
async loadConfig() {
|
|
35
|
+
if (this.config) {
|
|
36
|
+
return this.config;
|
|
37
|
+
}
|
|
38
|
+
try {
|
|
39
|
+
const content = await fs.readFile(this.configPath, 'utf-8');
|
|
40
|
+
this.config = JSON.parse(content);
|
|
41
|
+
return this.config;
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
if (error.code === 'ENOENT') {
|
|
45
|
+
this.config = {};
|
|
46
|
+
return this.config;
|
|
47
|
+
}
|
|
48
|
+
throw error;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Get sync configuration
|
|
53
|
+
*/
|
|
54
|
+
async getSyncConfig() {
|
|
55
|
+
const config = await this.loadConfig();
|
|
56
|
+
return config.sync || null;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Get project mappings
|
|
60
|
+
*/
|
|
61
|
+
async getProjectMappings() {
|
|
62
|
+
const config = await this.loadConfig();
|
|
63
|
+
return config.projectMappings || {};
|
|
64
|
+
}
|
|
65
|
+
// ==========================================================================
|
|
66
|
+
// Resolution Methods
|
|
67
|
+
// ==========================================================================
|
|
68
|
+
/**
|
|
69
|
+
* Resolve external tool for an increment
|
|
70
|
+
*
|
|
71
|
+
* Resolution priority:
|
|
72
|
+
* 1. Explicit syncTarget in metadata
|
|
73
|
+
* 2. Project mapping from spec.md **Project**: field
|
|
74
|
+
* 3. Default profile from config
|
|
75
|
+
*
|
|
76
|
+
* @param incrementId - Increment ID (e.g., "0142-feature")
|
|
77
|
+
* @param projectId - Optional project ID from spec.md (for priority 2)
|
|
78
|
+
* @returns Resolution result with sync target and profile
|
|
79
|
+
*/
|
|
80
|
+
async resolveForIncrement(incrementId, projectId) {
|
|
81
|
+
const resolutionPath = [];
|
|
82
|
+
const warnings = [];
|
|
83
|
+
// Step 1: Check for explicit syncTarget in metadata
|
|
84
|
+
const metadata = await this.loadIncrementMetadata(incrementId);
|
|
85
|
+
if (metadata?.syncTarget) {
|
|
86
|
+
resolutionPath.push(`metadata.syncTarget (profileId: ${metadata.syncTarget.profileId})`);
|
|
87
|
+
const profile = await this.getProfileById(metadata.syncTarget.profileId);
|
|
88
|
+
if (profile) {
|
|
89
|
+
return {
|
|
90
|
+
syncTarget: metadata.syncTarget,
|
|
91
|
+
profile,
|
|
92
|
+
resolutionPath,
|
|
93
|
+
warnings,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
warnings.push(`Profile '${metadata.syncTarget.profileId}' not found in config`);
|
|
98
|
+
resolutionPath.push('profile not found - falling through');
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
// Step 2: Resolve from project ID (if provided)
|
|
102
|
+
if (projectId) {
|
|
103
|
+
const projectResult = await this.resolveForProject(projectId);
|
|
104
|
+
if (projectResult.syncTarget) {
|
|
105
|
+
resolutionPath.push(`projectMappings['${projectId}'] → ${projectResult.syncTarget.profileId}`);
|
|
106
|
+
return {
|
|
107
|
+
...projectResult,
|
|
108
|
+
resolutionPath: [...resolutionPath, ...projectResult.resolutionPath],
|
|
109
|
+
warnings: [...warnings, ...projectResult.warnings],
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
resolutionPath.push(`projectMappings['${projectId}'] not found`);
|
|
113
|
+
}
|
|
114
|
+
// Step 3: Fall back to default profile
|
|
115
|
+
const syncConfig = await this.getSyncConfig();
|
|
116
|
+
if (syncConfig?.defaultProfile) {
|
|
117
|
+
const profile = syncConfig.profiles?.[syncConfig.defaultProfile];
|
|
118
|
+
if (profile) {
|
|
119
|
+
resolutionPath.push(`config.sync.defaultProfile → ${syncConfig.defaultProfile}`);
|
|
120
|
+
const syncTarget = {
|
|
121
|
+
profileId: syncConfig.defaultProfile,
|
|
122
|
+
provider: profile.provider,
|
|
123
|
+
derivedFrom: 'default-profile',
|
|
124
|
+
setAt: new Date().toISOString(),
|
|
125
|
+
};
|
|
126
|
+
return {
|
|
127
|
+
syncTarget,
|
|
128
|
+
profile,
|
|
129
|
+
resolutionPath,
|
|
130
|
+
warnings,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
warnings.push(`Default profile '${syncConfig.defaultProfile}' not found`);
|
|
134
|
+
}
|
|
135
|
+
// No resolution possible
|
|
136
|
+
resolutionPath.push('no external tool configured');
|
|
137
|
+
return {
|
|
138
|
+
syncTarget: null,
|
|
139
|
+
profile: null,
|
|
140
|
+
resolutionPath,
|
|
141
|
+
warnings,
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Resolve external tool for a specific project ID
|
|
146
|
+
*
|
|
147
|
+
* Looks up project in config.projectMappings and resolves to a profile.
|
|
148
|
+
*
|
|
149
|
+
* @param projectId - SpecWeave project ID (e.g., "frontend-app")
|
|
150
|
+
* @returns Resolution result
|
|
151
|
+
*/
|
|
152
|
+
async resolveForProject(projectId) {
|
|
153
|
+
const resolutionPath = [];
|
|
154
|
+
const warnings = [];
|
|
155
|
+
const mappings = await this.getProjectMappings();
|
|
156
|
+
const mapping = mappings[projectId];
|
|
157
|
+
if (!mapping) {
|
|
158
|
+
return {
|
|
159
|
+
syncTarget: null,
|
|
160
|
+
profile: null,
|
|
161
|
+
resolutionPath: [`projectMappings['${projectId}'] not found`],
|
|
162
|
+
warnings,
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
// Check for explicit profileId in mapping
|
|
166
|
+
const providers = ['github', 'jira', 'ado'];
|
|
167
|
+
for (const provider of providers) {
|
|
168
|
+
const providerMapping = mapping[provider];
|
|
169
|
+
if (providerMapping) {
|
|
170
|
+
resolutionPath.push(`projectMappings['${projectId}'].${provider}`);
|
|
171
|
+
// If explicit profileId specified, use that
|
|
172
|
+
if (providerMapping.profileId) {
|
|
173
|
+
const profile = await this.getProfileById(providerMapping.profileId);
|
|
174
|
+
if (profile) {
|
|
175
|
+
const syncTarget = {
|
|
176
|
+
profileId: providerMapping.profileId,
|
|
177
|
+
provider,
|
|
178
|
+
derivedFrom: 'project-mapping',
|
|
179
|
+
setAt: new Date().toISOString(),
|
|
180
|
+
sourceProjectId: projectId,
|
|
181
|
+
};
|
|
182
|
+
return {
|
|
183
|
+
syncTarget,
|
|
184
|
+
profile,
|
|
185
|
+
resolutionPath,
|
|
186
|
+
warnings,
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
warnings.push(`Explicit profileId '${providerMapping.profileId}' not found`);
|
|
190
|
+
}
|
|
191
|
+
// Otherwise, find matching profile by config
|
|
192
|
+
const matchingProfile = await this.findProfileByMapping(provider, providerMapping);
|
|
193
|
+
if (matchingProfile) {
|
|
194
|
+
const syncTarget = {
|
|
195
|
+
profileId: matchingProfile.id,
|
|
196
|
+
provider,
|
|
197
|
+
derivedFrom: 'project-mapping',
|
|
198
|
+
setAt: new Date().toISOString(),
|
|
199
|
+
sourceProjectId: projectId,
|
|
200
|
+
};
|
|
201
|
+
return {
|
|
202
|
+
syncTarget,
|
|
203
|
+
profile: matchingProfile.profile,
|
|
204
|
+
resolutionPath,
|
|
205
|
+
warnings,
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
// Mapping exists but no matching profile
|
|
209
|
+
warnings.push(`No profile matches ${provider} config for project '${projectId}'`);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
return {
|
|
213
|
+
syncTarget: null,
|
|
214
|
+
profile: null,
|
|
215
|
+
resolutionPath,
|
|
216
|
+
warnings,
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Resolve for a specific provider (e.g., "get me the GitHub profile")
|
|
221
|
+
*
|
|
222
|
+
* @param provider - Provider type
|
|
223
|
+
* @param projectId - Optional project ID for project-specific profile
|
|
224
|
+
* @returns Resolution result
|
|
225
|
+
*/
|
|
226
|
+
async resolveForProvider(provider, projectId) {
|
|
227
|
+
const resolutionPath = [];
|
|
228
|
+
const warnings = [];
|
|
229
|
+
// If projectId provided, try project mapping first
|
|
230
|
+
if (projectId) {
|
|
231
|
+
const mappings = await this.getProjectMappings();
|
|
232
|
+
const mapping = mappings[projectId]?.[provider];
|
|
233
|
+
if (mapping) {
|
|
234
|
+
const profileId = mapping.profileId;
|
|
235
|
+
if (profileId) {
|
|
236
|
+
const profile = await this.getProfileById(profileId);
|
|
237
|
+
if (profile && profile.provider === provider) {
|
|
238
|
+
resolutionPath.push(`projectMappings['${projectId}'].${provider}.profileId`);
|
|
239
|
+
return {
|
|
240
|
+
syncTarget: {
|
|
241
|
+
profileId,
|
|
242
|
+
provider,
|
|
243
|
+
derivedFrom: 'project-mapping',
|
|
244
|
+
setAt: new Date().toISOString(),
|
|
245
|
+
sourceProjectId: projectId,
|
|
246
|
+
},
|
|
247
|
+
profile,
|
|
248
|
+
resolutionPath,
|
|
249
|
+
warnings,
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
// Find any profile of this provider type
|
|
256
|
+
const syncConfig = await this.getSyncConfig();
|
|
257
|
+
if (syncConfig?.profiles) {
|
|
258
|
+
for (const [profileId, profile] of Object.entries(syncConfig.profiles)) {
|
|
259
|
+
if (profile.provider === provider) {
|
|
260
|
+
resolutionPath.push(`first ${provider} profile → ${profileId}`);
|
|
261
|
+
return {
|
|
262
|
+
syncTarget: {
|
|
263
|
+
profileId,
|
|
264
|
+
provider,
|
|
265
|
+
derivedFrom: 'default-profile',
|
|
266
|
+
setAt: new Date().toISOString(),
|
|
267
|
+
},
|
|
268
|
+
profile,
|
|
269
|
+
resolutionPath,
|
|
270
|
+
warnings,
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
resolutionPath.push(`no ${provider} profile configured`);
|
|
276
|
+
return {
|
|
277
|
+
syncTarget: null,
|
|
278
|
+
profile: null,
|
|
279
|
+
resolutionPath,
|
|
280
|
+
warnings,
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
// ==========================================================================
|
|
284
|
+
// Validation Methods
|
|
285
|
+
// ==========================================================================
|
|
286
|
+
/**
|
|
287
|
+
* Validate external tool configuration for an increment
|
|
288
|
+
*
|
|
289
|
+
* Call this at increment start to fail fast if config is missing.
|
|
290
|
+
*
|
|
291
|
+
* @param incrementId - Increment ID
|
|
292
|
+
* @param projectId - Project ID from spec.md
|
|
293
|
+
* @returns Validation result
|
|
294
|
+
*/
|
|
295
|
+
async validateIncrementConfig(incrementId, projectId) {
|
|
296
|
+
const errors = [];
|
|
297
|
+
const warnings = [];
|
|
298
|
+
const suggestions = [];
|
|
299
|
+
// Resolve the sync target
|
|
300
|
+
const resolution = await this.resolveForIncrement(incrementId, projectId);
|
|
301
|
+
if (!resolution.syncTarget) {
|
|
302
|
+
// Check what's missing
|
|
303
|
+
const syncConfig = await this.getSyncConfig();
|
|
304
|
+
const mappings = await this.getProjectMappings();
|
|
305
|
+
if (!syncConfig || Object.keys(syncConfig.profiles || {}).length === 0) {
|
|
306
|
+
errors.push('No sync profiles configured');
|
|
307
|
+
suggestions.push('Run `specweave init` to configure external tool integration');
|
|
308
|
+
}
|
|
309
|
+
else if (projectId && !mappings[projectId]) {
|
|
310
|
+
errors.push(`No project mapping for '${projectId}'`);
|
|
311
|
+
suggestions.push(`Add project mapping in config.json: projectMappings.${projectId}`);
|
|
312
|
+
}
|
|
313
|
+
else if (!syncConfig.defaultProfile) {
|
|
314
|
+
errors.push('No default sync profile configured');
|
|
315
|
+
suggestions.push('Set config.sync.defaultProfile in config.json');
|
|
316
|
+
}
|
|
317
|
+
return {
|
|
318
|
+
valid: false,
|
|
319
|
+
errors,
|
|
320
|
+
warnings: [...warnings, ...resolution.warnings],
|
|
321
|
+
suggestions,
|
|
322
|
+
};
|
|
323
|
+
}
|
|
324
|
+
// Validate the resolved profile exists and has required config
|
|
325
|
+
if (!resolution.profile) {
|
|
326
|
+
errors.push(`Profile '${resolution.syncTarget.profileId}' not found`);
|
|
327
|
+
return {
|
|
328
|
+
valid: false,
|
|
329
|
+
syncTarget: resolution.syncTarget,
|
|
330
|
+
errors,
|
|
331
|
+
warnings: [...warnings, ...resolution.warnings],
|
|
332
|
+
suggestions: ['Check config.sync.profiles in config.json'],
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
// Validate provider-specific config
|
|
336
|
+
const configErrors = this.validateProfileConfig(resolution.profile);
|
|
337
|
+
if (configErrors.length > 0) {
|
|
338
|
+
errors.push(...configErrors);
|
|
339
|
+
}
|
|
340
|
+
// Check for authentication
|
|
341
|
+
const authWarnings = await this.checkAuthentication(resolution.profile.provider);
|
|
342
|
+
warnings.push(...authWarnings);
|
|
343
|
+
return {
|
|
344
|
+
valid: errors.length === 0,
|
|
345
|
+
syncTarget: resolution.syncTarget,
|
|
346
|
+
errors,
|
|
347
|
+
warnings: [...warnings, ...resolution.warnings],
|
|
348
|
+
suggestions,
|
|
349
|
+
};
|
|
350
|
+
}
|
|
351
|
+
/**
|
|
352
|
+
* Validate profile configuration completeness
|
|
353
|
+
*/
|
|
354
|
+
validateProfileConfig(profile) {
|
|
355
|
+
const errors = [];
|
|
356
|
+
const config = profile.config;
|
|
357
|
+
switch (profile.provider) {
|
|
358
|
+
case 'github': {
|
|
359
|
+
const ghConfig = config;
|
|
360
|
+
if (!ghConfig.owner) {
|
|
361
|
+
errors.push('GitHub config missing: owner');
|
|
362
|
+
}
|
|
363
|
+
if (!ghConfig.repo && !ghConfig.repos?.length) {
|
|
364
|
+
errors.push('GitHub config missing: repo or repos[]');
|
|
365
|
+
}
|
|
366
|
+
break;
|
|
367
|
+
}
|
|
368
|
+
case 'jira': {
|
|
369
|
+
const jiraConfig = config;
|
|
370
|
+
if (!jiraConfig.domain) {
|
|
371
|
+
errors.push('JIRA config missing: domain');
|
|
372
|
+
}
|
|
373
|
+
if (!jiraConfig.projectKey && !jiraConfig.projects?.length) {
|
|
374
|
+
errors.push('JIRA config missing: projectKey or projects[]');
|
|
375
|
+
}
|
|
376
|
+
break;
|
|
377
|
+
}
|
|
378
|
+
case 'ado': {
|
|
379
|
+
const adoConfig = config;
|
|
380
|
+
if (!adoConfig.organization) {
|
|
381
|
+
errors.push('ADO config missing: organization');
|
|
382
|
+
}
|
|
383
|
+
if (!adoConfig.project && !adoConfig.projects?.length) {
|
|
384
|
+
errors.push('ADO config missing: project or projects[]');
|
|
385
|
+
}
|
|
386
|
+
break;
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
return errors;
|
|
390
|
+
}
|
|
391
|
+
/**
|
|
392
|
+
* Check if authentication is configured for a provider
|
|
393
|
+
*/
|
|
394
|
+
async checkAuthentication(provider) {
|
|
395
|
+
const warnings = [];
|
|
396
|
+
// Check .env file for tokens
|
|
397
|
+
const envPath = path.join(this.projectRoot, '.env');
|
|
398
|
+
let envContent = '';
|
|
399
|
+
try {
|
|
400
|
+
envContent = await fs.readFile(envPath, 'utf-8');
|
|
401
|
+
}
|
|
402
|
+
catch {
|
|
403
|
+
// No .env file
|
|
404
|
+
}
|
|
405
|
+
switch (provider) {
|
|
406
|
+
case 'github':
|
|
407
|
+
if (!envContent.includes('GITHUB_TOKEN') && !envContent.includes('GH_TOKEN')) {
|
|
408
|
+
warnings.push('GitHub token not found in .env (GITHUB_TOKEN or GH_TOKEN)');
|
|
409
|
+
}
|
|
410
|
+
break;
|
|
411
|
+
case 'jira':
|
|
412
|
+
if (!envContent.includes('JIRA_API_TOKEN')) {
|
|
413
|
+
warnings.push('JIRA API token not found in .env (JIRA_API_TOKEN)');
|
|
414
|
+
}
|
|
415
|
+
if (!envContent.includes('JIRA_EMAIL')) {
|
|
416
|
+
warnings.push('JIRA email not found in .env (JIRA_EMAIL)');
|
|
417
|
+
}
|
|
418
|
+
break;
|
|
419
|
+
case 'ado':
|
|
420
|
+
if (!envContent.includes('AZURE_DEVOPS_PAT')) {
|
|
421
|
+
warnings.push('Azure DevOps PAT not found in .env (AZURE_DEVOPS_PAT)');
|
|
422
|
+
}
|
|
423
|
+
break;
|
|
424
|
+
}
|
|
425
|
+
return warnings;
|
|
426
|
+
}
|
|
427
|
+
// ==========================================================================
|
|
428
|
+
// Helper Methods
|
|
429
|
+
// ==========================================================================
|
|
430
|
+
/**
|
|
431
|
+
* Load increment metadata
|
|
432
|
+
*/
|
|
433
|
+
async loadIncrementMetadata(incrementId) {
|
|
434
|
+
// Try main increments folder
|
|
435
|
+
const paths = [
|
|
436
|
+
path.join(this.projectRoot, '.specweave', 'increments', incrementId, 'metadata.json'),
|
|
437
|
+
path.join(this.projectRoot, '.specweave', 'increments', '_archive', incrementId, 'metadata.json'),
|
|
438
|
+
path.join(this.projectRoot, '.specweave', 'increments', '_paused', incrementId, 'metadata.json'),
|
|
439
|
+
];
|
|
440
|
+
for (const metadataPath of paths) {
|
|
441
|
+
try {
|
|
442
|
+
const content = await fs.readFile(metadataPath, 'utf-8');
|
|
443
|
+
return JSON.parse(content);
|
|
444
|
+
}
|
|
445
|
+
catch {
|
|
446
|
+
// Try next path
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
return null;
|
|
450
|
+
}
|
|
451
|
+
/**
|
|
452
|
+
* Get profile by ID
|
|
453
|
+
*/
|
|
454
|
+
async getProfileById(profileId) {
|
|
455
|
+
const syncConfig = await this.getSyncConfig();
|
|
456
|
+
return syncConfig?.profiles?.[profileId] || null;
|
|
457
|
+
}
|
|
458
|
+
/**
|
|
459
|
+
* Find profile matching a project mapping
|
|
460
|
+
*/
|
|
461
|
+
async findProfileByMapping(provider, mapping) {
|
|
462
|
+
const syncConfig = await this.getSyncConfig();
|
|
463
|
+
if (!syncConfig?.profiles)
|
|
464
|
+
return null;
|
|
465
|
+
for (const [profileId, profile] of Object.entries(syncConfig.profiles)) {
|
|
466
|
+
if (profile.provider !== provider)
|
|
467
|
+
continue;
|
|
468
|
+
// Match by config properties
|
|
469
|
+
const config = profile.config;
|
|
470
|
+
switch (provider) {
|
|
471
|
+
case 'github': {
|
|
472
|
+
const ghConfig = config;
|
|
473
|
+
const ghMapping = mapping;
|
|
474
|
+
if (ghConfig.owner === ghMapping.owner &&
|
|
475
|
+
(ghConfig.repo === ghMapping.repo || ghConfig.repos?.includes(ghMapping.repo))) {
|
|
476
|
+
return { id: profileId, profile };
|
|
477
|
+
}
|
|
478
|
+
break;
|
|
479
|
+
}
|
|
480
|
+
case 'jira': {
|
|
481
|
+
const jiraConfig = config;
|
|
482
|
+
const jiraMapping = mapping;
|
|
483
|
+
if (jiraConfig.projectKey === jiraMapping.project ||
|
|
484
|
+
jiraConfig.projects?.includes(jiraMapping.project)) {
|
|
485
|
+
return { id: profileId, profile };
|
|
486
|
+
}
|
|
487
|
+
break;
|
|
488
|
+
}
|
|
489
|
+
case 'ado': {
|
|
490
|
+
const adoConfig = config;
|
|
491
|
+
const adoMapping = mapping;
|
|
492
|
+
if (adoConfig.project === adoMapping.project ||
|
|
493
|
+
adoConfig.projects?.includes(adoMapping.project)) {
|
|
494
|
+
return { id: profileId, profile };
|
|
495
|
+
}
|
|
496
|
+
break;
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
return null;
|
|
501
|
+
}
|
|
502
|
+
/**
|
|
503
|
+
* Create a sync target for saving to metadata
|
|
504
|
+
*
|
|
505
|
+
* @param profileId - Profile ID
|
|
506
|
+
* @param provider - Provider type
|
|
507
|
+
* @param derivedFrom - How it was determined
|
|
508
|
+
* @param sourceProjectId - Optional source project
|
|
509
|
+
* @returns SyncTarget object
|
|
510
|
+
*/
|
|
511
|
+
static createSyncTarget(profileId, provider, derivedFrom, sourceProjectId) {
|
|
512
|
+
return {
|
|
513
|
+
profileId,
|
|
514
|
+
provider,
|
|
515
|
+
derivedFrom,
|
|
516
|
+
setAt: new Date().toISOString(),
|
|
517
|
+
sourceProjectId,
|
|
518
|
+
};
|
|
519
|
+
}
|
|
520
|
+
// ==========================================================================
|
|
521
|
+
// Utility Methods for Callers
|
|
522
|
+
// ==========================================================================
|
|
523
|
+
/**
|
|
524
|
+
* Check if any external tool is configured
|
|
525
|
+
*/
|
|
526
|
+
async hasExternalToolConfigured() {
|
|
527
|
+
const syncConfig = await this.getSyncConfig();
|
|
528
|
+
return !!(syncConfig?.profiles && Object.keys(syncConfig.profiles).length > 0);
|
|
529
|
+
}
|
|
530
|
+
/**
|
|
531
|
+
* Get all configured providers
|
|
532
|
+
*/
|
|
533
|
+
async getConfiguredProviders() {
|
|
534
|
+
const syncConfig = await this.getSyncConfig();
|
|
535
|
+
if (!syncConfig?.profiles)
|
|
536
|
+
return [];
|
|
537
|
+
const providers = new Set();
|
|
538
|
+
for (const profile of Object.values(syncConfig.profiles)) {
|
|
539
|
+
providers.add(profile.provider);
|
|
540
|
+
}
|
|
541
|
+
return Array.from(providers);
|
|
542
|
+
}
|
|
543
|
+
/**
|
|
544
|
+
* Get summary of external tool configuration
|
|
545
|
+
*/
|
|
546
|
+
async getConfigSummary() {
|
|
547
|
+
const syncConfig = await this.getSyncConfig();
|
|
548
|
+
const mappings = await this.getProjectMappings();
|
|
549
|
+
const profiles = syncConfig?.profiles || {};
|
|
550
|
+
const providers = new Set();
|
|
551
|
+
for (const profile of Object.values(profiles)) {
|
|
552
|
+
providers.add(profile.provider);
|
|
553
|
+
}
|
|
554
|
+
return {
|
|
555
|
+
hasConfig: Object.keys(profiles).length > 0,
|
|
556
|
+
providers: Array.from(providers),
|
|
557
|
+
profileCount: Object.keys(profiles).length,
|
|
558
|
+
defaultProfile: syncConfig?.defaultProfile,
|
|
559
|
+
projectMappingCount: Object.keys(mappings).length,
|
|
560
|
+
};
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
/**
|
|
564
|
+
* Factory function for creating ExternalToolResolver
|
|
565
|
+
*/
|
|
566
|
+
export function createExternalToolResolver(projectRoot, logger) {
|
|
567
|
+
return new ExternalToolResolver(projectRoot, { logger });
|
|
568
|
+
}
|
|
569
|
+
//# sourceMappingURL=external-tool-resolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"external-tool-resolver.js","sourceRoot":"","sources":["../../../../src/core/sync/external-tool-resolver.ts"],"names":[],"mappings":"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"}
|