chatup 0.2.10__tar.gz → 0.2.12__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 (91) hide show
  1. {chatup-0.2.10/src/chatup.egg-info → chatup-0.2.12}/PKG-INFO +18 -8
  2. {chatup-0.2.10 → chatup-0.2.12}/README.md +7 -1
  3. {chatup-0.2.10 → chatup-0.2.12}/pyproject.toml +11 -6
  4. {chatup-0.2.10 → chatup-0.2.12}/src/chatup/__init__.py +1 -1
  5. chatup-0.2.12/src/chatup/cli.py +38 -0
  6. {chatup-0.2.10 → chatup-0.2.12}/src/chatup/setup/elements.py +103 -0
  7. {chatup-0.2.10 → chatup-0.2.12}/src/chatup/setup/service_credentials.py +10 -6
  8. chatup-0.2.12/src/chatup/setup/twikoo.py +403 -0
  9. {chatup-0.2.10 → chatup-0.2.12/src/chatup.egg-info}/PKG-INFO +18 -8
  10. {chatup-0.2.10 → chatup-0.2.12}/src/chatup.egg-info/SOURCES.txt +2 -0
  11. chatup-0.2.12/src/chatup.egg-info/requires.txt +15 -0
  12. {chatup-0.2.10 → chatup-0.2.12}/tests/test_cli_tree_docs.py +2 -0
  13. {chatup-0.2.10 → chatup-0.2.12}/tests/test_publish_workflow.py +6 -0
  14. {chatup-0.2.10 → chatup-0.2.12}/tests/test_pyproject_metadata.py +5 -3
  15. {chatup-0.2.10 → chatup-0.2.12}/tests/test_service_installers.py +40 -0
  16. chatup-0.2.12/tests/test_twikoo_setup.py +136 -0
  17. chatup-0.2.12/tests/test_version.py +64 -0
  18. chatup-0.2.10/src/chatup/cli.py +0 -111
  19. chatup-0.2.10/src/chatup.egg-info/requires.txt +0 -10
  20. chatup-0.2.10/tests/test_version.py +0 -45
  21. {chatup-0.2.10 → chatup-0.2.12}/LICENSE +0 -0
  22. {chatup-0.2.10 → chatup-0.2.12}/setup.cfg +0 -0
  23. {chatup-0.2.10 → chatup-0.2.12}/src/chatup/chrome_for_testing.py +0 -0
  24. {chatup-0.2.10 → chatup-0.2.12}/src/chatup/chromedriver.py +0 -0
  25. {chatup-0.2.10 → chatup-0.2.12}/src/chatup/commands/__init__.py +0 -0
  26. {chatup-0.2.10 → chatup-0.2.12}/src/chatup/commands/chrome_for_testing.py +0 -0
  27. {chatup-0.2.10 → chatup-0.2.12}/src/chatup/commands/chromedriver.py +0 -0
  28. {chatup-0.2.10 → chatup-0.2.12}/src/chatup/commands/playwright.py +0 -0
  29. {chatup-0.2.10 → chatup-0.2.12}/src/chatup/config.py +0 -0
  30. {chatup-0.2.10 → chatup-0.2.12}/src/chatup/const.py +0 -0
  31. {chatup-0.2.10 → chatup-0.2.12}/src/chatup/interaction/__init__.py +0 -0
  32. {chatup-0.2.10 → chatup-0.2.12}/src/chatup/interaction/command_schema.py +0 -0
  33. {chatup-0.2.10 → chatup-0.2.12}/src/chatup/interaction/policy.py +0 -0
  34. {chatup-0.2.10 → chatup-0.2.12}/src/chatup/interaction/warnings.py +0 -0
  35. {chatup-0.2.10 → chatup-0.2.12}/src/chatup/playwright.py +0 -0
  36. {chatup-0.2.10 → chatup-0.2.12}/src/chatup/runtime/__init__.py +0 -0
  37. {chatup-0.2.10 → chatup-0.2.12}/src/chatup/runtime/_managed_artifact.py +0 -0
  38. {chatup-0.2.10 → chatup-0.2.12}/src/chatup/runtime/chrome_for_testing.py +0 -0
  39. {chatup-0.2.10 → chatup-0.2.12}/src/chatup/runtime/chromedriver.py +0 -0
  40. {chatup-0.2.10 → chatup-0.2.12}/src/chatup/runtime/playwright.py +0 -0
  41. {chatup-0.2.10 → chatup-0.2.12}/src/chatup/setup/__init__.py +0 -0
  42. {chatup-0.2.10 → chatup-0.2.12}/src/chatup/setup/assets/hermes/install.sh +0 -0
  43. {chatup-0.2.10 → chatup-0.2.12}/src/chatup/setup/assets/nvm.sh +0 -0
  44. {chatup-0.2.10 → chatup-0.2.12}/src/chatup/setup/cc_connect.py +0 -0
  45. {chatup-0.2.10 → chatup-0.2.12}/src/chatup/setup/claude.py +0 -0
  46. {chatup-0.2.10 → chatup-0.2.12}/src/chatup/setup/cli.py +0 -0
  47. {chatup-0.2.10 → chatup-0.2.12}/src/chatup/setup/codex.py +0 -0
  48. {chatup-0.2.10 → chatup-0.2.12}/src/chatup/setup/crs.py +0 -0
  49. {chatup-0.2.10 → chatup-0.2.12}/src/chatup/setup/cursor_agent.py +0 -0
  50. {chatup-0.2.10 → chatup-0.2.12}/src/chatup/setup/discourse.py +0 -0
  51. {chatup-0.2.10 → chatup-0.2.12}/src/chatup/setup/docker.py +0 -0
  52. {chatup-0.2.10 → chatup-0.2.12}/src/chatup/setup/frp.py +0 -0
  53. {chatup-0.2.10 → chatup-0.2.12}/src/chatup/setup/gitea.py +0 -0
  54. {chatup-0.2.10 → chatup-0.2.12}/src/chatup/setup/hermes.py +0 -0
  55. {chatup-0.2.10 → chatup-0.2.12}/src/chatup/setup/lark_cli.py +0 -0
  56. {chatup-0.2.10 → chatup-0.2.12}/src/chatup/setup/mode_prompt.py +0 -0
  57. {chatup-0.2.10 → chatup-0.2.12}/src/chatup/setup/mysql.py +0 -0
  58. {chatup-0.2.10 → chatup-0.2.12}/src/chatup/setup/nginx.py +0 -0
  59. {chatup-0.2.10 → chatup-0.2.12}/src/chatup/setup/nodejs.py +0 -0
  60. {chatup-0.2.10 → chatup-0.2.12}/src/chatup/setup/opencode.py +0 -0
  61. {chatup-0.2.10 → chatup-0.2.12}/src/chatup/setup/shell_rc.py +0 -0
  62. {chatup-0.2.10 → chatup-0.2.12}/src/chatup/setup/uv.py +0 -0
  63. {chatup-0.2.10 → chatup-0.2.12}/src/chatup/setup/workspace/__init__.py +0 -0
  64. {chatup-0.2.10 → chatup-0.2.12}/src/chatup/setup/workspace/cli.py +0 -0
  65. {chatup-0.2.10 → chatup-0.2.12}/src/chatup/setup/workspace/core.py +0 -0
  66. {chatup-0.2.10 → chatup-0.2.12}/src/chatup/setup/workspace/options.py +0 -0
  67. {chatup-0.2.10 → chatup-0.2.12}/src/chatup/setup/workspace/render.py +0 -0
  68. {chatup-0.2.10 → chatup-0.2.12}/src/chatup/setup/workspace/templates/default/en/AGENTS.md +0 -0
  69. {chatup-0.2.10 → chatup-0.2.12}/src/chatup/setup/workspace/templates/default/en/discussion/README.md +0 -0
  70. {chatup-0.2.10 → chatup-0.2.12}/src/chatup/setup/workspace/templates/default/en/projects/README.md +0 -0
  71. {chatup-0.2.10 → chatup-0.2.12}/src/chatup/setup/workspace/templates/default/zh/AGENTS.md +0 -0
  72. {chatup-0.2.10 → chatup-0.2.12}/src/chatup/setup/workspace/templates/default/zh/discussion/README.md +0 -0
  73. {chatup-0.2.10 → chatup-0.2.12}/src/chatup/setup/workspace/templates/default/zh/projects/README.md +0 -0
  74. {chatup-0.2.10 → chatup-0.2.12}/src/chatup/setup/workspace.py +0 -0
  75. {chatup-0.2.10 → chatup-0.2.12}/src/chatup/setup/zsh.py +0 -0
  76. {chatup-0.2.10 → chatup-0.2.12}/src/chatup/setup/zulip.py +0 -0
  77. {chatup-0.2.10 → chatup-0.2.12}/src/chatup/utils/__init__.py +0 -0
  78. {chatup-0.2.10 → chatup-0.2.12}/src/chatup/utils/custom_logger.py +0 -0
  79. {chatup-0.2.10 → chatup-0.2.12}/src/chatup/utils/pathing.py +0 -0
  80. {chatup-0.2.10 → chatup-0.2.12}/src/chatup.egg-info/dependency_links.txt +0 -0
  81. {chatup-0.2.10 → chatup-0.2.12}/src/chatup.egg-info/entry_points.txt +0 -0
  82. {chatup-0.2.10 → chatup-0.2.12}/src/chatup.egg-info/top_level.txt +0 -0
  83. {chatup-0.2.10 → chatup-0.2.12}/tests/test_browser_backend_cli.py +0 -0
  84. {chatup-0.2.10 → chatup-0.2.12}/tests/test_chrome_for_testing.py +0 -0
  85. {chatup-0.2.10 → chatup-0.2.12}/tests/test_chromedriver.py +0 -0
  86. {chatup-0.2.10 → chatup-0.2.12}/tests/test_crs_setup.py +0 -0
  87. {chatup-0.2.10 → chatup-0.2.12}/tests/test_cursor_agent_setup.py +0 -0
  88. {chatup-0.2.10 → chatup-0.2.12}/tests/test_playwright.py +0 -0
  89. {chatup-0.2.10 → chatup-0.2.12}/tests/test_playwright_cli.py +0 -0
  90. {chatup-0.2.10 → chatup-0.2.12}/tests/test_setup_cli.py +0 -0
  91. {chatup-0.2.10 → chatup-0.2.12}/tests/test_workspace_setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: chatup
