specweave 1.0.255 → 1.0.256

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 (92) hide show
  1. package/CLAUDE.md +24 -24
  2. package/README.md +138 -203
  3. package/dist/src/core/ac-checkbox-formatter.d.ts +24 -0
  4. package/dist/src/core/ac-checkbox-formatter.d.ts.map +1 -0
  5. package/dist/src/core/ac-checkbox-formatter.js +35 -0
  6. package/dist/src/core/ac-checkbox-formatter.js.map +1 -0
  7. package/dist/src/core/ac-progress-sync.d.ts +116 -0
  8. package/dist/src/core/ac-progress-sync.d.ts.map +1 -0
  9. package/dist/src/core/ac-progress-sync.js +272 -0
  10. package/dist/src/core/ac-progress-sync.js.map +1 -0
  11. package/dist/src/core/fabric/registry-schema.d.ts +79 -0
  12. package/dist/src/core/fabric/registry-schema.d.ts.map +1 -0
  13. package/dist/src/core/fabric/registry-schema.js +6 -0
  14. package/dist/src/core/fabric/registry-schema.js.map +1 -0
  15. package/dist/src/core/fabric/security-scanner.d.ts +12 -0
  16. package/dist/src/core/fabric/security-scanner.d.ts.map +1 -0
  17. package/dist/src/core/fabric/security-scanner.js +219 -0
  18. package/dist/src/core/fabric/security-scanner.js.map +1 -0
  19. package/dist/src/core/types/sync-profile.d.ts +44 -0
  20. package/dist/src/core/types/sync-profile.d.ts.map +1 -1
  21. package/dist/src/core/types/sync-profile.js.map +1 -1
  22. package/package.json +1 -1
  23. package/plugins/specweave/hooks/v2/dispatchers/post-tool-use.sh +4 -4
  24. package/plugins/{specweave-github/hooks/github-ac-sync-handler.sh → specweave/hooks/v2/handlers/ac-sync-dispatcher.sh} +96 -92
  25. package/plugins/specweave/skills/architect/SKILL.md +1 -1
  26. package/plugins/specweave/skills/auto/SKILL.md +1 -1
  27. package/plugins/specweave/skills/cancel-auto/SKILL.md +1 -1
  28. package/plugins/specweave/skills/code-simplifier/SKILL.md +1 -1
  29. package/plugins/specweave/skills/do/SKILL.md +1 -1
  30. package/plugins/specweave/skills/docs/SKILL.md +1 -1
  31. package/plugins/specweave/skills/docs-updater/SKILL.md +1 -1
  32. package/plugins/specweave/skills/done/SKILL.md +13 -70
  33. package/plugins/specweave/skills/framework/SKILL.md +1 -1
  34. package/plugins/specweave/skills/grill/SKILL.md +1 -1
  35. package/plugins/specweave/skills/increment/SKILL.md +1 -1
  36. package/plugins/specweave/skills/increment-planner/SKILL.md +1 -1
  37. package/plugins/specweave/skills/lsp/SKILL.md +1 -1
  38. package/plugins/specweave/skills/pm/SKILL.md +1 -1
  39. package/plugins/specweave/skills/progress/SKILL.md +1 -1
  40. package/plugins/specweave/skills/save/SKILL.md +1 -1
  41. package/plugins/specweave/skills/security/SKILL.md +1 -1
  42. package/plugins/specweave/skills/security-patterns/SKILL.md +1 -1
  43. package/plugins/specweave/skills/tdd-cycle/SKILL.md +1 -1
  44. package/plugins/specweave/skills/tdd-green/SKILL.md +1 -1
  45. package/plugins/specweave/skills/tdd-orchestrator/SKILL.md +1 -1
  46. package/plugins/specweave/skills/tdd-red/SKILL.md +1 -1
  47. package/plugins/specweave/skills/validate/SKILL.md +1 -1
  48. package/plugins/specweave-github/commands/sync.md +1 -22
  49. package/dist/plugins/specweave-github/lib/ThreeLayerSyncManager.d.ts +0 -205
  50. package/dist/plugins/specweave-github/lib/ThreeLayerSyncManager.d.ts.map +0 -1
  51. package/dist/plugins/specweave-github/lib/ThreeLayerSyncManager.js +0 -685
  52. package/dist/plugins/specweave-github/lib/ThreeLayerSyncManager.js.map +0 -1
  53. package/dist/plugins/specweave-github/lib/cli-sync-increment-changes.d.ts +0 -12
  54. package/dist/plugins/specweave-github/lib/cli-sync-increment-changes.d.ts.map +0 -1
  55. package/dist/plugins/specweave-github/lib/cli-sync-increment-changes.js +0 -28
  56. package/dist/plugins/specweave-github/lib/cli-sync-increment-changes.js.map +0 -1
  57. package/dist/plugins/specweave-github/lib/github-increment-sync-cli.d.ts +0 -21
  58. package/dist/plugins/specweave-github/lib/github-increment-sync-cli.d.ts.map +0 -1
  59. package/dist/plugins/specweave-github/lib/github-increment-sync-cli.js +0 -471
  60. package/dist/plugins/specweave-github/lib/github-increment-sync-cli.js.map +0 -1
  61. package/dist/plugins/specweave-github/lib/github-status-sync.d.ts +0 -53
  62. package/dist/plugins/specweave-github/lib/github-status-sync.d.ts.map +0 -1
  63. package/dist/plugins/specweave-github/lib/github-status-sync.js +0 -120
  64. package/dist/plugins/specweave-github/lib/github-status-sync.js.map +0 -1
  65. package/dist/plugins/specweave-github/lib/github-sync-increment-changes.d.ts +0 -18
  66. package/dist/plugins/specweave-github/lib/github-sync-increment-changes.d.ts.map +0 -1
  67. package/dist/plugins/specweave-github/lib/github-sync-increment-changes.js +0 -297
  68. package/dist/plugins/specweave-github/lib/github-sync-increment-changes.js.map +0 -1
  69. package/dist/plugins/specweave-github/lib/increment-issue-builder.d.ts +0 -94
  70. package/dist/plugins/specweave-github/lib/increment-issue-builder.d.ts.map +0 -1
  71. package/dist/plugins/specweave-github/lib/increment-issue-builder.js +0 -385
  72. package/dist/plugins/specweave-github/lib/increment-issue-builder.js.map +0 -1
  73. package/plugins/specweave-github/lib/ThreeLayerSyncManager.js +0 -611
  74. package/plugins/specweave-github/lib/ThreeLayerSyncManager.ts +0 -909
  75. package/plugins/specweave-github/lib/cli-sync-increment-changes.d.js +0 -1
  76. package/plugins/specweave-github/lib/cli-sync-increment-changes.d.ts +0 -12
  77. package/plugins/specweave-github/lib/cli-sync-increment-changes.d.ts.map +0 -1
  78. package/plugins/specweave-github/lib/cli-sync-increment-changes.js +0 -17
  79. package/plugins/specweave-github/lib/cli-sync-increment-changes.js.map +0 -1
  80. package/plugins/specweave-github/lib/cli-sync-increment-changes.ts +0 -33
  81. package/plugins/specweave-github/lib/github-increment-sync-cli.js +0 -474
  82. package/plugins/specweave-github/lib/github-increment-sync-cli.ts +0 -616
  83. package/plugins/specweave-github/lib/github-status-sync.js +0 -107
  84. package/plugins/specweave-github/lib/github-status-sync.ts +0 -163
  85. package/plugins/specweave-github/lib/github-sync-increment-changes.d.js +0 -0
  86. package/plugins/specweave-github/lib/github-sync-increment-changes.d.ts +0 -18
  87. package/plugins/specweave-github/lib/github-sync-increment-changes.d.ts.map +0 -1
  88. package/plugins/specweave-github/lib/github-sync-increment-changes.js +0 -253
  89. package/plugins/specweave-github/lib/github-sync-increment-changes.js.map +0 -1
  90. package/plugins/specweave-github/lib/github-sync-increment-changes.ts +0 -391
  91. package/plugins/specweave-github/lib/increment-issue-builder.js +0 -402
  92. package/plugins/specweave-github/lib/increment-issue-builder.ts +0 -520
