leetcode-local-cli 0.7.0__tar.gz → 0.7.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.
- {leetcode_local_cli-0.7.0 → leetcode_local_cli-0.7.1}/PKG-INFO +6 -4
- {leetcode_local_cli-0.7.0 → leetcode_local_cli-0.7.1}/README.md +5 -3
- {leetcode_local_cli-0.7.0 → leetcode_local_cli-0.7.1}/pyproject.toml +1 -1
- {leetcode_local_cli-0.7.0 → leetcode_local_cli-0.7.1}/src/leetcode_local_cli/doctor.py +13 -13
- {leetcode_local_cli-0.7.0 → leetcode_local_cli-0.7.1}/src/leetcode_local_cli/service.py +5 -5
- {leetcode_local_cli-0.7.0 → leetcode_local_cli-0.7.1}/LICENSE +0 -0
- {leetcode_local_cli-0.7.0 → leetcode_local_cli-0.7.1}/src/leetcode_local_cli/__init__.py +0 -0
- {leetcode_local_cli-0.7.0 → leetcode_local_cli-0.7.1}/src/leetcode_local_cli/__main__.py +0 -0
- {leetcode_local_cli-0.7.0 → leetcode_local_cli-0.7.1}/src/leetcode_local_cli/auth.py +0 -0
- {leetcode_local_cli-0.7.0 → leetcode_local_cli-0.7.1}/src/leetcode_local_cli/cli.py +0 -0
- {leetcode_local_cli-0.7.0 → leetcode_local_cli-0.7.1}/src/leetcode_local_cli/client.py +0 -0
- {leetcode_local_cli-0.7.0 → leetcode_local_cli-0.7.1}/src/leetcode_local_cli/problem.py +0 -0
- {leetcode_local_cli-0.7.0 → leetcode_local_cli-0.7.1}/src/leetcode_local_cli/ui.py +0 -0
- {leetcode_local_cli-0.7.0 → leetcode_local_cli-0.7.1}/src/leetcode_local_cli/version.py +0 -0
- {leetcode_local_cli-0.7.0 → leetcode_local_cli-0.7.1}/src/leetcode_local_cli/workspace.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: leetcode-local-cli
|
|
3
|
-
Version: 0.7.
|
|
3
|
+
Version: 0.7.1
|
|
4
4
|
Summary: Local coding workflow CLI for LeetCode CN.
|
|
5
5
|
Keywords: cli,leetcode,leetcode-cn,uv
|
|
6
6
|
Author: Aetherialter
|
|
@@ -26,7 +26,7 @@ Description-Content-Type: text/markdown
|
|
|
26
26
|
|
|
27
27
|
一个面向 LeetCode 中文站的轻量本地刷题 CLI。它复用浏览器登录态,在线获取题目,在当前工作目录生成单文件 `solution.py`,并支持本地测试和远程提交。
|
|
28
28
|
|
|
29
|
-
当前版本:`v0.7.
|
|
29
|
+
当前版本:`v0.7.1`
|
|
30
30
|
|
|
31
31
|
## 核心能力
|
|
32
32
|
|
|
@@ -54,13 +54,13 @@ Description-Content-Type: text/markdown
|
|
|
54
54
|
Linux / macOS 一键安装:
|
|
55
55
|
|
|
56
56
|
```bash
|
|
57
|
-
curl -LsSf https://raw.githubusercontent.com/Aetherialter/leetcode-local-cli/v0.7.
|
|
57
|
+
curl -LsSf https://raw.githubusercontent.com/Aetherialter/leetcode-local-cli/v0.7.1/scripts/install.sh | sh
|
|
58
58
|
```
|
|
59
59
|
|
|
60
60
|
Windows PowerShell 一键安装:
|
|
61
61
|
|
|
62
62
|
```powershell
|
|
63
|
-
powershell -ExecutionPolicy ByPass -Command "irm https://raw.githubusercontent.com/Aetherialter/leetcode-local-cli/v0.7.
|
|
63
|
+
powershell -ExecutionPolicy ByPass -Command "irm https://raw.githubusercontent.com/Aetherialter/leetcode-local-cli/v0.7.1/scripts/install.ps1 | iex"
|
|
64
64
|
```
|
|
65
65
|
|
|
66
66
|
安装器会在缺少 uv 时通过 uv 官方 HTTPS 安装器完成引导,然后使用 `uv tool install` 安装 `leetcode-local-cli`,并执行 `lc --version` 验证结果。安装过程不使用 `sudo`,也不会保存 PyPI 或 GitHub 凭据。
|
|
@@ -229,6 +229,7 @@ tests/
|
|
|
229
229
|
test_doctor.py
|
|
230
230
|
test_install_scripts.py
|
|
231
231
|
test_problem.py
|
|
232
|
+
test_release.py
|
|
232
233
|
test_service.py
|
|
233
234
|
test_ui.py
|
|
234
235
|
test_workspace.py
|
|
@@ -243,6 +244,7 @@ tests/
|
|
|
243
244
|
- `v0.5.7`: 修复非 Windows 环境导入 `os.startfile` 导致 CLI 无法启动的问题。
|
|
244
245
|
- `v0.6.0`: 新增 `lc doctor`,完善客户端边界校验、本地文件诊断、错误提示和提交目标展示。
|
|
245
246
|
- `v0.7.0`: uv 全局工具安装、跨平台引导脚本和 PyPI Trusted Publisher 发布流程。
|
|
247
|
+
- `v0.7.1`: 修正安装版 CLI 的命令建议,并引入版本化 GitHub Release Notes。
|
|
246
248
|
- `v0.8`: `lc init` 与正式工作区管理。
|
|
247
249
|
- `v0.9`: 轻量缓存。
|
|
248
250
|
- `v0.10`: 样例提取原型。
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
一个面向 LeetCode 中文站的轻量本地刷题 CLI。它复用浏览器登录态,在线获取题目,在当前工作目录生成单文件 `solution.py`,并支持本地测试和远程提交。
|
|
4
4
|
|
|
5
|
-
当前版本:`v0.7.
|
|
5
|
+
当前版本:`v0.7.1`
|
|
6
6
|
|
|
7
7
|
## 核心能力
|
|
8
8
|
|
|
@@ -30,13 +30,13 @@
|
|
|
30
30
|
Linux / macOS 一键安装:
|
|
31
31
|
|
|
32
32
|
```bash
|
|
33
|
-
curl -LsSf https://raw.githubusercontent.com/Aetherialter/leetcode-local-cli/v0.7.
|
|
33
|
+
curl -LsSf https://raw.githubusercontent.com/Aetherialter/leetcode-local-cli/v0.7.1/scripts/install.sh | sh
|
|
34
34
|
```
|
|
35
35
|
|
|
36
36
|
Windows PowerShell 一键安装:
|
|
37
37
|
|
|
38
38
|
```powershell
|
|
39
|
-
powershell -ExecutionPolicy ByPass -Command "irm https://raw.githubusercontent.com/Aetherialter/leetcode-local-cli/v0.7.
|
|
39
|
+
powershell -ExecutionPolicy ByPass -Command "irm https://raw.githubusercontent.com/Aetherialter/leetcode-local-cli/v0.7.1/scripts/install.ps1 | iex"
|
|
40
40
|
```
|
|
41
41
|
|
|
42
42
|
安装器会在缺少 uv 时通过 uv 官方 HTTPS 安装器完成引导,然后使用 `uv tool install` 安装 `leetcode-local-cli`,并执行 `lc --version` 验证结果。安装过程不使用 `sudo`,也不会保存 PyPI 或 GitHub 凭据。
|
|
@@ -205,6 +205,7 @@ tests/
|
|
|
205
205
|
test_doctor.py
|
|
206
206
|
test_install_scripts.py
|
|
207
207
|
test_problem.py
|
|
208
|
+
test_release.py
|
|
208
209
|
test_service.py
|
|
209
210
|
test_ui.py
|
|
210
211
|
test_workspace.py
|
|
@@ -219,6 +220,7 @@ tests/
|
|
|
219
220
|
- `v0.5.7`: 修复非 Windows 环境导入 `os.startfile` 导致 CLI 无法启动的问题。
|
|
220
221
|
- `v0.6.0`: 新增 `lc doctor`,完善客户端边界校验、本地文件诊断、错误提示和提交目标展示。
|
|
221
222
|
- `v0.7.0`: uv 全局工具安装、跨平台引导脚本和 PyPI Trusted Publisher 发布流程。
|
|
223
|
+
- `v0.7.1`: 修正安装版 CLI 的命令建议,并引入版本化 GitHub Release Notes。
|
|
222
224
|
- `v0.8`: `lc init` 与正式工作区管理。
|
|
223
225
|
- `v0.9`: 轻量缓存。
|
|
224
226
|
- `v0.10`: 样例提取原型。
|
|
@@ -65,7 +65,7 @@ def diagnose_session(path: Path | None = None) -> DoctorCheck:
|
|
|
65
65
|
name=SESSION_CHECK_NAME,
|
|
66
66
|
status=DoctorStatus.FAIL,
|
|
67
67
|
message="未找到 Session 文件",
|
|
68
|
-
suggestion="请执行
|
|
68
|
+
suggestion="请执行 lc login 创建登录态",
|
|
69
69
|
)
|
|
70
70
|
|
|
71
71
|
case SessionFileStatus.READ_ERROR:
|
|
@@ -73,7 +73,7 @@ def diagnose_session(path: Path | None = None) -> DoctorCheck:
|
|
|
73
73
|
name=SESSION_CHECK_NAME,
|
|
74
74
|
status=DoctorStatus.FAIL,
|
|
75
75
|
message="无法读取 Session 文件",
|
|
76
|
-
suggestion="请检查文件权限,或重新执行
|
|
76
|
+
suggestion="请检查文件权限,或重新执行 lc login",
|
|
77
77
|
)
|
|
78
78
|
|
|
79
79
|
case SessionFileStatus.INVALID_JSON:
|
|
@@ -81,7 +81,7 @@ def diagnose_session(path: Path | None = None) -> DoctorCheck:
|
|
|
81
81
|
name=SESSION_CHECK_NAME,
|
|
82
82
|
status=DoctorStatus.FAIL,
|
|
83
83
|
message="Session 文件不是有效的 JSON",
|
|
84
|
-
suggestion="请执行
|
|
84
|
+
suggestion="请执行 lc login 重新生成登录态",
|
|
85
85
|
)
|
|
86
86
|
|
|
87
87
|
case SessionFileStatus.INVALID_STRUCTURE:
|
|
@@ -89,7 +89,7 @@ def diagnose_session(path: Path | None = None) -> DoctorCheck:
|
|
|
89
89
|
name=SESSION_CHECK_NAME,
|
|
90
90
|
status=DoctorStatus.FAIL,
|
|
91
91
|
message="Session 文件结构无效",
|
|
92
|
-
suggestion="请执行
|
|
92
|
+
suggestion="请执行 lc login 重新生成登录态",
|
|
93
93
|
)
|
|
94
94
|
|
|
95
95
|
case SessionFileStatus.MISSING_COOKIES:
|
|
@@ -98,7 +98,7 @@ def diagnose_session(path: Path | None = None) -> DoctorCheck:
|
|
|
98
98
|
name=SESSION_CHECK_NAME,
|
|
99
99
|
status=DoctorStatus.FAIL,
|
|
100
100
|
message=f"缺少或无效的 Cookie:{missing}",
|
|
101
|
-
suggestion="请执行
|
|
101
|
+
suggestion="请执行 lc login 刷新 Cookie",
|
|
102
102
|
)
|
|
103
103
|
|
|
104
104
|
|
|
@@ -130,7 +130,7 @@ def diagnose_solution(path: Path | None = None) -> DoctorCheck:
|
|
|
130
130
|
name=SOLUTION_CHECK_NAME,
|
|
131
131
|
status=DoctorStatus.WARNING,
|
|
132
132
|
message="未找到 solution.py",
|
|
133
|
-
suggestion="请执行
|
|
133
|
+
suggestion="请执行 lc solve <题号> 创建解题文件",
|
|
134
134
|
)
|
|
135
135
|
|
|
136
136
|
case SolutionFileStatus.EMPTY:
|
|
@@ -138,7 +138,7 @@ def diagnose_solution(path: Path | None = None) -> DoctorCheck:
|
|
|
138
138
|
name=SOLUTION_CHECK_NAME,
|
|
139
139
|
status=DoctorStatus.WARNING,
|
|
140
140
|
message="solution.py 当前为空",
|
|
141
|
-
suggestion="请执行
|
|
141
|
+
suggestion="请执行 lc solve <题号> 生成解题模板",
|
|
142
142
|
)
|
|
143
143
|
|
|
144
144
|
case SolutionFileStatus.READ_ERROR:
|
|
@@ -159,7 +159,7 @@ def diagnose_solution(path: Path | None = None) -> DoctorCheck:
|
|
|
159
159
|
name=SOLUTION_CHECK_NAME,
|
|
160
160
|
status=DoctorStatus.FAIL,
|
|
161
161
|
message=f"solution.py 存在 Python 语法错误({line})",
|
|
162
|
-
suggestion="请修复语法错误后重新执行
|
|
162
|
+
suggestion="请修复语法错误后重新执行 lc doctor",
|
|
163
163
|
)
|
|
164
164
|
|
|
165
165
|
case SolutionFileStatus.NOT_SUBMITTABLE:
|
|
@@ -167,7 +167,7 @@ def diagnose_solution(path: Path | None = None) -> DoctorCheck:
|
|
|
167
167
|
name=SOLUTION_CHECK_NAME,
|
|
168
168
|
status=DoctorStatus.WARNING,
|
|
169
169
|
message=f"solution.py 可编译,但暂不可提交:{inspection.detail}",
|
|
170
|
-
suggestion="请执行
|
|
170
|
+
suggestion="请执行 lc solve <题号> 重新生成标准模板",
|
|
171
171
|
)
|
|
172
172
|
|
|
173
173
|
|
|
@@ -196,7 +196,7 @@ def _diagnose_solution_runtime(path: Path | None) -> DoctorCheck | None:
|
|
|
196
196
|
name=SOLUTION_CHECK_NAME,
|
|
197
197
|
status=DoctorStatus.FAIL,
|
|
198
198
|
message=f"solution.py 本地运行失败(退出码:{result.returncode})",
|
|
199
|
-
suggestion="请执行
|
|
199
|
+
suggestion="请执行 lc test 定位本地测试错误",
|
|
200
200
|
)
|
|
201
201
|
return None
|
|
202
202
|
|
|
@@ -228,7 +228,7 @@ def diagnose_remote(result: ClientResult) -> tuple[DoctorCheck, DoctorCheck]:
|
|
|
228
228
|
name=AUTHENTICATION_CHECK_NAME,
|
|
229
229
|
status=DoctorStatus.FAIL,
|
|
230
230
|
message="登录凭证无效或不完整",
|
|
231
|
-
suggestion="请执行
|
|
231
|
+
suggestion="请执行 lc login 刷新登录态",
|
|
232
232
|
),
|
|
233
233
|
)
|
|
234
234
|
case _:
|
|
@@ -246,7 +246,7 @@ def diagnose_remote(result: ClientResult) -> tuple[DoctorCheck, DoctorCheck]:
|
|
|
246
246
|
name=AUTHENTICATION_CHECK_NAME,
|
|
247
247
|
status=DoctorStatus.WARNING,
|
|
248
248
|
message="网络或接口异常,暂时无法验证 Cookie",
|
|
249
|
-
suggestion="请先解决连接问题后重新执行
|
|
249
|
+
suggestion="请先解决连接问题后重新执行 lc doctor",
|
|
250
250
|
),
|
|
251
251
|
)
|
|
252
252
|
|
|
@@ -264,7 +264,7 @@ def diagnose_remote(result: ClientResult) -> tuple[DoctorCheck, DoctorCheck]:
|
|
|
264
264
|
name=AUTHENTICATION_CHECK_NAME,
|
|
265
265
|
status=DoctorStatus.FAIL,
|
|
266
266
|
message="Cookie 无效、已过期或当前未登录",
|
|
267
|
-
suggestion="请执行
|
|
267
|
+
suggestion="请执行 lc login 刷新登录态",
|
|
268
268
|
)
|
|
269
269
|
else:
|
|
270
270
|
username = status.get("username")
|
|
@@ -45,10 +45,10 @@ def client_error_message(kind: ClientErrorKind | None) -> str:
|
|
|
45
45
|
return "LeetCode 接口数据结构异常,可能是接口变更"
|
|
46
46
|
|
|
47
47
|
case ClientErrorKind.UNAUTHORIZED:
|
|
48
|
-
return "登录态无效或已过期,请重新执行
|
|
48
|
+
return "登录态无效或已过期,请重新执行 lc login"
|
|
49
49
|
|
|
50
50
|
case ClientErrorKind.MISSING_CSRF:
|
|
51
|
-
return "缺少提交凭证 csrftoken,请重新执行
|
|
51
|
+
return "缺少提交凭证 csrftoken,请重新执行 lc login"
|
|
52
52
|
|
|
53
53
|
case _:
|
|
54
54
|
return "未知客户端错误"
|
|
@@ -67,18 +67,18 @@ def _load_cookies_from_session() -> dict[str, str]:
|
|
|
67
67
|
error(str(exc))
|
|
68
68
|
raise Exit(1)
|
|
69
69
|
if not isinstance(session, dict):
|
|
70
|
-
warning("未找到有效登录态,请先执行
|
|
70
|
+
warning("未找到有效登录态,请先执行 lc login")
|
|
71
71
|
raise Exit(1)
|
|
72
72
|
cookies = session.get("cookies")
|
|
73
73
|
if not isinstance(cookies, dict):
|
|
74
|
-
error("Session 文件结构无效,请重新执行
|
|
74
|
+
error("Session 文件结构无效,请重新执行 lc login")
|
|
75
75
|
raise Exit(1)
|
|
76
76
|
valid_cookies: dict[str, str] = {}
|
|
77
77
|
for name in REQUIRED_COOKIE_NAMES:
|
|
78
78
|
value = cookies.get(name)
|
|
79
79
|
if not isinstance(value, str) or not value:
|
|
80
80
|
error(f"缺少或无效的 Cookie:{name}")
|
|
81
|
-
warning("请重新执行
|
|
81
|
+
warning("请重新执行 lc login")
|
|
82
82
|
raise Exit(1)
|
|
83
83
|
valid_cookies[name] = value
|
|
84
84
|
return valid_cookies
|
|
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
|