specweave 0.22.14 → 0.23.0

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 (150) hide show
  1. package/CLAUDE.md +178 -1
  2. package/dist/src/cli/commands/import-external.d.ts +22 -0
  3. package/dist/src/cli/commands/import-external.d.ts.map +1 -0
  4. package/dist/src/cli/commands/import-external.js +282 -0
  5. package/dist/src/cli/commands/import-external.js.map +1 -0
  6. package/dist/src/cli/commands/init.d.ts.map +1 -1
  7. package/dist/src/cli/commands/init.js +46 -0
  8. package/dist/src/cli/commands/init.js.map +1 -1
  9. package/dist/src/cli/helpers/github-repo-selector.d.ts +59 -0
  10. package/dist/src/cli/helpers/github-repo-selector.d.ts.map +1 -0
  11. package/dist/src/cli/helpers/github-repo-selector.js +265 -0
  12. package/dist/src/cli/helpers/github-repo-selector.js.map +1 -0
  13. package/dist/src/config/types.d.ts +16 -16
  14. package/dist/src/core/increment/ac-status-manager.d.ts.map +1 -1
  15. package/dist/src/core/increment/ac-status-manager.js +4 -2
  16. package/dist/src/core/increment/ac-status-manager.js.map +1 -1
  17. package/dist/src/core/increment/completion-validator.d.ts +30 -1
  18. package/dist/src/core/increment/completion-validator.d.ts.map +1 -1
  19. package/dist/src/core/increment/completion-validator.js +151 -3
  20. package/dist/src/core/increment/completion-validator.js.map +1 -1
  21. package/dist/src/core/increment/increment-archiver.d.ts +25 -0
  22. package/dist/src/core/increment/increment-archiver.d.ts.map +1 -1
  23. package/dist/src/core/increment/increment-archiver.js +130 -3
  24. package/dist/src/core/increment/increment-archiver.js.map +1 -1
  25. package/dist/src/core/living-docs/feature-archiver.d.ts +37 -0
  26. package/dist/src/core/living-docs/feature-archiver.d.ts.map +1 -1
  27. package/dist/src/core/living-docs/feature-archiver.js +262 -18
  28. package/dist/src/core/living-docs/feature-archiver.js.map +1 -1
  29. package/dist/src/core/living-docs/feature-id-manager.d.ts +17 -0
  30. package/dist/src/core/living-docs/feature-id-manager.d.ts.map +1 -1
  31. package/dist/src/core/living-docs/feature-id-manager.js +25 -0
  32. package/dist/src/core/living-docs/feature-id-manager.js.map +1 -1
  33. package/dist/src/core/living-docs/living-docs-sync.d.ts +14 -0
  34. package/dist/src/core/living-docs/living-docs-sync.d.ts.map +1 -1
  35. package/dist/src/core/living-docs/living-docs-sync.js +46 -0
  36. package/dist/src/core/living-docs/living-docs-sync.js.map +1 -1
  37. package/dist/src/core/sync/sync-event-logger.d.ts +15 -1
  38. package/dist/src/core/sync/sync-event-logger.d.ts.map +1 -1
  39. package/dist/src/core/sync/sync-event-logger.js +39 -1
  40. package/dist/src/core/sync/sync-event-logger.js.map +1 -1
  41. package/dist/src/core/types/sync-config-validator.d.ts +57 -0
  42. package/dist/src/core/types/sync-config-validator.d.ts.map +1 -0
  43. package/dist/src/core/types/sync-config-validator.js +116 -0
  44. package/dist/src/core/types/sync-config-validator.js.map +1 -0
  45. package/dist/src/importers/duplicate-detector.d.ts +107 -0
  46. package/dist/src/importers/duplicate-detector.d.ts.map +1 -0
  47. package/dist/src/importers/duplicate-detector.js +189 -0
  48. package/dist/src/importers/duplicate-detector.js.map +1 -0
  49. package/dist/src/importers/import-coordinator.d.ts +15 -0
  50. package/dist/src/importers/import-coordinator.d.ts.map +1 -1
  51. package/dist/src/importers/import-coordinator.js +43 -1
  52. package/dist/src/importers/import-coordinator.js.map +1 -1
  53. package/dist/src/importers/item-converter.d.ts +5 -0
  54. package/dist/src/importers/item-converter.d.ts.map +1 -1
  55. package/dist/src/importers/item-converter.js +27 -2
  56. package/dist/src/importers/item-converter.js.map +1 -1
  57. package/dist/src/importers/rate-limiter.d.ts +128 -0
  58. package/dist/src/importers/rate-limiter.d.ts.map +1 -0
  59. package/dist/src/importers/rate-limiter.js +200 -0
  60. package/dist/src/importers/rate-limiter.js.map +1 -0
  61. package/dist/src/init/compliance/types.d.ts +2 -2
  62. package/dist/src/integrations/ado/ado-client.d.ts +6 -0
  63. package/dist/src/integrations/ado/ado-client.d.ts.map +1 -1
  64. package/dist/src/integrations/ado/ado-client.js +23 -0
  65. package/dist/src/integrations/ado/ado-client.js.map +1 -1
  66. package/dist/src/integrations/jira/jira-client.d.ts +6 -0
  67. package/dist/src/integrations/jira/jira-client.d.ts.map +1 -1
  68. package/dist/src/integrations/jira/jira-client.js +38 -0
  69. package/dist/src/integrations/jira/jira-client.js.map +1 -1
  70. package/dist/src/sync/external-item-sync-service.d.ts +150 -0
  71. package/dist/src/sync/external-item-sync-service.d.ts.map +1 -0
  72. package/dist/src/sync/external-item-sync-service.js +241 -0
  73. package/dist/src/sync/external-item-sync-service.js.map +1 -0
  74. package/dist/src/sync/format-preservation-sync.d.ts +90 -0
  75. package/dist/src/sync/format-preservation-sync.d.ts.map +1 -0
  76. package/dist/src/sync/format-preservation-sync.js +173 -0
  77. package/dist/src/sync/format-preservation-sync.js.map +1 -0
  78. package/dist/src/sync/index.d.ts +8 -0
  79. package/dist/src/sync/index.d.ts.map +1 -0
  80. package/dist/src/sync/index.js +6 -0
  81. package/dist/src/sync/index.js.map +1 -0
  82. package/dist/src/sync/sync-coordinator.d.ts +49 -0
  83. package/dist/src/sync/sync-coordinator.d.ts.map +1 -0
  84. package/dist/src/sync/sync-coordinator.js +248 -0
  85. package/dist/src/sync/sync-coordinator.js.map +1 -0
  86. package/dist/src/sync/sync-metadata.d.ts +75 -0
  87. package/dist/src/sync/sync-metadata.d.ts.map +1 -0
  88. package/dist/src/sync/sync-metadata.js +100 -0
  89. package/dist/src/sync/sync-metadata.js.map +1 -0
  90. package/dist/src/types/living-docs-us-file.d.ts +63 -0
  91. package/dist/src/types/living-docs-us-file.d.ts.map +1 -0
  92. package/dist/src/types/living-docs-us-file.js +27 -0
  93. package/dist/src/types/living-docs-us-file.js.map +1 -0
  94. package/dist/src/validators/format-preservation-validator.d.ts +127 -0
  95. package/dist/src/validators/format-preservation-validator.d.ts.map +1 -0
  96. package/dist/src/validators/format-preservation-validator.js +187 -0
  97. package/dist/src/validators/format-preservation-validator.js.map +1 -0
  98. package/package.json +3 -2
  99. package/plugins/specweave/.claude-plugin/plugin.json +20 -0
  100. package/plugins/specweave/commands/specweave-archive-features.md +11 -1
  101. package/plugins/specweave/commands/specweave-import-docs.md +88 -278
  102. package/plugins/specweave/commands/specweave-import-external.md +407 -0
  103. package/plugins/specweave/hooks/post-edit-spec.sh +41 -0
  104. package/plugins/specweave/hooks/post-increment-completion.sh +0 -0
  105. package/plugins/specweave/hooks/post-spec-update.sh +0 -0
  106. package/plugins/specweave/hooks/post-task-completion.sh +13 -3
  107. package/plugins/specweave/hooks/post-write-spec.sh +37 -0
  108. package/plugins/specweave/lib/hooks/auto-transition.js +1 -1
  109. package/plugins/specweave/lib/hooks/auto-transition.ts +1 -1
  110. package/plugins/specweave/lib/hooks/invoke-translator-skill.js +1 -1
  111. package/plugins/specweave/lib/hooks/invoke-translator-skill.ts +1 -1
  112. package/plugins/specweave/lib/hooks/sync-living-docs.js +35 -1
  113. package/plugins/specweave/lib/hooks/sync-us-tasks.js +179 -3
  114. package/plugins/specweave/lib/hooks/translate-file.js +1 -1
  115. package/plugins/specweave/lib/hooks/translate-file.ts +1 -1
  116. package/plugins/specweave/lib/hooks/update-ac-status.js +1 -1
  117. package/plugins/specweave/lib/hooks/update-ac-status.ts +1 -1
  118. package/plugins/specweave/lib/vendor/core/increment/ac-status-manager.d.ts +115 -0
  119. package/plugins/specweave/lib/vendor/core/increment/ac-status-manager.js +345 -0
  120. package/plugins/specweave/lib/vendor/core/increment/ac-status-manager.js.map +1 -0
  121. package/plugins/specweave/lib/vendor/core/increment/active-increment-manager.d.ts +106 -0
  122. package/plugins/specweave/lib/vendor/core/increment/active-increment-manager.js +220 -0
  123. package/plugins/specweave/lib/vendor/core/increment/active-increment-manager.js.map +1 -0
  124. package/plugins/specweave/lib/vendor/core/increment/auto-transition-manager.d.ts +60 -0
  125. package/plugins/specweave/lib/vendor/core/increment/auto-transition-manager.js +192 -0
  126. package/plugins/specweave/lib/vendor/core/increment/auto-transition-manager.js.map +1 -0
  127. package/plugins/specweave/lib/vendor/core/increment/duplicate-detector.d.ts +52 -0
  128. package/plugins/specweave/lib/vendor/core/increment/duplicate-detector.js +276 -0
  129. package/plugins/specweave/lib/vendor/core/increment/duplicate-detector.js.map +1 -0
  130. package/plugins/specweave/lib/vendor/core/increment/metadata-manager.d.ts +163 -0
  131. package/plugins/specweave/lib/vendor/core/increment/metadata-manager.js +541 -0
  132. package/plugins/specweave/lib/vendor/core/increment/metadata-manager.js.map +1 -0
  133. package/plugins/specweave/lib/vendor/core/types/increment-metadata.d.ts +157 -0
  134. package/plugins/specweave/lib/vendor/core/types/increment-metadata.js +191 -0
  135. package/plugins/specweave/lib/vendor/core/types/increment-metadata.js.map +1 -0
  136. package/plugins/specweave/lib/vendor/generators/spec/task-parser.d.ts +95 -0
  137. package/plugins/specweave/lib/vendor/generators/spec/task-parser.js +301 -0
  138. package/plugins/specweave/lib/vendor/generators/spec/task-parser.js.map +1 -0
  139. package/plugins/specweave/lib/vendor/utils/logger.d.ts +48 -0
  140. package/plugins/specweave/lib/vendor/utils/logger.js +53 -0
  141. package/plugins/specweave/lib/vendor/utils/logger.js.map +1 -0
  142. package/plugins/specweave/lib/vendor/utils/translation.d.ts +187 -0
  143. package/plugins/specweave/lib/vendor/utils/translation.js +414 -0
  144. package/plugins/specweave/lib/vendor/utils/translation.js.map +1 -0
  145. package/plugins/specweave-ado/lib/ado-multi-project-sync.js +0 -1
  146. package/plugins/specweave-github/commands/specweave-github-update-user-story.md +1 -1
  147. package/plugins/specweave-github/skills/github-issue-standard/SKILL.md +1 -1
  148. package/plugins/specweave-jira/lib/enhanced-jira-sync.js +3 -3
  149. package/plugins/specweave-ado/lib/enhanced-ado-sync.js +0 -170
  150. package/plugins/specweave-release/hooks/.specweave/logs/dora-tracking.log +0 -5694
