codex-watch 0.1.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.
Files changed (33) hide show
  1. codex_watch-0.1.1/.github/workflows/ci.yml +29 -0
  2. codex_watch-0.1.1/.github/workflows/release.yml +85 -0
  3. codex_watch-0.1.1/.gitignore +12 -0
  4. codex_watch-0.1.1/PACKAGING.md +180 -0
  5. codex_watch-0.1.1/PKG-INFO +190 -0
  6. codex_watch-0.1.1/README.md +229 -0
  7. codex_watch-0.1.1/capture_analysis.py +2 -0
  8. codex_watch-0.1.1/capture_core.py +2 -0
  9. codex_watch-0.1.1/chat_monitor.py +2 -0
  10. codex_watch-0.1.1/codex_capture.py +4 -0
  11. codex_watch-0.1.1/codex_dump.py +16 -0
  12. codex_watch-0.1.1/codex_watch/__init__.py +3 -0
  13. codex_watch-0.1.1/codex_watch/__main__.py +3 -0
  14. codex_watch-0.1.1/codex_watch/addon.py +176 -0
  15. codex_watch-0.1.1/codex_watch/analysis.py +517 -0
  16. codex_watch-0.1.1/codex_watch/cli.py +235 -0
  17. codex_watch-0.1.1/codex_watch/core.py +226 -0
  18. codex_watch-0.1.1/codex_watch/lifecycle.py +33 -0
  19. codex_watch-0.1.1/codex_watch/monitor.py +496 -0
  20. codex_watch-0.1.1/codex_watch/platform_support.py +81 -0
  21. codex_watch-0.1.1/codex_watch/removal.py +139 -0
  22. codex_watch-0.1.1/pyproject.toml +32 -0
  23. codex_watch-0.1.1/requirements.txt +1 -0
  24. codex_watch-0.1.1/scripts/verify_package.py +38 -0
  25. codex_watch-0.1.1/scripts/verify_uninstall.py +61 -0
  26. codex_watch-0.1.1/test_capture_analysis.py +208 -0
  27. codex_watch-0.1.1/test_capture_core.py +98 -0
  28. codex_watch-0.1.1/test_chat_monitor.py +191 -0
  29. codex_watch-0.1.1/test_packaging.py +88 -0
  30. codex_watch-0.1.1/test_proxy_integration.py +427 -0
  31. codex_watch-0.1.1/test_removal.py +168 -0
  32. codex_watch-0.1.1/test_support.py +11 -0
  33. codex_watch-0.1.1/test_workflows.py +31 -0
