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.
Files changed (75) hide show
  1. package/CLAUDE.md +153 -13
  2. package/README.md +97 -251
  3. package/bin/install-agents.sh +1 -1
  4. package/bin/install-commands.sh +1 -1
  5. package/bin/install-hooks.sh +1 -1
  6. package/bin/install-skills.sh +1 -1
  7. package/bin/specweave.js +32 -0
  8. package/dist/cli/commands/init.d.ts.map +1 -1
  9. package/dist/cli/commands/init.js +29 -1
  10. package/dist/cli/commands/init.js.map +1 -1
  11. package/dist/cli/commands/validate-jira.d.ts +35 -0
  12. package/dist/cli/commands/validate-jira.d.ts.map +1 -0
  13. package/dist/cli/commands/validate-jira.js +112 -0
  14. package/dist/cli/commands/validate-jira.js.map +1 -0
  15. package/dist/cli/commands/validate-plugins.d.ts +41 -0
  16. package/dist/cli/commands/validate-plugins.d.ts.map +1 -0
  17. package/dist/cli/commands/validate-plugins.js +171 -0
  18. package/dist/cli/commands/validate-plugins.js.map +1 -0
  19. package/dist/core/types/sync-profile.d.ts +177 -29
  20. package/dist/core/types/sync-profile.d.ts.map +1 -1
  21. package/dist/core/types/sync-profile.js +48 -1
  22. package/dist/core/types/sync-profile.js.map +1 -1
  23. package/dist/hooks/lib/translate-living-docs.d.ts.map +1 -1
  24. package/dist/hooks/lib/translate-living-docs.js +16 -7
  25. package/dist/hooks/lib/translate-living-docs.js.map +1 -1
  26. package/dist/metrics/dora-calculator.d.ts +7 -3
  27. package/dist/metrics/dora-calculator.d.ts.map +1 -1
  28. package/dist/metrics/dora-calculator.js +19 -6
  29. package/dist/metrics/dora-calculator.js.map +1 -1
  30. package/dist/metrics/report-generator.d.ts +17 -0
  31. package/dist/metrics/report-generator.d.ts.map +1 -0
  32. package/dist/metrics/report-generator.js +403 -0
  33. package/dist/metrics/report-generator.js.map +1 -0
  34. package/dist/utils/external-resource-validator.d.ts +102 -0
  35. package/dist/utils/external-resource-validator.d.ts.map +1 -0
  36. package/dist/utils/external-resource-validator.js +400 -0
  37. package/dist/utils/external-resource-validator.js.map +1 -0
  38. package/dist/utils/plugin-validator.d.ts +161 -0
  39. package/dist/utils/plugin-validator.d.ts.map +1 -0
  40. package/dist/utils/plugin-validator.js +565 -0
  41. package/dist/utils/plugin-validator.js.map +1 -0
  42. package/package.json +2 -1
  43. package/plugins/specweave/commands/specweave-do.md +47 -0
  44. package/plugins/specweave/commands/specweave-increment.md +82 -0
  45. package/plugins/specweave/commands/specweave-next.md +47 -0
  46. package/plugins/specweave/hooks/post-increment-planning.sh +117 -38
  47. package/plugins/specweave/hooks/pre-tool-use.sh +133 -0
  48. package/plugins/specweave/plugin.json +22 -0
  49. package/plugins/specweave/skills/SKILLS-INDEX.md +23 -2
  50. package/plugins/specweave/skills/plugin-installer/SKILL.md +340 -0
  51. package/plugins/specweave/skills/plugin-validator/SKILL.md +427 -0
  52. package/plugins/specweave-ado/.claude-plugin/plugin.json +2 -4
  53. package/plugins/specweave-ado/lib/ado-board-resolver.ts +328 -0
  54. package/plugins/specweave-ado/lib/ado-hierarchical-sync.ts +484 -0
  55. package/plugins/specweave-ado/plugin.json +20 -0
  56. package/plugins/specweave-alternatives/.claude-plugin/plugin.json +15 -2
  57. package/plugins/specweave-backend/.claude-plugin/plugin.json +15 -2
  58. package/plugins/specweave-cost-optimizer/.claude-plugin/plugin.json +14 -2
  59. package/plugins/specweave-diagrams/.claude-plugin/plugin.json +14 -2
  60. package/plugins/specweave-docs/.claude-plugin/plugin.json +13 -2
  61. package/plugins/specweave-figma/.claude-plugin/plugin.json +14 -2
  62. package/plugins/specweave-frontend/.claude-plugin/plugin.json +15 -2
  63. package/plugins/specweave-github/lib/github-board-resolver.ts +164 -0
  64. package/plugins/specweave-github/lib/github-hierarchical-sync.ts +344 -0
  65. package/plugins/specweave-github/plugin.json +19 -0
  66. package/plugins/specweave-infrastructure/.claude-plugin/plugin.json +15 -2
  67. package/plugins/specweave-jira/.claude-plugin/plugin.json +14 -2
  68. package/plugins/specweave-jira/lib/jira-board-resolver.ts +127 -0
  69. package/plugins/specweave-jira/lib/jira-hierarchical-sync.ts +283 -0
  70. package/plugins/specweave-jira/plugin.json +20 -0
  71. package/plugins/specweave-jira/skills/jira-resource-validator/SKILL.md +647 -0
  72. package/plugins/specweave-kubernetes/.claude-plugin/plugin.json +14 -2
  73. package/plugins/specweave-payments/.claude-plugin/plugin.json +14 -2
  74. package/plugins/specweave-testing/.claude-plugin/plugin.json +14 -2
  75. package/plugins/specweave-tooling/.claude-plugin/plugin.json +13 -2
