mdengine 0.5.0__tar.gz → 0.7.0__tar.gz

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 (341) hide show
  1. {mdengine-0.5.0 → mdengine-0.7.0}/PKG-INFO +38 -8
  2. {mdengine-0.5.0 → mdengine-0.7.0}/README.md +18 -5
  3. {mdengine-0.5.0 → mdengine-0.7.0}/pyproject.toml +34 -3
  4. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/__init__.py +1 -1
  5. mdengine-0.7.0/src/md_generator/codeflow/__init__.py +7 -0
  6. mdengine-0.7.0/src/md_generator/codeflow/analyzers/__init__.py +9 -0
  7. mdengine-0.7.0/src/md_generator/codeflow/analyzers/flow_analyzer.py +68 -0
  8. mdengine-0.7.0/src/md_generator/codeflow/api/__init__.py +1 -0
  9. mdengine-0.7.0/src/md_generator/codeflow/api/job_manager.py +249 -0
  10. mdengine-0.7.0/src/md_generator/codeflow/api/main.py +185 -0
  11. mdengine-0.7.0/src/md_generator/codeflow/api/mcp_server.py +16 -0
  12. mdengine-0.7.0/src/md_generator/codeflow/api/run.py +15 -0
  13. mdengine-0.7.0/src/md_generator/codeflow/api/schemas.py +96 -0
  14. mdengine-0.7.0/src/md_generator/codeflow/api/settings.py +28 -0
  15. mdengine-0.7.0/src/md_generator/codeflow/cli/__init__.py +1 -0
  16. mdengine-0.7.0/src/md_generator/codeflow/cli/main.py +132 -0
  17. mdengine-0.7.0/src/md_generator/codeflow/core/__init__.py +6 -0
  18. mdengine-0.7.0/src/md_generator/codeflow/core/extractor.py +193 -0
  19. mdengine-0.7.0/src/md_generator/codeflow/core/run_config.py +31 -0
  20. mdengine-0.7.0/src/md_generator/codeflow/detectors/__init__.py +7 -0
  21. mdengine-0.7.0/src/md_generator/codeflow/detectors/api_detector.py +222 -0
  22. mdengine-0.7.0/src/md_generator/codeflow/detectors/entry_detector.py +46 -0
  23. mdengine-0.7.0/src/md_generator/codeflow/detectors/entry_rank.py +51 -0
  24. mdengine-0.7.0/src/md_generator/codeflow/detectors/kafka_detector.py +47 -0
  25. mdengine-0.7.0/src/md_generator/codeflow/generators/__init__.py +1 -0
  26. mdengine-0.7.0/src/md_generator/codeflow/generators/business_rules_markdown.py +68 -0
  27. mdengine-0.7.0/src/md_generator/codeflow/generators/cytoscape_enrich.py +97 -0
  28. mdengine-0.7.0/src/md_generator/codeflow/generators/entry_markdown.py +198 -0
  29. mdengine-0.7.0/src/md_generator/codeflow/generators/flow_summary.py +262 -0
  30. mdengine-0.7.0/src/md_generator/codeflow/generators/html.py +361 -0
  31. mdengine-0.7.0/src/md_generator/codeflow/generators/markdown.py +35 -0
  32. mdengine-0.7.0/src/md_generator/codeflow/generators/mermaid.py +45 -0
  33. mdengine-0.7.0/src/md_generator/codeflow/generators/sequence.py +33 -0
  34. mdengine-0.7.0/src/md_generator/codeflow/graph/__init__.py +5 -0
  35. mdengine-0.7.0/src/md_generator/codeflow/graph/builder.py +181 -0
  36. mdengine-0.7.0/src/md_generator/codeflow/ingestion/__init__.py +10 -0
  37. mdengine-0.7.0/src/md_generator/codeflow/ingestion/loader.py +66 -0
  38. mdengine-0.7.0/src/md_generator/codeflow/lang_dispatch.py +64 -0
  39. mdengine-0.7.0/src/md_generator/codeflow/mcp/__init__.py +1 -0
  40. mdengine-0.7.0/src/md_generator/codeflow/mcp/server.py +42 -0
  41. mdengine-0.7.0/src/md_generator/codeflow/models/__init__.py +21 -0
  42. mdengine-0.7.0/src/md_generator/codeflow/models/ir.py +97 -0
  43. mdengine-0.7.0/src/md_generator/codeflow/parsers/__init__.py +18 -0
  44. mdengine-0.7.0/src/md_generator/codeflow/parsers/base.py +57 -0
  45. mdengine-0.7.0/src/md_generator/codeflow/parsers/cpp_parser.py +155 -0
  46. mdengine-0.7.0/src/md_generator/codeflow/parsers/go_parser.py +82 -0
  47. mdengine-0.7.0/src/md_generator/codeflow/parsers/java_parser.py +116 -0
  48. mdengine-0.7.0/src/md_generator/codeflow/parsers/php_parser.py +79 -0
  49. mdengine-0.7.0/src/md_generator/codeflow/parsers/python_parser.py +295 -0
  50. mdengine-0.7.0/src/md_generator/codeflow/parsers/treesitter_js_ts_parser.py +119 -0
  51. mdengine-0.7.0/src/md_generator/codeflow/rules/__init__.py +5 -0
  52. mdengine-0.7.0/src/md_generator/codeflow/rules/collector.py +284 -0
  53. mdengine-0.7.0/src/md_generator/codeflow/runtime/__init__.py +1 -0
  54. mdengine-0.7.0/src/md_generator/codeflow/runtime/tracer.py +14 -0
  55. mdengine-0.7.0/src/md_generator/codeflow/utils/__init__.py +1 -0
  56. mdengine-0.7.0/src/md_generator/codeflow/utils/tools_root.py +13 -0
  57. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/adapters/factory.py +6 -0
  58. mdengine-0.7.0/src/md_generator/db/adapters/sqlite_adapter.py +107 -0
  59. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/api/main.py +89 -1
  60. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/api/schemas.py +1 -1
  61. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/api/settings.py +1 -0
  62. mdengine-0.7.0/src/md_generator/db/api/sqlite_upload.py +87 -0
  63. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/cli/main.py +1 -1
  64. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/core/job_manager.py +44 -0
  65. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/core/run_config.py +5 -0
  66. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/core/util.py +12 -0
  67. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/engine_cli.py +10 -2
  68. mdengine-0.7.0/src/md_generator/graph/mcp/sse.py +8 -0
  69. mdengine-0.7.0/src/md_generator/openapi/__init__.py +5 -0
  70. mdengine-0.7.0/src/md_generator/openapi/api/__init__.py +1 -0
  71. mdengine-0.7.0/src/md_generator/openapi/api/main.py +84 -0
  72. mdengine-0.7.0/src/md_generator/openapi/api/mcp_server.py +29 -0
  73. mdengine-0.7.0/src/md_generator/openapi/api/run.py +15 -0
  74. mdengine-0.7.0/src/md_generator/openapi/api/schemas.py +33 -0
  75. mdengine-0.7.0/src/md_generator/openapi/api/settings.py +21 -0
  76. mdengine-0.7.0/src/md_generator/openapi/cli/__init__.py +1 -0
  77. mdengine-0.7.0/src/md_generator/openapi/cli/main.py +75 -0
  78. mdengine-0.7.0/src/md_generator/openapi/config/__init__.py +1 -0
  79. mdengine-0.7.0/src/md_generator/openapi/config/default.yaml +14 -0
  80. mdengine-0.7.0/src/md_generator/openapi/converters/__init__.py +5 -0
  81. mdengine-0.7.0/src/md_generator/openapi/converters/swagger2_to_openapi3.py +453 -0
  82. mdengine-0.7.0/src/md_generator/openapi/core/__init__.py +1 -0
  83. mdengine-0.7.0/src/md_generator/openapi/core/extractor.py +207 -0
  84. mdengine-0.7.0/src/md_generator/openapi/core/run_config.py +100 -0
  85. mdengine-0.7.0/src/md_generator/openapi/core/zip_export.py +24 -0
  86. mdengine-0.7.0/src/md_generator/openapi/enrichers/__init__.py +5 -0
  87. mdengine-0.7.0/src/md_generator/openapi/enrichers/rules.py +133 -0
  88. mdengine-0.7.0/src/md_generator/openapi/enrichers/sample_body.py +73 -0
  89. mdengine-0.7.0/src/md_generator/openapi/generators/__init__.py +9 -0
  90. mdengine-0.7.0/src/md_generator/openapi/generators/dependency_graph.py +54 -0
  91. mdengine-0.7.0/src/md_generator/openapi/loaders/__init__.py +5 -0
  92. mdengine-0.7.0/src/md_generator/openapi/loaders/spec_loader.py +115 -0
  93. mdengine-0.7.0/src/md_generator/openapi/mcp/__init__.py +1 -0
  94. mdengine-0.7.0/src/md_generator/openapi/mcp/server.py +71 -0
  95. mdengine-0.7.0/src/md_generator/openapi/models/__init__.py +25 -0
  96. mdengine-0.7.0/src/md_generator/openapi/models/domain.py +106 -0
  97. mdengine-0.7.0/src/md_generator/openapi/normalizers/__init__.py +6 -0
  98. mdengine-0.7.0/src/md_generator/openapi/normalizers/operations.py +287 -0
  99. mdengine-0.7.0/src/md_generator/openapi/normalizers/schema_flatten.py +104 -0
  100. mdengine-0.7.0/src/md_generator/openapi/parsers/__init__.py +5 -0
  101. mdengine-0.7.0/src/md_generator/openapi/parsers/openapi_parser.py +18 -0
  102. mdengine-0.7.0/src/md_generator/openapi/resolvers/__init__.py +5 -0
  103. mdengine-0.7.0/src/md_generator/openapi/resolvers/ref_resolver.py +16 -0
  104. mdengine-0.7.0/src/md_generator/openapi/writers/__init__.py +5 -0
  105. mdengine-0.7.0/src/md_generator/openapi/writers/markdown_writer.py +253 -0
  106. {mdengine-0.5.0 → mdengine-0.7.0}/src/mdengine.egg-info/PKG-INFO +38 -8
  107. {mdengine-0.5.0 → mdengine-0.7.0}/src/mdengine.egg-info/SOURCES.txt +92 -0
  108. {mdengine-0.5.0 → mdengine-0.7.0}/src/mdengine.egg-info/entry_points.txt +7 -0
  109. {mdengine-0.5.0 → mdengine-0.7.0}/src/mdengine.egg-info/requires.txt +21 -0
  110. {mdengine-0.5.0 → mdengine-0.7.0}/LICENSE +0 -0
  111. {mdengine-0.5.0 → mdengine-0.7.0}/setup.cfg +0 -0
  112. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/archive/__init__.py +0 -0
  113. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/archive/api/__init__.py +0 -0
  114. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/archive/api/convert_runner.py +0 -0
  115. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/archive/api/jobs.py +0 -0
  116. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/archive/api/main.py +0 -0
  117. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/archive/api/mcp_server.py +0 -0
  118. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/archive/api/mcp_setup.py +0 -0
  119. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/archive/api/query_options.py +0 -0
  120. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/archive/api/settings.py +0 -0
  121. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/archive/convert_impl.py +0 -0
  122. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/archive/converter.py +0 -0
  123. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/archive/options.py +0 -0
  124. {mdengine-0.5.0/src/md_generator/graph/mcp → mdengine-0.7.0/src/md_generator/codeflow/api}/sse.py +0 -0
  125. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/__init__.py +0 -0
  126. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/adapters/__init__.py +0 -0
  127. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/adapters/mongo_adapter.py +0 -0
  128. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/adapters/mysql_adapter.py +0 -0
  129. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/adapters/oracle_adapter.py +0 -0
  130. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/adapters/postgres_adapter.py +0 -0
  131. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/adapters/sql_common.py +0 -0
  132. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/api/__init__.py +0 -0
  133. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/api/mcp_server.py +0 -0
  134. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/api/run.py +0 -0
  135. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/cli/__init__.py +0 -0
  136. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/config/__init__.py +0 -0
  137. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/config/default.yaml +0 -0
  138. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/core/__init__.py +0 -0
  139. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/core/base_adapter.py +0 -0
  140. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/core/erd/__init__.py +0 -0
  141. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/core/erd/dot_emitter.py +0 -0
  142. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/core/erd/filter.py +0 -0
  143. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/core/erd/mermaid_emitter.py +0 -0
  144. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/core/erd/mermaid_render.py +0 -0
  145. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/core/erd/model.py +0 -0
  146. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/core/erd/pipeline.py +0 -0
  147. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/core/erd/render.py +0 -0
  148. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/core/extractor.py +0 -0
  149. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/core/markdown_writer.py +0 -0
  150. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/core/models.py +0 -0
  151. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/core/zip_export.py +0 -0
  152. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/mcp/__init__.py +0 -0
  153. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/mcp/server.py +0 -0
  154. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/mcp/sse.py +0 -0
  155. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/db/mcp/stream.py +0 -0
  156. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/graph/__init__.py +0 -0
  157. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/graph/adapters/__init__.py +0 -0
  158. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/graph/adapters/factory.py +0 -0
  159. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/graph/adapters/neo4j_adapter.py +0 -0
  160. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/graph/adapters/networkx_adapter.py +0 -0
  161. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/graph/api/__init__.py +0 -0
  162. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/graph/api/main.py +0 -0
  163. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/graph/api/mcp_server.py +0 -0
  164. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/graph/api/run.py +0 -0
  165. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/graph/api/schemas.py +0 -0
  166. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/graph/api/settings.py +0 -0
  167. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/graph/cli/__init__.py +0 -0
  168. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/graph/cli/main.py +0 -0
  169. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/graph/config/__init__.py +0 -0
  170. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/graph/config/default.yaml +0 -0
  171. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/graph/core/__init__.py +0 -0
  172. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/graph/core/base_adapter.py +0 -0
  173. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/graph/core/extractor.py +0 -0
  174. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/graph/core/graph_builder.py +0 -0
  175. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/graph/core/job_manager.py +0 -0
  176. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/graph/core/markdown_writer.py +0 -0
  177. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/graph/core/models.py +0 -0
  178. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/graph/core/run_config.py +0 -0
  179. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/graph/core/viz.py +0 -0
  180. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/graph/core/zip_export.py +0 -0
  181. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/graph/mcp/__init__.py +0 -0
  182. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/graph/mcp/server.py +0 -0
  183. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/graph/mcp/stream.py +0 -0
  184. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/image/__init__.py +0 -0
  185. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/image/api/__init__.py +0 -0
  186. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/image/api/main.py +0 -0
  187. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/image/api/mcp_server.py +0 -0
  188. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/image/api/query_options.py +0 -0
  189. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/image/api/settings.py +0 -0
  190. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/image/api/staging.py +0 -0
  191. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/image/api/zip_bundle.py +0 -0
  192. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/image/backends/__init__.py +0 -0
  193. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/image/backends/base.py +0 -0
  194. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/image/backends/easy.py +0 -0
  195. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/image/backends/paddle.py +0 -0
  196. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/image/backends/tesseract.py +0 -0
  197. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/image/convert_impl.py +0 -0
  198. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/image/converter.py +0 -0
  199. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/image/emit.py +0 -0
  200. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/image/io_util.py +0 -0
  201. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/image/utils.py +0 -0
  202. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/media/__init__.py +0 -0
  203. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/media/audio/__init__.py +0 -0
  204. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/media/audio/api/__init__.py +0 -0
  205. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/media/audio/api/main.py +0 -0
  206. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/media/audio/api/mcp_server.py +0 -0
  207. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/media/audio/api/mcp_setup.py +0 -0
  208. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/media/audio/api/run.py +0 -0
  209. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/media/audio/api/settings.py +0 -0
  210. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/media/audio/converter.py +0 -0
  211. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/media/audio/formatter.py +0 -0
  212. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/media/audio/service.py +0 -0
  213. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/media/document_converter.py +0 -0
  214. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/media/job_store.py +0 -0
  215. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/media/video/__init__.py +0 -0
  216. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/media/video/api/__init__.py +0 -0
  217. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/media/video/api/main.py +0 -0
  218. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/media/video/api/mcp_server.py +0 -0
  219. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/media/video/api/mcp_setup.py +0 -0
  220. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/media/video/api/run.py +0 -0
  221. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/media/video/api/settings.py +0 -0
  222. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/media/video/converter.py +0 -0
  223. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/media/video/formatter.py +0 -0
  224. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/media/video/service.py +0 -0
  225. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/media/whisper_language.py +0 -0
  226. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/media/youtube/__init__.py +0 -0
  227. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/media/youtube/api/__init__.py +0 -0
  228. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/media/youtube/api/main.py +0 -0
  229. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/media/youtube/api/mcp_server.py +0 -0
  230. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/media/youtube/api/mcp_setup.py +0 -0
  231. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/media/youtube/api/run.py +0 -0
  232. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/media/youtube/api/settings.py +0 -0
  233. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/media/youtube/converter.py +0 -0
  234. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/media/youtube/formatter.py +0 -0
  235. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/media/youtube/metadata.py +0 -0
  236. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/media/youtube/service.py +0 -0
  237. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/media/youtube/transcript.py +0 -0
  238. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/pdf/__init__.py +0 -0
  239. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/pdf/api/__init__.py +0 -0
  240. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/pdf/api/main.py +0 -0
  241. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/pdf/api/mcp_server.py +0 -0
  242. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/pdf/api/settings.py +0 -0
  243. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/pdf/api/zip_bundle.py +0 -0
  244. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/pdf/converter.py +0 -0
  245. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/pdf/md_emit.py +0 -0
  246. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/pdf/pdf_extract.py +0 -0
  247. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/pdf/utils.py +0 -0
  248. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/playwright/__init__.py +0 -0
  249. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/playwright/api/__init__.py +0 -0
  250. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/playwright/api/convert_runner.py +0 -0
  251. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/playwright/api/jobs.py +0 -0
  252. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/playwright/api/main.py +0 -0
  253. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/playwright/api/mcp_server.py +0 -0
  254. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/playwright/api/mcp_setup.py +0 -0
  255. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/playwright/api/run.py +0 -0
  256. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/playwright/api/settings.py +0 -0
  257. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/playwright/assets.py +0 -0
  258. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/playwright/chunker.py +0 -0
  259. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/playwright/cli.py +0 -0
  260. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/playwright/extractor.py +0 -0
  261. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/playwright/html_to_md.py +0 -0
  262. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/playwright/options.py +0 -0
  263. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/playwright/pipeline.py +0 -0
  264. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/playwright/playwright_fetcher.py +0 -0
  265. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/ppt/__init__.py +0 -0
  266. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/ppt/api/__init__.py +0 -0
  267. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/ppt/api/convert_runner.py +0 -0
  268. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/ppt/api/jobs.py +0 -0
  269. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/ppt/api/main.py +0 -0
  270. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/ppt/api/mcp_server.py +0 -0
  271. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/ppt/api/mcp_setup.py +0 -0
  272. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/ppt/api/query_options.py +0 -0
  273. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/ppt/api/settings.py +0 -0
  274. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/ppt/convert_impl.py +0 -0
  275. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/ppt/converter.py +0 -0
  276. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/ppt/embedded_extract.py +0 -0
  277. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/ppt/ooxml_media.py +0 -0
  278. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/ppt/options.py +0 -0
  279. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/ppt/post_assets.py +0 -0
  280. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/ppt/text_formatting.py +0 -0
  281. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/ppt/vendor_pdf_md/__init__.py +0 -0
  282. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/ppt/vendor_pdf_md/convert.py +0 -0
  283. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/ppt/vendor_word_md/__init__.py +0 -0
  284. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/ppt/vendor_word_md/convert.py +0 -0
  285. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/ppt/zip_deep.py +0 -0
  286. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/text/__init__.py +0 -0
  287. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/text/api/__init__.py +0 -0
  288. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/text/api/convert_runner.py +0 -0
  289. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/text/api/jobs.py +0 -0
  290. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/text/api/main.py +0 -0
  291. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/text/api/mcp_server.py +0 -0
  292. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/text/api/mcp_setup.py +0 -0
  293. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/text/api/query_options.py +0 -0
  294. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/text/api/settings.py +0 -0
  295. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/text/convert_impl.py +0 -0
  296. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/text/converter.py +0 -0
  297. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/text/format_detect.py +0 -0
  298. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/text/md_emit_json.py +0 -0
  299. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/text/md_emit_txt.py +0 -0
  300. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/text/md_emit_xml.py +0 -0
  301. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/text/options.py +0 -0
  302. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/url/__init__.py +0 -0
  303. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/url/api/__init__.py +0 -0
  304. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/url/api/convert_runner.py +0 -0
  305. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/url/api/jobs.py +0 -0
  306. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/url/api/main.py +0 -0
  307. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/url/api/mcp_server.py +0 -0
  308. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/url/api/mcp_setup.py +0 -0
  309. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/url/api/query_options.py +0 -0
  310. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/url/api/settings.py +0 -0
  311. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/url/assets.py +0 -0
  312. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/url/convert_impl.py +0 -0
  313. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/url/converter.py +0 -0
  314. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/url/crawl.py +0 -0
  315. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/url/extract.py +0 -0
  316. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/url/fetch.py +0 -0
  317. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/url/html_to_md.py +0 -0
  318. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/url/options.py +0 -0
  319. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/url/page_convert.py +0 -0
  320. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/url/post_convert_assets.py +0 -0
  321. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/url/robots_util.py +0 -0
  322. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/word/__init__.py +0 -0
  323. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/word/api/__init__.py +0 -0
  324. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/word/api/convert_util.py +0 -0
  325. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/word/api/jobs.py +0 -0
  326. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/word/api/main.py +0 -0
  327. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/word/api/mcp_server.py +0 -0
  328. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/word/artifact.py +0 -0
  329. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/word/converter.py +0 -0
  330. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/word/settings.py +0 -0
  331. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/xlsx/__init__.py +0 -0
  332. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/xlsx/api/__init__.py +0 -0
  333. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/xlsx/api/app.py +0 -0
  334. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/xlsx/convert_config.py +0 -0
  335. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/xlsx/converter.py +0 -0
  336. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/xlsx/converter_core.py +0 -0
  337. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/xlsx/excel_reader.py +0 -0
  338. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/xlsx/markdown_emitter.py +0 -0
  339. {mdengine-0.5.0 → mdengine-0.7.0}/src/md_generator/xlsx/mcp_server.py +0 -0
  340. {mdengine-0.5.0 → mdengine-0.7.0}/src/mdengine.egg-info/dependency_links.txt +0 -0
  341. {mdengine-0.5.0 → mdengine-0.7.0}/src/mdengine.egg-info/top_level.txt +0 -0
