sauron-cli 1.1.3 → 1.3.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 (671) hide show
  1. package/.agents/rules/memory.md +156 -0
  2. package/.agents/skills/wiki/SKILL.md +172 -0
  3. package/.aider.instructions.md +152 -0
  4. package/.cursor/rules/sauron-memory.mdc +157 -0
  5. package/.genesis/prompts/prompt-onboarding-inteligente.md +45 -0
  6. package/.genesis/prompts/prompt-sauron-vs-openspec-arquitetura.md +106 -0
  7. package/.github/workflows/ci.yml +27 -0
  8. package/.sauron/.manifest.json +2 -1
  9. package/.sauron/wiki/history/implementacao-scanner-inteligente.md +29 -0
  10. package/.sauron/wiki/history/reestruturacao-arquitetural-core.md +29 -0
  11. package/.sauron/wiki/history/resiliencia-caminho-templates.md +29 -0
  12. package/.sauron/wiki/standards/typescript.rules.md +21 -0
  13. package/.sauron/wiki/summary.json +81 -0
  14. package/.windsurfrules +160 -0
  15. package/55ea973d-e255-4f08-a313-a5d68243bd2d.png +0 -0
  16. package/Evolu/303/247/303/243o Arquitetural do Sauron CLI.md" +97 -0
  17. package/OpenSpec-main/.actrc +1 -0
  18. package/OpenSpec-main/.changeset/README.md +97 -0
  19. package/OpenSpec-main/.changeset/config.json +15 -0
  20. package/OpenSpec-main/.coderabbit.yaml +11 -0
  21. package/OpenSpec-main/.devcontainer/README.md +92 -0
  22. package/OpenSpec-main/.devcontainer/devcontainer.json +68 -0
  23. package/OpenSpec-main/.github/CODEOWNERS +2 -0
  24. package/OpenSpec-main/.github/workflows/README.md +20 -0
  25. package/OpenSpec-main/.github/workflows/ci.yml +346 -0
  26. package/OpenSpec-main/.github/workflows/release-prepare.yml +60 -0
  27. package/OpenSpec-main/CHANGELOG.md +594 -0
  28. package/OpenSpec-main/LICENSE +22 -0
  29. package/OpenSpec-main/MAINTAINERS.md +17 -0
  30. package/OpenSpec-main/README.md +206 -0
  31. package/OpenSpec-main/README_OLD.md +475 -0
  32. package/OpenSpec-main/assets/openspec_bg.png +0 -0
  33. package/OpenSpec-main/assets/openspec_dashboard.png +0 -0
  34. package/OpenSpec-main/assets/openspec_pixel_dark.svg +89 -0
  35. package/OpenSpec-main/assets/openspec_pixel_light.svg +89 -0
  36. package/OpenSpec-main/bin/openspec.js +5 -0
  37. package/OpenSpec-main/build.js +31 -0
  38. package/OpenSpec-main/eslint.config.js +42 -0
  39. package/OpenSpec-main/flake.lock +27 -0
  40. package/OpenSpec-main/flake.nix +114 -0
  41. package/OpenSpec-main/openspec/changes/IMPLEMENTATION_ORDER.md +68 -0
  42. package/OpenSpec-main/openspec/changes/add-artifact-regeneration-support/proposal.md +136 -0
  43. package/OpenSpec-main/openspec/changes/add-change-stacking-awareness/.openspec.yaml +2 -0
  44. package/OpenSpec-main/openspec/changes/add-change-stacking-awareness/proposal.md +93 -0
  45. package/OpenSpec-main/openspec/changes/add-change-stacking-awareness/specs/change-creation/spec.md +15 -0
  46. package/OpenSpec-main/openspec/changes/add-change-stacking-awareness/specs/change-stacking-workflow/spec.md +65 -0
  47. package/OpenSpec-main/openspec/changes/add-change-stacking-awareness/specs/cli-change/spec.md +27 -0
  48. package/OpenSpec-main/openspec/changes/add-change-stacking-awareness/specs/openspec-conventions/spec.md +29 -0
  49. package/OpenSpec-main/openspec/changes/add-change-stacking-awareness/tasks.md +39 -0
  50. package/OpenSpec-main/openspec/changes/add-global-install-scope/.openspec.yaml +2 -0
  51. package/OpenSpec-main/openspec/changes/add-global-install-scope/design.md +161 -0
  52. package/OpenSpec-main/openspec/changes/add-global-install-scope/proposal.md +101 -0
  53. package/OpenSpec-main/openspec/changes/add-global-install-scope/specs/ai-tool-paths/spec.md +35 -0
  54. package/OpenSpec-main/openspec/changes/add-global-install-scope/specs/cli-config/spec.md +21 -0
  55. package/OpenSpec-main/openspec/changes/add-global-install-scope/specs/cli-init/spec.md +28 -0
  56. package/OpenSpec-main/openspec/changes/add-global-install-scope/specs/cli-update/spec.md +34 -0
  57. package/OpenSpec-main/openspec/changes/add-global-install-scope/specs/command-generation/spec.md +22 -0
  58. package/OpenSpec-main/openspec/changes/add-global-install-scope/specs/global-config/spec.md +24 -0
  59. package/OpenSpec-main/openspec/changes/add-global-install-scope/specs/installation-scope/spec.md +71 -0
  60. package/OpenSpec-main/openspec/changes/add-global-install-scope/tasks.md +61 -0
  61. package/OpenSpec-main/openspec/changes/add-qa-smoke-harness/.openspec.yaml +2 -0
  62. package/OpenSpec-main/openspec/changes/add-qa-smoke-harness/proposal.md +45 -0
  63. package/OpenSpec-main/openspec/changes/add-qa-smoke-harness/specs/developer-qa-workflow/spec.md +49 -0
  64. package/OpenSpec-main/openspec/changes/add-tool-command-surface-capabilities/.openspec.yaml +2 -0
  65. package/OpenSpec-main/openspec/changes/add-tool-command-surface-capabilities/proposal.md +111 -0
  66. package/OpenSpec-main/openspec/changes/add-tool-command-surface-capabilities/specs/cli-init/spec.md +121 -0
  67. package/OpenSpec-main/openspec/changes/add-tool-command-surface-capabilities/specs/cli-update/spec.md +48 -0
  68. package/OpenSpec-main/openspec/changes/add-tool-command-surface-capabilities/tasks.md +53 -0
  69. package/OpenSpec-main/openspec/changes/archive/2025-01-11-add-update-command/design.md +86 -0
  70. package/OpenSpec-main/openspec/changes/archive/2025-01-11-add-update-command/proposal.md +29 -0
  71. package/OpenSpec-main/openspec/changes/archive/2025-01-11-add-update-command/specs/cli-update/spec.md +59 -0
  72. package/OpenSpec-main/openspec/changes/archive/2025-01-11-add-update-command/tasks.md +20 -0
  73. package/OpenSpec-main/openspec/changes/archive/2025-01-13-add-list-command/proposal.md +20 -0
  74. package/OpenSpec-main/openspec/changes/archive/2025-01-13-add-list-command/specs/cli-list/spec.md +69 -0
  75. package/OpenSpec-main/openspec/changes/archive/2025-01-13-add-list-command/tasks.md +26 -0
  76. package/OpenSpec-main/openspec/changes/archive/2025-08-05-initialize-typescript-project/design.md +64 -0
  77. package/OpenSpec-main/openspec/changes/archive/2025-08-05-initialize-typescript-project/proposal.md +18 -0
  78. package/OpenSpec-main/openspec/changes/archive/2025-08-05-initialize-typescript-project/tasks.md +25 -0
  79. package/OpenSpec-main/openspec/changes/archive/2025-08-06-add-init-command/design.md +104 -0
  80. package/OpenSpec-main/openspec/changes/archive/2025-08-06-add-init-command/proposal.md +30 -0
  81. package/OpenSpec-main/openspec/changes/archive/2025-08-06-add-init-command/specs/cli-init/spec.md +148 -0
  82. package/OpenSpec-main/openspec/changes/archive/2025-08-06-add-init-command/tasks.md +38 -0
  83. package/OpenSpec-main/openspec/changes/archive/2025-08-06-adopt-future-state-storage/proposal.md +24 -0
  84. package/OpenSpec-main/openspec/changes/archive/2025-08-06-adopt-future-state-storage/specs/openspec-conventions/spec.md +120 -0
  85. package/OpenSpec-main/openspec/changes/archive/2025-08-06-adopt-future-state-storage/tasks.md +38 -0
  86. package/OpenSpec-main/openspec/changes/archive/2025-08-11-add-complexity-guidelines/proposal.md +13 -0
  87. package/OpenSpec-main/openspec/changes/archive/2025-08-11-add-complexity-guidelines/specs/openspec-docs/README.md +472 -0
  88. package/OpenSpec-main/openspec/changes/archive/2025-08-11-add-complexity-guidelines/tasks.md +9 -0
  89. package/OpenSpec-main/openspec/changes/archive/2025-08-13-add-archive-command/proposal.md +15 -0
  90. package/OpenSpec-main/openspec/changes/archive/2025-08-13-add-archive-command/specs/cli-archive/spec.md +111 -0
  91. package/OpenSpec-main/openspec/changes/archive/2025-08-13-add-archive-command/tasks.md +44 -0
  92. package/OpenSpec-main/openspec/changes/archive/2025-08-13-add-diff-command/proposal.md +19 -0
  93. package/OpenSpec-main/openspec/changes/archive/2025-08-13-add-diff-command/specs/cli-diff/spec.md +77 -0
  94. package/OpenSpec-main/openspec/changes/archive/2025-08-13-add-diff-command/tasks.md +23 -0
  95. package/OpenSpec-main/openspec/changes/archive/2025-08-19-add-change-commands/design.md +56 -0
  96. package/OpenSpec-main/openspec/changes/archive/2025-08-19-add-change-commands/proposal.md +17 -0
  97. package/OpenSpec-main/openspec/changes/archive/2025-08-19-add-change-commands/specs/cli-change/spec.md +48 -0
  98. package/OpenSpec-main/openspec/changes/archive/2025-08-19-add-change-commands/specs/cli-list/spec.md +12 -0
  99. package/OpenSpec-main/openspec/changes/archive/2025-08-19-add-change-commands/tasks.md +34 -0
  100. package/OpenSpec-main/openspec/changes/archive/2025-08-19-add-interactive-show-command/proposal.md +20 -0
  101. package/OpenSpec-main/openspec/changes/archive/2025-08-19-add-interactive-show-command/specs/cli-change/spec.md +23 -0
  102. package/OpenSpec-main/openspec/changes/archive/2025-08-19-add-interactive-show-command/specs/cli-show/spec.md +83 -0
  103. package/OpenSpec-main/openspec/changes/archive/2025-08-19-add-interactive-show-command/specs/cli-spec/spec.md +23 -0
  104. package/OpenSpec-main/openspec/changes/archive/2025-08-19-add-interactive-show-command/tasks.md +142 -0
  105. package/OpenSpec-main/openspec/changes/archive/2025-08-19-add-skip-specs-archive-option/proposal.md +13 -0
  106. package/OpenSpec-main/openspec/changes/archive/2025-08-19-add-skip-specs-archive-option/specs/cli-archive/spec.md +191 -0
  107. package/OpenSpec-main/openspec/changes/archive/2025-08-19-add-skip-specs-archive-option/tasks.md +57 -0
  108. package/OpenSpec-main/openspec/changes/archive/2025-08-19-add-spec-commands/design.md +45 -0
  109. package/OpenSpec-main/openspec/changes/archive/2025-08-19-add-spec-commands/proposal.md +19 -0
  110. package/OpenSpec-main/openspec/changes/archive/2025-08-19-add-spec-commands/specs/cli-spec/spec.md +43 -0
  111. package/OpenSpec-main/openspec/changes/archive/2025-08-19-add-spec-commands/tasks.md +22 -0
  112. package/OpenSpec-main/openspec/changes/archive/2025-08-19-add-zod-validation/design.md +104 -0
  113. package/OpenSpec-main/openspec/changes/archive/2025-08-19-add-zod-validation/proposal.md +22 -0
  114. package/OpenSpec-main/openspec/changes/archive/2025-08-19-add-zod-validation/specs/cli-archive/spec.md +18 -0
  115. package/OpenSpec-main/openspec/changes/archive/2025-08-19-add-zod-validation/specs/cli-diff/spec.md +12 -0
  116. package/OpenSpec-main/openspec/changes/archive/2025-08-19-add-zod-validation/tasks.md +59 -0
  117. package/OpenSpec-main/openspec/changes/archive/2025-08-19-adopt-delta-based-changes/proposal.md +93 -0
  118. package/OpenSpec-main/openspec/changes/archive/2025-08-19-adopt-delta-based-changes/specs/cli-archive/spec.md +48 -0
  119. package/OpenSpec-main/openspec/changes/archive/2025-08-19-adopt-delta-based-changes/specs/cli-diff/spec.md +45 -0
  120. package/OpenSpec-main/openspec/changes/archive/2025-08-19-adopt-delta-based-changes/specs/openspec-conventions/spec.md +101 -0
  121. package/OpenSpec-main/openspec/changes/archive/2025-08-19-adopt-delta-based-changes/tasks.md +55 -0
  122. package/OpenSpec-main/openspec/changes/archive/2025-08-19-adopt-verb-noun-cli-structure/design.md +19 -0
  123. package/OpenSpec-main/openspec/changes/archive/2025-08-19-adopt-verb-noun-cli-structure/proposal.md +67 -0
  124. package/OpenSpec-main/openspec/changes/archive/2025-08-19-adopt-verb-noun-cli-structure/specs/cli-list/spec.md +57 -0
  125. package/OpenSpec-main/openspec/changes/archive/2025-08-19-adopt-verb-noun-cli-structure/specs/openspec-conventions/spec.md +23 -0
  126. package/OpenSpec-main/openspec/changes/archive/2025-08-19-adopt-verb-noun-cli-structure/tasks.md +27 -0
  127. package/OpenSpec-main/openspec/changes/archive/2025-08-19-bulk-validation-interactive-selection/proposal.md +20 -0
  128. package/OpenSpec-main/openspec/changes/archive/2025-08-19-bulk-validation-interactive-selection/specs/cli-change/spec.md +22 -0
  129. package/OpenSpec-main/openspec/changes/archive/2025-08-19-bulk-validation-interactive-selection/specs/cli-spec/spec.md +23 -0
  130. package/OpenSpec-main/openspec/changes/archive/2025-08-19-bulk-validation-interactive-selection/specs/cli-validate/spec.md +149 -0
  131. package/OpenSpec-main/openspec/changes/archive/2025-08-19-bulk-validation-interactive-selection/tasks.md +81 -0
  132. package/OpenSpec-main/openspec/changes/archive/2025-08-19-fix-update-tool-selection/proposal.md +40 -0
  133. package/OpenSpec-main/openspec/changes/archive/2025-08-19-fix-update-tool-selection/specs/cli-update/spec.md +23 -0
  134. package/OpenSpec-main/openspec/changes/archive/2025-08-19-fix-update-tool-selection/tasks.md +21 -0
  135. package/OpenSpec-main/openspec/changes/archive/2025-08-19-improve-validate-error-messages/proposal.md +25 -0
  136. package/OpenSpec-main/openspec/changes/archive/2025-08-19-improve-validate-error-messages/specs/cli-validate/spec.md +55 -0
  137. package/OpenSpec-main/openspec/changes/archive/2025-08-19-improve-validate-error-messages/tasks.md +21 -0
  138. package/OpenSpec-main/openspec/changes/archive/2025-08-19-structured-spec-format/proposal.md +36 -0
  139. package/OpenSpec-main/openspec/changes/archive/2025-08-19-structured-spec-format/specs/openspec-conventions/spec.md +192 -0
  140. package/OpenSpec-main/openspec/changes/archive/2025-08-19-structured-spec-format/tasks.md +19 -0
  141. package/OpenSpec-main/openspec/changes/archive/2025-09-12-add-view-dashboard-command/proposal.md +38 -0
  142. package/OpenSpec-main/openspec/changes/archive/2025-09-12-add-view-dashboard-command/specs/cli-view/spec.md +109 -0
  143. package/OpenSpec-main/openspec/changes/archive/2025-09-12-add-view-dashboard-command/tasks.md +47 -0
  144. package/OpenSpec-main/openspec/changes/archive/2025-09-29-add-agents-md-config/proposal.md +28 -0
  145. package/OpenSpec-main/openspec/changes/archive/2025-09-29-add-agents-md-config/specs/cli-init/spec.md +71 -0
  146. package/OpenSpec-main/openspec/changes/archive/2025-09-29-add-agents-md-config/specs/cli-update/spec.md +41 -0
  147. package/OpenSpec-main/openspec/changes/archive/2025-09-29-add-agents-md-config/tasks.md +17 -0
  148. package/OpenSpec-main/openspec/changes/archive/2025-09-29-add-multi-agent-init/proposal.md +35 -0
  149. package/OpenSpec-main/openspec/changes/archive/2025-09-29-add-multi-agent-init/specs/cli-init/spec.md +45 -0
  150. package/OpenSpec-main/openspec/changes/archive/2025-09-29-add-multi-agent-init/tasks.md +16 -0
  151. package/OpenSpec-main/openspec/changes/archive/2025-09-29-add-slash-command-support/proposal.md +119 -0
  152. package/OpenSpec-main/openspec/changes/archive/2025-09-29-add-slash-command-support/specs/cli-init/spec.md +21 -0
  153. package/OpenSpec-main/openspec/changes/archive/2025-09-29-add-slash-command-support/specs/cli-update/spec.md +22 -0
  154. package/OpenSpec-main/openspec/changes/archive/2025-09-29-add-slash-command-support/tasks.md +20 -0
  155. package/OpenSpec-main/openspec/changes/archive/2025-09-29-improve-cli-e2e-plan/proposal.md +19 -0
  156. package/OpenSpec-main/openspec/changes/archive/2025-09-29-improve-cli-e2e-plan/tasks.md +9 -0
  157. package/OpenSpec-main/openspec/changes/archive/2025-09-29-improve-deterministic-tests/proposal.md +78 -0
  158. package/OpenSpec-main/openspec/changes/archive/2025-09-29-improve-deterministic-tests/tasks.md +25 -0
  159. package/OpenSpec-main/openspec/changes/archive/2025-09-29-improve-init-onboarding/proposal.md +13 -0
  160. package/OpenSpec-main/openspec/changes/archive/2025-09-29-improve-init-onboarding/specs/cli-init/spec.md +92 -0
  161. package/OpenSpec-main/openspec/changes/archive/2025-09-29-improve-init-onboarding/tasks.md +12 -0
  162. package/OpenSpec-main/openspec/changes/archive/2025-09-29-remove-diff-command/proposal.md +81 -0
  163. package/OpenSpec-main/openspec/changes/archive/2025-09-29-remove-diff-command/tasks.md +37 -0
  164. package/OpenSpec-main/openspec/changes/archive/2025-09-29-sort-active-changes-by-progress/proposal.md +25 -0
  165. package/OpenSpec-main/openspec/changes/archive/2025-09-29-sort-active-changes-by-progress/specs/cli-view/spec.md +9 -0
  166. package/OpenSpec-main/openspec/changes/archive/2025-09-29-sort-active-changes-by-progress/tasks.md +8 -0
  167. package/OpenSpec-main/openspec/changes/archive/2025-09-29-update-agent-file-name/proposal.md +29 -0
  168. package/OpenSpec-main/openspec/changes/archive/2025-09-29-update-agent-file-name/specs/cli-init/spec.md +40 -0
  169. package/OpenSpec-main/openspec/changes/archive/2025-09-29-update-agent-file-name/specs/cli-update/spec.md +22 -0
  170. package/OpenSpec-main/openspec/changes/archive/2025-09-29-update-agent-file-name/specs/openspec-conventions/spec.md +27 -0
  171. package/OpenSpec-main/openspec/changes/archive/2025-09-29-update-agent-file-name/tasks.md +22 -0
  172. package/OpenSpec-main/openspec/changes/archive/2025-09-29-update-agent-instructions/design.md +130 -0
  173. package/OpenSpec-main/openspec/changes/archive/2025-09-29-update-agent-instructions/proposal.md +117 -0
  174. package/OpenSpec-main/openspec/changes/archive/2025-09-29-update-agent-instructions/tasks.md +69 -0
  175. package/OpenSpec-main/openspec/changes/archive/2025-09-29-update-markdown-parser-crlf/proposal.md +19 -0
  176. package/OpenSpec-main/openspec/changes/archive/2025-09-29-update-markdown-parser-crlf/specs/cli-validate/spec.md +9 -0
  177. package/OpenSpec-main/openspec/changes/archive/2025-09-29-update-markdown-parser-crlf/tasks.md +11 -0
  178. package/OpenSpec-main/openspec/changes/archive/2025-10-14-add-codex-slash-command-support/proposal.md +25 -0
  179. package/OpenSpec-main/openspec/changes/archive/2025-10-14-add-codex-slash-command-support/specs/cli-init/spec.md +56 -0
  180. package/OpenSpec-main/openspec/changes/archive/2025-10-14-add-codex-slash-command-support/specs/cli-update/spec.md +41 -0
  181. package/OpenSpec-main/openspec/changes/archive/2025-10-14-add-codex-slash-command-support/tasks.md +19 -0
  182. package/OpenSpec-main/openspec/changes/archive/2025-10-14-add-github-copilot-prompts/proposal.md +25 -0
  183. package/OpenSpec-main/openspec/changes/archive/2025-10-14-add-github-copilot-prompts/specs/cli-init/spec.md +48 -0
  184. package/OpenSpec-main/openspec/changes/archive/2025-10-14-add-github-copilot-prompts/specs/cli-update/spec.md +48 -0
  185. package/OpenSpec-main/openspec/changes/archive/2025-10-14-add-github-copilot-prompts/tasks.md +30 -0
  186. package/OpenSpec-main/openspec/changes/archive/2025-10-14-add-kilocode-workflows/proposal.md +17 -0
  187. package/OpenSpec-main/openspec/changes/archive/2025-10-14-add-kilocode-workflows/specs/cli-init/spec.md +43 -0
  188. package/OpenSpec-main/openspec/changes/archive/2025-10-14-add-kilocode-workflows/specs/cli-update/spec.md +27 -0
  189. package/OpenSpec-main/openspec/changes/archive/2025-10-14-add-kilocode-workflows/tasks.md +15 -0
  190. package/OpenSpec-main/openspec/changes/archive/2025-10-14-add-non-interactive-init-options/proposal.md +12 -0
  191. package/OpenSpec-main/openspec/changes/archive/2025-10-14-add-non-interactive-init-options/specs/cli-init/spec.md +39 -0
  192. package/OpenSpec-main/openspec/changes/archive/2025-10-14-add-non-interactive-init-options/tasks.md +17 -0
  193. package/OpenSpec-main/openspec/changes/archive/2025-10-14-add-windsurf-workflows/proposal.md +17 -0
  194. package/OpenSpec-main/openspec/changes/archive/2025-10-14-add-windsurf-workflows/specs/cli-init/spec.md +42 -0
  195. package/OpenSpec-main/openspec/changes/archive/2025-10-14-add-windsurf-workflows/specs/cli-update/spec.md +27 -0
  196. package/OpenSpec-main/openspec/changes/archive/2025-10-14-add-windsurf-workflows/tasks.md +17 -0
  197. package/OpenSpec-main/openspec/changes/archive/2025-10-14-enhance-validation-error-messages/proposal.md +12 -0
  198. package/OpenSpec-main/openspec/changes/archive/2025-10-14-enhance-validation-error-messages/specs/cli-validate/spec.md +39 -0
  199. package/OpenSpec-main/openspec/changes/archive/2025-10-14-enhance-validation-error-messages/tasks.md +12 -0
  200. package/OpenSpec-main/openspec/changes/archive/2025-10-14-improve-agent-instruction-usability/proposal.md +12 -0
  201. package/OpenSpec-main/openspec/changes/archive/2025-10-14-improve-agent-instruction-usability/specs/docs-agent-instructions/spec.md +33 -0
  202. package/OpenSpec-main/openspec/changes/archive/2025-10-14-improve-agent-instruction-usability/tasks.md +11 -0
  203. package/OpenSpec-main/openspec/changes/archive/2025-10-14-slim-root-agents-file/proposal.md +13 -0
  204. package/OpenSpec-main/openspec/changes/archive/2025-10-14-slim-root-agents-file/tasks.md +15 -0
  205. package/OpenSpec-main/openspec/changes/archive/2025-10-14-update-cli-init-enter-selection/proposal.md +14 -0
  206. package/OpenSpec-main/openspec/changes/archive/2025-10-14-update-cli-init-enter-selection/specs/cli-init/spec.md +10 -0
  207. package/OpenSpec-main/openspec/changes/archive/2025-10-14-update-cli-init-enter-selection/tasks.md +8 -0
  208. package/OpenSpec-main/openspec/changes/archive/2025-10-14-update-cli-init-root-agents/proposal.md +15 -0
  209. package/OpenSpec-main/openspec/changes/archive/2025-10-14-update-cli-init-root-agents/specs/cli-init/spec.md +32 -0
  210. package/OpenSpec-main/openspec/changes/archive/2025-10-14-update-cli-init-root-agents/specs/cli-update/spec.md +10 -0
  211. package/OpenSpec-main/openspec/changes/archive/2025-10-14-update-cli-init-root-agents/tasks.md +11 -0
  212. package/OpenSpec-main/openspec/changes/archive/2025-10-14-update-release-automation/proposal.md +49 -0
  213. package/OpenSpec-main/openspec/changes/archive/2025-10-14-update-release-automation/tasks.md +12 -0
  214. package/OpenSpec-main/openspec/changes/archive/2025-10-22-add-archive-command-arguments/proposal.md +17 -0
  215. package/OpenSpec-main/openspec/changes/archive/2025-10-22-add-archive-command-arguments/specs/cli-update/spec.md +32 -0
  216. package/OpenSpec-main/openspec/changes/archive/2025-10-22-add-archive-command-arguments/tasks.md +15 -0
  217. package/OpenSpec-main/openspec/changes/archive/2025-10-22-add-cline-support/proposal.md +15 -0
  218. package/OpenSpec-main/openspec/changes/archive/2025-10-22-add-cline-support/specs/cli-init/spec.md +97 -0
  219. package/OpenSpec-main/openspec/changes/archive/2025-10-22-add-cline-support/tasks.md +19 -0
  220. package/OpenSpec-main/openspec/changes/archive/2025-10-22-add-crush-support/proposal.md +13 -0
  221. package/OpenSpec-main/openspec/changes/archive/2025-10-22-add-crush-support/specs/cli-init/spec.md +67 -0
  222. package/OpenSpec-main/openspec/changes/archive/2025-10-22-add-crush-support/tasks.md +7 -0
  223. package/OpenSpec-main/openspec/changes/archive/2025-10-22-add-factory-slash-commands/proposal.md +12 -0
  224. package/OpenSpec-main/openspec/changes/archive/2025-10-22-add-factory-slash-commands/specs/cli-init/spec.md +54 -0
  225. package/OpenSpec-main/openspec/changes/archive/2025-10-22-add-factory-slash-commands/specs/cli-update/spec.md +54 -0
  226. package/OpenSpec-main/openspec/changes/archive/2025-10-22-add-factory-slash-commands/tasks.md +11 -0
  227. package/OpenSpec-main/openspec/changes/archive/2025-11-06-add-shell-completions/design.md +525 -0
  228. package/OpenSpec-main/openspec/changes/archive/2025-11-06-add-shell-completions/proposal.md +29 -0
  229. package/OpenSpec-main/openspec/changes/archive/2025-11-06-add-shell-completions/specs/cli-completion/spec.md +300 -0
  230. package/OpenSpec-main/openspec/changes/archive/2025-11-06-add-shell-completions/tasks.md +81 -0
  231. package/OpenSpec-main/openspec/changes/archive/2025-12-20-add-global-config-dir/design.md +105 -0
  232. package/OpenSpec-main/openspec/changes/archive/2025-12-20-add-global-config-dir/proposal.md +20 -0
  233. package/OpenSpec-main/openspec/changes/archive/2025-12-20-add-global-config-dir/specs/global-config/spec.md +76 -0
  234. package/OpenSpec-main/openspec/changes/archive/2025-12-20-add-global-config-dir/tasks.md +26 -0
  235. package/OpenSpec-main/openspec/changes/archive/2025-12-21-add-config-command/design.md +89 -0
  236. package/OpenSpec-main/openspec/changes/archive/2025-12-21-add-config-command/proposal.md +60 -0
  237. package/OpenSpec-main/openspec/changes/archive/2025-12-21-add-config-command/specs/cli-config/spec.md +213 -0
  238. package/OpenSpec-main/openspec/changes/archive/2025-12-21-add-config-command/tasks.md +28 -0
  239. package/OpenSpec-main/openspec/changes/archive/2025-12-23-extend-shell-completions/proposal.md +15 -0
  240. package/OpenSpec-main/openspec/changes/archive/2025-12-23-extend-shell-completions/specs/cli-completion/spec.md +328 -0
  241. package/OpenSpec-main/openspec/changes/archive/2025-12-23-extend-shell-completions/tasks.md +49 -0
  242. package/OpenSpec-main/openspec/changes/archive/2025-12-24-add-artifact-graph-core/design.md +197 -0
  243. package/OpenSpec-main/openspec/changes/archive/2025-12-24-add-artifact-graph-core/proposal.md +18 -0
  244. package/OpenSpec-main/openspec/changes/archive/2025-12-24-add-artifact-graph-core/specs/artifact-graph/spec.md +103 -0
  245. package/OpenSpec-main/openspec/changes/archive/2025-12-24-add-artifact-graph-core/tasks.md +61 -0
  246. package/OpenSpec-main/openspec/changes/archive/2025-12-25-add-change-manager/design.md +74 -0
  247. package/OpenSpec-main/openspec/changes/archive/2025-12-25-add-change-manager/proposal.md +45 -0
  248. package/OpenSpec-main/openspec/changes/archive/2025-12-25-add-change-manager/specs/change-creation/spec.md +63 -0
  249. package/OpenSpec-main/openspec/changes/archive/2025-12-25-add-change-manager/tasks.md +30 -0
  250. package/OpenSpec-main/openspec/changes/archive/2025-12-28-add-artifact-workflow-cli/design.md +112 -0
  251. package/OpenSpec-main/openspec/changes/archive/2025-12-28-add-artifact-workflow-cli/proposal.md +33 -0
  252. package/OpenSpec-main/openspec/changes/archive/2025-12-28-add-artifact-workflow-cli/specs/cli-artifact-workflow/spec.md +153 -0
  253. package/OpenSpec-main/openspec/changes/archive/2025-12-28-add-artifact-workflow-cli/tasks.md +48 -0
  254. package/OpenSpec-main/openspec/changes/archive/2025-12-28-add-instruction-loader/design.md +149 -0
  255. package/OpenSpec-main/openspec/changes/archive/2025-12-28-add-instruction-loader/proposal.md +20 -0
  256. package/OpenSpec-main/openspec/changes/archive/2025-12-28-add-instruction-loader/specs/instruction-loader/spec.md +70 -0
  257. package/OpenSpec-main/openspec/changes/archive/2025-12-28-add-instruction-loader/tasks.md +13 -0
  258. package/OpenSpec-main/openspec/changes/archive/2025-12-28-restructure-schema-directories/design.md +129 -0
  259. package/OpenSpec-main/openspec/changes/archive/2025-12-28-restructure-schema-directories/proposal.md +20 -0
  260. package/OpenSpec-main/openspec/changes/archive/2025-12-28-restructure-schema-directories/specs/artifact-graph/spec.md +49 -0
  261. package/OpenSpec-main/openspec/changes/archive/2025-12-28-restructure-schema-directories/tasks.md +32 -0
  262. package/OpenSpec-main/openspec/changes/archive/2025-12-29-unify-change-state-model/design.md +151 -0
  263. package/OpenSpec-main/openspec/changes/archive/2025-12-29-unify-change-state-model/proposal.md +101 -0
  264. package/OpenSpec-main/openspec/changes/archive/2025-12-29-unify-change-state-model/specs/cli-artifact-workflow/spec.md +109 -0
  265. package/OpenSpec-main/openspec/changes/archive/2025-12-29-unify-change-state-model/specs/cli-view/spec.md +60 -0
  266. package/OpenSpec-main/openspec/changes/archive/2025-12-29-unify-change-state-model/tasks.md +25 -0
  267. package/OpenSpec-main/openspec/changes/archive/2025-12-30-add-antigravity-support/proposal.md +11 -0
  268. package/OpenSpec-main/openspec/changes/archive/2025-12-30-add-antigravity-support/specs/cli-init/spec.md +105 -0
  269. package/OpenSpec-main/openspec/changes/archive/2025-12-30-add-antigravity-support/specs/cli-update/spec.md +92 -0
  270. package/OpenSpec-main/openspec/changes/archive/2025-12-30-add-antigravity-support/tasks.md +12 -0
  271. package/OpenSpec-main/openspec/changes/archive/2025-12-30-fix-cline-workflows-implementation/proposal.md +13 -0
  272. package/OpenSpec-main/openspec/changes/archive/2025-12-30-fix-cline-workflows-implementation/specs/cli-init/spec.md +105 -0
  273. package/OpenSpec-main/openspec/changes/archive/2025-12-30-fix-cline-workflows-implementation/specs/cli-update/spec.md +92 -0
  274. package/OpenSpec-main/openspec/changes/archive/2025-12-30-fix-cline-workflows-implementation/tasks.md +13 -0
  275. package/OpenSpec-main/openspec/changes/archive/2026-01-06-add-agent-schema-selection/proposal.md +26 -0
  276. package/OpenSpec-main/openspec/changes/archive/2026-01-06-add-agent-schema-selection/tasks.md +32 -0
  277. package/OpenSpec-main/openspec/changes/archive/2026-01-06-add-per-change-schema-metadata/design.md +147 -0
  278. package/OpenSpec-main/openspec/changes/archive/2026-01-06-add-per-change-schema-metadata/proposal.md +29 -0
  279. package/OpenSpec-main/openspec/changes/archive/2026-01-06-add-per-change-schema-metadata/specs/cli-artifact-workflow/spec.md +98 -0
  280. package/OpenSpec-main/openspec/changes/archive/2026-01-06-add-per-change-schema-metadata/tasks.md +29 -0
  281. package/OpenSpec-main/openspec/changes/archive/2026-01-06-add-specs-apply-command/.openspec.yaml +2 -0
  282. package/OpenSpec-main/openspec/changes/archive/2026-01-06-add-specs-apply-command/design.md +77 -0
  283. package/OpenSpec-main/openspec/changes/archive/2026-01-06-add-specs-apply-command/proposal.md +32 -0
  284. package/OpenSpec-main/openspec/changes/archive/2026-01-06-add-specs-apply-command/specs/specs-sync-skill/spec.md +67 -0
  285. package/OpenSpec-main/openspec/changes/archive/2026-01-06-add-specs-apply-command/tasks.md +40 -0
  286. package/OpenSpec-main/openspec/changes/archive/2026-01-06-make-apply-instructions-schema-aware/proposal.md +138 -0
  287. package/OpenSpec-main/openspec/changes/archive/2026-01-06-make-apply-instructions-schema-aware/specs/cli-artifact-workflow/spec.md +60 -0
  288. package/OpenSpec-main/openspec/changes/archive/2026-01-06-make-apply-instructions-schema-aware/tasks.md +35 -0
  289. package/OpenSpec-main/openspec/changes/archive/2026-01-06-opsx-archive-command/.openspec.yaml +2 -0
  290. package/OpenSpec-main/openspec/changes/archive/2026-01-06-opsx-archive-command/design.md +84 -0
  291. package/OpenSpec-main/openspec/changes/archive/2026-01-06-opsx-archive-command/proposal.md +28 -0
  292. package/OpenSpec-main/openspec/changes/archive/2026-01-06-opsx-archive-command/specs/opsx-archive-skill/spec.md +122 -0
  293. package/OpenSpec-main/openspec/changes/archive/2026-01-06-opsx-archive-command/tasks.md +23 -0
  294. package/OpenSpec-main/openspec/changes/archive/2026-01-07-add-nix-flake-support/.openspec.yaml +2 -0
  295. package/OpenSpec-main/openspec/changes/archive/2026-01-07-add-nix-flake-support/design.md +94 -0
  296. package/OpenSpec-main/openspec/changes/archive/2026-01-07-add-nix-flake-support/proposal.md +25 -0
  297. package/OpenSpec-main/openspec/changes/archive/2026-01-07-add-nix-flake-support/specs/nix-flake-support/spec.md +79 -0
  298. package/OpenSpec-main/openspec/changes/archive/2026-01-07-add-nix-flake-support/tasks.md +65 -0
  299. package/OpenSpec-main/openspec/changes/archive/2026-01-09-add-flake-update-script/.openspec.yaml +2 -0
  300. package/OpenSpec-main/openspec/changes/archive/2026-01-09-add-flake-update-script/design.md +117 -0
  301. package/OpenSpec-main/openspec/changes/archive/2026-01-09-add-flake-update-script/proposal.md +23 -0
  302. package/OpenSpec-main/openspec/changes/archive/2026-01-09-add-flake-update-script/specs/flake-update-script/spec.md +93 -0
  303. package/OpenSpec-main/openspec/changes/archive/2026-01-09-add-flake-update-script/tasks.md +55 -0
  304. package/OpenSpec-main/openspec/changes/archive/2026-01-09-add-posthog-analytics/.openspec.yaml +2 -0
  305. package/OpenSpec-main/openspec/changes/archive/2026-01-09-add-posthog-analytics/design.md +175 -0
  306. package/OpenSpec-main/openspec/changes/archive/2026-01-09-add-posthog-analytics/proposal.md +37 -0
  307. package/OpenSpec-main/openspec/changes/archive/2026-01-09-add-posthog-analytics/specs/global-config/spec.md +21 -0
  308. package/OpenSpec-main/openspec/changes/archive/2026-01-09-add-posthog-analytics/specs/telemetry/spec.md +116 -0
  309. package/OpenSpec-main/openspec/changes/archive/2026-01-09-add-posthog-analytics/tasks.md +47 -0
  310. package/OpenSpec-main/openspec/changes/archive/2026-01-09-fix-codebuddy-frontmatter-fields/proposal.md +16 -0
  311. package/OpenSpec-main/openspec/changes/archive/2026-01-09-fix-codebuddy-frontmatter-fields/specs/cli-init/spec.md +75 -0
  312. package/OpenSpec-main/openspec/changes/archive/2026-01-09-fix-codebuddy-frontmatter-fields/specs/cli-update/spec.md +56 -0
  313. package/OpenSpec-main/openspec/changes/archive/2026-01-09-fix-codebuddy-frontmatter-fields/tasks.md +6 -0
  314. package/OpenSpec-main/openspec/changes/archive/2026-01-15-add-nix-ci-validation/design.md +206 -0
  315. package/OpenSpec-main/openspec/changes/archive/2026-01-15-add-nix-ci-validation/proposal.md +21 -0
  316. package/OpenSpec-main/openspec/changes/archive/2026-01-15-add-nix-ci-validation/specs/ci-nix-validation/spec.md +104 -0
  317. package/OpenSpec-main/openspec/changes/archive/2026-01-15-add-nix-ci-validation/tasks.md +49 -0
  318. package/OpenSpec-main/openspec/changes/archive/2026-01-30-opencode-command-references/.openspec.yaml +2 -0
  319. package/OpenSpec-main/openspec/changes/archive/2026-01-30-opencode-command-references/README.md +3 -0
  320. package/OpenSpec-main/openspec/changes/archive/2026-01-30-opencode-command-references/design.md +70 -0
  321. package/OpenSpec-main/openspec/changes/archive/2026-01-30-opencode-command-references/proposal.md +32 -0
  322. package/OpenSpec-main/openspec/changes/archive/2026-01-30-opencode-command-references/specs/no-changes.md +9 -0
  323. package/OpenSpec-main/openspec/changes/archive/2026-01-30-opencode-command-references/tasks.md +22 -0
  324. package/OpenSpec-main/openspec/changes/archive/2026-02-17-add-feedback-command/proposal.md +20 -0
  325. package/OpenSpec-main/openspec/changes/archive/2026-02-17-add-feedback-command/specs/cli-feedback/spec.md +188 -0
  326. package/OpenSpec-main/openspec/changes/archive/2026-02-17-add-feedback-command/tasks.md +30 -0
  327. package/OpenSpec-main/openspec/changes/archive/2026-02-17-add-opsx-onboard-skill/.openspec.yaml +2 -0
  328. package/OpenSpec-main/openspec/changes/archive/2026-02-17-add-opsx-onboard-skill/design.md +115 -0
  329. package/OpenSpec-main/openspec/changes/archive/2026-02-17-add-opsx-onboard-skill/proposal.md +27 -0
  330. package/OpenSpec-main/openspec/changes/archive/2026-02-17-add-opsx-onboard-skill/specs/opsx-onboard-skill/spec.md +162 -0
  331. package/OpenSpec-main/openspec/changes/archive/2026-02-17-add-opsx-onboard-skill/tasks.md +21 -0
  332. package/OpenSpec-main/openspec/changes/archive/2026-02-17-add-verify-skill/design.md +96 -0
  333. package/OpenSpec-main/openspec/changes/archive/2026-02-17-add-verify-skill/proposal.md +48 -0
  334. package/OpenSpec-main/openspec/changes/archive/2026-02-17-add-verify-skill/specs/opsx-verify-skill/spec.md +190 -0
  335. package/OpenSpec-main/openspec/changes/archive/2026-02-17-add-verify-skill/tasks.md +15 -0
  336. package/OpenSpec-main/openspec/changes/archive/2026-02-17-merge-init-experimental/.openspec.yaml +2 -0
  337. package/OpenSpec-main/openspec/changes/archive/2026-02-17-merge-init-experimental/design.md +193 -0
  338. package/OpenSpec-main/openspec/changes/archive/2026-02-17-merge-init-experimental/proposal.md +32 -0
  339. package/OpenSpec-main/openspec/changes/archive/2026-02-17-merge-init-experimental/specs/cli-init/spec.md +176 -0
  340. package/OpenSpec-main/openspec/changes/archive/2026-02-17-merge-init-experimental/specs/legacy-cleanup/spec.md +158 -0
  341. package/OpenSpec-main/openspec/changes/archive/2026-02-17-merge-init-experimental/tasks.md +67 -0
  342. package/OpenSpec-main/openspec/changes/archive/2026-02-17-multi-provider-skill-generation/.openspec.yaml +2 -0
  343. package/OpenSpec-main/openspec/changes/archive/2026-02-17-multi-provider-skill-generation/design.md +144 -0
  344. package/OpenSpec-main/openspec/changes/archive/2026-02-17-multi-provider-skill-generation/proposal.md +36 -0
  345. package/OpenSpec-main/openspec/changes/archive/2026-02-17-multi-provider-skill-generation/specs/ai-tool-paths/spec.md +63 -0
  346. package/OpenSpec-main/openspec/changes/archive/2026-02-17-multi-provider-skill-generation/specs/cli-artifact-workflow/spec.md +60 -0
  347. package/OpenSpec-main/openspec/changes/archive/2026-02-17-multi-provider-skill-generation/specs/command-generation/spec.md +98 -0
  348. package/OpenSpec-main/openspec/changes/archive/2026-02-17-multi-provider-skill-generation/tasks.md +55 -0
  349. package/OpenSpec-main/openspec/changes/archive/2026-02-17-project-config/.openspec.yaml +2 -0
  350. package/OpenSpec-main/openspec/changes/archive/2026-02-17-project-config/design.md +665 -0
  351. package/OpenSpec-main/openspec/changes/archive/2026-02-17-project-config/proposal.md +774 -0
  352. package/OpenSpec-main/openspec/changes/archive/2026-02-17-project-config/specs/config-loading/spec.md +119 -0
  353. package/OpenSpec-main/openspec/changes/archive/2026-02-17-project-config/specs/context-injection/spec.md +51 -0
  354. package/OpenSpec-main/openspec/changes/archive/2026-02-17-project-config/specs/rules-injection/spec.md +99 -0
  355. package/OpenSpec-main/openspec/changes/archive/2026-02-17-project-config/specs/schema-resolution/spec.md +83 -0
  356. package/OpenSpec-main/openspec/changes/archive/2026-02-17-project-config/tasks.md +72 -0
  357. package/OpenSpec-main/openspec/changes/archive/2026-02-17-project-local-schemas/.openspec.yaml +2 -0
  358. package/OpenSpec-main/openspec/changes/archive/2026-02-17-project-local-schemas/design.md +117 -0
  359. package/OpenSpec-main/openspec/changes/archive/2026-02-17-project-local-schemas/proposal.md +167 -0
  360. package/OpenSpec-main/openspec/changes/archive/2026-02-17-project-local-schemas/specs/schema-resolution/spec.md +88 -0
  361. package/OpenSpec-main/openspec/changes/archive/2026-02-17-project-local-schemas/tasks.md +28 -0
  362. package/OpenSpec-main/openspec/changes/archive/2026-02-17-schema-management-cli/.openspec.yaml +2 -0
  363. package/OpenSpec-main/openspec/changes/archive/2026-02-17-schema-management-cli/design.md +113 -0
  364. package/OpenSpec-main/openspec/changes/archive/2026-02-17-schema-management-cli/proposal.md +55 -0
  365. package/OpenSpec-main/openspec/changes/archive/2026-02-17-schema-management-cli/specs/schema-fork-command/spec.md +66 -0
  366. package/OpenSpec-main/openspec/changes/archive/2026-02-17-schema-management-cli/specs/schema-init-command/spec.md +71 -0
  367. package/OpenSpec-main/openspec/changes/archive/2026-02-17-schema-management-cli/specs/schema-validate-command/spec.md +86 -0
  368. package/OpenSpec-main/openspec/changes/archive/2026-02-17-schema-management-cli/specs/schema-which-command/spec.md +65 -0
  369. package/OpenSpec-main/openspec/changes/archive/2026-02-17-schema-management-cli/tasks.md +67 -0
  370. package/OpenSpec-main/openspec/changes/archive/2026-04-23-add-kimi-cli-skills-only-support/.openspec.yaml +2 -0
  371. package/OpenSpec-main/openspec/changes/archive/2026-04-23-add-kimi-cli-skills-only-support/README.md +3 -0
  372. package/OpenSpec-main/openspec/changes/archive/2026-04-23-add-kimi-cli-skills-only-support/design.md +85 -0
  373. package/OpenSpec-main/openspec/changes/archive/2026-04-23-add-kimi-cli-skills-only-support/proposal.md +38 -0
  374. package/OpenSpec-main/openspec/changes/archive/2026-04-23-add-kimi-cli-skills-only-support/specs/ai-tool-paths/spec.md +12 -0
  375. package/OpenSpec-main/openspec/changes/archive/2026-04-23-add-kimi-cli-skills-only-support/specs/cli-init/spec.md +37 -0
  376. package/OpenSpec-main/openspec/changes/archive/2026-04-23-add-kimi-cli-skills-only-support/tasks.md +22 -0
  377. package/OpenSpec-main/openspec/changes/archive/2026-05-04-workspace-foundation/design.md +208 -0
  378. package/OpenSpec-main/openspec/changes/archive/2026-05-04-workspace-foundation/proposal.md +142 -0
  379. package/OpenSpec-main/openspec/changes/archive/2026-05-04-workspace-foundation/specs/openspec-conventions/spec.md +29 -0
  380. package/OpenSpec-main/openspec/changes/archive/2026-05-04-workspace-foundation/specs/workspace-foundation/spec.md +199 -0
  381. package/OpenSpec-main/openspec/changes/archive/2026-05-04-workspace-foundation/tasks.md +56 -0
  382. package/OpenSpec-main/openspec/changes/archive/2026-05-06-workspace-create-and-register-repos/design.md +356 -0
  383. package/OpenSpec-main/openspec/changes/archive/2026-05-06-workspace-create-and-register-repos/proposal.md +128 -0
  384. package/OpenSpec-main/openspec/changes/archive/2026-05-06-workspace-create-and-register-repos/specs/cli-artifact-workflow/spec.md +24 -0
  385. package/OpenSpec-main/openspec/changes/archive/2026-05-06-workspace-create-and-register-repos/specs/workspace-foundation/spec.md +35 -0
  386. package/OpenSpec-main/openspec/changes/archive/2026-05-06-workspace-create-and-register-repos/specs/workspace-links/spec.md +356 -0
  387. package/OpenSpec-main/openspec/changes/archive/2026-05-06-workspace-create-and-register-repos/tasks.md +121 -0
  388. package/OpenSpec-main/openspec/changes/archive/2026-05-06-workspace-open-agent-context/design.md +266 -0
  389. package/OpenSpec-main/openspec/changes/archive/2026-05-06-workspace-open-agent-context/proposal.md +65 -0
  390. package/OpenSpec-main/openspec/changes/archive/2026-05-06-workspace-open-agent-context/specs/workspace-foundation/spec.md +76 -0
  391. package/OpenSpec-main/openspec/changes/archive/2026-05-06-workspace-open-agent-context/specs/workspace-open/spec.md +199 -0
  392. package/OpenSpec-main/openspec/changes/archive/2026-05-06-workspace-open-agent-context/tasks.md +89 -0
  393. package/OpenSpec-main/openspec/changes/archive/2026-05-14-workspace-change-planning/design.md +242 -0
  394. package/OpenSpec-main/openspec/changes/archive/2026-05-14-workspace-change-planning/proposal.md +78 -0
  395. package/OpenSpec-main/openspec/changes/archive/2026-05-14-workspace-change-planning/specs/artifact-graph/spec.md +36 -0
  396. package/OpenSpec-main/openspec/changes/archive/2026-05-14-workspace-change-planning/specs/change-creation/spec.md +42 -0
  397. package/OpenSpec-main/openspec/changes/archive/2026-05-14-workspace-change-planning/specs/cli-artifact-workflow/spec.md +100 -0
  398. package/OpenSpec-main/openspec/changes/archive/2026-05-14-workspace-change-planning/specs/cli-config/spec.md +55 -0
  399. package/OpenSpec-main/openspec/changes/archive/2026-05-14-workspace-change-planning/specs/cli-update/spec.md +21 -0
  400. package/OpenSpec-main/openspec/changes/archive/2026-05-14-workspace-change-planning/specs/openspec-conventions/spec.md +32 -0
  401. package/OpenSpec-main/openspec/changes/archive/2026-05-14-workspace-change-planning/specs/schema-resolution/spec.md +25 -0
  402. package/OpenSpec-main/openspec/changes/archive/2026-05-14-workspace-change-planning/specs/workspace-change-planning/spec.md +67 -0
  403. package/OpenSpec-main/openspec/changes/archive/2026-05-14-workspace-change-planning/specs/workspace-links/spec.md +163 -0
  404. package/OpenSpec-main/openspec/changes/archive/2026-05-14-workspace-change-planning/tasks.md +133 -0
  405. package/OpenSpec-main/openspec/changes/fix-opencode-commands-directory/.openspec.yaml +2 -0
  406. package/OpenSpec-main/openspec/changes/fix-opencode-commands-directory/design.md +48 -0
  407. package/OpenSpec-main/openspec/changes/fix-opencode-commands-directory/proposal.md +26 -0
  408. package/OpenSpec-main/openspec/changes/fix-opencode-commands-directory/specs/command-generation/spec.md +63 -0
  409. package/OpenSpec-main/openspec/changes/fix-opencode-commands-directory/tasks.md +19 -0
  410. package/OpenSpec-main/openspec/changes/graceful-status-no-changes/.openspec.yaml +2 -0
  411. package/OpenSpec-main/openspec/changes/graceful-status-no-changes/design.md +38 -0
  412. package/OpenSpec-main/openspec/changes/graceful-status-no-changes/proposal.md +25 -0
  413. package/OpenSpec-main/openspec/changes/graceful-status-no-changes/specs/graceful-status-empty/spec.md +27 -0
  414. package/OpenSpec-main/openspec/changes/graceful-status-no-changes/tasks.md +16 -0
  415. package/OpenSpec-main/openspec/changes/schema-alias-support/.openspec.yaml +2 -0
  416. package/OpenSpec-main/openspec/changes/schema-alias-support/proposal.md +28 -0
  417. package/OpenSpec-main/openspec/changes/simplify-skill-installation/.openspec.yaml +2 -0
  418. package/OpenSpec-main/openspec/changes/simplify-skill-installation/design.md +288 -0
  419. package/OpenSpec-main/openspec/changes/simplify-skill-installation/proposal.md +202 -0
  420. package/OpenSpec-main/openspec/changes/simplify-skill-installation/specs/cli-init/spec.md +199 -0
  421. package/OpenSpec-main/openspec/changes/simplify-skill-installation/specs/cli-update/spec.md +177 -0
  422. package/OpenSpec-main/openspec/changes/simplify-skill-installation/specs/profiles/spec.md +142 -0
  423. package/OpenSpec-main/openspec/changes/simplify-skill-installation/specs/propose-workflow/spec.md +42 -0
  424. package/OpenSpec-main/openspec/changes/simplify-skill-installation/tasks.md +132 -0
  425. package/OpenSpec-main/openspec/changes/unify-template-generation-pipeline/.openspec.yaml +2 -0
  426. package/OpenSpec-main/openspec/changes/unify-template-generation-pipeline/design.md +149 -0
  427. package/OpenSpec-main/openspec/changes/unify-template-generation-pipeline/proposal.md +47 -0
  428. package/OpenSpec-main/openspec/changes/unify-template-generation-pipeline/specs/template-artifact-pipeline/spec.md +89 -0
  429. package/OpenSpec-main/openspec/changes/unify-template-generation-pipeline/tasks.md +41 -0
  430. package/OpenSpec-main/openspec/changes/workspace-agent-guidance/.openspec.yaml +2 -0
  431. package/OpenSpec-main/openspec/changes/workspace-agent-guidance/proposal.md +100 -0
  432. package/OpenSpec-main/openspec/changes/workspace-apply-repo-slice/proposal.md +58 -0
  433. package/OpenSpec-main/openspec/changes/workspace-reimplementation-roadmap/HISTORICAL_DIRECTION.md +511 -0
  434. package/OpenSpec-main/openspec/changes/workspace-reimplementation-roadmap/POC_REFERENCE_GUIDE.md +266 -0
  435. package/OpenSpec-main/openspec/changes/workspace-reimplementation-roadmap/README.md +107 -0
  436. package/OpenSpec-main/openspec/changes/workspace-reimplementation-roadmap/START_HERE.md +105 -0
  437. package/OpenSpec-main/openspec/changes/workspace-reimplementation-roadmap/proposal.md +62 -0
  438. package/OpenSpec-main/openspec/changes/workspace-verify-and-archive/proposal.md +57 -0
  439. package/OpenSpec-main/openspec/config.yaml +36 -0
  440. package/OpenSpec-main/openspec/explorations/explore-workflow-ux.md +116 -0
  441. package/OpenSpec-main/openspec/explorations/workspace-architecture.md +857 -0
  442. package/OpenSpec-main/openspec/explorations/workspace-roadmap.md +367 -0
  443. package/OpenSpec-main/openspec/explorations/workspace-user-journeys.md +2259 -0
  444. package/OpenSpec-main/openspec/explorations/workspace-ux-simplification.md +491 -0
  445. package/OpenSpec-main/openspec/initiatives/context-store-and-initiatives/.initiative.yaml +27 -0
  446. package/OpenSpec-main/openspec/initiatives/context-store-and-initiatives/README.md +33 -0
  447. package/OpenSpec-main/openspec/initiatives/context-store-and-initiatives/decisions.md +204 -0
  448. package/OpenSpec-main/openspec/initiatives/context-store-and-initiatives/direction.md +447 -0
  449. package/OpenSpec-main/openspec/initiatives/context-store-and-initiatives/questions.md +23 -0
  450. package/OpenSpec-main/openspec/initiatives/context-store-and-initiatives/roadmap.md +759 -0
  451. package/OpenSpec-main/openspec/initiatives/context-store-and-initiatives/tasks.md +308 -0
  452. package/OpenSpec-main/openspec/initiatives/context-store-and-initiatives/work-items/01-lock-the-direction/evidence.md +154 -0
  453. package/OpenSpec-main/openspec/initiatives/context-store-and-initiatives/work-items/01-lock-the-direction/plan.md +90 -0
  454. package/OpenSpec-main/openspec/initiatives/context-store-and-initiatives/work-items/01-lock-the-direction/tasks.md +44 -0
  455. package/OpenSpec-main/openspec/initiatives/context-store-and-initiatives/work-items/02-stabilize-workspace-as-local-view/evidence.md +68 -0
  456. package/OpenSpec-main/openspec/initiatives/context-store-and-initiatives/work-items/02-stabilize-workspace-as-local-view/plan.md +80 -0
  457. package/OpenSpec-main/openspec/initiatives/context-store-and-initiatives/work-items/02-stabilize-workspace-as-local-view/tasks.md +23 -0
  458. package/OpenSpec-main/openspec/initiatives/context-store-and-initiatives/work-items/03-add-context-store-foundation/evidence.md +43 -0
  459. package/OpenSpec-main/openspec/initiatives/context-store-and-initiatives/work-items/03-add-context-store-foundation/plan.md +85 -0
  460. package/OpenSpec-main/openspec/initiatives/context-store-and-initiatives/work-items/03-add-context-store-foundation/tasks.md +17 -0
  461. package/OpenSpec-main/openspec/initiatives/context-store-and-initiatives/work-items/04-add-collection-foundation/evidence.md +77 -0
  462. package/OpenSpec-main/openspec/initiatives/context-store-and-initiatives/work-items/04-add-collection-foundation/plan.md +198 -0
  463. package/OpenSpec-main/openspec/initiatives/context-store-and-initiatives/work-items/04-add-collection-foundation/tasks.md +14 -0
  464. package/OpenSpec-main/openspec/initiatives/context-store-and-initiatives/work-items/05-ship-initiative-mvp/evidence.md +99 -0
  465. package/OpenSpec-main/openspec/initiatives/context-store-and-initiatives/work-items/05-ship-initiative-mvp/plan.md +236 -0
  466. package/OpenSpec-main/openspec/initiatives/context-store-and-initiatives/work-items/05-ship-initiative-mvp/tasks.md +21 -0
  467. package/OpenSpec-main/openspec/initiatives/context-store-and-initiatives/work-items/06-add-minimal-context-store-ux/evidence.md +97 -0
  468. package/OpenSpec-main/openspec/initiatives/context-store-and-initiatives/work-items/06-add-minimal-context-store-ux/plan.md +333 -0
  469. package/OpenSpec-main/openspec/initiatives/context-store-and-initiatives/work-items/06-add-minimal-context-store-ux/tasks.md +29 -0
  470. package/OpenSpec-main/openspec/initiatives/context-store-and-initiatives/work-items/07-add-agent-first-initiative-discovery/evidence.md +97 -0
  471. package/OpenSpec-main/openspec/initiatives/context-store-and-initiatives/work-items/07-add-agent-first-initiative-discovery/plan.md +184 -0
  472. package/OpenSpec-main/openspec/initiatives/context-store-and-initiatives/work-items/07-add-agent-first-initiative-discovery/tasks.md +27 -0
  473. package/OpenSpec-main/openspec/initiatives/context-store-and-initiatives/work-items/08-connect-repo-local-changes-to-initiatives/evidence.md +239 -0
  474. package/OpenSpec-main/openspec/initiatives/context-store-and-initiatives/work-items/08-connect-repo-local-changes-to-initiatives/plan.md +279 -0
  475. package/OpenSpec-main/openspec/initiatives/context-store-and-initiatives/work-items/08-connect-repo-local-changes-to-initiatives/tasks.md +22 -0
  476. package/OpenSpec-main/openspec/initiatives/context-store-and-initiatives/work-items/09-add-initiative-resolve/decision-review.md +64 -0
  477. package/OpenSpec-main/openspec/initiatives/context-store-and-initiatives/work-items/09-add-initiative-resolve/evidence.md +106 -0
  478. package/OpenSpec-main/openspec/initiatives/context-store-and-initiatives/work-items/09-add-initiative-resolve/plan.md +141 -0
  479. package/OpenSpec-main/openspec/initiatives/context-store-and-initiatives/work-items/09-add-initiative-resolve/tasks.md +22 -0
  480. package/OpenSpec-main/openspec/initiatives/context-store-and-initiatives/work-items/10-let-workspaces-open-initiatives/plan.md +430 -0
  481. package/OpenSpec-main/openspec/initiatives/context-store-and-initiatives/work-items/10-let-workspaces-open-initiatives/tasks.md +43 -0
  482. package/OpenSpec-main/openspec/initiatives/context-store-and-initiatives/work-items/11-manual-beta-reality-pass/notes.md +289 -0
  483. package/OpenSpec-main/openspec/initiatives/context-store-and-initiatives/work-items/11-manual-beta-reality-pass/plan.md +39 -0
  484. package/OpenSpec-main/openspec/initiatives/context-store-and-initiatives/work-items/11-manual-beta-reality-pass/tasks.md +8 -0
  485. package/OpenSpec-main/openspec/initiatives/context-store-and-initiatives/work-items/12-context-store-first-run-and-cleanup-ux/evidence.md +45 -0
  486. package/OpenSpec-main/openspec/initiatives/context-store-and-initiatives/work-items/12-context-store-first-run-and-cleanup-ux/plan.md +150 -0
  487. package/OpenSpec-main/openspec/initiatives/context-store-and-initiatives/work-items/12-context-store-first-run-and-cleanup-ux/tasks.md +23 -0
  488. package/OpenSpec-main/openspec/initiatives/context-store-and-initiatives/work-items/13-agent-handoff-output-and-delivery-polish/evidence.md +25 -0
  489. package/OpenSpec-main/openspec/initiatives/context-store-and-initiatives/work-items/13-agent-handoff-output-and-delivery-polish/plan.md +98 -0
  490. package/OpenSpec-main/openspec/initiatives/context-store-and-initiatives/work-items/13-agent-handoff-output-and-delivery-polish/tasks.md +25 -0
  491. package/OpenSpec-main/openspec/initiatives/context-store-and-initiatives/work-items/14-workspaces-beta-guide-split/plan.md +37 -0
  492. package/OpenSpec-main/openspec/initiatives/context-store-and-initiatives/work-items/14-workspaces-beta-guide-split/tasks.md +9 -0
  493. package/OpenSpec-main/openspec/initiatives/context-store-and-initiatives/work-items/15-context-store-project-roots-and-schema-led-initiatives/evidence.md +140 -0
  494. package/OpenSpec-main/openspec/initiatives/context-store-and-initiatives/work-items/15-context-store-project-roots-and-schema-led-initiatives/plan.md +344 -0
  495. package/OpenSpec-main/openspec/initiatives/context-store-and-initiatives/work-items/15-context-store-project-roots-and-schema-led-initiatives/tasks.md +39 -0
  496. package/OpenSpec-main/openspec/initiatives/context-store-and-initiatives/work-items/16-add-escalation-ux/plan.md +26 -0
  497. package/OpenSpec-main/openspec/initiatives/context-store-and-initiatives/work-items/16-add-escalation-ux/tasks.md +7 -0
  498. package/OpenSpec-main/openspec/initiatives/context-store-and-initiatives/work-items/17-harden-team-shared-coordination/plan.md +25 -0
  499. package/OpenSpec-main/openspec/initiatives/context-store-and-initiatives/work-items/17-harden-team-shared-coordination/tasks.md +7 -0
  500. package/OpenSpec-main/openspec/initiatives/context-store-and-initiatives/work-items/18-explore-initiative-hosted-target-bound-change-artifacts/evidence.md +397 -0
  501. package/OpenSpec-main/openspec/initiatives/context-store-and-initiatives/work-items/18-explore-initiative-hosted-target-bound-change-artifacts/plan.md +180 -0
  502. package/OpenSpec-main/openspec/initiatives/context-store-and-initiatives/work-items/18-explore-initiative-hosted-target-bound-change-artifacts/tasks.md +28 -0
  503. package/OpenSpec-main/openspec/initiatives/context-store-and-initiatives/work-items/19-review-workspace-beta-compatibility-before-public-release/plan.md +62 -0
  504. package/OpenSpec-main/openspec/initiatives/context-store-and-initiatives/work-items/19-review-workspace-beta-compatibility-before-public-release/tasks.md +16 -0
  505. package/OpenSpec-main/openspec/initiatives/context-store-and-initiatives/work-items/proposed-initiative-next-agent-handoff-ux/evidence.md +47 -0
  506. package/OpenSpec-main/openspec/initiatives/context-store-and-initiatives/work-items/proposed-initiative-next-agent-handoff-ux/plan.md +90 -0
  507. package/OpenSpec-main/openspec/initiatives/context-store-and-initiatives/work-items/proposed-initiative-next-agent-handoff-ux/tasks.md +18 -0
  508. package/OpenSpec-main/openspec/specs/ai-tool-paths/spec.md +63 -0
  509. package/OpenSpec-main/openspec/specs/artifact-graph/spec.md +165 -0
  510. package/OpenSpec-main/openspec/specs/change-creation/spec.md +108 -0
  511. package/OpenSpec-main/openspec/specs/ci-nix-validation/spec.md +107 -0
  512. package/OpenSpec-main/openspec/specs/cli-archive/spec.md +210 -0
  513. package/OpenSpec-main/openspec/specs/cli-artifact-workflow/spec.md +398 -0
  514. package/OpenSpec-main/openspec/specs/cli-change/spec.md +92 -0
  515. package/OpenSpec-main/openspec/specs/cli-completion/spec.md +432 -0
  516. package/OpenSpec-main/openspec/specs/cli-config/spec.md +318 -0
  517. package/OpenSpec-main/openspec/specs/cli-feedback/spec.md +193 -0
  518. package/OpenSpec-main/openspec/specs/cli-init/spec.md +269 -0
  519. package/OpenSpec-main/openspec/specs/cli-list/spec.md +103 -0
  520. package/OpenSpec-main/openspec/specs/cli-show/spec.md +86 -0
  521. package/OpenSpec-main/openspec/specs/cli-spec/spec.md +88 -0
  522. package/OpenSpec-main/openspec/specs/cli-update/spec.md +229 -0
  523. package/OpenSpec-main/openspec/specs/cli-validate/spec.md +219 -0
  524. package/OpenSpec-main/openspec/specs/cli-view/spec.md +129 -0
  525. package/OpenSpec-main/openspec/specs/command-generation/spec.md +97 -0
  526. package/OpenSpec-main/openspec/specs/config-loading/spec.md +122 -0
  527. package/OpenSpec-main/openspec/specs/context-injection/spec.md +53 -0
  528. package/OpenSpec-main/openspec/specs/docs-agent-instructions/spec.md +62 -0
  529. package/OpenSpec-main/openspec/specs/global-config/spec.md +101 -0
  530. package/OpenSpec-main/openspec/specs/instruction-loader/spec.md +70 -0
  531. package/OpenSpec-main/openspec/specs/legacy-cleanup/spec.md +163 -0
  532. package/OpenSpec-main/openspec/specs/openspec-conventions/spec.md +556 -0
  533. package/OpenSpec-main/openspec/specs/opsx-archive-skill/spec.md +128 -0
  534. package/OpenSpec-main/openspec/specs/opsx-onboard-skill/spec.md +167 -0
  535. package/OpenSpec-main/openspec/specs/opsx-verify-skill/spec.md +189 -0
  536. package/OpenSpec-main/openspec/specs/rules-injection/spec.md +102 -0
  537. package/OpenSpec-main/openspec/specs/schema-fork-command/spec.md +71 -0
  538. package/OpenSpec-main/openspec/specs/schema-init-command/spec.md +76 -0
  539. package/OpenSpec-main/openspec/specs/schema-resolution/spec.md +201 -0
  540. package/OpenSpec-main/openspec/specs/schema-validate-command/spec.md +91 -0
  541. package/OpenSpec-main/openspec/specs/schema-which-command/spec.md +70 -0
  542. package/OpenSpec-main/openspec/specs/specs-sync-skill/spec.md +72 -0
  543. package/OpenSpec-main/openspec/specs/telemetry/spec.md +122 -0
  544. package/OpenSpec-main/openspec/specs/workspace-change-planning/spec.md +71 -0
  545. package/OpenSpec-main/openspec/specs/workspace-foundation/spec.md +279 -0
  546. package/OpenSpec-main/openspec/specs/workspace-links/spec.md +529 -0
  547. package/OpenSpec-main/openspec/specs/workspace-open/spec.md +205 -0
  548. package/OpenSpec-main/openspec-parallel-merge-plan.md +98 -0
  549. package/OpenSpec-main/package-lock.json +4978 -0
  550. package/OpenSpec-main/package.json +84 -0
  551. package/OpenSpec-main/pnpm-lock.yaml +3187 -0
  552. package/OpenSpec-main/schemas/spec-driven/schema.yaml +153 -0
  553. package/OpenSpec-main/schemas/spec-driven/templates/design.md +19 -0
  554. package/OpenSpec-main/schemas/spec-driven/templates/proposal.md +23 -0
  555. package/OpenSpec-main/schemas/spec-driven/templates/spec.md +8 -0
  556. package/OpenSpec-main/schemas/spec-driven/templates/tasks.md +9 -0
  557. package/OpenSpec-main/schemas/workspace-planning/schema.yaml +72 -0
  558. package/OpenSpec-main/schemas/workspace-planning/templates/design.md +33 -0
  559. package/OpenSpec-main/schemas/workspace-planning/templates/proposal.md +28 -0
  560. package/OpenSpec-main/schemas/workspace-planning/templates/spec.md +9 -0
  561. package/OpenSpec-main/schemas/workspace-planning/templates/tasks.md +15 -0
  562. package/OpenSpec-main/scripts/README.md +37 -0
  563. package/OpenSpec-main/scripts/pack-version-check.mjs +111 -0
  564. package/OpenSpec-main/scripts/postinstall.js +83 -0
  565. package/OpenSpec-main/scripts/test-postinstall.sh +57 -0
  566. package/OpenSpec-main/scripts/update-flake.sh +128 -0
  567. package/OpenSpec-main/test/cli-e2e/basic.test.ts +205 -0
  568. package/OpenSpec-main/test/commands/artifact-workflow.test.ts +1063 -0
  569. package/OpenSpec-main/test/commands/change-initiative-link.test.ts +532 -0
  570. package/OpenSpec-main/test/commands/change.interactive-show.test.ts +45 -0
  571. package/OpenSpec-main/test/commands/change.interactive-validate.test.ts +48 -0
  572. package/OpenSpec-main/test/commands/completion.test.ts +278 -0
  573. package/OpenSpec-main/test/commands/config-profile.test.ts +532 -0
  574. package/OpenSpec-main/test/commands/config.test.ts +285 -0
  575. package/OpenSpec-main/test/commands/context-store.test.ts +692 -0
  576. package/OpenSpec-main/test/commands/feedback.test.ts +429 -0
  577. package/OpenSpec-main/test/commands/initiative.test.ts +907 -0
  578. package/OpenSpec-main/test/commands/schema.test.ts +467 -0
  579. package/OpenSpec-main/test/commands/show.test.ts +123 -0
  580. package/OpenSpec-main/test/commands/spec.interactive-show.test.ts +44 -0
  581. package/OpenSpec-main/test/commands/spec.interactive-validate.test.ts +44 -0
  582. package/OpenSpec-main/test/commands/spec.test.ts +324 -0
  583. package/OpenSpec-main/test/commands/validate.enriched-output.test.ts +49 -0
  584. package/OpenSpec-main/test/commands/validate.test.ts +147 -0
  585. package/OpenSpec-main/test/commands/workspace-initiative-open.test.ts +638 -0
  586. package/OpenSpec-main/test/commands/workspace-open.test.ts +123 -0
  587. package/OpenSpec-main/test/commands/workspace.interactive.test.ts +696 -0
  588. package/OpenSpec-main/test/commands/workspace.test.ts +1812 -0
  589. package/OpenSpec-main/test/core/archive.test.ts +869 -0
  590. package/OpenSpec-main/test/core/artifact-graph/graph.test.ts +268 -0
  591. package/OpenSpec-main/test/core/artifact-graph/instruction-loader.test.ts +609 -0
  592. package/OpenSpec-main/test/core/artifact-graph/outputs.test.ts +175 -0
  593. package/OpenSpec-main/test/core/artifact-graph/resolver.test.ts +651 -0
  594. package/OpenSpec-main/test/core/artifact-graph/schema.test.ts +207 -0
  595. package/OpenSpec-main/test/core/artifact-graph/state.test.ts +174 -0
  596. package/OpenSpec-main/test/core/artifact-graph/workflow.integration.test.ts +182 -0
  597. package/OpenSpec-main/test/core/available-tools.test.ts +167 -0
  598. package/OpenSpec-main/test/core/collections/initiatives/operations.test.ts +342 -0
  599. package/OpenSpec-main/test/core/collections/initiatives/resolution.test.ts +21 -0
  600. package/OpenSpec-main/test/core/collections/initiatives/schema.test.ts +201 -0
  601. package/OpenSpec-main/test/core/collections/initiatives/templates.test.ts +74 -0
  602. package/OpenSpec-main/test/core/collections/runtime.test.ts +214 -0
  603. package/OpenSpec-main/test/core/command-generation/adapters.test.ts +710 -0
  604. package/OpenSpec-main/test/core/command-generation/generator.test.ts +110 -0
  605. package/OpenSpec-main/test/core/command-generation/registry.test.ts +108 -0
  606. package/OpenSpec-main/test/core/command-generation/types.test.ts +79 -0
  607. package/OpenSpec-main/test/core/commands/change-command.list.test.ts +76 -0
  608. package/OpenSpec-main/test/core/commands/change-command.show-validate.test.ts +111 -0
  609. package/OpenSpec-main/test/core/completions/command-registry.test.ts +201 -0
  610. package/OpenSpec-main/test/core/completions/completion-provider.test.ts +288 -0
  611. package/OpenSpec-main/test/core/completions/generators/bash-generator.test.ts +586 -0
  612. package/OpenSpec-main/test/core/completions/generators/fish-generator.test.ts +549 -0
  613. package/OpenSpec-main/test/core/completions/generators/powershell-generator.test.ts +621 -0
  614. package/OpenSpec-main/test/core/completions/generators/zsh-generator.test.ts +425 -0
  615. package/OpenSpec-main/test/core/completions/installers/bash-installer.test.ts +484 -0
  616. package/OpenSpec-main/test/core/completions/installers/fish-installer.test.ts +321 -0
  617. package/OpenSpec-main/test/core/completions/installers/powershell-installer.test.ts +824 -0
  618. package/OpenSpec-main/test/core/completions/installers/zsh-installer.test.ts +750 -0
  619. package/OpenSpec-main/test/core/config-schema.test.ts +340 -0
  620. package/OpenSpec-main/test/core/context-store/foundation.test.ts +364 -0
  621. package/OpenSpec-main/test/core/context-store/registry.test.ts +599 -0
  622. package/OpenSpec-main/test/core/converters/json-converter.test.ts +184 -0
  623. package/OpenSpec-main/test/core/global-config.test.ts +371 -0
  624. package/OpenSpec-main/test/core/init.test.ts +786 -0
  625. package/OpenSpec-main/test/core/legacy-cleanup.test.ts +1162 -0
  626. package/OpenSpec-main/test/core/list.test.ts +165 -0
  627. package/OpenSpec-main/test/core/migration.test.ts +150 -0
  628. package/OpenSpec-main/test/core/parsers/change-parser.test.ts +52 -0
  629. package/OpenSpec-main/test/core/parsers/markdown-parser.test.ts +355 -0
  630. package/OpenSpec-main/test/core/parsers/requirement-blocks.test.ts +46 -0
  631. package/OpenSpec-main/test/core/planning-home.test.ts +120 -0
  632. package/OpenSpec-main/test/core/profile-sync-drift.test.ts +92 -0
  633. package/OpenSpec-main/test/core/profiles.test.ts +63 -0
  634. package/OpenSpec-main/test/core/project-config.test.ts +610 -0
  635. package/OpenSpec-main/test/core/shared/skill-generation.test.ts +301 -0
  636. package/OpenSpec-main/test/core/shared/tool-detection.test.ts +333 -0
  637. package/OpenSpec-main/test/core/templates/skill-templates-parity.test.ts +172 -0
  638. package/OpenSpec-main/test/core/update.test.ts +1810 -0
  639. package/OpenSpec-main/test/core/validation.enriched-messages.test.ts +74 -0
  640. package/OpenSpec-main/test/core/validation.test.ts +680 -0
  641. package/OpenSpec-main/test/core/view.test.ts +129 -0
  642. package/OpenSpec-main/test/core/workspace/foundation.test.ts +694 -0
  643. package/OpenSpec-main/test/core/workspace/legacy-state.test.ts +221 -0
  644. package/OpenSpec-main/test/core/workspace/skills.test.ts +69 -0
  645. package/OpenSpec-main/test/fixtures/tmp-init/openspec/changes/c1/proposal.md +7 -0
  646. package/OpenSpec-main/test/fixtures/tmp-init/openspec/changes/c1/specs/alpha/spec.md +8 -0
  647. package/OpenSpec-main/test/fixtures/tmp-init/openspec/specs/alpha/spec.md +12 -0
  648. package/OpenSpec-main/test/helpers/path-env.ts +26 -0
  649. package/OpenSpec-main/test/helpers/run-cli.ts +150 -0
  650. package/OpenSpec-main/test/prompts/searchable-multi-select.test.ts +220 -0
  651. package/OpenSpec-main/test/specs/source-specs-normalization.test.ts +63 -0
  652. package/OpenSpec-main/test/telemetry/config.test.ts +298 -0
  653. package/OpenSpec-main/test/telemetry/index.test.ts +219 -0
  654. package/OpenSpec-main/test/utils/change-metadata.test.ts +368 -0
  655. package/OpenSpec-main/test/utils/change-utils.test.ts +201 -0
  656. package/OpenSpec-main/test/utils/command-references.test.ts +83 -0
  657. package/OpenSpec-main/test/utils/file-system.test.ts +322 -0
  658. package/OpenSpec-main/test/utils/interactive.test.ts +125 -0
  659. package/OpenSpec-main/test/utils/marker-updates.test.ts +448 -0
  660. package/OpenSpec-main/test/utils/shell-detection.test.ts +185 -0
  661. package/OpenSpec-main/vitest.config.ts +47 -0
  662. package/OpenSpec-main/vitest.setup.ts +15 -0
  663. package/README.md +37 -4
  664. package/Scanner CLI Inteligente para Projetos.md +433 -0
  665. package/dist/index.js +1248 -161
  666. package/package.json +1 -1
  667. package/templates/wiki-recipes/nextjs.rules.md +21 -0
  668. package/templates/wiki-recipes/postgresql.rules.md +20 -0
  669. package/templates/wiki-recipes/react.rules.md +18 -0
  670. package/templates/wiki-recipes/tailwindcss.rules.md +18 -0
  671. package/templates/wiki-recipes/typescript.rules.md +21 -0
