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
@@ -3,7 +3,7 @@
3
3
  # Timestamp: 2025-12-08
4
4
  # File: ./src/scitex/vis/io/canvas.py
5
5
  """
6
- Canvas JSON operations for scitex.fig.
6
+ Canvas JSON operations for scitex.canvas.
7
7
 
8
8
  Handles saving, loading, and updating canvas.json files.
9
9
  """
@@ -3,7 +3,7 @@
3
3
  # Timestamp: 2025-12-08
4
4
  # File: ./src/scitex/vis/io/data.py
5
5
  """
6
- Data operations for scitex.fig.
6
+ Data operations for scitex.canvas.
7
7
 
8
8
  Handles SHA256 hash computation and verification for data integrity.
9
9
  """
@@ -3,7 +3,7 @@
3
3
  # Timestamp: 2025-12-08
4
4
  # File: ./src/scitex/vis/io/export.py
5
5
  """
6
- Export operations for scitex.fig.
6
+ Export operations for scitex.canvas.
7
7
 
8
8
  Handles composing and exporting canvas to various formats (PNG, PDF, SVG).
9
9
  """
@@ -115,7 +115,7 @@ def load_figure_model(
115
115
 
116
116
  Examples
117
117
  --------
118
- >>> from scitex.fig.io import load_figure_model
118
+ >>> from scitex.canvas.io import load_figure_model
119
119
  >>> fig_model = load_figure_model("figure.json")
120
120
  >>> fig_model.width_mm
121
121
  180
@@ -3,7 +3,7 @@
3
3
  # Timestamp: 2025-12-08
4
4
  # File: ./src/scitex/vis/io/panel.py
5
5
  """
6
- Panel operations for scitex.fig.
6
+ Panel operations for scitex.canvas.
7
7
 
8
8
  Handles adding, removing, updating, and listing panels within a canvas.
9
9
  Panels can be either 'scitex' type (full stx.plt output) or 'image' type (static image).
@@ -119,7 +119,7 @@ def save_figure_model(
119
119
 
120
120
  Examples
121
121
  --------
122
- >>> from scitex.fig.model import FigureModel
122
+ >>> from scitex.canvas.model import FigureModel
123
123
  >>> fig_model = FigureModel(width_mm=180, height_mm=120)
124
124
  >>> save_figure_model(fig_model, "figure.json")
125
125
  PosixPath('figure.json')
@@ -0,0 +1,151 @@
1
+ #!/usr/bin/env python3
2
+ # Timestamp: 2026-01-08
3
+ # File: src/scitex/canvas/mcp_server.py
4
+ # ----------------------------------------
5
+
6
+ """
7
+ MCP Server for SciTeX canvas - Multi-panel figure composition.
8
+
9
+ Provides tools for:
10
+ - Creating canvas workspaces
11
+ - Adding/removing panels
12
+ - Exporting composed figures
13
+ - Managing multi-panel 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__ = ["CanvasServer", "main", "MCP_AVAILABLE"]
37
+
38
+
39
+ class CanvasServer:
40
+ """MCP Server for Multi-panel Figure Composition."""
41
+
42
+ def __init__(self):
43
+ self.server = Server("scitex-canvas")
44
+ self.setup_handlers()
45
+
46
+ def setup_handlers(self):
47
+ """Set up MCP server handlers."""
48
+ from ._mcp_handlers import (
49
+ add_panel_handler,
50
+ canvas_exists_handler,
51
+ create_canvas_handler,
52
+ export_canvas_handler,
53
+ list_canvases_handler,
54
+ list_panels_handler,
55
+ remove_panel_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_canvas":
66
+ return await self._wrap_result(create_canvas_handler(**arguments))
67
+
68
+ elif name == "add_panel":
69
+ return await self._wrap_result(add_panel_handler(**arguments))
70
+
71
+ elif name == "list_panels":
72
+ return await self._wrap_result(list_panels_handler(**arguments))
73
+
74
+ elif name == "remove_panel":
75
+ return await self._wrap_result(remove_panel_handler(**arguments))
76
+
77
+ elif name == "export_canvas":
78
+ return await self._wrap_result(export_canvas_handler(**arguments))
79
+
80
+ elif name == "list_canvases":
81
+ return await self._wrap_result(list_canvases_handler(**arguments))
82
+
83
+ elif name == "canvas_exists":
84
+ return await self._wrap_result(canvas_exists_handler(**arguments))
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 = CanvasServer()
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-canvas",
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-canvas' 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
@@ -2,7 +2,7 @@
2
2
  # -*- coding: utf-8 -*-
3
3
  # File: ./src/scitex/vis/model/__init__.py
4
4
  """
5
- JSON models for scitex.fig figure specifications.
5
+ JSON models for scitex.canvas figure specifications.
6
6
 
7
7
  This module provides dataclass-based models for representing
8
8
  publication-quality figures as JSON structures.
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env python3
2
2
  # -*- coding: utf-8 -*-
3
3
  # File: ./src/scitex/vis/model/annotations.py
4
- """Annotation JSON model for scitex.fig."""
4
+ """Annotation JSON model for scitex.canvas."""
5
5
 
6
6
  from typing import Optional, Dict, Any, Tuple
7
7
  from dataclasses import dataclass, field, asdict
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env python3
2
2
  # -*- coding: utf-8 -*-
3
3
  # File: ./src/scitex/vis/model/axes.py
4
- """Axes JSON model for scitex.fig."""
4
+ """Axes JSON model for scitex.canvas."""
5
5
 
6
6
  from typing import Optional, List, Dict, Any
7
7
  from dataclasses import dataclass, field, asdict
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env python3
2
2
  # -*- coding: utf-8 -*-
3
3
  # File: ./src/scitex/vis/model/figure.py
4
- """Figure JSON model for scitex.fig."""
4
+ """Figure JSON model for scitex.canvas."""
5
5
 
6
6
  from typing import Optional, List, Dict, Any
7
7
  from dataclasses import dataclass, field, asdict
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env python3
2
2
  # -*- coding: utf-8 -*-
3
3
  # File: ./src/scitex/vis/model/guides.py
4
- """Guide elements (lines, spans) JSON model for scitex.fig."""
4
+ """Guide elements (lines, spans) JSON model for scitex.canvas."""
5
5
 
6
6
  from typing import Optional, List, Dict, Any
7
7
  from dataclasses import dataclass, field, asdict
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env python3
2
2
  # -*- coding: utf-8 -*-
3
3
  # File: ./src/scitex/vis/model/plot.py
4
- """Plot JSON model for scitex.fig."""
4
+ """Plot JSON model for scitex.canvas."""
5
5
 
6
6
  from typing import Optional, List, Dict, Any
7
7
  from dataclasses import dataclass, field, asdict
@@ -2,7 +2,7 @@
2
2
  # -*- coding: utf-8 -*-
3
3
  # File: ./src/scitex/vis/model/styles.py
4
4
  """
5
- Style dataclasses for scitex.fig objects.
5
+ Style dataclasses for scitex.canvas objects.
6
6
 
7
7
  Separating style properties from data makes:
8
8
  - UI property panels easy to auto-generate
@@ -2,7 +2,7 @@
2
2
  # -*- coding: utf-8 -*-
3
3
  # File: ./src/scitex/vis/utils/__init__.py
4
4
  """
5
- Utilities for scitex.fig.
5
+ Utilities for scitex.canvas.
6
6
 
7
7
  Includes validation functions and default templates for
8
8
  common publication formats.
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env python3
2
- # -*- coding: utf-8 -*-
3
2
  # Timestamp: "2025-10-17 03:24:58 (ywatanabe)"
4
3
  # File: /home/ywatanabe/proj/scitex-code/src/scitex/capture/mcp_server.py
5
4
  # ----------------------------------------
6
5
  from __future__ import annotations
6
+
7
7
  import os
8
8
 
9
9
  __FILE__ = "./src/scitex/capture/mcp_server.py"
@@ -20,17 +20,27 @@ import base64
20
20
  from datetime import datetime
21
21
  from pathlib import Path
22
22
 
23
- import mcp.types as types
24
- from mcp.server import NotificationOptions, Server
25
- from mcp.server.models import InitializationOptions
26
- from mcp.server.stdio import stdio_server
27
-
28
- from scitex import capture
29
- import shutil
30
-
23
+ # Graceful MCP dependency handling
24
+ try:
25
+ import mcp.types as types
26
+ from mcp.server import NotificationOptions, Server
27
+ from mcp.server.models import InitializationOptions
28
+ from mcp.server.stdio import stdio_server
29
+
30
+ MCP_AVAILABLE = True
31
+ except ImportError:
32
+ MCP_AVAILABLE = False
33
+ types = None # type: ignore
34
+ Server = None # type: ignore
35
+ NotificationOptions = None # type: ignore
36
+ InitializationOptions = None # type: ignore
37
+ stdio_server = None # type: ignore
31
38
 
32
39
  # Directory configuration
33
40
  import os
41
+ import shutil
42
+
43
+ from scitex import capture
34
44
 
35
45
  # Use SCITEX_DIR environment variable if set, otherwise default to ~/.scitex
36
46
  SCITEX_BASE_DIR = Path(os.getenv("SCITEX_DIR", Path.home() / ".scitex"))
@@ -924,8 +934,8 @@ class CaptureServer:
924
934
  return {"success": False, "error": str(e)}
925
935
 
926
936
 
927
- async def main():
928
- """Main entry point for the MCP server."""
937
+ async def _run_server():
938
+ """Run the MCP server (internal)."""
929
939
  server = CaptureServer()
930
940
  async with stdio_server() as (read_stream, write_stream):
931
941
  await server.server.run(
@@ -942,7 +952,26 @@ async def main():
942
952
  )
943
953
 
944
954
 
955
+ def main():
956
+ """Main entry point for the MCP server."""
957
+ if not MCP_AVAILABLE:
958
+ import sys
959
+
960
+ print("=" * 60)
961
+ print("MCP Server 'scitex-capture' requires the 'mcp' package.")
962
+ print()
963
+ print("Install with:")
964
+ print(" pip install mcp")
965
+ print()
966
+ print("Or install scitex with MCP support:")
967
+ print(" pip install scitex[mcp]")
968
+ print("=" * 60)
969
+ sys.exit(1)
970
+
971
+ asyncio.run(_run_server())
972
+
973
+
945
974
  if __name__ == "__main__":
946
- asyncio.run(main())
975
+ main()
947
976
 
948
977
  # EOF
scitex/cli/audio.py ADDED
@@ -0,0 +1,233 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ SciTeX CLI - Audio Commands (Text-to-Speech)
4
+
5
+ Provides text-to-speech with multiple backend support.
6
+ """
7
+
8
+ import sys
9
+
10
+ import click
11
+
12
+
13
+ @click.group(context_settings={"help_option_names": ["-h", "--help"]})
14
+ def audio():
15
+ """
16
+ Text-to-speech utilities
17
+
18
+ \b
19
+ Backends (fallback order):
20
+ pyttsx3 - System TTS (offline, free)
21
+ gtts - Google TTS (free, needs internet)
22
+ elevenlabs - ElevenLabs (paid, high quality)
23
+
24
+ \b
25
+ Examples:
26
+ scitex audio speak "Hello world"
27
+ scitex audio speak "Bonjour" --backend gtts --voice fr
28
+ scitex audio backends # List available backends
29
+ scitex audio check # Check audio status (WSL)
30
+ """
31
+ pass
32
+
33
+
34
+ @audio.command()
35
+ @click.argument("text")
36
+ @click.option(
37
+ "--backend",
38
+ "-b",
39
+ type=click.Choice(["pyttsx3", "gtts", "elevenlabs"]),
40
+ help="TTS backend (auto-selects with fallback if not specified)",
41
+ )
42
+ @click.option("--voice", "-v", help="Voice name, ID, or language code")
43
+ @click.option("--output", "-o", type=click.Path(), help="Save audio to file")
44
+ @click.option("--no-play", is_flag=True, help="Don't play audio (only save)")
45
+ @click.option("--rate", "-r", type=int, help="Speech rate (pyttsx3 only, default: 150)")
46
+ @click.option(
47
+ "--speed", "-s", type=float, help="Speed multiplier (gtts only, e.g., 1.5)"
48
+ )
49
+ @click.option("--no-fallback", is_flag=True, help="Disable backend fallback on error")
50
+ def speak(text, backend, voice, output, no_play, rate, speed, no_fallback):
51
+ """
52
+ Convert text to speech
53
+
54
+ \b
55
+ Examples:
56
+ scitex audio speak "Hello world"
57
+ scitex audio speak "Bonjour" --backend gtts --voice fr
58
+ scitex audio speak "Test" --output speech.mp3 --no-play
59
+ scitex audio speak "Fast speech" --backend pyttsx3 --rate 200
60
+ scitex audio speak "Slow speech" --backend gtts --speed 0.8
61
+ """
62
+ try:
63
+ from scitex.audio import speak as tts_speak
64
+
65
+ kwargs = {
66
+ "text": text,
67
+ "play": not no_play,
68
+ "fallback": not no_fallback,
69
+ }
70
+
71
+ if backend:
72
+ kwargs["backend"] = backend
73
+ if voice:
74
+ kwargs["voice"] = voice
75
+ if output:
76
+ kwargs["output_path"] = output
77
+ if rate:
78
+ kwargs["rate"] = rate
79
+ if speed:
80
+ kwargs["speed"] = speed
81
+
82
+ result = tts_speak(**kwargs)
83
+
84
+ if output and result:
85
+ click.secho(f"Audio saved: {result}", fg="green")
86
+ elif not no_play:
87
+ click.secho("Speech completed", fg="green")
88
+
89
+ except Exception as e:
90
+ click.secho(f"Error: {e}", fg="red", err=True)
91
+ sys.exit(1)
92
+
93
+
94
+ @audio.command(name="backends")
95
+ @click.option("--json", "as_json", is_flag=True, help="Output as JSON")
96
+ def list_backends(as_json):
97
+ """
98
+ List available TTS backends
99
+
100
+ \b
101
+ Example:
102
+ scitex audio backends
103
+ scitex audio backends --json
104
+ """
105
+ try:
106
+ from scitex.audio import FALLBACK_ORDER, available_backends
107
+
108
+ backends = available_backends()
109
+
110
+ if as_json:
111
+ import json
112
+
113
+ output = {
114
+ "available": backends,
115
+ "fallback_order": FALLBACK_ORDER,
116
+ }
117
+ click.echo(json.dumps(output, indent=2))
118
+ else:
119
+ click.secho("Available TTS Backends", fg="cyan", bold=True)
120
+ click.echo("=" * 40)
121
+
122
+ click.echo("\nFallback order:")
123
+ for i, b in enumerate(FALLBACK_ORDER, 1):
124
+ status = (
125
+ click.style("available", fg="green")
126
+ if b in backends
127
+ else click.style("not installed", fg="red")
128
+ )
129
+ click.echo(f" {i}. {b}: {status}")
130
+
131
+ if not backends:
132
+ click.echo()
133
+ click.secho("No backends available!", fg="red")
134
+ click.echo("Install one of:")
135
+ click.echo(" pip install pyttsx3 # + apt install espeak-ng")
136
+ click.echo(" pip install gTTS")
137
+ click.echo(" pip install elevenlabs")
138
+
139
+ except Exception as e:
140
+ click.secho(f"Error: {e}", fg="red", err=True)
141
+ sys.exit(1)
142
+
143
+
144
+ @audio.command()
145
+ @click.option("--json", "as_json", is_flag=True, help="Output as JSON")
146
+ def check(as_json):
147
+ """
148
+ Check audio status (especially for WSL)
149
+
150
+ \b
151
+ Checks:
152
+ - WSL detection
153
+ - WSLg availability
154
+ - PulseAudio connection
155
+ - Windows fallback availability
156
+
157
+ \b
158
+ Example:
159
+ scitex audio check
160
+ scitex audio check --json
161
+ """
162
+ try:
163
+ from scitex.audio import check_wsl_audio
164
+
165
+ status = check_wsl_audio()
166
+
167
+ if as_json:
168
+ import json
169
+
170
+ click.echo(json.dumps(status, indent=2))
171
+ else:
172
+ click.secho("Audio Status Check", fg="cyan", bold=True)
173
+ click.echo("=" * 40)
174
+
175
+ def status_mark(val):
176
+ return (
177
+ click.style("Yes", fg="green")
178
+ if val
179
+ else click.style("No", fg="red")
180
+ )
181
+
182
+ click.echo(f"\nWSL Environment: {status_mark(status['is_wsl'])}")
183
+
184
+ if status["is_wsl"]:
185
+ click.echo(f"WSLg Available: {status_mark(status['wslg_available'])}")
186
+ click.echo(
187
+ f"PulseServer Socket: {status_mark(status['pulse_server_exists'])}"
188
+ )
189
+ click.echo(
190
+ f"PulseAudio Connected: {status_mark(status['pulse_connected'])}"
191
+ )
192
+ click.echo(
193
+ f"Windows Fallback: {status_mark(status['windows_fallback_available'])}"
194
+ )
195
+
196
+ click.echo()
197
+ rec = status["recommended"]
198
+ if rec == "linux":
199
+ click.secho("Recommended: Linux audio (PulseAudio)", fg="green")
200
+ elif rec == "windows":
201
+ click.secho(
202
+ "Recommended: Windows fallback (powershell.exe)", fg="yellow"
203
+ )
204
+ else:
205
+ click.secho("No audio output available", fg="red")
206
+
207
+ except Exception as e:
208
+ click.secho(f"Error: {e}", fg="red", err=True)
209
+ sys.exit(1)
210
+
211
+
212
+ @audio.command()
213
+ def stop():
214
+ """
215
+ Stop any currently playing speech
216
+
217
+ \b
218
+ Example:
219
+ scitex audio stop
220
+ """
221
+ try:
222
+ from scitex.audio import stop_speech
223
+
224
+ stop_speech()
225
+ click.secho("Speech stopped", fg="green")
226
+
227
+ except Exception as e:
228
+ click.secho(f"Error: {e}", fg="red", err=True)
229
+ sys.exit(1)
230
+
231
+
232
+ if __name__ == "__main__":
233
+ audio()