@fectivnfy112358/minimax-code-web 0.1.0-preview.0 → 0.1.0-preview.3

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 (656) hide show
  1. package/bin/mcode-webui.mjs +6 -2
  2. package/package.json +1 -1
  3. package/server/assets/agents/_default/prompt-base-all.md +121 -0
  4. package/server/assets/agents/_default/prompt-base-all.md.hbs +255 -0
  5. package/server/assets/agents/_default/prompt-base-windows.md +6 -0
  6. package/server/assets/agents/_default/prompt-base-windows.md.hbs +6 -0
  7. package/server/assets/agents/_default/prompt-base-worker.md +12 -0
  8. package/server/assets/agents/_default/prompt-base-worker.md.hbs +27 -0
  9. package/server/assets/agents/_default/prompt-session-branch.md +3 -0
  10. package/server/assets/agents/_default/prompt-session-branch.md.hbs +30 -0
  11. package/server/assets/agents/_default/prompt-session-root.md +4 -0
  12. package/server/assets/agents/_default/prompt-session-root.md.hbs +32 -0
  13. package/server/assets/agents/_migration/README.md +20 -0
  14. package/server/assets/agents/_migration/coder/PERSONA-zh.md +10 -0
  15. package/server/assets/agents/_migration/coder/PERSONA.md +11 -0
  16. package/server/assets/agents/_migration/coder/system-prompt.md.hbs +42 -0
  17. package/server/assets/agents/_migration/general/PERSONA-zh.md +11 -0
  18. package/server/assets/agents/_migration/general/PERSONA.md +11 -0
  19. package/server/assets/agents/_migration/general/system-prompt.md.hbs +49 -0
  20. package/server/assets/agents/_v2/AGENT_CONTEXT.md.hbs +222 -0
  21. package/server/assets/agents/_v2/coding/SYSTEM.md.hbs +161 -0
  22. package/server/assets/agents/_v2/explore.md.hbs +38 -0
  23. package/server/assets/agents/_v2/tui/SYSTEM.md.hbs +147 -0
  24. package/server/assets/agents/_v2/verifier.md.hbs +32 -0
  25. package/server/assets/agents/_v2/work/SYSTEM.md.hbs +173 -0
  26. package/server/assets/agents/_v2/worker.md.hbs +27 -0
  27. package/server/assets/agents/builtin-agents.json +1 -0
  28. package/server/assets/agents/desktop-task/archive-title/system-en.md +1 -0
  29. package/server/assets/agents/desktop-task/archive-title/system-zh.md +1 -0
  30. package/server/assets/agents/desktop-task/checkpoint/system.md +15 -0
  31. package/server/assets/agents/desktop-task/output-revision/system.md +1 -0
  32. package/server/assets/agents/desktop-task/retry/continuation.md +4 -0
  33. package/server/assets/agents/desktop-task/session-title/system.md +41 -0
  34. package/server/assets/agents/explore/PERSONA-zh.md +8 -0
  35. package/server/assets/agents/explore/PERSONA.md +8 -0
  36. package/server/assets/agents/explore/agent.md +14 -0
  37. package/server/assets/agents/explore/system-prompt.md.hbs +35 -0
  38. package/server/assets/agents/greeting-zh.md +61 -0
  39. package/server/assets/agents/greeting.md +61 -0
  40. package/server/assets/agents/managed-prompts.json +54 -0
  41. package/server/assets/agents/mavis/PERSONA-zh.md +7 -0
  42. package/server/assets/agents/mavis/PERSONA.md +7 -0
  43. package/server/assets/agents/mavis/features/cron.md.hbs +23 -0
  44. package/server/assets/agents/mavis/features/delegation.md.hbs +56 -0
  45. package/server/assets/agents/mavis/features/memory.md.hbs +61 -0
  46. package/server/assets/agents/mavis/features/recoverable-deletion.md.hbs +10 -0
  47. package/server/assets/agents/mavis/features/task-management.md.hbs +11 -0
  48. package/server/assets/agents/mavis/features/web-search.md.hbs +11 -0
  49. package/server/assets/agents/mavis/modes/coding/online/PERSONA-zh.md.hbs +20 -0
  50. package/server/assets/agents/mavis/modes/coding/online/PERSONA.md.hbs +20 -0
  51. package/server/assets/agents/mavis/modes/coding/online/SYSTEM.md.hbs +159 -0
  52. package/server/assets/agents/mavis/modes/work/online/PERSONA-zh.md.hbs +20 -0
  53. package/server/assets/agents/mavis/modes/work/online/PERSONA.md.hbs +20 -0
  54. package/server/assets/agents/mavis/modes/work/online/SYSTEM.md.hbs +161 -0
  55. package/server/assets/agents/mavis/prompt-session-root.md +4 -0
  56. package/server/assets/agents/mavis/prompt-session-root.md.hbs +4 -0
  57. package/server/assets/agents/mavis/skills/control-in-app-browser/SKILL.md +491 -0
  58. package/server/assets/agents/mavis/skills/minimax-code-product/SKILL.md +114 -0
  59. package/server/assets/agents/mavis/skills/minimax-code-product/references/account-models.md +32 -0
  60. package/server/assets/agents/mavis/skills/minimax-code-product/references/agents.md +25 -0
  61. package/server/assets/agents/mavis/skills/minimax-code-product/references/extensions.md +33 -0
  62. package/server/assets/agents/mavis/skills/minimax-code-product/references/workflows.md +30 -0
  63. package/server/assets/agents/mavis/system-prompt.md.hbs +97 -0
  64. package/server/assets/agents/prompt-exemptions.json +38 -0
  65. package/server/assets/agents/verifier/PERSONA-zh.md +8 -0
  66. package/server/assets/agents/verifier/PERSONA.md +8 -0
  67. package/server/assets/agents/verifier/agent.md +17 -0
  68. package/server/assets/agents/verifier/system-prompt.md.hbs +28 -0
  69. package/server/assets/agents/worker/PERSONA-zh.md +8 -0
  70. package/server/assets/agents/worker/PERSONA.md +8 -0
  71. package/server/assets/agents/worker/agent.md +18 -0
  72. package/server/assets/agents/worker/system-prompt.md.hbs +22 -0
  73. package/server/assets/agents/workflow/code-review/review-candidates.md +120 -0
  74. package/server/assets/agents/workflow/code-review/reviewer-system.md +75 -0
  75. package/server/assets/agents/workflow/goal/budget-limit.md +16 -0
  76. package/server/assets/agents/workflow/goal/continuation.md +62 -0
  77. package/server/assets/agents/workflow/goal/objective-updated.md +16 -0
  78. package/server/assets/agents/workflow/goal/recovery-terminal-audit.md +12 -0
  79. package/server/assets/agents/workflow/goal/recovery.md +11 -0
  80. package/server/assets/agents/workflow/goal/terminal-audit.md +9 -0
  81. package/server/assets/agents/workflow/plan-mode/agent-entry.md +72 -0
  82. package/server/assets/agents/workflow/prompt-hook/system.md +0 -0
  83. package/server/assets/models-dev-catalog.json.gz +0 -0
  84. package/server/assets/prompts/code-review/review-candidates.md +120 -0
  85. package/server/assets/prompts/code-review/reviewer-system.md +75 -0
  86. package/server/assets/skills/code-review/SKILL.md +51 -0
  87. package/server/assets/skills/cu-desktop/SKILL.md +257 -0
  88. package/server/assets/skills/deep-research/SKILL.md +219 -0
  89. package/server/assets/skills/deep-research/scripts/render_plan.py +33 -0
  90. package/server/assets/skills/deep-research/steps/1_background.md +65 -0
  91. package/server/assets/skills/deep-research/steps/2_judgment.md +66 -0
  92. package/server/assets/skills/deep-research/steps/3_analysis.md +114 -0
  93. package/server/assets/skills/deep-research/steps/4_research.md +161 -0
  94. package/server/assets/skills/deep-research/steps/5_writing.md +358 -0
  95. package/server/assets/skills/deploy-website/SKILL.md +55 -0
  96. package/server/assets/skills/docx/LICENSE +21 -0
  97. package/server/assets/skills/docx/SKILL.md +261 -0
  98. package/server/assets/skills/docx/assets/styles/academic_styles.xml +250 -0
  99. package/server/assets/skills/docx/assets/styles/corporate_styles.xml +284 -0
  100. package/server/assets/skills/docx/assets/styles/default_styles.xml +449 -0
  101. package/server/assets/skills/docx/assets/xsd/aesthetic-rules.xsd +470 -0
  102. package/server/assets/skills/docx/assets/xsd/business-rules.xsd +130 -0
  103. package/server/assets/skills/docx/assets/xsd/common-types.xsd +159 -0
  104. package/server/assets/skills/docx/assets/xsd/wml-subset.xsd +589 -0
  105. package/server/assets/skills/docx/docs/acceptance-checklists/create.md +7 -0
  106. package/server/assets/skills/docx/docs/acceptance-checklists/edit.md +6 -0
  107. package/server/assets/skills/docx/docs/acceptance-checklists/layout-repair.md +7 -0
  108. package/server/assets/skills/docx/docs/acceptance-checklists/template.md +6 -0
  109. package/server/assets/skills/docx/docs/acceptance.md +139 -0
  110. package/server/assets/skills/docx/docs/anti-patterns.md +14 -0
  111. package/server/assets/skills/docx/docs/backends.md +116 -0
  112. package/server/assets/skills/docx/docs/evidence.md +73 -0
  113. package/server/assets/skills/docx/docs/failure-taxonomy.md +71 -0
  114. package/server/assets/skills/docx/docs/index.md +50 -0
  115. package/server/assets/skills/docx/docs/rendered-delivery.md +125 -0
  116. package/server/assets/skills/docx/docs/router.md +122 -0
  117. package/server/assets/skills/docx/docs/tables-and-numbering.md +27 -0
  118. package/server/assets/skills/docx/docs/task-apply-template.md +141 -0
  119. package/server/assets/skills/docx/docs/task-compare-two-docx.md +48 -0
  120. package/server/assets/skills/docx/docs/task-create.md +124 -0
  121. package/server/assets/skills/docx/docs/task-edit-fill.md +69 -0
  122. package/server/assets/skills/docx/docs/task-read-content.md +148 -0
  123. package/server/assets/skills/docx/docs/task-read-rendered.md +78 -0
  124. package/server/assets/skills/docx/docs/task-read-structure.md +93 -0
  125. package/server/assets/skills/docx/docs/task-repair-layout.md +70 -0
  126. package/server/assets/skills/docx/docs/template-dsl.md +32 -0
  127. package/server/assets/skills/docx/docs/track-changes.md +15 -0
  128. package/server/assets/skills/docx/docs/xml-patch-dsl.md +33 -0
  129. package/server/assets/skills/docx/references/cjk_typography.md +357 -0
  130. package/server/assets/skills/docx/references/cjk_university_template_guide.md +184 -0
  131. package/server/assets/skills/docx/references/comments_guide.md +191 -0
  132. package/server/assets/skills/docx/references/design_good_bad_examples.md +829 -0
  133. package/server/assets/skills/docx/references/design_principles.md +819 -0
  134. package/server/assets/skills/docx/references/openxml_element_order.md +308 -0
  135. package/server/assets/skills/docx/references/openxml_encyclopedia_part1.md +4061 -0
  136. package/server/assets/skills/docx/references/openxml_encyclopedia_part2.md +2820 -0
  137. package/server/assets/skills/docx/references/openxml_encyclopedia_part3.md +3381 -0
  138. package/server/assets/skills/docx/references/openxml_namespaces.md +82 -0
  139. package/server/assets/skills/docx/references/openxml_units.md +72 -0
  140. package/server/assets/skills/docx/references/sample-patch-plans.json +22 -0
  141. package/server/assets/skills/docx/references/sample-task-intents.json +5 -0
  142. package/server/assets/skills/docx/references/sample-template-manifests.json +21 -0
  143. package/server/assets/skills/docx/references/scenario_a_create.md +284 -0
  144. package/server/assets/skills/docx/references/scenario_b_edit_content.md +295 -0
  145. package/server/assets/skills/docx/references/scenario_c_apply_template.md +456 -0
  146. package/server/assets/skills/docx/references/track_changes_guide.md +200 -0
  147. package/server/assets/skills/docx/references/troubleshooting.md +506 -0
  148. package/server/assets/skills/docx/references/typography_guide.md +294 -0
  149. package/server/assets/skills/docx/references/xsd_validation_guide.md +158 -0
  150. package/server/assets/skills/docx/scripts/build_patch_plan.py +29 -0
  151. package/server/assets/skills/docx/scripts/diff_docx_structure.py +61 -0
  152. package/server/assets/skills/docx/scripts/doc_to_docx.ps1 +85 -0
  153. package/server/assets/skills/docx/scripts/doc_to_docx.sh +40 -0
  154. package/server/assets/skills/docx/scripts/docx_preview.ps1 +76 -0
  155. package/server/assets/skills/docx/scripts/docx_preview.sh +37 -0
  156. package/server/assets/skills/docx/scripts/docx_to_pdf.py +87 -0
  157. package/server/assets/skills/docx/scripts/dotnet/MiniMaxAIDocx.Cli/MiniMaxAIDocx.Cli.csproj +19 -0
  158. package/server/assets/skills/docx/scripts/dotnet/MiniMaxAIDocx.Cli/Program.cs +18 -0
  159. package/server/assets/skills/docx/scripts/dotnet/MiniMaxAIDocx.Core/Commands/AnalyzeCommand.cs +147 -0
  160. package/server/assets/skills/docx/scripts/dotnet/MiniMaxAIDocx.Core/Commands/ApplyTemplateCommand.cs +322 -0
  161. package/server/assets/skills/docx/scripts/dotnet/MiniMaxAIDocx.Core/Commands/CreateCommand.cs +324 -0
  162. package/server/assets/skills/docx/scripts/dotnet/MiniMaxAIDocx.Core/Commands/DiffCommand.cs +155 -0
  163. package/server/assets/skills/docx/scripts/dotnet/MiniMaxAIDocx.Core/Commands/EditContentCommand.cs +487 -0
  164. package/server/assets/skills/docx/scripts/dotnet/MiniMaxAIDocx.Core/Commands/FixOrderCommand.cs +108 -0
  165. package/server/assets/skills/docx/scripts/dotnet/MiniMaxAIDocx.Core/Commands/MergeRunsCommand.cs +122 -0
  166. package/server/assets/skills/docx/scripts/dotnet/MiniMaxAIDocx.Core/Commands/ValidateCommand.cs +107 -0
  167. package/server/assets/skills/docx/scripts/dotnet/MiniMaxAIDocx.Core/MiniMaxAIDocx.Core.csproj +15 -0
  168. package/server/assets/skills/docx/scripts/dotnet/MiniMaxAIDocx.Core/OpenXml/CommentSynchronizer.cs +169 -0
  169. package/server/assets/skills/docx/scripts/dotnet/MiniMaxAIDocx.Core/OpenXml/ElementOrder.cs +80 -0
  170. package/server/assets/skills/docx/scripts/dotnet/MiniMaxAIDocx.Core/OpenXml/NamespaceConstants.cs +42 -0
  171. package/server/assets/skills/docx/scripts/dotnet/MiniMaxAIDocx.Core/OpenXml/RunMerger.cs +81 -0
  172. package/server/assets/skills/docx/scripts/dotnet/MiniMaxAIDocx.Core/OpenXml/StyleAnalyzer.cs +81 -0
  173. package/server/assets/skills/docx/scripts/dotnet/MiniMaxAIDocx.Core/OpenXml/TrackChangesHelper.cs +99 -0
  174. package/server/assets/skills/docx/scripts/dotnet/MiniMaxAIDocx.Core/OpenXml/UnitConverter.cs +23 -0
  175. package/server/assets/skills/docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/AestheticRecipeSamples.cs +1832 -0
  176. package/server/assets/skills/docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/AestheticRecipeSamples_Batch1.cs +910 -0
  177. package/server/assets/skills/docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/AestheticRecipeSamples_Batch2.cs +999 -0
  178. package/server/assets/skills/docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/AestheticRecipeSamples_Batch3.cs +1048 -0
  179. package/server/assets/skills/docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/AestheticRecipeSamples_Batch4.cs +1038 -0
  180. package/server/assets/skills/docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/CharacterFormattingSamples.cs +1020 -0
  181. package/server/assets/skills/docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/DocumentCreationSamples.cs +1121 -0
  182. package/server/assets/skills/docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/FieldAndTocSamples.cs +624 -0
  183. package/server/assets/skills/docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/FootnoteAndCommentSamples.cs +675 -0
  184. package/server/assets/skills/docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/HeaderFooterSamples.cs +838 -0
  185. package/server/assets/skills/docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/ImageSamples.cs +917 -0
  186. package/server/assets/skills/docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/ListAndNumberingSamples.cs +826 -0
  187. package/server/assets/skills/docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/ParagraphFormattingSamples.cs +1199 -0
  188. package/server/assets/skills/docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/StyleSystemSamples.cs +1487 -0
  189. package/server/assets/skills/docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/TableSamples.cs +1163 -0
  190. package/server/assets/skills/docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/TrackChangesSamples.cs +595 -0
  191. package/server/assets/skills/docx/scripts/dotnet/MiniMaxAIDocx.Core/Typography/CjkHelper.cs +39 -0
  192. package/server/assets/skills/docx/scripts/dotnet/MiniMaxAIDocx.Core/Typography/FontDefaults.cs +24 -0
  193. package/server/assets/skills/docx/scripts/dotnet/MiniMaxAIDocx.Core/Typography/PageSizes.cs +20 -0
  194. package/server/assets/skills/docx/scripts/dotnet/MiniMaxAIDocx.Core/Validation/BusinessRuleValidator.cs +224 -0
  195. package/server/assets/skills/docx/scripts/dotnet/MiniMaxAIDocx.Core/Validation/GateCheckValidator.cs +148 -0
  196. package/server/assets/skills/docx/scripts/dotnet/MiniMaxAIDocx.Core/Validation/ValidationResult.cs +23 -0
  197. package/server/assets/skills/docx/scripts/dotnet/MiniMaxAIDocx.Core/Validation/XsdValidator.cs +69 -0
  198. package/server/assets/skills/docx/scripts/dotnet/MiniMaxAIDocx.slnx +4 -0
  199. package/server/assets/skills/docx/scripts/env_check.ps1 +327 -0
  200. package/server/assets/skills/docx/scripts/env_check.sh +340 -0
  201. package/server/assets/skills/docx/scripts/extract_docx_text.py +1075 -0
  202. package/server/assets/skills/docx/scripts/pack_docx.py +31 -0
  203. package/server/assets/skills/docx/scripts/read_docx_structure.py +1032 -0
  204. package/server/assets/skills/docx/scripts/render_docx_pages.py +147 -0
  205. package/server/assets/skills/docx/scripts/rendered_report.py +609 -0
  206. package/server/assets/skills/docx/scripts/setup.ps1 +542 -0
  207. package/server/assets/skills/docx/scripts/setup.sh +537 -0
  208. package/server/assets/skills/docx/scripts/unpack_docx.py +29 -0
  209. package/server/assets/skills/docx/scripts/validate_template_manifest.py +60 -0
  210. package/server/assets/skills/docx/scripts/verify_anchor_atomicity.py +87 -0
  211. package/server/assets/skills/edit-deployed-website/SKILL.md +27 -0
  212. package/server/assets/skills/init/SKILL.md +137 -0
  213. package/server/assets/skills/lark-tools/SKILL.md +321 -0
  214. package/server/assets/skills/lark-tools/cli-skills/lark-approval/SKILL.md +48 -0
  215. package/server/assets/skills/lark-tools/cli-skills/lark-attendance/SKILL.md +57 -0
  216. package/server/assets/skills/lark-tools/cli-skills/lark-base/SKILL.md +372 -0
  217. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/dashboard-block-data-config.md +350 -0
  218. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/examples.md +130 -0
  219. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/formula-field-guide.md +735 -0
  220. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-advperm-disable.md +83 -0
  221. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-advperm-enable.md +80 -0
  222. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-base-copy.md +74 -0
  223. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-base-create.md +68 -0
  224. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-base-get.md +39 -0
  225. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-dashboard-arrange.md +83 -0
  226. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-dashboard-block-create.md +108 -0
  227. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-dashboard-block-delete.md +46 -0
  228. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-dashboard-block-get.md +57 -0
  229. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-dashboard-block-list.md +53 -0
  230. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-dashboard-block-update.md +84 -0
  231. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-dashboard-create.md +73 -0
  232. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-dashboard-delete.md +44 -0
  233. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-dashboard-get.md +59 -0
  234. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-dashboard-list.md +52 -0
  235. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-dashboard-update.md +69 -0
  236. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-dashboard.md +240 -0
  237. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-data-query.md +375 -0
  238. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-field-create.md +104 -0
  239. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-field-delete.md +51 -0
  240. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-field-get.md +42 -0
  241. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-field-list.md +44 -0
  242. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-field-search-options.md +48 -0
  243. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-field-update.md +97 -0
  244. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-field.md +22 -0
  245. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-form-create.md +87 -0
  246. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-form-delete.md +64 -0
  247. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-form-get.md +68 -0
  248. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-form-list.md +73 -0
  249. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-form-questions-create.md +118 -0
  250. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-form-questions-delete.md +68 -0
  251. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-form-questions-list.md +84 -0
  252. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-form-questions-update.md +92 -0
  253. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-form-questions.md +23 -0
  254. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-form-update.md +82 -0
  255. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-form.md +24 -0
  256. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-history.md +16 -0
  257. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-record-batch-create.md +76 -0
  258. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-record-batch-update.md +71 -0
  259. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-record-delete.md +51 -0
  260. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-record-get.md +38 -0
  261. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-record-history-list.md +86 -0
  262. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-record-list.md +83 -0
  263. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-record-search.md +72 -0
  264. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-record-upload-attachment.md +51 -0
  265. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-record-upsert.md +89 -0
  266. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-record.md +28 -0
  267. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-role-create.md +89 -0
  268. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-role-delete.md +83 -0
  269. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-role-get.md +87 -0
  270. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-role-list.md +81 -0
  271. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-role-update.md +94 -0
  272. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-shortcut-field-properties.md +679 -0
  273. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-shortcut-record-value.md +200 -0
  274. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-table-create.md +62 -0
  275. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-table-delete.md +51 -0
  276. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-table-get.md +46 -0
  277. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-table-list.md +43 -0
  278. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-table-update.md +49 -0
  279. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-table.md +20 -0
  280. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-view-create.md +83 -0
  281. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-view-delete.md +48 -0
  282. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-view-get-card.md +38 -0
  283. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-view-get-filter.md +38 -0
  284. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-view-get-group.md +38 -0
  285. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-view-get-sort.md +38 -0
  286. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-view-get-timebar.md +38 -0
  287. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-view-get-visible-fields.md +38 -0
  288. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-view-get.md +38 -0
  289. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-view-list.md +44 -0
  290. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-view-rename.md +44 -0
  291. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-view-set-card.md +81 -0
  292. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-view-set-filter.md +92 -0
  293. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-view-set-group.md +77 -0
  294. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-view-set-sort.md +77 -0
  295. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-view-set-timebar.md +79 -0
  296. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-view-set-visible-fields.md +73 -0
  297. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-view.md +44 -0
  298. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-workflow-create.md +180 -0
  299. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-workflow-disable.md +94 -0
  300. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-workflow-enable.md +94 -0
  301. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-workflow-get.md +147 -0
  302. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-workflow-guide.md +718 -0
  303. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-workflow-list.md +123 -0
  304. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-workflow-schema.md +935 -0
  305. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-workflow-update.md +167 -0
  306. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-workflow.md +23 -0
  307. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lark-base-workspace.md +18 -0
  308. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/lookup-field-guide.md +508 -0
  309. package/server/assets/skills/lark-tools/cli-skills/lark-base/references/role-config.md +532 -0
  310. package/server/assets/skills/lark-tools/cli-skills/lark-calendar/SKILL.md +143 -0
  311. package/server/assets/skills/lark-tools/cli-skills/lark-calendar/references/lark-calendar-agenda.md +78 -0
  312. package/server/assets/skills/lark-tools/cli-skills/lark-calendar/references/lark-calendar-create.md +109 -0
  313. package/server/assets/skills/lark-tools/cli-skills/lark-calendar/references/lark-calendar-freebusy.md +124 -0
  314. package/server/assets/skills/lark-tools/cli-skills/lark-calendar/references/lark-calendar-room-find.md +89 -0
  315. package/server/assets/skills/lark-tools/cli-skills/lark-calendar/references/lark-calendar-rsvp.md +42 -0
  316. package/server/assets/skills/lark-tools/cli-skills/lark-calendar/references/lark-calendar-schedule-meeting.md +194 -0
  317. package/server/assets/skills/lark-tools/cli-skills/lark-calendar/references/lark-calendar-suggestion.md +125 -0
  318. package/server/assets/skills/lark-tools/cli-skills/lark-contact/SKILL.md +23 -0
  319. package/server/assets/skills/lark-tools/cli-skills/lark-contact/references/lark-contact-get-user.md +47 -0
  320. package/server/assets/skills/lark-tools/cli-skills/lark-contact/references/lark-contact-search-user.md +39 -0
  321. package/server/assets/skills/lark-tools/cli-skills/lark-doc/SKILL.md +189 -0
  322. package/server/assets/skills/lark-tools/cli-skills/lark-doc/references/lark-doc-create.md +673 -0
  323. package/server/assets/skills/lark-tools/cli-skills/lark-doc/references/lark-doc-fetch.md +120 -0
  324. package/server/assets/skills/lark-tools/cli-skills/lark-doc/references/lark-doc-media-download.md +50 -0
  325. package/server/assets/skills/lark-tools/cli-skills/lark-doc/references/lark-doc-media-insert.md +51 -0
  326. package/server/assets/skills/lark-tools/cli-skills/lark-doc/references/lark-doc-media-preview.md +41 -0
  327. package/server/assets/skills/lark-tools/cli-skills/lark-doc/references/lark-doc-search.md +213 -0
  328. package/server/assets/skills/lark-tools/cli-skills/lark-doc/references/lark-doc-update.md +264 -0
  329. package/server/assets/skills/lark-tools/cli-skills/lark-doc/references/lark-doc-whiteboard-update.md +6 -0
  330. package/server/assets/skills/lark-tools/cli-skills/lark-drive/SKILL.md +294 -0
  331. package/server/assets/skills/lark-tools/cli-skills/lark-drive/references/lark-drive-add-comment.md +99 -0
  332. package/server/assets/skills/lark-tools/cli-skills/lark-drive/references/lark-drive-create-folder.md +73 -0
  333. package/server/assets/skills/lark-tools/cli-skills/lark-drive/references/lark-drive-create-shortcut.md +103 -0
  334. package/server/assets/skills/lark-tools/cli-skills/lark-drive/references/lark-drive-delete.md +79 -0
  335. package/server/assets/skills/lark-tools/cli-skills/lark-drive/references/lark-drive-download.md +31 -0
  336. package/server/assets/skills/lark-tools/cli-skills/lark-drive/references/lark-drive-export-download.md +50 -0
  337. package/server/assets/skills/lark-tools/cli-skills/lark-drive/references/lark-drive-export.md +100 -0
  338. package/server/assets/skills/lark-tools/cli-skills/lark-drive/references/lark-drive-import.md +132 -0
  339. package/server/assets/skills/lark-tools/cli-skills/lark-drive/references/lark-drive-move.md +120 -0
  340. package/server/assets/skills/lark-tools/cli-skills/lark-drive/references/lark-drive-reactions.md +113 -0
  341. package/server/assets/skills/lark-tools/cli-skills/lark-drive/references/lark-drive-task-result.md +264 -0
  342. package/server/assets/skills/lark-tools/cli-skills/lark-drive/references/lark-drive-upload.md +67 -0
  343. package/server/assets/skills/lark-tools/cli-skills/lark-event/SKILL.md +21 -0
  344. package/server/assets/skills/lark-tools/cli-skills/lark-event/references/lark-event-subscribe.md +217 -0
  345. package/server/assets/skills/lark-tools/cli-skills/lark-im/SKILL.md +140 -0
  346. package/server/assets/skills/lark-tools/cli-skills/lark-im/references/lark-im-chat-create.md +156 -0
  347. package/server/assets/skills/lark-tools/cli-skills/lark-im/references/lark-im-chat-identity.md +55 -0
  348. package/server/assets/skills/lark-tools/cli-skills/lark-im/references/lark-im-chat-messages-list.md +142 -0
  349. package/server/assets/skills/lark-tools/cli-skills/lark-im/references/lark-im-chat-search.md +114 -0
  350. package/server/assets/skills/lark-tools/cli-skills/lark-im/references/lark-im-chat-update.md +84 -0
  351. package/server/assets/skills/lark-tools/cli-skills/lark-im/references/lark-im-messages-mget.md +95 -0
  352. package/server/assets/skills/lark-tools/cli-skills/lark-im/references/lark-im-messages-reply.md +222 -0
  353. package/server/assets/skills/lark-tools/cli-skills/lark-im/references/lark-im-messages-resources-download.md +94 -0
  354. package/server/assets/skills/lark-tools/cli-skills/lark-im/references/lark-im-messages-search.md +213 -0
  355. package/server/assets/skills/lark-tools/cli-skills/lark-im/references/lark-im-messages-send.md +223 -0
  356. package/server/assets/skills/lark-tools/cli-skills/lark-im/references/lark-im-reactions.md +297 -0
  357. package/server/assets/skills/lark-tools/cli-skills/lark-im/references/lark-im-threads-messages-list.md +111 -0
  358. package/server/assets/skills/lark-tools/cli-skills/lark-mail/SKILL.md +550 -0
  359. package/server/assets/skills/lark-tools/cli-skills/lark-mail/references/lark-mail-draft-create.md +110 -0
  360. package/server/assets/skills/lark-tools/cli-skills/lark-mail/references/lark-mail-draft-edit.md +376 -0
  361. package/server/assets/skills/lark-tools/cli-skills/lark-mail/references/lark-mail-forward.md +208 -0
  362. package/server/assets/skills/lark-tools/cli-skills/lark-mail/references/lark-mail-message.md +201 -0
  363. package/server/assets/skills/lark-tools/cli-skills/lark-mail/references/lark-mail-messages.md +108 -0
  364. package/server/assets/skills/lark-tools/cli-skills/lark-mail/references/lark-mail-reply-all.md +184 -0
  365. package/server/assets/skills/lark-tools/cli-skills/lark-mail/references/lark-mail-reply.md +220 -0
  366. package/server/assets/skills/lark-tools/cli-skills/lark-mail/references/lark-mail-send.md +178 -0
  367. package/server/assets/skills/lark-tools/cli-skills/lark-mail/references/lark-mail-signature.md +98 -0
  368. package/server/assets/skills/lark-tools/cli-skills/lark-mail/references/lark-mail-thread.md +111 -0
  369. package/server/assets/skills/lark-tools/cli-skills/lark-mail/references/lark-mail-triage.md +122 -0
  370. package/server/assets/skills/lark-tools/cli-skills/lark-mail/references/lark-mail-watch.md +94 -0
  371. package/server/assets/skills/lark-tools/cli-skills/lark-minutes/SKILL.md +116 -0
  372. package/server/assets/skills/lark-tools/cli-skills/lark-minutes/references/lark-minutes-download.md +119 -0
  373. package/server/assets/skills/lark-tools/cli-skills/lark-minutes/references/lark-minutes-search.md +180 -0
  374. package/server/assets/skills/lark-tools/cli-skills/lark-openapi-explorer/SKILL.md +153 -0
  375. package/server/assets/skills/lark-tools/cli-skills/lark-shared/SKILL.md +141 -0
  376. package/server/assets/skills/lark-tools/cli-skills/lark-sheets/SKILL.md +262 -0
  377. package/server/assets/skills/lark-tools/cli-skills/lark-sheets/references/lark-sheets-add-dimension.md +51 -0
  378. package/server/assets/skills/lark-tools/cli-skills/lark-sheets/references/lark-sheets-append.md +56 -0
  379. package/server/assets/skills/lark-tools/cli-skills/lark-sheets/references/lark-sheets-batch-set-style.md +53 -0
  380. package/server/assets/skills/lark-tools/cli-skills/lark-sheets/references/lark-sheets-create-filter-view-condition.md +42 -0
  381. package/server/assets/skills/lark-tools/cli-skills/lark-sheets/references/lark-sheets-create-filter-view.md +42 -0
  382. package/server/assets/skills/lark-tools/cli-skills/lark-sheets/references/lark-sheets-create.md +69 -0
  383. package/server/assets/skills/lark-tools/cli-skills/lark-sheets/references/lark-sheets-delete-dimension.md +53 -0
  384. package/server/assets/skills/lark-tools/cli-skills/lark-sheets/references/lark-sheets-delete-dropdown.md +46 -0
  385. package/server/assets/skills/lark-tools/cli-skills/lark-sheets/references/lark-sheets-delete-filter-view-condition.md +26 -0
  386. package/server/assets/skills/lark-tools/cli-skills/lark-sheets/references/lark-sheets-delete-filter-view.md +25 -0
  387. package/server/assets/skills/lark-tools/cli-skills/lark-sheets/references/lark-sheets-export.md +51 -0
  388. package/server/assets/skills/lark-tools/cli-skills/lark-sheets/references/lark-sheets-find.md +62 -0
  389. package/server/assets/skills/lark-tools/cli-skills/lark-sheets/references/lark-sheets-formula.md +89 -0
  390. package/server/assets/skills/lark-tools/cli-skills/lark-sheets/references/lark-sheets-get-dropdown.md +43 -0
  391. package/server/assets/skills/lark-tools/cli-skills/lark-sheets/references/lark-sheets-get-filter-view-condition.md +27 -0
  392. package/server/assets/skills/lark-tools/cli-skills/lark-sheets/references/lark-sheets-get-filter-view.md +26 -0
  393. package/server/assets/skills/lark-tools/cli-skills/lark-sheets/references/lark-sheets-info.md +43 -0
  394. package/server/assets/skills/lark-tools/cli-skills/lark-sheets/references/lark-sheets-insert-dimension.md +51 -0
  395. package/server/assets/skills/lark-tools/cli-skills/lark-sheets/references/lark-sheets-list-filter-view-conditions.md +28 -0
  396. package/server/assets/skills/lark-tools/cli-skills/lark-sheets/references/lark-sheets-list-filter-views.md +26 -0
  397. package/server/assets/skills/lark-tools/cli-skills/lark-sheets/references/lark-sheets-merge-cells.md +47 -0
  398. package/server/assets/skills/lark-tools/cli-skills/lark-sheets/references/lark-sheets-move-dimension.md +52 -0
  399. package/server/assets/skills/lark-tools/cli-skills/lark-sheets/references/lark-sheets-read.md +61 -0
  400. package/server/assets/skills/lark-tools/cli-skills/lark-sheets/references/lark-sheets-replace.md +62 -0
  401. package/server/assets/skills/lark-tools/cli-skills/lark-sheets/references/lark-sheets-set-dropdown.md +62 -0
  402. package/server/assets/skills/lark-tools/cli-skills/lark-sheets/references/lark-sheets-set-style.md +71 -0
  403. package/server/assets/skills/lark-tools/cli-skills/lark-sheets/references/lark-sheets-unmerge-cells.md +46 -0
  404. package/server/assets/skills/lark-tools/cli-skills/lark-sheets/references/lark-sheets-update-dimension.md +60 -0
  405. package/server/assets/skills/lark-tools/cli-skills/lark-sheets/references/lark-sheets-update-dropdown.md +51 -0
  406. package/server/assets/skills/lark-tools/cli-skills/lark-sheets/references/lark-sheets-update-filter-view-condition.md +27 -0
  407. package/server/assets/skills/lark-tools/cli-skills/lark-sheets/references/lark-sheets-update-filter-view.md +24 -0
  408. package/server/assets/skills/lark-tools/cli-skills/lark-sheets/references/lark-sheets-write-image.md +65 -0
  409. package/server/assets/skills/lark-tools/cli-skills/lark-sheets/references/lark-sheets-write.md +60 -0
  410. package/server/assets/skills/lark-tools/cli-skills/lark-skill-maker/SKILL.md +85 -0
  411. package/server/assets/skills/lark-tools/cli-skills/lark-slides/SKILL.md +368 -0
  412. package/server/assets/skills/lark-tools/cli-skills/lark-slides/references/examples.md +179 -0
  413. package/server/assets/skills/lark-tools/cli-skills/lark-slides/references/lark-slides-create.md +137 -0
  414. package/server/assets/skills/lark-tools/cli-skills/lark-slides/references/lark-slides-media-upload.md +143 -0
  415. package/server/assets/skills/lark-tools/cli-skills/lark-slides/references/lark-slides-xml-presentation-slide-create.md +215 -0
  416. package/server/assets/skills/lark-tools/cli-skills/lark-slides/references/lark-slides-xml-presentation-slide-delete.md +119 -0
  417. package/server/assets/skills/lark-tools/cli-skills/lark-slides/references/lark-slides-xml-presentations-get.md +94 -0
  418. package/server/assets/skills/lark-tools/cli-skills/lark-slides/references/slide-templates.md +199 -0
  419. package/server/assets/skills/lark-tools/cli-skills/lark-slides/references/slides_demo.xml +226 -0
  420. package/server/assets/skills/lark-tools/cli-skills/lark-slides/references/slides_xml_schema_definition.xml +3004 -0
  421. package/server/assets/skills/lark-tools/cli-skills/lark-slides/references/xml-format-guide.md +369 -0
  422. package/server/assets/skills/lark-tools/cli-skills/lark-slides/references/xml-schema-quick-ref.md +215 -0
  423. package/server/assets/skills/lark-tools/cli-skills/lark-task/SKILL.md +151 -0
  424. package/server/assets/skills/lark-tools/cli-skills/lark-task/references/lark-task-assign.md +35 -0
  425. package/server/assets/skills/lark-tools/cli-skills/lark-task/references/lark-task-comment.md +28 -0
  426. package/server/assets/skills/lark-tools/cli-skills/lark-task/references/lark-task-complete.md +27 -0
  427. package/server/assets/skills/lark-tools/cli-skills/lark-task/references/lark-task-create.md +51 -0
  428. package/server/assets/skills/lark-tools/cli-skills/lark-task/references/lark-task-followers.md +32 -0
  429. package/server/assets/skills/lark-tools/cli-skills/lark-task/references/lark-task-get-my-tasks.md +55 -0
  430. package/server/assets/skills/lark-tools/cli-skills/lark-task/references/lark-task-get-related-tasks.md +53 -0
  431. package/server/assets/skills/lark-tools/cli-skills/lark-task/references/lark-task-reminder.md +36 -0
  432. package/server/assets/skills/lark-tools/cli-skills/lark-task/references/lark-task-reopen.md +27 -0
  433. package/server/assets/skills/lark-tools/cli-skills/lark-task/references/lark-task-search.md +41 -0
  434. package/server/assets/skills/lark-tools/cli-skills/lark-task/references/lark-task-set-ancestor.md +32 -0
  435. package/server/assets/skills/lark-tools/cli-skills/lark-task/references/lark-task-subscribe-event.md +86 -0
  436. package/server/assets/skills/lark-tools/cli-skills/lark-task/references/lark-task-tasklist-create.md +35 -0
  437. package/server/assets/skills/lark-tools/cli-skills/lark-task/references/lark-task-tasklist-members.md +36 -0
  438. package/server/assets/skills/lark-tools/cli-skills/lark-task/references/lark-task-tasklist-search.md +38 -0
  439. package/server/assets/skills/lark-tools/cli-skills/lark-task/references/lark-task-tasklist-task-add.md +38 -0
  440. package/server/assets/skills/lark-tools/cli-skills/lark-task/references/lark-task-update.md +37 -0
  441. package/server/assets/skills/lark-tools/cli-skills/lark-vc/SKILL.md +143 -0
  442. package/server/assets/skills/lark-tools/cli-skills/lark-vc/references/lark-vc-notes.md +126 -0
  443. package/server/assets/skills/lark-tools/cli-skills/lark-vc/references/lark-vc-recording.md +141 -0
  444. package/server/assets/skills/lark-tools/cli-skills/lark-vc/references/lark-vc-search.md +159 -0
  445. package/server/assets/skills/lark-tools/cli-skills/lark-whiteboard/SKILL.md +118 -0
  446. package/server/assets/skills/lark-tools/cli-skills/lark-whiteboard/references/lark-whiteboard-query.md +49 -0
  447. package/server/assets/skills/lark-tools/cli-skills/lark-whiteboard/references/lark-whiteboard-update.md +97 -0
  448. package/server/assets/skills/lark-tools/cli-skills/lark-whiteboard-cli/SKILL.md +236 -0
  449. package/server/assets/skills/lark-tools/cli-skills/lark-whiteboard-cli/references/connectors.md +102 -0
  450. package/server/assets/skills/lark-tools/cli-skills/lark-whiteboard-cli/references/content.md +40 -0
  451. package/server/assets/skills/lark-tools/cli-skills/lark-whiteboard-cli/references/layout.md +374 -0
  452. package/server/assets/skills/lark-tools/cli-skills/lark-whiteboard-cli/references/schema.md +333 -0
  453. package/server/assets/skills/lark-tools/cli-skills/lark-whiteboard-cli/references/style.md +318 -0
  454. package/server/assets/skills/lark-tools/cli-skills/lark-whiteboard-cli/references/typography.md +73 -0
  455. package/server/assets/skills/lark-tools/cli-skills/lark-whiteboard-cli/scenes/architecture.md +433 -0
  456. package/server/assets/skills/lark-tools/cli-skills/lark-whiteboard-cli/scenes/bar-chart.md +181 -0
  457. package/server/assets/skills/lark-tools/cli-skills/lark-whiteboard-cli/scenes/comparison.md +135 -0
  458. package/server/assets/skills/lark-tools/cli-skills/lark-whiteboard-cli/scenes/fishbone.md +238 -0
  459. package/server/assets/skills/lark-tools/cli-skills/lark-whiteboard-cli/scenes/flowchart.md +185 -0
  460. package/server/assets/skills/lark-tools/cli-skills/lark-whiteboard-cli/scenes/flywheel.md +195 -0
  461. package/server/assets/skills/lark-tools/cli-skills/lark-whiteboard-cli/scenes/funnel.md +101 -0
  462. package/server/assets/skills/lark-tools/cli-skills/lark-whiteboard-cli/scenes/line-chart.md +208 -0
  463. package/server/assets/skills/lark-tools/cli-skills/lark-whiteboard-cli/scenes/mermaid.md +136 -0
  464. package/server/assets/skills/lark-tools/cli-skills/lark-whiteboard-cli/scenes/milestone.md +139 -0
  465. package/server/assets/skills/lark-tools/cli-skills/lark-whiteboard-cli/scenes/organization.md +175 -0
  466. package/server/assets/skills/lark-tools/cli-skills/lark-whiteboard-cli/scenes/pyramid.md +99 -0
  467. package/server/assets/skills/lark-tools/cli-skills/lark-whiteboard-cli/scenes/swimlane.md +370 -0
  468. package/server/assets/skills/lark-tools/cli-skills/lark-whiteboard-cli/scenes/treemap.md +210 -0
  469. package/server/assets/skills/lark-tools/cli-skills/lark-wiki/SKILL.md +93 -0
  470. package/server/assets/skills/lark-tools/cli-skills/lark-wiki/references/lark-wiki-move.md +183 -0
  471. package/server/assets/skills/lark-tools/cli-skills/lark-wiki/references/lark-wiki-node-create.md +127 -0
  472. package/server/assets/skills/lark-tools/cli-skills/lark-workflow-meeting-summary/SKILL.md +99 -0
  473. package/server/assets/skills/lark-tools/cli-skills/lark-workflow-standup-report/SKILL.md +120 -0
  474. package/server/assets/skills/lark-tools/references/commands-macos-linux.md +42 -0
  475. package/server/assets/skills/lark-tools/references/commands-windows-powershell.md +54 -0
  476. package/server/assets/skills/lark-tools/references/storage-paths.md +21 -0
  477. package/server/assets/skills/llm-call/SKILL.md +50 -0
  478. package/server/assets/skills/llm-call/scripts/llm_call.py +458 -0
  479. package/server/assets/skills/mcode-tools-master/SKILL.md +133 -0
  480. package/server/assets/skills/pdf/SKILL.md +287 -0
  481. package/server/assets/skills/pdf/docs/advanced-reference.md +711 -0
  482. package/server/assets/skills/pdf/docs/ai-voice-cloning-regulatory-report-case.md +303 -0
  483. package/server/assets/skills/pdf/docs/annual-report-financial-digest-latex-case.md +233 -0
  484. package/server/assets/skills/pdf/docs/create-guide.md +438 -0
  485. package/server/assets/skills/pdf/docs/design-guide.md +204 -0
  486. package/server/assets/skills/pdf/docs/docx-contract-roundtrip-professional-case.md +328 -0
  487. package/server/assets/skills/pdf/docs/email-translation-goldman-two-sessions-case.md +346 -0
  488. package/server/assets/skills/pdf/docs/forms-guide.md +462 -0
  489. package/server/assets/skills/pdf/docs/html-pdf-spec.md +500 -0
  490. package/server/assets/skills/pdf/docs/italy-schengen-visa-acroform-case.md +22 -0
  491. package/server/assets/skills/pdf/docs/latex-academic-thesis-guide.md +234 -0
  492. package/server/assets/skills/pdf/docs/latex-technical-book-guide.md +112 -0
  493. package/server/assets/skills/pdf/docs/markdown-static-academic-data-viz-case.md +280 -0
  494. package/server/assets/skills/pdf/docs/pitfalls-index.md +798 -0
  495. package/server/assets/skills/pdf/docs/read-guide.md +358 -0
  496. package/server/assets/skills/pdf/docs/reformat-guide.md +238 -0
  497. package/server/assets/skills/pdf/docs/skill-readme-archive.md +152 -0
  498. package/server/assets/skills/pdf/docs/troubleshooting.md +86 -0
  499. package/server/assets/skills/pdf/docs/vision-guide.md +188 -0
  500. package/server/assets/skills/pdf/scripts/__init__.py +0 -0
  501. package/server/assets/skills/pdf/scripts/_pdf_read_lib.py +284 -0
  502. package/server/assets/skills/pdf/scripts/fill/__init__.py +0 -0
  503. package/server/assets/skills/pdf/scripts/fill/acroform_apply.py +153 -0
  504. package/server/assets/skills/pdf/scripts/fill/overlay_apply.py +109 -0
  505. package/server/assets/skills/pdf/scripts/lib/__init__.py +0 -0
  506. package/server/assets/skills/pdf/scripts/lib/acroform_io.py +170 -0
  507. package/server/assets/skills/pdf/scripts/lib/cli_utils.py +41 -0
  508. package/server/assets/skills/pdf/scripts/lib/geometry.py +79 -0
  509. package/server/assets/skills/pdf/scripts/make.sh +388 -0
  510. package/server/assets/skills/pdf/scripts/merge.py +112 -0
  511. package/server/assets/skills/pdf/scripts/pdf_inspect/__init__.py +0 -0
  512. package/server/assets/skills/pdf/scripts/pdf_inspect/acroform_inspect.py +52 -0
  513. package/server/assets/skills/pdf/scripts/pdf_inspect/acroform_probe.py +57 -0
  514. package/server/assets/skills/pdf/scripts/pdf_inspect/layout_scan.py +164 -0
  515. package/server/assets/skills/pdf/scripts/read_pdf_vision.py +473 -0
  516. package/server/assets/skills/pdf/scripts/reformat_parse.py +181 -0
  517. package/server/assets/skills/pdf/scripts/render/__init__.py +0 -0
  518. package/server/assets/skills/pdf/scripts/render/overlay_preview.py +86 -0
  519. package/server/assets/skills/pdf/scripts/render/page_rasterize.py +85 -0
  520. package/server/assets/skills/pdf/scripts/render_html.cjs +205 -0
  521. package/server/assets/skills/pdf/scripts/validate/__init__.py +0 -0
  522. package/server/assets/skills/pdf/scripts/validate/geometry_lint.py +124 -0
  523. package/server/assets/skills/pdf/templates/INDEX.md +97 -0
  524. package/server/assets/skills/pdf/templates/bilingual-menu-premium/README.md +175 -0
  525. package/server/assets/skills/pdf/templates/bilingual-menu-premium/skeleton.html +343 -0
  526. package/server/assets/skills/pdf/templates/brand-guide-2page/README.md +140 -0
  527. package/server/assets/skills/pdf/templates/brand-guide-2page/cases/minimax-web-brand-guide/README.md +155 -0
  528. package/server/assets/skills/pdf/templates/brand-guide-2page/cases/minimax-web-brand-guide/source.html +188 -0
  529. package/server/assets/skills/pdf/templates/brand-guide-2page/skeleton.html +264 -0
  530. package/server/assets/skills/pdf/templates/data-viz-report/README.md +234 -0
  531. package/server/assets/skills/pdf/templates/data-viz-report/cases/annual-report-financial-digest-latex/README.md +12 -0
  532. package/server/assets/skills/pdf/templates/data-viz-report/cases/annual-report-financial-digest-latex/build_charts.py +341 -0
  533. package/server/assets/skills/pdf/templates/data-viz-report/cases/annual-report-financial-digest-latex/source.tex +161 -0
  534. package/server/assets/skills/pdf/templates/data-viz-report/cases/apple-m-ai-static-academic/assets/fig_1_1_table_1_1_specs.png +0 -0
  535. package/server/assets/skills/pdf/templates/data-viz-report/cases/apple-m-ai-static-academic/assets/fig_1_2_table_1_2_geekbench.png +0 -0
  536. package/server/assets/skills/pdf/templates/data-viz-report/cases/apple-m-ai-static-academic/assets/fig_1_3_mmax_generation.png +0 -0
  537. package/server/assets/skills/pdf/templates/data-viz-report/cases/apple-m-ai-static-academic/source.html +656 -0
  538. package/server/assets/skills/pdf/templates/data-viz-report/skeleton.html +835 -0
  539. package/server/assets/skills/pdf/templates/form-fill-acroform/README.md +198 -0
  540. package/server/assets/skills/pdf/templates/form-fill-acroform/cases/italy-schengen-visa-example/USER-FINAL-SUMMARY.template.md +42 -0
  541. package/server/assets/skills/pdf/templates/form-fill-acroform/cases/italy-schengen-visa-example/extract_pdfs_key_info.py +80 -0
  542. package/server/assets/skills/pdf/templates/form-fill-acroform/cases/italy-schengen-visa-example/field_values.case.json +233 -0
  543. package/server/assets/skills/pdf/templates/form-fill-acroform/field_values.template.json +118 -0
  544. package/server/assets/skills/pdf/templates/latex-academic-thesis/README.md +146 -0
  545. package/server/assets/skills/pdf/templates/latex-academic-thesis/source.tex +334 -0
  546. package/server/assets/skills/pdf/templates/latex-technical-book/README.md +130 -0
  547. package/server/assets/skills/pdf/templates/latex-technical-book/README.template-source.md +62 -0
  548. package/server/assets/skills/pdf/templates/latex-technical-book/source.tex +439 -0
  549. package/server/assets/skills/pdf/templates/multi-article-aggregator/README.md +148 -0
  550. package/server/assets/skills/pdf/templates/multi-article-aggregator/pipeline.md +223 -0
  551. package/server/assets/skills/pdf/templates/multilang-research-report/README.md +146 -0
  552. package/server/assets/skills/pdf/templates/multilang-research-report/cases/ai-voice-cloning-regulatory/source.html +244 -0
  553. package/server/assets/skills/pdf/templates/multilang-research-report/skeleton.html +242 -0
  554. package/server/assets/skills/pdf/templates/reformat-default/README.md +137 -0
  555. package/server/assets/skills/pdf/templates/reformat-default/cases/pku-contract-roundtrip/docx_engine.py +68 -0
  556. package/server/assets/skills/pdf/templates/reformat-default/cases/pku-contract-roundtrip/source.html +231 -0
  557. package/server/assets/skills/pdf/templates/reformat-default/cases/pku-contract-roundtrip/source.md +196 -0
  558. package/server/assets/skills/pdf/templates/reformat-default/skeleton.html +204 -0
  559. package/server/assets/skills/pdf/templates/translate-preserve-layout/README.md +147 -0
  560. package/server/assets/skills/pdf/templates/translate-preserve-layout/cases/goldman-china-two-sessions-cn.html +1660 -0
  561. package/server/assets/skills/pdf/templates/translate-preserve-layout/skeleton.html +96 -0
  562. package/server/assets/skills/pdf/templates/translate-preserve-layout/terminology.template.json +66 -0
  563. package/server/assets/skills/pptx/SKILL.md +285 -0
  564. package/server/assets/skills/pptx/references/design-system.md +424 -0
  565. package/server/assets/skills/pptx/references/editing.md +162 -0
  566. package/server/assets/skills/pptx/references/element-map.md +229 -0
  567. package/server/assets/skills/pptx/references/pitfalls.md +205 -0
  568. package/server/assets/skills/pptx/references/pptxgenjs.md +420 -0
  569. package/server/assets/skills/pptx/references/preview-selection-writeback.md +65 -0
  570. package/server/assets/skills/pptx/references/python-pptx-recipes.md +63 -0
  571. package/server/assets/skills/pptx/references/slide-types.md +413 -0
  572. package/server/assets/skills/pptx/scripts/audit_pptx.py +708 -0
  573. package/server/assets/skills/pptx/scripts/extract_comments.py +468 -0
  574. package/server/assets/skills/pptx/scripts/extract_images.py +226 -0
  575. package/server/assets/skills/pptx/scripts/extract_pptx.py +285 -0
  576. package/server/assets/skills/pptx/scripts/mavis-ppt-map.cjs +280 -0
  577. package/server/assets/skills/pptx/scripts/pdf2png.swift +203 -0
  578. package/server/assets/skills/pptx/scripts/pptx-screenshot.sh +105 -0
  579. package/server/assets/skills/resume-codex/SKILL.md +55 -0
  580. package/server/assets/skills/resume-codex/scripts/session-reader.mjs +445 -0
  581. package/server/assets/skills/skill-creator/SKILL.md +190 -0
  582. package/server/assets/skills/skill-creator/references/anti-patterns.md +149 -0
  583. package/server/assets/skills/skill-creator/references/commands-macos-linux.md +38 -0
  584. package/server/assets/skills/skill-creator/references/commands-windows-powershell.md +48 -0
  585. package/server/assets/skills/skill-creator/references/description-rubric.md +83 -0
  586. package/server/assets/skills/skill-creator/references/skill-template.md +101 -0
  587. package/server/assets/skills/skill-creator/references/when-to-bundle-scripts.md +139 -0
  588. package/server/assets/skills/skill-creator/scripts/lint-skill.js +226 -0
  589. package/server/assets/skills/skill-refiner/SKILL.md +139 -0
  590. package/server/assets/skills/visual-page/SKILL.md +196 -0
  591. package/server/assets/skills/x-link-reader/SKILL.md +110 -0
  592. package/server/assets/skills/xlsx/SKILL.md +501 -0
  593. package/server/assets/skills/xlsx/docs/advanced-reference.md +410 -0
  594. package/server/assets/skills/xlsx/docs/cases/superstore-multiformat/conversion_manifest.example.json +49 -0
  595. package/server/assets/skills/xlsx/docs/cases/superstore-multiformat/superstore_orders_print.html +17 -0
  596. package/server/assets/skills/xlsx/docs/conventions-guide.md +217 -0
  597. package/server/assets/skills/xlsx/docs/create-edit-guide.md +410 -0
  598. package/server/assets/skills/xlsx/docs/pitfalls-index.md +760 -0
  599. package/server/assets/skills/xlsx/docs/raw-xml-escape-hatch.md +201 -0
  600. package/server/assets/skills/xlsx/docs/recalc-guide.md +295 -0
  601. package/server/assets/skills/xlsx/docs/superstore-multiformat-conversion-case.md +413 -0
  602. package/server/assets/skills/xlsx/scripts/office/helpers/__init__.py +0 -0
  603. package/server/assets/skills/xlsx/scripts/office/helpers/merge_runs.py +199 -0
  604. package/server/assets/skills/xlsx/scripts/office/helpers/simplify_redlines.py +197 -0
  605. package/server/assets/skills/xlsx/scripts/office/pack.py +159 -0
  606. package/server/assets/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
  607. package/server/assets/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
  608. package/server/assets/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
  609. package/server/assets/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
  610. package/server/assets/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
  611. package/server/assets/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
  612. package/server/assets/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
  613. package/server/assets/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
  614. package/server/assets/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
  615. package/server/assets/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
  616. package/server/assets/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
  617. package/server/assets/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
  618. package/server/assets/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
  619. package/server/assets/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
  620. package/server/assets/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
  621. package/server/assets/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
  622. package/server/assets/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
  623. package/server/assets/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
  624. package/server/assets/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
  625. package/server/assets/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
  626. package/server/assets/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
  627. package/server/assets/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
  628. package/server/assets/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
  629. package/server/assets/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
  630. package/server/assets/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
  631. package/server/assets/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
  632. package/server/assets/skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
  633. package/server/assets/skills/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
  634. package/server/assets/skills/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
  635. package/server/assets/skills/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
  636. package/server/assets/skills/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
  637. package/server/assets/skills/xlsx/scripts/office/schemas/mce/mc.xsd +75 -0
  638. package/server/assets/skills/xlsx/scripts/office/schemas/microsoft/wml-2010.xsd +560 -0
  639. package/server/assets/skills/xlsx/scripts/office/schemas/microsoft/wml-2012.xsd +67 -0
  640. package/server/assets/skills/xlsx/scripts/office/schemas/microsoft/wml-2018.xsd +14 -0
  641. package/server/assets/skills/xlsx/scripts/office/schemas/microsoft/wml-cex-2018.xsd +20 -0
  642. package/server/assets/skills/xlsx/scripts/office/schemas/microsoft/wml-cid-2016.xsd +13 -0
  643. package/server/assets/skills/xlsx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
  644. package/server/assets/skills/xlsx/scripts/office/schemas/microsoft/wml-symex-2015.xsd +8 -0
  645. package/server/assets/skills/xlsx/scripts/office/soffice.py +191 -0
  646. package/server/assets/skills/xlsx/scripts/office/unpack.py +132 -0
  647. package/server/assets/skills/xlsx/scripts/office/validate.py +117 -0
  648. package/server/assets/skills/xlsx/scripts/office/validators/__init__.py +15 -0
  649. package/server/assets/skills/xlsx/scripts/office/validators/base.py +851 -0
  650. package/server/assets/skills/xlsx/scripts/office/validators/docx.py +446 -0
  651. package/server/assets/skills/xlsx/scripts/office/validators/pptx.py +275 -0
  652. package/server/assets/skills/xlsx/scripts/office/validators/redlining.py +247 -0
  653. package/server/assets/skills/xlsx/scripts/recalc.py +450 -0
  654. package/server/mcode-tools.js +2 -0
  655. package/server/package-info.json +1 -1
  656. package/server/server.js +2 -0
