docagent-cli 0.0.35__py3-none-any.whl

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 (300) hide show
  1. docagent_cli/__init__.py +36 -0
  2. docagent_cli/__main__.py +6 -0
  3. docagent_cli/_ask_user_types.py +90 -0
  4. docagent_cli/_cli_context.py +27 -0
  5. docagent_cli/_debug.py +52 -0
  6. docagent_cli/_env_vars.py +56 -0
  7. docagent_cli/_server_config.py +352 -0
  8. docagent_cli/_session_stats.py +114 -0
  9. docagent_cli/_testing_models.py +144 -0
  10. docagent_cli/_version.py +17 -0
  11. docagent_cli/agent.py +1193 -0
  12. docagent_cli/app.py +4979 -0
  13. docagent_cli/app.tcss +283 -0
  14. docagent_cli/ask_user.py +301 -0
  15. docagent_cli/built_in_skills/__init__.py +5 -0
  16. docagent_cli/built_in_skills/doc-coauthoring/SKILL.md +375 -0
  17. docagent_cli/built_in_skills/docx/LICENSE.txt +30 -0
  18. docagent_cli/built_in_skills/docx/SKILL.md +590 -0
  19. docagent_cli/built_in_skills/docx/scripts/__init__.py +1 -0
  20. docagent_cli/built_in_skills/docx/scripts/accept_changes.py +135 -0
  21. docagent_cli/built_in_skills/docx/scripts/comment.py +318 -0
  22. docagent_cli/built_in_skills/docx/scripts/office/helpers/__init__.py +0 -0
  23. docagent_cli/built_in_skills/docx/scripts/office/helpers/merge_runs.py +199 -0
  24. docagent_cli/built_in_skills/docx/scripts/office/helpers/simplify_redlines.py +197 -0
  25. docagent_cli/built_in_skills/docx/scripts/office/pack.py +159 -0
  26. docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
  27. docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
  28. docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
  29. docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
  30. docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
  31. docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
  32. docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
  33. docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
  34. docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
  35. docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
  36. docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
  37. docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
  38. docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
  39. docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
  40. docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
  41. docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
  42. docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
  43. docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
  44. docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
  45. docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
  46. docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
  47. docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
  48. docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
  49. docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
  50. docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
  51. docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
  52. docagent_cli/built_in_skills/docx/scripts/office/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
  53. docagent_cli/built_in_skills/docx/scripts/office/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
  54. docagent_cli/built_in_skills/docx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
  55. docagent_cli/built_in_skills/docx/scripts/office/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
  56. docagent_cli/built_in_skills/docx/scripts/office/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
  57. docagent_cli/built_in_skills/docx/scripts/office/schemas/mce/mc.xsd +75 -0
  58. docagent_cli/built_in_skills/docx/scripts/office/schemas/microsoft/wml-2010.xsd +560 -0
  59. docagent_cli/built_in_skills/docx/scripts/office/schemas/microsoft/wml-2012.xsd +67 -0
  60. docagent_cli/built_in_skills/docx/scripts/office/schemas/microsoft/wml-2018.xsd +14 -0
  61. docagent_cli/built_in_skills/docx/scripts/office/schemas/microsoft/wml-cex-2018.xsd +20 -0
  62. docagent_cli/built_in_skills/docx/scripts/office/schemas/microsoft/wml-cid-2016.xsd +13 -0
  63. docagent_cli/built_in_skills/docx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
  64. docagent_cli/built_in_skills/docx/scripts/office/schemas/microsoft/wml-symex-2015.xsd +8 -0
  65. docagent_cli/built_in_skills/docx/scripts/office/soffice.py +183 -0
  66. docagent_cli/built_in_skills/docx/scripts/office/unpack.py +132 -0
  67. docagent_cli/built_in_skills/docx/scripts/office/validate.py +111 -0
  68. docagent_cli/built_in_skills/docx/scripts/office/validators/__init__.py +15 -0
  69. docagent_cli/built_in_skills/docx/scripts/office/validators/base.py +847 -0
  70. docagent_cli/built_in_skills/docx/scripts/office/validators/docx.py +446 -0
  71. docagent_cli/built_in_skills/docx/scripts/office/validators/pptx.py +275 -0
  72. docagent_cli/built_in_skills/docx/scripts/office/validators/redlining.py +247 -0
  73. docagent_cli/built_in_skills/docx/scripts/templates/comments.xml +3 -0
  74. docagent_cli/built_in_skills/docx/scripts/templates/commentsExtended.xml +3 -0
  75. docagent_cli/built_in_skills/docx/scripts/templates/commentsExtensible.xml +3 -0
  76. docagent_cli/built_in_skills/docx/scripts/templates/commentsIds.xml +3 -0
  77. docagent_cli/built_in_skills/docx/scripts/templates/people.xml +3 -0
  78. docagent_cli/built_in_skills/pdf/LICENSE.txt +30 -0
  79. docagent_cli/built_in_skills/pdf/SKILL.md +314 -0
  80. docagent_cli/built_in_skills/pdf/forms.md +294 -0
  81. docagent_cli/built_in_skills/pdf/reference.md +612 -0
  82. docagent_cli/built_in_skills/pdf/scripts/check_bounding_boxes.py +65 -0
  83. docagent_cli/built_in_skills/pdf/scripts/check_fillable_fields.py +11 -0
  84. docagent_cli/built_in_skills/pdf/scripts/convert_pdf_to_images.py +33 -0
  85. docagent_cli/built_in_skills/pdf/scripts/create_validation_image.py +37 -0
  86. docagent_cli/built_in_skills/pdf/scripts/extract_form_field_info.py +122 -0
  87. docagent_cli/built_in_skills/pdf/scripts/extract_form_structure.py +115 -0
  88. docagent_cli/built_in_skills/pdf/scripts/fill_fillable_fields.py +98 -0
  89. docagent_cli/built_in_skills/pdf/scripts/fill_pdf_form_with_annotations.py +107 -0
  90. docagent_cli/built_in_skills/pptx/LICENSE.txt +30 -0
  91. docagent_cli/built_in_skills/pptx/SKILL.md +232 -0
  92. docagent_cli/built_in_skills/pptx/editing.md +205 -0
  93. docagent_cli/built_in_skills/pptx/pptxgenjs.md +420 -0
  94. docagent_cli/built_in_skills/pptx/scripts/__init__.py +0 -0
  95. docagent_cli/built_in_skills/pptx/scripts/add_slide.py +195 -0
  96. docagent_cli/built_in_skills/pptx/scripts/clean.py +286 -0
  97. docagent_cli/built_in_skills/pptx/scripts/office/helpers/__init__.py +0 -0
  98. docagent_cli/built_in_skills/pptx/scripts/office/helpers/merge_runs.py +199 -0
  99. docagent_cli/built_in_skills/pptx/scripts/office/helpers/simplify_redlines.py +197 -0
  100. docagent_cli/built_in_skills/pptx/scripts/office/pack.py +159 -0
  101. docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
  102. docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
  103. docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
  104. docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
  105. docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
  106. docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
  107. docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
  108. docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
  109. docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
  110. docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
  111. docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
  112. docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
  113. docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
  114. docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
  115. docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
  116. docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
  117. docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
  118. docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
  119. docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
  120. docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
  121. docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
  122. docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
  123. docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
  124. docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
  125. docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
  126. docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
  127. docagent_cli/built_in_skills/pptx/scripts/office/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
  128. docagent_cli/built_in_skills/pptx/scripts/office/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
  129. docagent_cli/built_in_skills/pptx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
  130. docagent_cli/built_in_skills/pptx/scripts/office/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
  131. docagent_cli/built_in_skills/pptx/scripts/office/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
  132. docagent_cli/built_in_skills/pptx/scripts/office/schemas/mce/mc.xsd +75 -0
  133. docagent_cli/built_in_skills/pptx/scripts/office/schemas/microsoft/wml-2010.xsd +560 -0
  134. docagent_cli/built_in_skills/pptx/scripts/office/schemas/microsoft/wml-2012.xsd +67 -0
  135. docagent_cli/built_in_skills/pptx/scripts/office/schemas/microsoft/wml-2018.xsd +14 -0
  136. docagent_cli/built_in_skills/pptx/scripts/office/schemas/microsoft/wml-cex-2018.xsd +20 -0
  137. docagent_cli/built_in_skills/pptx/scripts/office/schemas/microsoft/wml-cid-2016.xsd +13 -0
  138. docagent_cli/built_in_skills/pptx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
  139. docagent_cli/built_in_skills/pptx/scripts/office/schemas/microsoft/wml-symex-2015.xsd +8 -0
  140. docagent_cli/built_in_skills/pptx/scripts/office/soffice.py +183 -0
  141. docagent_cli/built_in_skills/pptx/scripts/office/unpack.py +132 -0
  142. docagent_cli/built_in_skills/pptx/scripts/office/validate.py +111 -0
  143. docagent_cli/built_in_skills/pptx/scripts/office/validators/__init__.py +15 -0
  144. docagent_cli/built_in_skills/pptx/scripts/office/validators/base.py +847 -0
  145. docagent_cli/built_in_skills/pptx/scripts/office/validators/docx.py +446 -0
  146. docagent_cli/built_in_skills/pptx/scripts/office/validators/pptx.py +275 -0
  147. docagent_cli/built_in_skills/pptx/scripts/office/validators/redlining.py +247 -0
  148. docagent_cli/built_in_skills/pptx/scripts/thumbnail.py +289 -0
  149. docagent_cli/built_in_skills/remember/SKILL.md +118 -0
  150. docagent_cli/built_in_skills/skill-creator/LICENSE.txt +202 -0
  151. docagent_cli/built_in_skills/skill-creator/SKILL.md +485 -0
  152. docagent_cli/built_in_skills/skill-creator/agents/analyzer.md +274 -0
  153. docagent_cli/built_in_skills/skill-creator/agents/comparator.md +202 -0
  154. docagent_cli/built_in_skills/skill-creator/agents/grader.md +223 -0
  155. docagent_cli/built_in_skills/skill-creator/assets/eval_review.html +146 -0
  156. docagent_cli/built_in_skills/skill-creator/eval-viewer/generate_review.py +471 -0
  157. docagent_cli/built_in_skills/skill-creator/eval-viewer/viewer.html +1325 -0
  158. docagent_cli/built_in_skills/skill-creator/references/schemas.md +430 -0
  159. docagent_cli/built_in_skills/skill-creator/scripts/__init__.py +0 -0
  160. docagent_cli/built_in_skills/skill-creator/scripts/aggregate_benchmark.py +401 -0
  161. docagent_cli/built_in_skills/skill-creator/scripts/generate_report.py +326 -0
  162. docagent_cli/built_in_skills/skill-creator/scripts/improve_description.py +247 -0
  163. docagent_cli/built_in_skills/skill-creator/scripts/package_skill.py +136 -0
  164. docagent_cli/built_in_skills/skill-creator/scripts/quick_validate.py +103 -0
  165. docagent_cli/built_in_skills/skill-creator/scripts/run_eval.py +310 -0
  166. docagent_cli/built_in_skills/skill-creator/scripts/run_loop.py +328 -0
  167. docagent_cli/built_in_skills/skill-creator/scripts/utils.py +47 -0
  168. docagent_cli/built_in_skills/theme-factory/LICENSE.txt +202 -0
  169. docagent_cli/built_in_skills/theme-factory/SKILL.md +59 -0
  170. docagent_cli/built_in_skills/theme-factory/theme-showcase.pdf +0 -0
  171. docagent_cli/built_in_skills/theme-factory/themes/arctic-frost.md +19 -0
  172. docagent_cli/built_in_skills/theme-factory/themes/botanical-garden.md +19 -0
  173. docagent_cli/built_in_skills/theme-factory/themes/desert-rose.md +19 -0
  174. docagent_cli/built_in_skills/theme-factory/themes/forest-canopy.md +19 -0
  175. docagent_cli/built_in_skills/theme-factory/themes/golden-hour.md +19 -0
  176. docagent_cli/built_in_skills/theme-factory/themes/midnight-galaxy.md +19 -0
  177. docagent_cli/built_in_skills/theme-factory/themes/modern-minimalist.md +19 -0
  178. docagent_cli/built_in_skills/theme-factory/themes/ocean-depths.md +19 -0
  179. docagent_cli/built_in_skills/theme-factory/themes/sunset-boulevard.md +19 -0
  180. docagent_cli/built_in_skills/theme-factory/themes/tech-innovation.md +19 -0
  181. docagent_cli/built_in_skills/xlsx/LICENSE.txt +30 -0
  182. docagent_cli/built_in_skills/xlsx/SKILL.md +292 -0
  183. docagent_cli/built_in_skills/xlsx/scripts/office/helpers/__init__.py +0 -0
  184. docagent_cli/built_in_skills/xlsx/scripts/office/helpers/merge_runs.py +199 -0
  185. docagent_cli/built_in_skills/xlsx/scripts/office/helpers/simplify_redlines.py +197 -0
  186. docagent_cli/built_in_skills/xlsx/scripts/office/pack.py +159 -0
  187. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
  188. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
  189. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
  190. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
  191. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
  192. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
  193. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
  194. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
  195. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
  196. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
  197. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
  198. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
  199. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
  200. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
  201. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
  202. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
  203. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
  204. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
  205. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
  206. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
  207. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
  208. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
  209. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
  210. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
  211. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
  212. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
  213. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
  214. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
  215. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
  216. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
  217. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
  218. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/mce/mc.xsd +75 -0
  219. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/microsoft/wml-2010.xsd +560 -0
  220. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/microsoft/wml-2012.xsd +67 -0
  221. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/microsoft/wml-2018.xsd +14 -0
  222. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/microsoft/wml-cex-2018.xsd +20 -0
  223. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/microsoft/wml-cid-2016.xsd +13 -0
  224. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
  225. docagent_cli/built_in_skills/xlsx/scripts/office/schemas/microsoft/wml-symex-2015.xsd +8 -0
  226. docagent_cli/built_in_skills/xlsx/scripts/office/soffice.py +183 -0
  227. docagent_cli/built_in_skills/xlsx/scripts/office/unpack.py +132 -0
  228. docagent_cli/built_in_skills/xlsx/scripts/office/validate.py +111 -0
  229. docagent_cli/built_in_skills/xlsx/scripts/office/validators/__init__.py +15 -0
  230. docagent_cli/built_in_skills/xlsx/scripts/office/validators/base.py +847 -0
  231. docagent_cli/built_in_skills/xlsx/scripts/office/validators/docx.py +446 -0
  232. docagent_cli/built_in_skills/xlsx/scripts/office/validators/pptx.py +275 -0
  233. docagent_cli/built_in_skills/xlsx/scripts/office/validators/redlining.py +247 -0
  234. docagent_cli/built_in_skills/xlsx/scripts/recalc.py +184 -0
  235. docagent_cli/clipboard.py +128 -0
  236. docagent_cli/command_registry.py +284 -0
  237. docagent_cli/config.py +2418 -0
  238. docagent_cli/configurable_model.py +162 -0
  239. docagent_cli/default_agent_prompt.md +12 -0
  240. docagent_cli/editor.py +142 -0
  241. docagent_cli/file_ops.py +473 -0
  242. docagent_cli/formatting.py +28 -0
  243. docagent_cli/hooks.py +206 -0
  244. docagent_cli/input.py +787 -0
  245. docagent_cli/integrations/__init__.py +1 -0
  246. docagent_cli/integrations/sandbox_factory.py +873 -0
  247. docagent_cli/integrations/sandbox_provider.py +71 -0
  248. docagent_cli/local_context.py +718 -0
  249. docagent_cli/main.py +1641 -0
  250. docagent_cli/mcp_tools.py +707 -0
  251. docagent_cli/mcp_trust.py +168 -0
  252. docagent_cli/media_utils.py +478 -0
  253. docagent_cli/model_config.py +1620 -0
  254. docagent_cli/non_interactive.py +948 -0
  255. docagent_cli/offload.py +371 -0
  256. docagent_cli/output.py +69 -0
  257. docagent_cli/project_utils.py +188 -0
  258. docagent_cli/py.typed +0 -0
  259. docagent_cli/remote_client.py +515 -0
  260. docagent_cli/server.py +520 -0
  261. docagent_cli/server_graph.py +196 -0
  262. docagent_cli/server_manager.py +365 -0
  263. docagent_cli/sessions.py +1262 -0
  264. docagent_cli/skills/__init__.py +18 -0
  265. docagent_cli/skills/commands.py +1090 -0
  266. docagent_cli/skills/load.py +192 -0
  267. docagent_cli/subagents.py +173 -0
  268. docagent_cli/system_prompt.md +247 -0
  269. docagent_cli/textual_adapter.py +1352 -0
  270. docagent_cli/theme.py +842 -0
  271. docagent_cli/token_state.py +31 -0
  272. docagent_cli/tool_display.py +298 -0
  273. docagent_cli/tools.py +236 -0
  274. docagent_cli/ui.py +420 -0
  275. docagent_cli/unicode_security.py +516 -0
  276. docagent_cli/update_check.py +454 -0
  277. docagent_cli/widgets/__init__.py +9 -0
  278. docagent_cli/widgets/_links.py +63 -0
  279. docagent_cli/widgets/approval.py +442 -0
  280. docagent_cli/widgets/ask_user.py +398 -0
  281. docagent_cli/widgets/autocomplete.py +691 -0
  282. docagent_cli/widgets/chat_input.py +1827 -0
  283. docagent_cli/widgets/diff.py +248 -0
  284. docagent_cli/widgets/history.py +188 -0
  285. docagent_cli/widgets/loading.py +177 -0
  286. docagent_cli/widgets/mcp_viewer.py +362 -0
  287. docagent_cli/widgets/message_store.py +675 -0
  288. docagent_cli/widgets/messages.py +1751 -0
  289. docagent_cli/widgets/model_selector.py +964 -0
  290. docagent_cli/widgets/status.py +372 -0
  291. docagent_cli/widgets/theme_selector.py +164 -0
  292. docagent_cli/widgets/thread_selector.py +1905 -0
  293. docagent_cli/widgets/tool_renderers.py +148 -0
  294. docagent_cli/widgets/tool_widgets.py +274 -0
  295. docagent_cli/widgets/welcome.py +339 -0
  296. docagent_cli-0.0.35.data/data/docagent_cli/default_agent_prompt.md +12 -0
  297. docagent_cli-0.0.35.dist-info/METADATA +200 -0
  298. docagent_cli-0.0.35.dist-info/RECORD +300 -0
  299. docagent_cli-0.0.35.dist-info/WHEEL +4 -0
  300. docagent_cli-0.0.35.dist-info/entry_points.txt +3 -0