@@ -0,0 +1,1162 @@
1
+ import { describe, it, expect, beforeEach, afterEach } from 'vitest';
2
+ import { promises as fs } from 'fs';
3
+ import path from 'path';
4
+ import os from 'os';
5
+ import { randomUUID } from 'crypto';
6
+ import {
7
+ detectLegacyArtifacts,
8
+ detectLegacyConfigFiles,
9
+ detectLegacySlashCommands,
10
+ detectLegacyStructureFiles,
11
+ hasOpenSpecMarkers,
12
+ isOnlyOpenSpecContent,
13
+ removeMarkerBlock,
14
+ cleanupLegacyArtifacts,
15
+ formatCleanupSummary,
16
+ formatDetectionSummary,
17
+ formatProjectMdMigrationHint,
18
+ getToolsFromLegacyArtifacts,
19
+ LEGACY_CONFIG_FILES,
20
+ LEGACY_SLASH_COMMAND_PATHS,
21
+ } from '../../src/core/legacy-cleanup.js';
22
+ import { OPENSPEC_MARKERS } from '../../src/core/config.js';
23
+ import { CommandAdapterRegistry } from '../../src/core/command-generation/registry.js';
24
+
25
+ describe('legacy-cleanup', () => {
26
+ let testDir: string;
27
+
28
+ beforeEach(async () => {
29
+ testDir = path.join(os.tmpdir(), `openspec-legacy-test-${randomUUID()}`);
30
+ await fs.mkdir(testDir, { recursive: true });
31
+ // Create openspec directory structure
32
+ await fs.mkdir(path.join(testDir, 'openspec'), { recursive: true });
33
+ });
34
+
35
+ afterEach(async () => {
36
+ await fs.rm(testDir, { recursive: true, force: true });
37
+ });
38
+
39
+ describe('hasOpenSpecMarkers', () => {
40
+ it('should return true when both markers are present', () => {
41
+ const content = `Some content
42
+ ${OPENSPEC_MARKERS.start}
43
+ OpenSpec content
44
+ ${OPENSPEC_MARKERS.end}
45
+ More content`;
46
+ expect(hasOpenSpecMarkers(content)).toBe(true);
47
+ });
48
+
49
+ it('should return false when start marker is missing', () => {
50
+ const content = `Some content
51
+ OpenSpec content
52
+ ${OPENSPEC_MARKERS.end}`;
53
+ expect(hasOpenSpecMarkers(content)).toBe(false);
54
+ });
55
+
56
+ it('should return false when end marker is missing', () => {
57
+ const content = `${OPENSPEC_MARKERS.start}
58
+ OpenSpec content
59
+ Some content`;
60
+ expect(hasOpenSpecMarkers(content)).toBe(false);
61
+ });
62
+
63
+ it('should return false when no markers are present', () => {
64
+ const content = 'Plain content without markers';
65
+ expect(hasOpenSpecMarkers(content)).toBe(false);
66
+ });
67
+ });
68
+
69
+ describe('isOnlyOpenSpecContent', () => {
70
+ it('should return true when content is only markers and whitespace outside', () => {
71
+ const content = `${OPENSPEC_MARKERS.start}
72
+ OpenSpec content here
73
+ ${OPENSPEC_MARKERS.end}`;
74
+ expect(isOnlyOpenSpecContent(content)).toBe(true);
75
+ });
76
+
77
+ it('should return true with whitespace before and after markers', () => {
78
+ const content = `
79
+
80
+ ${OPENSPEC_MARKERS.start}
81
+ OpenSpec content
82
+ ${OPENSPEC_MARKERS.end}
83
+
84
+ `;
85
+ expect(isOnlyOpenSpecContent(content)).toBe(true);
86
+ });
87
+
88
+ it('should return false when content exists before markers', () => {
89
+ const content = `User content here
90
+ ${OPENSPEC_MARKERS.start}
91
+ OpenSpec content
92
+ ${OPENSPEC_MARKERS.end}`;
93
+ expect(isOnlyOpenSpecContent(content)).toBe(false);
94
+ });
95
+
96
+ it('should return false when content exists after markers', () => {
97
+ const content = `${OPENSPEC_MARKERS.start}
98
+ OpenSpec content
99
+ ${OPENSPEC_MARKERS.end}
100
+ User content here`;
101
+ expect(isOnlyOpenSpecContent(content)).toBe(false);
102
+ });
103
+
104
+ it('should return false when markers are missing', () => {
105
+ const content = 'Plain content without markers';
106
+ expect(isOnlyOpenSpecContent(content)).toBe(false);
107
+ });
108
+
109
+ it('should return false when end marker comes before start marker', () => {
110
+ const content = `${OPENSPEC_MARKERS.end}
111
+ Content
112
+ ${OPENSPEC_MARKERS.start}`;
113
+ expect(isOnlyOpenSpecContent(content)).toBe(false);
114
+ });
115
+ });
116
+
117
+ describe('removeMarkerBlock', () => {
118
+ it('should remove marker block and preserve content before', () => {
119
+ const content = `User content before
120
+ ${OPENSPEC_MARKERS.start}
121
+ OpenSpec content
122
+ ${OPENSPEC_MARKERS.end}`;
123
+ const result = removeMarkerBlock(content);
124
+ expect(result).toBe('User content before\n');
125
+ expect(result).not.toContain(OPENSPEC_MARKERS.start);
126
+ expect(result).not.toContain(OPENSPEC_MARKERS.end);
127
+ });
128
+
129
+ it('should remove marker block and preserve content after', () => {
130
+ const content = `${OPENSPEC_MARKERS.start}
131
+ OpenSpec content
132
+ ${OPENSPEC_MARKERS.end}
133
+ User content after`;
134
+ const result = removeMarkerBlock(content);
135
+ expect(result).toBe('User content after\n');
136
+ });
137
+
138
+ it('should remove marker block and preserve content before and after', () => {
139
+ const content = `User content before
140
+ ${OPENSPEC_MARKERS.start}
141
+ OpenSpec content
142
+ ${OPENSPEC_MARKERS.end}
143
+ User content after`;
144
+ const result = removeMarkerBlock(content);
145
+ expect(result).toContain('User content before');
146
+ expect(result).toContain('User content after');
147
+ expect(result).not.toContain(OPENSPEC_MARKERS.start);
148
+ });
149
+
150
+ it('should clean up double blank lines', () => {
151
+ const content = `Line 1
152
+
153
+
154
+ ${OPENSPEC_MARKERS.start}
155
+ OpenSpec content
156
+ ${OPENSPEC_MARKERS.end}
157
+
158
+
159
+ Line 2`;
160
+ const result = removeMarkerBlock(content);
161
+ expect(result).not.toMatch(/\n{3,}/);
162
+ });
163
+
164
+ it('should return empty string when only markers remain', () => {
165
+ const content = `${OPENSPEC_MARKERS.start}
166
+ OpenSpec content
167
+ ${OPENSPEC_MARKERS.end}`;
168
+ const result = removeMarkerBlock(content);
169
+ expect(result).toBe('');
170
+ });
171
+
172
+ it('should return original content when markers are missing', () => {
173
+ const content = 'Plain content without markers';
174
+ const result = removeMarkerBlock(content);
175
+ // When no markers found, content is returned trimmed (no trailing newline added)
176
+ expect(result).toBe('Plain content without markers');
177
+ });
178
+
179
+ it('should return original content when markers are in wrong order', () => {
180
+ const content = `${OPENSPEC_MARKERS.end}
181
+ Content
182
+ ${OPENSPEC_MARKERS.start}`;
183
+ const result = removeMarkerBlock(content);
184
+ expect(result).toContain(OPENSPEC_MARKERS.end);
185
+ expect(result).toContain(OPENSPEC_MARKERS.start);
186
+ });
187
+
188
+ it('should ignore inline mentions of markers and only remove actual block', () => {
189
+ const content = `Intro referencing ${OPENSPEC_MARKERS.start} and ${OPENSPEC_MARKERS.end} inline.
190
+
191
+ ${OPENSPEC_MARKERS.start}
192
+ Managed content here
193
+ ${OPENSPEC_MARKERS.end}
194
+ After content`;
195
+ const result = removeMarkerBlock(content);
196
+ // Inline mentions preserved
197
+ expect(result).toContain('Intro referencing');
198
+ expect(result).toContain(OPENSPEC_MARKERS.start);
199
+ expect(result).toContain(OPENSPEC_MARKERS.end);
200
+ // Managed content removed
201
+ expect(result).not.toContain('Managed content here');
202
+ expect(result).toContain('After content');
203
+ });
204
+ });
205
+
206
+ describe('detectLegacyConfigFiles', () => {
207
+ it('should detect CLAUDE.md with OpenSpec markers and put in update list', async () => {
208
+ const claudePath = path.join(testDir, 'CLAUDE.md');
209
+ await fs.writeFile(claudePath, `${OPENSPEC_MARKERS.start}
210
+ OpenSpec content
211
+ ${OPENSPEC_MARKERS.end}`);
212
+
213
+ const result = await detectLegacyConfigFiles(testDir);
214
+ expect(result.allFiles).toContain('CLAUDE.md');
215
+ // Config files are NEVER deleted, always updated (markers removed)
216
+ expect(result.filesToUpdate).toContain('CLAUDE.md');
217
+ });
218
+
219
+ it('should detect files with mixed content and put in update list', async () => {
220
+ const claudePath = path.join(testDir, 'CLAUDE.md');
221
+ await fs.writeFile(claudePath, `User instructions here
222
+ ${OPENSPEC_MARKERS.start}
223
+ OpenSpec content
224
+ ${OPENSPEC_MARKERS.end}`);
225
+
226
+ const result = await detectLegacyConfigFiles(testDir);
227
+ expect(result.allFiles).toContain('CLAUDE.md');
228
+ expect(result.filesToUpdate).toContain('CLAUDE.md');
229
+ });
230
+
231
+ it('should not detect files without OpenSpec markers', async () => {
232
+ const claudePath = path.join(testDir, 'CLAUDE.md');
233
+ await fs.writeFile(claudePath, 'Plain instructions without markers');
234
+
235
+ const result = await detectLegacyConfigFiles(testDir);
236
+ expect(result.allFiles).not.toContain('CLAUDE.md');
237
+ });
238
+
239
+ it('should detect multiple config files', async () => {
240
+ // Create multiple config files with markers
241
+ await fs.writeFile(path.join(testDir, 'CLAUDE.md'), `${OPENSPEC_MARKERS.start}\nContent\n${OPENSPEC_MARKERS.end}`);
242
+ await fs.writeFile(path.join(testDir, 'CLINE.md'), `${OPENSPEC_MARKERS.start}\nContent\n${OPENSPEC_MARKERS.end}`);
243
+ await fs.writeFile(path.join(testDir, 'QODER.md'), `${OPENSPEC_MARKERS.start}\nContent\n${OPENSPEC_MARKERS.end}`);
244
+
245
+ const result = await detectLegacyConfigFiles(testDir);
246
+ expect(result.allFiles).toHaveLength(3);
247
+ expect(result.allFiles).toContain('CLAUDE.md');
248
+ expect(result.allFiles).toContain('CLINE.md');
249
+ expect(result.allFiles).toContain('QODER.md');
250
+ // All should be in update list, none deleted
251
+ expect(result.filesToUpdate).toHaveLength(3);
252
+ });
253
+
254
+ it('should handle non-existent files gracefully', async () => {
255
+ const result = await detectLegacyConfigFiles(testDir);
256
+ expect(result.allFiles).toHaveLength(0);
257
+ expect(result.filesToUpdate).toHaveLength(0);
258
+ });
259
+ });
260
+
261
+ describe('detectLegacySlashCommands', () => {
262
+ it('should detect legacy Claude slash command directory', async () => {
263
+ const dirPath = path.join(testDir, '.claude', 'commands', 'openspec');
264
+ await fs.mkdir(dirPath, { recursive: true });
265
+ await fs.writeFile(path.join(dirPath, 'proposal.md'), 'content');
266
+
267
+ const result = await detectLegacySlashCommands(testDir);
268
+ expect(result.directories).toContain('.claude/commands/openspec');
269
+ });
270
+
271
+ it('should detect legacy Cursor slash command files', async () => {
272
+ const dirPath = path.join(testDir, '.cursor', 'commands');
273
+ await fs.mkdir(dirPath, { recursive: true });
274
+ await fs.writeFile(path.join(dirPath, 'openspec-proposal.md'), 'content');
275
+ await fs.writeFile(path.join(dirPath, 'openspec-apply.md'), 'content');
276
+
277
+ const result = await detectLegacySlashCommands(testDir);
278
+ expect(result.files).toContain('.cursor/commands/openspec-proposal.md');
279
+ expect(result.files).toContain('.cursor/commands/openspec-apply.md');
280
+ });
281
+
282
+ it('should detect legacy Windsurf workflow files', async () => {
283
+ const dirPath = path.join(testDir, '.windsurf', 'workflows');
284
+ await fs.mkdir(dirPath, { recursive: true });
285
+ await fs.writeFile(path.join(dirPath, 'openspec-archive.md'), 'content');
286
+
287
+ const result = await detectLegacySlashCommands(testDir);
288
+ expect(result.files).toContain('.windsurf/workflows/openspec-archive.md');
289
+ });
290
+
291
+ it('should detect multiple tool directories and files', async () => {
292
+ // Create directory-based
293
+ await fs.mkdir(path.join(testDir, '.claude', 'commands', 'openspec'), { recursive: true });
294
+ await fs.mkdir(path.join(testDir, '.qoder', 'commands', 'openspec'), { recursive: true });
295
+
296
+ // Create file-based
297
+ await fs.mkdir(path.join(testDir, '.cursor', 'commands'), { recursive: true });
298
+ await fs.writeFile(path.join(testDir, '.cursor', 'commands', 'openspec-proposal.md'), 'content');
299
+
300
+ const result = await detectLegacySlashCommands(testDir);
301
+ expect(result.directories).toContain('.claude/commands/openspec');
302
+ expect(result.directories).toContain('.qoder/commands/openspec');
303
+ expect(result.files).toContain('.cursor/commands/openspec-proposal.md');
304
+ });
305
+
306
+ it('should not detect non-openspec files', async () => {
307
+ const dirPath = path.join(testDir, '.cursor', 'commands');
308
+ await fs.mkdir(dirPath, { recursive: true });
309
+ await fs.writeFile(path.join(dirPath, 'other-command.md'), 'content');
310
+
311
+ const result = await detectLegacySlashCommands(testDir);
312
+ expect(result.files).not.toContain('.cursor/commands/other-command.md');
313
+ });
314
+
315
+ it('should handle non-existent directories gracefully', async () => {
316
+ const result = await detectLegacySlashCommands(testDir);
317
+ expect(result.directories).toHaveLength(0);
318
+ expect(result.files).toHaveLength(0);
319
+ });
320
+
321
+ it('should detect TOML-based slash commands for Qwen', async () => {
322
+ const dirPath = path.join(testDir, '.qwen', 'commands');
323
+ await fs.mkdir(dirPath, { recursive: true });
324
+ await fs.writeFile(path.join(dirPath, 'openspec-proposal.toml'), 'content');
325
+
326
+ const result = await detectLegacySlashCommands(testDir);
327
+ expect(result.files).toContain('.qwen/commands/openspec-proposal.toml');
328
+ });
329
+
330
+ it('should detect Continue prompt files', async () => {
331
+ const dirPath = path.join(testDir, '.continue', 'prompts');
332
+ await fs.mkdir(dirPath, { recursive: true });
333
+ await fs.writeFile(path.join(dirPath, 'openspec-apply.prompt'), 'content');
334
+
335
+ const result = await detectLegacySlashCommands(testDir);
336
+ expect(result.files).toContain('.continue/prompts/openspec-apply.prompt');
337
+ });
338
+
339
+ it('should detect legacy OpenCode opsx-* command files', async () => {
340
+ const dirPath = path.join(testDir, '.opencode', 'command');
341
+ await fs.mkdir(dirPath, { recursive: true });
342
+ await fs.writeFile(path.join(dirPath, 'opsx-propose.md'), 'content');
343
+
344
+ const result = await detectLegacySlashCommands(testDir);
345
+ expect(result.files).toContain('.opencode/command/opsx-propose.md');
346
+ });
347
+
348
+ it('should detect legacy OpenCode openspec-* command files', async () => {
349
+ const dirPath = path.join(testDir, '.opencode', 'command');
350
+ await fs.mkdir(dirPath, { recursive: true });
351
+ await fs.writeFile(path.join(dirPath, 'openspec-new.md'), 'content');
352
+
353
+ const result = await detectLegacySlashCommands(testDir);
354
+ expect(result.files).toContain('.opencode/command/openspec-new.md');
355
+ });
356
+
357
+ it('should detect both opsx-* and openspec-* OpenCode command files', async () => {
358
+ const dirPath = path.join(testDir, '.opencode', 'command');
359
+ await fs.mkdir(dirPath, { recursive: true });
360
+ await fs.writeFile(path.join(dirPath, 'opsx-propose.md'), 'content');
361
+ await fs.writeFile(path.join(dirPath, 'openspec-new.md'), 'content');
362
+
363
+ const result = await detectLegacySlashCommands(testDir);
364
+ expect(result.files).toContain('.opencode/command/opsx-propose.md');
365
+ expect(result.files).toContain('.opencode/command/openspec-new.md');
366
+ });
367
+ });
368
+
369
+ describe('detectLegacyStructureFiles', () => {
370
+ it('should detect openspec/AGENTS.md', async () => {
371
+ const agentsPath = path.join(testDir, 'openspec', 'AGENTS.md');
372
+ await fs.writeFile(agentsPath, '# AGENTS.md content');
373
+
374
+ const result = await detectLegacyStructureFiles(testDir);
375
+ expect(result.hasOpenspecAgents).toBe(true);
376
+ });
377
+
378
+ it('should detect openspec/project.md', async () => {
379
+ const projectPath = path.join(testDir, 'openspec', 'project.md');
380
+ await fs.writeFile(projectPath, '# Project content');
381
+
382
+ const result = await detectLegacyStructureFiles(testDir);
383
+ expect(result.hasProjectMd).toBe(true);
384
+ });
385
+
386
+ it('should detect root AGENTS.md with OpenSpec markers', async () => {
387
+ const agentsPath = path.join(testDir, 'AGENTS.md');
388
+ await fs.writeFile(agentsPath, `${OPENSPEC_MARKERS.start}
389
+ OpenSpec content
390
+ ${OPENSPEC_MARKERS.end}`);
391
+
392
+ const result = await detectLegacyStructureFiles(testDir);
393
+ expect(result.hasRootAgentsWithMarkers).toBe(true);
394
+ });
395
+
396
+ it('should not detect root AGENTS.md without markers', async () => {
397
+ const agentsPath = path.join(testDir, 'AGENTS.md');
398
+ await fs.writeFile(agentsPath, 'Plain content without markers');
399
+
400
+ const result = await detectLegacyStructureFiles(testDir);
401
+ expect(result.hasRootAgentsWithMarkers).toBe(false);
402
+ });
403
+
404
+ it('should handle non-existent files gracefully', async () => {
405
+ const result = await detectLegacyStructureFiles(testDir);
406
+ expect(result.hasOpenspecAgents).toBe(false);
407
+ expect(result.hasProjectMd).toBe(false);
408
+ expect(result.hasRootAgentsWithMarkers).toBe(false);
409
+ });
410
+ });
411
+
412
+ describe('detectLegacyArtifacts', () => {
413
+ it('should return hasLegacyArtifacts: false when nothing is found', async () => {
414
+ const result = await detectLegacyArtifacts(testDir);
415
+ expect(result.hasLegacyArtifacts).toBe(false);
416
+ });
417
+
418
+ it('should return hasLegacyArtifacts: true when config files are found', async () => {
419
+ await fs.writeFile(path.join(testDir, 'CLAUDE.md'), `${OPENSPEC_MARKERS.start}\nContent\n${OPENSPEC_MARKERS.end}`);
420
+
421
+ const result = await detectLegacyArtifacts(testDir);
422
+ expect(result.hasLegacyArtifacts).toBe(true);
423
+ expect(result.configFiles).toContain('CLAUDE.md');
424
+ });
425
+
426
+ it('should return hasLegacyArtifacts: true when slash commands are found', async () => {
427
+ await fs.mkdir(path.join(testDir, '.claude', 'commands', 'openspec'), { recursive: true });
428
+
429
+ const result = await detectLegacyArtifacts(testDir);
430
+ expect(result.hasLegacyArtifacts).toBe(true);
431
+ expect(result.slashCommandDirs).toContain('.claude/commands/openspec');
432
+ });
433
+
434
+ it('should return hasLegacyArtifacts: true when openspec/AGENTS.md is found', async () => {
435
+ await fs.writeFile(path.join(testDir, 'openspec', 'AGENTS.md'), 'content');
436
+
437
+ const result = await detectLegacyArtifacts(testDir);
438
+ expect(result.hasLegacyArtifacts).toBe(true);
439
+ expect(result.hasOpenspecAgents).toBe(true);
440
+ });
441
+
442
+ it('should detect project.md for migration hint (it is preserved, not deleted)', async () => {
443
+ await fs.writeFile(path.join(testDir, 'openspec', 'project.md'), 'content');
444
+
445
+ const result = await detectLegacyArtifacts(testDir);
446
+ // project.md triggers hasLegacyArtifacts to show migration hint
447
+ expect(result.hasLegacyArtifacts).toBe(true);
448
+ expect(result.hasProjectMd).toBe(true);
449
+ });
450
+
451
+ it('should combine all detection results', async () => {
452
+ // Create various legacy artifacts
453
+ await fs.writeFile(path.join(testDir, 'CLAUDE.md'), `${OPENSPEC_MARKERS.start}\nContent\n${OPENSPEC_MARKERS.end}`);
454
+ await fs.mkdir(path.join(testDir, '.claude', 'commands', 'openspec'), { recursive: true });
455
+ await fs.writeFile(path.join(testDir, 'openspec', 'AGENTS.md'), 'content');
456
+ await fs.writeFile(path.join(testDir, 'openspec', 'project.md'), 'content');
457
+
458
+ const result = await detectLegacyArtifacts(testDir);
459
+ expect(result.hasLegacyArtifacts).toBe(true);
460
+ expect(result.configFiles).toContain('CLAUDE.md');
461
+ expect(result.slashCommandDirs).toContain('.claude/commands/openspec');
462
+ expect(result.hasOpenspecAgents).toBe(true);
463
+ expect(result.hasProjectMd).toBe(true);
464
+ });
465
+ });
466
+
467
+ describe('cleanupLegacyArtifacts', () => {
468
+ it('should remove markers from config files that have only OpenSpec content (never delete)', async () => {
469
+ const claudePath = path.join(testDir, 'CLAUDE.md');
470
+ await fs.writeFile(claudePath, `${OPENSPEC_MARKERS.start}\nContent\n${OPENSPEC_MARKERS.end}`);
471
+
472
+ const detection = await detectLegacyArtifacts(testDir);
473
+ const result = await cleanupLegacyArtifacts(testDir, detection);
474
+
475
+ // Config files should NEVER be deleted, only have markers removed
476
+ expect(result.deletedFiles).not.toContain('CLAUDE.md');
477
+ expect(result.modifiedFiles).toContain('CLAUDE.md');
478
+ // File should still exist
479
+ await expect(fs.access(claudePath)).resolves.not.toThrow();
480
+ // File should be empty or have markers removed
481
+ const content = await fs.readFile(claudePath, 'utf-8');
482
+ expect(content).not.toContain(OPENSPEC_MARKERS.start);
483
+ expect(content).not.toContain(OPENSPEC_MARKERS.end);
484
+ });
485
+
486
+ it('should remove marker block from files with mixed content', async () => {
487
+ const claudePath = path.join(testDir, 'CLAUDE.md');
488
+ await fs.writeFile(claudePath, `User instructions
489
+ ${OPENSPEC_MARKERS.start}
490
+ OpenSpec content
491
+ ${OPENSPEC_MARKERS.end}`);
492
+
493
+ const detection = await detectLegacyArtifacts(testDir);
494
+ const result = await cleanupLegacyArtifacts(testDir, detection);
495
+
496
+ expect(result.modifiedFiles).toContain('CLAUDE.md');
497
+ const content = await fs.readFile(claudePath, 'utf-8');
498
+ expect(content).toContain('User instructions');
499
+ expect(content).not.toContain(OPENSPEC_MARKERS.start);
500
+ });
501
+
502
+ it('should delete legacy slash command directories', async () => {
503
+ const dirPath = path.join(testDir, '.claude', 'commands', 'openspec');
504
+ await fs.mkdir(dirPath, { recursive: true });
505
+ await fs.writeFile(path.join(dirPath, 'proposal.md'), 'content');
506
+
507
+ const detection = await detectLegacyArtifacts(testDir);
508
+ const result = await cleanupLegacyArtifacts(testDir, detection);
509
+
510
+ expect(result.deletedDirs).toContain('.claude/commands/openspec');
511
+ await expect(fs.access(dirPath)).rejects.toThrow();
512
+ // Parent directory should still exist
513
+ await expect(fs.access(path.join(testDir, '.claude', 'commands'))).resolves.not.toThrow();
514
+ });
515
+
516
+ it('should delete legacy slash command files', async () => {
517
+ const dirPath = path.join(testDir, '.cursor', 'commands');
518
+ await fs.mkdir(dirPath, { recursive: true });
519
+ const filePath = path.join(dirPath, 'openspec-proposal.md');
520
+ await fs.writeFile(filePath, 'content');
521
+
522
+ const detection = await detectLegacyArtifacts(testDir);
523
+ const result = await cleanupLegacyArtifacts(testDir, detection);
524
+
525
+ expect(result.deletedFiles).toContain('.cursor/commands/openspec-proposal.md');
526
+ await expect(fs.access(filePath)).rejects.toThrow();
527
+ });
528
+
529
+ it('should delete openspec/AGENTS.md', async () => {
530
+ const agentsPath = path.join(testDir, 'openspec', 'AGENTS.md');
531
+ await fs.writeFile(agentsPath, 'content');
532
+
533
+ const detection = await detectLegacyArtifacts(testDir);
534
+ const result = await cleanupLegacyArtifacts(testDir, detection);
535
+
536
+ expect(result.deletedFiles).toContain('openspec/AGENTS.md');
537
+ await expect(fs.access(agentsPath)).rejects.toThrow();
538
+ // openspec directory should still exist
539
+ await expect(fs.access(path.join(testDir, 'openspec'))).resolves.not.toThrow();
540
+ });
541
+
542
+ it('should NOT delete openspec/project.md', async () => {
543
+ const projectPath = path.join(testDir, 'openspec', 'project.md');
544
+ await fs.writeFile(projectPath, 'User project content');
545
+
546
+ const detection = await detectLegacyArtifacts(testDir);
547
+ const result = await cleanupLegacyArtifacts(testDir, detection);
548
+
549
+ expect(result.projectMdNeedsMigration).toBe(true);
550
+ expect(result.deletedFiles).not.toContain('openspec/project.md');
551
+ await expect(fs.access(projectPath)).resolves.not.toThrow();
552
+ });
553
+
554
+ it('should handle root AGENTS.md with mixed content', async () => {
555
+ const agentsPath = path.join(testDir, 'AGENTS.md');
556
+ await fs.writeFile(agentsPath, `User content
557
+ ${OPENSPEC_MARKERS.start}
558
+ OpenSpec content
559
+ ${OPENSPEC_MARKERS.end}`);
560
+
561
+ const detection = await detectLegacyArtifacts(testDir);
562
+ const result = await cleanupLegacyArtifacts(testDir, detection);
563
+
564
+ expect(result.modifiedFiles).toContain('AGENTS.md');
565
+ const content = await fs.readFile(agentsPath, 'utf-8');
566
+ expect(content).toContain('User content');
567
+ expect(content).not.toContain(OPENSPEC_MARKERS.start);
568
+ });
569
+
570
+ it('should remove markers from root AGENTS.md even when only OpenSpec content (never delete)', async () => {
571
+ const agentsPath = path.join(testDir, 'AGENTS.md');
572
+ await fs.writeFile(agentsPath, `${OPENSPEC_MARKERS.start}\nOpenSpec content\n${OPENSPEC_MARKERS.end}`);
573
+
574
+ const detection = await detectLegacyArtifacts(testDir);
575
+ const result = await cleanupLegacyArtifacts(testDir, detection);
576
+
577
+ // Root AGENTS.md should NEVER be deleted, only have markers removed
578
+ expect(result.deletedFiles).not.toContain('AGENTS.md');
579
+ expect(result.modifiedFiles).toContain('AGENTS.md');
580
+ // File should still exist
581
+ await expect(fs.access(agentsPath)).resolves.not.toThrow();
582
+ });
583
+
584
+ it('should report errors without stopping cleanup', async () => {
585
+ // Create a valid detection result with a non-existent file to simulate error
586
+ const detection = {
587
+ configFiles: ['NON_EXISTENT.md'],
588
+ configFilesToUpdate: ['NON_EXISTENT.md'],
589
+ slashCommandDirs: [],
590
+ slashCommandFiles: [],
591
+ hasOpenspecAgents: false,
592
+ hasProjectMd: false,
593
+ hasRootAgentsWithMarkers: false,
594
+ hasLegacyArtifacts: true,
595
+ };
596
+
597
+ const result = await cleanupLegacyArtifacts(testDir, detection);
598
+
599
+ // Should not throw, but should record the error
600
+ expect(result.errors.length).toBeGreaterThan(0);
601
+ expect(result.errors[0]).toContain('NON_EXISTENT.md');
602
+ });
603
+ });
604
+
605
+ describe('formatCleanupSummary', () => {
606
+ it('should format deleted files', () => {
607
+ const result = {
608
+ deletedFiles: ['CLAUDE.md', 'CLINE.md'],
609
+ modifiedFiles: [],
610
+ deletedDirs: [],
611
+ projectMdNeedsMigration: false,
612
+ errors: [],
613
+ };
614
+
615
+ const summary = formatCleanupSummary(result);
616
+ expect(summary).toContain('Cleaned up legacy files:');
617
+ expect(summary).toContain('✓ Removed CLAUDE.md');
618
+ expect(summary).toContain('✓ Removed CLINE.md');
619
+ });
620
+
621
+ it('should format deleted directories', () => {
622
+ const result = {
623
+ deletedFiles: [],
624
+ modifiedFiles: [],
625
+ deletedDirs: ['.claude/commands/openspec'],
626
+ projectMdNeedsMigration: false,
627
+ errors: [],
628
+ };
629
+
630
+ const summary = formatCleanupSummary(result);
631
+ expect(summary).toContain('✓ Removed .claude/commands/openspec/ (replaced by /opsx:*)');
632
+ });
633
+
634
+ it('should format modified files', () => {
635
+ const result = {
636
+ deletedFiles: [],
637
+ modifiedFiles: ['AGENTS.md'],
638
+ deletedDirs: [],
639
+ projectMdNeedsMigration: false,
640
+ errors: [],
641
+ };
642
+
643
+ const summary = formatCleanupSummary(result);
644
+ expect(summary).toContain('✓ Removed OpenSpec markers from AGENTS.md');
645
+ });
646
+
647
+ it('should include migration hint for project.md', () => {
648
+ const result = {
649
+ deletedFiles: [],
650
+ modifiedFiles: [],
651
+ deletedDirs: [],
652
+ projectMdNeedsMigration: true,
653
+ errors: [],
654
+ };
655
+
656
+ const summary = formatCleanupSummary(result);
657
+ expect(summary).toContain('Needs your attention');
658
+ expect(summary).toContain('openspec/project.md');
659
+ expect(summary).toContain('config.yaml');
660
+ });
661
+
662
+ it('should include errors', () => {
663
+ const result = {
664
+ deletedFiles: [],
665
+ modifiedFiles: [],
666
+ deletedDirs: [],
667
+ projectMdNeedsMigration: false,
668
+ errors: ['Failed to delete CLAUDE.md: Permission denied'],
669
+ };
670
+
671
+ const summary = formatCleanupSummary(result);
672
+ expect(summary).toContain('Errors during cleanup:');
673
+ expect(summary).toContain('Failed to delete CLAUDE.md');
674
+ });
675
+
676
+ it('should return empty string when nothing to report', () => {
677
+ const result = {
678
+ deletedFiles: [],
679
+ modifiedFiles: [],
680
+ deletedDirs: [],
681
+ projectMdNeedsMigration: false,
682
+ errors: [],
683
+ };
684
+
685
+ const summary = formatCleanupSummary(result);
686
+ expect(summary).toBe('');
687
+ });
688
+ });
689
+
690
+ describe('formatDetectionSummary', () => {
691
+ it('should include welcoming upgrade header and explanation', () => {
692
+ const detection = {
693
+ configFiles: ['CLAUDE.md'],
694
+ configFilesToUpdate: ['CLAUDE.md'],
695
+ slashCommandDirs: [],
696
+ slashCommandFiles: [],
697
+ hasOpenspecAgents: false,
698
+ hasProjectMd: false,
699
+ hasRootAgentsWithMarkers: false,
700
+ hasLegacyArtifacts: true,
701
+ };
702
+
703
+ const summary = formatDetectionSummary(detection);
704
+ expect(summary).toContain('Upgrading to the new OpenSpec');
705
+ expect(summary).toContain('agent skills');
706
+ expect(summary).toContain('keeping everything working');
707
+ });
708
+
709
+ it('should format config files as files to update (never remove)', () => {
710
+ const detection = {
711
+ configFiles: ['CLAUDE.md'],
712
+ configFilesToUpdate: ['CLAUDE.md'],
713
+ slashCommandDirs: [],
714
+ slashCommandFiles: [],
715
+ hasOpenspecAgents: false,
716
+ hasProjectMd: false,
717
+ hasRootAgentsWithMarkers: false,
718
+ hasLegacyArtifacts: true,
719
+ };
720
+
721
+ const summary = formatDetectionSummary(detection);
722
+ // Config files should be in "Files to update", not "Files to remove"
723
+ expect(summary).toContain('Files to update');
724
+ expect(summary).toContain('• CLAUDE.md');
725
+ // Should NOT be in removals
726
+ expect(summary).not.toContain('No user content to preserve');
727
+ });
728
+
729
+ it('should format files to be updated', () => {
730
+ const detection = {
731
+ configFiles: ['CLINE.md'],
732
+ configFilesToUpdate: ['CLINE.md'],
733
+ slashCommandDirs: [],
734
+ slashCommandFiles: [],
735
+ hasOpenspecAgents: false,
736
+ hasProjectMd: false,
737
+ hasRootAgentsWithMarkers: false,
738
+ hasLegacyArtifacts: true,
739
+ };
740
+
741
+ const summary = formatDetectionSummary(detection);
742
+ expect(summary).toContain('Files to update');
743
+ expect(summary).toContain('markers will be removed');
744
+ expect(summary).toContain('your content preserved');
745
+ expect(summary).toContain('• CLINE.md');
746
+ });
747
+
748
+ it('should format slash command directories', () => {
749
+ const detection = {
750
+ configFiles: [],
751
+ configFilesToUpdate: [],
752
+ slashCommandDirs: ['.claude/commands/openspec'],
753
+ slashCommandFiles: [],
754
+ hasOpenspecAgents: false,
755
+ hasProjectMd: false,
756
+ hasRootAgentsWithMarkers: false,
757
+ hasLegacyArtifacts: true,
758
+ };
759
+
760
+ const summary = formatDetectionSummary(detection);
761
+ expect(summary).toContain('Files to remove');
762
+ expect(summary).toContain('• .claude/commands/openspec/');
763
+ });
764
+
765
+ it('should format slash command files', () => {
766
+ const detection = {
767
+ configFiles: [],
768
+ configFilesToUpdate: [],
769
+ slashCommandDirs: [],
770
+ slashCommandFiles: ['.cursor/commands/openspec-proposal.md'],
771
+ hasOpenspecAgents: false,
772
+ hasProjectMd: false,
773
+ hasRootAgentsWithMarkers: false,
774
+ hasLegacyArtifacts: true,
775
+ };
776
+
777
+ const summary = formatDetectionSummary(detection);
778
+ expect(summary).toContain('Files to remove');
779
+ expect(summary).toContain('• .cursor/commands/openspec-proposal.md');
780
+ });
781
+
782
+ it('should format openspec/AGENTS.md', () => {
783
+ const detection = {
784
+ configFiles: [],
785
+ configFilesToUpdate: [],
786
+ slashCommandDirs: [],
787
+ slashCommandFiles: [],
788
+ hasOpenspecAgents: true,
789
+ hasProjectMd: false,
790
+ hasRootAgentsWithMarkers: false,
791
+ hasLegacyArtifacts: true,
792
+ };
793
+
794
+ const summary = formatDetectionSummary(detection);
795
+ expect(summary).toContain('Files to remove');
796
+ expect(summary).toContain('• openspec/AGENTS.md');
797
+ });
798
+
799
+ it('should include attention section for project.md', () => {
800
+ const detection = {
801
+ configFiles: [],
802
+ configFilesToUpdate: [],
803
+ slashCommandDirs: [],
804
+ slashCommandFiles: [],
805
+ hasOpenspecAgents: false,
806
+ hasProjectMd: true,
807
+ hasRootAgentsWithMarkers: false,
808
+ hasLegacyArtifacts: false,
809
+ };
810
+
811
+ const summary = formatDetectionSummary(detection);
812
+ expect(summary).toContain('Needs your attention');
813
+ expect(summary).toContain('• openspec/project.md');
814
+ expect(summary).toContain('won\'t delete this file');
815
+ expect(summary).toContain('config.yaml');
816
+ expect(summary).toContain('"context:"');
817
+ });
818
+
819
+ it('should include attention section with other legacy artifacts', () => {
820
+ const detection = {
821
+ configFiles: ['CLAUDE.md'],
822
+ configFilesToUpdate: ['CLAUDE.md'],
823
+ slashCommandDirs: [],
824
+ slashCommandFiles: [],
825
+ hasOpenspecAgents: false,
826
+ hasProjectMd: true,
827
+ hasRootAgentsWithMarkers: false,
828
+ hasLegacyArtifacts: true,
829
+ };
830
+
831
+ const summary = formatDetectionSummary(detection);
832
+ // Config files now in "Files to update", not "Files to remove"
833
+ expect(summary).toContain('Files to update');
834
+ expect(summary).toContain('CLAUDE.md');
835
+ expect(summary).toContain('Needs your attention');
836
+ expect(summary).toContain('openspec/project.md');
837
+ });
838
+
839
+ it('should group both removals and updates correctly', () => {
840
+ const detection = {
841
+ configFiles: ['CLAUDE.md', 'CLINE.md'],
842
+ configFilesToUpdate: ['CLAUDE.md', 'CLINE.md'],
843
+ slashCommandDirs: ['.claude/commands/openspec'],
844
+ slashCommandFiles: [],
845
+ hasOpenspecAgents: true,
846
+ hasProjectMd: false,
847
+ hasRootAgentsWithMarkers: false,
848
+ hasLegacyArtifacts: true,
849
+ };
850
+
851
+ const summary = formatDetectionSummary(detection);
852
+ // Check both sections exist
853
+ expect(summary).toContain('Files to remove');
854
+ expect(summary).toContain('Files to update');
855
+ // Check removals (only slash commands and openspec/AGENTS.md)
856
+ expect(summary).toContain('• .claude/commands/openspec/');
857
+ expect(summary).toContain('• openspec/AGENTS.md');
858
+ // Check updates (all config files)
859
+ expect(summary).toContain('• CLAUDE.md');
860
+ expect(summary).toContain('• CLINE.md');
861
+ });
862
+
863
+ it('should return empty string when nothing is detected', () => {
864
+ const detection = {
865
+ configFiles: [],
866
+ configFilesToUpdate: [],
867
+ slashCommandDirs: [],
868
+ slashCommandFiles: [],
869
+ hasOpenspecAgents: false,
870
+ hasProjectMd: false,
871
+ hasRootAgentsWithMarkers: false,
872
+ hasLegacyArtifacts: false,
873
+ };
874
+
875
+ const summary = formatDetectionSummary(detection);
876
+ expect(summary).toBe('');
877
+ });
878
+ });
879
+
880
+ describe('formatProjectMdMigrationHint', () => {
881
+ it('should return migration hint message', () => {
882
+ const hint = formatProjectMdMigrationHint();
883
+ expect(hint).toContain('Needs your attention');
884
+ expect(hint).toContain('openspec/project.md');
885
+ expect(hint).toContain('won\'t delete this file');
886
+ expect(hint).toContain('config.yaml');
887
+ expect(hint).toContain('"context:"');
888
+ });
889
+
890
+ it('should include actionable instructions', () => {
891
+ const hint = formatProjectMdMigrationHint();
892
+ expect(hint).toContain('move any useful content');
893
+ expect(hint).toContain('delete the file when ready');
894
+ });
895
+
896
+ it('should explain the new context section benefits', () => {
897
+ const hint = formatProjectMdMigrationHint();
898
+ expect(hint).toContain('included in every OpenSpec request');
899
+ expect(hint).toContain('reliably');
900
+ });
901
+ });
902
+
903
+ describe('LEGACY_CONFIG_FILES', () => {
904
+ it('should include expected config file names', () => {
905
+ expect(LEGACY_CONFIG_FILES).toContain('CLAUDE.md');
906
+ expect(LEGACY_CONFIG_FILES).toContain('CLINE.md');
907
+ expect(LEGACY_CONFIG_FILES).toContain('CODEBUDDY.md');
908
+ expect(LEGACY_CONFIG_FILES).toContain('COSTRICT.md');
909
+ expect(LEGACY_CONFIG_FILES).toContain('QODER.md');
910
+ expect(LEGACY_CONFIG_FILES).toContain('IFLOW.md');
911
+ expect(LEGACY_CONFIG_FILES).toContain('AGENTS.md');
912
+ expect(LEGACY_CONFIG_FILES).toContain('QWEN.md');
913
+ });
914
+ });
915
+
916
+ describe('LEGACY_SLASH_COMMAND_PATHS', () => {
917
+ it('should include expected tool patterns', () => {
918
+ expect(LEGACY_SLASH_COMMAND_PATHS['claude']).toEqual({
919
+ type: 'directory',
920
+ path: '.claude/commands/openspec',
921
+ });
922
+
923
+ expect(LEGACY_SLASH_COMMAND_PATHS['cursor']).toEqual({
924
+ type: 'files',
925
+ pattern: '.cursor/commands/openspec-*.md',
926
+ });
927
+
928
+ expect(LEGACY_SLASH_COMMAND_PATHS['windsurf']).toEqual({
929
+ type: 'files',
930
+ pattern: '.windsurf/workflows/openspec-*.md',
931
+ });
932
+ });
933
+
934
+ it('should only include legacy tool IDs that are present in the CommandAdapterRegistry', () => {
935
+ const registeredTools = new Set(CommandAdapterRegistry.getAll().map(adapter => adapter.toolId));
936
+
937
+ // Verify all legacy map entries correspond to known adapters
938
+ for (const tool of Object.keys(LEGACY_SLASH_COMMAND_PATHS)) {
939
+ expect(registeredTools.has(tool)).toBe(true);
940
+ }
941
+
942
+ // Pi was never a pre-1.0 legacy tool
943
+ expect(LEGACY_SLASH_COMMAND_PATHS).not.toHaveProperty('pi');
944
+ });
945
+ });
946
+
947
+ describe('getToolsFromLegacyArtifacts', () => {
948
+ it('should extract claude from directory-based legacy artifacts', () => {
949
+ const detection = {
950
+ configFiles: [],
951
+ configFilesToUpdate: [],
952
+ slashCommandDirs: ['.claude/commands/openspec'],
953
+ slashCommandFiles: [],
954
+ hasOpenspecAgents: false,
955
+ hasProjectMd: false,
956
+ hasRootAgentsWithMarkers: false,
957
+ hasLegacyArtifacts: true,
958
+ };
959
+
960
+ const tools = getToolsFromLegacyArtifacts(detection);
961
+ expect(tools).toContain('claude');
962
+ expect(tools).toHaveLength(1);
963
+ });
964
+
965
+ it('should extract cursor from file-based legacy artifacts', () => {
966
+ const detection = {
967
+ configFiles: [],
968
+ configFilesToUpdate: [],
969
+ slashCommandDirs: [],
970
+ slashCommandFiles: ['.cursor/commands/openspec-proposal.md'],
971
+ hasOpenspecAgents: false,
972
+ hasProjectMd: false,
973
+ hasRootAgentsWithMarkers: false,
974
+ hasLegacyArtifacts: true,
975
+ };
976
+
977
+ const tools = getToolsFromLegacyArtifacts(detection);
978
+ expect(tools).toContain('cursor');
979
+ expect(tools).toHaveLength(1);
980
+ });
981
+
982
+ it('should extract multiple tools from mixed legacy artifacts', () => {
983
+ const detection = {
984
+ configFiles: [],
985
+ configFilesToUpdate: [],
986
+ slashCommandDirs: ['.claude/commands/openspec', '.qoder/commands/openspec'],
987
+ slashCommandFiles: ['.cursor/commands/openspec-apply.md', '.windsurf/workflows/openspec-archive.md'],
988
+ hasOpenspecAgents: false,
989
+ hasProjectMd: false,
990
+ hasRootAgentsWithMarkers: false,
991
+ hasLegacyArtifacts: true,
992
+ };
993
+
994
+ const tools = getToolsFromLegacyArtifacts(detection);
995
+ expect(tools).toContain('claude');
996
+ expect(tools).toContain('qoder');
997
+ expect(tools).toContain('cursor');
998
+ expect(tools).toContain('windsurf');
999
+ expect(tools).toHaveLength(4);
1000
+ });
1001
+
1002
+ it('should deduplicate tools when multiple files match same tool', () => {
1003
+ const detection = {
1004
+ configFiles: [],
1005
+ configFilesToUpdate: [],
1006
+ slashCommandDirs: [],
1007
+ slashCommandFiles: [
1008
+ '.cursor/commands/openspec-proposal.md',
1009
+ '.cursor/commands/openspec-apply.md',
1010
+ '.cursor/commands/openspec-archive.md',
1011
+ ],
1012
+ hasOpenspecAgents: false,
1013
+ hasProjectMd: false,
1014
+ hasRootAgentsWithMarkers: false,
1015
+ hasLegacyArtifacts: true,
1016
+ };
1017
+
1018
+ const tools = getToolsFromLegacyArtifacts(detection);
1019
+ expect(tools).toContain('cursor');
1020
+ expect(tools).toHaveLength(1);
1021
+ });
1022
+
1023
+ it('should return empty array when no legacy artifacts', () => {
1024
+ const detection = {
1025
+ configFiles: [],
1026
+ configFilesToUpdate: [],
1027
+ slashCommandDirs: [],
1028
+ slashCommandFiles: [],
1029
+ hasOpenspecAgents: false,
1030
+ hasProjectMd: false,
1031
+ hasRootAgentsWithMarkers: false,
1032
+ hasLegacyArtifacts: false,
1033
+ };
1034
+
1035
+ const tools = getToolsFromLegacyArtifacts(detection);
1036
+ expect(tools).toHaveLength(0);
1037
+ });
1038
+
1039
+ it('should handle qwen TOML-based legacy files', () => {
1040
+ const detection = {
1041
+ configFiles: [],
1042
+ configFilesToUpdate: [],
1043
+ slashCommandDirs: [],
1044
+ slashCommandFiles: ['.qwen/commands/openspec-proposal.toml'],
1045
+ hasOpenspecAgents: false,
1046
+ hasProjectMd: false,
1047
+ hasRootAgentsWithMarkers: false,
1048
+ hasLegacyArtifacts: true,
1049
+ };
1050
+
1051
+ const tools = getToolsFromLegacyArtifacts(detection);
1052
+ expect(tools).toContain('qwen');
1053
+ expect(tools).toHaveLength(1);
1054
+ });
1055
+
1056
+ it('should handle continue prompt files', () => {
1057
+ const detection = {
1058
+ configFiles: [],
1059
+ configFilesToUpdate: [],
1060
+ slashCommandDirs: [],
1061
+ slashCommandFiles: ['.continue/prompts/openspec-apply.prompt'],
1062
+ hasOpenspecAgents: false,
1063
+ hasProjectMd: false,
1064
+ hasRootAgentsWithMarkers: false,
1065
+ hasLegacyArtifacts: true,
1066
+ };
1067
+
1068
+ const tools = getToolsFromLegacyArtifacts(detection);
1069
+ expect(tools).toContain('continue');
1070
+ expect(tools).toHaveLength(1);
1071
+ });
1072
+
1073
+ it('should handle github-copilot prompt files', () => {
1074
+ const detection = {
1075
+ configFiles: [],
1076
+ configFilesToUpdate: [],
1077
+ slashCommandDirs: [],
1078
+ slashCommandFiles: ['.github/prompts/openspec-apply.prompt.md'],
1079
+ hasOpenspecAgents: false,
1080
+ hasProjectMd: false,
1081
+ hasRootAgentsWithMarkers: false,
1082
+ hasLegacyArtifacts: true,
1083
+ };
1084
+
1085
+ const tools = getToolsFromLegacyArtifacts(detection);
1086
+ expect(tools).toContain('github-copilot');
1087
+ expect(tools).toHaveLength(1);
1088
+ });
1089
+
1090
+ it('should handle opencode opsx-* legacy files', () => {
1091
+ const detection = {
1092
+ configFiles: [],
1093
+ configFilesToUpdate: [],
1094
+ slashCommandDirs: [],
1095
+ slashCommandFiles: ['.opencode/command/opsx-propose.md'],
1096
+ hasOpenspecAgents: false,
1097
+ hasProjectMd: false,
1098
+ hasRootAgentsWithMarkers: false,
1099
+ hasLegacyArtifacts: true,
1100
+ };
1101
+
1102
+ const tools = getToolsFromLegacyArtifacts(detection);
1103
+ expect(tools).toContain('opencode');
1104
+ expect(tools).toHaveLength(1);
1105
+ });
1106
+
1107
+ it('should handle opencode openspec-* legacy files', () => {
1108
+ const detection = {
1109
+ configFiles: [],
1110
+ configFilesToUpdate: [],
1111
+ slashCommandDirs: [],
1112
+ slashCommandFiles: ['.opencode/command/openspec-new.md'],
1113
+ hasOpenspecAgents: false,
1114
+ hasProjectMd: false,
1115
+ hasRootAgentsWithMarkers: false,
1116
+ hasLegacyArtifacts: true,
1117
+ };
1118
+
1119
+ const tools = getToolsFromLegacyArtifacts(detection);
1120
+ expect(tools).toContain('opencode');
1121
+ expect(tools).toHaveLength(1);
1122
+ });
1123
+
1124
+ it('should deduplicate opencode when both opsx-* and openspec-* files exist', () => {
1125
+ const detection = {
1126
+ configFiles: [],
1127
+ configFilesToUpdate: [],
1128
+ slashCommandDirs: [],
1129
+ slashCommandFiles: [
1130
+ '.opencode/command/opsx-propose.md',
1131
+ '.opencode/command/openspec-new.md',
1132
+ ],
1133
+ hasOpenspecAgents: false,
1134
+ hasProjectMd: false,
1135
+ hasRootAgentsWithMarkers: false,
1136
+ hasLegacyArtifacts: true,
1137
+ };
1138
+
1139
+ const tools = getToolsFromLegacyArtifacts(detection);
1140
+ expect(tools).toContain('opencode');
1141
+ expect(tools).toHaveLength(1);
1142
+ });
1143
+
1144
+ it('should not extract tools from config files only', () => {
1145
+ // Config files don't indicate which tools were configured
1146
+ // Only slash command dirs/files tell us which tools to upgrade
1147
+ const detection = {
1148
+ configFiles: ['CLAUDE.md'],
1149
+ configFilesToUpdate: ['CLAUDE.md'],
1150
+ slashCommandDirs: [],
1151
+ slashCommandFiles: [],
1152
+ hasOpenspecAgents: true,
1153
+ hasProjectMd: false,
1154
+ hasRootAgentsWithMarkers: false,
1155
+ hasLegacyArtifacts: true,
1156
+ };
1157
+
1158
+ const tools = getToolsFromLegacyArtifacts(detection);
1159
+ expect(tools).toHaveLength(0);
1160
+ });
1161
+ });
1162
+ });