scitex 2.14.0__py3-none-any.whl → 2.15.3__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 (264) hide show
  1. scitex/__init__.py +71 -17
  2. scitex/_env_loader.py +156 -0
  3. scitex/_mcp_resources/__init__.py +37 -0
  4. scitex/_mcp_resources/_cheatsheet.py +135 -0
  5. scitex/_mcp_resources/_figrecipe.py +138 -0
  6. scitex/_mcp_resources/_formats.py +102 -0
  7. scitex/_mcp_resources/_modules.py +337 -0
  8. scitex/_mcp_resources/_session.py +149 -0
  9. scitex/_mcp_tools/__init__.py +4 -0
  10. scitex/_mcp_tools/audio.py +66 -0
  11. scitex/_mcp_tools/diagram.py +11 -95
  12. scitex/_mcp_tools/introspect.py +210 -0
  13. scitex/_mcp_tools/plt.py +260 -305
  14. scitex/_mcp_tools/scholar.py +74 -0
  15. scitex/_mcp_tools/social.py +27 -0
  16. scitex/_mcp_tools/template.py +24 -0
  17. scitex/_mcp_tools/writer.py +17 -210
  18. scitex/ai/_gen_ai/_PARAMS.py +10 -7
  19. scitex/ai/classification/reporters/_SingleClassificationReporter.py +45 -1603
  20. scitex/ai/classification/reporters/_mixins/__init__.py +36 -0
  21. scitex/ai/classification/reporters/_mixins/_constants.py +67 -0
  22. scitex/ai/classification/reporters/_mixins/_cv_summary.py +387 -0
  23. scitex/ai/classification/reporters/_mixins/_feature_importance.py +119 -0
  24. scitex/ai/classification/reporters/_mixins/_metrics.py +275 -0
  25. scitex/ai/classification/reporters/_mixins/_plotting.py +179 -0
  26. scitex/ai/classification/reporters/_mixins/_reports.py +153 -0
  27. scitex/ai/classification/reporters/_mixins/_storage.py +160 -0
  28. scitex/ai/classification/timeseries/_TimeSeriesSlidingWindowSplit.py +30 -1550
  29. scitex/ai/classification/timeseries/_sliding_window_core.py +467 -0
  30. scitex/ai/classification/timeseries/_sliding_window_plotting.py +369 -0
  31. scitex/audio/README.md +40 -36
  32. scitex/audio/__init__.py +129 -61
  33. scitex/audio/_branding.py +185 -0
  34. scitex/audio/_mcp/__init__.py +32 -0
  35. scitex/audio/_mcp/handlers.py +59 -6
  36. scitex/audio/_mcp/speak_handlers.py +238 -0
  37. scitex/audio/_relay.py +225 -0
  38. scitex/audio/_tts.py +18 -10
  39. scitex/audio/engines/base.py +17 -10
  40. scitex/audio/engines/elevenlabs_engine.py +7 -2
  41. scitex/audio/mcp_server.py +228 -75
  42. scitex/canvas/README.md +1 -1
  43. scitex/canvas/editor/_dearpygui/__init__.py +25 -0
  44. scitex/canvas/editor/_dearpygui/_editor.py +147 -0
  45. scitex/canvas/editor/_dearpygui/_handlers.py +476 -0
  46. scitex/canvas/editor/_dearpygui/_panels/__init__.py +17 -0
  47. scitex/canvas/editor/_dearpygui/_panels/_control.py +119 -0
  48. scitex/canvas/editor/_dearpygui/_panels/_element_controls.py +190 -0
  49. scitex/canvas/editor/_dearpygui/_panels/_preview.py +43 -0
  50. scitex/canvas/editor/_dearpygui/_panels/_sections.py +390 -0
  51. scitex/canvas/editor/_dearpygui/_plotting.py +187 -0
  52. scitex/canvas/editor/_dearpygui/_rendering.py +504 -0
  53. scitex/canvas/editor/_dearpygui/_selection.py +295 -0
  54. scitex/canvas/editor/_dearpygui/_state.py +93 -0
  55. scitex/canvas/editor/_dearpygui/_utils.py +61 -0
  56. scitex/canvas/editor/flask_editor/_core/__init__.py +27 -0
  57. scitex/canvas/editor/flask_editor/_core/_bbox_extraction.py +200 -0
  58. scitex/canvas/editor/flask_editor/_core/_editor.py +173 -0
  59. scitex/canvas/editor/flask_editor/_core/_export_helpers.py +353 -0
  60. scitex/canvas/editor/flask_editor/_core/_routes_basic.py +190 -0
  61. scitex/canvas/editor/flask_editor/_core/_routes_export.py +332 -0
  62. scitex/canvas/editor/flask_editor/_core/_routes_panels.py +252 -0
  63. scitex/canvas/editor/flask_editor/_core/_routes_save.py +218 -0
  64. scitex/canvas/editor/flask_editor/_core.py +25 -1684
  65. scitex/canvas/editor/flask_editor/templates/__init__.py +32 -70
  66. scitex/cli/__init__.py +38 -43
  67. scitex/cli/audio.py +160 -41
  68. scitex/cli/capture.py +133 -20
  69. scitex/cli/introspect.py +488 -0
  70. scitex/cli/main.py +200 -109
  71. scitex/cli/mcp.py +60 -34
  72. scitex/cli/plt.py +414 -0
  73. scitex/cli/repro.py +15 -8
  74. scitex/cli/resource.py +15 -8
  75. scitex/cli/scholar/__init__.py +154 -8
  76. scitex/cli/scholar/_crossref_scitex.py +296 -0
  77. scitex/cli/scholar/_fetch.py +25 -3
  78. scitex/cli/social.py +355 -0
  79. scitex/cli/stats.py +136 -11
  80. scitex/cli/template.py +129 -12
  81. scitex/cli/tex.py +15 -8
  82. scitex/cli/writer.py +49 -299
  83. scitex/cloud/__init__.py +41 -2
  84. scitex/config/README.md +1 -1
  85. scitex/config/__init__.py +16 -2
  86. scitex/config/_env_registry.py +256 -0
  87. scitex/context/__init__.py +22 -0
  88. scitex/dev/__init__.py +20 -1
  89. scitex/diagram/__init__.py +42 -19
  90. scitex/diagram/mcp_server.py +13 -125
  91. scitex/gen/__init__.py +50 -14
  92. scitex/gen/_list_packages.py +4 -4
  93. scitex/introspect/__init__.py +82 -0
  94. scitex/introspect/_call_graph.py +303 -0
  95. scitex/introspect/_class_hierarchy.py +163 -0
  96. scitex/introspect/_core.py +41 -0
  97. scitex/introspect/_docstring.py +131 -0
  98. scitex/introspect/_examples.py +113 -0
  99. scitex/introspect/_imports.py +271 -0
  100. scitex/{gen/_inspect_module.py → introspect/_list_api.py} +48 -56
  101. scitex/introspect/_mcp/__init__.py +41 -0
  102. scitex/introspect/_mcp/handlers.py +233 -0
  103. scitex/introspect/_members.py +155 -0
  104. scitex/introspect/_resolve.py +89 -0
  105. scitex/introspect/_signature.py +131 -0
  106. scitex/introspect/_source.py +80 -0
  107. scitex/introspect/_type_hints.py +172 -0
  108. scitex/io/_save.py +1 -2
  109. scitex/io/bundle/README.md +1 -1
  110. scitex/logging/_formatters.py +19 -9
  111. scitex/mcp_server.py +98 -5
  112. scitex/os/__init__.py +4 -0
  113. scitex/{gen → os}/_check_host.py +4 -5
  114. scitex/plt/__init__.py +245 -550
  115. scitex/plt/_subplots/_AxisWrapperMixins/_SeabornMixin/_wrappers.py +5 -10
  116. scitex/plt/docs/EXTERNAL_PACKAGE_BRANDING.md +149 -0
  117. scitex/plt/gallery/README.md +1 -1
  118. scitex/plt/utils/_hitmap/__init__.py +82 -0
  119. scitex/plt/utils/_hitmap/_artist_extraction.py +343 -0
  120. scitex/plt/utils/_hitmap/_color_application.py +346 -0
  121. scitex/plt/utils/_hitmap/_color_conversion.py +121 -0
  122. scitex/plt/utils/_hitmap/_constants.py +40 -0
  123. scitex/plt/utils/_hitmap/_hitmap_core.py +334 -0
  124. scitex/plt/utils/_hitmap/_path_extraction.py +357 -0
  125. scitex/plt/utils/_hitmap/_query.py +113 -0
  126. scitex/plt/utils/_hitmap.py +46 -1616
  127. scitex/plt/utils/_metadata/__init__.py +80 -0
  128. scitex/plt/utils/_metadata/_artists/__init__.py +25 -0
  129. scitex/plt/utils/_metadata/_artists/_base.py +195 -0
  130. scitex/plt/utils/_metadata/_artists/_collections.py +356 -0
  131. scitex/plt/utils/_metadata/_artists/_extract.py +57 -0
  132. scitex/plt/utils/_metadata/_artists/_images.py +80 -0
  133. scitex/plt/utils/_metadata/_artists/_lines.py +261 -0
  134. scitex/plt/utils/_metadata/_artists/_patches.py +247 -0
  135. scitex/plt/utils/_metadata/_artists/_text.py +106 -0
  136. scitex/plt/utils/_metadata/_csv.py +416 -0
  137. scitex/plt/utils/_metadata/_detect.py +225 -0
  138. scitex/plt/utils/_metadata/_legend.py +127 -0
  139. scitex/plt/utils/_metadata/_rounding.py +117 -0
  140. scitex/plt/utils/_metadata/_verification.py +202 -0
  141. scitex/schema/README.md +1 -1
  142. scitex/scholar/__init__.py +8 -0
  143. scitex/scholar/_mcp/crossref_handlers.py +265 -0
  144. scitex/scholar/core/Scholar.py +63 -1700
  145. scitex/scholar/core/_mixins/__init__.py +36 -0
  146. scitex/scholar/core/_mixins/_enrichers.py +270 -0
  147. scitex/scholar/core/_mixins/_library_handlers.py +100 -0
  148. scitex/scholar/core/_mixins/_loaders.py +103 -0
  149. scitex/scholar/core/_mixins/_pdf_download.py +375 -0
  150. scitex/scholar/core/_mixins/_pipeline.py +312 -0
  151. scitex/scholar/core/_mixins/_project_handlers.py +125 -0
  152. scitex/scholar/core/_mixins/_savers.py +69 -0
  153. scitex/scholar/core/_mixins/_search.py +103 -0
  154. scitex/scholar/core/_mixins/_services.py +88 -0
  155. scitex/scholar/core/_mixins/_url_finding.py +105 -0
  156. scitex/scholar/crossref_scitex.py +367 -0
  157. scitex/scholar/docs/EXTERNAL_PACKAGE_BRANDING.md +149 -0
  158. scitex/scholar/examples/00_run_all.sh +120 -0
  159. scitex/scholar/jobs/_executors.py +27 -3
  160. scitex/scholar/pdf_download/ScholarPDFDownloader.py +38 -416
  161. scitex/scholar/pdf_download/_cli.py +154 -0
  162. scitex/scholar/pdf_download/strategies/__init__.py +11 -8
  163. scitex/scholar/pdf_download/strategies/manual_download_fallback.py +80 -3
  164. scitex/scholar/pipelines/ScholarPipelineBibTeX.py +73 -121
  165. scitex/scholar/pipelines/ScholarPipelineParallel.py +80 -138
  166. scitex/scholar/pipelines/ScholarPipelineSingle.py +43 -63
  167. scitex/scholar/pipelines/_single_steps.py +71 -36
  168. scitex/scholar/storage/_LibraryManager.py +97 -1695
  169. scitex/scholar/storage/_mixins/__init__.py +30 -0
  170. scitex/scholar/storage/_mixins/_bibtex_handlers.py +128 -0
  171. scitex/scholar/storage/_mixins/_library_operations.py +218 -0
  172. scitex/scholar/storage/_mixins/_metadata_conversion.py +226 -0
  173. scitex/scholar/storage/_mixins/_paper_saving.py +456 -0
  174. scitex/scholar/storage/_mixins/_resolution.py +376 -0
  175. scitex/scholar/storage/_mixins/_storage_helpers.py +121 -0
  176. scitex/scholar/storage/_mixins/_symlink_handlers.py +226 -0
  177. scitex/security/README.md +3 -3
  178. scitex/session/README.md +1 -1
  179. scitex/session/__init__.py +26 -7
  180. scitex/session/_decorator.py +1 -1
  181. scitex/sh/README.md +1 -1
  182. scitex/sh/__init__.py +7 -4
  183. scitex/social/__init__.py +155 -0
  184. scitex/social/docs/EXTERNAL_PACKAGE_BRANDING.md +149 -0
  185. scitex/stats/_mcp/_handlers/__init__.py +31 -0
  186. scitex/stats/_mcp/_handlers/_corrections.py +113 -0
  187. scitex/stats/_mcp/_handlers/_descriptive.py +78 -0
  188. scitex/stats/_mcp/_handlers/_effect_size.py +106 -0
  189. scitex/stats/_mcp/_handlers/_format.py +94 -0
  190. scitex/stats/_mcp/_handlers/_normality.py +110 -0
  191. scitex/stats/_mcp/_handlers/_posthoc.py +224 -0
  192. scitex/stats/_mcp/_handlers/_power.py +247 -0
  193. scitex/stats/_mcp/_handlers/_recommend.py +102 -0
  194. scitex/stats/_mcp/_handlers/_run_test.py +279 -0
  195. scitex/stats/_mcp/_handlers/_stars.py +48 -0
  196. scitex/stats/_mcp/handlers.py +19 -1171
  197. scitex/stats/auto/_stat_style.py +175 -0
  198. scitex/stats/auto/_style_definitions.py +411 -0
  199. scitex/stats/auto/_styles.py +22 -620
  200. scitex/stats/descriptive/__init__.py +11 -8
  201. scitex/stats/descriptive/_ci.py +39 -0
  202. scitex/stats/power/_power.py +15 -4
  203. scitex/str/__init__.py +2 -1
  204. scitex/str/_title_case.py +63 -0
  205. scitex/template/README.md +1 -1
  206. scitex/template/__init__.py +25 -10
  207. scitex/template/_code_templates.py +147 -0
  208. scitex/template/_mcp/handlers.py +81 -0
  209. scitex/template/_mcp/tool_schemas.py +55 -0
  210. scitex/template/_templates/__init__.py +51 -0
  211. scitex/template/_templates/audio.py +233 -0
  212. scitex/template/_templates/canvas.py +312 -0
  213. scitex/template/_templates/capture.py +268 -0
  214. scitex/template/_templates/config.py +43 -0
  215. scitex/template/_templates/diagram.py +294 -0
  216. scitex/template/_templates/io.py +107 -0
  217. scitex/template/_templates/module.py +53 -0
  218. scitex/template/_templates/plt.py +202 -0
  219. scitex/template/_templates/scholar.py +267 -0
  220. scitex/template/_templates/session.py +130 -0
  221. scitex/template/_templates/session_minimal.py +43 -0
  222. scitex/template/_templates/session_plot.py +67 -0
  223. scitex/template/_templates/session_stats.py +77 -0
  224. scitex/template/_templates/stats.py +323 -0
  225. scitex/template/_templates/writer.py +296 -0
  226. scitex/template/clone_writer_directory.py +5 -5
  227. scitex/ui/_backends/_email.py +10 -2
  228. scitex/ui/_backends/_webhook.py +5 -1
  229. scitex/web/_search_pubmed.py +10 -6
  230. scitex/writer/README.md +1 -1
  231. scitex/writer/__init__.py +43 -34
  232. scitex/writer/_mcp/handlers.py +11 -744
  233. scitex/writer/_mcp/tool_schemas.py +5 -335
  234. scitex-2.15.3.dist-info/METADATA +667 -0
  235. {scitex-2.14.0.dist-info → scitex-2.15.3.dist-info}/RECORD +241 -120
  236. scitex/canvas/editor/flask_editor/templates/_scripts.py +0 -4933
  237. scitex/canvas/editor/flask_editor/templates/_styles.py +0 -1658
  238. scitex/diagram/_compile.py +0 -312
  239. scitex/diagram/_diagram.py +0 -355
  240. scitex/diagram/_mcp/__init__.py +0 -4
  241. scitex/diagram/_mcp/handlers.py +0 -400
  242. scitex/diagram/_mcp/tool_schemas.py +0 -157
  243. scitex/diagram/_presets.py +0 -173
  244. scitex/diagram/_schema.py +0 -182
  245. scitex/diagram/_split.py +0 -278
  246. scitex/gen/_ci.py +0 -12
  247. scitex/gen/_title_case.py +0 -89
  248. scitex/plt/_mcp/__init__.py +0 -4
  249. scitex/plt/_mcp/_handlers_annotation.py +0 -102
  250. scitex/plt/_mcp/_handlers_figure.py +0 -195
  251. scitex/plt/_mcp/_handlers_plot.py +0 -252
  252. scitex/plt/_mcp/_handlers_style.py +0 -219
  253. scitex/plt/_mcp/handlers.py +0 -74
  254. scitex/plt/_mcp/tool_schemas.py +0 -497
  255. scitex/plt/mcp_server.py +0 -231
  256. scitex/scholar/examples/SUGGESTIONS.md +0 -865
  257. scitex/scholar/examples/dev.py +0 -38
  258. scitex-2.14.0.dist-info/METADATA +0 -1238
  259. /scitex/{gen → context}/_detect_environment.py +0 -0
  260. /scitex/{gen → context}/_get_notebook_path.py +0 -0
  261. /scitex/{gen/_shell.py → sh/_shell_legacy.py} +0 -0
  262. {scitex-2.14.0.dist-info → scitex-2.15.3.dist-info}/WHEEL +0 -0
  263. {scitex-2.14.0.dist-info → scitex-2.15.3.dist-info}/entry_points.txt +0 -0
  264. {scitex-2.14.0.dist-info → scitex-2.15.3.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,256 @@
1
+ #!/usr/bin/env python3
2
+ # Timestamp: 2026-01-24
3
+ # File: src/scitex/config/_env_registry.py
4
+
5
+ """
6
+ Registry of all SCITEX environment variables.
7
+
8
+ Provides documentation and template generation for environment configuration.
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ from dataclasses import dataclass
14
+ from typing import Dict, List, Optional
15
+
16
+
17
+ @dataclass
18
+ class EnvVar:
19
+ """Environment variable definition."""
20
+
21
+ name: str
22
+ description: str
23
+ module: str
24
+ default: Optional[str] = None
25
+ required: bool = False
26
+ sensitive: bool = False
27
+
28
+
29
+ # Registry of all SCITEX environment variables
30
+ ENV_REGISTRY: List[EnvVar] = [
31
+ # Core
32
+ EnvVar("SCITEX_DIR", "Base directory for scitex data", "core", "~/.scitex"),
33
+ EnvVar("SCITEX_ENV_SRC", "Path to env source file/directory", "core"),
34
+ EnvVar("SCITEX_LOGGING_LEVEL", "Logging level", "logging", "INFO"),
35
+ EnvVar("SCITEX_LOGGING_FORMAT", "Log format style", "logging", "default"),
36
+ EnvVar("SCITEX_LOGGING_FORCE_COLOR", "Force colored output", "logging", "false"),
37
+ # Audio
38
+ EnvVar("SCITEX_AUDIO_MODE", "Audio mode: local/remote/auto", "audio", "auto"),
39
+ EnvVar("SCITEX_AUDIO_RELAY_URL", "Relay server URL for remote audio", "audio"),
40
+ EnvVar("SCITEX_AUDIO_RELAY_HOST", "Relay server host", "audio"),
41
+ EnvVar("SCITEX_AUDIO_RELAY_PORT", "Relay server port", "audio", "31293"),
42
+ EnvVar("SCITEX_AUDIO_PORT", "Audio server port", "audio", "31293"),
43
+ EnvVar(
44
+ "SCITEX_AUDIO_ELEVENLABS_API_KEY", "ElevenLabs API key", "audio", sensitive=True
45
+ ),
46
+ # Scholar
47
+ EnvVar("SCITEX_SCHOLAR_DIR", "Scholar library directory", "scholar"),
48
+ EnvVar("SCITEX_SCHOLAR_CROSSREF_EMAIL", "Email for Crossref API", "scholar"),
49
+ EnvVar("SCITEX_SCHOLAR_PUBMED_EMAIL", "Email for PubMed API", "scholar"),
50
+ EnvVar("SCITEX_SCHOLAR_CROSSREF_DB", "Local Crossref database path", "scholar"),
51
+ EnvVar("SCITEX_SCHOLAR_CROSSREF_API_URL", "Crossref API URL", "scholar"),
52
+ EnvVar(
53
+ "SCITEX_SCHOLAR_CROSSREF_MODE", "Crossref mode: local/api/hybrid", "scholar"
54
+ ),
55
+ EnvVar("SCITEX_SCHOLAR_OPENATHENS_EMAIL", "OpenAthens login email", "scholar"),
56
+ EnvVar(
57
+ "SCITEX_SCHOLAR_OPENATHENS_ENABLED",
58
+ "Enable OpenAthens auth",
59
+ "scholar",
60
+ "false",
61
+ ),
62
+ EnvVar(
63
+ "SCITEX_SCHOLAR_EZPROXY_URL", "EZProxy URL for institutional access", "scholar"
64
+ ),
65
+ EnvVar("SCITEX_SCHOLAR_OPENURL_RESOLVER_URL", "OpenURL resolver URL", "scholar"),
66
+ EnvVar(
67
+ "SCITEX_SCHOLAR_ZENROWS_API_KEY",
68
+ "ZenRows API key for scraping",
69
+ "scholar",
70
+ sensitive=True,
71
+ ),
72
+ # Social
73
+ EnvVar(
74
+ "SCITEX_SOCIAL_X_CONSUMER_KEY",
75
+ "Twitter/X consumer key",
76
+ "social",
77
+ sensitive=True,
78
+ ),
79
+ EnvVar(
80
+ "SCITEX_SOCIAL_X_CONSUMER_KEY_SECRET",
81
+ "Twitter/X consumer secret",
82
+ "social",
83
+ sensitive=True,
84
+ ),
85
+ EnvVar(
86
+ "SCITEX_SOCIAL_X_ACCESS_TOKEN",
87
+ "Twitter/X access token",
88
+ "social",
89
+ sensitive=True,
90
+ ),
91
+ EnvVar(
92
+ "SCITEX_SOCIAL_X_ACCESS_TOKEN_SECRET",
93
+ "Twitter/X access token secret",
94
+ "social",
95
+ sensitive=True,
96
+ ),
97
+ EnvVar(
98
+ "SCITEX_SOCIAL_X_BEARER_TOKEN",
99
+ "Twitter/X bearer token",
100
+ "social",
101
+ sensitive=True,
102
+ ),
103
+ EnvVar(
104
+ "SCITEX_SOCIAL_LINKEDIN_CLIENT_ID",
105
+ "LinkedIn client ID",
106
+ "social",
107
+ sensitive=True,
108
+ ),
109
+ EnvVar(
110
+ "SCITEX_SOCIAL_LINKEDIN_CLIENT_SECRET",
111
+ "LinkedIn client secret",
112
+ "social",
113
+ sensitive=True,
114
+ ),
115
+ EnvVar(
116
+ "SCITEX_SOCIAL_LINKEDIN_ACCESS_TOKEN",
117
+ "LinkedIn access token",
118
+ "social",
119
+ sensitive=True,
120
+ ),
121
+ EnvVar(
122
+ "SCITEX_SOCIAL_REDDIT_CLIENT_ID",
123
+ "Reddit client ID",
124
+ "social",
125
+ sensitive=True,
126
+ ),
127
+ EnvVar(
128
+ "SCITEX_SOCIAL_REDDIT_CLIENT_SECRET",
129
+ "Reddit client secret",
130
+ "social",
131
+ sensitive=True,
132
+ ),
133
+ EnvVar(
134
+ "SCITEX_SOCIAL_YOUTUBE_API_KEY",
135
+ "YouTube API key",
136
+ "social",
137
+ sensitive=True,
138
+ ),
139
+ EnvVar(
140
+ "SCITEX_SOCIAL_YOUTUBE_CLIENT_SECRETS_FILE",
141
+ "YouTube client secrets file path",
142
+ "social",
143
+ ),
144
+ EnvVar(
145
+ "SCITEX_SOCIAL_GOOGLE_ANALYTICS_PROPERTY_ID",
146
+ "Google Analytics property ID",
147
+ "social",
148
+ ),
149
+ EnvVar(
150
+ "SCITEX_SOCIAL_GOOGLE_ANALYTICS_MEASUREMENT_ID",
151
+ "Google Analytics measurement ID",
152
+ "social",
153
+ ),
154
+ EnvVar(
155
+ "SCITEX_SOCIAL_GOOGLE_ANALYTICS_API_SECRET",
156
+ "Google Analytics API secret",
157
+ "social",
158
+ sensitive=True,
159
+ ),
160
+ EnvVar(
161
+ "SCITEX_SOCIAL_GOOGLE_APPLICATION_CREDENTIALS",
162
+ "Google service account credentials path",
163
+ "social",
164
+ ),
165
+ # Cloud
166
+ EnvVar("SCITEX_CLOUD_USERNAME", "Cloud username", "cloud", sensitive=True),
167
+ EnvVar("SCITEX_CLOUD_PASSWORD", "Cloud password", "cloud", sensitive=True),
168
+ EnvVar(
169
+ "SCITEX_CLOUD_CODE_WORKSPACE", "Running in cloud workspace", "cloud", "false"
170
+ ),
171
+ EnvVar("SCITEX_CLOUD_CODE_PROJECT_ROOT", "Cloud project root", "cloud"),
172
+ EnvVar("SCITEX_CLOUD_CODE_BACKEND", "Cloud backend type", "cloud"),
173
+ # UI/Notification
174
+ EnvVar("SCITEX_UI_DEFAULT_BACKEND", "Default notification backend", "ui"),
175
+ EnvVar(
176
+ "SCITEX_UI_BACKEND_PRIORITY",
177
+ "Notification backend priority (comma-sep)",
178
+ "ui",
179
+ ),
180
+ EnvVar("SCITEX_UI_INFO_BACKENDS", "Backends for info notifications", "ui"),
181
+ EnvVar("SCITEX_UI_WARNING_BACKENDS", "Backends for warning notifications", "ui"),
182
+ EnvVar("SCITEX_UI_ERROR_BACKENDS", "Backends for error notifications", "ui"),
183
+ EnvVar("SCITEX_UI_CRITICAL_BACKENDS", "Backends for critical notifications", "ui"),
184
+ EnvVar("SCITEX_UI_EMAIL_NOTIFICATION_FROM", "Email notification sender", "ui"),
185
+ EnvVar("SCITEX_UI_EMAIL_NOTIFICATION_TO", "Email notification recipient", "ui"),
186
+ EnvVar("SCITEX_UI_WEBHOOK_URL", "Webhook URL for notifications", "ui"),
187
+ # Capture
188
+ EnvVar("SCITEX_CAPTURE_DIR", "Screenshot capture directory", "capture"),
189
+ # Web
190
+ EnvVar("SCITEX_WEB_DOWNLOADS_DIR", "Web downloads directory", "web"),
191
+ # PLT
192
+ EnvVar("SCITEX_PLT_AXES_WIDTH_MM", "Default axes width in mm", "plt"),
193
+ EnvVar("SCITEX_PLT_LINES_TRACE_MM", "Default line trace width in mm", "plt"),
194
+ EnvVar("SCITEX_PLT_STYLE", "Default plot style", "plt"),
195
+ EnvVar("SCITEX_PLT_COLORS", "Color palette to use", "plt"),
196
+ ]
197
+
198
+
199
+ def get_env_by_module(module: str) -> List[EnvVar]:
200
+ """Get all environment variables for a module."""
201
+ return [e for e in ENV_REGISTRY if e.module == module]
202
+
203
+
204
+ def get_all_modules() -> List[str]:
205
+ """Get list of all modules with env vars."""
206
+ return sorted(set(e.module for e in ENV_REGISTRY))
207
+
208
+
209
+ def generate_template(
210
+ include_sensitive: bool = True, include_defaults: bool = True
211
+ ) -> str:
212
+ """Generate a template .src file with all environment variables."""
213
+ lines = [
214
+ "#!/bin/bash",
215
+ "# SciTeX Environment Variables Template",
216
+ "# Generated by scitex.config.generate_template()",
217
+ "#",
218
+ "# Usage: source this file or set SCITEX_ENV_SRC to this path",
219
+ "",
220
+ ]
221
+
222
+ for module in get_all_modules():
223
+ lines.append(f"# === {module.upper()} ===")
224
+ for env in get_env_by_module(module):
225
+ if env.sensitive and not include_sensitive:
226
+ continue
227
+
228
+ if env.description:
229
+ lines.append(f"# {env.description}")
230
+
231
+ if env.default and include_defaults:
232
+ lines.append(f'export {env.name}="{env.default}"')
233
+ elif env.sensitive:
234
+ lines.append(f'# export {env.name}="YOUR_{env.name}_HERE"')
235
+ else:
236
+ lines.append(f"# export {env.name}=")
237
+ lines.append("")
238
+
239
+ return "\n".join(lines)
240
+
241
+
242
+ def get_env_docs() -> Dict[str, Dict]:
243
+ """Get documentation for all environment variables."""
244
+ return {
245
+ e.name: {
246
+ "description": e.description,
247
+ "module": e.module,
248
+ "default": e.default,
249
+ "required": e.required,
250
+ "sensitive": e.sensitive,
251
+ }
252
+ for e in ENV_REGISTRY
253
+ }
254
+
255
+
256
+ # EOF
@@ -1,9 +1,31 @@
1
1
  #!/usr/bin/env python3
2
2
  """Scitex context module."""
3
3
 
4
+ from ._detect_environment import (
5
+ detect_environment,
6
+ get_output_directory,
7
+ is_ipython,
8
+ is_notebook,
9
+ is_script,
10
+ )
11
+ from ._get_notebook_path import (
12
+ get_notebook_directory,
13
+ get_notebook_info_simple,
14
+ get_notebook_name,
15
+ get_notebook_path,
16
+ )
4
17
  from ._suppress_output import quiet, suppress_output
5
18
 
6
19
  __all__ = [
20
+ "detect_environment",
21
+ "get_notebook_directory",
22
+ "get_notebook_info_simple",
23
+ "get_notebook_name",
24
+ "get_notebook_path",
25
+ "get_output_directory",
26
+ "is_ipython",
27
+ "is_notebook",
28
+ "is_script",
7
29
  "quiet",
8
30
  "suppress_output",
9
31
  ]
scitex/dev/__init__.py CHANGED
@@ -1,20 +1,39 @@
1
1
  #!/usr/bin/env python3
2
- """Scitex dev module."""
2
+ """Scitex dev module - Development and debugging utilities."""
3
3
 
4
4
  # Pyproject utilities (lazy import to avoid tomlkit dependency)
5
+ # Installation guide utilities (moved from root scitex module)
6
+ from .._install_guide import (
7
+ MODULE_REQUIREMENTS,
8
+ check_module_deps,
9
+ require_module,
10
+ requires,
11
+ show_install_guide,
12
+ warn_module_deps,
13
+ )
5
14
  from . import _pyproject as pyproject
6
15
  from . import cv
7
16
  from ._analyze_code_flow import CodeFlowAnalyzer, analyze_code_flow, main, parse_args
8
17
  from ._reload import reload, reload_auto, reload_stop
9
18
 
10
19
  __all__ = [
20
+ # Code flow analysis
11
21
  "CodeFlowAnalyzer",
12
22
  "analyze_code_flow",
13
23
  "main",
14
24
  "parse_args",
25
+ # Hot reloading
15
26
  "reload",
16
27
  "reload_auto",
17
28
  "reload_stop",
29
+ # Submodules
18
30
  "pyproject",
19
31
  "cv",
32
+ # Installation guide utilities
33
+ "show_install_guide",
34
+ "check_module_deps",
35
+ "require_module",
36
+ "requires",
37
+ "warn_module_deps",
38
+ "MODULE_REQUIREMENTS",
20
39
  ]
@@ -1,38 +1,59 @@
1
1
  #!/usr/bin/env python3
2
- # -*- coding: utf-8 -*-
3
- # Timestamp: 2025-12-15
2
+ # Timestamp: 2026-01-24
4
3
  # Author: ywatanabe / Claude
5
4
  # File: scitex/diagram/__init__.py
6
5
 
7
6
  """
8
7
  SciTeX Diagram - Paper-optimized diagram generation.
9
8
 
10
- This module provides a semantic layer above Mermaid/Graphviz/D2 that
11
- understands paper constraints (column width, reading direction, emphasis)
12
- and compiles to backend formats with appropriate layout hints.
13
-
14
- Key insight: LLMs are good at generating CONSTRAINTS, not pixel layouts.
15
- SciTeX Diagram defines "what this diagram means for a paper" and compiles
16
- that to backend-specific layout directives.
9
+ This module delegates entirely to figrecipe._diagram.
10
+ figrecipe is the single source of truth for diagram functionality.
17
11
 
18
12
  Example
19
13
  -------
20
- >>> from scitex.diagram import Diagram
14
+ >>> import scitex as stx
15
+ >>>
16
+ >>> # Recommended: Use stx.Diagram directly
17
+ >>> d = stx.Diagram(type="pipeline")
18
+ >>> d.add_node("input", "Raw Data")
19
+ >>> d.add_node("process", "Transform", emphasis="primary")
20
+ >>> d.add_edge("input", "process")
21
+ >>> d.to_mermaid("pipeline.mmd")
21
22
  >>>
22
- >>> diagram = Diagram.from_yaml("workflow.diagram.yaml")
23
- >>> diagram.to_mermaid("workflow.mmd")
24
- >>> diagram.to_graphviz("workflow.dot")
23
+ >>> # From YAML spec
24
+ >>> d = stx.Diagram.from_yaml("workflow.diagram.yaml")
25
+ >>> d.to_mermaid("workflow.mmd")
26
+ >>> d.to_graphviz("workflow.dot")
25
27
  """
26
28
 
27
- from scitex.diagram._schema import DiagramSpec, PaperConstraints, LayoutHints, PaperMode
28
- from scitex.diagram._diagram import Diagram
29
- from scitex.diagram._compile import compile_to_mermaid, compile_to_graphviz
30
- from scitex.diagram._presets import WORKFLOW_PRESET, DECISION_PRESET, PIPELINE_PRESET
31
- from scitex.diagram._split import split_diagram, SplitConfig, SplitStrategy, SplitResult
29
+ # Import everything from figrecipe._diagram (single source of truth)
30
+ from figrecipe._diagram import (
31
+ DECISION_PRESET,
32
+ PIPELINE_PRESET,
33
+ SCIENTIFIC_PRESET,
34
+ WORKFLOW_PRESET,
35
+ Diagram,
36
+ DiagramSpec,
37
+ DiagramType,
38
+ EdgeSpec,
39
+ LayoutHints,
40
+ NodeSpec,
41
+ PaperConstraints,
42
+ PaperMode,
43
+ SplitConfig,
44
+ SplitResult,
45
+ SplitStrategy,
46
+ get_preset,
47
+ list_presets,
48
+ )
49
+ from figrecipe._diagram._compile import compile_to_graphviz, compile_to_mermaid
32
50
 
33
51
  __all__ = [
34
52
  "Diagram",
35
53
  "DiagramSpec",
54
+ "DiagramType",
55
+ "NodeSpec",
56
+ "EdgeSpec",
36
57
  "PaperConstraints",
37
58
  "LayoutHints",
38
59
  "PaperMode",
@@ -41,7 +62,9 @@ __all__ = [
41
62
  "WORKFLOW_PRESET",
42
63
  "DECISION_PRESET",
43
64
  "PIPELINE_PRESET",
44
- "split_diagram",
65
+ "SCIENTIFIC_PRESET",
66
+ "get_preset",
67
+ "list_presets",
45
68
  "SplitConfig",
46
69
  "SplitStrategy",
47
70
  "SplitResult",
@@ -1,148 +1,36 @@
1
1
  #!/usr/bin/env python3
2
- # Timestamp: 2026-01-08
2
+ # Timestamp: 2026-01-24
3
3
  # File: src/scitex/diagram/mcp_server.py
4
- # ----------------------------------------
5
4
 
6
5
  """
7
- MCP Server for SciTeX diagram - Paper-optimized diagram generation.
6
+ MCP Server for SciTeX diagram - delegates to figrecipe.
8
7
 
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
8
+ This is a thin wrapper that redirects to figrecipe's MCP server.
9
+ figrecipe is the single source of truth for diagram functionality.
14
10
  """
15
11
 
16
12
  from __future__ import annotations
17
13
 
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
14
 
128
15
  def main():
129
- """Main entry point for the MCP server."""
130
- if not MCP_AVAILABLE:
16
+ """Main entry point - delegates to figrecipe's MCP server."""
17
+ try:
18
+ from figrecipe._mcp.server import mcp
19
+
20
+ mcp.run()
21
+ except ImportError as e:
131
22
  import sys
132
23
 
133
24
  print("=" * 60)
134
- print("MCP Server 'scitex-diagram' requires the 'mcp' package.")
25
+ print("scitex-diagram requires figrecipe with MCP support.")
135
26
  print()
136
27
  print("Install with:")
137
- print(" pip install mcp")
28
+ print(" pip install figrecipe[mcp]")
138
29
  print()
139
- print("Or install scitex with MCP support:")
140
- print(" pip install scitex[mcp]")
30
+ print(f"Error: {e}")
141
31
  print("=" * 60)
142
32
  sys.exit(1)
143
33
 
144
- asyncio.run(_run_server())
145
-
146
34
 
147
35
  if __name__ == "__main__":
148
36
  main()