scitex 2.14.0__py3-none-any.whl → 2.15.1__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 (218) hide show
  1. scitex/__init__.py +47 -0
  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 +191 -0
  13. scitex/_mcp_tools/plt.py +260 -305
  14. scitex/_mcp_tools/scholar.py +74 -0
  15. scitex/_mcp_tools/social.py +244 -0
  16. scitex/_mcp_tools/writer.py +21 -204
  17. scitex/ai/_gen_ai/_PARAMS.py +10 -7
  18. scitex/ai/classification/reporters/_SingleClassificationReporter.py +45 -1603
  19. scitex/ai/classification/reporters/_mixins/__init__.py +36 -0
  20. scitex/ai/classification/reporters/_mixins/_constants.py +67 -0
  21. scitex/ai/classification/reporters/_mixins/_cv_summary.py +387 -0
  22. scitex/ai/classification/reporters/_mixins/_feature_importance.py +119 -0
  23. scitex/ai/classification/reporters/_mixins/_metrics.py +275 -0
  24. scitex/ai/classification/reporters/_mixins/_plotting.py +179 -0
  25. scitex/ai/classification/reporters/_mixins/_reports.py +153 -0
  26. scitex/ai/classification/reporters/_mixins/_storage.py +160 -0
  27. scitex/audio/README.md +40 -36
  28. scitex/audio/__init__.py +127 -59
  29. scitex/audio/_branding.py +185 -0
  30. scitex/audio/_mcp/__init__.py +32 -0
  31. scitex/audio/_mcp/handlers.py +59 -6
  32. scitex/audio/_mcp/speak_handlers.py +238 -0
  33. scitex/audio/_relay.py +225 -0
  34. scitex/audio/engines/elevenlabs_engine.py +6 -1
  35. scitex/audio/mcp_server.py +228 -75
  36. scitex/canvas/README.md +1 -1
  37. scitex/canvas/editor/_dearpygui/__init__.py +25 -0
  38. scitex/canvas/editor/_dearpygui/_editor.py +147 -0
  39. scitex/canvas/editor/_dearpygui/_handlers.py +476 -0
  40. scitex/canvas/editor/_dearpygui/_panels/__init__.py +17 -0
  41. scitex/canvas/editor/_dearpygui/_panels/_control.py +119 -0
  42. scitex/canvas/editor/_dearpygui/_panels/_element_controls.py +190 -0
  43. scitex/canvas/editor/_dearpygui/_panels/_preview.py +43 -0
  44. scitex/canvas/editor/_dearpygui/_panels/_sections.py +390 -0
  45. scitex/canvas/editor/_dearpygui/_plotting.py +187 -0
  46. scitex/canvas/editor/_dearpygui/_rendering.py +504 -0
  47. scitex/canvas/editor/_dearpygui/_selection.py +295 -0
  48. scitex/canvas/editor/_dearpygui/_state.py +93 -0
  49. scitex/canvas/editor/_dearpygui/_utils.py +61 -0
  50. scitex/canvas/editor/flask_editor/templates/__init__.py +32 -70
  51. scitex/cli/__init__.py +38 -43
  52. scitex/cli/audio.py +76 -27
  53. scitex/cli/capture.py +13 -20
  54. scitex/cli/introspect.py +443 -0
  55. scitex/cli/main.py +198 -109
  56. scitex/cli/mcp.py +60 -34
  57. scitex/cli/scholar/__init__.py +8 -0
  58. scitex/cli/scholar/_crossref_scitex.py +296 -0
  59. scitex/cli/scholar/_fetch.py +25 -3
  60. scitex/cli/social.py +314 -0
  61. scitex/cli/writer.py +117 -0
  62. scitex/config/README.md +1 -1
  63. scitex/config/__init__.py +16 -2
  64. scitex/config/_env_registry.py +191 -0
  65. scitex/diagram/__init__.py +42 -19
  66. scitex/diagram/mcp_server.py +13 -125
  67. scitex/introspect/__init__.py +75 -0
  68. scitex/introspect/_call_graph.py +303 -0
  69. scitex/introspect/_class_hierarchy.py +163 -0
  70. scitex/introspect/_core.py +42 -0
  71. scitex/introspect/_docstring.py +131 -0
  72. scitex/introspect/_examples.py +113 -0
  73. scitex/introspect/_imports.py +271 -0
  74. scitex/introspect/_mcp/__init__.py +37 -0
  75. scitex/introspect/_mcp/handlers.py +208 -0
  76. scitex/introspect/_members.py +151 -0
  77. scitex/introspect/_resolve.py +89 -0
  78. scitex/introspect/_signature.py +131 -0
  79. scitex/introspect/_source.py +80 -0
  80. scitex/introspect/_type_hints.py +172 -0
  81. scitex/io/bundle/README.md +1 -1
  82. scitex/mcp_server.py +98 -5
  83. scitex/plt/__init__.py +248 -550
  84. scitex/plt/_subplots/_AxisWrapperMixins/_SeabornMixin/_wrappers.py +5 -10
  85. scitex/plt/docs/EXTERNAL_PACKAGE_BRANDING.md +149 -0
  86. scitex/plt/gallery/README.md +1 -1
  87. scitex/plt/utils/_hitmap/__init__.py +82 -0
  88. scitex/plt/utils/_hitmap/_artist_extraction.py +343 -0
  89. scitex/plt/utils/_hitmap/_color_application.py +346 -0
  90. scitex/plt/utils/_hitmap/_color_conversion.py +121 -0
  91. scitex/plt/utils/_hitmap/_constants.py +40 -0
  92. scitex/plt/utils/_hitmap/_hitmap_core.py +334 -0
  93. scitex/plt/utils/_hitmap/_path_extraction.py +357 -0
  94. scitex/plt/utils/_hitmap/_query.py +113 -0
  95. scitex/plt/utils/_hitmap.py +46 -1616
  96. scitex/plt/utils/_metadata/__init__.py +80 -0
  97. scitex/plt/utils/_metadata/_artists/__init__.py +25 -0
  98. scitex/plt/utils/_metadata/_artists/_base.py +195 -0
  99. scitex/plt/utils/_metadata/_artists/_collections.py +356 -0
  100. scitex/plt/utils/_metadata/_artists/_extract.py +57 -0
  101. scitex/plt/utils/_metadata/_artists/_images.py +80 -0
  102. scitex/plt/utils/_metadata/_artists/_lines.py +261 -0
  103. scitex/plt/utils/_metadata/_artists/_patches.py +247 -0
  104. scitex/plt/utils/_metadata/_artists/_text.py +106 -0
  105. scitex/plt/utils/_metadata/_csv.py +416 -0
  106. scitex/plt/utils/_metadata/_detect.py +225 -0
  107. scitex/plt/utils/_metadata/_legend.py +127 -0
  108. scitex/plt/utils/_metadata/_rounding.py +117 -0
  109. scitex/plt/utils/_metadata/_verification.py +202 -0
  110. scitex/schema/README.md +1 -1
  111. scitex/scholar/__init__.py +8 -0
  112. scitex/scholar/_mcp/crossref_handlers.py +265 -0
  113. scitex/scholar/core/Scholar.py +63 -1700
  114. scitex/scholar/core/_mixins/__init__.py +36 -0
  115. scitex/scholar/core/_mixins/_enrichers.py +270 -0
  116. scitex/scholar/core/_mixins/_library_handlers.py +100 -0
  117. scitex/scholar/core/_mixins/_loaders.py +103 -0
  118. scitex/scholar/core/_mixins/_pdf_download.py +375 -0
  119. scitex/scholar/core/_mixins/_pipeline.py +312 -0
  120. scitex/scholar/core/_mixins/_project_handlers.py +125 -0
  121. scitex/scholar/core/_mixins/_savers.py +69 -0
  122. scitex/scholar/core/_mixins/_search.py +103 -0
  123. scitex/scholar/core/_mixins/_services.py +88 -0
  124. scitex/scholar/core/_mixins/_url_finding.py +105 -0
  125. scitex/scholar/crossref_scitex.py +367 -0
  126. scitex/scholar/docs/EXTERNAL_PACKAGE_BRANDING.md +149 -0
  127. scitex/scholar/examples/00_run_all.sh +120 -0
  128. scitex/scholar/jobs/_executors.py +27 -3
  129. scitex/scholar/pdf_download/ScholarPDFDownloader.py +38 -416
  130. scitex/scholar/pdf_download/_cli.py +154 -0
  131. scitex/scholar/pdf_download/strategies/__init__.py +11 -8
  132. scitex/scholar/pdf_download/strategies/manual_download_fallback.py +80 -3
  133. scitex/scholar/pipelines/ScholarPipelineBibTeX.py +73 -121
  134. scitex/scholar/pipelines/ScholarPipelineParallel.py +80 -138
  135. scitex/scholar/pipelines/ScholarPipelineSingle.py +43 -63
  136. scitex/scholar/pipelines/_single_steps.py +71 -36
  137. scitex/scholar/storage/_LibraryManager.py +97 -1695
  138. scitex/scholar/storage/_mixins/__init__.py +30 -0
  139. scitex/scholar/storage/_mixins/_bibtex_handlers.py +128 -0
  140. scitex/scholar/storage/_mixins/_library_operations.py +218 -0
  141. scitex/scholar/storage/_mixins/_metadata_conversion.py +226 -0
  142. scitex/scholar/storage/_mixins/_paper_saving.py +456 -0
  143. scitex/scholar/storage/_mixins/_resolution.py +376 -0
  144. scitex/scholar/storage/_mixins/_storage_helpers.py +121 -0
  145. scitex/scholar/storage/_mixins/_symlink_handlers.py +226 -0
  146. scitex/scholar/url_finder/.tmp/open_url/KNOWN_RESOLVERS.py +462 -0
  147. scitex/scholar/url_finder/.tmp/open_url/README.md +223 -0
  148. scitex/scholar/url_finder/.tmp/open_url/_DOIToURLResolver.py +694 -0
  149. scitex/scholar/url_finder/.tmp/open_url/_OpenURLResolver.py +1160 -0
  150. scitex/scholar/url_finder/.tmp/open_url/_ResolverLinkFinder.py +344 -0
  151. scitex/scholar/url_finder/.tmp/open_url/__init__.py +24 -0
  152. scitex/security/README.md +3 -3
  153. scitex/session/README.md +1 -1
  154. scitex/sh/README.md +1 -1
  155. scitex/social/__init__.py +153 -0
  156. scitex/social/docs/EXTERNAL_PACKAGE_BRANDING.md +149 -0
  157. scitex/template/README.md +1 -1
  158. scitex/template/clone_writer_directory.py +5 -5
  159. scitex/writer/README.md +1 -1
  160. scitex/writer/_mcp/handlers.py +11 -744
  161. scitex/writer/_mcp/tool_schemas.py +5 -335
  162. scitex-2.15.1.dist-info/METADATA +648 -0
  163. {scitex-2.14.0.dist-info → scitex-2.15.1.dist-info}/RECORD +166 -111
  164. scitex/canvas/editor/flask_editor/templates/_scripts.py +0 -4933
  165. scitex/canvas/editor/flask_editor/templates/_styles.py +0 -1658
  166. scitex/dev/plt/data/mpl/PLOTTING_FUNCTIONS.yaml +0 -90
  167. scitex/dev/plt/data/mpl/PLOTTING_SIGNATURES.yaml +0 -1571
  168. scitex/dev/plt/data/mpl/PLOTTING_SIGNATURES_DETAILED.yaml +0 -6262
  169. scitex/dev/plt/data/mpl/SIGNATURES_FLATTENED.yaml +0 -1274
  170. scitex/dev/plt/data/mpl/dir_ax.txt +0 -459
  171. scitex/diagram/_compile.py +0 -312
  172. scitex/diagram/_diagram.py +0 -355
  173. scitex/diagram/_mcp/__init__.py +0 -4
  174. scitex/diagram/_mcp/handlers.py +0 -400
  175. scitex/diagram/_mcp/tool_schemas.py +0 -157
  176. scitex/diagram/_presets.py +0 -173
  177. scitex/diagram/_schema.py +0 -182
  178. scitex/diagram/_split.py +0 -278
  179. scitex/plt/_mcp/__init__.py +0 -4
  180. scitex/plt/_mcp/_handlers_annotation.py +0 -102
  181. scitex/plt/_mcp/_handlers_figure.py +0 -195
  182. scitex/plt/_mcp/_handlers_plot.py +0 -252
  183. scitex/plt/_mcp/_handlers_style.py +0 -219
  184. scitex/plt/_mcp/handlers.py +0 -74
  185. scitex/plt/_mcp/tool_schemas.py +0 -497
  186. scitex/plt/mcp_server.py +0 -231
  187. scitex/scholar/data/.gitkeep +0 -0
  188. scitex/scholar/data/README.md +0 -44
  189. scitex/scholar/data/bib_files/bibliography.bib +0 -1952
  190. scitex/scholar/data/bib_files/neurovista.bib +0 -277
  191. scitex/scholar/data/bib_files/neurovista_enriched.bib +0 -441
  192. scitex/scholar/data/bib_files/neurovista_enriched_enriched.bib +0 -441
  193. scitex/scholar/data/bib_files/neurovista_processed.bib +0 -338
  194. scitex/scholar/data/bib_files/openaccess.bib +0 -89
  195. scitex/scholar/data/bib_files/pac-seizure_prediction_enriched.bib +0 -2178
  196. scitex/scholar/data/bib_files/pac.bib +0 -698
  197. scitex/scholar/data/bib_files/pac_enriched.bib +0 -1061
  198. scitex/scholar/data/bib_files/pac_processed.bib +0 -0
  199. scitex/scholar/data/bib_files/pac_titles.txt +0 -75
  200. scitex/scholar/data/bib_files/paywalled.bib +0 -98
  201. scitex/scholar/data/bib_files/related-papers-by-coauthors.bib +0 -58
  202. scitex/scholar/data/bib_files/related-papers-by-coauthors_enriched.bib +0 -87
  203. scitex/scholar/data/bib_files/seizure_prediction.bib +0 -694
  204. scitex/scholar/data/bib_files/seizure_prediction_processed.bib +0 -0
  205. scitex/scholar/data/bib_files/test_complete_enriched.bib +0 -437
  206. scitex/scholar/data/bib_files/test_final_enriched.bib +0 -437
  207. scitex/scholar/data/bib_files/test_seizure.bib +0 -46
  208. scitex/scholar/data/impact_factor/JCR_IF_2022.xlsx +0 -0
  209. scitex/scholar/data/impact_factor/JCR_IF_2024.db +0 -0
  210. scitex/scholar/data/impact_factor/JCR_IF_2024.xlsx +0 -0
  211. scitex/scholar/data/impact_factor/JCR_IF_2024_v01.db +0 -0
  212. scitex/scholar/data/impact_factor.db +0 -0
  213. scitex/scholar/examples/SUGGESTIONS.md +0 -865
  214. scitex/scholar/examples/dev.py +0 -38
  215. scitex-2.14.0.dist-info/METADATA +0 -1238
  216. {scitex-2.14.0.dist-info → scitex-2.15.1.dist-info}/WHEEL +0 -0
  217. {scitex-2.14.0.dist-info → scitex-2.15.1.dist-info}/entry_points.txt +0 -0
  218. {scitex-2.14.0.dist-info → scitex-2.15.1.dist-info}/licenses/LICENSE +0 -0
