superwise-sentinel-cli 0.3.0__tar.gz → 0.3.1__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 (28) hide show
  1. {superwise_sentinel_cli-0.3.0 → superwise_sentinel_cli-0.3.1}/CHANGELOG.md +12 -0
  2. {superwise_sentinel_cli-0.3.0 → superwise_sentinel_cli-0.3.1}/PKG-INFO +1 -1
  3. superwise_sentinel_cli-0.3.1/build.env +1 -0
  4. {superwise_sentinel_cli-0.3.0 → superwise_sentinel_cli-0.3.1}/pyproject.toml +1 -1
  5. {superwise_sentinel_cli-0.3.0 → superwise_sentinel_cli-0.3.1}/src/superwise_sentinel_cli/cli.py +34 -10
  6. {superwise_sentinel_cli-0.3.0 → superwise_sentinel_cli-0.3.1}/src/superwise_sentinel_cli/controller.py +16 -0
  7. {superwise_sentinel_cli-0.3.0 → superwise_sentinel_cli-0.3.1}/src/superwise_sentinel_cli/docker_manager.py +8 -0
  8. superwise_sentinel_cli-0.3.0/build.env +0 -1
  9. {superwise_sentinel_cli-0.3.0 → superwise_sentinel_cli-0.3.1}/.gitignore +0 -0
  10. {superwise_sentinel_cli-0.3.0 → superwise_sentinel_cli-0.3.1}/.gitlab-ci.yml +0 -0
  11. {superwise_sentinel_cli-0.3.0 → superwise_sentinel_cli-0.3.1}/.pre-commit-config.yaml +0 -0
  12. {superwise_sentinel_cli-0.3.0 → superwise_sentinel_cli-0.3.1}/.releaserc.json +0 -0
  13. {superwise_sentinel_cli-0.3.0 → superwise_sentinel_cli-0.3.1}/CLAUDE.md +0 -0
  14. {superwise_sentinel_cli-0.3.0 → superwise_sentinel_cli-0.3.1}/README.md +0 -0
  15. {superwise_sentinel_cli-0.3.0 → superwise_sentinel_cli-0.3.1}/poetry.lock +0 -0
  16. {superwise_sentinel_cli-0.3.0 → superwise_sentinel_cli-0.3.1}/poetry.toml +0 -0
  17. {superwise_sentinel_cli-0.3.0 → superwise_sentinel_cli-0.3.1}/scripts/semantic-release-cli-publish.sh +0 -0
  18. {superwise_sentinel_cli-0.3.0 → superwise_sentinel_cli-0.3.1}/src/superwise_sentinel_cli/__init__.py +0 -0
  19. {superwise_sentinel_cli-0.3.0 → superwise_sentinel_cli-0.3.1}/src/superwise_sentinel_cli/auth.py +0 -0
  20. {superwise_sentinel_cli-0.3.0 → superwise_sentinel_cli-0.3.1}/src/superwise_sentinel_cli/codex_profile.py +0 -0
  21. {superwise_sentinel_cli-0.3.0 → superwise_sentinel_cli-0.3.1}/src/superwise_sentinel_cli/config.py +0 -0
  22. {superwise_sentinel_cli-0.3.0 → superwise_sentinel_cli-0.3.1}/src/superwise_sentinel_cli/exceptions.py +0 -0
  23. {superwise_sentinel_cli-0.3.0 → superwise_sentinel_cli-0.3.1}/src/superwise_sentinel_cli/shell_profile.py +0 -0
  24. {superwise_sentinel_cli-0.3.0 → superwise_sentinel_cli-0.3.1}/tests/__init__.py +0 -0
  25. {superwise_sentinel_cli-0.3.0 → superwise_sentinel_cli-0.3.1}/tests/test_auth.py +0 -0
  26. {superwise_sentinel_cli-0.3.0 → superwise_sentinel_cli-0.3.1}/tests/test_controller.py +0 -0
  27. {superwise_sentinel_cli-0.3.0 → superwise_sentinel_cli-0.3.1}/tests/test_docker_manager.py +0 -0
  28. {superwise_sentinel_cli-0.3.0 → superwise_sentinel_cli-0.3.1}/tests/test_shell_profile.py +0 -0