@@ -0,0 +1,127 @@
1
+ /**
2
+ * Format Preservation Validator
3
+ *
4
+ * Validates sync operations to ensure external items maintain their original format.
5
+ * Prevents unintended modifications to external item titles, descriptions, and ACs.
6
+ *
7
+ * Key validations:
8
+ * - External items (format_preservation=true) → only comments allowed
9
+ * - Internal items (format_preservation=false) → full sync allowed
10
+ * - Title immutability for external items
11
+ * - Description immutability for external items
12
+ * - AC modifications blocked for external items
13
+ *
14
+ * Part of increment 0047-us-task-linkage (T-034C)
15
+ */
16
+ import type { Logger } from '../utils/logger.js';
17
+ /**
18
+ * Sync operation to validate
19
+ */
20
+ export interface SyncOperation {
21
+ /** User Story ID (e.g., "US-009") */
22
+ usId: string;
23
+ /** Format preservation enabled flag */
24
+ formatPreservation: boolean;
25
+ /** Fields to update (e.g., ['title', 'description', 'comments']) */
26
+ updates: string[];
27
+ /** Origin (internal | external) */
28
+ origin?: 'internal' | 'external';
29
+ /** Proposed title change (if any) */
30
+ proposedTitle?: string;
31
+ /** Current title (for validation) */
32
+ currentTitle?: string;
33
+ }
34
+ /**
35
+ * Validation result
36
+ */
37
+ export interface ValidationResult {
38
+ /** Validation passed flag */
39
+ valid: boolean;
40
+ /** Validation errors */
41
+ errors?: string[];
42
+ /** Validation warnings (non-blocking) */
43
+ warnings?: string[];
44
+ /** Allowed fields (after filtering blocked fields) */
45
+ allowedFields?: string[];
46
+ /** Blocked fields */
47
+ blockedFields?: string[];
48
+ }
49
+ /**
50
+ * Format Preservation Validator
51
+ *
52
+ * Ensures external items maintain their original format during sync operations.
53
+ */
54
+ export declare class FormatPreservationValidator {
55
+ private logger;
56
+ constructor(options?: {
57
+ logger?: Logger;
58
+ });
59
+ /**
60
+ * Validate sync operation
61
+ *
62
+ * Checks if the proposed sync operation violates format preservation rules.
63
+ *
64
+ * Rules:
65
+ * 1. External items (format_preservation=true) → ONLY comments allowed
66
+ * 2. Title updates → BLOCKED for external items
67
+ * 3. Description updates → BLOCKED for external items
68
+ * 4. AC updates → BLOCKED for external items
69
+ * 5. Status updates → ALLOWED (external tools control lifecycle)
70
+ * 6. Comments → ALWAYS ALLOWED
71
+ *
72
+ * @param operation - Sync operation to validate
73
+ * @returns Validation result
74
+ */
75
+ validate(operation: SyncOperation): ValidationResult;
76
+ /**
77
+ * Check if field is blocked for external items
78
+ *
79
+ * @param field - Field name (e.g., 'title', 'description', 'comments')
80
+ * @returns True if field is blocked for external items
81
+ */
82
+ private isBlockedField;
83
+ /**
84
+ * Get error message for blocked field
85
+ *
86
+ * @param field - Blocked field name
87
+ * @param usId - User Story ID
88
+ * @returns Error message
89
+ */
90
+ private getBlockedFieldError;
91
+ /**
92
+ * Validate batch sync operations
93
+ *
94
+ * Validates multiple sync operations and returns results for each.
95
+ *
96
+ * @param operations - Array of sync operations
97
+ * @returns Array of validation results
98
+ */
99
+ validateBatch(operations: SyncOperation[]): ValidationResult[];
100
+ /**
101
+ * Quick check: Is sync allowed?
102
+ *
103
+ * Simplified validation that returns true/false without detailed errors.
104
+ *
105
+ * @param formatPreservation - Format preservation flag
106
+ * @param proposedUpdates - Fields to update
107
+ * @returns True if sync is allowed
108
+ */
109
+ isSyncAllowed(formatPreservation: boolean, proposedUpdates: string[]): boolean;
110
+ /**
111
+ * Filter allowed fields from sync operation
112
+ *
113
+ * Returns only the fields that are allowed for the given operation.
114
+ *
115
+ * @param operation - Sync operation
116
+ * @returns Array of allowed field names
117
+ */
118
+ filterAllowedFields(operation: SyncOperation): string[];
119
+ /**
120
+ * Get validation summary for logging
121
+ *
122
+ * @param result - Validation result
123
+ * @returns Human-readable summary
124
+ */
125
+ getValidationSummary(result: ValidationResult): string;
126
+ }
127
+ //# sourceMappingURL=format-preservation-validator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format-preservation-validator.d.ts","sourceRoot":"","sources":["../../../src/validators/format-preservation-validator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAGjD;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,qCAAqC;IACrC,IAAI,EAAE,MAAM,CAAC;IAEb,uCAAuC;IACvC,kBAAkB,EAAE,OAAO,CAAC;IAE5B,oEAAoE;IACpE,OAAO,EAAE,MAAM,EAAE,CAAC;IAElB,mCAAmC;IACnC,MAAM,CAAC,EAAE,UAAU,GAAG,UAAU,CAAC;IAEjC,qCAAqC;IACrC,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB,qCAAqC;IACrC,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,6BAA6B;IAC7B,KAAK,EAAE,OAAO,CAAC;IAEf,wBAAwB;IACxB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAElB,yCAAyC;IACzC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IAEpB,sDAAsD;IACtD,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IAEzB,qBAAqB;IACrB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED;;;;GAIG;AACH,qBAAa,2BAA2B;IACtC,OAAO,CAAC,MAAM,CAAS;gBAEX,OAAO,GAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAA;KAAO;IAI7C;;;;;;;;;;;;;;;OAeG;IACH,QAAQ,CAAC,SAAS,EAAE,aAAa,GAAG,gBAAgB;IAsDpD;;;;;OAKG;IACH,OAAO,CAAC,cAAc;IAatB;;;;;;OAMG;IACH,OAAO,CAAC,oBAAoB;IAqB5B;;;;;;;OAOG;IACH,aAAa,CAAC,UAAU,EAAE,aAAa,EAAE,GAAG,gBAAgB,EAAE;IAI9D;;;;;;;;OAQG;IACH,aAAa,CAAC,kBAAkB,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,GAAG,OAAO;IAU9E;;;;;;;OAOG;IACH,mBAAmB,CAAC,SAAS,EAAE,aAAa,GAAG,MAAM,EAAE;IASvD;;;;;OAKG;IACH,oBAAoB,CAAC,MAAM,EAAE,gBAAgB,GAAG,MAAM;CAWvD"}
@@ -0,0 +1,187 @@
1
+ /**
2
+ * Format Preservation Validator
3
+ *
4
+ * Validates sync operations to ensure external items maintain their original format.
5
+ * Prevents unintended modifications to external item titles, descriptions, and ACs.
6
+ *
7
+ * Key validations:
8
+ * - External items (format_preservation=true) → only comments allowed
9
+ * - Internal items (format_preservation=false) → full sync allowed
10
+ * - Title immutability for external items
11
+ * - Description immutability for external items
12
+ * - AC modifications blocked for external items
13
+ *
14
+ * Part of increment 0047-us-task-linkage (T-034C)
15
+ */
16
+ import { consoleLogger } from '../utils/logger.js';
17
+ /**
18
+ * Format Preservation Validator
19
+ *
20
+ * Ensures external items maintain their original format during sync operations.
21
+ */
22
+ export class FormatPreservationValidator {
23
+ constructor(options = {}) {
24
+ this.logger = options.logger ?? consoleLogger;
25
+ }
26
+ /**
27
+ * Validate sync operation
28
+ *
29
+ * Checks if the proposed sync operation violates format preservation rules.
30
+ *
31
+ * Rules:
32
+ * 1. External items (format_preservation=true) → ONLY comments allowed
33
+ * 2. Title updates → BLOCKED for external items
34
+ * 3. Description updates → BLOCKED for external items
35
+ * 4. AC updates → BLOCKED for external items
36
+ * 5. Status updates → ALLOWED (external tools control lifecycle)
37
+ * 6. Comments → ALWAYS ALLOWED
38
+ *
39
+ * @param operation - Sync operation to validate
40
+ * @returns Validation result
41
+ */
42
+ validate(operation) {
43
+ const errors = [];
44
+ const warnings = [];
45
+ const blockedFields = [];
46
+ const allowedFields = [];
47
+ // Internal items → full sync allowed, no validation needed
48
+ if (!operation.formatPreservation) {
49
+ return {
50
+ valid: true,
51
+ allowedFields: operation.updates,
52
+ blockedFields: []
53
+ };
54
+ }
55
+ // External items → validate each field
56
+ for (const field of operation.updates) {
57
+ if (this.isBlockedField(field)) {
58
+ blockedFields.push(field);
59
+ errors.push(this.getBlockedFieldError(field, operation.usId));
60
+ }
61
+ else {
62
+ allowedFields.push(field);
63
+ }
64
+ }
65
+ // Validate title immutability (if title change proposed)
66
+ if (operation.proposedTitle && operation.currentTitle) {
67
+ if (operation.proposedTitle !== operation.currentTitle) {
68
+ errors.push(`Title immutability violation for ${operation.usId}: ` +
69
+ `Cannot change external item title from "${operation.currentTitle}" to "${operation.proposedTitle}"`);
70
+ }
71
+ }
72
+ // Log validation result
73
+ if (errors.length > 0) {
74
+ this.logger.warn(` ⚠️ Format preservation validation failed for ${operation.usId}:`);
75
+ errors.forEach(err => this.logger.warn(` - ${err}`));
76
+ }
77
+ if (warnings.length > 0) {
78
+ warnings.forEach(warn => this.logger.warn(` ⚠️ ${warn}`));
79
+ }
80
+ return {
81
+ valid: errors.length === 0,
82
+ errors: errors.length > 0 ? errors : undefined,
83
+ warnings: warnings.length > 0 ? warnings : undefined,
84
+ allowedFields,
85
+ blockedFields
86
+ };
87
+ }
88
+ /**
89
+ * Check if field is blocked for external items
90
+ *
91
+ * @param field - Field name (e.g., 'title', 'description', 'comments')
92
+ * @returns True if field is blocked for external items
93
+ */
94
+ isBlockedField(field) {
95
+ const BLOCKED_FIELDS = [
96
+ 'title',
97
+ 'description',
98
+ 'acceptance_criteria',
99
+ 'acs',
100
+ 'body',
101
+ 'overview'
102
+ ];
103
+ return BLOCKED_FIELDS.includes(field.toLowerCase());
104
+ }
105
+ /**
106
+ * Get error message for blocked field
107
+ *
108
+ * @param field - Blocked field name
109
+ * @param usId - User Story ID
110
+ * @returns Error message
111
+ */
112
+ getBlockedFieldError(field, usId) {
113
+ const fieldName = field.toLowerCase();
114
+ switch (fieldName) {
115
+ case 'title':
116
+ return `Cannot update title for ${usId} (external item with format preservation enabled). Original title must be preserved.`;
117
+ case 'description':
118
+ case 'body':
119
+ case 'overview':
120
+ return `Cannot update description/body for ${usId} (external item with format preservation enabled). Original description must be preserved.`;
121
+ case 'acceptance_criteria':
122
+ case 'acs':
123
+ return `Cannot update acceptance criteria for ${usId} (external item with format preservation enabled). Original ACs must be preserved.`;
124
+ default:
125
+ return `Cannot update field "${field}" for ${usId} (external item with format preservation enabled).`;
126
+ }
127
+ }
128
+ /**
129
+ * Validate batch sync operations
130
+ *
131
+ * Validates multiple sync operations and returns results for each.
132
+ *
133
+ * @param operations - Array of sync operations
134
+ * @returns Array of validation results
135
+ */
136
+ validateBatch(operations) {
137
+ return operations.map(op => this.validate(op));
138
+ }
139
+ /**
140
+ * Quick check: Is sync allowed?
141
+ *
142
+ * Simplified validation that returns true/false without detailed errors.
143
+ *
144
+ * @param formatPreservation - Format preservation flag
145
+ * @param proposedUpdates - Fields to update
146
+ * @returns True if sync is allowed
147
+ */
148
+ isSyncAllowed(formatPreservation, proposedUpdates) {
149
+ // Internal items → always allowed
150
+ if (!formatPreservation) {
151
+ return true;
152
+ }
153
+ // External items → check if any blocked fields
154
+ return !proposedUpdates.some(field => this.isBlockedField(field));
155
+ }
156
+ /**
157
+ * Filter allowed fields from sync operation
158
+ *
159
+ * Returns only the fields that are allowed for the given operation.
160
+ *
161
+ * @param operation - Sync operation
162
+ * @returns Array of allowed field names
163
+ */
164
+ filterAllowedFields(operation) {
165
+ if (!operation.formatPreservation) {
166
+ return operation.updates; // All fields allowed for internal items
167
+ }
168
+ // For external items, filter out blocked fields
169
+ return operation.updates.filter(field => !this.isBlockedField(field));
170
+ }
171
+ /**
172
+ * Get validation summary for logging
173
+ *
174
+ * @param result - Validation result
175
+ * @returns Human-readable summary
176
+ */
177
+ getValidationSummary(result) {
178
+ if (result.valid) {
179
+ return `✅ Validation passed (${result.allowedFields?.length || 0} fields allowed)`;
180
+ }
181
+ const errorCount = result.errors?.length || 0;
182
+ const warningCount = result.warnings?.length || 0;
183
+ const blockedCount = result.blockedFields?.length || 0;
184
+ return `❌ Validation failed: ${errorCount} error(s), ${warningCount} warning(s), ${blockedCount} field(s) blocked`;
185
+ }
186
+ }
187
+ //# sourceMappingURL=format-preservation-validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format-preservation-validator.js","sourceRoot":"","sources":["../../../src/validators/format-preservation-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.22.14",
3
+ "version": "0.23.0",
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",
@@ -9,10 +9,11 @@
9
9
  },
