sing-box-cli 0.0.27__tar.gz → 0.0.29__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.
- {sing_box_cli-0.0.27 → sing_box_cli-0.0.29}/CHANGELOG.md +22 -0
- {sing_box_cli-0.0.27 → sing_box_cli-0.0.29}/PKG-INFO +4 -4
- {sing_box_cli-0.0.27 → sing_box_cli-0.0.29}/pyproject.toml +8 -8
- {sing_box_cli-0.0.27/src/sing_box_service → sing_box_cli-0.0.29/src/sing_box_cli}/__init__.py +1 -1
- {sing_box_cli-0.0.27/src/sing_box_service → sing_box_cli-0.0.29/src/sing_box_cli}/common.py +6 -0
- {sing_box_cli-0.0.27/src/sing_box_service → sing_box_cli-0.0.29/src/sing_box_cli}/config/__init__.py +19 -8
- {sing_box_cli-0.0.27/src/sing_box_service → sing_box_cli-0.0.29/src/sing_box_cli}/main.py +12 -16
- {sing_box_cli-0.0.27/src/sing_box_service → sing_box_cli-0.0.29/src/sing_box_cli}/service/__init__.py +15 -15
- {sing_box_cli-0.0.27/src/sing_box_service → sing_box_cli-0.0.29/src/sing_box_cli}/service/manager.py +1 -14
- {sing_box_cli-0.0.27 → sing_box_cli-0.0.29}/tests/test_config.py +1 -1
- {sing_box_cli-0.0.27 → sing_box_cli-0.0.29}/.github/dependabot.yml +0 -0
- {sing_box_cli-0.0.27 → sing_box_cli-0.0.29}/.github/workflows/main.yml +0 -0
- {sing_box_cli-0.0.27 → sing_box_cli-0.0.29}/.gitignore +0 -0
- {sing_box_cli-0.0.27 → sing_box_cli-0.0.29}/.pre-commit-config.yaml +0 -0
- {sing_box_cli-0.0.27 → sing_box_cli-0.0.29}/LICENSE +0 -0
- {sing_box_cli-0.0.27 → sing_box_cli-0.0.29}/README.md +0 -0
- {sing_box_cli-0.0.27 → sing_box_cli-0.0.29}/assets/image.png +0 -0
- {sing_box_cli-0.0.27 → sing_box_cli-0.0.29}/scripts/bump.sh +0 -0
- {sing_box_cli-0.0.27 → sing_box_cli-0.0.29}/scripts/format.sh +0 -0
- {sing_box_cli-0.0.27 → sing_box_cli-0.0.29}/scripts/lint.sh +0 -0
- {sing_box_cli-0.0.27 → sing_box_cli-0.0.29}/scripts/pre-commit.sh +0 -0
- {sing_box_cli-0.0.27/src/sing_box_service → sing_box_cli-0.0.29/src/sing_box_cli}/api/__init__.py +0 -0
- {sing_box_cli-0.0.27/src/sing_box_service → sing_box_cli-0.0.29/src/sing_box_cli}/api/client.py +0 -0
- {sing_box_cli-0.0.27/src/sing_box_service → sing_box_cli-0.0.29/src/sing_box_cli}/api/connections.py +0 -0
- {sing_box_cli-0.0.27/src/sing_box_service → sing_box_cli-0.0.29/src/sing_box_cli}/api/logs.py +0 -0
- {sing_box_cli-0.0.27/src/sing_box_service → sing_box_cli-0.0.29/src/sing_box_cli}/api/monitor.py +0 -0
- {sing_box_cli-0.0.27/src/sing_box_service → sing_box_cli-0.0.29/src/sing_box_cli}/api/policy.py +0 -0
- {sing_box_cli-0.0.27/src/sing_box_service → sing_box_cli-0.0.29/src/sing_box_cli}/api/widget.py +0 -0
- {sing_box_cli-0.0.27/src/sing_box_service → sing_box_cli-0.0.29/src/sing_box_cli}/config/config.py +0 -0
- {sing_box_cli-0.0.27/src/sing_box_service → sing_box_cli-0.0.29/src/sing_box_cli}/config/utils.py +0 -0
- {sing_box_cli-0.0.27/src/sing_box_service → sing_box_cli-0.0.29/src/sing_box_cli}/py.typed +0 -0
- {sing_box_cli-0.0.27 → sing_box_cli-0.0.29}/uv.lock +0 -0
|
@@ -2,6 +2,28 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## 0.0.29 - 2025-03-22
|
|
6
|
+
|
|
7
|
+
### 🚀 Features
|
|
8
|
+
|
|
9
|
+
- Add update option for `run` and `service restart` to update config automatically
|
|
10
|
+
- Add `--restart` option for `config add-sub`
|
|
11
|
+
|
|
12
|
+
### 📚 Documentation
|
|
13
|
+
|
|
14
|
+
- Fix email
|
|
15
|
+
|
|
16
|
+
### ⚙️ Miscellaneous Tasks
|
|
17
|
+
|
|
18
|
+
- Rename dir sing_box_service as sing_box_cli
|
|
19
|
+
- Replace creating service instance manually with context object
|
|
20
|
+
|
|
21
|
+
## 0.0.28 - 2025-03-21
|
|
22
|
+
|
|
23
|
+
### ⚙️ Miscellaneous Tasks
|
|
24
|
+
|
|
25
|
+
- Remove commands about capture logs in windows
|
|
26
|
+
|
|
5
27
|
## 0.0.27 - 2025-03-21
|
|
6
28
|
|
|
7
29
|
### 🐛 Bug Fixes
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sing-box-cli
|
|
3
|
-
Version: 0.0.
|
|
4
|
-
Summary: cross-platform sing-box
|
|
3
|
+
Version: 0.0.29
|
|
4
|
+
Summary: cross-platform sing-box manager.
|
|
5
5
|
Project-URL: Homepage, https://github.com/aittcuszz/sing-box-service
|
|
6
6
|
Project-URL: Issues, https://github.com/atticuszz/sing-box-service/issues
|
|
7
7
|
Project-URL: documentation, https://atticuszz.github.io/sing-box-service/
|
|
8
8
|
Project-URL: Changelog, https://github.com/atticuszz/sing-box-service/blob/main/CHANGELOG.md
|
|
9
|
-
Author-email: "A.J.Zeller" <
|
|
10
|
-
Maintainer-email: "A.J.Zeller" <
|
|
9
|
+
Author-email: "A.J.Zeller" <hello@atticux.me>
|
|
10
|
+
Maintainer-email: "A.J.Zeller" <hello@atticux.me>
|
|
11
11
|
License: MIT License
|
|
12
12
|
|
|
13
13
|
Copyright (c) 2024 A.J.Zeller
|
|
@@ -5,7 +5,7 @@ build-backend = "hatchling.build"
|
|
|
5
5
|
|
|
6
6
|
[project]
|
|
7
7
|
name = "sing-box-cli"
|
|
8
|
-
description = "cross-platform sing-box
|
|
8
|
+
description = "cross-platform sing-box manager."
|
|
9
9
|
classifiers = [
|
|
10
10
|
"License :: OSI Approved :: MIT License",
|
|
11
11
|
"Programming Language :: Python",
|
|
@@ -19,8 +19,8 @@ classifiers = [
|
|
|
19
19
|
readme = "README.md"
|
|
20
20
|
requires-python = ">=3.10"
|
|
21
21
|
license = { file = "LICENSE" }
|
|
22
|
-
authors = [{ name = "A.J.Zeller", email = "
|
|
23
|
-
maintainers = [{ name = "A.J.Zeller", email = "
|
|
22
|
+
authors = [{ name = "A.J.Zeller", email = "hello@atticux.me" }]
|
|
23
|
+
maintainers = [{ name = "A.J.Zeller", email = "hello@atticux.me" }]
|
|
24
24
|
|
|
25
25
|
dynamic = ["version"] # https://hatch.pypa.io/latest/config/metadata/#version
|
|
26
26
|
dependencies = [
|
|
@@ -39,7 +39,7 @@ documentation = "https://atticuszz.github.io/sing-box-service/"
|
|
|
39
39
|
Changelog = "https://github.com/atticuszz/sing-box-service/blob/main/CHANGELOG.md"
|
|
40
40
|
|
|
41
41
|
[project.scripts] # build-backend config needed
|
|
42
|
-
sing-box-cli = "
|
|
42
|
+
sing-box-cli = "sing_box_cli:main" # equal to from python import main; then run main()
|
|
43
43
|
# FROM: https://packaging.python.org/en/latest/guides/writing-pyproject-toml/
|
|
44
44
|
|
|
45
45
|
[tool.uv]
|
|
@@ -65,11 +65,11 @@ dev = [
|
|
|
65
65
|
]
|
|
66
66
|
|
|
67
67
|
[tool.hatch.version]
|
|
68
|
-
path = "src/
|
|
68
|
+
path = "src/sing_box_cli/__init__.py"
|
|
69
69
|
# FROM: https://hatch.pypa.io/latest/version/
|
|
70
70
|
|
|
71
71
|
[tool.hatch.build.targets.wheel]
|
|
72
|
-
packages = ["src/
|
|
72
|
+
packages = ["src/sing_box_cli"]
|
|
73
73
|
# FROM: https://hatch.pypa.io/latest/build/
|
|
74
74
|
|
|
75
75
|
|
|
@@ -213,7 +213,7 @@ sort_commits = "oldest"
|
|
|
213
213
|
|
|
214
214
|
|
|
215
215
|
[tool.bumpversion]
|
|
216
|
-
current_version = "0.0.
|
|
216
|
+
current_version = "0.0.29"
|
|
217
217
|
parse = "(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<patch>\\d+)"
|
|
218
218
|
serialize = ["{major}.{minor}.{patch}"]
|
|
219
219
|
search = "{current_version}"
|
|
@@ -234,7 +234,7 @@ pre_commit_hooks = []
|
|
|
234
234
|
post_commit_hooks = []
|
|
235
235
|
|
|
236
236
|
[[tool.bumpversion.files]]
|
|
237
|
-
filename = "src/
|
|
237
|
+
filename = "src/sing_box_cli/__init__.py"
|
|
238
238
|
|
|
239
239
|
[[tool.bumpversion.files]]
|
|
240
240
|
filename = "CHANGELOG.md"
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
import os
|
|
2
2
|
from enum import Enum
|
|
3
|
+
from typing import Annotated
|
|
4
|
+
|
|
5
|
+
import typer
|
|
3
6
|
|
|
4
7
|
StrOrNone = str | None
|
|
8
|
+
UpdateConfigOption = Annotated[
|
|
9
|
+
bool, typer.Option("--update", "-u", help="Update configuration before running.")
|
|
10
|
+
]
|
|
5
11
|
|
|
6
12
|
|
|
7
13
|
class LogLevel(str, Enum):
|
{sing_box_cli-0.0.27/src/sing_box_service → sing_box_cli-0.0.29/src/sing_box_cli}/config/__init__.py
RENAMED
|
@@ -7,22 +7,33 @@ from .config import SingBoxConfig, get_config
|
|
|
7
7
|
|
|
8
8
|
__all__ = ["config", "SingBoxConfig", "get_config"]
|
|
9
9
|
|
|
10
|
+
SubUrlArg = Annotated[str, typer.Argument(help="Subscription URL")]
|
|
11
|
+
RestartServiceOption = Annotated[
|
|
12
|
+
bool, typer.Option("--restart", "-r", help="Restart service after update.")
|
|
13
|
+
]
|
|
14
|
+
|
|
10
15
|
config = typer.Typer(help="Configuration management commands")
|
|
11
16
|
|
|
12
17
|
|
|
13
18
|
@config.command("add-sub")
|
|
14
|
-
def config_add_sub(
|
|
15
|
-
|
|
16
|
-
|
|
19
|
+
def config_add_sub(
|
|
20
|
+
ctx: typer.Context, url: SubUrlArg, restart: RestartServiceOption = False
|
|
21
|
+
) -> None:
|
|
22
|
+
"""Add subscription URL, download configuration and restart service if needed"""
|
|
17
23
|
if ctx.obj.config.add_subscription(url):
|
|
18
|
-
#
|
|
19
|
-
if not ctx.obj.service.check_service():
|
|
20
|
-
ctx.obj.service.create_service()
|
|
21
|
-
print("⌛ Service created successfully.")
|
|
24
|
+
# download config
|
|
22
25
|
if ctx.obj.config.update_config():
|
|
23
|
-
|
|
26
|
+
print("✅ Configuration updated.")
|
|
24
27
|
else:
|
|
28
|
+
print("❌ Failed to update configuration.")
|
|
25
29
|
raise typer.Exit(1)
|
|
30
|
+
if restart:
|
|
31
|
+
ensure_root()
|
|
32
|
+
# init service
|
|
33
|
+
if not ctx.obj.service.check_service():
|
|
34
|
+
ctx.obj.service.create_service()
|
|
35
|
+
print("⌛ Service created successfully.")
|
|
36
|
+
ctx.obj.service.restart()
|
|
26
37
|
else:
|
|
27
38
|
print("❌ Failed to add subscription.")
|
|
28
39
|
raise typer.Exit(1)
|
|
@@ -5,7 +5,7 @@ import typer
|
|
|
5
5
|
from rich import print
|
|
6
6
|
|
|
7
7
|
from .api import api as api_app
|
|
8
|
-
from .common import ensure_root
|
|
8
|
+
from .common import UpdateConfigOption, ensure_root
|
|
9
9
|
from .config import SingBoxConfig, config as config_app, get_config
|
|
10
10
|
from .service import (
|
|
11
11
|
LinuxServiceManager,
|
|
@@ -35,26 +35,22 @@ def callback(ctx: typer.Context) -> None:
|
|
|
35
35
|
|
|
36
36
|
|
|
37
37
|
@app.command()
|
|
38
|
-
def run(ctx: typer.Context) -> None:
|
|
38
|
+
def run(ctx: typer.Context, update: UpdateConfigOption = False) -> None:
|
|
39
39
|
"""Run sing-box if host's service unavailable"""
|
|
40
40
|
ensure_root()
|
|
41
41
|
cfg = ctx.obj.config
|
|
42
|
-
if
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
"run",
|
|
46
|
-
"-C",
|
|
47
|
-
str(cfg.install_dir),
|
|
48
|
-
"-D",
|
|
49
|
-
str(cfg.install_dir),
|
|
50
|
-
]
|
|
51
|
-
if cfg.is_windows:
|
|
52
|
-
subprocess.run(["pwsh"] + cmd)
|
|
42
|
+
if update:
|
|
43
|
+
if cfg.update_config():
|
|
44
|
+
print("✅ Configuration updated.")
|
|
53
45
|
else:
|
|
54
|
-
|
|
46
|
+
print("❌ Failed to update configuration.")
|
|
47
|
+
raise typer.Exit(1)
|
|
48
|
+
|
|
49
|
+
cmd = [cfg.bin_path, "run", "-C", str(cfg.config_dir), "-D", str(cfg.config_dir)]
|
|
50
|
+
if cfg.is_windows:
|
|
51
|
+
subprocess.run(["pwsh"] + cmd)
|
|
55
52
|
else:
|
|
56
|
-
|
|
57
|
-
raise typer.Exit(1)
|
|
53
|
+
subprocess.run(cmd)
|
|
58
54
|
|
|
59
55
|
|
|
60
56
|
@app.command()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import typer
|
|
2
2
|
|
|
3
|
-
from ..common import ensure_root
|
|
3
|
+
from ..common import UpdateConfigOption, ensure_root
|
|
4
4
|
from .manager import LinuxServiceManager, WindowsServiceManager, create_service
|
|
5
5
|
|
|
6
6
|
__all__ = ["service", "WindowsServiceManager", "LinuxServiceManager", "create_service"]
|
|
@@ -14,7 +14,7 @@ def service_enable(ctx: typer.Context) -> None:
|
|
|
14
14
|
"""Create sing-box service, enable autostart and start service"""
|
|
15
15
|
ensure_root()
|
|
16
16
|
config = ctx.obj.config
|
|
17
|
-
service =
|
|
17
|
+
service = ctx.obj.service
|
|
18
18
|
service.create_service()
|
|
19
19
|
service.start()
|
|
20
20
|
print("🔥 Service started.")
|
|
@@ -26,26 +26,28 @@ def service_enable(ctx: typer.Context) -> None:
|
|
|
26
26
|
def service_disable(ctx: typer.Context) -> None:
|
|
27
27
|
"""Stop service, disable sing-box service autostart and remove service"""
|
|
28
28
|
ensure_root()
|
|
29
|
-
|
|
30
|
-
service = create_service(config)
|
|
29
|
+
service = ctx.obj.service
|
|
31
30
|
service.stop()
|
|
32
31
|
service.disable()
|
|
33
32
|
print("✋ Autostart disabled.")
|
|
34
33
|
|
|
35
34
|
|
|
36
35
|
@service.command("restart")
|
|
37
|
-
def service_restart(ctx: typer.Context) -> None:
|
|
36
|
+
def service_restart(ctx: typer.Context, update: UpdateConfigOption = False) -> None:
|
|
38
37
|
"""Restart sing-box service, update configuration if needed, create service if not exists"""
|
|
39
38
|
ensure_root()
|
|
40
39
|
config = ctx.obj.config
|
|
41
|
-
service =
|
|
40
|
+
service = ctx.obj.service
|
|
42
41
|
if not service.check_service():
|
|
43
42
|
service.create_service()
|
|
44
|
-
if
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
43
|
+
if update:
|
|
44
|
+
if config.update_config():
|
|
45
|
+
print("✅ Configuration updated.")
|
|
46
|
+
else:
|
|
47
|
+
print("❌ Failed to update configuration.")
|
|
48
|
+
raise typer.Exit(1)
|
|
49
|
+
|
|
50
|
+
service.restart()
|
|
49
51
|
print("🔥 Service restarted.")
|
|
50
52
|
if config.api_base_url:
|
|
51
53
|
print(f"🔌 Default API: {config.api_base_url}")
|
|
@@ -55,8 +57,7 @@ def service_restart(ctx: typer.Context) -> None:
|
|
|
55
57
|
def service_stop(ctx: typer.Context) -> None:
|
|
56
58
|
"""Stop sing-box service"""
|
|
57
59
|
ensure_root()
|
|
58
|
-
|
|
59
|
-
service = create_service(config)
|
|
60
|
+
service = ctx.obj.service
|
|
60
61
|
service.stop()
|
|
61
62
|
print("✋ Service stopped.")
|
|
62
63
|
|
|
@@ -65,7 +66,6 @@ def service_stop(ctx: typer.Context) -> None:
|
|
|
65
66
|
def service_status(ctx: typer.Context) -> None:
|
|
66
67
|
"""Check service status"""
|
|
67
68
|
ensure_root()
|
|
68
|
-
|
|
69
|
-
service = create_service(config)
|
|
69
|
+
service = ctx.obj.service
|
|
70
70
|
status = service.status()
|
|
71
71
|
print(f"🏃 Service status: {status}")
|
{sing_box_cli-0.0.27/src/sing_box_service → sing_box_cli-0.0.29/src/sing_box_cli}/service/manager.py
RENAMED
|
@@ -38,7 +38,6 @@ class WindowsServiceManager(ServiceManager):
|
|
|
38
38
|
def __init__(self, config: SingBoxConfig) -> None:
|
|
39
39
|
super().__init__(config)
|
|
40
40
|
self.task_name = "sing-box-service"
|
|
41
|
-
self.log_file = self.config.config_dir / "sing-box.log"
|
|
42
41
|
|
|
43
42
|
def create_service(self) -> None:
|
|
44
43
|
start_script = self.config.config_dir / "start-singbox.ps1"
|
|
@@ -52,21 +51,9 @@ public static extern bool ShowWindow(IntPtr hWnd, Int32 nCmdShow);
|
|
|
52
51
|
$console = [Console.Window]::GetConsoleWindow()
|
|
53
52
|
[Console.Window]::ShowWindow($console, 0)
|
|
54
53
|
|
|
55
|
-
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
|
|
56
|
-
$OutputEncoding = [System.Text.Encoding]::UTF8
|
|
57
|
-
chcp 65001 | Out-Null
|
|
58
|
-
|
|
59
54
|
Set-Location "{self.config.config_dir}"
|
|
60
55
|
|
|
61
|
-
|
|
62
|
-
Clear-Content "{self.log_file}"
|
|
63
|
-
}}
|
|
64
|
-
|
|
65
|
-
try {{
|
|
66
|
-
& "{self.config.bin_path}" run -C "{self.config.config_dir}" *>&1 | Tee-Object -FilePath "{self.log_file}" -Append
|
|
67
|
-
}} catch {{
|
|
68
|
-
$_ | Out-File -FilePath "{self.log_file}" -Append
|
|
69
|
-
}}
|
|
56
|
+
& "{self.config.bin_path}" run -C "{self.config.config_dir}"
|
|
70
57
|
"""
|
|
71
58
|
start_script.write_text(script_content, encoding="utf-8")
|
|
72
59
|
|
|
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
|
{sing_box_cli-0.0.27/src/sing_box_service → sing_box_cli-0.0.29/src/sing_box_cli}/api/__init__.py
RENAMED
|
File without changes
|
{sing_box_cli-0.0.27/src/sing_box_service → sing_box_cli-0.0.29/src/sing_box_cli}/api/client.py
RENAMED
|
File without changes
|
{sing_box_cli-0.0.27/src/sing_box_service → sing_box_cli-0.0.29/src/sing_box_cli}/api/connections.py
RENAMED
|
File without changes
|
{sing_box_cli-0.0.27/src/sing_box_service → sing_box_cli-0.0.29/src/sing_box_cli}/api/logs.py
RENAMED
|
File without changes
|
{sing_box_cli-0.0.27/src/sing_box_service → sing_box_cli-0.0.29/src/sing_box_cli}/api/monitor.py
RENAMED
|
File without changes
|
{sing_box_cli-0.0.27/src/sing_box_service → sing_box_cli-0.0.29/src/sing_box_cli}/api/policy.py
RENAMED
|
File without changes
|
{sing_box_cli-0.0.27/src/sing_box_service → sing_box_cli-0.0.29/src/sing_box_cli}/api/widget.py
RENAMED
|
File without changes
|
{sing_box_cli-0.0.27/src/sing_box_service → sing_box_cli-0.0.29/src/sing_box_cli}/config/config.py
RENAMED
|
File without changes
|
{sing_box_cli-0.0.27/src/sing_box_service → sing_box_cli-0.0.29/src/sing_box_cli}/config/utils.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|