specweave 0.26.2 ā 0.26.4
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 +172 -1413
- package/dist/src/cli/commands/plan/plan-orchestrator.js +2 -2
- package/dist/src/cli/commands/plan/plan-orchestrator.js.map +1 -1
- 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 +147 -55
- package/dist/src/cli/helpers/issue-tracker/github-multi-repo.js.map +1 -1
- package/dist/src/core/increment/completion-validator.d.ts +4 -0
- package/dist/src/core/increment/completion-validator.d.ts.map +1 -1
- package/dist/src/core/increment/completion-validator.js +36 -0
- package/dist/src/core/increment/completion-validator.js.map +1 -1
- package/dist/src/core/living-docs/living-docs-sync.d.ts.map +1 -1
- package/dist/src/core/living-docs/living-docs-sync.js +47 -13
- package/dist/src/core/living-docs/living-docs-sync.js.map +1 -1
- package/dist/src/core/us-sync-throttle.d.ts +113 -0
- package/dist/src/core/us-sync-throttle.d.ts.map +1 -0
- package/dist/src/core/us-sync-throttle.js +195 -0
- package/dist/src/core/us-sync-throttle.js.map +1 -0
- package/dist/src/utils/external-tool-drift-detector.d.ts +76 -0
- package/dist/src/utils/external-tool-drift-detector.d.ts.map +1 -0
- package/dist/src/utils/external-tool-drift-detector.js +235 -0
- package/dist/src/utils/external-tool-drift-detector.js.map +1 -0
- package/package.json +4 -4
- package/plugins/specweave/hooks/post-task-completion.sh +6 -6
- package/plugins/specweave/hooks/pre-increment-start.sh +6 -1
- package/plugins/specweave/lib/hooks/us-completion-orchestrator.js +62 -89
- package/plugins/specweave/lib/hooks/us-completion-orchestrator.ts +215 -0
- package/plugins/specweave-ado/lib/ado-multi-project-sync.js +0 -1
- package/plugins/specweave-jira/lib/enhanced-jira-sync.js +3 -3
- package/plugins/specweave-release/hooks/post-task-completion.sh +5 -1
- package/plugins/specweave/agents/pm/AGENT.md.bak +0 -1893
- package/plugins/specweave/hooks/docs-changed.sh.backup +0 -79
- package/plugins/specweave/hooks/human-input-required.sh.backup +0 -75
- package/plugins/specweave/hooks/lib/migrate-increment-work.sh.bak +0 -245
- package/plugins/specweave/hooks/lib/sync-spec-content.sh.bak +0 -149
- package/plugins/specweave/hooks/lib/validate-spec-status.sh.bak +0 -163
- package/plugins/specweave/hooks/post-first-increment.sh.backup +0 -61
- package/plugins/specweave/hooks/post-first-increment.sh.bak +0 -61
- package/plugins/specweave/hooks/post-increment-change.sh.backup +0 -98
- package/plugins/specweave/hooks/post-increment-completion.sh.backup +0 -231
- package/plugins/specweave/hooks/post-increment-planning.sh.backup +0 -1048
- package/plugins/specweave/hooks/post-increment-status-change.sh.backup +0 -147
- package/plugins/specweave/hooks/post-spec-update.sh.backup +0 -158
- package/plugins/specweave/hooks/post-spec-update.sh.bak +0 -158
- package/plugins/specweave/hooks/post-user-story-complete.sh.backup +0 -179
- package/plugins/specweave/hooks/post-user-story-complete.sh.bak +0 -179
- package/plugins/specweave/hooks/pre-command-deduplication.sh.backup +0 -83
- package/plugins/specweave/hooks/pre-command-deduplication.sh.bak +0 -83
- package/plugins/specweave/hooks/pre-implementation.sh.backup +0 -67
- package/plugins/specweave/hooks/pre-task-completion.sh.backup +0 -194
- package/plugins/specweave/hooks/pre-tool-use.sh.backup +0 -133
- package/plugins/specweave/hooks/user-prompt-submit.sh.backup +0 -386
- package/plugins/specweave/hooks/user-prompt-submit.sh.bak +0 -386
- package/plugins/specweave/lib/hooks/auto-transition.js.bak +0 -50
- package/plugins/specweave/lib/hooks/auto-transition.ts.bak +0 -84
- package/plugins/specweave/lib/hooks/git-diff-analyzer.d.js.bak +0 -0
- package/plugins/specweave/lib/hooks/git-diff-analyzer.d.ts.bak +0 -89
- package/plugins/specweave/lib/hooks/git-diff-analyzer.js.bak +0 -142
- package/plugins/specweave/lib/hooks/git-diff-analyzer.ts.bak +0 -269
- package/plugins/specweave/lib/hooks/invoke-translator-skill.d.js.bak +0 -0
- package/plugins/specweave/lib/hooks/invoke-translator-skill.d.ts.bak +0 -60
- package/plugins/specweave/lib/hooks/invoke-translator-skill.js.bak +0 -155
- package/plugins/specweave/lib/hooks/invoke-translator-skill.ts.bak +0 -264
- package/plugins/specweave/lib/hooks/prepare-reflection-context.d.js.bak +0 -0
- package/plugins/specweave/lib/hooks/prepare-reflection-context.d.ts.bak +0 -42
- package/plugins/specweave/lib/hooks/prepare-reflection-context.js.bak +0 -110
- package/plugins/specweave/lib/hooks/prepare-reflection-context.ts.bak +0 -178
- package/plugins/specweave/lib/hooks/reflection-config-loader.d.js.bak +0 -0
- package/plugins/specweave/lib/hooks/reflection-config-loader.d.ts.bak +0 -45
- package/plugins/specweave/lib/hooks/reflection-config-loader.js.bak +0 -92
- package/plugins/specweave/lib/hooks/reflection-config-loader.ts.bak +0 -156
- package/plugins/specweave/lib/hooks/reflection-parser.d.js.bak +0 -0
- package/plugins/specweave/lib/hooks/reflection-parser.d.ts.bak +0 -33
- package/plugins/specweave/lib/hooks/reflection-parser.js.bak +0 -301
- package/plugins/specweave/lib/hooks/reflection-parser.ts.bak +0 -484
- package/plugins/specweave/lib/hooks/reflection-prompt-builder.d.js.bak +0 -0
- package/plugins/specweave/lib/hooks/reflection-prompt-builder.d.ts.bak +0 -56
- package/plugins/specweave/lib/hooks/reflection-prompt-builder.js.bak +0 -182
- package/plugins/specweave/lib/hooks/reflection-prompt-builder.ts.bak +0 -306
- package/plugins/specweave/lib/hooks/reflection-storage.d.js.bak +0 -0
- package/plugins/specweave/lib/hooks/reflection-storage.d.ts.bak +0 -64
- package/plugins/specweave/lib/hooks/reflection-storage.js.bak +0 -231
- package/plugins/specweave/lib/hooks/reflection-storage.ts.bak +0 -369
- package/plugins/specweave/lib/hooks/run-self-reflection.d.js.bak +0 -0
- package/plugins/specweave/lib/hooks/run-self-reflection.d.ts.bak +0 -43
- package/plugins/specweave/lib/hooks/run-self-reflection.js.bak +0 -132
- package/plugins/specweave/lib/hooks/run-self-reflection.ts.bak +0 -258
- package/plugins/specweave/lib/hooks/sync-cache.js.bak +0 -294
- package/plugins/specweave/lib/hooks/sync-living-docs.d.js.bak +0 -1
- package/plugins/specweave/lib/hooks/sync-living-docs.d.ts.bak +0 -27
- package/plugins/specweave/lib/hooks/sync-living-docs.js.bak +0 -339
- package/plugins/specweave/lib/hooks/sync-us-tasks.js.bak +0 -476
- package/plugins/specweave/lib/hooks/translate-file.d.js.bak +0 -0
- package/plugins/specweave/lib/hooks/translate-file.d.ts.bak +0 -59
- package/plugins/specweave/lib/hooks/translate-file.js.bak +0 -289
- package/plugins/specweave/lib/hooks/translate-file.ts.bak +0 -428
- package/plugins/specweave/lib/hooks/translate-living-docs.d.js.bak +0 -0
- package/plugins/specweave/lib/hooks/translate-living-docs.d.ts.bak +0 -13
- package/plugins/specweave/lib/hooks/translate-living-docs.js.bak +0 -119
- package/plugins/specweave/lib/hooks/translate-living-docs.ts.bak +0 -224
- package/plugins/specweave/lib/hooks/update-ac-status.js.bak +0 -51
- package/plugins/specweave/lib/hooks/update-ac-status.ts.bak +0 -103
- package/plugins/specweave/lib/hooks/update-tasks-md.d.js.bak +0 -1
- package/plugins/specweave/lib/hooks/update-tasks-md.d.ts.bak +0 -29
- package/plugins/specweave/lib/hooks/update-tasks-md.js.bak +0 -296
- package/plugins/specweave/lib/hooks/update-tasks-md.ts.bak +0 -489
- package/plugins/specweave-ado/hooks/post-living-docs-update.sh.backup +0 -353
- package/plugins/specweave-ado/hooks/post-task-completion.sh.backup +0 -172
- package/plugins/specweave-ado/lib/enhanced-ado-sync.js +0 -170
- package/plugins/specweave-github/hooks/.specweave/logs/hooks-debug.log +0 -904
- package/plugins/specweave-github/hooks/post-task-completion.sh.backup +0 -258
- package/plugins/specweave-jira/hooks/post-task-completion.sh.backup +0 -172
- package/plugins/specweave-release/hooks/.specweave/logs/dora-tracking.log +0 -738
- package/plugins/specweave-release/hooks/post-task-completion.sh.backup +0 -110
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* User Story Completion Orchestrator (v0.26.1 - Throttle Integration)
|
|
4
|
+
*
|
|
5
|
+
* Orchestrates the sync cascade when user stories become complete:
|
|
6
|
+
* 1. Detect newly completed user stories (all ACs satisfied)
|
|
7
|
+
* 2. Update living docs for completed USs
|
|
8
|
+
* 3. Trigger external tool sync (GitHub/JIRA/ADO)
|
|
9
|
+
*
|
|
10
|
+
* CRITICAL: This is the bridge between AC-level completion and US-level sync.
|
|
11
|
+
* Called by consolidated-sync.js after AC sync completes.
|
|
12
|
+
*
|
|
13
|
+
* Architecture (v0.26.1 Changes):
|
|
14
|
+
* - Uses USCompletionDetector to find newly completed USs
|
|
15
|
+
* - Uses LivingDocsSync to update living docs (which triggers external tools)
|
|
16
|
+
* - **NEW**: Uses USSyncThrottle to prevent spam (60s window)
|
|
17
|
+
* - Non-blocking: Errors logged but don't break workflow
|
|
18
|
+
*
|
|
19
|
+
* Integration:
|
|
20
|
+
* - Called from consolidated-sync.js (OPERATION 6)
|
|
21
|
+
* - Runs after AC sync (ensures ACs are up-to-date)
|
|
22
|
+
* - ~~Skipped if SKIP_US_SYNC=true (REMOVED in v0.26.1)~~
|
|
23
|
+
* - **NEW**: Throttled to once per 60 seconds per increment
|
|
24
|
+
*
|
|
25
|
+
* Safety:
|
|
26
|
+
* - fs.writeFile() verified to NOT trigger Claude Code hooks (test confirmed)
|
|
27
|
+
* - SKIP_EXTERNAL_SYNC still guards actual external tool sync
|
|
28
|
+
* - Throttle prevents rapid sync spam
|
|
29
|
+
* - Circuit breaker active at hook level
|
|
30
|
+
*
|
|
31
|
+
* See:
|
|
32
|
+
* - FS-WRITEFILE-HOOK-TEST-RESULTS-2025-11-24.md (test results)
|
|
33
|
+
* - ADR-0129: US Sync Guard Rails (long-term fix strategy)
|
|
34
|
+
* - src/core/us-sync-throttle.ts (throttle implementation)
|
|
35
|
+
*/
|
|
36
|
+
|
|
37
|
+
// Import REAL implementations
|
|
38
|
+
import { USCompletionDetector } from '../../../../dist/src/core/us-completion-detector.js';
|
|
39
|
+
import { LivingDocsSync } from '../../../../dist/src/core/living-docs/living-docs-sync.js';
|
|
40
|
+
import { USSyncThrottle } from '../../../../dist/src/core/us-sync-throttle.js';
|
|
41
|
+
import { consoleLogger } from '../vendor/utils/logger.js';
|
|
42
|
+
|
|
43
|
+
export interface USSyncResult {
|
|
44
|
+
success: boolean;
|
|
45
|
+
newlyCompleted?: Array<{
|
|
46
|
+
usId: string;
|
|
47
|
+
title: string;
|
|
48
|
+
totalACs: number;
|
|
49
|
+
completedACs: number;
|
|
50
|
+
}>;
|
|
51
|
+
syncResult?: any;
|
|
52
|
+
message: string;
|
|
53
|
+
skipped?: boolean;
|
|
54
|
+
throttled?: boolean;
|
|
55
|
+
error?: string;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Detect and sync newly completed user stories
|
|
60
|
+
*
|
|
61
|
+
* v0.26.1: Now includes smart throttling (60s window) to prevent spam
|
|
62
|
+
*
|
|
63
|
+
* @param incrementId - Increment ID (e.g., "0053-safe-feature-deletion")
|
|
64
|
+
* @returns Result object with success status and sync details
|
|
65
|
+
*/
|
|
66
|
+
export async function syncCompletedUserStories(incrementId: string): Promise<USSyncResult> {
|
|
67
|
+
try {
|
|
68
|
+
console.log(`\nšÆ [6/6] Detecting completed user stories for ${incrementId}...`);
|
|
69
|
+
|
|
70
|
+
const projectRoot = process.cwd();
|
|
71
|
+
|
|
72
|
+
// ========================================================================
|
|
73
|
+
// THROTTLE CHECK (v0.26.1 - NEW!)
|
|
74
|
+
// ========================================================================
|
|
75
|
+
// Prevent spam: Limit US sync to once per 60 seconds per increment
|
|
76
|
+
// Rationale:
|
|
77
|
+
// - Rapid task completions (10 in 5s) ā 10 US sync attempts
|
|
78
|
+
// - Without throttle: 100+ GitHub API calls (rate limit risk)
|
|
79
|
+
// - With throttle: 1 US sync, 9 throttled (10 GitHub calls)
|
|
80
|
+
//
|
|
81
|
+
// Safety:
|
|
82
|
+
// - fs.writeFile() confirmed to NOT trigger hooks (no infinite loop risk)
|
|
83
|
+
// - SKIP_EXTERNAL_SYNC still guards external tool sync layer
|
|
84
|
+
// - Users can manually sync if needed: /specweave:sync-progress
|
|
85
|
+
//
|
|
86
|
+
// Trade-off:
|
|
87
|
+
// - Potential 60s delay for US completion visibility
|
|
88
|
+
// - Acceptable for UX (tasks complete immediately, US sync deferred)
|
|
89
|
+
|
|
90
|
+
const throttle = USSyncThrottle.getInstance({ projectRoot });
|
|
91
|
+
|
|
92
|
+
if (throttle.shouldSkipSync(incrementId)) {
|
|
93
|
+
const timeSinceLastSync = throttle.getTimeSinceLastSync(incrementId);
|
|
94
|
+
const secondsRemaining = Math.ceil((60000 - timeSinceLastSync) / 1000);
|
|
95
|
+
|
|
96
|
+
console.log(`āļø US sync throttled (last sync ${Math.floor(timeSinceLastSync / 1000)}s ago)`);
|
|
97
|
+
console.log(` ā¹ļø Sync will be available in ${secondsRemaining}s`);
|
|
98
|
+
console.log(` š” Manual sync: /specweave:sync-progress ${incrementId}`);
|
|
99
|
+
|
|
100
|
+
return {
|
|
101
|
+
success: true,
|
|
102
|
+
message: 'Sync throttled',
|
|
103
|
+
throttled: true,
|
|
104
|
+
skipped: true
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// 1. Initialize US completion detector
|
|
109
|
+
const detector = new USCompletionDetector(projectRoot, {
|
|
110
|
+
logger: consoleLogger
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
// 2. Detect newly completed user stories
|
|
114
|
+
const newlyCompleted = await detector.getNewlyCompletedUSs(incrementId);
|
|
115
|
+
|
|
116
|
+
if (newlyCompleted.length === 0) {
|
|
117
|
+
console.log('ā
No newly completed user stories detected (no sync needed)');
|
|
118
|
+
|
|
119
|
+
return {
|
|
120
|
+
success: true,
|
|
121
|
+
newlyCompleted: [],
|
|
122
|
+
message: 'No new completions'
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
console.log(`\nš DETECTED ${newlyCompleted.length} NEWLY COMPLETED USER STORIES:`);
|
|
127
|
+
for (const us of newlyCompleted) {
|
|
128
|
+
console.log(` ${us.usId}: ${us.title} (${us.completedACs}/${us.totalACs} ACs complete)`);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// 3. Save completion state (mark USs as complete to prevent re-sync)
|
|
132
|
+
const allCompletions = await detector.detectCompletions(incrementId);
|
|
133
|
+
await detector.saveCompletionState(incrementId, allCompletions);
|
|
134
|
+
|
|
135
|
+
// 4. Trigger living docs sync (which will sync to external tools)
|
|
136
|
+
console.log(`\nš Syncing living docs for ${incrementId}...`);
|
|
137
|
+
|
|
138
|
+
const livingDocsSync = new LivingDocsSync(projectRoot, {
|
|
139
|
+
logger: consoleLogger
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
const syncResult = await livingDocsSync.syncIncrement(incrementId);
|
|
143
|
+
|
|
144
|
+
if (syncResult.success) {
|
|
145
|
+
console.log(`ā
Living docs synced successfully`);
|
|
146
|
+
console.log(` Feature: ${syncResult.featureId}`);
|
|
147
|
+
console.log(` Files updated: ${syncResult.filesCreated.length + syncResult.filesUpdated.length}`);
|
|
148
|
+
|
|
149
|
+
// External tool sync happens automatically inside livingDocsSync.syncIncrement()
|
|
150
|
+
// It calls syncToExternalTools() which handles GitHub/JIRA/ADO
|
|
151
|
+
console.log(`\nš” External tool sync completed (GitHub/JIRA/ADO updated if configured)`);
|
|
152
|
+
|
|
153
|
+
// Record successful sync for throttling
|
|
154
|
+
throttle.recordSync(incrementId);
|
|
155
|
+
console.log(` ā±ļø Throttle recorded (next sync allowed in 60s)`);
|
|
156
|
+
} else {
|
|
157
|
+
console.warn(`ā ļø Living docs sync had errors (see logs)`);
|
|
158
|
+
console.warn(` Errors: ${syncResult.errors.join(', ')}`);
|
|
159
|
+
|
|
160
|
+
// Don't record sync on failure (allow immediate retry)
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
return {
|
|
164
|
+
success: true,
|
|
165
|
+
newlyCompleted: newlyCompleted.map(us => ({
|
|
166
|
+
usId: us.usId,
|
|
167
|
+
title: us.title,
|
|
168
|
+
totalACs: us.totalACs,
|
|
169
|
+
completedACs: us.completedACs
|
|
170
|
+
})),
|
|
171
|
+
syncResult,
|
|
172
|
+
message: `${newlyCompleted.length} user stories synced`
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
} catch (error: any) {
|
|
176
|
+
// Non-blocking: Log error but don't break workflow
|
|
177
|
+
console.error('ā Error in US completion orchestrator:', error.message);
|
|
178
|
+
|
|
179
|
+
return {
|
|
180
|
+
success: false,
|
|
181
|
+
error: error.message,
|
|
182
|
+
message: 'Orchestrator error'
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// CLI Interface (for manual testing)
|
|
188
|
+
const isMainModule = import.meta.url === `file://${process.argv[1]}`;
|
|
189
|
+
if (isMainModule) {
|
|
190
|
+
const incrementId = process.argv[2];
|
|
191
|
+
|
|
192
|
+
if (!incrementId) {
|
|
193
|
+
console.error('Usage: node us-completion-orchestrator.js <increment-id>');
|
|
194
|
+
console.error('Example: node us-completion-orchestrator.js 0053-safe-feature-deletion');
|
|
195
|
+
process.exit(1);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
syncCompletedUserStories(incrementId)
|
|
199
|
+
.then(result => {
|
|
200
|
+
if (result.success) {
|
|
201
|
+
console.log('\nā
US completion orchestration completed successfully');
|
|
202
|
+
if (result.throttled) {
|
|
203
|
+
console.log(' (Throttled - no sync performed)');
|
|
204
|
+
}
|
|
205
|
+
process.exit(0);
|
|
206
|
+
} else {
|
|
207
|
+
console.error('\nā US completion orchestration failed');
|
|
208
|
+
process.exit(1);
|
|
209
|
+
}
|
|
210
|
+
})
|
|
211
|
+
.catch(error => {
|
|
212
|
+
console.error('\nā Fatal error:', error);
|
|
213
|
+
process.exit(1);
|
|
214
|
+
});
|
|
215
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { EnhancedContentBuilder } from "../../../
|
|
2
|
-
import { SpecIncrementMapper } from "../../../
|
|
3
|
-
import { parseSpecContent } from "../../../
|
|
1
|
+
import { EnhancedContentBuilder } from "../../../src/core/sync/enhanced-content-builder.js";
|
|
2
|
+
import { SpecIncrementMapper } from "../../../src/core/sync/spec-increment-mapper.js";
|
|
3
|
+
import { parseSpecContent } from "../../../src/core/spec-content-sync.js";
|
|
4
4
|
import * as path from "path";
|
|
5
5
|
import * as fs from "fs/promises";
|
|
6
6
|
async function syncSpecToJiraWithEnhancedContent(options) {
|
|
@@ -6,7 +6,11 @@
|
|
|
6
6
|
#
|
|
7
7
|
# Integration: plugins/specweave-release/hooks/hooks.json
|
|
8
8
|
|
|
9
|
-
set -
|
|
9
|
+
# CRITICAL (v0.25.2): NEVER use 'set -e' in hooks - causes Claude Code crashes
|
|
10
|
+
# See: CLAUDE.md Section 9a (Hook Safety Checklist), ADR-0060 (Hook Performance)
|
|
11
|
+
set +e # Allow commands to fail without terminating script
|
|
12
|
+
set -u # Fail on undefined variables
|
|
13
|
+
set -o pipefail # Fail if any command in pipeline fails
|
|
10
14
|
|
|
11
15
|
# Constants
|
|
12
16
|
SPECWEAVE_ROOT="${SPECWEAVE_ROOT:-$(pwd)}"
|