python-codex 0.2.5__tar.gz → 0.2.6__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 (128) hide show
  1. {python_codex-0.2.5 → python_codex-0.2.6}/.github/workflows/publish.yml +32 -4
  2. {python_codex-0.2.5 → python_codex-0.2.6}/AGENTS.md +3 -1
  3. {python_codex-0.2.5 → python_codex-0.2.6}/PKG-INFO +19 -3
  4. {python_codex-0.2.5 → python_codex-0.2.6}/README.md +18 -2
  5. {python_codex-0.2.5 → python_codex-0.2.6}/README_ZH.md +17 -2
  6. python_codex-0.2.6/packages/pycodex-ws/README.md +13 -0
  7. python_codex-0.2.6/packages/pycodex-ws/pycodex_ws_meta/__init__.py +1 -0
  8. python_codex-0.2.6/packages/pycodex-ws/pyproject.toml +16 -0
  9. {python_codex-0.2.5 → python_codex-0.2.6}/pyproject.toml +1 -1
  10. python_codex-0.2.6/tests/test_packaging.py +27 -0
  11. {python_codex-0.2.5 → python_codex-0.2.6}/tests/test_workspace_server.py +29 -2
  12. {python_codex-0.2.5 → python_codex-0.2.6}/workspace_server/workspace.html +293 -99
  13. {python_codex-0.2.5 → python_codex-0.2.6}/.github/workflows/test.yml +0 -0
  14. {python_codex-0.2.5 → python_codex-0.2.6}/.gitignore +0 -0
  15. {python_codex-0.2.5 → python_codex-0.2.6}/LICENSE +0 -0
  16. {python_codex-0.2.5 → python_codex-0.2.6}/docs/ALIGNMENT.md +0 -0
  17. {python_codex-0.2.5 → python_codex-0.2.6}/docs/CONTEXT.md +0 -0
  18. {python_codex-0.2.5 → python_codex-0.2.6}/docs/responses_server/README.md +0 -0
  19. {python_codex-0.2.5 → python_codex-0.2.6}/pycodex/__init__.py +0 -0
  20. {python_codex-0.2.5 → python_codex-0.2.6}/pycodex/agent.py +0 -0
  21. {python_codex-0.2.5 → python_codex-0.2.6}/pycodex/cli.py +0 -0
  22. {python_codex-0.2.5 → python_codex-0.2.6}/pycodex/collaboration.py +0 -0
  23. {python_codex-0.2.5 → python_codex-0.2.6}/pycodex/compat.py +0 -0
  24. {python_codex-0.2.5 → python_codex-0.2.6}/pycodex/context.py +0 -0
  25. {python_codex-0.2.5 → python_codex-0.2.6}/pycodex/doctor.py +0 -0
  26. {python_codex-0.2.5 → python_codex-0.2.6}/pycodex/feishu_card.py +0 -0
  27. {python_codex-0.2.5 → python_codex-0.2.6}/pycodex/feishu_link.py +0 -0
  28. {python_codex-0.2.5 → python_codex-0.2.6}/pycodex/interactive_session.py +0 -0
  29. {python_codex-0.2.5 → python_codex-0.2.6}/pycodex/model.py +0 -0
  30. {python_codex-0.2.5 → python_codex-0.2.6}/pycodex/model_metadata.py +0 -0
  31. {python_codex-0.2.5 → python_codex-0.2.6}/pycodex/portable.py +0 -0
  32. {python_codex-0.2.5 → python_codex-0.2.6}/pycodex/portable_server.py +0 -0
  33. {python_codex-0.2.5 → python_codex-0.2.6}/pycodex/prompts/collaboration_default.md +0 -0
  34. {python_codex-0.2.5 → python_codex-0.2.6}/pycodex/prompts/collaboration_plan.md +0 -0
  35. {python_codex-0.2.5 → python_codex-0.2.6}/pycodex/prompts/default_base_instructions.md +0 -0
  36. {python_codex-0.2.5 → python_codex-0.2.6}/pycodex/prompts/models.json +0 -0
  37. {python_codex-0.2.5 → python_codex-0.2.6}/pycodex/prompts/permissions/approval_policy/never.md +0 -0
  38. {python_codex-0.2.5 → python_codex-0.2.6}/pycodex/prompts/permissions/approval_policy/on_failure.md +0 -0
  39. {python_codex-0.2.5 → python_codex-0.2.6}/pycodex/prompts/permissions/approval_policy/on_request.md +0 -0
  40. {python_codex-0.2.5 → python_codex-0.2.6}/pycodex/prompts/permissions/approval_policy/on_request_rule_request_permission.md +0 -0
  41. {python_codex-0.2.5 → python_codex-0.2.6}/pycodex/prompts/permissions/approval_policy/unless_trusted.md +0 -0
  42. {python_codex-0.2.5 → python_codex-0.2.6}/pycodex/prompts/permissions/sandbox_mode/danger_full_access.md +0 -0
  43. {python_codex-0.2.5 → python_codex-0.2.6}/pycodex/prompts/permissions/sandbox_mode/read_only.md +0 -0
  44. {python_codex-0.2.5 → python_codex-0.2.6}/pycodex/prompts/permissions/sandbox_mode/workspace_write.md +0 -0
  45. {python_codex-0.2.5 → python_codex-0.2.6}/pycodex/protocol.py +0 -0
  46. {python_codex-0.2.5 → python_codex-0.2.6}/pycodex/runtime.py +0 -0
  47. {python_codex-0.2.5 → python_codex-0.2.6}/pycodex/runtime_services.py +0 -0
  48. {python_codex-0.2.5 → python_codex-0.2.6}/pycodex/tools/__init__.py +0 -0
  49. {python_codex-0.2.5 → python_codex-0.2.6}/pycodex/tools/agent_tool_schemas.py +0 -0
  50. {python_codex-0.2.5 → python_codex-0.2.6}/pycodex/tools/apply_patch_tool.py +0 -0
  51. {python_codex-0.2.5 → python_codex-0.2.6}/pycodex/tools/base_tool.py +0 -0
  52. {python_codex-0.2.5 → python_codex-0.2.6}/pycodex/tools/close_agent_tool.py +0 -0
  53. {python_codex-0.2.5 → python_codex-0.2.6}/pycodex/tools/code_mode_manager.py +0 -0
  54. {python_codex-0.2.5 → python_codex-0.2.6}/pycodex/tools/exec_command_tool.py +0 -0
  55. {python_codex-0.2.5 → python_codex-0.2.6}/pycodex/tools/exec_runtime.js +0 -0
  56. {python_codex-0.2.5 → python_codex-0.2.6}/pycodex/tools/exec_tool.py +0 -0
  57. {python_codex-0.2.5 → python_codex-0.2.6}/pycodex/tools/grep_files_tool.py +0 -0
  58. {python_codex-0.2.5 → python_codex-0.2.6}/pycodex/tools/ipython_tool.py +0 -0
  59. {python_codex-0.2.5 → python_codex-0.2.6}/pycodex/tools/list_dir_tool.py +0 -0
  60. {python_codex-0.2.5 → python_codex-0.2.6}/pycodex/tools/read_file_tool.py +0 -0
  61. {python_codex-0.2.5 → python_codex-0.2.6}/pycodex/tools/request_permissions_tool.py +0 -0
  62. {python_codex-0.2.5 → python_codex-0.2.6}/pycodex/tools/request_user_input_tool.py +0 -0
  63. {python_codex-0.2.5 → python_codex-0.2.6}/pycodex/tools/resume_agent_tool.py +0 -0
  64. {python_codex-0.2.5 → python_codex-0.2.6}/pycodex/tools/send_input_tool.py +0 -0
  65. {python_codex-0.2.5 → python_codex-0.2.6}/pycodex/tools/shell_command_tool.py +0 -0
  66. {python_codex-0.2.5 → python_codex-0.2.6}/pycodex/tools/shell_tool.py +0 -0
  67. {python_codex-0.2.5 → python_codex-0.2.6}/pycodex/tools/spawn_agent_tool.py +0 -0
  68. {python_codex-0.2.5 → python_codex-0.2.6}/pycodex/tools/unified_exec_manager.py +0 -0
  69. {python_codex-0.2.5 → python_codex-0.2.6}/pycodex/tools/update_plan_tool.py +0 -0
  70. {python_codex-0.2.5 → python_codex-0.2.6}/pycodex/tools/view_image_tool.py +0 -0
  71. {python_codex-0.2.5 → python_codex-0.2.6}/pycodex/tools/wait_agent_tool.py +0 -0
  72. {python_codex-0.2.5 → python_codex-0.2.6}/pycodex/tools/wait_tool.py +0 -0
  73. {python_codex-0.2.5 → python_codex-0.2.6}/pycodex/tools/web_search_tool.py +0 -0
  74. {python_codex-0.2.5 → python_codex-0.2.6}/pycodex/tools/write_stdin_tool.py +0 -0
  75. {python_codex-0.2.5 → python_codex-0.2.6}/pycodex/utils/__init__.py +0 -0
  76. {python_codex-0.2.5 → python_codex-0.2.6}/pycodex/utils/async_bridge.py +0 -0
  77. {python_codex-0.2.5 → python_codex-0.2.6}/pycodex/utils/compactor.py +0 -0
  78. {python_codex-0.2.5 → python_codex-0.2.6}/pycodex/utils/debug.py +0 -0
  79. {python_codex-0.2.5 → python_codex-0.2.6}/pycodex/utils/dotenv.py +0 -0
  80. {python_codex-0.2.5 → python_codex-0.2.6}/pycodex/utils/get_env.py +0 -0
  81. {python_codex-0.2.5 → python_codex-0.2.6}/pycodex/utils/random_ids.py +0 -0
  82. {python_codex-0.2.5 → python_codex-0.2.6}/pycodex/utils/session_persist.py +0 -0
  83. {python_codex-0.2.5 → python_codex-0.2.6}/pycodex/utils/toolcall_visualize.py +0 -0
  84. {python_codex-0.2.5 → python_codex-0.2.6}/pycodex/utils/truncation.py +0 -0
  85. {python_codex-0.2.5 → python_codex-0.2.6}/pycodex/utils/visualize.py +0 -0
  86. {python_codex-0.2.5 → python_codex-0.2.6}/responses_server/__init__.py +0 -0
  87. {python_codex-0.2.5 → python_codex-0.2.6}/responses_server/__main__.py +0 -0
  88. {python_codex-0.2.5 → python_codex-0.2.6}/responses_server/app.py +0 -0
  89. {python_codex-0.2.5 → python_codex-0.2.6}/responses_server/config.py +0 -0
  90. {python_codex-0.2.5 → python_codex-0.2.6}/responses_server/messages_api.py +0 -0
  91. {python_codex-0.2.5 → python_codex-0.2.6}/responses_server/payload_processors.py +0 -0
  92. {python_codex-0.2.5 → python_codex-0.2.6}/responses_server/server.py +0 -0
  93. {python_codex-0.2.5 → python_codex-0.2.6}/responses_server/session_store.py +0 -0
  94. {python_codex-0.2.5 → python_codex-0.2.6}/responses_server/stream_router.py +0 -0
  95. {python_codex-0.2.5 → python_codex-0.2.6}/responses_server/tools/__init__.py +0 -0
  96. {python_codex-0.2.5 → python_codex-0.2.6}/responses_server/tools/custom_adapter.py +0 -0
  97. {python_codex-0.2.5 → python_codex-0.2.6}/responses_server/tools/web_search.py +0 -0
  98. {python_codex-0.2.5 → python_codex-0.2.6}/responses_server/trajectory_dump.py +0 -0
  99. {python_codex-0.2.5 → python_codex-0.2.6}/tests/TESTS.md +0 -0
  100. {python_codex-0.2.5 → python_codex-0.2.6}/tests/__init__.py +0 -0
  101. {python_codex-0.2.5 → python_codex-0.2.6}/tests/compare_request_user_input_roundtrip.py +0 -0
  102. {python_codex-0.2.5 → python_codex-0.2.6}/tests/compare_steer_request_bodies.py +0 -0
  103. {python_codex-0.2.5 → python_codex-0.2.6}/tests/compare_tool_schemas.py +0 -0
  104. {python_codex-0.2.5 → python_codex-0.2.6}/tests/fake_responses_server.py +0 -0
  105. {python_codex-0.2.5 → python_codex-0.2.6}/tests/fakes.py +0 -0
  106. {python_codex-0.2.5 → python_codex-0.2.6}/tests/responses_server/fake_chat_completions_server.py +0 -0
  107. {python_codex-0.2.5 → python_codex-0.2.6}/tests/responses_server/test_server.py +0 -0
  108. {python_codex-0.2.5 → python_codex-0.2.6}/tests/test_agent.py +0 -0
  109. {python_codex-0.2.5 → python_codex-0.2.6}/tests/test_async_bridge.py +0 -0
  110. {python_codex-0.2.5 → python_codex-0.2.6}/tests/test_builtin_tools.py +0 -0
  111. {python_codex-0.2.5 → python_codex-0.2.6}/tests/test_cli.py +0 -0
  112. {python_codex-0.2.5 → python_codex-0.2.6}/tests/test_compactor.py +0 -0
  113. {python_codex-0.2.5 → python_codex-0.2.6}/tests/test_context.py +0 -0
  114. {python_codex-0.2.5 → python_codex-0.2.6}/tests/test_doctor.py +0 -0
  115. {python_codex-0.2.5 → python_codex-0.2.6}/tests/test_fake_responses_server.py +0 -0
  116. {python_codex-0.2.5 → python_codex-0.2.6}/tests/test_feishu_card.py +0 -0
  117. {python_codex-0.2.5 → python_codex-0.2.6}/tests/test_feishu_link.py +0 -0
  118. {python_codex-0.2.5 → python_codex-0.2.6}/tests/test_ipython_tool.py +0 -0
  119. {python_codex-0.2.5 → python_codex-0.2.6}/tests/test_model.py +0 -0
  120. {python_codex-0.2.5 → python_codex-0.2.6}/tests/test_portable.py +0 -0
  121. {python_codex-0.2.5 → python_codex-0.2.6}/tests/test_py36_syntax.py +0 -0
  122. {python_codex-0.2.5 → python_codex-0.2.6}/tests/test_visualize.py +0 -0
  123. {python_codex-0.2.5 → python_codex-0.2.6}/tools/feishu_oauth.py +0 -0
  124. {python_codex-0.2.5 → python_codex-0.2.6}/workspace_server/__init__.py +0 -0
  125. {python_codex-0.2.5 → python_codex-0.2.6}/workspace_server/__main__.py +0 -0
  126. {python_codex-0.2.5 → python_codex-0.2.6}/workspace_server/app.py +0 -0
  127. {python_codex-0.2.5 → python_codex-0.2.6}/workspace_server/workspaces.html +0 -0
  128. {python_codex-0.2.5 → python_codex-0.2.6}/workspace_server/workspaces.py +0 -0
