xelta-cli 0.1.2__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.
- {xelta_cli-0.1.2 → xelta_cli-0.1.4}/PKG-INFO +1 -1
- xelta_cli-0.1.4/README.md +118 -0
- {xelta_cli-0.1.2 → xelta_cli-0.1.4}/pyproject.toml +21 -21
- {xelta_cli-0.1.2 → xelta_cli-0.1.4}/xelta/cli.py +102 -102
- {xelta_cli-0.1.2 → xelta_cli-0.1.4}/xelta/oauth.py +2 -2
- {xelta_cli-0.1.2 → xelta_cli-0.1.4}/xelta_cli.egg-info/PKG-INFO +1 -1
- {xelta_cli-0.1.2 → xelta_cli-0.1.4}/xelta_cli.egg-info/SOURCES.txt +1 -0
- {xelta_cli-0.1.2 → xelta_cli-0.1.4}/setup.cfg +0 -0
- {xelta_cli-0.1.2 → xelta_cli-0.1.4}/xelta/__init__.py +0 -0
- {xelta_cli-0.1.2 → xelta_cli-0.1.4}/xelta/auth.py +0 -0
- {xelta_cli-0.1.2 → xelta_cli-0.1.4}/xelta/commands/__init__.py +0 -0
- {xelta_cli-0.1.2 → xelta_cli-0.1.4}/xelta/commands/balance.py +0 -0
- {xelta_cli-0.1.2 → xelta_cli-0.1.4}/xelta/commands/image.py +0 -0
- {xelta_cli-0.1.2 → xelta_cli-0.1.4}/xelta/commands/mixboard.py +0 -0
- {xelta_cli-0.1.2 → xelta_cli-0.1.4}/xelta/commands/reel.py +0 -0
- {xelta_cli-0.1.2 → xelta_cli-0.1.4}/xelta/commands/status.py +0 -0
- {xelta_cli-0.1.2 → xelta_cli-0.1.4}/xelta/commands/street_ad.py +0 -0
- {xelta_cli-0.1.2 → xelta_cli-0.1.4}/xelta/commands/website.py +0 -0
- {xelta_cli-0.1.2 → xelta_cli-0.1.4}/xelta/config.py +0 -0
- {xelta_cli-0.1.2 → xelta_cli-0.1.4}/xelta_cli.egg-info/dependency_links.txt +0 -0
- {xelta_cli-0.1.2 → xelta_cli-0.1.4}/xelta_cli.egg-info/entry_points.txt +0 -0
- {xelta_cli-0.1.2 → xelta_cli-0.1.4}/xelta_cli.egg-info/requires.txt +0 -0
- {xelta_cli-0.1.2 → xelta_cli-0.1.4}/xelta_cli.egg-info/top_level.txt +0 -0
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# Xelta CLI
|
|
2
|
+
|
|
3
|
+
Official command-line interface for [xelta.ai](https://xelta.ai) — generate images, reels, websites, street ads, and more from your terminal.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
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
|
+
|
|
16
|
+
```bash
|
|
17
|
+
pip install xelta-cli
|
|
18
|
+
```
|
|
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
|
+
|
|
38
|
+
## Authentication
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
xelta login --token <your-jwt-token>
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Commands
|
|
45
|
+
|
|
46
|
+
### Check Status & Balance
|
|
47
|
+
```bash
|
|
48
|
+
xelta status # Check connection and auth
|
|
49
|
+
xelta balance # Check your credit balance
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Generate an Image
|
|
53
|
+
```bash
|
|
54
|
+
xelta image "a futuristic city at night"
|
|
55
|
+
```
|
|
56
|
+
Picks model and resolution interactively. Or skip the prompts:
|
|
57
|
+
```bash
|
|
58
|
+
xelta image "a futuristic city at night" --model seedream-5-0-lite-workflow --size 2K
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Generate a Mixboard
|
|
62
|
+
A grid of AI images from a single prompt:
|
|
63
|
+
```bash
|
|
64
|
+
xelta mixboard "luxury car showroom vibes"
|
|
65
|
+
xelta mixboard "neon Tokyo street" --num 12
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Generate a Street Ad
|
|
69
|
+
Graffiti-style brand ad:
|
|
70
|
+
```bash
|
|
71
|
+
xelta street-ad "Nike"
|
|
72
|
+
xelta street-ad "Adidas" --style graffiti --surface brick --logo ./logo.png
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Generate a Video Reel
|
|
76
|
+
```bash
|
|
77
|
+
xelta reel "a cinematic product reveal for a sports shoe"
|
|
78
|
+
xelta reel "drone shot over mountains" --image ./photo.jpg
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### AI Website Builder
|
|
82
|
+
```bash
|
|
83
|
+
xelta website build "A modern portfolio for a UX designer" --industry technology --pages "Home, About, Contact"
|
|
84
|
+
xelta website build "Coffee shop website" --industry food --pages "Home, Menu, Contact" --deploy
|
|
85
|
+
xelta website history
|
|
86
|
+
```
|
|
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
|
+
|
|
95
|
+
## All Options
|
|
96
|
+
|
|
97
|
+
| Command | Option | Description |
|
|
98
|
+
|---|---|---|
|
|
99
|
+
| `login` | `--token` | Paste JWT directly |
|
|
100
|
+
| `image` | `--model` | Skip model picker |
|
|
101
|
+
| `image` | `--size` | 1080p, 2K, or 4K |
|
|
102
|
+
| `image` | `--no-optimize` | Disable prompt enhancement |
|
|
103
|
+
| `mixboard` | `--num` | Number of images (default: 8) |
|
|
104
|
+
| `street-ad` | `--style` | auto, graffiti, stencil, wildstyle |
|
|
105
|
+
| `street-ad` | `--surface` | brick, wall, concrete |
|
|
106
|
+
| `street-ad` | `--logo` | Path or URL to logo |
|
|
107
|
+
| `reel` | `--image` | Path or URL to image |
|
|
108
|
+
| `website build` | `--industry` | technology, fashion, healthcare, etc. |
|
|
109
|
+
| `website build` | `--pages` | Comma-separated page list |
|
|
110
|
+
| `website build` | `--palette` | Color palette name or hex values |
|
|
111
|
+
| `website build` | `--logo` | Path or URL to logo |
|
|
112
|
+
| `website build` | `--deploy` | Deploy live to Vercel |
|
|
113
|
+
| `website history` | `--limit` | Number of results (default: 5) |
|
|
114
|
+
|
|
115
|
+
## Requirements
|
|
116
|
+
|
|
117
|
+
- Python 3.10+
|
|
118
|
+
- A valid Xelta account with credits
|
|
@@ -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.
|
|
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,102 +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
|
-
|
|
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")
|
|
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://
|
|
11
|
-
XELTA_TOKEN_URL = "https://
|
|
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"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|