3
- Version: 0.2.10
3
+ Version: 0.2.12
4
4
  Summary: ChatArch setup CLI extracted from ChatTool
5
5
  Author-email: rexwzh <1073853456@qq.com>
6
6
  License-Expression: MIT
@@ -13,15 +13,19 @@ Classifier: Operating System :: OS Independent
13
13
  Requires-Python: >=3.10
14
14
  Description-Content-Type: text/markdown
15
15
  License-File: LICENSE
16
- Requires-Dist: click>=8.0
17
- Requires-Dist: chatstyle<0.2.0,>=0.1.1
18
- Requires-Dist: chatenv<0.3.0,>=0.2.0
16
+ Requires-Dist: click<9.0,>=8.0
17
+ Requires-Dist: chatstyle<0.3.0,>=0.2.0
18
+ Requires-Dist: chatenv<0.3.0,>=0.2.10
19
19
  Requires-Dist: colorama
20
+ Provides-Extra: dev
21
+ Requires-Dist: build; extra == "dev"
22
+ Requires-Dist: pytest; extra == "dev"
23
+ Requires-Dist: twine; extra == "dev"
20
24
  Provides-Extra: docs
21
25
  Requires-Dist: mkdocs<2.0,>=1.6; extra == "docs"
22
- Requires-Dist: mkdocs-material<10.0,>=9.5; extra == "docs"
23
- Requires-Dist: mkdocs-static-i18n<2.0,>=1.3; extra == "docs"
24
- Requires-Dist: mike<3.0,>=2.1; extra == "docs"
26
+ Requires-Dist: mkdocs-material<9.7,>=9.5; extra == "docs"
27
+ Requires-Dist: mkdocs-static-i18n<2.0,>=1.2; extra == "docs"
28
+ Requires-Dist: mike<3.0,>=2.0; extra == "docs"
25
29
  Dynamic: license-file
