openspecui 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (311) hide show
  1. package/.gitmodules +3 -0
  2. package/CHAT.md +3 -0
  3. package/package.json +12 -0
  4. package/references/openspec/.changeset/README.md +6 -0
  5. package/references/openspec/.changeset/config.json +12 -0
  6. package/references/openspec/.coderabbit.yaml +11 -0
  7. package/references/openspec/.devcontainer/README.md +92 -0
  8. package/references/openspec/.devcontainer/devcontainer.json +68 -0
  9. package/references/openspec/.github/CODEOWNERS +2 -0
  10. package/references/openspec/.github/workflows/ci.yml +222 -0
  11. package/references/openspec/.github/workflows/release-prepare.yml +50 -0
  12. package/references/openspec/AGENTS.md +18 -0
  13. package/references/openspec/CHANGELOG.md +205 -0
  14. package/references/openspec/LICENSE +22 -0
  15. package/references/openspec/README.md +374 -0
  16. package/references/openspec/assets/openspec_dashboard.png +0 -0
  17. package/references/openspec/assets/openspec_pixel_dark.svg +89 -0
  18. package/references/openspec/assets/openspec_pixel_light.svg +89 -0
  19. package/references/openspec/bin/openspec.js +3 -0
  20. package/references/openspec/build.js +31 -0
  21. package/references/openspec/openspec/AGENTS.md +454 -0
  22. package/references/openspec/openspec/changes/IMPLEMENTATION_ORDER.md +68 -0
  23. package/references/openspec/openspec/changes/add-antigravity-support/proposal.md +11 -0
  24. package/references/openspec/openspec/changes/add-antigravity-support/specs/cli-init/spec.md +9 -0
  25. package/references/openspec/openspec/changes/add-antigravity-support/specs/cli-update/spec.md +8 -0
  26. package/references/openspec/openspec/changes/add-antigravity-support/tasks.md +12 -0
  27. package/references/openspec/openspec/changes/add-scaffold-command/proposal.md +11 -0
  28. package/references/openspec/openspec/changes/add-scaffold-command/specs/cli-scaffold/spec.md +36 -0
  29. package/references/openspec/openspec/changes/add-scaffold-command/tasks.md +12 -0
  30. package/references/openspec/openspec/changes/archive/2025-01-11-add-update-command/design.md +86 -0
  31. package/references/openspec/openspec/changes/archive/2025-01-11-add-update-command/proposal.md +29 -0
  32. package/references/openspec/openspec/changes/archive/2025-01-11-add-update-command/specs/cli-update/spec.md +59 -0
  33. package/references/openspec/openspec/changes/archive/2025-01-11-add-update-command/tasks.md +20 -0
  34. package/references/openspec/openspec/changes/archive/2025-01-13-add-list-command/proposal.md +20 -0
  35. package/references/openspec/openspec/changes/archive/2025-01-13-add-list-command/specs/cli-list/spec.md +69 -0
  36. package/references/openspec/openspec/changes/archive/2025-01-13-add-list-command/tasks.md +26 -0
  37. package/references/openspec/openspec/changes/archive/2025-08-05-initialize-typescript-project/design.md +64 -0
  38. package/references/openspec/openspec/changes/archive/2025-08-05-initialize-typescript-project/proposal.md +18 -0
  39. package/references/openspec/openspec/changes/archive/2025-08-05-initialize-typescript-project/tasks.md +25 -0
  40. package/references/openspec/openspec/changes/archive/2025-08-06-add-init-command/design.md +104 -0
  41. package/references/openspec/openspec/changes/archive/2025-08-06-add-init-command/proposal.md +30 -0
  42. package/references/openspec/openspec/changes/archive/2025-08-06-add-init-command/specs/cli-init/spec.md +148 -0
  43. package/references/openspec/openspec/changes/archive/2025-08-06-add-init-command/tasks.md +38 -0
  44. package/references/openspec/openspec/changes/archive/2025-08-06-adopt-future-state-storage/proposal.md +24 -0
  45. package/references/openspec/openspec/changes/archive/2025-08-06-adopt-future-state-storage/specs/openspec-conventions/spec.md +120 -0
  46. package/references/openspec/openspec/changes/archive/2025-08-06-adopt-future-state-storage/tasks.md +38 -0
  47. package/references/openspec/openspec/changes/archive/2025-08-11-add-complexity-guidelines/proposal.md +13 -0
  48. package/references/openspec/openspec/changes/archive/2025-08-11-add-complexity-guidelines/specs/openspec-docs/README.md +472 -0
  49. package/references/openspec/openspec/changes/archive/2025-08-11-add-complexity-guidelines/tasks.md +9 -0
  50. package/references/openspec/openspec/changes/archive/2025-08-13-add-archive-command/proposal.md +15 -0
  51. package/references/openspec/openspec/changes/archive/2025-08-13-add-archive-command/specs/cli-archive/spec.md +111 -0
  52. package/references/openspec/openspec/changes/archive/2025-08-13-add-archive-command/tasks.md +44 -0
  53. package/references/openspec/openspec/changes/archive/2025-08-13-add-diff-command/proposal.md +19 -0
  54. package/references/openspec/openspec/changes/archive/2025-08-13-add-diff-command/specs/cli-diff/spec.md +77 -0
  55. package/references/openspec/openspec/changes/archive/2025-08-13-add-diff-command/tasks.md +23 -0
  56. package/references/openspec/openspec/changes/archive/2025-08-19-add-change-commands/design.md +56 -0
  57. package/references/openspec/openspec/changes/archive/2025-08-19-add-change-commands/proposal.md +17 -0
  58. package/references/openspec/openspec/changes/archive/2025-08-19-add-change-commands/specs/cli-change/spec.md +48 -0
  59. package/references/openspec/openspec/changes/archive/2025-08-19-add-change-commands/specs/cli-list/spec.md +12 -0
  60. package/references/openspec/openspec/changes/archive/2025-08-19-add-change-commands/tasks.md +34 -0
  61. package/references/openspec/openspec/changes/archive/2025-08-19-add-interactive-show-command/proposal.md +20 -0
  62. package/references/openspec/openspec/changes/archive/2025-08-19-add-interactive-show-command/specs/cli-change/spec.md +23 -0
  63. package/references/openspec/openspec/changes/archive/2025-08-19-add-interactive-show-command/specs/cli-show/spec.md +83 -0
  64. package/references/openspec/openspec/changes/archive/2025-08-19-add-interactive-show-command/specs/cli-spec/spec.md +23 -0
  65. package/references/openspec/openspec/changes/archive/2025-08-19-add-interactive-show-command/tasks.md +142 -0
  66. package/references/openspec/openspec/changes/archive/2025-08-19-add-skip-specs-archive-option/proposal.md +13 -0
  67. package/references/openspec/openspec/changes/archive/2025-08-19-add-skip-specs-archive-option/specs/cli-archive/spec.md +191 -0
  68. package/references/openspec/openspec/changes/archive/2025-08-19-add-skip-specs-archive-option/tasks.md +57 -0
  69. package/references/openspec/openspec/changes/archive/2025-08-19-add-spec-commands/design.md +45 -0
  70. package/references/openspec/openspec/changes/archive/2025-08-19-add-spec-commands/proposal.md +19 -0
  71. package/references/openspec/openspec/changes/archive/2025-08-19-add-spec-commands/specs/cli-spec/spec.md +43 -0
  72. package/references/openspec/openspec/changes/archive/2025-08-19-add-spec-commands/tasks.md +22 -0
  73. package/references/openspec/openspec/changes/archive/2025-08-19-add-zod-validation/design.md +104 -0
  74. package/references/openspec/openspec/changes/archive/2025-08-19-add-zod-validation/proposal.md +22 -0
  75. package/references/openspec/openspec/changes/archive/2025-08-19-add-zod-validation/specs/cli-archive/spec.md +18 -0
  76. package/references/openspec/openspec/changes/archive/2025-08-19-add-zod-validation/specs/cli-diff/spec.md +12 -0
  77. package/references/openspec/openspec/changes/archive/2025-08-19-add-zod-validation/tasks.md +59 -0
  78. package/references/openspec/openspec/changes/archive/2025-08-19-adopt-delta-based-changes/proposal.md +93 -0
  79. package/references/openspec/openspec/changes/archive/2025-08-19-adopt-delta-based-changes/specs/cli-archive/spec.md +48 -0
  80. package/references/openspec/openspec/changes/archive/2025-08-19-adopt-delta-based-changes/specs/cli-diff/spec.md +45 -0
  81. package/references/openspec/openspec/changes/archive/2025-08-19-adopt-delta-based-changes/specs/openspec-conventions/spec.md +101 -0
  82. package/references/openspec/openspec/changes/archive/2025-08-19-adopt-delta-based-changes/tasks.md +55 -0
  83. package/references/openspec/openspec/changes/archive/2025-08-19-adopt-verb-noun-cli-structure/design.md +19 -0
  84. package/references/openspec/openspec/changes/archive/2025-08-19-adopt-verb-noun-cli-structure/proposal.md +67 -0
  85. package/references/openspec/openspec/changes/archive/2025-08-19-adopt-verb-noun-cli-structure/specs/cli-list/spec.md +57 -0
  86. package/references/openspec/openspec/changes/archive/2025-08-19-adopt-verb-noun-cli-structure/specs/openspec-conventions/spec.md +23 -0
  87. package/references/openspec/openspec/changes/archive/2025-08-19-adopt-verb-noun-cli-structure/tasks.md +27 -0
  88. package/references/openspec/openspec/changes/archive/2025-08-19-bulk-validation-interactive-selection/proposal.md +20 -0
  89. package/references/openspec/openspec/changes/archive/2025-08-19-bulk-validation-interactive-selection/specs/cli-change/spec.md +22 -0
  90. package/references/openspec/openspec/changes/archive/2025-08-19-bulk-validation-interactive-selection/specs/cli-spec/spec.md +23 -0
  91. package/references/openspec/openspec/changes/archive/2025-08-19-bulk-validation-interactive-selection/specs/cli-validate/spec.md +149 -0
  92. package/references/openspec/openspec/changes/archive/2025-08-19-bulk-validation-interactive-selection/tasks.md +81 -0
  93. package/references/openspec/openspec/changes/archive/2025-08-19-fix-update-tool-selection/proposal.md +40 -0
  94. package/references/openspec/openspec/changes/archive/2025-08-19-fix-update-tool-selection/specs/cli-update/spec.md +23 -0
  95. package/references/openspec/openspec/changes/archive/2025-08-19-fix-update-tool-selection/tasks.md +21 -0
  96. package/references/openspec/openspec/changes/archive/2025-08-19-improve-validate-error-messages/proposal.md +25 -0
  97. package/references/openspec/openspec/changes/archive/2025-08-19-improve-validate-error-messages/specs/cli-validate/spec.md +55 -0
  98. package/references/openspec/openspec/changes/archive/2025-08-19-improve-validate-error-messages/tasks.md +21 -0
  99. package/references/openspec/openspec/changes/archive/2025-08-19-structured-spec-format/proposal.md +36 -0
  100. package/references/openspec/openspec/changes/archive/2025-08-19-structured-spec-format/specs/openspec-conventions/spec.md +192 -0
  101. package/references/openspec/openspec/changes/archive/2025-08-19-structured-spec-format/tasks.md +19 -0
  102. package/references/openspec/openspec/changes/archive/2025-09-12-add-view-dashboard-command/proposal.md +38 -0
  103. package/references/openspec/openspec/changes/archive/2025-09-12-add-view-dashboard-command/specs/cli-view/spec.md +109 -0
  104. package/references/openspec/openspec/changes/archive/2025-09-12-add-view-dashboard-command/tasks.md +47 -0
  105. package/references/openspec/openspec/changes/archive/2025-09-29-add-agents-md-config/proposal.md +28 -0
  106. package/references/openspec/openspec/changes/archive/2025-09-29-add-agents-md-config/specs/cli-init/spec.md +71 -0
  107. package/references/openspec/openspec/changes/archive/2025-09-29-add-agents-md-config/specs/cli-update/spec.md +41 -0
  108. package/references/openspec/openspec/changes/archive/2025-09-29-add-agents-md-config/tasks.md +17 -0
  109. package/references/openspec/openspec/changes/archive/2025-09-29-add-multi-agent-init/proposal.md +35 -0
  110. package/references/openspec/openspec/changes/archive/2025-09-29-add-multi-agent-init/specs/cli-init/spec.md +45 -0
  111. package/references/openspec/openspec/changes/archive/2025-09-29-add-multi-agent-init/tasks.md +16 -0
  112. package/references/openspec/openspec/changes/archive/2025-09-29-add-slash-command-support/proposal.md +119 -0
  113. package/references/openspec/openspec/changes/archive/2025-09-29-add-slash-command-support/specs/cli-init/spec.md +21 -0
  114. package/references/openspec/openspec/changes/archive/2025-09-29-add-slash-command-support/specs/cli-update/spec.md +22 -0
  115. package/references/openspec/openspec/changes/archive/2025-09-29-add-slash-command-support/tasks.md +20 -0
  116. package/references/openspec/openspec/changes/archive/2025-09-29-improve-cli-e2e-plan/proposal.md +19 -0
  117. package/references/openspec/openspec/changes/archive/2025-09-29-improve-cli-e2e-plan/tasks.md +9 -0
  118. package/references/openspec/openspec/changes/archive/2025-09-29-improve-deterministic-tests/proposal.md +78 -0
  119. package/references/openspec/openspec/changes/archive/2025-09-29-improve-deterministic-tests/tasks.md +25 -0
  120. package/references/openspec/openspec/changes/archive/2025-09-29-improve-init-onboarding/proposal.md +13 -0
  121. package/references/openspec/openspec/changes/archive/2025-09-29-improve-init-onboarding/specs/cli-init/spec.md +92 -0
  122. package/references/openspec/openspec/changes/archive/2025-09-29-improve-init-onboarding/tasks.md +12 -0
  123. package/references/openspec/openspec/changes/archive/2025-09-29-remove-diff-command/proposal.md +81 -0
  124. package/references/openspec/openspec/changes/archive/2025-09-29-remove-diff-command/tasks.md +37 -0
  125. package/references/openspec/openspec/changes/archive/2025-09-29-sort-active-changes-by-progress/proposal.md +25 -0
  126. package/references/openspec/openspec/changes/archive/2025-09-29-sort-active-changes-by-progress/specs/cli-view/spec.md +9 -0
  127. package/references/openspec/openspec/changes/archive/2025-09-29-sort-active-changes-by-progress/tasks.md +8 -0
  128. package/references/openspec/openspec/changes/archive/2025-09-29-update-agent-file-name/proposal.md +29 -0
  129. package/references/openspec/openspec/changes/archive/2025-09-29-update-agent-file-name/specs/cli-init/spec.md +40 -0
  130. package/references/openspec/openspec/changes/archive/2025-09-29-update-agent-file-name/specs/cli-update/spec.md +22 -0
  131. package/references/openspec/openspec/changes/archive/2025-09-29-update-agent-file-name/specs/openspec-conventions/spec.md +27 -0
  132. package/references/openspec/openspec/changes/archive/2025-09-29-update-agent-file-name/tasks.md +22 -0
  133. package/references/openspec/openspec/changes/archive/2025-09-29-update-agent-instructions/design.md +130 -0
  134. package/references/openspec/openspec/changes/archive/2025-09-29-update-agent-instructions/proposal.md +117 -0
  135. package/references/openspec/openspec/changes/archive/2025-09-29-update-agent-instructions/tasks.md +69 -0
  136. package/references/openspec/openspec/changes/archive/2025-09-29-update-markdown-parser-crlf/proposal.md +19 -0
  137. package/references/openspec/openspec/changes/archive/2025-09-29-update-markdown-parser-crlf/specs/cli-validate/spec.md +9 -0
  138. package/references/openspec/openspec/changes/archive/2025-09-29-update-markdown-parser-crlf/tasks.md +11 -0
  139. package/references/openspec/openspec/changes/archive/2025-10-14-add-codex-slash-command-support/proposal.md +25 -0
  140. package/references/openspec/openspec/changes/archive/2025-10-14-add-codex-slash-command-support/specs/cli-init/spec.md +56 -0
  141. package/references/openspec/openspec/changes/archive/2025-10-14-add-codex-slash-command-support/specs/cli-update/spec.md +41 -0
  142. package/references/openspec/openspec/changes/archive/2025-10-14-add-codex-slash-command-support/tasks.md +19 -0
  143. package/references/openspec/openspec/changes/archive/2025-10-14-add-github-copilot-prompts/proposal.md +25 -0
  144. package/references/openspec/openspec/changes/archive/2025-10-14-add-github-copilot-prompts/specs/cli-init/spec.md +48 -0
  145. package/references/openspec/openspec/changes/archive/2025-10-14-add-github-copilot-prompts/specs/cli-update/spec.md +48 -0
  146. package/references/openspec/openspec/changes/archive/2025-10-14-add-github-copilot-prompts/tasks.md +30 -0
  147. package/references/openspec/openspec/changes/archive/2025-10-14-add-kilocode-workflows/proposal.md +17 -0
  148. package/references/openspec/openspec/changes/archive/2025-10-14-add-kilocode-workflows/specs/cli-init/spec.md +43 -0
  149. package/references/openspec/openspec/changes/archive/2025-10-14-add-kilocode-workflows/specs/cli-update/spec.md +27 -0
  150. package/references/openspec/openspec/changes/archive/2025-10-14-add-kilocode-workflows/tasks.md +15 -0
  151. package/references/openspec/openspec/changes/archive/2025-10-14-add-non-interactive-init-options/proposal.md +12 -0
  152. package/references/openspec/openspec/changes/archive/2025-10-14-add-non-interactive-init-options/specs/cli-init/spec.md +39 -0
  153. package/references/openspec/openspec/changes/archive/2025-10-14-add-non-interactive-init-options/tasks.md +17 -0
  154. package/references/openspec/openspec/changes/archive/2025-10-14-add-windsurf-workflows/proposal.md +17 -0
  155. package/references/openspec/openspec/changes/archive/2025-10-14-add-windsurf-workflows/specs/cli-init/spec.md +42 -0
  156. package/references/openspec/openspec/changes/archive/2025-10-14-add-windsurf-workflows/specs/cli-update/spec.md +27 -0
  157. package/references/openspec/openspec/changes/archive/2025-10-14-add-windsurf-workflows/tasks.md +17 -0
  158. package/references/openspec/openspec/changes/archive/2025-10-14-enhance-validation-error-messages/proposal.md +12 -0
  159. package/references/openspec/openspec/changes/archive/2025-10-14-enhance-validation-error-messages/specs/cli-validate/spec.md +39 -0
  160. package/references/openspec/openspec/changes/archive/2025-10-14-enhance-validation-error-messages/tasks.md +12 -0
  161. package/references/openspec/openspec/changes/archive/2025-10-14-improve-agent-instruction-usability/proposal.md +12 -0
  162. package/references/openspec/openspec/changes/archive/2025-10-14-improve-agent-instruction-usability/specs/docs-agent-instructions/spec.md +33 -0
  163. package/references/openspec/openspec/changes/archive/2025-10-14-improve-agent-instruction-usability/tasks.md +11 -0
  164. package/references/openspec/openspec/changes/archive/2025-10-14-slim-root-agents-file/proposal.md +13 -0
  165. package/references/openspec/openspec/changes/archive/2025-10-14-slim-root-agents-file/tasks.md +15 -0
  166. package/references/openspec/openspec/changes/archive/2025-10-14-update-cli-init-enter-selection/proposal.md +14 -0
  167. package/references/openspec/openspec/changes/archive/2025-10-14-update-cli-init-enter-selection/specs/cli-init/spec.md +10 -0
  168. package/references/openspec/openspec/changes/archive/2025-10-14-update-cli-init-enter-selection/tasks.md +8 -0
  169. package/references/openspec/openspec/changes/archive/2025-10-14-update-cli-init-root-agents/proposal.md +15 -0
  170. package/references/openspec/openspec/changes/archive/2025-10-14-update-cli-init-root-agents/specs/cli-init/spec.md +32 -0
  171. package/references/openspec/openspec/changes/archive/2025-10-14-update-cli-init-root-agents/specs/cli-update/spec.md +10 -0
  172. package/references/openspec/openspec/changes/archive/2025-10-14-update-cli-init-root-agents/tasks.md +11 -0
  173. package/references/openspec/openspec/changes/archive/2025-10-14-update-release-automation/proposal.md +49 -0
  174. package/references/openspec/openspec/changes/archive/2025-10-14-update-release-automation/tasks.md +12 -0
  175. package/references/openspec/openspec/changes/archive/2025-10-22-add-archive-command-arguments/proposal.md +17 -0
  176. package/references/openspec/openspec/changes/archive/2025-10-22-add-archive-command-arguments/specs/cli-update/spec.md +32 -0
  177. package/references/openspec/openspec/changes/archive/2025-10-22-add-archive-command-arguments/tasks.md +15 -0
  178. package/references/openspec/openspec/changes/archive/2025-10-22-add-cline-support/proposal.md +15 -0
  179. package/references/openspec/openspec/changes/archive/2025-10-22-add-cline-support/specs/cli-init/spec.md +97 -0
  180. package/references/openspec/openspec/changes/archive/2025-10-22-add-cline-support/tasks.md +19 -0
  181. package/references/openspec/openspec/changes/archive/2025-10-22-add-crush-support/proposal.md +13 -0
  182. package/references/openspec/openspec/changes/archive/2025-10-22-add-crush-support/specs/cli-init/spec.md +67 -0
  183. package/references/openspec/openspec/changes/archive/2025-10-22-add-crush-support/tasks.md +7 -0
  184. package/references/openspec/openspec/changes/archive/2025-10-22-add-factory-slash-commands/proposal.md +12 -0
  185. package/references/openspec/openspec/changes/archive/2025-10-22-add-factory-slash-commands/specs/cli-init/spec.md +54 -0
  186. package/references/openspec/openspec/changes/archive/2025-10-22-add-factory-slash-commands/specs/cli-update/spec.md +54 -0
  187. package/references/openspec/openspec/changes/archive/2025-10-22-add-factory-slash-commands/tasks.md +11 -0
  188. package/references/openspec/openspec/changes/fix-cline-workflows-implementation/proposal.md +13 -0
  189. package/references/openspec/openspec/changes/fix-cline-workflows-implementation/specs/cli-init/spec.md +11 -0
  190. package/references/openspec/openspec/changes/fix-cline-workflows-implementation/tasks.md +13 -0
  191. package/references/openspec/openspec/changes/make-validation-scope-aware/proposal.md +12 -0
  192. package/references/openspec/openspec/changes/make-validation-scope-aware/specs/cli-validate/spec.md +25 -0
  193. package/references/openspec/openspec/changes/make-validation-scope-aware/tasks.md +16 -0
  194. package/references/openspec/openspec/project.md +53 -0
  195. package/references/openspec/openspec/specs/cli-archive/spec.md +210 -0
  196. package/references/openspec/openspec/specs/cli-change/spec.md +91 -0
  197. package/references/openspec/openspec/specs/cli-init/spec.md +311 -0
  198. package/references/openspec/openspec/specs/cli-list/spec.md +103 -0
  199. package/references/openspec/openspec/specs/cli-show/spec.md +85 -0
  200. package/references/openspec/openspec/specs/cli-spec/spec.md +87 -0
  201. package/references/openspec/openspec/specs/cli-update/spec.md +190 -0
  202. package/references/openspec/openspec/specs/cli-validate/spec.md +218 -0
  203. package/references/openspec/openspec/specs/cli-view/spec.md +105 -0
  204. package/references/openspec/openspec/specs/docs-agent-instructions/spec.md +38 -0
  205. package/references/openspec/openspec/specs/openspec-conventions/spec.md +474 -0
  206. package/references/openspec/openspec-parallel-merge-plan.md +98 -0
  207. package/references/openspec/package.json +73 -0
  208. package/references/openspec/pnpm-lock.yaml +2324 -0
  209. package/references/openspec/scripts/pack-version-check.mjs +111 -0
  210. package/references/openspec/src/cli/index.ts +253 -0
  211. package/references/openspec/src/commands/change.ts +291 -0
  212. package/references/openspec/src/commands/show.ts +139 -0
  213. package/references/openspec/src/commands/spec.ts +250 -0
  214. package/references/openspec/src/commands/validate.ts +305 -0
  215. package/references/openspec/src/core/archive.ts +606 -0
  216. package/references/openspec/src/core/config.ts +41 -0
  217. package/references/openspec/src/core/configurators/agents.ts +23 -0
  218. package/references/openspec/src/core/configurators/base.ts +6 -0
  219. package/references/openspec/src/core/configurators/claude.ts +23 -0
  220. package/references/openspec/src/core/configurators/cline.ts +23 -0
  221. package/references/openspec/src/core/configurators/codebuddy.ts +24 -0
  222. package/references/openspec/src/core/configurators/costrict.ts +23 -0
  223. package/references/openspec/src/core/configurators/iflow.ts +23 -0
  224. package/references/openspec/src/core/configurators/qoder.ts +53 -0
  225. package/references/openspec/src/core/configurators/qwen.ts +47 -0
  226. package/references/openspec/src/core/configurators/registry.ts +49 -0
  227. package/references/openspec/src/core/configurators/slash/amazon-q.ts +51 -0
  228. package/references/openspec/src/core/configurators/slash/antigravity.ts +28 -0
  229. package/references/openspec/src/core/configurators/slash/auggie.ts +37 -0
  230. package/references/openspec/src/core/configurators/slash/base.ts +95 -0
  231. package/references/openspec/src/core/configurators/slash/claude.ts +42 -0
  232. package/references/openspec/src/core/configurators/slash/cline.ts +27 -0
  233. package/references/openspec/src/core/configurators/slash/codebuddy.ts +43 -0
  234. package/references/openspec/src/core/configurators/slash/codex.ts +126 -0
  235. package/references/openspec/src/core/configurators/slash/costrict.ts +36 -0
  236. package/references/openspec/src/core/configurators/slash/crush.ts +42 -0
  237. package/references/openspec/src/core/configurators/slash/cursor.ts +42 -0
  238. package/references/openspec/src/core/configurators/slash/factory.ts +41 -0
  239. package/references/openspec/src/core/configurators/slash/gemini.ts +27 -0
  240. package/references/openspec/src/core/configurators/slash/github-copilot.ts +39 -0
  241. package/references/openspec/src/core/configurators/slash/iflow.ts +42 -0
  242. package/references/openspec/src/core/configurators/slash/kilocode.ts +21 -0
  243. package/references/openspec/src/core/configurators/slash/opencode.ts +83 -0
  244. package/references/openspec/src/core/configurators/slash/qoder.ts +84 -0
  245. package/references/openspec/src/core/configurators/slash/qwen.ts +55 -0
  246. package/references/openspec/src/core/configurators/slash/registry.ts +81 -0
  247. package/references/openspec/src/core/configurators/slash/roocode.ts +27 -0
  248. package/references/openspec/src/core/configurators/slash/toml-base.ts +66 -0
  249. package/references/openspec/src/core/configurators/slash/windsurf.ts +27 -0
  250. package/references/openspec/src/core/converters/json-converter.ts +61 -0
  251. package/references/openspec/src/core/index.ts +2 -0
  252. package/references/openspec/src/core/init.ts +986 -0
  253. package/references/openspec/src/core/list.ts +104 -0
  254. package/references/openspec/src/core/parsers/change-parser.ts +234 -0
  255. package/references/openspec/src/core/parsers/markdown-parser.ts +237 -0
  256. package/references/openspec/src/core/parsers/requirement-blocks.ts +234 -0
  257. package/references/openspec/src/core/schemas/base.schema.ts +20 -0
  258. package/references/openspec/src/core/schemas/change.schema.ts +42 -0
  259. package/references/openspec/src/core/schemas/index.ts +20 -0
  260. package/references/openspec/src/core/schemas/spec.schema.ts +17 -0
  261. package/references/openspec/src/core/styles/palette.ts +8 -0
  262. package/references/openspec/src/core/templates/agents-root-stub.ts +16 -0
  263. package/references/openspec/src/core/templates/agents-template.ts +457 -0
  264. package/references/openspec/src/core/templates/claude-template.ts +1 -0
  265. package/references/openspec/src/core/templates/cline-template.ts +1 -0
  266. package/references/openspec/src/core/templates/costrict-template.ts +1 -0
  267. package/references/openspec/src/core/templates/index.ts +50 -0
  268. package/references/openspec/src/core/templates/project-template.ts +38 -0
  269. package/references/openspec/src/core/templates/slash-command-templates.ts +60 -0
  270. package/references/openspec/src/core/update.ts +129 -0
  271. package/references/openspec/src/core/validation/constants.ts +48 -0
  272. package/references/openspec/src/core/validation/types.ts +19 -0
  273. package/references/openspec/src/core/validation/validator.ts +448 -0
  274. package/references/openspec/src/core/view.ts +189 -0
  275. package/references/openspec/src/index.ts +2 -0
  276. package/references/openspec/src/utils/file-system.ts +187 -0
  277. package/references/openspec/src/utils/index.ts +2 -0
  278. package/references/openspec/src/utils/interactive.ts +7 -0
  279. package/references/openspec/src/utils/item-discovery.ts +45 -0
  280. package/references/openspec/src/utils/match.ts +26 -0
  281. package/references/openspec/src/utils/task-progress.ts +43 -0
  282. package/references/openspec/test/cli-e2e/basic.test.ts +156 -0
  283. package/references/openspec/test/commands/change.interactive-show.test.ts +45 -0
  284. package/references/openspec/test/commands/change.interactive-validate.test.ts +48 -0
  285. package/references/openspec/test/commands/show.test.ts +123 -0
  286. package/references/openspec/test/commands/spec.interactive-show.test.ts +44 -0
  287. package/references/openspec/test/commands/spec.interactive-validate.test.ts +44 -0
  288. package/references/openspec/test/commands/spec.test.ts +324 -0
  289. package/references/openspec/test/commands/validate.enriched-output.test.ts +49 -0
  290. package/references/openspec/test/commands/validate.test.ts +133 -0
  291. package/references/openspec/test/core/archive.test.ts +680 -0
  292. package/references/openspec/test/core/commands/change-command.list.test.ts +76 -0
  293. package/references/openspec/test/core/commands/change-command.show-validate.test.ts +111 -0
  294. package/references/openspec/test/core/converters/json-converter.test.ts +184 -0
  295. package/references/openspec/test/core/init.test.ts +1710 -0
  296. package/references/openspec/test/core/list.test.ts +165 -0
  297. package/references/openspec/test/core/parsers/change-parser.test.ts +52 -0
  298. package/references/openspec/test/core/parsers/markdown-parser.test.ts +291 -0
  299. package/references/openspec/test/core/update.test.ts +1642 -0
  300. package/references/openspec/test/core/validation.enriched-messages.test.ts +74 -0
  301. package/references/openspec/test/core/validation.test.ts +489 -0
  302. package/references/openspec/test/core/view.test.ts +79 -0
  303. package/references/openspec/test/fixtures/tmp-init/openspec/changes/c1/proposal.md +7 -0
  304. package/references/openspec/test/fixtures/tmp-init/openspec/changes/c1/specs/alpha/spec.md +8 -0
  305. package/references/openspec/test/fixtures/tmp-init/openspec/specs/alpha/spec.md +12 -0
  306. package/references/openspec/test/helpers/run-cli.ts +139 -0
  307. package/references/openspec/test/utils/file-system.test.ts +211 -0
  308. package/references/openspec/test/utils/marker-updates.test.ts +287 -0
  309. package/references/openspec/tsconfig.json +21 -0
  310. package/references/openspec/vitest.config.ts +25 -0
  311. package/references/openspec/vitest.setup.ts +6 -0