@@ -0,0 +1,484 @@
1
+ /**
2
+ * Azure DevOps Hierarchical Sync Implementation
3
+ *
4
+ * Supports three sync strategies:
5
+ * 1. Simple: One project, all work items (backward compatible)
6
+ * 2. Filtered: Multiple projects + area paths + filters
7
+ * 3. Custom: Raw WIQL query
8
+ */
9
+
10
+ import {
11
+ SyncProfile,
12
+ SyncContainer,
13
+ AdoConfig,
14
+ isSimpleStrategy,
15
+ isFilteredStrategy,
16
+ isCustomStrategy,
17
+ TimeRangePreset,
18
+ } from '../../../src/core/types/sync-profile.js';
19
+ import { WorkItem } from './ado-client-v2.js';
20
+ import { getAreaPaths } from './ado-board-resolver.js';
21
+ import https from 'https';
22
+
23
+ /**
24
+ * Build hierarchical WIQL query from containers
25
+ *
26
+ * Example output:
27
+ * SELECT [System.Id], [System.Title], [System.State]
28
+ * FROM WorkItems
29
+ * WHERE (
30
+ * ([System.TeamProject] = 'PROJECT-A' AND [System.AreaPath] UNDER 'PROJECT-A\\Team Alpha')
31
+ * OR
32
+ * ([System.TeamProject] = 'PROJECT-B' AND [System.AreaPath] UNDER 'PROJECT-B\\Platform')
33
+ * )
34
+ * AND [System.WorkItemType] IN ('User Story', 'Bug')
35
+ * AND [System.State] IN ('Active', 'New')
36
+ *
37
+ * @param organization Organization name
38
+ * @param pat Personal Access Token
39
+ * @param containers Array of containers (projects) with filters
40
+ * @returns WIQL query string
41
+ */
42
+ export async function buildHierarchicalWIQL(
43
+ organization: string,
44
+ pat: string,
45
+ containers: SyncContainer[]
46
+ ): Promise<string> {
47
+ const projectClauses: string[] = [];
48
+
49
+ for (const container of containers) {
50
+ const parts: string[] = [];
51
+
52
+ // Project clause
53
+ parts.push(`[System.TeamProject] = '${container.id}'`);
54
+
55
+ // Area path filtering (sub-organizations)
56
+ if (container.subOrganizations && container.subOrganizations.length > 0) {
57
+ try {
58
+ const areaPaths = await getAreaPaths(
59
+ organization,
60
+ container.id,
61
+ pat,
62
+ container.subOrganizations
63
+ );
64
+
65
+ if (areaPaths.length > 0) {
66
+ const areaPathClauses = areaPaths
67
+ .map((path) => `[System.AreaPath] UNDER '${path}'`)
68
+ .join(' OR ');
69
+
70
+ parts.push(`(${areaPathClauses})`);
71
+ } else {
72
+ console.warn(
73
+ `⚠️ No valid area paths found for project ${container.id}, syncing all areas`
74
+ );
75
+ }
76
+ } catch (error) {
77
+ console.warn(
78
+ `⚠️ Failed to resolve area paths for ${container.id}, syncing all areas:`,
79
+ (error as Error).message
80
+ );
81
+ }
82
+ }
83
+
84
+ // Combine parts with AND
85
+ projectClauses.push(`(${parts.join(' AND ')})`);
86
+ }
87
+
88
+ // Build WHERE clause with project clauses
89
+ let whereClause = projectClauses.join(' OR ');
90
+
91
+ // Add global filters (apply to all projects)
92
+ const filters = containers[0]?.filters;
93
+ if (filters) {
94
+ const filterClauses = buildFilterClauses(filters);
95
+ if (filterClauses.length > 0) {
96
+ whereClause = `(${whereClause}) AND ${filterClauses.join(' AND ')}`;
97
+ }
98
+ }
99
+
100
+ // Build complete WIQL query
101
+ return `
102
+ SELECT [System.Id], [System.Title], [System.Description], [System.State],
103
+ [System.CreatedDate], [System.ChangedDate], [System.WorkItemType],
104
+ [System.AreaPath], [System.IterationPath], [System.Tags]
105
+ FROM WorkItems
106
+ WHERE ${whereClause}
107
+ ORDER BY [System.CreatedDate] DESC
108
+ `.trim();
109
+ }
110
+
111
+ /**
112
+ * Build filter clauses from container filters
113
+ *
114
+ * @param filters Container filters
115
+ * @returns Array of WIQL filter clauses
116
+ */
117
+ function buildFilterClauses(filters: any): string[] {
118
+ const clauses: string[] = [];
119
+
120
+ // Work item types (ADO-specific)
121
+ if (filters.workItemTypes && filters.workItemTypes.length > 0) {
122
+ const types = filters.workItemTypes.map((t: string) => `'${t}'`).join(', ');
123
+ clauses.push(`[System.WorkItemType] IN (${types})`);
124
+ }
125
+
126
+ // Status categories (ADO uses State field)
127
+ if (filters.statusCategories && filters.statusCategories.length > 0) {
128
+ const states = filters.statusCategories.map((s: string) => `'${s}'`).join(', ');
129
+ clauses.push(`[System.State] IN (${states})`);
130
+ }
131
+
132
+ // Area paths (additional filtering beyond sub-organizations)
133
+ if (filters.areaPaths && filters.areaPaths.length > 0) {
134
+ const areaPathClauses = filters.areaPaths
135
+ .map((path: string) => `[System.AreaPath] UNDER '${path}'`)
136
+ .join(' OR ');
137
+ clauses.push(`(${areaPathClauses})`);
138
+ }
139
+
140
+ // Iteration paths (sprints in ADO)
141
+ if (filters.iterationPaths && filters.iterationPaths.length > 0) {
142
+ const iterationClauses = filters.iterationPaths
143
+ .map((path: string) => `[System.IterationPath] UNDER '${path}'`)
144
+ .join(' OR ');
145
+ clauses.push(`(${iterationClauses})`);
146
+ }
147
+
148
+ // Tags (labels in ADO)
149
+ if (filters.includeLabels && filters.includeLabels.length > 0) {
150
+ const tagClauses = filters.includeLabels
151
+ .map((tag: string) => `[System.Tags] CONTAINS '${tag}'`)
152
+ .join(' OR ');
153
+ clauses.push(`(${tagClauses})`);
154
+ }
155
+
156
+ // Exclude labels/tags
157
+ if (filters.excludeLabels && filters.excludeLabels.length > 0) {
158
+ for (const tag of filters.excludeLabels) {
159
+ clauses.push(`NOT [System.Tags] CONTAINS '${tag}'`);
160
+ }
161
+ }
162
+
163
+ // Assignees (assigned to)
164
+ if (filters.assignees && filters.assignees.length > 0) {
165
+ const assigneeClauses = filters.assignees
166
+ .map((assignee: string) => `[System.AssignedTo] = '${assignee}'`)
167
+ .join(' OR ');
168
+ clauses.push(`(${assigneeClauses})`);
169
+ }
170
+
171
+ return clauses;
172
+ }
173
+
174
+ /**
175
+ * Add time range filter to WIQL query
176
+ *
177
+ * @param wiql Base WIQL query
178
+ * @param timeRange Time range preset (1W, 1M, 3M, 6M, ALL)
179
+ * @returns WIQL with time range filter
180
+ */
181
+ function addTimeRangeFilter(wiql: string, timeRange: string): string {
182
+ if (timeRange === 'ALL') {
183
+ return wiql; // No time filter
184
+ }
185
+
186
+ const { since, until } = calculateTimeRange(timeRange as TimeRangePreset);
187
+
188
+ // Add time range to WHERE clause
189
+ const timeFilter = `[System.CreatedDate] >= '${since}' AND [System.CreatedDate] <= '${until}'`;
190
+
191
+ // Insert before ORDER BY if present, otherwise append
192
+ if (wiql.includes('ORDER BY')) {
193
+ return wiql.replace('ORDER BY', `AND ${timeFilter} ORDER BY`);
194
+ } else {
195
+ return `${wiql} AND ${timeFilter}`;
196
+ }
197
+ }
198
+
199
+ /**
200
+ * Calculate date range from time range preset
201
+ */
202
+ function calculateTimeRange(timeRange: TimeRangePreset): {
203
+ since: string;
204
+ until: string;
205
+ } {
206
+ const now = new Date();
207
+ const since = new Date(now);
208
+
209
+ switch (timeRange) {
210
+ case '1W':
211
+ since.setDate(now.getDate() - 7);
212
+ break;
213
+ case '2W':
214
+ since.setDate(now.getDate() - 14);
215
+ break;
216
+ case '1M':
217
+ since.setMonth(now.getMonth() - 1);
218
+ break;
219
+ case '3M':
220
+ since.setMonth(now.getMonth() - 3);
221
+ break;
222
+ case '6M':
223
+ since.setMonth(now.getMonth() - 6);
224
+ break;
225
+ case '1Y':
226
+ since.setFullYear(now.getFullYear() - 1);
227
+ break;
228
+ case 'ALL':
229
+ return {
230
+ since: '1970-01-01T00:00:00Z',
231
+ until: now.toISOString(),
232
+ };
233
+ }
234
+
235
+ return {
236
+ since: since.toISOString(),
237
+ until: now.toISOString(),
238
+ };
239
+ }
240
+
241
+ /**
242
+ * Fetch work items hierarchically based on sync strategy
243
+ *
244
+ * @param profile Sync profile with strategy
245
+ * @param pat Personal Access Token
246
+ * @param timeRange Time range preset
247
+ * @returns Array of work items
248
+ */
249
+ export async function fetchWorkItemsHierarchical(
250
+ profile: SyncProfile,
251
+ pat: string,
252
+ timeRange: string = '1M'
253
+ ): Promise<WorkItem[]> {
254
+ const config = profile.config as AdoConfig;
255
+
256
+ // Strategy 1: SIMPLE (backward compatible)
257
+ if (isSimpleStrategy(profile)) {
258
+ return fetchWorkItemsSimple(config, pat, timeRange);
259
+ }
260
+
261
+ // Strategy 2: CUSTOM (raw WIQL)
262
+ if (isCustomStrategy(profile)) {
263
+ return fetchWorkItemsCustom(config, pat, timeRange);
264
+ }
265
+
266
+ // Strategy 3: FILTERED (hierarchical)
267
+ if (isFilteredStrategy(profile)) {
268
+ return fetchWorkItemsFiltered(config, pat, timeRange);
269
+ }
270
+
271
+ // Default to simple if strategy not recognized
272
+ console.warn('⚠️ Unknown strategy, defaulting to simple');
273
+ return fetchWorkItemsSimple(config, pat, timeRange);
274
+ }
275
+
276
+ /**
277
+ * Fetch work items using SIMPLE strategy (one project, all work items)
278
+ *
279
+ * @param config ADO configuration
280
+ * @param pat Personal Access Token
281
+ * @param timeRange Time range preset
282
+ * @returns Array of work items
283
+ */
284
+ async function fetchWorkItemsSimple(
285
+ config: AdoConfig,
286
+ pat: string,
287
+ timeRange: string
288
+ ): Promise<WorkItem[]> {
289
+ const organization = config.organization;
290
+ const project = config.project;
291
+
292
+ if (!project) {
293
+ throw new Error('Simple strategy requires project in config');
294
+ }
295
+
296
+ let wiql = `
297
+ SELECT [System.Id], [System.Title], [System.State], [System.CreatedDate]
298
+ FROM WorkItems
299
+ WHERE [System.TeamProject] = '${project}'
300
+ `.trim();
301
+
302
+ // Add time range
303
+ wiql = addTimeRangeFilter(wiql, timeRange);
304
+
305
+ console.log('🔍 Fetching work items (SIMPLE strategy):', wiql);
306
+
307
+ return executeQuery(organization, project, pat, wiql);
308
+ }
309
+
310
+ /**
311
+ * Fetch work items using CUSTOM strategy (raw WIQL)
312
+ *
313
+ * @param config ADO configuration
314
+ * @param pat Personal Access Token
315
+ * @param timeRange Time range preset
316
+ * @returns Array of work items
317
+ */
318
+ async function fetchWorkItemsCustom(
319
+ config: AdoConfig,
320
+ pat: string,
321
+ timeRange: string
322
+ ): Promise<WorkItem[]> {
323
+ const organization = config.organization;
324
+ const project = config.project || 'DefaultProject';
325
+ const customQuery = config.customQuery;
326
+
327
+ if (!customQuery) {
328
+ throw new Error('Custom strategy requires customQuery in config');
329
+ }
330
+
331
+ // Add time range to custom query
332
+ const wiql = addTimeRangeFilter(customQuery, timeRange);
333
+
334
+ console.log('🔍 Fetching work items (CUSTOM strategy):', wiql);
335
+
336
+ return executeQuery(organization, project, pat, wiql);
337
+ }
338
+
339
+ /**
340
+ * Fetch work items using FILTERED strategy (multiple projects + area paths + filters)
341
+ *
342
+ * @param config ADO configuration
343
+ * @param pat Personal Access Token
344
+ * @param timeRange Time range preset
345
+ * @returns Array of work items
346
+ */
347
+ async function fetchWorkItemsFiltered(
348
+ config: AdoConfig,
349
+ pat: string,
350
+ timeRange: string
351
+ ): Promise<WorkItem[]> {
352
+ const organization = config.organization;
353
+ const containers = config.containers;
354
+
355
+ if (!containers || containers.length === 0) {
356
+ throw new Error('Filtered strategy requires containers array in config');
357
+ }
358
+
359
+ // Build hierarchical WIQL
360
+ const baseWiql = await buildHierarchicalWIQL(organization, pat, containers);
361
+
362
+ // Add time range
363
+ const wiql = addTimeRangeFilter(baseWiql, timeRange);
364
+
365
+ console.log('🔍 Fetching work items (FILTERED strategy):', wiql);
366
+
367
+ // Use first project for API endpoint (WIQL can query across projects)
368
+ const project = containers[0].id;
369
+
370
+ return executeQuery(organization, project, pat, wiql);
371
+ }
372
+
373
+ /**
374
+ * Execute WIQL query and return work items
375
+ *
376
+ * @param organization Organization name
377
+ * @param project Project name
378
+ * @param pat Personal Access Token
379
+ * @param wiql WIQL query string
380
+ * @returns Array of work items
381
+ */
382
+ async function executeQuery(
383
+ organization: string,
384
+ project: string,
385
+ pat: string,
386
+ wiql: string
387
+ ): Promise<WorkItem[]> {
388
+ const baseUrl = `https://dev.azure.com/${organization}/${project}`;
389
+
390
+ // Execute query
391
+ const queryUrl = `${baseUrl}/_apis/wit/wiql?api-version=7.1`;
392
+ const queryResult: any = await makeRequest(queryUrl, pat, 'POST', { query: wiql });
393
+
394
+ if (!queryResult.workItems || queryResult.workItems.length === 0) {
395
+ return [];
396
+ }
397
+
398
+ // Get full work item details (batch request)
399
+ const ids = queryResult.workItems.map((wi: any) => wi.id);
400
+ const batchUrl = `${baseUrl}/_apis/wit/workitemsbatch?api-version=7.1`;
401
+
402
+ const response: any = await makeRequest(batchUrl, pat, 'POST', {
403
+ ids,
404
+ fields: [
405
+ 'System.Id',
406
+ 'System.Title',
407
+ 'System.Description',
408
+ 'System.State',
409
+ 'System.CreatedDate',
410
+ 'System.ChangedDate',
411
+ 'System.WorkItemType',
412
+ 'System.AreaPath',
413
+ 'System.IterationPath',
414
+ 'System.Tags',
415
+ ],
416
+ });
417
+
418
+ return response.value || [];
419
+ }
420
+
421
+ /**
422
+ * Make HTTPS request to ADO API
423
+ */
424
+ function makeRequest(
425
+ url: string,
426
+ pat: string,
427
+ method: string = 'GET',
428
+ body?: any
429
+ ): Promise<any> {
430
+ return new Promise((resolve, reject) => {
431
+ const { hostname, pathname, search } = new URL(url);
432
+
433
+ const authHeader = 'Basic ' + Buffer.from(`:${pat}`).toString('base64');
434
+
435
+ const headers: Record<string, string> = {
436
+ Authorization: authHeader,
437
+ Accept: 'application/json',
438
+ };
439
+
440
+ if (body) {
441
+ headers['Content-Type'] = 'application/json';
442
+ }
443
+
444
+ const options = {
445
+ hostname,
446
+ path: pathname + search,
447
+ method,
448
+ headers,
449
+ };
450
+
451
+ const req = https.request(options, (res) => {
452
+ let data = '';
453
+
454
+ res.on('data', (chunk) => {
455
+ data += chunk;
456
+ });
457
+
458
+ res.on('end', () => {
459
+ try {
460
+ const parsed = JSON.parse(data);
461
+
462
+ if (res.statusCode && res.statusCode >= 200 && res.statusCode < 300) {
463
+ resolve(parsed);
464
+ } else {
465
+ reject(new Error(`HTTP ${res.statusCode}: ${parsed.message || data}`));
466
+ }
467
+ } catch (error) {
468
+ reject(new Error(`Failed to parse response: ${data}`));
469
+ }
470
+ });
471
+ });
472
+
473
+ req.on('error', (error) => {
474
+ reject(error);
475
+ });
476
+
477
+ // Send body if present
478
+ if (body) {
479
+ req.write(JSON.stringify(body));
480
+ }
481
+
482
+ req.end();
483
+ });
484
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "name": "specweave-ado",
3
+ "version": "0.1.0",
4
+ "description": "Azure DevOps integration for SpecWeave - sync increments with ADO work items, track progress, and manage project workflows",
5
+ "author": {
6
+ "name": "SpecWeave Team",
7
+ "url": "https://spec-weave.com"
8
+ },
9
+ "homepage": "https://spec-weave.com",
10
+ "repository": "https://github.com/anton-abyzov/specweave",
11
+ "keywords": [
12
+ "azure-devops",
13
+ "ado",
14
+ "project-management",
15
+ "work-items",
16
+ "sync",
17
+ "integration"
18
+ ],
19
+ "license": "MIT"
20
+ }
@@ -3,6 +3,19 @@
3
3
  "description": "Compare SpecWeave with BMAD, spec-kit, openspec, and other spec-driven frameworks. Get gap analysis, feature comparison, and strategic recommendations to choose the best framework for your needs.",