@@ -107,8 +107,10 @@ jobs:
107
107
 
108
108
  - name: Build distributions
109
109
  run: |
110
- python -m pip install --upgrade build
111
- python -m build
110
+ python -m pip install --upgrade build twine
111
+ python -m build --outdir dist/python-codex .
112
+ python -m build --outdir dist/pycodex-ws packages/pycodex-ws
113
+ python -m twine check dist/python-codex/* dist/pycodex-ws/*
112
114
 
113
115
  - name: Upload distributions
114
116
  uses: actions/upload-artifact@v4
@@ -124,7 +126,7 @@ jobs:
124
126
  id-token: write
125
127
  environment:
126
128
  name: testpypi
127
- url: https://test.pypi.org/project/pycodex/
129
+ url: https://test.pypi.org/project/python-codex/
128
130
  steps:
129
131
  - name: Download distributions
130
132
  uses: actions/download-artifact@v4
@@ -135,6 +137,7 @@ jobs:
135
137
  - name: Publish to TestPyPI
136
138
  uses: pypa/gh-action-pypi-publish@release/v1
137
139
  with:
140
+ packages-dir: dist/python-codex/
138
141
  repository-url: https://test.pypi.org/legacy/
139
142
 
140
143
  publish-pypi:
@@ -145,7 +148,7 @@ jobs:
145
148
  id-token: write
146
149
  environment:
147
150
  name: pypi
148
- url: https://pypi.org/project/pycodex/
151
+ url: https://pypi.org/project/python-codex/
149
152
  steps:
150
153
  - name: Download distributions
151
154
  uses: actions/download-artifact@v4
@@ -155,3 +158,28 @@ jobs:
155
158
 
156
159
  - name: Publish to PyPI
157
160
  uses: pypa/gh-action-pypi-publish@release/v1
161
+ with:
162
+ packages-dir: dist/python-codex/
163
+
164
+ publish-pycodex-ws:
165
+ if: github.event_name == 'release' || github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && inputs.repository == 'pypi')
166
+ needs:
167
+ - build
168
+ - publish-pypi
169
+ runs-on: ubuntu-latest
170
+ permissions:
171
+ id-token: write
172
+ environment:
173
+ name: pypi
174
+ url: https://pypi.org/project/pycodex-ws/
175
+ steps:
176
+ - name: Download distributions
177
+ uses: actions/download-artifact@v4
178
+ with:
179
+ name: python-package-distributions
180
+ path: dist/
181
+
182
+ - name: Publish pycodex-ws to PyPI
183
+ uses: pypa/gh-action-pypi-publish@release/v1
184
+ with:
185
+ packages-dir: dist/pycodex-ws/
@@ -3,7 +3,9 @@
3
3
  ## Repo Priors
4
4
 
5
5
  - 这个仓库的目标是尽可能准确地复现上游 Codex(`https://github.com/openai/codex`),不是发明一个“类似 Codex”的简化替代品;凡是行为差异都应优先朝原版 Codex 收敛。
6
- - 发布到 PyPI 时,distribution name 用 `python-codex`;代码包目录、`import` 路径和 CLI 命令仍保持 `pycodex`。
6
+ - PyPI 主 distribution name 用 `python-codex`;代码包目录、`import` 路径和 CLI 命令仍保持 `pycodex`。
7
+ - `pycodex-ws` 是与 `python-codex` 锁步同版本的薄 metapackage,只依赖精确同版本的 `python-codex`;不要在两个 wheel 中重复打包 `pycodex/`、`workspace_server/` 或重复声明 `pycodex-ws` console script。
8
+ - 双包发布时先发布 `python-codex`,成功后再发布 `pycodex-ws`,避免新 metapackage 短暂指向尚不存在的核心版本。
7
9
  - 包结构直接放在 repo 根目录下的 `pycodex/`,不使用 `src/` layout。
8
10
  - Rust 到 Python 的主映射:`submission_loop` -> `pycodex/runtime.py`,`run_turn` / `run_sampling_request` -> `pycodex/agent.py`,`ToolRouter` -> `pycodex/tools/base_tool.py` + `pycodex/tools/`.
9
11
  - 会话协议先收敛到 4 类 item:`UserMessage`、`AssistantMessage`、`ToolCall`、`ToolResult`;只有这层稳定后再扩 richer event model。
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: python-codex
3
- Version: 0.2.5
3
+ Version: 0.2.6
4
4
  Summary: A minimal Python extraction of Codex's main agent loop
5
5
  License-File: LICENSE
6
6
  Requires-Python: >=3.6.2
@@ -23,8 +23,17 @@ Description-Content-Type: text/markdown
23
23
 
24
24
  English README. Chinese version: `README_ZH.md`
25
25
 
26
- PyPI distribution name: `python-codex`
27
- Import path and CLI command remain `pycodex`.
26
+ PyPI distributions:
27
+
28
+ - Primary package: `python-codex`
29
+ - Workspace install alias: `pycodex-ws`
30
+
31
+ The import path remains `pycodex`; the CLI commands are `pycodex` and
32
+ `pycodex-ws`.
33
+
34
+ `pycodex-ws` is a thin metapackage that depends on the exact matching
35
+ `python-codex` version. The implementation and console script remain owned by
36
+ `python-codex`, so the two distributions never install duplicate modules.
28
37
 
29
38
  This repository extracts the core Codex agent loop from upstream Codex
30
39
  (`https://github.com/openai/codex`) into a deliberately small Python version,
@@ -44,6 +53,13 @@ Relevant Rust reference points:
44
53
 
45
54
  ## Quick Start
46
55
 
56
+ Install the full package or the workspace-oriented alias:
57
+
58
+ ```bash
59
+ pip install python-codex
60
+ pip install pycodex-ws
61
+ ```
62
+
47
63
  Install dependencies first:
48
64
 
49
65
  ```bash
@@ -2,8 +2,17 @@
2
2
 
3
3
  English README. Chinese version: `README_ZH.md`
4
4
 
5
- PyPI distribution name: `python-codex`
6
- Import path and CLI command remain `pycodex`.
5
+ PyPI distributions:
6
+
7
+ - Primary package: `python-codex`
8
+ - Workspace install alias: `pycodex-ws`
9
+
10
+ The import path remains `pycodex`; the CLI commands are `pycodex` and
11
+ `pycodex-ws`.
12
+
13
+ `pycodex-ws` is a thin metapackage that depends on the exact matching
14
+ `python-codex` version. The implementation and console script remain owned by
15
+ `python-codex`, so the two distributions never install duplicate modules.
7
16
 
8
17
  This repository extracts the core Codex agent loop from upstream Codex
9
18
  (`https://github.com/openai/codex`) into a deliberately small Python version,
@@ -23,6 +32,13 @@ Relevant Rust reference points:
23
32
 
24
33
  ## Quick Start
25
34
 
35
+ Install the full package or the workspace-oriented alias:
36
+
37
+ ```bash
38
+ pip install python-codex
39
+ pip install pycodex-ws
40
+ ```
41
+
26
42
  Install dependencies first:
27
43
 
28
44
  ```bash
@@ -2,8 +2,16 @@
2
2
 
3
3
  中文 README。English version: `README.md`
4
4
 
5
- PyPI distribution name: `python-codex`
6
- Import path and CLI command remain `pycodex`.
5
+ PyPI distributions:
6
+
7
+ - 主包:`python-codex`
8
+ - Workspace 安装别名:`pycodex-ws`
9
+
10
+ Import 路径仍保持 `pycodex`;CLI 命令为 `pycodex` 和 `pycodex-ws`。
11
+
12
+ `pycodex-ws` 是一个薄 metapackage,精确依赖同版本的 `python-codex`。
13
+ 实际代码和 console script 继续由 `python-codex` 提供,两个 distribution
14
+ 不会重复安装同名模块。
7
15
 
8
16
  这个仓库把上游 Codex(`https://github.com/openai/codex`)里最核心的 agent
9
17
  闭环先抽成一个尽量小的 Python 版本,重点保留两层结构:
@@ -21,6 +29,13 @@ Import path and CLI command remain `pycodex`.
21
29
 
22
30
  ## 快速开始
23
31
 
32
+ 安装完整包或 workspace 安装别名:
33
+
34
+ ```bash
35
+ pip install python-codex
36
+ pip install pycodex-ws
37
+ ```
38
+
24
39
  先安装开发依赖:
25
40
 
26
41
  ```bash
@@ -0,0 +1,13 @@
1
+ # pycodex-ws
2
+
3
+ `pycodex-ws` is the workspace-oriented installation name for
4
+ [`python-codex`](https://pypi.org/project/python-codex/).
5
+
6
+ ```bash
7
+ pip install pycodex-ws
8
+ pycodex-ws --help
9
+ ```
10
+
11
+ This distribution intentionally contains only package metadata. It depends on
12
+ the exact matching `python-codex` version, which provides the `workspace_server`
13
+ implementation and the `pycodex-ws` console script.
@@ -0,0 +1 @@
1
+ """Metadata-only package for the pycodex-ws distribution."""
@@ -0,0 +1,16 @@
1
+ [build-system]
2
+ requires = ["hatchling>=1.17.1,<1.18"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "pycodex-ws"
7
+ version = "0.2.6"
8
+ description = "Browser workspace install alias for python-codex"
9
+ readme = "README.md"
10
+ requires-python = ">=3.6.2"
11
+ dependencies = [
12
+ "python-codex==0.2.6",
13
+ ]
14
+
15
+ [tool.hatch.build.targets.wheel]
16
+ packages = ["pycodex_ws_meta"]
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "python-codex"
7
- version = "0.2.5"
7
+ version = "0.2.6"
8
8
  description = "A minimal Python extraction of Codex's main agent loop"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.6.2"
@@ -0,0 +1,27 @@
1
+ from pathlib import Path
2
+
3
+ try:
4
+ import tomllib
5
+ except ImportError: # pragma: no cover - exercised on Python < 3.11
6
+ import tomli as tomllib
7
+
8
+
9
+ ROOT = Path(__file__).resolve().parents[1]
10
+
11
+
12
+ def _load_toml(path):
13
+ with path.open("rb") as handle:
14
+ return tomllib.load(handle)
15
+
16
+
17
+ def test_workspace_distribution_tracks_core_version() -> 'None':
18
+ core = _load_toml(ROOT / "pyproject.toml")
19
+ workspace = _load_toml(ROOT / "packages" / "pycodex-ws" / "pyproject.toml")
20
+ version = core["project"]["version"]
21
+
22
+ assert workspace["project"]["version"] == version
23
+ assert workspace["project"]["dependencies"] == [
24
+ "python-codex=={0}".format(version),
25
+ ]
26
+ assert "scripts" not in workspace["project"]
27
+ assert core["project"]["scripts"]["pycodex-ws"] == "workspace_server:main"
@@ -794,6 +794,24 @@ def test_workspace_app_shell_uses_spinner_without_send_button(tmp_path) -> None:
794
794
  assert "mobile-switch" not in response.text
795
795
 
796
796
 
797
+ def test_workspace_app_shell_uses_carbon_signal_dark_theme(tmp_path) -> None:
798
+ board = tmp_path / "board.html"
799
+ board.write_text("<!doctype html><title>Board</title>", encoding="utf-8")
800
+ app = create_app(lambda: _DormantLink(), board)
801
+
802
+ with TestClient(app) as client:
803
+ response = client.get("/")
804
+
805
+ assert response.status_code == 200
806
+ assert "color-scheme: light;" in response.text
807
+ assert "--bg: #eef3f6;" in response.text
808
+ assert "--panel: #f8fbfd;" in response.text
809
+ assert "--accent: #087f9a;" in response.text
810
+ assert "--warn-soft: #fff7df;" in response.text
811
+ assert "--danger-soft: #fff0f2;" in response.text
812
+ assert "--violet-soft: #f4f0ff;" in response.text
813
+
814
+
797
815
  def test_workspace_app_shell_renders_latex_with_katex(tmp_path) -> None:
798
816
  board = tmp_path / "board.html"
799
817
  board.write_text("<!doctype html><title>Board</title>", encoding="utf-8")
@@ -806,13 +824,22 @@ def test_workspace_app_shell_renders_latex_with_katex(tmp_path) -> None:
806
824
  assert "katex@0.16.22/dist/katex.min.css" in response.text
807
825
  assert "katex@0.16.22/dist/katex.min.js" in response.text
808
826
  assert "katex@0.16.22/dist/contrib/auto-render.min.js" in response.text
809
- assert "window.renderMathInElement(root" in response.text
827
+ assert "window.renderMathInElement(mathNode" in response.text
810
828
  assert '{left: "$$", right: "$$", display: true}' in response.text
811
829
  assert '{left: "\\\\[", right: "\\\\]", display: true}' in response.text
812
830
  assert '{left: "\\\\(", right: "\\\\)", display: false}' in response.text
813
831
  assert '{left: "$", right: "$", display: false}' in response.text
814
- assert "mathDelimiterPlaceholders" in response.text
832
+ assert "const mathDelimiters" in response.text
833
+ assert "const mathTokenPrefix" in response.text
834
+ assert "function protectMath(source)" in response.text
835
+ assert "function renderProtectedMath(root, expressions)" in response.text
836
+ assert "const textNodes = []" in response.text
837
+ assert "function restoreUnrenderedMathTokens(root, expressionByToken)" in response.text
838
+ assert "countBackticks(source, index)" in response.text
815
839
  assert "document.createTreeWalker(root, NodeFilter.SHOW_TEXT)" in response.text
840
+ assert ".markdown .katex .text" in response.text
841
+ assert "overflow-wrap: normal" in response.text
842
+ assert "word-break: normal" in response.text
816
843
  assert "throwOnError: false" in response.text
817
844
  assert "trust: false" in response.text
818
845
  assert ".markdown .katex-display" in response.text