specweave 0.29.2 → 0.30.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 (366) hide show
  1. package/README.md +65 -16
  2. package/bin/specweave.js +16 -0
  3. package/dist/plugins/specweave-ado/lib/ado-spec-commit-sync.d.ts +1 -1
  4. package/dist/plugins/specweave-ado/lib/ado-spec-commit-sync.d.ts.map +1 -1
  5. package/dist/plugins/specweave-ado/lib/ado-spec-commit-sync.js +1 -1
  6. package/dist/plugins/specweave-ado/lib/ado-spec-commit-sync.js.map +1 -1
  7. package/dist/plugins/specweave-ado/lib/ado-spec-content-sync.d.ts +1 -1
  8. package/dist/plugins/specweave-ado/lib/ado-spec-content-sync.d.ts.map +1 -1
  9. package/dist/plugins/specweave-ado/lib/ado-spec-content-sync.js +1 -1
  10. package/dist/plugins/specweave-ado/lib/ado-spec-content-sync.js.map +1 -1
  11. package/dist/plugins/specweave-ado/lib/conflict-resolver.d.ts +134 -0
  12. package/dist/plugins/specweave-ado/lib/conflict-resolver.d.ts.map +1 -0
  13. package/dist/plugins/specweave-ado/lib/conflict-resolver.js +423 -0
  14. package/dist/plugins/specweave-ado/lib/conflict-resolver.js.map +1 -0
  15. package/dist/plugins/specweave-github/lib/github-client-v2.d.ts +23 -1
  16. package/dist/plugins/specweave-github/lib/github-client-v2.d.ts.map +1 -1
  17. package/dist/plugins/specweave-github/lib/github-client-v2.js +95 -0
  18. package/dist/plugins/specweave-github/lib/github-client-v2.js.map +1 -1
  19. package/dist/plugins/specweave-github/lib/github-spec-commit-sync.d.ts +1 -1
  20. package/dist/plugins/specweave-github/lib/github-spec-commit-sync.d.ts.map +1 -1
  21. package/dist/plugins/specweave-github/lib/github-spec-commit-sync.js +1 -1
  22. package/dist/plugins/specweave-github/lib/github-spec-commit-sync.js.map +1 -1
  23. package/dist/plugins/specweave-github/lib/github-spec-content-sync.d.ts +1 -1
  24. package/dist/plugins/specweave-github/lib/github-spec-content-sync.d.ts.map +1 -1
  25. package/dist/plugins/specweave-github/lib/github-spec-content-sync.js +1 -1
  26. package/dist/plugins/specweave-github/lib/github-spec-content-sync.js.map +1 -1
  27. package/dist/plugins/specweave-github/lib/types.d.ts +20 -0
  28. package/dist/plugins/specweave-github/lib/types.d.ts.map +1 -1
  29. package/dist/plugins/specweave-jira/lib/jira-spec-commit-sync.d.ts +1 -1
  30. package/dist/plugins/specweave-jira/lib/jira-spec-commit-sync.d.ts.map +1 -1
  31. package/dist/plugins/specweave-jira/lib/jira-spec-commit-sync.js +1 -1
  32. package/dist/plugins/specweave-jira/lib/jira-spec-commit-sync.js.map +1 -1
  33. package/dist/plugins/specweave-jira/lib/jira-spec-content-sync.d.ts +1 -1
  34. package/dist/plugins/specweave-jira/lib/jira-spec-content-sync.d.ts.map +1 -1
  35. package/dist/plugins/specweave-jira/lib/jira-spec-content-sync.js +1 -1
  36. package/dist/plugins/specweave-jira/lib/jira-spec-content-sync.js.map +1 -1
  37. package/dist/plugins/specweave-jira/lib/setup-wizard.d.ts +2 -2
  38. package/dist/plugins/specweave-jira/lib/setup-wizard.d.ts.map +1 -1
  39. package/dist/plugins/specweave-jira/lib/setup-wizard.js +1 -1
  40. package/dist/plugins/specweave-jira/lib/setup-wizard.js.map +1 -1
  41. package/dist/src/adapters/claude/adapter.js +1 -1
  42. package/dist/src/adapters/claude/adapter.js.map +1 -1
  43. package/dist/src/cli/commands/detect-project.js +1 -1
  44. package/dist/src/cli/commands/detect-project.js.map +1 -1
  45. package/dist/src/cli/commands/detect-specs.js +1 -1
  46. package/dist/src/cli/commands/detect-specs.js.map +1 -1
  47. package/dist/src/cli/commands/import-docs.js +1 -1
  48. package/dist/src/cli/commands/import-docs.js.map +1 -1
  49. package/dist/src/cli/commands/init-multiproject.js +1 -1
  50. package/dist/src/cli/commands/init-multiproject.js.map +1 -1
  51. package/dist/src/cli/commands/init.d.ts.map +1 -1
  52. package/dist/src/cli/commands/init.js +31 -1
  53. package/dist/src/cli/commands/init.js.map +1 -1
  54. package/dist/src/cli/commands/jobs.js +15 -1
  55. package/dist/src/cli/commands/jobs.js.map +1 -1
  56. package/dist/src/cli/commands/migrate-to-multiproject.js +1 -1
  57. package/dist/src/cli/commands/migrate-to-multiproject.js.map +1 -1
  58. package/dist/src/cli/commands/switch-project.js +1 -1
  59. package/dist/src/cli/commands/switch-project.js.map +1 -1
  60. package/dist/src/cli/commands/sync-scheduled.d.ts +38 -0
  61. package/dist/src/cli/commands/sync-scheduled.d.ts.map +1 -0
  62. package/dist/src/cli/commands/sync-scheduled.js +170 -0
  63. package/dist/src/cli/commands/sync-scheduled.js.map +1 -0
  64. package/dist/src/cli/helpers/init/external-import-grouping.d.ts +53 -0
  65. package/dist/src/cli/helpers/init/external-import-grouping.d.ts.map +1 -0
  66. package/dist/src/cli/helpers/init/external-import-grouping.js +287 -0
  67. package/dist/src/cli/helpers/init/external-import-grouping.js.map +1 -0
  68. package/dist/src/cli/helpers/init/external-import.d.ts +1 -34
  69. package/dist/src/cli/helpers/init/external-import.d.ts.map +1 -1
  70. package/dist/src/cli/helpers/init/external-import.js +15 -486
  71. package/dist/src/cli/helpers/init/external-import.js.map +1 -1
  72. package/dist/src/cli/helpers/init/living-docs-preflight.d.ts +58 -0
  73. package/dist/src/cli/helpers/init/living-docs-preflight.d.ts.map +1 -0
  74. package/dist/src/cli/helpers/init/living-docs-preflight.js +290 -0
  75. package/dist/src/cli/helpers/init/living-docs-preflight.js.map +1 -0
  76. package/dist/src/cli/helpers/init/sync-profile-helpers.d.ts +48 -0
  77. package/dist/src/cli/helpers/init/sync-profile-helpers.d.ts.map +1 -0
  78. package/dist/src/cli/helpers/init/sync-profile-helpers.js +238 -0
  79. package/dist/src/cli/helpers/init/sync-profile-helpers.js.map +1 -0
  80. package/dist/src/cli/helpers/init/types.d.ts +1 -0
  81. package/dist/src/cli/helpers/init/types.d.ts.map +1 -1
  82. package/dist/src/cli/helpers/issue-tracker/ado.d.ts.map +1 -1
  83. package/dist/src/cli/helpers/issue-tracker/ado.js +113 -3
  84. package/dist/src/cli/helpers/issue-tracker/ado.js.map +1 -1
  85. package/dist/src/cli/helpers/issue-tracker/index.d.ts.map +1 -1
  86. package/dist/src/cli/helpers/issue-tracker/index.js +2 -287
  87. package/dist/src/cli/helpers/issue-tracker/index.js.map +1 -1
  88. package/dist/src/cli/helpers/issue-tracker/sync-config-writer.d.ts +25 -0
  89. package/dist/src/cli/helpers/issue-tracker/sync-config-writer.d.ts.map +1 -0
  90. package/dist/src/cli/helpers/issue-tracker/sync-config-writer.js +306 -0
  91. package/dist/src/cli/helpers/issue-tracker/sync-config-writer.js.map +1 -0
  92. package/dist/src/cli/helpers/issue-tracker/types.d.ts +27 -0
  93. package/dist/src/cli/helpers/issue-tracker/types.d.ts.map +1 -1
  94. package/dist/src/cli/helpers/issue-tracker/types.js.map +1 -1
  95. package/dist/src/cli/workers/living-docs-worker.d.ts +16 -0
  96. package/dist/src/cli/workers/living-docs-worker.d.ts.map +1 -0
  97. package/dist/src/cli/workers/living-docs-worker.js +395 -0
  98. package/dist/src/cli/workers/living-docs-worker.js.map +1 -0
  99. package/dist/src/core/background/job-dependency.d.ts +45 -0
  100. package/dist/src/core/background/job-dependency.d.ts.map +1 -0
  101. package/dist/src/core/background/job-dependency.js +144 -0
  102. package/dist/src/core/background/job-dependency.js.map +1 -0
  103. package/dist/src/core/background/job-launcher.d.ts +21 -1
  104. package/dist/src/core/background/job-launcher.d.ts.map +1 -1
  105. package/dist/src/core/background/job-launcher.js +93 -0
  106. package/dist/src/core/background/job-launcher.js.map +1 -1
  107. package/dist/src/core/background/types.d.ts +73 -2
  108. package/dist/src/core/background/types.d.ts.map +1 -1
  109. package/dist/src/core/brownfield/importer.js +1 -1
  110. package/dist/src/core/brownfield/importer.js.map +1 -1
  111. package/dist/src/core/comment-builder.d.ts +1 -1
  112. package/dist/src/core/comment-builder.d.ts.map +1 -1
  113. package/dist/src/core/{cost-tracker.d.ts → cost/cost-tracker.d.ts} +2 -2
  114. package/dist/src/core/cost/cost-tracker.d.ts.map +1 -0
  115. package/dist/src/core/{cost-tracker.js → cost/cost-tracker.js} +2 -2
  116. package/dist/src/core/cost/cost-tracker.js.map +1 -0
  117. package/dist/src/core/credentials/credentials-manager.d.ts.map +1 -0
  118. package/dist/src/core/credentials/credentials-manager.js.map +1 -0
  119. package/dist/src/core/increment/discipline-checker.js +1 -1
  120. package/dist/src/core/increment/discipline-checker.js.map +1 -1
  121. package/dist/src/core/increment/increment-archiver.d.ts +9 -8
  122. package/dist/src/core/increment/increment-archiver.d.ts.map +1 -1
  123. package/dist/src/core/increment/increment-archiver.js +40 -42
  124. package/dist/src/core/increment/increment-archiver.js.map +1 -1
  125. package/dist/src/core/increment/increment-status.d.ts.map +1 -0
  126. package/dist/src/core/{increment-status.js → increment/increment-status.js} +1 -1
  127. package/dist/src/core/increment/increment-status.js.map +1 -0
  128. package/dist/src/core/increment/increment-utils.d.ts.map +1 -0
  129. package/dist/src/core/increment/increment-utils.js.map +1 -0
  130. package/dist/src/core/increment/metadata-validator.js +1 -1
  131. package/dist/src/core/increment/metadata-validator.js.map +1 -1
  132. package/dist/src/core/living-docs/checkpoint-manager.d.ts +120 -0
  133. package/dist/src/core/living-docs/checkpoint-manager.d.ts.map +1 -0
  134. package/dist/src/core/living-docs/checkpoint-manager.js +231 -0
  135. package/dist/src/core/living-docs/checkpoint-manager.js.map +1 -0
  136. package/dist/src/core/living-docs/discovery.d.ts +91 -0
  137. package/dist/src/core/living-docs/discovery.d.ts.map +1 -0
  138. package/dist/src/core/living-docs/discovery.js +656 -0
  139. package/dist/src/core/living-docs/discovery.js.map +1 -0
  140. package/dist/src/core/living-docs/feature-archiver.d.ts +23 -4
  141. package/dist/src/core/living-docs/feature-archiver.d.ts.map +1 -1
  142. package/dist/src/core/living-docs/feature-archiver.js +133 -30
  143. package/dist/src/core/living-docs/feature-archiver.js.map +1 -1
  144. package/dist/src/core/living-docs/foundation-builder.d.ts +37 -0
  145. package/dist/src/core/living-docs/foundation-builder.d.ts.map +1 -0
  146. package/dist/src/core/living-docs/foundation-builder.js +357 -0
  147. package/dist/src/core/living-docs/foundation-builder.js.map +1 -0
  148. package/dist/src/core/living-docs/living-docs-sync.d.ts +58 -0
  149. package/dist/src/core/living-docs/living-docs-sync.d.ts.map +1 -1
  150. package/dist/src/core/living-docs/living-docs-sync.js +204 -7
  151. package/dist/src/core/living-docs/living-docs-sync.js.map +1 -1
  152. package/dist/src/core/living-docs/module-analyzer.d.ts +97 -0
  153. package/dist/src/core/living-docs/module-analyzer.d.ts.map +1 -0
  154. package/dist/src/core/living-docs/module-analyzer.js +427 -0
  155. package/dist/src/core/living-docs/module-analyzer.js.map +1 -0
  156. package/dist/src/core/living-docs/suggestions-generator.d.ts +112 -0
  157. package/dist/src/core/living-docs/suggestions-generator.d.ts.map +1 -0
  158. package/dist/src/core/living-docs/suggestions-generator.js +362 -0
  159. package/dist/src/core/living-docs/suggestions-generator.js.map +1 -0
  160. package/dist/src/core/living-docs/workitem-matcher.d.ts +116 -0
  161. package/dist/src/core/living-docs/workitem-matcher.d.ts.map +1 -0
  162. package/dist/src/core/living-docs/workitem-matcher.js +356 -0
  163. package/dist/src/core/living-docs/workitem-matcher.js.map +1 -0
  164. package/dist/src/core/{plugin-loader.d.ts → plugins/plugin-loader.d.ts} +1 -1
  165. package/dist/src/core/plugins/plugin-loader.d.ts.map +1 -0
  166. package/dist/src/core/{plugin-loader.js → plugins/plugin-loader.js} +2 -2
  167. package/dist/src/core/plugins/plugin-loader.js.map +1 -0
  168. package/dist/src/core/{project-manager.d.ts → project/project-manager.d.ts} +1 -1
  169. package/dist/src/core/project/project-manager.d.ts.map +1 -0
  170. package/dist/src/core/{project-manager.js → project/project-manager.js} +3 -3
  171. package/dist/src/core/project/project-manager.js.map +1 -0
  172. package/dist/src/core/project/project-structure-detector.d.ts.map +1 -0
  173. package/dist/src/core/project/project-structure-detector.js.map +1 -0
  174. package/dist/src/core/{rfc-generator-v2.d.ts → rfc/rfc-generator-v2.d.ts} +1 -1
  175. package/dist/src/core/rfc/rfc-generator-v2.d.ts.map +1 -0
  176. package/dist/src/core/{rfc-generator-v2.js → rfc/rfc-generator-v2.js} +1 -1
  177. package/dist/src/core/rfc/rfc-generator-v2.js.map +1 -0
  178. package/dist/src/core/scheduler/index.d.ts +1 -0
  179. package/dist/src/core/scheduler/index.d.ts.map +1 -1
  180. package/dist/src/core/scheduler/index.js +1 -0
  181. package/dist/src/core/scheduler/index.js.map +1 -1
  182. package/dist/src/core/scheduler/scheduled-job.d.ts +1 -1
  183. package/dist/src/core/scheduler/scheduled-job.d.ts.map +1 -1
  184. package/dist/src/core/scheduler/scheduled-job.js.map +1 -1
  185. package/dist/src/core/scheduler/session-sync-executor.d.ts +138 -0
  186. package/dist/src/core/scheduler/session-sync-executor.d.ts.map +1 -0
  187. package/dist/src/core/scheduler/session-sync-executor.js +333 -0
  188. package/dist/src/core/scheduler/session-sync-executor.js.map +1 -0
  189. package/dist/src/core/{spec-content-sync.d.ts → specs/spec-content-sync.d.ts} +2 -2
  190. package/dist/src/core/specs/spec-content-sync.d.ts.map +1 -0
  191. package/dist/src/core/{spec-content-sync.js → specs/spec-content-sync.js} +1 -1
  192. package/dist/src/core/specs/spec-content-sync.js.map +1 -0
  193. package/dist/src/core/{spec-detector.d.ts → specs/spec-detector.d.ts} +1 -1
  194. package/dist/src/core/specs/spec-detector.d.ts.map +1 -0
  195. package/dist/src/core/{spec-detector.js → specs/spec-detector.js} +1 -1
  196. package/dist/src/core/specs/spec-detector.js.map +1 -0
  197. package/dist/src/core/{spec-identifier-detector.d.ts → specs/spec-identifier-detector.d.ts} +2 -2
  198. package/dist/src/core/specs/spec-identifier-detector.d.ts.map +1 -0
  199. package/dist/src/core/{spec-identifier-detector.js → specs/spec-identifier-detector.js} +1 -1
  200. package/dist/src/core/specs/spec-identifier-detector.js.map +1 -0
  201. package/dist/src/core/specs/spec-metadata-manager.js +1 -1
  202. package/dist/src/core/specs/spec-metadata-manager.js.map +1 -1
  203. package/dist/src/core/specs/spec-task-mapper.d.ts.map +1 -0
  204. package/dist/src/core/specs/spec-task-mapper.js.map +1 -0
  205. package/dist/src/core/sync/sync-audit-logger.d.ts +62 -0
  206. package/dist/src/core/sync/sync-audit-logger.d.ts.map +1 -1
  207. package/dist/src/core/sync/sync-audit-logger.js +59 -0
  208. package/dist/src/core/sync/sync-audit-logger.js.map +1 -1
  209. package/dist/src/importers/item-converter.d.ts +51 -27
  210. package/dist/src/importers/item-converter.d.ts.map +1 -1
  211. package/dist/src/importers/item-converter.js +219 -179
  212. package/dist/src/importers/item-converter.js.map +1 -1
  213. package/dist/src/importers/markdown-generator.d.ts +75 -0
  214. package/dist/src/importers/markdown-generator.d.ts.map +1 -0
  215. package/dist/src/importers/markdown-generator.js +250 -0
  216. package/dist/src/importers/markdown-generator.js.map +1 -0
  217. package/dist/src/integrations/ado/ado-client.d.ts +93 -0
  218. package/dist/src/integrations/ado/ado-client.d.ts.map +1 -1
  219. package/dist/src/integrations/ado/ado-client.js +172 -1
  220. package/dist/src/integrations/ado/ado-client.js.map +1 -1
  221. package/dist/src/integrations/jira/jira-client.d.ts +44 -0
  222. package/dist/src/integrations/jira/jira-client.d.ts.map +1 -1
  223. package/dist/src/integrations/jira/jira-client.js +119 -1
  224. package/dist/src/integrations/jira/jira-client.js.map +1 -1
  225. package/dist/src/integrations/jira/jira-incremental-mapper.js +2 -2
  226. package/dist/src/integrations/jira/jira-incremental-mapper.js.map +1 -1
  227. package/dist/src/integrations/jira/jira-mapper.js +1 -1
  228. package/dist/src/integrations/jira/jira-mapper.js.map +1 -1
  229. package/dist/src/living-docs/epic-id-allocator.d.ts +177 -0
  230. package/dist/src/living-docs/epic-id-allocator.d.ts.map +1 -0
  231. package/dist/src/living-docs/epic-id-allocator.js +363 -0
  232. package/dist/src/living-docs/epic-id-allocator.js.map +1 -0
  233. package/dist/src/sync/external-change-puller.d.ts +94 -0
  234. package/dist/src/sync/external-change-puller.d.ts.map +1 -0
  235. package/dist/src/sync/external-change-puller.js +181 -0
  236. package/dist/src/sync/external-change-puller.js.map +1 -0
  237. package/dist/src/sync/index.d.ts +4 -0
  238. package/dist/src/sync/index.d.ts.map +1 -1
  239. package/dist/src/sync/index.js +2 -0
  240. package/dist/src/sync/index.js.map +1 -1
  241. package/dist/src/sync/living-docs-updater.d.ts +93 -0
  242. package/dist/src/sync/living-docs-updater.d.ts.map +1 -0
  243. package/dist/src/sync/living-docs-updater.js +218 -0
  244. package/dist/src/sync/living-docs-updater.js.map +1 -0
  245. package/dist/src/testing/test-generator.js +1 -1
  246. package/dist/src/testing/test-generator.js.map +1 -1
  247. package/dist/src/utils/cost-reporter.d.ts +1 -1
  248. package/dist/src/utils/cost-reporter.d.ts.map +1 -1
  249. package/dist/src/utils/model-selection.js +4 -4
  250. package/dist/src/utils/model-selection.js.map +1 -1
  251. package/dist/src/utils/pricing-constants.d.ts +2 -2
  252. package/dist/src/utils/pricing-constants.js +2 -2
  253. package/package.json +1 -1
  254. package/plugins/specweave/.claude-plugin/plugin.json +1 -28
  255. package/plugins/specweave/agents/code-standards-detective/AGENT.md +3 -3
  256. package/plugins/specweave/agents/infrastructure/AGENT.md +4 -0
  257. package/plugins/specweave/agents/performance/AGENT.md +2 -2
  258. package/plugins/specweave/agents/reflective-reviewer/AGENT.md +3 -3
  259. package/plugins/specweave/agents/translator/AGENT.md +2 -2
  260. package/plugins/specweave/commands/specweave-costs.md +2 -2
  261. package/plugins/specweave/commands/specweave-do.md +2 -2
  262. package/plugins/specweave/hooks/lib/scheduler-startup.sh +59 -8
  263. package/plugins/specweave/skills/code-reviewer/SKILL.md +1 -1
  264. package/plugins/specweave/skills/role-orchestrator/README.md +1 -1
  265. package/plugins/specweave-ado/agents/ado-manager/AGENT.md +8 -2
  266. package/plugins/specweave-ado/agents/ado-multi-project-mapper/AGENT.md +2 -2
  267. package/plugins/specweave-ado/agents/ado-sync-judge/AGENT.md +2 -2
  268. package/plugins/specweave-ado/lib/ado-spec-commit-sync.d.ts +1 -1
  269. package/plugins/specweave-ado/lib/ado-spec-commit-sync.js +1 -1
  270. package/plugins/specweave-ado/lib/ado-spec-commit-sync.ts +1 -1
  271. package/plugins/specweave-ado/lib/ado-spec-content-sync.js +1 -1
  272. package/plugins/specweave-ado/lib/ado-spec-content-sync.ts +1 -1
  273. package/plugins/specweave-ado/lib/conflict-resolver.js +87 -0
  274. package/plugins/specweave-ado/lib/conflict-resolver.ts +124 -0
  275. package/plugins/specweave-ado/skills/specweave-ado-mapper/SKILL.md +1 -1
  276. package/plugins/specweave-backend/agents/database-optimizer/AGENT.md +3 -3
  277. package/plugins/specweave-backend/skills/dotnet-backend/SKILL.md +1 -1
  278. package/plugins/specweave-backend/skills/nodejs-backend/SKILL.md +1 -1
  279. package/plugins/specweave-backend/skills/python-backend/SKILL.md +1 -1
  280. package/plugins/specweave-confluent/agents/confluent-architect/AGENT.md +6 -1
  281. package/plugins/specweave-diagrams/agents/diagrams-architect/AGENT.md +2 -2
  282. package/plugins/specweave-diagrams/skills/diagrams-architect/SKILL.md +1 -1
  283. package/plugins/specweave-frontend/agents/frontend-architect/AGENT.md +4 -0
  284. package/plugins/specweave-github/agents/github-manager/AGENT.md +1 -1
  285. package/plugins/specweave-github/agents/github-task-splitter/AGENT.md +11 -1
  286. package/plugins/specweave-github/agents/user-story-updater/AGENT.md +6 -1
  287. package/plugins/specweave-github/hooks/.specweave/logs/hooks-debug.log +90 -0
  288. package/plugins/specweave-github/lib/github-client-v2.js +97 -0
  289. package/plugins/specweave-github/lib/github-client-v2.ts +115 -1
  290. package/plugins/specweave-github/lib/github-spec-commit-sync.d.ts +1 -1
  291. package/plugins/specweave-github/lib/github-spec-commit-sync.js +1 -1
  292. package/plugins/specweave-github/lib/github-spec-commit-sync.ts +1 -1
  293. package/plugins/specweave-github/lib/github-spec-content-sync.js +1 -1
  294. package/plugins/specweave-github/lib/github-spec-content-sync.ts +1 -1
  295. package/plugins/specweave-github/lib/types.ts +21 -0
  296. package/plugins/specweave-infrastructure/agents/devops/AGENT.md +1 -1
  297. package/plugins/specweave-infrastructure/agents/network-engineer/AGENT.md +3 -3
  298. package/plugins/specweave-infrastructure/agents/observability-engineer/AGENT.md +2 -2
  299. package/plugins/specweave-infrastructure/agents/performance-engineer/AGENT.md +3 -3
  300. package/plugins/specweave-infrastructure/agents/sre/AGENT.md +2 -2
  301. package/plugins/specweave-jira/agents/jira-manager/AGENT.md +11 -1
  302. package/plugins/specweave-jira/commands/import-projects.js +1 -1
  303. package/plugins/specweave-jira/commands/import-projects.ts +1 -1
  304. package/plugins/specweave-jira/lib/jira-spec-commit-sync.d.ts +1 -1
  305. package/plugins/specweave-jira/lib/jira-spec-commit-sync.js +1 -1
  306. package/plugins/specweave-jira/lib/jira-spec-commit-sync.ts +1 -1
  307. package/plugins/specweave-jira/lib/jira-spec-content-sync.js +1 -1
  308. package/plugins/specweave-jira/lib/jira-spec-content-sync.ts +1 -1
  309. package/plugins/specweave-jira/lib/setup-wizard.js +2 -2
  310. package/plugins/specweave-jira/lib/setup-wizard.ts +2 -2
  311. package/plugins/specweave-jira/skills/specweave-jira-mapper/SKILL.md +1 -1
  312. package/plugins/specweave-kafka/agents/kafka-architect/AGENT.md +5 -1
  313. package/plugins/specweave-kafka/agents/kafka-devops/AGENT.md +6 -1
  314. package/plugins/specweave-kafka/agents/kafka-observability/AGENT.md +6 -1
  315. package/plugins/specweave-kubernetes/agents/kubernetes-architect/AGENT.md +3 -3
  316. package/plugins/specweave-ml/agents/data-scientist/AGENT.md +2 -1
  317. package/plugins/specweave-ml/agents/ml-engineer/AGENT.md +2 -1
  318. package/plugins/specweave-ml/agents/mlops-engineer/AGENT.md +3 -3
  319. package/plugins/specweave-mobile/agents/mobile-architect/AGENT.md +6 -1
  320. package/plugins/specweave-payments/agents/payment-integration/AGENT.md +3 -3
  321. package/plugins/specweave-release/agents/release-manager/AGENT.md +6 -1
  322. package/plugins/specweave-release/commands/specweave-release-npm.md +8 -0
  323. package/plugins/specweave-release/hooks/.specweave/logs/dora-tracking.log +135 -0
  324. package/plugins/specweave-testing/agents/qa-engineer/AGENT.md +5 -0
  325. package/src/templates/AGENTS.md.template +97 -0
  326. package/dist/src/core/cost-tracker.d.ts.map +0 -1
  327. package/dist/src/core/cost-tracker.js.map +0 -1
  328. package/dist/src/core/credentials-manager.d.ts.map +0 -1
  329. package/dist/src/core/credentials-manager.js.map +0 -1
  330. package/dist/src/core/increment-status.d.ts.map +0 -1
  331. package/dist/src/core/increment-status.js.map +0 -1
  332. package/dist/src/core/increment-utils.d.ts.map +0 -1
  333. package/dist/src/core/increment-utils.js.map +0 -1
  334. package/dist/src/core/plugin-loader.d.ts.map +0 -1
  335. package/dist/src/core/plugin-loader.js.map +0 -1
  336. package/dist/src/core/project-manager.d.ts.map +0 -1
  337. package/dist/src/core/project-manager.js.map +0 -1
  338. package/dist/src/core/project-structure-detector.d.ts.map +0 -1
  339. package/dist/src/core/project-structure-detector.js.map +0 -1
  340. package/dist/src/core/rfc-generator-v2.d.ts.map +0 -1
  341. package/dist/src/core/rfc-generator-v2.js.map +0 -1
  342. package/dist/src/core/spec-content-sync.d.ts.map +0 -1
  343. package/dist/src/core/spec-content-sync.js.map +0 -1
  344. package/dist/src/core/spec-detector.d.ts.map +0 -1
  345. package/dist/src/core/spec-detector.js.map +0 -1
  346. package/dist/src/core/spec-identifier-detector.d.ts.map +0 -1
  347. package/dist/src/core/spec-identifier-detector.js.map +0 -1
  348. package/dist/src/core/spec-task-mapper.d.ts.map +0 -1
  349. package/dist/src/core/spec-task-mapper.js.map +0 -1
  350. package/dist/src/utils/spec-parser.d.ts +0 -145
  351. package/dist/src/utils/spec-parser.d.ts.map +0 -1
  352. package/dist/src/utils/spec-parser.js +0 -640
  353. package/dist/src/utils/spec-parser.js.map +0 -1
  354. package/plugins/specweave/agents/pm/AGENT.md.bak2 +0 -1754
  355. package/plugins/specweave/hooks/hooks.json.bak +0 -72
  356. package/plugins/specweave/hooks/hooks.json.v1-backup +0 -16
  357. package/plugins/specweave/hooks/v2/hooks.json +0 -16
  358. /package/dist/src/core/{credentials-manager.d.ts → credentials/credentials-manager.d.ts} +0 -0
  359. /package/dist/src/core/{credentials-manager.js → credentials/credentials-manager.js} +0 -0
  360. /package/dist/src/core/{increment-status.d.ts → increment/increment-status.d.ts} +0 -0
  361. /package/dist/src/core/{increment-utils.d.ts → increment/increment-utils.d.ts} +0 -0
  362. /package/dist/src/core/{increment-utils.js → increment/increment-utils.js} +0 -0
  363. /package/dist/src/core/{project-structure-detector.d.ts → project/project-structure-detector.d.ts} +0 -0
  364. /package/dist/src/core/{project-structure-detector.js → project/project-structure-detector.js} +0 -0
  365. /package/dist/src/core/{spec-task-mapper.d.ts → specs/spec-task-mapper.d.ts} +0 -0
  366. /package/dist/src/core/{spec-task-mapper.js → specs/spec-task-mapper.js} +0 -0
