@waoooo/claude-skills 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (264) hide show
  1. package/README.md +48 -0
  2. package/package.json +28 -0
  3. package/registry.json +431 -0
  4. package/skills/acceptance-review/SKILL.md +537 -0
  5. package/skills/all-plan/SKILL.md +19 -0
  6. package/skills/all-plan/references/flow.md +750 -0
  7. package/skills/api-docs-generate/SKILL.md +204 -0
  8. package/skills/api-docs-generate/assets/templates/api.mdx +140 -0
  9. package/skills/api-docs-generate/scripts/generate-api-docs.ts +308 -0
  10. package/skills/ask/SKILL.md +42 -0
  11. package/skills/autonew/SKILL.md +34 -0
  12. package/skills/capability-analyze/SKILL.md +300 -0
  13. package/skills/capability-analyze/scripts/analyze-capabilities.ts +531 -0
  14. package/skills/capability-docs-generate/SKILL.md +155 -0
  15. package/skills/capability-docs-generate/assets/templates/capability.mdx +271 -0
  16. package/skills/capability-docs-generate/scripts/generate-capability-docs.ts +358 -0
  17. package/skills/capability-tree-query/SKILL.md +112 -0
  18. package/skills/capability-tree-query/scripts/build-capability-tree.ts +402 -0
  19. package/skills/changelog-generator/SKILL.md +104 -0
  20. package/skills/continue/SKILL.md +39 -0
  21. package/skills/continue/agents/openai.yaml +3 -0
  22. package/skills/creating-skills/SKILL.md +158 -0
  23. package/skills/creating-skills/references/official_best_practices.md +128 -0
  24. package/skills/creating-skills/references/skill_examples.md +199 -0
  25. package/skills/docx/LICENSE.txt +30 -0
  26. package/skills/docx/SKILL.md +197 -0
  27. package/skills/docx/docx-js.md +350 -0
  28. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
  29. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
  30. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
  31. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
  32. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
  33. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
  34. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
  35. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
  36. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
  37. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
  38. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
  39. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
  40. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
  41. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
  42. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
  43. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
  44. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
  45. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
  46. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
  47. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
  48. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
  49. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
  50. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
  51. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
  52. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
  53. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
  54. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
  55. package/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
  56. package/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
  57. package/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
  58. package/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
  59. package/skills/docx/ooxml/schemas/mce/mc.xsd +75 -0
  60. package/skills/docx/ooxml/schemas/microsoft/wml-2010.xsd +560 -0
  61. package/skills/docx/ooxml/schemas/microsoft/wml-2012.xsd +67 -0
  62. package/skills/docx/ooxml/schemas/microsoft/wml-2018.xsd +14 -0
  63. package/skills/docx/ooxml/schemas/microsoft/wml-cex-2018.xsd +20 -0
  64. package/skills/docx/ooxml/schemas/microsoft/wml-cid-2016.xsd +13 -0
  65. package/skills/docx/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
  66. package/skills/docx/ooxml/schemas/microsoft/wml-symex-2015.xsd +8 -0
  67. package/skills/docx/ooxml/scripts/pack.py +159 -0
  68. package/skills/docx/ooxml/scripts/unpack.py +29 -0
  69. package/skills/docx/ooxml/scripts/validate.py +69 -0
  70. package/skills/docx/ooxml/scripts/validation/__init__.py +15 -0
  71. package/skills/docx/ooxml/scripts/validation/base.py +951 -0
  72. package/skills/docx/ooxml/scripts/validation/docx.py +274 -0
  73. package/skills/docx/ooxml/scripts/validation/pptx.py +315 -0
  74. package/skills/docx/ooxml/scripts/validation/redlining.py +279 -0
  75. package/skills/docx/ooxml.md +610 -0
  76. package/skills/docx/scripts/__init__.py +1 -0
  77. package/skills/docx/scripts/document.py +1276 -0
  78. package/skills/docx/scripts/templates/comments.xml +3 -0
  79. package/skills/docx/scripts/templates/commentsExtended.xml +3 -0
  80. package/skills/docx/scripts/templates/commentsExtensible.xml +3 -0
  81. package/skills/docx/scripts/templates/commentsIds.xml +3 -0
  82. package/skills/docx/scripts/templates/people.xml +3 -0
  83. package/skills/docx/scripts/utilities.py +374 -0
  84. package/skills/git-branch-create/SKILL.md +170 -0
  85. package/skills/git-branch-merge/SKILL.md +176 -0
  86. package/skills/git-commit/SKILL.md +56 -0
  87. package/skills/git-commit/references/commit_examples.md +311 -0
  88. package/skills/github-actions-trigger/SKILL.md +367 -0
  89. package/skills/github-issue-create/SKILL.md +294 -0
  90. package/skills/github-pr-creation/SKILL.md +137 -0
  91. package/skills/github-pr-creation/references/pr_templates.md +187 -0
  92. package/skills/github-pr-merge/SKILL.md +112 -0
  93. package/skills/github-pr-review/SKILL.md +110 -0
  94. package/skills/github-pr-review/references/severity_guide.md +168 -0
  95. package/skills/job-create/SKILL.md +294 -0
  96. package/skills/job-create/scripts/create-job.ts +105 -0
  97. package/skills/job-workflow/SKILL.md +212 -0
  98. package/skills/keyword-extract/SKILL.md +229 -0
  99. package/skills/mcp-builder/LICENSE.txt +202 -0
  100. package/skills/mcp-builder/SKILL.md +236 -0
  101. package/skills/mcp-builder/reference/evaluation.md +602 -0
  102. package/skills/mcp-builder/reference/mcp_best_practices.md +249 -0
  103. package/skills/mcp-builder/reference/node_mcp_server.md +970 -0
  104. package/skills/mcp-builder/reference/python_mcp_server.md +719 -0
  105. package/skills/mcp-builder/scripts/connections.py +151 -0
  106. package/skills/mcp-builder/scripts/evaluation.py +373 -0
  107. package/skills/mcp-builder/scripts/example_evaluation.xml +22 -0
  108. package/skills/mcp-builder/scripts/requirements.txt +2 -0
  109. package/skills/mdx-to-openspec/SKILL.md +827 -0
  110. package/skills/mdx-to-openspec/scripts/mdx-to-openspec.ts +320 -0
  111. package/skills/mounted/SKILL.md +20 -0
  112. package/skills/multi-model-review/SKILL.md +459 -0
  113. package/skills/notion-automation/SKILL.md +215 -0
  114. package/skills/openspec-review/SKILL.md +513 -0
  115. package/skills/pdf/LICENSE.txt +30 -0
  116. package/skills/pdf/SKILL.md +294 -0
  117. package/skills/pdf/forms.md +205 -0
  118. package/skills/pdf/reference.md +612 -0
  119. package/skills/pdf/scripts/check_bounding_boxes.py +70 -0
  120. package/skills/pdf/scripts/check_bounding_boxes_test.py +226 -0
  121. package/skills/pdf/scripts/check_fillable_fields.py +12 -0
  122. package/skills/pdf/scripts/convert_pdf_to_images.py +35 -0
  123. package/skills/pdf/scripts/create_validation_image.py +41 -0
  124. package/skills/pdf/scripts/extract_form_field_info.py +152 -0
  125. package/skills/pdf/scripts/fill_fillable_fields.py +114 -0
  126. package/skills/pdf/scripts/fill_pdf_form_with_annotations.py +108 -0
  127. package/skills/pend/SKILL.md +33 -0
  128. package/skills/ping/SKILL.md +39 -0
  129. package/skills/pptx/LICENSE.txt +30 -0
  130. package/skills/pptx/SKILL.md +484 -0
  131. package/skills/pptx/html2pptx.md +625 -0
  132. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
  133. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
  134. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
  135. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
  136. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
  137. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
  138. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
  139. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
  140. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
  141. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
  142. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
  143. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
  144. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
  145. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
  146. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
  147. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
  148. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
  149. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
  150. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
  151. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
  152. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
  153. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
  154. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
  155. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
  156. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
  157. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
  158. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
  159. package/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
  160. package/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
  161. package/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
  162. package/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
  163. package/skills/pptx/ooxml/schemas/mce/mc.xsd +75 -0
  164. package/skills/pptx/ooxml/schemas/microsoft/wml-2010.xsd +560 -0
  165. package/skills/pptx/ooxml/schemas/microsoft/wml-2012.xsd +67 -0
  166. package/skills/pptx/ooxml/schemas/microsoft/wml-2018.xsd +14 -0
  167. package/skills/pptx/ooxml/schemas/microsoft/wml-cex-2018.xsd +20 -0
  168. package/skills/pptx/ooxml/schemas/microsoft/wml-cid-2016.xsd +13 -0
  169. package/skills/pptx/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
  170. package/skills/pptx/ooxml/schemas/microsoft/wml-symex-2015.xsd +8 -0
  171. package/skills/pptx/ooxml/scripts/pack.py +159 -0
  172. package/skills/pptx/ooxml/scripts/unpack.py +29 -0
  173. package/skills/pptx/ooxml/scripts/validate.py +69 -0
  174. package/skills/pptx/ooxml/scripts/validation/__init__.py +15 -0
  175. package/skills/pptx/ooxml/scripts/validation/base.py +951 -0
  176. package/skills/pptx/ooxml/scripts/validation/docx.py +274 -0
  177. package/skills/pptx/ooxml/scripts/validation/pptx.py +315 -0
  178. package/skills/pptx/ooxml/scripts/validation/redlining.py +279 -0
  179. package/skills/pptx/ooxml.md +427 -0
  180. package/skills/pptx/scripts/html2pptx.js +979 -0
  181. package/skills/pptx/scripts/inventory.py +1020 -0
  182. package/skills/pptx/scripts/rearrange.py +231 -0
  183. package/skills/pptx/scripts/replace.py +385 -0
  184. package/skills/pptx/scripts/thumbnail.py +450 -0
  185. package/skills/progress-update/SKILL.md +394 -0
  186. package/skills/progress-update/scripts/update-progress.ts +221 -0
  187. package/skills/release-automation/SKILL.md +306 -0
  188. package/skills/requirement-parse/SKILL.md +212 -0
  189. package/skills/requirement-parse/scripts/infer-builder-config.ts +346 -0
  190. package/skills/requirement-parse/scripts/merge-requirements.ts +228 -0
  191. package/skills/requirement-parse/scripts/parse-docs.ts +206 -0
  192. package/skills/requirement-parse/scripts/parse-openspec.ts +168 -0
  193. package/skills/roadmap-docs-generate/SKILL.md +483 -0
  194. package/skills/roadmap-docs-generate/assets/templates/ROADMAP.mdx +75 -0
  195. package/skills/roadmap-docs-generate/assets/templates/ROADMAP.mdx.template +330 -0
  196. package/skills/roadmap-docs-generate/assets/templates/TODO.mdx +56 -0
  197. package/skills/roadmap-docs-generate/assets/templates/TODO.mdx.template +363 -0
  198. package/skills/roadmap-docs-generate/scripts/json-to-mdx.ts +445 -0
  199. package/skills/roadmap-docs-generate/scripts/json-to-mdx.ts.backup +411 -0
  200. package/skills/roadmap-generate/SKILL.md +396 -0
  201. package/skills/roadmap-generate/scripts/generate-roadmap.ts +496 -0
  202. package/skills/skill-creator/LICENSE.txt +202 -0
  203. package/skills/skill-creator/SKILL.md +356 -0
  204. package/skills/skill-creator/references/output-patterns.md +82 -0
  205. package/skills/skill-creator/references/workflows.md +28 -0
  206. package/skills/skill-creator/scripts/init_skill.py +303 -0
  207. package/skills/skill-creator/scripts/package_skill.py +110 -0
  208. package/skills/skill-creator/scripts/quick_validate.py +95 -0
  209. package/skills/spec-generate/SKILL.md +408 -0
  210. package/skills/spec-generate/scripts/generate-specs.ts +538 -0
  211. package/skills/spec-generate/scripts/generate-tasks.ts +174 -0
  212. package/skills/specs-review/SKILL.md +370 -0
  213. package/skills/task-execute/SKILL.md +399 -0
  214. package/skills/task-update-status/SKILL.md +349 -0
  215. package/skills/task-update-status/scripts/update-task-status.ts +192 -0
  216. package/skills/task-verify/SKILL.md +407 -0
  217. package/skills/ui-ux-pro-max/SKILL.md +386 -0
  218. package/skills/ui-ux-pro-max/data/charts.csv +26 -0
  219. package/skills/ui-ux-pro-max/data/colors.csv +97 -0
  220. package/skills/ui-ux-pro-max/data/icons.csv +101 -0
  221. package/skills/ui-ux-pro-max/data/landing.csv +31 -0
  222. package/skills/ui-ux-pro-max/data/products.csv +97 -0
  223. package/skills/ui-ux-pro-max/data/react-performance.csv +45 -0
  224. package/skills/ui-ux-pro-max/data/stacks/astro.csv +54 -0
  225. package/skills/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
  226. package/skills/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
  227. package/skills/ui-ux-pro-max/data/stacks/jetpack-compose.csv +53 -0
  228. package/skills/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
  229. package/skills/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -0
  230. package/skills/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -0
  231. package/skills/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
  232. package/skills/ui-ux-pro-max/data/stacks/react.csv +54 -0
  233. package/skills/ui-ux-pro-max/data/stacks/shadcn.csv +61 -0
  234. package/skills/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
  235. package/skills/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
  236. package/skills/ui-ux-pro-max/data/stacks/vue.csv +50 -0
  237. package/skills/ui-ux-pro-max/data/styles.csv +68 -0
  238. package/skills/ui-ux-pro-max/data/typography.csv +58 -0
  239. package/skills/ui-ux-pro-max/data/ui-reasoning.csv +101 -0
  240. package/skills/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
  241. package/skills/ui-ux-pro-max/data/web-interface.csv +31 -0
  242. package/skills/ui-ux-pro-max/scripts/core.py +253 -0
  243. package/skills/ui-ux-pro-max/scripts/design_system.py +1067 -0
  244. package/skills/ui-ux-pro-max/scripts/search.py +114 -0
  245. package/skills/vercel-automation/SKILL.md +226 -0
  246. package/skills/webapp-testing/LICENSE.txt +202 -0
  247. package/skills/webapp-testing/SKILL.md +96 -0
  248. package/skills/webapp-testing/examples/console_logging.py +35 -0
  249. package/skills/webapp-testing/examples/element_discovery.py +40 -0
  250. package/skills/webapp-testing/examples/static_html_automation.py +33 -0
  251. package/skills/webapp-testing/scripts/with_server.py +106 -0
  252. package/skills/worktree-manager/SKILL.md +725 -0
  253. package/skills/worktree-manager/config.json +15 -0
  254. package/skills/worktree-manager/scripts/allocate-ports.sh +100 -0
  255. package/skills/worktree-manager/scripts/cleanup.sh +185 -0
  256. package/skills/worktree-manager/scripts/launch-agent.sh +155 -0
  257. package/skills/worktree-manager/scripts/register.sh +125 -0
  258. package/skills/worktree-manager/scripts/release-ports.sh +48 -0
  259. package/skills/worktree-manager/scripts/status.sh +169 -0
  260. package/skills/worktree-manager/scripts/sync.sh +168 -0
  261. package/skills/worktree-manager/templates/worktree.json +23 -0
  262. package/skills/xlsx/LICENSE.txt +30 -0
  263. package/skills/xlsx/SKILL.md +289 -0
  264. package/skills/xlsx/recalc.py +178 -0
