xelta-cli 0.1.3__tar.gz → 0.1.4__tar.gz

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 (24) hide show
  1. {xelta_cli-0.1.3 → xelta_cli-0.1.4}/PKG-INFO +1 -1
  2. {xelta_cli-0.1.3 → xelta_cli-0.1.4}/README.md +34 -0
  3. {xelta_cli-0.1.3 → xelta_cli-0.1.4}/pyproject.toml +21 -21
  4. {xelta_cli-0.1.3 → xelta_cli-0.1.4}/xelta/cli.py +102 -111
  5. {xelta_cli-0.1.3 → xelta_cli-0.1.4}/xelta/oauth.py +2 -2
  6. {xelta_cli-0.1.3 → xelta_cli-0.1.4}/xelta_cli.egg-info/PKG-INFO +1 -1
  7. {xelta_cli-0.1.3 → xelta_cli-0.1.4}/xelta_cli.egg-info/SOURCES.txt +0 -1
  8. xelta_cli-0.1.3/xelta/commands/install.py +0 -85
  9. {xelta_cli-0.1.3 → xelta_cli-0.1.4}/setup.cfg +0 -0
  10. {xelta_cli-0.1.3 → xelta_cli-0.1.4}/xelta/__init__.py +0 -0
  11. {xelta_cli-0.1.3 → xelta_cli-0.1.4}/xelta/auth.py +0 -0
  12. {xelta_cli-0.1.3 → xelta_cli-0.1.4}/xelta/commands/__init__.py +0 -0
  13. {xelta_cli-0.1.3 → xelta_cli-0.1.4}/xelta/commands/balance.py +0 -0
  14. {xelta_cli-0.1.3 → xelta_cli-0.1.4}/xelta/commands/image.py +0 -0
  15. {xelta_cli-0.1.3 → xelta_cli-0.1.4}/xelta/commands/mixboard.py +0 -0
  16. {xelta_cli-0.1.3 → xelta_cli-0.1.4}/xelta/commands/reel.py +0 -0
  17. {xelta_cli-0.1.3 → xelta_cli-0.1.4}/xelta/commands/status.py +0 -0
  18. {xelta_cli-0.1.3 → xelta_cli-0.1.4}/xelta/commands/street_ad.py +0 -0
  19. {xelta_cli-0.1.3 → xelta_cli-0.1.4}/xelta/commands/website.py +0 -0
  20. {xelta_cli-0.1.3 → xelta_cli-0.1.4}/xelta/config.py +0 -0
  21. {xelta_cli-0.1.3 → xelta_cli-0.1.4}/xelta_cli.egg-info/dependency_links.txt +0 -0
  22. {xelta_cli-0.1.3 → xelta_cli-0.1.4}/xelta_cli.egg-info/entry_points.txt +0 -0
  23. {xelta_cli-0.1.3 → xelta_cli-0.1.4}/xelta_cli.egg-info/requires.txt +0 -0
  24. {xelta_cli-0.1.3 → xelta_cli-0.1.4}/xelta_cli.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: xelta-cli
3
- Version: 0.1.3
3
+ Version: 0.1.4
4
4
  Summary: Official CLI for xelta.ai
5
5
  Requires-Python: >=3.10
6
6
  Requires-Dist: httpx>=0.27
