@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,3 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2
+ <w:comments xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas" xmlns:cx="http://schemas.microsoft.com/office/drawing/2014/chartex" xmlns:cx1="http://schemas.microsoft.com/office/drawing/2015/9/8/chartex" xmlns:cx2="http://schemas.microsoft.com/office/drawing/2015/10/21/chartex" xmlns:cx3="http://schemas.microsoft.com/office/drawing/2016/5/9/chartex" xmlns:cx4="http://schemas.microsoft.com/office/drawing/2016/5/10/chartex" xmlns:cx5="http://schemas.microsoft.com/office/drawing/2016/5/11/chartex" xmlns:cx6="http://schemas.microsoft.com/office/drawing/2016/5/12/chartex" xmlns:cx7="http://schemas.microsoft.com/office/drawing/2016/5/13/chartex" xmlns:cx8="http://schemas.microsoft.com/office/drawing/2016/5/14/chartex" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:aink="http://schemas.microsoft.com/office/drawing/2016/ink" xmlns:am3d="http://schemas.microsoft.com/office/drawing/2017/model3d" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:oel="http://schemas.microsoft.com/office/2019/extlst" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" xmlns:w16cex="http://schemas.microsoft.com/office/word/2018/wordml/cex" xmlns:w16cid="http://schemas.microsoft.com/office/word/2016/wordml/cid" xmlns:w16="http://schemas.microsoft.com/office/word/2018/wordml" xmlns:w16du="http://schemas.microsoft.com/office/word/2023/wordml/word16du" xmlns:w16sdtdh="http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash" xmlns:w16sdtfl="http://schemas.microsoft.com/office/word/2024/wordml/sdtformatlock" xmlns:w16se="http://schemas.microsoft.com/office/word/2015/wordml/symex" xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml" xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape" mc:Ignorable="w14 w15 w16se w16cid w16 w16cex w16sdtdh w16sdtfl w16du wp14">
3
+ </w:comments>
@@ -0,0 +1,3 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2
+ <w15:commentsEx xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas" xmlns:cx="http://schemas.microsoft.com/office/drawing/2014/chartex" xmlns:cx1="http://schemas.microsoft.com/office/drawing/2015/9/8/chartex" xmlns:cx2="http://schemas.microsoft.com/office/drawing/2015/10/21/chartex" xmlns:cx3="http://schemas.microsoft.com/office/drawing/2016/5/9/chartex" xmlns:cx4="http://schemas.microsoft.com/office/drawing/2016/5/10/chartex" xmlns:cx5="http://schemas.microsoft.com/office/drawing/2016/5/11/chartex" xmlns:cx6="http://schemas.microsoft.com/office/drawing/2016/5/12/chartex" xmlns:cx7="http://schemas.microsoft.com/office/drawing/2016/5/13/chartex" xmlns:cx8="http://schemas.microsoft.com/office/drawing/2016/5/14/chartex" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:aink="http://schemas.microsoft.com/office/drawing/2016/ink" xmlns:am3d="http://schemas.microsoft.com/office/drawing/2017/model3d" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:oel="http://schemas.microsoft.com/office/2019/extlst" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" xmlns:w16cex="http://schemas.microsoft.com/office/word/2018/wordml/cex" xmlns:w16cid="http://schemas.microsoft.com/office/word/2016/wordml/cid" xmlns:w16="http://schemas.microsoft.com/office/word/2018/wordml" xmlns:w16du="http://schemas.microsoft.com/office/word/2023/wordml/word16du" xmlns:w16sdtdh="http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash" xmlns:w16sdtfl="http://schemas.microsoft.com/office/word/2024/wordml/sdtformatlock" xmlns:w16se="http://schemas.microsoft.com/office/word/2015/wordml/symex" xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml" xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape" mc:Ignorable="w14 w15 w16se w16cid w16 w16cex w16sdtdh w16sdtfl w16du wp14">
3
+ </w15:commentsEx>
@@ -0,0 +1,3 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2
+ <w16cex:commentsExtensible xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas" xmlns:cx="http://schemas.microsoft.com/office/drawing/2014/chartex" xmlns:cx1="http://schemas.microsoft.com/office/drawing/2015/9/8/chartex" xmlns:cx2="http://schemas.microsoft.com/office/drawing/2015/10/21/chartex" xmlns:cx3="http://schemas.microsoft.com/office/drawing/2016/5/9/chartex" xmlns:cx4="http://schemas.microsoft.com/office/drawing/2016/5/10/chartex" xmlns:cx5="http://schemas.microsoft.com/office/drawing/2016/5/11/chartex" xmlns:cx6="http://schemas.microsoft.com/office/drawing/2016/5/12/chartex" xmlns:cx7="http://schemas.microsoft.com/office/drawing/2016/5/13/chartex" xmlns:cx8="http://schemas.microsoft.com/office/drawing/2016/5/14/chartex" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:aink="http://schemas.microsoft.com/office/drawing/2016/ink" xmlns:am3d="http://schemas.microsoft.com/office/drawing/2017/model3d" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:oel="http://schemas.microsoft.com/office/2019/extlst" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" xmlns:w16cex="http://schemas.microsoft.com/office/word/2018/wordml/cex" xmlns:w16cid="http://schemas.microsoft.com/office/word/2016/wordml/cid" xmlns:w16="http://schemas.microsoft.com/office/word/2018/wordml" xmlns:w16du="http://schemas.microsoft.com/office/word/2023/wordml/word16du" xmlns:w16sdtdh="http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash" xmlns:w16sdtfl="http://schemas.microsoft.com/office/word/2024/wordml/sdtformatlock" xmlns:w16se="http://schemas.microsoft.com/office/word/2015/wordml/symex" xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml" xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape" xmlns:cr="http://schemas.microsoft.com/office/comments/2020/reactions" mc:Ignorable="w14 w15 w16se w16cid w16 w16cex w16sdtdh w16sdtfl cr w16du wp14">
3
+ </w16cex:commentsExtensible>
@@ -0,0 +1,3 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2
+ <w16cid:commentsIds xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas" xmlns:cx="http://schemas.microsoft.com/office/drawing/2014/chartex" xmlns:cx1="http://schemas.microsoft.com/office/drawing/2015/9/8/chartex" xmlns:cx2="http://schemas.microsoft.com/office/drawing/2015/10/21/chartex" xmlns:cx3="http://schemas.microsoft.com/office/drawing/2016/5/9/chartex" xmlns:cx4="http://schemas.microsoft.com/office/drawing/2016/5/10/chartex" xmlns:cx5="http://schemas.microsoft.com/office/drawing/2016/5/11/chartex" xmlns:cx6="http://schemas.microsoft.com/office/drawing/2016/5/12/chartex" xmlns:cx7="http://schemas.microsoft.com/office/drawing/2016/5/13/chartex" xmlns:cx8="http://schemas.microsoft.com/office/drawing/2016/5/14/chartex" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:aink="http://schemas.microsoft.com/office/drawing/2016/ink" xmlns:am3d="http://schemas.microsoft.com/office/drawing/2017/model3d" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:oel="http://schemas.microsoft.com/office/2019/extlst" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" xmlns:w16cex="http://schemas.microsoft.com/office/word/2018/wordml/cex" xmlns:w16cid="http://schemas.microsoft.com/office/word/2016/wordml/cid" xmlns:w16="http://schemas.microsoft.com/office/word/2018/wordml" xmlns:w16du="http://schemas.microsoft.com/office/word/2023/wordml/word16du" xmlns:w16sdtdh="http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash" xmlns:w16sdtfl="http://schemas.microsoft.com/office/word/2024/wordml/sdtformatlock" xmlns:w16se="http://schemas.microsoft.com/office/word/2015/wordml/symex" xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml" xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape" mc:Ignorable="w14 w15 w16se w16cid w16 w16cex w16sdtdh w16sdtfl w16du wp14">
3
+ </w16cid:commentsIds>
@@ -0,0 +1,3 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2
+ <w15:people xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml">
3
+ </w15:people>
@@ -0,0 +1,374 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Utilities for editing OOXML documents.
4
+
5
+ This module provides XMLEditor, a tool for manipulating XML files with support for
6
+ line-number-based node finding and DOM manipulation. Each element is automatically
7
+ annotated with its original line and column position during parsing.
8
+
9
+ Example usage:
10
+ editor = XMLEditor("document.xml")
11
+
12
+ # Find node by line number or range
13
+ elem = editor.get_node(tag="w:r", line_number=519)
14
+ elem = editor.get_node(tag="w:p", line_number=range(100, 200))
15
+
16
+ # Find node by text content
17
+ elem = editor.get_node(tag="w:p", contains="specific text")
18
+
19
+ # Find node by attributes
20
+ elem = editor.get_node(tag="w:r", attrs={"w:id": "target"})
21
+
22
+ # Combine filters
23
+ elem = editor.get_node(tag="w:p", line_number=range(1, 50), contains="text")
24
+
25
+ # Replace, insert, or manipulate
26
+ new_elem = editor.replace_node(elem, "<w:r><w:t>new text</w:t></w:r>")
27
+ editor.insert_after(new_elem, "<w:r><w:t>more</w:t></w:r>")
28
+
29
+ # Save changes
30
+ editor.save()
31
+ """
32
+
33
+ import html
34
+ from pathlib import Path
35
+ from typing import Optional, Union
36
+
37
+ import defusedxml.minidom
38
+ import defusedxml.sax
39
+
40
+
41
+ class XMLEditor:
42
+ """
43
+ Editor for manipulating OOXML XML files with line-number-based node finding.
44
+
45
+ This class parses XML files and tracks the original line and column position
46
+ of each element. This enables finding nodes by their line number in the original
47
+ file, which is useful when working with Read tool output.
48
+
49
+ Attributes:
50
+ xml_path: Path to the XML file being edited
51
+ encoding: Detected encoding of the XML file ('ascii' or 'utf-8')
52
+ dom: Parsed DOM tree with parse_position attributes on elements
53
+ """
54
+
55
+ def __init__(self, xml_path):
56
+ """
57
+ Initialize with path to XML file and parse with line number tracking.
58
+
59
+ Args:
60
+ xml_path: Path to XML file to edit (str or Path)
61
+
62
+ Raises:
63
+ ValueError: If the XML file does not exist
64
+ """
65
+ self.xml_path = Path(xml_path)
66
+ if not self.xml_path.exists():
67
+ raise ValueError(f"XML file not found: {xml_path}")
68
+
69
+ with open(self.xml_path, "rb") as f:
70
+ header = f.read(200).decode("utf-8", errors="ignore")
71
+ self.encoding = "ascii" if 'encoding="ascii"' in header else "utf-8"
72
+
73
+ parser = _create_line_tracking_parser()
74
+ self.dom = defusedxml.minidom.parse(str(self.xml_path), parser)
75
+
76
+ def get_node(
77
+ self,
78
+ tag: str,
79
+ attrs: Optional[dict[str, str]] = None,
80
+ line_number: Optional[Union[int, range]] = None,
81
+ contains: Optional[str] = None,
82
+ ):
83
+ """
84
+ Get a DOM element by tag and identifier.
85
+
86
+ Finds an element by either its line number in the original file or by
87
+ matching attribute values. Exactly one match must be found.
88
+
89
+ Args:
90
+ tag: The XML tag name (e.g., "w:del", "w:ins", "w:r")
91
+ attrs: Dictionary of attribute name-value pairs to match (e.g., {"w:id": "1"})
92
+ line_number: Line number (int) or line range (range) in original XML file (1-indexed)
93
+ contains: Text string that must appear in any text node within the element.
94
+ Supports both entity notation (&#8220;) and Unicode characters (\u201c).
95
+
96
+ Returns:
97
+ defusedxml.minidom.Element: The matching DOM element
98
+
99
+ Raises:
100
+ ValueError: If node not found or multiple matches found
101
+
102
+ Example:
103
+ elem = editor.get_node(tag="w:r", line_number=519)
104
+ elem = editor.get_node(tag="w:r", line_number=range(100, 200))
105
+ elem = editor.get_node(tag="w:del", attrs={"w:id": "1"})
106
+ elem = editor.get_node(tag="w:p", attrs={"w14:paraId": "12345678"})
107
+ elem = editor.get_node(tag="w:commentRangeStart", attrs={"w:id": "0"})
108
+ elem = editor.get_node(tag="w:p", contains="specific text")
109
+ elem = editor.get_node(tag="w:t", contains="&#8220;Agreement") # Entity notation
110
+ elem = editor.get_node(tag="w:t", contains="\u201cAgreement") # Unicode character
111
+ """
112
+ matches = []
113
+ for elem in self.dom.getElementsByTagName(tag):
114
+ # Check line_number filter
115
+ if line_number is not None:
116
+ parse_pos = getattr(elem, "parse_position", (None,))
117
+ elem_line = parse_pos[0]
118
+
119
+ # Handle both single line number and range
120
+ if isinstance(line_number, range):
121
+ if elem_line not in line_number:
122
+ continue
123
+ else:
124
+ if elem_line != line_number:
125
+ continue
126
+
127
+ # Check attrs filter
128
+ if attrs is not None:
129
+ if not all(
130
+ elem.getAttribute(attr_name) == attr_value
131
+ for attr_name, attr_value in attrs.items()
132
+ ):
133
+ continue
134
+
135
+ # Check contains filter
136
+ if contains is not None:
137
+ elem_text = self._get_element_text(elem)
138
+ # Normalize the search string: convert HTML entities to Unicode characters
139
+ # This allows searching for both "&#8220;Rowan" and ""Rowan"
140
+ normalized_contains = html.unescape(contains)
141
+ if normalized_contains not in elem_text:
142
+ continue
143
+
144
+ # If all applicable filters passed, this is a match
145
+ matches.append(elem)
146
+
147
+ if not matches:
148
+ # Build descriptive error message
149
+ filters = []
150
+ if line_number is not None:
151
+ line_str = (
152
+ f"lines {line_number.start}-{line_number.stop - 1}"
153
+ if isinstance(line_number, range)
154
+ else f"line {line_number}"
155
+ )
156
+ filters.append(f"at {line_str}")
157
+ if attrs is not None:
158
+ filters.append(f"with attributes {attrs}")
159
+ if contains is not None:
160
+ filters.append(f"containing '{contains}'")
161
+
162
+ filter_desc = " ".join(filters) if filters else ""
163
+ base_msg = f"Node not found: <{tag}> {filter_desc}".strip()
164
+
165
+ # Add helpful hint based on filters used
166
+ if contains:
167
+ hint = "Text may be split across elements or use different wording."
168
+ elif line_number:
169
+ hint = "Line numbers may have changed if document was modified."
170
+ elif attrs:
171
+ hint = "Verify attribute values are correct."
172
+ else:
173
+ hint = "Try adding filters (attrs, line_number, or contains)."
174
+
175
+ raise ValueError(f"{base_msg}. {hint}")
176
+ if len(matches) > 1:
177
+ raise ValueError(
178
+ f"Multiple nodes found: <{tag}>. "
179
+ f"Add more filters (attrs, line_number, or contains) to narrow the search."
180
+ )
181
+ return matches[0]
182
+
183
+ def _get_element_text(self, elem):
184
+ """
185
+ Recursively extract all text content from an element.
186
+
187
+ Skips text nodes that contain only whitespace (spaces, tabs, newlines),
188
+ which typically represent XML formatting rather than document content.
189
+
190
+ Args:
191
+ elem: defusedxml.minidom.Element to extract text from
192
+
193
+ Returns:
194
+ str: Concatenated text from all non-whitespace text nodes within the element
195
+ """
196
+ text_parts = []
197
+ for node in elem.childNodes:
198
+ if node.nodeType == node.TEXT_NODE:
199
+ # Skip whitespace-only text nodes (XML formatting)
200
+ if node.data.strip():
201
+ text_parts.append(node.data)
202
+ elif node.nodeType == node.ELEMENT_NODE:
203
+ text_parts.append(self._get_element_text(node))
204
+ return "".join(text_parts)
205
+
206
+ def replace_node(self, elem, new_content):
207
+ """
208
+ Replace a DOM element with new XML content.
209
+
210
+ Args:
211
+ elem: defusedxml.minidom.Element to replace
212
+ new_content: String containing XML to replace the node with
213
+
214
+ Returns:
215
+ List[defusedxml.minidom.Node]: All inserted nodes
216
+
217
+ Example:
218
+ new_nodes = editor.replace_node(old_elem, "<w:r><w:t>text</w:t></w:r>")
219
+ """
220
+ parent = elem.parentNode
221
+ nodes = self._parse_fragment(new_content)
222
+ for node in nodes:
223
+ parent.insertBefore(node, elem)
224
+ parent.removeChild(elem)
225
+ return nodes
226
+
227
+ def insert_after(self, elem, xml_content):
228
+ """
229
+ Insert XML content after a DOM element.
230
+
231
+ Args:
232
+ elem: defusedxml.minidom.Element to insert after
233
+ xml_content: String containing XML to insert
234
+
235
+ Returns:
236
+ List[defusedxml.minidom.Node]: All inserted nodes
237
+
238
+ Example:
239
+ new_nodes = editor.insert_after(elem, "<w:r><w:t>text</w:t></w:r>")
240
+ """
241
+ parent = elem.parentNode
242
+ next_sibling = elem.nextSibling
243
+ nodes = self._parse_fragment(xml_content)
244
+ for node in nodes:
245
+ if next_sibling:
246
+ parent.insertBefore(node, next_sibling)
247
+ else:
248
+ parent.appendChild(node)
249
+ return nodes
250
+
251
+ def insert_before(self, elem, xml_content):
252
+ """
253
+ Insert XML content before a DOM element.
254
+
255
+ Args:
256
+ elem: defusedxml.minidom.Element to insert before
257
+ xml_content: String containing XML to insert
258
+
259
+ Returns:
260
+ List[defusedxml.minidom.Node]: All inserted nodes
261
+
262
+ Example:
263
+ new_nodes = editor.insert_before(elem, "<w:r><w:t>text</w:t></w:r>")
264
+ """
265
+ parent = elem.parentNode
266
+ nodes = self._parse_fragment(xml_content)
267
+ for node in nodes:
268
+ parent.insertBefore(node, elem)
269
+ return nodes
270
+
271
+ def append_to(self, elem, xml_content):
272
+ """
273
+ Append XML content as a child of a DOM element.
274
+
275
+ Args:
276
+ elem: defusedxml.minidom.Element to append to
277
+ xml_content: String containing XML to append
278
+
279
+ Returns:
280
+ List[defusedxml.minidom.Node]: All inserted nodes
281
+
282
+ Example:
283
+ new_nodes = editor.append_to(elem, "<w:r><w:t>text</w:t></w:r>")
284
+ """
285
+ nodes = self._parse_fragment(xml_content)
286
+ for node in nodes:
287
+ elem.appendChild(node)
288
+ return nodes
289
+
290
+ def get_next_rid(self):
291
+ """Get the next available rId for relationships files."""
292
+ max_id = 0
293
+ for rel_elem in self.dom.getElementsByTagName("Relationship"):
294
+ rel_id = rel_elem.getAttribute("Id")
295
+ if rel_id.startswith("rId"):
296
+ try:
297
+ max_id = max(max_id, int(rel_id[3:]))
298
+ except ValueError:
299
+ pass
300
+ return f"rId{max_id + 1}"
301
+
302
+ def save(self):
303
+ """
304
+ Save the edited XML back to the file.
305
+
306
+ Serializes the DOM tree and writes it back to the original file path,
307
+ preserving the original encoding (ascii or utf-8).
308
+ """
309
+ content = self.dom.toxml(encoding=self.encoding)
310
+ self.xml_path.write_bytes(content)
311
+
312
+ def _parse_fragment(self, xml_content):
313
+ """
314
+ Parse XML fragment and return list of imported nodes.
315
+
316
+ Args:
317
+ xml_content: String containing XML fragment
318
+
319
+ Returns:
320
+ List of defusedxml.minidom.Node objects imported into this document
321
+
322
+ Raises:
323
+ AssertionError: If fragment contains no element nodes
324
+ """
325
+ # Extract namespace declarations from the root document element
326
+ root_elem = self.dom.documentElement
327
+ namespaces = []
328
+ if root_elem and root_elem.attributes:
329
+ for i in range(root_elem.attributes.length):
330
+ attr = root_elem.attributes.item(i)
331
+ if attr.name.startswith("xmlns"): # type: ignore
332
+ namespaces.append(f'{attr.name}="{attr.value}"') # type: ignore
333
+
334
+ ns_decl = " ".join(namespaces)
335
+ wrapper = f"<root {ns_decl}>{xml_content}</root>"
336
+ fragment_doc = defusedxml.minidom.parseString(wrapper)
337
+ nodes = [
338
+ self.dom.importNode(child, deep=True)
339
+ for child in fragment_doc.documentElement.childNodes # type: ignore
340
+ ]
341
+ elements = [n for n in nodes if n.nodeType == n.ELEMENT_NODE]
342
+ assert elements, "Fragment must contain at least one element"
343
+ return nodes
344
+
345
+
346
+ def _create_line_tracking_parser():
347
+ """
348
+ Create a SAX parser that tracks line and column numbers for each element.
349
+
350
+ Monkey patches the SAX content handler to store the current line and column
351
+ position from the underlying expat parser onto each element as a parse_position
352
+ attribute (line, column) tuple.
353
+
354
+ Returns:
355
+ defusedxml.sax.xmlreader.XMLReader: Configured SAX parser
356
+ """
357
+
358
+ def set_content_handler(dom_handler):
359
+ def startElementNS(name, tagName, attrs):
360
+ orig_start_cb(name, tagName, attrs)
361
+ cur_elem = dom_handler.elementStack[-1]
362
+ cur_elem.parse_position = (
363
+ parser._parser.CurrentLineNumber, # type: ignore
364
+ parser._parser.CurrentColumnNumber, # type: ignore
365
+ )
366
+
367
+ orig_start_cb = dom_handler.startElementNS
368
+ dom_handler.startElementNS = startElementNS
369
+ orig_set_content_handler(dom_handler)
370
+
371
+ parser = defusedxml.sax.make_parser()
372
+ orig_set_content_handler = parser.setContentHandler
373
+ parser.setContentHandler = set_content_handler # type: ignore
374
+ return parser
@@ -0,0 +1,170 @@
1
+ ---
2
+ name: git-branch-create
3
+ description: Create or switch to a git branch. Use when user wants to create branch, switch branch, start new feature, or checkout branch. Checks if branch exists locally or remotely, creates if needed, and pulls latest changes.
4
+ ---
5
+
6
+ # Git Branch Create
7
+
8
+ Create new branch or switch to existing branch with automatic handling.
9
+
10
+ ## Current status
11
+
12
+ !`git branch --show-current 2>/dev/null || echo "Not in a git repository"`
13
+
14
+ ## Core workflow
15
+
16
+ ### 1. Get branch name
17
+
18
+ Ask user: "What branch name?" (if not provided)
19
+
20
+ **Branch naming conventions** (suggest to user):
21
+ - `feature/description` - New features
22
+ - `fix/description` - Bug fixes
23
+ - `refactor/description` - Code refactoring
24
+ - `docs/description` - Documentation
25
+ - `chore/description` - Maintenance tasks
26
+
27
+ ### 2. Check if branch exists
28
+
29
+ ```bash
30
+ BRANCH_NAME="feature/auth"
31
+
32
+ # Check local branches
33
+ git branch --list "$BRANCH_NAME"
34
+
35
+ # Check remote branches
36
+ git branch -r --list "origin/$BRANCH_NAME"
37
+ ```
38
+
39
+ ### 3. Handle based on existence
40
+
41
+ #### Case A: Branch exists locally
42
+
43
+ ```bash
44
+ # Switch to existing branch
45
+ git checkout $BRANCH_NAME
46
+
47
+ # Pull latest changes
48
+ git pull origin $BRANCH_NAME 2>/dev/null || echo "No remote tracking branch"
49
+ ```
50
+
51
+ #### Case B: Branch exists remotely but not locally
52
+
53
+ ```bash
54
+ # Fetch remote branch
55
+ git fetch origin $BRANCH_NAME
56
+
57
+ # Create local branch tracking remote
58
+ git checkout -b $BRANCH_NAME origin/$BRANCH_NAME
59
+ ```
60
+
61
+ #### Case C: Branch doesn't exist anywhere
62
+
63
+ ```bash
64
+ # Create new branch from current branch
65
+ git checkout -b $BRANCH_NAME
66
+
67
+ # Push to remote and set upstream
68
+ git push -u origin $BRANCH_NAME
69
+ ```
70
+
71
+ ## Important rules
72
+
73
+ - **ALWAYS** check if branch exists before creating
74
+ - **ALWAYS** pull latest changes when switching to existing branch
75
+ - **NEVER** force create (overwrite) existing branches
76
+ - **NEVER** assume branch naming convention - let user decide
77
+ - If branch exists, inform user and switch to it (don't create duplicate)
78
+
79
+ ## Error handling
80
+
81
+ ### Uncommitted changes
82
+
83
+ If switching fails due to uncommitted changes:
84
+ ```bash
85
+ # Show uncommitted changes
86
+ git status --short
87
+ ```
88
+
89
+ **Action**:
90
+ 1. Inform user: "You have uncommitted changes"
91
+ 2. Ask: "Stash changes or commit them first?"
92
+ 3. If stash: `git stash`
93
+ 4. Retry checkout
94
+
95
+ ### Branch name conflicts
96
+
97
+ If branch name is invalid:
98
+ ```bash
99
+ # Git will show error like: "invalid branch name"
100
+ ```
101
+
102
+ **Action**: Ask user for a valid branch name (no spaces, special chars)
103
+
104
+ ### Remote doesn't exist
105
+
106
+ If remote push fails:
107
+ ```bash
108
+ # Check if remote exists
109
+ git remote -v
110
+ ```
111
+
112
+ **Action**: Inform user that remote doesn't exist or isn't configured
113
+
114
+ ## Examples
115
+
116
+ ### Create new feature branch
117
+ ```bash
118
+ # User: "Create branch feature/auth"
119
+
120
+ # Check if exists
121
+ git branch --list "feature/auth"
122
+
123
+ # If not exists, create
124
+ git checkout -b feature/auth
125
+ git push -u origin feature/auth
126
+ ```
127
+
128
+ ### Switch to existing branch
129
+ ```bash
130
+ # User: "Switch to feature/auth"
131
+
132
+ # Branch exists locally
133
+ git checkout feature/auth
134
+ git pull origin feature/auth
135
+ ```
136
+
137
+ ### Create from remote
138
+ ```bash
139
+ # User: "Checkout feature/auth"
140
+
141
+ # Branch exists on remote but not local
142
+ git fetch origin feature/auth
143
+ git checkout -b feature/auth origin/feature/auth
144
+ ```
145
+
146
+ ## Advanced: Create from specific base
147
+
148
+ If user specifies base branch:
149
+ ```bash
150
+ # User: "Create feature/auth from develop"
151
+
152
+ # Switch to base branch first
153
+ git checkout develop
154
+ git pull origin develop
155
+
156
+ # Create new branch
157
+ git checkout -b feature/auth
158
+
159
+ # Push to remote
160
+ git push -u origin feature/auth
161
+ ```
162
+
163
+ ## Notes
164
+
165
+ - Works in **current directory**
166
+ - No hardcoded paths or repository names
167
+ - Uses standard git commands
168
+ - Compatible with any git repository
169
+ - Handles local and remote branches automatically
170
+ - Suggests but doesn't enforce naming conventions