uno-cli 1.0.2__tar.gz → 1.0.3__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.
@@ -20,3 +20,7 @@ data_export/
20
20
  data_export_prod/
21
21
  scripts/backup_prod*.json
22
22
  .mcp_auth/
23
+ .cursor/
24
+ .worktrees/
25
+ skills/.skills_store_lock.json
26
+ test_gpt_image2.py
@@ -1,9 +1,9 @@
1
- Metadata-Version: 2.4
1
+ Metadata-Version: 2.5
2
2
  Name: uno-cli
3
- Version: 1.0.2
3
+ Version: 1.0.3
4
4
  Summary: Uno CLI — Agent tool gateway by ClawdChat. Access 2000+ real-world tools from the command line.
5
- Project-URL: Homepage, https://clawdtools.uno
6
- Project-URL: Documentation, https://clawdtools.uno/docs
5
+ Project-URL: Homepage, https://agentools.uno
6
+ Project-URL: Documentation, https://agentools.uno/docs
7
7
  Project-URL: Repository, https://github.com/xray918/uno-mcp-cli
8
8
  Project-URL: Issues, https://github.com/xray918/uno-mcp-cli/issues
9
9
  Author-email: ClawdChat <dev@clawdchat.cn>
@@ -77,7 +77,7 @@ All commands output JSON. Add `--compact` for single-line output (fewer tokens f
77
77
  | Variable | Purpose |
78
78
  |---|---|
79
79
  | `UNO_API_KEY` | Override stored credentials (useful for CI). |
80
- | `UNO_API_URL` | Override API base URL (default `https://clawdtools.uno`). |
80
+ | `UNO_API_URL` | Override API base URL (default `https://agentools.uno`; legacy host `https://clawdtools.uno` still serves `/v1` and `/mcp`). |
81
81
  | `UNO_OAUTH_SCOPE` | OAuth scope requested at `login --start` (default `mcp:*`). Single-purpose skills narrow this to `mcp:<tool>`. |
82
82
  | `UNO_ALLOWED_TOOLS` | Comma-separated glob whitelist enforced by `uno call`. Tools not matching any pattern are rejected with `tool_not_allowed`. Example: `gpt-image-2.*,time.*`. |
83
83
  | `UNO_CALLER_SKILL` | Identifier (e.g. `gpt-image2`) appended to the `User-Agent` for attribution. |
@@ -46,7 +46,7 @@ All commands output JSON. Add `--compact` for single-line output (fewer tokens f
46
46
  | Variable | Purpose |
47
47
  |---|---|
48
48
  | `UNO_API_KEY` | Override stored credentials (useful for CI). |
49
- | `UNO_API_URL` | Override API base URL (default `https://clawdtools.uno`). |
49
+ | `UNO_API_URL` | Override API base URL (default `https://agentools.uno`; legacy host `https://clawdtools.uno` still serves `/v1` and `/mcp`). |
50
50
  | `UNO_OAUTH_SCOPE` | OAuth scope requested at `login --start` (default `mcp:*`). Single-purpose skills narrow this to `mcp:<tool>`. |
51
51
  | `UNO_ALLOWED_TOOLS` | Comma-separated glob whitelist enforced by `uno call`. Tools not matching any pattern are rejected with `tool_not_allowed`. Example: `gpt-image-2.*,time.*`. |
52
52
  | `UNO_CALLER_SKILL` | Identifier (e.g. `gpt-image2`) appended to the `User-Agent` for attribution. |
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "uno-cli"
3
- version = "1.0.2"
3
+ version = "1.0.3"
4
4
  description = "Uno CLI — Agent tool gateway by ClawdChat. Access 2000+ real-world tools from the command line."
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.8"
@@ -35,8 +35,8 @@ classifiers = [
35
35
  dependencies = []
36
36
 
37
37
  [project.urls]
38
- Homepage = "https://clawdtools.uno"
39
- Documentation = "https://clawdtools.uno/docs"
38
+ Homepage = "https://agentools.uno"
39
+ Documentation = "https://agentools.uno/docs"
40
40
  Repository = "https://github.com/xray918/uno-mcp-cli"
41
41
  Issues = "https://github.com/xray918/uno-mcp-cli/issues"
42
42
 
@@ -39,6 +39,22 @@ class TestPreprocessArgv:
39
39
  # ── Parser structure ───────────────────────────────────────────────
40
40
 
41
41
 
42
+ class TestDefaultBase:
43
+ def test_default_base_is_agentools(self):
44
+ assert cli.DEFAULT_BASE == "https://agentools.uno"
45
+ assert cli.LEGACY_BASE == "https://clawdtools.uno"
46
+
47
+ def test_parser_defaults_to_agentools(self, monkeypatch):
48
+ monkeypatch.delenv("UNO_API_URL", raising=False)
49
+ args = cli.build_parser().parse_args(["whoami"])
50
+ assert args.base_url == "https://agentools.uno"
51
+
52
+ def test_env_overrides_default(self, monkeypatch):
53
+ monkeypatch.setenv("UNO_API_URL", "https://clawdtools.uno")
54
+ args = cli.build_parser().parse_args(["whoami"])
55
+ assert args.base_url == "https://clawdtools.uno"
56
+
57
+
42
58
  class TestParser:
43
59
  def test_version_flag_matches_package(self, capsys):
44
60
  parser = cli.build_parser()
@@ -55,7 +71,8 @@ class TestParser:
55
71
  )
56
72
  expected = {
57
73
  "login", "logout", "use", "whoami", "search", "tool",
58
- "call", "rate", "servers", "keys", "health", "disconnect",
74
+ "call", "rate", "servers", "keys", "health",
75
+ "disconnect", "connections", "auth", "logs",
59
76
  }
60
77
  assert expected <= set(subparsers_action.choices.keys())
61
78
 
@@ -121,6 +138,23 @@ class TestErrorHints:
121
138
  out = cli._format_api_error(500, "server exploded")
122
139
  assert out["error"] == "server exploded"
123
140
 
141
+ def test_missing_credentials_points_to_login_start(self, capsys, monkeypatch, tmp_path):
142
+ cred_dir = tmp_path / ".uno"
143
+ monkeypatch.setattr(cli, "CRED_DIR", str(cred_dir))
144
+ monkeypatch.setattr(cli, "CRED_FILE", str(cred_dir / "credentials.json"))
145
+ monkeypatch.delenv("UNO_API_KEY", raising=False)
146
+ args = type("Args", (), {"base_url": "https://example.invalid"})()
147
+ with pytest.raises(SystemExit) as ei:
148
+ cli._get_api(args)
149
+ assert ei.value.code == 1
150
+ payload = json.loads(capsys.readouterr().out)
151
+ assert payload["error"] == "Not logged in. Run: uno login --start"
152
+
153
+ def test_auth_error_hints_point_to_login_start(self):
154
+ for msg in ("unauthorized", "invalid credentials", "invalid api key"):
155
+ hint = cli._match_hint(msg)
156
+ assert "uno login --start" in hint
157
+
124
158
 
125
159
  # ── JSON output shape of _out ──────────────────────────────────────
126
160
 
@@ -0,0 +1,148 @@
1
+ """CLI unit tests for `uno logs --last 20` and `uno connections`."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import json
6
+ from types import SimpleNamespace
7
+
8
+ import pytest
9
+
10
+ from uno_cli import cli
11
+
12
+
13
+ class _FakeAPI:
14
+ def __init__(self, payload):
15
+ self.payload = payload
16
+ self.calls = []
17
+
18
+ def get(self, path, params=None):
19
+ self.calls.append((path, params))
20
+ return self.payload
21
+
22
+
23
+ def _args(**extra):
24
+ base = {"base_url": "https://clawdtools.uno", "reconnect": None, "last": 20}
25
+ base.update(extra)
26
+ return SimpleNamespace(**base)
27
+
28
+
29
+ class TestConnectionsCommand:
30
+ def test_lists_connections(self, monkeypatch, capsys):
31
+ payload = {
32
+ "connections": [
33
+ {
34
+ "slug": "github",
35
+ "name": "GitHub",
36
+ "auth_type": "oauth2",
37
+ "connected": False,
38
+ "status": "missing",
39
+ "auth_url": "https://clawdtools.uno/oauth/start/github",
40
+ "platform_held": False,
41
+ },
42
+ {
43
+ "slug": "brave-search",
44
+ "auth_type": "none",
45
+ "connected": True,
46
+ "status": "active",
47
+ "platform_held": True,
48
+ "auth_url": None,
49
+ },
50
+ ],
51
+ "total": 2,
52
+ }
53
+ fake = _FakeAPI(payload)
54
+ monkeypatch.setattr(cli, "_get_api", lambda args: fake)
55
+ cli._out.compact = False
56
+ cli.cmd_connections(_args())
57
+ out = json.loads(capsys.readouterr().out)
58
+ assert out["success"] is True
59
+ assert out["data"]["total"] == 2
60
+ assert fake.calls == [("/v1/auth/connections", None)]
61
+
62
+ def test_reconnect_prints_auth_url(self, monkeypatch, capsys):
63
+ payload = {
64
+ "connections": [
65
+ {
66
+ "slug": "github",
67
+ "status": "expired",
68
+ "connected": False,
69
+ "auth_url": "https://clawdtools.uno/oauth/start/github",
70
+ "platform_held": False,
71
+ }
72
+ ]
73
+ }
74
+ fake = _FakeAPI(payload)
75
+ monkeypatch.setattr(cli, "_get_api", lambda args: fake)
76
+ cli.cmd_connections(_args(reconnect="github"))
77
+ out = json.loads(capsys.readouterr().out)
78
+ assert out["data"]["auth_url"] == "https://clawdtools.uno/oauth/start/github"
79
+ assert "hint" in out["data"]
80
+
81
+ def test_auth_list_alias(self, monkeypatch, capsys):
82
+ fake = _FakeAPI({"connections": [], "total": 0})
83
+ monkeypatch.setattr(cli, "_get_api", lambda args: fake)
84
+ cli.cmd_auth(SimpleNamespace(base_url="https://x", auth_action="list", reconnect=None))
85
+ out = json.loads(capsys.readouterr().out)
86
+ assert out["success"] is True
87
+ assert fake.calls[0][0] == "/v1/auth/connections"
88
+
89
+
90
+ class TestLogsCommand:
91
+ def test_logs_last_20_hits_history(self, monkeypatch, capsys):
92
+ payload = {
93
+ "records": [
94
+ {
95
+ "tool": "brave-search.web_search",
96
+ "latency_ms": 12,
97
+ "credits": 1.0,
98
+ "success": True,
99
+ "error_code": None,
100
+ "created_at": "2026-08-30T00:00:00",
101
+ "request_params": {"q": "secret-payload"},
102
+ }
103
+ ],
104
+ "total": 1,
105
+ }
106
+ fake = _FakeAPI(payload)
107
+ monkeypatch.setattr(cli, "_get_api", lambda args: fake)
108
+ cli.cmd_logs(_args(last=20))
109
+ path, params = fake.calls[0]
110
+ assert path == "/v1/usage/history"
111
+ assert params == {"limit": 20, "days": 7}
112
+ out = json.loads(capsys.readouterr().out)
113
+ rec = out["data"]["records"][0]
114
+ assert rec["tool"] == "brave-search.web_search"
115
+ assert rec["success"] is True
116
+ assert "request_params" not in rec
117
+ assert out["data"]["days"] == 7
118
+
119
+ def test_parser_registers_logs_and_connections(self):
120
+ parser = cli.build_parser()
121
+ logs = parser.parse_args(["logs", "--last", "20"])
122
+ assert logs.command == "logs"
123
+ assert logs.last == 20
124
+ conn = parser.parse_args(["connections", "--reconnect", "github"])
125
+ assert conn.command == "connections"
126
+ assert conn.reconnect == "github"
127
+
128
+
129
+ class TestSearchPrintsStats:
130
+ def test_search_output_includes_success_rate_and_calls_7d(self, monkeypatch, capsys):
131
+ payload = {
132
+ "tools": [
133
+ {
134
+ "tool": "weather.get",
135
+ "stats": {"success_rate": 0.95, "calls_7d": 12, "avg_ms": 80, "rating": 4.5},
136
+ }
137
+ ],
138
+ "total": 1,
139
+ }
140
+ fake = _FakeAPI(payload)
141
+ monkeypatch.setattr(cli, "_get_public_api", lambda args: fake)
142
+ cli.cmd_search(SimpleNamespace(
143
+ query="weather", limit=5, mode=None, category=None, server=None, base_url="https://x",
144
+ ))
145
+ out = json.loads(capsys.readouterr().out)
146
+ stats = out["data"]["tools"][0]["stats"]
147
+ assert stats["success_rate"] == 0.95
148
+ assert stats["calls_7d"] == 12
@@ -0,0 +1,85 @@
1
+ """Tests for the ``uno register`` command."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import json
6
+
7
+ import pytest
8
+
9
+ from uno_cli import cli
10
+
11
+
12
+ class TestCmdRegister:
13
+ def _fake_api(self, monkeypatch, return_value=None, raise_error=None):
14
+ captured = {}
15
+
16
+ class _FakeAPI:
17
+ def __init__(self, api_key="", base_url=""):
18
+ self.api_key = api_key
19
+ captured["api_key"] = api_key
20
+
21
+ def post(self, path, data, timeout=60):
22
+ captured["path"] = path
23
+ captured["data"] = data
24
+ if raise_error:
25
+ raise raise_error
26
+ return return_value if return_value is not None else {"id": "u_1", "email": data["email"]}
27
+
28
+ monkeypatch.setattr(cli, "UnoAPI", _FakeAPI)
29
+ return captured
30
+
31
+ def test_register_posts_to_correct_endpoint(self, monkeypatch, capsys):
32
+ captured = self._fake_api(monkeypatch)
33
+ cli.main(["register", "alice@example.com", "s3cr3tP@ss"])
34
+
35
+ assert captured["path"] == "/v1/auth/register"
36
+ assert captured["data"]["email"] == "alice@example.com"
37
+ assert captured["data"]["password"] == "s3cr3tP@ss"
38
+
39
+ def test_register_sends_name_when_provided(self, monkeypatch):
40
+ captured = self._fake_api(monkeypatch)
41
+ cli.main(["register", "bob@example.com", "p@ss", "--name", "Bob"])
42
+ assert captured["data"]["name"] == "Bob"
43
+
44
+ def test_register_name_defaults_to_empty_string(self, monkeypatch):
45
+ captured = self._fake_api(monkeypatch, return_value={})
46
+ cli.main(["register", "carol@example.com", "p@ss"])
47
+ assert captured["data"]["name"] == ""
48
+
49
+ def test_register_success_output_shape(self, monkeypatch, capsys):
50
+ self._fake_api(monkeypatch, return_value={"id": "u_1", "email": "alice@example.com", "name": ""})
51
+ cli.main(["register", "alice@example.com", "p@ss"])
52
+ out = json.loads(capsys.readouterr().out)
53
+ assert out["success"] is True
54
+ assert "data" in out
55
+
56
+ def test_register_409_conflict_exits_nonzero(self, monkeypatch, capsys):
57
+ self._fake_api(monkeypatch, raise_error=cli.APIError(409, {"detail": "Email already registered"}))
58
+ with pytest.raises(SystemExit) as exc:
59
+ cli.main(["register", "dup@example.com", "p@ss"])
60
+
61
+ assert exc.value.code != 0
62
+ out = json.loads(capsys.readouterr().out)
63
+ assert "error" in out
64
+ assert out["status"] == 409
65
+
66
+ def test_register_uses_no_auth_header(self, monkeypatch):
67
+ """register 是公开接口,不需要已存储的 API key."""
68
+ captured = self._fake_api(monkeypatch)
69
+ cli.main(["register", "new@example.com", "p@ss"])
70
+ assert captured["api_key"] == ""
71
+
72
+ def test_register_empty_response_returns_fallback(self, monkeypatch, capsys):
73
+ """服务端返回空 dict 时,fallback 输出包含 email."""
74
+ self._fake_api(monkeypatch, return_value={})
75
+ cli.main(["register", "x@example.com", "p@ss"])
76
+ out = json.loads(capsys.readouterr().out)
77
+ assert out["success"] is True
78
+ assert out["data"]["email"] == "x@example.com"
79
+
80
+ def test_register_subcommand_in_parser(self):
81
+ parser = cli.build_parser()
82
+ subparsers_action = next(
83
+ a for a in parser._actions if isinstance(a, cli.argparse._SubParsersAction)
84
+ )
85
+ assert "register" in subparsers_action.choices
@@ -0,0 +1 @@
1
+ __version__ = "1.0.3"
@@ -23,7 +23,8 @@ import urllib.request
23
23
 
24
24
  from uno_cli._version import __version__
25
25
 
26
- DEFAULT_BASE = "https://clawdtools.uno"
26
+ DEFAULT_BASE = "https://agentools.uno"
27
+ LEGACY_BASE = "https://clawdtools.uno"
27
28
  CRED_DIR = os.path.expanduser("~/.uno")
28
29
  CRED_FILE = os.path.join(CRED_DIR, "credentials.json")
29
30
 
@@ -458,9 +459,9 @@ _ERROR_HINTS = {
458
459
  "tool_not_found": "Tool not found. Try: uno search <keyword>",
459
460
  "insufficient_credits": "Out of credits. Visit the billing page.",
460
461
  "auth_required": "OAuth required. Open the auth_url in a browser.",
461
- "invalid api key": "API key expired or invalid. Run: uno login",
462
- "invalid credentials": "Login required. Run: uno login",
463
- "unauthorized": "Login required. Run: uno login",
462
+ "invalid api key": "API key expired or invalid. Run: uno login --start",
463
+ "invalid credentials": "Login required. Run: uno login --start",
464
+ "unauthorized": "Login required. Run: uno login --start",
464
465
  "rate limit": "Rate limited. Please wait and retry.",
465
466
  "not_found": "Resource not found. Check the ID/slug.",
466
467
  "not found": "Resource not found. Check the ID/slug.",
@@ -531,7 +532,7 @@ def _get_api(args):
531
532
  auth = AuthManager(base_url=args.base_url)
532
533
  key = auth.load_key()
533
534
  if not key:
534
- _fail("Not logged in. Run: uno login")
535
+ _fail("Not logged in. Run: uno login --start")
535
536
  return UnoAPI(api_key=key, base_url=args.base_url)
536
537
 
537
538
 
@@ -543,6 +544,23 @@ def _get_public_api(args):
543
544
  # ── Commands ───────────────────────────────────────────────────────
544
545
 
545
546
 
547
+ def cmd_register(args):
548
+ email = args.email
549
+ password = args.password
550
+ name = getattr(args, "name", "") or ""
551
+
552
+ api = UnoAPI(base_url=args.base_url)
553
+ try:
554
+ result = api.post("/v1/auth/register", {"email": email, "password": password, "name": name})
555
+ if isinstance(result, dict) and result.get("error"):
556
+ _out(result)
557
+ sys.exit(1)
558
+ _ok(result if result else {"registered": True, "email": email})
559
+ except APIError as e:
560
+ _out(_format_api_error(e.status, e.body))
561
+ sys.exit(1)
562
+
563
+
546
564
  def cmd_login(args):
547
565
  auth = AuthManager(base_url=args.base_url)
548
566
 
@@ -812,13 +830,72 @@ def cmd_health(args):
812
830
  sys.exit(1)
813
831
 
814
832
 
833
+ def cmd_connections(args):
834
+ """List third-party connections; --reconnect prints auth_url."""
835
+ api = _get_api(args)
836
+ reconnect = getattr(args, "reconnect", None)
837
+ try:
838
+ result = api.get("/v1/auth/connections")
839
+ if reconnect:
840
+ items = result.get("connections") if isinstance(result, dict) else result
841
+ match = next((c for c in (items or []) if c.get("slug") == reconnect), None)
842
+ if not match:
843
+ _fail(f"No connection for {reconnect}")
844
+ out = {
845
+ "slug": reconnect,
846
+ "status": match.get("status"),
847
+ "connected": match.get("connected"),
848
+ "platform_held": match.get("platform_held", False),
849
+ }
850
+ if match.get("auth_url"):
851
+ out["auth_url"] = match["auth_url"]
852
+ out["hint"] = "Open auth_url in a browser to reconnect."
853
+ _ok(out)
854
+ return
855
+ _ok(result)
856
+ except APIError as e:
857
+ _out(_format_api_error(e.status, e.body))
858
+ sys.exit(1)
859
+
860
+
861
+ def cmd_auth(args):
862
+ action = getattr(args, "auth_action", None) or "list"
863
+ if action == "list":
864
+ return cmd_connections(args)
865
+ _fail(f"Unknown auth action: {action}")
866
+
867
+
868
+ def cmd_logs(args):
869
+ """GET /v1/usage/history?limit=N&days=7 — compact call log."""
870
+ api = _get_api(args)
871
+ last = getattr(args, "last", 20) or 20
872
+ try:
873
+ result = api.get("/v1/usage/history", params={"limit": last, "days": 7})
874
+ records = result.get("records") if isinstance(result, dict) else result
875
+ compact = []
876
+ for r in records or []:
877
+ compact.append({
878
+ "tool": r.get("tool"),
879
+ "latency_ms": r.get("latency_ms"),
880
+ "credits": r.get("credits"),
881
+ "success": r.get("success"),
882
+ "error_code": r.get("error_code"),
883
+ "created_at": r.get("created_at"),
884
+ })
885
+ total = result.get("total", len(compact)) if isinstance(result, dict) else len(compact)
886
+ _ok({"records": compact, "total": total, "days": 7})
887
+ except APIError as e:
888
+ _out(_format_api_error(e.status, e.body))
889
+ sys.exit(1)
890
+
891
+
815
892
  # ── Argparse Setup ─────────────────────────────────────────────────
816
893
 
817
894
 
818
895
  def build_parser():
819
896
  p = argparse.ArgumentParser(
820
897
  prog="uno",
821
- description="Uno — Agent tool gateway CLI (2000+ real-world tools)",
898
+ description="Uno — Agent tool gateway CLI (live catalog via /v1/tools)",
822
899
  )
823
900
  p.add_argument("--version", action="version", version=f"%(prog)s {__version__}")
824
901
  p.add_argument("--compact", action="store_true", help="Output compact (single-line) JSON instead of formatted")
@@ -830,6 +907,11 @@ def build_parser():
830
907
 
831
908
  sub = p.add_subparsers(dest="command")
832
909
 
910
+ register_p = sub.add_parser("register", help="Register a new Uno account")
911
+ register_p.add_argument("email", help="Email address")
912
+ register_p.add_argument("password", help="Password")
913
+ register_p.add_argument("--name", default="", help="Display name (optional)")
914
+
833
915
  login_p = sub.add_parser("login", help="Authenticate with Uno (via ClawdChat SSO)")
834
916
  login_p.add_argument("--start", action="store_true", help="Step 1: get device code (non-blocking, for agents)")
835
917
  login_p.add_argument("--poll", metavar="DEVICE_CODE", help="Step 2: poll for authorization")
@@ -901,10 +983,22 @@ def build_parser():
901
983
  disc_p = sub.add_parser("disconnect", help="Revoke third-party OAuth/API-key authorization")
902
984
  disc_p.add_argument("server", help="Server slug to disconnect (e.g. github, canva)")
903
985
 
986
+ conn_p = sub.add_parser("connections", help="List third-party connections")
987
+ conn_p.add_argument("--reconnect", metavar="SERVER", help="Print auth_url for a server that needs reconnect")
988
+
989
+ auth_p = sub.add_parser("auth", help="Auth helpers (list connections)")
990
+ auth_sub = auth_p.add_subparsers(dest="auth_action")
991
+ auth_list = auth_sub.add_parser("list", help="List connections (alias of uno connections)")
992
+ auth_list.add_argument("--reconnect", metavar="SERVER", help="Print auth_url for a server that needs reconnect")
993
+
994
+ logs_p = sub.add_parser("logs", help="Recent call logs (last 7 days)")
995
+ logs_p.add_argument("--last", type=int, default=20, help="Number of records (default: 20)")
996
+
904
997
  return p
905
998
 
906
999
 
907
1000
  COMMAND_MAP = {
1001
+ "register": cmd_register,
908
1002
  "login": cmd_login,
909
1003
  "logout": cmd_logout,
910
1004
  "use": cmd_use,
@@ -917,6 +1011,9 @@ COMMAND_MAP = {
917
1011
  "keys": cmd_keys,
918
1012
  "health": cmd_health,
919
1013
  "disconnect": cmd_disconnect,
1014
+ "connections": cmd_connections,
1015
+ "auth": cmd_auth,
1016
+ "logs": cmd_logs,
920
1017
  }
921
1018
 
922
1019
 
@@ -1 +0,0 @@
1
- __version__ = "1.0.2"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes