chatup 0.2.12__tar.gz → 0.2.13__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 (89) hide show
  1. {chatup-0.2.12/src/chatup.egg-info → chatup-0.2.13}/PKG-INFO +2 -2
  2. {chatup-0.2.12 → chatup-0.2.13}/pyproject.toml +1 -1
  3. {chatup-0.2.12 → chatup-0.2.13}/src/chatup/__init__.py +1 -1
  4. {chatup-0.2.12 → chatup-0.2.13}/src/chatup/setup/codex.py +60 -34
  5. {chatup-0.2.12 → chatup-0.2.13/src/chatup.egg-info}/PKG-INFO +2 -2
  6. {chatup-0.2.12 → chatup-0.2.13}/src/chatup.egg-info/SOURCES.txt +1 -0
  7. {chatup-0.2.12 → chatup-0.2.13}/src/chatup.egg-info/requires.txt +1 -1
  8. chatup-0.2.13/tests/test_codex_setup.py +151 -0
  9. {chatup-0.2.12 → chatup-0.2.13}/tests/test_pyproject_metadata.py +1 -1
  10. {chatup-0.2.12 → chatup-0.2.13}/tests/test_version.py +2 -2
  11. {chatup-0.2.12 → chatup-0.2.13}/LICENSE +0 -0
  12. {chatup-0.2.12 → chatup-0.2.13}/README.md +0 -0
  13. {chatup-0.2.12 → chatup-0.2.13}/setup.cfg +0 -0
  14. {chatup-0.2.12 → chatup-0.2.13}/src/chatup/chrome_for_testing.py +0 -0
  15. {chatup-0.2.12 → chatup-0.2.13}/src/chatup/chromedriver.py +0 -0
  16. {chatup-0.2.12 → chatup-0.2.13}/src/chatup/cli.py +0 -0
  17. {chatup-0.2.12 → chatup-0.2.13}/src/chatup/commands/__init__.py +0 -0
  18. {chatup-0.2.12 → chatup-0.2.13}/src/chatup/commands/chrome_for_testing.py +0 -0
  19. {chatup-0.2.12 → chatup-0.2.13}/src/chatup/commands/chromedriver.py +0 -0
  20. {chatup-0.2.12 → chatup-0.2.13}/src/chatup/commands/playwright.py +0 -0
  21. {chatup-0.2.12 → chatup-0.2.13}/src/chatup/config.py +0 -0
  22. {chatup-0.2.12 → chatup-0.2.13}/src/chatup/const.py +0 -0
  23. {chatup-0.2.12 → chatup-0.2.13}/src/chatup/interaction/__init__.py +0 -0
  24. {chatup-0.2.12 → chatup-0.2.13}/src/chatup/interaction/command_schema.py +0 -0
  25. {chatup-0.2.12 → chatup-0.2.13}/src/chatup/interaction/policy.py +0 -0
  26. {chatup-0.2.12 → chatup-0.2.13}/src/chatup/interaction/warnings.py +0 -0
  27. {chatup-0.2.12 → chatup-0.2.13}/src/chatup/playwright.py +0 -0
  28. {chatup-0.2.12 → chatup-0.2.13}/src/chatup/runtime/__init__.py +0 -0
  29. {chatup-0.2.12 → chatup-0.2.13}/src/chatup/runtime/_managed_artifact.py +0 -0
  30. {chatup-0.2.12 → chatup-0.2.13}/src/chatup/runtime/chrome_for_testing.py +0 -0
  31. {chatup-0.2.12 → chatup-0.2.13}/src/chatup/runtime/chromedriver.py +0 -0
  32. {chatup-0.2.12 → chatup-0.2.13}/src/chatup/runtime/playwright.py +0 -0
  33. {chatup-0.2.12 → chatup-0.2.13}/src/chatup/setup/__init__.py +0 -0
  34. {chatup-0.2.12 → chatup-0.2.13}/src/chatup/setup/assets/hermes/install.sh +0 -0
  35. {chatup-0.2.12 → chatup-0.2.13}/src/chatup/setup/assets/nvm.sh +0 -0
  36. {chatup-0.2.12 → chatup-0.2.13}/src/chatup/setup/cc_connect.py +0 -0
  37. {chatup-0.2.12 → chatup-0.2.13}/src/chatup/setup/claude.py +0 -0
  38. {chatup-0.2.12 → chatup-0.2.13}/src/chatup/setup/cli.py +0 -0
  39. {chatup-0.2.12 → chatup-0.2.13}/src/chatup/setup/crs.py +0 -0
  40. {chatup-0.2.12 → chatup-0.2.13}/src/chatup/setup/cursor_agent.py +0 -0
  41. {chatup-0.2.12 → chatup-0.2.13}/src/chatup/setup/discourse.py +0 -0
  42. {chatup-0.2.12 → chatup-0.2.13}/src/chatup/setup/docker.py +0 -0
  43. {chatup-0.2.12 → chatup-0.2.13}/src/chatup/setup/elements.py +0 -0
  44. {chatup-0.2.12 → chatup-0.2.13}/src/chatup/setup/frp.py +0 -0
  45. {chatup-0.2.12 → chatup-0.2.13}/src/chatup/setup/gitea.py +0 -0
  46. {chatup-0.2.12 → chatup-0.2.13}/src/chatup/setup/hermes.py +0 -0
  47. {chatup-0.2.12 → chatup-0.2.13}/src/chatup/setup/lark_cli.py +0 -0
  48. {chatup-0.2.12 → chatup-0.2.13}/src/chatup/setup/mode_prompt.py +0 -0
  49. {chatup-0.2.12 → chatup-0.2.13}/src/chatup/setup/mysql.py +0 -0
  50. {chatup-0.2.12 → chatup-0.2.13}/src/chatup/setup/nginx.py +0 -0
  51. {chatup-0.2.12 → chatup-0.2.13}/src/chatup/setup/nodejs.py +0 -0
  52. {chatup-0.2.12 → chatup-0.2.13}/src/chatup/setup/opencode.py +0 -0
  53. {chatup-0.2.12 → chatup-0.2.13}/src/chatup/setup/service_credentials.py +0 -0
  54. {chatup-0.2.12 → chatup-0.2.13}/src/chatup/setup/shell_rc.py +0 -0
  55. {chatup-0.2.12 → chatup-0.2.13}/src/chatup/setup/twikoo.py +0 -0
  56. {chatup-0.2.12 → chatup-0.2.13}/src/chatup/setup/uv.py +0 -0
  57. {chatup-0.2.12 → chatup-0.2.13}/src/chatup/setup/workspace/__init__.py +0 -0
  58. {chatup-0.2.12 → chatup-0.2.13}/src/chatup/setup/workspace/cli.py +0 -0
  59. {chatup-0.2.12 → chatup-0.2.13}/src/chatup/setup/workspace/core.py +0 -0
  60. {chatup-0.2.12 → chatup-0.2.13}/src/chatup/setup/workspace/options.py +0 -0
  61. {chatup-0.2.12 → chatup-0.2.13}/src/chatup/setup/workspace/render.py +0 -0
  62. {chatup-0.2.12 → chatup-0.2.13}/src/chatup/setup/workspace/templates/default/en/AGENTS.md +0 -0
  63. {chatup-0.2.12 → chatup-0.2.13}/src/chatup/setup/workspace/templates/default/en/discussion/README.md +0 -0
  64. {chatup-0.2.12 → chatup-0.2.13}/src/chatup/setup/workspace/templates/default/en/projects/README.md +0 -0
  65. {chatup-0.2.12 → chatup-0.2.13}/src/chatup/setup/workspace/templates/default/zh/AGENTS.md +0 -0
  66. {chatup-0.2.12 → chatup-0.2.13}/src/chatup/setup/workspace/templates/default/zh/discussion/README.md +0 -0
  67. {chatup-0.2.12 → chatup-0.2.13}/src/chatup/setup/workspace/templates/default/zh/projects/README.md +0 -0
  68. {chatup-0.2.12 → chatup-0.2.13}/src/chatup/setup/workspace.py +0 -0
  69. {chatup-0.2.12 → chatup-0.2.13}/src/chatup/setup/zsh.py +0 -0
  70. {chatup-0.2.12 → chatup-0.2.13}/src/chatup/setup/zulip.py +0 -0
  71. {chatup-0.2.12 → chatup-0.2.13}/src/chatup/utils/__init__.py +0 -0
  72. {chatup-0.2.12 → chatup-0.2.13}/src/chatup/utils/custom_logger.py +0 -0
  73. {chatup-0.2.12 → chatup-0.2.13}/src/chatup/utils/pathing.py +0 -0
  74. {chatup-0.2.12 → chatup-0.2.13}/src/chatup.egg-info/dependency_links.txt +0 -0
  75. {chatup-0.2.12 → chatup-0.2.13}/src/chatup.egg-info/entry_points.txt +0 -0
  76. {chatup-0.2.12 → chatup-0.2.13}/src/chatup.egg-info/top_level.txt +0 -0
  77. {chatup-0.2.12 → chatup-0.2.13}/tests/test_browser_backend_cli.py +0 -0
  78. {chatup-0.2.12 → chatup-0.2.13}/tests/test_chrome_for_testing.py +0 -0
  79. {chatup-0.2.12 → chatup-0.2.13}/tests/test_chromedriver.py +0 -0
  80. {chatup-0.2.12 → chatup-0.2.13}/tests/test_cli_tree_docs.py +0 -0
  81. {chatup-0.2.12 → chatup-0.2.13}/tests/test_crs_setup.py +0 -0
  82. {chatup-0.2.12 → chatup-0.2.13}/tests/test_cursor_agent_setup.py +0 -0
  83. {chatup-0.2.12 → chatup-0.2.13}/tests/test_playwright.py +0 -0
  84. {chatup-0.2.12 → chatup-0.2.13}/tests/test_playwright_cli.py +0 -0
  85. {chatup-0.2.12 → chatup-0.2.13}/tests/test_publish_workflow.py +0 -0
  86. {chatup-0.2.12 → chatup-0.2.13}/tests/test_service_installers.py +0 -0
  87. {chatup-0.2.12 → chatup-0.2.13}/tests/test_setup_cli.py +0 -0
  88. {chatup-0.2.12 → chatup-0.2.13}/tests/test_twikoo_setup.py +0 -0
  89. {chatup-0.2.12 → chatup-0.2.13}/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.12