@@ -0,0 +1,363 @@
1
+ /**
2
+ * Epic ID Allocator - Intelligent Epic ID allocation with chronological placement
3
+ *
4
+ * Allocates EP-XXX IDs for external work items (ADO Capabilities, Strategic Themes)
5
+ * based on creation date, attempting chronological insertion while preventing collisions.
6
+ *
7
+ * Features:
8
+ * - Chronological ID allocation based on work item creation date
9
+ * - Gap filling (insert EP-011E between EP-010 and EP-020)
10
+ * - Append mode fallback (max ID + 1)
11
+ * - Collision detection (checks both EP-XXX and EP-XXXE)
12
+ * - Archive-aware (scans both active and archived epics)
13
+ *
14
+ * @module living-docs/epic-id-allocator
15
+ * @version 0.29.3
16
+ */
17
+ import * as fs from '../utils/fs-native.js';
18
+ import path from 'path';
19
+ import matter from 'gray-matter';
20
+ import { formatOrigin } from '../core/types/origin-metadata.js';
21
+ import { consoleLogger } from '../utils/logger.js';
22
+ /**
23
+ * Epic ID Allocator
24
+ *
25
+ * Intelligently allocates Epic IDs with chronological placement.
26
+ * Epics are stored in _epics/ folder at the specs root level.
27
+ *
28
+ * CRITICAL: In umbrella/multi-repo setups, enable globalCollisionDetection
29
+ * to prevent ID collisions like EP-001 in one repo and EP-001E in another.
30
+ */
31
+ export class EpicIdAllocator {
32
+ constructor(projectRoot, options) {
33
+ this.existingEpics = new Map();
34
+ this.scanned = false;
35
+ this.projectRoot = projectRoot;
36
+ this.specsPath = path.join(projectRoot, '.specweave/docs/internal/specs');
37
+ // Epics are at the root level: _epics/ (NOT inside project folders)
38
+ this.epicsPath = path.join(this.specsPath, '_epics');
39
+ this.globalCollisionDetection = options?.globalCollisionDetection ?? false;
40
+ this.externalContainer = options?.externalContainer;
41
+ this.logger = options?.logger ?? consoleLogger;
42
+ }
43
+ /**
44
+ * Scan existing EP-IDs (both active and archived)
45
+ *
46
+ * CRITICAL: Archives are scanned to prevent ID reuse
47
+ *
48
+ * Structure:
49
+ * - _epics/EP-XXX/
50
+ * - _epics/_archive/EP-XXX/
51
+ */
52
+ async scanExistingIds() {
53
+ this.existingEpics.clear();
54
+ // Scan active epics
55
+ if (await fs.pathExists(this.epicsPath)) {
56
+ await this.scanDirectory(this.epicsPath, 'active');
57
+ }
58
+ // Scan archived epics
59
+ const archivePath = path.join(this.epicsPath, '_archive');
60
+ if (await fs.pathExists(archivePath)) {
61
+ await this.scanDirectory(archivePath, 'archived');
62
+ }
63
+ this.scanned = true;
64
+ this.logger.log(`📊 Scanned ${this.existingEpics.size} existing Epic IDs`);
65
+ }
66
+ /**
67
+ * Scan directory for EP-XXX folders
68
+ */
69
+ async scanDirectory(dirPath, source) {
70
+ const entries = await fs.readdir(dirPath, { withFileTypes: true });
71
+ for (const entry of entries) {
72
+ if (!entry.isDirectory())
73
+ continue;
74
+ // Match EP-XXX or EP-XXXE pattern (3+ digits)
75
+ const match = entry.name.match(/^(EP-\d{3,}E?)$/);
76
+ if (!match)
77
+ continue;
78
+ const epId = match[1];
79
+ const epicPath = path.join(dirPath, entry.name);
80
+ // Try to parse epic metadata from EPIC.md
81
+ const metadata = await this.parseEpicMetadata(epicPath, epId);
82
+ if (metadata) {
83
+ this.existingEpics.set(epId, metadata);
84
+ }
85
+ }
86
+ }
87
+ /**
88
+ * Parse epic metadata from EPIC.md frontmatter
89
+ */
90
+ async parseEpicMetadata(epicPath, epId) {
91
+ // Try EPIC.md first, then README.md
92
+ const possibleFiles = ['EPIC.md', 'README.md', 'epic.md', 'readme.md'];
93
+ for (const filename of possibleFiles) {
94
+ const filePath = path.join(epicPath, filename);
95
+ if (await fs.pathExists(filePath)) {
96
+ try {
97
+ const content = await fs.readFile(filePath, 'utf-8');
98
+ const parsed = matter(content);
99
+ const frontmatter = parsed.data;
100
+ // Normalize timestamp
101
+ const rawTimestamp = frontmatter.created || frontmatter.createdAt || new Date(0);
102
+ const timestamp = rawTimestamp instanceof Date ? rawTimestamp.toISOString() : rawTimestamp;
103
+ const normalizedTimestamp = timestamp.replace(/\.\d{3}Z$/, 'Z');
104
+ return {
105
+ id: epId,
106
+ createdAt: normalizedTimestamp,
107
+ origin: epId.endsWith('E') ? 'external' : 'internal',
108
+ externalId: frontmatter.external_id || frontmatter.externalId,
109
+ path: epicPath
110
+ };
111
+ }
112
+ catch (error) {
113
+ // Continue to next file
114
+ continue;
115
+ }
116
+ }
117
+ }
118
+ // Fallback: create minimal metadata if no file found
119
+ return {
120
+ id: epId,
121
+ createdAt: new Date(0).toISOString(), // Epoch (will sort to beginning)
122
+ origin: epId.endsWith('E') ? 'external' : 'internal',
123
+ path: epicPath
124
+ };
125
+ }
126
+ /**
127
+ * Allocate EP-ID for external work item with chronological placement
128
+ *
129
+ * Algorithm:
130
+ * 1. Sort existing IDs by creation date
131
+ * 2. Find chronological insertion point based on work item creation date
132
+ * 3. Check for ID gaps between consecutive epics
133
+ * 4. If gap exists, allocate next ID in gap (e.g., EP-011E between EP-010 and EP-020)
134
+ * 5. If no gap, append to end (max ID + 1 with E suffix)
135
+ *
136
+ * CRITICAL: Unified numeric sequence - EP-XXX and EP-XXXE never share same index
137
+ *
138
+ * @param workItem - External epic item to allocate ID for
139
+ * @returns Allocation result with ID and strategy
140
+ */
141
+ async allocateId(workItem) {
142
+ if (!this.scanned) {
143
+ await this.scanExistingIds();
144
+ }
145
+ // Handle empty case (first epic)
146
+ if (this.existingEpics.size === 0) {
147
+ const result = {
148
+ id: 'EP-001E',
149
+ strategy: 'first',
150
+ reason: 'First external epic in project',
151
+ number: 1
152
+ };
153
+ // Track allocated IDs to prevent duplicates in same session
154
+ this.trackAllocatedId(result.id, workItem.createdAt);
155
+ return result;
156
+ }
157
+ // Sort epics by creation date
158
+ const sortedEpics = Array.from(this.existingEpics.values()).sort((a, b) => {
159
+ return new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime();
160
+ });
161
+ // Find chronological insertion point
162
+ const workItemDate = new Date(workItem.createdAt).getTime();
163
+ let insertionIndex = sortedEpics.findIndex(e => new Date(e.createdAt).getTime() > workItemDate);
164
+ // If work item is after all existing epics, append
165
+ if (insertionIndex === -1) {
166
+ const maxId = this.getMaxId();
167
+ const nextNumber = maxId + 1;
168
+ const nextId = `EP-${String(nextNumber).padStart(3, '0')}E`;
169
+ // Check for collision
170
+ if (this.hasCollision(nextId)) {
171
+ throw new Error(`ID collision: ${nextId} already exists`);
172
+ }
173
+ const result = {
174
+ id: nextId,
175
+ strategy: 'append',
176
+ reason: `Work item created after all existing epics (${new Date(workItem.createdAt).toISOString()})`,
177
+ number: nextNumber
178
+ };
179
+ this.trackAllocatedId(result.id, workItem.createdAt);
180
+ return result;
181
+ }
182
+ // Try chronological insertion into gap
183
+ const beforeEpic = insertionIndex > 0 ? sortedEpics[insertionIndex - 1] : null;
184
+ const afterEpic = sortedEpics[insertionIndex];
185
+ if (beforeEpic && afterEpic) {
186
+ const beforeNumber = this.extractNumber(beforeEpic.id);
187
+ const afterNumber = this.extractNumber(afterEpic.id);
188
+ // Check if there's a gap (at least 2 numbers apart)
189
+ if (afterNumber - beforeNumber > 1) {
190
+ // Allocate next ID after beforeEpic
191
+ const nextNumber = beforeNumber + 1;
192
+ const nextId = `EP-${String(nextNumber).padStart(3, '0')}E`;
193
+ // Check for collision
194
+ if (!this.hasCollision(nextId)) {
195
+ const result = {
196
+ id: nextId,
197
+ strategy: 'chronological-insert',
198
+ reason: `Inserted chronologically between ${beforeEpic.id} and ${afterEpic.id}`,
199
+ number: nextNumber
200
+ };
201
+ this.trackAllocatedId(result.id, workItem.createdAt);
202
+ return result;
203
+ }
204
+ else {
205
+ const collidingId = this.findCollidingId(nextNumber);
206
+ this.logger.warn(`⚠️ Numeric collision prevented: ${collidingId} exists, skipping index ${nextNumber}`);
207
+ }
208
+ }
209
+ }
210
+ // Fallback: append to end if gap insertion failed
211
+ const maxId = this.getMaxId();
212
+ const nextNumber = maxId + 1;
213
+ const nextId = `EP-${String(nextNumber).padStart(3, '0')}E`;
214
+ // Check for collision
215
+ if (this.hasCollision(nextId)) {
216
+ throw new Error(`ID collision: ${nextId} already exists`);
217
+ }
218
+ const result = {
219
+ id: nextId,
220
+ strategy: 'append',
221
+ reason: 'Gap insertion not possible, appended to end',
222
+ number: nextNumber
223
+ };
224
+ this.trackAllocatedId(result.id, workItem.createdAt);
225
+ return result;
226
+ }
227
+ /**
228
+ * Track a newly allocated ID to prevent duplicates in the same session
229
+ */
230
+ trackAllocatedId(id, createdAt) {
231
+ this.existingEpics.set(id, {
232
+ id,
233
+ createdAt,
234
+ origin: 'external',
235
+ path: ''
236
+ });
237
+ }
238
+ /**
239
+ * Check if ID has collision (exact match or variant)
240
+ */
241
+ hasCollision(id) {
242
+ // Exact match
243
+ if (this.existingEpics.has(id)) {
244
+ return true;
245
+ }
246
+ // Variant match (check both EP-XXX and EP-XXXE)
247
+ const number = this.extractNumber(id);
248
+ const internalId = `EP-${String(number).padStart(3, '0')}`;
249
+ const externalId = `EP-${String(number).padStart(3, '0')}E`;
250
+ return this.existingEpics.has(internalId) || this.existingEpics.has(externalId);
251
+ }
252
+ /**
253
+ * Get maximum numeric ID value (ignoring E suffix)
254
+ */
255
+ getMaxId() {
256
+ if (this.existingEpics.size === 0) {
257
+ return 0;
258
+ }
259
+ const numbers = Array.from(this.existingEpics.keys()).map(id => this.extractNumber(id));
260
+ return Math.max(...numbers);
261
+ }
262
+ /**
263
+ * Extract numeric part from EP-ID
264
+ */
265
+ extractNumber(id) {
266
+ const match = id.match(/^EP-(\d{3,})E?$/);
267
+ if (!match) {
268
+ throw new Error(`Invalid EP-ID format: ${id}`);
269
+ }
270
+ return parseInt(match[1], 10);
271
+ }
272
+ /**
273
+ * Find which epic ID is using a numeric index
274
+ */
275
+ findCollidingId(index) {
276
+ const internalId = `EP-${String(index).padStart(3, '0')}`;
277
+ const externalId = `EP-${String(index).padStart(3, '0')}E`;
278
+ if (this.existingEpics.has(internalId)) {
279
+ return internalId;
280
+ }
281
+ if (this.existingEpics.has(externalId)) {
282
+ return externalId;
283
+ }
284
+ return `index ${index}`;
285
+ }
286
+ /**
287
+ * Get all existing epic IDs (sorted by creation date)
288
+ */
289
+ getExistingEpics() {
290
+ return Array.from(this.existingEpics.values()).sort((a, b) => {
291
+ return new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime();
292
+ });
293
+ }
294
+ /**
295
+ * Get allocation statistics
296
+ */
297
+ getStats() {
298
+ const epics = Array.from(this.existingEpics.values());
299
+ return {
300
+ total: epics.length,
301
+ active: epics.filter(e => !e.path.includes('/_archive/')).length,
302
+ archived: epics.filter(e => e.path.includes('/_archive/')).length,
303
+ internal: epics.filter(e => e.origin === 'internal').length,
304
+ external: epics.filter(e => e.origin === 'external').length,
305
+ maxId: this.getMaxId()
306
+ };
307
+ }
308
+ /**
309
+ * Create epic folder with EPIC.md and metadata
310
+ *
311
+ * Structure:
312
+ * - _epics/EP-XXX/EPIC.md
313
+ *
314
+ * @param epId - Epic ID (e.g., "EP-042E")
315
+ * @param workItem - External epic item metadata
316
+ * @param metadata - External item metadata for origin tracking
317
+ * @returns Path to created epic folder
318
+ */
319
+ async createEpicFolder(epId, workItem, metadata) {
320
+ // Epics are at root level: _epics/EP-XXX/
321
+ const epicPath = path.join(this.epicsPath, epId);
322
+ await fs.ensureDir(epicPath);
323
+ // Generate EPIC.md with frontmatter
324
+ const originBadge = formatOrigin(metadata);
325
+ const workItemTypeLabel = workItem.workItemType || 'Capability';
326
+ const epicContent = `---
327
+ id: ${epId}
328
+ title: "${workItem.title}"
329
+ type: epic
330
+ origin: external
331
+ source: ${metadata.source}
332
+ external_id: ${metadata.external_id}
333
+ external_url: ${metadata.external_url}
334
+ work_item_type: ${workItemTypeLabel}
335
+ created: ${workItem.createdAt}
336
+ imported_at: ${metadata.imported_at}
337
+ ---
338
+
339
+ # ${workItemTypeLabel}: ${workItem.title}
340
+
341
+ **Origin**: ${originBadge}
342
+
343
+ ## Description
344
+
345
+ This ${workItemTypeLabel.toLowerCase()} was imported from an external tool.
346
+
347
+ ## Features in This Epic
348
+
349
+ Features belonging to this ${workItemTypeLabel.toLowerCase()} will be listed here.
350
+
351
+ ## Status
352
+
353
+ - **Created**: ${workItem.createdAt}
354
+ - **Imported**: ${metadata.imported_at}
355
+ - **External ID**: ${metadata.external_id}
356
+ `;
357
+ const epicFilePath = path.join(epicPath, 'EPIC.md');
358
+ await fs.writeFile(epicFilePath, epicContent);
359
+ this.logger.log(`📁 Created Epic folder: ${epId}`);
360
+ return epicPath;
361
+ }
362
+ }
363
+ //# sourceMappingURL=epic-id-allocator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"epic-id-allocator.js","sourceRoot":"","sources":["../../../src/living-docs/epic-id-allocator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,94 @@
1
+ /**
2
+ * External Change Puller
3
+ *
4
+ * Pulls changes from external tools (ADO, JIRA, GitHub) back to SpecWeave.
5
+ * Implements the pull direction of bidirectional sync.
6
+ *
7
+ * Features:
8
+ * - Fetch recent changes from all configured platforms
9
+ * - Map external changes to living docs format
10
+ * - Support for timestamp-based filtering
11
+ *
12
+ * @module sync/external-change-puller
13
+ */
14
+ import { Logger } from '../utils/logger.js';
15
+ /**
16
+ * Generic external change interface
17
+ * Unifies changes from ADO, JIRA, and GitHub
18
+ */
19
+ export interface ExternalChange {
20
+ platform: 'ado' | 'jira' | 'github';
21
+ externalId: string;
22
+ changedAt: string;
23
+ changedBy: string;
24
+ changedFields: Array<{
25
+ field: string;
26
+ oldValue: unknown;
27
+ newValue: unknown;
28
+ }>;
29
+ currentState: {
30
+ status: string;
31
+ priority: string | number | null;
32
+ assignee: string | null;
33
+ };
34
+ }
35
+ /**
36
+ * External change puller options
37
+ */
38
+ export interface ExternalChangePullerOptions {
39
+ /**
40
+ * Project root directory
41
+ */
42
+ projectRoot: string;
43
+ /**
44
+ * Logger instance
45
+ */
46
+ logger?: Logger;
47
+ /**
48
+ * Platforms to pull from
49
+ */
50
+ platforms?: Array<'ado' | 'jira' | 'github'>;
51
+ }
52
+ /**
53
+ * ExternalChangePuller - Fetches changes from external tools
54
+ *
55
+ * Aggregates changes from all configured external tools and
56
+ * transforms them into a unified format for processing.
57
+ */
58
+ export declare class ExternalChangePuller {
59
+ private readonly projectRoot;
60
+ private readonly logger;
61
+ private readonly platforms;
62
+ constructor(options: ExternalChangePullerOptions);
63
+ /**
64
+ * Fetch recent changes from all configured platforms
65
+ *
66
+ * @param since - Timestamp to query changes from
67
+ * @param linkedItems - Optional map of platform -> item IDs to filter
68
+ * @returns Array of external changes from all platforms
69
+ */
70
+ fetchRecentChanges(since: Date, linkedItems?: {
71
+ ado?: number[];
72
+ jira?: string[];
73
+ github?: number[];
74
+ }): Promise<ExternalChange[]>;
75
+ /**
76
+ * Fetch changes from Azure DevOps
77
+ */
78
+ private fetchAdoChanges;
79
+ /**
80
+ * Fetch changes from JIRA
81
+ */
82
+ private fetchJiraChanges;
83
+ /**
84
+ * Fetch changes from GitHub
85
+ */
86
+ private fetchGitHubChanges;
87
+ /**
88
+ * Map external status to SpecWeave status
89
+ *
90
+ * Converts platform-specific status values to SpecWeave's status taxonomy.
91
+ */
92
+ mapToSpecWeaveStatus(platform: 'ado' | 'jira' | 'github', externalStatus: string): string;
93
+ }
94
+ //# sourceMappingURL=external-change-puller.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"external-change-puller.d.ts","sourceRoot":"","sources":["../../../src/sync/external-change-puller.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,MAAM,EAAiB,MAAM,oBAAoB,CAAC;AAI3D;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,KAAK,GAAG,MAAM,GAAG,QAAQ,CAAC;IACpC,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,KAAK,CAAC;QACnB,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,EAAE,OAAO,CAAC;QAClB,QAAQ,EAAE,OAAO,CAAC;KACnB,CAAC,CAAC;IACH,YAAY,EAAE;QACZ,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;QACjC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;KACzB,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,2BAA2B;IAC1C;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,SAAS,CAAC,EAAE,KAAK,CAAC,KAAK,GAAG,MAAM,GAAG,QAAQ,CAAC,CAAC;CAC9C;AAED;;;;;GAKG;AACH,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAmC;gBAEjD,OAAO,EAAE,2BAA2B;IAMhD;;;;;;OAMG;IACG,kBAAkB,CACtB,KAAK,EAAE,IAAI,EACX,WAAW,CAAC,EAAE;QACZ,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC;QACf,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;QAChB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;KACnB,GACA,OAAO,CAAC,cAAc,EAAE,CAAC;IA4C5B;;OAEG;YACW,eAAe;IA8B7B;;OAEG;YACW,gBAAgB;IA8B9B;;OAEG;YACW,kBAAkB;IAqChC;;;;OAIG;IACH,oBAAoB,CAClB,QAAQ,EAAE,KAAK,GAAG,MAAM,GAAG,QAAQ,EACnC,cAAc,EAAE,MAAM,GACrB,MAAM;CA0BV"}
@@ -0,0 +1,181 @@
1
+ /**
2
+ * External Change Puller
3
+ *
4
+ * Pulls changes from external tools (ADO, JIRA, GitHub) back to SpecWeave.
5
+ * Implements the pull direction of bidirectional sync.
6
+ *
7
+ * Features:
8
+ * - Fetch recent changes from all configured platforms
9
+ * - Map external changes to living docs format
10
+ * - Support for timestamp-based filtering
11
+ *
12
+ * @module sync/external-change-puller
13
+ */
14
+ import { consoleLogger } from '../utils/logger.js';
15
+ /**
16
+ * ExternalChangePuller - Fetches changes from external tools
17
+ *
18
+ * Aggregates changes from all configured external tools and
19
+ * transforms them into a unified format for processing.
20
+ */
21
+ export class ExternalChangePuller {
22
+ constructor(options) {
23
+ this.projectRoot = options.projectRoot;
24
+ this.logger = options.logger ?? consoleLogger;
25
+ this.platforms = options.platforms ?? ['ado', 'jira', 'github'];
26
+ }
27
+ /**
28
+ * Fetch recent changes from all configured platforms
29
+ *
30
+ * @param since - Timestamp to query changes from
31
+ * @param linkedItems - Optional map of platform -> item IDs to filter
32
+ * @returns Array of external changes from all platforms
33
+ */
34
+ async fetchRecentChanges(since, linkedItems) {
35
+ const allChanges = [];
36
+ this.logger.log(`⬇️ Fetching changes since ${since.toISOString()}`);
37
+ // Fetch from each platform in parallel
38
+ const fetchPromises = [];
39
+ if (this.platforms.includes('ado')) {
40
+ fetchPromises.push(this.fetchAdoChanges(since, linkedItems?.ado)
41
+ .then(changes => { allChanges.push(...changes); })
42
+ .catch(err => { this.logger.warn(`ADO fetch failed: ${err.message}`); }));
43
+ }
44
+ if (this.platforms.includes('jira')) {
45
+ fetchPromises.push(this.fetchJiraChanges(since, linkedItems?.jira)
46
+ .then(changes => { allChanges.push(...changes); })
47
+ .catch(err => { this.logger.warn(`JIRA fetch failed: ${err.message}`); }));
48
+ }
49
+ if (this.platforms.includes('github')) {
50
+ fetchPromises.push(this.fetchGitHubChanges(since, linkedItems?.github)
51
+ .then(changes => { allChanges.push(...changes); })
52
+ .catch(err => { this.logger.warn(`GitHub fetch failed: ${err.message}`); }));
53
+ }
54
+ await Promise.all(fetchPromises);
55
+ // Sort by changedAt (most recent first)
56
+ allChanges.sort((a, b) => new Date(b.changedAt).getTime() - new Date(a.changedAt).getTime());
57
+ this.logger.log(`📥 Fetched ${allChanges.length} changes from external tools`);
58
+ return allChanges;
59
+ }
60
+ /**
61
+ * Fetch changes from Azure DevOps
62
+ */
63
+ async fetchAdoChanges(since, linkedItemIds) {
64
+ try {
65
+ // Dynamic import to avoid initialization errors when ADO is not configured
66
+ const { AdoClient } = await import('../integrations/ado/ado-client.js');
67
+ const client = new AdoClient();
68
+ const adoChanges = await client.fetchRecentChanges(since, linkedItemIds);
69
+ // Map to unified format
70
+ return adoChanges.map(change => ({
71
+ platform: 'ado',
72
+ externalId: change.externalId,
73
+ changedAt: change.changedAt,
74
+ changedBy: change.changedBy,
75
+ changedFields: change.changedFields,
76
+ currentState: {
77
+ status: change.currentState.status,
78
+ priority: change.currentState.priority,
79
+ assignee: change.currentState.assignee,
80
+ },
81
+ }));
82
+ }
83
+ catch (err) {
84
+ this.logger.debug(`ADO not configured or error: ${err.message}`);
85
+ return [];
86
+ }
87
+ }
88
+ /**
89
+ * Fetch changes from JIRA
90
+ */
91
+ async fetchJiraChanges(since, linkedIssueKeys) {
92
+ try {
93
+ // Dynamic import to avoid initialization errors when JIRA is not configured
94
+ const { JiraClient } = await import('../integrations/jira/jira-client.js');
95
+ const client = new JiraClient();
96
+ const jiraChanges = await client.fetchRecentChanges(since, linkedIssueKeys);
97
+ // Map to unified format
98
+ return jiraChanges.map(change => ({
99
+ platform: 'jira',
100
+ externalId: change.externalId,
101
+ changedAt: change.changedAt,
102
+ changedBy: change.changedBy,
103
+ changedFields: change.changedFields,
104
+ currentState: {
105
+ status: change.currentState.status,
106
+ priority: change.currentState.priority,
107
+ assignee: change.currentState.assignee,
108
+ },
109
+ }));
110
+ }
111
+ catch (err) {
112
+ this.logger.debug(`JIRA not configured or error: ${err.message}`);
113
+ return [];
114
+ }
115
+ }
116
+ /**
117
+ * Fetch changes from GitHub
118
+ */
119
+ async fetchGitHubChanges(since, linkedIssueNumbers) {
120
+ try {
121
+ // Dynamic import to avoid initialization errors when GitHub is not configured
122
+ const { GitHubClientV2 } = await import('../../plugins/specweave-github/lib/github-client-v2.js');
123
+ // Detect repo from git remote
124
+ const detected = await GitHubClientV2.detectRepo(this.projectRoot);
125
+ if (!detected) {
126
+ this.logger.debug('GitHub: No git remote detected');
127
+ return [];
128
+ }
129
+ const client = GitHubClientV2.fromRepo(detected.owner, detected.repo);
130
+ const githubChanges = await client.fetchRecentChanges(since, linkedIssueNumbers);
131
+ // Map to unified format (GitHub returns slightly different format)
132
+ return githubChanges.map(change => ({
133
+ platform: 'github',
134
+ externalId: change.externalId,
135
+ changedAt: change.changedAt,
136
+ changedBy: change.changedBy,
137
+ changedFields: change.changedFields,
138
+ currentState: {
139
+ status: change.currentState.status,
140
+ priority: null, // GitHub doesn't have priority
141
+ assignee: change.currentState.assignee,
142
+ },
143
+ }));
144
+ }
145
+ catch (err) {
146
+ this.logger.debug(`GitHub not configured or error: ${err.message}`);
147
+ return [];
148
+ }
149
+ }
150
+ /**
151
+ * Map external status to SpecWeave status
152
+ *
153
+ * Converts platform-specific status values to SpecWeave's status taxonomy.
154
+ */
155
+ mapToSpecWeaveStatus(platform, externalStatus) {
156
+ // Status mapping by platform
157
+ const statusMaps = {
158
+ ado: {
159
+ 'New': 'pending',
160
+ 'Active': 'in_progress',
161
+ 'Resolved': 'completed',
162
+ 'Closed': 'completed',
163
+ 'Removed': 'cancelled',
164
+ },
165
+ jira: {
166
+ 'To Do': 'pending',
167
+ 'In Progress': 'in_progress',
168
+ 'Done': 'completed',
169
+ 'Closed': 'completed',
170
+ 'Won\'t Do': 'cancelled',
171
+ },
172
+ github: {
173
+ 'open': 'in_progress',
174
+ 'closed': 'completed',
175
+ },
176
+ };
177
+ const map = statusMaps[platform] || {};
178
+ return map[externalStatus] || externalStatus.toLowerCase().replace(/\s+/g, '_');
179
+ }
180
+ }
181
+ //# sourceMappingURL=external-change-puller.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"external-change-puller.js","sourceRoot":"","sources":["../../../src/sync/external-change-puller.ts"],"names":[],"mappings":"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"}