@@ -1,391 +0,0 @@
1
- /**
2
- * GitHub Sync for Increment Changes
3
- *
4
- * Handles syncing spec.md, plan.md, and tasks.md changes to GitHub issues.
5
- * Detects scope changes, architecture updates, and task modifications.
6
- *
7
- * @module github-sync-increment-changes
8
- */
9
-
10
- import * as fs from '../../../src/utils/fs-native.js';
11
- import path from 'path';
12
- import { execSync } from 'child_process';
13
- import {
14
- loadIncrementMetadata,
15
- detectRepo,
16
- postScopeChangeComment
17
- } from './github-issue-updater.js';
18
- import { execFileNoThrow } from '../../../src/utils/execFileNoThrow.js';
19
- import { getGitHubAuthFromProject } from '../../../src/utils/auth-helpers.js';
20
-
21
- /**
22
- * Get environment object with GH_TOKEN for gh CLI commands.
23
- */
24
- function getGhEnv(): NodeJS.ProcessEnv {
25
- const { token } = getGitHubAuthFromProject(process.cwd());
26
- return token
27
- ? { ...process.env, GH_TOKEN: token }
28
- : process.env;
29
- }
30
-
31
- export interface SpecChanges {
32
- added: string[];
33
- removed: string[];
34
- modified: string[];
35
- }
36
-
37
- /**
38
- * Sync increment file changes to GitHub
39
- */
40
- export async function syncIncrementChanges(
41
- incrementId: string,
42
- changedFile: 'spec.md' | 'plan.md' | 'tasks.md'
43
- ): Promise<void> {
44
- console.log(`\n🔄 Syncing ${changedFile} changes to GitHub...`);
45
-
46
- try {
47
- // 1. Load metadata
48
- const metadata = await loadIncrementMetadata(incrementId);
49
- if (!metadata?.github?.issue) {
50
- console.log('ℹ️ No GitHub issue linked, skipping sync');
51
- return;
52
- }
53
-
54
- // 2. Detect repository
55
- const repoInfo = await detectRepo();
56
- if (!repoInfo) {
57
- console.log('⚠️ Could not detect GitHub repository, skipping sync');
58
- return;
59
- }
60
-
61
- const { owner, repo } = repoInfo;
62
- const issueNumber = metadata.github.issue;
63
-
64
- // 3. Handle different file types
65
- switch (changedFile) {
66
- case 'spec.md':
67
- await syncSpecChanges(incrementId, issueNumber, owner, repo);
68
- break;
69
- case 'plan.md':
70
- await syncPlanChanges(incrementId, issueNumber, owner, repo);
71
- break;
72
- case 'tasks.md':
73
- await syncTasksChanges(incrementId, issueNumber, owner, repo);
74
- break;
75
- }
76
-
77
- console.log(`✅ ${changedFile} changes synced to issue #${issueNumber}`);
78
-
79
- } catch (error) {
80
- console.error(`❌ Error syncing ${changedFile}:`, error);
81
- console.error(' (Non-blocking - continuing...)');
82
- }
83
- }
84
-
85
- /**
86
- * Sync spec.md changes (scope changes)
87
- */
88
- async function syncSpecChanges(
89
- incrementId: string,
90
- issueNumber: number,
91
- owner: string,
92
- repo: string
93
- ): Promise<void> {
94
- const specPath = path.join(
95
- process.cwd(),
96
- '.specweave/increments',
97
- incrementId,
98
- 'spec.md'
99
- );
100
-
101
- // Detect what changed in spec.md
102
- const changes = await detectSpecChanges(specPath);
103
-
104
- if (changes.added.length === 0 && changes.removed.length === 0 && changes.modified.length === 0) {
105
- console.log('ℹ️ No significant spec changes detected');
106
- return;
107
- }
108
-
109
- // Post scope change comment
110
- await postScopeChangeComment(
111
- issueNumber,
112
- {
113
- added: changes.added,
114
- removed: changes.removed,
115
- modified: changes.modified,
116
- reason: 'Spec updated',
117
- impact: estimateImpact(changes)
118
- },
119
- owner,
120
- repo
121
- );
122
-
123
- // Update issue title if needed
124
- const title = await extractSpecTitle(specPath);
125
- if (title) {
126
- await updateIssueTitle(issueNumber, title, owner, repo);
127
- }
128
- }
129
-
130
- /**
131
- * Sync plan.md changes (architecture updates)
132
- */
133
- async function syncPlanChanges(
134
- incrementId: string,
135
- issueNumber: number,
136
- owner: string,
137
- repo: string
138
- ): Promise<void> {
139
- const comment = `
140
- 🏗️ **Architecture Plan Updated**
141
-
142
- The implementation plan has been updated. See [\`plan.md\`](https://github.com/${owner}/${repo}/blob/develop/.specweave/increments/${incrementId}/plan.md) for details.
143
-
144
- **Timestamp**: ${new Date().toISOString()}
145
-
146
- ---
147
- 🤖 Auto-updated by SpecWeave
148
- `.trim();
149
-
150
- await postComment(issueNumber, comment, owner, repo);
151
- }
152
-
153
- /**
154
- * Sync tasks.md changes (task updates)
155
- */
156
- async function syncTasksChanges(
157
- incrementId: string,
158
- issueNumber: number,
159
- owner: string,
160
- repo: string
161
- ): Promise<void> {
162
- const tasksPath = path.join(
163
- process.cwd(),
164
- '.specweave/increments',
165
- incrementId,
166
- 'tasks.md'
167
- );
168
-
169
- // Extract task list
170
- const tasks = await extractTasks(tasksPath);
171
-
172
- // Update issue body with new task checklist
173
- await updateIssueTaskChecklist(issueNumber, tasks, owner, repo);
174
-
175
- const comment = `
176
- 📋 **Task List Updated**
177
-
178
- Tasks have been updated. Total tasks: ${tasks.length}
179
-
180
- **Timestamp**: ${new Date().toISOString()}
181
-
182
- ---
183
- 🤖 Auto-updated by SpecWeave
184
- `.trim();
185
-
186
- await postComment(issueNumber, comment, owner, repo);
187
- }
188
-
189
- /**
190
- * Detect changes in spec.md by comparing with git history
191
- */
192
- async function detectSpecChanges(specPath: string): Promise<SpecChanges> {
193
- const changes: SpecChanges = {
194
- added: [],
195
- removed: [],
196
- modified: []
197
- };
198
-
199
- try {
200
- // Get git diff for spec.md
201
- const diff = execSync(`git diff HEAD~1 "${specPath}" 2>/dev/null || true`, {
202
- encoding: 'utf-8',
203
- cwd: process.cwd()
204
- });
205
-
206
- if (!diff) {
207
- return changes;
208
- }
209
-
210
- // Parse diff to find user story changes
211
- const lines = diff.split('\n');
212
- for (const line of lines) {
213
- // Look for user story additions/removals
214
- if (line.startsWith('+') && line.includes('US-')) {
215
- const match = line.match(/US-\d+:([^(]+)/);
216
- if (match) {
217
- changes.added.push(match[1].trim());
218
- }
219
- } else if (line.startsWith('-') && line.includes('US-')) {
220
- const match = line.match(/US-\d+:([^(]+)/);
221
- if (match) {
222
- changes.removed.push(match[1].trim());
223
- }
224
- }
225
- }
226
-
227
- } catch (error) {
228
- console.warn('⚠️ Could not detect spec changes:', error);
229
- }
230
-
231
- return changes;
232
- }
233
-
234
- /**
235
- * Extract title from spec.md frontmatter
236
- */
237
- async function extractSpecTitle(specPath: string): Promise<string | null> {
238
- try {
239
- const content = await fs.readFile(specPath, 'utf-8');
240
- const match = content.match(/^#\s+(.+)$/m);
241
- return match ? match[1].trim() : null;
242
- } catch (error) {
243
- return null;
244
- }
245
- }
246
-
247
- /**
248
- * Extract tasks from tasks.md
249
- */
250
- async function extractTasks(tasksPath: string): Promise<string[]> {
251
- try {
252
- const content = await fs.readFile(tasksPath, 'utf-8');
253
- const tasks: string[] = [];
254
- const lines = content.split('\n');
255
-
256
- for (const line of lines) {
257
- // Match task headers: ## T-001: Task name
258
- const match = line.match(/^##\s+(T-\d+):\s*(.+)$/);
259
- if (match) {
260
- tasks.push(`${match[1]}: ${match[2]}`);
261
- }
262
- }
263
-
264
- return tasks;
265
- } catch (error) {
266
- return [];
267
- }
268
- }
269
-
270
- /**
271
- * Estimate impact of spec changes
272
- */
273
- function estimateImpact(changes: SpecChanges): string {
274
- const addedCount = changes.added.length;
275
- const removedCount = changes.removed.length;
276
-
277
- if (addedCount > removedCount) {
278
- return `+${addedCount * 8} hours (${addedCount} user stories added)`;
279
- } else if (removedCount > addedCount) {
280
- return `-${removedCount * 8} hours (${removedCount} user stories removed)`;
281
- } else {
282
- return 'Neutral (scope adjusted)';
283
- }
284
- }
285
-
286
- /**
287
- * Update issue title
288
- */
289
- async function updateIssueTitle(
290
- issueNumber: number,
291
- title: string,
292
- owner: string,
293
- repo: string
294
- ): Promise<void> {
295
- const result = await execFileNoThrow('gh', [
296
- 'issue',
297
- 'edit',
298
- String(issueNumber),
299
- '--repo',
300
- `${owner}/${repo}`,
301
- '--title',
302
- title
303
- ], { env: getGhEnv() });
304
-
305
- if (result.exitCode !== 0) {
306
- console.warn(`⚠️ Could not update issue title: ${result.stderr}`);
307
- }
308
- }
309
-
310
- /**
311
- * Update issue task checklist
312
- */
313
- async function updateIssueTaskChecklist(
314
- issueNumber: number,
315
- tasks: string[],
316
- owner: string,
317
- repo: string
318
- ): Promise<void> {
319
- // Get current issue body
320
- const result = await execFileNoThrow('gh', [
321
- 'issue',
322
- 'view',
323
- String(issueNumber),
324
- '--repo',
325
- `${owner}/${repo}`,
326
- '--json',
327
- 'body',
328
- '-q',
329
- '.body'
330
- ], { env: getGhEnv() });
331
-
332
- if (result.exitCode !== 0) {
333
- throw new Error(`Failed to get issue body: ${result.stderr}`);
334
- }
335
-
336
- const currentBody = result.stdout.trim();
337
-
338
- // Build new task checklist
339
- const taskChecklist = tasks.map(task => `- [ ] ${task}`).join('\n');
340
-
341
- // Find and replace task section
342
- const taskSectionRegex = /## Tasks\n\n[\s\S]*?(?=\n## |$)/;
343
- const newTaskSection = `## Tasks\n\nProgress: 0/${tasks.length} tasks (0%)\n\n${taskChecklist}\n`;
344
-
345
- let updatedBody: string;
346
- if (taskSectionRegex.test(currentBody)) {
347
- updatedBody = currentBody.replace(taskSectionRegex, newTaskSection);
348
- } else {
349
- // Append task section
350
- updatedBody = currentBody + '\n\n' + newTaskSection;
351
- }
352
-
353
- // Update issue
354
- const updateResult = await execFileNoThrow('gh', [
355
- 'issue',
356
- 'edit',
357
- String(issueNumber),
358
- '--repo',
359
- `${owner}/${repo}`,
360
- '--body',
361
- updatedBody
362
- ], { env: getGhEnv() });
363
-
364
- if (updateResult.exitCode !== 0) {
365
- throw new Error(`Failed to update issue body: ${updateResult.stderr}`);
366
- }
367
- }
368
-
369
- /**
370
- * Post comment to issue
371
- */
372
- async function postComment(
373
- issueNumber: number,
374
- comment: string,
375
- owner: string,
376
- repo: string
377
- ): Promise<void> {
378
- const result = await execFileNoThrow('gh', [
379
- 'issue',
380
- 'comment',
381
- String(issueNumber),
382
- '--repo',
383
- `${owner}/${repo}`,
384
- '--body',
385
- comment
386
- ], { env: getGhEnv() });
387
-
388
- if (result.exitCode !== 0) {
389
- throw new Error(`Failed to post comment: ${result.stderr}`);
390
- }
391
- }