scitex 2.10.3__py3-none-any.whl → 2.13.0__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 (504) hide show
  1. scitex/__init__.py +1 -4
  2. scitex/__main__.py +24 -5
  3. scitex/__version__.py +1 -1
  4. scitex/_install_guide.py +14 -2
  5. scitex/_optional_deps.py +33 -0
  6. scitex/ai/classification/reporters/_ClassificationReporter.py +1 -1
  7. scitex/ai/classification/timeseries/_TimeSeriesBlockingSplit.py +2 -2
  8. scitex/ai/classification/timeseries/_TimeSeriesCalendarSplit.py +2 -2
  9. scitex/ai/classification/timeseries/_TimeSeriesSlidingWindowSplit.py +2 -2
  10. scitex/ai/classification/timeseries/_TimeSeriesSlidingWindowSplit_v01-not-using-n_splits.py +2 -2
  11. scitex/ai/classification/timeseries/_TimeSeriesStratifiedSplit.py +2 -2
  12. scitex/ai/classification/timeseries/_normalize_timestamp.py +1 -1
  13. scitex/ai/metrics/_calc_seizure_prediction_metrics.py +1 -1
  14. scitex/ai/plt/_plot_feature_importance.py +1 -1
  15. scitex/ai/plt/_plot_learning_curve.py +1 -1
  16. scitex/ai/plt/_plot_optuna_study.py +1 -1
  17. scitex/ai/plt/_plot_pre_rec_curve.py +1 -1
  18. scitex/ai/plt/_plot_roc_curve.py +1 -1
  19. scitex/ai/plt/_stx_conf_mat.py +1 -1
  20. scitex/ai/training/_LearningCurveLogger.py +1 -1
  21. scitex/audio/mcp_server.py +38 -8
  22. scitex/bridge/_figrecipe.py +1 -1
  23. scitex/bridge/_helpers.py +1 -1
  24. scitex/bridge/_plt_vis.py +1 -1
  25. scitex/bridge/_stats_plt.py +1 -1
  26. scitex/bridge/_stats_vis.py +2 -2
  27. scitex/browser/automation/CookieHandler.py +1 -1
  28. scitex/browser/core/BrowserMixin.py +1 -1
  29. scitex/browser/core/ChromeProfileManager.py +1 -1
  30. scitex/browser/debugging/_browser_logger.py +1 -1
  31. scitex/browser/debugging/_highlight_element.py +1 -1
  32. scitex/browser/debugging/_show_grid.py +1 -1
  33. scitex/browser/interaction/click_center.py +1 -1
  34. scitex/browser/interaction/click_with_fallbacks.py +1 -1
  35. scitex/browser/interaction/close_popups.py +1 -1
  36. scitex/browser/interaction/fill_with_fallbacks.py +1 -1
  37. scitex/browser/pdf/click_download_for_chrome_pdf_viewer.py +1 -1
  38. scitex/browser/pdf/detect_chrome_pdf_viewer.py +1 -1
  39. scitex/browser/stealth/HumanBehavior.py +1 -1
  40. scitex/browser/stealth/StealthManager.py +1 -1
  41. scitex/{fig → canvas}/__init__.py +84 -96
  42. scitex/canvas/_mcp_handlers.py +372 -0
  43. scitex/canvas/_mcp_tool_schemas.py +219 -0
  44. scitex/{fig → canvas}/backend/_parser.py +1 -1
  45. scitex/{fig → canvas}/canvas.py +13 -14
  46. scitex/{fts/_fig/_editor → canvas/editor}/_defaults.py +2 -2
  47. scitex/{fig → canvas}/editor/edit/__init__.py +11 -14
  48. scitex/{fig → canvas}/editor/edit/bundle_resolver.py +56 -48
  49. scitex/{fig → canvas}/editor/edit/editor_launcher.py +79 -26
  50. scitex/{fts/_fig/_editor/_cui/_panel_loader.py → canvas/editor/edit/panel_loader.py} +8 -8
  51. scitex/{fts/_fig/_editor/_gui/_flask_editor → canvas/editor/flask_editor}/_bbox.py +2 -1
  52. scitex/{fts/_fig/_editor/_gui/_flask_editor → canvas/editor/flask_editor}/_core.py +84 -84
  53. scitex/{fts/_fig/_editor/_gui/_flask_editor → canvas/editor/flask_editor}/_renderer.py +7 -6
  54. scitex/{fts/_fig/_editor/_gui/_flask_editor → canvas/editor/flask_editor}/static/css/features/canvas.css +2 -2
  55. scitex/{fig → canvas}/editor/flask_editor/static/css/features/panel-grid.css +1 -1
  56. scitex/{fig → canvas}/editor/flask_editor/static/js/core/api.js +3 -4
  57. scitex/{fig → canvas}/editor/flask_editor/static/js/editor/preview.js +5 -5
  58. scitex/{fig → canvas}/editor/flask_editor/templates/_html.py +3 -3
  59. scitex/{fig → canvas}/editor/flask_editor/templates/_scripts.py +10 -10
  60. scitex/{fig → canvas}/editor/flask_editor/templates/_styles.py +3 -3
  61. scitex/{fig → canvas}/io/__init__.py +32 -38
  62. scitex/{fig → canvas}/io/_bundle.py +217 -154
  63. scitex/{fig → canvas}/io/_canvas.py +1 -1
  64. scitex/{fig → canvas}/io/_data.py +1 -1
  65. scitex/{fig → canvas}/io/_export.py +1 -1
  66. scitex/{fig → canvas}/io/_load.py +1 -1
  67. scitex/{fig → canvas}/io/_panel.py +1 -1
  68. scitex/{fig → canvas}/io/_save.py +1 -1
  69. scitex/canvas/mcp_server.py +151 -0
  70. scitex/{fig → canvas}/model/__init__.py +1 -1
  71. scitex/{fig → canvas}/model/_annotations.py +1 -1
  72. scitex/{fig → canvas}/model/_axes.py +1 -1
  73. scitex/{fig → canvas}/model/_figure.py +1 -1
  74. scitex/{fig → canvas}/model/_guides.py +1 -1
  75. scitex/{fig → canvas}/model/_plot.py +1 -1
  76. scitex/{fig → canvas}/model/_styles.py +1 -1
  77. scitex/{fig → canvas}/utils/__init__.py +1 -1
  78. scitex/capture/mcp_server.py +41 -12
  79. scitex/cli/audio.py +233 -0
  80. scitex/cli/capture.py +307 -0
  81. scitex/cli/convert.py +10 -6
  82. scitex/cli/main.py +27 -4
  83. scitex/cli/repro.py +233 -0
  84. scitex/cli/resource.py +240 -0
  85. scitex/cli/stats.py +325 -0
  86. scitex/cli/template.py +236 -0
  87. scitex/cli/tex.py +286 -0
  88. scitex/cli/web.py +11 -12
  89. scitex/dev/__init__.py +3 -0
  90. scitex/dev/_pyproject.py +405 -0
  91. scitex/dev/plt/__init__.py +2 -2
  92. scitex/dev/plt/mpl/get_dir_ax.py +1 -1
  93. scitex/dev/plt/mpl/get_signatures.py +1 -1
  94. scitex/dev/plt/mpl/get_signatures_details.py +1 -1
  95. scitex/diagram/README.md +7 -7
  96. scitex/diagram/_mcp_handlers.py +400 -0
  97. scitex/diagram/_mcp_tool_schemas.py +157 -0
  98. scitex/diagram/mcp_server.py +151 -0
  99. scitex/dsp/_demo_sig.py +51 -5
  100. scitex/dsp/_mne.py +13 -2
  101. scitex/dsp/_modulation_index.py +15 -3
  102. scitex/dsp/_pac.py +23 -5
  103. scitex/dsp/_psd.py +16 -4
  104. scitex/dsp/_resample.py +24 -4
  105. scitex/dsp/_transform.py +16 -3
  106. scitex/dsp/add_noise.py +15 -1
  107. scitex/dsp/norm.py +17 -2
  108. scitex/dsp/reference.py +17 -1
  109. scitex/dsp/utils/_differential_bandpass_filters.py +20 -2
  110. scitex/dsp/utils/_zero_pad.py +18 -4
  111. scitex/dt/_normalize_timestamp.py +1 -1
  112. scitex/git/_session.py +1 -1
  113. scitex/io/__init__.py +7 -19
  114. scitex/io/_load.py +15 -19
  115. scitex/io/_load_modules/_canvas.py +2 -2
  116. scitex/io/_load_modules/_con.py +17 -6
  117. scitex/io/_load_modules/_eeg.py +28 -13
  118. scitex/io/_load_modules/_optuna.py +21 -63
  119. scitex/io/_load_modules/_torch.py +11 -3
  120. scitex/io/_save.py +11 -16
  121. scitex/io/_save_modules/__init__.py +6 -10
  122. scitex/io/_save_modules/_canvas.py +3 -3
  123. scitex/io/_save_modules/_optuna_study_as_csv_and_pngs.py +13 -2
  124. scitex/io/_save_modules/_plot_bundle.py +112 -0
  125. scitex/io/_save_modules/{_pltz_stx.py → _plot_scitex.py} +7 -7
  126. scitex/io/_save_modules/_stx_bundle.py +16 -16
  127. scitex/io/_save_modules/_torch.py +11 -3
  128. scitex/io/bundle/README.md +89 -80
  129. scitex/{fts/_bundle/_FTS.py → io/bundle/_Bundle.py} +197 -95
  130. scitex/io/bundle/__init__.py +67 -35
  131. scitex/{fts/_bundle → io/bundle}/_children.py +32 -40
  132. scitex/io/bundle/_core.py +184 -97
  133. scitex/{fts/_bundle/_dataclasses/_Node.py → io/bundle/_dataclasses/_Spec.py} +29 -23
  134. scitex/{fts/_bundle/_dataclasses/_NodeRefs.py → io/bundle/_dataclasses/_SpecRefs.py} +6 -6
  135. scitex/{fts/_bundle → io/bundle}/_dataclasses/__init__.py +4 -4
  136. scitex/{fts/_bundle → io/bundle}/_loader.py +19 -19
  137. scitex/io/bundle/_manifest.py +99 -0
  138. scitex/{fts/_bundle → io/bundle}/_mpl_helpers.py +119 -28
  139. scitex/io/bundle/_nested.py +113 -100
  140. scitex/{fts/_bundle → io/bundle}/_saver.py +13 -14
  141. scitex/{fts/_bundle → io/bundle}/_storage.py +3 -3
  142. scitex/io/bundle/_types.py +41 -16
  143. scitex/{fts/_bundle → io/bundle}/_validation.py +20 -18
  144. scitex/io/bundle/_zip.py +21 -31
  145. scitex/{fts/_kinds → io/bundle/kinds}/_plot/_backend/_parser.py +1 -1
  146. scitex/{fts/_kinds → io/bundle/kinds}/_plot/_models/_Annotations.py +1 -1
  147. scitex/{fts/_kinds → io/bundle/kinds}/_plot/_models/_Axes.py +1 -1
  148. scitex/{fts/_kinds → io/bundle/kinds}/_plot/_models/_Figure.py +1 -1
  149. scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_Guides.py +1 -1
  150. scitex/{fts/_kinds → io/bundle/kinds}/_plot/_models/_Plot.py +1 -1
  151. scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_Styles.py +1 -1
  152. scitex/{fts/_kinds → io/bundle/kinds}/_plot/_utils/_plot_layout.py +1 -1
  153. scitex/{fts/_kinds → io/bundle/kinds}/_table/_latex/__init__.py +1 -1
  154. scitex/{fts/_kinds → io/bundle/kinds}/_table/_latex/_editor/_app.py +1 -1
  155. scitex/{fts/_tables → io/bundle/kinds/_table}/_latex/_export.py +1 -1
  156. scitex/{fts/_kinds → io/bundle/kinds}/_table/_latex/_figure_exporter.py +1 -1
  157. scitex/{fts/_kinds → io/bundle/kinds}/_table/_latex/_table_exporter.py +1 -1
  158. scitex/io/bundle/schemas/__init__.py +30 -0
  159. scitex/mcp_server.py +159 -0
  160. scitex/parallel/_run.py +5 -4
  161. scitex/path/_find.py +60 -83
  162. scitex/path/_get_module_path.py +23 -21
  163. scitex/path/_get_spath.py +6 -27
  164. scitex/path/_getsize.py +23 -9
  165. scitex/path/_increment_version.py +31 -38
  166. scitex/path/_mk_spath.py +26 -29
  167. scitex/path/_path.py +5 -12
  168. scitex/path/_split.py +27 -15
  169. scitex/path/_this_path.py +23 -9
  170. scitex/plt/_mcp_handlers.py +361 -0
  171. scitex/plt/_mcp_tool_schemas.py +169 -0
  172. scitex/plt/_subplots/_AxisWrapperMixins/_MatplotlibPlotMixin/__init__.py +2 -1
  173. scitex/plt/_subplots/_AxisWrapperMixins/__init__.py +2 -2
  174. scitex/plt/gallery/_generate.py +76 -50
  175. scitex/plt/io/__init__.py +17 -19
  176. scitex/plt/io/_bundle.py +99 -52
  177. scitex/plt/io/_layered_bundle.py +303 -168
  178. scitex/plt/mcp_server.py +205 -0
  179. scitex/plt/utils/_csv_column_naming.py +250 -118
  180. scitex/repro/README_RandomStateManager.md +3 -3
  181. scitex/repro/_RandomStateManager.py +14 -14
  182. scitex/repro/_gen_ID.py +1 -1
  183. scitex/repro/_gen_timestamp.py +1 -1
  184. scitex/repro/_hash_array.py +4 -4
  185. scitex/schema/__init__.py +69 -73
  186. scitex/schema/_canvas.py +1 -1
  187. scitex/schema/_stats.py +2 -2
  188. scitex/scholar/__main__.py +24 -2
  189. scitex/scholar/_mcp_handlers.py +685 -0
  190. scitex/scholar/_mcp_tool_schemas.py +339 -0
  191. scitex/scholar/docs/template.py +1 -1
  192. scitex/scholar/examples/07_storage_integration.py +1 -1
  193. scitex/scholar/impact_factor/jcr/ImpactFactorJCREngine.py +1 -1
  194. scitex/scholar/impact_factor/jcr/build_database.py +1 -1
  195. scitex/scholar/mcp_server.py +315 -0
  196. scitex/scholar/pdf_download/ScholarPDFDownloader.py +1 -1
  197. scitex/scholar/pipelines/ScholarPipelineBibTeX.py +1 -1
  198. scitex/scholar/pipelines/ScholarPipelineParallel.py +1 -1
  199. scitex/scholar/pipelines/ScholarPipelineSingle.py +1 -1
  200. scitex/scholar/storage/PaperIO.py +1 -1
  201. scitex/session/README.md +4 -4
  202. scitex/session/__init__.py +1 -1
  203. scitex/session/_decorator.py +9 -9
  204. scitex/session/_lifecycle.py +5 -5
  205. scitex/session/template.py +1 -1
  206. scitex/stats/__init__.py +30 -33
  207. scitex/stats/__main__.py +281 -0
  208. scitex/stats/_mcp_handlers.py +1191 -0
  209. scitex/stats/_mcp_tool_schemas.py +384 -0
  210. scitex/stats/_schema.py +1 -1
  211. scitex/stats/correct/_correct_bonferroni.py +1 -1
  212. scitex/stats/correct/_correct_fdr.py +1 -1
  213. scitex/stats/correct/_correct_fdr_.py +1 -1
  214. scitex/stats/correct/_correct_holm.py +1 -1
  215. scitex/stats/correct/_correct_sidak.py +1 -1
  216. scitex/stats/effect_sizes/_cliffs_delta.py +1 -1
  217. scitex/stats/effect_sizes/_cohens_d.py +1 -1
  218. scitex/stats/effect_sizes/_epsilon_squared.py +1 -1
  219. scitex/stats/effect_sizes/_eta_squared.py +1 -1
  220. scitex/stats/effect_sizes/_prob_superiority.py +1 -1
  221. scitex/stats/io/__init__.py +10 -11
  222. scitex/stats/io/_bundle.py +16 -16
  223. scitex/stats/mcp_server.py +405 -0
  224. scitex/stats/posthoc/_dunnett.py +1 -1
  225. scitex/stats/posthoc/_games_howell.py +1 -1
  226. scitex/stats/posthoc/_tukey_hsd.py +1 -1
  227. scitex/stats/power/_power.py +1 -1
  228. scitex/stats/utils/_effect_size.py +1 -1
  229. scitex/stats/utils/_formatters.py +1 -1
  230. scitex/stats/utils/_power.py +1 -1
  231. scitex/template/_mcp_handlers.py +259 -0
  232. scitex/template/_mcp_tool_schemas.py +112 -0
  233. scitex/template/mcp_server.py +186 -0
  234. scitex/utils/_verify_scitex_format.py +2 -2
  235. scitex/utils/template.py +1 -1
  236. scitex/web/__init__.py +12 -11
  237. scitex/web/_scraping.py +26 -265
  238. scitex/web/download_images.py +316 -0
  239. scitex/writer/Writer.py +1 -1
  240. scitex/writer/_clone_writer_project.py +1 -1
  241. scitex/writer/_validate_tree_structures.py +1 -1
  242. scitex/writer/dataclasses/config/_WriterConfig.py +1 -1
  243. scitex/writer/dataclasses/contents/_ManuscriptContents.py +1 -1
  244. scitex/writer/dataclasses/core/_Document.py +1 -1
  245. scitex/writer/dataclasses/core/_DocumentSection.py +1 -1
  246. scitex/writer/dataclasses/results/_CompilationResult.py +1 -1
  247. scitex/writer/dataclasses/results/_LaTeXIssue.py +1 -1
  248. scitex/writer/utils/.legacy_git_retry.py +7 -5
  249. scitex/writer/utils/_parse_latex_logs.py +1 -1
  250. scitex-2.13.0.dist-info/METADATA +1231 -0
  251. {scitex-2.10.3.dist-info → scitex-2.13.0.dist-info}/RECORD +376 -470
  252. scitex-2.13.0.dist-info/entry_points.txt +11 -0
  253. scitex/fig/editor/_defaults.py +0 -300
  254. scitex/fig/editor/edit/panel_loader.py +0 -232
  255. scitex/fig/editor/flask_editor/_bbox.py +0 -1299
  256. scitex/fig/editor/flask_editor/_core.py +0 -1429
  257. scitex/fig/editor/flask_editor/_renderer.py +0 -813
  258. scitex/fig/editor/flask_editor/static/css/features/canvas.css +0 -176
  259. scitex/fts/README.md +0 -262
  260. scitex/fts/TODO.md +0 -66
  261. scitex/fts/__init__.py +0 -90
  262. scitex/fts/_bundle/README_IN_BUNDLE.md +0 -102
  263. scitex/fts/_bundle/__init__.py +0 -38
  264. scitex/fts/_bundle/_utils/__init__.py +0 -55
  265. scitex/fts/_bundle/_utils/_const.py +0 -26
  266. scitex/fts/_bundle/_utils/_errors.py +0 -73
  267. scitex/fts/_bundle/_utils/_generate.py +0 -21
  268. scitex/fts/_bundle/_utils/_types.py +0 -76
  269. scitex/fts/_bundle/_zipbundle.py +0 -165
  270. scitex/fts/_fig/__init__.py +0 -22
  271. scitex/fts/_fig/_backend/_parser.py +0 -188
  272. scitex/fts/_fig/_editor/__init__.py +0 -14
  273. scitex/fts/_fig/_editor/_cui/__init__.py +0 -33
  274. scitex/fts/_fig/_editor/_cui/_backend_detector.py +0 -39
  275. scitex/fts/_fig/_editor/_cui/_bundle_resolver.py +0 -366
  276. scitex/fts/_fig/_editor/_cui/_editor_launcher.py +0 -175
  277. scitex/fts/_fig/_editor/_cui/_manual_handler.py +0 -52
  278. scitex/fts/_fig/_editor/_cui/_path_resolver.py +0 -66
  279. scitex/fts/_fig/_editor/_gui/__init__.py +0 -11
  280. scitex/fts/_fig/_editor/_gui/_flask_editor/__init__.py +0 -20
  281. scitex/fts/_fig/_editor/_gui/_flask_editor/_plotter.py +0 -664
  282. scitex/fts/_fig/_editor/_gui/_flask_editor/_utils.py +0 -79
  283. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/base/reset.css +0 -41
  284. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/base/typography.css +0 -16
  285. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/base/variables.css +0 -85
  286. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/components/buttons.css +0 -217
  287. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/components/context-menu.css +0 -93
  288. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/components/dropdown.css +0 -57
  289. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/components/forms.css +0 -112
  290. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/components/modal.css +0 -59
  291. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/components/sections.css +0 -212
  292. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/features/element-inspector.css +0 -190
  293. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/features/loading.css +0 -59
  294. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/features/overlay.css +0 -45
  295. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/features/panel-grid.css +0 -95
  296. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/features/selection.css +0 -101
  297. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/features/statistics.css +0 -138
  298. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/index.css +0 -31
  299. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/layout/container.css +0 -7
  300. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/layout/controls.css +0 -56
  301. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/layout/preview.css +0 -78
  302. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/alignment/axis.js +0 -314
  303. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/alignment/basic.js +0 -107
  304. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/alignment/distribute.js +0 -54
  305. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/canvas/canvas.js +0 -172
  306. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/canvas/dragging.js +0 -258
  307. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/canvas/resize.js +0 -48
  308. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/canvas/selection.js +0 -71
  309. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/core/api.js +0 -288
  310. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/core/state.js +0 -143
  311. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/core/utils.js +0 -245
  312. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/dev/element-inspector.js +0 -992
  313. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/editor/bbox.js +0 -339
  314. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/editor/element-drag.js +0 -286
  315. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/editor/overlay.js +0 -371
  316. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/editor/preview.js +0 -293
  317. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/main.js +0 -426
  318. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/shortcuts/context-menu.js +0 -152
  319. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/shortcuts/keyboard.js +0 -265
  320. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/ui/controls.js +0 -184
  321. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/ui/download.js +0 -57
  322. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/ui/help.js +0 -100
  323. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/ui/theme.js +0 -34
  324. scitex/fts/_fig/_editor/_gui/_flask_editor/templates/__init__.py +0 -124
  325. scitex/fts/_fig/_editor/_gui/_flask_editor/templates/_html.py +0 -851
  326. scitex/fts/_fig/_editor/_gui/_flask_editor/templates/_scripts.py +0 -4932
  327. scitex/fts/_fig/_editor/_gui/_flask_editor/templates/_styles.py +0 -1657
  328. scitex/fts/_fig/_editor/_gui/_flask_editor.py +0 -36
  329. scitex/fts/_fig/_models/_Annotations.py +0 -115
  330. scitex/fts/_fig/_models/_Axes.py +0 -152
  331. scitex/fts/_fig/_models/_Figure.py +0 -138
  332. scitex/fts/_fig/_models/_Plot.py +0 -123
  333. scitex/fts/_fig/_utils/_plot_layout.py +0 -397
  334. scitex/fts/_kinds/_figure/_composite.py +0 -345
  335. scitex/fts/_kinds/_plot/_backend/__init__.py +0 -53
  336. scitex/fts/_kinds/_plot/_backend/_export.py +0 -165
  337. scitex/fts/_kinds/_plot/_backend/_render.py +0 -538
  338. scitex/fts/_kinds/_plot/_dataclasses/_ChannelEncoding.py +0 -46
  339. scitex/fts/_kinds/_plot/_dataclasses/_Encoding.py +0 -82
  340. scitex/fts/_kinds/_plot/_dataclasses/_Theme.py +0 -441
  341. scitex/fts/_kinds/_plot/_dataclasses/_TraceEncoding.py +0 -52
  342. scitex/fts/_kinds/_plot/_dataclasses/__init__.py +0 -47
  343. scitex/fts/_kinds/_plot/_models/_Guides.py +0 -104
  344. scitex/fts/_kinds/_plot/_models/_Styles.py +0 -245
  345. scitex/fts/_kinds/_plot/_models/__init__.py +0 -80
  346. scitex/fts/_kinds/_plot/_models/_plot_types/__init__.py +0 -156
  347. scitex/fts/_kinds/_plot/_models/_plot_types/_bar.py +0 -43
  348. scitex/fts/_kinds/_plot/_models/_plot_types/_box.py +0 -38
  349. scitex/fts/_kinds/_plot/_models/_plot_types/_distribution.py +0 -36
  350. scitex/fts/_kinds/_plot/_models/_plot_types/_errorbar.py +0 -60
  351. scitex/fts/_kinds/_plot/_models/_plot_types/_histogram.py +0 -30
  352. scitex/fts/_kinds/_plot/_models/_plot_types/_image.py +0 -61
  353. scitex/fts/_kinds/_plot/_models/_plot_types/_line.py +0 -57
  354. scitex/fts/_kinds/_plot/_models/_plot_types/_scatter.py +0 -30
  355. scitex/fts/_kinds/_plot/_models/_plot_types/_seaborn.py +0 -121
  356. scitex/fts/_kinds/_plot/_models/_plot_types/_violin.py +0 -36
  357. scitex/fts/_kinds/_plot/_utils/__init__.py +0 -129
  358. scitex/fts/_kinds/_plot/_utils/_auto_layout.py +0 -127
  359. scitex/fts/_kinds/_plot/_utils/_calc_bounds.py +0 -111
  360. scitex/fts/_kinds/_plot/_utils/_const_sizes.py +0 -48
  361. scitex/fts/_kinds/_plot/_utils/_convert_coords.py +0 -77
  362. scitex/fts/_kinds/_plot/_utils/_get_template.py +0 -178
  363. scitex/fts/_kinds/_plot/_utils/_normalize.py +0 -73
  364. scitex/fts/_kinds/_plot/_utils/_validate.py +0 -197
  365. scitex/fts/_kinds/_table/_latex/_export.py +0 -279
  366. scitex/fts/_stats/__init__.py +0 -48
  367. scitex/fts/_stats/_dataclasses/_Stats.py +0 -423
  368. scitex/fts/_stats/_dataclasses/__init__.py +0 -48
  369. scitex/fts/_tables/__init__.py +0 -65
  370. scitex/fts/_tables/_latex/__init__.py +0 -93
  371. scitex/fts/_tables/_latex/_editor/__init__.py +0 -11
  372. scitex/fts/_tables/_latex/_editor/_app.py +0 -725
  373. scitex/fts/_tables/_latex/_figure_exporter.py +0 -153
  374. scitex/fts/_tables/_latex/_stats_formatter.py +0 -274
  375. scitex/fts/_tables/_latex/_table_exporter.py +0 -362
  376. scitex/fts/_tables/_latex/_utils.py +0 -369
  377. scitex/fts/_tables/_latex/_validator.py +0 -445
  378. scitex/io/_save_modules/_pltz_bundle.py +0 -356
  379. scitex-2.10.3.dist-info/METADATA +0 -952
  380. scitex-2.10.3.dist-info/entry_points.txt +0 -2
  381. /scitex/{fig → canvas}/README.md +0 -0
  382. /scitex/{fig → canvas}/backend/__init__.py +0 -0
  383. /scitex/{fig → canvas}/backend/_export.py +0 -0
  384. /scitex/{fig → canvas}/backend/_render.py +0 -0
  385. /scitex/{fig → canvas}/docs/CANVAS_ARCHITECTURE.md +0 -0
  386. /scitex/{fig → canvas}/editor/__init__.py +0 -0
  387. /scitex/{fig → canvas}/editor/_dearpygui_editor.py +0 -0
  388. /scitex/{fig → canvas}/editor/_flask_editor.py +0 -0
  389. /scitex/{fig → canvas}/editor/_mpl_editor.py +0 -0
  390. /scitex/{fig → canvas}/editor/_qt_editor.py +0 -0
  391. /scitex/{fig → canvas}/editor/_tkinter_editor.py +0 -0
  392. /scitex/{fig → canvas}/editor/edit/backend_detector.py +0 -0
  393. /scitex/{fig → canvas}/editor/edit/manual_handler.py +0 -0
  394. /scitex/{fig → canvas}/editor/edit/path_resolver.py +0 -0
  395. /scitex/{fig → canvas}/editor/flask_editor/__init__.py +0 -0
  396. /scitex/{fig → canvas}/editor/flask_editor/_plotter.py +0 -0
  397. /scitex/{fig → canvas}/editor/flask_editor/_utils.py +0 -0
  398. /scitex/{fig → canvas}/editor/flask_editor/static/css/base/reset.css +0 -0
  399. /scitex/{fig → canvas}/editor/flask_editor/static/css/base/typography.css +0 -0
  400. /scitex/{fig → canvas}/editor/flask_editor/static/css/base/variables.css +0 -0
  401. /scitex/{fig → canvas}/editor/flask_editor/static/css/components/buttons.css +0 -0
  402. /scitex/{fig → canvas}/editor/flask_editor/static/css/components/context-menu.css +0 -0
  403. /scitex/{fig → canvas}/editor/flask_editor/static/css/components/dropdown.css +0 -0
  404. /scitex/{fig → canvas}/editor/flask_editor/static/css/components/forms.css +0 -0
  405. /scitex/{fig → canvas}/editor/flask_editor/static/css/components/modal.css +0 -0
  406. /scitex/{fig → canvas}/editor/flask_editor/static/css/components/sections.css +0 -0
  407. /scitex/{fig → canvas}/editor/flask_editor/static/css/features/element-inspector.css +0 -0
  408. /scitex/{fig → canvas}/editor/flask_editor/static/css/features/loading.css +0 -0
  409. /scitex/{fig → canvas}/editor/flask_editor/static/css/features/overlay.css +0 -0
  410. /scitex/{fig → canvas}/editor/flask_editor/static/css/features/selection.css +0 -0
  411. /scitex/{fig → canvas}/editor/flask_editor/static/css/features/statistics.css +0 -0
  412. /scitex/{fig → canvas}/editor/flask_editor/static/css/index.css +0 -0
  413. /scitex/{fig → canvas}/editor/flask_editor/static/css/layout/container.css +0 -0
  414. /scitex/{fig → canvas}/editor/flask_editor/static/css/layout/controls.css +0 -0
  415. /scitex/{fig → canvas}/editor/flask_editor/static/css/layout/preview.css +0 -0
  416. /scitex/{fig → canvas}/editor/flask_editor/static/js/alignment/axis.js +0 -0
  417. /scitex/{fig → canvas}/editor/flask_editor/static/js/alignment/basic.js +0 -0
  418. /scitex/{fig → canvas}/editor/flask_editor/static/js/alignment/distribute.js +0 -0
  419. /scitex/{fig → canvas}/editor/flask_editor/static/js/canvas/canvas.js +0 -0
  420. /scitex/{fig → canvas}/editor/flask_editor/static/js/canvas/dragging.js +0 -0
  421. /scitex/{fig → canvas}/editor/flask_editor/static/js/canvas/resize.js +0 -0
  422. /scitex/{fig → canvas}/editor/flask_editor/static/js/canvas/selection.js +0 -0
  423. /scitex/{fig → canvas}/editor/flask_editor/static/js/core/state.js +0 -0
  424. /scitex/{fig → canvas}/editor/flask_editor/static/js/core/utils.js +0 -0
  425. /scitex/{fig → canvas}/editor/flask_editor/static/js/dev/element-inspector.js +0 -0
  426. /scitex/{fig → canvas}/editor/flask_editor/static/js/editor/bbox.js +0 -0
  427. /scitex/{fig → canvas}/editor/flask_editor/static/js/editor/element-drag.js +0 -0
  428. /scitex/{fig → canvas}/editor/flask_editor/static/js/editor/overlay.js +0 -0
  429. /scitex/{fig → canvas}/editor/flask_editor/static/js/main.js +0 -0
  430. /scitex/{fig → canvas}/editor/flask_editor/static/js/shortcuts/context-menu.js +0 -0
  431. /scitex/{fig → canvas}/editor/flask_editor/static/js/shortcuts/keyboard.js +0 -0
  432. /scitex/{fig → canvas}/editor/flask_editor/static/js/ui/controls.js +0 -0
  433. /scitex/{fig → canvas}/editor/flask_editor/static/js/ui/download.js +0 -0
  434. /scitex/{fig → canvas}/editor/flask_editor/static/js/ui/help.js +0 -0
  435. /scitex/{fig → canvas}/editor/flask_editor/static/js/ui/theme.js +0 -0
  436. /scitex/{fig → canvas}/editor/flask_editor/templates/__init__.py +0 -0
  437. /scitex/{fig → canvas}/io/_directory.py +0 -0
  438. /scitex/{fig → canvas}/model/_plot_types.py +0 -0
  439. /scitex/{fig → canvas}/utils/_defaults.py +0 -0
  440. /scitex/{fig → canvas}/utils/_validate.py +0 -0
  441. /scitex/{fts/_bundle → io/bundle}/_conversion/__init__.py +0 -0
  442. /scitex/{fts/_bundle → io/bundle}/_conversion/_bundle2dict.py +0 -0
  443. /scitex/{fts/_bundle → io/bundle}/_conversion/_dict2bundle.py +0 -0
  444. /scitex/{fts/_bundle → io/bundle}/_dataclasses/_Axes.py +0 -0
  445. /scitex/{fts/_bundle → io/bundle}/_dataclasses/_BBox.py +0 -0
  446. /scitex/{fts/_bundle → io/bundle}/_dataclasses/_ColumnDef.py +0 -0
  447. /scitex/{fts/_bundle → io/bundle}/_dataclasses/_DataFormat.py +0 -0
  448. /scitex/{fts/_bundle → io/bundle}/_dataclasses/_DataInfo.py +0 -0
  449. /scitex/{fts/_bundle → io/bundle}/_dataclasses/_DataSource.py +0 -0
  450. /scitex/{fts/_bundle → io/bundle}/_dataclasses/_SizeMM.py +0 -0
  451. /scitex/{fts/_bundle → io/bundle}/_extractors/__init__.py +0 -0
  452. /scitex/{fts/_bundle → io/bundle}/_extractors/_extract_bar.py +0 -0
  453. /scitex/{fts/_bundle → io/bundle}/_extractors/_extract_line.py +0 -0
  454. /scitex/{fts/_bundle → io/bundle}/_extractors/_extract_scatter.py +0 -0
  455. /scitex/{fts/_kinds → io/bundle/kinds}/__init__.py +0 -0
  456. /scitex/{fts/_kinds → io/bundle/kinds}/_figure/__init__.py +0 -0
  457. /scitex/{fts/_fig → io/bundle/kinds/_figure}/_composite.py +0 -0
  458. /scitex/{fts/_kinds → io/bundle/kinds}/_plot/__init__.py +0 -0
  459. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_backend/__init__.py +0 -0
  460. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_backend/_export.py +0 -0
  461. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_backend/_render.py +0 -0
  462. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_dataclasses/_ChannelEncoding.py +0 -0
  463. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_dataclasses/_Encoding.py +0 -0
  464. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_dataclasses/_Theme.py +0 -0
  465. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_dataclasses/_TraceEncoding.py +0 -0
  466. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_dataclasses/__init__.py +0 -0
  467. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/__init__.py +0 -0
  468. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/__init__.py +0 -0
  469. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_bar.py +0 -0
  470. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_box.py +0 -0
  471. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_distribution.py +0 -0
  472. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_errorbar.py +0 -0
  473. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_histogram.py +0 -0
  474. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_image.py +0 -0
  475. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_line.py +0 -0
  476. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_scatter.py +0 -0
  477. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_seaborn.py +0 -0
  478. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_violin.py +0 -0
  479. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_utils/__init__.py +0 -0
  480. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_utils/_auto_layout.py +0 -0
  481. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_utils/_calc_bounds.py +0 -0
  482. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_utils/_const_sizes.py +0 -0
  483. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_utils/_convert_coords.py +0 -0
  484. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_utils/_get_template.py +0 -0
  485. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_utils/_normalize.py +0 -0
  486. /scitex/{fts/_fig → io/bundle/kinds/_plot}/_utils/_validate.py +0 -0
  487. /scitex/{fts/_kinds → io/bundle/kinds}/_shape/__init__.py +0 -0
  488. /scitex/{fts/_kinds → io/bundle/kinds}/_stats/__init__.py +0 -0
  489. /scitex/{fts/_kinds → io/bundle/kinds}/_stats/_dataclasses/_Stats.py +0 -0
  490. /scitex/{fts/_kinds → io/bundle/kinds}/_stats/_dataclasses/__init__.py +0 -0
  491. /scitex/{fts/_kinds → io/bundle/kinds}/_table/__init__.py +0 -0
  492. /scitex/{fts/_kinds → io/bundle/kinds}/_table/_latex/_editor/__init__.py +0 -0
  493. /scitex/{fts/_kinds → io/bundle/kinds}/_table/_latex/_stats_formatter.py +0 -0
  494. /scitex/{fts/_kinds → io/bundle/kinds}/_table/_latex/_utils.py +0 -0
  495. /scitex/{fts/_kinds → io/bundle/kinds}/_table/_latex/_validator.py +0 -0
  496. /scitex/{fts/_kinds → io/bundle/kinds}/_text/__init__.py +0 -0
  497. /scitex/{fts/_schemas → io/bundle/schemas}/data_info.schema.json +0 -0
  498. /scitex/{fts/_schemas → io/bundle/schemas}/encoding.schema.json +0 -0
  499. /scitex/{fts/_schemas → io/bundle/schemas}/node.schema.json +0 -0
  500. /scitex/{fts/_schemas → io/bundle/schemas}/render_manifest.schema.json +0 -0
  501. /scitex/{fts/_schemas → io/bundle/schemas}/stats.schema.json +0 -0
  502. /scitex/{fts/_schemas → io/bundle/schemas}/theme.schema.json +0 -0
  503. {scitex-2.10.3.dist-info → scitex-2.13.0.dist-info}/WHEEL +0 -0
  504. {scitex-2.10.3.dist-info → scitex-2.13.0.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,400 @@
1
+ #!/usr/bin/env python3
2
+ # Timestamp: 2026-01-08
3
+ # File: src/scitex/diagram/_mcp_handlers.py
4
+ # ----------------------------------------
5
+
6
+ """
7
+ MCP Handler implementations for SciTeX diagram module.
8
+
9
+ Provides async handlers for paper-optimized diagram generation.
10
+ """
11
+
12
+ from __future__ import annotations
13
+
14
+ import asyncio
15
+ from typing import Optional
16
+
17
+
18
+ async def create_diagram_handler(
19
+ spec_path: Optional[str] = None,
20
+ spec_dict: Optional[dict] = None,
21
+ ) -> dict:
22
+ """
23
+ Create a diagram from specification.
24
+
25
+ Parameters
26
+ ----------
27
+ spec_path : str, optional
28
+ Path to YAML spec file
29
+ spec_dict : dict, optional
30
+ Spec as dictionary
31
+
32
+ Returns
33
+ -------
34
+ dict
35
+ Success status and diagram info
36
+ """
37
+ try:
38
+ from scitex.diagram import Diagram
39
+
40
+ if spec_path:
41
+ loop = asyncio.get_event_loop()
42
+ diagram = await loop.run_in_executor(
43
+ None,
44
+ lambda: Diagram.from_yaml(spec_path),
45
+ )
46
+ elif spec_dict:
47
+ diagram = Diagram(spec_dict)
48
+ else:
49
+ return {
50
+ "success": False,
51
+ "error": "Either spec_path or spec_dict must be provided",
52
+ }
53
+
54
+ # Get diagram info
55
+ spec = diagram.spec if hasattr(diagram, "spec") else {}
56
+
57
+ return {
58
+ "success": True,
59
+ "diagram_type": spec.get("type", "unknown"),
60
+ "node_count": len(spec.get("nodes", [])),
61
+ "edge_count": len(spec.get("edges", [])),
62
+ "message": "Diagram created successfully",
63
+ }
64
+ except Exception as e:
65
+ return {
66
+ "success": False,
67
+ "error": str(e),
68
+ }
69
+
70
+
71
+ async def compile_mermaid_handler(
72
+ spec_path: Optional[str] = None,
73
+ output_path: Optional[str] = None,
74
+ spec_dict: Optional[dict] = None,
75
+ ) -> dict:
76
+ """
77
+ Compile diagram to Mermaid format.
78
+
79
+ Parameters
80
+ ----------
81
+ spec_path : str, optional
82
+ Path to YAML spec file
83
+ output_path : str, optional
84
+ Output .mmd file path
85
+ spec_dict : dict, optional
86
+ Spec as dictionary
87
+
88
+ Returns
89
+ -------
90
+ dict
91
+ Success status and Mermaid output
92
+ """
93
+ try:
94
+ from scitex.diagram import Diagram, compile_to_mermaid
95
+
96
+ if spec_path:
97
+ loop = asyncio.get_event_loop()
98
+ diagram = await loop.run_in_executor(
99
+ None,
100
+ lambda: Diagram.from_yaml(spec_path),
101
+ )
102
+ elif spec_dict:
103
+ diagram = Diagram(spec_dict)
104
+ else:
105
+ return {
106
+ "success": False,
107
+ "error": "Either spec_path or spec_dict must be provided",
108
+ }
109
+
110
+ # Compile to Mermaid
111
+ loop = asyncio.get_event_loop()
112
+ mermaid_code = await loop.run_in_executor(
113
+ None,
114
+ lambda: compile_to_mermaid(diagram.spec),
115
+ )
116
+
117
+ # Save if output path provided
118
+ if output_path:
119
+ from pathlib import Path
120
+
121
+ Path(output_path).write_text(mermaid_code)
122
+
123
+ return {
124
+ "success": True,
125
+ "mermaid_code": mermaid_code,
126
+ "output_path": output_path,
127
+ "message": f"Compiled to Mermaid{f' and saved to {output_path}' if output_path else ''}",
128
+ }
129
+ except Exception as e:
130
+ return {
131
+ "success": False,
132
+ "error": str(e),
133
+ }
134
+
135
+
136
+ async def compile_graphviz_handler(
137
+ spec_path: Optional[str] = None,
138
+ output_path: Optional[str] = None,
139
+ spec_dict: Optional[dict] = None,
140
+ ) -> dict:
141
+ """
142
+ Compile diagram to Graphviz DOT format.
143
+
144
+ Parameters
145
+ ----------
146
+ spec_path : str, optional
147
+ Path to YAML spec file
148
+ output_path : str, optional
149
+ Output .dot file path
150
+ spec_dict : dict, optional
151
+ Spec as dictionary
152
+
153
+ Returns
154
+ -------
155
+ dict
156
+ Success status and DOT output
157
+ """
158
+ try:
159
+ from scitex.diagram import Diagram, compile_to_graphviz
160
+
161
+ if spec_path:
162
+ loop = asyncio.get_event_loop()
163
+ diagram = await loop.run_in_executor(
164
+ None,
165
+ lambda: Diagram.from_yaml(spec_path),
166
+ )
167
+ elif spec_dict:
168
+ diagram = Diagram(spec_dict)
169
+ else:
170
+ return {
171
+ "success": False,
172
+ "error": "Either spec_path or spec_dict must be provided",
173
+ }
174
+
175
+ # Compile to Graphviz
176
+ loop = asyncio.get_event_loop()
177
+ dot_code = await loop.run_in_executor(
178
+ None,
179
+ lambda: compile_to_graphviz(diagram.spec),
180
+ )
181
+
182
+ # Save if output path provided
183
+ if output_path:
184
+ from pathlib import Path
185
+
186
+ Path(output_path).write_text(dot_code)
187
+
188
+ return {
189
+ "success": True,
190
+ "dot_code": dot_code,
191
+ "output_path": output_path,
192
+ "message": f"Compiled to Graphviz{f' and saved to {output_path}' if output_path else ''}",
193
+ }
194
+ except Exception as e:
195
+ return {
196
+ "success": False,
197
+ "error": str(e),
198
+ }
199
+
200
+
201
+ async def list_presets_handler() -> dict:
202
+ """
203
+ List available diagram presets.
204
+
205
+ Returns
206
+ -------
207
+ dict
208
+ Success status and preset list
209
+ """
210
+ try:
211
+ presets = [
212
+ {
213
+ "name": "workflow",
214
+ "description": "Linear workflow diagrams (step1 → step2 → step3)",
215
+ "use_case": "Methods section, data processing pipelines",
216
+ "direction": "left-to-right",
217
+ },
218
+ {
219
+ "name": "decision",
220
+ "description": "Decision tree/flowchart diagrams",
221
+ "use_case": "Algorithm flowcharts, decision processes",
222
+ "direction": "top-to-bottom",
223
+ },
224
+ {
225
+ "name": "pipeline",
226
+ "description": "Data pipeline with parallel branches",
227
+ "use_case": "Complex data flows, parallel processing",
228
+ "direction": "left-to-right",
229
+ },
230
+ ]
231
+
232
+ return {
233
+ "success": True,
234
+ "count": len(presets),
235
+ "presets": presets,
236
+ }
237
+ except Exception as e:
238
+ return {
239
+ "success": False,
240
+ "error": str(e),
241
+ }
242
+
243
+
244
+ async def get_preset_handler(preset_name: str) -> dict:
245
+ """
246
+ Get a specific preset configuration.
247
+
248
+ Parameters
249
+ ----------
250
+ preset_name : str
251
+ Preset name (workflow, decision, pipeline)
252
+
253
+ Returns
254
+ -------
255
+ dict
256
+ Success status and preset config
257
+ """
258
+ try:
259
+ from scitex.diagram import DECISION_PRESET, PIPELINE_PRESET, WORKFLOW_PRESET
260
+
261
+ presets = {
262
+ "workflow": WORKFLOW_PRESET,
263
+ "decision": DECISION_PRESET,
264
+ "pipeline": PIPELINE_PRESET,
265
+ }
266
+
267
+ if preset_name not in presets:
268
+ return {
269
+ "success": False,
270
+ "error": f"Unknown preset: {preset_name}",
271
+ "available": list(presets.keys()),
272
+ }
273
+
274
+ preset = presets[preset_name]
275
+
276
+ return {
277
+ "success": True,
278
+ "preset_name": preset_name,
279
+ "config": preset,
280
+ }
281
+ except Exception as e:
282
+ return {
283
+ "success": False,
284
+ "error": str(e),
285
+ }
286
+
287
+
288
+ async def split_diagram_handler(
289
+ spec_path: str,
290
+ strategy: str = "horizontal",
291
+ max_nodes_per_part: int = 10,
292
+ ) -> dict:
293
+ """
294
+ Split a large diagram into smaller parts.
295
+
296
+ Parameters
297
+ ----------
298
+ spec_path : str
299
+ Path to YAML spec file
300
+ strategy : str
301
+ Split strategy (horizontal, vertical, semantic)
302
+ max_nodes_per_part : int
303
+ Max nodes per part
304
+
305
+ Returns
306
+ -------
307
+ dict
308
+ Success status and split results
309
+ """
310
+ try:
311
+ from scitex.diagram import Diagram, SplitConfig, SplitStrategy, split_diagram
312
+
313
+ # Map strategy string to enum
314
+ strategy_map = {
315
+ "horizontal": SplitStrategy.HORIZONTAL,
316
+ "vertical": SplitStrategy.VERTICAL,
317
+ "semantic": SplitStrategy.SEMANTIC,
318
+ }
319
+
320
+ if strategy not in strategy_map:
321
+ return {
322
+ "success": False,
323
+ "error": f"Unknown strategy: {strategy}",
324
+ "available": list(strategy_map.keys()),
325
+ }
326
+
327
+ loop = asyncio.get_event_loop()
328
+ diagram = await loop.run_in_executor(
329
+ None,
330
+ lambda: Diagram.from_yaml(spec_path),
331
+ )
332
+
333
+ config = SplitConfig(
334
+ strategy=strategy_map[strategy],
335
+ max_nodes_per_part=max_nodes_per_part,
336
+ )
337
+
338
+ result = await loop.run_in_executor(
339
+ None,
340
+ lambda: split_diagram(diagram.spec, config),
341
+ )
342
+
343
+ return {
344
+ "success": True,
345
+ "strategy": strategy,
346
+ "parts_count": len(result.parts) if hasattr(result, "parts") else 0,
347
+ "result": str(result),
348
+ }
349
+ except Exception as e:
350
+ return {
351
+ "success": False,
352
+ "error": str(e),
353
+ }
354
+
355
+
356
+ async def get_paper_modes_handler() -> dict:
357
+ """
358
+ Get available paper layout modes.
359
+
360
+ Returns
361
+ -------
362
+ dict
363
+ Success status and paper modes
364
+ """
365
+ try:
366
+ from scitex.diagram import PaperMode
367
+
368
+ modes = []
369
+ for mode in PaperMode:
370
+ modes.append(
371
+ {
372
+ "name": mode.name,
373
+ "value": mode.value,
374
+ }
375
+ )
376
+
377
+ return {
378
+ "success": True,
379
+ "count": len(modes),
380
+ "modes": modes,
381
+ "description": "Paper modes control diagram sizing for publication layouts",
382
+ }
383
+ except Exception as e:
384
+ return {
385
+ "success": False,
386
+ "error": str(e),
387
+ }
388
+
389
+
390
+ __all__ = [
391
+ "create_diagram_handler",
392
+ "compile_mermaid_handler",
393
+ "compile_graphviz_handler",
394
+ "list_presets_handler",
395
+ "get_preset_handler",
396
+ "split_diagram_handler",
397
+ "get_paper_modes_handler",
398
+ ]
399
+
400
+ # EOF
@@ -0,0 +1,157 @@
1
+ #!/usr/bin/env python3
2
+ # Timestamp: 2026-01-08
3
+ # File: src/scitex/diagram/_mcp_tool_schemas.py
4
+ # ----------------------------------------
5
+
6
+ """
7
+ MCP Tool schemas for SciTeX diagram module.
8
+
9
+ Defines tools for paper-optimized diagram generation:
10
+ - create_diagram: Create diagram from YAML spec
11
+ - compile_mermaid: Export to Mermaid format
12
+ - compile_graphviz: Export to Graphviz DOT format
13
+ - list_presets: List available diagram presets
14
+ - apply_preset: Apply workflow/decision/pipeline preset
15
+ """
16
+
17
+ from __future__ import annotations
18
+
19
+ import mcp.types as types
20
+
21
+
22
+ def get_tool_schemas() -> list[types.Tool]:
23
+ """Return list of available MCP tools for diagram operations."""
24
+ return [
25
+ # Create diagram from YAML
26
+ types.Tool(
27
+ name="create_diagram",
28
+ description="Create a diagram from a YAML specification file or dictionary",
29
+ inputSchema={
30
+ "type": "object",
31
+ "properties": {
32
+ "spec_path": {
33
+ "type": "string",
34
+ "description": "Path to YAML specification file",
35
+ },
36
+ "spec_dict": {
37
+ "type": "object",
38
+ "description": "Diagram specification as dictionary (alternative to spec_path)",
39
+ },
40
+ },
41
+ "required": [],
42
+ },
43
+ ),
44
+ # Compile to Mermaid
45
+ types.Tool(
46
+ name="compile_mermaid",
47
+ description="Compile diagram specification to Mermaid format",
48
+ inputSchema={
49
+ "type": "object",
50
+ "properties": {
51
+ "spec_path": {
52
+ "type": "string",
53
+ "description": "Path to YAML specification file",
54
+ },
55
+ "output_path": {
56
+ "type": "string",
57
+ "description": "Output file path for .mmd file",
58
+ },
59
+ "spec_dict": {
60
+ "type": "object",
61
+ "description": "Diagram specification as dictionary (alternative to spec_path)",
62
+ },
63
+ },
64
+ "required": [],
65
+ },
66
+ ),
67
+ # Compile to Graphviz
68
+ types.Tool(
69
+ name="compile_graphviz",
70
+ description="Compile diagram specification to Graphviz DOT format",
71
+ inputSchema={
72
+ "type": "object",
73
+ "properties": {
74
+ "spec_path": {
75
+ "type": "string",
76
+ "description": "Path to YAML specification file",
77
+ },
78
+ "output_path": {
79
+ "type": "string",
80
+ "description": "Output file path for .dot file",
81
+ },
82
+ "spec_dict": {
83
+ "type": "object",
84
+ "description": "Diagram specification as dictionary (alternative to spec_path)",
85
+ },
86
+ },
87
+ "required": [],
88
+ },
89
+ ),
90
+ # List presets
91
+ types.Tool(
92
+ name="list_presets",
93
+ description="List available diagram presets (workflow, decision, pipeline)",
94
+ inputSchema={
95
+ "type": "object",
96
+ "properties": {},
97
+ "required": [],
98
+ },
99
+ ),
100
+ # Get preset
101
+ types.Tool(
102
+ name="get_preset",
103
+ description="Get a diagram preset configuration by name",
104
+ inputSchema={
105
+ "type": "object",
106
+ "properties": {
107
+ "preset_name": {
108
+ "type": "string",
109
+ "description": "Preset name",
110
+ "enum": ["workflow", "decision", "pipeline"],
111
+ },
112
+ },
113
+ "required": ["preset_name"],
114
+ },
115
+ ),
116
+ # Split diagram
117
+ types.Tool(
118
+ name="split_diagram",
119
+ description="Split a large diagram into smaller parts for multi-column layouts",
120
+ inputSchema={
121
+ "type": "object",
122
+ "properties": {
123
+ "spec_path": {
124
+ "type": "string",
125
+ "description": "Path to YAML specification file",
126
+ },
127
+ "strategy": {
128
+ "type": "string",
129
+ "description": "Split strategy",
130
+ "enum": ["horizontal", "vertical", "semantic"],
131
+ "default": "horizontal",
132
+ },
133
+ "max_nodes_per_part": {
134
+ "type": "integer",
135
+ "description": "Maximum nodes per split part",
136
+ "default": 10,
137
+ },
138
+ },
139
+ "required": ["spec_path"],
140
+ },
141
+ ),
142
+ # Get paper modes
143
+ types.Tool(
144
+ name="get_paper_modes",
145
+ description="Get available paper layout modes and their constraints",
146
+ inputSchema={
147
+ "type": "object",
148
+ "properties": {},
149
+ "required": [],
150
+ },
151
+ ),
152
+ ]
153
+
154
+
155
+ __all__ = ["get_tool_schemas"]
156
+
157
+ # EOF
@@ -0,0 +1,151 @@
1
+ #!/usr/bin/env python3
2
+ # Timestamp: 2026-01-08
3
+ # File: src/scitex/diagram/mcp_server.py
4
+ # ----------------------------------------
5
+
6
+ """
7
+ MCP Server for SciTeX diagram - Paper-optimized diagram generation.
8
+
9
+ Provides tools for:
10
+ - Creating diagrams from YAML specs
11
+ - Compiling to Mermaid/Graphviz formats
12
+ - Using workflow/decision/pipeline presets
13
+ - Splitting large diagrams for publication layouts
14
+ """
15
+
16
+ from __future__ import annotations
17
+
18
+ import asyncio
19
+
20
+ # Graceful MCP dependency handling
21
+ try:
22
+ import mcp.types as types
23
+ from mcp.server import NotificationOptions, Server
24
+ from mcp.server.models import InitializationOptions
25
+ from mcp.server.stdio import stdio_server
26
+
27
+ MCP_AVAILABLE = True
28
+ except ImportError:
29
+ MCP_AVAILABLE = False
30
+ types = None # type: ignore
31
+ Server = None # type: ignore
32
+ NotificationOptions = None # type: ignore
33
+ InitializationOptions = None # type: ignore
34
+ stdio_server = None # type: ignore
35
+
36
+ __all__ = ["DiagramServer", "main", "MCP_AVAILABLE"]
37
+
38
+
39
+ class DiagramServer:
40
+ """MCP Server for Paper-Optimized Diagram Generation."""
41
+
42
+ def __init__(self):
43
+ self.server = Server("scitex-diagram")
44
+ self.setup_handlers()
45
+
46
+ def setup_handlers(self):
47
+ """Set up MCP server handlers."""
48
+ from ._mcp_handlers import (
49
+ compile_graphviz_handler,
50
+ compile_mermaid_handler,
51
+ create_diagram_handler,
52
+ get_paper_modes_handler,
53
+ get_preset_handler,
54
+ list_presets_handler,
55
+ split_diagram_handler,
56
+ )
57
+ from ._mcp_tool_schemas import get_tool_schemas
58
+
59
+ @self.server.list_tools()
60
+ async def handle_list_tools():
61
+ return get_tool_schemas()
62
+
63
+ @self.server.call_tool()
64
+ async def handle_call_tool(name: str, arguments: dict):
65
+ if name == "create_diagram":
66
+ return await self._wrap_result(create_diagram_handler(**arguments))
67
+
68
+ elif name == "compile_mermaid":
69
+ return await self._wrap_result(compile_mermaid_handler(**arguments))
70
+
71
+ elif name == "compile_graphviz":
72
+ return await self._wrap_result(compile_graphviz_handler(**arguments))
73
+
74
+ elif name == "list_presets":
75
+ return await self._wrap_result(list_presets_handler())
76
+
77
+ elif name == "get_preset":
78
+ return await self._wrap_result(get_preset_handler(**arguments))
79
+
80
+ elif name == "split_diagram":
81
+ return await self._wrap_result(split_diagram_handler(**arguments))
82
+
83
+ elif name == "get_paper_modes":
84
+ return await self._wrap_result(get_paper_modes_handler())
85
+
86
+ else:
87
+ raise ValueError(f"Unknown tool: {name}")
88
+
89
+ async def _wrap_result(self, coro):
90
+ """Wrap handler result as MCP TextContent."""
91
+ import json
92
+
93
+ try:
94
+ result = await coro
95
+ return [
96
+ types.TextContent(
97
+ type="text",
98
+ text=json.dumps(result, indent=2, default=str),
99
+ )
100
+ ]
101
+ except Exception as e:
102
+ return [
103
+ types.TextContent(
104
+ type="text",
105
+ text=json.dumps({"success": False, "error": str(e)}, indent=2),
106
+ )
107
+ ]
108
+
109
+
110
+ async def _run_server():
111
+ """Run the MCP server (internal)."""
112
+ server = DiagramServer()
113
+ async with stdio_server() as (read_stream, write_stream):
114
+ await server.server.run(
115
+ read_stream,
116
+ write_stream,
117
+ InitializationOptions(
118
+ server_name="scitex-diagram",
119
+ server_version="0.1.0",
120
+ capabilities=server.server.get_capabilities(
121
+ notification_options=NotificationOptions(),
122
+ experimental_capabilities={},
123
+ ),
124
+ ),
125
+ )
126
+
127
+
128
+ def main():
129
+ """Main entry point for the MCP server."""
130
+ if not MCP_AVAILABLE:
131
+ import sys
132
+
133
+ print("=" * 60)
134
+ print("MCP Server 'scitex-diagram' requires the 'mcp' package.")
135
+ print()
136
+ print("Install with:")
137
+ print(" pip install mcp")
138
+ print()
139
+ print("Or install scitex with MCP support:")
140
+ print(" pip install scitex[mcp]")
141
+ print("=" * 60)
142
+ sys.exit(1)
143
+
144
+ asyncio.run(_run_server())
145
+
146
+
147
+ if __name__ == "__main__":
148
+ main()
149
+
150
+
151
+ # EOF