specweave 0.28.68 → 0.29.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 (318) hide show
  1. package/CLAUDE.md +3 -2
  2. package/README.md +19 -2
  3. package/dist/src/cli/commands/discrepancies.d.ts +89 -0
  4. package/dist/src/cli/commands/discrepancies.d.ts.map +1 -0
  5. package/dist/src/cli/commands/discrepancies.js +385 -0
  6. package/dist/src/cli/commands/discrepancies.js.map +1 -0
  7. package/dist/src/cli/commands/notifications.d.ts +70 -0
  8. package/dist/src/cli/commands/notifications.d.ts.map +1 -0
  9. package/dist/src/cli/commands/notifications.js +236 -0
  10. package/dist/src/cli/commands/notifications.js.map +1 -0
  11. package/dist/src/cli/commands/sync-logs.d.ts +54 -0
  12. package/dist/src/cli/commands/sync-logs.d.ts.map +1 -0
  13. package/dist/src/cli/commands/sync-logs.js +240 -0
  14. package/dist/src/cli/commands/sync-logs.js.map +1 -0
  15. package/dist/src/cli/commands/sync-monitor.d.ts +42 -0
  16. package/dist/src/cli/commands/sync-monitor.d.ts.map +1 -0
  17. package/dist/src/cli/commands/sync-monitor.js +191 -0
  18. package/dist/src/cli/commands/sync-monitor.js.map +1 -0
  19. package/dist/src/cli/helpers/init/brownfield-analysis.d.ts +45 -0
  20. package/dist/src/cli/helpers/init/brownfield-analysis.d.ts.map +1 -0
  21. package/dist/src/cli/helpers/init/brownfield-analysis.js +431 -0
  22. package/dist/src/cli/helpers/init/brownfield-analysis.js.map +1 -0
  23. package/dist/src/cli/helpers/init/index.d.ts +1 -0
  24. package/dist/src/cli/helpers/init/index.d.ts.map +1 -1
  25. package/dist/src/cli/helpers/init/index.js +2 -0
  26. package/dist/src/cli/helpers/init/index.js.map +1 -1
  27. package/dist/src/cli/workers/brownfield-worker.d.ts +66 -0
  28. package/dist/src/cli/workers/brownfield-worker.d.ts.map +1 -0
  29. package/dist/src/cli/workers/brownfield-worker.js +417 -0
  30. package/dist/src/cli/workers/brownfield-worker.js.map +1 -0
  31. package/dist/src/core/background/brownfield-launcher.d.ts +86 -0
  32. package/dist/src/core/background/brownfield-launcher.d.ts.map +1 -0
  33. package/dist/src/core/background/brownfield-launcher.js +295 -0
  34. package/dist/src/core/background/brownfield-launcher.js.map +1 -0
  35. package/dist/src/core/background/index.d.ts +2 -0
  36. package/dist/src/core/background/index.d.ts.map +1 -1
  37. package/dist/src/core/background/index.js +2 -0
  38. package/dist/src/core/background/index.js.map +1 -1
  39. package/dist/src/core/background/types.d.ts +23 -2
  40. package/dist/src/core/background/types.d.ts.map +1 -1
  41. package/dist/src/core/config/index.d.ts +1 -0
  42. package/dist/src/core/config/index.d.ts.map +1 -1
  43. package/dist/src/core/config/index.js +1 -0
  44. package/dist/src/core/config/index.js.map +1 -1
  45. package/dist/src/core/config/types.d.ts +6 -0
  46. package/dist/src/core/config/types.d.ts.map +1 -1
  47. package/dist/src/core/config/types.js.map +1 -1
  48. package/dist/src/core/dashboard/dashboard-data.d.ts +156 -0
  49. package/dist/src/core/dashboard/dashboard-data.d.ts.map +1 -0
  50. package/dist/src/core/dashboard/dashboard-data.js +191 -0
  51. package/dist/src/core/dashboard/dashboard-data.js.map +1 -0
  52. package/dist/src/core/dashboard/index.d.ts +9 -0
  53. package/dist/src/core/dashboard/index.d.ts.map +1 -0
  54. package/dist/src/core/dashboard/index.js +9 -0
  55. package/dist/src/core/dashboard/index.js.map +1 -0
  56. package/dist/src/core/discrepancy/analyzers/api-route-analyzer.d.ts +77 -0
  57. package/dist/src/core/discrepancy/analyzers/api-route-analyzer.d.ts.map +1 -0
  58. package/dist/src/core/discrepancy/analyzers/api-route-analyzer.js +286 -0
  59. package/dist/src/core/discrepancy/analyzers/api-route-analyzer.js.map +1 -0
  60. package/dist/src/core/discrepancy/analyzers/index.d.ts +8 -0
  61. package/dist/src/core/discrepancy/analyzers/index.d.ts.map +1 -0
  62. package/dist/src/core/discrepancy/analyzers/index.js +8 -0
  63. package/dist/src/core/discrepancy/analyzers/index.js.map +1 -0
  64. package/dist/src/core/discrepancy/analyzers/typescript-analyzer.d.ts +96 -0
  65. package/dist/src/core/discrepancy/analyzers/typescript-analyzer.d.ts.map +1 -0
  66. package/dist/src/core/discrepancy/analyzers/typescript-analyzer.js +247 -0
  67. package/dist/src/core/discrepancy/analyzers/typescript-analyzer.js.map +1 -0
  68. package/dist/src/core/discrepancy/brownfield-manager.d.ts +88 -0
  69. package/dist/src/core/discrepancy/brownfield-manager.d.ts.map +1 -0
  70. package/dist/src/core/discrepancy/brownfield-manager.js +520 -0
  71. package/dist/src/core/discrepancy/brownfield-manager.js.map +1 -0
  72. package/dist/src/core/discrepancy/brownfield-types.d.ts +174 -0
  73. package/dist/src/core/discrepancy/brownfield-types.d.ts.map +1 -0
  74. package/dist/src/core/discrepancy/brownfield-types.js +11 -0
  75. package/dist/src/core/discrepancy/brownfield-types.js.map +1 -0
  76. package/dist/src/core/discrepancy/detector.d.ts +92 -0
  77. package/dist/src/core/discrepancy/detector.d.ts.map +1 -0
  78. package/dist/src/core/discrepancy/detector.js +346 -0
  79. package/dist/src/core/discrepancy/detector.js.map +1 -0
  80. package/dist/src/core/discrepancy/increment-generator.d.ts +51 -0
  81. package/dist/src/core/discrepancy/increment-generator.d.ts.map +1 -0
  82. package/dist/src/core/discrepancy/increment-generator.js +234 -0
  83. package/dist/src/core/discrepancy/increment-generator.js.map +1 -0
  84. package/dist/src/core/discrepancy/index.d.ts +18 -0
  85. package/dist/src/core/discrepancy/index.d.ts.map +1 -0
  86. package/dist/src/core/discrepancy/index.js +24 -0
  87. package/dist/src/core/discrepancy/index.js.map +1 -0
  88. package/dist/src/core/discrepancy/severity-classifier.d.ts +81 -0
  89. package/dist/src/core/discrepancy/severity-classifier.d.ts.map +1 -0
  90. package/dist/src/core/discrepancy/severity-classifier.js +289 -0
  91. package/dist/src/core/discrepancy/severity-classifier.js.map +1 -0
  92. package/dist/src/core/discrepancy/spec-parser.d.ts +74 -0
  93. package/dist/src/core/discrepancy/spec-parser.d.ts.map +1 -0
  94. package/dist/src/core/discrepancy/spec-parser.js +213 -0
  95. package/dist/src/core/discrepancy/spec-parser.js.map +1 -0
  96. package/dist/src/core/discrepancy/update-recommender.d.ts +77 -0
  97. package/dist/src/core/discrepancy/update-recommender.d.ts.map +1 -0
  98. package/dist/src/core/discrepancy/update-recommender.js +323 -0
  99. package/dist/src/core/discrepancy/update-recommender.js.map +1 -0
  100. package/dist/src/core/living-docs/living-docs-sync.d.ts +13 -16
  101. package/dist/src/core/living-docs/living-docs-sync.d.ts.map +1 -1
  102. package/dist/src/core/living-docs/living-docs-sync.js +31 -112
  103. package/dist/src/core/living-docs/living-docs-sync.js.map +1 -1
  104. package/dist/src/core/logs/index.d.ts +10 -0
  105. package/dist/src/core/logs/index.d.ts.map +1 -0
  106. package/dist/src/core/logs/index.js +10 -0
  107. package/dist/src/core/logs/index.js.map +1 -0
  108. package/dist/src/core/logs/log-aggregator.d.ts +130 -0
  109. package/dist/src/core/logs/log-aggregator.d.ts.map +1 -0
  110. package/dist/src/core/logs/log-aggregator.js +206 -0
  111. package/dist/src/core/logs/log-aggregator.js.map +1 -0
  112. package/dist/src/core/logs/log-exporter.d.ts +81 -0
  113. package/dist/src/core/logs/log-exporter.d.ts.map +1 -0
  114. package/dist/src/core/logs/log-exporter.js +141 -0
  115. package/dist/src/core/logs/log-exporter.js.map +1 -0
  116. package/dist/src/core/notifications/command-integration.d.ts +82 -0
  117. package/dist/src/core/notifications/command-integration.d.ts.map +1 -0
  118. package/dist/src/core/notifications/command-integration.js +80 -0
  119. package/dist/src/core/notifications/command-integration.js.map +1 -0
  120. package/dist/src/core/notifications/index.d.ts +12 -0
  121. package/dist/src/core/notifications/index.d.ts.map +1 -0
  122. package/dist/src/core/notifications/index.js +12 -0
  123. package/dist/src/core/notifications/index.js.map +1 -0
  124. package/dist/src/core/notifications/notification-display.d.ts +70 -0
  125. package/dist/src/core/notifications/notification-display.d.ts.map +1 -0
  126. package/dist/src/core/notifications/notification-display.js +177 -0
  127. package/dist/src/core/notifications/notification-display.js.map +1 -0
  128. package/dist/src/core/notifications/notification-manager.d.ts +126 -0
  129. package/dist/src/core/notifications/notification-manager.d.ts.map +1 -0
  130. package/dist/src/core/notifications/notification-manager.js +287 -0
  131. package/dist/src/core/notifications/notification-manager.js.map +1 -0
  132. package/dist/src/core/notifications/notification-types.d.ts +159 -0
  133. package/dist/src/core/notifications/notification-types.d.ts.map +1 -0
  134. package/dist/src/core/notifications/notification-types.js +93 -0
  135. package/dist/src/core/notifications/notification-types.js.map +1 -0
  136. package/dist/src/core/scheduler/index.d.ts +11 -0
  137. package/dist/src/core/scheduler/index.d.ts.map +1 -0
  138. package/dist/src/core/scheduler/index.js +11 -0
  139. package/dist/src/core/scheduler/index.js.map +1 -0
  140. package/dist/src/core/scheduler/job-scheduler.d.ts +179 -0
  141. package/dist/src/core/scheduler/job-scheduler.d.ts.map +1 -0
  142. package/dist/src/core/scheduler/job-scheduler.js +282 -0
  143. package/dist/src/core/scheduler/job-scheduler.js.map +1 -0
  144. package/dist/src/core/scheduler/schedule-persistence.d.ts +83 -0
  145. package/dist/src/core/scheduler/schedule-persistence.d.ts.map +1 -0
  146. package/dist/src/core/scheduler/schedule-persistence.js +180 -0
  147. package/dist/src/core/scheduler/schedule-persistence.js.map +1 -0
  148. package/dist/src/core/scheduler/scheduled-job.d.ts +188 -0
  149. package/dist/src/core/scheduler/scheduled-job.d.ts.map +1 -0
  150. package/dist/src/core/scheduler/scheduled-job.js +182 -0
  151. package/dist/src/core/scheduler/scheduled-job.js.map +1 -0
  152. package/dist/src/core/sync/permission-enforcer.d.ts +206 -0
  153. package/dist/src/core/sync/permission-enforcer.d.ts.map +1 -0
  154. package/dist/src/core/sync/permission-enforcer.js +268 -0
  155. package/dist/src/core/sync/permission-enforcer.js.map +1 -0
  156. package/dist/src/core/sync/sync-audit-logger.d.ts +217 -0
  157. package/dist/src/core/sync/sync-audit-logger.d.ts.map +1 -0
  158. package/dist/src/core/sync/sync-audit-logger.js +327 -0
  159. package/dist/src/core/sync/sync-audit-logger.js.map +1 -0
  160. package/dist/src/core/sync/sync-interceptor.d.ts +190 -0
  161. package/dist/src/core/sync/sync-interceptor.d.ts.map +1 -0
  162. package/dist/src/core/sync/sync-interceptor.js +224 -0
  163. package/dist/src/core/sync/sync-interceptor.js.map +1 -0
  164. package/dist/src/core/types/increment-metadata.d.ts +5 -2
  165. package/dist/src/core/types/increment-metadata.d.ts.map +1 -1
  166. package/dist/src/core/types/sync-config.d.ts +267 -0
  167. package/dist/src/core/types/sync-config.d.ts.map +1 -0
  168. package/dist/src/core/types/sync-config.js +304 -0
  169. package/dist/src/core/types/sync-config.js.map +1 -0
  170. package/dist/src/hooks/index.d.ts +11 -0
  171. package/dist/src/hooks/index.d.ts.map +1 -0
  172. package/dist/src/hooks/index.js +11 -0
  173. package/dist/src/hooks/index.js.map +1 -0
  174. package/dist/src/hooks/platform.d.ts +125 -0
  175. package/dist/src/hooks/platform.d.ts.map +1 -0
  176. package/dist/src/hooks/platform.js +325 -0
  177. package/dist/src/hooks/platform.js.map +1 -0
  178. package/dist/src/hooks/processor.d.ts +20 -0
  179. package/dist/src/hooks/processor.d.ts.map +1 -0
  180. package/dist/src/hooks/processor.js +317 -0
  181. package/dist/src/hooks/processor.js.map +1 -0
  182. package/dist/src/hooks/scheduler-startup.d.ts +19 -0
  183. package/dist/src/hooks/scheduler-startup.d.ts.map +1 -0
  184. package/dist/src/hooks/scheduler-startup.js +92 -0
  185. package/dist/src/hooks/scheduler-startup.js.map +1 -0
  186. package/dist/src/hooks/session-start.d.ts +16 -0
  187. package/dist/src/hooks/session-start.d.ts.map +1 -0
  188. package/dist/src/hooks/session-start.js +92 -0
  189. package/dist/src/hooks/session-start.js.map +1 -0
  190. package/dist/src/importers/duplicate-detector.d.ts +13 -2
  191. package/dist/src/importers/duplicate-detector.d.ts.map +1 -1
  192. package/dist/src/importers/duplicate-detector.js +21 -2
  193. package/dist/src/importers/duplicate-detector.js.map +1 -1
  194. package/dist/src/importers/item-converter.d.ts +41 -2
  195. package/dist/src/importers/item-converter.d.ts.map +1 -1
  196. package/dist/src/importers/item-converter.js +225 -38
  197. package/dist/src/importers/item-converter.js.map +1 -1
  198. package/dist/src/living-docs/fs-id-allocator.d.ts +7 -0
  199. package/dist/src/living-docs/fs-id-allocator.d.ts.map +1 -1
  200. package/dist/src/living-docs/fs-id-allocator.js +30 -4
  201. package/dist/src/living-docs/fs-id-allocator.js.map +1 -1
  202. package/dist/src/sync/ado-sync-wrapper.d.ts +137 -0
  203. package/dist/src/sync/ado-sync-wrapper.d.ts.map +1 -0
  204. package/dist/src/sync/ado-sync-wrapper.js +148 -0
  205. package/dist/src/sync/ado-sync-wrapper.js.map +1 -0
  206. package/dist/src/sync/github-sync-wrapper.d.ts +195 -0
  207. package/dist/src/sync/github-sync-wrapper.d.ts.map +1 -0
  208. package/dist/src/sync/github-sync-wrapper.js +220 -0
  209. package/dist/src/sync/github-sync-wrapper.js.map +1 -0
  210. package/dist/src/sync/jira-sync-wrapper.d.ts +155 -0
  211. package/dist/src/sync/jira-sync-wrapper.d.ts.map +1 -0
  212. package/dist/src/sync/jira-sync-wrapper.js +175 -0
  213. package/dist/src/sync/jira-sync-wrapper.js.map +1 -0
  214. package/dist/src/utils/feature-id-derivation.d.ts +58 -0
  215. package/dist/src/utils/feature-id-derivation.d.ts.map +1 -0
  216. package/dist/src/utils/feature-id-derivation.js +77 -0
  217. package/dist/src/utils/feature-id-derivation.js.map +1 -0
  218. package/package.json +3 -1
  219. package/plugins/specweave/commands/specweave-discrepancies.md +141 -0
  220. package/plugins/specweave/commands/specweave-discrepancy-to-increment.md +160 -0
  221. package/plugins/specweave/commands/specweave-jobs.md +45 -2
  222. package/plugins/specweave/commands/specweave-notifications.md +92 -0
  223. package/plugins/specweave/commands/specweave-sync-logs.md +131 -0
  224. package/plugins/specweave/commands/specweave-sync-monitor.md +57 -0
  225. package/plugins/specweave/hooks/hooks.json +3 -3
  226. package/plugins/specweave/hooks/lib/scheduler-startup.sh +72 -0
  227. package/plugins/specweave/hooks/universal/dispatcher.mjs +246 -0
  228. package/plugins/specweave/hooks/universal/session-start.cmd +16 -0
  229. package/plugins/specweave/hooks/universal/session-start.ps1 +16 -0
  230. package/plugins/specweave/hooks/v2/dispatchers/session-start.sh +14 -5
  231. package/plugins/specweave/lib/vendor/core/types/increment-metadata.d.ts +5 -2
  232. package/plugins/specweave/skills/discrepancy-viewer.md +154 -0
  233. package/plugins/specweave-github/hooks/.specweave/logs/hooks-debug.log +46 -0
  234. package/plugins/specweave-release/hooks/.specweave/logs/dora-tracking.log +69 -0
  235. package/dist/plugins/specweave-github/lib/enhanced-github-sync.d.ts +0 -26
  236. package/dist/plugins/specweave-github/lib/enhanced-github-sync.d.ts.map +0 -1
  237. package/dist/plugins/specweave-github/lib/enhanced-github-sync.js +0 -249
  238. package/dist/plugins/specweave-github/lib/enhanced-github-sync.js.map +0 -1
  239. package/dist/plugins/specweave-jira/lib/enhanced-jira-sync.d.ts +0 -28
  240. package/dist/plugins/specweave-jira/lib/enhanced-jira-sync.d.ts.map +0 -1
  241. package/dist/plugins/specweave-jira/lib/enhanced-jira-sync.js +0 -156
  242. package/dist/plugins/specweave-jira/lib/enhanced-jira-sync.js.map +0 -1
  243. package/dist/src/core/sync/bidirectional-engine.d.ts +0 -119
  244. package/dist/src/core/sync/bidirectional-engine.d.ts.map +0 -1
  245. package/dist/src/core/sync/bidirectional-engine.js +0 -359
  246. package/dist/src/core/sync/bidirectional-engine.js.map +0 -1
  247. package/dist/src/core/sync/conflict-resolver.d.ts +0 -66
  248. package/dist/src/core/sync/conflict-resolver.d.ts.map +0 -1
  249. package/dist/src/core/sync/conflict-resolver.js +0 -108
  250. package/dist/src/core/sync/conflict-resolver.js.map +0 -1
  251. package/dist/src/core/sync/enhanced-content-builder.d.ts +0 -55
  252. package/dist/src/core/sync/enhanced-content-builder.d.ts.map +0 -1
  253. package/dist/src/core/sync/enhanced-content-builder.js +0 -203
  254. package/dist/src/core/sync/enhanced-content-builder.js.map +0 -1
  255. package/dist/src/core/sync/folder-mapper.d.ts +0 -71
  256. package/dist/src/core/sync/folder-mapper.d.ts.map +0 -1
  257. package/dist/src/core/sync/folder-mapper.js +0 -203
  258. package/dist/src/core/sync/folder-mapper.js.map +0 -1
  259. package/dist/src/core/sync/label-detector.d.ts +0 -66
  260. package/dist/src/core/sync/label-detector.d.ts.map +0 -1
  261. package/dist/src/core/sync/label-detector.js +0 -224
  262. package/dist/src/core/sync/label-detector.js.map +0 -1
  263. package/dist/src/core/sync/performance-optimizer.d.ts +0 -153
  264. package/dist/src/core/sync/performance-optimizer.d.ts.map +0 -1
  265. package/dist/src/core/sync/performance-optimizer.js +0 -220
  266. package/dist/src/core/sync/performance-optimizer.js.map +0 -1
  267. package/dist/src/core/sync/profile-selector.d.ts +0 -52
  268. package/dist/src/core/sync/profile-selector.d.ts.map +0 -1
  269. package/dist/src/core/sync/profile-selector.js +0 -179
  270. package/dist/src/core/sync/profile-selector.js.map +0 -1
  271. package/dist/src/core/sync/profile-validator.d.ts +0 -52
  272. package/dist/src/core/sync/profile-validator.d.ts.map +0 -1
  273. package/dist/src/core/sync/profile-validator.js +0 -170
  274. package/dist/src/core/sync/profile-validator.js.map +0 -1
  275. package/dist/src/core/sync/rate-limiter.d.ts +0 -116
  276. package/dist/src/core/sync/rate-limiter.d.ts.map +0 -1
  277. package/dist/src/core/sync/rate-limiter.js +0 -308
  278. package/dist/src/core/sync/rate-limiter.js.map +0 -1
  279. package/dist/src/core/sync/retry-handler.d.ts +0 -98
  280. package/dist/src/core/sync/retry-handler.d.ts.map +0 -1
  281. package/dist/src/core/sync/retry-handler.js +0 -196
  282. package/dist/src/core/sync/retry-handler.js.map +0 -1
  283. package/dist/src/core/sync/retry-logic.d.ts +0 -64
  284. package/dist/src/core/sync/retry-logic.d.ts.map +0 -1
  285. package/dist/src/core/sync/retry-logic.js +0 -165
  286. package/dist/src/core/sync/retry-logic.js.map +0 -1
  287. package/dist/src/core/sync/status-cache.d.ts +0 -91
  288. package/dist/src/core/sync/status-cache.d.ts.map +0 -1
  289. package/dist/src/core/sync/status-cache.js +0 -140
  290. package/dist/src/core/sync/status-cache.js.map +0 -1
  291. package/dist/src/core/sync/status-mapper.d.ts +0 -69
  292. package/dist/src/core/sync/status-mapper.d.ts.map +0 -1
  293. package/dist/src/core/sync/status-mapper.js +0 -90
  294. package/dist/src/core/sync/status-mapper.js.map +0 -1
  295. package/dist/src/core/sync/status-sync-engine.d.ts +0 -162
  296. package/dist/src/core/sync/status-sync-engine.d.ts.map +0 -1
  297. package/dist/src/core/sync/status-sync-engine.js +0 -347
  298. package/dist/src/core/sync/status-sync-engine.js.map +0 -1
  299. package/dist/src/core/sync/sync-event-logger.d.ts +0 -113
  300. package/dist/src/core/sync/sync-event-logger.d.ts.map +0 -1
  301. package/dist/src/core/sync/sync-event-logger.js +0 -141
  302. package/dist/src/core/sync/sync-event-logger.js.map +0 -1
  303. package/dist/src/core/sync/time-range-selector.d.ts +0 -48
  304. package/dist/src/core/sync/time-range-selector.d.ts.map +0 -1
  305. package/dist/src/core/sync/time-range-selector.js +0 -224
  306. package/dist/src/core/sync/time-range-selector.js.map +0 -1
  307. package/dist/src/core/sync/types.d.ts +0 -52
  308. package/dist/src/core/sync/types.d.ts.map +0 -1
  309. package/dist/src/core/sync/types.js +0 -5
  310. package/dist/src/core/sync/types.js.map +0 -1
  311. package/dist/src/core/sync/workflow-detector.d.ts +0 -95
  312. package/dist/src/core/sync/workflow-detector.d.ts.map +0 -1
  313. package/dist/src/core/sync/workflow-detector.js +0 -175
  314. package/dist/src/core/sync/workflow-detector.js.map +0 -1
  315. package/plugins/specweave-github/lib/enhanced-github-sync.js +0 -220
  316. package/plugins/specweave-github/lib/enhanced-github-sync.ts +0 -322
  317. package/plugins/specweave-jira/lib/enhanced-jira-sync.js +0 -134
  318. package/plugins/specweave-jira/lib/enhanced-jira-sync.ts +0 -196
