Skip to content

Commit 97ebce8

Browse files
committed
fix(ci): correct pyinstaller test assertion and ruff format; add changelog
- copy_metadata() returns one directory entry per package (the whole dist-info dir), not individual file entries. The test was asserting p.endswith("/METADATA") which can never match a directory path — fix to assert the dest dir name matches. - Inline the asyncio.to_thread lambda to satisfy ruff line-length check. - Add changelog entries for the mcp add fix and gitignore auto-exclusion feature.
1 parent 36e2c9d commit 97ebce8

3 files changed

Lines changed: 7 additions & 5 deletions

File tree

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ GitHub Releases page; `0.8.0` is the new starting line.
1515

1616
## Unreleased
1717

18+
- **`pythinker mcp add` no longer crashes on Windows and Linux native builds.** The PyInstaller specs were using `collect_data_files()` which silently omits the `fastmcp-*.dist-info/` sibling directory; fastmcp calls `importlib.metadata.version("fastmcp")` at import time, so every `mcp add` / `mcp list` invocation raised `PackageNotFoundError`. Switched all three specs (Windows installer, Linux installer, macOS/tarball) to `copy_metadata()` — the PyInstaller-standard hook for bundling dist-info.
19+
- **Pythinker work directories are automatically gitignored on startup.** When the agent starts inside a git repository, `.pythinker/`, `.pythinker-review/`, and `.pythinker-review-flow/` are silently appended to the project's `.gitignore` if missing, preventing local agent state from making the working tree dirty.
1820
- **Windows upgrade version display fix.** In-place upgrades no longer show a stale version number or re-trigger the update prompt. Inno Setup now wipes `_internal` before installing new files, preventing old `dist-info` directories from accumulating and causing `importlib.metadata` to report the previous version.
1921

2022
## 0.31.0 (2026-06-02)

src/pythinker_code/scratchpad.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -445,9 +445,7 @@ async def _append_gitignore_entries(work_dir: HostPath) -> None:
445445
"""
446446
gitignore_path = Path(str(work_dir)) / ".gitignore"
447447
try:
448-
await with_retries(
449-
lambda: asyncio.to_thread(_write_gitignore_entries, gitignore_path)
450-
)
448+
await with_retries(lambda: asyncio.to_thread(_write_gitignore_entries, gitignore_path))
451449
except Exception:
452450
logger.debug("scratchpad .gitignore update failed")
453451

tests/utils/test_pyinstaller_utils.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,12 @@ def test_pyinstaller_datas():
4646
# justext stoplists), so assert METADATA presence rather than pinning every
4747
# file. copy_metadata() produces clean paths ({dist-info}/FILE) — no
4848
# fastmcp/../ prefix that the old collect_data_files workaround created.
49+
# copy_metadata() returns a single directory entry per package (the whole
50+
# dist-info dir), so check that the dest dir name matches — not a file inside it.
4951
for pkg in ("fastmcp", "mcp"):
5052
pkg_dist = f"{pkg}-{version(pkg)}.dist-info"
51-
assert any(d == pkg_dist and p.endswith("/METADATA") for p, d in datas), (
52-
f"{pkg_dist}/METADATA must be bundled so importlib.metadata works in the frozen app"
53+
assert any(d == pkg_dist for p, d in datas), (
54+
f"{pkg_dist} must be bundled so importlib.metadata works in the frozen app"
5355
)
5456

5557
dist_info_dirs = {f"{pkg}-{version(pkg)}.dist-info" for pkg in ("fastmcp", "mcp")}

0 commit comments

Comments
 (0)