@@ -0,0 +1,1032 @@
1
+ #!/usr/bin/env python3
2
+ """Deep DOCX structure analyzer.
3
+
4
+ This script is the **primary** structure-truth implementation for the docx
5
+ skill. It is intentionally not "a summarizer that needs dotnet to corroborate" —
6
+ it parses the OOXML parts directly (stdlib only) and produces an independent,
7
+ self-contained structure report covering:
8
+
9
+ * parts inventory + Content-Types vs rels cross-check
10
+ * relationship graph (document, headers, footers)
11
+ * section graph with page geometry, header/footer references and titlePg
12
+ * numbering chain (numId -> abstractNumId -> level definitions) plus usage
13
+ * field topology (simple + complex fields, instruction text, dirty/locked)
14
+ * bookmark topology (start/end pairing, orphan detection, reserved names)
15
+ * hyperlink topology (internal anchors + external URLs resolved via rels)
16
+ * comments topology (definitions, in-document ranges, parent links, orphans)
17
+ * revisions topology (kinds, actors, date range)
18
+ * styles inventory + cross-reference audit (defined/used/missing/contaminated)
19
+ * direct-formatting contamination heatmap
20
+ * a `diagnostics` array of categorized findings (template diagnosis aid)
21
+
22
+ The dotnet `analyze` command remains useful as an **independent confirmation**
23
+ shot (different parser, different runtime), but it is not the structure-truth
24
+ oracle. This script is.
25
+
26
+ Run:
27
+ python3 read_docx_structure.py path/to/file.docx --json
28
+ python3 read_docx_structure.py path/to/file.docx --section sections,numbering
29
+ """
30
+
31
+ from __future__ import annotations
32
+
33
+ import argparse
34
+ import json
35
+ import re
36
+ import sys
37
+ import xml.etree.ElementTree as ET
38
+ from collections import Counter, defaultdict
39
+ from datetime import datetime
40
+ from pathlib import Path
41
+ from typing import Any, Dict, Iterable, List, Optional, Tuple
42
+ from zipfile import ZipFile
43
+
44
+ # -- namespaces ----------------------------------------------------------------
45
+
46
+ NS = {
47
+ "w": "http://schemas.openxmlformats.org/wordprocessingml/2006/main",
48
+ "r": "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
49
+ "rel": "http://schemas.openxmlformats.org/package/2006/relationships",
50
+ "ct": "http://schemas.openxmlformats.org/package/2006/content-types",
51
+ "w14": "http://schemas.microsoft.com/office/word/2010/wordml",
52
+ "w15": "http://schemas.microsoft.com/office/word/2012/wordml",
53
+ }
54
+
55
+ W = NS["w"]
56
+ R = NS["r"]
57
+ REL = NS["rel"]
58
+ CT = NS["ct"]
59
+
60
+
61
+ def qn(prefix: str, name: str) -> str:
62
+ return f"{{{NS[prefix]}}}{name}"
63
+
64
+
65
+ WVAL = qn("w", "val")
66
+ WTYPE = qn("w", "type")
67
+ WSTYLEID = qn("w", "styleId")
68
+ WCUSTOM = qn("w", "customStyle")
69
+ WDEFAULT = qn("w", "default")
70
+ RID = qn("r", "id")
71
+ WAUTHOR = qn("w", "author")
72
+ WDATE = qn("w", "date")
73
+
74
+
75
+ # -- XML helpers ---------------------------------------------------------------
76
+
77
+ def load_xml(archive: ZipFile, entry_name: str) -> Optional[ET.Element]:
78
+ try:
79
+ with archive.open(entry_name) as handle:
80
+ return ET.fromstring(handle.read())
81
+ except KeyError:
82
+ return None
83
+ except ET.ParseError as exc:
84
+ # Surface as diagnostic but do not crash the whole analysis.
85
+ return ET.fromstring(f"<broken xmlns='urn:broken'>{exc}</broken>")
86
+
87
+
88
+ def text_of(node: ET.Element) -> str:
89
+ return "".join(part.text or "" for part in node.findall(".//w:t", NS)).strip()
90
+
91
+
92
+ def attr(elem: ET.Element, name: str) -> Optional[str]:
93
+ """Return attribute by prefixed-or-bare name."""
94
+ return elem.get(name) or elem.get(name.split("}", 1)[-1] if "}" in name else name)
95
+
96
+
97
+ def w_attr(elem: ET.Element, local: str) -> Optional[str]:
98
+ return elem.get(qn("w", local)) or elem.get(local)
99
+
100
+
101
+ # -- conversion helpers --------------------------------------------------------
102
+
103
+ def twips_to_mm(value: Optional[str]) -> Optional[float]:
104
+ if value is None:
105
+ return None
106
+ try:
107
+ return round(int(value) / 1440.0 * 25.4, 2)
108
+ except (TypeError, ValueError):
109
+ return None
110
+
111
+
112
+ # -- packaging layer -----------------------------------------------------------
113
+
114
+ def parse_content_types(archive: ZipFile) -> Dict[str, Any]:
115
+ elem = load_xml(archive, "[Content_Types].xml")
116
+ if elem is None:
117
+ return {"defaults": {}, "overrides": {}, "missing": True}
118
+ defaults: Dict[str, str] = {}
119
+ overrides: Dict[str, str] = {}
120
+ for child in elem.findall(qn("ct", "Default")):
121
+ defaults[child.get("Extension", "")] = child.get("ContentType", "")
122
+ for child in elem.findall(qn("ct", "Override")):
123
+ overrides[child.get("PartName", "")] = child.get("ContentType", "")
124
+ return {"defaults": defaults, "overrides": overrides, "missing": False}
125
+
126
+
127
+ def parse_rels(archive: ZipFile, rels_path: str) -> List[Dict[str, str]]:
128
+ elem = load_xml(archive, rels_path)
129
+ if elem is None:
130
+ return []
131
+ rels: List[Dict[str, str]] = []
132
+ for child in elem.findall(qn("rel", "Relationship")):
133
+ rels.append({
134
+ "id": child.get("Id", ""),
135
+ "type": child.get("Type", ""),
136
+ "target": child.get("Target", ""),
137
+ "targetMode": child.get("TargetMode", "Internal"),
138
+ })
139
+ return rels
140
+
141
+
142
+ def collect_parts_inventory(archive: ZipFile) -> Dict[str, Any]:
143
+ parts = []
144
+ for info in archive.infolist():
145
+ parts.append({
146
+ "name": info.filename,
147
+ "size": info.file_size,
148
+ "compressed": info.compress_size,
149
+ })
150
+ return {
151
+ "count": len(parts),
152
+ "totalUncompressed": sum(p["size"] for p in parts),
153
+ "items": parts,
154
+ }
155
+
156
+
157
+ # -- styles --------------------------------------------------------------------
158
+
159
+ def parse_styles(styles_doc: Optional[ET.Element]) -> Dict[str, Any]:
160
+ if styles_doc is None:
161
+ return {"missing": True, "byId": {}, "defaults": {}}
162
+ by_id: Dict[str, Dict[str, Any]] = {}
163
+ defaults: Dict[str, str] = {}
164
+ for style in styles_doc.findall(qn("w", "style")):
165
+ style_id = w_attr(style, "styleId")
166
+ if not style_id:
167
+ continue
168
+ name_node = style.find(qn("w", "name"))
169
+ based_on = style.find(qn("w", "basedOn"))
170
+ link = style.find(qn("w", "link"))
171
+ next_style = style.find(qn("w", "next"))
172
+ ppr = style.find(qn("w", "pPr"))
173
+ outline_lvl = ppr.find(qn("w", "outlineLvl")) if ppr is not None else None
174
+ num_pr = ppr.find(qn("w", "numPr")) if ppr is not None else None
175
+ num_id = None
176
+ if num_pr is not None:
177
+ num_id_node = num_pr.find(qn("w", "numId"))
178
+ if num_id_node is not None:
179
+ num_id = w_attr(num_id_node, "val")
180
+ info = {
181
+ "styleId": style_id,
182
+ "type": w_attr(style, "type"),
183
+ "name": w_attr(name_node, "val") if name_node is not None else None,
184
+ "basedOn": w_attr(based_on, "val") if based_on is not None else None,
185
+ "linked": w_attr(link, "val") if link is not None else None,
186
+ "next": w_attr(next_style, "val") if next_style is not None else None,
187
+ "isDefault": w_attr(style, "default") == "1",
188
+ "isCustom": w_attr(style, "customStyle") == "1",
189
+ "outlineLvl": w_attr(outline_lvl, "val") if outline_lvl is not None else None,
190
+ "numId": num_id,
191
+ }
192
+ if info["isDefault"] and info["type"]:
193
+ defaults[info["type"]] = style_id
194
+ by_id[style_id] = info
195
+ return {"missing": False, "byId": by_id, "defaults": defaults}
196
+
197
+
198
+ def style_inheritance_chain(styles: Dict[str, Any], style_id: str) -> List[str]:
199
+ chain: List[str] = []
200
+ seen = set()
201
+ cursor = style_id
202
+ while cursor and cursor not in seen:
203
+ seen.add(cursor)
204
+ chain.append(cursor)
205
+ info = styles["byId"].get(cursor)
206
+ if not info:
207
+ break
208
+ cursor = info.get("basedOn")
209
+ return chain
210
+
211
+
212
+ # -- numbering -----------------------------------------------------------------
213
+
214
+ def parse_numbering(numbering_doc: Optional[ET.Element]) -> Dict[str, Any]:
215
+ if numbering_doc is None:
216
+ return {"missing": True, "abstractNums": {}, "nums": {}}
217
+ abstract: Dict[str, Dict[str, Any]] = {}
218
+ for an in numbering_doc.findall(qn("w", "abstractNum")):
219
+ an_id = w_attr(an, "abstractNumId")
220
+ multi = an.find(qn("w", "multiLevelType"))
221
+ levels: List[Dict[str, Any]] = []
222
+ for lvl in an.findall(qn("w", "lvl")):
223
+ num_fmt = lvl.find(qn("w", "numFmt"))
224
+ lvl_text = lvl.find(qn("w", "lvlText"))
225
+ start = lvl.find(qn("w", "start"))
226
+ p_style = lvl.find(qn("w", "pStyle"))
227
+ levels.append({
228
+ "ilvl": w_attr(lvl, "ilvl"),
229
+ "numFmt": w_attr(num_fmt, "val") if num_fmt is not None else None,
230
+ "lvlText": w_attr(lvl_text, "val") if lvl_text is not None else None,
231
+ "start": w_attr(start, "val") if start is not None else None,
232
+ "pStyle": w_attr(p_style, "val") if p_style is not None else None,
233
+ })
234
+ abstract[an_id or ""] = {
235
+ "abstractNumId": an_id,
236
+ "multiLevelType": w_attr(multi, "val") if multi is not None else None,
237
+ "levels": levels,
238
+ }
239
+ nums: Dict[str, Dict[str, Any]] = {}
240
+ for num in numbering_doc.findall(qn("w", "num")):
241
+ num_id = w_attr(num, "numId")
242
+ an_ref = num.find(qn("w", "abstractNumId"))
243
+ overrides = []
244
+ for ov in num.findall(qn("w", "lvlOverride")):
245
+ overrides.append({"ilvl": w_attr(ov, "ilvl")})
246
+ nums[num_id or ""] = {
247
+ "numId": num_id,
248
+ "abstractNumId": w_attr(an_ref, "val") if an_ref is not None else None,
249
+ "lvlOverrides": overrides,
250
+ }
251
+ return {"missing": False, "abstractNums": abstract, "nums": nums}
252
+
253
+
254
+ # -- comments ------------------------------------------------------------------
255
+
256
+ def parse_comments(comments_doc: Optional[ET.Element]) -> List[Dict[str, Any]]:
257
+ if comments_doc is None:
258
+ return []
259
+ items: List[Dict[str, Any]] = []
260
+ for comment in comments_doc.findall(qn("w", "comment")):
261
+ items.append({
262
+ "id": w_attr(comment, "id"),
263
+ "author": w_attr(comment, "author"),
264
+ "initials": w_attr(comment, "initials"),
265
+ "date": w_attr(comment, "date"),
266
+ "text": text_of(comment),
267
+ })
268
+ return items
269
+
270
+
271
+ def parse_comments_extended(doc: Optional[ET.Element]) -> List[Dict[str, Any]]:
272
+ if doc is None:
273
+ return []
274
+ items: List[Dict[str, Any]] = []
275
+ for entry in doc.findall(qn("w15", "commentEx")):
276
+ items.append({
277
+ "paraId": entry.get(qn("w15", "paraId")) or entry.get("paraId"),
278
+ "paraIdParent": entry.get(qn("w15", "paraIdParent")) or entry.get("paraIdParent"),
279
+ "done": (entry.get(qn("w15", "done")) or entry.get("done")) == "1",
280
+ })
281
+ return items
282
+
283
+
284
+ # -- field state machine -------------------------------------------------------
285
+
286
+ FIELD_KIND = re.compile(r"^\s*([A-Z]+)")
287
+
288
+
289
+ def classify_field(instr: str) -> str:
290
+ match = FIELD_KIND.match(instr.strip())
291
+ return match.group(1) if match else "UNKNOWN"
292
+
293
+
294
+ def collect_complex_fields(body: ET.Element) -> List[Dict[str, Any]]:
295
+ """Walk body in document order pairing fldChar begin/separate/end."""
296
+ out: List[Dict[str, Any]] = []
297
+ stack: List[Dict[str, Any]] = []
298
+ for run in body.iter(qn("w", "r")):
299
+ fld_char = run.find(qn("w", "fldChar"))
300
+ instr = run.find(qn("w", "instrText"))
301
+ text = run.find(qn("w", "t"))
302
+ if fld_char is not None:
303
+ kind = w_attr(fld_char, "fldCharType")
304
+ if kind == "begin":
305
+ stack.append({
306
+ "instr": "",
307
+ "result": "",
308
+ "dirty": w_attr(fld_char, "dirty") == "1",
309
+ "locked": w_attr(fld_char, "fldLock") == "1",
310
+ "phase": "instr",
311
+ })
312
+ elif kind == "separate" and stack:
313
+ stack[-1]["phase"] = "result"
314
+ elif kind == "end" and stack:
315
+ completed = stack.pop()
316
+ completed["kind"] = classify_field(completed["instr"])
317
+ completed.pop("phase", None)
318
+ if stack:
319
+ # Field-in-field (rare); treat outer result as still being captured.
320
+ stack[-1]["result"] += completed.get("result", "")
321
+ out.append(completed)
322
+ elif instr is not None and stack and stack[-1].get("phase") == "instr":
323
+ stack[-1]["instr"] += instr.text or ""
324
+ elif text is not None and stack and stack[-1].get("phase") == "result":
325
+ stack[-1]["result"] += text.text or ""
326
+ return out
327
+
328
+
329
+ def collect_simple_fields(body: ET.Element) -> List[Dict[str, Any]]:
330
+ out: List[Dict[str, Any]] = []
331
+ for fld in body.iter(qn("w", "fldSimple")):
332
+ instr = w_attr(fld, "instr") or ""
333
+ out.append({
334
+ "instr": instr.strip(),
335
+ "kind": classify_field(instr),
336
+ "dirty": w_attr(fld, "dirty") == "1",
337
+ "result": text_of(fld),
338
+ })
339
+ return out
340
+
341
+
342
+ # -- bookmarks -----------------------------------------------------------------
343
+
344
+ def collect_bookmarks(body: ET.Element) -> Dict[str, Any]:
345
+ starts: Dict[str, Dict[str, Any]] = {}
346
+ ends_seen: List[str] = []
347
+ paragraph_seq: List[ET.Element] = list(body.iter(qn("w", "p")))
348
+ para_index_by_id = {id(p): idx for idx, p in enumerate(paragraph_seq)}
349
+
350
+ def parent_paragraph_index(elem: ET.Element) -> Optional[int]:
351
+ # Walk through the tree to find the enclosing <w:p>; ET has no parent
352
+ # pointer, so we precomputed paragraph identity below.
353
+ return None
354
+
355
+ # Instead of walking ancestors we walk paragraphs and record bookmark anchors
356
+ # encountered inside each paragraph. This still provides a correct paragraph-
357
+ # span for any bookmark whose start/end are inside the body's paragraph tree.
358
+ para_index: Dict[str, Dict[str, int]] = {}
359
+ for idx, paragraph in enumerate(paragraph_seq):
360
+ for bm in paragraph.iter(qn("w", "bookmarkStart")):
361
+ bm_id = w_attr(bm, "id")
362
+ if bm_id is not None:
363
+ para_index.setdefault(bm_id, {})["startPara"] = idx
364
+ for bm in paragraph.iter(qn("w", "bookmarkEnd")):
365
+ bm_id = w_attr(bm, "id")
366
+ if bm_id is not None:
367
+ para_index.setdefault(bm_id, {})["endPara"] = idx
368
+
369
+ for bm in body.iter(qn("w", "bookmarkStart")):
370
+ bm_id = w_attr(bm, "id")
371
+ name = w_attr(bm, "name") or ""
372
+ starts[bm_id or ""] = {
373
+ "id": bm_id,
374
+ "name": name,
375
+ "reserved": name.startswith("_"),
376
+ "startPara": para_index.get(bm_id or "", {}).get("startPara"),
377
+ }
378
+ for bm in body.iter(qn("w", "bookmarkEnd")):
379
+ bm_id = w_attr(bm, "id")
380
+ ends_seen.append(bm_id or "")
381
+ if bm_id and bm_id in starts:
382
+ starts[bm_id]["endPara"] = para_index.get(bm_id, {}).get("endPara")
383
+ end_counter = Counter(ends_seen)
384
+ pairs: List[Dict[str, Any]] = []
385
+ orphan_starts: List[Dict[str, Any]] = []
386
+ for bm_id, info in starts.items():
387
+ if end_counter.get(bm_id, 0) >= 1:
388
+ pairs.append(info)
389
+ else:
390
+ orphan_starts.append(info)
391
+ orphan_ends = [bm_id for bm_id in end_counter if bm_id not in starts]
392
+ return {
393
+ "pairs": pairs,
394
+ "orphanStarts": orphan_starts,
395
+ "orphanEnds": orphan_ends,
396
+ }
397
+
398
+
399
+ # -- hyperlinks ----------------------------------------------------------------
400
+
401
+ def collect_hyperlinks(body: ET.Element, rels_by_id: Dict[str, Dict[str, str]]) -> List[Dict[str, Any]]:
402
+ items: List[Dict[str, Any]] = []
403
+ for hl in body.iter(qn("w", "hyperlink")):
404
+ anchor = w_attr(hl, "anchor")
405
+ rid = hl.get(RID)
406
+ target_url = None
407
+ target_mode = None
408
+ if rid and rid in rels_by_id:
409
+ target_url = rels_by_id[rid].get("target")
410
+ target_mode = rels_by_id[rid].get("targetMode")
411
+ items.append({
412
+ "anchor": anchor,
413
+ "rId": rid,
414
+ "url": target_url,
415
+ "external": target_mode == "External",
416
+ "text": text_of(hl)[:200] or None,
417
+ })
418
+ return items
419
+
420
+
421
+ # -- sections / page setup -----------------------------------------------------
422
+
423
+ def parse_section(sect_pr: ET.Element) -> Dict[str, Any]:
424
+ pg_sz = sect_pr.find(qn("w", "pgSz"))
425
+ pg_mar = sect_pr.find(qn("w", "pgMar"))
426
+ type_node = sect_pr.find(qn("w", "type"))
427
+ cols = sect_pr.find(qn("w", "cols"))
428
+ title_pg = sect_pr.find(qn("w", "titlePg"))
429
+ line_num = sect_pr.find(qn("w", "lnNumType"))
430
+ pg_borders = sect_pr.find(qn("w", "pgBorders"))
431
+ headers = []
432
+ footers = []
433
+ for ref in sect_pr.findall(qn("w", "headerReference")):
434
+ headers.append({"type": w_attr(ref, "type"), "rId": ref.get(RID)})
435
+ for ref in sect_pr.findall(qn("w", "footerReference")):
436
+ footers.append({"type": w_attr(ref, "type"), "rId": ref.get(RID)})
437
+
438
+ page_size = None
439
+ if pg_sz is not None:
440
+ page_size = {
441
+ "widthMm": twips_to_mm(w_attr(pg_sz, "w")),
442
+ "heightMm": twips_to_mm(w_attr(pg_sz, "h")),
443
+ "orient": w_attr(pg_sz, "orient") or "portrait",
444
+ }
445
+ margins = None
446
+ if pg_mar is not None:
447
+ margins = {
448
+ side: twips_to_mm(w_attr(pg_mar, side))
449
+ for side in ("top", "right", "bottom", "left", "header", "footer", "gutter")
450
+ }
451
+ return {
452
+ "type": (w_attr(type_node, "val") if type_node is not None else None) or "nextPage",
453
+ "pageSize": page_size,
454
+ "margins": margins,
455
+ "columns": (int(w_attr(cols, "num")) if cols is not None and (w_attr(cols, "num") or "").isdigit() else 1),
456
+ "titlePg": title_pg is not None,
457
+ "lineNumbering": line_num is not None,
458
+ "pageBorders": pg_borders is not None,
459
+ "headerReferences": headers,
460
+ "footerReferences": footers,
461
+ }
462
+
463
+
464
+ # -- direct-formatting contamination ------------------------------------------
465
+
466
+ NON_REF_PPR_CHILDREN = {
467
+ qn("w", "rPr"), qn("w", "sectPr"),
468
+ }
469
+ ALLOWED_PPR_REF_CHILDREN = {qn("w", "pStyle"), qn("w", "numPr")}
470
+
471
+
472
+ def paragraph_contamination(paragraph: ET.Element) -> Dict[str, int]:
473
+ info = {"pPrDirect": 0, "rPrDirectRuns": 0, "totalRuns": 0}
474
+ ppr = paragraph.find(qn("w", "pPr"))
475
+ if ppr is not None:
476
+ for child in list(ppr):
477
+ if child.tag not in ALLOWED_PPR_REF_CHILDREN and child.tag not in NON_REF_PPR_CHILDREN:
478
+ info["pPrDirect"] += 1
479
+ # rPr inside pPr (paragraph-mark formatting) also counts as direct
480
+ run_ppr = ppr.find(qn("w", "rPr"))
481
+ if run_ppr is not None and len(list(run_ppr)) > 0:
482
+ info["pPrDirect"] += 1
483
+ for run in paragraph.findall(qn("w", "r")):
484
+ info["totalRuns"] += 1
485
+ rpr = run.find(qn("w", "rPr"))
486
+ if rpr is not None:
487
+ non_style = [c for c in list(rpr) if c.tag != qn("w", "rStyle")]
488
+ if non_style:
489
+ info["rPrDirectRuns"] += 1
490
+ return info
491
+
492
+
493
+ # -- main analyze --------------------------------------------------------------
494
+
495
+ def analyze(path: Path) -> Dict[str, Any]:
496
+ diagnostics: List[Dict[str, str]] = []
497
+
498
+ def diag(severity: str, code: str, message: str, **extra: Any) -> None:
499
+ item = {"severity": severity, "code": code, "message": message}
500
+ item.update(extra)
501
+ diagnostics.append(item)
502
+
503
+ with ZipFile(path, "r") as archive:
504
+ document = load_xml(archive, "word/document.xml")
505
+ if document is None:
506
+ raise RuntimeError("Not a valid DOCX: word/document.xml missing")
507
+ body = document.find(qn("w", "body"))
508
+ if body is None:
509
+ raise RuntimeError("Document body missing")
510
+
511
+ styles_doc = load_xml(archive, "word/styles.xml")
512
+ numbering_doc = load_xml(archive, "word/numbering.xml")
513
+ comments_doc = load_xml(archive, "word/comments.xml")
514
+ comments_ext_doc = load_xml(archive, "word/commentsExtended.xml")
515
+ footnotes_doc = load_xml(archive, "word/footnotes.xml")
516
+ endnotes_doc = load_xml(archive, "word/endnotes.xml")
517
+ settings_doc = load_xml(archive, "word/settings.xml")
518
+
519
+ content_types = parse_content_types(archive)
520
+ rels_doc = parse_rels(archive, "word/_rels/document.xml.rels")
521
+ package_rels = parse_rels(archive, "_rels/.rels")
522
+ rels_by_id = {r["id"]: r for r in rels_doc}
523
+
524
+ styles = parse_styles(styles_doc)
525
+ numbering = parse_numbering(numbering_doc)
526
+ comments = parse_comments(comments_doc)
527
+ comments_ext = parse_comments_extended(comments_ext_doc)
528
+
529
+ # --- traverse body --------------------------------------------------
530
+
531
+ paragraphs = list(body.iter(qn("w", "p")))
532
+ tables = list(body.iter(qn("w", "tbl")))
533
+ sect_prs = list(body.iter(qn("w", "sectPr")))
534
+ drawings = list(body.iter(qn("w", "drawing")))
535
+
536
+ used_para_styles: Counter = Counter()
537
+ used_run_styles: Counter = Counter()
538
+ numbered_paragraphs: List[Dict[str, Any]] = []
539
+ contamination_total = {"pPrDirect": 0, "rPrDirectRuns": 0, "paragraphsDirty": 0, "totalRuns": 0}
540
+ heading_paragraphs: List[Dict[str, Any]] = []
541
+ para_ids: List[str] = []
542
+
543
+ for index, paragraph in enumerate(paragraphs):
544
+ ppr = paragraph.find(qn("w", "pPr"))
545
+ style_node = ppr.find(qn("w", "pStyle")) if ppr is not None else None
546
+ style_id = w_attr(style_node, "val") if style_node is not None else None
547
+ if style_id:
548
+ used_para_styles[style_id] += 1
549
+ for run in paragraph.findall(qn("w", "r")):
550
+ rpr = run.find(qn("w", "rPr"))
551
+ if rpr is not None:
552
+ rstyle = rpr.find(qn("w", "rStyle"))
553
+ if rstyle is not None:
554
+ rs_val = w_attr(rstyle, "val")
555
+ if rs_val:
556
+ used_run_styles[rs_val] += 1
557
+ num_pr = ppr.find(qn("w", "numPr")) if ppr is not None else None
558
+ if num_pr is not None:
559
+ num_id_node = num_pr.find(qn("w", "numId"))
560
+ ilvl_node = num_pr.find(qn("w", "ilvl"))
561
+ numbered_paragraphs.append({
562
+ "index": index,
563
+ "numId": w_attr(num_id_node, "val") if num_id_node is not None else None,
564
+ "ilvl": w_attr(ilvl_node, "val") if ilvl_node is not None else None,
565
+ "styleId": style_id,
566
+ })
567
+
568
+ para_id = paragraph.get(qn("w14", "paraId"))
569
+ if para_id:
570
+ para_ids.append(para_id)
571
+
572
+ cont = paragraph_contamination(paragraph)
573
+ contamination_total["pPrDirect"] += cont["pPrDirect"]
574
+ contamination_total["rPrDirectRuns"] += cont["rPrDirectRuns"]
575
+ contamination_total["totalRuns"] += cont["totalRuns"]
576
+ if cont["pPrDirect"] or cont["rPrDirectRuns"]:
577
+ contamination_total["paragraphsDirty"] += 1
578
+
579
+ text = text_of(paragraph)
580
+ outline_lvl = None
581
+ if style_id and style_id in styles["byId"]:
582
+ outline_lvl = styles["byId"][style_id].get("outlineLvl")
583
+ if outline_lvl is None and ppr is not None:
584
+ outline_node = ppr.find(qn("w", "outlineLvl"))
585
+ if outline_node is not None:
586
+ outline_lvl = w_attr(outline_node, "val")
587
+ heading_like = bool(style_id and (
588
+ "heading" in style_id.lower() or style_id.lower() in {"title", "subtitle"}
589
+ ))
590
+ if text and (outline_lvl is not None or heading_like):
591
+ heading_paragraphs.append({
592
+ "paraIndex": index,
593
+ "styleId": style_id,
594
+ "outlineLvl": int(outline_lvl) if outline_lvl and str(outline_lvl).isdigit() else None,
595
+ "text": text[:240],
596
+ })
597
+
598
+ # --- sections -------------------------------------------------------
599
+
600
+ sections: List[Dict[str, Any]] = []
601
+ for sect_index, sect_pr in enumerate(sect_prs, start=1):
602
+ entry = parse_section(sect_pr)
603
+ entry["index"] = sect_index
604
+ sections.append(entry)
605
+
606
+ # --- header/footer parts via rels ----------------------------------
607
+
608
+ header_footer_parts = []
609
+ for rel in rels_doc:
610
+ if rel["type"].endswith("/header") or rel["type"].endswith("/footer"):
611
+ target = rel["target"]
612
+ if not target.startswith("/"):
613
+ full = f"word/{target.lstrip('./')}"
614
+ else:
615
+ full = target.lstrip("/")
616
+ part_xml = load_xml(archive, full)
617
+ if part_xml is None:
618
+ diag("error", "missing-header-footer-part",
619
+ f"rel {rel['id']} -> {target} but part not found", target=target)
620
+ continue
621
+ paragraphs_in_part = list(part_xml.iter(qn("w", "p")))
622
+ simple_in_part = collect_simple_fields(part_xml)
623
+ complex_in_part = collect_complex_fields(part_xml)
624
+ part_fields = simple_in_part + complex_in_part
625
+ images_in_part = sum(1 for _ in part_xml.iter(qn("w", "drawing")))
626
+ hyperlinks_in_part = sum(1 for _ in part_xml.iter(qn("w", "hyperlink")))
627
+ header_footer_parts.append({
628
+ "kind": "header" if rel["type"].endswith("/header") else "footer",
629
+ "rId": rel["id"],
630
+ "target": target,
631
+ "paragraphs": len(paragraphs_in_part),
632
+ "fields": len(part_fields),
633
+ "fieldKinds": dict(Counter(f["kind"] for f in part_fields)),
634
+ "drawings": images_in_part,
635
+ "hyperlinks": hyperlinks_in_part,
636
+ })
637
+
638
+ # Cross-check: every header/footerReference in any section MUST resolve.
639
+ ref_rids = set()
640
+ for sect in sections:
641
+ for ref in sect["headerReferences"] + sect["footerReferences"]:
642
+ rid = ref.get("rId")
643
+ if rid:
644
+ ref_rids.add(rid)
645
+ if rid not in rels_by_id:
646
+ diag("error", "section-ref-broken",
647
+ f"section {sect['index']} references rId {rid} but rels has no such id",
648
+ sectionIndex=sect["index"], rId=rid)
649
+
650
+ # --- numbering analysis --------------------------------------------
651
+
652
+ num_usage: Counter = Counter()
653
+ num_per_level: Dict[Tuple[str, str], int] = defaultdict(int)
654
+ for entry in numbered_paragraphs:
655
+ nid = entry.get("numId") or ""
656
+ num_usage[nid] += 1
657
+ ilvl = entry.get("ilvl") or "0"
658
+ num_per_level[(nid, ilvl)] += 1
659
+ numbering_usage = {
660
+ "perNumId": dict(num_usage),
661
+ "perNumIdLevel": [
662
+ {"numId": k[0], "ilvl": k[1], "paragraphs": v}
663
+ for k, v in sorted(num_per_level.items())
664
+ ],
665
+ }
666
+
667
+ for nid in num_usage:
668
+ if nid not in numbering["nums"]:
669
+ diag("error", "numbering-numid-missing",
670
+ f"numId {nid} used in body but not defined in numbering.xml",
671
+ numId=nid)
672
+ else:
673
+ an_id = numbering["nums"][nid].get("abstractNumId")
674
+ if an_id and an_id not in numbering["abstractNums"]:
675
+ diag("error", "numbering-abstractnum-missing",
676
+ f"numId {nid} -> abstractNumId {an_id} (definition missing)",
677
+ numId=nid, abstractNumId=an_id)
678
+ for nid, info in numbering["nums"].items():
679
+ if nid not in num_usage:
680
+ diag("info", "numbering-numid-unused",
681
+ f"numId {nid} defined in numbering.xml but not referenced in document body",
682
+ numId=nid)
683
+
684
+ # --- styles audit ---------------------------------------------------
685
+
686
+ defined_ids = set(styles["byId"].keys())
687
+ referenced_para_styles = set(used_para_styles)
688
+ referenced_run_styles = set(used_run_styles)
689
+ # styles linked from numbering pStyle pull
690
+ for an in numbering["abstractNums"].values():
691
+ for lvl in an["levels"]:
692
+ if lvl.get("pStyle"):
693
+ referenced_para_styles.add(lvl["pStyle"])
694
+ all_referenced = referenced_para_styles | referenced_run_styles
695
+ missing_styles = sorted(s for s in all_referenced if s not in defined_ids)
696
+ for s in missing_styles:
697
+ diag("error", "style-missing",
698
+ f"style '{s}' is referenced but not defined in styles.xml",
699
+ styleId=s)
700
+ unused_defined = sorted(s for s in defined_ids if s not in all_referenced)
701
+
702
+ heading_outline_audit = []
703
+ for sid, info in styles["byId"].items():
704
+ name = (info.get("name") or "").lower()
705
+ if "heading" in (sid.lower() + name) and info.get("outlineLvl") is None:
706
+ heading_outline_audit.append(sid)
707
+ diag("warn", "heading-style-without-outline",
708
+ f"heading-like style '{sid}' has no <w:outlineLvl/>; TOC and nav pane will misbehave",
709
+ styleId=sid)
710
+
711
+ # --- references -----------------------------------------------------
712
+
713
+ complex_fields = collect_complex_fields(body)
714
+ simple_fields = collect_simple_fields(body)
715
+ all_fields = simple_fields + complex_fields
716
+ field_kinds = Counter(f["kind"] for f in all_fields)
717
+ dirty_fields = sum(1 for f in all_fields if f.get("dirty"))
718
+
719
+ bookmarks = collect_bookmarks(body)
720
+ if bookmarks["orphanStarts"]:
721
+ diag("warn", "bookmark-orphan-start",
722
+ f"{len(bookmarks['orphanStarts'])} bookmarkStart without matching bookmarkEnd",
723
+ ids=[b.get("id") for b in bookmarks["orphanStarts"]])
724
+ if bookmarks["orphanEnds"]:
725
+ diag("warn", "bookmark-orphan-end",
726
+ f"{len(bookmarks['orphanEnds'])} bookmarkEnd without matching bookmarkStart",
727
+ ids=bookmarks["orphanEnds"])
728
+
729
+ hyperlinks = collect_hyperlinks(body, rels_by_id)
730
+ for hl in hyperlinks:
731
+ if hl["rId"] and hl["url"] is None:
732
+ diag("error", "hyperlink-rel-broken",
733
+ f"hyperlink references rId {hl['rId']} but rel target missing",
734
+ rId=hl["rId"])
735
+
736
+ # --- comments topology ---------------------------------------------
737
+
738
+ comment_starts = list(body.iter(qn("w", "commentRangeStart")))
739
+ comment_ends = list(body.iter(qn("w", "commentRangeEnd")))
740
+ comment_refs = list(body.iter(qn("w", "commentReference")))
741
+ comment_ids_in_body = {w_attr(c, "id") for c in comment_starts}
742
+ comment_ids_defined = {c["id"] for c in comments}
743
+ comment_orphan_in_body = sorted(comment_ids_in_body - comment_ids_defined)
744
+ comment_orphan_in_defs = sorted(comment_ids_defined - comment_ids_in_body)
745
+ for cid in comment_orphan_in_body:
746
+ diag("error", "comment-id-undefined",
747
+ f"commentRangeStart id={cid} not defined in comments.xml",
748
+ commentId=cid)
749
+ for cid in comment_orphan_in_defs:
750
+ diag("info", "comment-defined-not-anchored",
751
+ f"comment {cid} defined but no commentRangeStart in document body",
752
+ commentId=cid)
753
+
754
+ # --- revisions ------------------------------------------------------
755
+
756
+ revision_kinds = [
757
+ "ins", "del", "moveFrom", "moveTo",
758
+ "cellIns", "cellDel", "cellMerge",
759
+ "rPrChange", "pPrChange", "tblPrChange",
760
+ "trPrChange", "tcPrChange", "sectPrChange", "numberingChange",
761
+ ]
762
+ revision_counts: Dict[str, int] = {}
763
+ revision_actors: Counter = Counter()
764
+ revision_dates: List[str] = []
765
+ for kind in revision_kinds:
766
+ elems = list(body.iter(qn("w", kind)))
767
+ revision_counts[kind] = len(elems)
768
+ for el in elems:
769
+ author = el.get(WAUTHOR)
770
+ if author:
771
+ revision_actors[author] += 1
772
+ date = el.get(WDATE)
773
+ if date:
774
+ revision_dates.append(date)
775
+ date_min = min(revision_dates) if revision_dates else None
776
+ date_max = max(revision_dates) if revision_dates else None
777
+
778
+ # --- footnotes / endnotes ------------------------------------------
779
+
780
+ def count_notes(doc: Optional[ET.Element], tag: str) -> int:
781
+ if doc is None:
782
+ return 0
783
+ return sum(1 for n in doc.findall(qn("w", tag))
784
+ if w_attr(n, "type") not in {"separator", "continuationSeparator"})
785
+
786
+ footnotes_count = count_notes(footnotes_doc, "footnote")
787
+ endnotes_count = count_notes(endnotes_doc, "endnote")
788
+
789
+ # --- settings flags relevant to structure --------------------------
790
+
791
+ settings_flags: Dict[str, Any] = {}
792
+ if settings_doc is not None:
793
+ for flag in ("trackChanges", "evenAndOddHeaders", "mirrorMargins",
794
+ "updateFields", "compatSetting", "footnotePr", "endnotePr"):
795
+ node = settings_doc.find(qn("w", flag))
796
+ settings_flags[flag] = node is not None
797
+
798
+ # --- packaging audit ------------------------------------------------
799
+
800
+ overrides = content_types["overrides"]
801
+ rel_targets = set()
802
+ for rel in rels_doc:
803
+ if rel["targetMode"] == "Internal":
804
+ target = rel["target"]
805
+ full = "word/" + target.lstrip("./") if not target.startswith("/") else target.lstrip("/")
806
+ rel_targets.add(full)
807
+ overrides_paths = {p.lstrip("/") for p in overrides.keys()}
808
+ for tgt in rel_targets:
809
+ if tgt not in overrides_paths and tgt + "" not in overrides_paths:
810
+ # allow non-override parts (e.g. images, fonts handled by Default content type)
811
+ pass
812
+
813
+ # ------------------------------------------------------------------
814
+ return {
815
+ "file": str(path),
816
+ "summary": {
817
+ "paragraphs": len(paragraphs),
818
+ "tables": len(tables),
819
+ "drawings": len(drawings),
820
+ "sections": len(sections),
821
+ "definedStyles": len(styles["byId"]),
822
+ "fields": len(all_fields),
823
+ "bookmarks": len(bookmarks["pairs"]) + len(bookmarks["orphanStarts"]),
824
+ "hyperlinks": len(hyperlinks),
825
+ "comments": len(comments),
826
+ "footnotes": footnotes_count,
827
+ "endnotes": endnotes_count,
828
+ "diagnostics": len(diagnostics),
829
+ },
830
+ "packaging": {
831
+ "contentTypes": content_types,
832
+ "packageRels": package_rels,
833
+ "documentRels": rels_doc,
834
+ "parts": collect_parts_inventory(archive),
835
+ },
836
+ "sections": sections,
837
+ "headerFooterParts": header_footer_parts,
838
+ "styles": {
839
+ "byId": styles["byId"],
840
+ "defaults": styles["defaults"],
841
+ "usedParagraphStyles": used_para_styles.most_common(),
842
+ "usedRunStyles": used_run_styles.most_common(),
843
+ "missingReferenced": missing_styles,
844
+ "definedButUnused": unused_defined,
845
+ "headingsWithoutOutlineLvl": heading_outline_audit,
846
+ "missing": styles["missing"],
847
+ },
848
+ "numbering": {
849
+ "abstractNums": numbering["abstractNums"],
850
+ "nums": numbering["nums"],
851
+ "usage": numbering_usage,
852
+ "missing": numbering["missing"],
853
+ },
854
+ "headings": heading_paragraphs,
855
+ "fields": {
856
+ "simple": simple_fields,
857
+ "complex": complex_fields,
858
+ "kindCounts": dict(field_kinds),
859
+ "kindCountsAllParts": dict(
860
+ field_kinds + sum(
861
+ (Counter(p.get("fieldKinds", {})) for p in header_footer_parts),
862
+ Counter(),
863
+ )
864
+ ),
865
+ "dirty": dirty_fields,
866
+ },
867
+ "bookmarks": bookmarks,
868
+ "hyperlinks": hyperlinks,
869
+ "comments": {
870
+ "definitions": comments,
871
+ "extended": comments_ext,
872
+ "rangeStartsInBody": len(comment_starts),
873
+ "rangeEndsInBody": len(comment_ends),
874
+ "referencesInBody": len(comment_refs),
875
+ "orphansInBody": comment_orphan_in_body,
876
+ "definedNotAnchored": comment_orphan_in_defs,
877
+ },
878
+ "revisions": {
879
+ "counts": revision_counts,
880
+ "actors": dict(revision_actors),
881
+ "dateRange": {"min": date_min, "max": date_max},
882
+ },
883
+ "contamination": {
884
+ **contamination_total,
885
+ "paragraphTotal": len(paragraphs),
886
+ "dirtyRatio": round(
887
+ contamination_total["paragraphsDirty"] / len(paragraphs), 4
888
+ ) if paragraphs else 0.0,
889
+ },
890
+ "settingsFlags": settings_flags,
891
+ "diagnostics": diagnostics,
892
+ }
893
+
894
+
895
+ # -- text rendering ------------------------------------------------------------
896
+
897
+ def render_text(report: Dict[str, Any]) -> str:
898
+ out: List[str] = []
899
+ s = report["summary"]
900
+ out.append(f"File: {report['file']}")
901
+ out.append(f"Paragraphs: {s['paragraphs']} Tables: {s['tables']} Drawings: {s['drawings']}")
902
+ out.append(f"Sections: {s['sections']} Defined styles: {s['definedStyles']}")
903
+ out.append(
904
+ f"Fields: {s['fields']} Bookmarks: {s['bookmarks']} Hyperlinks: {s['hyperlinks']}"
905
+ )
906
+ out.append(
907
+ f"Comments: {s['comments']} Footnotes: {s['footnotes']} Endnotes: {s['endnotes']}"
908
+ )
909
+ out.append(f"Diagnostics: {s['diagnostics']}")
910
+ out.append("")
911
+
912
+ out.append("Sections:")
913
+ for sect in report["sections"]:
914
+ margins = sect.get("margins") or {}
915
+ page = sect.get("pageSize") or {}
916
+ out.append(
917
+ f" #{sect['index']} type={sect['type']} "
918
+ f"page={page.get('widthMm')}x{page.get('heightMm')}mm "
919
+ f"margins(top/right/bottom/left)={margins.get('top')}/{margins.get('right')}/{margins.get('bottom')}/{margins.get('left')} "
920
+ f"titlePg={sect['titlePg']} cols={sect['columns']}"
921
+ )
922
+ for ref in sect["headerReferences"]:
923
+ out.append(f" header[{ref['type']}] -> {ref['rId']}")
924
+ for ref in sect["footerReferences"]:
925
+ out.append(f" footer[{ref['type']}] -> {ref['rId']}")
926
+ if report["headerFooterParts"]:
927
+ out.append("Header/footer parts:")
928
+ for p in report["headerFooterParts"]:
929
+ out.append(
930
+ f" {p['kind']:<6} rId={p['rId']:<6} target={p['target']} "
931
+ f"paragraphs={p['paragraphs']} fields={p['fields']} drawings={p['drawings']}"
932
+ )
933
+
934
+ out.append("")
935
+ out.append("Styles audit:")
936
+ out.append(f" used paragraph styles: {len(report['styles']['usedParagraphStyles'])}")
937
+ out.append(f" used run styles: {len(report['styles']['usedRunStyles'])}")
938
+ out.append(f" missing referenced: {report['styles']['missingReferenced']}")
939
+ out.append(f" defined-but-unused: {len(report['styles']['definedButUnused'])}")
940
+ out.append(f" headings missing outlineLvl: {report['styles']['headingsWithoutOutlineLvl']}")
941
+
942
+ out.append("")
943
+ out.append("Numbering:")
944
+ out.append(f" abstractNums: {len(report['numbering']['abstractNums'])}")
945
+ out.append(f" nums: {len(report['numbering']['nums'])}")
946
+ out.append(f" numbered paragraphs by numId: {report['numbering']['usage']['perNumId']}")
947
+
948
+ out.append("")
949
+ out.append("Field kinds: " + ", ".join(f"{k}={v}" for k, v in report["fields"]["kindCounts"].items()))
950
+ out.append(f"Dirty fields: {report['fields']['dirty']}")
951
+
952
+ out.append("")
953
+ out.append("Comments:")
954
+ out.append(
955
+ f" definitions={len(report['comments']['definitions'])} "
956
+ f"rangeStartsInBody={report['comments']['rangeStartsInBody']} "
957
+ f"orphansInBody={report['comments']['orphansInBody']}"
958
+ )
959
+
960
+ out.append("")
961
+ out.append("Contamination:")
962
+ c = report["contamination"]
963
+ out.append(
964
+ f" paragraphsDirty={c['paragraphsDirty']}/{c['paragraphTotal']} "
965
+ f"({c['dirtyRatio']*100:.1f}%) pPrDirect={c['pPrDirect']} rPrDirectRuns={c['rPrDirectRuns']}"
966
+ )
967
+
968
+ out.append("")
969
+ out.append("Diagnostics:")
970
+ if not report["diagnostics"]:
971
+ out.append(" (none)")
972
+ for d in report["diagnostics"]:
973
+ out.append(f" [{d['severity']}] {d['code']}: {d['message']}")
974
+
975
+ return "\n".join(out)
976
+
977
+
978
+ # -- CLI -----------------------------------------------------------------------
979
+
980
+ SECTION_KEYS = {
981
+ "summary", "packaging", "sections", "headerFooterParts", "styles",
982
+ "numbering", "headings", "fields", "bookmarks", "hyperlinks",
983
+ "comments", "revisions", "contamination", "settingsFlags", "diagnostics",
984
+ }
985
+
986
+
987
+ def main(argv: Optional[List[str]] = None) -> int:
988
+ parser = argparse.ArgumentParser(
989
+ description=(
990
+ "Deep DOCX structure analyzer. Primary structure-truth implementation; "
991
+ "no dotnet required."
992
+ )
993
+ )
994
+ parser.add_argument("input_path", help="Path to the .docx file")
995
+ parser.add_argument("--json", action="store_true", help="Emit JSON instead of text")
996
+ parser.add_argument(
997
+ "--section", default="",
998
+ help=(
999
+ "Comma-separated subset of top-level keys to include. "
1000
+ "Allowed: " + ",".join(sorted(SECTION_KEYS))
1001
+ ),
1002
+ )
1003
+ args = parser.parse_args(argv)
1004
+
1005
+ input_path = Path(args.input_path).expanduser().resolve()
1006
+ if not input_path.exists():
1007
+ raise RuntimeError(f"Input file does not exist: {input_path}")
1008
+ if input_path.suffix.lower() != ".docx":
1009
+ raise RuntimeError("read_docx_structure.py currently supports .docx only")
1010
+
1011
+ report = analyze(input_path)
1012
+
1013
+ if args.section:
1014
+ wanted = {s.strip() for s in args.section.split(",") if s.strip()}
1015
+ unknown = wanted - SECTION_KEYS
1016
+ if unknown:
1017
+ raise RuntimeError(f"Unknown --section keys: {sorted(unknown)}")
1018
+ report = {k: v for k, v in report.items() if k in wanted or k == "file"}
1019
+
1020
+ if args.json:
1021
+ print(json.dumps(report, ensure_ascii=False, indent=2))
1022
+ else:
1023
+ print(render_text(report))
1024
+ return 0
1025
+
1026
+
1027
+ if __name__ == "__main__":
1028
+ try:
1029
+ raise SystemExit(main())
1030
+ except Exception as exc: # pragma: no cover - CLI error path
1031
+ print(f"read_docx_structure.py failed: {exc}", file=sys.stderr)
1032
+ raise SystemExit(1)