10
10
  "scripts": {
11
11
  "clean": "rm -rf dist/",
12
- "build": "tsc && npm run copy:locales && npm run copy:plugins",
12
+ "build": "tsc && npm run copy:locales && npm run copy:plugins && npm run copy:hook-deps",
13
13
  "rebuild": "npm run clean && npm run build",
14
14
  "copy:locales": "node scripts/copy-locales.js",
15
15
  "copy:plugins": "node scripts/copy-plugin-js.js",
16
+ "copy:hook-deps": "node scripts/copy-hook-dependencies.js",
16
17
  "dev": "tsc --watch",
17
18
  "prepare": "npm run build",
18
19
  "prepublishOnly": "npm run rebuild",
@@ -30,6 +30,26 @@
30
30
  "timeout": 10
31
31
  }
32
32
  ]
33
+ },
34
+ {
35
+ "matcher": "Edit",
36
+ "hooks": [
37
+ {
38
+ "type": "command",
39
+ "command": "${CLAUDE_PLUGIN_ROOT}/hooks/post-edit-spec.sh",
40
+ "timeout": 5
41
+ }
42
+ ]
43
+ },
44
+ {
45
+ "matcher": "Write",
46
+ "hooks": [
47
+ {
48
+ "type": "command",
49
+ "command": "${CLAUDE_PLUGIN_ROOT}/hooks/post-write-spec.sh",
50
+ "timeout": 5
51
+ }
52
+ ]
33
53
  }