scitex/__init__.py CHANGED
@@ -196,6 +196,50 @@ config = _LazyModule("config")
196
196
  audio = _LazyModule("audio")
197
197
  msword = _LazyModule("msword")
198
198
  fts = _LazyModule("fts") # Bundle schemas module
199
+ social = _LazyModule("social") # Social media integration (socialia wrapper)
200
+ diagram = _LazyModule("diagram") # Diagram creation (delegates to figrecipe)
201
+
202
+
203
+ # Lazy Diagram class - delegates to figrecipe.Diagram
204
+ class _LazyDiagram:
205
+ """Lazy loader for Diagram class from figrecipe."""
206
+
207
+ _class = None
208
+
209
+ def __new__(cls, *args, **kwargs):
210
+ if cls._class is None:
211
+ try:
212
+ from figrecipe import Diagram as _FigrecipeDiagram
213
+
214
+ cls._class = _FigrecipeDiagram
215
+ except ImportError:
216
+ # Fallback to scitex's own implementation if figrecipe not available
217
+ from scitex.diagram._diagram import Diagram as _ScitexDiagram
218
+
219
+ cls._class = _ScitexDiagram
220
+ return cls._class(*args, **kwargs)
221
+
222
+ @classmethod
223
+ def from_yaml(cls, *args, **kwargs):
224
+ if cls._class is None:
225
+ cls.__new__(cls) # Trigger lazy load
226
+ return cls._class.from_yaml(*args, **kwargs)
227
+
228
+ @classmethod
229
+ def from_mermaid(cls, *args, **kwargs):
230
+ if cls._class is None:
231
+ cls.__new__(cls) # Trigger lazy load
232
+ return cls._class.from_mermaid(*args, **kwargs)
233
+
234
+ @classmethod
235
+ def from_dict(cls, *args, **kwargs):
236
+ if cls._class is None:
237
+ cls.__new__(cls) # Trigger lazy load
238
+ return cls._class.from_dict(*args, **kwargs)
239
+
240
+
241
+ Diagram = _LazyDiagram
242
+
199
243
 