@@ -1,13 +1,13 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mdengine
3
- Version: 0.5.0
4
- Summary: Convert PDF, Office, images, audio, video, text/JSON/XML, ZIP archives, and web URLs to Markdown.
3
+ Version: 0.7.0
4
+ Summary: Convert PDF, Office, images, audio, video, text/JSON/XML, ZIP archives, web URLs, databases, graphs, and OpenAPI specs to Markdown.
5
5
  Author: mdengine contributors
6
6
  License-Expression: MIT
7
7
  Project-URL: Homepage, https://github.com/vishal7090/md-generator
8
8
  Project-URL: Repository, https://github.com/vishal7090/md-generator
9
9
  Project-URL: Issues, https://github.com/vishal7090/md-generator/issues
10
- Keywords: markdown,pdf,docx,pptx,xlsx,ocr,zip,url,html,youtube,playwright,database
10
+ Keywords: markdown,pdf,docx,pptx,xlsx,ocr,zip,url,html,youtube,playwright,database,openapi,codeflow
11
11
  Classifier: Programming Language :: Python :: 3
12
12
  Classifier: Programming Language :: Python :: 3 :: Only
13
13
  Classifier: Topic :: Text Processing :: Markup :: Markdown
@@ -99,6 +99,20 @@ Provides-Extra: graph
99
99
  Requires-Dist: networkx>=3.2.0; extra == "graph"