3
+ Version: 0.2.13
4
4
  Summary: ChatArch setup CLI extracted from ChatTool
5
5
  Author-email: rexwzh <1073853456@qq.com>
6
6
  License-Expression: MIT
@@ -15,7 +15,7 @@ Description-Content-Type: text/markdown
15
15
  License-File: LICENSE
16
16
  Requires-Dist: click<9.0,>=8.0
17
17
  Requires-Dist: chatstyle<0.3.0,>=0.2.0
18
- Requires-Dist: chatenv<0.3.0,>=0.2.10
18
+ Requires-Dist: chatenv<0.3.0,>=0.2.11
19
19
  Requires-Dist: colorama
20
20
  Provides-Extra: dev
21
21
  Requires-Dist: build; extra == "dev"
@@ -12,7 +12,7 @@ license = "MIT"
12
12
  dependencies = [
13
13
  "click>=8.0,<9.0",
14
14
  "chatstyle>=0.2.0,<0.3.0",
15
- "chatenv>=0.2.10,<0.3.0",
15
+ "chatenv>=0.2.11,<0.3.0",
16
16
  "colorama",
17
17
  ]
18
18
  authors = [{name = "rexwzh", email = "1073853456@qq.com"}]
@@ -2,4 +2,4 @@
2
2
 
