Changelog
Unreleased
0.8.0 (2026-05-21)
First-class review-first workflows: code review, security scanning, root-cause debugging, PR artifact helpers, and Reviewflow stateful review/fix workflows.
- Added the
pythinker-reviewworkspace package and wired it into the rootpythinker-codepackage via the pinnedpythinker-review==0.1.0dependency. - Added
pythinker review,pythinker secscan,pythinker security-scan, andpythinker debugcommand surfaces, backed by standalonepythinker-review,pythinker-secscan,pythinker-security-scan, andpythinker-debugconsole scripts. - Added read-only PR artifact/helper commands:
describe,improve/suggest,ask,ask-line,labels,changelog,docs,compliance,help-docs,similar-issues,tools, andconfig. - Added Reviewflow workflow commands and state models for
init,map,review,report,next,show --finding,triage,revalidate,fix,open-pr,ci, anddoctor. - Added the
code-reviewer,security-reviewer, anddebuggersubagent roles for interactive Pythinker sessions. - Hardened review output validation so unsafe paths, stale line ranges, mismatched evidence snippets, malformed model JSON, worker failures, and timeouts fail closed unless
--allow-partialis explicitly used. - Refreshed README release notes with the 0.8.0 review/security/debug feature set and the pinned
pythinker-code==0.8.0upgrade snippet required by the release gate.
Upgrade with pythinker update or pip install --upgrade pythinker-code==0.8.0.
2.6.0 (2026-05-13)
Packaging fix: pin pythinker-core[contrib]==1.1.0 so the Kimi K2.x / DeepSeek strict-interleaved reasoning-replay fix reaches PyPI installs.
Why 2.6.0 lands the same day as 2.5.0
The runtime fix for the strict-interleaved thinking is enabled but reasoning_content is missing in assistant tool call message at index N rejection landed in the pythinker-core source tree on 2026-05-11 (released in pythinker-code 2.4.0 source), but the published pythinker-core==1.0.0 on PyPI predates that change (uploaded 2026-05-07). pythinker-code 2.4.0 and 2.5.0 both pinned pythinker-core[contrib]==1.0.0, so PyPI users on Kimi K2.5 / K2.6 / DeepSeek through OpenCode Go (and elsewhere) kept hitting the bug even on the latest CLI. Reported in #37.
The fix
pythinker-corebumped to 1.1.0 (published independently on PyPI) — carries the strict-interleaved replay logic that emitsreasoning_contenton every assistant turn forkimi-k2*/deepseek*models, falling back toextract_text()then"[reasoning unavailable]"when noThinkPartwas captured.- Root pin updated to
pythinker-core[contrib]==1.1.0inpyproject.toml. New installs ofpip install --upgrade pythinker-code==2.6.0(anduv tool install/upgrade) get the fix automatically. - See
packages/pythinker-core/CHANGELOG.mdfor the full pythinker-core 1.1.0 entry.
No app-level behavior changes vs 2.5.0
Everything that landed in 2.5.0 is still there. The 2.6.0 diff is exclusively the version bump and the upstream-dep pin; existing 2.5.0 users must upgrade to 2.6.0 if they use Kimi K2.x, DeepSeek, or any other strict-interleaved-thinking model through an OpenAI-compatible provider.
Upgrade with pythinker update or pip install --upgrade pythinker-code==2.6.0.
2.5.0 (2026-05-13)
bk_box_main coding-agent runtime port, Windows self-upgrade fix, FetchURL SSRF hardening, and a broad reliability/security pass.
Subagent runtime & permissions
- Runtime-enforced permission profiles for every built-in role: read-only, plan, ask, implement, review, verify. Profiles are snapshot per LLM step in the new
src/pythinker_code/soul/permission.pyso a mid-step model switch can't escalate. Plan mode now hard-denies non-plan writes and dangerous shell mutations instead of relying on prompt-deny. - New plan-handoff workflow in
src/pythinker_code/tools/plan/handoff.pywith dynamic injection throughsoul/dynamic_injections/plan_mode.py. Smooth handoff fromplan→implementwithout re-priming the context. - New smart-search grep variant; new subagent metadata plumbing (
subagents/models.py,subagents/store.py,subagents/builder.py,subagents/runner.py).
Background tasks
- Recovery distinguishes
recoverable(resumable via a storedagent_id) fromlost(worker is gone with no resume target). Agent instances are parked asidlerather than failed when the underlying task is recoverable. - Guards against overwriting terminal task states; subagent races on instance transitions closed.
pythinker-host: subprocess teardown now kills the entire child process tree and creates a new session group, so background workers can no longer survive their parent on Linux/macOS.
FetchURL — SSRF + resource-exhaustion hardening
pythinker_code.tools.web.fetch._validate_fetch_urlblocks private, loopback, link-local, multicast, and reserved IPv4/IPv6 ranges; rejects non-http/httpsschemes and host-less URLs up front.- Responses are streamed with a hard 5 MB ceiling (
_read_limited) honoringContent-Length. Both the direct path and the configured fetch-service path enforce the same caps.
Web / vis surface
- Upload limits, open-in path escaping, and vis auth all hardened (
src/pythinker_code/web/,src/pythinker_code/vis/,vis/src/lib/api.ts).
Plugin
- Plugin definitions no longer persist host credentials. Plugin name validation tightened to reject path-traversal and shell-meta characters.
Telemetry & observability
- OTel
service.namenormalized to a stable value, decoupled from the configured display name, so SigNoz dashboards keep working across rebrands. - Sentry filters drop test-process noise and benign shutdown errors;
pythinker_code/telemetry/config.pyandpythinker_code/telemetry/crash.pyupdated accordingly. - New
tests/telemetry/test_otel_resource.pyasserts the resource identity used by the dashboards.
Windows
pythinker updateon Windows now spawns the upgrade in a detached console and exits the parent process beforeuv tool upgraderuns, releasing the lock on the runningpythinker.exe. Fixes theos error 32: The process cannot access the file because it is being used by another processerror that blocked self-upgrade.- New CI matrix entry on
windows-2025-vs2026(experimental, non-blocking) for the pythinker-host and pythinker-cli build, validating Visual Studio 2026 / MSVC v144 forward-compat before GitHub eventually deprecateswindows-2022.
Feedback
- New
feedbackconfig block:endpoint_url,api_key,custom_headers. The/feedbackslash command now routes user submissions to a user-configured HTTP endpoint instead of being a no-op.
UI
- Pythinker version is shown on the welcome screen.
CI
- Pre-push hooks mirror CI's
checktarget (ruff format --check,ruff check,pyright) so local pushes catch the same regressions CI does. - README + CHANGELOG release-validate gate hardened; the GitHub Release publish step is now resilient to transient upstream failures.
- Spell-check vocabulary fix in
soul/permission.pyfor an internal error string the typos crate flagged; experimentalwindows-2025-vs2026build no longer collides withwindows-2022on the sharedpythinker-x86_64-pc-windows-msvcartifact name.
Compatibility
pythinker_core.contrib.chat_provider.anthropic: handle the six new tool-result block types added by anthropic SDK 0.101 (web_fetch_tool_result,code_execution_tool_result,bash_code_execution_tool_result,text_editor_code_execution_tool_result,tool_search_tool_result,container_upload). pyright is exhaustive again.
Upgrade with pythinker update or pip install --upgrade pythinker-code==2.5.0.
2.4.0 (2026-05-11)
Subagent roles overhaul, Kimi K2 provider support, and a ripgrep-free Grep fallback.
- New built-in subagents under
src/pythinker_code/agents/default/:implementer.yaml— scoped code changes with minimum surrounding edits and a quick verification pass.review.yaml— read-only code review with severity-scored findings (BLOCKER / MAJOR / MINOR / NIT).verifier.yaml— read-only validation runner that reportsPASS/FAIL/FLAKYwithout applying fixes.
coder.yaml,explore.yaml, andplan.yamlnow emit a standard### SUMMARY / EVIDENCE / CHANGES / RISKS / BLOCKERSresponse contract so the parent agent can consume subagent output without re-parsing prose.agent.yamlregisters the three new roles;tools/agent/description.mddocuments the Scout → Plan → Implement → Review → Verify workflow and the parallel review/verification pattern.agents/default/system.md: adds decomposition guidance (preview → todo list → parallel chunks), enforces post-tool-call verification before acting on results, and tells the agent to cross-check at least one load-bearing subagent finding before editing from it.- Kimi K2.5 / K2.6 and other strict interleaved-thinking providers:
packages/pythinker-core/.../chat_provider/pythinker.py: always emitreasoning_contenton assistant tool-call replays so the strict "thinking is enabled but reasoning_content is missing in assistant tool call message at index N" error no longer trips multi-step tool flows.packages/pythinker-core/.../contrib/chat_provider/openai_legacy.py: replay reasoning metadata on every assistant turn forkimi-k2*/deepseek*models (falls back to the assistant text or"[reasoning unavailable]"when reasoning content was not retained).src/pythinker_code/llm.py: route Kimi K2 thinking through the provider-specificextra_body={"thinking": {"type": "enabled"|"disabled"}}body field instead of OpenAI'sreasoning_effort(which Kimi ignores), and persistLLM.thinkingacrossclone_llm_with_model_aliasso model switches preserve the user's thinking choice.
tools/file/grep_local.py:- Pure-Python
rg-free fallback (_python_grep) honoringpattern,path,glob,type(bash / c / cpp / go / java / js / json / md / py / rust / sh / toml / ts / txt / yaml / zsh),ignore_case,multiline,context/before_context/after_context,line_number,output_mode(content/files_with_matches/count_matches),offset,head_limit, and the standard sensitive-file redaction..gitignore/.ignoreand the VCS metadata directories (.git,.svn,.hg,.bzr,.jj,.sl) are respected unlessinclude_ignored=true. _find_existing_rgnow honorsPYTHINKER_RG_PATHand additionally probes/usr/bin,/usr/local/bin,~/.cargo/bin,~/.local/bin, and~/.pi/agent/binbefore falling through to download.- Downloader retries against the upstream GitHub releases mirror (
https://github.com/BurntSushi/ripgrep/releases/download/<version>/...) when the CDN mirror is unreachable, and the failure path now degrades into the Python fallback instead of raising.
- Pure-Python
.gitignore: ignore generated code-graph outputs and the local reference-scan scratch area.AGENTS.mdrewritten to reflect the new subagent roster and workflow.
2.3.0 (2026-05-09)
Telemetry & observability audit.
- New
pythinker_code/telemetry/errors.pyhelperreport_handled_error(exc, *, site, tool=None, **attrs)forwards caught-and-rendered exceptions to both Sentry/Bugsink and the OTelerrorevent stream. Both forwarding paths arecontextlib.suppress-wrapped so monitoring can never break the host program. - 38 silent-catch sites instrumented across
tools/,auth/,soul/,acp/,hooks/,subagents/. Tool failures, OAuth errors, MCP server hiccups, hook callback failures, and subagent crashes now reach Bugsink and SigNoz. pythinker_code/telemetry/otel.py: TracerProvider now usesParentBased(TraceIdRatioBased(rate))driven byPYTHINKER_OTEL_TRACE_SAMPLE_RATE(default 1.0).- New
pythinker.mcp.callspan around every MCPTool RPC. - New
/report-errorslash command (aliases/report,/report-error). docs/en/reference/telemetry.mddocuments the full telemetry contract.chore(test): updated google-genai snapshot for pydantic 2.13.4 + google-genai 2.0.0.
2.2.1 (2026-05-09)
CI hardening: macOS binary build is now optional-codesign.
.github/workflows/release-pythinker-cli.yml: detect whetherAPPLE_CERTIFICATE_P12andAPPLE_NOTARIZATION_KEY_P8repo secrets are configured. When they aren't, skip the keychain setup, codesign, and notarization steps and ship an ad-hoc-signed PyInstaller binary instead of failing the whole release. The 2.2.0 release run failed because those secrets were empty in CI; this makes the release matrix all-green even without an Apple Developer cert..github/workflows/release-pythinker-cli.yml: addskip-existing: truetopypa/gh-action-pypi-publishso re-runs of the release workflow against an already-published version are no-ops instead of HTTP 400 errors.- macOS-arm64 binary downloads from the GitHub Release page will now show a Gatekeeper warning on first launch when the secrets aren't configured. Users can clear it with
xattr -d com.apple.quarantine ./pythinker. PyPI install (pip install pythinker-code) is unaffected.
2.2.0 (2026-05-09)
Installer UX: animated logo + Windows PATH automation.
scripts/install.sh: Tetris-style logo animation. Pieces (walls, bars, eyes, ears, antenna) fall from above the canvas one at a time and settle into the robot head before install proceeds. Static logo remains the fallback for non-TTY /NO_COLOR/TERM=dumb/CI=1/PYTHINKER_NO_ANIMATION=1. Tunables:PYTHINKER_LOGO_FRAME_DELAYandPYTHINKER_LOGO_STAGGER_DELAY(seconds).scripts/install.ps1: same animation, PowerShell port. Tunables:PYTHINKER_LOGO_FRAME_DELAY_MSandPYTHINKER_LOGO_STAGGER_DELAY_MS(milliseconds).scripts/install.ps1: idempotently append$USERPROFILE\.local\binto the User PATH via[Environment]::SetEnvironmentVariableand broadcastWM_SETTINGCHANGEso future shells (and Explorer-spawned children) pick up the new PATH automatically. No-op when the directory is already present.scripts/install.ps1: force[Console]::OutputEncoding = UTF8so the box-drawing characters render correctly on Windows hosts.
2.1.2 (2026-05-09)
Windows installer fix.
scripts/install.ps1: dot-source Astral'suvbootstrap inside& { ... }instead of spawningpowershell -File, so$env:PATHupdates land in the running process.scripts/install.ps1: refresh PATH afteruv tool installand verifypythinkerresolves before printing success; otherwise emit the absolute shim path.- README: invoke the downloaded
install.ps1with& $installer(current shell) instead of apowershell -NoProfile -File $installersubprocess.uv,uvx, andpythinkerare now usable in the calling shell as soon as the installer exits. tests/test_installation_docs.py: lock in current-session invocation in the README and a dot-sourceduvbootstrap ininstall.ps1.
2.1.1 (2026-05-08)
Documentation refresh.
- README: image and key file links converted to absolute GitHub URLs so the project page on PyPI renders the logo, demo GIFs, and architecture diagram correctly.
- README: added a "What's New in 2.1.0" section summarising the TUI CLI and slash-command enhancements.
- README: corrected the License section to Apache-2.0 (matches
pyproject.tomland theLICENSEbadge).
2.1.0 (2026-05-08)
TUI CLI design and slash command enhancements.
New selectors package — interactive
/theme,/thinking,/model,/login,/settings,/extension, and/show-imagespanels replace inline numeric/text prompts.New
/thinkingslash command for adjusting reasoning effort at runtime.SettingsListcomponent +/settingsselector for liveConfigediting (theme, default model, TUI style, default thinking, telemetry).Selector framework:
SelectorHeadersentinel and per-rowon_changecallback.Card-style TUI polish: bordered shell card, footer/toolbar, tool renderers (read/write/edit/grep/find/bash/agent) and a diff component; subagent tool cards get a running-dots spinner.
Pythinker-branded slash menu, input row, and tool execution components.
Prompt template discovery simplified to
.pythinker/promptsat project and user scope (legacy directory lookup removed).TUI style flag now accepts only
card(default) orpythinker; the legacy alias has been dropped.Update notifier: standalone "Update Available" banner shown above the welcome panel when a newer release is on PyPI; suppressed by
PYTHINKER_CLI_NO_AUTO_UPDATE=1.New
pythinker updatesubcommand (--checkfor a non-installing check) that auto-detects the install method (uv tool,pipx, orpip) and runs the matching upgrade command.Image paste placeholder now renders as
[Image #N]in the input/buffer (mirroring[Pasted text #N +K lines]); history serialization keeps the canonical[image:<id>,WxH]form so attachments still resolve cross-session.Lower default paste-placeholderize thresholds to 200 chars / 5 lines (was 1000 / 15) so medium-length pastes collapse into
[Pasted text #N]instead of overflowing the compact input window. Override viaPYTHINKER_CLI_PASTE_CHAR_THRESHOLDandPYTHINKER_CLI_PASTE_LINE_THRESHOLD.
1.0.0 (2026-05-06)
Initial release of Pythinker CLI.
- Interactive terminal AI coding agent with shell command mode (Ctrl-X)
- ACP server (
pythinker acp) for IDE integrations such as Zed and JetBrains - MCP tool support:
pythinker mcpsub-commands and ad-hoc--mcp-config-file - Multi-provider auth: OpenAI, OpenAI Codex, Anthropic, OpenRouter, DeepSeek, MiniMax, Opencode-Go
- Skills, plugins, and slash commands across project / user / built-in scopes
- Session persistence with subagents and approval workflows
- Print mode and wire mode for non-interactive and programmatic use
- Plan mode for read-only research and design before code changes
- YOLO mode (
--yolo//yolo) to dangerously skip permission approvals while keeping the user reachable viaAskUserQuestion - Auto mode (
--auto//auto) for unattended runs: auto-approves tool calls and auto-dismissesAskUserQuestionso the agent finishes end-to-end without a user