@@ -1,3 +1,15 @@
1
+ ## [0.3.0](https://gitlab.com/askboss/product/superwise/platform/sentinel-cli/compare/0.2.3...0.3.0) (2026-09-16)
2
+
3
+
4
+ ### <!-- 1. -->:rocket: New Features
5
+
6
+ * configure codex ([16acd79](https://gitlab.com/askboss/product/superwise/platform/sentinel-cli/commit/16acd797fa82669ec3d195fbee8c50e1b4ab0055))
7
+
8
+
9
+ ### <!-- 2. -->:bug: Bug Fixes
10
+
11
+ * configure sentinel-cli request timeout ([a2597b7](https://gitlab.com/askboss/product/superwise/platform/sentinel-cli/commit/a2597b742136bb5b05baa046e2a13340b75577cc))
12
+
1
13
  ## [0.2.3](https://gitlab.com/askboss/product/superwise/platform/sentinel-cli/compare/0.2.2...0.2.3) (2026-08-25)
2
14
 
3
15
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: superwise-sentinel-cli
3
- Version: 0.3.0
3
+ Version: 0.3.1
4
4
  Summary: Sentinel is an LLM proxy that intercepts traffic, enabling you to monitor, secure, and optimize your AI usage. This CLI tool helps you quickly set up traffic interception on this machine
5
5
  Requires-Python: <4.0,>=3.11
6
6
  Requires-Dist: click>=8.1
@@ -0,0 +1 @@
1
+ RELEASED_VERSION=0.3.1
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "superwise-sentinel-cli"
7
- version = "0.3.0"
7
+ version = "0.3.1"
8
8
  description = "Sentinel is an LLM proxy that intercepts traffic, enabling you to monitor, secure, and optimize your AI usage. This CLI tool helps you quickly set up traffic interception on this machine"
9
9
  requires-python = ">=3.11, <4.0"
10
10
  dependencies = [
@@ -13,6 +13,7 @@ from superwise_sentinel_cli.config import AppConfig
13
13
  from superwise_sentinel_cli.config import CustomProvider
14
14
  from superwise_sentinel_cli.config import VALID_APPS
15
15
  from superwise_sentinel_cli.config import VALID_PROVIDERS
16
+ from superwise_sentinel_cli.controller import check_gateway_health
16
17
  from superwise_sentinel_cli.controller import check_invalid_apps
17
18
  from superwise_sentinel_cli.controller import check_invalid_providers
18
19
  from superwise_sentinel_cli.controller import clear_env_vars
@@ -20,6 +21,7 @@ from superwise_sentinel_cli.controller import get_activation_url
20
21
  from superwise_sentinel_cli.controller import get_proxy_status
21
22
  from superwise_sentinel_cli.controller import get_running_gateway
22
23
  from superwise_sentinel_cli.controller import get_sentinel_url
24
+ from superwise_sentinel_cli.controller import is_docker_running
23
25
  from superwise_sentinel_cli.controller import needs_auth
24
26
  from superwise_sentinel_cli.controller import parse_apps
25
27
  from superwise_sentinel_cli.controller import parse_providers
@@ -105,10 +107,20 @@ def main() -> None:
105
107
  @click.pass_context
106
108
  def quickstart_flow(ctx, new_sentinel: bool) -> None:
107
109
  """Configure your first sentinel proxy."""
108
- if new_sentinel or not click.confirm("Do you want to use an existing gateway?"):
110
+ click.echo(
111
+ """Welcome to SUPERWISE Sentinel!
112
+ The Sentinel proxy routes your local LLM traffic through a secure gateway, enabling guardrails and optimizations.
113
+ Select your gateway setup:
114
+ A) Provide the URL for an existing gateway.
115
+ B) Create a new gateway locally. Docker needs to be installed and running on this machine."""
116
+ )
117
+ if new_sentinel or not click.confirm("Do you have a URL for an existing gateway?"):
109
118
  ctx.invoke(start_gateway, new_sentinel=new_sentinel)
110
119
  else:
111
120
  ctx.invoke(config_url)
121
+ gateway_text = click.style("gateway", fg="green")
122
+ proxy_text = click.style("proxy", fg="yellow")
123
+ click.echo(f"\nWith the {gateway_text} ready, let's customize our {proxy_text} traffic routing.")
112
124
  ctx.invoke(config_providers)
113
125
  ctx.invoke(config_apps)
114
126
  ctx.invoke(start_proxy)
@@ -210,7 +222,9 @@ def start_gateway(
210
222
  force: bool,
211
223
  timeout_seconds: int | None,
212
224
  ) -> None:
213
- """Bootstrap & run a local Sentinel gateway container."""
225
+ """Bootstrap & run a local Sentinel gateway container. Accessible only from this machine."""
226
+ if not is_docker_running():
227
+ raise click.ClickException("Docker is not responsive. Is it running?")
214
228
  cfg = AppConfig.load()
215
229
 
216
230
  if custom_providers:
@@ -259,13 +273,16 @@ def start_gateway(
259
273
 
260
274
  if created_name:
261
275
  click.echo(f"New sentinel '{created_name}' created. Sentinel ID: {cfg.sentinel_id}.")
276
+ local_notice = click.style("This gateway is local, and accessible only from this machine.", fg="cyan")
262
277
  click.echo(
263
- f"Gateway running on {url} with sentinel ID: {cfg.sentinel_id}. Configuration updated to match."
278
+ f"Gateway created and running on {url}!"
264
279
  f"\nTo view Sentinel configuration and metrics, please visit {get_sentinel_url(cfg)}"
280
+ f"\n{local_notice}"
265
281
  )
266
282
  if timeout_seconds is not None:
267
283
  click.echo(f"Timeout set to {timeout_seconds} seconds.")
268
- click.echo("Want to test it out? Run 'sentinel test --text \"Your text here\"' to see it in action.")
284
+ test_command = click.style('sentinel test --text "Your text here"', italic=True)
285
+ click.echo(f"\nWant to test it out? Run '{test_command}' to see it in action.")
269
286
 
270
287
 
271
288
  @gateway.command("stop")
@@ -296,7 +313,12 @@ def update_gateway() -> None:
296
313
  click.echo("Image is up to date.")
297
314
 
298
315
 
299
- @main.group("config", invoke_without_command=True)
316
+ @main.group()
317
+ def proxy() -> None:
318
+ """Toggle traffic interception."""
319
+
320
+
321
+ @proxy.group("config", invoke_without_command=True)
300
322
  @click.option("--url", "url_value", default=None, help="Set the gateway URL non-interactively.")
301
323
  @click.option(
302
324
  "--providers",
@@ -412,11 +434,6 @@ def config_apps(set_value: str | None) -> None:
412
434
  break
413
435
 
414
436
 
415
- @main.group()
416
- def proxy() -> None:
417
- """Toggle traffic interception."""
418
-
419
-
420
437
  @proxy.command("on")
421
438
  @click.pass_context
422
439
  def start_proxy(ctx) -> None:
@@ -429,6 +446,13 @@ def start_proxy(ctx) -> None:
429
446
  if not cfg.providers:
430
447
  ctx.invoke(config_providers)
431
448
 
449
+ if not check_gateway_health(cfg.gateway_url):
450
+ click.echo(
451
+ f"Gateway at {cfg.gateway_url} did not respond in a timely manner."
452
+ f" Please verify it is healthy and try again."
453
+ )
454
+ return
455
+
432
456
  cfg = AppConfig.load()
433
457
  pairs = update_env_vars(cfg)
434
458
 
@@ -2,6 +2,7 @@ from __future__ import annotations
2
2
 
3
3
  import json
4
4
  import os
5
+ import time
5
6
 
6
7
  import requests
7
8
  from superwise_sentinel_cli.auth import authenticate
@@ -14,6 +15,7 @@ from superwise_sentinel_cli.config import VALID_APPS
14
15
  from superwise_sentinel_cli.config import VALID_PROVIDERS
15
16
  from superwise_sentinel_cli.docker_manager import ensure_container_running
16
17
  from superwise_sentinel_cli.docker_manager import get_running_gateway_info
18
+ from superwise_sentinel_cli.docker_manager import is_docker_running
17
19
  from superwise_sentinel_cli.docker_manager import pull_latest_image
18
20
  from superwise_sentinel_cli.docker_manager import stop_container
19
21
  from superwise_sentinel_cli.exceptions import AuthenticationError
@@ -156,6 +158,20 @@ def update_env_vars(cfg: AppConfig) -> list[tuple[str, str]]:
156
158
  return pairs
157
159
 
158
160
 
161
+ def check_gateway_health(gateway_url: str, retries: int = 3, delay_seconds: float = 1.0) -> bool:
162
+ url = gateway_url.rstrip("/") + "/healthz"
163
+ for attempt in range(retries):
164
+ try:
165
+ resp = requests.get(url, timeout=5)
166
+ if resp.ok:
167
+ return True
168
+ except requests.RequestException:
169
+ pass
170
+ if attempt < retries - 1:
171
+ time.sleep(delay_seconds)
172
+ return False
173
+
174
+
159
175
  def write_codex_config(cfg: AppConfig) -> bool:
160
176
  if "openai" not in cfg.providers or "codex" not in cfg.apps:
161
177
  return False
@@ -35,6 +35,14 @@ def _docker_client() -> docker.DockerClient:
35
35
  raise DockerUnavailableError() from exc
36
36
 
37
37
 
38
+ def is_docker_running() -> bool:
39
+ try:
40
+ _docker_client()
41
+ return True
42
+ except DockerUnavailableError:
43
+ return False
44
+
45
+
38
46
  def _running_container(client: docker.DockerClient) -> Container | None:
39
47
  matches = client.containers.list(filters={"name": CONTAINER_NAME, "status": "running"})
40
48
  return matches[0] if matches else None
@@ -1 +0,0 @@
1
- RELEASED_VERSION=0.3.0