Skip to content

Commit 32ef417

Browse files
committed
chore(release): prepare 0.40.0
Bump version to 0.40.0, cut the 0.40.0 CHANGELOG/breaking-changes blocks, and refresh release-asset references across README and the linux-installer docs. Highlights: Alibaba plan-key routing fix and live model discovery, Qwen3.x always-thinking on both Alibaba plans, same-origin WebSocket fix and web version banner sync, deep security/correctness/multi-instance audit remediation, thinking effort top-right label, TUI refinements and agent prompt overhaul. Breaking: pythinker web/vis -h renamed to -H.
1 parent c819e4b commit 32ef417

8 files changed

Lines changed: 62 additions & 42 deletions

File tree

CHANGELOG.md

Lines changed: 4 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+
## 0.40.0 (2026-06-10)
19+
1820
- **Web: same-origin WebSockets accepted, version banner synced to the backend, and token bootstrap race fixed.** The local-mode web server now auto-populates the allowed-origin list (an empty allowlist rejects every `Origin`-bearing request, which previously broke all WebSocket handshakes with a 403). The UI version banner prefers the version the running backend reports (via the config API) over the stale build-time constant, and a transient version-fetch failure no longer permanently disables the backend banner for the session. The initial auth-token bootstrap race that could fail the first request is resolved. `ESC` now reliably terminates only the background tasks spawned by the interrupted turn, and recall context is re-framed so prior-session snippets can't be misread as new instructions.
1921
- **Deep-audit remediation: security, correctness, and multi-instance robustness.** Permission gate: awk programs that shell out via `print | "cmd"` / `getline` are now classified as mutating AND destructive (previously only `system(`/`>` and only mutating), and `xargs -L N` no longer hides its payload from classification. Glob resolves symlinks before its workspace-boundary check (an in-workspace symlink could previously list outside content); progress-note titles are ANSI-sanitized like every other transcript field. Grep content lines are parsed with unambiguous field separators, so paths like `utf-8-codec.py` are no longer mangled with `-n=false` and sensitive-file attribution is exact. Multi-line edits on CRLF files work again (LF-joined old strings are CRLF-translated when needed). `/import` preserves paths byte-for-byte (only a standalone leading/trailing `--force` is treated as the flag). Post-compaction file reminders include `--add-dir` files. Double-interrupt can no longer orphan the interruption-marker write (unanswered tool_calls). Background web replay falls back to full history (not empty) when the watermark stat fails, and a malformed Agent resume id returns a clean "Agent not found". OAuth: login fails loud when the token response lacks a `refresh_token`; a refresh response without `expires_in` carries the previous lifetime forward instead of refreshing every tick; the device-id file can no longer be read empty mid-creation. A failed `theme="auto"` background probe can be retried by re-selecting auto via `/theme`. Multi-instance: sessions now take a per-session writer lock (a second `pythinker -r <id>`/web worker on the same session is refused instead of interleaving turns), the shared `pythinker.json` index uses a locked read-modify-write (no more lost work-dir registrations), JSONL appenders repair torn final lines after a crash, forks materialize atomically, project-memory mutations abort on read failure instead of wiping the file, the journal is capped at 100 recaps, inbox approve/reject claims candidates atomically, and recall re-arms when another instance writes new memory. Subagents: a failed summary continuation no longer discards a completed agent's work, hallucinated subagent types fail fast with the valid-type list (before any RunAgents child launches), background failures carry an `Agent ID:` + resume hint, and a crash inside the runner's own error handling is logged instead of silently lost.
2022
- **Breaking (CLI flags): `pythinker web` / `pythinker vis` host short flag is now `-H`.** `-h` is a help alias on both subcommands (matching the root CLI); previously `-h <ip>` bound the host. Scripts using `-h 0.0.0.0` now print help and exit 0 without starting a server — switch to `-H <ip>` or `--host <ip>`. Part of the security/correctness audit (which also confined Grep to the workspace, gated non-HTTPS provider URLs in the web config API to loopback, and stopped saving OpenAI keys on 401/403).
@@ -23,6 +25,8 @@ GitHub Releases page; `0.8.0` is the new starting line.
2325
- **Qwen models treated as native-thinking across both plans.** Qwen3.x/3.7 (e.g. `qwen3.7-max`, `qwen3.6-plus`, the Qwen3 Coder models) now carry the `always_thinking` capability on both the Alibaba Model Studio and OpenCode Go plans, matching GLM/MiniMax: reasoning is built in and always on, with no user effort dial and no top-border effort label. Reasoning still flows over the Anthropic `thinking` block that both Anthropic-compatible routes accept.
2426
- **TUI enhancements: adaptive theme, layout, and agent prompt overhaul.** Adaptive terminal-background probe + color-depth blending; reference-CLI layout and palette refinements; unified todo-list renderer; white running-task titles with consistent diff palette; elapsed/tokens/t-s metadata on the background status line; transcript-row bullet fix; renderer guards and markdown fence table unwrapping. All default agent prompts restructured with explicit Mission / Hard Constraints / Workflow / Output Contract sections. Background manager and subagent runner hardened with stale-record reconciliation and resume contract enforcement. Automatic turn recaps disabled by default.
2527

