@hivehub/rulebook 1.2.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 (379) hide show
  1. package/LICENSE +191 -0
  2. package/README.md +539 -0
  3. package/dist/agents/claude-code.d.ts +69 -0
  4. package/dist/agents/claude-code.d.ts.map +1 -0
  5. package/dist/agents/claude-code.js +180 -0
  6. package/dist/agents/claude-code.js.map +1 -0
  7. package/dist/agents/cursor-agent.d.ts +184 -0
  8. package/dist/agents/cursor-agent.d.ts.map +1 -0
  9. package/dist/agents/cursor-agent.js +299 -0
  10. package/dist/agents/cursor-agent.js.map +1 -0
  11. package/dist/agents/gemini-cli.d.ts +69 -0
  12. package/dist/agents/gemini-cli.d.ts.map +1 -0
  13. package/dist/agents/gemini-cli.js +180 -0
  14. package/dist/agents/gemini-cli.js.map +1 -0
  15. package/dist/cli/commands.d.ts +57 -0
  16. package/dist/cli/commands.d.ts.map +1 -0
  17. package/dist/cli/commands.js +1370 -0
  18. package/dist/cli/commands.js.map +1 -0
  19. package/dist/cli/docs-prompts.d.ts +3 -0
  20. package/dist/cli/docs-prompts.d.ts.map +1 -0
  21. package/dist/cli/docs-prompts.js +45 -0
  22. package/dist/cli/docs-prompts.js.map +1 -0
  23. package/dist/cli/prompts.d.ts +6 -0
  24. package/dist/cli/prompts.d.ts.map +1 -0
  25. package/dist/cli/prompts.js +376 -0
  26. package/dist/cli/prompts.js.map +1 -0
  27. package/dist/core/agent-manager.d.ts +89 -0
  28. package/dist/core/agent-manager.d.ts.map +1 -0
  29. package/dist/core/agent-manager.js +546 -0
  30. package/dist/core/agent-manager.js.map +1 -0
  31. package/dist/core/auto-fixer.d.ts +14 -0
  32. package/dist/core/auto-fixer.d.ts.map +1 -0
  33. package/dist/core/auto-fixer.js +207 -0
  34. package/dist/core/auto-fixer.js.map +1 -0
  35. package/dist/core/changelog-generator.d.ts +44 -0
  36. package/dist/core/changelog-generator.d.ts.map +1 -0
  37. package/dist/core/changelog-generator.js +222 -0
  38. package/dist/core/changelog-generator.js.map +1 -0
  39. package/dist/core/cli-bridge.d.ts +113 -0
  40. package/dist/core/cli-bridge.d.ts.map +1 -0
  41. package/dist/core/cli-bridge.js +1094 -0
  42. package/dist/core/cli-bridge.js.map +1 -0
  43. package/dist/core/config-manager.d.ts +65 -0
  44. package/dist/core/config-manager.d.ts.map +1 -0
  45. package/dist/core/config-manager.js +266 -0
  46. package/dist/core/config-manager.js.map +1 -0
  47. package/dist/core/coverage-checker.d.ts +14 -0
  48. package/dist/core/coverage-checker.d.ts.map +1 -0
  49. package/dist/core/coverage-checker.js +176 -0
  50. package/dist/core/coverage-checker.js.map +1 -0
  51. package/dist/core/custom-templates.d.ts +27 -0
  52. package/dist/core/custom-templates.d.ts.map +1 -0
  53. package/dist/core/custom-templates.js +122 -0
  54. package/dist/core/custom-templates.js.map +1 -0
  55. package/dist/core/dependency-checker.d.ts +21 -0
  56. package/dist/core/dependency-checker.d.ts.map +1 -0
  57. package/dist/core/dependency-checker.js +247 -0
  58. package/dist/core/dependency-checker.js.map +1 -0
  59. package/dist/core/detector.d.ts +3 -0
  60. package/dist/core/detector.d.ts.map +1 -0
  61. package/dist/core/detector.js +1443 -0
  62. package/dist/core/detector.js.map +1 -0
  63. package/dist/core/docs-generator.d.ts +9 -0
  64. package/dist/core/docs-generator.d.ts.map +1 -0
  65. package/dist/core/docs-generator.js +531 -0
  66. package/dist/core/docs-generator.js.map +1 -0
  67. package/dist/core/generator.d.ts +16 -0
  68. package/dist/core/generator.d.ts.map +1 -0
  69. package/dist/core/generator.js +561 -0
  70. package/dist/core/generator.js.map +1 -0
  71. package/dist/core/gitignore-generator.d.ts +13 -0
  72. package/dist/core/gitignore-generator.d.ts.map +1 -0
  73. package/dist/core/gitignore-generator.js +307 -0
  74. package/dist/core/gitignore-generator.js.map +1 -0
  75. package/dist/core/health-scorer.d.ts +22 -0
  76. package/dist/core/health-scorer.d.ts.map +1 -0
  77. package/dist/core/health-scorer.js +395 -0
  78. package/dist/core/health-scorer.js.map +1 -0
  79. package/dist/core/logger.d.ts +116 -0
  80. package/dist/core/logger.d.ts.map +1 -0
  81. package/dist/core/logger.js +289 -0
  82. package/dist/core/logger.js.map +1 -0
  83. package/dist/core/merger.d.ts +6 -0
  84. package/dist/core/merger.d.ts.map +1 -0
  85. package/dist/core/merger.js +131 -0
  86. package/dist/core/merger.js.map +1 -0
  87. package/dist/core/migrator.d.ts +19 -0
  88. package/dist/core/migrator.d.ts.map +1 -0
  89. package/dist/core/migrator.js +102 -0
  90. package/dist/core/migrator.js.map +1 -0
  91. package/dist/core/minimal-scaffolder.d.ts +8 -0
  92. package/dist/core/minimal-scaffolder.d.ts.map +1 -0
  93. package/dist/core/minimal-scaffolder.js +51 -0
  94. package/dist/core/minimal-scaffolder.js.map +1 -0
  95. package/dist/core/modern-console-new.d.ts +81 -0
  96. package/dist/core/modern-console-new.d.ts.map +1 -0
  97. package/dist/core/modern-console-new.js +340 -0
  98. package/dist/core/modern-console-new.js.map +1 -0
  99. package/dist/core/modern-console.d.ts +99 -0
  100. package/dist/core/modern-console.d.ts.map +1 -0
  101. package/dist/core/modern-console.js +568 -0
  102. package/dist/core/modern-console.js.map +1 -0
  103. package/dist/core/openspec-manager.d.ts +133 -0
  104. package/dist/core/openspec-manager.d.ts.map +1 -0
  105. package/dist/core/openspec-manager.js +605 -0
  106. package/dist/core/openspec-manager.js.map +1 -0
  107. package/dist/core/openspec-migrator.d.ts +27 -0
  108. package/dist/core/openspec-migrator.d.ts.map +1 -0
  109. package/dist/core/openspec-migrator.js +255 -0
  110. package/dist/core/openspec-migrator.js.map +1 -0
  111. package/dist/core/task-manager.d.ts +65 -0
  112. package/dist/core/task-manager.d.ts.map +1 -0
  113. package/dist/core/task-manager.js +318 -0
  114. package/dist/core/task-manager.js.map +1 -0
  115. package/dist/core/test-task-manager.d.ts +49 -0
  116. package/dist/core/test-task-manager.d.ts.map +1 -0
  117. package/dist/core/test-task-manager.js +121 -0
  118. package/dist/core/test-task-manager.js.map +1 -0
  119. package/dist/core/validator.d.ts +21 -0
  120. package/dist/core/validator.d.ts.map +1 -0
  121. package/dist/core/validator.js +177 -0
  122. package/dist/core/validator.js.map +1 -0
  123. package/dist/core/version-bumper.d.ts +19 -0
  124. package/dist/core/version-bumper.d.ts.map +1 -0
  125. package/dist/core/version-bumper.js +180 -0
  126. package/dist/core/version-bumper.js.map +1 -0
  127. package/dist/core/watcher.d.ts +9 -0
  128. package/dist/core/watcher.d.ts.map +1 -0
  129. package/dist/core/watcher.js +22 -0
  130. package/dist/core/watcher.js.map +1 -0
  131. package/dist/core/workflow-generator.d.ts +10 -0
  132. package/dist/core/workflow-generator.d.ts.map +1 -0
  133. package/dist/core/workflow-generator.js +279 -0
  134. package/dist/core/workflow-generator.js.map +1 -0
  135. package/dist/index.d.ts +3 -0
  136. package/dist/index.d.ts.map +1 -0
  137. package/dist/index.js +159 -0
  138. package/dist/index.js.map +1 -0
  139. package/dist/mcp/handlers/archive-task.d.ts +17 -0
  140. package/dist/mcp/handlers/archive-task.d.ts.map +1 -0
  141. package/dist/mcp/handlers/archive-task.js +36 -0
  142. package/dist/mcp/handlers/archive-task.js.map +1 -0
  143. package/dist/mcp/handlers/create-task.d.ts +17 -0
  144. package/dist/mcp/handlers/create-task.d.ts.map +1 -0
  145. package/dist/mcp/handlers/create-task.js +56 -0
  146. package/dist/mcp/handlers/create-task.js.map +1 -0
  147. package/dist/mcp/handlers/list-tasks.d.ts +22 -0
  148. package/dist/mcp/handlers/list-tasks.d.ts.map +1 -0
  149. package/dist/mcp/handlers/list-tasks.js +42 -0
  150. package/dist/mcp/handlers/list-tasks.js.map +1 -0
  151. package/dist/mcp/handlers/show-task.d.ts +25 -0
  152. package/dist/mcp/handlers/show-task.d.ts.map +1 -0
  153. package/dist/mcp/handlers/show-task.js +43 -0
  154. package/dist/mcp/handlers/show-task.js.map +1 -0
  155. package/dist/mcp/handlers/update-task.d.ts +17 -0
  156. package/dist/mcp/handlers/update-task.d.ts.map +1 -0
  157. package/dist/mcp/handlers/update-task.js +35 -0
  158. package/dist/mcp/handlers/update-task.js.map +1 -0
  159. package/dist/mcp/handlers/validate-task.d.ts +15 -0
  160. package/dist/mcp/handlers/validate-task.d.ts.map +1 -0
  161. package/dist/mcp/handlers/validate-task.js +27 -0
  162. package/dist/mcp/handlers/validate-task.js.map +1 -0
  163. package/dist/mcp/rulebook-config.d.ts +22 -0
  164. package/dist/mcp/rulebook-config.d.ts.map +1 -0
  165. package/dist/mcp/rulebook-config.js +65 -0
  166. package/dist/mcp/rulebook-config.js.map +1 -0
  167. package/dist/mcp/rulebook-server.d.ts +4 -0
  168. package/dist/mcp/rulebook-server.d.ts.map +1 -0
  169. package/dist/mcp/rulebook-server.js +246 -0
  170. package/dist/mcp/rulebook-server.js.map +1 -0
  171. package/dist/types.d.ts +190 -0
  172. package/dist/types.d.ts.map +1 -0
  173. package/dist/types.js +2 -0
  174. package/dist/types.js.map +1 -0
  175. package/dist/utils/file-system.d.ts +9 -0
  176. package/dist/utils/file-system.d.ts.map +1 -0
  177. package/dist/utils/file-system.js +51 -0
  178. package/dist/utils/file-system.js.map +1 -0
  179. package/dist/utils/git-hooks.d.ts +8 -0
  180. package/dist/utils/git-hooks.d.ts.map +1 -0
  181. package/dist/utils/git-hooks.js +440 -0
  182. package/dist/utils/git-hooks.js.map +1 -0
  183. package/dist/utils/rulesignore.d.ts +9 -0
  184. package/dist/utils/rulesignore.d.ts.map +1 -0
  185. package/dist/utils/rulesignore.js +42 -0
  186. package/dist/utils/rulesignore.js.map +1 -0
  187. package/package.json +106 -0
  188. package/templates/cli/AIDER.md +49 -0
  189. package/templates/cli/AMAZON_Q.md +25 -0
  190. package/templates/cli/AUGGIE.md +32 -0
  191. package/templates/cli/CLAUDE.md +32 -0
  192. package/templates/cli/CLAUDE_CODE.md +35 -0
  193. package/templates/cli/CLINE.md +32 -0
  194. package/templates/cli/CODEBUDDY.md +20 -0
  195. package/templates/cli/CODEIUM.md +20 -0
  196. package/templates/cli/CODEX.md +21 -0
  197. package/templates/cli/CONTINUE.md +34 -0
  198. package/templates/cli/CURSOR_CLI.md +28 -0
  199. package/templates/cli/FACTORY.md +18 -0
  200. package/templates/cli/GEMINI.md +35 -0
  201. package/templates/cli/KILOCODE.md +18 -0
  202. package/templates/cli/OPENCODE.md +18 -0
  203. package/templates/cli/_GENERIC_TEMPLATE.md +29 -0
  204. package/templates/commands/rulebook-task-apply.md +67 -0
  205. package/templates/commands/rulebook-task-archive.md +70 -0
  206. package/templates/commands/rulebook-task-create.md +93 -0
  207. package/templates/commands/rulebook-task-list.md +42 -0
  208. package/templates/commands/rulebook-task-show.md +52 -0
  209. package/templates/commands/rulebook-task-validate.md +53 -0
  210. package/templates/core/AGENT_AUTOMATION.md +184 -0
  211. package/templates/core/DAG.md +304 -0
  212. package/templates/core/DOCUMENTATION_RULES.md +37 -0
  213. package/templates/core/QUALITY_ENFORCEMENT.md +68 -0
  214. package/templates/core/RULEBOOK.md +1874 -0
  215. package/templates/frameworks/ANGULAR.md +36 -0
  216. package/templates/frameworks/DJANGO.md +83 -0
  217. package/templates/frameworks/ELECTRON.md +147 -0
  218. package/templates/frameworks/FLASK.md +38 -0
  219. package/templates/frameworks/FLUTTER.md +55 -0
  220. package/templates/frameworks/JQUERY.md +32 -0
  221. package/templates/frameworks/LARAVEL.md +38 -0
  222. package/templates/frameworks/NESTJS.md +43 -0
  223. package/templates/frameworks/NEXTJS.md +127 -0
  224. package/templates/frameworks/NUXT.md +40 -0
  225. package/templates/frameworks/RAILS.md +66 -0
  226. package/templates/frameworks/REACT.md +38 -0
  227. package/templates/frameworks/REACT_NATIVE.md +47 -0
  228. package/templates/frameworks/SPRING.md +39 -0
  229. package/templates/frameworks/SYMFONY.md +36 -0
  230. package/templates/frameworks/VUE.md +36 -0
  231. package/templates/frameworks/ZEND.md +35 -0
  232. package/templates/git/CI_CD_PATTERNS.md +661 -0
  233. package/templates/git/GITHUB_ACTIONS.md +728 -0
  234. package/templates/git/GITLAB_CI.md +730 -0
  235. package/templates/git/GIT_WORKFLOW.md +1157 -0
  236. package/templates/git/SECRETS_MANAGEMENT.md +585 -0
  237. package/templates/hooks/COMMIT_MSG.md +530 -0
  238. package/templates/hooks/POST_CHECKOUT.md +546 -0
  239. package/templates/hooks/PREPARE_COMMIT_MSG.md +619 -0
  240. package/templates/hooks/PRE_COMMIT.md +414 -0
  241. package/templates/hooks/PRE_PUSH.md +601 -0
  242. package/templates/hooks/csharp-pre-commit.sh +23 -0
  243. package/templates/hooks/csharp-pre-push.sh +23 -0
  244. package/templates/hooks/dart-pre-commit.sh +30 -0
  245. package/templates/hooks/dart-pre-push.sh +25 -0
  246. package/templates/hooks/elixir-pre-commit.sh +32 -0
  247. package/templates/hooks/elixir-pre-push.sh +31 -0
  248. package/templates/hooks/erlang-pre-commit.sh +30 -0
  249. package/templates/hooks/erlang-pre-push.sh +37 -0
  250. package/templates/hooks/go-pre-commit.sh +40 -0
  251. package/templates/hooks/go-pre-push.sh +31 -0
  252. package/templates/hooks/haskell-pre-commit.sh +41 -0
  253. package/templates/hooks/haskell-pre-push.sh +37 -0
  254. package/templates/hooks/java-pre-commit.sh +34 -0
  255. package/templates/hooks/java-pre-push.sh +24 -0
  256. package/templates/hooks/kotlin-pre-commit.sh +32 -0
  257. package/templates/hooks/kotlin-pre-push.sh +16 -0
  258. package/templates/hooks/php-pre-commit.sh +36 -0
  259. package/templates/hooks/php-pre-push.sh +26 -0
  260. package/templates/hooks/python-pre-commit.sh +51 -0
  261. package/templates/hooks/python-pre-push.sh +25 -0
  262. package/templates/hooks/ruby-pre-commit.sh +33 -0
  263. package/templates/hooks/ruby-pre-push.sh +32 -0
  264. package/templates/hooks/rust-pre-commit.sh +30 -0
  265. package/templates/hooks/rust-pre-push.sh +30 -0
  266. package/templates/hooks/scala-pre-commit.sh +32 -0
  267. package/templates/hooks/scala-pre-push.sh +24 -0
  268. package/templates/hooks/swift-pre-commit.sh +25 -0
  269. package/templates/hooks/swift-pre-push.sh +23 -0
  270. package/templates/hooks/typescript-pre-commit.sh +37 -0
  271. package/templates/hooks/typescript-pre-push.sh +36 -0
  272. package/templates/ides/COPILOT.md +37 -0
  273. package/templates/ides/CURSOR.md +43 -0
  274. package/templates/ides/JETBRAINS_AI.md +35 -0
  275. package/templates/ides/REPLIT.md +36 -0
  276. package/templates/ides/TABNINE.md +29 -0
  277. package/templates/ides/VSCODE.md +40 -0
  278. package/templates/ides/WINDSURF.md +36 -0
  279. package/templates/ides/ZED.md +32 -0
  280. package/templates/languages/ADA.md +58 -0
  281. package/templates/languages/C.md +333 -0
  282. package/templates/languages/CPP.md +743 -0
  283. package/templates/languages/CSHARP.md +417 -0
  284. package/templates/languages/DART.md +332 -0
  285. package/templates/languages/ELIXIR.md +454 -0
  286. package/templates/languages/ERLANG.md +361 -0
  287. package/templates/languages/GO.md +645 -0
  288. package/templates/languages/HASKELL.md +177 -0
  289. package/templates/languages/JAVA.md +607 -0
  290. package/templates/languages/JAVASCRIPT.md +631 -0
  291. package/templates/languages/JULIA.md +97 -0
  292. package/templates/languages/KOTLIN.md +511 -0
  293. package/templates/languages/LISP.md +100 -0
  294. package/templates/languages/LUA.md +74 -0
  295. package/templates/languages/OBJECTIVEC.md +90 -0
  296. package/templates/languages/PHP.md +416 -0
  297. package/templates/languages/PYTHON.md +682 -0
  298. package/templates/languages/R.md +350 -0
  299. package/templates/languages/RUBY.md +421 -0
  300. package/templates/languages/RUST.md +477 -0
  301. package/templates/languages/SAS.md +73 -0
  302. package/templates/languages/SCALA.md +348 -0
  303. package/templates/languages/SOLIDITY.md +580 -0
  304. package/templates/languages/SQL.md +137 -0
  305. package/templates/languages/SWIFT.md +466 -0
  306. package/templates/languages/TYPESCRIPT.md +591 -0
  307. package/templates/languages/ZIG.md +265 -0
  308. package/templates/modules/ATLASSIAN.md +255 -0
  309. package/templates/modules/CONTEXT7.md +54 -0
  310. package/templates/modules/FIGMA.md +267 -0
  311. package/templates/modules/GITHUB_MCP.md +64 -0
  312. package/templates/modules/GRAFANA.md +328 -0
  313. package/templates/modules/NOTION.md +247 -0
  314. package/templates/modules/PLAYWRIGHT.md +90 -0
  315. package/templates/modules/RULEBOOK_MCP.md +156 -0
  316. package/templates/modules/SERENA.md +337 -0
  317. package/templates/modules/SUPABASE.md +223 -0
  318. package/templates/modules/SYNAP.md +69 -0
  319. package/templates/modules/VECTORIZER.md +63 -0
  320. package/templates/services/AZURE_BLOB.md +184 -0
  321. package/templates/services/CASSANDRA.md +239 -0
  322. package/templates/services/DYNAMODB.md +308 -0
  323. package/templates/services/ELASTICSEARCH.md +347 -0
  324. package/templates/services/GCS.md +178 -0
  325. package/templates/services/INFLUXDB.md +265 -0
  326. package/templates/services/KAFKA.md +341 -0
  327. package/templates/services/MARIADB.md +183 -0
  328. package/templates/services/MEMCACHED.md +242 -0
  329. package/templates/services/MINIO.md +201 -0
  330. package/templates/services/MONGODB.md +268 -0
  331. package/templates/services/MYSQL.md +358 -0
  332. package/templates/services/NEO4J.md +247 -0
  333. package/templates/services/ORACLE.md +290 -0
  334. package/templates/services/POSTGRESQL.md +326 -0
  335. package/templates/services/RABBITMQ.md +286 -0
  336. package/templates/services/REDIS.md +292 -0
  337. package/templates/services/S3.md +298 -0
  338. package/templates/services/SQLITE.md +294 -0
  339. package/templates/services/SQLSERVER.md +294 -0
  340. package/templates/workflows/codespell.yml +31 -0
  341. package/templates/workflows/cpp-lint.yml +47 -0
  342. package/templates/workflows/cpp-publish.yml +119 -0
  343. package/templates/workflows/cpp-test.yml +77 -0
  344. package/templates/workflows/dotnet-lint.yml +29 -0
  345. package/templates/workflows/dotnet-publish.yml +40 -0
  346. package/templates/workflows/dotnet-test.yml +41 -0
  347. package/templates/workflows/elixir-lint.yml +45 -0
  348. package/templates/workflows/elixir-publish.yml +49 -0
  349. package/templates/workflows/elixir-test.yml +54 -0
  350. package/templates/workflows/erlang-lint.yml +47 -0
  351. package/templates/workflows/erlang-test.yml +62 -0
  352. package/templates/workflows/go-lint.yml +39 -0
  353. package/templates/workflows/go-publish.yml +95 -0
  354. package/templates/workflows/go-test.yml +59 -0
  355. package/templates/workflows/java-lint.yml +60 -0
  356. package/templates/workflows/java-publish.yml +120 -0
  357. package/templates/workflows/java-test.yml +85 -0
  358. package/templates/workflows/kotlin-lint.yml +34 -0
  359. package/templates/workflows/kotlin-publish.yml +56 -0
  360. package/templates/workflows/kotlin-test.yml +48 -0
  361. package/templates/workflows/php-lint.yml +39 -0
  362. package/templates/workflows/php-publish.yml +50 -0
  363. package/templates/workflows/php-test.yml +54 -0
  364. package/templates/workflows/python-lint.yml +47 -0
  365. package/templates/workflows/python-publish.yml +91 -0
  366. package/templates/workflows/python-test.yml +59 -0
  367. package/templates/workflows/rust-lint.yml +54 -0
  368. package/templates/workflows/rust-publish.yml +66 -0
  369. package/templates/workflows/rust-test.yml +75 -0
  370. package/templates/workflows/solidity-lint.yml +41 -0
  371. package/templates/workflows/solidity-test.yml +47 -0
  372. package/templates/workflows/swift-lint.yml +32 -0
  373. package/templates/workflows/swift-publish.yml +58 -0
  374. package/templates/workflows/swift-test.yml +44 -0
  375. package/templates/workflows/typescript-lint.yml +61 -0
  376. package/templates/workflows/typescript-publish.yml +60 -0
  377. package/templates/workflows/typescript-test.yml +73 -0
  378. package/templates/workflows/zig-lint.yml +27 -0
  379. package/templates/workflows/zig-test.yml +40 -0
