ccoding 0.3.0__tar.gz → 0.4.0__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 (34) hide show
  1. {ccoding-0.3.0 → ccoding-0.4.0}/CLAUDE.md +3 -3
  2. {ccoding-0.3.0 → ccoding-0.4.0}/PKG-INFO +3 -2
  3. {ccoding-0.3.0 → ccoding-0.4.0}/README.md +2 -1
  4. {ccoding-0.3.0 → ccoding-0.4.0}/pyproject.toml +1 -1
  5. {ccoding-0.3.0 → ccoding-0.4.0}/src/ccode/__init__.py +1 -1
  6. {ccoding-0.3.0 → ccoding-0.4.0}/src/ccode/api.py +3 -3
  7. {ccoding-0.3.0 → ccoding-0.4.0}/src/ccode/config.py +14 -10
  8. ccoding-0.4.0/src/ccode/env_schema.json +2214 -0
  9. {ccoding-0.3.0 → ccoding-0.4.0}/src/ccode/ui.py +4 -1
  10. ccoding-0.3.0/src/ccode/env_schema.json +0 -979
  11. {ccoding-0.3.0 → ccoding-0.4.0}/.github/workflows/publish.yml +0 -0
  12. {ccoding-0.3.0 → ccoding-0.4.0}/.gitignore +0 -0
  13. {ccoding-0.3.0 → ccoding-0.4.0}/LICENSE +0 -0
  14. {ccoding-0.3.0 → ccoding-0.4.0}/screenshot.png +0 -0
  15. {ccoding-0.3.0 → ccoding-0.4.0}/screenshot_mobile1.jpeg +0 -0
  16. {ccoding-0.3.0 → ccoding-0.4.0}/screenshot_mobile2.jpeg +0 -0
  17. {ccoding-0.3.0 → ccoding-0.4.0}/src/ccode/__main__.py +0 -0
  18. {ccoding-0.3.0 → ccoding-0.4.0}/src/ccode/cli.py +0 -0
  19. {ccoding-0.3.0 → ccoding-0.4.0}/src/ccode/logo.py +0 -0
  20. {ccoding-0.3.0 → ccoding-0.4.0}/src/ccode/remote.py +0 -0
  21. {ccoding-0.3.0 → ccoding-0.4.0}/src/ccode/remote_cli.py +0 -0
  22. {ccoding-0.3.0 → ccoding-0.4.0}/src/ccode/remote_client.py +0 -0
  23. {ccoding-0.3.0 → ccoding-0.4.0}/src/ccode/remote_common.py +0 -0
  24. {ccoding-0.3.0 → ccoding-0.4.0}/src/ccode/remote_server.py +0 -0
  25. {ccoding-0.3.0 → ccoding-0.4.0}/src/ccode/web/__init__.py +0 -0
  26. {ccoding-0.3.0 → ccoding-0.4.0}/src/ccode/web/app.js +0 -0
  27. {ccoding-0.3.0 → ccoding-0.4.0}/src/ccode/web/assets/addon-fit.js +0 -0
  28. {ccoding-0.3.0 → ccoding-0.4.0}/src/ccode/web/assets/xterm-LICENSE +0 -0
  29. {ccoding-0.3.0 → ccoding-0.4.0}/src/ccode/web/assets/xterm-addon-fit-LICENSE +0 -0
  30. {ccoding-0.3.0 → ccoding-0.4.0}/src/ccode/web/assets/xterm.css +0 -0
  31. {ccoding-0.3.0 → ccoding-0.4.0}/src/ccode/web/assets/xterm.js +0 -0
  32. {ccoding-0.3.0 → ccoding-0.4.0}/src/ccode/web/index.html +0 -0
  33. {ccoding-0.3.0 → ccoding-0.4.0}/src/ccode/web/style.css +0 -0
  34. {ccoding-0.3.0 → ccoding-0.4.0}/uv.lock +0 -0
@@ -24,14 +24,14 @@ uv build # 构建 wheel / sdist
24
24
  - **`config.py`** — 所有持久化逻辑。配置文件路径 `~/.ccode/config.json`。`toggles` 字段存储任意环境变量键值对(`dict[str, str]`)。提供 `load_env_schema()` / `env_schema_keys()` / `env_schema_description()` / `env_schema_enum()` 四个函数,从 `env_schema.json` 读取已知变量的元数据。