28+
Upgrade with `pythinker update`, `pip install --upgrade pythinker-code==0.40.0`, or use the native installer for your platform from the [Releases page](https://github.com/Pythoughts-labs/pythinker-code/releases/latest).
29+
2630
## 0.39.0 (2026-06-09)
2731

2832
- **Refreshed TUI theme and Catppuccin syntax highlighting.** The interface adopts a brand periwinkle/indigo accent (`#B3B9F4` dark / `#0B114E` light) with a reharmonized selection tint, and code blocks now highlight with Catppuccin Mocha (dark) / Latte (light), adaptive to the active theme — implemented as foreground-only Pygments styles with no new dependency. Markdown inline code and links render terminal-native cyan, blockquotes green, and ordered-list markers bright blue (so they adapt per terminal), and user messages sit on a neutral grey block instead of the prior blue tint.

README.md

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -50,17 +50,17 @@ It speaks the [**Agent Client Protocol (ACP)**](https://github.com/agentclientpr
5050
5151
---
5252

53-
## 🆕 What's New in 0.39.0
53+
## 🆕 What's New in 0.40.0
5454

55-
- **Refreshed TUI theme and Catppuccin syntax highlighting.** The interface adopts a brand periwinkle/indigo accent with a reharmonized selection tint, and code blocks now highlight with Catppuccin Mocha (dark) / Latte (light). Inline code, links, blockquotes, and list markers all render with terminal-native colours; user messages sit on a neutral grey block instead of the prior blue tint.
56-
- **Homebrew updater no longer no-ops or false-reports success.** `pythinker update` on a Homebrew install now refreshes the tap before upgrading and re-checks the installed version afterwards, reporting a clear failure instead of "Updated successfully!" when the version did not actually advance.
57-
- **Friendlier 429 messages and ChatGPT account switching.** Rate-limit responses now render a human-readable notice (plan name, reset window, dimmed server detail) instead of a raw error string. `/login` for ChatGPT uses `prompt=login` so you can switch accounts.
58-
- **Agent phase-0 enhancements.** Adds a cross-session Recall tool, read-only MCP resources/prompts surfaced as tools, project-scoped `.pythinker/mcp.json` layering, subagent token/cost roll-up, and truncated tool output that spills to disk with a recovery hint.
59-
- **Agent knows how to manage MCP servers.** The agent configures, lists, and tests MCP servers via the `pythinker mcp` CLI rather than refusing or citing wrong config paths. YAML `mcpServers` misplacements now log a diagnosable warning.
60-
- **Read-only profile guard hardened.** Version-suffixed or absolute interpreter invocations (`python3.14 -c …`, `node20 -e …`) are now classified as mutating, closing a bypass in read-only subagent profiles.
61-
- **Security: dependency vulnerability remediation.** `asyncssh` → 2.23.0, `starlette` → 1.2.1, JS lockfiles regenerated with `vitest` → ^3.2.6, clearing all critical/high/moderate Dependabot advisories.
55+
- **Alibaba: plan-key routing fixed, live model discovery, and `qwen3.7-plus` default.** Token Plan keys (`sk-sp-`, `sk-tok-`, `sk-ws-`) now route to the correct endpoint — `sk-sp-` was previously sent to the Coding Plan host, causing 401s. Model discovery no longer filters to a hardcoded allowlist; every chat model the endpoint returns now appears, so Token Plan users see the full multi-vendor set (Qwen, DeepSeek, GLM, Kimi, MiniMax). First-login default is `qwen3.7-plus`.
56+
- **Qwen3.x models always-thinking on both Alibaba plans.** Qwen3.x/3.7 models carry the `always_thinking` capability on Alibaba Model Studio and OpenCode Go plans — no effort dial, no top-border label.
57+
- **Web: same-origin WebSockets, synced version banner, and token bootstrap fix.** An empty allowed-origin list no longer rejects all WebSocket connections with a 403; the UI banner prefers the version the running backend reports; the initial auth-token race is resolved. `ESC` reliably clears only turn-spawned background tasks.
58+
- **Security, correctness, and multi-instance hardening.** Permission gate closes awk-pipe and `xargs -L N` shell-out bypasses. Glob enforces workspace boundary via resolved symlinks. Multi-instance sessions use a per-session writer lock; the shared metadata index uses locked read-modify-write; JSONL appenders repair torn final lines. OAuth refresh carries lifetime forward on missing `expires_in`.
59+
- **Thinking effort: single top-right label, input border stays neutral.** The border no longer recolors per effort level. Effort is shown once as a level-colored dot+label flushed to the right of the input's top border, hidden for always-thinking and non-thinking models.
60+
- **TUI refinements and agent prompt overhaul.** Adaptive terminal-background probe, unified todo renderer, elapsed/tokens/t-s status line, consistent diff palette. All default agent prompts restructured with Mission / Hard Constraints / Workflow / Output Contract sections.
61+
- **Breaking: `pythinker web` / `pythinker vis` host flag is now `-H`.** `-h` is now a help alias. Scripts using `-h 0.0.0.0` must switch to `-H <ip>` or `--host <ip>`.
6262

63-
Upgrade with `pythinker update`, `pip install --upgrade pythinker-code==0.39.0`, or use the native installer for your platform from the [Releases page](https://github.com/Pythoughts-labs/pythinker-code/releases/latest).
63+
Upgrade with `pythinker update`, `pip install --upgrade pythinker-code==0.40.0`, or use the native installer for your platform from the [Releases page](https://github.com/Pythoughts-labs/pythinker-code/releases/latest).
6464

6565

6666
---
@@ -150,7 +150,7 @@ matches your OS — no Python, Node, or `uv` prerequisite.
150150

151151
| Platform | Recommended install | Artifact source |
152152
|---|---|---|
153-
| **🪟 Windows** | `irm https://pythinker.com/install.ps1 \| iex` | `PythinkerSetup-0.39.0.exe` from [Releases](https://github.com/Pythoughts-labs/pythinker-code/releases/latest) |
153+
| **🪟 Windows** | `irm https://pythinker.com/install.ps1 \| iex` | `PythinkerSetup-0.40.0.exe` from [Releases](https://github.com/Pythoughts-labs/pythinker-code/releases/latest) |
154154
| **<img src="https://img.shields.io/badge/-macOS-000000?style=flat-square&logo=apple&logoColor=white" alt="macOS"> / <img src="https://img.shields.io/badge/-Linux-FCC624?style=flat-square&logo=linux&logoColor=black" alt="Linux">** | `curl -fsSL https://pythinker.com/install.sh \| bash` | native tarball from [Releases](https://github.com/Pythoughts-labs/pythinker-code/releases/latest) |
155155
| **<img src="https://img.shields.io/badge/-macOS-000000?style=flat-square&logo=apple&logoColor=white" alt="macOS"> — Homebrew** | `brew install Pythoughts-labs/pythinker/pythinker-code` | auto-published Homebrew tap |
156156
| **🐳 Docker** | `docker run --rm -it ghcr.io/pythoughts-labs/pythinker-code` | GHCR multi-arch image |
@@ -178,7 +178,7 @@ pythinker # start the interactive TUI
178178

179179
### 🪟 Windows — native installer
180180

181-
`PythinkerSetup-0.39.0.exe` is a signed* Inno Setup wizard. Installs per-user
181+
`PythinkerSetup-0.40.0.exe` is a signed* Inno Setup wizard. Installs per-user
182182
into `%LOCALAPPDATA%\Programs\Pythinker`, registers `pythinker` on your user
183183
PATH (`HKCU\Environment`), broadcasts `WM_SETTINGCHANGE` so new shells see
184184
the change. **No UAC prompt.**
@@ -189,13 +189,13 @@ irm https://pythinker.com/install.ps1 | iex
189189
190190
# Or manually download the installer + checksum from the Releases page,
191191
# verify with Get-FileHash, then run:
192-
.\PythinkerSetup-0.39.0.exe
192+
.\PythinkerSetup-0.40.0.exe
193193
194194
# Open a fresh PowerShell
195195
pythinker --version
196196
```
197197

198-
**Per-machine install** (IT-managed boxes): `.\PythinkerSetup-0.39.0.exe /ALLUSERS`
198+
**Per-machine install** (IT-managed boxes): `.\PythinkerSetup-0.40.0.exe /ALLUSERS`
199199
installs to `%ProgramFiles%\Pythinker` and writes PATH to HKLM (requires admin).
200200

201201
**Upgrade:** `pythinker update` from inside the running app — it downloads
@@ -246,26 +246,26 @@ attached to every GitHub Release.
246246

247247
```sh
248248
# Debian / Ubuntu (x86_64)
249-
sudo dpkg -i pythinker-code_0.39.0_amd64.deb
249+
sudo dpkg -i pythinker-code_0.40.0_amd64.deb
250250
sudo apt-get install -f # only if dpkg reports missing deps
251251

252252
# Debian / Ubuntu (ARM64)
253-
sudo dpkg -i pythinker-code_0.39.0_arm64.deb
253+
sudo dpkg -i pythinker-code_0.40.0_arm64.deb
254254

255255
# Fedora / RHEL / openSUSE (x86_64)
256-
curl -LO https://github.com/Pythoughts-labs/pythinker-code/releases/download/v0.39.0/pythinker-code-0.39.0.x86_64.rpm
257-
curl -LO https://github.com/Pythoughts-labs/pythinker-code/releases/download/v0.39.0/pythinker-code-0.39.0.x86_64.rpm.sha256
258-
sha256sum -c pythinker-code-0.39.0.x86_64.rpm.sha256
256+
curl -LO https://github.com/Pythoughts-labs/pythinker-code/releases/download/v0.40.0/pythinker-code-0.40.0.x86_64.rpm
257+
curl -LO https://github.com/Pythoughts-labs/pythinker-code/releases/download/v0.40.0/pythinker-code-0.40.0.x86_64.rpm.sha256
258+
sha256sum -c pythinker-code-0.40.0.x86_64.rpm.sha256
259259
# Fedora / RHEL:
260-
sudo dnf install ./pythinker-code-0.39.0.x86_64.rpm
260+
sudo dnf install ./pythinker-code-0.40.0.x86_64.rpm
261261
# openSUSE:
262-
sudo zypper install ./pythinker-code-0.39.0.x86_64.rpm
262+
sudo zypper install ./pythinker-code-0.40.0.x86_64.rpm
263263

264264
# Fedora / RHEL (aarch64)
265-
curl -LO https://github.com/Pythoughts-labs/pythinker-code/releases/download/v0.39.0/pythinker-code-0.39.0.aarch64.rpm
266-
curl -LO https://github.com/Pythoughts-labs/pythinker-code/releases/download/v0.39.0/pythinker-code-0.39.0.aarch64.rpm.sha256
267-
sha256sum -c pythinker-code-0.39.0.aarch64.rpm.sha256
268-
sudo dnf install ./pythinker-code-0.39.0.aarch64.rpm
265+
curl -LO https://github.com/Pythoughts-labs/pythinker-code/releases/download/v0.40.0/pythinker-code-0.40.0.aarch64.rpm
266+
curl -LO https://github.com/Pythoughts-labs/pythinker-code/releases/download/v0.40.0/pythinker-code-0.40.0.aarch64.rpm.sha256
267+
sha256sum -c pythinker-code-0.40.0.aarch64.rpm.sha256
268+
sudo dnf install ./pythinker-code-0.40.0.aarch64.rpm
269269
```
270270

271271
Both packages drop a small `/usr/bin/pythinker` launcher that execs the real
@@ -274,8 +274,8 @@ binary under `/usr/lib/pythinker/`, so your `$PATH` stays tidy.
274274
**Verify before install:**
275275

276276
```sh
277-
sha256sum -c pythinker-code_0.39.0_amd64.deb.sha256 # Debian/Ubuntu
278-
sha256sum -c pythinker-code-0.39.0.x86_64.rpm.sha256 # Fedora/RHEL
277+
sha256sum -c pythinker-code_0.40.0_amd64.deb.sha256 # Debian/Ubuntu
278+
sha256sum -c pythinker-code-0.40.0.x86_64.rpm.sha256 # Fedora/RHEL
279279
```
280280

281281
**Upgrade:** download the new `.deb`/`.rpm` from Releases and `dpkg -i` /

docs/en/guides/getting-started.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ On Windows, run the PowerShell bootstrap. It downloads the native installer, ver
4444
irm https://pythinker.com/install.ps1 | iex
4545
```
4646

47-
You can also download `PythinkerSetup-0.39.0.exe` manually from the [latest release](https://github.com/Pythoughts-labs/pythinker-code/releases/latest).
47+
You can also download `PythinkerSetup-0.40.0.exe` manually from the [latest release](https://github.com/Pythoughts-labs/pythinker-code/releases/latest).
4848

4949
Verify the installation:
5050

docs/en/release-notes/breaking-changes.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ This page documents breaking changes in Pythinker Code releases and provides mig
44

55
## Unreleased
66

7+
## 0.40.0 (2026-06-10)
8+
9+
**`pythinker web` / `pythinker vis` `-h` host flag renamed to `-H`.** The short flag `-h` is now a help alias on both subcommands (matching the root CLI); previously `-h <ip>` bound the host. Scripts using `-h 0.0.0.0` must switch to `-H <ip>` or `--host <ip>`.
10+
711
## 0.39.0 (2026-06-09)
812

913
No breaking changes. This release is compatible with 0.38.0 user configuration, native installs, and session data.

0 commit comments

Comments
 (0)