@@ -0,0 +1,104 @@
1
+ import { promises as fs } from 'fs';
2
+ import path from 'path';
3
+ import { getTaskProgressForChange, formatTaskStatus } from '../utils/task-progress.js';
4
+ import { readFileSync } from 'fs';
5
+ import { join } from 'path';
6
+ import { MarkdownParser } from './parsers/markdown-parser.js';
7
+
8
+ interface ChangeInfo {
9
+ name: string;
10
+ completedTasks: number;
11
+ totalTasks: number;
12
+ }
13
+
14
+ export class ListCommand {
15
+ async execute(targetPath: string = '.', mode: 'changes' | 'specs' = 'changes'): Promise<void> {
16
+ if (mode === 'changes') {
17
+ const changesDir = path.join(targetPath, 'openspec', 'changes');
18
+
19
+ // Check if changes directory exists
20
+ try {
21
+ await fs.access(changesDir);
22
+ } catch {
23
+ throw new Error("No OpenSpec changes directory found. Run 'openspec init' first.");
24
+ }
25
+
26
+ // Get all directories in changes (excluding archive)
27
+ const entries = await fs.readdir(changesDir, { withFileTypes: true });
28
+ const changeDirs = entries
29
+ .filter(entry => entry.isDirectory() && entry.name !== 'archive')
30
+ .map(entry => entry.name);
31
+
32
+ if (changeDirs.length === 0) {
33
+ console.log('No active changes found.');
34
+ return;
35
+ }
36
+
37
+ // Collect information about each change
38
+ const changes: ChangeInfo[] = [];
39
+
40
+ for (const changeDir of changeDirs) {
41
+ const progress = await getTaskProgressForChange(changesDir, changeDir);
42
+ changes.push({
43
+ name: changeDir,
44
+ completedTasks: progress.completed,
45
+ totalTasks: progress.total
46
+ });
47
+ }
48
+
49
+ // Sort alphabetically by name
50
+ changes.sort((a, b) => a.name.localeCompare(b.name));
51
+
52
+ // Display results
53
+ console.log('Changes:');
54
+ const padding = ' ';
55
+ const nameWidth = Math.max(...changes.map(c => c.name.length));
56
+ for (const change of changes) {
57
+ const paddedName = change.name.padEnd(nameWidth);
58
+ const status = formatTaskStatus({ total: change.totalTasks, completed: change.completedTasks });
59
+ console.log(`${padding}${paddedName} ${status}`);
60
+ }
61
+ return;
62
+ }
63
+
64
+ // specs mode
65
+ const specsDir = path.join(targetPath, 'openspec', 'specs');
66
+ try {
67
+ await fs.access(specsDir);
68
+ } catch {
69
+ console.log('No specs found.');
70
+ return;
71
+ }
72
+
73
+ const entries = await fs.readdir(specsDir, { withFileTypes: true });
74
+ const specDirs = entries.filter(e => e.isDirectory()).map(e => e.name);
75
+ if (specDirs.length === 0) {
76
+ console.log('No specs found.');
77
+ return;
78
+ }
79
+
80
+ type SpecInfo = { id: string; requirementCount: number };
81
+ const specs: SpecInfo[] = [];
82
+ for (const id of specDirs) {
83
+ const specPath = join(specsDir, id, 'spec.md');
84
+ try {
85
+ const content = readFileSync(specPath, 'utf-8');
86
+ const parser = new MarkdownParser(content);
87
+ const spec = parser.parseSpec(id);
88
+ specs.push({ id, requirementCount: spec.requirements.length });
89
+ } catch {
90
+ // If spec cannot be read or parsed, include with 0 count
91
+ specs.push({ id, requirementCount: 0 });
92
+ }
93
+ }
94
+
95
+ specs.sort((a, b) => a.id.localeCompare(b.id));
96
+ console.log('Specs:');
97
+ const padding = ' ';
98
+ const nameWidth = Math.max(...specs.map(s => s.id.length));
99
+ for (const spec of specs) {
100
+ const padded = spec.id.padEnd(nameWidth);
101
+ console.log(`${padding}${padded} requirements ${spec.requirementCount}`);
102
+ }
103
+ }
104
+ }
@@ -0,0 +1,234 @@
1
+ import { MarkdownParser, Section } from './markdown-parser.js';
2
+ import { Change, Delta, DeltaOperation, Requirement } from '../schemas/index.js';
3
+ import path from 'path';
4
+ import { promises as fs } from 'fs';
5
+
6
+ interface DeltaSection {
7
+ operation: DeltaOperation;
8
+ requirements: Requirement[];
9
+ renames?: Array<{ from: string; to: string }>;
10
+ }
11
+
12
+ export class ChangeParser extends MarkdownParser {
13
+ private changeDir: string;
14
+
15
+ constructor(content: string, changeDir: string) {
16
+ super(content);
17
+ this.changeDir = changeDir;
18
+ }
19
+
20
+ async parseChangeWithDeltas(name: string): Promise<Change> {
21
+ const sections = this.parseSections();
22
+ const why = this.findSection(sections, 'Why')?.content || '';
23
+ const whatChanges = this.findSection(sections, 'What Changes')?.content || '';
24
+
25
+ if (!why) {
26
+ throw new Error('Change must have a Why section');
27
+ }
28
+
29
+ if (!whatChanges) {
30
+ throw new Error('Change must have a What Changes section');
31
+ }
32
+
33
+ // Parse deltas from the What Changes section (simple format)
34
+ const simpleDeltas = this.parseDeltas(whatChanges);
35
+
36
+ // Check if there are spec files with delta format
37
+ const specsDir = path.join(this.changeDir, 'specs');
38
+ const deltaDeltas = await this.parseDeltaSpecs(specsDir);
39
+
40
+ // Combine both types of deltas, preferring delta format if available
41
+ const deltas = deltaDeltas.length > 0 ? deltaDeltas : simpleDeltas;
42
+
43
+ return {
44
+ name,
45
+ why: why.trim(),
46
+ whatChanges: whatChanges.trim(),
47
+ deltas,
48
+ metadata: {
49
+ version: '1.0.0',
50
+ format: 'openspec-change',
51
+ },
52
+ };
53
+ }
54
+
55
+ private async parseDeltaSpecs(specsDir: string): Promise<Delta[]> {
56
+ const deltas: Delta[] = [];
57
+
58
+ try {
59
+ const specDirs = await fs.readdir(specsDir, { withFileTypes: true });
60
+
61
+ for (const dir of specDirs) {
62
+ if (!dir.isDirectory()) continue;
63
+
64
+ const specName = dir.name;
65
+ const specFile = path.join(specsDir, specName, 'spec.md');
66
+
67
+ try {
68
+ const content = await fs.readFile(specFile, 'utf-8');
69
+ const specDeltas = this.parseSpecDeltas(specName, content);
70
+ deltas.push(...specDeltas);
71
+ } catch (error) {
72
+ // Spec file might not exist, which is okay
73
+ continue;
74
+ }
75
+ }
76
+ } catch (error) {
77
+ // Specs directory might not exist, which is okay
78
+ return [];
79
+ }
80
+
81
+ return deltas;
82
+ }
83
+
84
+ private parseSpecDeltas(specName: string, content: string): Delta[] {
85
+ const deltas: Delta[] = [];
86
+ const sections = this.parseSectionsFromContent(content);
87
+
88
+ // Parse ADDED requirements
89
+ const addedSection = this.findSection(sections, 'ADDED Requirements');
90
+ if (addedSection) {
91
+ const requirements = this.parseRequirements(addedSection);
92
+ requirements.forEach(req => {
93
+ deltas.push({
94
+ spec: specName,
95
+ operation: 'ADDED' as DeltaOperation,
96
+ description: `Add requirement: ${req.text}`,
97
+ // Provide both single and plural forms for compatibility
98
+ requirement: req,
99
+ requirements: [req],
100
+ });
101
+ });
102
+ }
103
+
104
+ // Parse MODIFIED requirements
105
+ const modifiedSection = this.findSection(sections, 'MODIFIED Requirements');
106
+ if (modifiedSection) {
107
+ const requirements = this.parseRequirements(modifiedSection);
108
+ requirements.forEach(req => {
109
+ deltas.push({
110
+ spec: specName,
111
+ operation: 'MODIFIED' as DeltaOperation,
112
+ description: `Modify requirement: ${req.text}`,
113
+ requirement: req,
114
+ requirements: [req],
115
+ });
116
+ });
117
+ }
118
+
119
+ // Parse REMOVED requirements
120
+ const removedSection = this.findSection(sections, 'REMOVED Requirements');
121
+ if (removedSection) {
122
+ const requirements = this.parseRequirements(removedSection);
123
+ requirements.forEach(req => {
124
+ deltas.push({
125
+ spec: specName,
126
+ operation: 'REMOVED' as DeltaOperation,
127
+ description: `Remove requirement: ${req.text}`,
128
+ requirement: req,
129
+ requirements: [req],
130
+ });
131
+ });
132
+ }
133
+
134
+ // Parse RENAMED requirements
135
+ const renamedSection = this.findSection(sections, 'RENAMED Requirements');
136
+ if (renamedSection) {
137
+ const renames = this.parseRenames(renamedSection.content);
138
+ renames.forEach(rename => {
139
+ deltas.push({
140
+ spec: specName,
141
+ operation: 'RENAMED' as DeltaOperation,
142
+ description: `Rename requirement from "${rename.from}" to "${rename.to}"`,
143
+ rename,
144
+ });
145
+ });
146
+ }
147
+
148
+ return deltas;
149
+ }
150
+
151
+ private parseRenames(content: string): Array<{ from: string; to: string }> {
152
+ const renames: Array<{ from: string; to: string }> = [];
153
+ const lines = ChangeParser.normalizeContent(content).split('\n');
154
+
155
+ let currentRename: { from?: string; to?: string } = {};
156
+
157
+ for (const line of lines) {
158
+ const fromMatch = line.match(/^\s*-?\s*FROM:\s*`?###\s*Requirement:\s*(.+?)`?\s*$/);
159
+ const toMatch = line.match(/^\s*-?\s*TO:\s*`?###\s*Requirement:\s*(.+?)`?\s*$/);
160
+
161
+ if (fromMatch) {
162
+ currentRename.from = fromMatch[1].trim();
163
+ } else if (toMatch) {
164
+ currentRename.to = toMatch[1].trim();
165
+
166
+ if (currentRename.from && currentRename.to) {
167
+ renames.push({
168
+ from: currentRename.from,
169
+ to: currentRename.to,
170
+ });
171
+ currentRename = {};
172
+ }
173
+ }
174
+ }
175
+
176
+ return renames;
177
+ }
178
+
179
+ private parseSectionsFromContent(content: string): Section[] {
180
+ const normalizedContent = ChangeParser.normalizeContent(content);
181
+ const lines = normalizedContent.split('\n');
182
+ const sections: Section[] = [];
183
+ const stack: Section[] = [];
184
+
185
+ for (let i = 0; i < lines.length; i++) {
186
+ const line = lines[i];
187
+ const headerMatch = line.match(/^(#{1,6})\s+(.+)$/);
188
+
189
+ if (headerMatch) {
190
+ const level = headerMatch[1].length;
191
+ const title = headerMatch[2].trim();
192
+ const contentLines = this.getContentUntilNextHeaderFromLines(lines, i + 1, level);
193
+
194
+ const section = {
195
+ level,
196
+ title,
197
+ content: contentLines.join('\n').trim(),
198
+ children: [],
199
+ };
200
+
201
+ while (stack.length > 0 && stack[stack.length - 1].level >= level) {
202
+ stack.pop();
203
+ }
204
+
205
+ if (stack.length === 0) {
206
+ sections.push(section);
207
+ } else {
208
+ stack[stack.length - 1].children.push(section);
209
+ }
210
+
211
+ stack.push(section);
212
+ }
213
+ }
214
+
215
+ return sections;
216
+ }
217
+
218
+ private getContentUntilNextHeaderFromLines(lines: string[], startLine: number, currentLevel: number): string[] {
219
+ const contentLines: string[] = [];
220
+
221
+ for (let i = startLine; i < lines.length; i++) {
222
+ const line = lines[i];
223
+ const headerMatch = line.match(/^(#{1,6})\s+/);
224
+
225
+ if (headerMatch && headerMatch[1].length <= currentLevel) {
226
+ break;
227
+ }
228
+
229
+ contentLines.push(line);
230
+ }
231
+
232
+ return contentLines;
233
+ }
234
+ }
@@ -0,0 +1,237 @@
1
+ import { Spec, Change, Requirement, Scenario, Delta, DeltaOperation } from '../schemas/index.js';
2
+
3
+ export interface Section {
4
+ level: number;
5
+ title: string;
6
+ content: string;
7
+ children: Section[];
8
+ }
9
+
10
+ export class MarkdownParser {
11
+ private lines: string[];
12
+ private currentLine: number;
13
+
14
+ constructor(content: string) {
15
+ const normalized = MarkdownParser.normalizeContent(content);
16
+ this.lines = normalized.split('\n');
17
+ this.currentLine = 0;
18
+ }
19
+
20
+ protected static normalizeContent(content: string): string {
21
+ return content.replace(/\r\n?/g, '\n');
22
+ }
23
+
24
+ parseSpec(name: string): Spec {
25
+ const sections = this.parseSections();
26
+ const purpose = this.findSection(sections, 'Purpose')?.content || '';
27
+
28
+ const requirementsSection = this.findSection(sections, 'Requirements');
29
+
30
+ if (!purpose) {
31
+ throw new Error('Spec must have a Purpose section');
32
+ }
33
+
34
+ if (!requirementsSection) {
35
+ throw new Error('Spec must have a Requirements section');
36
+ }
37
+
38
+ const requirements = this.parseRequirements(requirementsSection);
39
+
40
+ return {
41
+ name,
42
+ overview: purpose.trim(),
43
+ requirements,
44
+ metadata: {
45
+ version: '1.0.0',
46
+ format: 'openspec',
47
+ },
48
+ };
49
+ }
50
+
51
+ parseChange(name: string): Change {
52
+ const sections = this.parseSections();
53
+ const why = this.findSection(sections, 'Why')?.content || '';
54
+ const whatChanges = this.findSection(sections, 'What Changes')?.content || '';
55
+
56
+ if (!why) {
57
+ throw new Error('Change must have a Why section');
58
+ }
59
+
60
+ if (!whatChanges) {
61
+ throw new Error('Change must have a What Changes section');
62
+ }
63
+
64
+ const deltas = this.parseDeltas(whatChanges);
65
+
66
+ return {
67
+ name,
68
+ why: why.trim(),
69
+ whatChanges: whatChanges.trim(),
70
+ deltas,
71
+ metadata: {
72
+ version: '1.0.0',
73
+ format: 'openspec-change',
74
+ },
75
+ };
76
+ }
77
+
78
+ protected parseSections(): Section[] {
79
+ const sections: Section[] = [];
80
+ const stack: Section[] = [];
81
+
82
+ for (let i = 0; i < this.lines.length; i++) {
83
+ const line = this.lines[i];
84
+ const headerMatch = line.match(/^(#{1,6})\s+(.+)$/);
85
+
86
+ if (headerMatch) {
87
+ const level = headerMatch[1].length;
88
+ const title = headerMatch[2].trim();
89
+ const content = this.getContentUntilNextHeader(i + 1, level);
90
+
91
+ const section: Section = {
92
+ level,
93
+ title,
94
+ content,
95
+ children: [],
96
+ };
97
+
98
+ while (stack.length > 0 && stack[stack.length - 1].level >= level) {
99
+ stack.pop();
100
+ }
101
+
102
+ if (stack.length === 0) {
103
+ sections.push(section);
104
+ } else {
105
+ stack[stack.length - 1].children.push(section);
106
+ }
107
+
108
+ stack.push(section);
109
+ }
110
+ }
111
+
112
+ return sections;
113
+ }
114
+
115
+ protected getContentUntilNextHeader(startLine: number, currentLevel: number): string {
116
+ const contentLines: string[] = [];
117
+
118
+ for (let i = startLine; i < this.lines.length; i++) {
119
+ const line = this.lines[i];
120
+ const headerMatch = line.match(/^(#{1,6})\s+/);
121
+
122
+ if (headerMatch && headerMatch[1].length <= currentLevel) {
123
+ break;
124
+ }
125
+
126
+ contentLines.push(line);
127
+ }
128
+
129
+ return contentLines.join('\n').trim();
130
+ }
131
+
132
+ protected findSection(sections: Section[], title: string): Section | undefined {
133
+ for (const section of sections) {
134
+ if (section.title.toLowerCase() === title.toLowerCase()) {
135
+ return section;
136
+ }
137
+ const child = this.findSection(section.children, title);
138
+ if (child) {
139
+ return child;
140
+ }
141
+ }
142
+ return undefined;
143
+ }
144
+
145
+ protected parseRequirements(section: Section): Requirement[] {
146
+ const requirements: Requirement[] = [];
147
+
148
+ for (const child of section.children) {
149
+ // Extract requirement text from first non-empty content line, fall back to heading
150
+ let text = child.title;
151
+
152
+ // Get content before any child sections (scenarios)
153
+ if (child.content.trim()) {
154
+ // Split content into lines and find content before any child headers
155
+ const lines = child.content.split('\n');
156
+ const contentBeforeChildren: string[] = [];
157
+
158
+ for (const line of lines) {
159
+ // Stop at child headers (scenarios start with ####)
160
+ if (line.trim().startsWith('#')) {
161
+ break;
162
+ }
163
+ contentBeforeChildren.push(line);
164
+ }
165
+
166
+ // Find first non-empty line
167
+ const directContent = contentBeforeChildren.join('\n').trim();
168
+ if (directContent) {
169
+ const firstLine = directContent.split('\n').find(l => l.trim());
170
+ if (firstLine) {
171
+ text = firstLine.trim();
172
+ }
173
+ }
174
+ }
175
+
176
+ const scenarios = this.parseScenarios(child);
177
+
178
+ requirements.push({
179
+ text,
180
+ scenarios,
181
+ });
182
+ }
183
+
184
+ return requirements;
185
+ }
186
+
187
+ protected parseScenarios(requirementSection: Section): Scenario[] {
188
+ const scenarios: Scenario[] = [];
189
+
190
+ for (const scenarioSection of requirementSection.children) {
191
+ // Store the raw text content of the scenario section
192
+ if (scenarioSection.content.trim()) {
193
+ scenarios.push({
194
+ rawText: scenarioSection.content
195
+ });
196
+ }
197
+ }
198
+
199
+ return scenarios;
200
+ }
201
+
202
+
203
+ protected parseDeltas(content: string): Delta[] {
204
+ const deltas: Delta[] = [];
205
+ const lines = content.split('\n');
206
+
207
+ for (const line of lines) {
208
+ // Match both formats: **spec:** and **spec**:
209
+ const deltaMatch = line.match(/^\s*-\s*\*\*([^*:]+)(?::\*\*|\*\*:)\s*(.+)$/);
210
+ if (deltaMatch) {
211
+ const specName = deltaMatch[1].trim();
212
+ const description = deltaMatch[2].trim();
213
+
214
+ let operation: DeltaOperation = 'MODIFIED';
215
+ const lowerDesc = description.toLowerCase();
216
+
217
+ // Use word boundaries to avoid false matches (e.g., "address" matching "add")
218
+ // Check RENAMED first since it's more specific than patterns containing "new"
219
+ if (/\brename(s|d|ing)?\b/.test(lowerDesc) || /\brenamed\s+(to|from)\b/.test(lowerDesc)) {
220
+ operation = 'RENAMED';
221
+ } else if (/\badd(s|ed|ing)?\b/.test(lowerDesc) || /\bcreate(s|d|ing)?\b/.test(lowerDesc) || /\bnew\b/.test(lowerDesc)) {
222
+ operation = 'ADDED';
223
+ } else if (/\bremove(s|d|ing)?\b/.test(lowerDesc) || /\bdelete(s|d|ing)?\b/.test(lowerDesc)) {
224
+ operation = 'REMOVED';
225
+ }
226
+
227
+ deltas.push({
228
+ spec: specName,
229
+ operation,
230
+ description,
231
+ });
232
+ }
233
+ }
234
+
235
+ return deltas;
236
+ }
237
+ }