25
25
  - **`api.py`** — 无状态函数层:HTTP 拉取 `/v1/models`、构建启动环境变量 `build_env()`、调用 `subprocess.run(["claude", ...])` 启动 claude。
26
26
  - **`logo.py`** — LOGOS 数据(3 种 ASCII 字体)及 4 种渲染风格函数(wave / pulse / glitch / rain),接收独立参数,不依赖 `CursesApp`。
27
- - **`ui.py`** — `CursesApp` 类,持有全部 UI 状态。配置界面的 field 列表由 `_config_fields()` 动态构建(`base_url`、`api_key`、每个 toggle key、`__add__` 新增行),支持运行时增删 toggle。新增 toggle 时 key 输入框实时展示候选列表,Tab 键补全,候选来源为 `env_schema.json` 的 217 个已知变量。
27
+ - **`ui.py`** — `CursesApp` 类,持有全部 UI 状态。配置界面的 field 列表由 `_config_fields()` 动态构建(`base_url`、`api_key`、每个 toggle key、`__add__` 新增行),支持运行时增删 toggle。新增 toggle 时 key 输入框实时展示候选列表,Tab 键补全,候选来源为 `env_schema.json` 中的已知变量。
28
28
  - **`cli.py`** — 入口,`main(argv)` 构造 `CursesApp` 并调用 `curses.wrapper`。
29
- - **`env_schema.json`** — 从官方文档生成的 Claude Code 环境变量 JSON Schema,含 `description` 和 `enum` 字段,供 UI 补全和提示使用。更新 claude code 版本后如需同步新变量,手动编辑此文件的 `properties` 节。
29
+ - **`env_schema.json`** — 从官方文档 `https://code.claude.com/docs/en/env-vars` 同步的 Claude Code 环境变量 JSON Schema,含 `description` 和 `enum` 字段,供 UI 补全和提示使用。更新 claude code 版本后重新抓取该页面的变量表并同步此文件的 `properties` 节(仅保留文档未收录的 `CLAUDE_CODE_AUTO_MODE_MODEL` 等本地条目)。
30
30
 
31
31
  ## 关键数据流
32
32
 
33
33
  1. `load_config()` 读取 `~/.ccode/config.json`,toggles 值统一为字符串。
34
- 2. 主界面 → `fetch_models()` 拉取可用模型 → 用户选择 opus/sonnet/haiku 的 owned_by 和 model_id。
34
+ 2. 主界面 → `fetch_models()` 拉取可用模型 → 用户选择 opus/sonnet/haiku/auto 的 owned_by 和 model_id(auto 可选项,对应 `CLAUDE_CODE_AUTO_MODE_MODEL`)。
35
35
  3. 启动时 `build_env()` 将 `base_url`、`api_key`、model id、toggles 全部注入环境变量,执行 `claude`。
36
36
  4. 配置界面 `ESC` 自动保存后刷新模型列表。
37
37
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: ccoding
3
- Version: 0.3.0
3
+ Version: 0.4.0
4
4
  Summary: Curses-based Claude Code launcher
5
5
  Project-URL: Homepage, https://github.com/8DE4732A/ccode
6
6
  Project-URL: Repository, https://github.com/8DE4732A/ccode
@@ -194,7 +194,8 @@ uv sync --extra remote # 同时安装 client/server 依赖
194
194
  "models": {
195
195
  "opus": {"owned_by": null, "id": null},
196
196
  "sonnet": {"owned_by": null, "id": null},
197
- "haiku": {"owned_by": null, "id": null}
197
+ "haiku": {"owned_by": null, "id": null},
198
+ "auto": {"owned_by": null, "id": null}
198
199
  },
