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
@@ -1,220 +0,0 @@
1
- import { GitHubClientV2 } from "./github-client-v2.js";
2
- import { EnhancedContentBuilder } from "../../../src/core/sync/enhanced-content-builder.js";
3
- import { SpecIncrementMapper } from "../../../src/core/sync/spec-increment-mapper.js";
4
- import { parseSpecContent } from "../../../src/core/spec-content-sync.js";
5
- import { LabelDetector } from "../../../src/core/sync/label-detector.js";
6
- import path from "path";
7
- import fs from "fs/promises";
8
- async function syncSpecWithEnhancedContent(options) {
9
- const { specPath, owner, repo, dryRun = false, verbose = false } = options;
10
- try {
11
- const baseSpec = await parseSpecContent(specPath);
12
- if (!baseSpec) {
13
- return {
14
- success: false,
15
- action: "error",
16
- error: "Failed to parse spec content"
17
- };
18
- }
19
- if (verbose) {
20
- console.log(`\u{1F4C4} Parsed spec: ${baseSpec.identifier.compact}`);
21
- }
22
- const specId = baseSpec.identifier.full || baseSpec.identifier.compact;
23
- const rootDir = await findSpecWeaveRoot(specPath);
24
- const mapper = new SpecIncrementMapper(rootDir);
25
- const mapping = await mapper.mapSpecToIncrements(specId);
26
- if (verbose) {
27
- console.log(`\u{1F517} Found ${mapping.increments.length} related increments`);
28
- console.log(`\u{1F4CB} Mapped ${Object.keys(mapping.userStoryMappings).length} user stories to tasks`);
29
- }
30
- const taskMapping = buildTaskMapping(mapping.increments, owner, repo);
31
- const architectureDocs = await findArchitectureDocs(rootDir, specId);
32
- const sourceLinks = buildSourceLinks(mapping.increments[0]?.id, owner, repo);
33
- const enhancedSpec = {
34
- ...baseSpec,
35
- summary: baseSpec.description,
36
- taskMapping,
37
- architectureDocs,
38
- sourceLinks
39
- };
40
- const builder = new EnhancedContentBuilder();
41
- const originalBuildExternal = builder.buildExternalDescription.bind(builder);
42
- const description = (() => {
43
- const sections = [];
44
- sections.push(builder.buildSummarySection(enhancedSpec));
45
- if (enhancedSpec.userStories && enhancedSpec.userStories.length > 0) {
46
- sections.push(builder.buildUserStoriesSection(enhancedSpec.userStories));
47
- }
48
- if (enhancedSpec.taskMapping) {
49
- sections.push(builder.buildTasksSection(enhancedSpec.taskMapping, {
50
- showCheckboxes: true,
51
- showProgressBar: true,
52
- showCompletionStatus: true,
53
- provider: "github"
54
- }));
55
- }
56
- if (enhancedSpec.architectureDocs && enhancedSpec.architectureDocs.length > 0) {
57
- sections.push(builder.buildArchitectureSection(enhancedSpec.architectureDocs));
58
- }
59
- if (enhancedSpec.sourceLinks) {
60
- sections.push(builder.buildSourceLinksSection(enhancedSpec.sourceLinks));
61
- }
62
- return sections.filter((s) => s.length > 0).join("\n\n---\n\n");
63
- })();
64
- if (verbose) {
65
- console.log(`\u{1F4DD} Generated description: ${description.length} characters`);
66
- }
67
- if (dryRun) {
68
- console.log("\u{1F50D} DRY RUN - Would create/update issue with:");
69
- console.log(` Title: ${baseSpec.title}`);
70
- console.log(` Description length: ${description.length}`);
71
- console.log(` Tasks linked: ${taskMapping?.tasks.length || 0}`);
72
- return {
73
- success: true,
74
- action: "no-change",
75
- tasksLinked: taskMapping?.tasks.length || 0
76
- };
77
- }
78
- if (!owner || !repo) {
79
- return {
80
- success: false,
81
- action: "error",
82
- error: "GitHub owner/repo not specified"
83
- };
84
- }
85
- const client = GitHubClientV2.fromRepo(owner, repo);
86
- const labelDetector = new LabelDetector(void 0, false);
87
- const detection = labelDetector.detectType(
88
- await fs.readFile(specPath, "utf-8"),
89
- mapping.increments[0]?.id
90
- );
91
- const githubLabels = labelDetector.getGitHubLabels(detection.type);
92
- const allLabels = ["spec", ...githubLabels];
93
- if (verbose) {
94
- console.log(`\u{1F3F7}\uFE0F Detected type: ${detection.type} (${detection.confidence}% confidence)`);
95
- console.log(` Labels: ${allLabels.join(", ")}`);
96
- }
97
- const existingIssue = await findExistingIssue(client, baseSpec.identifier.compact);
98
- let result;
99
- if (existingIssue) {
100
- await client.updateIssueBody(existingIssue.number, description);
101
- await client.addLabels(existingIssue.number, allLabels);
102
- result = {
103
- success: true,
104
- action: "updated",
105
- issueNumber: existingIssue.number,
106
- issueUrl: existingIssue.html_url,
107
- tasksLinked: taskMapping?.tasks.length || 0
108
- };
109
- } else {
110
- const issue = await client.createEpicIssue(
111
- `[${baseSpec.project === "_features" ? baseSpec.identifier.display : baseSpec.identifier.compact}] ${baseSpec.title}`,
112
- description,
113
- void 0,
114
- allLabels
115
- // Apply labels at creation
116
- );
117
- result = {
118
- success: true,
119
- action: "created",
120
- issueNumber: issue.number,
121
- issueUrl: issue.html_url,
122
- tasksLinked: taskMapping?.tasks.length || 0
123
- };
124
- await mapper.updateSpecWithIncrementLinks(specId, mapping.increments[0]?.id);
125
- }
126
- if (verbose) {
127
- console.log(`\u2705 ${result.action === "created" ? "Created" : "Updated"} issue #${result.issueNumber}`);
128
- console.log(` URL: ${result.issueUrl}`);
129
- console.log(` Tasks linked: ${result.tasksLinked}`);
130
- }
131
- return result;
132
- } catch (error) {
133
- return {
134
- success: false,
135
- action: "error",
136
- error: error.message
137
- };
138
- }
139
- }
140
- async function findSpecWeaveRoot(specPath) {
141
- let currentDir = path.dirname(specPath);
142
- while (true) {
143
- const specweaveDir = path.join(currentDir, ".specweave");
144
- try {
145
- await fs.access(specweaveDir);
146
- return currentDir;
147
- } catch {
148
- const parentDir = path.dirname(currentDir);
149
- if (parentDir === currentDir) {
150
- throw new Error(".specweave directory not found");
151
- }
152
- currentDir = parentDir;
153
- }
154
- }
155
- }
156
- function buildTaskMapping(increments, owner, repo) {
157
- if (increments.length === 0) return void 0;
158
- const firstIncrement = increments[0];
159
- const tasks = firstIncrement.tasks.map((task) => ({
160
- id: task.id,
161
- title: task.title,
162
- userStories: task.userStories,
163
- githubIssue: task.githubIssue
164
- }));
165
- return {
166
- incrementId: firstIncrement.id,
167
- tasks,
168
- tasksUrl: `https://github.com/${owner}/${repo}/blob/develop/.specweave/increments/${firstIncrement.id}/tasks.md`
169
- };
170
- }
171
- async function findArchitectureDocs(rootDir, specId) {
172
- const docs = [];
173
- const archDir = path.join(rootDir, ".specweave/docs/internal/architecture");
174
- try {
175
- const adrDir = path.join(archDir, "adr");
176
- try {
177
- const adrs = await fs.readdir(adrDir);
178
- const relatedAdrs = adrs.filter((file) => file.includes(specId.replace("spec-", "")));
179
- for (const adr of relatedAdrs) {
180
- docs.push({
181
- type: "adr",
182
- path: path.join(adrDir, adr),
183
- title: adr.replace(".md", "").replace(/-/g, " ")
184
- });
185
- }
186
- } catch {
187
- }
188
- const hlds = await fs.readdir(archDir);
189
- const relatedHlds = hlds.filter((file) => file.includes("hld") && file.includes(specId.replace("spec-", "")));
190
- for (const hld of relatedHlds) {
191
- docs.push({
192
- type: "hld",
193
- path: path.join(archDir, hld),
194
- title: hld.replace(".md", "").replace(/-/g, " ")
195
- });
196
- }
197
- } catch {
198
- }
199
- return docs;
200
- }
201
- function buildSourceLinks(incrementId, owner, repo) {
202
- if (!incrementId) return void 0;
203
- const baseUrl = `https://github.com/${owner}/${repo}/blob/develop/.specweave`;
204
- return {
205
- spec: `${baseUrl}/docs/internal/specs/default/spec-${incrementId.replace(/^\d+-/, "")}.md`,
206
- plan: `${baseUrl}/increments/${incrementId}/plan.md`,
207
- tasks: `${baseUrl}/increments/${incrementId}/tasks.md`
208
- };
209
- }
210
- async function findExistingIssue(client, specId) {
211
- try {
212
- const issues = await client.listIssuesInTimeRange("ALL");
213
- return issues.find((issue) => issue.title.includes(`[${specId}]`) && issue.labels?.some((l) => l.name === "spec")) || null;
214
- } catch {
215
- return null;
216
- }
217
- }
218
- export {
219
- syncSpecWithEnhancedContent
220
- };
@@ -1,322 +0,0 @@
1
- /**
2
- * Enhanced GitHub Spec Content Sync
3
- *
4
- * Uses EnhancedContentBuilder and SpecIncrementMapper for rich external descriptions.
5
- * NEW (v0.21.0): Supports task checkboxes and automatic labeling.
6
- */
7
-
8
- import { GitHubClientV2 } from './github-client-v2.js';
9
- import { EnhancedContentBuilder, EnhancedSpecContent } from '../../../src/core/sync/enhanced-content-builder.js';
10
- import { SpecIncrementMapper, TaskInfo } from '../../../src/core/sync/spec-increment-mapper.js';
11
- import { parseSpecContent, SpecContent } from '../../../src/core/spec-content-sync.js';
12
- import { LabelDetector } from '../../../src/core/sync/label-detector.js';
13
- import path from 'path';
14
- import fs from 'fs/promises';
15
-
16
- export interface EnhancedGitHubSyncOptions {
17
- specPath: string;
18
- owner?: string;
19
- repo?: string;
20
- dryRun?: boolean;
21
- verbose?: boolean;
22
- }
23
-
24
- export interface EnhancedSyncResult {
25
- success: boolean;
26
- action: 'created' | 'updated' | 'no-change' | 'error';
27
- issueNumber?: number;
28
- issueUrl?: string;
29
- error?: string;
30
- tasksLinked?: number;
31
- }
32
-
33
- /**
34
- * Enhanced sync with rich content including task mappings
35
- */
36
- export async function syncSpecWithEnhancedContent(
37
- options: EnhancedGitHubSyncOptions
38
- ): Promise<EnhancedSyncResult> {
39
- const { specPath, owner, repo, dryRun = false, verbose = false } = options;
40
-
41
- try {
42
- // 1. Parse spec content
43
- const baseSpec = await parseSpecContent(specPath);
44
- if (!baseSpec) {
45
- return {
46
- success: false,
47
- action: 'error',
48
- error: 'Failed to parse spec content',
49
- };
50
- }
51
-
52
- if (verbose) {
53
- console.log(`📄 Parsed spec: ${baseSpec.identifier.compact}`);
54
- }
55
-
56
- // 2. Build enhanced spec with task mappings
57
- const specId = baseSpec.identifier.full || baseSpec.identifier.compact;
58
- const rootDir = await findSpecWeaveRoot(specPath);
59
- const mapper = new SpecIncrementMapper(rootDir);
60
- const mapping = await mapper.mapSpecToIncrements(specId);
61
-
62
- if (verbose) {
63
- console.log(`🔗 Found ${mapping.increments.length} related increments`);
64
- console.log(`📋 Mapped ${Object.keys(mapping.userStoryMappings).length} user stories to tasks`);
65
- }
66
-
67
- // 3. Build task mapping for EnhancedSpecContent
68
- const taskMapping = buildTaskMapping(mapping.increments, owner!, repo!);
69
-
70
- // 4. Build architecture docs references
71
- const architectureDocs = await findArchitectureDocs(rootDir, specId);
72
-
73
- // 5. Build source links
74
- const sourceLinks = buildSourceLinks(mapping.increments[0]?.id, owner!, repo!);
75
-
76
- // 6. Create enhanced spec content
77
- const enhancedSpec: EnhancedSpecContent = {
78
- ...baseSpec,
79
- summary: baseSpec.description,
80
- taskMapping,
81
- architectureDocs,
82
- sourceLinks
83
- };
84
-
85
- // 7. Build external description with task checkboxes
86
- const builder = new EnhancedContentBuilder();
87
-
88
- // NEW: Override buildTasksSection call to include checkboxes
89
- const originalBuildExternal = builder.buildExternalDescription.bind(builder);
90
- const description = (() => {
91
- const sections: string[] = [];
92
-
93
- // Summary
94
- sections.push(builder.buildSummarySection(enhancedSpec));
95
-
96
- // User stories
97
- if (enhancedSpec.userStories && enhancedSpec.userStories.length > 0) {
98
- sections.push(builder.buildUserStoriesSection(enhancedSpec.userStories));
99
- }
100
-
101
- // Tasks with checkboxes (NEW!)
102
- if (enhancedSpec.taskMapping) {
103
- sections.push(builder.buildTasksSection(enhancedSpec.taskMapping, {
104
- showCheckboxes: true,
105
- showProgressBar: true,
106
- showCompletionStatus: true,
107
- provider: 'github'
108
- }));
109
- }
110
-
111
- // Architecture
112
- if (enhancedSpec.architectureDocs && enhancedSpec.architectureDocs.length > 0) {
113
- sections.push(builder.buildArchitectureSection(enhancedSpec.architectureDocs));
114
- }
115
-
116
- // Source links
117
- if (enhancedSpec.sourceLinks) {
118
- sections.push(builder.buildSourceLinksSection(enhancedSpec.sourceLinks));
119
- }
120
-
121
- return sections.filter(s => s.length > 0).join('\n\n---\n\n');
122
- })();
123
-
124
- if (verbose) {
125
- console.log(`📝 Generated description: ${description.length} characters`);
126
- }
127
-
128
- if (dryRun) {
129
- console.log('🔍 DRY RUN - Would create/update issue with:');
130
- console.log(` Title: ${baseSpec.title}`);
131
- console.log(` Description length: ${description.length}`);
132
- console.log(` Tasks linked: ${taskMapping?.tasks.length || 0}`);
133
- return {
134
- success: true,
135
- action: 'no-change',
136
- tasksLinked: taskMapping?.tasks.length || 0
137
- };
138
- }
139
-
140
- // 8. Create or update GitHub issue
141
- if (!owner || !repo) {
142
- return {
143
- success: false,
144
- action: 'error',
145
- error: 'GitHub owner/repo not specified',
146
- };
147
- }
148
-
149
- const client = GitHubClientV2.fromRepo(owner, repo);
150
-
151
- // NEW: Detect increment type and apply labels
152
- const labelDetector = new LabelDetector(undefined, false); // Use GitHub format
153
- const detection = labelDetector.detectType(
154
- await fs.readFile(specPath, 'utf-8'),
155
- mapping.increments[0]?.id
156
- );
157
- const githubLabels = labelDetector.getGitHubLabels(detection.type);
158
- const allLabels = ['spec', ...githubLabels]; // Include both 'spec' and type labels
159
-
160
- if (verbose) {
161
- console.log(`🏷️ Detected type: ${detection.type} (${detection.confidence}% confidence)`);
162
- console.log(` Labels: ${allLabels.join(', ')}`);
163
- }
164
-
165
- // Check if issue already exists
166
- const existingIssue = await findExistingIssue(client, baseSpec.identifier.compact);
167
-
168
- let result: EnhancedSyncResult;
169
-
170
- if (existingIssue) {
171
- // Update existing issue (body + labels)
172
- await client.updateIssueBody(existingIssue.number, description);
173
-
174
- // Update labels if autoApplyLabels is enabled
175
- // TODO: Read from config, for now always apply
176
- await client.addLabels(existingIssue.number, allLabels);
177
-
178
- result = {
179
- success: true,
180
- action: 'updated',
181
- issueNumber: existingIssue.number,
182
- issueUrl: existingIssue.html_url,
183
- tasksLinked: taskMapping?.tasks.length || 0
184
- };
185
- } else {
186
- // Create new issue with labels
187
- const issue = await client.createEpicIssue(
188
- `[${baseSpec.project === '_features' ? baseSpec.identifier.display : baseSpec.identifier.compact}] ${baseSpec.title}`,
189
- description,
190
- undefined,
191
- allLabels // Apply labels at creation
192
- );
193
-
194
- result = {
195
- success: true,
196
- action: 'created',
197
- issueNumber: issue.number,
198
- issueUrl: issue.html_url,
199
- tasksLinked: taskMapping?.tasks.length || 0
200
- };
201
-
202
- // Update spec with GitHub link
203
- await mapper.updateSpecWithIncrementLinks(specId, mapping.increments[0]?.id);
204
- }
205
-
206
- if (verbose) {
207
- console.log(`✅ ${result.action === 'created' ? 'Created' : 'Updated'} issue #${result.issueNumber}`);
208
- console.log(` URL: ${result.issueUrl}`);
209
- console.log(` Tasks linked: ${result.tasksLinked}`);
210
- }
211
-
212
- return result;
213
- } catch (error: any) {
214
- return {
215
- success: false,
216
- action: 'error',
217
- error: error.message
218
- };
219
- }
220
- }
221
-
222
- // Helper functions
223
-
224
- async function findSpecWeaveRoot(specPath: string): Promise<string> {
225
- let currentDir = path.dirname(specPath);
226
-
227
- while (true) {
228
- const specweaveDir = path.join(currentDir, '.specweave');
229
- try {
230
- await fs.access(specweaveDir);
231
- return currentDir;
232
- } catch {
233
- const parentDir = path.dirname(currentDir);
234
- if (parentDir === currentDir) {
235
- throw new Error('.specweave directory not found');
236
- }
237
- currentDir = parentDir;
238
- }
239
- }
240
- }
241
-
242
- function buildTaskMapping(
243
- increments: any[],
244
- owner: string,
245
- repo: string
246
- ): any {
247
- if (increments.length === 0) return undefined;
248
-
249
- const firstIncrement = increments[0];
250
- const tasks = firstIncrement.tasks.map((task: TaskInfo) => ({
251
- id: task.id,
252
- title: task.title,
253
- userStories: task.userStories,
254
- githubIssue: task.githubIssue
255
- }));
256
-
257
- return {
258
- incrementId: firstIncrement.id,
259
- tasks,
260
- tasksUrl: `https://github.com/${owner}/${repo}/blob/develop/.specweave/increments/${firstIncrement.id}/tasks.md`
261
- };
262
- }
263
-
264
- async function findArchitectureDocs(
265
- rootDir: string,
266
- specId: string
267
- ): Promise<any[]> {
268
- const docs: any[] = [];
269
- const archDir = path.join(rootDir, '.specweave/docs/internal/architecture');
270
-
271
- try {
272
- // Check for ADRs
273
- const adrDir = path.join(archDir, 'adr');
274
- try {
275
- const adrs = await fs.readdir(adrDir);
276
- const relatedAdrs = adrs.filter(file => file.includes(specId.replace('spec-', '')));
277
-
278
- for (const adr of relatedAdrs) {
279
- docs.push({
280
- type: 'adr',
281
- path: path.join(adrDir, adr),
282
- title: adr.replace('.md', '').replace(/-/g, ' ')
283
- });
284
- }
285
- } catch {}
286
-
287
- // Check for HLD
288
- const hlds = await fs.readdir(archDir);
289
- const relatedHlds = hlds.filter(file => file.includes('hld') && file.includes(specId.replace('spec-', '')));
290
-
291
- for (const hld of relatedHlds) {
292
- docs.push({
293
- type: 'hld',
294
- path: path.join(archDir, hld),
295
- title: hld.replace('.md', '').replace(/-/g, ' ')
296
- });
297
- }
298
- } catch {}
299
-
300
- return docs;
301
- }
302
-
303
- function buildSourceLinks(incrementId: string | undefined, owner: string, repo: string): any {
304
- if (!incrementId) return undefined;
305
-
306
- const baseUrl = `https://github.com/${owner}/${repo}/blob/develop/.specweave`;
307
-
308
- return {
309
- spec: `${baseUrl}/docs/internal/specs/default/spec-${incrementId.replace(/^\d+-/, '')}.md`,
310
- plan: `${baseUrl}/increments/${incrementId}/plan.md`,
311
- tasks: `${baseUrl}/increments/${incrementId}/tasks.md`
312
- };
313
- }
314
-
315
- async function findExistingIssue(client: GitHubClientV2, specId: string): Promise<any | null> {
316
- try {
317
- const issues = await client.listIssuesInTimeRange('ALL');
318
- return issues.find((issue: any) => issue.title.includes(`[${specId}]`) && issue.labels?.some((l: any) => l.name === 'spec')) || null;
319
- } catch {
320
- return null;
321
- }
322
- }
@@ -1,134 +0,0 @@
1
- import { EnhancedContentBuilder } from "../../../src/core/sync/enhanced-content-builder.js";
2
- import { SpecIncrementMapper } from "../../../src/core/sync/spec-increment-mapper.js";
3
- import { parseSpecContent } from "../../../src/core/spec-content-sync.js";
4
- import * as path from "path";
5
- import * as fs from "fs/promises";
6
- async function syncSpecToJiraWithEnhancedContent(options) {
7
- const { specPath, domain, project, dryRun = false, verbose = false } = options;
8
- try {
9
- const baseSpec = await parseSpecContent(specPath);
10
- if (!baseSpec) {
11
- return {
12
- success: false,
13
- action: "error",
14
- error: "Failed to parse spec content"
15
- };
16
- }
17
- if (verbose) {
18
- console.log(`\u{1F4C4} Parsed spec: ${baseSpec.identifier.compact}`);
19
- }
20
- const specId = baseSpec.identifier.full || baseSpec.identifier.compact;
21
- const rootDir = await findSpecWeaveRoot(specPath);
22
- const mapper = new SpecIncrementMapper(rootDir);
23
- const mapping = await mapper.mapSpecToIncrements(specId);
24
- if (verbose) {
25
- console.log(`\u{1F517} Found ${mapping.increments.length} related increments`);
26
- }
27
- const taskMapping = buildTaskMapping(mapping.increments);
28
- const architectureDocs = await findArchitectureDocs(rootDir, specId);
29
- const enhancedSpec = {
30
- ...baseSpec,
31
- summary: baseSpec.description,
32
- taskMapping,
33
- architectureDocs
34
- };
35
- const builder = new EnhancedContentBuilder();
36
- const description = builder.buildExternalDescription(enhancedSpec);
37
- if (verbose) {
38
- console.log(`\u{1F4DD} Generated description: ${description.length} characters`);
39
- }
40
- if (dryRun) {
41
- console.log("\u{1F50D} DRY RUN - Would create/update epic with:");
42
- console.log(` Summary: ${baseSpec.title}`);
43
- console.log(` Description length: ${description.length}`);
44
- return {
45
- success: true,
46
- action: "no-change",
47
- tasksLinked: taskMapping?.tasks.length || 0
48
- };
49
- }
50
- if (!dryRun && (!domain || !project)) {
51
- return {
52
- success: false,
53
- action: "error",
54
- error: "JIRA domain/project not specified (required for actual sync)"
55
- };
56
- }
57
- const result = {
58
- success: true,
59
- action: dryRun ? "no-change" : "created",
60
- // Assume create if not dry run
61
- tasksLinked: taskMapping?.tasks.length || 0
62
- };
63
- if (domain && project && !dryRun) {
64
- result.epicKey = `SPEC-001`;
65
- result.epicUrl = `https://${domain}/browse/SPEC-001`;
66
- if (verbose) {
67
- console.log(`\u26A0\uFE0F JIRA API integration not implemented in this file`);
68
- console.log(` Use jira-spec-sync.ts for actual JIRA synchronization`);
69
- }
70
- }
71
- return result;
72
- } catch (error) {
73
- return {
74
- success: false,
75
- action: "error",
76
- error: error.message
77
- };
78
- }
79
- }
80
- async function findSpecWeaveRoot(specPath) {
81
- let currentDir = path.dirname(specPath);
82
- while (true) {
83
- const specweaveDir = path.join(currentDir, ".specweave");
84
- try {
85
- await fs.access(specweaveDir);
86
- return currentDir;
87
- } catch {
88
- const parentDir = path.dirname(currentDir);
89
- if (parentDir === currentDir) {
90
- throw new Error(".specweave directory not found");
91
- }
92
- currentDir = parentDir;
93
- }
94
- }
95
- }
96
- function buildTaskMapping(increments) {
97
- if (increments.length === 0) return void 0;
98
- const firstIncrement = increments[0];
99
- const tasks = firstIncrement.tasks.map((task) => ({
100
- id: task.id,
101
- title: task.title,
102
- userStories: task.userStories
103
- }));
104
- return {
105
- incrementId: firstIncrement.id,
106
- tasks,
107
- tasksUrl: `tasks.md`
108
- // JIRA doesn't support external links in same way
109
- };
110
- }
111
- async function findArchitectureDocs(rootDir, specId) {
112
- const docs = [];
113
- const archDir = path.join(rootDir, ".specweave/docs/internal/architecture");
114
- try {
115
- const adrDir = path.join(archDir, "adr");
116
- try {
117
- const adrs = await fs.readdir(adrDir);
118
- const relatedAdrs = adrs.filter((file) => file.includes(specId.replace("spec-", "")));
119
- for (const adr of relatedAdrs) {
120
- docs.push({
121
- type: "adr",
122
- path: path.join(adrDir, adr),
123
- title: adr.replace(".md", "").replace(/-/g, " ")
124
- });
125
- }
126
- } catch {
127
- }
128
- } catch {
129
- }
130
- return docs;
131
- }
132
- export {
133
- syncSpecToJiraWithEnhancedContent
134
- };