@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.
- package/README.md +48 -0
- package/package.json +28 -0
- package/registry.json +431 -0
- package/skills/acceptance-review/SKILL.md +537 -0
- package/skills/all-plan/SKILL.md +19 -0
- package/skills/all-plan/references/flow.md +750 -0
- package/skills/api-docs-generate/SKILL.md +204 -0
- package/skills/api-docs-generate/assets/templates/api.mdx +140 -0
- package/skills/api-docs-generate/scripts/generate-api-docs.ts +308 -0
- package/skills/ask/SKILL.md +42 -0
- package/skills/autonew/SKILL.md +34 -0
- package/skills/capability-analyze/SKILL.md +300 -0
- package/skills/capability-analyze/scripts/analyze-capabilities.ts +531 -0
- package/skills/capability-docs-generate/SKILL.md +155 -0
- package/skills/capability-docs-generate/assets/templates/capability.mdx +271 -0
- package/skills/capability-docs-generate/scripts/generate-capability-docs.ts +358 -0
- package/skills/capability-tree-query/SKILL.md +112 -0
- package/skills/capability-tree-query/scripts/build-capability-tree.ts +402 -0
- package/skills/changelog-generator/SKILL.md +104 -0
- package/skills/continue/SKILL.md +39 -0
- package/skills/continue/agents/openai.yaml +3 -0
- package/skills/creating-skills/SKILL.md +158 -0
- package/skills/creating-skills/references/official_best_practices.md +128 -0
- package/skills/creating-skills/references/skill_examples.md +199 -0
- package/skills/docx/LICENSE.txt +30 -0
- package/skills/docx/SKILL.md +197 -0
- package/skills/docx/docx-js.md +350 -0
- package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
- package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
- package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
- package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
- package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
- package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
- package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
- package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
- package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
- package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
- package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
- package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
- package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
- package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
- package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
- package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
- package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
- package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
- package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
- package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
- package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
- package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
- package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
- package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
- package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
- package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
- package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
- package/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
- package/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
- package/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
- package/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
- package/skills/docx/ooxml/schemas/mce/mc.xsd +75 -0
- package/skills/docx/ooxml/schemas/microsoft/wml-2010.xsd +560 -0
- package/skills/docx/ooxml/schemas/microsoft/wml-2012.xsd +67 -0
- package/skills/docx/ooxml/schemas/microsoft/wml-2018.xsd +14 -0
- package/skills/docx/ooxml/schemas/microsoft/wml-cex-2018.xsd +20 -0
- package/skills/docx/ooxml/schemas/microsoft/wml-cid-2016.xsd +13 -0
- package/skills/docx/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
- package/skills/docx/ooxml/schemas/microsoft/wml-symex-2015.xsd +8 -0
- package/skills/docx/ooxml/scripts/pack.py +159 -0
- package/skills/docx/ooxml/scripts/unpack.py +29 -0
- package/skills/docx/ooxml/scripts/validate.py +69 -0
- package/skills/docx/ooxml/scripts/validation/__init__.py +15 -0
- package/skills/docx/ooxml/scripts/validation/base.py +951 -0
- package/skills/docx/ooxml/scripts/validation/docx.py +274 -0
- package/skills/docx/ooxml/scripts/validation/pptx.py +315 -0
- package/skills/docx/ooxml/scripts/validation/redlining.py +279 -0
- package/skills/docx/ooxml.md +610 -0
- package/skills/docx/scripts/__init__.py +1 -0
- package/skills/docx/scripts/document.py +1276 -0
- package/skills/docx/scripts/templates/comments.xml +3 -0
- package/skills/docx/scripts/templates/commentsExtended.xml +3 -0
- package/skills/docx/scripts/templates/commentsExtensible.xml +3 -0
- package/skills/docx/scripts/templates/commentsIds.xml +3 -0
- package/skills/docx/scripts/templates/people.xml +3 -0
- package/skills/docx/scripts/utilities.py +374 -0
- package/skills/git-branch-create/SKILL.md +170 -0
- package/skills/git-branch-merge/SKILL.md +176 -0
- package/skills/git-commit/SKILL.md +56 -0
- package/skills/git-commit/references/commit_examples.md +311 -0
- package/skills/github-actions-trigger/SKILL.md +367 -0
- package/skills/github-issue-create/SKILL.md +294 -0
- package/skills/github-pr-creation/SKILL.md +137 -0
- package/skills/github-pr-creation/references/pr_templates.md +187 -0
- package/skills/github-pr-merge/SKILL.md +112 -0
- package/skills/github-pr-review/SKILL.md +110 -0
- package/skills/github-pr-review/references/severity_guide.md +168 -0
- package/skills/job-create/SKILL.md +294 -0
- package/skills/job-create/scripts/create-job.ts +105 -0
- package/skills/job-workflow/SKILL.md +212 -0
- package/skills/keyword-extract/SKILL.md +229 -0
- package/skills/mcp-builder/LICENSE.txt +202 -0
- package/skills/mcp-builder/SKILL.md +236 -0
- package/skills/mcp-builder/reference/evaluation.md +602 -0
- package/skills/mcp-builder/reference/mcp_best_practices.md +249 -0
- package/skills/mcp-builder/reference/node_mcp_server.md +970 -0
- package/skills/mcp-builder/reference/python_mcp_server.md +719 -0
- package/skills/mcp-builder/scripts/connections.py +151 -0
- package/skills/mcp-builder/scripts/evaluation.py +373 -0
- package/skills/mcp-builder/scripts/example_evaluation.xml +22 -0
- package/skills/mcp-builder/scripts/requirements.txt +2 -0
- package/skills/mdx-to-openspec/SKILL.md +827 -0
- package/skills/mdx-to-openspec/scripts/mdx-to-openspec.ts +320 -0
- package/skills/mounted/SKILL.md +20 -0
- package/skills/multi-model-review/SKILL.md +459 -0
- package/skills/notion-automation/SKILL.md +215 -0
- package/skills/openspec-review/SKILL.md +513 -0
- package/skills/pdf/LICENSE.txt +30 -0
- package/skills/pdf/SKILL.md +294 -0
- package/skills/pdf/forms.md +205 -0
- package/skills/pdf/reference.md +612 -0
- package/skills/pdf/scripts/check_bounding_boxes.py +70 -0
- package/skills/pdf/scripts/check_bounding_boxes_test.py +226 -0
- package/skills/pdf/scripts/check_fillable_fields.py +12 -0
- package/skills/pdf/scripts/convert_pdf_to_images.py +35 -0
- package/skills/pdf/scripts/create_validation_image.py +41 -0
- package/skills/pdf/scripts/extract_form_field_info.py +152 -0
- package/skills/pdf/scripts/fill_fillable_fields.py +114 -0
- package/skills/pdf/scripts/fill_pdf_form_with_annotations.py +108 -0
- package/skills/pend/SKILL.md +33 -0
- package/skills/ping/SKILL.md +39 -0
- package/skills/pptx/LICENSE.txt +30 -0
- package/skills/pptx/SKILL.md +484 -0
- package/skills/pptx/html2pptx.md +625 -0
- package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
- package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
- package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
- package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
- package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
- package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
- package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
- package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
- package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
- package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
- package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
- package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
- package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
- package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
- package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
- package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
- package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
- package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
- package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
- package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
- package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
- package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
- package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
- package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
- package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
- package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
- package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
- package/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
- package/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
- package/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
- package/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
- package/skills/pptx/ooxml/schemas/mce/mc.xsd +75 -0
- package/skills/pptx/ooxml/schemas/microsoft/wml-2010.xsd +560 -0
- package/skills/pptx/ooxml/schemas/microsoft/wml-2012.xsd +67 -0
- package/skills/pptx/ooxml/schemas/microsoft/wml-2018.xsd +14 -0
- package/skills/pptx/ooxml/schemas/microsoft/wml-cex-2018.xsd +20 -0
- package/skills/pptx/ooxml/schemas/microsoft/wml-cid-2016.xsd +13 -0
- package/skills/pptx/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
- package/skills/pptx/ooxml/schemas/microsoft/wml-symex-2015.xsd +8 -0
- package/skills/pptx/ooxml/scripts/pack.py +159 -0
- package/skills/pptx/ooxml/scripts/unpack.py +29 -0
- package/skills/pptx/ooxml/scripts/validate.py +69 -0
- package/skills/pptx/ooxml/scripts/validation/__init__.py +15 -0
- package/skills/pptx/ooxml/scripts/validation/base.py +951 -0
- package/skills/pptx/ooxml/scripts/validation/docx.py +274 -0
- package/skills/pptx/ooxml/scripts/validation/pptx.py +315 -0
- package/skills/pptx/ooxml/scripts/validation/redlining.py +279 -0
- package/skills/pptx/ooxml.md +427 -0
- package/skills/pptx/scripts/html2pptx.js +979 -0
- package/skills/pptx/scripts/inventory.py +1020 -0
- package/skills/pptx/scripts/rearrange.py +231 -0
- package/skills/pptx/scripts/replace.py +385 -0
- package/skills/pptx/scripts/thumbnail.py +450 -0
- package/skills/progress-update/SKILL.md +394 -0
- package/skills/progress-update/scripts/update-progress.ts +221 -0
- package/skills/release-automation/SKILL.md +306 -0
- package/skills/requirement-parse/SKILL.md +212 -0
- package/skills/requirement-parse/scripts/infer-builder-config.ts +346 -0
- package/skills/requirement-parse/scripts/merge-requirements.ts +228 -0
- package/skills/requirement-parse/scripts/parse-docs.ts +206 -0
- package/skills/requirement-parse/scripts/parse-openspec.ts +168 -0
- package/skills/roadmap-docs-generate/SKILL.md +483 -0
- package/skills/roadmap-docs-generate/assets/templates/ROADMAP.mdx +75 -0
- package/skills/roadmap-docs-generate/assets/templates/ROADMAP.mdx.template +330 -0
- package/skills/roadmap-docs-generate/assets/templates/TODO.mdx +56 -0
- package/skills/roadmap-docs-generate/assets/templates/TODO.mdx.template +363 -0
- package/skills/roadmap-docs-generate/scripts/json-to-mdx.ts +445 -0
- package/skills/roadmap-docs-generate/scripts/json-to-mdx.ts.backup +411 -0
- package/skills/roadmap-generate/SKILL.md +396 -0
- package/skills/roadmap-generate/scripts/generate-roadmap.ts +496 -0
- package/skills/skill-creator/LICENSE.txt +202 -0
- package/skills/skill-creator/SKILL.md +356 -0
- package/skills/skill-creator/references/output-patterns.md +82 -0
- package/skills/skill-creator/references/workflows.md +28 -0
- package/skills/skill-creator/scripts/init_skill.py +303 -0
- package/skills/skill-creator/scripts/package_skill.py +110 -0
- package/skills/skill-creator/scripts/quick_validate.py +95 -0
- package/skills/spec-generate/SKILL.md +408 -0
- package/skills/spec-generate/scripts/generate-specs.ts +538 -0
- package/skills/spec-generate/scripts/generate-tasks.ts +174 -0
- package/skills/specs-review/SKILL.md +370 -0
- package/skills/task-execute/SKILL.md +399 -0
- package/skills/task-update-status/SKILL.md +349 -0
- package/skills/task-update-status/scripts/update-task-status.ts +192 -0
- package/skills/task-verify/SKILL.md +407 -0
- package/skills/ui-ux-pro-max/SKILL.md +386 -0
- package/skills/ui-ux-pro-max/data/charts.csv +26 -0
- package/skills/ui-ux-pro-max/data/colors.csv +97 -0
- package/skills/ui-ux-pro-max/data/icons.csv +101 -0
- package/skills/ui-ux-pro-max/data/landing.csv +31 -0
- package/skills/ui-ux-pro-max/data/products.csv +97 -0
- package/skills/ui-ux-pro-max/data/react-performance.csv +45 -0
- package/skills/ui-ux-pro-max/data/stacks/astro.csv +54 -0
- package/skills/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
- package/skills/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
- package/skills/ui-ux-pro-max/data/stacks/jetpack-compose.csv +53 -0
- package/skills/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
- package/skills/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -0
- package/skills/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -0
- package/skills/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
- package/skills/ui-ux-pro-max/data/stacks/react.csv +54 -0
- package/skills/ui-ux-pro-max/data/stacks/shadcn.csv +61 -0
- package/skills/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
- package/skills/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
- package/skills/ui-ux-pro-max/data/stacks/vue.csv +50 -0
- package/skills/ui-ux-pro-max/data/styles.csv +68 -0
- package/skills/ui-ux-pro-max/data/typography.csv +58 -0
- package/skills/ui-ux-pro-max/data/ui-reasoning.csv +101 -0
- package/skills/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
- package/skills/ui-ux-pro-max/data/web-interface.csv +31 -0
- package/skills/ui-ux-pro-max/scripts/core.py +253 -0
- package/skills/ui-ux-pro-max/scripts/design_system.py +1067 -0
- package/skills/ui-ux-pro-max/scripts/search.py +114 -0
- package/skills/vercel-automation/SKILL.md +226 -0
- package/skills/webapp-testing/LICENSE.txt +202 -0
- package/skills/webapp-testing/SKILL.md +96 -0
- package/skills/webapp-testing/examples/console_logging.py +35 -0
- package/skills/webapp-testing/examples/element_discovery.py +40 -0
- package/skills/webapp-testing/examples/static_html_automation.py +33 -0
- package/skills/webapp-testing/scripts/with_server.py +106 -0
- package/skills/worktree-manager/SKILL.md +725 -0
- package/skills/worktree-manager/config.json +15 -0
- package/skills/worktree-manager/scripts/allocate-ports.sh +100 -0
- package/skills/worktree-manager/scripts/cleanup.sh +185 -0
- package/skills/worktree-manager/scripts/launch-agent.sh +155 -0
- package/skills/worktree-manager/scripts/register.sh +125 -0
- package/skills/worktree-manager/scripts/release-ports.sh +48 -0
- package/skills/worktree-manager/scripts/status.sh +169 -0
- package/skills/worktree-manager/scripts/sync.sh +168 -0
- package/skills/worktree-manager/templates/worktree.json +23 -0
- package/skills/xlsx/LICENSE.txt +30 -0
- package/skills/xlsx/SKILL.md +289 -0
- package/skills/xlsx/recalc.py +178 -0
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parse MDX Planning Documents to Unified Requirements
|
|
3
|
+
*
|
|
4
|
+
* This script extracts requirements from MDX planning documents.
|
|
5
|
+
* It looks for structured markers and extracts requirement information.
|
|
6
|
+
* Keywords are read from frontmatter (not auto-generated).
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import fs from 'fs';
|
|
10
|
+
import path from 'path';
|
|
11
|
+
import matter from 'gray-matter';
|
|
12
|
+
import type { UnifiedRequirement, UnifiedRequirements, RequirementBlock } from '../types/unified-requirements';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Parse a single MDX file
|
|
16
|
+
*/
|
|
17
|
+
function parseMdxFile(filePath: string): { blocks: RequirementBlock[]; keywords: string[] } {
|
|
18
|
+
const fileContent = fs.readFileSync(filePath, 'utf-8');
|
|
19
|
+
|
|
20
|
+
// Parse frontmatter
|
|
21
|
+
const { data, content } = matter(fileContent);
|
|
22
|
+
|
|
23
|
+
// Extract keywords from frontmatter
|
|
24
|
+
const keywords = data.keywords || [];
|
|
25
|
+
|
|
26
|
+
const blocks: RequirementBlock[] = [];
|
|
27
|
+
|
|
28
|
+
// Extract requirement blocks using markers
|
|
29
|
+
// Format: <!-- REQ-PRICING-021 | P0 | L1 | pricing -->
|
|
30
|
+
const markerPattern = /<!-- (REQ-[\w-]+)(?:\s*\|\s*(P\d))? -->\s*###\s+(.+?)(?:\n|$)/g;
|
|
31
|
+
|
|
32
|
+
let match;
|
|
33
|
+
while ((match = markerPattern.exec(content)) !== null) {
|
|
34
|
+
const reqId = match[1];
|
|
35
|
+
const priority = match[2];
|
|
36
|
+
const title = match[3].replace(/š“|š”|š¢|ā
|š§|š
|š®/g, '').trim();
|
|
37
|
+
|
|
38
|
+
// Find the section content
|
|
39
|
+
const sectionStart = match.index + match[0].length;
|
|
40
|
+
const nextMarkerMatch = content.slice(sectionStart).match(/<!-- REQ-[\w-]+ -->/);
|
|
41
|
+
const sectionEnd = nextMarkerMatch
|
|
42
|
+
? sectionStart + nextMarkerMatch.index
|
|
43
|
+
: content.length;
|
|
44
|
+
|
|
45
|
+
const sectionContent = content.slice(sectionStart, sectionEnd);
|
|
46
|
+
|
|
47
|
+
// Extract description (first paragraph)
|
|
48
|
+
const descMatch = sectionContent.match(/^(.+?)(?:\n\n|\n###|\n-)/s);
|
|
49
|
+
const description = descMatch ? descMatch[1].trim() : '';
|
|
50
|
+
|
|
51
|
+
// Extract tasks (checkbox items)
|
|
52
|
+
const tasks: string[] = [];
|
|
53
|
+
const taskPattern = /- \[ \] (.+)/g;
|
|
54
|
+
let taskMatch;
|
|
55
|
+
while ((taskMatch = taskPattern.exec(sectionContent)) !== null) {
|
|
56
|
+
tasks.push(taskMatch[1].trim());
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Extract acceptance criteria
|
|
60
|
+
const acceptance: string[] = [];
|
|
61
|
+
const acceptanceSection = sectionContent.match(/\*\*éŖę¶ę å[ļ¼:]\*\*\s*\n([\s\S]+?)(?:\n\n|\n###|$)/);
|
|
62
|
+
if (acceptanceSection) {
|
|
63
|
+
const criteriaPattern = /[-ā¢]\s*(.+)/g;
|
|
64
|
+
let criteriaMatch;
|
|
65
|
+
while ((criteriaMatch = criteriaPattern.exec(acceptanceSection[1])) !== null) {
|
|
66
|
+
acceptance.push(criteriaMatch[1].trim());
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Extract phase
|
|
71
|
+
const phaseMatch = title.match(/Phase\s+([\d.]+)/i);
|
|
72
|
+
const phase = phaseMatch ? `Phase ${phaseMatch[1]}` : undefined;
|
|
73
|
+
|
|
74
|
+
// Extract estimated days
|
|
75
|
+
const daysMatch = sectionContent.match(/é¢č®”[ļ¼:]\s*(\d+)\s*天/);
|
|
76
|
+
const estimatedDays = daysMatch ? parseInt(daysMatch[1]) : undefined;
|
|
77
|
+
|
|
78
|
+
blocks.push({
|
|
79
|
+
reqId,
|
|
80
|
+
title,
|
|
81
|
+
description,
|
|
82
|
+
phase,
|
|
83
|
+
tasks,
|
|
84
|
+
acceptance,
|
|
85
|
+
estimatedDays,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return { blocks, keywords };
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Convert requirement blocks to unified format
|
|
94
|
+
*/
|
|
95
|
+
function blocksToUnified(
|
|
96
|
+
blocks: RequirementBlock[],
|
|
97
|
+
sourceFile: string
|
|
98
|
+
): UnifiedRequirement[] {
|
|
99
|
+
return blocks.map(block => ({
|
|
100
|
+
reqId: block.reqId || `REQ-${Date.now()}`,
|
|
101
|
+
title: block.title,
|
|
102
|
+
description: block.description,
|
|
103
|
+
source: 'docs' as const,
|
|
104
|
+
sourceFiles: [sourceFile],
|
|
105
|
+
type: inferType(block),
|
|
106
|
+
status: block.status || 'draft',
|
|
107
|
+
phase: block.phase,
|
|
108
|
+
acceptance: block.acceptance,
|
|
109
|
+
tasks: block.tasks,
|
|
110
|
+
dependsOn: block.dependsOn,
|
|
111
|
+
estimatedDays: block.estimatedDays,
|
|
112
|
+
createdAt: new Date().toISOString(),
|
|
113
|
+
}));
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Infer requirement type from block
|
|
118
|
+
*/
|
|
119
|
+
function inferType(block: RequirementBlock): 'epic' | 'feature' | 'task' {
|
|
120
|
+
// If has sub-tasks, it's at least a feature
|
|
121
|
+
if (block.tasks && block.tasks.length > 5) {
|
|
122
|
+
return 'epic';
|
|
123
|
+
}
|
|
124
|
+
if (block.tasks && block.tasks.length > 0) {
|
|
125
|
+
return 'feature';
|
|
126
|
+
}
|
|
127
|
+
return 'task';
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Parse all MDX files in a directory or a single file
|
|
132
|
+
*/
|
|
133
|
+
export function parseMdxDirectory(inputPath: string): UnifiedRequirements {
|
|
134
|
+
const requirements: UnifiedRequirement[] = [];
|
|
135
|
+
const sourceFiles: string[] = [];
|
|
136
|
+
const allKeywords = new Set<string>();
|
|
137
|
+
|
|
138
|
+
// Check if input is a file or directory
|
|
139
|
+
const stat = fs.statSync(inputPath);
|
|
140
|
+
|
|
141
|
+
let files: string[];
|
|
142
|
+
if (stat.isFile()) {
|
|
143
|
+
// Single file
|
|
144
|
+
files = [inputPath];
|
|
145
|
+
} else {
|
|
146
|
+
// Directory - find all .mdx files
|
|
147
|
+
files = fs.readdirSync(inputPath, { recursive: true })
|
|
148
|
+
.filter(file => typeof file === 'string' && file.endsWith('.mdx'))
|
|
149
|
+
.map(file => path.join(inputPath, file as string));
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// Parse each file
|
|
153
|
+
for (const file of files) {
|
|
154
|
+
try {
|
|
155
|
+
const { blocks, keywords } = parseMdxFile(file);
|
|
156
|
+
keywords.forEach(k => allKeywords.add(k));
|
|
157
|
+
|
|
158
|
+
const unified = blocksToUnified(blocks, file);
|
|
159
|
+
requirements.push(...unified);
|
|
160
|
+
sourceFiles.push(file);
|
|
161
|
+
} catch (error) {
|
|
162
|
+
console.error(`Error parsing ${file}:`, error);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
const keywords = Array.from(allKeywords);
|
|
167
|
+
|
|
168
|
+
if (keywords.length > 0) {
|
|
169
|
+
console.log(`\nš Found ${keywords.length} keywords from frontmatter:`, keywords.join(', '));
|
|
170
|
+
} else {
|
|
171
|
+
console.log(`\nā ļø No keywords found in frontmatter. Please add keywords to MDX files.`);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
return {
|
|
175
|
+
version: '1.0.0',
|
|
176
|
+
generatedAt: new Date().toISOString(),
|
|
177
|
+
sources: {
|
|
178
|
+
docs: {
|
|
179
|
+
files: sourceFiles,
|
|
180
|
+
extractedAt: new Date().toISOString(),
|
|
181
|
+
keywords, // Add keywords to output
|
|
182
|
+
},
|
|
183
|
+
},
|
|
184
|
+
requirements,
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* CLI entry point
|
|
190
|
+
*/
|
|
191
|
+
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
192
|
+
const args = process.argv.slice(2);
|
|
193
|
+
const inputDir = args[0] || '../../../waoooo-docs/developer-docs/planning';
|
|
194
|
+
const outputFile = args[1] || './exports/temp/requirements-from-docs.json';
|
|
195
|
+
|
|
196
|
+
console.log('Parsing MDX documents...');
|
|
197
|
+
console.log('Input:', inputDir);
|
|
198
|
+
|
|
199
|
+
const result = parseMdxDirectory(inputDir);
|
|
200
|
+
|
|
201
|
+
console.log(`Found ${result.requirements.length} requirements`);
|
|
202
|
+
|
|
203
|
+
// Write output
|
|
204
|
+
fs.writeFileSync(outputFile, JSON.stringify(result, null, 2));
|
|
205
|
+
console.log('Output:', outputFile);
|
|
206
|
+
}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parse OpenSpec Changes to Unified Requirements
|
|
3
|
+
*
|
|
4
|
+
* This script extracts requirements from OpenSpec change proposals.
|
|
5
|
+
* Reads proposal.md, design.md, and tasks.md
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import fs from 'fs';
|
|
9
|
+
import path from 'path';
|
|
10
|
+
import matter from 'gray-matter';
|
|
11
|
+
import type { UnifiedRequirement, UnifiedRequirements } from '../types/unified-requirements';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Parse OpenSpec change directory
|
|
15
|
+
*/
|
|
16
|
+
export function parseOpenSpec(changeDir: string): UnifiedRequirements {
|
|
17
|
+
console.log('š Parsing OpenSpec change...');
|
|
18
|
+
console.log(' Input:', changeDir);
|
|
19
|
+
|
|
20
|
+
if (!fs.existsSync(changeDir)) {
|
|
21
|
+
throw new Error(`OpenSpec change directory not found: ${changeDir}`);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const changeId = path.basename(changeDir);
|
|
25
|
+
const requirements: UnifiedRequirement[] = [];
|
|
26
|
+
const keywords: string[] = [];
|
|
27
|
+
|
|
28
|
+
// Read proposal.md
|
|
29
|
+
const proposalPath = path.join(changeDir, 'proposal.md');
|
|
30
|
+
if (fs.existsSync(proposalPath)) {
|
|
31
|
+
const proposalContent = fs.readFileSync(proposalPath, 'utf-8');
|
|
32
|
+
const { data } = matter(proposalContent);
|
|
33
|
+
|
|
34
|
+
// Extract keywords from frontmatter
|
|
35
|
+
if (data.keywords && Array.isArray(data.keywords)) {
|
|
36
|
+
keywords.push(...data.keywords);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
console.log(' ā
Read proposal.md');
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Read tasks.md
|
|
43
|
+
const tasksPath = path.join(changeDir, 'tasks.md');
|
|
44
|
+
if (fs.existsSync(tasksPath)) {
|
|
45
|
+
const tasksContent = fs.readFileSync(tasksPath, 'utf-8');
|
|
46
|
+
const { data, content } = matter(tasksContent);
|
|
47
|
+
|
|
48
|
+
// Parse tasks from markdown
|
|
49
|
+
const taskMatches = content.matchAll(/^[-*]\s+\[([x\s])\]\s+(.+)$/gm);
|
|
50
|
+
|
|
51
|
+
let currentPhase = 0;
|
|
52
|
+
let lastTaskInPhase: string | null = null;
|
|
53
|
+
const phaseFirstTasks: Record<number, string> = {};
|
|
54
|
+
|
|
55
|
+
// First pass: extract all tasks
|
|
56
|
+
for (const match of taskMatches) {
|
|
57
|
+
const status = match[1] === 'x' ? 'done' : 'draft';
|
|
58
|
+
const title = match[2].trim();
|
|
59
|
+
const reqId = `REQ-${changeId.toUpperCase()}-${requirements.length + 1}`;
|
|
60
|
+
|
|
61
|
+
// Detect phase number from task title (e.g., "1.1", "2.1")
|
|
62
|
+
const phaseMatch = title.match(/^(\d+)\.(\d+)/);
|
|
63
|
+
const phase = phaseMatch ? parseInt(phaseMatch[1]) : 0;
|
|
64
|
+
const taskNum = phaseMatch ? parseInt(phaseMatch[2]) : 0;
|
|
65
|
+
|
|
66
|
+
// Track phase changes
|
|
67
|
+
if (phase !== currentPhase) {
|
|
68
|
+
currentPhase = phase;
|
|
69
|
+
lastTaskInPhase = null;
|
|
70
|
+
if (taskNum === 1) {
|
|
71
|
+
phaseFirstTasks[phase] = reqId;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Infer dependencies
|
|
76
|
+
const blockedBy: string[] = [];
|
|
77
|
+
|
|
78
|
+
// Rule 1: Sequential dependency within same phase
|
|
79
|
+
// Each task depends on the previous task in the same phase
|
|
80
|
+
if (lastTaskInPhase && taskNum > 1) {
|
|
81
|
+
blockedBy.push(lastTaskInPhase);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Rule 2: Phase dependency
|
|
85
|
+
// First task of each phase depends on last task of previous phase
|
|
86
|
+
if (taskNum === 1 && phase > 1 && requirements.length > 0) {
|
|
87
|
+
// Find last task of previous phase
|
|
88
|
+
for (let i = requirements.length - 1; i >= 0; i--) {
|
|
89
|
+
const prevReq = requirements[i];
|
|
90
|
+
const prevMatch = prevReq.title.match(/^(\d+)\.(\d+)/);
|
|
91
|
+
if (prevMatch && parseInt(prevMatch[1]) === phase - 1) {
|
|
92
|
+
blockedBy.push(prevReq.reqId);
|
|
93
|
+
break;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
requirements.push({
|
|
99
|
+
reqId,
|
|
100
|
+
title,
|
|
101
|
+
description: '',
|
|
102
|
+
source: 'openspec',
|
|
103
|
+
sourceFiles: [tasksPath],
|
|
104
|
+
type: 'task',
|
|
105
|
+
status,
|
|
106
|
+
acceptance: [],
|
|
107
|
+
tasks: [],
|
|
108
|
+
blockedBy,
|
|
109
|
+
blocks: [],
|
|
110
|
+
createdAt: new Date().toISOString(),
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
lastTaskInPhase = reqId;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
console.log(` ā
Read tasks.md (${requirements.length} tasks)`);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (keywords.length > 0) {
|
|
120
|
+
console.log(`\nš Found ${keywords.length} keywords from OpenSpec:`, keywords.join(', '));
|
|
121
|
+
} else {
|
|
122
|
+
console.log(`\nā ļø No keywords found in OpenSpec. Please add keywords to proposal.md frontmatter.`);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
return {
|
|
126
|
+
version: '1.0.0',
|
|
127
|
+
generatedAt: new Date().toISOString(),
|
|
128
|
+
sources: {
|
|
129
|
+
openspec: {
|
|
130
|
+
changeId,
|
|
131
|
+
files: ['proposal.md', 'design.md', 'tasks.md'],
|
|
132
|
+
extractedAt: new Date().toISOString(),
|
|
133
|
+
keywords,
|
|
134
|
+
},
|
|
135
|
+
},
|
|
136
|
+
requirements,
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* CLI entry point
|
|
142
|
+
*/
|
|
143
|
+
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
144
|
+
const args = process.argv.slice(2);
|
|
145
|
+
const inputDir = args[0];
|
|
146
|
+
const outputFile = args[1] || './exports/temp/requirements-from-openspec.json';
|
|
147
|
+
|
|
148
|
+
if (!inputDir) {
|
|
149
|
+
console.error('Usage: tsx parse-openspec.ts <openspec-change-dir> [output.json]');
|
|
150
|
+
console.error('');
|
|
151
|
+
console.error('Example:');
|
|
152
|
+
console.error(' tsx parse-openspec.ts openspec/changes/001-pricing-system/ output.json');
|
|
153
|
+
process.exit(1);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const result = parseOpenSpec(inputDir);
|
|
157
|
+
|
|
158
|
+
console.log(`\nFound ${result.requirements.length} requirements`);
|
|
159
|
+
|
|
160
|
+
// Write output
|
|
161
|
+
const outputDir = path.dirname(outputFile);
|
|
162
|
+
if (!fs.existsSync(outputDir)) {
|
|
163
|
+
fs.mkdirSync(outputDir, { recursive: true });
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
fs.writeFileSync(outputFile, JSON.stringify(result, null, 2));
|
|
167
|
+
console.log('Output:', outputFile);
|
|
168
|
+
}
|