34
54
  ]
35
55
  }
@@ -19,6 +19,7 @@ Archive features and epics based on their increment archive status. Features are
19
19
  - `--update-links`: Update all links to archived items (default: true)
20
20
  - `--preserve-active`: Don't archive features with active projects (default: true)
21
21
  - `--orphaned`: Also archive orphaned features/epics with no increments/features
22
+ - `--reason <text>`: Optional reason for archiving (for audit trail, AC-US13-07)
22
23
 
23
24
  ## Examples
24
25
 
@@ -31,6 +32,9 @@ Archive features and epics based on their increment archive status. Features are
31
32
 
32
33
  # Archive including orphaned features
33
34
  /specweave:archive-features --orphaned
35
+
36
+ # Archive with custom reason for audit trail (AC-US13-07)
37
+ /specweave:archive-features --reason="Obsolete after product pivot"
34
38
  ```
35
39
 
36
40
  ## Archive Rules
@@ -80,12 +84,18 @@ task.run(async () => {
80
84
  const archiver = new FeatureArchiver(process.cwd());
81
85
 
82
86
  // Parse options
87
+ const reasonIndex = process.argv.indexOf('--reason');
88
+ const customReason = reasonIndex !== -1 && reasonIndex + 1 < process.argv.length
89
+ ? process.argv[reasonIndex + 1]
90
+ : undefined;
91
+
83
92
  const options = {
84
93
  dryRun: process.argv.includes('--dry-run'),
85
94
  updateLinks: !process.argv.includes('--no-update-links'),
86
95
  preserveActiveFeatures: !process.argv.includes('--no-preserve-active'),
87
96
  archiveOrphanedFeatures: process.argv.includes('--orphaned'),
88
- archiveOrphanedEpics: process.argv.includes('--orphaned')
97
+ archiveOrphanedEpics: process.argv.includes('--orphaned'),
98
+ customReason: customReason
89
99
  };
90
100
 
91
101
  // Execute archiving