@@ -0,0 +1,131 @@
1
+ # Sync Logs Command
2
+
3
+ Query and export sync audit logs. Supports date range, platform, and result filtering.
4
+
5
+ ## Usage
6
+
7
+ ```bash
8
+ /specweave:sync-logs # Last 24 hours
9
+ /specweave:sync-logs --since "2025-12-01" # Since specific date
10
+ /specweave:sync-logs --platform github # Filter by platform
11
+ /specweave:sync-logs --result denied # Filter by result
12
+ /specweave:sync-logs --export logs.json # Export to file
13
+ ```
14
+
15
+ ## Arguments
16
+
17
+ - `--since <date>`: Start date (ISO 8601 or YYYY-MM-DD)
18
+ - `--until <date>`: End date (ISO 8601 or YYYY-MM-DD)
19
+ - `--platform <name>`: Filter by platform: `github`, `jira`, `ado`
20
+ - `--operation <type>`: Filter by operation type
21
+ - `--result <result>`: Filter by result: `success`, `denied`, `error`
22
+ - `--limit <n>`: Maximum entries to return (default: 100)
23
+ - `--export <path>`: Export to file (JSON, JSONL, or CSV based on extension)
24
+ - `--json`: Output as JSON to stdout
25
+
26
+ ## Examples
27
+
28
+ ### View Recent Logs
29
+
30
+ ```bash
31
+ /specweave:sync-logs
32
+ ```
33
+
34
+ Output:
35
+ ```
36
+ 📋 SYNC LOGS (last 24 hours)
37
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
38
+
39
+ 2025-12-01 12:00:05 github upsert-internal FS-001 ✅ success 150ms
40
+ 2025-12-01 12:00:04 jira update-status US-001 ✅ success 200ms
41
+ 2025-12-01 12:00:03 github upsert-external EXT-001 🚫 denied -
42
+ 2025-12-01 12:00:02 ado read WI-001 ❌ error -
43
+ 2025-12-01 12:00:01 github upsert-internal FS-002 ✅ success 100ms
44
+
45
+ Showing 5 of 57 entries
46
+ Use --limit to show more, --export to save all
47
+ ```
48
+
49
+ ### Filter by Platform
50
+
51
+ ```bash
52
+ /specweave:sync-logs --platform github
53
+ ```
54
+
55
+ ### Filter by Result
56
+
57
+ ```bash
58
+ /specweave:sync-logs --result denied
59
+ ```
60
+
61
+ Shows only denied operations (permission enforcement in action):
62
+ ```
63
+ 📋 SYNC LOGS (denied only)
64
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
65
+
66
+ 2025-12-01 12:00:03 github upsert-external EXT-001 🚫 denied
67
+ Reason: External updates disabled in config
68
+
69
+ 2025-12-01 11:45:00 jira delete JIRA-123 🚫 denied
70
+ Reason: Delete operations not permitted
71
+ ```
72
+
73
+ ### Date Range Query
74
+
75
+ ```bash
76
+ /specweave:sync-logs --since "2025-12-01" --until "2025-12-02"
77
+ ```
78
+
79
+ ### Export to File
80
+
81
+ ```bash
82
+ # Export to JSON
83
+ /specweave:sync-logs --export logs.json
84
+
85
+ # Export to CSV (for spreadsheets)
86
+ /specweave:sync-logs --export logs.csv
87
+
88
+ # Export to JSONL (for processing)
89
+ /specweave:sync-logs --export logs.jsonl
90
+ ```
91
+
92
+ ## Output Formats
93
+
94
+ ### Default (Human-readable)
95
+
96
+ Tabular format with timestamps, platforms, operations, items, results, and durations.
97
+
98
+ ### JSON (`--json` or `.json` export)
99
+
100
+ ```json
101
+ {
102
+ "metadata": {
103
+ "exportedAt": "2025-12-01T12:00:00Z",
104
+ "total": 57,
105
+ "hasMore": false,
106
+ "query": { "limit": 100 }
107
+ },
108
+ "entries": [
109
+ {
110
+ "timestamp": "2025-12-01T12:00:05Z",
111
+ "platform": "github",
112
+ "operation": "upsert-internal",
113
+ "itemId": "FS-001",
114
+ "result": "success",
115
+ "durationMs": 150
116
+ }
117
+ ]
118
+ }
119
+ ```
120
+
121
+ ### CSV (`.csv` export)
122
+
123
+ ```csv
124
+ timestamp,platform,operation,itemId,result,reason,error,durationMs
125
+ 2025-12-01T12:00:05Z,github,upsert-internal,FS-001,success,,,150
126
+ ```
127
+
128
+ ## Related
129
+
130
+ - `/specweave:sync-monitor`: Dashboard with activity summary
131
+ - `/specweave:notifications`: View sync failure notifications
@@ -0,0 +1,57 @@
1
+ # Sync Monitor Dashboard
2
+
3
+ Show sync orchestration status at a glance - jobs, notifications, and recent activity.
4
+
5
+ ## Usage
6
+
7
+ ```bash
8
+ /specweave:sync-monitor # Show dashboard
9
+ /specweave:sync-monitor --json # JSON output for scripting
10
+ ```
11
+
12
+ ## Arguments
13
+
14
+ - `--json`: Output machine-readable JSON instead of formatted dashboard
15
+
16
+ ## Workflow
17
+
18
+ 1. **Fetch dashboard data** from DashboardDataProvider:
19
+ - Get all scheduled job statuses (real-time)
20
+ - Get notification summary (5s cache)
21
+ - Get last 24h sync activity (1m cache)
22
+
23
+ 2. **Display formatted dashboard**:
24
+ ```
25
+ ╔══════════════════════════════════════════════════════════════╗
26
+ ║ SYNC MONITOR DASHBOARD ║
27
+ ╠══════════════════════════════════════════════════════════════╣
28
+ ║ SCHEDULED JOBS ║
29
+ ╟──────────────────────────────────────────────────────────────╢
30
+ ║ external-sync │ ✅ idle │ Last: 5m ago │ Next: 10m ║
31
+ ║ discrepancy-check │ 🔄 running │ Started: 2m ago ║
32
+ ║ living-docs-sync │ ⏸️ disabled ║
33
+ ╠══════════════════════════════════════════════════════════════╣
34
+ ║ PENDING NOTIFICATIONS (3) ║
35
+ ╟──────────────────────────────────────────────────────────────╢
36
+ ║ ❗ CRITICAL: GitHub sync failed (rate limited) ║
37
+ ║ ⚠️ WARNING: 2 discrepancies detected in FS-045 ║
38
+ ║ ℹ️ INFO: 107 items imported from JIRA (project CORE) ║
39
+ ╠══════════════════════════════════════════════════════════════╣
40
+ ║ RECENT SYNC ACTIVITY (last 24h) ║
41
+ ╟──────────────────────────────────────────────────────────────╢
42
+ ║ GitHub: 45 synced │ JIRA: 12 synced │ ADO: 0 synced ║
43
+ ║ Success: 55 │ Failed: 2 │ Skipped (no permission): 8 ║
44
+ ╚══════════════════════════════════════════════════════════════╝
45
+ ```
46
+
47
+ ## Output
48
+
49
+ - **Jobs Section**: Shows each scheduled job with status emoji, last run, next run
50
+ - **Notifications Section**: Shows pending notification count and recent items
51
+ - **Activity Section**: Shows last 24h sync stats by platform and result
52
+
53
+ ## Related
54
+
55
+ - `/specweave:notifications`: Manage notifications
56
+ - `/specweave:discrepancies`: View and act on discrepancies
57
+ - `/specweave:sync-logs`: Query sync audit logs
@@ -5,7 +5,7 @@
5
5
  "hooks": [
6
6
  {
7
7
  "type": "command",
8
- "command": "${CLAUDE_PLUGIN_ROOT}/hooks/v2/dispatchers/session-start.sh"
8
+ "command": "node \"${CLAUDE_PLUGIN_ROOT}/hooks/universal/dispatcher.mjs\" session-start"
9
9
  }
10
10
  ]
