specweave 0.9.1 → 0.10.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 +153 -13
- package/README.md +97 -251
- package/bin/install-agents.sh +1 -1
- package/bin/install-commands.sh +1 -1
- package/bin/install-hooks.sh +1 -1
- package/bin/install-skills.sh +1 -1
- package/bin/specweave.js +32 -0
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +29 -1
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/validate-jira.d.ts +35 -0
- package/dist/cli/commands/validate-jira.d.ts.map +1 -0
- package/dist/cli/commands/validate-jira.js +112 -0
- package/dist/cli/commands/validate-jira.js.map +1 -0
- package/dist/cli/commands/validate-plugins.d.ts +41 -0
- package/dist/cli/commands/validate-plugins.d.ts.map +1 -0
- package/dist/cli/commands/validate-plugins.js +171 -0
- package/dist/cli/commands/validate-plugins.js.map +1 -0
- package/dist/core/types/sync-profile.d.ts +177 -29
- package/dist/core/types/sync-profile.d.ts.map +1 -1
- package/dist/core/types/sync-profile.js +48 -1
- package/dist/core/types/sync-profile.js.map +1 -1
- package/dist/hooks/lib/translate-living-docs.d.ts.map +1 -1
- package/dist/hooks/lib/translate-living-docs.js +16 -7
- package/dist/hooks/lib/translate-living-docs.js.map +1 -1
- package/dist/metrics/dora-calculator.d.ts +7 -3
- package/dist/metrics/dora-calculator.d.ts.map +1 -1
- package/dist/metrics/dora-calculator.js +19 -6
- package/dist/metrics/dora-calculator.js.map +1 -1
- package/dist/metrics/report-generator.d.ts +17 -0
- package/dist/metrics/report-generator.d.ts.map +1 -0
- package/dist/metrics/report-generator.js +403 -0
- package/dist/metrics/report-generator.js.map +1 -0
- package/dist/utils/external-resource-validator.d.ts +102 -0
- package/dist/utils/external-resource-validator.d.ts.map +1 -0
- package/dist/utils/external-resource-validator.js +400 -0
- package/dist/utils/external-resource-validator.js.map +1 -0
- package/dist/utils/plugin-validator.d.ts +161 -0
- package/dist/utils/plugin-validator.d.ts.map +1 -0
- package/dist/utils/plugin-validator.js +565 -0
- package/dist/utils/plugin-validator.js.map +1 -0
- package/package.json +2 -1
- package/plugins/specweave/commands/specweave-do.md +47 -0
- package/plugins/specweave/commands/specweave-increment.md +82 -0
- package/plugins/specweave/commands/specweave-next.md +47 -0
- package/plugins/specweave/hooks/post-increment-planning.sh +117 -38
- package/plugins/specweave/hooks/pre-tool-use.sh +133 -0
- package/plugins/specweave/plugin.json +22 -0
- package/plugins/specweave/skills/SKILLS-INDEX.md +23 -2
- package/plugins/specweave/skills/plugin-installer/SKILL.md +340 -0
- package/plugins/specweave/skills/plugin-validator/SKILL.md +427 -0
- package/plugins/specweave-ado/.claude-plugin/plugin.json +2 -4
- package/plugins/specweave-ado/lib/ado-board-resolver.ts +328 -0
- package/plugins/specweave-ado/lib/ado-hierarchical-sync.ts +484 -0
- package/plugins/specweave-ado/plugin.json +20 -0
- package/plugins/specweave-alternatives/.claude-plugin/plugin.json +15 -2
- package/plugins/specweave-backend/.claude-plugin/plugin.json +15 -2
- package/plugins/specweave-cost-optimizer/.claude-plugin/plugin.json +14 -2
- package/plugins/specweave-diagrams/.claude-plugin/plugin.json +14 -2
- package/plugins/specweave-docs/.claude-plugin/plugin.json +13 -2
- package/plugins/specweave-figma/.claude-plugin/plugin.json +14 -2
- package/plugins/specweave-frontend/.claude-plugin/plugin.json +15 -2
- package/plugins/specweave-github/lib/github-board-resolver.ts +164 -0
- package/plugins/specweave-github/lib/github-hierarchical-sync.ts +344 -0
- package/plugins/specweave-github/plugin.json +19 -0
- package/plugins/specweave-infrastructure/.claude-plugin/plugin.json +15 -2
- package/plugins/specweave-jira/.claude-plugin/plugin.json +14 -2
- package/plugins/specweave-jira/lib/jira-board-resolver.ts +127 -0
- package/plugins/specweave-jira/lib/jira-hierarchical-sync.ts +283 -0
- package/plugins/specweave-jira/plugin.json +20 -0
- package/plugins/specweave-jira/skills/jira-resource-validator/SKILL.md +647 -0
- package/plugins/specweave-kubernetes/.claude-plugin/plugin.json +14 -2
- package/plugins/specweave-payments/.claude-plugin/plugin.json +14 -2
- package/plugins/specweave-testing/.claude-plugin/plugin.json +14 -2
- package/plugins/specweave-tooling/.claude-plugin/plugin.json +13 -2
|
@@ -0,0 +1,565 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plugin Validation System
|
|
3
|
+
*
|
|
4
|
+
* Proactively validates SpecWeave plugin installation before workflow commands.
|
|
5
|
+
* Ensures marketplace is registered, core plugin is installed, and context-specific
|
|
6
|
+
* plugins are available.
|
|
7
|
+
*
|
|
8
|
+
* @module plugin-validator
|
|
9
|
+
* @since 0.9.4
|
|
10
|
+
*/
|
|
11
|
+
import fs from 'fs-extra';
|
|
12
|
+
import path from 'path';
|
|
13
|
+
import os from 'os';
|
|
14
|
+
import { exec } from 'child_process';
|
|
15
|
+
import { promisify } from 'util';
|
|
16
|
+
const execAsync = promisify(exec);
|
|
17
|
+
// ============================================================================
|
|
18
|
+
// Constants
|
|
19
|
+
// ============================================================================
|
|
20
|
+
/**
|
|
21
|
+
* Plugin keyword mappings
|
|
22
|
+
* Maps plugin names to keywords that should trigger their suggestion
|
|
23
|
+
* Scoring: 2+ keyword matches = high confidence (plugin suggested)
|
|
24
|
+
*/
|
|
25
|
+
export const PLUGIN_KEYWORDS = {
|
|
26
|
+
'specweave-github': [
|
|
27
|
+
'github',
|
|
28
|
+
'git',
|
|
29
|
+
'issues',
|
|
30
|
+
'pull request',
|
|
31
|
+
'pr',
|
|
32
|
+
'repository',
|
|
33
|
+
'commit',
|
|
34
|
+
],
|
|
35
|
+
'specweave-jira': [
|
|
36
|
+
'jira',
|
|
37
|
+
'epic',
|
|
38
|
+
'story',
|
|
39
|
+
'sprint',
|
|
40
|
+
'backlog',
|
|
41
|
+
'atlassian',
|
|
42
|
+
],
|
|
43
|
+
'specweave-ado': [
|
|
44
|
+
'azure devops',
|
|
45
|
+
'ado',
|
|
46
|
+
'azure',
|
|
47
|
+
'devops',
|
|
48
|
+
'work item',
|
|
49
|
+
'boards',
|
|
50
|
+
],
|
|
51
|
+
'specweave-payments': [
|
|
52
|
+
'stripe',
|
|
53
|
+
'billing',
|
|
54
|
+
'payment',
|
|
55
|
+
'subscription',
|
|
56
|
+
'invoice',
|
|
57
|
+
'checkout',
|
|
58
|
+
],
|
|
59
|
+
'specweave-frontend': [
|
|
60
|
+
'react',
|
|
61
|
+
'nextjs',
|
|
62
|
+
'next.js',
|
|
63
|
+
'vue',
|
|
64
|
+
'angular',
|
|
65
|
+
'svelte',
|
|
66
|
+
'frontend',
|
|
67
|
+
'ui',
|
|
68
|
+
],
|
|
69
|
+
'specweave-kubernetes': [
|
|
70
|
+
'kubernetes',
|
|
71
|
+
'k8s',
|
|
72
|
+
'helm',
|
|
73
|
+
'pod',
|
|
74
|
+
'deployment',
|
|
75
|
+
'service mesh',
|
|
76
|
+
'kubectl',
|
|
77
|
+
],
|
|
78
|
+
'specweave-ml': [
|
|
79
|
+
'machine learning',
|
|
80
|
+
'ml',
|
|
81
|
+
'tensorflow',
|
|
82
|
+
'pytorch',
|
|
83
|
+
'model',
|
|
84
|
+
'training',
|
|
85
|
+
'dataset',
|
|
86
|
+
],
|
|
87
|
+
'specweave-observability': [
|
|
88
|
+
'prometheus',
|
|
89
|
+
'grafana',
|
|
90
|
+
'monitoring',
|
|
91
|
+
'metrics',
|
|
92
|
+
'alerting',
|
|
93
|
+
'observability',
|
|
94
|
+
],
|
|
95
|
+
'specweave-security': [
|
|
96
|
+
'security',
|
|
97
|
+
'owasp',
|
|
98
|
+
'vulnerability',
|
|
99
|
+
'penetration',
|
|
100
|
+
'audit',
|
|
101
|
+
'csrf',
|
|
102
|
+
'xss',
|
|
103
|
+
],
|
|
104
|
+
'specweave-diagrams': [
|
|
105
|
+
'diagram',
|
|
106
|
+
'c4',
|
|
107
|
+
'mermaid',
|
|
108
|
+
'architecture',
|
|
109
|
+
'visualization',
|
|
110
|
+
'flowchart',
|
|
111
|
+
],
|
|
112
|
+
'specweave-backend-nodejs': [
|
|
113
|
+
'nodejs',
|
|
114
|
+
'express',
|
|
115
|
+
'fastify',
|
|
116
|
+
'nestjs',
|
|
117
|
+
'backend',
|
|
118
|
+
'api',
|
|
119
|
+
],
|
|
120
|
+
'specweave-backend-python': [
|
|
121
|
+
'python',
|
|
122
|
+
'fastapi',
|
|
123
|
+
'django',
|
|
124
|
+
'flask',
|
|
125
|
+
'backend',
|
|
126
|
+
'api',
|
|
127
|
+
],
|
|
128
|
+
'specweave-backend-dotnet': [
|
|
129
|
+
'dotnet',
|
|
130
|
+
'.net',
|
|
131
|
+
'aspnet',
|
|
132
|
+
'asp.net',
|
|
133
|
+
'c#',
|
|
134
|
+
'csharp',
|
|
135
|
+
],
|
|
136
|
+
'specweave-docs-preview': [
|
|
137
|
+
'documentation',
|
|
138
|
+
'docs',
|
|
139
|
+
'preview',
|
|
140
|
+
'docusaurus',
|
|
141
|
+
'publish',
|
|
142
|
+
],
|
|
143
|
+
'specweave-e2e-testing': [
|
|
144
|
+
'playwright',
|
|
145
|
+
'e2e',
|
|
146
|
+
'end-to-end',
|
|
147
|
+
'browser',
|
|
148
|
+
'visual regression',
|
|
149
|
+
],
|
|
150
|
+
};
|
|
151
|
+
/** Cache TTL in seconds (5 minutes) */
|
|
152
|
+
const CACHE_TTL = 300;
|
|
153
|
+
/** Confidence threshold for plugin detection (2+ keyword matches) */
|
|
154
|
+
const KEYWORD_CONFIDENCE_THRESHOLD = 2;
|
|
155
|
+
/** SpecWeave marketplace configuration */
|
|
156
|
+
const SPECWEAVE_MARKETPLACE_CONFIG = {
|
|
157
|
+
source: {
|
|
158
|
+
source: 'github',
|
|
159
|
+
repo: 'anton-abyzov/specweave',
|
|
160
|
+
path: '.claude-plugin',
|
|
161
|
+
},
|
|
162
|
+
};
|
|
163
|
+
// ============================================================================
|
|
164
|
+
// Main Validator Class
|
|
165
|
+
// ============================================================================
|
|
166
|
+
/**
|
|
167
|
+
* Plugin Validator
|
|
168
|
+
*
|
|
169
|
+
* Validates SpecWeave plugin installation and provides auto-installation
|
|
170
|
+
* capabilities. Uses caching to minimize validation overhead.
|
|
171
|
+
*/
|
|
172
|
+
export class PluginValidator {
|
|
173
|
+
constructor() {
|
|
174
|
+
this.verbose = false;
|
|
175
|
+
this.cacheFile = path.join(os.homedir(), '.specweave', 'validation-cache.json');
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Main validation entry point
|
|
179
|
+
*
|
|
180
|
+
* @param options - Validation options
|
|
181
|
+
* @returns Validation result with missing/installed components
|
|
182
|
+
*/
|
|
183
|
+
async validate(options = {}) {
|
|
184
|
+
this.verbose = options.verbose ?? false;
|
|
185
|
+
// Check cache first (unless verbose mode)
|
|
186
|
+
if (!options.verbose && !options.dryRun) {
|
|
187
|
+
const cached = await this.getCachedValidation();
|
|
188
|
+
if (cached) {
|
|
189
|
+
this.log('Using cached validation result');
|
|
190
|
+
return cached;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
const result = {
|
|
194
|
+
valid: true,
|
|
195
|
+
timestamp: Date.now(),
|
|
196
|
+
missing: {
|
|
197
|
+
marketplace: false,
|
|
198
|
+
corePlugin: false,
|
|
199
|
+
contextPlugins: [],
|
|
200
|
+
},
|
|
201
|
+
installed: {
|
|
202
|
+
corePlugin: false,
|
|
203
|
+
contextPlugins: [],
|
|
204
|
+
},
|
|
205
|
+
recommendations: [],
|
|
206
|
+
errors: [],
|
|
207
|
+
};
|
|
208
|
+
try {
|
|
209
|
+
// Step 1: Check marketplace
|
|
210
|
+
this.log('Checking marketplace registration...');
|
|
211
|
+
if (!(await this.checkMarketplace())) {
|
|
212
|
+
result.valid = false;
|
|
213
|
+
result.missing.marketplace = true;
|
|
214
|
+
result.recommendations.push('Register SpecWeave marketplace in ~/.claude/settings.json');
|
|
215
|
+
// Auto-install marketplace if requested
|
|
216
|
+
if (options.autoInstall && !options.dryRun) {
|
|
217
|
+
this.log('Auto-installing marketplace...');
|
|
218
|
+
const installResult = await this.installMarketplace();
|
|
219
|
+
if (!installResult.success) {
|
|
220
|
+
result.errors.push(`Failed to install marketplace: ${installResult.error}`);
|
|
221
|
+
}
|
|
222
|
+
else {
|
|
223
|
+
result.missing.marketplace = false;
|
|
224
|
+
this.log('Marketplace installed successfully');
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
else {
|
|
229
|
+
this.log('Marketplace registered ✓');
|
|
230
|
+
}
|
|
231
|
+
// Step 2: Check core plugin
|
|
232
|
+
this.log('Checking core plugin (specweave)...');
|
|
233
|
+
const corePluginInfo = await this.checkCorePlugin();
|
|
234
|
+
if (!corePluginInfo.installed) {
|
|
235
|
+
result.valid = false;
|
|
236
|
+
result.missing.corePlugin = true;
|
|
237
|
+
result.recommendations.push('Install core plugin: /plugin install specweave');
|
|
238
|
+
// Auto-install core plugin if requested
|
|
239
|
+
if (options.autoInstall && !options.dryRun) {
|
|
240
|
+
this.log('Auto-installing core plugin...');
|
|
241
|
+
const installResult = await this.installPlugin('specweave');
|
|
242
|
+
if (!installResult.success) {
|
|
243
|
+
result.errors.push(`Failed to install core plugin: ${installResult.error}`);
|
|
244
|
+
}
|
|
245
|
+
else {
|
|
246
|
+
result.missing.corePlugin = false;
|
|
247
|
+
result.installed.corePlugin = true;
|
|
248
|
+
this.log('Core plugin installed successfully');
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
else {
|
|
253
|
+
result.installed.corePlugin = true;
|
|
254
|
+
result.installed.corePluginVersion = corePluginInfo.version;
|
|
255
|
+
this.log(`Core plugin installed ✓ (${corePluginInfo.version})`);
|
|
256
|
+
}
|
|
257
|
+
// Step 3: Detect context plugins (if context provided)
|
|
258
|
+
if (options.context) {
|
|
259
|
+
this.log('Detecting context plugins from description...');
|
|
260
|
+
const requiredPlugins = this.detectRequiredPlugins(options.context);
|
|
261
|
+
if (requiredPlugins.length > 0) {
|
|
262
|
+
this.log(`Detected plugins: ${requiredPlugins.join(', ')}`);
|
|
263
|
+
for (const plugin of requiredPlugins) {
|
|
264
|
+
const pluginInfo = await this.checkPlugin(plugin);
|
|
265
|
+
if (!pluginInfo.installed) {
|
|
266
|
+
result.valid = false;
|
|
267
|
+
result.missing.contextPlugins.push(plugin);
|
|
268
|
+
result.recommendations.push(`Install context plugin: /plugin install ${plugin}`);
|
|
269
|
+
// Auto-install context plugin if requested
|
|
270
|
+
if (options.autoInstall && !options.dryRun) {
|
|
271
|
+
this.log(`Auto-installing context plugin: ${plugin}...`);
|
|
272
|
+
const installResult = await this.installPlugin(plugin);
|
|
273
|
+
if (!installResult.success) {
|
|
274
|
+
result.errors.push(`Failed to install ${plugin}: ${installResult.error}`);
|
|
275
|
+
}
|
|
276
|
+
else {
|
|
277
|
+
result.installed.contextPlugins.push(plugin);
|
|
278
|
+
this.log(`${plugin} installed successfully`);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
else {
|
|
283
|
+
result.installed.contextPlugins.push(plugin);
|
|
284
|
+
this.log(`${plugin} already installed ✓`);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
else {
|
|
289
|
+
this.log('No context plugins detected');
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
// Cache result (if not dry-run)
|
|
293
|
+
if (!options.dryRun) {
|
|
294
|
+
await this.setCachedValidation(result);
|
|
295
|
+
}
|
|
296
|
+
return result;
|
|
297
|
+
}
|
|
298
|
+
catch (error) {
|
|
299
|
+
result.valid = false;
|
|
300
|
+
result.errors.push(`Validation error: ${error.message}`);
|
|
301
|
+
return result;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Check if SpecWeave marketplace is registered
|
|
306
|
+
*
|
|
307
|
+
* @returns True if marketplace is registered correctly
|
|
308
|
+
*/
|
|
309
|
+
async checkMarketplace() {
|
|
310
|
+
try {
|
|
311
|
+
const settingsPath = path.join(os.homedir(), '.claude', 'settings.json');
|
|
312
|
+
// Check if settings.json exists
|
|
313
|
+
if (!(await fs.pathExists(settingsPath))) {
|
|
314
|
+
this.log('settings.json not found');
|
|
315
|
+
return false;
|
|
316
|
+
}
|
|
317
|
+
// Read settings
|
|
318
|
+
const settings = await fs.readJson(settingsPath);
|
|
319
|
+
// Check if specweave marketplace is registered
|
|
320
|
+
const marketplace = settings.extraKnownMarketplaces?.specweave;
|
|
321
|
+
if (!marketplace) {
|
|
322
|
+
this.log('SpecWeave marketplace not registered');
|
|
323
|
+
return false;
|
|
324
|
+
}
|
|
325
|
+
// Validate marketplace structure
|
|
326
|
+
if (marketplace.source.source === 'github' &&
|
|
327
|
+
marketplace.source.repo === 'anton-abyzov/specweave' &&
|
|
328
|
+
marketplace.source.path === '.claude-plugin') {
|
|
329
|
+
this.log('Marketplace configuration valid');
|
|
330
|
+
return true;
|
|
331
|
+
}
|
|
332
|
+
// Check if it's a local marketplace (dev mode)
|
|
333
|
+
if (marketplace.source.source === 'local') {
|
|
334
|
+
this.log('Development mode detected (local marketplace)');
|
|
335
|
+
return true;
|
|
336
|
+
}
|
|
337
|
+
this.log('Marketplace configuration invalid');
|
|
338
|
+
return false;
|
|
339
|
+
}
|
|
340
|
+
catch (error) {
|
|
341
|
+
this.log(`Error checking marketplace: ${error.message}`);
|
|
342
|
+
return false;
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
/**
|
|
346
|
+
* Check if core plugin (specweave) is installed
|
|
347
|
+
*
|
|
348
|
+
* @returns Plugin installation info
|
|
349
|
+
*/
|
|
350
|
+
async checkCorePlugin() {
|
|
351
|
+
return this.checkPlugin('specweave');
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* Check if a specific plugin is installed
|
|
355
|
+
*
|
|
356
|
+
* @param pluginName - Name of plugin to check
|
|
357
|
+
* @returns Plugin installation info
|
|
358
|
+
*/
|
|
359
|
+
async checkPlugin(pluginName) {
|
|
360
|
+
try {
|
|
361
|
+
// Execute: claude plugin list --installed | grep "{pluginName}"
|
|
362
|
+
// Note: This assumes Claude CLI is available
|
|
363
|
+
const { stdout } = await execAsync(`claude plugin list --installed 2>/dev/null | grep -i "${pluginName}"`);
|
|
364
|
+
if (stdout.trim()) {
|
|
365
|
+
// Parse version from output (format: "name version description")
|
|
366
|
+
const match = stdout.match(/(\d+\.\d+\.\d+)/);
|
|
367
|
+
const version = match ? match[1] : undefined;
|
|
368
|
+
this.log(`Plugin ${pluginName} found (version: ${version})`);
|
|
369
|
+
return { installed: true, version };
|
|
370
|
+
}
|
|
371
|
+
this.log(`Plugin ${pluginName} not found`);
|
|
372
|
+
return { installed: false };
|
|
373
|
+
}
|
|
374
|
+
catch (error) {
|
|
375
|
+
// grep returns exit code 1 if no matches (not an error)
|
|
376
|
+
if (error.code === 1) {
|
|
377
|
+
this.log(`Plugin ${pluginName} not found`);
|
|
378
|
+
return { installed: false };
|
|
379
|
+
}
|
|
380
|
+
// Check if Claude CLI is not available
|
|
381
|
+
if (error.message.includes('command not found')) {
|
|
382
|
+
this.log('Claude CLI not available');
|
|
383
|
+
throw new Error('Claude CLI not available. Please ensure Claude Code is installed.');
|
|
384
|
+
}
|
|
385
|
+
this.log(`Error checking plugin ${pluginName}: ${error.message}`);
|
|
386
|
+
return { installed: false };
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
/**
|
|
390
|
+
* Detect required plugins based on keywords in description
|
|
391
|
+
*
|
|
392
|
+
* @param description - Increment description or context
|
|
393
|
+
* @returns List of required plugin names
|
|
394
|
+
*/
|
|
395
|
+
detectRequiredPlugins(description) {
|
|
396
|
+
const scores = {};
|
|
397
|
+
const lowerDesc = description.toLowerCase();
|
|
398
|
+
// Score each plugin based on keyword matches
|
|
399
|
+
for (const [plugin, keywords] of Object.entries(PLUGIN_KEYWORDS)) {
|
|
400
|
+
scores[plugin] = keywords.filter((kw) => lowerDesc.includes(kw.toLowerCase())).length;
|
|
401
|
+
}
|
|
402
|
+
// Return plugins with score >= threshold (high confidence)
|
|
403
|
+
const detected = Object.entries(scores)
|
|
404
|
+
.filter(([_, score]) => score >= KEYWORD_CONFIDENCE_THRESHOLD)
|
|
405
|
+
.map(([plugin]) => plugin)
|
|
406
|
+
.sort((a, b) => scores[b] - scores[a]); // Sort by score (highest first)
|
|
407
|
+
return detected;
|
|
408
|
+
}
|
|
409
|
+
/**
|
|
410
|
+
* Install SpecWeave marketplace
|
|
411
|
+
*
|
|
412
|
+
* @returns Installation result
|
|
413
|
+
*/
|
|
414
|
+
async installMarketplace() {
|
|
415
|
+
try {
|
|
416
|
+
const settingsPath = path.join(os.homedir(), '.claude', 'settings.json');
|
|
417
|
+
// Create .claude directory if needed
|
|
418
|
+
await fs.ensureDir(path.dirname(settingsPath));
|
|
419
|
+
// Read existing settings or create new
|
|
420
|
+
let settings = {};
|
|
421
|
+
if (await fs.pathExists(settingsPath)) {
|
|
422
|
+
settings = await fs.readJson(settingsPath);
|
|
423
|
+
}
|
|
424
|
+
// Add SpecWeave marketplace
|
|
425
|
+
settings.extraKnownMarketplaces =
|
|
426
|
+
settings.extraKnownMarketplaces || {};
|
|
427
|
+
settings.extraKnownMarketplaces.specweave = SPECWEAVE_MARKETPLACE_CONFIG;
|
|
428
|
+
// Write settings
|
|
429
|
+
await fs.writeJson(settingsPath, settings, { spaces: 2 });
|
|
430
|
+
this.log('Marketplace configuration written to settings.json');
|
|
431
|
+
return {
|
|
432
|
+
success: true,
|
|
433
|
+
component: 'marketplace',
|
|
434
|
+
details: settingsPath,
|
|
435
|
+
};
|
|
436
|
+
}
|
|
437
|
+
catch (error) {
|
|
438
|
+
return {
|
|
439
|
+
success: false,
|
|
440
|
+
component: 'marketplace',
|
|
441
|
+
error: error.message,
|
|
442
|
+
};
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
/**
|
|
446
|
+
* Install a plugin
|
|
447
|
+
*
|
|
448
|
+
* @param pluginName - Name of plugin to install
|
|
449
|
+
* @returns Installation result
|
|
450
|
+
*/
|
|
451
|
+
async installPlugin(pluginName) {
|
|
452
|
+
try {
|
|
453
|
+
// Execute: claude plugin install {pluginName}
|
|
454
|
+
// Note: This requires Claude CLI to be available
|
|
455
|
+
this.log(`Executing: claude plugin install ${pluginName}`);
|
|
456
|
+
const { stdout, stderr } = await execAsync(`claude plugin install ${pluginName}`);
|
|
457
|
+
// Check if installation succeeded
|
|
458
|
+
const pluginInfo = await this.checkPlugin(pluginName);
|
|
459
|
+
if (pluginInfo.installed) {
|
|
460
|
+
return {
|
|
461
|
+
success: true,
|
|
462
|
+
component: pluginName,
|
|
463
|
+
details: stdout.trim() || stderr.trim(),
|
|
464
|
+
};
|
|
465
|
+
}
|
|
466
|
+
return {
|
|
467
|
+
success: false,
|
|
468
|
+
component: pluginName,
|
|
469
|
+
error: 'Installation completed but plugin not detected',
|
|
470
|
+
details: stdout.trim() || stderr.trim(),
|
|
471
|
+
};
|
|
472
|
+
}
|
|
473
|
+
catch (error) {
|
|
474
|
+
// Check if Claude CLI is not available
|
|
475
|
+
if (error.message.includes('command not found')) {
|
|
476
|
+
return {
|
|
477
|
+
success: false,
|
|
478
|
+
component: pluginName,
|
|
479
|
+
error: 'Claude CLI not available. Please install manually using /plugin install command.',
|
|
480
|
+
};
|
|
481
|
+
}
|
|
482
|
+
return {
|
|
483
|
+
success: false,
|
|
484
|
+
component: pluginName,
|
|
485
|
+
error: error.message,
|
|
486
|
+
};
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
/**
|
|
490
|
+
* Get cached validation result
|
|
491
|
+
*
|
|
492
|
+
* @returns Cached result if valid, null otherwise
|
|
493
|
+
*/
|
|
494
|
+
async getCachedValidation() {
|
|
495
|
+
try {
|
|
496
|
+
if (!(await fs.pathExists(this.cacheFile))) {
|
|
497
|
+
return null;
|
|
498
|
+
}
|
|
499
|
+
const cache = await fs.readJson(this.cacheFile);
|
|
500
|
+
const age = (Date.now() - cache.timestamp) / 1000; // seconds
|
|
501
|
+
if (age > CACHE_TTL) {
|
|
502
|
+
this.log(`Cache expired (age: ${age}s, TTL: ${CACHE_TTL}s)`);
|
|
503
|
+
return null;
|
|
504
|
+
}
|
|
505
|
+
this.log(`Cache hit (age: ${age}s)`);
|
|
506
|
+
return { ...cache.result, cache: { hit: true, age } };
|
|
507
|
+
}
|
|
508
|
+
catch (error) {
|
|
509
|
+
this.log(`Error reading cache: ${error.message}`);
|
|
510
|
+
return null;
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
/**
|
|
514
|
+
* Set cached validation result
|
|
515
|
+
*
|
|
516
|
+
* @param result - Validation result to cache
|
|
517
|
+
*/
|
|
518
|
+
async setCachedValidation(result) {
|
|
519
|
+
try {
|
|
520
|
+
await fs.ensureDir(path.dirname(this.cacheFile));
|
|
521
|
+
const cache = {
|
|
522
|
+
timestamp: Date.now(),
|
|
523
|
+
result,
|
|
524
|
+
};
|
|
525
|
+
await fs.writeJson(this.cacheFile, cache, { spaces: 2 });
|
|
526
|
+
this.log('Validation result cached');
|
|
527
|
+
}
|
|
528
|
+
catch (error) {
|
|
529
|
+
this.log(`Error writing cache: ${error.message}`);
|
|
530
|
+
// Non-fatal error, continue
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
/**
|
|
534
|
+
* Log message if verbose mode enabled
|
|
535
|
+
*/
|
|
536
|
+
log(message) {
|
|
537
|
+
if (this.verbose) {
|
|
538
|
+
console.log(`[PluginValidator] ${message}`);
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
// ============================================================================
|
|
543
|
+
// Utility Functions
|
|
544
|
+
// ============================================================================
|
|
545
|
+
/**
|
|
546
|
+
* Validate plugins (convenience function)
|
|
547
|
+
*
|
|
548
|
+
* @param options - Validation options
|
|
549
|
+
* @returns Validation result
|
|
550
|
+
*/
|
|
551
|
+
export async function validatePlugins(options = {}) {
|
|
552
|
+
const validator = new PluginValidator();
|
|
553
|
+
return validator.validate(options);
|
|
554
|
+
}
|
|
555
|
+
/**
|
|
556
|
+
* Check if SpecWeave is properly installed
|
|
557
|
+
*
|
|
558
|
+
* @returns True if marketplace and core plugin are installed
|
|
559
|
+
*/
|
|
560
|
+
export async function isSpecWeaveInstalled() {
|
|
561
|
+
const validator = new PluginValidator();
|
|
562
|
+
const result = await validator.validate({ autoInstall: false });
|
|
563
|
+
return result.valid;
|
|
564
|
+
}
|
|
565
|
+
//# sourceMappingURL=plugin-validator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin-validator.js","sourceRoot":"","sources":["../../src/utils/plugin-validator.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "specweave",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.1",
|
|
4
4
|
"description": "Spec-driven development framework for Claude Code. AI-native workflow with living documentation, intelligent agents, and multilingual support (9 languages). Enterprise-grade traceability with permanent specs and temporary increments.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
"test:e2e": "playwright test tests/e2e/ --grep-invert=\"(should default to claude adapter|should use claude adapter when explicitly requested|should use generic adapter|should create .claude|should initialize project with specweave init|should create correct directory structure|should handle non-interactive mode correctly|should validate config.json structure|should create .specweave directory structure|should create CLAUDE.md and AGENTS.md|should initialize git repository|should install SpecWeave|should scaffold SaaS|should create proper directory|should create required configuration|should install core skills|should install core agents|should have deployment|should have Stripe|ADO Sync)\"",
|
|
18
18
|
"test:integration": "echo 'Integration tests are temporarily disabled (excluded in jest.config.cjs line 31)' && exit 0",
|
|
19
19
|
"test": "npm run test:smoke && npm run test:e2e",
|
|
20
|
+
"validate:plugins": "node scripts/validate-plugin-manifests.cjs",
|
|
20
21
|
"metrics:dora": "node dist/metrics/dora-calculator.js",
|
|
21
22
|
"generate:diagrams": "bash scripts/generate-diagram-svgs.sh",
|
|
22
23
|
"docs:dev": "cd docs-site && npm start",
|
|
@@ -40,6 +40,53 @@ You are helping the user implement a SpecWeave increment by executing tasks from
|
|
|
40
40
|
|
|
41
41
|
## Workflow
|
|
42
42
|
|
|
43
|
+
### Step 0: Plugin Validation (MANDATORY - ALWAYS FIRST! v0.9.4+)
|
|
44
|
+
|
|
45
|
+
🚨 **CRITICAL**: Before ANY task execution, validate SpecWeave plugin installation.
|
|
46
|
+
|
|
47
|
+
**Why This Matters**:
|
|
48
|
+
- Ensures SpecWeave marketplace is registered in Claude Code
|
|
49
|
+
- Ensures core `specweave` plugin is installed
|
|
50
|
+
- Prevents execution failures from missing dependencies
|
|
51
|
+
- Enables seamless environment migration (local → VM → Cloud IDE)
|
|
52
|
+
|
|
53
|
+
**Implementation**:
|
|
54
|
+
|
|
55
|
+
Use the Bash tool to run:
|
|
56
|
+
```bash
|
|
57
|
+
npx specweave validate-plugins --auto-install
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
**Expected Output (Success)**:
|
|
61
|
+
```
|
|
62
|
+
✅ All plugins validated!
|
|
63
|
+
• Core plugin: installed (v0.9.4)
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
**Expected Output (Missing Components)**:
|
|
67
|
+
```
|
|
68
|
+
❌ Missing components detected:
|
|
69
|
+
• SpecWeave marketplace not registered
|
|
70
|
+
• Core plugin (specweave) not installed
|
|
71
|
+
|
|
72
|
+
📦 Installing missing components...
|
|
73
|
+
✅ Marketplace registered (.claude/settings.json)
|
|
74
|
+
✅ Core plugin installed (specweave)
|
|
75
|
+
|
|
76
|
+
🎉 Environment ready! Proceeding with task execution...
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
**What to Do After Validation**:
|
|
80
|
+
|
|
81
|
+
1. ✅ **If validation passes**: Proceed to Step 1
|
|
82
|
+
2. ⚠️ **If validation fails with errors**: Show error messages and STOP (do NOT proceed)
|
|
83
|
+
3. 🔄 **If auto-install succeeded**: Proceed to Step 1
|
|
84
|
+
4. ⚠️ **If auto-install failed**: Show manual instructions and STOP
|
|
85
|
+
|
|
86
|
+
**DO NOT PROCEED** to Step 1 until plugin validation passes!
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
43
90
|
### Step 1: Load Context
|
|
44
91
|
|
|
45
92
|
1. **Find increment directory**:
|