26
30
 
27
31
  # ChatUp
@@ -47,6 +51,9 @@ ChatUp 是 ChatArch 的独立环境与工具安装 CLI。它承接原来 `chatto
47
51
 
48
52
  ```bash
49
53
  chatup --help
54
+ chatup --version
55
+ chatup --tree
56
+ chatup --tree-brief
50
57
  chatup doctor
51
58
  chatup uv
52
59
  chatup chrome-for-testing install --channel stable -I
@@ -75,7 +82,7 @@ chatup crs --install-dir ~/.chatarch/crs/local --port 12392 --redis-port 6379
75
82
  | 本地服务安装 | `gitea`、`discourse`、`zulip`、`mysql`、`nginx`、`crs` |
76
83
  | Agent 工具链 | `cc-connect`、`claude`、`codex`、`cursor-agent`、`opencode`、`hermes`、`lark-cli` |
77
84
 
78
- 所有新增安装项默认目录都收敛到 `~/.chatarch/...`,例如 `~/.chatarch/chrome-for-testing`、`~/.chatarch/chromedriver`、`~/.chatarch/playwright`、`~/.chatarch/chattea`、`~/.chatarch/discourse`、`~/.chatarch/zulip`、`~/.chatarch/chatdata`、`~/.chatarch/nginx` 和 `~/.chatarch/crs/local`。`cursor-agent` 额外注册 ChatEnv `CursorAgent` profile,`discourse`/`zulip` 注册管理员凭据 profile,并支持 `-e/--env` 从 env 文件或 profile 快速配置。更完整的能力边界见 `docs/capability-map.md`。
85
+ 所有新增安装项默认目录都收敛到 `~/.chatarch/...`,例如 `~/.chatarch/chrome-for-testing`、`~/.chatarch/chromedriver`、`~/.chatarch/playwright`、`~/.chatarch/chattea`、`~/.chatarch/discourse`、`~/.chatarch/zulip`、`~/.chatarch/chatdata`、`~/.chatarch/nginx` 和 `~/.chatarch/crs/local`。`cursor-agent` 额外注册 ChatEnv `CursorAgent` profile,`discourse`/`zulip` 注册管理员凭据 profile,并支持 `-e/--env` 从 env 文件或 profile 快速配置;显式选择 profile 时不会混入进程环境中的其他账号凭据。CLI 树由 ChatStyle 的注册表渲染。更完整的能力边界见 `docs/capability-map.md`。
79
86
 
