@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,346 @@
1
+ /**
2
+ * Infer Builder Configuration from MDX Content
3
+ *
4
+ * This script analyzes MDX content and automatically infers:
5
+ * - Required capabilities (L1/L2/L3)
6
+ * - Layer hints
7
+ *
8
+ * Uses simple keyword matching (keywords from MDX frontmatter vs capability tree keywords)
9
+ */
10
+
11
+ import fs from 'fs';
12
+ import path from 'path';
13
+ import type { UnifiedRequirement } from '../types/unified-requirements';
14
+
15
+ /**
16
+ * Load capability definitions from capability tree
17
+ */
18
+ function loadCapabilityDefinitions(): Array<{
19
+ id: string;
20
+ name: string;
21
+ tags: string[];
22
+ layer: string;
23
+ }> {
24
+ const capabilityTreePath = path.join(process.cwd(), 'exports/capability-tree/capability-tree.json');
25
+
26
+ if (!fs.existsSync(capabilityTreePath)) {
27
+ throw new Error(`
28
+ āŒ Capability tree not found: ${capabilityTreePath}
29
+
30
+ Please run: pnpm capability:build-tree
31
+
32
+ Or create the capability tree manually.
33
+ `);
34
+ }
35
+
36
+ try {
37
+ const treeData = JSON.parse(fs.readFileSync(capabilityTreePath, 'utf-8'));
38
+ const capabilities: Array<{ id: string; name: string; tags: string[]; layer: string }> = [];
39
+
40
+ // Flatten capability tree
41
+ function flattenTree(nodes: any[], layer: string = 'L1') {
42
+ for (const node of nodes) {
43
+ if (node.id && node.name) {
44
+ capabilities.push({
45
+ id: node.id,
46
+ name: node.name,
47
+ tags: node.tags || [node.id, node.name.toLowerCase()],
48
+ layer: node.layer || layer,
49
+ });
50
+ }
51
+ if (node.children && node.children.length > 0) {
52
+ flattenTree(node.children, node.layer || layer);
53
+ }
54
+ }
55
+ }
56
+
57
+ flattenTree(treeData.capabilities || treeData);
58
+
59
+ if (capabilities.length === 0) {
60
+ throw new Error('Capability tree is empty');
61
+ }
62
+
63
+ console.log(` Loaded ${capabilities.length} capabilities from tree`);
64
+
65
+ return capabilities;
66
+ } catch (error) {
67
+ throw new Error(`Failed to load capability tree: ${error}`);
68
+ }
69
+ }
70
+
71
+ /**
72
+ * Extract keywords from text (simple tokenization)
73
+ */
74
+ function extractTags(text: string): string[] {
75
+ // Remove special characters and split by whitespace
76
+ const words = text
77
+ .toLowerCase()
78
+ .replace(/[^\w\s-]/g, ' ')
79
+ .split(/\s+/)
80
+ .filter(w => w.length > 2); // Filter out short words
81
+
82
+ // Remove duplicates and return
83
+ return Array.from(new Set(words));
84
+ }
85
+
86
+ /**
87
+ * Match keywords with capabilities (simple intersection)
88
+ */
89
+ function matchCapabilities(
90
+ docKeywords: string[],
91
+ capabilities: Array<{ id: string; name: string; tags: string[]; layer: string }>
92
+ ): Array<{ id: string; layer: string; score: number }> {
93
+ const matches: Array<{ id: string; layer: string; score: number }> = [];
94
+
95
+ // Normalize keywords to lowercase
96
+ const normalizedKeywords = docKeywords.map(k => k.toLowerCase());
97
+
98
+ for (const cap of capabilities) {
99
+ // Normalize capability tags to lowercase
100
+ const normalizedTags = cap.tags.map(t => t.toLowerCase());
101
+
102
+ // Calculate intersection (how many keywords match)
103
+ const matchCount = normalizedKeywords.filter(k => normalizedTags.includes(k)).length;
104
+
105
+ if (matchCount > 0) {
106
+ // Score = match count / total tags (normalized)
107
+ const score = matchCount / normalizedTags.length;
108
+ matches.push({
109
+ id: cap.id,
110
+ layer: cap.layer,
111
+ score,
112
+ });
113
+ }
114
+ }
115
+
116
+ // Sort by score (descending)
117
+ return matches.sort((a, b) => b.score - a.score);
118
+ }
119
+
120
+ /**
121
+ * Infer required capabilities from requirements
122
+ */
123
+ export function inferCapabilities(requirements: UnifiedRequirement[], docKeywords?: string[]): {
124
+ L1: string[];
125
+ L2: string[];
126
+ L3: string[];
127
+ } {
128
+ // Load capability definitions
129
+ const capabilityDefs = loadCapabilityDefinitions();
130
+
131
+ // Use provided keywords or extract from requirements
132
+ let keywords: string[];
133
+ if (docKeywords && docKeywords.length > 0) {
134
+ keywords = docKeywords;
135
+ console.log('šŸ“ Using provided keywords:', keywords.slice(0, 10).join(', '), '...');
136
+ } else {
137
+ // Fallback: extract from requirements
138
+ const allText = requirements
139
+ .map(req => `${req.title} ${req.description} ${req.acceptance?.join(' ')} ${req.tasks?.join(' ')}`)
140
+ .join(' ');
141
+ keywords = extractTags(allText);
142
+ console.log('šŸ“ Extracted keywords:', keywords.slice(0, 10).join(', '), '...');
143
+ }
144
+
145
+ // Match capabilities
146
+ const matches = matchCapabilities(keywords, capabilityDefs);
147
+ console.log('šŸŽÆ Matched capabilities:', matches.slice(0, 5).map(m => `${m.id}(${m.score.toFixed(2)})`).join(', '));
148
+
149
+ // Group by layer
150
+ const capabilities = {
151
+ L1: new Set<string>(),
152
+ L2: new Set<string>(),
153
+ L3: new Set<string>(),
154
+ };
155
+
156
+ // Take top matches (score > 0.1)
157
+ matches
158
+ .filter(m => m.score > 0.1)
159
+ .forEach(match => {
160
+ const layer = match.layer as 'L1' | 'L2' | 'L3';
161
+ if (capabilities[layer]) {
162
+ capabilities[layer].add(match.id);
163
+ }
164
+ });
165
+
166
+ // Also check explicit hints from requirements
167
+ requirements.forEach(req => {
168
+ if (req.layerHint && req.capabilityHints) {
169
+ req.capabilityHints.forEach(capId => {
170
+ const layer = req.layerHint as 'L1' | 'L2' | 'L3';
171
+ if (capabilities[layer]) {
172
+ capabilities[layer].add(capId);
173
+ }
174
+ });
175
+ }
176
+ });
177
+
178
+ return {
179
+ L1: Array.from(capabilities.L1),
180
+ L2: Array.from(capabilities.L2),
181
+ L3: Array.from(capabilities.L3),
182
+ };
183
+ }
184
+
185
+ /**
186
+ * Infer project name from requirements
187
+ */
188
+ function inferProjectName(requirements: UnifiedRequirement[]): string {
189
+ // Try to extract from first requirement's source file
190
+ const firstReq = requirements[0];
191
+ if (firstReq?.sourceFiles?.[0]) {
192
+ const filename = firstReq.sourceFiles[0].split('/').pop()?.replace('.mdx', '');
193
+ if (filename) {
194
+ return filename
195
+ .replace(/-/g, ' ')
196
+ .replace(/\b\w/g, l => l.toUpperCase());
197
+ }
198
+ }
199
+
200
+ // Fallback: use common words from titles
201
+ const words = requirements
202
+ .map(r => r.title.split(/\s+/))
203
+ .flat()
204
+ .filter(w => w.length > 2);
205
+
206
+ const wordCount = new Map<string, number>();
207
+ words.forEach(w => {
208
+ wordCount.set(w, (wordCount.get(w) || 0) + 1);
209
+ });
210
+
211
+ const mostCommon = Array.from(wordCount.entries())
212
+ .sort((a, b) => b[1] - a[1])[0];
213
+
214
+ return mostCommon ? `${mostCommon[0]} System` : 'Untitled Project';
215
+ }
216
+
217
+ /**
218
+ * Generate Builder configuration from requirements
219
+ * Output format: UnifiedRequirements (for merging)
220
+ */
221
+ export function generateBuilderConfig(
222
+ requirements: UnifiedRequirement[],
223
+ docKeywords?: string[]
224
+ ): {
225
+ version: string;
226
+ sources: {
227
+ builder: {
228
+ method: string;
229
+ capabilities: string[];
230
+ extractedAt: string;
231
+ keywords?: string[];
232
+ };
233
+ };
234
+ requirements: UnifiedRequirement[];
235
+ } {
236
+ const capabilities = inferCapabilities(requirements, docKeywords);
237
+ const allCapabilities = [...capabilities.L1, ...capabilities.L2, ...capabilities.L3];
238
+
239
+ // Generate requirements from inferred capabilities
240
+ const builderRequirements: UnifiedRequirement[] = [];
241
+
242
+ // Add L1 capabilities
243
+ capabilities.L1.forEach(capId => {
244
+ builderRequirements.push({
245
+ reqId: `REQ-BUILDER-${capId.toUpperCase()}`,
246
+ title: `集ꈐ ${capId} čƒ½åŠ›`,
247
+ description: `使用 ${capId} čƒ½åŠ›`,
248
+ source: 'builder',
249
+ type: 'feature',
250
+ status: 'ready',
251
+ layerHint: 'L1',
252
+ capabilityHints: [capId],
253
+ acceptance: [],
254
+ tasks: [],
255
+ blockedBy: [],
256
+ blocks: [],
257
+ });
258
+ });
259
+
260
+ // Add L2 capabilities
261
+ capabilities.L2.forEach(capId => {
262
+ builderRequirements.push({
263
+ reqId: `REQ-BUILDER-${capId.toUpperCase()}`,
264
+ title: `集ꈐ ${capId} čƒ½åŠ›`,
265
+ description: `使用 ${capId} čƒ½åŠ›`,
266
+ source: 'builder',
267
+ type: 'feature',
268
+ status: 'ready',
269
+ layerHint: 'L2',
270
+ capabilityHints: [capId],
271
+ acceptance: [],
272
+ tasks: [],
273
+ blockedBy: [],
274
+ blocks: [],
275
+ });
276
+ });
277
+
278
+ // Add L3 capabilities
279
+ capabilities.L3.forEach(capId => {
280
+ builderRequirements.push({
281
+ reqId: `REQ-BUILDER-${capId.toUpperCase()}`,
282
+ title: `集ꈐ ${capId} čƒ½åŠ›`,
283
+ description: `使用 ${capId} čƒ½åŠ›`,
284
+ source: 'builder',
285
+ type: 'feature',
286
+ status: 'ready',
287
+ layerHint: 'L3',
288
+ capabilityHints: [capId],
289
+ acceptance: [],
290
+ tasks: [],
291
+ blockedBy: [],
292
+ blocks: [],
293
+ });
294
+ });
295
+
296
+ return {
297
+ version: '1.0.0',
298
+ sources: {
299
+ builder: {
300
+ method: 'inferred',
301
+ capabilities: allCapabilities,
302
+ extractedAt: new Date().toISOString(),
303
+ keywords: docKeywords, // Include keywords in output
304
+ },
305
+ },
306
+ requirements: builderRequirements,
307
+ };
308
+ }
309
+
310
+ /**
311
+ * CLI entry point
312
+ */
313
+ if (import.meta.url === `file://${process.argv[1]}`) {
314
+ const args = process.argv.slice(2);
315
+ const inputFile = args[0] || './exports/requirements.pricing-from-docs.json';
316
+ const outputFile = args[1] || './exports/requirements.pricing-from-builder-inferred.json';
317
+
318
+ console.log('šŸ” Inferring Builder configuration from requirements...');
319
+ console.log(' Input:', inputFile);
320
+
321
+ // Load requirements
322
+ const data = JSON.parse(fs.readFileSync(inputFile, 'utf-8'));
323
+ const requirements = data.requirements as UnifiedRequirement[];
324
+ const docKeywords = data.sources?.docs?.keywords as string[] | undefined;
325
+
326
+ if (docKeywords && docKeywords.length > 0) {
327
+ console.log(` Found ${docKeywords.length} keywords from docs`);
328
+ }
329
+
330
+ // Generate config
331
+ const config = generateBuilderConfig(requirements, docKeywords);
332
+
333
+ console.log('\nāœ… Inferred capabilities:');
334
+ const l1Caps = config.requirements.filter(r => r.layerHint === 'L1').map(r => r.capabilityHints?.[0]).filter(Boolean);
335
+ const l2Caps = config.requirements.filter(r => r.layerHint === 'L2').map(r => r.capabilityHints?.[0]).filter(Boolean);
336
+ const l3Caps = config.requirements.filter(r => r.layerHint === 'L3').map(r => r.capabilityHints?.[0]).filter(Boolean);
337
+
338
+ console.log(' L1:', l1Caps.join(', ') || 'none');
339
+ console.log(' L2:', l2Caps.join(', ') || 'none');
340
+ console.log(' L3:', l3Caps.join(', ') || 'none');
341
+ console.log(` Total: ${config.requirements.length} capability requirements`);
342
+
343
+ // Write output
344
+ fs.writeFileSync(outputFile, JSON.stringify(config, null, 2));
345
+ console.log('\nšŸ“„ Output:', outputFile);
346
+ }
@@ -0,0 +1,228 @@
1
+ /**
2
+ * Merge Requirements from Multiple Sources
3
+ *
4
+ * This script merges requirements from:
5
+ * - MDX planning documents (narrative, flexible)
6
+ * - Product Builder (structured, technical)
7
+ * - Historical data (preserves status)
8
+ */
9
+
10
+ import fs from 'fs';
11
+ import path from 'path';
12
+ import type { UnifiedRequirement, UnifiedRequirements } from '../types/unified-requirements';
13
+
14
+ /**
15
+ * Merge requirements from multiple sources
16
+ */
17
+ export function mergeRequirements(
18
+ fromDocs?: UnifiedRequirements,
19
+ fromBuilder?: UnifiedRequirements,
20
+ history?: UnifiedRequirements
21
+ ): UnifiedRequirements {
22
+ const merged = new Map<string, UnifiedRequirement>();
23
+
24
+ // 1. Load history (preserve status)
25
+ if (history) {
26
+ history.requirements.forEach(req => {
27
+ merged.set(req.reqId, { ...req });
28
+ });
29
+ }
30
+
31
+ // 2. Merge docs (high priority)
32
+ if (fromDocs) {
33
+ fromDocs.requirements.forEach(req => {
34
+ const existing = merged.get(req.reqId);
35
+
36
+ if (existing) {
37
+ // Preserve completed status
38
+ if (existing.status === 'done') {
39
+ req.status = 'done';
40
+ req.completedAt = existing.completedAt;
41
+ }
42
+
43
+ // Merge source files
44
+ req.sourceFiles = [
45
+ ...(existing.sourceFiles || []),
46
+ ...(req.sourceFiles || []),
47
+ ];
48
+ req.source = 'merged';
49
+ }
50
+
51
+ merged.set(req.reqId, req);
52
+ });
53
+ }
54
+
55
+ // 3. Supplement with builder info (only add missing fields)
56
+ if (fromBuilder) {
57
+ fromBuilder.requirements.forEach(req => {
58
+ const existing = merged.get(req.reqId);
59
+
60
+ if (!existing) {
61
+ // New requirement from builder
62
+ merged.set(req.reqId, req);
63
+ } else {
64
+ // Supplement technical fields
65
+ if (!existing.layerHint) existing.layerHint = req.layerHint;
66
+ if (!existing.capabilityHints) existing.capabilityHints = req.capabilityHints;
67
+ if (!existing.module) existing.module = req.module;
68
+ if (!existing.modules) existing.modules = req.modules;
69
+ existing.source = 'merged';
70
+ }
71
+ });
72
+ }
73
+
74
+ // 4. Calculate dependencies and execution order
75
+ const requirements = Array.from(merged.values());
76
+ calculateBlockedBy(requirements);
77
+ const executionOrder = calculateExecutionOrder(requirements);
78
+
79
+ return {
80
+ version: '1.0.0',
81
+ generatedAt: new Date().toISOString(),
82
+ sources: {
83
+ docs: fromDocs?.sources.docs,
84
+ builder: fromBuilder?.sources.builder,
85
+ },
86
+ requirements,
87
+ executionOrder,
88
+ };
89
+ }
90
+
91
+ /**
92
+ * Calculate blockedBy and blocks fields
93
+ */
94
+ function calculateBlockedBy(requirements: UnifiedRequirement[]): void {
95
+ const reqMap = new Map(requirements.map(r => [r.reqId, r]));
96
+
97
+ // Don't clear existing blockedBy/blocks - preserve them from parse-openspec
98
+ // Only initialize if they don't exist
99
+ requirements.forEach(req => {
100
+ if (!req.blockedBy) req.blockedBy = [];
101
+ if (!req.blocks) req.blocks = [];
102
+ });
103
+
104
+ // Add additional dependencies from dependsOn field
105
+ requirements.forEach(req => {
106
+ if (req.dependsOn) {
107
+ req.dependsOn.forEach(depId => {
108
+ const dep = reqMap.get(depId);
109
+ if (dep) {
110
+ // This req is blocked by dep
111
+ if (dep.status !== 'done' && !req.blockedBy!.includes(depId)) {
112
+ req.blockedBy!.push(depId);
113
+ }
114
+ // dep blocks this req
115
+ if (!dep.blocks) dep.blocks = [];
116
+ if (!dep.blocks.includes(req.reqId)) {
117
+ dep.blocks.push(req.reqId);
118
+ }
119
+ }
120
+ });
121
+ }
122
+ });
123
+ }
124
+
125
+ /**
126
+ * Calculate execution order using topological sort
127
+ */
128
+ function calculateExecutionOrder(requirements: UnifiedRequirement[]): string[] {
129
+ const graph = new Map<string, string[]>();
130
+ const inDegree = new Map<string, number>();
131
+
132
+ // Build graph
133
+ requirements.forEach(req => {
134
+ graph.set(req.reqId, req.dependsOn || []);
135
+ inDegree.set(req.reqId, 0);
136
+ });
137
+
138
+ // Calculate in-degrees
139
+ requirements.forEach(req => {
140
+ (req.dependsOn || []).forEach(depId => {
141
+ inDegree.set(depId, (inDegree.get(depId) || 0) + 1);
142
+ });
143
+ });
144
+
145
+ // Topological sort
146
+ const queue: string[] = [];
147
+ const sorted: string[] = [];
148
+
149
+ // Start with nodes that have no dependencies
150
+ inDegree.forEach((degree, reqId) => {
151
+ if (degree === 0) {
152
+ queue.push(reqId);
153
+ }
154
+ });
155
+
156
+ while (queue.length > 0) {
157
+ const reqId = queue.shift()!;
158
+ sorted.push(reqId);
159
+
160
+ const deps = graph.get(reqId) || [];
161
+ deps.forEach(depId => {
162
+ const newDegree = (inDegree.get(depId) || 0) - 1;
163
+ inDegree.set(depId, newDegree);
164
+ if (newDegree === 0) {
165
+ queue.push(depId);
166
+ }
167
+ });
168
+ }
169
+
170
+ // Check for cycles
171
+ if (sorted.length !== requirements.length) {
172
+ console.warn('Warning: Circular dependencies detected');
173
+ }
174
+
175
+ return sorted;
176
+ }
177
+
178
+ /**
179
+ * CLI entry point
180
+ */
181
+ if (import.meta.url === `file://${process.argv[1]}`) {
182
+ const args = process.argv.slice(2);
183
+
184
+ if (args.length < 3) {
185
+ console.error('Usage: tsx merge-requirements.ts <docs.json> <form.json> <output.json>');
186
+ console.error('');
187
+ console.error('Example:');
188
+ console.error(' tsx merge-requirements.ts docs.json form.json unified.json');
189
+ process.exit(1);
190
+ }
191
+
192
+ const docsFile = args[0];
193
+ const builderFile = args[1];
194
+ const outputFile = args[2];
195
+
196
+ console.log('šŸ”„ Merging requirements...');
197
+ console.log(' Docs:', docsFile);
198
+ console.log(' Builder:', builderFile);
199
+
200
+ // Load inputs
201
+ const fromDocs = fs.existsSync(docsFile)
202
+ ? JSON.parse(fs.readFileSync(docsFile, 'utf-8'))
203
+ : undefined;
204
+
205
+ const fromBuilder = fs.existsSync(builderFile)
206
+ ? JSON.parse(fs.readFileSync(builderFile, 'utf-8'))
207
+ : undefined;
208
+
209
+ if (!fromDocs && !fromBuilder) {
210
+ console.error('āŒ Error: At least one input file must exist');
211
+ process.exit(1);
212
+ }
213
+
214
+ // Merge (no history for now)
215
+ const result = mergeRequirements(fromDocs, fromBuilder, undefined);
216
+
217
+ console.log(`\nāœ… Merged ${result.requirements.length} requirements`);
218
+ console.log(` Execution order: ${result.executionOrder?.length || 0} items`);
219
+
220
+ // Write output
221
+ const outputDir = path.dirname(outputFile);
222
+ if (!fs.existsSync(outputDir)) {
223
+ fs.mkdirSync(outputDir, { recursive: true });
224
+ }
225
+
226
+ fs.writeFileSync(outputFile, JSON.stringify(result, null, 2));
227
+ console.log(`\nšŸ“„ Output: ${outputFile}`);
228
+ }