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.
- scitex/__init__.py +71 -17
- scitex/_env_loader.py +156 -0
- scitex/_mcp_resources/__init__.py +37 -0
- scitex/_mcp_resources/_cheatsheet.py +135 -0
- scitex/_mcp_resources/_figrecipe.py +138 -0
- scitex/_mcp_resources/_formats.py +102 -0
- scitex/_mcp_resources/_modules.py +337 -0
- scitex/_mcp_resources/_session.py +149 -0
- scitex/_mcp_tools/__init__.py +4 -0
- scitex/_mcp_tools/audio.py +66 -0
- scitex/_mcp_tools/diagram.py +11 -95
- scitex/_mcp_tools/introspect.py +210 -0
- scitex/_mcp_tools/plt.py +260 -305
- scitex/_mcp_tools/scholar.py +74 -0
- scitex/_mcp_tools/social.py +27 -0
- scitex/_mcp_tools/template.py +24 -0
- scitex/_mcp_tools/writer.py +17 -210
- scitex/ai/_gen_ai/_PARAMS.py +10 -7
- scitex/ai/classification/reporters/_SingleClassificationReporter.py +45 -1603
- scitex/ai/classification/reporters/_mixins/__init__.py +36 -0
- scitex/ai/classification/reporters/_mixins/_constants.py +67 -0
- scitex/ai/classification/reporters/_mixins/_cv_summary.py +387 -0
- scitex/ai/classification/reporters/_mixins/_feature_importance.py +119 -0
- scitex/ai/classification/reporters/_mixins/_metrics.py +275 -0
- scitex/ai/classification/reporters/_mixins/_plotting.py +179 -0
- scitex/ai/classification/reporters/_mixins/_reports.py +153 -0
- scitex/ai/classification/reporters/_mixins/_storage.py +160 -0
- scitex/ai/classification/timeseries/_TimeSeriesSlidingWindowSplit.py +30 -1550
- scitex/ai/classification/timeseries/_sliding_window_core.py +467 -0
- scitex/ai/classification/timeseries/_sliding_window_plotting.py +369 -0
- scitex/audio/README.md +40 -36
- scitex/audio/__init__.py +129 -61
- scitex/audio/_branding.py +185 -0
- scitex/audio/_mcp/__init__.py +32 -0
- scitex/audio/_mcp/handlers.py +59 -6
- scitex/audio/_mcp/speak_handlers.py +238 -0
- scitex/audio/_relay.py +225 -0
- scitex/audio/_tts.py +18 -10
- scitex/audio/engines/base.py +17 -10
- scitex/audio/engines/elevenlabs_engine.py +7 -2
- scitex/audio/mcp_server.py +228 -75
- scitex/canvas/README.md +1 -1
- scitex/canvas/editor/_dearpygui/__init__.py +25 -0
- scitex/canvas/editor/_dearpygui/_editor.py +147 -0
- scitex/canvas/editor/_dearpygui/_handlers.py +476 -0
- scitex/canvas/editor/_dearpygui/_panels/__init__.py +17 -0
- scitex/canvas/editor/_dearpygui/_panels/_control.py +119 -0
- scitex/canvas/editor/_dearpygui/_panels/_element_controls.py +190 -0
- scitex/canvas/editor/_dearpygui/_panels/_preview.py +43 -0
- scitex/canvas/editor/_dearpygui/_panels/_sections.py +390 -0
- scitex/canvas/editor/_dearpygui/_plotting.py +187 -0
- scitex/canvas/editor/_dearpygui/_rendering.py +504 -0
- scitex/canvas/editor/_dearpygui/_selection.py +295 -0
- scitex/canvas/editor/_dearpygui/_state.py +93 -0
- scitex/canvas/editor/_dearpygui/_utils.py +61 -0
- scitex/canvas/editor/flask_editor/_core/__init__.py +27 -0
- scitex/canvas/editor/flask_editor/_core/_bbox_extraction.py +200 -0
- scitex/canvas/editor/flask_editor/_core/_editor.py +173 -0
- scitex/canvas/editor/flask_editor/_core/_export_helpers.py +353 -0
- scitex/canvas/editor/flask_editor/_core/_routes_basic.py +190 -0
- scitex/canvas/editor/flask_editor/_core/_routes_export.py +332 -0
- scitex/canvas/editor/flask_editor/_core/_routes_panels.py +252 -0
- scitex/canvas/editor/flask_editor/_core/_routes_save.py +218 -0
- scitex/canvas/editor/flask_editor/_core.py +25 -1684
- scitex/canvas/editor/flask_editor/templates/__init__.py +32 -70
- scitex/cli/__init__.py +38 -43
- scitex/cli/audio.py +160 -41
- scitex/cli/capture.py +133 -20
- scitex/cli/introspect.py +488 -0
- scitex/cli/main.py +200 -109
- scitex/cli/mcp.py +60 -34
- scitex/cli/plt.py +414 -0
- scitex/cli/repro.py +15 -8
- scitex/cli/resource.py +15 -8
- scitex/cli/scholar/__init__.py +154 -8
- scitex/cli/scholar/_crossref_scitex.py +296 -0
- scitex/cli/scholar/_fetch.py +25 -3
- scitex/cli/social.py +355 -0
- scitex/cli/stats.py +136 -11
- scitex/cli/template.py +129 -12
- scitex/cli/tex.py +15 -8
- scitex/cli/writer.py +49 -299
- scitex/cloud/__init__.py +41 -2
- scitex/config/README.md +1 -1
- scitex/config/__init__.py +16 -2
- scitex/config/_env_registry.py +256 -0
- scitex/context/__init__.py +22 -0
- scitex/dev/__init__.py +20 -1
- scitex/diagram/__init__.py +42 -19
- scitex/diagram/mcp_server.py +13 -125
- scitex/gen/__init__.py +50 -14
- scitex/gen/_list_packages.py +4 -4
- scitex/introspect/__init__.py +82 -0
- scitex/introspect/_call_graph.py +303 -0
- scitex/introspect/_class_hierarchy.py +163 -0
- scitex/introspect/_core.py +41 -0
- scitex/introspect/_docstring.py +131 -0
- scitex/introspect/_examples.py +113 -0
- scitex/introspect/_imports.py +271 -0
- scitex/{gen/_inspect_module.py → introspect/_list_api.py} +48 -56
- scitex/introspect/_mcp/__init__.py +41 -0
- scitex/introspect/_mcp/handlers.py +233 -0
- scitex/introspect/_members.py +155 -0
- scitex/introspect/_resolve.py +89 -0
- scitex/introspect/_signature.py +131 -0
- scitex/introspect/_source.py +80 -0
- scitex/introspect/_type_hints.py +172 -0
- scitex/io/_save.py +1 -2
- scitex/io/bundle/README.md +1 -1
- scitex/logging/_formatters.py +19 -9
- scitex/mcp_server.py +98 -5
- scitex/os/__init__.py +4 -0
- scitex/{gen → os}/_check_host.py +4 -5
- scitex/plt/__init__.py +245 -550
- scitex/plt/_subplots/_AxisWrapperMixins/_SeabornMixin/_wrappers.py +5 -10
- scitex/plt/docs/EXTERNAL_PACKAGE_BRANDING.md +149 -0
- scitex/plt/gallery/README.md +1 -1
- scitex/plt/utils/_hitmap/__init__.py +82 -0
- scitex/plt/utils/_hitmap/_artist_extraction.py +343 -0
- scitex/plt/utils/_hitmap/_color_application.py +346 -0
- scitex/plt/utils/_hitmap/_color_conversion.py +121 -0
- scitex/plt/utils/_hitmap/_constants.py +40 -0
- scitex/plt/utils/_hitmap/_hitmap_core.py +334 -0
- scitex/plt/utils/_hitmap/_path_extraction.py +357 -0
- scitex/plt/utils/_hitmap/_query.py +113 -0
- scitex/plt/utils/_hitmap.py +46 -1616
- scitex/plt/utils/_metadata/__init__.py +80 -0
- scitex/plt/utils/_metadata/_artists/__init__.py +25 -0
- scitex/plt/utils/_metadata/_artists/_base.py +195 -0
- scitex/plt/utils/_metadata/_artists/_collections.py +356 -0
- scitex/plt/utils/_metadata/_artists/_extract.py +57 -0
- scitex/plt/utils/_metadata/_artists/_images.py +80 -0
- scitex/plt/utils/_metadata/_artists/_lines.py +261 -0
- scitex/plt/utils/_metadata/_artists/_patches.py +247 -0
- scitex/plt/utils/_metadata/_artists/_text.py +106 -0
- scitex/plt/utils/_metadata/_csv.py +416 -0
- scitex/plt/utils/_metadata/_detect.py +225 -0
- scitex/plt/utils/_metadata/_legend.py +127 -0
- scitex/plt/utils/_metadata/_rounding.py +117 -0
- scitex/plt/utils/_metadata/_verification.py +202 -0
- scitex/schema/README.md +1 -1
- scitex/scholar/__init__.py +8 -0
- scitex/scholar/_mcp/crossref_handlers.py +265 -0
- scitex/scholar/core/Scholar.py +63 -1700
- scitex/scholar/core/_mixins/__init__.py +36 -0
- scitex/scholar/core/_mixins/_enrichers.py +270 -0
- scitex/scholar/core/_mixins/_library_handlers.py +100 -0
- scitex/scholar/core/_mixins/_loaders.py +103 -0
- scitex/scholar/core/_mixins/_pdf_download.py +375 -0
- scitex/scholar/core/_mixins/_pipeline.py +312 -0
- scitex/scholar/core/_mixins/_project_handlers.py +125 -0
- scitex/scholar/core/_mixins/_savers.py +69 -0
- scitex/scholar/core/_mixins/_search.py +103 -0
- scitex/scholar/core/_mixins/_services.py +88 -0
- scitex/scholar/core/_mixins/_url_finding.py +105 -0
- scitex/scholar/crossref_scitex.py +367 -0
- scitex/scholar/docs/EXTERNAL_PACKAGE_BRANDING.md +149 -0
- scitex/scholar/examples/00_run_all.sh +120 -0
- scitex/scholar/jobs/_executors.py +27 -3
- scitex/scholar/pdf_download/ScholarPDFDownloader.py +38 -416
- scitex/scholar/pdf_download/_cli.py +154 -0
- scitex/scholar/pdf_download/strategies/__init__.py +11 -8
- scitex/scholar/pdf_download/strategies/manual_download_fallback.py +80 -3
- scitex/scholar/pipelines/ScholarPipelineBibTeX.py +73 -121
- scitex/scholar/pipelines/ScholarPipelineParallel.py +80 -138
- scitex/scholar/pipelines/ScholarPipelineSingle.py +43 -63
- scitex/scholar/pipelines/_single_steps.py +71 -36
- scitex/scholar/storage/_LibraryManager.py +97 -1695
- scitex/scholar/storage/_mixins/__init__.py +30 -0
- scitex/scholar/storage/_mixins/_bibtex_handlers.py +128 -0
- scitex/scholar/storage/_mixins/_library_operations.py +218 -0
- scitex/scholar/storage/_mixins/_metadata_conversion.py +226 -0
- scitex/scholar/storage/_mixins/_paper_saving.py +456 -0
- scitex/scholar/storage/_mixins/_resolution.py +376 -0
- scitex/scholar/storage/_mixins/_storage_helpers.py +121 -0
- scitex/scholar/storage/_mixins/_symlink_handlers.py +226 -0
- scitex/security/README.md +3 -3
- scitex/session/README.md +1 -1
- scitex/session/__init__.py +26 -7
- scitex/session/_decorator.py +1 -1
- scitex/sh/README.md +1 -1
- scitex/sh/__init__.py +7 -4
- scitex/social/__init__.py +155 -0
- scitex/social/docs/EXTERNAL_PACKAGE_BRANDING.md +149 -0
- scitex/stats/_mcp/_handlers/__init__.py +31 -0
- scitex/stats/_mcp/_handlers/_corrections.py +113 -0
- scitex/stats/_mcp/_handlers/_descriptive.py +78 -0
- scitex/stats/_mcp/_handlers/_effect_size.py +106 -0
- scitex/stats/_mcp/_handlers/_format.py +94 -0
- scitex/stats/_mcp/_handlers/_normality.py +110 -0
- scitex/stats/_mcp/_handlers/_posthoc.py +224 -0
- scitex/stats/_mcp/_handlers/_power.py +247 -0
- scitex/stats/_mcp/_handlers/_recommend.py +102 -0
- scitex/stats/_mcp/_handlers/_run_test.py +279 -0
- scitex/stats/_mcp/_handlers/_stars.py +48 -0
- scitex/stats/_mcp/handlers.py +19 -1171
- scitex/stats/auto/_stat_style.py +175 -0
- scitex/stats/auto/_style_definitions.py +411 -0
- scitex/stats/auto/_styles.py +22 -620
- scitex/stats/descriptive/__init__.py +11 -8
- scitex/stats/descriptive/_ci.py +39 -0
- scitex/stats/power/_power.py +15 -4
- scitex/str/__init__.py +2 -1
- scitex/str/_title_case.py +63 -0
- scitex/template/README.md +1 -1
- scitex/template/__init__.py +25 -10
- scitex/template/_code_templates.py +147 -0
- scitex/template/_mcp/handlers.py +81 -0
- scitex/template/_mcp/tool_schemas.py +55 -0
- scitex/template/_templates/__init__.py +51 -0
- scitex/template/_templates/audio.py +233 -0
- scitex/template/_templates/canvas.py +312 -0
- scitex/template/_templates/capture.py +268 -0
- scitex/template/_templates/config.py +43 -0
- scitex/template/_templates/diagram.py +294 -0
- scitex/template/_templates/io.py +107 -0
- scitex/template/_templates/module.py +53 -0
- scitex/template/_templates/plt.py +202 -0
- scitex/template/_templates/scholar.py +267 -0
- scitex/template/_templates/session.py +130 -0
- scitex/template/_templates/session_minimal.py +43 -0
- scitex/template/_templates/session_plot.py +67 -0
- scitex/template/_templates/session_stats.py +77 -0
- scitex/template/_templates/stats.py +323 -0
- scitex/template/_templates/writer.py +296 -0
- scitex/template/clone_writer_directory.py +5 -5
- scitex/ui/_backends/_email.py +10 -2
- scitex/ui/_backends/_webhook.py +5 -1
- scitex/web/_search_pubmed.py +10 -6
- scitex/writer/README.md +1 -1
- scitex/writer/__init__.py +43 -34
- scitex/writer/_mcp/handlers.py +11 -744
- scitex/writer/_mcp/tool_schemas.py +5 -335
- scitex-2.15.3.dist-info/METADATA +667 -0
- {scitex-2.14.0.dist-info → scitex-2.15.3.dist-info}/RECORD +241 -120
- scitex/canvas/editor/flask_editor/templates/_scripts.py +0 -4933
- scitex/canvas/editor/flask_editor/templates/_styles.py +0 -1658
- scitex/diagram/_compile.py +0 -312
- scitex/diagram/_diagram.py +0 -355
- scitex/diagram/_mcp/__init__.py +0 -4
- scitex/diagram/_mcp/handlers.py +0 -400
- scitex/diagram/_mcp/tool_schemas.py +0 -157
- scitex/diagram/_presets.py +0 -173
- scitex/diagram/_schema.py +0 -182
- scitex/diagram/_split.py +0 -278
- scitex/gen/_ci.py +0 -12
- scitex/gen/_title_case.py +0 -89
- scitex/plt/_mcp/__init__.py +0 -4
- scitex/plt/_mcp/_handlers_annotation.py +0 -102
- scitex/plt/_mcp/_handlers_figure.py +0 -195
- scitex/plt/_mcp/_handlers_plot.py +0 -252
- scitex/plt/_mcp/_handlers_style.py +0 -219
- scitex/plt/_mcp/handlers.py +0 -74
- scitex/plt/_mcp/tool_schemas.py +0 -497
- scitex/plt/mcp_server.py +0 -231
- scitex/scholar/examples/SUGGESTIONS.md +0 -865
- scitex/scholar/examples/dev.py +0 -38
- scitex-2.14.0.dist-info/METADATA +0 -1238
- /scitex/{gen → context}/_detect_environment.py +0 -0
- /scitex/{gen → context}/_get_notebook_path.py +0 -0
- /scitex/{gen/_shell.py → sh/_shell_legacy.py} +0 -0
- {scitex-2.14.0.dist-info → scitex-2.15.3.dist-info}/WHEEL +0 -0
- {scitex-2.14.0.dist-info → scitex-2.15.3.dist-info}/entry_points.txt +0 -0
- {scitex-2.14.0.dist-info → scitex-2.15.3.dist-info}/licenses/LICENSE +0 -0
scitex/cli/main.py
CHANGED
|
@@ -15,11 +15,14 @@ from . import (
|
|
|
15
15
|
cloud,
|
|
16
16
|
config,
|
|
17
17
|
convert,
|
|
18
|
+
introspect,
|
|
18
19
|
mcp,
|
|
20
|
+
plt,
|
|
19
21
|
repro,
|
|
20
22
|
resource,
|
|
21
23
|
scholar,
|
|
22
24
|
security,
|
|
25
|
+
social,
|
|
23
26
|
stats,
|
|
24
27
|
template,
|
|
25
28
|
tex,
|
|
@@ -28,36 +31,36 @@ from . import (
|
|
|
28
31
|
)
|
|
29
32
|
|
|
30
33
|
|
|
31
|
-
@click.group(
|
|
34
|
+
@click.group(
|
|
35
|
+
context_settings={"help_option_names": ["-h", "--help"]},
|
|
36
|
+
invoke_without_command=True,
|
|
37
|
+
)
|
|
32
38
|
@click.version_option()
|
|
33
|
-
|
|
39
|
+
@click.option("--help-recursive", is_flag=True, help="Show help for all commands")
|
|
40
|
+
@click.pass_context
|
|
41
|
+
def cli(ctx, help_recursive):
|
|
34
42
|
"""
|
|
35
43
|
SciTeX - Integrated Scientific Research Platform
|
|
36
44
|
|
|
37
45
|
\b
|
|
38
46
|
Examples:
|
|
39
|
-
scitex config list # Show
|
|
40
|
-
scitex
|
|
41
|
-
scitex
|
|
42
|
-
scitex
|
|
43
|
-
scitex
|
|
44
|
-
scitex
|
|
45
|
-
scitex security check --save
|
|
46
|
-
scitex web get-urls https://example.com
|
|
47
|
-
scitex web download-images https://example.com --output ./downloads
|
|
48
|
-
scitex audio speak "Hello world"
|
|
49
|
-
scitex capture snap --output screenshot.jpg
|
|
50
|
-
scitex resource usage
|
|
51
|
-
scitex stats recommend --data data.csv
|
|
52
|
-
scitex mcp list # List all MCP tools
|
|
53
|
-
scitex mcp serve # Start MCP server
|
|
47
|
+
scitex config list # Show configured paths
|
|
48
|
+
scitex cloud clone user/project # Clone from cloud
|
|
49
|
+
scitex scholar bibtex papers.bib # Manage papers
|
|
50
|
+
scitex audio speak "Hello" # Text-to-speech
|
|
51
|
+
scitex mcp list-tools # List MCP tools
|
|
52
|
+
scitex mcp start # Start MCP server
|
|
54
53
|
|
|
55
54
|
\b
|
|
56
55
|
Enable tab-completion:
|
|
57
56
|
scitex completion # Auto-install for your shell
|
|
58
57
|
scitex completion --show # Show installation instructions
|
|
59
58
|
"""
|
|
60
|
-
|
|
59
|
+
if help_recursive:
|
|
60
|
+
_print_help_recursive(ctx)
|
|
61
|
+
ctx.exit(0)
|
|
62
|
+
elif ctx.invoked_subcommand is None:
|
|
63
|
+
click.echo(ctx.get_help())
|
|
61
64
|
|
|
62
65
|
|
|
63
66
|
# Add command groups
|
|
@@ -67,11 +70,14 @@ cli.add_command(capture.capture)
|
|
|
67
70
|
cli.add_command(cloud.cloud)
|
|
68
71
|
cli.add_command(config.config)
|
|
69
72
|
cli.add_command(convert.convert)
|
|
73
|
+
cli.add_command(introspect.introspect)
|
|
70
74
|
cli.add_command(mcp.mcp)
|
|
75
|
+
cli.add_command(plt.plt)
|
|
71
76
|
cli.add_command(repro.repro)
|
|
72
77
|
cli.add_command(resource.resource)
|
|
73
78
|
cli.add_command(scholar.scholar)
|
|
74
79
|
cli.add_command(security.security)
|
|
80
|
+
cli.add_command(social.social)
|
|
75
81
|
cli.add_command(stats.stats)
|
|
76
82
|
cli.add_command(template.template)
|
|
77
83
|
cli.add_command(tex.tex)
|
|
@@ -93,10 +99,8 @@ def _get_all_command_paths(group, prefix=""):
|
|
|
93
99
|
return paths
|
|
94
100
|
|
|
95
101
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
def help_recursive(ctx):
|
|
99
|
-
"""Show help for all commands recursively."""
|
|
102
|
+
def _print_help_recursive(ctx):
|
|
103
|
+
"""Print help for all commands recursively."""
|
|
100
104
|
# Show main CLI help first
|
|
101
105
|
click.secho("━━━ scitex ━━━", fg="cyan", bold=True)
|
|
102
106
|
click.echo(cli.get_help(ctx))
|
|
@@ -111,49 +115,88 @@ def help_recursive(ctx):
|
|
|
111
115
|
click.echo(cmd.get_help(sub_ctx))
|
|
112
116
|
|
|
113
117
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
"
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
"
|
|
122
|
-
|
|
123
|
-
|
|
118
|
+
def _detect_shell() -> str | None:
|
|
119
|
+
"""Auto-detect current shell."""
|
|
120
|
+
shell_env = os.environ.get("SHELL", "")
|
|
121
|
+
if "bash" in shell_env:
|
|
122
|
+
return "bash"
|
|
123
|
+
elif "zsh" in shell_env:
|
|
124
|
+
return "zsh"
|
|
125
|
+
elif "fish" in shell_env:
|
|
126
|
+
return "fish"
|
|
127
|
+
return None
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def _get_rc_file(shell: str) -> str:
|
|
131
|
+
"""Get shell config file path."""
|
|
132
|
+
if shell == "bash":
|
|
133
|
+
return os.path.expanduser("~/.bashrc")
|
|
134
|
+
elif shell == "zsh":
|
|
135
|
+
return os.path.expanduser("~/.zshrc")
|
|
136
|
+
elif shell == "fish":
|
|
137
|
+
return os.path.expanduser("~/.config/fish/config.fish")
|
|
138
|
+
return ""
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
def _generate_completion_script(shell: str) -> str:
|
|
142
|
+
"""Generate completion script for scitex CLI."""
|
|
143
|
+
import shutil
|
|
144
|
+
|
|
145
|
+
cli_path = shutil.which("scitex")
|
|
146
|
+
if not cli_path:
|
|
147
|
+
return ""
|
|
148
|
+
|
|
149
|
+
if shell == "bash":
|
|
150
|
+
return f'# scitex tab completion\neval "$(_SCITEX_COMPLETE=bash_source {cli_path})"'
|
|
151
|
+
elif shell == "zsh":
|
|
152
|
+
return (
|
|
153
|
+
f'# scitex tab completion\neval "$(_SCITEX_COMPLETE=zsh_source {cli_path})"'
|
|
154
|
+
)
|
|
155
|
+
elif shell == "fish":
|
|
156
|
+
return f"# scitex tab completion\neval (env _SCITEX_COMPLETE=fish_source {cli_path})"
|
|
157
|
+
return ""
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
@cli.group(invoke_without_command=True)
|
|
161
|
+
@click.pass_context
|
|
162
|
+
def completion(ctx):
|
|
124
163
|
"""
|
|
125
|
-
|
|
164
|
+
Shell completion for scitex CLI.
|
|
126
165
|
|
|
127
166
|
\b
|
|
128
|
-
|
|
167
|
+
Commands:
|
|
168
|
+
scitex completion install # Install completion (default)
|
|
169
|
+
scitex completion status # Check installation status
|
|
170
|
+
scitex completion bash # Show bash completion script
|
|
171
|
+
scitex completion zsh # Show zsh completion script
|
|
129
172
|
|
|
130
173
|
\b
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
174
|
+
Quick install:
|
|
175
|
+
scitex completion install
|
|
176
|
+
"""
|
|
177
|
+
if ctx.invoked_subcommand is None:
|
|
178
|
+
# Default to install
|
|
179
|
+
ctx.invoke(completion_install)
|
|
134
180
|
|
|
135
|
-
# Specify shell
|
|
136
|
-
scitex completion --shell bash
|
|
137
|
-
scitex completion --shell zsh
|
|
138
181
|
|
|
139
|
-
|
|
140
|
-
|
|
182
|
+
@completion.command("install")
|
|
183
|
+
@click.option(
|
|
184
|
+
"--shell",
|
|
185
|
+
type=click.Choice(["bash", "zsh", "fish"], case_sensitive=False),
|
|
186
|
+
help="Shell type (auto-detected if not provided).",
|
|
187
|
+
)
|
|
188
|
+
def completion_install(shell):
|
|
189
|
+
"""
|
|
190
|
+
Install shell completion for scitex CLI.
|
|
141
191
|
|
|
142
192
|
\b
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
193
|
+
Examples:
|
|
194
|
+
scitex completion install # Auto-detect shell
|
|
195
|
+
scitex completion install --shell bash
|
|
146
196
|
"""
|
|
147
|
-
# Auto-detect shell if not provided
|
|
148
197
|
if not shell:
|
|
149
|
-
|
|
150
|
-
if
|
|
151
|
-
shell = "bash"
|
|
152
|
-
elif "zsh" in shell_env:
|
|
153
|
-
shell = "zsh"
|
|
154
|
-
elif "fish" in shell_env:
|
|
155
|
-
shell = "fish"
|
|
156
|
-
else:
|
|
198
|
+
shell = _detect_shell()
|
|
199
|
+
if not shell:
|
|
157
200
|
click.secho(
|
|
158
201
|
"Could not auto-detect shell. Please specify with --shell option.",
|
|
159
202
|
fg="red",
|
|
@@ -162,72 +205,120 @@ def completion(shell, show):
|
|
|
162
205
|
sys.exit(1)
|
|
163
206
|
|
|
164
207
|
shell = shell.lower()
|
|
208
|
+
rc_file = _get_rc_file(shell)
|
|
209
|
+
completion_script = _generate_completion_script(shell)
|
|
165
210
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
# If relative path, find the full path
|
|
170
|
-
import shutil
|
|
171
|
-
|
|
172
|
-
scitex_full = shutil.which("scitex") or scitex_path
|
|
173
|
-
else:
|
|
174
|
-
scitex_full = scitex_path
|
|
175
|
-
|
|
176
|
-
# Generate completion script
|
|
177
|
-
if shell == "bash":
|
|
178
|
-
rc_file = os.path.expanduser("~/.bashrc")
|
|
179
|
-
eval_line = f'eval "$(_SCITEX_COMPLETE=bash_source {scitex_full})"'
|
|
180
|
-
elif shell == "zsh":
|
|
181
|
-
rc_file = os.path.expanduser("~/.zshrc")
|
|
182
|
-
eval_line = f'eval "$(_SCITEX_COMPLETE=zsh_source {scitex_full})"'
|
|
183
|
-
elif shell == "fish":
|
|
184
|
-
rc_file = os.path.expanduser("~/.config/fish/config.fish")
|
|
185
|
-
eval_line = f"eval (env _SCITEX_COMPLETE=fish_source {scitex_full})"
|
|
186
|
-
|
|
187
|
-
if show:
|
|
188
|
-
# Just show the completion script
|
|
189
|
-
click.echo(f"Add this line to your {rc_file}:")
|
|
190
|
-
click.echo()
|
|
191
|
-
click.secho(eval_line, fg="green")
|
|
192
|
-
sys.exit(0)
|
|
211
|
+
if not completion_script:
|
|
212
|
+
click.secho("scitex CLI not found in PATH.", fg="red", err=True)
|
|
213
|
+
sys.exit(1)
|
|
193
214
|
|
|
194
|
-
# Check if already installed
|
|
215
|
+
# Check if already installed
|
|
195
216
|
if os.path.exists(rc_file):
|
|
196
217
|
with open(rc_file) as f:
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
# Install completion
|
|
218
|
+
content = f.read()
|
|
219
|
+
if "scitex tab completion" in content:
|
|
220
|
+
click.secho(f"Completion already installed in {rc_file}", fg="yellow")
|
|
221
|
+
click.echo(
|
|
222
|
+
"\nTo reinstall, first remove the existing block, then run again."
|
|
223
|
+
)
|
|
224
|
+
click.echo("\nTo reload, run:")
|
|
225
|
+
click.secho(f" source {rc_file}", fg="cyan")
|
|
226
|
+
sys.exit(0)
|
|
227
|
+
|
|
228
|
+
# Install
|
|
210
229
|
try:
|
|
211
|
-
# Create config directory if it doesn't exist (for fish)
|
|
212
230
|
os.makedirs(os.path.dirname(rc_file), exist_ok=True)
|
|
213
|
-
|
|
214
231
|
with open(rc_file, "a") as f:
|
|
215
|
-
f.write("\n
|
|
216
|
-
f.write(f"{eval_line}\n")
|
|
232
|
+
f.write(f"\n{completion_script}\n")
|
|
217
233
|
|
|
218
|
-
click.secho(f"
|
|
219
|
-
click.echo()
|
|
220
|
-
click.echo("To activate completion in current shell, run:")
|
|
234
|
+
click.secho(f"Installed scitex completion to {rc_file}", fg="green")
|
|
235
|
+
click.echo("\nTo activate, run:")
|
|
221
236
|
click.secho(f" source {rc_file}", fg="cyan")
|
|
222
|
-
click.echo()
|
|
223
|
-
click.echo("Or restart your shell.")
|
|
224
|
-
sys.exit(0)
|
|
225
237
|
|
|
226
238
|
except Exception as e:
|
|
227
|
-
click.secho(f"ERROR:
|
|
228
|
-
click.echo()
|
|
229
|
-
click.echo(
|
|
230
|
-
|
|
239
|
+
click.secho(f"ERROR: {e}", fg="red", err=True)
|
|
240
|
+
click.echo("\nManually add to your shell config:")
|
|
241
|
+
click.echo(completion_script)
|
|
242
|
+
sys.exit(1)
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
@completion.command("status")
|
|
246
|
+
def completion_status():
|
|
247
|
+
"""
|
|
248
|
+
Check shell completion installation status.
|
|
249
|
+
|
|
250
|
+
\b
|
|
251
|
+
Shows:
|
|
252
|
+
- Current shell
|
|
253
|
+
- Config file path
|
|
254
|
+
- Installation status
|
|
255
|
+
"""
|
|
256
|
+
import shutil
|
|
257
|
+
|
|
258
|
+
shell = _detect_shell() or "unknown"
|
|
259
|
+
rc_file = _get_rc_file(shell) if shell != "unknown" else "N/A"
|
|
260
|
+
|
|
261
|
+
click.secho("Shell Completion Status", fg="cyan", bold=True)
|
|
262
|
+
click.echo(f" Shell: {shell}")
|
|
263
|
+
click.echo(f" Config: {rc_file}")
|
|
264
|
+
|
|
265
|
+
# Check if installed
|
|
266
|
+
installed = False
|
|
267
|
+
if rc_file != "N/A" and os.path.exists(rc_file):
|
|
268
|
+
with open(rc_file) as f:
|
|
269
|
+
content = f.read()
|
|
270
|
+
if "scitex tab completion" in content:
|
|
271
|
+
installed = True
|
|
272
|
+
|
|
273
|
+
status = (
|
|
274
|
+
click.style("installed", fg="green")
|
|
275
|
+
if installed
|
|
276
|
+
else click.style("not installed", fg="yellow")
|
|
277
|
+
)
|
|
278
|
+
click.echo(f" Status: {status}")
|
|
279
|
+
|
|
280
|
+
# Check if scitex is in PATH
|
|
281
|
+
cli_path = shutil.which("scitex")
|
|
282
|
+
path_status = (
|
|
283
|
+
click.style("OK", fg="green") if cli_path else click.style("missing", fg="red")
|
|
284
|
+
)
|
|
285
|
+
click.echo(f" scitex in PATH: {path_status}")
|
|
286
|
+
|
|
287
|
+
if not installed:
|
|
288
|
+
click.echo("\nTo install completion:")
|
|
289
|
+
click.secho(" scitex completion install", fg="cyan")
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
@completion.command("bash")
|
|
293
|
+
def completion_bash():
|
|
294
|
+
"""Show bash completion script."""
|
|
295
|
+
script = _generate_completion_script("bash")
|
|
296
|
+
if script:
|
|
297
|
+
click.echo(script)
|
|
298
|
+
else:
|
|
299
|
+
click.secho("scitex CLI not found in PATH.", fg="red", err=True)
|
|
300
|
+
sys.exit(1)
|
|
301
|
+
|
|
302
|
+
|
|
303
|
+
@completion.command("zsh")
|
|
304
|
+
def completion_zsh():
|
|
305
|
+
"""Show zsh completion script."""
|
|
306
|
+
script = _generate_completion_script("zsh")
|
|
307
|
+
if script:
|
|
308
|
+
click.echo(script)
|
|
309
|
+
else:
|
|
310
|
+
click.secho("scitex CLI not found in PATH.", fg="red", err=True)
|
|
311
|
+
sys.exit(1)
|
|
312
|
+
|
|
313
|
+
|
|
314
|
+
@completion.command("fish")
|
|
315
|
+
def completion_fish():
|
|
316
|
+
"""Show fish completion script."""
|
|
317
|
+
script = _generate_completion_script("fish")
|
|
318
|
+
if script:
|
|
319
|
+
click.echo(script)
|
|
320
|
+
else:
|
|
321
|
+
click.secho("scitex CLI not found in PATH.", fg="red", err=True)
|
|
231
322
|
sys.exit(1)
|
|
232
323
|
|
|
233
324
|
|
scitex/cli/mcp.py
CHANGED
|
@@ -13,23 +13,26 @@ Commands:
|
|
|
13
13
|
import click
|
|
14
14
|
|
|
15
15
|
|
|
16
|
-
@click.group()
|
|
17
|
-
|
|
16
|
+
@click.group(invoke_without_command=True)
|
|
17
|
+
@click.option("--help-recursive", is_flag=True, help="Show help for all subcommands")
|
|
18
|
+
@click.pass_context
|
|
19
|
+
def mcp(ctx, help_recursive):
|
|
18
20
|
"""
|
|
19
21
|
MCP (Model Context Protocol) server management.
|
|
20
22
|
|
|
21
23
|
\b
|
|
22
24
|
Examples:
|
|
23
|
-
scitex mcp list
|
|
24
|
-
scitex mcp
|
|
25
|
-
scitex mcp doctor # Check server health
|
|
26
|
-
scitex mcp serve # Start stdio server
|
|
27
|
-
scitex mcp serve -t sse -p 8085 # Start SSE server
|
|
25
|
+
scitex mcp list-tools # List all tools
|
|
26
|
+
scitex mcp start # Start MCP server
|
|
28
27
|
"""
|
|
29
|
-
|
|
28
|
+
if help_recursive:
|
|
29
|
+
_print_help_recursive(ctx)
|
|
30
|
+
ctx.exit(0)
|
|
31
|
+
elif ctx.invoked_subcommand is None:
|
|
32
|
+
click.echo(ctx.get_help())
|
|
30
33
|
|
|
31
34
|
|
|
32
|
-
@mcp.command("list")
|
|
35
|
+
@mcp.command("list-tools")
|
|
33
36
|
@click.option(
|
|
34
37
|
"--module",
|
|
35
38
|
"-m",
|
|
@@ -44,9 +47,8 @@ def list_tools(module: str, as_json: bool):
|
|
|
44
47
|
|
|
45
48
|
\b
|
|
46
49
|
Examples:
|
|
47
|
-
scitex mcp list
|
|
48
|
-
scitex mcp list --module audio
|
|
49
|
-
scitex mcp list --json # Output as JSON
|
|
50
|
+
scitex mcp list-tools
|
|
51
|
+
scitex mcp list-tools --module audio
|
|
50
52
|
"""
|
|
51
53
|
try:
|
|
52
54
|
from scitex.mcp_server import FASTMCP_AVAILABLE
|
|
@@ -268,11 +270,8 @@ def doctor(verbose: bool):
|
|
|
268
270
|
raise SystemExit(1 if issues else 0)
|
|
269
271
|
|
|
270
272
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
def help_recursive(ctx):
|
|
274
|
-
"""Show help for all MCP commands recursively."""
|
|
275
|
-
# Create a fake parent context to show "scitex mcp" in Usage
|
|
273
|
+
def _print_help_recursive(ctx):
|
|
274
|
+
"""Print help for mcp and all its subcommands."""
|
|
276
275
|
fake_parent = click.Context(click.Group(), info_name="scitex")
|
|
277
276
|
parent_ctx = click.Context(mcp, info_name="mcp", parent=fake_parent)
|
|
278
277
|
|
|
@@ -289,7 +288,7 @@ def help_recursive(ctx):
|
|
|
289
288
|
click.echo(cmd.get_help(sub_ctx))
|
|
290
289
|
|
|
291
290
|
|
|
292
|
-
@mcp.command("
|
|
291
|
+
@mcp.command("start")
|
|
293
292
|
@click.option(
|
|
294
293
|
"--transport",
|
|
295
294
|
"-t",
|
|
@@ -301,27 +300,14 @@ def help_recursive(ctx):
|
|
|
301
300
|
@click.option(
|
|
302
301
|
"--port", "-p", default=8085, type=int, help="Port to bind (default: 8085)"
|
|
303
302
|
)
|
|
304
|
-
def
|
|
303
|
+
def start(transport: str, host: str, port: int):
|
|
305
304
|
"""
|
|
306
305
|
Start the unified MCP server.
|
|
307
306
|
|
|
308
|
-
\b
|
|
309
|
-
Transport types:
|
|
310
|
-
stdio - Standard I/O (for Claude Desktop)
|
|
311
|
-
sse - Server-Sent Events (for remote via SSH)
|
|
312
|
-
http - HTTP streamable (for web clients)
|
|
313
|
-
|
|
314
307
|
\b
|
|
315
308
|
Examples:
|
|
316
|
-
scitex mcp
|
|
317
|
-
scitex mcp
|
|
318
|
-
scitex mcp serve -t http -p 8085 # Start HTTP server
|
|
319
|
-
|
|
320
|
-
\b
|
|
321
|
-
Remote Setup (SSE):
|
|
322
|
-
1. Local: scitex mcp serve -t sse -p 8085
|
|
323
|
-
2. SSH: ssh -R 8085:localhost:8085 remote-host
|
|
324
|
-
3. Config: {"type": "sse", "url": "http://localhost:8085/sse"}
|
|
309
|
+
scitex mcp start
|
|
310
|
+
scitex mcp start -t sse -p 8085
|
|
325
311
|
"""
|
|
326
312
|
try:
|
|
327
313
|
from scitex.mcp_server import run_server
|
|
@@ -333,4 +319,44 @@ def serve(transport: str, host: str, port: int):
|
|
|
333
319
|
run_server(transport=transport, host=host, port=port)
|
|
334
320
|
|
|
335
321
|
|
|
322
|
+
@mcp.command("installation")
|
|
323
|
+
def installation():
|
|
324
|
+
"""
|
|
325
|
+
Show Claude Desktop configuration for SciTeX MCP server.
|
|
326
|
+
|
|
327
|
+
\b
|
|
328
|
+
Examples:
|
|
329
|
+
scitex mcp installation
|
|
330
|
+
"""
|
|
331
|
+
import shutil
|
|
332
|
+
import sys
|
|
333
|
+
|
|
334
|
+
from scitex import __version__
|
|
335
|
+
|
|
336
|
+
click.secho(f"SciTeX MCP Server v{__version__}", fg="cyan", bold=True)
|
|
337
|
+
click.echo()
|
|
338
|
+
|
|
339
|
+
# Get actual path
|
|
340
|
+
scitex_path = shutil.which("scitex")
|
|
341
|
+
python_path = sys.executable
|
|
342
|
+
|
|
343
|
+
if scitex_path:
|
|
344
|
+
click.echo(f"Your installation path: {scitex_path}")
|
|
345
|
+
click.echo(f"Your Python path: {python_path}")
|
|
346
|
+
click.echo()
|
|
347
|
+
|
|
348
|
+
click.secho("Claude Desktop Configuration:", fg="green", bold=True)
|
|
349
|
+
click.echo(
|
|
350
|
+
"Add to ~/Library/Application Support/Claude/claude_desktop_config.json (macOS)"
|
|
351
|
+
)
|
|
352
|
+
click.echo("or %APPDATA%\\Claude\\claude_desktop_config.json (Windows):")
|
|
353
|
+
click.echo()
|
|
354
|
+
|
|
355
|
+
config = f'''"scitex": {{
|
|
356
|
+
"command": "{scitex_path or "/path/to/.venv/bin/scitex"}",
|
|
357
|
+
"args": ["mcp", "start"]
|
|
358
|
+
}}'''
|
|
359
|
+
click.secho(config, fg="yellow")
|
|
360
|
+
|
|
361
|
+
|
|
336
362
|
# EOF
|