@@ -0,0 +1,516 @@
1
+ """Unicode security helpers for deceptive text and URL checks.
2
+
3
+ This module is intentionally lightweight so it can be imported in display and
4
+ approval paths without affecting startup performance.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import ipaddress
10
+ import unicodedata
11
+ from dataclasses import dataclass
12
+ from typing import Any
13
+ from urllib.parse import urlparse
14
+
15
+ _DANGEROUS_CODEPOINTS: frozenset[int] = frozenset(
16
+ {
17
+ # BiDi directional formatting controls (embeddings, overrides, pop)
18
+ *range(0x202A, 0x202F),
19
+ # BiDi isolate controls (isolates, pop isolate)
20
+ *range(0x2066, 0x206A),
21
+ # Zero-width and invisible formatting controls
22
+ 0x200B, # ZERO WIDTH SPACE
23
+ 0x200C, # ZERO WIDTH NON-JOINER
24
+ 0x200D, # ZERO WIDTH JOINER
25
+ 0x200E, # LEFT-TO-RIGHT MARK
26
+ 0x200F, # RIGHT-TO-LEFT MARK
27
+ 0x2060, # WORD JOINER
28
+ 0xFEFF, # ZERO WIDTH NO-BREAK SPACE / BOM
29
+ # Other commonly abused invisible controls
30
+ 0x00AD, # SOFT HYPHEN
31
+ 0x034F, # COMBINING GRAPHEME JOINER
32
+ 0x115F, # HANGUL CHOSEONG FILLER
33
+ 0x1160, # HANGUL JUNGSEONG FILLER
34
+ }
35
+ )
36
+ """Code points that should be treated as deceptive/invisible for CLI safety."""
37
+
38
+ _DANGEROUS_CHARACTERS: frozenset[str] = frozenset(
39
+ chr(codepoint) for codepoint in _DANGEROUS_CODEPOINTS
40
+ )
41
+
42
+ # Minimal high-risk confusables for warn-level detection.
43
+ CONFUSABLES: dict[str, str] = {
44
+ # Cyrillic
45
+ "\u0430": "a", # CYRILLIC SMALL LETTER A
46
+ "\u0435": "e", # CYRILLIC SMALL LETTER IE
47
+ "\u043e": "o", # CYRILLIC SMALL LETTER O
48
+ "\u0440": "p", # CYRILLIC SMALL LETTER ER
49
+ "\u0441": "c", # CYRILLIC SMALL LETTER ES
50
+ "\u0443": "y", # CYRILLIC SMALL LETTER U
51
+ "\u0445": "x", # CYRILLIC SMALL LETTER HA
52
+ "\u043d": "h", # CYRILLIC SMALL LETTER EN
53
+ "\u0456": "i", # CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I
54
+ "\u0458": "j", # CYRILLIC SMALL LETTER JE
55
+ "\u043a": "k", # CYRILLIC SMALL LETTER KA
56
+ "\u0455": "s", # CYRILLIC SMALL LETTER DZE
57
+ # Greek
58
+ "\u03b1": "a", # GREEK SMALL LETTER ALPHA
59
+ "\u03b5": "e", # GREEK SMALL LETTER EPSILON
60
+ "\u03bf": "o", # GREEK SMALL LETTER OMICRON
61
+ "\u03c1": "p", # GREEK SMALL LETTER RHO
62
+ "\u03c7": "x", # GREEK SMALL LETTER CHI
63
+ "\u03ba": "k", # GREEK SMALL LETTER KAPPA
64
+ "\u03bd": "v", # GREEK SMALL LETTER NU
65
+ "\u03c4": "t", # GREEK SMALL LETTER TAU
66
+ # Armenian
67
+ "\u0570": "h", # ARMENIAN SMALL LETTER HO
68
+ "\u0578": "n", # ARMENIAN SMALL LETTER VO
69
+ "\u057d": "u", # ARMENIAN SMALL LETTER SEH
70
+ # Fullwidth Latin
71
+ "\uff41": "a", # FULLWIDTH LATIN SMALL LETTER A
72
+ "\uff45": "e", # FULLWIDTH LATIN SMALL LETTER E
73
+ "\uff4f": "o", # FULLWIDTH LATIN SMALL LETTER O
74
+ }
75
+
76
+ URL_ARG_KEYS: frozenset[str] = frozenset(
77
+ {"url", "uri", "href", "link", "base_url", "endpoint"}
78
+ )
79
+ """Argument key names that likely contain URLs and should be safety-checked."""
80
+
81
+ _URL_SAFE_LOCAL_HOSTS: frozenset[str] = frozenset({"localhost"})
82
+
83
+
84
+ @dataclass(frozen=True, slots=True)
85
+ class UnicodeIssue:
86
+ """A dangerous Unicode character found in text.
87
+
88
+ Attributes:
89
+ position: Zero-based index in the original string.
90
+ character: The single raw character found in the input.
91
+ codepoint: Uppercase code point string like ``U+202E``.
92
+ name: Unicode character name.
93
+ """
94
+
95
+ position: int
96
+ character: str
97
+ codepoint: str
98
+ name: str
99
+
100
+ def __post_init__(self) -> None: # noqa: D105
101
+ if len(self.character) != 1:
102
+ msg = (
103
+ "character must be a single code point, "
104
+ f"got length {len(self.character)}"
105
+ )
106
+ raise ValueError(msg)
107
+ expected = f"U+{ord(self.character):04X}"
108
+ if self.codepoint != expected:
109
+ msg = (
110
+ f"codepoint {self.codepoint!r} does not match "
111
+ f"character (expected {expected})"
112
+ )
113
+ raise ValueError(msg)
114
+
115
+
116
+ @dataclass(frozen=True, slots=True)
117
+ class UrlSafetyResult:
118
+ """Safety analysis output for a URL string.
119
+
120
+ A result may have `safe=True` with non-empty `warnings` when
121
+ informational warnings (e.g. punycode decoding) are present without
122
+ suspicious patterns.
123
+
124
+ Attributes:
125
+ safe: `True` if no suspicious patterns were found.
126
+ decoded_domain: Punycode-decoded hostname when it differs from the
127
+ original hostname.
128
+
129
+ `None` when unchanged or no hostname exists.
130
+ warnings: Human-readable warning strings (immutable).
131
+ issues: Dangerous Unicode issues found in the full URL (immutable).
132
+ """
133
+
134
+ safe: bool
135
+ decoded_domain: str | None
136
+ warnings: tuple[str, ...]
137
+ issues: tuple[UnicodeIssue, ...]
138
+
139
+
140
+ def detect_dangerous_unicode(text: str) -> list[UnicodeIssue]:
141
+ """Detect deceptive or hidden Unicode code points in text.
142
+
143
+ Args:
144
+ text: Input text to inspect.
145
+
146
+ Returns:
147
+ A list of `UnicodeIssue` entries in source order.
148
+ """
149
+ issues: list[UnicodeIssue] = []
150
+ for position, character in enumerate(text):
151
+ if character not in _DANGEROUS_CHARACTERS:
152
+ continue
153
+ issues.append(
154
+ UnicodeIssue(
155
+ position=position,
156
+ character=character,
157
+ codepoint=_format_codepoint(character),
158
+ name=_unicode_name(character),
159
+ )
160
+ )
161
+ return issues
162
+
163
+
164
+ def strip_dangerous_unicode(text: str) -> str:
165
+ """Remove known dangerous/invisible Unicode characters from text.
166
+
167
+ Args:
168
+ text: Input text to sanitize.
169
+
170
+ Returns:
171
+ Sanitized text with dangerous characters removed.
172
+ """
173
+ return "".join(ch for ch in text if ch not in _DANGEROUS_CHARACTERS)
174
+
175
+
176
+ def render_with_unicode_markers(text: str) -> str:
177
+ """Render hidden Unicode characters as explicit markers.
178
+
179
+ Example output: `abc<U+202E RIGHT-TO-LEFT OVERRIDE>def`.
180
+
181
+ Args:
182
+ text: Input text to render.
183
+
184
+ Returns:
185
+ Text where dangerous characters are replaced with visible markers.
186
+ """
187
+ rendered_parts: list[str] = []
188
+ for character in text:
189
+ if character not in _DANGEROUS_CHARACTERS:
190
+ rendered_parts.append(character)
191
+ continue
192
+ rendered_parts.append(
193
+ f"<{_format_codepoint(character)} {_unicode_name(character)}>"
194
+ )
195
+ return "".join(rendered_parts)
196
+
197
+
198
+ def summarize_issues(issues: list[UnicodeIssue], *, max_items: int = 3) -> str:
199
+ """Summarize Unicode issues for warning messages.
200
+
201
+ Deduplicates by code point. When more than *max_items* unique entries exist,
202
+ the summary is truncated with a `+N more entries` suffix.
203
+
204
+ Args:
205
+ issues: A list of detected issues.
206
+ max_items: Max unique code points to include in output.
207
+
208
+ Returns:
209
+ Comma-separated summary, e.g.
210
+ `U+202E RIGHT-TO-LEFT OVERRIDE, U+200B ZERO WIDTH SPACE`.
211
+ """
212
+ unique_entries: list[str] = []
213
+ seen: set[str] = set()
214
+ for issue in issues:
215
+ entry = f"{issue.codepoint} {issue.name}"
216
+ if entry in seen:
217
+ continue
218
+ seen.add(entry)
219
+ unique_entries.append(entry)
220
+
221
+ if len(unique_entries) <= max_items:
222
+ return ", ".join(unique_entries)
223
+
224
+ displayed = ", ".join(unique_entries[:max_items])
225
+ remainder = len(unique_entries) - max_items
226
+ suffix = "entry" if remainder == 1 else "entries"
227
+ return f"{displayed}, +{remainder} more {suffix}"
228
+
229
+
230
+ def format_warning_detail(warnings: tuple[str, ...], *, max_shown: int = 2) -> str:
231
+ """Join safety warnings into a display string with overflow indicator.
232
+
233
+ Args:
234
+ warnings: Warning strings from a `UrlSafetyResult`.
235
+ max_shown: Maximum warnings to include before truncating.
236
+
237
+ Returns:
238
+ Semicolon-separated detail string, e.g. `'warn1; warn2; +1 more'`.
239
+ """
240
+ shown = warnings[:max_shown]
241
+ detail = "; ".join(shown)
242
+ remaining = len(warnings) - max_shown
243
+ if remaining > 0:
244
+ detail += f"; +{remaining} more"
245
+ return detail
246
+
247
+
248
+ def check_url_safety(url: str) -> UrlSafetyResult:
249
+ """Check a URL for suspicious Unicode and domain spoofing patterns.
250
+
251
+ Args:
252
+ url: URL string to inspect.
253
+
254
+ Returns:
255
+ `UrlSafetyResult` including decoded domain and warning details.
256
+ """
257
+ warnings: list[str] = []
258
+ suspicious = False
259
+
260
+ issues = detect_dangerous_unicode(url)
261
+ if issues:
262
+ suspicious = True
263
+ warnings.append(
264
+ f"URL contains hidden Unicode characters ({summarize_issues(issues)})"
265
+ )
266
+
267
+ parsed = urlparse(url)
268
+ hostname = parsed.hostname
269
+ if not hostname:
270
+ return UrlSafetyResult(
271
+ safe=not suspicious,
272
+ decoded_domain=None,
273
+ warnings=tuple(warnings),
274
+ issues=tuple(issues),
275
+ )
276
+
277
+ decoded_hostname, failed_punycode = _decode_hostname(hostname)
278
+ decoded_domain = decoded_hostname if decoded_hostname != hostname else None
279
+ if decoded_domain:
280
+ warnings.append(f"Punycode domain decodes to '{decoded_domain}'")
281
+ if failed_punycode:
282
+ suspicious = True
283
+ labels = ", ".join(failed_punycode)
284
+ warnings.append(f"Punycode label(s) could not be decoded: {labels}")
285
+
286
+ if _is_local_or_ip_hostname(decoded_hostname):
287
+ return UrlSafetyResult(
288
+ safe=not suspicious,
289
+ decoded_domain=decoded_domain,
290
+ warnings=tuple(warnings),
291
+ issues=tuple(issues),
292
+ )
293
+
294
+ for label in _split_hostname_labels(decoded_hostname):
295
+ scripts = _scripts_in_label(label)
296
+ if len(scripts) > 1:
297
+ suspicious = True
298
+ script_names = ", ".join(sorted(scripts))
299
+ warnings.append(f"Domain label '{label}' mixes scripts ({script_names})")
300
+
301
+ if _label_has_suspicious_confusable_mix(label):
302
+ suspicious = True
303
+ warnings.append(
304
+ f"Domain label '{label}' contains confusable Unicode characters"
305
+ )
306
+
307
+ return UrlSafetyResult(
308
+ safe=not suspicious,
309
+ decoded_domain=decoded_domain,
310
+ warnings=tuple(warnings),
311
+ issues=tuple(issues),
312
+ )
313
+
314
+
315
+ def _decode_hostname(hostname: str) -> tuple[str, list[str]]:
316
+ """Decode `xn--` punycode labels into Unicode labels when possible.
317
+
318
+ Returns:
319
+ Tuple of (decoded hostname, list of labels that failed to decode).
320
+ """
321
+ decoded_labels: list[str] = []
322
+ failed_labels: list[str] = []
323
+ for label in _split_hostname_labels(hostname):
324
+ if label.startswith("xn--"):
325
+ try:
326
+ decoded_labels.append(label.encode("ascii").decode("idna"))
327
+ except UnicodeError:
328
+ decoded_labels.append(label)
329
+ failed_labels.append(label)
330
+ continue
331
+ decoded_labels.append(label)
332
+ return ".".join(decoded_labels), failed_labels
333
+
334
+
335
+ def _split_hostname_labels(hostname: str) -> list[str]:
336
+ """Split a hostname into non-empty labels.
337
+
338
+ Returns:
339
+ Hostname labels without empty entries.
340
+ """
341
+ return [label for label in hostname.split(".") if label]
342
+
343
+
344
+ def _is_local_or_ip_hostname(hostname: str) -> bool:
345
+ """Return whether hostname is localhost or an IP address literal.
346
+
347
+ Returns:
348
+ `True` when hostname is localhost or an IP literal, else `False`.
349
+ """
350
+ host = hostname.strip().rstrip(".")
351
+ if not host:
352
+ return False
353
+
354
+ if host.lower() in _URL_SAFE_LOCAL_HOSTS:
355
+ return True
356
+
357
+ try:
358
+ ipaddress.ip_address(host)
359
+ except ValueError:
360
+ return False
361
+ return True
362
+
363
+
364
+ def _scripts_in_label(label: str) -> set[str]:
365
+ """Collect non-common scripts used by a domain label.
366
+
367
+ Returns:
368
+ Set of script names used by the label, excluding common/inherited.
369
+ """
370
+ scripts: set[str] = set()
371
+ for character in label:
372
+ script = _char_script(character)
373
+ if script in {"Common", "Inherited"}:
374
+ continue
375
+ scripts.add(script)
376
+ return scripts
377
+
378
+
379
+ def _label_has_suspicious_confusable_mix(label: str) -> bool:
380
+ """Return whether a label has likely deceptive confusable characters.
381
+
382
+ Only flags labels that mix multiple scripts while containing confusable
383
+ characters. Single-script labels (even with confusables) are not flagged
384
+ because they represent legitimate use of that script.
385
+
386
+ Returns:
387
+ `True` when the label mixes scripts and contains confusable characters.
388
+ """
389
+ if not any(character in CONFUSABLES for character in label):
390
+ return False
391
+
392
+ scripts = _scripts_in_label(label)
393
+ return len(scripts) > 1
394
+
395
+
396
+ def _char_script(character: str) -> str:
397
+ """Classify a character into a coarse Unicode script bucket.
398
+
399
+ Returns:
400
+ One of: `'Fullwidth'`, `'Latin'`, `'Cyrillic'`, `'Greek'`, `'Armenian'`,
401
+ `'EastAsian'`, `'Inherited'`, `'Common'`, or `'Other'`.
402
+ """
403
+ name = unicodedata.name(character, "")
404
+ category = unicodedata.category(character)
405
+
406
+ if "FULLWIDTH LATIN" in name:
407
+ return "Fullwidth"
408
+ if "LATIN" in name:
409
+ return "Latin"
410
+ if "CYRILLIC" in name:
411
+ return "Cyrillic"
412
+ if "GREEK" in name:
413
+ return "Greek"
414
+ if "ARMENIAN" in name:
415
+ return "Armenian"
416
+ if any(
417
+ token in name
418
+ for token in (
419
+ "CJK",
420
+ "HIRAGANA",
421
+ "KATAKANA",
422
+ "HANGUL",
423
+ "BOPOMOFO",
424
+ "IDEOGRAPHIC",
425
+ )
426
+ ):
427
+ return "EastAsian"
428
+
429
+ if category.startswith("M"):
430
+ return "Inherited"
431
+ if category[0] in {"N", "P", "S", "Z", "C"}:
432
+ return "Common"
433
+
434
+ return "Other"
435
+
436
+
437
+ def _format_codepoint(character: str) -> str:
438
+ """Format character code point in `U+XXXX` uppercase form.
439
+
440
+ Returns:
441
+ Uppercase `U+XXXX` codepoint string.
442
+ """
443
+ return f"U+{ord(character):04X}"
444
+
445
+
446
+ def _unicode_name(character: str) -> str:
447
+ """Return a stable Unicode name with a fallback for unknown code points.
448
+
449
+ Returns:
450
+ Unicode name string for the character.
451
+ """
452
+ return unicodedata.name(character, "UNKNOWN CHARACTER")
453
+
454
+
455
+ # ---------------------------------------------------------------------------
456
+ # Shared helpers for recursive argument inspection
457
+ # ---------------------------------------------------------------------------
458
+
459
+
460
+ def iter_string_values(
461
+ data: dict[str, Any],
462
+ *,
463
+ prefix: str = "",
464
+ ) -> list[tuple[str, str]]:
465
+ """Flatten nested dict/list structures into key-path/string pairs.
466
+
467
+ Returns:
468
+ List of ``(path, value)`` tuples for all string leaves.
469
+ """
470
+ values: list[tuple[str, str]] = []
471
+ for key, value in data.items():
472
+ key_path = f"{prefix}.{key}" if prefix else key
473
+ if isinstance(value, str):
474
+ values.append((key_path, value))
475
+ continue
476
+ if isinstance(value, dict):
477
+ values.extend(iter_string_values(value, prefix=key_path))
478
+ continue
479
+ if isinstance(value, list):
480
+ values.extend(_iter_string_values_from_list(value, prefix=key_path))
481
+ return values
482
+
483
+
484
+ def _iter_string_values_from_list(
485
+ values: list[Any],
486
+ *,
487
+ prefix: str,
488
+ ) -> list[tuple[str, str]]:
489
+ """Flatten nested list values into key-path/string pairs.
490
+
491
+ Returns:
492
+ List of `(path, value)` tuples for all string leaves.
493
+ """
494
+ entries: list[tuple[str, str]] = []
495
+ for index, value in enumerate(values):
496
+ key_path = f"{prefix}[{index}]"
497
+ if isinstance(value, str):
498
+ entries.append((key_path, value))
499
+ continue
500
+ if isinstance(value, dict):
501
+ entries.extend(iter_string_values(value, prefix=key_path))
502
+ continue
503
+ if isinstance(value, list):
504
+ entries.extend(_iter_string_values_from_list(value, prefix=key_path))
505
+ return entries
506
+
507
+
508
+ def looks_like_url_key(arg_path: str) -> bool:
509
+ """Return whether a key path suggests URL-like content.
510
+
511
+ Returns:
512
+ `True` for URL-like key names, otherwise `False`.
513
+ """
514
+ key = arg_path.rsplit(".", maxsplit=1)[-1]
515
+ key = key.split("[", maxsplit=1)[0].lower()
516
+ return key in URL_ARG_KEYS