11
11
  }
@@ -17,7 +17,7 @@
17
17
  "hooks": [
18
18
  {
19
19
  "type": "command",
20
- "command": "${CLAUDE_PLUGIN_ROOT}/hooks/v2/guards/completion-guard.sh"
20
+ "command": "node \"${CLAUDE_PLUGIN_ROOT}/hooks/universal/dispatcher.mjs\" completion-guard"
21
21
  }
22
22
  ]
23
23
  }
@@ -29,7 +29,7 @@
29
29
  "hooks": [
30
30
  {
31
31
  "type": "command",
32
- "command": "${CLAUDE_PLUGIN_ROOT}/hooks/v2/dispatchers/post-tool-use.sh"
32
+ "command": "node \"${CLAUDE_PLUGIN_ROOT}/hooks/universal/dispatcher.mjs\" post-tool-use"
33
33
  }
34
34
  ]
35
35
  }
@@ -0,0 +1,72 @@
1
+ #!/bin/bash
2
+ # scheduler-startup.sh - Check for due jobs on session start
3
+ # Called from session-start hook to initialize scheduler
4
+ set -e
5
+
6
+ # Skip if hooks disabled
7
+ [[ "${SPECWEAVE_DISABLE_HOOKS:-0}" == "1" ]] && exit 0
8
+
9
+ # Find project root
10
+ PROJECT_ROOT="$PWD"
11
+ while [[ "$PROJECT_ROOT" != "/" ]] && [[ ! -d "$PROJECT_ROOT/.specweave" ]]; do
12
+ PROJECT_ROOT=$(dirname "$PROJECT_ROOT")
13
+ done
14
+
15
+ # Exit if no .specweave directory
16
+ [[ ! -d "$PROJECT_ROOT/.specweave" ]] && exit 0
17
+
18
+ # Paths
19
+ SCHEDULED_JOBS_FILE="$PROJECT_ROOT/.specweave/state/scheduled-jobs.json"
20
+ CONFIG_FILE="$PROJECT_ROOT/.specweave/config.json"
21
+
22
+ # Check if scheduler is enabled
23
+ if [[ -f "$CONFIG_FILE" ]]; then
24
+ # Check if sync.orchestration.scheduler.enabled is true
25
+ # Use node for reliable JSON parsing
26
+ SCHEDULER_ENABLED=$(node -e "
27
+ try {
28
+ const config = require('$CONFIG_FILE');
29
+ const enabled = config?.sync?.orchestration?.scheduler?.enabled ?? false;
30
+ console.log(enabled ? 'true' : 'false');
31
+ } catch(e) {
32
+ console.log('false');
33
+ }
34
+ " 2>/dev/null || echo "false")
35
+
36
+ if [[ "$SCHEDULER_ENABLED" != "true" ]]; then
37
+ exit 0
38
+ fi
39
+ fi
40
+
41
+ # Check if scheduled jobs file exists
42
+ if [[ ! -f "$SCHEDULED_JOBS_FILE" ]]; then
43
+ exit 0
44
+ fi
45
+
46
+ # Use node to check for due jobs (robust JSON parsing)
47
+ DUE_JOBS=$(node -e "
48
+ const fs = require('fs');
49
+ try {
50
+ const data = JSON.parse(fs.readFileSync('$SCHEDULED_JOBS_FILE', 'utf-8'));
51
+ const now = Date.now();
52
+ const dueJobs = (data.jobs || []).filter(job => {
53
+ if (!job.schedule.enabled || job.status !== 'idle') return false;
54
+ if (!job.schedule.nextRun) return true;
55
+ return new Date(job.schedule.nextRun).getTime() <= now;
56
+ });
57
+ console.log(JSON.stringify(dueJobs.map(j => j.id)));
58
+ } catch(e) {
59
+ console.log('[]');
60
+ }
61
+ " 2>/dev/null || echo "[]")
62
+
63
+ # Exit if no due jobs
64
+ if [[ "$DUE_JOBS" == "[]" ]]; then
65
+ exit 0
66
+ fi
67
+
68
+ # Log due jobs (for debugging)
69
+ echo "📅 Due sync jobs: $DUE_JOBS" >> "$PROJECT_ROOT/.specweave/logs/scheduler.log" 2>/dev/null || true
70
+
71
+ # Output status (will be captured by hook system)
72
+ echo "{\"continue\": true, \"systemMessage\": \"📅 Scheduled sync jobs ready to run. Use /specweave:sync-now to execute.\"}"
@@ -0,0 +1,246 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Universal Hook Dispatcher (Cross-Platform)
4
+ *
5
+ * Routes hook calls to the appropriate TypeScript implementation.
6
+ * Works on Windows, macOS, and Linux.
7
+ *
8
+ * Usage:
9
+ * node dispatcher.mjs <hook-type>
10
+ *
11
+ * Where hook-type is one of:
12
+ * - session-start
13
+ * - post-tool-use
14
+ * - completion-guard
15
+ *
16
+ * @module hooks/universal/dispatcher
17
+ */
18
+
19
+ import { spawn } from 'child_process';
20
+ import { fileURLToPath } from 'url';
21
+ import { dirname, join, resolve } from 'path';
22
+ import { existsSync } from 'fs';
23
+
24
+ const __filename = fileURLToPath(import.meta.url);
25
+ const __dirname = dirname(__filename);
26
+
27
+ // Hook type from arguments
28
+ const hookType = process.argv[2] || 'unknown';
29
+
30
+ /**
31
+ * Find the dist/hooks directory
32
+ */
33
+ function findHooksDir() {
34
+ // Try multiple locations
35
+ const candidates = [
36
+ // Production: node_modules/specweave/dist/hooks
37
+ join(__dirname, '..', '..', '..', '..', 'node_modules', 'specweave', 'dist', 'hooks'),
38
+ // Development: project root dist/hooks
39
+ join(__dirname, '..', '..', '..', '..', 'dist', 'hooks'),
40
+ // Relative to this file
41
+ join(__dirname, '..', '..', '..', '..', 'src', 'hooks'),
42
+ ];
43
+
44
+ for (const candidate of candidates) {
45
+ const resolved = resolve(candidate);
46
+ if (existsSync(resolved)) {
47
+ return resolved;
48
+ }
49
+ }
50
+
51
+ return null;
52
+ }
53
+
54
+ /**
55
+ * Run a hook script
56
+ */
57
+ async function runHook(scriptName) {
58
+ const hooksDir = findHooksDir();
59
+ if (!hooksDir) {
60
+ // No hooks directory - just continue
61
+ console.log(JSON.stringify({ continue: true }));
62
+ return;
63
+ }
64
+
65
+ const scriptPath = join(hooksDir, scriptName);
66
+ if (!existsSync(scriptPath) && !existsSync(scriptPath + '.js')) {
67
+ console.log(JSON.stringify({ continue: true }));
68
+ return;
69
+ }
70
+
71
+ // Spawn node to run the script
72
+ const child = spawn(process.execPath, [scriptPath], {
73
+ stdio: ['inherit', 'inherit', 'inherit'],
74
+ windowsHide: true,
75
+ });
76
+
77
+ return new Promise((resolve) => {
78
+ child.on('exit', (code) => resolve(code || 0));
79
+ child.on('error', () => {
80
+ console.log(JSON.stringify({ continue: true }));
81
+ resolve(1);
82
+ });
83
+ });
84
+ }
85
+
86
+ /**
87
+ * Cached Git Bash path (computed once per session)
88
+ * undefined = not yet checked, null = checked and not found, string = path found
89
+ */
90
+ let gitBashCache = undefined;
91
+
92
+ /**
93
+ * Find Git Bash on Windows (with caching)
94
+ *
95
+ * Checks common Git for Windows installation paths.
96
+ * Caches result to avoid repeated filesystem checks.
97
+ */
98
+ function findGitBash() {
99
+ // Return cached result if available
100
+ if (gitBashCache !== undefined) {
101
+ return gitBashCache;
102
+ }
103
+
104
+ const gitBashPaths = [
105
+ // Environment variable paths with proper fallbacks
106
+ join(process.env.PROGRAMFILES || 'C:\\Program Files', 'Git', 'bin', 'bash.exe'),
107
+ join(process.env['PROGRAMFILES(X86)'] || 'C:\\Program Files (x86)', 'Git', 'bin', 'bash.exe'),
108
+ join(process.env.LOCALAPPDATA || '', 'Programs', 'Git', 'bin', 'bash.exe'),
109
+ // Hardcoded fallbacks for edge cases where env vars are missing
110
+ 'C:\\Program Files\\Git\\bin\\bash.exe',
111
+ 'C:\\Program Files (x86)\\Git\\bin\\bash.exe',
112
+ 'C:\\Git\\bin\\bash.exe',
113
+ ];
114
+
115
+ for (const p of gitBashPaths) {
116
+ if (p && existsSync(p)) {
117
+ gitBashCache = p;
118
+ return p;
119
+ }
120
+ }
121
+
122
+ gitBashCache = null;
123
+ return null;
124
+ }
125
+
126
+ /**
127
+ * Fallback to bash script if TypeScript not built
128
+ *
129
+ * @param bashScript - Name of the bash script (e.g., 'post-tool-use.sh')
130
+ * @param subdir - Subdirectory under v2 (e.g., 'dispatchers', 'guards')
131
+ */
132
+ async function fallbackToBash(bashScript, subdir = 'dispatchers') {
133
+ const isWindows = process.platform === 'win32';
134
+ const bashDir = join(__dirname, '..', 'v2', subdir);
135
+ const scriptPath = join(bashDir, bashScript);
136
+
137
+ if (!existsSync(scriptPath)) {
138
+ console.log(JSON.stringify({ continue: true }));
139
+ return;
140
+ }
141
+
142
+ if (isWindows) {
143
+ // Strategy 1: Git Bash (preferred - most common)
144
+ const bashExe = findGitBash();
145
+ if (bashExe) {
146
+ const child = spawn(bashExe, [scriptPath], {
147
+ stdio: ['inherit', 'inherit', 'inherit'],
148
+ windowsHide: true,
149
+ });
150
+ return new Promise((resolve) => {
151
+ child.on('exit', (code) => resolve(code || 0));
152
+ child.on('error', () => {
153
+ console.log(JSON.stringify({ continue: true }));
154
+ resolve(1);
155
+ });
156
+ });
157
+ }
158
+
159
+ // Strategy 2: WSL (if Git Bash not available) - FALLBACK only
160
+ const wslPath = join(process.env.SYSTEMROOT || 'C:\\Windows', 'System32', 'wsl.exe');
161
+ if (existsSync(wslPath)) {
162
+ // Convert Windows path to WSL path:
163
+ // 1. Backslashes to forward slashes: C:\path\file -> C:/path/file
164
+ // 2. Drive letter to /mnt/: C:/path/file -> /mnt/c/path/file
165
+ // NOTE: Handle BOTH uppercase and lowercase drive letters (C: and c:)
166
+ const wslScriptPath = scriptPath
167
+ .replace(/\\/g, '/')
168
+ .replace(/^([A-Za-z]):/, (_, d) => `/mnt/${d.toLowerCase()}`);
169
+ const child = spawn('wsl', ['bash', wslScriptPath], {
170
+ stdio: ['inherit', 'inherit', 'inherit'],
171
+ windowsHide: true,
172
+ });
173
+ return new Promise((resolve) => {
174
+ child.on('exit', (code) => resolve(code || 0));
175
+ child.on('error', () => {
176
+ console.log(JSON.stringify({ continue: true }));
177
+ resolve(1);
178
+ });
179
+ });
180
+ }
181
+
182
+ // Strategy 3: No bash available - output warning and continue
183
+ // Hooks should not block Claude Code operation
184
+ console.log(JSON.stringify({
185
+ continue: true,
186
+ systemMessage: 'SpecWeave hooks require Git Bash on Windows. Install from https://git-scm.com'
187
+ }));
188
+ return;
189
+ }
190
+
191
+ // POSIX (macOS, Linux) - run directly
192
+ const child = spawn('bash', [scriptPath], {
193
+ stdio: ['inherit', 'inherit', 'inherit'],
194
+ });
195
+ return new Promise((resolve) => {
196
+ child.on('exit', (code) => resolve(code || 0));
197
+ child.on('error', () => {
198
+ console.log(JSON.stringify({ continue: true }));
199
+ resolve(1);
200
+ });
201
+ });
202
+ }
203
+
204
+ // Main routing
205
+ async function main() {
206
+ const isWindows = process.platform === 'win32';
207
+
208
+ try {
209
+ switch (hookType) {
210
+ case 'session-start':
211
+ // CRITICAL: On Windows, ALWAYS use TypeScript implementation
212
+ // Bash nohup/disown is unreliable in Git Bash (process may terminate early)
213
+ // TypeScript uses proper Windows detached spawn with windowsHide
214
+ if (isWindows) {
215
+ await runHook('session-start.js');
216
+ } else {
217
+ // POSIX: try TypeScript first (preferred), fallback to bash for compatibility
218
+ try {
219
+ await runHook('session-start.js');
220
+ } catch {
221
+ await fallbackToBash('session-start.sh', 'dispatchers');
222
+ }
223
+ }
224
+ break;
225
+
226
+ case 'post-tool-use':
227
+ // Currently only bash implementation
228
+ // On Windows without Git Bash, will gracefully skip
229
+ await fallbackToBash('post-tool-use.sh', 'dispatchers');
230
+ break;
231
+
232
+ case 'completion-guard':
233
+ // Guards are in a different subdirectory
234
+ // On Windows without Git Bash, will gracefully skip
235
+ await fallbackToBash('completion-guard.sh', 'guards');
236
+ break;
237
+
238
+ default:
239
+ console.log(JSON.stringify({ continue: true, error: `Unknown hook type: ${hookType}` }));
240
+ }
241
+ } catch (err) {
242
+ console.log(JSON.stringify({ continue: true, error: String(err) }));
243
+ }
244
+ }
245
+
246
+ main();
@@ -0,0 +1,16 @@
1
+ @echo off
2
+ :: Universal Session Start Hook for Windows
3
+ :: Calls the Node.js dispatcher
4
+
5
+ :: Find node.exe
6
+ where node >nul 2>&1
7
+ if %ERRORLEVEL% neq 0 (
8
+ echo {"continue": true, "error": "Node.js not found"}
9
+ exit /b 0
10
+ )
11
+
12
+ :: Get the directory of this script
13
+ set "SCRIPT_DIR=%~dp0"
14
+
15
+ :: Run the dispatcher
16
+ node "%SCRIPT_DIR%dispatcher.mjs" session-start
@@ -0,0 +1,16 @@
1
+ # Universal Session Start Hook for Windows PowerShell
2
+ # Calls the Node.js dispatcher for cross-platform compatibility
3
+
4
+ # Find node.exe
5
+ $nodePath = Get-Command node -ErrorAction SilentlyContinue
6
+
7
+ if (-not $nodePath) {
8
+ Write-Host '{"continue": true, "error": "Node.js not found"}'
9
+ exit 0
10
+ }
11
+
12
+ # Get script directory
13
+ $scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
14
+
15
+ # Run the dispatcher
16
+ & node "$scriptDir\dispatcher.mjs" session-start
@@ -15,10 +15,19 @@ done
15
15
  # Consume stdin
16
16
  cat > /dev/null
17
17
 
18
- PROCESSOR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../queue" && pwd)/processor.sh"
19
- [[ ! -f "$PROCESSOR" ]] && exit 0
18
+ HOOK_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
19
+ PROCESSOR="$HOOK_DIR/../queue/processor.sh"
20
+ SCHEDULER_STARTUP="$HOOK_DIR/../../lib/scheduler-startup.sh"
21
+
22
+ # Launch queue processor in background (daemon mode)
23
+ if [[ -f "$PROCESSOR" ]]; then
24
+ nohup bash "$PROCESSOR" --daemon > /dev/null 2>&1 &
25
+ disown 2>/dev/null
26
+ fi
27
+
28
+ # Check for due scheduled jobs (non-blocking)
29
+ if [[ -f "$SCHEDULER_STARTUP" ]]; then
30
+ bash "$SCHEDULER_STARTUP" 2>/dev/null || true
31
+ fi
20
32
 
21
- # Launch processor in background (daemon mode)
22
- nohup bash "$PROCESSOR" --daemon > /dev/null 2>&1 &
23
- disown 2>/dev/null
24
33
  exit 0
@@ -247,6 +247,11 @@ export interface ExternalContainerContext {
247
247
  }
248
248
  /**
249
249
  * Extended increment metadata with multi-project support (v0.29.0+)
250
+ *
251
+ * NOTE (v0.29.0): featureId field was REMOVED
252
+ * Feature ID is derived from increment number: 0081 → FS-081
253
+ * Use deriveFeatureId() from src/utils/feature-id-derivation.ts
254
+ * See ADR-0140 for rationale
250
255
  */
251
256
  export interface IncrementMetadataV2 extends IncrementMetadata {
252
257
  /** Single project ID (backward compatible) */
@@ -255,8 +260,6 @@ export interface IncrementMetadataV2 extends IncrementMetadata {
255
260
  multiProject?: MultiProjectUserStory;
256
261
  /** External container context for 2-level directory structure */
257
262
  externalContainer?: ExternalContainerContext;
258
- /** Feature ID this increment belongs to */
259
- featureId?: string;
260
263
  /** Epic ID if part of an epic */
261
264
  epicId?: string;
262
265
  }