@@ -4,10 +4,37 @@ Official command-line interface for [xelta.ai](https://xelta.ai) — generate im
4
4
 
5
5
  ## Install
6
6
 
7
+ **Recommended — use `pipx` (handles PATH automatically):**
8
+
9
+ ```bash
10
+ pip install pipx
11
+ pipx install xelta-cli
12
+ ```
13
+
14
+ **Alternative — plain pip:**
15
+
7
16
  ```bash
8
17
  pip install xelta-cli
9
18
  ```
10
19
 
20
+ > **Windows users:** If you get `'xelta' is not recognized` after `pip install`, your Python Scripts folder is not in PATH. Run the following in a normal CMD window (not as admin), then close and reopen CMD:
21
+ > ```cmd
22
+ > setx PATH "%PATH%;<scripts-path>"
23
+ > ```
24
+ > Replace `<scripts-path>` with the path shown in the pip install output — look for the line:
25
+ > `WARNING: The script xelta.exe is installed in '...' which is not on PATH.`
26
+ > Using `pipx` avoids this entirely.
27
+
28
+ To upgrade:
29
+
30
+ ```bash
31
+ pipx upgrade xelta-cli
32
+ # or
33
+ pip install --upgrade xelta-cli
34
+ ```
35
+
36
+ After installation the `xelta` binary is available in your terminal.
37
+
11
38
  ## Authentication
12
39
 
13
40
  ```bash
@@ -58,6 +85,13 @@ xelta website build "Coffee shop website" --industry food --pages "Home, Menu, C
58
85
  xelta website history
59
86
  ```
60
87
 
88
+ ### Claude Code MCP Integration
89
+ ```bash
90
+ xelta install claude-code
91
+ ```
92
+
93
+ Installs `xelta-mcp` from PyPI and registers it as an MCP server in Claude Code — lets you call Xelta tools directly from AI-assisted workflows. Restart Claude Code after running.
94
+
61
95
  ## All Options
62
96
 
63
97
  | Command | Option | Description |
@@ -1,21 +1,21 @@
1
- [build-system]
2
- requires = ["setuptools>=68", "wheel"]
3
- build-backend = "setuptools.build_meta"
4
-
5
- [project]
6
- name = "xelta-cli"
7
- version = "0.1.3"
8
- description = "Official CLI for xelta.ai"
9
- requires-python = ">=3.10"
10
- dependencies = [
11
- "httpx>=0.27",
12
- "typer>=0.12",
13
- "rich>=13",
14
- ]
15
-
16
- [project.scripts]
17
- xelta = "xelta.cli:app"
18
-
19
- [tool.setuptools.packages.find]
20
- where = ["."]
21
- include = ["xelta*"]
1
+ [build-system]
2
+ requires = ["setuptools>=68", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "xelta-cli"
7
+ version = "0.1.4"
8
+ description = "Official CLI for xelta.ai"
9
+ requires-python = ">=3.10"
10
+ dependencies = [
11
+ "httpx>=0.27",
12
+ "typer>=0.12",
13
+ "rich>=13",
14
+ ]
15
+
16
+ [project.scripts]
17
+ xelta = "xelta.cli:app"
18
+
19
+ [tool.setuptools.packages.find]
20
+ where = ["."]
21
+ include = ["xelta*"]
@@ -1,111 +1,102 @@
1
- import typer
2
- from rich.console import Console
3
- from xelta.auth import save_token, delete_token, load_token
4
- from xelta.commands.status import status_cmd
5
- from xelta.commands.balance import balance_cmd
6
- from xelta.commands.image import image_cmd
7
- from xelta.commands.mixboard import mixboard_cmd
8
- from xelta.commands.street_ad import street_ad_cmd
9
- from xelta.commands.reel import reel_cmd
10
- from xelta.commands import website
11
- from xelta.commands.install import install_cmd
12
-
13
- console = Console()
14
-
15
- app = typer.Typer(
16
- name="xelta",
17
- help="Official CLI for xelta.ai — generate images, reels, websites, and more.",
18
- no_args_is_help=True,
19
- rich_markup_mode="rich",
20
- )
21
-
22
-
23
- @app.command()
24
- def login(
25
- token: str = typer.Option(None, "--token", "-t", help="Paste a JWT directly instead of browser login"),
26
- ):
27
- """Authenticate with your Xelta account via browser."""
28
- if token:
29
- save_token(token.strip())
30
- console.print("[green]Logged in successfully.[/green]")
31
- return
32
-
33
- try:
34
- from xelta.oauth import browser_login
35
- console.print("[bold]Opening browser for Xelta login...[/bold]")
36
- jwt = browser_login()
37
- save_token(jwt)
38
- console.print("[green]Logged in successfully.[/green]")
39
- except Exception as e:
40
- console.print(f"[red]Login failed:[/red] {e}")
41
- raise typer.Exit(1)
42
-
43
-
44
- @app.command()
45
- def logout():
46
- """Remove stored credentials."""
47
- delete_token()
48
- console.print("Logged out.")
49
-
50
-
51
- @app.command()
52
- def status(debug: bool = typer.Option(False, "--debug", help="Show token prefix and raw API error")):
53
- """Check authentication status and API connectivity."""
54
- status_cmd(debug=debug)
55
-
56
-
57
- @app.command()
58
- def balance():
59
- """Check your Xelta credit balance."""
60
- balance_cmd()
61
-
62
-
63
- @app.command()
64
- def image(
65
- prompt: str = typer.Argument(..., help="Description of the image to generate"),
66
- model: str = typer.Option(None, "--model", "-m", help="Model ID (skip interactive picker)"),
67
- size: str = typer.Option(None, "--size", "-s", help="Resolution: 1080p, 2K, or 4K"),
68
- no_optimize: bool = typer.Option(False, "--no-optimize", help="Disable prompt enhancement"),
69
- ):
70
- """Generate an image from a text prompt."""
71
- image_cmd(prompt=prompt, model=model, size=size, no_optimize=no_optimize)
72
-
73
-
74
- @app.command()
75
- def mixboard(
76
- prompt: str = typer.Argument(..., help="Creative prompt for the image grid"),
77
- num: int = typer.Option(8, "--num", "-n", help="Number of images"),
78
- ):
79
- """Generate a mixboard — a grid of AI images from a prompt."""
80
- mixboard_cmd(prompt=prompt, num=num)
81
-
82
-
83
- @app.command(name="street-ad")
84
- def street_ad(
85
- brand: str = typer.Argument(..., help="Brand name to feature"),
86
- style: str = typer.Option("auto", "--style", help="Art style: auto, graffiti, stencil, wildstyle"),
87
- surface: str = typer.Option("brick", "--surface", help="Surface: brick, wall, concrete"),
88
- logo: str = typer.Option(None, "--logo", help="Path or URL to logo image"),
89
- ):
90
- """Generate a street art / graffiti-style ad for a brand."""
91
- street_ad_cmd(brand=brand, style=style, surface=surface, logo=logo)
92
-
93
-
94
- @app.command()
95
- def reel(
96
- prompt: str = typer.Argument(..., help="Description of the reel to generate"),
97
- image: str = typer.Option(None, "--image", help="Path or URL to an image to include"),
98
- ):
99
- """Generate a short AI video reel from a text prompt."""
100
- reel_cmd(prompt=prompt, image=image)
101
-
102
-
103
- app.add_typer(website.app, name="website")
104
-
105
-
106
- @app.command()
107
- def install(
108
- target: str = typer.Argument(..., help="Integration to install: claude-code"),
109
- ):
110
- """Install Xelta integrations (e.g. xelta install claude-code)."""
111
- install_cmd(target=target)
1
+ import typer
2
+ from rich.console import Console
3
+ from xelta.auth import save_token, delete_token, load_token
4
+ from xelta.commands.status import status_cmd
5
+ from xelta.commands.balance import balance_cmd
6
+ from xelta.commands.image import image_cmd
7
+ from xelta.commands.mixboard import mixboard_cmd
8
+ from xelta.commands.street_ad import street_ad_cmd
9
+ from xelta.commands.reel import reel_cmd
10
+ from xelta.commands import website
11
+
12
+ console = Console()
13
+
14
+ app = typer.Typer(
15
+ name="xelta",
16
+ help="Official CLI for xelta.ai — generate images, reels, websites, and more.",
17
+ no_args_is_help=True,
18
+ rich_markup_mode="rich",
19
+ )
20
+
21
+
22
+ @app.command()
23
+ def login(
24
+ token: str = typer.Option(None, "--token", "-t", help="Paste a JWT directly instead of browser login"),
25
+ ):
26
+ """Authenticate with your Xelta account via browser."""
27
+ if token:
28
+ save_token(token.strip())
29
+ console.print("[green]Logged in successfully.[/green]")
30
+ return
31
+
32
+ try:
33
+ from xelta.oauth import browser_login
34
+ console.print("[bold]Opening browser for Xelta login...[/bold]")
35
+ jwt = browser_login()
36
+ save_token(jwt)
37
+ console.print("[green]Logged in successfully.[/green]")
38
+ except Exception as e:
39
+ console.print(f"[red]Login failed:[/red] {e}")
40
+ raise typer.Exit(1)
41
+
42
+
43
+ @app.command()
44
+ def logout():
45
+ """Remove stored credentials."""
46
+ delete_token()
47
+ console.print("Logged out.")
48
+
49
+
50
+ @app.command()
51
+ def status(debug: bool = typer.Option(False, "--debug", help="Show token prefix and raw API error")):
52
+ """Check authentication status and API connectivity."""
53
+ status_cmd(debug=debug)
54
+
55
+
56
+ @app.command()
57
+ def balance():
58
+ """Check your Xelta credit balance."""
59
+ balance_cmd()
60
+
61
+
62
+ @app.command()
63
+ def image(
64
+ prompt: str = typer.Argument(..., help="Description of the image to generate"),
65
+ model: str = typer.Option(None, "--model", "-m", help="Model ID (skip interactive picker)"),
66
+ size: str = typer.Option(None, "--size", "-s", help="Resolution: 1080p, 2K, or 4K"),
67
+ no_optimize: bool = typer.Option(False, "--no-optimize", help="Disable prompt enhancement"),
68
+ ):
69
+ """Generate an image from a text prompt."""
70
+ image_cmd(prompt=prompt, model=model, size=size, no_optimize=no_optimize)
71
+
72
+
73
+ @app.command()
74
+ def mixboard(
75
+ prompt: str = typer.Argument(..., help="Creative prompt for the image grid"),
76
+ num: int = typer.Option(8, "--num", "-n", help="Number of images"),
77
+ ):
78
+ """Generate a mixboard — a grid of AI images from a prompt."""
79
+ mixboard_cmd(prompt=prompt, num=num)
80
+
81
+
82
+ @app.command(name="street-ad")
83
+ def street_ad(
84
+ brand: str = typer.Argument(..., help="Brand name to feature"),
85
+ style: str = typer.Option("auto", "--style", help="Art style: auto, graffiti, stencil, wildstyle"),
86
+ surface: str = typer.Option("brick", "--surface", help="Surface: brick, wall, concrete"),
87
+ logo: str = typer.Option(None, "--logo", help="Path or URL to logo image"),
88
+ ):
89
+ """Generate a street art / graffiti-style ad for a brand."""
90
+ street_ad_cmd(brand=brand, style=style, surface=surface, logo=logo)
91
+
92
+
93
+ @app.command()
94
+ def reel(
95
+ prompt: str = typer.Argument(..., help="Description of the reel to generate"),
96
+ image: str = typer.Option(None, "--image", help="Path or URL to an image to include"),
97
+ ):
98
+ """Generate a short AI video reel from a text prompt."""
99
+ reel_cmd(prompt=prompt, image=image)
100
+
101
+
102
+ app.add_typer(website.app, name="website")
@@ -7,8 +7,8 @@ from urllib.parse import parse_qs, urlencode, urlparse
7
7
 
8
8
  import httpx
9
9
 
10
- XELTA_AUTHORIZE_URL = "https://api.xelta.ai/api/auth/oauth/authorize"
11
- XELTA_TOKEN_URL = "https://api.xelta.ai/api/auth/oauth/token"
10
+ XELTA_AUTHORIZE_URL = "https://stb.xelta.ai/api/auth/oauth/authorize"
11
+ XELTA_TOKEN_URL = "https://stb.xelta.ai/api/auth/oauth/token"
12
12
  CLI_CLIENT_ID = "xelta-cli"
13
13
  CALLBACK_PORT = 8787
14
14
  REDIRECT_URI = f"http://localhost:{CALLBACK_PORT}/callback"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: xelta-cli
3
- Version: 0.1.3
3
+ Version: 0.1.4
4
4
  Summary: Official CLI for xelta.ai
5
5
  Requires-Python: >=3.10
6
6
  Requires-Dist: httpx>=0.27
@@ -8,7 +8,6 @@ xelta/oauth.py
8
8
  xelta/commands/__init__.py
9
9
  xelta/commands/balance.py
10
10
  xelta/commands/image.py
11
- xelta/commands/install.py
12
11
  xelta/commands/mixboard.py
13
12
  xelta/commands/reel.py
14
13
  xelta/commands/status.py
@@ -1,85 +0,0 @@
1
- import json
2
- import shutil
3
- import subprocess
4
- import sys
5
- from pathlib import Path
6
-
7
- import typer
8
- from rich.console import Console
9
-
10
- from xelta.auth import load_token
11
-
12
- console = Console()
13
-
14
- SUPPORTED_TARGETS = {"claude-code"}
15
-
16
-
17
- def install_cmd(target: str):
18
- if target not in SUPPORTED_TARGETS:
19
- console.print(
20
- f"[red]Unknown target:[/red] {target!r}\n"
21
- f"Supported: {', '.join(sorted(SUPPORTED_TARGETS))}"
22
- )
23
- raise typer.Exit(1)
24
-
25
- jwt = load_token()
26
- if not jwt:
27
- console.print(
28
- "[red]Not logged in.[/red] Run [bold]xelta login --token <jwt>[/bold] first."
29
- )
30
- raise typer.Exit(1)
31
-
32
- # Install / upgrade xelta-mcp from PyPI
33
- console.print("[dim]Installing xelta-mcp...[/dim]")
34
- result = subprocess.run(
35
- [sys.executable, "-m", "pip", "install", "--upgrade", "xelta-mcp"],
36
- capture_output=True,
37
- text=True,
38
- )
39
- if result.returncode != 0:
40
- console.print(f"[red]pip install failed:[/red]\n{result.stderr.strip()}")
41
- raise typer.Exit(1)
42
- console.print("[green]xelta-mcp installed.[/green]")
43
-
44
- # Locate the xelta-mcp binary; fall back to `python -m xelta_mcp.server`
45
- mcp_bin = shutil.which("xelta-mcp")
46
- if not mcp_bin:
47
- scripts_dir = Path(sys.executable).parent / "Scripts"
48
- candidate = scripts_dir / "xelta-mcp.exe"
49
- if candidate.exists():
50
- mcp_bin = str(candidate)
51
-
52
- if mcp_bin:
53
- mcp_command = mcp_bin
54
- mcp_args = []
55
- else:
56
- mcp_command = sys.executable
57
- mcp_args = ["-m", "xelta_mcp.server"]
58
-
59
- # Write MCP server entry into ~/.claude/settings.json
60
- claude_settings = Path.home() / ".claude" / "settings.json"
61
- claude_settings.parent.mkdir(exist_ok=True)
62
-
63
- if claude_settings.exists():
64
- try:
65
- settings = json.loads(claude_settings.read_text(encoding="utf-8"))
66
- except Exception:
67
- settings = {}
68
- else:
69
- settings = {}
70
-
71
- settings.setdefault("mcpServers", {})
72
- settings["mcpServers"]["xelta"] = {
73
- "command": mcp_command,
74
- "args": mcp_args,
75
- "env": {"XELTA_JWT_TOKEN": jwt},
76
- }
77
-
78
- claude_settings.write_text(
79
- json.dumps(settings, indent=2), encoding="utf-8"
80
- )
81
-
82
- console.print("[green]Xelta MCP server registered in Claude Code.[/green]")
83
- console.print(f" Config: {claude_settings}")
84
- console.print(f" Binary: {mcp_command}")
85
- console.print("\n[bold]Restart Claude Code to apply the changes.[/bold]")
File without changes
File without changes
File without changes
File without changes