100
100
  Requires-Dist: neo4j>=5.14.0; extra == "graph"
101
101
  Requires-Dist: pyyaml>=6.0.0; extra == "graph"
102
+ Provides-Extra: openapi
103
+ Requires-Dist: pyyaml>=6.0.0; extra == "openapi"
104
+ Requires-Dist: prance>=23.6.0; extra == "openapi"
105
+ Requires-Dist: openapi-spec-validator>=0.7.0; extra == "openapi"
106
+ Provides-Extra: codeflow
107
+ Requires-Dist: networkx>=3.2.0; extra == "codeflow"
108
+ Requires-Dist: javalang>=0.13.0; extra == "codeflow"
109
+ Provides-Extra: codeflow-treesitter
110
+ Requires-Dist: tree-sitter>=0.21.0; extra == "codeflow-treesitter"
111
+ Requires-Dist: tree-sitter-javascript>=0.21.0; extra == "codeflow-treesitter"
112
+ Requires-Dist: tree-sitter-typescript>=0.23.0; extra == "codeflow-treesitter"
113
+ Requires-Dist: tree-sitter-cpp>=0.23.0; extra == "codeflow-treesitter"
114
+ Provides-Extra: codeflow-clang
115
+ Requires-Dist: clang>=16.0.0; extra == "codeflow-clang"
102
116
  Provides-Extra: api
103
117
  Requires-Dist: fastapi>=0.115.0; extra == "api"
104
118
  Requires-Dist: uvicorn[standard]>=0.32.0; extra == "api"