3
3
  __all__ = ["__version__"]
4
4
 
5
- __version__ = "0.2.12"
5
+ __version__ = "0.2.13"
@@ -7,6 +7,7 @@ import click
7
7
  from chatenv.configs import OpenAIConfig
8
8
  from chatenv.fields import BaseEnvConfig
9
9
  from chatenv.source_chain import split_config_sources
10
+ from chatenv.store import EnvStore
10
11
  from chatup.const import CHATARCH_ENV_DIR, CHATARCH_ENV_FILE
11
12
  from chatup.interaction import (
12
13
  BACK_VALUE,
@@ -25,7 +26,7 @@ from chatup.setup.nodejs import (
25
26
  )
26
27
  from chatup.utils.custom_logger import setup_logger
27
28
 
28
- DEFAULT_MODEL = "gpt-5.4"
29
+ DEFAULT_MODEL = "gpt-5.5"
29
30
  DEFAULT_BASE_URL = "https://api.openai.com/v1"
30
31
  DEFAULT_AUTH_METHOD = "apikey"
31
32
  logger = setup_logger("setup_codex")
@@ -264,17 +265,24 @@ def _resolve_openai_env_path(env_ref: str) -> Path:
264
265
  )
265
266
 
266
267
 
268
+ def _openai_values_from_mapping(values: dict[str, str]) -> dict[str, str | None]:
269
+ return {
270
+ "openai_api_key": values.get("OPENAI_API_KEY"),
271
+ "base_url": values.get("OPENAI_API_BASE"),
272
+ "model": values.get("OPENAI_API_MODEL"),
273
+ }
274
+
275
+
267
276
  def _load_openai_values_from_env_ref(env_ref: str) -> dict[str, str | None]:
