specweave 0.17.13 → 0.17.16

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 (62) hide show
  1. package/CLAUDE.md +456 -0
  2. package/README.md +38 -1
  3. package/dist/src/cli/commands/cicd-monitor.d.ts +11 -0
  4. package/dist/src/cli/commands/cicd-monitor.d.ts.map +1 -0
  5. package/dist/src/cli/commands/cicd-monitor.js +154 -0
  6. package/dist/src/cli/commands/cicd-monitor.js.map +1 -0
  7. package/dist/src/cli/commands/validate-parent-repo.d.ts +8 -0
  8. package/dist/src/cli/commands/validate-parent-repo.d.ts.map +1 -0
  9. package/dist/src/cli/commands/validate-parent-repo.js +15 -0
  10. package/dist/src/cli/commands/validate-parent-repo.js.map +1 -0
  11. package/dist/src/cli/helpers/issue-tracker/types.d.ts +5 -0
  12. package/dist/src/cli/helpers/issue-tracker/types.d.ts.map +1 -1
  13. package/dist/src/cli/helpers/issue-tracker/types.js.map +1 -1
  14. package/dist/src/core/cicd/config-loader.d.ts +21 -0
  15. package/dist/src/core/cicd/config-loader.d.ts.map +1 -0
  16. package/dist/src/core/cicd/config-loader.js +190 -0
  17. package/dist/src/core/cicd/config-loader.js.map +1 -0
  18. package/dist/src/core/cicd/index.d.ts +12 -0
  19. package/dist/src/core/cicd/index.d.ts.map +1 -0
  20. package/dist/src/core/cicd/index.js +18 -0
  21. package/dist/src/core/cicd/index.js.map +1 -0
  22. package/dist/src/core/cicd/monitor-service.d.ts +92 -0
  23. package/dist/src/core/cicd/monitor-service.d.ts.map +1 -0
  24. package/dist/src/core/cicd/monitor-service.js +132 -0
  25. package/dist/src/core/cicd/monitor-service.js.map +1 -0
  26. package/dist/src/core/cicd/notifier.d.ts +102 -0
  27. package/dist/src/core/cicd/notifier.d.ts.map +1 -0
  28. package/dist/src/core/cicd/notifier.js +184 -0
  29. package/dist/src/core/cicd/notifier.js.map +1 -0
  30. package/dist/src/core/cicd/parent-repo-validator.d.ts +42 -0
  31. package/dist/src/core/cicd/parent-repo-validator.d.ts.map +1 -0
  32. package/dist/src/core/cicd/parent-repo-validator.js +201 -0
  33. package/dist/src/core/cicd/parent-repo-validator.js.map +1 -0
  34. package/dist/src/core/cicd/state-manager.d.ts +79 -0
  35. package/dist/src/core/cicd/state-manager.d.ts.map +1 -0
  36. package/dist/src/core/cicd/state-manager.js +197 -0
  37. package/dist/src/core/cicd/state-manager.js.map +1 -0
  38. package/dist/src/core/cicd/types.d.ts +119 -0
  39. package/dist/src/core/cicd/types.d.ts.map +1 -0
  40. package/dist/src/core/cicd/types.js +18 -0
  41. package/dist/src/core/cicd/types.js.map +1 -0
  42. package/dist/src/core/cicd/workflow-monitor.d.ts +98 -0
  43. package/dist/src/core/cicd/workflow-monitor.d.ts.map +1 -0
  44. package/dist/src/core/cicd/workflow-monitor.js +215 -0
  45. package/dist/src/core/cicd/workflow-monitor.js.map +1 -0
  46. package/dist/src/core/spec-content-sync.d.ts.map +1 -1
  47. package/dist/src/core/spec-content-sync.js +14 -6
  48. package/dist/src/core/spec-content-sync.js.map +1 -1
  49. package/dist/src/utils/plugin-validator.d.ts +9 -0
  50. package/dist/src/utils/plugin-validator.d.ts.map +1 -1
  51. package/dist/src/utils/plugin-validator.js +86 -19
  52. package/dist/src/utils/plugin-validator.js.map +1 -1
  53. package/package.json +2 -2
  54. package/plugins/specweave/agents/pm/AGENT.md +170 -2
  55. package/plugins/specweave/hooks/post-increment-planning.sh +89 -26
  56. package/plugins/specweave/hooks/user-prompt-submit.sh +4 -4
  57. package/plugins/specweave/skills/increment-planner/SKILL.md +15 -10
  58. package/plugins/specweave/skills/plugin-validator/SKILL.md +16 -13
  59. package/plugins/specweave-ado/lib/ado-project-detector.js +32 -5
  60. package/plugins/specweave-ado/lib/ado-project-detector.ts +44 -5
  61. package/src/templates/AGENTS.md.template +55 -1
  62. package/src/templates/CLAUDE.md.template +51 -1