4
4
  "version": "1.0.0",
5
5
  "author": {
6
- "name": "SpecWeave Team"
7
- }
6
+ "name": "SpecWeave Team",
7
+ "url": "https://spec-weave.com"
8
+ },
9
+ "homepage": "https://spec-weave.com",
10
+ "repository": "https://github.com/anton-abyzov/specweave",
11
+ "license": "MIT",
12
+ "keywords": [
13
+ "alternatives",
14
+ "comparison",
15
+ "bmad",
16
+ "spec-kit",
17
+ "openspec",
18
+ "framework-comparison",
19
+ "specweave"
20
+ ]
8
21
  }
@@ -3,6 +3,19 @@
3
3
  "description": "Backend API development for Node.js, Python, and .NET stacks. Includes Express, NestJS, FastAPI, Django, Flask, ASP.NET Core, and Entity Framework Core. Focus on REST APIs, authentication, database operations, and background services.",
4
4
  "version": "1.0.0",
5
5
  "author": {
6
- "name": "SpecWeave Team"
7
- }
6
+ "name": "SpecWeave Team",
7
+ "url": "https://spec-weave.com"
8
+ },
9
+ "homepage": "https://spec-weave.com",
10
+ "repository": "https://github.com/anton-abyzov/specweave",
11
+ "license": "MIT",
12
+ "keywords": [
13
+ "backend",
14
+ "nodejs",
15
+ "python",
16
+ "dotnet",
17
+ "rest-api",
18
+ "server",
19
+ "specweave"
20
+ ]
8
21
  }