@@ -120,6 +134,9 @@ Requires-Dist: mdengine[url]; extra == "dev"
120
134
  Requires-Dist: mdengine[playwright]; extra == "dev"
121
135
  Requires-Dist: mdengine[db]; extra == "dev"
122
136
  Requires-Dist: mdengine[graph]; extra == "dev"
137
+ Requires-Dist: mdengine[openapi]; extra == "dev"
138
+ Requires-Dist: mdengine[codeflow]; extra == "dev"
139
+ Requires-Dist: mdengine[codeflow-treesitter]; extra == "dev"
123
140
  Provides-Extra: all
124
141
  Requires-Dist: pymupdf>=1.24.0; extra == "all"
125
142
  Requires-Dist: pdfplumber>=0.11.0; extra == "all"
@@ -279,17 +296,26 @@ If the shell reports “command not found”, ensure the Python **Scripts** dire
279
296
  | `md-video-mcp` | `md_generator.media.video.api.mcp_server:main` | Same for video |
280
297
  | `md-youtube-mcp` | `md_generator.media.youtube.api.mcp_server:main` | Same for YouTube (`youtube_url_to_markdown`) |
281
298
  | `md-db` | `md_generator.db.cli.main:main` | `pip install "mdengine[db]"` then `md-db --config db.yaml` (or `mdengine db-to-md …`) |
282
- | `md-db-api` | `md_generator.db.api.run:main` | FastAPI on port **8010** (`DB_TO_MD_PORT`): `POST /db-to-md/run`, `/db-to-md/job`, SSE `/db-to-md/job/{id}/events` |
299
+ | `md-db-api` | `md_generator.db.api.run:main` | FastAPI on port **8010** (`DB_TO_MD_PORT`): `POST /db-to-md/run`, `POST /db-to-md/run/sqlite` (upload + ZIP), `POST /db-to-md/job`, `POST /db-to-md/job/sqlite` (upload + async job), SSE `/db-to-md/job/{id}/events` |
283
300
  | `md-db-mcp` | `md_generator.db.api.mcp_server:main` | Standalone MCP for metadata export tools |
284
301
  | `md-graph` | `md_generator.graph.cli.main:main` | `pip install "mdengine[graph]"` then `md-graph --source neo4j --uri bolt://…` (or `mdengine graph-to-md …`) |
285
302
  | `md-graph-api` | `md_generator.graph.api.run:main` | FastAPI on port **8012** (`GRAPH_TO_MD_PORT`): `POST /graph-to-md/run`, `/graph-to-md/job`, SSE `/graph-to-md/job/{id}/events` |
286
303
  | `md-graph-mcp` | `md_generator.graph.api.mcp_server:main` | Standalone MCP for graph export tools |
287
- | `mdengine` | `md_generator.engine_cli:main` | `mdengine db-to-md …` / `mdengine graph-to-md …` (delegates to `md-db` / `md-graph`) |
304
+ | `md-openapi` | `md_generator.openapi.cli.main:main` | `pip install "mdengine[openapi]"` then `md-openapi generate --file openapi.yaml --output ./docs` (or `mdengine openapi-to-md generate …`) |
305
+ | `md-openapi-api` | `md_generator.openapi.api.run:main` | FastAPI on port **8015** (`OPENAPI_TO_MD_PORT`): `POST /openapi-to-md/generate` (OpenAPI upload → ZIP), `/health`, MCP at **`/mcp`** |
306
+ | `md-openapi-mcp` | `md_generator.openapi.api.mcp_server:main` | Standalone MCP: `api_validate_openapi_yaml`, `api_generate_readme_markdown`, `api_run_sync_zip_base64` |
307
+ | `mdengine` | `md_generator.engine_cli:main` | `mdengine db-to-md …` / `mdengine graph-to-md …` / `mdengine openapi-to-md generate …` |
308
+
309
+ **openapi-to-md (`md-openapi`):** OpenAPI **3.x** is parsed directly; **Swagger 2.0** (`swagger: "2.0"`) documents are **converted in-process** to OpenAPI 3.0.3 (deterministic, in-repo converter) before `$ref` resolution. Edge-heavy specs (unusual OAuth2 flows, vendor extensions) may still need fixes after conversion.
288
310
 