268
- current_values = _snapshot_openai_values()
269
- try:
270
- env_path = _resolve_openai_env_path(env_ref)
271
- BaseEnvConfig.load_all_with_override(
272
- CHATARCH_ENV_DIR,
273
- override_env_file=env_path,
274
- )
275
- return _snapshot_openai_values()
276
- finally:
277
- _restore_openai_values(current_values)
277
+ """Load only the explicitly selected OpenAI env file/profile.
278
+
279
+ `chatup codex -e PROFILE` is an account-selection boundary. Do not merge
280
+ the selected profile with the active/default ChatEnv profile or process
281
+ environment, otherwise a profile missing `OPENAI_API_KEY` can silently write
282
+ a different account's key into `~/.codex/auth.json`.
283
+ """
284
+ env_path = _resolve_openai_env_path(env_ref)
285
+ return _openai_values_from_mapping(EnvStore(CHATARCH_ENV_DIR).load_path(env_path))
278
286
 
279
287
 
280
288
  def setup_codex(
@@ -302,13 +310,19 @@ def setup_codex(
302
310
  if isinstance(model, str) and not model.strip():
303
311
  model = None
304
312
 
305
- api_key = resolve_value(
306
- api_key,
307
- env_config.get("openai_api_key"),
308
- existing_api_key,
309
- env_values.get("OPENAI_API_KEY"),
310
- typed_env_values.get("OPENAI_API_KEY"),
311
- )
313
+ if env_ref:
314
+ api_key = resolve_value(
315
+ api_key,
316
+ env_config.get("openai_api_key"),
317
+ )
318
+ else:
319
+ api_key = resolve_value(
320
+ api_key,
321
+ env_config.get("openai_api_key"),
322
+ existing_api_key,
323
+ env_values.get("OPENAI_API_KEY"),
324
+ typed_env_values.get("OPENAI_API_KEY"),
325
+ )
312
326
  missing_required = not api_key
313
327
  has_existing_config = any(
314
328
  value for key, value in existing.items() if key != "openai_api_key"
@@ -421,22 +435,34 @@ def setup_codex(
421
435
  click.echo(result.stderr.strip(), err=True)
422
436
  raise click.Abort()
423
437
 
424
- base_url = resolve_value(
425
- base_url,
426
- env_config.get("base_url"),
427
- existing.get("base_url"),
428
- env_values.get("OPENAI_API_BASE"),
429
- typed_env_values.get("OPENAI_API_BASE"),
430
- DEFAULT_BASE_URL,
431
- )
432
- model = resolve_value(
433
- model,
434
- env_config.get("model"),
435
- existing.get("model"),
436
- env_values.get("OPENAI_API_MODEL"),
437
- typed_env_values.get("OPENAI_API_MODEL"),
438
- DEFAULT_MODEL,
439
- )
438
+ if env_ref:
439
+ base_url = resolve_value(
440
+ base_url,
441
+ env_config.get("base_url"),
442
+ DEFAULT_BASE_URL,
443
+ )
444
+ model = resolve_value(
445
+ model,
446
+ env_config.get("model"),
447
+ DEFAULT_MODEL,
448
+ )
449
+ else:
450
+ base_url = resolve_value(
451
+ base_url,
452
+ env_config.get("base_url"),
453
+ existing.get("base_url"),
454
+ env_values.get("OPENAI_API_BASE"),
455
+ typed_env_values.get("OPENAI_API_BASE"),
456
+ DEFAULT_BASE_URL,
457
+ )
458
+ model = resolve_value(
459
+ model,
460
+ env_config.get("model"),
461
+ existing.get("model"),
462
+ env_values.get("OPENAI_API_MODEL"),
463
+ typed_env_values.get("OPENAI_API_MODEL"),
464
+ DEFAULT_MODEL,
465
+ )
440
466
 
441
467
  codex_dir.mkdir(parents=True, exist_ok=True)
442
468
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: chatup
3
- Version: 0.2.12
3
+ Version: 0.2.13
4
4
  Summary: ChatArch setup CLI extracted from ChatTool
5
5
  Author-email: rexwzh <1073853456@qq.com>
6
6
  License-Expression: MIT
@@ -15,7 +15,7 @@ Description-Content-Type: text/markdown
15
15
  License-File: LICENSE
16
16
  Requires-Dist: click<9.0,>=8.0
17
17
  Requires-Dist: chatstyle<0.3.0,>=0.2.0
18
- Requires-Dist: chatenv<0.3.0,>=0.2.10
18
+ Requires-Dist: chatenv<0.3.0,>=0.2.11
19
19
  Requires-Dist: colorama
20
20
  Provides-Extra: dev
21
21
  Requires-Dist: build; extra == "dev"
@@ -73,6 +73,7 @@ tests/test_browser_backend_cli.py
73
73
  tests/test_chrome_for_testing.py
74
74
  tests/test_chromedriver.py
75
75
  tests/test_cli_tree_docs.py
76
+ tests/test_codex_setup.py
76
77
  tests/test_crs_setup.py
77
78
  tests/test_cursor_agent_setup.py
78
79
  tests/test_playwright.py
@@ -1,6 +1,6 @@
1
1
  click<9.0,>=8.0
2
2
  chatstyle<0.3.0,>=0.2.0
3
- chatenv<0.3.0,>=0.2.10
3
+ chatenv<0.3.0,>=0.2.11
4
4
  colorama
5
5
 
6
6
  [dev]
@@ -0,0 +1,151 @@
1
+ from __future__ import annotations
2
+
3
+ import json
4
+
5
+ import click
6
+ import pytest
7
+
8
+
9
+ def _write_env(path, values):
10
+ path.parent.mkdir(parents=True, exist_ok=True)
11
+ lines = [f"{key}='{value}'" for key, value in values.items()]
12
+ path.write_text("\n".join(lines) + "\n", encoding="utf-8")
13
+
14
+
15
+ def test_codex_env_profile_does_not_backfill_missing_key_from_active_or_process_env(
16
+ tmp_path, monkeypatch
17
+ ):
18
+ import chatup.setup.codex as codex_setup
19
+
20
+ home = tmp_path / "home"
21
+ envs_dir = tmp_path / "chatarch" / "envs"
22
+ openai_dir = envs_dir / "OpenAI"
23
+ monkeypatch.setenv("HOME", str(home))
24
+ monkeypatch.setenv("OPENAI_API_KEY", "process-key-should-not-be-used")
25
+ monkeypatch.setenv("OPENAI_API_BASE", "https://process.example/v1")
26
+ monkeypatch.setenv("OPENAI_API_MODEL", "process-model")
27
+ monkeypatch.setattr(codex_setup, "CHATARCH_ENV_DIR", envs_dir)
28
+ monkeypatch.setattr(codex_setup, "CHATARCH_ENV_FILE", envs_dir / ".env")
29
+ monkeypatch.setattr(codex_setup, "ensure_nodejs_requirement", lambda **kwargs: None)
30
+ monkeypatch.setattr(
31
+ codex_setup,
32
+ "should_install_global_npm_package",
33
+ lambda *args, **kwargs: False,
34
+ )
35
+
36
+ _write_env(
37
+ openai_dir / ".env",
38
+ {
39
+ "OPENAI_API_KEY": "active-key-should-not-be-used",
40
+ "OPENAI_API_BASE": "https://active.example/v1",
41
+ "OPENAI_API_MODEL": "active-model",
42
+ },
43
+ )
44
+ _write_env(
45
+ openai_dir / "apple.env",
46
+ {
47
+ "OPENAI_API_BASE": "https://crs.example/openai/v1",
48
+ "OPENAI_API_MODEL": "gpt-5.5",
49
+ },
50
+ )
51
+
52
+ with pytest.raises(click.Abort):
53
+ codex_setup.setup_codex(env_ref="apple", interactive=False)
54
+
55
+ auth_path = home / ".codex" / "auth.json"
56
+ if auth_path.exists():
57
+ auth_data = json.loads(auth_path.read_text(encoding="utf-8"))
58
+ assert auth_data.get("OPENAI_API_KEY") not in {
59
+ "active-key-should-not-be-used",
60
+ "process-key-should-not-be-used",
61
+ }
62
+
63
+
64
+ def test_codex_env_profile_writes_exact_named_profile_values(tmp_path, monkeypatch):
65
+ import chatup.setup.codex as codex_setup
66
+
67
+ home = tmp_path / "home"
68
+ envs_dir = tmp_path / "chatarch" / "envs"
69
+ openai_dir = envs_dir / "OpenAI"
70
+ monkeypatch.setenv("HOME", str(home))
71
+ monkeypatch.setenv("OPENAI_API_KEY", "process-key-should-not-be-used")
72
+ monkeypatch.setattr(codex_setup, "CHATARCH_ENV_DIR", envs_dir)
73
+ monkeypatch.setattr(codex_setup, "CHATARCH_ENV_FILE", envs_dir / ".env")
74
+ monkeypatch.setattr(codex_setup, "ensure_nodejs_requirement", lambda **kwargs: None)
75
+ monkeypatch.setattr(
76
+ codex_setup,
77
+ "should_install_global_npm_package",
78
+ lambda *args, **kwargs: False,
79
+ )
80
+
81
+ _write_env(
82
+ openai_dir / ".env",
83
+ {
84
+ "OPENAI_API_KEY": "active-key-should-not-be-used",
85
+ "OPENAI_API_BASE": "https://active.example/v1",
86
+ "OPENAI_API_MODEL": "active-model",
87
+ },
88
+ )
89
+ _write_env(
90
+ openai_dir / "apple.env",
91
+ {
92
+ "OPENAI_API_KEY": "apple-key",
93
+ "OPENAI_API_BASE": "https://crs.example/openai/v1",
94
+ "OPENAI_API_MODEL": "gpt-5.5",
95
+ },
96
+ )
97
+
98
+ codex_setup.setup_codex(env_ref="apple", interactive=False)
99
+
100
+ auth_path = home / ".codex" / "auth.json"
101
+ auth_data = json.loads(auth_path.read_text(encoding="utf-8"))
102
+ assert auth_data == {"OPENAI_API_KEY": "apple-key"}
103
+ assert auth_path.stat().st_mode & 0o777 == 0o600
104
+
105
+ config_text = (home / ".codex" / "config.toml").read_text(encoding="utf-8")
106
+ assert 'model = "gpt-5.5"' in config_text
107
+ assert 'base_url = "https://crs.example/openai/v1"' in config_text
108
+ assert "active-key-should-not-be-used" not in config_text
109
+ assert "process-key-should-not-be-used" not in config_text
110
+
111
+
112
+ def test_codex_env_dotenv_ref_loads_active_openai_profile(tmp_path, monkeypatch):
113
+ import chatup.setup.codex as codex_setup
114
+
115
+ home = tmp_path / "home"
116
+ envs_dir = tmp_path / "chatarch" / "envs"
117
+ openai_dir = envs_dir / "OpenAI"
118
+ monkeypatch.setenv("HOME", str(home))
119
+ monkeypatch.setenv("OPENAI_API_KEY", "process-key-should-not-be-used")
120
+ monkeypatch.setattr(codex_setup, "CHATARCH_ENV_DIR", envs_dir)
121
+ monkeypatch.setattr(codex_setup, "CHATARCH_ENV_FILE", envs_dir / ".env")
122
+ monkeypatch.setattr(codex_setup, "ensure_nodejs_requirement", lambda **kwargs: None)
123
+ monkeypatch.setattr(
124
+ codex_setup,
125
+ "should_install_global_npm_package",
126
+ lambda *args, **kwargs: False,
127
+ )
128
+ _write_env(
129
+ openai_dir / ".env",
130
+ {
131
+ "OPENAI_API_KEY": "active-key",
132
+ "OPENAI_API_BASE": "https://active.example/v1",
133
+ "OPENAI_API_MODEL": "gpt-5.5",
134
+ },
135
+ )
136
+
137
+ codex_setup.setup_codex(env_ref=".env", interactive=False)
138
+
139
+ auth_data = json.loads((home / ".codex" / "auth.json").read_text(encoding="utf-8"))
140
+ assert auth_data == {"OPENAI_API_KEY": "active-key"}
141
+ config_text = (home / ".codex" / "config.toml").read_text(encoding="utf-8")
142
+ assert 'model = "gpt-5.5"' in config_text
143
+ assert 'base_url = "https://active.example/v1"' in config_text
144
+ assert "process-key-should-not-be-used" not in config_text
145
+
146
+
147
+ def test_codex_default_model_matches_shared_openai_default():
148
+ from chatenv.configs import OpenAIConfig
149
+ import chatup.setup.codex as codex_setup
150
+
151
+ assert codex_setup.DEFAULT_MODEL == OpenAIConfig.OPENAI_API_MODEL.default
@@ -23,7 +23,7 @@ def test_chatup_depends_on_chatenv_and_registers_cursor_agent_config_provider():
23
23
  assert data["project"]["requires-python"] == ">=3.10"
24
24
  assert "click>=8.0,<9.0" in data["project"]["dependencies"]
25
25
  assert "chatstyle>=0.2.0,<0.3.0" in data["project"]["dependencies"]
26
- assert "chatenv>=0.2.10,<0.3.0" in data["project"]["dependencies"]
26
+ assert "chatenv>=0.2.11,<0.3.0" in data["project"]["dependencies"]
27
27
  entry_points = data["project"]["entry-points"]["chatenv.configs"]
28
28
  assert entry_points["cursor-agent"] == "chatup.config:CursorAgentConfig"
29
29
  assert entry_points["discourse"] == "chatup.config:DiscourseAdminConfig"
@@ -5,7 +5,7 @@ from chatup.cli import main
5
5
 
6
6
 
7
7
  def test_version_present():
8
- assert __version__ == "0.2.12"
8
+ assert __version__ == "0.2.13"
9
9
 
10
10
 
11
11
  def test_cli_help():
@@ -61,4 +61,4 @@ def test_cli_doctor():
61
61
  result = CliRunner().invoke(main, ["doctor"])
62
62
 
63
63
  assert result.exit_code == 0
64
- assert "chatup 0.2.12 ok" in result.output
64
+ assert "chatup 0.2.13 ok" in result.output
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
File without changes
File without changes