@@ -3,6 +3,18 @@
3
3
  "description": "Cloud cost optimization and platform comparison. Analyzes infrastructure requirements and recommends cheapest cloud platform (Hetzner, Vercel, AWS, Railway, Fly.io, DigitalOcean). Shows cost breakdown and savings calculations.",
4
4
  "version": "1.0.0",
5
5
  "author": {
6
- "name": "SpecWeave Team"
7
- }
6
+ "name": "SpecWeave Team",
7
+ "url": "https://spec-weave.com"
8
+ },
9
+ "homepage": "https://spec-weave.com",
10
+ "repository": "https://github.com/anton-abyzov/specweave",
11
+ "license": "MIT",
12
+ "keywords": [
13
+ "cost",
14
+ "optimization",
15
+ "cloud",
16
+ "pricing",
17
+ "budget",
18
+ "specweave"
19
+ ]
8
20
  }
@@ -3,6 +3,18 @@
3
3
  "description": "Architecture diagram generation with Mermaid following C4 Model conventions. Creates C4 Context/Container/Component diagrams, sequence diagrams, ER diagrams, and deployment diagrams. SpecWeave-aware for HLD/LLD documentation.",
4
4
  "version": "1.0.0",
5
5
  "author": {
6
- "name": "SpecWeave Team"
7
- }
6
+ "name": "SpecWeave Team",
7
+ "url": "https://spec-weave.com"
8
+ },
9
+ "homepage": "https://spec-weave.com",
10
+ "repository": "https://github.com/anton-abyzov/specweave",
11
+ "license": "MIT",
12
+ "keywords": [
13
+ "diagrams",
14
+ "mermaid",
15
+ "c4-model",
16
+ "architecture",
17
+ "visualization",
18
+ "specweave"
19
+ ]
8
20
  }