@@ -0,0 +1,102 @@
1
+ /**
2
+ * CI/CD Failure Notifier
3
+ *
4
+ * Sends notifications when workflow failures are detected.
5
+ * Supports multiple notification channels (console, file, webhook).
6
+ */
7
+ import { FailureRecord } from './types';
8
+ /**
9
+ * Notification channel types
10
+ */
11
+ export type NotificationChannel = 'console' | 'file' | 'webhook';
12
+ /**
13
+ * Notification configuration
14
+ */
15
+ export interface NotifierConfig {
16
+ /** Enabled channels */
17
+ channels: NotificationChannel[];
18
+ /** Log file path (for 'file' channel) */
19
+ logFile?: string;
20
+ /** Webhook URL (for 'webhook' channel) */
21
+ webhookUrl?: string;
22
+ /** Enable debug logging */
23
+ debug?: boolean;
24
+ }
25
+ /**
26
+ * Notification payload
27
+ */
28
+ export interface Notification {
29
+ /** Notification type */
30
+ type: 'failure_detected' | 'analysis_complete' | 'fix_applied';
31
+ /** Failure record */
32
+ failure: FailureRecord;
33
+ /** Additional message */
34
+ message?: string;
35
+ /** Timestamp */
36
+ timestamp: string;
37
+ }
38
+ /**
39
+ * Notifier - Sends failure notifications to configured channels
40
+ *
41
+ * Features:
42
+ * - Multiple notification channels (console, file, webhook)
43
+ * - Structured notification format
44
+ * - Async delivery (non-blocking)
45
+ * - Error handling and retry logic
46
+ */
47
+ export declare class Notifier {
48
+ private config;
49
+ /**
50
+ * Create notifier
51
+ *
52
+ * @param config - Notification configuration
53
+ */
54
+ constructor(config: NotifierConfig);
55
+ /**
56
+ * Send notification about failure detection
57
+ *
58
+ * @param failure - Failure record
59
+ */
60
+ notifyFailureDetected(failure: FailureRecord): Promise<void>;
61
+ /**
62
+ * Send notification about analysis completion
63
+ *
64
+ * @param failure - Failure record
65
+ * @param analysis - Analysis result
66
+ */
67
+ notifyAnalysisComplete(failure: FailureRecord, analysis: string): Promise<void>;
68
+ /**
69
+ * Send notification about fix application
70
+ *
71
+ * @param failure - Failure record
72
+ * @param fixDetails - Fix details
73
+ */
74
+ notifyFixApplied(failure: FailureRecord, fixDetails: string): Promise<void>;
75
+ /**
76
+ * Send notification to all configured channels
77
+ *
78
+ * @param notification - Notification payload
79
+ */
80
+ private send;
81
+ /**
82
+ * Send notification to console (stderr for visibility)
83
+ */
84
+ private sendToConsole;
85
+ /**
86
+ * Send notification to log file
87
+ */
88
+ private sendToFile;
89
+ /**
90
+ * Send notification to webhook
91
+ */
92
+ private sendToWebhook;
93
+ /**
94
+ * Get icon for notification type
95
+ */
96
+ private getIcon;
97
+ /**
98
+ * Get ANSI color code for notification type
99
+ */
100
+ private getColor;
101
+ }
102
+ //# sourceMappingURL=notifier.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notifier.d.ts","sourceRoot":"","sources":["../../../../src/core/cicd/notifier.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAExC;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAAC;AAEjE;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,uBAAuB;IACvB,QAAQ,EAAE,mBAAmB,EAAE,CAAC;IAEhC,yCAAyC;IACzC,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,0CAA0C;IAC1C,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,2BAA2B;IAC3B,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,wBAAwB;IACxB,IAAI,EAAE,kBAAkB,GAAG,mBAAmB,GAAG,aAAa,CAAC;IAE/D,qBAAqB;IACrB,OAAO,EAAE,aAAa,CAAC;IAEvB,yBAAyB;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,gBAAgB;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;GAQG;AACH,qBAAa,QAAQ;IACnB,OAAO,CAAC,MAAM,CAA2B;IAEzC;;;;OAIG;gBACS,MAAM,EAAE,cAAc;IASlC;;;;OAIG;IACG,qBAAqB,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAWlE;;;;;OAKG;IACG,sBAAsB,CAC1B,OAAO,EAAE,aAAa,EACtB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC;IAWhB;;;;;OAKG;IACG,gBAAgB,CACpB,OAAO,EAAE,aAAa,EACtB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,IAAI,CAAC;IAWhB;;;;OAIG;YACW,IAAI;IAmBlB;;OAEG;YACW,aAAa;IAW3B;;OAEG;YACW,UAAU;IAmBxB;;OAEG;YACW,aAAa;IA4B3B;;OAEG;IACH,OAAO,CAAC,OAAO;IAaf;;OAEG;IACH,OAAO,CAAC,QAAQ;CAYjB"}
@@ -0,0 +1,184 @@
1
+ /**
2
+ * CI/CD Failure Notifier
3
+ *
4
+ * Sends notifications when workflow failures are detected.
5
+ * Supports multiple notification channels (console, file, webhook).
6
+ */
7
+ import * as fs from 'fs-extra';
8
+ import * as path from 'path';
9
+ /**
10
+ * Notifier - Sends failure notifications to configured channels
11
+ *
12
+ * Features:
13
+ * - Multiple notification channels (console, file, webhook)
14
+ * - Structured notification format
15
+ * - Async delivery (non-blocking)
16
+ * - Error handling and retry logic
17
+ */
18
+ export class Notifier {
19
+ /**
20
+ * Create notifier
21
+ *
22
+ * @param config - Notification configuration
23
+ */
24
+ constructor(config) {
25
+ this.config = {
26
+ channels: config.channels,
27
+ logFile: config.logFile ?? '.specweave/logs/cicd-notifications.log',
28
+ webhookUrl: config.webhookUrl ?? '',
29
+ debug: config.debug ?? false
30
+ };
31
+ }
32
+ /**
33
+ * Send notification about failure detection
34
+ *
35
+ * @param failure - Failure record
36
+ */
37
+ async notifyFailureDetected(failure) {
38
+ const notification = {
39
+ type: 'failure_detected',
40
+ failure,
41
+ message: `Workflow "${failure.workflowName}" failed (run #${failure.runId})`,
42
+ timestamp: new Date().toISOString()
43
+ };
44
+ await this.send(notification);
45
+ }
46
+ /**
47
+ * Send notification about analysis completion
48
+ *
49
+ * @param failure - Failure record
50
+ * @param analysis - Analysis result
51
+ */
52
+ async notifyAnalysisComplete(failure, analysis) {
53
+ const notification = {
54
+ type: 'analysis_complete',
55
+ failure,
56
+ message: `Root cause analysis complete for ${failure.workflowName}:\n${analysis}`,
57
+ timestamp: new Date().toISOString()
58
+ };
59
+ await this.send(notification);
60
+ }
61
+ /**
62
+ * Send notification about fix application
63
+ *
64
+ * @param failure - Failure record
65
+ * @param fixDetails - Fix details
66
+ */
67
+ async notifyFixApplied(failure, fixDetails) {
68
+ const notification = {
69
+ type: 'fix_applied',
70
+ failure,
71
+ message: `Fix applied for ${failure.workflowName}:\n${fixDetails}`,
72
+ timestamp: new Date().toISOString()
73
+ };
74
+ await this.send(notification);
75
+ }
76
+ /**
77
+ * Send notification to all configured channels
78
+ *
79
+ * @param notification - Notification payload
80
+ */
81
+ async send(notification) {
82
+ const promises = this.config.channels.map((channel) => {
83
+ switch (channel) {
84
+ case 'console':
85
+ return this.sendToConsole(notification);
86
+ case 'file':
87
+ return this.sendToFile(notification);
88
+ case 'webhook':
89
+ return this.sendToWebhook(notification);
90
+ default:
91
+ console.warn(`Unknown notification channel: ${channel}`);
92
+ return Promise.resolve();
93
+ }
94
+ });
95
+ // Send to all channels (non-blocking, errors logged)
96
+ await Promise.allSettled(promises);
97
+ }
98
+ /**
99
+ * Send notification to console (stderr for visibility)
100
+ */
101
+ async sendToConsole(notification) {
102
+ const icon = this.getIcon(notification.type);
103
+ const color = this.getColor(notification.type);
104
+ console.error(`${color}${icon} ${notification.message}\x1b[0m`);
105
+ if (this.config.debug) {
106
+ console.error('Full notification:', JSON.stringify(notification, null, 2));
107
+ }
108
+ }
109
+ /**
110
+ * Send notification to log file
111
+ */
112
+ async sendToFile(notification) {
113
+ try {
114
+ await fs.ensureDir(path.dirname(this.config.logFile));
115
+ const logLine = `${notification.timestamp} [${notification.type}] ${notification.message}\n`;
116
+ await fs.appendFile(this.config.logFile, logLine, 'utf-8');
117
+ if (this.config.debug) {
118
+ await fs.appendFile(this.config.logFile, `${JSON.stringify(notification, null, 2)}\n`, 'utf-8');
119
+ }
120
+ }
121
+ catch (error) {
122
+ console.error('Failed to write notification to file:', error);
123
+ }
124
+ }
125
+ /**
126
+ * Send notification to webhook
127
+ */
128
+ async sendToWebhook(notification) {
129
+ if (!this.config.webhookUrl) {
130
+ console.warn('Webhook URL not configured, skipping webhook notification');
131
+ return;
132
+ }
133
+ try {
134
+ // Use native fetch (Node.js 18+)
135
+ const response = await fetch(this.config.webhookUrl, {
136
+ method: 'POST',
137
+ headers: {
138
+ 'Content-Type': 'application/json'
139
+ },
140
+ body: JSON.stringify(notification)
141
+ });
142
+ if (!response.ok) {
143
+ throw new Error(`Webhook returned ${response.status}: ${response.statusText}`);
144
+ }
145
+ if (this.config.debug) {
146
+ console.log('Webhook notification sent successfully');
147
+ }
148
+ }
149
+ catch (error) {
150
+ console.error('Failed to send webhook notification:', error);
151
+ }
152
+ }
153
+ /**
154
+ * Get icon for notification type
155
+ */
156
+ getIcon(type) {
157
+ switch (type) {
158
+ case 'failure_detected':
159
+ return '🚨';
160
+ case 'analysis_complete':
161
+ return '🔍';
162
+ case 'fix_applied':
163
+ return '✅';
164
+ default:
165
+ return '📢';
166
+ }
167
+ }
168
+ /**
169
+ * Get ANSI color code for notification type
170
+ */
171
+ getColor(type) {
172
+ switch (type) {
173
+ case 'failure_detected':
174
+ return '\x1b[31m'; // Red
175
+ case 'analysis_complete':
176
+ return '\x1b[33m'; // Yellow
177
+ case 'fix_applied':
178
+ return '\x1b[32m'; // Green
179
+ default:
180
+ return '\x1b[37m'; // White
181
+ }
182
+ }
183
+ }
184
+ //# sourceMappingURL=notifier.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notifier.js","sourceRoot":"","sources":["../../../../src/core/cicd/notifier.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Parent Repository Validation Utility
3
+ *
4
+ * Validates consistency of parent repo naming across:
5
+ * - .specweave/config.json (source of truth)
6
+ * - Git remote (origin)
7
+ * - .env file (if exists)
8
+ *
9
+ * Prevents the common mistake of creating duplicate parent repos
10
+ * when using multi-project mode with -shared flag.
11
+ */
12
+ export interface ValidationResult {
13
+ valid: boolean;
14
+ errors: string[];
15
+ warnings: string[];
16
+ configName?: string;
17
+ gitRemoteName?: string;
18
+ envName?: string;
19
+ }
20
+ export interface ParentRepoCheck {
21
+ configParentName: string | null;
22
+ gitRemoteName: string | null;
23
+ envParentName: string | null;
24
+ }
25
+ /**
26
+ * Get all parent repo names from different sources
27
+ */
28
+ export declare function checkParentRepoSetup(projectRoot: string): ParentRepoCheck;
29
+ /**
30
+ * Validate parent repo setup consistency
31
+ */
32
+ export declare function validateParentRepoSetup(projectRoot: string): ValidationResult;
33
+ /**
34
+ * Print validation result to console
35
+ */
36
+ export declare function printValidationResult(result: ValidationResult): void;
37
+ /**
38
+ * Validate and exit with error code if validation fails
39
+ * Use this in CLI commands that require valid parent repo setup
40
+ */
41
+ export declare function validateOrExit(projectRoot: string): void;
42
+ //# sourceMappingURL=parent-repo-validator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parent-repo-validator.d.ts","sourceRoot":"","sources":["../../../../src/core/cicd/parent-repo-validator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAOH,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC9B,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAwED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,eAAe,CAMzE;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,MAAM,GAAG,gBAAgB,CAiF7E;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,gBAAgB,GAAG,IAAI,CA+CpE;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAYxD"}
@@ -0,0 +1,201 @@
1
+ /**
2
+ * Parent Repository Validation Utility
3
+ *
4
+ * Validates consistency of parent repo naming across:
5
+ * - .specweave/config.json (source of truth)
6
+ * - Git remote (origin)
7
+ * - .env file (if exists)
8
+ *
9
+ * Prevents the common mistake of creating duplicate parent repos
10
+ * when using multi-project mode with -shared flag.
11
+ */
12
+ import * as fs from 'fs-extra';
13
+ import * as path from 'path';
14
+ import { execSync } from 'child_process';
15
+ import chalk from 'chalk';
16
+ /**
17
+ * Extract parent repo name from config.json
18
+ */
19
+ function getConfigParentRepoName(projectRoot) {
20
+ const configPath = path.join(projectRoot, '.specweave', 'config.json');
21
+ if (!fs.existsSync(configPath)) {
22
+ return null;
23
+ }
24
+ try {
25
+ const config = fs.readJsonSync(configPath);
26
+ return config.multiProject?.parentRepoName || null;
27
+ }
28
+ catch (error) {
29
+ console.error(chalk.yellow('⚠️ Failed to parse config.json:'), error);
30
+ return null;
31
+ }
32
+ }
33
+ /**
34
+ * Extract parent repo name from git remote origin
35
+ */
36
+ function getGitRemoteRepoName(projectRoot) {
37
+ try {
38
+ const remoteUrl = execSync('git remote get-url origin', {
39
+ cwd: projectRoot,
40
+ encoding: 'utf-8',
41
+ stdio: ['pipe', 'pipe', 'ignore'] // Suppress stderr
42
+ }).trim();
43
+ // Extract repo name from URL
44
+ // Examples:
45
+ // - https://github.com/owner/repo.git → repo
46
+ // - git@github.com:owner/repo.git → repo
47
+ const match = remoteUrl.match(/\/([^\/]+?)(\.git)?$/);
48
+ return match ? match[1].replace('.git', '') : null;
49
+ }
50
+ catch (error) {
51
+ // Git remote doesn't exist or not a git repo
52
+ return null;
53
+ }
54
+ }
55
+ /**
56
+ * Extract parent repo name from .env file
57
+ */
58
+ function getEnvParentRepoName(projectRoot) {
59
+ const envPath = path.join(projectRoot, '.env');
60
+ if (!fs.existsSync(envPath)) {
61
+ return null;
62
+ }
63
+ try {
64
+ const envContent = fs.readFileSync(envPath, 'utf-8');
65
+ const match = envContent.match(/^PARENT_REPO_NAME=(.*)$/m);
66
+ if (!match) {
67
+ return null;
68
+ }
69
+ // Format: shared:repo-name or repo-name
70
+ const value = match[1].trim();
71
+ const parts = value.split(':');
72
+ return parts.length === 2 ? parts[1] : value;
73
+ }
74
+ catch (error) {
75
+ console.error(chalk.yellow('⚠️ Failed to read .env:'), error);
76
+ return null;
77
+ }
78
+ }
79
+ /**
80
+ * Get all parent repo names from different sources
81
+ */
82
+ export function checkParentRepoSetup(projectRoot) {
83
+ return {
84
+ configParentName: getConfigParentRepoName(projectRoot),
85
+ gitRemoteName: getGitRemoteRepoName(projectRoot),
86
+ envParentName: getEnvParentRepoName(projectRoot)
87
+ };
88
+ }
89
+ /**
90
+ * Validate parent repo setup consistency
91
+ */
92
+ export function validateParentRepoSetup(projectRoot) {
93
+ const result = {
94
+ valid: true,
95
+ errors: [],
96
+ warnings: []
97
+ };
98
+ // Get all names
99
+ const check = checkParentRepoSetup(projectRoot);
100
+ result.configName = check.configParentName || undefined;
101
+ result.gitRemoteName = check.gitRemoteName || undefined;
102
+ result.envName = check.envParentName || undefined;
103
+ // Check 1: Config has parent repo name (if multi-project enabled)
104
+ const configPath = path.join(projectRoot, '.specweave', 'config.json');
105
+ if (fs.existsSync(configPath)) {
106
+ const config = fs.readJsonSync(configPath);
107
+ const multiProjectEnabled = config.multiProject?.enabled === true;
108
+ if (multiProjectEnabled && !check.configParentName) {
109
+ result.valid = false;
110
+ result.errors.push('❌ Multi-project enabled but parentRepoName not set in config.json');
111
+ }
112
+ }
113
+ // Check 2: Git remote matches config (if both exist)
114
+ if (check.configParentName && check.gitRemoteName) {
115
+ if (check.configParentName !== check.gitRemoteName) {
116
+ result.valid = false;
117
+ result.errors.push('❌ Git remote mismatch!', ` Config expects: ${check.configParentName}`, ` Git remote has: ${check.gitRemoteName}`, '', ' Fix with:', ` git remote set-url origin https://github.com/OWNER/${check.configParentName}.git`);
118
+ }
119
+ }
120
+ // Check 3: .env matches config (if both exist)
121
+ if (check.configParentName && check.envParentName) {
122
+ if (check.configParentName !== check.envParentName) {
123
+ result.warnings.push('⚠️ .env mismatch (will be ignored):', ` Config: ${check.configParentName}`, ` .env: ${check.envParentName}`, '', ' Update .env to match config.json');
124
+ }
125
+ }
126
+ // Check 4: -shared suffix consistency
127
+ if (check.configParentName && check.configParentName.endsWith('-shared')) {
128
+ // Config has -shared, check git and env also have it
129
+ if (check.gitRemoteName && !check.gitRemoteName.endsWith('-shared')) {
130
+ result.valid = false;
131
+ result.errors.push('❌ Config has -shared suffix, but git remote doesn\'t', '', ` Config: ${check.configParentName} (has -shared)`, ` Git: ${check.gitRemoteName} (missing -shared)`, '');
132
+ }
133
+ if (check.envParentName && !check.envParentName.endsWith('-shared')) {
134
+ result.warnings.push('⚠️ Config has -shared suffix, but .env doesn\'t', '', ` Config: ${check.configParentName} (has -shared)`, ` .env: ${check.envParentName} (missing -shared)`, '');
135
+ }
136
+ }
137
+ return result;
138
+ }
139
+ /**
140
+ * Print validation result to console
141
+ */
142
+ export function printValidationResult(result) {
143
+ console.log('\n🔍 Validating Parent Repo Setup...\n');
144
+ // Show current setup
145
+ console.log('📋 Current Setup:\n');
146
+ console.log(` Config (parentRepoName): ${result.configName || chalk.gray('<not set>')}`);
147
+ console.log(` Git Remote (origin): ${result.gitRemoteName || chalk.gray('<not set>')}`);
148
+ console.log(` .env (PARENT_REPO_NAME): ${result.envName || chalk.gray('<not set>')}`);
149
+ console.log('');
150
+ // Show errors
151
+ if (result.errors.length > 0) {
152
+ result.errors.forEach(error => {
153
+ console.log(chalk.red(error));
154
+ });
155
+ console.log('');
156
+ }
157
+ // Show warnings
158
+ if (result.warnings.length > 0) {
159
+ result.warnings.forEach(warning => {
160
+ console.log(chalk.yellow(warning));
161
+ });
162
+ console.log('');
163
+ }
164
+ // Summary
165
+ console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
166
+ if (result.valid && result.warnings.length === 0) {
167
+ console.log(chalk.green('✅ All checks passed!'));
168
+ console.log('\nYour parent repo setup is consistent across:');
169
+ console.log(' ✓ .specweave/config.json');
170
+ console.log(' ✓ git remote (origin)');
171
+ if (result.envName) {
172
+ console.log(' ✓ .env');
173
+ }
174
+ }
175
+ else {
176
+ if (!result.valid) {
177
+ console.log(chalk.red(`❌ Validation failed with ${result.errors.length} error(s)`));
178
+ }
179
+ if (result.warnings.length > 0) {
180
+ console.log(chalk.yellow(`⚠️ Found ${result.warnings.length} warning(s)`));
181
+ }
182
+ console.log('\nPlease fix the issues above before syncing to GitHub.');
183
+ }
184
+ console.log('');
185
+ }
186
+ /**
187
+ * Validate and exit with error code if validation fails
188
+ * Use this in CLI commands that require valid parent repo setup
189
+ */
190
+ export function validateOrExit(projectRoot) {
191
+ const result = validateParentRepoSetup(projectRoot);
192
+ printValidationResult(result);
193
+ if (!result.valid) {
194
+ process.exit(1);
195
+ }
196
+ // Show warnings but don't exit
197
+ if (result.warnings.length > 0) {
198
+ console.log(chalk.yellow('⚠️ Warnings detected but continuing...\n'));
199
+ }
200
+ }
201
+ //# sourceMappingURL=parent-repo-validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parent-repo-validator.js","sourceRoot":"","sources":["../../../../src/core/cicd/parent-repo-validator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,79 @@
1
+ /**
2
+ * CI/CD Monitor State Manager
3
+ *
4
+ * Manages persistent state for workflow monitoring, failure detection,
5
+ * and deduplication. Uses file-based storage with locking to prevent
6
+ * concurrent write corruption.
7
+ */
8
+ import { CICDMonitorState, FailureRecord, IStateManager } from './types';
9
+ /**
10
+ * StateManager - Manages CI/CD monitor persistent state
11
+ *
12
+ * Features:
13
+ * - File-based JSON storage
14
+ * - File locking to prevent corruption
15
+ * - Automatic directory creation
16
+ * - State migration support
17
+ * - Deduplication tracking
18
+ */
19
+ export declare class StateManager implements IStateManager {
20
+ private statePath;
21
+ private lockPath;
22
+ /**
23
+ * Create state manager
24
+ *
25
+ * @param rootDir - Project root directory (defaults to cwd)
26
+ */
27
+ constructor(rootDir?: string);
28
+ /**
29
+ * Load state from disk
30
+ *
31
+ * @returns Current state (or default if file doesn't exist)
32
+ */
33
+ loadState(): Promise<CICDMonitorState>;
34
+ /**
35
+ * Save state to disk with file locking
36
+ *
37
+ * @param state - State to save
38
+ */
39
+ saveState(state: CICDMonitorState): Promise<void>;
40
+ /**
41
+ * Mark failure as processed (deduplication)
42
+ *
43
+ * @param runId - Workflow run ID
44
+ */
45
+ markProcessed(runId: number): Promise<void>;
46
+ /**
47
+ * Get last poll timestamp
48
+ *
49
+ * @returns ISO 8601 timestamp or null
50
+ */
51
+ getLastPoll(): Promise<string | null>;
52
+ /**
53
+ * Update last poll timestamp to now
54
+ */
55
+ updateLastPoll(): Promise<void>;
56
+ /**
57
+ * Add failure record
58
+ *
59
+ * @param failure - Failure record to add
60
+ */
61
+ addFailure(failure: FailureRecord): Promise<void>;
62
+ /**
63
+ * Get all unprocessed failures
64
+ *
65
+ * @returns Array of unprocessed failure records
66
+ */
67
+ getUnprocessedFailures(): Promise<FailureRecord[]>;
68
+ /**
69
+ * Acquire file lock (with timeout)
70
+ *
71
+ * Prevents concurrent writes from corrupting state file.
72
+ */
73
+ private acquireLock;
74
+ /**
75
+ * Release file lock
76
+ */
77
+ private releaseLock;
78
+ }
79
+ //# sourceMappingURL=state-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state-manager.d.ts","sourceRoot":"","sources":["../../../../src/core/cicd/state-manager.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,EACL,gBAAgB,EAEhB,aAAa,EACb,aAAa,EACd,MAAM,SAAS,CAAC;AAiBjB;;;;;;;;;GASG;AACH,qBAAa,YAAa,YAAW,aAAa;IAChD,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,QAAQ,CAAS;IAEzB;;;;OAIG;gBACS,OAAO,GAAE,MAAsB;IAK3C;;;;OAIG;IACG,SAAS,IAAI,OAAO,CAAC,gBAAgB,CAAC;IA6B5C;;;;OAIG;IACG,SAAS,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBvD;;;;OAIG;IACG,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAUjD;;;;OAIG;IACG,WAAW,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAK3C;;OAEG;IACG,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IAMrC;;;;OAIG;IACG,UAAU,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBvD;;;;OAIG;IACG,sBAAsB,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC;IAQxD;;;;OAIG;YACW,WAAW;IAkCzB;;OAEG;YACW,WAAW;CAO1B"}