200
244
  # Centralized path configuration - eager loaded for convenience
201
245
  # Usage: scitex.PATHS.logs, scitex.PATHS.cache, etc.
@@ -261,6 +305,9 @@ __all__ = [
261
305
  "msword",
262
306
  "fts",
263
307
  "fsb", # Legacy alias
308
+ "social", # Social media integration
309
+ "diagram", # Diagram module (delegates to figrecipe)
310
+ "Diagram", # Diagram class (from figrecipe)
264
311
  "PATHS",
265
312
  "INJECTED",
266
313
  ]
scitex/_env_loader.py ADDED
@@ -0,0 +1,156 @@
1
+ #!/usr/bin/env python3
2
+ # Timestamp: 2026-01-24
3
+ # File: src/scitex/_env_loader.py
4
+
5
+ """
6
+ Environment variable loader for SCITEX_ENV_SRC.
7
+
8
+ Parses and loads bash-compatible .src files containing environment variable definitions.
9
+ Supports both directory paths (all *.src files) and single file paths.
10
+ """
11
+
12
+ from __future__ import annotations
13
+
14
+ import logging
15
+ import os
16
+ import re
17
+ from pathlib import Path
18
+ from typing import Dict, List
19
+
20
+ logger = logging.getLogger(__name__)
21
+
22
+ # Pattern to match: export VAR=value or VAR=value (with optional quotes)
23
+ _ENV_PATTERN = re.compile(r"^(?:export\s+)?([A-Za-z_][A-Za-z0-9_]*)=(.*)$")
24
+
25
+
26
+ def _parse_value(value: str) -> str:
27
+ """Parse a bash-style value, handling quotes and escapes."""
28
+ value = value.strip()
29
+
30
+ # Handle double-quoted strings
31
+ if value.startswith('"') and value.endswith('"'):
32
+ value = value[1:-1]
33
+ # Unescape common bash escapes
34
+ value = value.replace('\\"', '"')
35
+ value = value.replace("\\$", "$")
36
+ value = value.replace("\\\\", "\\")
37
+ # Handle single-quoted strings (no escaping in bash single quotes)
38
+ elif value.startswith("'") and value.endswith("'"):
39
+ value = value[1:-1]
40
+
41
+ # Expand $VAR and ${VAR} references
42
+ def expand_var(match):
43
+ var_name = match.group(1) or match.group(2)
44
+ return os.environ.get(var_name, "")
45
+
46
+ value = re.sub(r"\$\{([^}]+)\}|\$([A-Za-z_][A-Za-z0-9_]*)", expand_var, value)
47
+
48
+ return value
49
+
50
+
51
+ def parse_src_file(filepath: Path) -> Dict[str, str]:
52
+ """
53
+ Parse a bash-compatible .src file and extract environment variables.
54
+
55
+ Parameters
56
+ ----------
57
+ filepath : Path
58
+ Path to the .src file.
59
+
60
+ Returns
61
+ -------
62
+ dict
63
+ Dictionary of variable names to values.
64
+ """
65
+ env_vars = {}
66
+
67
+ try:
68
+ with open(filepath) as f:
69
+ for line_num, line in enumerate(f, 1):
70
+ line = line.strip()
71
+
72
+ # Skip empty lines and comments
73
+ if not line or line.startswith("#"):
74
+ continue
75
+
76
+ match = _ENV_PATTERN.match(line)
77
+ if match:
78
+ name, value = match.groups()
79
+ env_vars[name] = _parse_value(value)
80
+
81
+ except Exception as e:
82
+ logger.warning(f"Failed to parse {filepath}: {e}")
83
+
84
+ return env_vars
85
+
86
+
87
+ def load_env_from_path(path: str) -> Dict[str, str]:
88
+ """
89
+ Load environment variables from a file or directory.
90
+
91
+ Parameters
92
+ ----------
93
+ path : str
94
+ Path to a .src file or directory containing .src files.
95
+
96
+ Returns
97
+ -------
98
+ dict
99
+ All loaded environment variables.
100
+ """
101
+ loaded = {}
102
+ path_obj = Path(path).expanduser()
103
+
104
+ if not path_obj.exists():
105
+ logger.warning(f"SCITEX_ENV_SRC path does not exist: {path}")
106
+ return loaded
107
+
108
+ files_to_load: List[Path] = []
109
+
110
+ if path_obj.is_dir():
111
+ # Load all .src files in directory
112
+ files_to_load = sorted(path_obj.glob("*.src"))
113
+ elif path_obj.is_file():
114
+ files_to_load = [path_obj]
115
+ else:
116
+ logger.warning(f"SCITEX_ENV_SRC is not a file or directory: {path}")
117
+ return loaded
118
+
119
+ for src_file in files_to_load:
120
+ env_vars = parse_src_file(src_file)
121
+ if env_vars:
122
+ logger.info(f"Loaded {len(env_vars)} vars from {src_file.name}")
123
+ loaded.update(env_vars)
124
+
125
+ return loaded
126
+
127
+
128
+ def load_scitex_env() -> int:
129
+ """
130
+ Load environment variables from SCITEX_ENV_SRC if set.
131
+
132
+ This function should be called early in the MCP server startup.
133
+
134
+ Returns
135
+ -------
136
+ int
137
+ Number of environment variables loaded.
138
+ """
139
+ env_src = os.environ.get("SCITEX_ENV_SRC")
140
+
141
+ if not env_src:
142
+ return 0
143
+
144
+ loaded = load_env_from_path(env_src)
145
+
146
+ # Apply to current process environment
147
+ for name, value in loaded.items():
148
+ os.environ[name] = value
149
+
150
+ if loaded:
151
+ logger.info(f"SCITEX_ENV_SRC: Loaded {len(loaded)} environment variables")
152
+
153
+ return len(loaded)
154
+
155
+
156
+ # EOF
@@ -0,0 +1,37 @@
1
+ #!/usr/bin/env python3
2
+ # Timestamp: 2026-01-20
3
+ # File: /home/ywatanabe/proj/scitex-code/src/scitex/_mcp_resources/__init__.py
4
+ """MCP Resources for SciTeX - Dynamic documentation for AI agents.
5
+
6
+ This module provides MCP resources that expose SciTeX documentation,
7
+ patterns, and examples to AI agents for code generation guidance.
8
+
9
+ Resources:
10
+ - scitex://cheatsheet - Quick reference for all core patterns
11
+ - scitex://session-tree - Output directory structure explanation
12
+ - scitex://module/{name} - Module-specific documentation (io, plt, stats, scholar, session)
13
+ - scitex://io-formats - Supported file formats
14
+ - scitex://figrecipe-spec - Figure recipe specification
15
+ """
16
+
17
+ from __future__ import annotations
18
+
19
+ from ._cheatsheet import register_cheatsheet_resources
20
+ from ._figrecipe import register_figrecipe_resources
21
+ from ._formats import register_format_resources
22
+ from ._modules import register_module_resources
23
+ from ._session import register_session_resources
24
+
25
+ __all__ = ["register_resources"]
26
+
27
+
28
+ def register_resources(mcp) -> None:
29
+ """Register all MCP resources with the FastMCP server."""
30
+ register_cheatsheet_resources(mcp)
31
+ register_session_resources(mcp)
32
+ register_module_resources(mcp)
33
+ register_format_resources(mcp)
34
+ register_figrecipe_resources(mcp)
35
+
36
+
37
+ # EOF
@@ -0,0 +1,135 @@
1
+ #!/usr/bin/env python3
2
+ # Timestamp: 2026-01-20
3
+ # File: /home/ywatanabe/proj/scitex-code/src/scitex/_mcp_resources/_cheatsheet.py
4
+ """Core SciTeX cheatsheet resource for AI agents."""
5
+
6
+ from __future__ import annotations
7
+
8
+ __all__ = ["register_cheatsheet_resources"]
9
+
10
+ CHEATSHEET = """\
11
+ # SciTeX Cheatsheet for AI Agents
12
+ =================================
13
+
14
+ ## Import Pattern (ALWAYS use this)
15
+ ```python
16
+ import scitex as stx
17
+ import numpy as np
18
+ ```
19
+
20
+ ## 1. @stx.session - Reproducible Experiment Tracking
21
+
22
+ The MOST IMPORTANT pattern. Wrap your main function with @stx.session:
23
+
24
+ ```python
25
+ @stx.session
26
+ def main(
27
+ # User parameters (become CLI arguments automatically)
28
+ input_file="data.csv", # --input-file (default: data.csv)
29
+ n_samples=100, # --n-samples (default: 100)
30
+
31
+ # INJECTED parameters (auto-provided by session)
32
+ CONFIG=stx.INJECTED, # Session config with ID, paths
33
+ plt=stx.INJECTED, # Pre-configured matplotlib
34
+ COLORS=stx.INJECTED, # Color palette
35
+ rng=stx.INJECTED, # Seeded random generator
36
+ logger=stx.INJECTED, # Session logger
37
+ ):
38
+ \"\"\"This docstring becomes --help description.\"\"\"
39
+
40
+ # Your analysis code here
41
+ data = stx.io.load(input_file)
42
+ results = process(data, n_samples)
43
+
44
+ # Save outputs (automatically to session directory)
45
+ stx.io.save(results, "results.csv")
46
+ stx.io.save(fig, "plot.png", symlink_to="./data")
47
+
48
+ return 0 # Exit status
49
+
50
+ if __name__ == "__main__":
51
+ main() # CLI mode when no args passed
52
+ ```
53
+
54
+ ## 2. stx.io - Universal File I/O (30+ formats)
55
+
56
+ ALWAYS use stx.io.save() and stx.io.load() for file operations:
57
+
58
+ ```python
59
+ # Saving - extension determines format automatically
60
+ stx.io.save(df, "data.csv") # DataFrame -> CSV
61
+ stx.io.save(arr, "data.npy") # NumPy array
62
+ stx.io.save(obj, "data.pkl") # Any Python object
63
+ stx.io.save(fig, "plot.png") # Figure + auto CSV
64
+
65
+ # Loading - format auto-detected
66
+ data = stx.io.load("data.csv")
67
+
68
+ # With options
69
+ stx.io.save(fig, "plot.png",
70
+ metadata={"exp": "exp01"}, # Embedded metadata
71
+ symlink_to="./data", # Create symlink
72
+ verbose=True, # Log messages
73
+ )
74
+ ```
75
+
76
+ IMPORTANT: stx.io.save shows logging messages:
77
+ ```
78
+ SUCC: Saved to: ./script_out/results.csv (4.0 KiB)
79
+ SUCC: Symlinked: ./script_out/results.csv -> ./data/results.csv
80
+ ```
81
+
82
+ ## 3. stx.plt - Publication-Ready Figures (Auto CSV Export)
83
+
84
+ ```python
85
+ fig, ax = stx.plt.subplots()
86
+
87
+ # Use stx_ prefixed methods for auto CSV export
88
+ ax.stx_line(x, y, label="Signal") # Tracked: exports to CSV
89
+ ax.stx_scatter(x, y) # Tracked
90
+
91
+ # Set labels with convenience method
92
+ ax.set_xyt("X axis", "Y axis", "Title")
93
+
94
+ # Save figure -> creates BOTH plot.png AND plot.csv
95
+ stx.io.save(fig, "plot.png")
96
+ fig.close()
97
+ ```
98
+
99
+ ## 4. stx.stats - Publication Statistics (23 tests)
100
+
101
+ ```python
102
+ result = stx.stats.test_ttest_ind(group1, group2, return_as="dataframe")
103
+ # Returns: p-value, Cohen's d, 95% CI, normality check, power analysis
104
+
105
+ result = stx.stats.test_anova(*groups, return_as="latex")
106
+ ```
107
+
108
+ ## 5. stx.scholar - Literature Management
109
+
110
+ ```bash
111
+ scitex scholar bibtex papers.bib --project myresearch --num-workers 8
112
+ # Enriches BibTeX with abstracts, DOIs, impact factors, downloads PDFs
113
+ ```
114
+
115
+ ## Quick Tips
116
+
117
+ 1. ALWAYS use `import scitex as stx`
118
+ 2. ALWAYS wrap main functions with `@stx.session`
119
+ 3. ALWAYS use `stx.io.save()` and `stx.io.load()` for files
120
+ 4. ALWAYS use `stx.plt.subplots()` for figures
121
+ 5. ALWAYS use `ax.stx_*` methods for auto CSV export
122
+ 6. ALWAYS return exit status (0 for success) from main
123
+ """
124
+
125
+
126
+ def register_cheatsheet_resources(mcp) -> None:
127
+ """Register cheatsheet resource."""
128
+
129
+ @mcp.resource("scitex://cheatsheet")
130
+ def cheatsheet() -> str:
131
+ """Complete SciTeX quick reference for AI code generation."""
132
+ return CHEATSHEET
133
+
134
+
135
+ # EOF
@@ -0,0 +1,138 @@
1
+ #!/usr/bin/env python3
2
+ # Timestamp: 2026-01-20
3
+ # File: /home/ywatanabe/proj/scitex-code/src/scitex/_mcp_resources/_figrecipe.py
4
+ """Figrecipe integration documentation for stx.plt MCP tools."""
5
+
6
+ from __future__ import annotations
7
+
8
+ __all__ = ["register_figrecipe_resources"]
9
+
10
+ FIGRECIPE_INTEGRATION = """\
11
+ # stx.plt - Powered by FigRecipe
12
+ =================================
13
+
14
+ stx.plt provides publication-ready figures with **automatic reproducibility**.
15
+ It's built on FigRecipe, which records all matplotlib calls to YAML recipes.
16
+
17
+ ## Using stx.plt in @stx.session
18
+ ```python
19
+ @stx.session
20
+ def main(plt=stx.INJECTED, COLORS=stx.INJECTED):
21
+ fig, ax = stx.plt.subplots()
22
+
23
+ # Use stx_ prefixed methods for auto CSV export
24
+ ax.stx_line(x, y, color=COLORS.blue, label="data")
25
+ ax.set_xyt("X", "Y", "Title")
26
+
27
+ # Save creates: plot.png + plot.csv (data)
28
+ stx.io.save(fig, "plot.png", symlink_to="./data")
29
+ fig.close()
30
+ return 0
31
+ ```
32
+
33
+ ## Output Files from stx.io.save(fig, ...)
34
+ ```
35
+ script_out/
36
+ ├── plot.png # Image file
37
+ ├── plot.csv # Extracted plot data (auto-generated)
38
+ └── plot.yaml # FigRecipe recipe (if using fr.save directly)
39
+ ```
40
+
41
+ ## Tracked Methods (stx_ prefix)
42
+ These methods track data for automatic CSV export:
43
+ - ax.stx_line(x, y)
44
+ - ax.stx_scatter(x, y)
45
+ - ax.stx_bar(x, height)
46
+ - ax.stx_errorbar(x, y, yerr)
47
+ - ax.stx_hist(data, bins)
48
+ - ax.stx_boxplot(data)
49
+ - ax.stx_violinplot(data)
50
+ - ax.stx_imshow(matrix)
51
+
52
+ ## MCP Declarative Spec (via plt_plot tool)
53
+
54
+ ### RECOMMENDED: CSV Column Input
55
+ Use CSV files - enables code to write data, MCP to visualize:
56
+ ```yaml
57
+ plots:
58
+ - type: scatter
59
+ data_file: results.csv # CSV from your analysis
60
+ x: time # Column name (string)
61
+ y: measurement # Column name
62
+ color: blue
63
+ ```
64
+
65
+ **Workflow**: Python writes CSV → MCP reads columns → Creates figure
66
+
67
+ ### Alternative: Inline Data (simple cases only)
68
+ ```yaml
69
+ plots:
70
+ - type: line
71
+ x: [1, 2, 3, 4, 5] # Inline array (less flexible)
72
+ y: [1, 4, 9, 16, 25]
73
+ color: blue
74
+ ```
75
+
76
+ ### Full Example
77
+ ```yaml
78
+ figure:
79
+ width_mm: 85 # Nature single-column width
80
+ height_mm: 60
81
+ plots:
82
+ - type: scatter
83
+ data_file: experiment.csv
84
+ x: time_hours
85
+ y: concentration_mm
86
+ color: blue
87
+ label: "Data"
88
+ xlabel: "Time (h)"
89
+ ylabel: "Concentration (mM)"
90
+ title: "Enzyme Kinetics"
91
+ legend: true
92
+ stat_annotations:
93
+ - x1: 1
94
+ x2: 3
95
+ p_value: 0.01
96
+ style: stars
97
+ ```
98
+
99
+ ## Statistical Annotations
100
+ ```python
101
+ # Method 1: Via stx.plt (Python API)
102
+ ax.add_stat_annotation(x1=0, x2=1, p_value=0.01, style="stars")
103
+
104
+ # Method 2: Via MCP spec (declarative)
105
+ stat_annotations:
106
+ - x1: 0
107
+ x2: 1
108
+ p_value: 0.01 # Converts to ** automatically
109
+ ```
110
+
111
+ ## Color Palette (COLORS=stx.INJECTED)
112
+ ```python
113
+ COLORS.blue, COLORS.red, COLORS.green, COLORS.orange
114
+ COLORS.purple, COLORS.navy, COLORS.pink, COLORS.brown
115
+ ```
116
+
117
+ ## For Detailed FigRecipe Documentation
118
+ See figrecipe MCP resources directly:
119
+ - figrecipe://cheatsheet - Quick reference
120
+ - figrecipe://api/core - Full API documentation
121
+ - figrecipe://mcp-spec - Declarative spec format
122
+
123
+ ## Supported Plot Types
124
+ line, scatter, bar, barh, hist, boxplot, violinplot, imshow, heatmap,
125
+ errorbar, fill_between, contour, contourf, pie, stem
126
+ """
127
+
128
+
129
+ def register_figrecipe_resources(mcp) -> None:
130
+ """Register figrecipe integration resource."""
131
+
132
+ @mcp.resource("scitex://plt-figrecipe")
133
+ def figrecipe_integration() -> str:
134
+ """stx.plt integration with FigRecipe for reproducible figures."""
135
+ return FIGRECIPE_INTEGRATION
136
+
137
+
138
+ # EOF
@@ -0,0 +1,102 @@
1
+ #!/usr/bin/env python3
2
+ # Timestamp: 2026-01-20
3
+ # File: /home/ywatanabe/proj/scitex-code/src/scitex/_mcp_resources/_formats.py
4
+ """IO format documentation resource."""
5
+
6
+ from __future__ import annotations
7
+
8
+ __all__ = ["register_format_resources"]
9
+
10
+ IO_FORMATS = """\
11
+ # stx.io Supported Formats
12
+ ===========================
13
+
14
+ ## Data Formats
15
+
16
+ | Extension | Type | Save | Load | Notes |
17
+ |-----------|------|:----:|:----:|-------|
18
+ | .csv | DataFrame/Array | ✓ | ✓ | Comma-separated |
19
+ | .tsv | DataFrame/Array | ✓ | ✓ | Tab-separated |
20
+ | .xlsx | DataFrame | ✓ | ✓ | Excel workbook |
21
+ | .json | Dict/List | ✓ | ✓ | JSON format |
22
+ | .yaml/.yml | Dict/List | ✓ | ✓ | YAML format |
23
+ | .pkl/.pickle | Any | ✓ | ✓ | Python pickle |
24
+ | .npy | Array | ✓ | ✓ | NumPy array |
25
+ | .npz | Dict[Array] | ✓ | ✓ | Compressed NumPy |
26
+ | .h5/.hdf5 | Array/Dict | ✓ | ✓ | HDF5 format |
27
+ | .zarr | Array | ✓ | ✓ | Zarr array |
28
+ | .parquet | DataFrame | ✓ | ✓ | Apache Parquet |
29
+ | .feather | DataFrame | ✓ | ✓ | Feather format |
30
+
31
+ ## Image Formats
32
+
33
+ | Extension | Type | Save | Load | Notes |
34
+ |-----------|------|:----:|:----:|-------|
35
+ | .png | Figure/Array | ✓ | ✓ | Lossless, metadata |
36
+ | .jpg/.jpeg | Figure/Array | ✓ | ✓ | Lossy, metadata |
37
+ | .tiff/.tif | Figure/Array | ✓ | ✓ | Scientific imaging |
38
+ | .pdf | Figure | ✓ | ✓ | Vector format |
39
+ | .svg | Figure | ✓ | - | Vector format |
40
+
41
+ ## Scientific Formats
42
+
43
+ | Extension | Type | Load | Notes |
44
+ |-----------|------|:----:|-------|
45
+ | .edf | EEG | ✓ | European Data Format |
46
+ | .fif | MNE | ✓ | MNE-Python |
47
+ | .set | EEGLAB | ✓ | EEGLAB format |
48
+ | .mat | MATLAB | ✓ | MATLAB files |
49
+
50
+ ## PyTorch Formats
51
+
52
+ | Extension | Type | Save | Load |
53
+ |-----------|------|:----:|:----:|
54
+ | .pt | Tensor/Model | ✓ | ✓ |
55
+ | .pth | Model | ✓ | ✓ |
56
+
57
+ ## Usage Notes
58
+
59
+ 1. **Extension determines handler**: `stx.io.save(df, "data.csv")` uses CSV
60
+ 2. **Metadata embedding**: PNG/JPEG support embedded metadata
61
+ 3. **Figure auto-CSV**: Saving figures also exports plotted data as CSV
62
+ 4. **Symlink support**: `symlink_to="./data"` creates symlinks
63
+
64
+ ## Examples
65
+
66
+ ```python
67
+ import scitex as stx
68
+ import pandas as pd
69
+ import numpy as np
70
+
71
+ # DataFrame
72
+ df = pd.DataFrame({"x": [1, 2], "y": [3, 4]})
73
+ stx.io.save(df, "data.csv")
74
+ stx.io.save(df, "data.parquet")
75
+
76
+ # NumPy
77
+ arr = np.random.randn(100, 100)
78
+ stx.io.save(arr, "array.npy")
79
+ stx.io.save(arr, "array.npz")
80
+
81
+ # Any Python object
82
+ stx.io.save({"config": "value"}, "config.yaml")
83
+ stx.io.save(complex_obj, "obj.pkl")
84
+
85
+ # Figure with auto-CSV
86
+ fig, ax = stx.plt.subplots()
87
+ ax.stx_line([1, 2, 3], [4, 5, 6])
88
+ stx.io.save(fig, "plot.png") # Creates plot.png + plot.csv
89
+ ```
90
+ """
91
+
92
+
93
+ def register_format_resources(mcp) -> None:
94
+ """Register IO formats resource."""
95
+
96
+ @mcp.resource("scitex://io-formats")
97
+ def io_formats() -> str:
98
+ """List all supported file formats for stx.io."""
99
+ return IO_FORMATS
100
+
101
+
102
+ # EOF