@@ -0,0 +1,29 @@
1
+ name: Test
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+
8
+ permissions:
9
+ contents: read
10
+
11
+ jobs:
12
+ test:
13
+ runs-on: ubuntu-latest
14
+ steps:
15
+ - name: Check out source
16
+ uses: actions/checkout@v4
17
+ - name: Set up Python
18
+ uses: actions/setup-python@v5
19
+ with:
20
+ python-version: '3.12'
21
+ cache: pip
22
+ - name: Install package and test dependencies
23
+ run: python -m pip install --upgrade pip build && python -m pip install .
24
+ - name: Build distributions
25
+ run: python -m build --outdir dist
26
+ - name: Run unit and packaging tests
27
+ run: python -m unittest -v test_capture_core test_capture_analysis test_chat_monitor test_packaging test_removal
28
+ - name: Run local proxy integration tests
29
+ run: python -m unittest -v test_proxy_integration
@@ -0,0 +1,85 @@
1
+ name: Release
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - 'v*'
7
+
8
+ permissions:
9
+ contents: read
10
+
11
+ jobs:
12
+ test-and-build:
13
+ name: Test and build distributions
14
+ runs-on: ubuntu-latest
15
+ steps:
16
+ - name: Check out source
17
+ uses: actions/checkout@v4
18
+ - name: Set up Python
19
+ uses: actions/setup-python@v5
20
+ with:
21
+ python-version: '3.12'
22
+ cache: pip
23
+ - name: Install package and build tools
24
+ run: python -m pip install --upgrade pip build && python -m pip install .
25
+ - name: Verify tag matches package version
26
+ shell: bash
27
+ run: |
28
+ tag_version="${GITHUB_REF_NAME#v}"
29
+ package_version="$(python -c 'from codex_watch import __version__; print(__version__)')"
30
+ test "$tag_version" = "$package_version" || {
31
+ echo "Tag v$tag_version does not match package version $package_version" >&2
32
+ exit 1
33
+ }
34
+ - name: Build wheel and source distribution
35
+ run: python -m build --outdir dist
36
+ - name: Run tests
37
+ run: python -m unittest -v test_capture_core test_capture_analysis test_chat_monitor test_packaging test_removal test_proxy_integration
38
+ - name: Store release distributions
39
+ uses: actions/upload-artifact@v4
40
+ with:
41
+ name: python-distributions
42
+ path: dist/
43
+ if-no-files-found: error
44
+
45
+ github-release:
46
+ name: Create GitHub Release
47
+ needs: test-and-build
48
+ runs-on: ubuntu-latest
49
+ permissions:
50
+ contents: write
51
+ steps:
52
+ - name: Download release distributions
53
+ uses: actions/download-artifact@v4
54
+ with:
55
+ name: python-distributions
56
+ path: dist/
57
+ - name: Create or update GitHub Release
58
+ env:
59
+ GH_TOKEN: ${{ github.token }}
60
+ GH_REPO: ${{ github.repository }}
61
+ TAG: ${{ github.ref_name }}
62
+ run: |
63
+ if gh release view "$TAG" >/dev/null 2>&1; then
64
+ gh release upload "$TAG" dist/* --clobber
65
+ else
66
+ gh release create "$TAG" dist/* --verify-tag --generate-notes --title "$TAG"
67
+ fi
68
+
69
+ publish-pypi:
70
+ name: Publish to PyPI
71
+ needs: github-release
72
+ runs-on: ubuntu-latest
73
+ environment:
74
+ name: pypi
75
+ url: https://pypi.org/p/codex-watch
76
+ permissions:
77
+ id-token: write
78
+ steps:
79
+ - name: Download release distributions
80
+ uses: actions/download-artifact@v4
81
+ with:
82
+ name: python-distributions
83
+ path: dist/
84
+ - name: Publish distributions to PyPI
85
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,12 @@
1
+ .venv/
2
+ __pycache__/
3
+ *.py[cod]
4
+ captures/
5
+ .mitmproxy/
6
+ .pytest_cache/
7
+ .DS_Store
8
+ dist/
9
+ build/
10
+ *.egg-info/
11
+ .build-cache/
12
+ .package-test/
@@ -0,0 +1,180 @@
1
+ # codex-watch 0.1.1
2
+
3
+ 在本机监听经代理发出的 Codex 聊天请求,比较请求模型与返回模型,并按输入或回复内容查找对应抓包。支持 HTTP、SSE 和 WebSocket。
4
+
5
+ 本版本以源码和 Python 安装包交付:`codex_watch-0.1.1-py3-none-any.whl`。源码仓库为 [invokerw/codex_watch](https://github.com/invokerw/codex_watch)。尚未制作自带 Python 的独立可执行程序,也未发布到 PyPI。
6
+
7
+ 仓库已经包含 `ci.yml` 和 `release.yml`:推送与 Pull Request 会运行测试;推送匹配 `v*` 的标签时,先验证、构建并创建 GitHub Release,再通过 PyPI Trusted Publishing 上传 wheel 和源码归档。
8
+
9
+ ## 安装
10
+
11
+ 从 GitHub 获取源码:
12
+
13
+ ```bash
14
+ git clone https://github.com/invokerw/codex_watch.git
15
+ cd codex_watch
16
+ uv tool install --python 3.12 .
17
+ ```
18
+
19
+ 收到源码压缩包时,解压后在包含 `pyproject.toml` 的目录执行:
20
+
21
+ ```bash
22
+ uv tool install --python 3.12 .
23
+ codex-watch doctor
24
+ codex-watch watch
25
+ ```
26
+
27
+ 然后在另一个终端的工作项目目录运行 `codex-watch run`。源码包不含依赖、聊天记录或证书;首次安装会获取依赖,首次启动代理会生成本机证书。
28
+
29
+ 安装本地 wheel(路径替换为实际下载位置):
30
+
31
+ ```bash
32
+ uv tool install --python 3.12 /path/to/codex_watch-0.1.1-py3-none-any.whl
33
+ codex-watch --version
34
+ codex-watch doctor
35
+ ```
36
+
37
+ 若安装后找不到命令,执行 `uv tool update-shell` 并重新打开终端。升级本地包可以使用相同命令并加 `--force`。彻底卸载使用 `codex-watch uninstall`,会同时清理当前数据目录;详见下面的卸载说明。
38
+
39
+ 本版本明确使用 Python 3.12 和已验证的 mitmproxy 11.1.3,安装器会获取其余依赖。wheel 本身不包含 Python 或依赖,首次安装通常需要联网。没有 uv 时,也可在 Python 3.12 虚拟环境中执行 `python -m pip install /path/to/codex_watch-0.1.1-py3-none-any.whl`。
40
+
41
+ ## 使用
42
+
43
+ 终端 A:
44
+
45
+ ```bash
46
+ codex-watch watch
47
+ ```
48
+
49
+ 终端 B 切换到工作项目目录,然后执行:
50
+
51
+ ```bash
52
+ codex-watch run
53
+ ```
54
+
55
+ `watch` 自动启动代理、捕获正文和更新聊天索引;`run` 给新启动的 Codex CLI 配置代理和 CA。需要自行安装并登录 Codex。已有代理时用 `codex-watch watch --attach`。已有 Codex 进程不会自动改走代理。
56
+
57
+ ```bash
58
+ codex-watch search "聊天内容"
59
+ codex-watch search
60
+ codex-watch show 聊天编号
61
+ codex-watch show 聊天编号 --raw
62
+ codex-watch watch --once --file /path/to/codex.jsonl
63
+ codex-watch analyze /path/to/captures
64
+ ```
65
+
66
+ 同一线程、同一轮聊天的请求归到同一个编号;返回事件出现不同模型时即时提示。模型名称差异不等于验证了后台实际使用的模型权重。
67
+
68
+ ## 数据与配置
69
+
70
+ 安装版的数据目录固定在当前用户下,与启动命令的工作目录无关:
71
+
72
+ | 系统 | 默认目录 |
73
+ | --- | --- |
74
+ | macOS | `~/Library/Application Support/codex-watch` |
75
+ | Windows | `%LOCALAPPDATA%\codex-watch` |
76
+ | Linux | `$XDG_DATA_HOME/codex-watch`,缺省为 `~/.local/share/codex-watch` |
77
+
78
+ 目录中包含 `captures/codex.jsonl`、`captures/monitor/index.sqlite3`、报告和 `.mitmproxy` 证书目录。每台机器在首次启动代理时生成自己的 CA。抓包和索引包含已捕获的聊天内容;发布文件不包含用户抓包、数据库或证书。
79
+
80
+ 可以设置环境变量 `CODEX_WATCH_HOME`,或在子命令前指定 `--data-dir`:
81
+
82
+ ```bash
83
+ codex-watch --data-dir /path/to/my-data watch
84
+ codex-watch --data-dir /path/to/my-data run
85
+ codex-watch --data-dir /path/to/my-data search "关键词"
86
+ ```
87
+
88
+ `watch` 和 `run` 必须使用相同的数据目录与端口。自定义端口示例:`codex-watch watch --port 8899` 与 `codex-watch run --port 8899`。需要上游 HTTP 代理时使用 `codex-watch watch --upstream http://127.0.0.1:7890`。
89
+
90
+ 原有源码命令 `python3 codex_dump.py ...` 继续默认使用源码目录内的数据,不会移动或覆盖历史数据。安装版可通过 `--data-dir` 指向原项目目录,直接使用原索引。不要同时运行两个监视器更新同一索引。
91
+
92
+ ## 卸载与清理
93
+
94
+ 从 0.1.1 起,使用工具自己的卸载命令会默认同时清理数据:
95
+
96
+ ```bash
97
+ codex-watch uninstall --dry-run # 预览路径,不执行删除
98
+ codex-watch uninstall # 显示路径,输入 DELETE 后执行
99
+ codex-watch uninstall --yes # 已确认,跳过交互确认
100
+ ```
101
+
102
+ 会删除当前数据目录下的 `captures/`(含抓包、聊天索引、报告、代理日志)和 `.mitmproxy/`(证书),然后通过 uv 卸载当前工具环境。空数据目录会一并移除;同目录下的其他文件保留。清理抓包是不可恢复的文件删除,不保证存储介质上的安全擦除。
103
+
104
+ 先退出正在运行的 watch / serve。新版进程和聊天索引锁会阻止清理;旧版独立 serve 或直接加载 addon 的代理需要自行停止。符号链接或联接点会中止清理,避免删除链接目标。
105
+
106
+ 自定义数据目录时,卸载也要指定同一个目录:
107
+
108
+ ```bash
109
+ codex-watch --data-dir /path/to/my-data uninstall
110
+ ```
111
+
112
+ 只清理选定目录;单独通过 `--file`、`--index`、`--confdir` 保存到其他位置的文件不会被搜索删除,原源码目录的 captures 也不会自动被安装版清理。
113
+
114
+ 其他选择:
115
+
116
+ ```bash
117
+ codex-watch uninstall --keep-data # 卸载程序,保留数据
118
+ codex-watch purge # 清理数据,保留程序;适用于源码和 pip 安装
119
+ uv tool uninstall codex-watch # uv 自身的卸载命令仍只移除程序
120
+ ```
121
+
122
+ 自动卸载会验证当前程序确实来自该 uv 工具环境,避免误卸载另一个安装。对于源码或普通虚拟环境安装,先 `purge`,再用原安装方式卸载程序。若数据清理成功但 uv 卸载失败,会明确报告部分完成的状态。
123
+
124
+ ## 发布到 GitHub Release 和 PyPI
125
+
126
+ 发布前先把 `codex_watch/__init__.py` 中的 `__version__` 改成新版本,例如 `0.1.2`,提交到 `main`。然后在 PyPI 的账号发布设置中登记一次 Trusted Publisher:
127
+
128
+ | 字段 | 值 |
129
+ | --- | --- |
130
+ | PyPI 项目名 | `codex-watch` |
131
+ | Owner | `invokerw` |
132
+ | Repository | `codex_watch` |
133
+ | Workflow filename | `release.yml` |
134
+ | Environment | `pypi` |
135
+
136
+ GitHub 仓库 Settings → Environments 中创建同名 `pypi` environment;建议给它配置 required reviewer,发布 job 会在上传前等待审批。PyPI Trusted Publishing 使用短期 OIDC 凭据,不需要在 GitHub Secrets 保存长期 PyPI token。PyPI 还未创建项目时,可以在 PyPI 的 Publishing 页面添加 pending publisher;首次成功发布会创建项目。
137
+
138
+ 然后推送版本标签:
139
+
140
+ ```bash
141
+ git tag v0.1.2
142
+ git push origin v0.1.2
143
+ ```
144
+
145
+ Actions 会依次执行测试、构建、创建 GitHub Release、上传 PyPI。标签版本必须和 `__version__` 一致;重复运行同一个标签会更新 Release 附件,但 PyPI 对已存在的同版本文件仍会拒绝重复上传。
146
+
147
+ 如果希望先试运行,可以在 TestPyPI 注册相同的 Trusted Publisher,把 workflow 的发布地址改为 TestPyPI,或另外增加一个带 `repository-url: https://test.pypi.org/legacy/` 的发布 job。正式 workflow 默认只上传 PyPI,不会自动上传 TestPyPI。
148
+
149
+ 安全边界:只有匹配 `v*` 的标签触发发布;测试和构建 job 没有 `id-token` 权限,只有 `publish-pypi` job 有 `id-token: write`;发布 workflow 位于固定的 `.github/workflows/release.yml`。不要让不受信任的贡献者直接修改该 workflow。
150
+
151
+ ## 构建与验证
152
+
153
+ 从源码目录构建 wheel 和源码归档:
154
+
155
+ ```bash
156
+ uv build --python 3.12 --out-dir dist
157
+ python3 -m unittest -v test_capture_core test_capture_analysis test_chat_monitor test_packaging test_removal
158
+ .venv/bin/python -m unittest -v test_proxy_integration
159
+ ```
160
+
161
+ 验证安装包时,在独立环境安装后运行以下脚本。脚本把测试复制到临时目录,移除 `PYTHONPATH`,确认程序从新环境的 `site-packages` 加载,再执行全部测试:
162
+
163
+ ```bash
164
+ uv venv --python 3.12 .package-test/venv
165
+ uv pip install --python .package-test/venv/bin/python dist/codex_watch-0.1.1-py3-none-any.whl
166
+ python3 scripts/verify_package.py --python .package-test/venv/bin/python
167
+ python3 scripts/verify_uninstall.py --wheel dist/codex_watch-0.1.1-py3-none-any.whl --python .package-test/venv/bin/python --cache-dir .build-cache
168
+ ```
169
+
170
+ 卸载验收只使用临时的 uv 工具目录、命令目录和模拟数据,分别验证默认删除数据与 `--keep-data`,不会卸载用户已安装的工具。该脚本使用离线缓存,运行前需要安装依赖以填充指定缓存目录。
171
+
172
+ 以上虚拟环境路径示例用于 macOS / Linux;Windows 的解释器位于 `.package-test\venv\Scripts\python.exe`。
173
+
174
+ 构建使用明确的文件包含列表;wheel 只包含 `codex_watch` 程序包和分发元数据。源码归档额外包含文档、兼容启动器和测试。
175
+
176
+ 本地验收需在新的 Python 3.12 环境安装 wheel,并从项目外运行测试,验证资源加载、代理启动、模型告警、检索和进程退出。测试只连接临时本地服务,不调用真实 OpenAI API。验证结果见交付目录中的 `VALIDATION.md`。
177
+
178
+ 已为用户目录、文件锁和进程管理增加 macOS / Linux / Windows 分支。当前机器是 macOS Apple Silicon;Windows 和 Linux 仍需在对应系统做集成验证,不能据此声称所有平台已经通过。
179
+
180
+ 打包方式参考 [Python Packaging 官方指南](https://packaging.python.org/en/latest/tutorials/packaging-projects/),工具安装参考 [uv 文档](https://docs.astral.sh/uv/concepts/tools/)。
@@ -0,0 +1,190 @@
1
+ Metadata-Version: 2.5
2
+ Name: codex-watch
3
+ Version: 0.1.1
4
+ Summary: Local Codex model monitoring and searchable chat captures
5
+ Project-URL: Repository, https://github.com/invokerw/codex_watch
6
+ Project-URL: Issues, https://github.com/invokerw/codex_watch/issues
7
+ Requires-Python: <3.13,>=3.12
8
+ Requires-Dist: mitmproxy==11.1.3
9
+ Description-Content-Type: text/markdown
10
+
11
+ # codex-watch 0.1.1
12
+
13
+ 在本机监听经代理发出的 Codex 聊天请求,比较请求模型与返回模型,并按输入或回复内容查找对应抓包。支持 HTTP、SSE 和 WebSocket。
14
+
15
+ 本版本以源码和 Python 安装包交付:`codex_watch-0.1.1-py3-none-any.whl`。源码仓库为 [invokerw/codex_watch](https://github.com/invokerw/codex_watch)。尚未制作自带 Python 的独立可执行程序,也未发布到 PyPI。
16
+
17
+ 仓库已经包含 `ci.yml` 和 `release.yml`:推送与 Pull Request 会运行测试;推送匹配 `v*` 的标签时,先验证、构建并创建 GitHub Release,再通过 PyPI Trusted Publishing 上传 wheel 和源码归档。
18
+
19
+ ## 安装
20
+
21
+ 从 GitHub 获取源码:
22
+
23
+ ```bash
24
+ git clone https://github.com/invokerw/codex_watch.git
25
+ cd codex_watch
26
+ uv tool install --python 3.12 .
27
+ ```
28
+
29
+ 收到源码压缩包时,解压后在包含 `pyproject.toml` 的目录执行:
30
+
31
+ ```bash
32
+ uv tool install --python 3.12 .
33
+ codex-watch doctor
34
+ codex-watch watch
35
+ ```
36
+
37
+ 然后在另一个终端的工作项目目录运行 `codex-watch run`。源码包不含依赖、聊天记录或证书;首次安装会获取依赖,首次启动代理会生成本机证书。
38
+
39
+ 安装本地 wheel(路径替换为实际下载位置):
40
+
41
+ ```bash
42
+ uv tool install --python 3.12 /path/to/codex_watch-0.1.1-py3-none-any.whl
43
+ codex-watch --version
44
+ codex-watch doctor
45
+ ```
46
+
47
+ 若安装后找不到命令,执行 `uv tool update-shell` 并重新打开终端。升级本地包可以使用相同命令并加 `--force`。彻底卸载使用 `codex-watch uninstall`,会同时清理当前数据目录;详见下面的卸载说明。
48
+
49
+ 本版本明确使用 Python 3.12 和已验证的 mitmproxy 11.1.3,安装器会获取其余依赖。wheel 本身不包含 Python 或依赖,首次安装通常需要联网。没有 uv 时,也可在 Python 3.12 虚拟环境中执行 `python -m pip install /path/to/codex_watch-0.1.1-py3-none-any.whl`。
50
+
51
+ ## 使用
52
+
53
+ 终端 A:
54
+
55
+ ```bash
56
+ codex-watch watch
57
+ ```
58
+
59
+ 终端 B 切换到工作项目目录,然后执行:
60
+
61
+ ```bash
62
+ codex-watch run
63
+ ```
64
+
65
+ `watch` 自动启动代理、捕获正文和更新聊天索引;`run` 给新启动的 Codex CLI 配置代理和 CA。需要自行安装并登录 Codex。已有代理时用 `codex-watch watch --attach`。已有 Codex 进程不会自动改走代理。
66
+
67
+ ```bash
68
+ codex-watch search "聊天内容"
69
+ codex-watch search
70
+ codex-watch show 聊天编号
71
+ codex-watch show 聊天编号 --raw
72
+ codex-watch watch --once --file /path/to/codex.jsonl
73
+ codex-watch analyze /path/to/captures
74
+ ```
75
+
76
+ 同一线程、同一轮聊天的请求归到同一个编号;返回事件出现不同模型时即时提示。模型名称差异不等于验证了后台实际使用的模型权重。
77
+
78
+ ## 数据与配置
79
+
80
+ 安装版的数据目录固定在当前用户下,与启动命令的工作目录无关:
81
+
82
+ | 系统 | 默认目录 |
83
+ | --- | --- |
84
+ | macOS | `~/Library/Application Support/codex-watch` |
85
+ | Windows | `%LOCALAPPDATA%\codex-watch` |
86
+ | Linux | `$XDG_DATA_HOME/codex-watch`,缺省为 `~/.local/share/codex-watch` |
87
+
88
+ 目录中包含 `captures/codex.jsonl`、`captures/monitor/index.sqlite3`、报告和 `.mitmproxy` 证书目录。每台机器在首次启动代理时生成自己的 CA。抓包和索引包含已捕获的聊天内容;发布文件不包含用户抓包、数据库或证书。
89
+
90
+ 可以设置环境变量 `CODEX_WATCH_HOME`,或在子命令前指定 `--data-dir`:
91
+
92
+ ```bash
93
+ codex-watch --data-dir /path/to/my-data watch
94
+ codex-watch --data-dir /path/to/my-data run
95
+ codex-watch --data-dir /path/to/my-data search "关键词"
96
+ ```
97
+
98
+ `watch` 和 `run` 必须使用相同的数据目录与端口。自定义端口示例:`codex-watch watch --port 8899` 与 `codex-watch run --port 8899`。需要上游 HTTP 代理时使用 `codex-watch watch --upstream http://127.0.0.1:7890`。
99
+
100
+ 原有源码命令 `python3 codex_dump.py ...` 继续默认使用源码目录内的数据,不会移动或覆盖历史数据。安装版可通过 `--data-dir` 指向原项目目录,直接使用原索引。不要同时运行两个监视器更新同一索引。
101
+
102
+ ## 卸载与清理
103
+
104
+ 从 0.1.1 起,使用工具自己的卸载命令会默认同时清理数据:
105
+
106
+ ```bash
107
+ codex-watch uninstall --dry-run # 预览路径,不执行删除
108
+ codex-watch uninstall # 显示路径,输入 DELETE 后执行
109
+ codex-watch uninstall --yes # 已确认,跳过交互确认
110
+ ```
111
+
112
+ 会删除当前数据目录下的 `captures/`(含抓包、聊天索引、报告、代理日志)和 `.mitmproxy/`(证书),然后通过 uv 卸载当前工具环境。空数据目录会一并移除;同目录下的其他文件保留。清理抓包是不可恢复的文件删除,不保证存储介质上的安全擦除。
113
+
114
+ 先退出正在运行的 watch / serve。新版进程和聊天索引锁会阻止清理;旧版独立 serve 或直接加载 addon 的代理需要自行停止。符号链接或联接点会中止清理,避免删除链接目标。
115
+
116
+ 自定义数据目录时,卸载也要指定同一个目录:
117
+
118
+ ```bash
119
+ codex-watch --data-dir /path/to/my-data uninstall
120
+ ```
121
+
122
+ 只清理选定目录;单独通过 `--file`、`--index`、`--confdir` 保存到其他位置的文件不会被搜索删除,原源码目录的 captures 也不会自动被安装版清理。
123
+
124
+ 其他选择:
125
+
126
+ ```bash
127
+ codex-watch uninstall --keep-data # 卸载程序,保留数据
128
+ codex-watch purge # 清理数据,保留程序;适用于源码和 pip 安装
129
+ uv tool uninstall codex-watch # uv 自身的卸载命令仍只移除程序
130
+ ```
131
+
132
+ 自动卸载会验证当前程序确实来自该 uv 工具环境,避免误卸载另一个安装。对于源码或普通虚拟环境安装,先 `purge`,再用原安装方式卸载程序。若数据清理成功但 uv 卸载失败,会明确报告部分完成的状态。
133
+
134
+ ## 发布到 GitHub Release 和 PyPI
135
+
136
+ 发布前先把 `codex_watch/__init__.py` 中的 `__version__` 改成新版本,例如 `0.1.2`,提交到 `main`。然后在 PyPI 的账号发布设置中登记一次 Trusted Publisher:
137
+
138
+ | 字段 | 值 |
139
+ | --- | --- |
140
+ | PyPI 项目名 | `codex-watch` |
141
+ | Owner | `invokerw` |
142
+ | Repository | `codex_watch` |
143
+ | Workflow filename | `release.yml` |
144
+ | Environment | `pypi` |
145
+
146
+ GitHub 仓库 Settings → Environments 中创建同名 `pypi` environment;建议给它配置 required reviewer,发布 job 会在上传前等待审批。PyPI Trusted Publishing 使用短期 OIDC 凭据,不需要在 GitHub Secrets 保存长期 PyPI token。PyPI 还未创建项目时,可以在 PyPI 的 Publishing 页面添加 pending publisher;首次成功发布会创建项目。
147
+
148
+ 然后推送版本标签:
149
+
150
+ ```bash
151
+ git tag v0.1.2
152
+ git push origin v0.1.2
153
+ ```
154
+
155
+ Actions 会依次执行测试、构建、创建 GitHub Release、上传 PyPI。标签版本必须和 `__version__` 一致;重复运行同一个标签会更新 Release 附件,但 PyPI 对已存在的同版本文件仍会拒绝重复上传。
156
+
157
+ 如果希望先试运行,可以在 TestPyPI 注册相同的 Trusted Publisher,把 workflow 的发布地址改为 TestPyPI,或另外增加一个带 `repository-url: https://test.pypi.org/legacy/` 的发布 job。正式 workflow 默认只上传 PyPI,不会自动上传 TestPyPI。
158
+
159
+ 安全边界:只有匹配 `v*` 的标签触发发布;测试和构建 job 没有 `id-token` 权限,只有 `publish-pypi` job 有 `id-token: write`;发布 workflow 位于固定的 `.github/workflows/release.yml`。不要让不受信任的贡献者直接修改该 workflow。
160
+
161
+ ## 构建与验证
162
+
163
+ 从源码目录构建 wheel 和源码归档:
164
+
165
+ ```bash
166
+ uv build --python 3.12 --out-dir dist
167
+ python3 -m unittest -v test_capture_core test_capture_analysis test_chat_monitor test_packaging test_removal
168
+ .venv/bin/python -m unittest -v test_proxy_integration
169
+ ```
170
+
171
+ 验证安装包时,在独立环境安装后运行以下脚本。脚本把测试复制到临时目录,移除 `PYTHONPATH`,确认程序从新环境的 `site-packages` 加载,再执行全部测试:
172
+
173
+ ```bash
174
+ uv venv --python 3.12 .package-test/venv
175
+ uv pip install --python .package-test/venv/bin/python dist/codex_watch-0.1.1-py3-none-any.whl
176
+ python3 scripts/verify_package.py --python .package-test/venv/bin/python
177
+ python3 scripts/verify_uninstall.py --wheel dist/codex_watch-0.1.1-py3-none-any.whl --python .package-test/venv/bin/python --cache-dir .build-cache
178
+ ```
179
+
180
+ 卸载验收只使用临时的 uv 工具目录、命令目录和模拟数据,分别验证默认删除数据与 `--keep-data`,不会卸载用户已安装的工具。该脚本使用离线缓存,运行前需要安装依赖以填充指定缓存目录。
181
+
182
+ 以上虚拟环境路径示例用于 macOS / Linux;Windows 的解释器位于 `.package-test\venv\Scripts\python.exe`。
183
+
184
+ 构建使用明确的文件包含列表;wheel 只包含 `codex_watch` 程序包和分发元数据。源码归档额外包含文档、兼容启动器和测试。
185
+
186
+ 本地验收需在新的 Python 3.12 环境安装 wheel,并从项目外运行测试,验证资源加载、代理启动、模型告警、检索和进程退出。测试只连接临时本地服务,不调用真实 OpenAI API。验证结果见交付目录中的 `VALIDATION.md`。
187
+
188
+ 已为用户目录、文件锁和进程管理增加 macOS / Linux / Windows 分支。当前机器是 macOS Apple Silicon;Windows 和 Linux 仍需在对应系统做集成验证,不能据此声称所有平台已经通过。
189
+
190
+ 打包方式参考 [Python Packaging 官方指南](https://packaging.python.org/en/latest/tutorials/packaging-projects/),工具安装参考 [uv 文档](https://docs.astral.sh/uv/concepts/tools/)。