@@ -0,0 +1,538 @@
1
+ /**
2
+ * Generate Specs
3
+ *
4
+ * Generate specs/ directory with README.md, tasks.json, verification.json, progress.json
5
+ */
6
+
7
+ import fs from 'fs';
8
+ import path from 'path';
9
+
10
+ interface CapabilityAnalysis {
11
+ version: string;
12
+ jobId: string;
13
+ analyzedAt: string;
14
+ summary: {
15
+ totalRequirements: number;
16
+ requiredCapabilities: number;
17
+ availableCapabilities: number;
18
+ missingCapabilities: number;
19
+ implementedInProject: number;
20
+ };
21
+ capabilities: {
22
+ available: Array<{
23
+ capId: string;
24
+ name: string;
25
+ layer: string;
26
+ status: string;
27
+ source: string;
28
+ usedBy?: string[];
29
+ suggestedAction?: string;
30
+ }>;
31
+ missing: Array<{
32
+ capId: string;
33
+ name: string;
34
+ layer: string;
35
+ status: string;
36
+ requiredBy?: string[];
37
+ suggestedAction?: string;
38
+ }>;
39
+ implemented: Array<{
40
+ capId: string;
41
+ name: string;
42
+ layer: string;
43
+ detectedIn?: string[];
44
+ notInTree?: boolean;
45
+ suggestedAction?: string;
46
+ }>;
47
+ };
48
+ dependencies: {
49
+ graph: Record<string, { requires: string[]; blocks: string[] }>;
50
+ layers: Record<string, string[]>;
51
+ };
52
+ recommendations: Array<{
53
+ type: string;
54
+ capability: string;
55
+ reason: string;
56
+ priority: string;
57
+ }>;
58
+ }
59
+
60
+ interface UnifiedRequirements {
61
+ version: string;
62
+ sources: any;
63
+ requirements: Array<{
64
+ reqId: string;
65
+ title: string;
66
+ description?: string;
67
+ type?: string;
68
+ status?: string;
69
+ layerHint?: string;
70
+ capabilityHints?: string[];
71
+ acceptance?: string[];
72
+ tasks?: string[];
73
+ blockedBy?: string[];
74
+ blocks?: string[];
75
+ }>;
76
+ executionOrder?: string[];
77
+ }
78
+
79
+ interface Task {
80
+ taskId: string;
81
+ title: string;
82
+ type: 'capability-development' | 'documentation' | 'integration' | 'testing';
83
+ priority: 'high' | 'medium' | 'low';
84
+ layer?: string;
85
+ capability?: string;
86
+ requirements?: string[];
87
+ dependencies?: string[];
88
+ estimatedHours: number;
89
+ status: 'pending' | 'in-progress' | 'completed';
90
+ subtasks: Array<{
91
+ id: string;
92
+ title: string;
93
+ status: 'pending' | 'in-progress' | 'completed';
94
+ }>;
95
+ verification: string[];
96
+ }
97
+
98
+ /**
99
+ * Generate README.md
100
+ */
101
+ function generateReadme(
102
+ analysis: CapabilityAnalysis,
103
+ unified: UnifiedRequirements,
104
+ outputPath: string
105
+ ): void {
106
+ const { jobId, summary, capabilities, dependencies } = analysis;
107
+
108
+ // Extract job name from jobId
109
+ const jobName = jobId.split('-').slice(3).join(' ').replace(/\b\w/g, l => l.toUpperCase());
110
+
111
+ let content = `# Development Specification: ${jobName}\n\n`;
112
+ content += `**Job ID**: ${jobId} \n`;
113
+ content += `**Generated**: ${new Date().toISOString()} \n`;
114
+ content += `**Status**: Ready for Development\n\n`;
115
+
116
+ content += `## Overview\n\n`;
117
+ content += `This specification outlines the development plan for the ${jobName} feature.\n\n`;
118
+
119
+ content += `## Summary\n\n`;
120
+ content += `- **Total Requirements**: ${summary.totalRequirements}\n`;
121
+ content += `- **Required Capabilities**: ${summary.requiredCapabilities}\n`;
122
+ content += `- **Available Capabilities**: ${summary.availableCapabilities}\n`;
123
+ content += `- **Missing Capabilities**: ${summary.missingCapabilities}\n`;
124
+ content += `- **Implemented (not in tree)**: ${summary.implementedInProject}\n\n`;
125
+
126
+ // Available capabilities
127
+ if (capabilities.available.length > 0) {
128
+ content += `## āœ… Available Capabilities (${capabilities.available.length})\n\n`;
129
+ content += `| Capability | Layer | Status | Action |\n`;
130
+ content += `|------------|-------|--------|--------|\n`;
131
+ for (const cap of capabilities.available) {
132
+ content += `| ${cap.name || cap.capId} | ${cap.layer} | ${cap.status} | ${cap.suggestedAction || 'use'} |\n`;
133
+ }
134
+ content += `\n`;
135
+ }
136
+
137
+ // Missing capabilities
138
+ if (capabilities.missing.length > 0) {
139
+ content += `## āŒ Missing Capabilities (${capabilities.missing.length})\n\n`;
140
+ content += `| Capability | Layer | Priority | Action |\n`;
141
+ content += `|------------|-------|----------|--------|\n`;
142
+ for (const cap of capabilities.missing) {
143
+ const priority = cap.layer === 'L1' ? 'High' : cap.layer === 'L2' ? 'Medium' : 'Low';
144
+ content += `| ${cap.name || cap.capId} | ${cap.layer} | ${priority} | ${cap.suggestedAction || 'develop'} |\n`;
145
+ }
146
+ content += `\n`;
147
+ }
148
+
149
+ // Implemented but not in tree
150
+ if (capabilities.implemented.length > 0) {
151
+ content += `## šŸ” Implemented but Not in Tree (${capabilities.implemented.length})\n\n`;
152
+ content += `| Capability | Detected In | Action |\n`;
153
+ content += `|------------|-------------|--------|\n`;
154
+ for (const cap of capabilities.implemented) {
155
+ const detectedIn = cap.detectedIn?.join(', ') || 'unknown';
156
+ content += `| ${cap.name || cap.capId} | ${detectedIn} | ${cap.suggestedAction || 'update-tree'} |\n`;
157
+ }
158
+ content += `\n`;
159
+ }
160
+
161
+ // Dependencies
162
+ content += `## Dependencies\n\n`;
163
+ content += `\`\`\`mermaid\n`;
164
+ content += `graph TD\n`;
165
+
166
+ // Build dependency graph
167
+ const layers = dependencies.layers;
168
+ const layerOrder = ['L1', 'L2', 'L3', 'L4'];
169
+
170
+ for (const layer of layerOrder) {
171
+ if (layers[layer] && layers[layer].length > 0) {
172
+ for (const cap of layers[layer]) {
173
+ const deps = dependencies.graph[cap]?.requires || [];
174
+ if (deps.length > 0) {
175
+ for (const dep of deps) {
176
+ content += ` ${dep} --> ${cap}\n`;
177
+ }
178
+ } else {
179
+ content += ` ${cap}\n`;
180
+ }
181
+ }
182
+ }
183
+ }
184
+
185
+ content += `\`\`\`\n\n`;
186
+
187
+ // Execution plan
188
+ content += `## Execution Plan\n\n`;
189
+ for (const layer of layerOrder) {
190
+ if (layers[layer] && layers[layer].length > 0) {
191
+ const layerName = layer === 'L1' ? 'Foundation' : layer === 'L2' ? 'Core Features' : layer === 'L3' ? 'Business Logic' : 'Advanced Features';
192
+ content += `### Phase ${layer.slice(1)}: ${layerName} (${layer})\n`;
193
+ for (const cap of layers[layer]) {
194
+ const capInfo = capabilities.available.find(c => c.capId === cap) ||
195
+ capabilities.missing.find(c => c.capId === cap) ||
196
+ capabilities.implemented.find(c => c.capId === cap);
197
+ const action = capInfo?.suggestedAction || 'develop';
198
+ content += `- ${action === 'use' ? 'Use existing' : action === 'develop' ? 'Develop' : 'Update'} \`${cap}\` capability\n`;
199
+ }
200
+ content += `\n`;
201
+ }
202
+ }
203
+
204
+ content += `## Tasks\n\n`;
205
+ content += `See [tasks.json](./tasks.json) for detailed task list.\n\n`;
206
+
207
+ content += `## Verification\n\n`;
208
+ content += `See [verification.json](./verification.json) for test commands.\n\n`;
209
+
210
+ content += `## Progress Tracking\n\n`;
211
+ content += `See [progress.json](./progress.json) for current status.\n`;
212
+
213
+ fs.writeFileSync(outputPath, content);
214
+ console.log(` āœ… Generated: README.md`);
215
+ }
216
+
217
+ /**
218
+ * Generate tasks.json
219
+ */
220
+ function generateTasks(
221
+ analysis: CapabilityAnalysis,
222
+ unified: UnifiedRequirements,
223
+ outputPath: string
224
+ ): void {
225
+ const tasks: Task[] = [];
226
+ let taskCounter = 1;
227
+
228
+ // Generate tasks for missing capabilities
229
+ for (const cap of analysis.capabilities.missing) {
230
+ const taskId = `TASK-${String(taskCounter).padStart(3, '0')}`;
231
+ taskCounter++;
232
+
233
+ const priority = cap.layer === 'L1' ? 'high' : cap.layer === 'L2' ? 'medium' : 'low';
234
+ const estimatedHours = cap.layer === 'L1' ? 4 : cap.layer === 'L2' ? 8 : 6;
235
+
236
+ tasks.push({
237
+ taskId,
238
+ title: `Develop ${cap.name || cap.capId} capability`,
239
+ type: 'capability-development',
240
+ priority,
241
+ layer: cap.layer,
242
+ capability: cap.capId,
243
+ requirements: cap.requiredBy || [],
244
+ dependencies: analysis.dependencies.graph[cap.capId]?.requires || [],
245
+ estimatedHours,
246
+ status: 'pending',
247
+ subtasks: [
248
+ {
249
+ id: `${taskId}-1`,
250
+ title: `Design ${cap.name || cap.capId} interface`,
251
+ status: 'pending',
252
+ },
253
+ {
254
+ id: `${taskId}-2`,
255
+ title: `Implement ${cap.name || cap.capId} logic`,
256
+ status: 'pending',
257
+ },
258
+ {
259
+ id: `${taskId}-3`,
260
+ title: `Add tests for ${cap.name || cap.capId}`,
261
+ status: 'pending',
262
+ },
263
+ ],
264
+ verification: [
265
+ `pnpm test:${cap.capId}`,
266
+ 'pnpm build',
267
+ ],
268
+ });
269
+ }
270
+
271
+ // Generate tasks for implemented but not in tree
272
+ for (const cap of analysis.capabilities.implemented) {
273
+ if (cap.notInTree) {
274
+ const taskId = `TASK-${String(taskCounter).padStart(3, '0')}`;
275
+ taskCounter++;
276
+
277
+ tasks.push({
278
+ taskId,
279
+ title: `Update capability tree with ${cap.name || cap.capId}`,
280
+ type: 'documentation',
281
+ priority: 'medium',
282
+ capability: cap.capId,
283
+ estimatedHours: 1,
284
+ status: 'pending',
285
+ subtasks: [
286
+ {
287
+ id: `${taskId}-1`,
288
+ title: `Document ${cap.name || cap.capId} capability`,
289
+ status: 'pending',
290
+ },
291
+ {
292
+ id: `${taskId}-2`,
293
+ title: 'Add to capability-tree.json',
294
+ status: 'pending',
295
+ },
296
+ ],
297
+ verification: [
298
+ 'pnpm capability:build-tree',
299
+ ],
300
+ });
301
+ }
302
+ }
303
+
304
+ // Generate integration tasks from requirements
305
+ for (const req of unified.requirements || []) {
306
+ // Skip capability requirements (source === 'builder')
307
+ if (req.source === 'builder') {
308
+ continue;
309
+ }
310
+
311
+ const taskId = `TASK-${String(taskCounter).padStart(3, '0')}`;
312
+ taskCounter++;
313
+
314
+ // Determine task type based on requirement type
315
+ let taskType: 'capability-development' | 'documentation' | 'integration' | 'testing' = 'integration';
316
+ if (req.type === 'documentation' || req.title.includes('文攣') || req.title.includes('Documentation')) {
317
+ taskType = 'documentation';
318
+ } else if (req.type === 'testing' || req.title.includes('测试') || req.title.includes('Test')) {
319
+ taskType = 'testing';
320
+ }
321
+
322
+ // Determine priority based on task number (earlier tasks are higher priority)
323
+ let priority: 'high' | 'medium' | 'low' = 'medium';
324
+ const taskNumber = req.title.match(/^(\d+)\.(\d+)/);
325
+ if (taskNumber) {
326
+ const phase = parseInt(taskNumber[1]);
327
+ if (phase <= 3) {
328
+ priority = 'high';
329
+ } else if (phase >= 8) {
330
+ priority = 'low';
331
+ }
332
+ }
333
+
334
+ tasks.push({
335
+ taskId,
336
+ title: req.title,
337
+ type: taskType,
338
+ priority,
339
+ requirements: [req.reqId],
340
+ dependencies: req.blockedBy || [],
341
+ estimatedHours: 2,
342
+ status: req.status === 'done' ? 'completed' : 'pending',
343
+ subtasks: req.acceptance?.map((acc, idx) => ({
344
+ id: `${taskId}-${idx + 1}`,
345
+ title: acc,
346
+ status: 'pending' as const,
347
+ })) || [],
348
+ verification: [
349
+ 'pnpm test',
350
+ 'pnpm build',
351
+ ],
352
+ });
353
+ }
354
+
355
+ // Sort tasks by priority and dependencies
356
+ const sortedTasks = tasks.sort((a, b) => {
357
+ const priorityOrder = { high: 0, medium: 1, low: 2 };
358
+ return priorityOrder[a.priority] - priorityOrder[b.priority];
359
+ });
360
+
361
+ const tasksJson = {
362
+ version: '1.0.0',
363
+ jobId: analysis.jobId,
364
+ generatedAt: new Date().toISOString(),
365
+ tasks: sortedTasks,
366
+ executionOrder: sortedTasks.map(t => t.taskId),
367
+ summary: {
368
+ totalTasks: tasks.length,
369
+ pending: tasks.length,
370
+ inProgress: 0,
371
+ completed: 0,
372
+ estimatedHours: tasks.reduce((sum, t) => sum + t.estimatedHours, 0),
373
+ },
374
+ };
375
+
376
+ fs.writeFileSync(outputPath, JSON.stringify(tasksJson, null, 2));
377
+ console.log(` āœ… Generated: tasks.json (${tasks.length} tasks)`);
378
+ }
379
+
380
+ /**
381
+ * Generate verification.json
382
+ */
383
+ function generateVerification(
384
+ analysis: CapabilityAnalysis,
385
+ outputPath: string
386
+ ): void {
387
+ const verifications = [
388
+ {
389
+ id: 'VERIFY-001',
390
+ name: 'Type Check',
391
+ command: 'pnpm type-check',
392
+ required: true,
393
+ runBefore: 'commit',
394
+ },
395
+ {
396
+ id: 'VERIFY-002',
397
+ name: 'Unit Tests',
398
+ command: 'pnpm test',
399
+ required: true,
400
+ runBefore: 'commit',
401
+ },
402
+ {
403
+ id: 'VERIFY-003',
404
+ name: 'Build',
405
+ command: 'pnpm build',
406
+ required: true,
407
+ runBefore: 'push',
408
+ },
409
+ ];
410
+
411
+ // Add capability-specific tests
412
+ let verifyCounter = 4;
413
+ for (const cap of analysis.capabilities.missing) {
414
+ verifications.push({
415
+ id: `VERIFY-${String(verifyCounter).padStart(3, '0')}`,
416
+ name: `${cap.name || cap.capId} Tests`,
417
+ command: `pnpm test:${cap.capId}`,
418
+ required: true,
419
+ runBefore: 'merge',
420
+ });
421
+ verifyCounter++;
422
+ }
423
+
424
+ const verificationJson = {
425
+ version: '1.0.0',
426
+ jobId: analysis.jobId,
427
+ generatedAt: new Date().toISOString(),
428
+ verifications,
429
+ preCommitChecks: ['VERIFY-001', 'VERIFY-002'],
430
+ prePushChecks: ['VERIFY-003'],
431
+ preMergeChecks: verifications.filter(v => v.runBefore === 'merge').map(v => v.id),
432
+ };
433
+
434
+ fs.writeFileSync(outputPath, JSON.stringify(verificationJson, null, 2));
435
+ console.log(` āœ… Generated: verification.json (${verifications.length} checks)`);
436
+ }
437
+
438
+ /**
439
+ * Generate progress.json
440
+ */
441
+ function generateProgress(
442
+ analysis: CapabilityAnalysis,
443
+ tasksCount: number,
444
+ outputPath: string
445
+ ): void {
446
+ const progressJson = {
447
+ version: '1.0.0',
448
+ jobId: analysis.jobId,
449
+ updatedAt: new Date().toISOString(),
450
+ status: 'pending',
451
+ progress: {
452
+ totalTasks: tasksCount,
453
+ completed: 0,
454
+ inProgress: 0,
455
+ pending: tasksCount,
456
+ percentage: 0,
457
+ },
458
+ timeline: [
459
+ {
460
+ timestamp: new Date().toISOString(),
461
+ event: 'specs-generated',
462
+ description: 'Development specifications generated',
463
+ },
464
+ ],
465
+ currentTask: null,
466
+ nextTask: tasksCount > 0 ? 'TASK-001' : null,
467
+ blockers: [],
468
+ };
469
+
470
+ fs.writeFileSync(outputPath, JSON.stringify(progressJson, null, 2));
471
+ console.log(` āœ… Generated: progress.json`);
472
+ }
473
+
474
+ /**
475
+ * Main function
476
+ */
477
+ function generateSpecs(
478
+ analysisPath: string,
479
+ unifiedPath: string,
480
+ outputDir: string
481
+ ): void {
482
+ console.log('šŸ“‹ Generating specs...');
483
+
484
+ // Read analysis
485
+ if (!fs.existsSync(analysisPath)) {
486
+ throw new Error(`Analysis file not found: ${analysisPath}`);
487
+ }
488
+ const analysis: CapabilityAnalysis = JSON.parse(fs.readFileSync(analysisPath, 'utf-8'));
489
+
490
+ // Read unified
491
+ if (!fs.existsSync(unifiedPath)) {
492
+ throw new Error(`Unified file not found: ${unifiedPath}`);
493
+ }
494
+ const unified: UnifiedRequirements = JSON.parse(fs.readFileSync(unifiedPath, 'utf-8'));
495
+
496
+ // Create output directory
497
+ if (!fs.existsSync(outputDir)) {
498
+ fs.mkdirSync(outputDir, { recursive: true });
499
+ }
500
+
501
+ // Generate files
502
+ generateReadme(analysis, unified, path.join(outputDir, 'README.md'));
503
+ generateTasks(analysis, unified, path.join(outputDir, 'tasks.json'));
504
+
505
+ // Read tasks count for progress
506
+ const tasksJson = JSON.parse(fs.readFileSync(path.join(outputDir, 'tasks.json'), 'utf-8'));
507
+ const tasksCount = tasksJson.tasks.length;
508
+
509
+ generateVerification(analysis, path.join(outputDir, 'verification.json'));
510
+ generateProgress(analysis, tasksCount, path.join(outputDir, 'progress.json'));
511
+
512
+ console.log(`\nāœ… Specs generated in: ${outputDir}`);
513
+ console.log(` README.md - Development specification`);
514
+ console.log(` tasks.json - ${tasksCount} tasks`);
515
+ console.log(` verification.json - Verification commands`);
516
+ console.log(` progress.json - Progress tracking`);
517
+ }
518
+
519
+ // CLI
520
+ if (import.meta.url === `file://${process.argv[1]}`) {
521
+ const args = process.argv.slice(2);
522
+
523
+ if (args.length < 3) {
524
+ console.error('Usage: tsx generate-specs.ts <capability-analysis.json> <unified.json> <output-dir>');
525
+ process.exit(1);
526
+ }
527
+
528
+ const [analysisPath, unifiedPath, outputDir] = args;
529
+
530
+ try {
531
+ generateSpecs(analysisPath, unifiedPath, outputDir);
532
+ } catch (error) {
533
+ console.error('āŒ Error:', error);
534
+ process.exit(1);
535
+ }
536
+ }
537
+
538
+ export { generateSpecs };
@@ -0,0 +1,174 @@
1
+ /**
2
+ * Generate Tasks
3
+ *
4
+ * Generate task list from capability analysis
5
+ * Output: tasks.json with execution order
6
+ */
7
+
8
+ import fs from 'fs';
9
+ import path from 'path';
10
+
11
+ interface CapabilityAnalysis {
12
+ available: Array<{
13
+ id: string;
14
+ name: string;
15
+ layer: string;
16
+ status: string;
17
+ }>;
18
+ missing: Array<{
19
+ id: string;
20
+ name: string;
21
+ reason: string;
22
+ }>;
23
+ dependencies: Record<string, string[]>;
24
+ executionOrder: string[];
25
+ }
26
+
27
+ interface Task {
28
+ id: string;
29
+ order: number;
30
+ type: 'develop-capability' | 'integrate' | 'test';
31
+ target: string;
32
+ description: string;
33
+ blockedBy: string[];
34
+ status: 'pending' | 'in-progress' | 'completed' | 'failed';
35
+ estimatedHours?: number;
36
+ }
37
+
38
+ interface TaskList {
39
+ version: string;
40
+ generatedAt: string;
41
+ tasks: Task[];
42
+ summary: {
43
+ total: number;
44
+ pending: number;
45
+ inProgress: number;
46
+ completed: number;
47
+ };
48
+ }
49
+
50
+ /**
51
+ * Generate tasks from capability analysis
52
+ */
53
+ function generateTasks(analysisPath: string, outputPath: string) {
54
+ console.log('šŸ“‹ Generating tasks...');
55
+
56
+ // Read capability analysis
57
+ if (!fs.existsSync(analysisPath)) {
58
+ throw new Error(`Capability analysis not found: ${analysisPath}`);
59
+ }
60
+
61
+ const analysis: CapabilityAnalysis = JSON.parse(fs.readFileSync(analysisPath, 'utf-8'));
62
+
63
+ const tasks: Task[] = [];
64
+ let taskOrder = 1;
65
+
66
+ // Generate tasks for missing capabilities (ęŒ‰ę‰§č”Œé”ŗåŗ)
67
+ const taskIdMap = new Map<string, string>();
68
+
69
+ for (const capId of analysis.executionOrder) {
70
+ const missing = analysis.missing.find(m => m.id === capId);
71
+ if (!missing) continue;
72
+
73
+ const taskId = `task-${taskOrder}`;
74
+ taskIdMap.set(capId, taskId);
75
+
76
+ // Find dependencies
77
+ const deps = analysis.dependencies[capId] || [];
78
+ const blockedBy = deps.map(dep => taskIdMap.get(dep)).filter(Boolean) as string[];
79
+
80
+ tasks.push({
81
+ id: taskId,
82
+ order: taskOrder,
83
+ type: 'develop-capability',
84
+ target: capId,
85
+ description: `å¼€å‘čƒ½åŠ›: ${missing.name}`,
86
+ blockedBy,
87
+ status: 'pending',
88
+ estimatedHours: 8, // Default estimate
89
+ });
90
+
91
+ console.log(` ${taskOrder}. ${missing.name}${blockedBy.length > 0 ? ` (ä¾čµ–: ${blockedBy.join(', ')})` : ''}`);
92
+ taskOrder++;
93
+ }
94
+
95
+ // Add integration task (after all capabilities are developed)
96
+ if (tasks.length > 0) {
97
+ const integrationTaskId = `task-${taskOrder}`;
98
+ const allCapabilityTasks = tasks.map(t => t.id);
99
+
100
+ tasks.push({
101
+ id: integrationTaskId,
102
+ order: taskOrder,
103
+ type: 'integrate',
104
+ target: 'job-main',
105
+ description: 'åÆ¹ęŽ„ę‰€ęœ‰čƒ½åŠ›åˆ°äø»åŠŸčƒ½',
106
+ blockedBy: allCapabilityTasks,
107
+ status: 'pending',
108
+ estimatedHours: 4,
109
+ });
110
+
111
+ console.log(` ${taskOrder}. åÆ¹ęŽ„ę‰€ęœ‰čƒ½åŠ› (ä¾čµ–: ${allCapabilityTasks.join(', ')})`);
112
+ taskOrder++;
113
+
114
+ // Add test task
115
+ const testTaskId = `task-${taskOrder}`;
116
+ tasks.push({
117
+ id: testTaskId,
118
+ order: taskOrder,
119
+ type: 'test',
120
+ target: 'job-main',
121
+ description: 'ęµ‹čÆ•å®Œę•“åŠŸčƒ½',
122
+ blockedBy: [integrationTaskId],
123
+ status: 'pending',
124
+ estimatedHours: 2,
125
+ });
126
+
127
+ console.log(` ${taskOrder}. ęµ‹čÆ•å®Œę•“åŠŸčƒ½ (ä¾čµ–: ${integrationTaskId})`);
128
+ }
129
+
130
+ // Create task list
131
+ const taskList: TaskList = {
132
+ version: '1.0.0',
133
+ generatedAt: new Date().toISOString(),
134
+ tasks,
135
+ summary: {
136
+ total: tasks.length,
137
+ pending: tasks.filter(t => t.status === 'pending').length,
138
+ inProgress: tasks.filter(t => t.status === 'in-progress').length,
139
+ completed: tasks.filter(t => t.status === 'completed').length,
140
+ },
141
+ };
142
+
143
+ // Write output
144
+ const outputDir = path.dirname(outputPath);
145
+ if (!fs.existsSync(outputDir)) {
146
+ fs.mkdirSync(outputDir, { recursive: true });
147
+ }
148
+
149
+ fs.writeFileSync(outputPath, JSON.stringify(taskList, null, 2));
150
+ console.log(`\nāœ… Tasks saved to: ${outputPath}`);
151
+ console.log(` Total tasks: ${taskList.summary.total}`);
152
+ console.log(` Estimated hours: ${tasks.reduce((sum, t) => sum + (t.estimatedHours || 0), 0)}h`);
153
+ }
154
+
155
+ // CLI
156
+ if (import.meta.url === `file://${process.argv[1]}`) {
157
+ const args = process.argv.slice(2);
158
+
159
+ if (args.length < 2) {
160
+ console.error('Usage: tsx generate-tasks.ts <capability-analysis.json> <output.json>');
161
+ process.exit(1);
162
+ }
163
+
164
+ const [analysisPath, outputPath] = args;
165
+
166
+ try {
167
+ generateTasks(analysisPath, outputPath);
168
+ } catch (error) {
169
+ console.error('āŒ Error:', error);
170
+ process.exit(1);
171
+ }
172
+ }
173
+
174
+ export { generateTasks };