289
311
  **db-to-md ER diagrams:** add **`erd`** to the export feature list (YAML `features.include`, API body, or CLI `--include …,erd`). **Preferred:** **Graphviz** (`dot` on `PATH`, or **`GRAPHVIZ_DOT`**) produces `erd/*.dot`, `erd/*.png`, and `erd/*.svg`. **If Graphviz is missing,** the exporter falls back to **Mermaid** (`erDiagram`): it writes `erd/*.mermaid` plus a fenced **`erd/*.md`** for GitHub-style preview. With **`mermaid-py`** (included in `mdengine[db]`), it also requests **PNG/SVG** via mermaid.ink (requires network unless you self-host mermaid.ink and set **`MERMAID_INK_SERVER`** per [mermaid-py](https://pypi.org/project/mermaid-py/)). Tune **`erd.max_tables`** (default 100) and **`erd.scope`** (`full` \| `per_schema` \| `per_table`) under `erd:` in YAML; CLI: `--erd-max-tables`, `--erd-scope`. Async job SSE uses `progress_update` with `current` starting with `erd:`.
290
312
 
291
313
  **db-to-md split exports and README merge:** with **`output.split_files: true`**, set **`output.write_combined_feature_markdown: true`** to also write root-level combined Markdown (for example `tables.md`, `functions.md`, `indexes.md`, and feature-specific paths such as `oracle/packages.md` or `mongodb/collections.md` when those features run). Set **`output.readme_feature_merge`** to **`inline`** (append full bundle bodies into `README.md`) or **`toc`** (append a linked list to those files). If merge is not **`none`** and split files are on, combined bundle writes are turned on automatically when loading config. CLI: `--write-combined-feature-markdown`, `--readme-feature-merge none|inline|toc`.
292
314
 
315
+ **db-to-md SQLite:** set **`database.type: sqlite`** and **`database.uri`** to a SQLAlchemy URL such as **`sqlite:///my.db`** or **`sqlite:////C:/data/my.db`**. The default SQLite catalog is **`main`**; packaged YAML that still has **`schema: public`** is normalized to **`main`** when the type is SQLite. CLI: **`--type sqlite`**. Stored routines, sequences, and partitions are not used by SQLite and stay empty; tables, indexes, views, triggers, and ERD (via FK introspection) follow the same export path as other SQL engines.
316
+
317
+ **db-to-md API SQLite upload:** **`POST /db-to-md/run/sqlite`** — `multipart/form-data` with field **`file`** (the `.sqlite` / `.db` bytes; must start with the standard `SQLite format 3` header) and optional **`config`** (JSON string with the same shape as a normal run body minus `database`: `schema`, `output`, `features`, `execution`, `limits`, `erd`). Returns the metadata ZIP immediately. **`POST /db-to-md/job/sqlite`** — same form fields; saves the file under the job workspace and runs the existing job pipeline (`GET /db-to-md/job/{id}/download` when complete). Upload size cap: env **`DB_TO_MD_MAX_SQLITE_UPLOAD_MB`** (default **256**). Large ZIPs may still require the async job path if they exceed **`DB_TO_MD_MAX_SYNC_ZIP_MB`** on the sync upload route.
318
+
293
319
  **graph-to-md (Neo4j + NetworkX):** library lives under [`md_generator/graph/`](src/md_generator/graph/). **Sources:** **`networkx`** (GraphML/GML via `graph.graph_file` or `--graph-file`) or **`neo4j`** (`graph.uri`, `graph.user`, `graph.password`, optional `graph.database` for `session(database=…)`). **Output layout:** by default **`output.combine_markdown: true`** writes **`nodes.md`**, **`relationship.md`**, and **`graph_summary.md`** (summary plus embedded nodes and relationships). Set **`combine_markdown: false`** or CLI **`--individual` / `--markdown-layout individual`** for per-entity files under **`nodes/`** and **`relationships/`**. **Diagrams:** **`viz.mermaid: true`** (default) writes **`graph/graph.mmd`** and embeds a fenced Mermaid block in the export **`README.md`** (no Graphviz required). **`viz.enabled: true`** or CLI **`--viz`** also writes **`graph/graph.dot`** and runs **`dot`** for PNG/SVG/PDF when Graphviz is on `PATH` (or **`GRAPHVIZ_DOT`**). CLI **`--no-mermaid`** disables Mermaid; **`--depth`**, **`--start-node`**, **`--max-nodes`**, **`--max-edges`** bound traversal. Packaged defaults: [`src/md_generator/graph/config/default.yaml`](src/md_generator/graph/config/default.yaml). Tests: **`graph-to-md/tests/`**; API image: [`graph-to-md/Dockerfile.api`](graph-to-md/Dockerfile.api).
294
320
 
295
321
  Every command accepts **`-h` / `--help`** for full flags (artifact layout, OCR, ZIP options, etc.).
@@ -606,7 +632,7 @@ Equivalent modules: `python -m md_generator.media.audio.api.mcp_server`, `python
606
632
 
607
633
  ### Thin shims (repo clone)
608
634
 
609
- [`audio-to-md/converter.py`](audio-to-md/converter.py), [`video-to-md/converter.py`](video-to-md/converter.py), and [`youtube-to-md/converter.py`](youtube-to-md/converter.py) delegate to the same `main` as `md-audio` / `md-video` / `md-youtube`. Tests and `pytest.ini` live under `audio-to-md/tests/`, `video-to-md/tests/`, and `youtube-to-md/tests/`. [`db-to-md/converter.py`](db-to-md/converter.py) delegates to `md-db`; tests live under `db-to-md/tests/`. **graph-to-md** uses `md-graph` / `mdengine graph-to-md` directly (no thin `converter.py` shim); tests live under [`graph-to-md/tests/`](graph-to-md/tests/).
635
+ [`audio-to-md/converter.py`](audio-to-md/converter.py), [`video-to-md/converter.py`](video-to-md/converter.py), and [`youtube-to-md/converter.py`](youtube-to-md/converter.py) delegate to the same `main` as `md-audio` / `md-video` / `md-youtube`. Tests and `pytest.ini` live under `audio-to-md/tests/`, `video-to-md/tests/`, and `youtube-to-md/tests/`. [`db-to-md/converter.py`](db-to-md/converter.py) delegates to `md-db`; tests live under `db-to-md/tests/`. **graph-to-md** uses `md-graph` / `mdengine graph-to-md` directly (no thin `converter.py` shim); tests live under [`graph-to-md/tests/`](graph-to-md/tests/). [`openapi-to-md/converter.py`](openapi-to-md/converter.py) delegates to `md-openapi`; tests live under [`openapi-to-md/tests/`](openapi-to-md/tests/); example OpenAPI and output notes: [`openapi-to-md/examples/`](openapi-to-md/examples/).
610
636
 
611
637
  ---
612
638
 
@@ -638,6 +664,7 @@ Install `mdengine[api]` plus the format extra(s), then run the **`app`** object
638
664
  | Playwright / SPA | `md_generator.playwright.api.main:app` | `playwright`, `api`, `mcp` |
639
665
  | Database metadata | `md_generator.db.api.main:app` | `db`, `api`, `mcp` |
640
666
  | Graph metadata (Neo4j / NetworkX) | `md_generator.graph.api.main:app` | `graph`, `api`, `mcp` |
667
+ | OpenAPI → Markdown | `md_generator.openapi.api.main:app` | `openapi`, `api`, `mcp` |
641
668
  | Audio (Whisper) | `md_generator.media.audio.api.main:create_app` (use **`--factory`**) or `…main:app` | `audio`, `api`, `mcp` |
642
669
  | Video (Whisper) | `md_generator.media.video.api.main:create_app` (use **`--factory`**) or `…main:app` | `video`, `api`, `mcp` |
643
670
  | YouTube | `md_generator.media.youtube.api.main:create_app` (use **`--factory`**) or `…main:app` | `youtube`, `api`, `mcp` |
@@ -651,12 +678,13 @@ uvicorn md_generator.archive.api.main:app --host 127.0.0.1 --port 8010
651
678
  uvicorn md_generator.url.api.main:app --host 127.0.0.1 --port 8011
652
679
  uvicorn md_generator.playwright.api.main:app --host 127.0.0.1 --port 8014
653
680
  uvicorn md_generator.graph.api.main:app --host 127.0.0.1 --port 8012
681
+ uvicorn md_generator.openapi.api.main:app --host 127.0.0.1 --port 8015
654
682
  uvicorn md_generator.media.audio.api.main:create_app --factory --host 127.0.0.1 --port 8011
655
683
  uvicorn md_generator.media.video.api.main:create_app --factory --host 127.0.0.1 --port 8012
656
684
  uvicorn md_generator.media.youtube.api.main:create_app --factory --host 127.0.0.1 --port 8013
657
685
  ```
658
686
 
659
- **Port note:** **`md-graph-api`** and **`md-video-api`** both default to **8012**; set **`GRAPH_TO_MD_PORT`** or **`MD_VIDEO_API_PORT`** when you need both on one machine.
687
+ **Port note:** **`md-graph-api`** and **`md-video-api`** both default to **8012**; set **`GRAPH_TO_MD_PORT`** or **`MD_VIDEO_API_PORT`** when you need both on one machine. **`md-openapi-api`** defaults to **8015** (`OPENAPI_TO_MD_PORT`) so it does not collide with **`md-youtube-api`** (**8013**) or **`md-playwright-api`** (**8014**).
660
688
 
661
689
  ### MCP over HTTP on the same server
662
690
 
@@ -678,6 +706,7 @@ Prefixes differ per service (often read from a `.env` file next to the process):
678
706
  | Playwright / SPA | `PLAYWRIGHT_TO_MD_` | `PLAYWRIGHT_TO_MD_MAX_SYNC_URLS`, `PLAYWRIGHT_TO_MD_MAX_JOB_URLS`, `PLAYWRIGHT_TO_MD_JOB_TTL_SECONDS`, `PLAYWRIGHT_TO_MD_TEMP_DIR`, `PLAYWRIGHT_TO_MD_CORS_ORIGINS`, `PLAYWRIGHT_TO_MD_API_HOST`, `PLAYWRIGHT_TO_MD_API_PORT` (default **8014**) |
679
707
  | Database metadata | `DB_TO_MD_` | `DB_TO_MD_JOB_SQLITE_PATH`, `DB_TO_MD_JOB_WORKSPACE_ROOT`, `DB_TO_MD_CORS_ORIGINS`, `DB_TO_MD_MAX_SYNC_ZIP_MB`, `DB_TO_MD_HOST`, `DB_TO_MD_PORT` (default **8010**) |
680
708
  | Graph metadata | `GRAPH_TO_MD_` | `GRAPH_TO_MD_JOB_SQLITE_PATH`, `GRAPH_TO_MD_JOB_WORKSPACE_ROOT`, `GRAPH_TO_MD_CORS_ORIGINS`, `GRAPH_TO_MD_MAX_SYNC_ZIP_MB`, `GRAPH_TO_MD_HOST`, `GRAPH_TO_MD_PORT` (default **8012**) |
709
+ | OpenAPI → Markdown | `OPENAPI_TO_MD_` | `OPENAPI_TO_MD_CORS_ORIGINS`, `OPENAPI_TO_MD_MAX_SYNC_ZIP_MB`, `OPENAPI_TO_MD_HOST`, `OPENAPI_TO_MD_PORT` (default **8015**) |
681
710
  | Audio API | `MD_AUDIO_` | `MD_AUDIO_MAX_UPLOAD_MB`, `MD_AUDIO_MAX_SYNC_UPLOAD_MB`, `MD_AUDIO_JOB_TTL_SECONDS`, `MD_AUDIO_TEMP_DIR`, `MD_AUDIO_CORS_ORIGINS`, `MD_AUDIO_API_HOST`, `MD_AUDIO_API_PORT` |
682
711
  | Video API | `MD_VIDEO_` | Same pattern as audio with `MD_VIDEO_*` (defaults: larger upload/sync caps, port **8012**) |
683
712
  | YouTube API | `MD_YOUTUBE_` | `MD_YOUTUBE_JOB_TTL_SECONDS`, `MD_YOUTUBE_TEMP_DIR`, `MD_YOUTUBE_CORS_ORIGINS`, `MD_YOUTUBE_API_HOST`, `MD_YOUTUBE_API_PORT` (default **8013**); optional `MD_YOUTUBE_YTDLP` path for audio fallback |
@@ -710,6 +739,7 @@ Two usage patterns:
710
739
  | YouTube | `md-youtube-mcp` or `python -m md_generator.media.youtube.api.mcp_server` — same transports |
711
740
  | Database metadata | `md-db-mcp` or `python -m md_generator.db.api.mcp_server` — `--transport stdio` (default), `sse`, `streamable-http` |
712
741
  | Graph (Neo4j / NetworkX) | `md-graph-mcp` or `python -m md_generator.graph.api.mcp_server` — `--transport stdio` (default), `sse`, `streamable-http` |
742
+ | OpenAPI → Markdown | `md-openapi-mcp` or `python -m md_generator.openapi.api.mcp_server` — `--transport stdio` (default), `sse`, `streamable-http` |
713
743
 
714
744
  **Word** and **XLSX** also ship a small runner script in the repo:
715
745
 
@@ -734,7 +764,7 @@ pip install -e ".[dev,all]" # or a smaller subset of extras
734
764
  python -m pytest
735
765
  ```
736
766
 
737
- Tests live under each legacy folder’s `tests/` directory (e.g. `pdf-to-md/tests/`) and **`graph-to-md/tests/`**; `pyproject.toml` configures `pythonpath = ["src"]` so `md_generator` resolves without a separate `PYTHONPATH`.
767
+ Tests live under each legacy folder’s `tests/` directory (e.g. `pdf-to-md/tests/`), **`graph-to-md/tests/`**, and **`openapi-to-md/tests/`**; `pyproject.toml` configures `pythonpath = ["src"]` so `md_generator` resolves without a separate `PYTHONPATH`.
738
768
 
739
769
  ---
740
770
 
@@ -129,17 +129,26 @@ If the shell reports “command not found”, ensure the Python **Scripts** dire
129
129
  | `md-video-mcp` | `md_generator.media.video.api.mcp_server:main` | Same for video |
130
130
  | `md-youtube-mcp` | `md_generator.media.youtube.api.mcp_server:main` | Same for YouTube (`youtube_url_to_markdown`) |
131
131
  | `md-db` | `md_generator.db.cli.main:main` | `pip install "mdengine[db]"` then `md-db --config db.yaml` (or `mdengine db-to-md …`) |
132
- | `md-db-api` | `md_generator.db.api.run:main` | FastAPI on port **8010** (`DB_TO_MD_PORT`): `POST /db-to-md/run`, `/db-to-md/job`, SSE `/db-to-md/job/{id}/events` |
132
+ | `md-db-api` | `md_generator.db.api.run:main` | FastAPI on port **8010** (`DB_TO_MD_PORT`): `POST /db-to-md/run`, `POST /db-to-md/run/sqlite` (upload + ZIP), `POST /db-to-md/job`, `POST /db-to-md/job/sqlite` (upload + async job), SSE `/db-to-md/job/{id}/events` |
133
133
  | `md-db-mcp` | `md_generator.db.api.mcp_server:main` | Standalone MCP for metadata export tools |
134
134
  | `md-graph` | `md_generator.graph.cli.main:main` | `pip install "mdengine[graph]"` then `md-graph --source neo4j --uri bolt://…` (or `mdengine graph-to-md …`) |
135
135
  | `md-graph-api` | `md_generator.graph.api.run:main` | FastAPI on port **8012** (`GRAPH_TO_MD_PORT`): `POST /graph-to-md/run`, `/graph-to-md/job`, SSE `/graph-to-md/job/{id}/events` |
136
136
  | `md-graph-mcp` | `md_generator.graph.api.mcp_server:main` | Standalone MCP for graph export tools |
137
- | `mdengine` | `md_generator.engine_cli:main` | `mdengine db-to-md …` / `mdengine graph-to-md …` (delegates to `md-db` / `md-graph`) |
137
+ | `md-openapi` | `md_generator.openapi.cli.main:main` | `pip install "mdengine[openapi]"` then `md-openapi generate --file openapi.yaml --output ./docs` (or `mdengine openapi-to-md generate …`) |
138
+ | `md-openapi-api` | `md_generator.openapi.api.run:main` | FastAPI on port **8015** (`OPENAPI_TO_MD_PORT`): `POST /openapi-to-md/generate` (OpenAPI upload → ZIP), `/health`, MCP at **`/mcp`** |
139
+ | `md-openapi-mcp` | `md_generator.openapi.api.mcp_server:main` | Standalone MCP: `api_validate_openapi_yaml`, `api_generate_readme_markdown`, `api_run_sync_zip_base64` |
140
+ | `mdengine` | `md_generator.engine_cli:main` | `mdengine db-to-md …` / `mdengine graph-to-md …` / `mdengine openapi-to-md generate …` |
141
+
142
+ **openapi-to-md (`md-openapi`):** OpenAPI **3.x** is parsed directly; **Swagger 2.0** (`swagger: "2.0"`) documents are **converted in-process** to OpenAPI 3.0.3 (deterministic, in-repo converter) before `$ref` resolution. Edge-heavy specs (unusual OAuth2 flows, vendor extensions) may still need fixes after conversion.
138
143
 
139
144
  **db-to-md ER diagrams:** add **`erd`** to the export feature list (YAML `features.include`, API body, or CLI `--include …,erd`). **Preferred:** **Graphviz** (`dot` on `PATH`, or **`GRAPHVIZ_DOT`**) produces `erd/*.dot`, `erd/*.png`, and `erd/*.svg`. **If Graphviz is missing,** the exporter falls back to **Mermaid** (`erDiagram`): it writes `erd/*.mermaid` plus a fenced **`erd/*.md`** for GitHub-style preview. With **`mermaid-py`** (included in `mdengine[db]`), it also requests **PNG/SVG** via mermaid.ink (requires network unless you self-host mermaid.ink and set **`MERMAID_INK_SERVER`** per [mermaid-py](https://pypi.org/project/mermaid-py/)). Tune **`erd.max_tables`** (default 100) and **`erd.scope`** (`full` \| `per_schema` \| `per_table`) under `erd:` in YAML; CLI: `--erd-max-tables`, `--erd-scope`. Async job SSE uses `progress_update` with `current` starting with `erd:`.
140
145
 
141
146
  **db-to-md split exports and README merge:** with **`output.split_files: true`**, set **`output.write_combined_feature_markdown: true`** to also write root-level combined Markdown (for example `tables.md`, `functions.md`, `indexes.md`, and feature-specific paths such as `oracle/packages.md` or `mongodb/collections.md` when those features run). Set **`output.readme_feature_merge`** to **`inline`** (append full bundle bodies into `README.md`) or **`toc`** (append a linked list to those files). If merge is not **`none`** and split files are on, combined bundle writes are turned on automatically when loading config. CLI: `--write-combined-feature-markdown`, `--readme-feature-merge none|inline|toc`.
142
147
 
148
+ **db-to-md SQLite:** set **`database.type: sqlite`** and **`database.uri`** to a SQLAlchemy URL such as **`sqlite:///my.db`** or **`sqlite:////C:/data/my.db`**. The default SQLite catalog is **`main`**; packaged YAML that still has **`schema: public`** is normalized to **`main`** when the type is SQLite. CLI: **`--type sqlite`**. Stored routines, sequences, and partitions are not used by SQLite and stay empty; tables, indexes, views, triggers, and ERD (via FK introspection) follow the same export path as other SQL engines.
149
+
150
+ **db-to-md API SQLite upload:** **`POST /db-to-md/run/sqlite`** — `multipart/form-data` with field **`file`** (the `.sqlite` / `.db` bytes; must start with the standard `SQLite format 3` header) and optional **`config`** (JSON string with the same shape as a normal run body minus `database`: `schema`, `output`, `features`, `execution`, `limits`, `erd`). Returns the metadata ZIP immediately. **`POST /db-to-md/job/sqlite`** — same form fields; saves the file under the job workspace and runs the existing job pipeline (`GET /db-to-md/job/{id}/download` when complete). Upload size cap: env **`DB_TO_MD_MAX_SQLITE_UPLOAD_MB`** (default **256**). Large ZIPs may still require the async job path if they exceed **`DB_TO_MD_MAX_SYNC_ZIP_MB`** on the sync upload route.
151
+
143
152
  **graph-to-md (Neo4j + NetworkX):** library lives under [`md_generator/graph/`](src/md_generator/graph/). **Sources:** **`networkx`** (GraphML/GML via `graph.graph_file` or `--graph-file`) or **`neo4j`** (`graph.uri`, `graph.user`, `graph.password`, optional `graph.database` for `session(database=…)`). **Output layout:** by default **`output.combine_markdown: true`** writes **`nodes.md`**, **`relationship.md`**, and **`graph_summary.md`** (summary plus embedded nodes and relationships). Set **`combine_markdown: false`** or CLI **`--individual` / `--markdown-layout individual`** for per-entity files under **`nodes/`** and **`relationships/`**. **Diagrams:** **`viz.mermaid: true`** (default) writes **`graph/graph.mmd`** and embeds a fenced Mermaid block in the export **`README.md`** (no Graphviz required). **`viz.enabled: true`** or CLI **`--viz`** also writes **`graph/graph.dot`** and runs **`dot`** for PNG/SVG/PDF when Graphviz is on `PATH` (or **`GRAPHVIZ_DOT`**). CLI **`--no-mermaid`** disables Mermaid; **`--depth`**, **`--start-node`**, **`--max-nodes`**, **`--max-edges`** bound traversal. Packaged defaults: [`src/md_generator/graph/config/default.yaml`](src/md_generator/graph/config/default.yaml). Tests: **`graph-to-md/tests/`**; API image: [`graph-to-md/Dockerfile.api`](graph-to-md/Dockerfile.api).
144
153
 
145
154
  Every command accepts **`-h` / `--help`** for full flags (artifact layout, OCR, ZIP options, etc.).
@@ -456,7 +465,7 @@ Equivalent modules: `python -m md_generator.media.audio.api.mcp_server`, `python
456
465
 
457
466
  ### Thin shims (repo clone)
458
467
 
459
- [`audio-to-md/converter.py`](audio-to-md/converter.py), [`video-to-md/converter.py`](video-to-md/converter.py), and [`youtube-to-md/converter.py`](youtube-to-md/converter.py) delegate to the same `main` as `md-audio` / `md-video` / `md-youtube`. Tests and `pytest.ini` live under `audio-to-md/tests/`, `video-to-md/tests/`, and `youtube-to-md/tests/`. [`db-to-md/converter.py`](db-to-md/converter.py) delegates to `md-db`; tests live under `db-to-md/tests/`. **graph-to-md** uses `md-graph` / `mdengine graph-to-md` directly (no thin `converter.py` shim); tests live under [`graph-to-md/tests/`](graph-to-md/tests/).
468
+ [`audio-to-md/converter.py`](audio-to-md/converter.py), [`video-to-md/converter.py`](video-to-md/converter.py), and [`youtube-to-md/converter.py`](youtube-to-md/converter.py) delegate to the same `main` as `md-audio` / `md-video` / `md-youtube`. Tests and `pytest.ini` live under `audio-to-md/tests/`, `video-to-md/tests/`, and `youtube-to-md/tests/`. [`db-to-md/converter.py`](db-to-md/converter.py) delegates to `md-db`; tests live under `db-to-md/tests/`. **graph-to-md** uses `md-graph` / `mdengine graph-to-md` directly (no thin `converter.py` shim); tests live under [`graph-to-md/tests/`](graph-to-md/tests/). [`openapi-to-md/converter.py`](openapi-to-md/converter.py) delegates to `md-openapi`; tests live under [`openapi-to-md/tests/`](openapi-to-md/tests/); example OpenAPI and output notes: [`openapi-to-md/examples/`](openapi-to-md/examples/).
460
469
 
461
470
  ---
462
471
 
@@ -488,6 +497,7 @@ Install `mdengine[api]` plus the format extra(s), then run the **`app`** object
488
497
  | Playwright / SPA | `md_generator.playwright.api.main:app` | `playwright`, `api`, `mcp` |
489
498
  | Database metadata | `md_generator.db.api.main:app` | `db`, `api`, `mcp` |
490
499
  | Graph metadata (Neo4j / NetworkX) | `md_generator.graph.api.main:app` | `graph`, `api`, `mcp` |
500
+ | OpenAPI → Markdown | `md_generator.openapi.api.main:app` | `openapi`, `api`, `mcp` |
491
501
  | Audio (Whisper) | `md_generator.media.audio.api.main:create_app` (use **`--factory`**) or `…main:app` | `audio`, `api`, `mcp` |
492
502
  | Video (Whisper) | `md_generator.media.video.api.main:create_app` (use **`--factory`**) or `…main:app` | `video`, `api`, `mcp` |
493
503
  | YouTube | `md_generator.media.youtube.api.main:create_app` (use **`--factory`**) or `…main:app` | `youtube`, `api`, `mcp` |
@@ -501,12 +511,13 @@ uvicorn md_generator.archive.api.main:app --host 127.0.0.1 --port 8010
501
511
  uvicorn md_generator.url.api.main:app --host 127.0.0.1 --port 8011
502
512
  uvicorn md_generator.playwright.api.main:app --host 127.0.0.1 --port 8014
503
513
  uvicorn md_generator.graph.api.main:app --host 127.0.0.1 --port 8012
514
+ uvicorn md_generator.openapi.api.main:app --host 127.0.0.1 --port 8015
504
515
  uvicorn md_generator.media.audio.api.main:create_app --factory --host 127.0.0.1 --port 8011
505
516
  uvicorn md_generator.media.video.api.main:create_app --factory --host 127.0.0.1 --port 8012
506
517
  uvicorn md_generator.media.youtube.api.main:create_app --factory --host 127.0.0.1 --port 8013
507
518
  ```
508
519
 
509
- **Port note:** **`md-graph-api`** and **`md-video-api`** both default to **8012**; set **`GRAPH_TO_MD_PORT`** or **`MD_VIDEO_API_PORT`** when you need both on one machine.
520
+ **Port note:** **`md-graph-api`** and **`md-video-api`** both default to **8012**; set **`GRAPH_TO_MD_PORT`** or **`MD_VIDEO_API_PORT`** when you need both on one machine. **`md-openapi-api`** defaults to **8015** (`OPENAPI_TO_MD_PORT`) so it does not collide with **`md-youtube-api`** (**8013**) or **`md-playwright-api`** (**8014**).
510
521
 
511
522
  ### MCP over HTTP on the same server
512
523
 
@@ -528,6 +539,7 @@ Prefixes differ per service (often read from a `.env` file next to the process):
528
539
  | Playwright / SPA | `PLAYWRIGHT_TO_MD_` | `PLAYWRIGHT_TO_MD_MAX_SYNC_URLS`, `PLAYWRIGHT_TO_MD_MAX_JOB_URLS`, `PLAYWRIGHT_TO_MD_JOB_TTL_SECONDS`, `PLAYWRIGHT_TO_MD_TEMP_DIR`, `PLAYWRIGHT_TO_MD_CORS_ORIGINS`, `PLAYWRIGHT_TO_MD_API_HOST`, `PLAYWRIGHT_TO_MD_API_PORT` (default **8014**) |
529
540
  | Database metadata | `DB_TO_MD_` | `DB_TO_MD_JOB_SQLITE_PATH`, `DB_TO_MD_JOB_WORKSPACE_ROOT`, `DB_TO_MD_CORS_ORIGINS`, `DB_TO_MD_MAX_SYNC_ZIP_MB`, `DB_TO_MD_HOST`, `DB_TO_MD_PORT` (default **8010**) |
530
541
  | Graph metadata | `GRAPH_TO_MD_` | `GRAPH_TO_MD_JOB_SQLITE_PATH`, `GRAPH_TO_MD_JOB_WORKSPACE_ROOT`, `GRAPH_TO_MD_CORS_ORIGINS`, `GRAPH_TO_MD_MAX_SYNC_ZIP_MB`, `GRAPH_TO_MD_HOST`, `GRAPH_TO_MD_PORT` (default **8012**) |
542
+ | OpenAPI → Markdown | `OPENAPI_TO_MD_` | `OPENAPI_TO_MD_CORS_ORIGINS`, `OPENAPI_TO_MD_MAX_SYNC_ZIP_MB`, `OPENAPI_TO_MD_HOST`, `OPENAPI_TO_MD_PORT` (default **8015**) |
531
543
  | Audio API | `MD_AUDIO_` | `MD_AUDIO_MAX_UPLOAD_MB`, `MD_AUDIO_MAX_SYNC_UPLOAD_MB`, `MD_AUDIO_JOB_TTL_SECONDS`, `MD_AUDIO_TEMP_DIR`, `MD_AUDIO_CORS_ORIGINS`, `MD_AUDIO_API_HOST`, `MD_AUDIO_API_PORT` |
532
544
  | Video API | `MD_VIDEO_` | Same pattern as audio with `MD_VIDEO_*` (defaults: larger upload/sync caps, port **8012**) |
533
545
  | YouTube API | `MD_YOUTUBE_` | `MD_YOUTUBE_JOB_TTL_SECONDS`, `MD_YOUTUBE_TEMP_DIR`, `MD_YOUTUBE_CORS_ORIGINS`, `MD_YOUTUBE_API_HOST`, `MD_YOUTUBE_API_PORT` (default **8013**); optional `MD_YOUTUBE_YTDLP` path for audio fallback |
@@ -560,6 +572,7 @@ Two usage patterns:
560
572
  | YouTube | `md-youtube-mcp` or `python -m md_generator.media.youtube.api.mcp_server` — same transports |
561
573
  | Database metadata | `md-db-mcp` or `python -m md_generator.db.api.mcp_server` — `--transport stdio` (default), `sse`, `streamable-http` |
562
574
  | Graph (Neo4j / NetworkX) | `md-graph-mcp` or `python -m md_generator.graph.api.mcp_server` — `--transport stdio` (default), `sse`, `streamable-http` |
575
+ | OpenAPI → Markdown | `md-openapi-mcp` or `python -m md_generator.openapi.api.mcp_server` — `--transport stdio` (default), `sse`, `streamable-http` |
563
576
 
564
577
  **Word** and **XLSX** also ship a small runner script in the repo:
565
578
 
@@ -584,7 +597,7 @@ pip install -e ".[dev,all]" # or a smaller subset of extras
584
597
  python -m pytest
585
598
  ```
586
599
 
587
- Tests live under each legacy folder’s `tests/` directory (e.g. `pdf-to-md/tests/`) and **`graph-to-md/tests/`**; `pyproject.toml` configures `pythonpath = ["src"]` so `md_generator` resolves without a separate `PYTHONPATH`.
600
+ Tests live under each legacy folder’s `tests/` directory (e.g. `pdf-to-md/tests/`), **`graph-to-md/tests/`**, and **`openapi-to-md/tests/`**; `pyproject.toml` configures `pythonpath = ["src"]` so `md_generator` resolves without a separate `PYTHONPATH`.
588
601
 
589
602
  ---
590
603
 
@@ -4,14 +4,14 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "mdengine"
7
- version = "0.5.0"
8
- description = "Convert PDF, Office, images, audio, video, text/JSON/XML, ZIP archives, and web URLs to Markdown."
7
+ version = "0.7.0"
8
+ description = "Convert PDF, Office, images, audio, video, text/JSON/XML, ZIP archives, web URLs, databases, graphs, and OpenAPI specs to Markdown."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
11
11
  license = "MIT"
12
12
  license-files = ["LICENSE"]
13
13
  authors = [{ name = "mdengine contributors" }]
14
- keywords = ["markdown", "pdf", "docx", "pptx", "xlsx", "ocr", "zip", "url", "html", "youtube", "playwright", "database"]
14
+ keywords = ["markdown", "pdf", "docx", "pptx", "xlsx", "ocr", "zip", "url", "html", "youtube", "playwright", "database", "openapi", "codeflow"]
15
15
  classifiers = [
16
16
  "Programming Language :: Python :: 3",
17
17
  "Programming Language :: Python :: 3 :: Only",
@@ -106,6 +106,24 @@ graph = [
106
106
  "neo4j>=5.14.0",
107
107
  "pyyaml>=6.0.0",
108
108
  ]
109
+ openapi = [
110
+ "pyyaml>=6.0.0",
111
+ "prance>=23.6.0",
112
+ "openapi-spec-validator>=0.7.0",
113
+ ]
114
+ codeflow = [
115
+ "networkx>=3.2.0",
116
+ "javalang>=0.13.0",
117
+ ]
118
+ codeflow-treesitter = [
119
+ "tree-sitter>=0.21.0",
120
+ "tree-sitter-javascript>=0.21.0",
121
+ "tree-sitter-typescript>=0.23.0",
122
+ "tree-sitter-cpp>=0.23.0",
123
+ ]
124
+ codeflow-clang = [
125
+ "clang>=16.0.0",
126
+ ]
109
127
  api = [
110
128
  "fastapi>=0.115.0",
111
129
  "uvicorn[standard]>=0.32.0",
@@ -126,6 +144,9 @@ dev = [
126
144
  "mdengine[playwright]",
127
145
  "mdengine[db]",
128
146
  "mdengine[graph]",
147
+ "mdengine[openapi]",
148
+ "mdengine[codeflow]",
149
+ "mdengine[codeflow-treesitter]",
129
150
  ]
130
151
  all = [
131
152
  "pymupdf>=1.24.0",
@@ -187,6 +208,13 @@ md-db-mcp = "md_generator.db.api.mcp_server:main"
187
208
  md-graph = "md_generator.graph.cli.main:main"
188
209
  md-graph-api = "md_generator.graph.api.run:main"
189
210
  md-graph-mcp = "md_generator.graph.api.mcp_server:main"
211
+ md-openapi = "md_generator.openapi.cli.main:main"
212
+ md-openapi-api = "md_generator.openapi.api.run:main"
213
+ md-openapi-mcp = "md_generator.openapi.api.mcp_server:main"
214
+ md-codeflow = "md_generator.codeflow.cli.main:main"
215
+ codeflow = "md_generator.codeflow.cli.main:main"
216
+ md-codeflow-api = "md_generator.codeflow.api.run:main"
217
+ md-codeflow-mcp = "md_generator.codeflow.api.mcp_server:main"
190
218
  mdengine = "md_generator.engine_cli:main"
191
219
 
192
220
  [tool.setuptools.packages.find]
@@ -195,6 +223,7 @@ where = ["src"]
195
223
  [tool.setuptools.package-data]
196
224
  "md_generator.db.config" = ["*.yaml"]
197
225
  "md_generator.graph.config" = ["*.yaml"]
226
+ "md_generator.openapi.config" = ["*.yaml"]
198
227
 
199
228
  [tool.pytest.ini_options]
200
229
  pythonpath = ["src"]
@@ -213,5 +242,7 @@ testpaths = [
213
242
  "playwright-to-md/tests",
214
243
  "db-to-md/tests",
215
244
  "graph-to-md/tests",
245
+ "openapi-to-md/tests",
246
+ "codeflow-to-md/tests",
216
247
  ]
217
248
  markers = ["integration: optional dependency or slower checks"]
@@ -1,5 +1,5 @@
1
1
  """md_generator: PDF, Office, image, text, and ZIP to Markdown conversion."""
2
2
 
3
- __version__ = "0.5.0"
3
+ __version__ = "0.7.0"
4
4
 
5
5
  __all__ = ["__version__"]
@@ -0,0 +1,7 @@
1
+ """Multi-language execution flow extraction → Markdown, Mermaid, graph JSON, HTML."""
2
+
3
+ from __future__ import annotations
4
+
5
+ __all__ = ["__version__"]
6
+
7
+ __version__ = "0.1.0"
@@ -0,0 +1,9 @@
1
+ from __future__ import annotations
2
+
3
+ from md_generator.codeflow.analyzers.flow_analyzer import (
4
+ FlowSlice,
5
+ slice_from_entry,
6
+ walk_with_depth,
7
+ )
8
+
9
+ __all__ = ["FlowSlice", "slice_from_entry", "walk_with_depth"]
@@ -0,0 +1,68 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass, field
4
+
5
+ import networkx as nx
6
+
7
+
8
+ @dataclass(slots=True)
9
+ class FlowSlice:
10
+ entry_id: str
11
+ nodes: set[str]
12
+ edges: list[tuple[str, str, dict]]
13
+ depth: int
14
+ cycle_nodes: set[str] = field(default_factory=set)
15
+ truncated: bool = False
16
+
17
+
18
+ def walk_with_depth(
19
+ g: nx.DiGraph,
20
+ start: str,
21
+ max_depth: int,
22
+ ) -> tuple[set[str], list[tuple[str, str, dict]], set[str], bool]:
23
+ """Reachability from start within ``max_depth`` hops (shortest-path layering)."""
24
+ if start not in g:
25
+ return {start}, [], set(), False
26
+ try:
27
+ plen = nx.single_source_shortest_path_length(g, start, cutoff=max_depth)
28
+ except nx.NetworkXError:
29
+ plen = {start: 0}
30
+
31
+ nodes = set(plen.keys())
32
+ edges_out: list[tuple[str, str, dict]] = []
33
+ cycle_guess: set[str] = set()
34
+ truncated = False
35
+
36
+ for u in nodes:
37
+ du = plen[u]
38
+ if du >= max_depth:
39
+ succ = list(g.successors(u))
40
+ if succ:
41
+ truncated = True
42
+ continue
43
+ for v in g.successors(u):
44
+ ed = dict(g.edges[u, v])
45
+ edges_out.append((u, v, ed))
46
+ dv = plen.get(v)
47
+ if dv is not None and dv <= du:
48
+ cycle_guess.add(v)
49
+ if v not in plen and du + 1 > max_depth:
50
+ truncated = True
51
+
52
+ return nodes, edges_out, cycle_guess, truncated
53
+
54
+
55
+ def slice_from_entry(
56
+ g: nx.DiGraph,
57
+ entry_id: str,
58
+ max_depth: int,
59
+ ) -> FlowSlice:
60
+ nodes, edges, cycles, truncated = walk_with_depth(g, entry_id, max_depth)
61
+ return FlowSlice(
62
+ entry_id=entry_id,
63
+ nodes=nodes,
64
+ edges=edges,
65
+ depth=max_depth,
66
+ cycle_nodes=cycles,
67
+ truncated=truncated,
68
+ )
@@ -0,0 +1 @@
1
+ from __future__ import annotations