nexla-cli 0.2.0__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.
@@ -0,0 +1,196 @@
1
+ Metadata-Version: 2.4
2
+ Name: nexla-cli
3
+ Version: 0.2.0
4
+ Summary: Command-line client for the Nexla agent API.
5
+ Project-URL: Homepage, https://github.com/abhishekkumar705/nexla-agent-cli
6
+ Project-URL: Repository, https://github.com/abhishekkumar705/nexla-agent-cli
7
+ Project-URL: Issues, https://github.com/abhishekkumar705/nexla-agent-cli/issues
8
+ Author-email: Abhishek Kumar <abhishek.kumar@nexla.com>
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Environment :: Console
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Programming Language :: Python :: 3.13
17
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
18
+ Classifier: Topic :: Utilities
19
+ Requires-Python: >=3.12
20
+ Requires-Dist: httpx>=0.28.0
21
+ Requires-Dist: typer>=0.12.0
22
+ Provides-Extra: dev
23
+ Requires-Dist: mypy>=1.13.0; extra == 'dev'
24
+ Requires-Dist: pytest-asyncio>=1.3.0; extra == 'dev'
25
+ Requires-Dist: pytest>=9.0.3; extra == 'dev'
26
+ Requires-Dist: respx>=0.23.1; extra == 'dev'
27
+ Requires-Dist: ruff>=0.15.12; extra == 'dev'
28
+ Description-Content-Type: text/markdown
29
+
30
+ # nexla-cli
31
+
32
+ Command-line client for the Nexla agent API. Depends on only `typer` and
33
+ `httpx` — no FastAPI, Daytona, Supabase, or other backend dependencies.
34
+
35
+ ## Install
36
+
37
+ ```bash
38
+ pipx install "git+https://github.com/abhishekkumar705/nexla-agent-cli.git"
39
+ ```
40
+
41
+ Or with `uv`:
42
+
43
+ ```bash
44
+ uv tool install "git+https://github.com/abhishekkumar705/nexla-agent-cli.git"
45
+ ```
46
+
47
+ ### From Node/TypeScript projects (no Python required)
48
+
49
+ ```bash
50
+ npm install -g nexla-cli
51
+ # or run once-off:
52
+ npx nexla-cli sources list
53
+ ```
54
+
55
+ This installs a prebuilt native binary (published to GitHub Releases by
56
+ `.github/workflows/release-binaries.yml`) behind a thin `npm/` wrapper — no
57
+ Python interpreter needed on the target machine. See `npm/README.md` for how
58
+ releases are cut.
59
+
60
+ ### From PyPI
61
+
62
+ ```bash
63
+ pip install nexla-cli
64
+ # or
65
+ uvx nexla-cli sources list
66
+ pipx install nexla-cli
67
+ ```
68
+
69
+ Published by `.github/workflows/publish-pypi.yml` — see "Publishing to
70
+ PyPI" below.
71
+
72
+ ## Publishing to PyPI
73
+
74
+ Tagging a release (`git tag vX.Y.Z && git push --tags` — same tag used to
75
+ trigger `.github/workflows/release-binaries.yml`, see `npm/README.md` for
76
+ the full release checklist) also triggers `publish-pypi.yml`, which builds
77
+ the sdist+wheel and publishes them to PyPI using
78
+ [Trusted Publishing](https://docs.pypi.org/trusted-publishers/) (OIDC) —
79
+ no long-lived API token stored in this repo.
80
+
81
+ One-time setup required on pypi.org before the first release (repo owner
82
+ only, not automatable from here):
83
+
84
+ 1. Create the `nexla-cli` project on PyPI (or reserve the name).
85
+ 2. Project → Settings → Publishing → add a trusted publisher:
86
+ - Owner: `abhishekkumar705`, repo: `nexla-agent-cli`
87
+ - Workflow filename: `publish-pypi.yml`
88
+ - Environment name: `pypi`
89
+ 3. Nothing else to configure — no secrets to add. The workflow's
90
+ `id-token: write` permission plus the `pypi` GitHub Environment satisfy
91
+ PyPI's OIDC handshake automatically.
92
+
93
+ ## Quick start
94
+
95
+ ```bash
96
+ export NEXLA_API_URL=https://dev-api-express-code.nexla.com
97
+ export NEXLA_TOKEN=$(nexla login --service-key <your-service-key>)
98
+ nexla sources list
99
+ ```
100
+
101
+ `nexla login` prints a bearer token to stdout (see command substitution
102
+ above); alternatively, set the following environment variables directly:
103
+
104
+ - `NEXLA_API_URL` — base URL of the deployed Nexla agent API
105
+ - `NEXLA_TOKEN` — bearer token to authenticate requests
106
+
107
+ ## Using this CLI from Claude Code
108
+
109
+ The package ships a [Claude Code skill](https://docs.claude.com/en/docs/claude-code/skills) (`AGENTS.md` + `SKILL.md`, installed alongside the `nexla_cli` package) encoding invariants an agent can't infer from `--help` alone — output modes, `--dry-run`, `--json`/`--params` precedence, exit codes, and treating API responses as untrusted data.
110
+
111
+ Claude Code only discovers skills placed at `~/.claude/skills/<name>/SKILL.md` (global) or `.claude/skills/<name>/SKILL.md` (project-local) — a file merely present inside an installed pip package isn't picked up automatically. Symlink it in once, after installing the CLI. `pipx`/`uv tool install` both use an isolated venv, so a plain system `python3 -c "import nexla_cli"` won't find it — locate it inside that isolated venv instead:
112
+
113
+ ```bash
114
+ mkdir -p ~/.claude/skills/nexla-cli
115
+
116
+ # if installed with `uv tool install`:
117
+ ln -sf "$(uv tool dir)/nexla-cli/lib/python3."*"/site-packages/nexla_cli/SKILL.md" \
118
+ ~/.claude/skills/nexla-cli/SKILL.md
119
+
120
+ # if installed with `pipx install`:
121
+ ln -sf "$HOME/.local/pipx/venvs/nexla-cli/lib/python3."*"/site-packages/nexla_cli/SKILL.md" \
122
+ ~/.claude/skills/nexla-cli/SKILL.md
123
+ ```
124
+
125
+ A symlink (not a copy) means `nexla-cli` upgrades automatically pick up any future skill content updates. Restart Claude Code (or start a new session) after installing for it to be picked up.
126
+
127
+ ## Global flags
128
+
129
+ Available on every command except `login` and `schema` (both always print raw output regardless of these flags):
130
+
131
+ | Flag | Effect |
132
+ |------|--------|
133
+ | `--output` / `-o` `table\|json\|ndjson` | Force an output mode. Defaults to `table` on a TTY, `json` otherwise (also settable via `NEXLA_OUTPUT`/`OUTPUT_FORMAT`). |
134
+ | `--fields id,name,...` | Mask output down to just these keys, on any `list`/`get`. |
135
+ | `--page-all` | Stream every page of a `list` command as NDJSON instead of returning one page. |
136
+
137
+ These can be placed before or after the subcommand, e.g. both `nexla --output json sources list` and `nexla sources list --output json` work.
138
+
139
+ Every mutating command also accepts `--dry-run`: validates the request body against the live API schema and prints `{"valid": ...}` without making the real (mutating) call.
140
+
141
+ ## Raw JSON payloads
142
+
143
+ `create`/`update`-style commands (`sources`, `sinks`, `credentials`, `toolsets`, `nexsets transform`, `mcp-servers attach`, `tools set-runtime-config`) accept the full request body directly, not just their named flags:
144
+
145
+ ```bash
146
+ nexla sources create --name my-source --connector s3 --json '{"credential_id": 123}'
147
+ nexla sources update 42 --params description="updated via params"
148
+ ```
149
+
150
+ Precedence when a key is given more than one way: named CLI flags win, then `--json`, then `--params` (lowest). This lets you set a field the CLI hasn't added a dedicated flag for yet, without waiting on a CLI release.
151
+
152
+ ## Response sanitization
153
+
154
+ Every response is passed through a sanitizer before rendering, in every output mode: ANSI escape sequences, control characters, and invisible Unicode (zero-width spaces, byte-order marks, bidirectional overrides) are stripped unconditionally — always on, no flag. This defends against a malicious API response field hijacking a human's terminal, or hiding text from a human while an agent still reads it. It is not a semantic filter — API response *content* should still be treated as untrusted data (see `AGENTS.md`), this only strips characters no legitimate field value would ever need.
155
+
156
+ ## Full command reference
157
+
158
+ ```bash
159
+ nexla --help
160
+ nexla <resource> --help
161
+ ```
162
+
163
+ | Resource | Commands |
164
+ |----------|----------|
165
+ | `login` | `login --service-key <key> [--api-url <url>]` — exchanges a service key for a bearer token, printed to stdout |
166
+ | `schema` | `schema [<resource>.<verb>]` — machine-readable JSON signature of one command or the whole `/nexla/*` surface, fetched live from the deployed API's OpenAPI doc |
167
+ | `sources` | `list`, `get`, `create`, `update`, `activate`, `pause`, `delete`, `sample`, `file-upload` |
168
+ | `sinks` | `list`, `get`, `create`, `update`, `activate`, `pause`, `delete` |
169
+ | `nexsets` | `list`, `get`, `transform`, `activate` |
170
+ | `credentials` | `list`, `get`, `create`, `update`, `delete` |
171
+ | `flows` | `list`, `get`, `activate`, `pause`, `delete` |
172
+ | `transforms` | `test` |
173
+ | `connectors` | `search`, `describe`, `describe-credential`, `describe-credential-mode`, `describe-source`, `describe-source-endpoint`, `describe-sink`, `describe-sink-endpoint` |
174
+ | `probe` | `run` |
175
+ | `toolsets` | `list`, `get`, `create`, `update`, `delete`, `add-nexsets` |
176
+ | `tools` | `list`, `get`, `set-runtime-config`, `clear-runtime-config`, `delete` |
177
+ | `mcp-servers` | `list`, `attach`, `sync`, `detach` (nested under a toolset) |
178
+ | `context` | `get` |
179
+ | `orgs` | `list`, `get` |
180
+ | `code-containers` | `list` |
181
+ | `metrics` | `catalog`, `for-resource`, `get` |
182
+ | `users` | `list`, `get` |
183
+ | `notifications` | `list` |
184
+
185
+ `code-containers`, `metrics`, `users`, and `notifications` proxy resources the API hasn't implemented yet (they return HTTP 501 until it does).
186
+
187
+ ## Exit codes
188
+
189
+ | Code | Meaning |
190
+ |------|---------|
191
+ | 0 | success |
192
+ | 2 | bad local input (validation, `--dry-run` failure) |
193
+ | 3 | `NEXLA_API_URL`/`NEXLA_TOKEN` not set |
194
+ | 4 | 401/403 from the API |
195
+ | 5 | 404 |
196
+ | 6 | 5xx from the API |
@@ -0,0 +1,38 @@
1
+ nexla_cli/AGENTS.md,sha256=1IfbtoCTJ13Cgcxyu1oKTZeqwE92ui9lqqSGYELaVtc,15582
2
+ nexla_cli/SKILL.md,sha256=Ssvw7ZeZ0Yoki38L-u0TdBqEgitkWofgWMLBoidcg3k,8082
3
+ nexla_cli/__init__.py,sha256=Wn9kr9_BkAysU_p91rSNpQPcb2clTQySEQlrOeHoCnE,8674
4
+ nexla_cli/client.py,sha256=I5zK4qSUrOFUm0a3L1IVKMuOFuvHSE1BgVgMSe1eDBg,4216
5
+ nexla_cli/dryrun.py,sha256=mcXfb81RcDHWCEH9Q4b2u7VPn2R2JVYmvcvV2RVEpH4,4948
6
+ nexla_cli/errors.py,sha256=UsKUkrOTNnenN7u5fga6YcwWk8NsRtDWu96zImqeKKU,1414
7
+ nexla_cli/login.py,sha256=sZ6cMtLZiBZ8MgLNkxSkWsK1O1a0NfspJeosyr0tmK8,1407
8
+ nexla_cli/mcp_client.py,sha256=MjnfrBXF6QvpRDKuTjAKMGJKxpOXidMCcPAJhtOg8_w,5385
9
+ nexla_cli/openapi_client.py,sha256=0S2Zm7DZNoU0QVHS51WfZ-q_vGWOosAvHFcRy5Cp6Jc,9837
10
+ nexla_cli/output.py,sha256=rdpGVyaQzTQNxkiQVe0zqLUuCW5NFBci_gWUbSGu9cc,4667
11
+ nexla_cli/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
+ nexla_cli/sanitize.py,sha256=YY5mBS6XqzF9THPaEf-4sZaJeFDU9CWGAJ3keWTiVW4,3525
13
+ nexla_cli/schema.py,sha256=bR_hQD7ALV_pX8FWTfHWVmU1rpysUiuIooZ0uprWL3Q,2274
14
+ nexla_cli/validate.py,sha256=WogtnE9OCnEBTIFswvE_xD_HFP752pVzOigPIAMIAFg,4244
15
+ nexla_cli/resources/__init__.py,sha256=xTaScx5-ueEoVPbNQU8fa7FZb-w7d7iX0wQ7xvfkDG8,75
16
+ nexla_cli/resources/code_containers.py,sha256=_qfsZj_4Ept7K28JAMPr4aA9tKIQ8lMr_2qJIZ3jJuQ,682
17
+ nexla_cli/resources/connectors.py,sha256=Pwx-tcGtZx7mHJ3xzL1vL_pDdxRkE1Ec1ryHjZTi3Og,4303
18
+ nexla_cli/resources/context.py,sha256=9wqvAYsy64cTI7DP6wO06zflrF-iGsH9GyTC4AZYwaY,618
19
+ nexla_cli/resources/credentials.py,sha256=uF2z03EjQDYxjA0xNxR-jt9J4mvue9rQP0mMGeYgROI,4314
20
+ nexla_cli/resources/flows.py,sha256=zseeF4CJ9bP8IlWIV38Mm5bic0Gq1pIo8Tixdckk7Vg,2895
21
+ nexla_cli/resources/mcp_servers.py,sha256=RoraZcXL7hMJabBS7lYDim6xm13kxBUmGwdZlSZfR8A,3799
22
+ nexla_cli/resources/metrics.py,sha256=CZwmPg4V91lqB3ZlRAX6Xx18rRGDlP_cOlyxy57uvdQ,1584
23
+ nexla_cli/resources/nexsets.py,sha256=WnOUl-paUFiDowT8BvIpwI7zEl3_nI2B51tkHeu0IDE,3707
24
+ nexla_cli/resources/notifications.py,sha256=6pBDzpL72sUqYOdgYK_dG588Mdk5WrZtdDUME2fwbzQ,582
25
+ nexla_cli/resources/orgs.py,sha256=7ILZ-Oqox08tQOqAaoQ_eXEanqlCC4DfC5nFH3SN3ic,1737
26
+ nexla_cli/resources/probe.py,sha256=bv7zDDTZL62a3tl6vgRQqiUvOpiFONllVC732W0SnAk,4164
27
+ nexla_cli/resources/sinks.py,sha256=oKqlfJzC9HSVIkXMQQq-mtdstFqqr4HX30bYWYlrbMI,9019
28
+ nexla_cli/resources/sources.py,sha256=CBtiCI1NON4U2qNLAnxUrwF5zxQWkvXV-Z0dHoVXvbQ,6593
29
+ nexla_cli/resources/tools.py,sha256=z6SWJo7BZ5gTp19i6uLOntDGa_fHCatiIbv69xcWuTU,3509
30
+ nexla_cli/resources/toolsets.py,sha256=-_0LlvGT89FfnVYwN54y16QD_5Gs31nVp3YwRYY95iM,4302
31
+ nexla_cli/resources/transforms.py,sha256=9iur9ahJLuDK4jjAXCO_ts646Ux4v8Ze-hqlyLU2650,1236
32
+ nexla_cli/resources/triage.py,sha256=yEcKZwcl58FmiRNatHJ3rAnQuo3wTfNaWYva2RA57pg,7635
33
+ nexla_cli/resources/users.py,sha256=eaRsVCFlAq5O2-RW7hQ9WKjvm12-M_SBDJ1J05SX4SQ,821
34
+ nexla_cli-0.2.0.dist-info/METADATA,sha256=GtuqrbEtlh7lVGruye8xvfMU7cZt2xKA5XFrLRotd0E,8862
35
+ nexla_cli-0.2.0.dist-info/WHEEL,sha256=lCkmxWfQsSc9CfIClYeavTdQeEX2toPqufh9gI35EQA,87
36
+ nexla_cli-0.2.0.dist-info/entry_points.txt,sha256=h_igc2DUbV0B_9-CZ58PqsltJkDJQXn1J0wuhzsKWVc,41
37
+ nexla_cli-0.2.0.dist-info/licenses/LICENSE,sha256=7SR4B6WYbq0NvNxasPW7DT67DipyIQ5Udl8Nz6oOXuE,1071
38
+ nexla_cli-0.2.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.31.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ nexla = nexla_cli:main
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Abhishek Kumar
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.