199
200
  "toggles": {
200
201
  "CLAUDE_CODE_ENABLE_TELEMETRY": "0",
@@ -143,7 +143,8 @@ uv sync --extra remote # 同时安装 client/server 依赖
143
143
  "models": {
144
144
  "opus": {"owned_by": null, "id": null},
145
145
  "sonnet": {"owned_by": null, "id": null},
146
- "haiku": {"owned_by": null, "id": null}
146
+ "haiku": {"owned_by": null, "id": null},
147
+ "auto": {"owned_by": null, "id": null}
147
148
  },
148
149
  "toggles": {
149
150
  "CLAUDE_CODE_ENABLE_TELEMETRY": "0",
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "ccoding"
3
- version = "0.3.0"
3
+ version = "0.4.0"
4
4
  description = "Curses-based Claude Code launcher"
5
5
  readme = "README.md"
6
6
  license = { file = "LICENSE" }
@@ -1,6 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
- __version__ = "0.2.0"
3
+ __version__ = "0.4.0"
4
4
 
5
5
 
6
6
  def main() -> None:
@@ -7,7 +7,7 @@ import urllib.error
7
7
  import urllib.request
8
8
  from typing import Any
9
9
 
10
- from .config import MODEL_KEYS, mask_secret
10
+ from .config import MODEL_ENV_VARS, MODEL_KEYS, REQUIRED_MODEL_KEYS, mask_secret
11
11
 
12
12
 
13
13
  def _truncate_body(text: str, max_len: int = 200) -> str:
@@ -107,7 +107,7 @@ def build_env(config: dict[str, Any], masked: bool = False) -> dict[str, str]:
107
107
  entry = config["models"].get(key, {})
108
108
  model_id = entry.get("id")
109
109
  if model_id:
110
- env[f"ANTHROPIC_DEFAULT_{key.upper()}_MODEL"] = model_id
110
+ env[MODEL_ENV_VARS[key]] = model_id
111
111
  for key, value in config.get("toggles", {}).items():
112
112
  env[key] = str(value)
113
113
  return env
@@ -118,7 +118,7 @@ def validate_launch_requirements(config: dict[str, Any]) -> str | None:
118
118
  api_key = config.get("api_key", "").strip()
119
119
  if not base_url or not api_key:
120
120
  return "Base URL and API key are required."
121
- for key in MODEL_KEYS:
121
+ for key in REQUIRED_MODEL_KEYS:
122
122
  entry = config["models"].get(key, {})
123
123
  if not entry.get("owned_by") or not entry.get("id"):
124
124
  return "OPUS, SONNET, and HAIKU selections are required."
@@ -11,12 +11,20 @@ from typing import Any
11
11
  CONFIG_DIR = Path.home() / ".ccode"
12
12
  CONFIG_PATH = CONFIG_DIR / "config.json"
13
13
  DEFAULT_BASE_URL = "http://127.0.0.1:8317"
14
- MODEL_KEYS = ("opus", "sonnet", "haiku")
15
- MODEL_LABELS = {
16
- "opus": "OPUS",
17
- "sonnet": "SONNET",
18
- "haiku": "HAIKU",
14
+ # 模型 key 及其对应的环境变量,dict 顺序即主界面展示顺序。
15
+ # auto 对应客户端 auto mode 分类器模型,其余沿用 ANTHROPIC_DEFAULT_<KEY>_MODEL。
16
+ MODEL_ENV_VARS = {
17
+ "opus": "ANTHROPIC_DEFAULT_OPUS_MODEL",
18
+ "sonnet": "ANTHROPIC_DEFAULT_SONNET_MODEL",
19
+ "haiku": "ANTHROPIC_DEFAULT_HAIKU_MODEL",
20
+ "auto": "CLAUDE_CODE_AUTO_MODE_MODEL",
19
21
  }
22
+ MODEL_KEYS = tuple(MODEL_ENV_VARS)
23
+ MODEL_LABELS = {key: key.upper() for key in MODEL_KEYS}
24
+
25
+ # auto 为可选项,其余模型启动时必选
26
+ OPTIONAL_MODEL_KEYS = ("auto",)
27
+ REQUIRED_MODEL_KEYS = tuple(key for key in MODEL_KEYS if key not in OPTIONAL_MODEL_KEYS)
20
28
 
21
29
  # toggles 的默认值:值统一用字符串存储
22
30
  DEFAULT_TOGGLES: dict[str, str] = {
@@ -85,11 +93,7 @@ def default_config() -> dict[str, Any]:
85
93
  return {
86
94
  "base_url": DEFAULT_BASE_URL,
87
95
  "api_key": "",
88
- "models": {
89
- "opus": {"owned_by": None, "id": None},
90
- "sonnet": {"owned_by": None, "id": None},
91
- "haiku": {"owned_by": None, "id": None},
92
- },
96
+ "models": {key: {"owned_by": None, "id": None} for key in MODEL_KEYS},
93
97
  "toggles": DEFAULT_TOGGLES.copy(),
94
98
  "skip_permissions": False,
95
99
  "remote": copy.deepcopy(DEFAULT_REMOTE),