@@ -3,6 +3,17 @@
3
3
  "description": "Documentation generation and spec-driven workflows. Includes Docusaurus site generation from SpecWeave structure, spec-driven brainstorming for feature ideation, and spec-driven debugging. Focus on living documentation and knowledge management.",
4
4
  "version": "1.0.0",
5
5
  "author": {
6
- "name": "SpecWeave Team"
7
- }
6
+ "name": "SpecWeave Team",
7
+ "url": "https://spec-weave.com"
8
+ },
9
+ "homepage": "https://spec-weave.com",
10
+ "repository": "https://github.com/anton-abyzov/specweave",
11
+ "license": "MIT",
12
+ "keywords": [
13
+ "documentation",
14
+ "docusaurus",
15
+ "specs",
16
+ "docs-generation",
17
+ "specweave"
18
+ ]
8
19
  }
@@ -3,6 +3,18 @@
3
3
  "description": "Design-to-code workflow patterns for Figma (MCP-first). Requires Figma MCP server. Extracts design tokens, generates components (React/Angular/Vue/Svelte), scaffolds tests. Uses Atomic Design and TypeScript.",
4
4
  "version": "1.0.0",
5
5
  "author": {
6
- "name": "SpecWeave Team"
7
- }
6
+ "name": "SpecWeave Team",
7
+ "url": "https://spec-weave.com"
8
+ },
9
+ "homepage": "https://spec-weave.com",
10
+ "repository": "https://github.com/anton-abyzov/specweave",
11
+ "license": "MIT",
12
+ "keywords": [
13
+ "figma",
14
+ "design",
15
+ "design-system",
16
+ "mcp",
17
+ "design-tokens",
18
+ "specweave"
19
+ ]
8
20
  }
@@ -3,6 +3,19 @@
3
3
  "description": "Frontend development for React, Vue, and Angular projects. Includes Next.js 14+ App Router support, design system architecture (Atomic Design), and UI component best practices. Focus on modern frontend patterns and performance.",
4
4
  "version": "1.0.0",
5
5
  "author": {
6
- "name": "SpecWeave Team"
7
- }
6
+ "name": "SpecWeave Team",
7
+ "url": "https://spec-weave.com"
8
+ },
9
+ "homepage": "https://spec-weave.com",
10
+ "repository": "https://github.com/anton-abyzov/specweave",
11
+ "license": "MIT",
12
+ "keywords": [
13
+ "frontend",
14
+ "react",
15
+ "vue",
16
+ "angular",
17
+ "nextjs",
18
+ "ui",
19
+ "specweave"
20
+ ]
8
21
  }