Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 15 additions & 4 deletions .github/workflows/docs-pages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,15 @@ permissions:
env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true"

concurrency:
group: pages
cancel-in-progress: false

jobs:
deploy:
build:
# Only run on the original repository, not on forks
if: github.repository == 'Pythoughts-labs/pythinker-code'
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deploy.outputs.page_url }}
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # pinned from v6.0.2
Expand Down Expand Up @@ -76,6 +77,16 @@ jobs:
with:
path: docs/.vitepress/dist

deploy:
needs: build
runs-on: ubuntu-latest
permissions:
pages: write
id-token: write
environment:
name: github-pages
url: ${{ steps.deploy.outputs.page_url }}
steps:
- name: Deploy to GitHub Pages
id: deploy
uses: actions/deploy-pages@cd2ce8fcbc39b97be8ca5fce6e763baed58fa128 # pinned from v5.0.0
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -78,3 +78,6 @@ blackbox/
coverage.xml
htmlcov/
*.scratchpad.lock

.playwright-mcp/
.playwright/
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ GitHub Releases page; `0.8.0` is the new starting line.
- **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.
- **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).
- **Thinking effort moved to a single top-right label on the input border.** The input box border is now one static frame grey at every effort level instead of recoloring the whole bar cold→hot, and the effort is no longer duplicated in the footer line. It's shown once, as a small label flushed to the right of the input's top border — a level-colored dot (slate→blue→teal→amber→orange→red as `off→max`) plus the muted level word — so the dial stays glanceable without tinting the typing area or cluttering the footer. The label is hidden entirely for native-thinking models (`always_thinking`, no user dial) and non-thinking models, and the rule auto-shortens by the label width so the line never wraps.
- **Alibaba login: correct plan-key routing, full live model discovery, and `qwen3.7-plus` default.** Subscription "plan" keys — `sk-sp-`, `sk-tok-`, and `sk-ws-` — now route to the shared international Token Plan endpoint (`token-plan.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1`), fixing a bug where `sk-sp-` keys were sent to the Coding Plan host (`coding-intl`) and every chat then failed with `401 invalid_api_key`. Generic `sk-` keys remain pay-as-you-go Cloud (DashScope) keys. Model discovery no longer filters the live `/models` response down to a hardcoded allowlist — every chat model the endpoint returns now appears (known models keep curated capabilities/context; the rest get sensible defaults), while text-to-image models (Wan, Qwen-Image) are excluded since they can't serve as the agent's LLM. The catalog therefore reflects the key's tier: a Token Plan key surfaces the multi-vendor set (Qwen, DeepSeek, GLM, Kimi, MiniMax), a pay-as-you-go key surfaces that account's Qwen line. The first-login default model is now `qwen3.7-plus` (falling back to the first available model when an endpoint doesn't offer it). The usage panel detects endpoints with no quota API and shows a clear note pointing to the Model Studio console alongside Pythinker's local token tally instead of probing a 404 quota endpoint. The built-in catalog remains the offline fallback when discovery is unavailable. For the Token Plan, whose usage policy forbids automated balance polling and exposes no quota API, `/usage` shows Pythinker's local token tally plus a note pointing to the Model Studio console (My Subscriptions / Usage Analysis) for the Credits balance.
- **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.
- **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.

Expand Down
Loading
Loading