@@ -0,0 +1,255 @@
1
+ import { existsSync, readdirSync, mkdirSync } from 'fs';
2
+ import { join } from 'path';
3
+ import { fileExists, readFile, writeFile } from '../utils/file-system.js';
4
+ import { createTaskManager } from './task-manager.js';
5
+ const OPENSPEC_DIR = 'openspec';
6
+ const CHANGES_DIR = 'changes';
7
+ const SPECS_DIR = 'specs';
8
+ const TASKS_FILE = 'tasks.md';
9
+ const PROPOSAL_FILE = 'proposal.md';
10
+ const DESIGN_FILE = 'design.md';
11
+ /**
12
+ * Migrate OpenSpec tasks to Rulebook format
13
+ */
14
+ export async function migrateOpenSpecToRulebook(projectRoot, rulebookDir = 'rulebook') {
15
+ const result = {
16
+ migrated: 0,
17
+ skipped: 0,
18
+ errors: [],
19
+ migratedTasks: [],
20
+ };
21
+ const openspecPath = join(projectRoot, OPENSPEC_DIR);
22
+ const changesPath = join(openspecPath, CHANGES_DIR);
23
+ // Check if OpenSpec directory exists
24
+ if (!existsSync(changesPath)) {
25
+ return result; // No OpenSpec tasks to migrate
26
+ }
27
+ // Get all change directories
28
+ let changeDirs = [];
29
+ try {
30
+ changeDirs = readdirSync(changesPath, { withFileTypes: true })
31
+ .filter((dirent) => dirent.isDirectory())
32
+ .map((dirent) => dirent.name);
33
+ }
34
+ catch (error) {
35
+ result.errors.push(`Failed to read OpenSpec changes directory: ${error.message}`);
36
+ return result;
37
+ }
38
+ if (changeDirs.length === 0) {
39
+ return result; // No tasks to migrate
40
+ }
41
+ // Initialize TaskManager
42
+ const taskManager = createTaskManager(projectRoot, rulebookDir);
43
+ await taskManager.initialize();
44
+ // Migrate each task
45
+ for (const changeDir of changeDirs) {
46
+ const taskId = changeDir; // Use directory name as task ID
47
+ const sourceTaskPath = join(changesPath, changeDir);
48
+ const targetTaskPath = join(projectRoot, rulebookDir, 'tasks', taskId);
49
+ try {
50
+ // Check if task already exists in Rulebook
51
+ if (existsSync(targetTaskPath)) {
52
+ result.skipped++;
53
+ continue;
54
+ }
55
+ // Create target directory
56
+ mkdirSync(targetTaskPath, { recursive: true });
57
+ mkdirSync(join(targetTaskPath, SPECS_DIR), { recursive: true });
58
+ // Migrate proposal.md
59
+ const proposalSource = join(sourceTaskPath, PROPOSAL_FILE);
60
+ if (await fileExists(proposalSource)) {
61
+ const proposalContent = await readFile(proposalSource);
62
+ await writeFile(join(targetTaskPath, PROPOSAL_FILE), proposalContent);
63
+ }
64
+ // Migrate tasks.md
65
+ const tasksSource = join(sourceTaskPath, TASKS_FILE);
66
+ if (await fileExists(tasksSource)) {
67
+ const tasksContent = await readFile(tasksSource);
68
+ await writeFile(join(targetTaskPath, TASKS_FILE), tasksContent);
69
+ }
70
+ // Migrate design.md (if exists)
71
+ const designSource = join(sourceTaskPath, DESIGN_FILE);
72
+ if (await fileExists(designSource)) {
73
+ const designContent = await readFile(designSource);
74
+ await writeFile(join(targetTaskPath, DESIGN_FILE), designContent);
75
+ }
76
+ // Migrate specs
77
+ const specsSource = join(sourceTaskPath, SPECS_DIR);
78
+ if (existsSync(specsSource)) {
79
+ const specDirs = readdirSync(specsSource, { withFileTypes: true })
80
+ .filter((dirent) => dirent.isDirectory())
81
+ .map((dirent) => dirent.name);
82
+ for (const specDir of specDirs) {
83
+ const specSource = join(specsSource, specDir, 'spec.md');
84
+ if (await fileExists(specSource)) {
85
+ const specContent = await readFile(specSource);
86
+ const targetSpecDir = join(targetTaskPath, SPECS_DIR, specDir);
87
+ mkdirSync(targetSpecDir, { recursive: true });
88
+ await writeFile(join(targetSpecDir, 'spec.md'), specContent);
89
+ }
90
+ }
91
+ }
92
+ result.migrated++;
93
+ result.migratedTasks.push(taskId);
94
+ }
95
+ catch (error) {
96
+ result.errors.push(`Failed to migrate task ${taskId}: ${error.message}`);
97
+ result.skipped++;
98
+ }
99
+ }
100
+ return result;
101
+ }
102
+ /**
103
+ * Migrate OpenSpec archived tasks to Rulebook format
104
+ */
105
+ export async function migrateOpenSpecArchives(projectRoot, rulebookDir = 'rulebook') {
106
+ const result = {
107
+ migrated: 0,
108
+ skipped: 0,
109
+ errors: [],
110
+ migratedTasks: [],
111
+ };
112
+ const openspecPath = join(projectRoot, OPENSPEC_DIR);
113
+ const archivePath = join(openspecPath, CHANGES_DIR, 'archive');
114
+ // Check if OpenSpec archive directory exists
115
+ if (!existsSync(archivePath)) {
116
+ return result; // No archived tasks to migrate
117
+ }
118
+ // Get all archived task directories
119
+ let archiveDirs = [];
120
+ try {
121
+ archiveDirs = readdirSync(archivePath, { withFileTypes: true })
122
+ .filter((dirent) => dirent.isDirectory())
123
+ .map((dirent) => dirent.name);
124
+ }
125
+ catch (error) {
126
+ result.errors.push(`Failed to read OpenSpec archive directory: ${error.message}`);
127
+ return result;
128
+ }
129
+ if (archiveDirs.length === 0) {
130
+ return result; // No archived tasks to migrate
131
+ }
132
+ // Initialize TaskManager
133
+ const taskManager = createTaskManager(projectRoot, rulebookDir);
134
+ await taskManager.initialize();
135
+ // Migrate each archived task
136
+ for (const archiveDir of archiveDirs) {
137
+ const sourceArchivePath = join(archivePath, archiveDir);
138
+ // Preserve archive date prefix (YYYY-MM-DD-task-id format)
139
+ const archiveName = archiveDir; // Keep original name with date prefix
140
+ const targetArchivePath = join(projectRoot, rulebookDir, 'tasks', 'archive', archiveName);
141
+ try {
142
+ // Check if archive already exists in Rulebook
143
+ if (existsSync(targetArchivePath)) {
144
+ result.skipped++;
145
+ continue;
146
+ }
147
+ // Create target archive directory
148
+ mkdirSync(targetArchivePath, { recursive: true });
149
+ mkdirSync(join(targetArchivePath, SPECS_DIR), { recursive: true });
150
+ // Migrate proposal.md
151
+ const proposalSource = join(sourceArchivePath, PROPOSAL_FILE);
152
+ if (await fileExists(proposalSource)) {
153
+ const proposalContent = await readFile(proposalSource);
154
+ await writeFile(join(targetArchivePath, PROPOSAL_FILE), proposalContent);
155
+ }
156
+ // Migrate tasks.md
157
+ const tasksSource = join(sourceArchivePath, TASKS_FILE);
158
+ if (await fileExists(tasksSource)) {
159
+ const tasksContent = await readFile(tasksSource);
160
+ await writeFile(join(targetArchivePath, TASKS_FILE), tasksContent);
161
+ }
162
+ // Migrate design.md (if exists)
163
+ const designSource = join(sourceArchivePath, DESIGN_FILE);
164
+ if (await fileExists(designSource)) {
165
+ const designContent = await readFile(designSource);
166
+ await writeFile(join(targetArchivePath, DESIGN_FILE), designContent);
167
+ }
168
+ // Migrate specs
169
+ const specsSource = join(sourceArchivePath, SPECS_DIR);
170
+ if (existsSync(specsSource)) {
171
+ const specDirs = readdirSync(specsSource, { withFileTypes: true })
172
+ .filter((dirent) => dirent.isDirectory())
173
+ .map((dirent) => dirent.name);
174
+ for (const specDir of specDirs) {
175
+ const specSource = join(specsSource, specDir, 'spec.md');
176
+ if (await fileExists(specSource)) {
177
+ const specContent = await readFile(specSource);
178
+ const targetSpecDir = join(targetArchivePath, SPECS_DIR, specDir);
179
+ mkdirSync(targetSpecDir, { recursive: true });
180
+ await writeFile(join(targetSpecDir, 'spec.md'), specContent);
181
+ }
182
+ }
183
+ }
184
+ result.migrated++;
185
+ result.migratedTasks.push(archiveName);
186
+ }
187
+ catch (error) {
188
+ result.errors.push(`Failed to migrate archived task ${archiveName}: ${error.message}`);
189
+ result.skipped++;
190
+ }
191
+ }
192
+ return result;
193
+ }
194
+ /**
195
+ * Remove /rulebook/OPENSPEC.md if it exists
196
+ */
197
+ export async function removeOpenSpecRulebookFile(projectRoot, rulebookDir = 'rulebook') {
198
+ const openspecRulebookPath = join(projectRoot, rulebookDir, 'OPENSPEC.md');
199
+ if (await fileExists(openspecRulebookPath)) {
200
+ const { unlink } = await import('fs/promises');
201
+ await unlink(openspecRulebookPath);
202
+ return true;
203
+ }
204
+ return false;
205
+ }
206
+ /**
207
+ * Remove OpenSpec commands from .cursor/commands/
208
+ */
209
+ export async function removeOpenSpecCommands(projectRoot) {
210
+ const commandsDir = join(projectRoot, '.cursor', 'commands');
211
+ if (!existsSync(commandsDir)) {
212
+ return 0;
213
+ }
214
+ const openspecCommands = ['openspec-proposal.md', 'openspec-archive.md', 'openspec-apply.md'];
215
+ let removed = 0;
216
+ for (const command of openspecCommands) {
217
+ const commandPath = join(commandsDir, command);
218
+ if (await fileExists(commandPath)) {
219
+ const { unlink } = await import('fs/promises');
220
+ await unlink(commandPath);
221
+ removed++;
222
+ }
223
+ }
224
+ return removed;
225
+ }
226
+ /**
227
+ * Archive OpenSpec directory (move to archive)
228
+ */
229
+ export async function archiveOpenSpecDirectory(projectRoot) {
230
+ const openspecPath = join(projectRoot, OPENSPEC_DIR);
231
+ if (!existsSync(openspecPath)) {
232
+ return false;
233
+ }
234
+ const archiveDate = new Date().toISOString().split('T')[0];
235
+ const archivePath = join(projectRoot, `openspec-archive-${archiveDate}`);
236
+ try {
237
+ // Use mv command to move directory
238
+ const { execSync } = await import('child_process');
239
+ execSync(`mv "${openspecPath}" "${archivePath}"`, { cwd: projectRoot });
240
+ return true;
241
+ }
242
+ catch {
243
+ // Fallback: copy and remove
244
+ const { cpSync, rmSync } = await import('fs');
245
+ try {
246
+ cpSync(openspecPath, archivePath, { recursive: true });
247
+ rmSync(openspecPath, { recursive: true, force: true });
248
+ return true;
249
+ }
250
+ catch {
251
+ return false;
252
+ }
253
+ }
254
+ }
255
+ //# sourceMappingURL=openspec-migrator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openspec-migrator.js","sourceRoot":"","sources":["../../src/core/openspec-migrator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,65 @@
1
+ export interface RulebookTask {
2
+ id: string;
3
+ title: string;
4
+ proposal?: string;
5
+ tasks?: string;
6
+ design?: string;
7
+ specs?: Record<string, string>;
8
+ status: 'pending' | 'in-progress' | 'completed' | 'blocked';
9
+ createdAt: string;
10
+ updatedAt: string;
11
+ archivedAt?: string;
12
+ }
13
+ export interface TaskValidationResult {
14
+ valid: boolean;
15
+ errors: string[];
16
+ warnings: string[];
17
+ }
18
+ export declare class TaskManager {
19
+ private rulebookPath;
20
+ private tasksPath;
21
+ private archivePath;
22
+ constructor(projectRoot: string, rulebookDir?: string);
23
+ /**
24
+ * Initialize Rulebook tasks directory structure
25
+ */
26
+ initialize(): Promise<void>;
27
+ /**
28
+ * Get the path to a task directory
29
+ */
30
+ getTaskPath(taskId: string): string;
31
+ /**
32
+ * Create a new task
33
+ */
34
+ createTask(taskId: string): Promise<void>;
35
+ /**
36
+ * List all tasks
37
+ */
38
+ listTasks(includeArchived?: boolean): Promise<RulebookTask[]>;
39
+ /**
40
+ * Load a task by ID
41
+ */
42
+ loadTask(taskId: string, archived?: boolean): Promise<RulebookTask | null>;
43
+ /**
44
+ * Validate task format (OpenSpec-compatible)
45
+ */
46
+ validateTask(taskId: string): Promise<TaskValidationResult>;
47
+ /**
48
+ * Archive a completed task
49
+ */
50
+ archiveTask(taskId: string, skipValidation?: boolean): Promise<void>;
51
+ /**
52
+ * Update task status
53
+ */
54
+ updateTaskStatus(taskId: string, status: RulebookTask['status']): Promise<void>;
55
+ /**
56
+ * Show task details
57
+ */
58
+ showTask(taskId: string): Promise<RulebookTask | null>;
59
+ /**
60
+ * Delete a task permanently
61
+ */
62
+ deleteTask(taskId: string): Promise<void>;
63
+ }
64
+ export declare function createTaskManager(projectRoot: string, rulebookDir?: string): TaskManager;
65
+ //# sourceMappingURL=task-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task-manager.d.ts","sourceRoot":"","sources":["../../src/core/task-manager.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,MAAM,EAAE,SAAS,GAAG,aAAa,GAAG,WAAW,GAAG,SAAS,CAAC;IAC5D,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,WAAW,CAAS;gBAEhB,WAAW,EAAE,MAAM,EAAE,WAAW,GAAE,MAAmB;IAMjE;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAYjC;;OAEG;IACH,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAInC;;OAEG;IACG,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA8C/C;;OAEG;IACG,SAAS,CAAC,eAAe,GAAE,OAAe,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAyC1E;;OAEG;IACG,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,GAAE,OAAe,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC;IA8DvF;;OAEG;IACG,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAkEjE;;OAEG;IACG,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,cAAc,GAAE,OAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAoCjF;;OAEG;IACG,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,CAAC,QAAQ,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAarF;;OAEG;IACG,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC;IAiB5D;;OAEG;IACG,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAWhD;AAED,wBAAgB,iBAAiB,CAC/B,WAAW,EAAE,MAAM,EACnB,WAAW,GAAE,MAAmB,GAC/B,WAAW,CAEb"}
@@ -0,0 +1,318 @@
1
+ import { writeFile, existsSync, mkdirSync, readdirSync, statSync } from 'fs';
2
+ import { promisify } from 'util';
3
+ import { join } from 'path';
4
+ import { fileExists, readFile as readFileUtil } from '../utils/file-system.js';
5
+ const writeFileAsync = promisify(writeFile);
6
+ const TASKS_DIR = 'tasks';
7
+ const ARCHIVE_DIR = 'archive';
8
+ const SPECS_DIR = 'specs';
9
+ export class TaskManager {
10
+ rulebookPath;
11
+ tasksPath;
12
+ archivePath;
13
+ constructor(projectRoot, rulebookDir = 'rulebook') {
14
+ this.rulebookPath = join(projectRoot, rulebookDir);
15
+ this.tasksPath = join(this.rulebookPath, TASKS_DIR);
16
+ this.archivePath = join(this.tasksPath, ARCHIVE_DIR);
17
+ }
18
+ /**
19
+ * Initialize Rulebook tasks directory structure
20
+ */
21
+ async initialize() {
22
+ if (!existsSync(this.rulebookPath)) {
23
+ mkdirSync(this.rulebookPath, { recursive: true });
24
+ }
25
+ if (!existsSync(this.tasksPath)) {
26
+ mkdirSync(this.tasksPath, { recursive: true });
27
+ }
28
+ if (!existsSync(this.archivePath)) {
29
+ mkdirSync(this.archivePath, { recursive: true });
30
+ }
31
+ }
32
+ /**
33
+ * Get the path to a task directory
34
+ */
35
+ getTaskPath(taskId) {
36
+ return join(this.tasksPath, taskId);
37
+ }
38
+ /**
39
+ * Create a new task
40
+ */
41
+ async createTask(taskId) {
42
+ await this.initialize();
43
+ const taskPath = join(this.tasksPath, taskId);
44
+ if (existsSync(taskPath)) {
45
+ throw new Error(`Task ${taskId} already exists`);
46
+ }
47
+ mkdirSync(taskPath, { recursive: true });
48
+ mkdirSync(join(taskPath, SPECS_DIR), { recursive: true });
49
+ // Create proposal.md template
50
+ const proposalContent = `# Proposal: ${taskId}
51
+
52
+ ## Why
53
+ [Explain why this change is needed - minimum 20 characters]
54
+
55
+ ## What Changes
56
+ [Describe what will change]
57
+
58
+ ## Impact
59
+ - Affected specs: [list]
60
+ - Affected code: [list]
61
+ - Breaking change: YES/NO
62
+ - User benefit: [describe]
63
+ `;
64
+ await writeFileAsync(join(taskPath, 'proposal.md'), proposalContent);
65
+ // Create tasks.md template
66
+ const tasksContent = `## 1. Implementation
67
+ - [ ] 1.1 First task
68
+ - [ ] 1.2 Second task
69
+
70
+ ## 2. Testing
71
+ - [ ] 2.1 Write tests
72
+ - [ ] 2.2 Verify coverage
73
+
74
+ ## 3. Documentation
75
+ - [ ] 3.1 Update README
76
+ - [ ] 3.2 Update CHANGELOG
77
+ `;
78
+ await writeFileAsync(join(taskPath, 'tasks.md'), tasksContent);
79
+ }
80
+ /**
81
+ * List all tasks
82
+ */
83
+ async listTasks(includeArchived = false) {
84
+ await this.initialize();
85
+ const tasks = [];
86
+ // List active tasks
87
+ if (existsSync(this.tasksPath)) {
88
+ const entries = readdirSync(this.tasksPath, { withFileTypes: true });
89
+ for (const entry of entries) {
90
+ if (entry.isDirectory() && entry.name !== ARCHIVE_DIR) {
91
+ const task = await this.loadTask(entry.name);
92
+ if (task) {
93
+ tasks.push(task);
94
+ }
95
+ }
96
+ }
97
+ }
98
+ // List archived tasks if requested
99
+ if (includeArchived && existsSync(this.archivePath)) {
100
+ const archiveEntries = readdirSync(this.archivePath, { withFileTypes: true });
101
+ for (const entry of archiveEntries) {
102
+ if (entry.isDirectory()) {
103
+ const task = await this.loadTask(entry.name, true);
104
+ if (task) {
105
+ // Extract date from archive name (YYYY-MM-DD-task-id format)
106
+ const dateMatch = entry.name.match(/^(\d{4}-\d{2}-\d{2})-/);
107
+ if (dateMatch) {
108
+ task.archivedAt = dateMatch[1];
109
+ }
110
+ else {
111
+ task.archivedAt = new Date().toISOString().split('T')[0];
112
+ }
113
+ tasks.push(task);
114
+ }
115
+ }
116
+ }
117
+ }
118
+ return tasks;
119
+ }
120
+ /**
121
+ * Load a task by ID
122
+ */
123
+ async loadTask(taskId, archived = false) {
124
+ const basePath = archived ? this.archivePath : this.tasksPath;
125
+ const taskPath = join(basePath, taskId);
126
+ if (!existsSync(taskPath)) {
127
+ return null;
128
+ }
129
+ const proposalPath = join(taskPath, 'proposal.md');
130
+ const tasksPath = join(taskPath, 'tasks.md');
131
+ const designPath = join(taskPath, 'design.md');
132
+ const specsPath = join(taskPath, SPECS_DIR);
133
+ const task = {
134
+ id: taskId,
135
+ title: taskId,
136
+ status: 'pending',
137
+ createdAt: new Date().toISOString(),
138
+ updatedAt: new Date().toISOString(),
139
+ specs: {},
140
+ };
141
+ // Load proposal
142
+ if (await fileExists(proposalPath)) {
143
+ task.proposal = await readFileUtil(proposalPath);
144
+ }
145
+ // Load tasks
146
+ if (await fileExists(tasksPath)) {
147
+ task.tasks = await readFileUtil(tasksPath);
148
+ }
149
+ // Load design
150
+ if (await fileExists(designPath)) {
151
+ task.design = await readFileUtil(designPath);
152
+ }
153
+ // Load specs
154
+ if (existsSync(specsPath)) {
155
+ const specEntries = readdirSync(specsPath, { withFileTypes: true });
156
+ for (const specEntry of specEntries) {
157
+ if (specEntry.isDirectory()) {
158
+ const specFile = join(specsPath, specEntry.name, 'spec.md');
159
+ if (await fileExists(specFile)) {
160
+ task.specs[specEntry.name] = await readFileUtil(specFile);
161
+ }
162
+ }
163
+ }
164
+ }
165
+ // Get file stats for dates
166
+ try {
167
+ const stats = statSync(taskPath);
168
+ task.createdAt = stats.birthtime.toISOString();
169
+ task.updatedAt = stats.mtime.toISOString();
170
+ }
171
+ catch {
172
+ // Use defaults if stats fail
173
+ }
174
+ return task;
175
+ }
176
+ /**
177
+ * Validate task format (OpenSpec-compatible)
178
+ */
179
+ async validateTask(taskId) {
180
+ const task = await this.loadTask(taskId);
181
+ if (!task) {
182
+ return {
183
+ valid: false,
184
+ errors: [`Task ${taskId} not found`],
185
+ warnings: [],
186
+ };
187
+ }
188
+ const errors = [];
189
+ const warnings = [];
190
+ // Validate proposal
191
+ if (!task.proposal) {
192
+ errors.push('Missing proposal.md');
193
+ }
194
+ else {
195
+ // Check Purpose section (minimum 20 characters)
196
+ const purposeMatch = task.proposal.match(/## Why\s*\n([\s\S]*?)(?=\n##|$)/);
197
+ if (!purposeMatch || purposeMatch[1].trim().length < 20) {
198
+ errors.push('Purpose section (## Why) must have at least 20 characters');
199
+ }
200
+ }
201
+ // Validate specs
202
+ if (!task.specs || Object.keys(task.specs).length === 0) {
203
+ warnings.push('No spec files found (specs/*/spec.md)');
204
+ }
205
+ else {
206
+ for (const [module, specContent] of Object.entries(task.specs)) {
207
+ // Check for requirements with SHALL/MUST
208
+ const requirementMatches = specContent.match(/### Requirement:.*/g) || [];
209
+ for (const req of requirementMatches) {
210
+ const reqText = specContent.substring(specContent.indexOf(req));
211
+ const reqBody = reqText.split('\n').slice(1).join('\n').split('####')[0];
212
+ if (!reqBody.match(/\b(SHALL|MUST)\b/i)) {
213
+ errors.push(`Requirement in ${module}/spec.md missing SHALL or MUST keyword: ${req}`);
214
+ }
215
+ }
216
+ // Check for scenarios with 4 hashtags (not 3)
217
+ // Only check at start of line (not in text content)
218
+ const scenario3Matches = specContent.match(/^### Scenario:/gm) || [];
219
+ if (scenario3Matches.length > 0) {
220
+ errors.push(`Scenarios in ${module}/spec.md must use 4 hashtags (####), not 3 (###)`);
221
+ }
222
+ // Check for Given/When/Then structure
223
+ const scenarios = specContent.match(/#### Scenario:[\s\S]*?(?=####|##|$)/g) || [];
224
+ for (const scenario of scenarios) {
225
+ const hasGiven = /Given/i.test(scenario);
226
+ const hasWhen = /When/i.test(scenario);
227
+ const hasThen = /Then/i.test(scenario);
228
+ if (!hasGiven || !hasWhen || !hasThen) {
229
+ warnings.push(`Scenario in ${module}/spec.md should use Given/When/Then structure`);
230
+ }
231
+ }
232
+ }
233
+ }
234
+ return {
235
+ valid: errors.length === 0,
236
+ errors,
237
+ warnings,
238
+ };
239
+ }
240
+ /**
241
+ * Archive a completed task
242
+ */
243
+ async archiveTask(taskId, skipValidation = false) {
244
+ const task = await this.loadTask(taskId);
245
+ if (!task) {
246
+ throw new Error(`Task ${taskId} not found`);
247
+ }
248
+ // Validate before archiving (unless skipped)
249
+ if (!skipValidation) {
250
+ const validation = await this.validateTask(taskId);
251
+ if (!validation.valid) {
252
+ throw new Error(`Task validation failed:\n${validation.errors.join('\n')}`);
253
+ }
254
+ }
255
+ const taskPath = join(this.tasksPath, taskId);
256
+ const archiveDate = new Date().toISOString().split('T')[0];
257
+ const archiveName = `${archiveDate}-${taskId}`;
258
+ const archiveTaskPath = join(this.archivePath, archiveName);
259
+ // Ensure archive directory exists
260
+ if (!existsSync(this.archivePath)) {
261
+ mkdirSync(this.archivePath, { recursive: true });
262
+ }
263
+ if (existsSync(archiveTaskPath)) {
264
+ throw new Error(`Archive ${archiveName} already exists`);
265
+ }
266
+ // Move task to archive using cross-platform filesystem operations
267
+ const { renameSync } = await import('fs');
268
+ renameSync(taskPath, archiveTaskPath);
269
+ // TODO: Apply spec deltas to main specifications
270
+ // This would require parsing the spec deltas and merging them into /rulebook/specs/
271
+ }
272
+ /**
273
+ * Update task status
274
+ */
275
+ async updateTaskStatus(taskId, status) {
276
+ const task = await this.loadTask(taskId);
277
+ if (!task) {
278
+ throw new Error(`Task ${taskId} not found`);
279
+ }
280
+ task.status = status;
281
+ task.updatedAt = new Date().toISOString();
282
+ // Status is updated in memory only
283
+ // In the future, we could persist this to a status.md file or update tasks.md
284
+ }
285
+ /**
286
+ * Show task details
287
+ */
288
+ async showTask(taskId) {
289
+ // Try active tasks first
290
+ let task = await this.loadTask(taskId, false);
291
+ if (task) {
292
+ return task;
293
+ }
294
+ // Try archived tasks
295
+ task = await this.loadTask(taskId, true);
296
+ if (task) {
297
+ task.archivedAt = taskId.split('-').slice(0, 3).join('-'); // Extract date from task ID
298
+ return task;
299
+ }
300
+ return null;
301
+ }
302
+ /**
303
+ * Delete a task permanently
304
+ */
305
+ async deleteTask(taskId) {
306
+ const taskPath = join(this.tasksPath, taskId);
307
+ if (!existsSync(taskPath)) {
308
+ throw new Error(`Task ${taskId} not found`);
309
+ }
310
+ // Remove task directory recursively
311
+ const { rmSync } = await import('fs');
312
+ rmSync(taskPath, { recursive: true, force: true });
313
+ }
314
+ }
315
+ export function createTaskManager(projectRoot, rulebookDir = 'rulebook') {
316
+ return new TaskManager(projectRoot, rulebookDir);
317
+ }
318
+ //# sourceMappingURL=task-manager.js.map