80
87
  ## 开发
81
88
 
@@ -84,6 +91,9 @@ python -m pytest -q
84
91
  python -m build
85
92
  python -m twine check dist/*
86
93
  mkdocs build --strict
94
+ chatup --version
95
+ chatup --tree
96
+ chatup --tree-brief
87
97
  ```
88
98
 
89
99
  更多使用说明见文档站的 [快速开始](https://arch.gh.wzhecnu.cn/ChatUp/quickstart/)、[命令参考](https://arch.gh.wzhecnu.cn/ChatUp/commands/) 和 [CLI 能力地图](https://arch.gh.wzhecnu.cn/ChatUp/capability-map/)。
@@ -21,6 +21,9 @@ ChatUp 是 ChatArch 的独立环境与工具安装 CLI。它承接原来 `chatto
21
21
 
22
22
  ```bash
23
23
  chatup --help
24
+ chatup --version
25
+ chatup --tree
26
+ chatup --tree-brief
24
27
  chatup doctor
25
28
  chatup uv
26
29
  chatup chrome-for-testing install --channel stable -I
@@ -49,7 +52,7 @@ chatup crs --install-dir ~/.chatarch/crs/local --port 12392 --redis-port 6379
49
52
  | 本地服务安装 | `gitea`、`discourse`、`zulip`、`mysql`、`nginx`、`crs` |
50
53
  | Agent 工具链 | `cc-connect`、`claude`、`codex`、`cursor-agent`、`opencode`、`hermes`、`lark-cli` |
51
54
 
52
- 所有新增安装项默认目录都收敛到 `~/.chatarch/...`,例如 `~/.chatarch/chrome-for-testing`、`~/.chatarch/chromedriver`、`~/.chatarch/playwright`、`~/.chatarch/chattea`、`~/.chatarch/discourse`、`~/.chatarch/zulip`、`~/.chatarch/chatdata`、`~/.chatarch/nginx` 和 `~/.chatarch/crs/local`。`cursor-agent` 额外注册 ChatEnv `CursorAgent` profile,`discourse`/`zulip` 注册管理员凭据 profile,并支持 `-e/--env` 从 env 文件或 profile 快速配置。更完整的能力边界见 `docs/capability-map.md`。
55
+ 所有新增安装项默认目录都收敛到 `~/.chatarch/...`,例如 `~/.chatarch/chrome-for-testing`、`~/.chatarch/chromedriver`、`~/.chatarch/playwright`、`~/.chatarch/chattea`、`~/.chatarch/discourse`、`~/.chatarch/zulip`、`~/.chatarch/chatdata`、`~/.chatarch/nginx` 和 `~/.chatarch/crs/local`。`cursor-agent` 额外注册 ChatEnv `CursorAgent` profile,`discourse`/`zulip` 注册管理员凭据 profile,并支持 `-e/--env` 从 env 文件或 profile 快速配置;显式选择 profile 时不会混入进程环境中的其他账号凭据。CLI 树由 ChatStyle 的注册表渲染。更完整的能力边界见 `docs/capability-map.md`。
53
56
 
54
57
  ## 开发
55
58
 
@@ -58,6 +61,9 @@ python -m pytest -q
58
61
  python -m build
59
62
  python -m twine check dist/*
60
63
  mkdocs build --strict
64
+ chatup --version
65
+ chatup --tree
66
+ chatup --tree-brief
61
67
  ```
62
68
 
63
69
  更多使用说明见文档站的 [快速开始](https://arch.gh.wzhecnu.cn/ChatUp/quickstart/)、[命令参考](https://arch.gh.wzhecnu.cn/ChatUp/commands/) 和 [CLI 能力地图](https://arch.gh.wzhecnu.cn/ChatUp/capability-map/)。
@@ -10,9 +10,9 @@ readme = "README.md"
10
10
  requires-python = ">=3.10"
11
11
  license = "MIT"
12
12
  dependencies = [
13
- "click>=8.0",
14
- "chatstyle>=0.1.1,<0.2.0",
15
- "chatenv>=0.2.0,<0.3.0",
13
+ "click>=8.0,<9.0",
14
+ "chatstyle>=0.2.0,<0.3.0",
15
+ "chatenv>=0.2.10,<0.3.0",
16
16
  "colorama",
17
17
  ]
18
18
  authors = [{name = "rexwzh", email = "1073853456@qq.com"}]
@@ -28,11 +28,16 @@ Source = "https://github.com/ChatArch/ChatUp"
28
28
  Issues = "https://github.com/ChatArch/ChatUp/issues"
29
29
 
30
30
  [project.optional-dependencies]
31
+ dev = [
32
+ "build",
33
+ "pytest",
34
+ "twine",
35
+ ]
31
36
  docs = [
32
37
  "mkdocs>=1.6,<2.0",
33
- "mkdocs-material>=9.5,<10.0",
34
- "mkdocs-static-i18n>=1.3,<2.0",
35
- "mike>=2.1,<3.0",
38
+ "mkdocs-material>=9.5,<9.7",
39
+ "mkdocs-static-i18n>=1.2,<2.0",
40
+ "mike>=2.0,<3.0",
36
41
  ]
37
42
 
38
43
  [project.scripts]
@@ -2,4 +2,4 @@
2
2
 
3
3
  __all__ = ["__version__"]
4
4
 
5
- __version__ = "0.2.10"
5
+ __version__ = "0.2.12"
@@ -0,0 +1,38 @@
1
+ from __future__ import annotations
2
+
3
+ import click
4
+ from chatstyle import add_tree_option
5
+
6
+ from chatup import __version__
7
+ from chatup.commands.chrome_for_testing import cli as chrome_for_testing_cli
8
+ from chatup.commands.chromedriver import cli as chromedriver_cli
9
+ from chatup.commands.playwright import cli as playwright_cli
10
+ from chatup.setup.cli import register_setup_commands
11
+
12
+
13
+ @click.group(
14
+ name="chatup",
15
+ context_settings={"help_option_names": ["-h", "--help"]},
16
+ invoke_without_command=True,
17
+ no_args_is_help=True,
18
+ )
19
+ @click.version_option(__version__, prog_name="chatup")
20
+ @add_tree_option(renderer_options={"root_name": "chatup"})
21
+ def main() -> None:
22
+ """ChatUp CLI for ChatArch bootstrap workflows."""
23
+
24
+
25
+ @main.command(name="doctor")
26
+ def doctor() -> None:
27
+ """Check that ChatUp is installed and callable."""
28
+ click.echo(f"chatup {__version__} ok")
29
+
30
+
31
+ register_setup_commands(main)
32
+ main.add_command(chrome_for_testing_cli)
33
+ main.add_command(chromedriver_cli)
34
+ main.add_command(playwright_cli)
35
+
36
+
37
+ if __name__ == "__main__":
38
+ main()
@@ -54,6 +54,14 @@ from chatup.setup.nginx import (
54
54
  )
55
55
  from chatup.setup.opencode import setup_opencode
56
56
  from chatup.setup.nodejs import setup_nodejs
57
+ from chatup.setup.twikoo import (
58
+ DEFAULT_TWIKOO_BIND_ADDRESS,
59
+ DEFAULT_TWIKOO_INSTANCE,
60
+ DEFAULT_TWIKOO_PORT,
61
+ DEFAULT_TWIKOO_REPO,
62
+ DEFAULT_TWIKOO_VERSION,
63
+ setup_twikoo,
64
+ )
57
65
  from chatup.setup.uv import DEFAULT_PYTHON_VERSION, DEFAULT_VENV_PATH, setup_uv
58
66
  from chatup.setup.workspace import setup_workspace
59
67
  from chatup.setup.zsh import setup_zsh
@@ -304,6 +312,41 @@ def mysql_setup(
304
312
  )
305
313
 
306
314
 
315
+ def twikoo_setup(
316
+ version,
317
+ repo,
318
+ home,
319
+ name,
320
+ port,
321
+ bind_address,
322
+ install,
323
+ init,
324
+ service,
325
+ start,
326
+ smoke,
327
+ force,
328
+ log_level,
329
+ ):
330
+ result = setup_twikoo(
331
+ name=name,
332
+ version=version,
333
+ repo=repo,
334
+ home=home,
335
+ port=port,
336
+ bind_address=bind_address,
337
+ install=install,
338
+ init=init,
339
+ service=service,
340
+ start=start,
341
+ smoke=smoke,
342
+ force=force,
343
+ log_level=log_level,
344
+ )
345
+ service_info = result.get("service") if isinstance(result, dict) else None
346
+ if isinstance(service_info, dict) and service_info.get("unit"):
347
+ click.echo(service_info["unit"])
348
+
349
+
307
350
  def nginx_setup(
308
351
  template,
309
352
  output_file,
@@ -870,6 +913,66 @@ SETUP_COMMAND_ELEMENTS = (
870
913
  ),
871
914
  ),
872
915
  ),
916
+ SetupCommandElement(
917
+ name="twikoo",
918
+ help="Install and prepare a multi-instance Twikoo comment service runtime.",
919
+ callback=twikoo_setup,
920
+ options=(
921
+ LOG_LEVEL_OPTION,
922
+ SetupOptionElement(
923
+ param_decls=("--version",),
924
+ kwargs={"default": DEFAULT_TWIKOO_VERSION, "show_default": True},
925
+ ),
926
+ SetupOptionElement(
927
+ param_decls=("--repo",),
928
+ kwargs={"default": DEFAULT_TWIKOO_REPO, "show_default": True},
929
+ ),
930
+ SetupOptionElement(
931
+ param_decls=("--home",),
932
+ kwargs={
933
+ "default": None,
934
+ "type": click.Path(path_type=Path),
935
+ "help": "Twikoo home. Defaults to ~/.chatarch/twikoo.",
936
+ },
937
+ ),
938
+ SetupOptionElement(
939
+ param_decls=("--name",),
940
+ kwargs={"default": DEFAULT_TWIKOO_INSTANCE, "show_default": True},
941
+ ),
942
+ SetupOptionElement(
943
+ param_decls=("--port",),
944
+ kwargs={"default": DEFAULT_TWIKOO_PORT, "show_default": True, "type": int},
945
+ ),
946
+ SetupOptionElement(
947
+ param_decls=("--bind-address",),
948
+ kwargs={"default": DEFAULT_TWIKOO_BIND_ADDRESS, "show_default": True},
949
+ ),
950
+ SetupOptionElement(
951
+ param_decls=("--install/--no-install",),
952
+ kwargs={"default": True, "show_default": True, "help": "Download the Twikoo release binary."},
953
+ ),
954
+ SetupOptionElement(
955
+ param_decls=("--init/--no-init",),
956
+ kwargs={"default": True, "show_default": True, "help": "Create instance directories, env file, and instance-local binary link."},
957
+ ),
958
+ SetupOptionElement(
959
+ param_decls=("--service/--no-service",),
960
+ kwargs={"default": True, "show_default": True, "help": "Install a user-level systemd service."},
961
+ ),
962
+ SetupOptionElement(
963
+ param_decls=("--start/--no-start",),
964
+ kwargs={"default": False, "show_default": True, "help": "Start the user-level Twikoo service."},
965
+ ),
966
+ SetupOptionElement(
967
+ param_decls=("--smoke/--no-smoke",),
968
+ kwargs={"default": False, "show_default": True, "help": "Run a local HTTP smoke test after starting."},
969
+ ),
970
+ SetupOptionElement(
971
+ param_decls=("--force", "-f"),
972
+ kwargs={"is_flag": True, "help": "Replace existing runtime/config/service where supported."},
973
+ ),
974
+ ),
975
+ ),
873
976
  SetupCommandElement(
874
977
  name="nginx",
875
978
  help="Prepare user-level NGINX under ChatArch home and render config templates.",
@@ -29,16 +29,19 @@ def load_chatenv_values(
29
29
  ) -> tuple[dict[str, str], str]:
30
30
  """Load service setup values without printing secrets.
31
31
 
32
- Precedence is current environment > explicit env file/profile values.
33
32
  The env_ref option mirrors Cursor Agent's `-e/--env`: an existing path is
34
33
  parsed as a dotenv-style file; otherwise it is treated as a ChatEnv profile.
34
+ Explicit files/profiles are isolated from process-environment credentials;
35
+ the process environment is used only when no explicit source is selected.
35
36
  """
36
37
 
37
38
  values: dict[str, str] = {}
38
39
  source = "environment"
39
40
  store = EnvStore(get_paths().envs_dir)
41
+ explicit_source = False
40
42
 
41
43
  if env_ref:
44
+ explicit_source = True
42
45
  candidate = Path(env_ref).expanduser()
43
46
  if candidate.exists():
44
47
  values.update(parse_env_file(candidate))
@@ -48,14 +51,15 @@ def load_chatenv_values(
48
51
  source = f"ChatEnv profile {env_ref}"
49
52
 
50
53
  if env_profile:
54
+ explicit_source = True
51
55
  values.update(store.load_profile(config_cls, env_profile))
52
56
  source = f"ChatEnv profile {env_profile}"
53
57
 
54
- for key in config_cls.get_fields():
55
- env_value = os.getenv(key)
56
- if env_value:
57
- values[key] = env_value
58
- source = "environment"
58
+ if not explicit_source:
59
+ for key in config_cls.get_fields():
60
+ env_value = os.getenv(key)
61
+ if env_value:
62
+ values[key] = env_value
59
63
  return values, source
60
64
 
61
65