From 5af452a5dbced4236ea3a237efc3fab047fdcceb Mon Sep 17 00:00:00 2001 From: fylorn <249551762+fylorn@users.noreply.github.com> Date: Fri, 16 Oct 2026 16:33:07 +0800 Subject: [PATCH 1/2] Plugin template: edit req in place and use tw.appendSystem The new-plugin template now relies on core's plugin helpers: changes to req take effect without returning it, and tw.appendSystem adds the note to the end of the system prompt (skipping it when already present). Co-Authored-By: Claude Opus 5.5 --- src/plugins/Editor.i18n.ts | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/src/plugins/Editor.i18n.ts b/src/plugins/Editor.i18n.ts index 87bc6d0d..7a2ee7c5 100644 --- a/src/plugins/Editor.i18n.ts +++ b/src/plugins/Editor.i18n.ts @@ -41,13 +41,11 @@ export const editorText = messages( ' settings: { note: { type: "string", label: "附加内容", value: "" } },', "};", "", - "// 请求发往上游之前调用:req.system 为系统提示词,ctx.settings 为设置项的值。", - "// 返回修改后的 req;返回 undefined 表示不修改。", + "// 请求发往上游之前调用:修改 req 即生效,ctx.settings 为设置项的值。", + "// tw 提供常用的改写函数,例如 tw.appendSystem 在系统提示词末尾附加一段文字。", "export function onRequest(req, ctx) {", ' const note = String(ctx.settings.note ?? "").trim();', - ' if (note === "" || req.system.includes(note)) return undefined;', - ' req.system = req.system ? req.system + "\\n\\n" + note : note;', - " return req;", + ' if (note !== "") tw.appendSystem(req, note);', "}", ]), @@ -117,14 +115,12 @@ export const editorText = messages( ' settings: { note: { type: "string", label: "Note", value: "" } },', "};", "", - "// Runs before a request goes to the upstream: req.system is the system prompt, and", - "// ctx.settings holds the values of the settings. Return the changed req, or undefined", - "// to leave the request unchanged.", + "// Runs before a request goes to the upstream: changes to req take effect, and", + "// ctx.settings holds the values of the settings. tw provides common edits, such as", + "// tw.appendSystem, which adds text to the end of the system prompt.", "export function onRequest(req, ctx) {", ' const note = String(ctx.settings.note ?? "").trim();', - ' if (note === "" || req.system.includes(note)) return undefined;', - ' req.system = req.system ? req.system + "\\n\\n" + note : note;', - " return req;", + ' if (note !== "") tw.appendSystem(req, note);', "}", ]), From f5d9f43a61d582df507084f3d9efdac2dc12c190 Mon Sep 17 00:00:00 2001 From: fylorn <249551762+fylorn@users.noreply.github.com> Date: Fri, 16 Oct 2026 19:37:19 +0800 Subject: [PATCH 2/2] 2026.10.22: pin core v0.75.0; release notes and version Core 0.75.0 adds plugin helpers and in-place edits, checks every choice of an answer for dangerous commands, and fixes reply plugins on split placeholders, skipped plugins and answers with several choices. Protocol 48 and the request store schema are unchanged. Co-Authored-By: Claude Opus 5.5 --- package.json | 2 +- release-notes/2026.10.22.md | 18 ++++++++++++++ src-tauri/Cargo.lock | 48 ++++++++++++++++++------------------- src-tauri/Cargo.toml | 14 +++++------ src-tauri/tauri.conf.json | 2 +- 5 files changed, 51 insertions(+), 33 deletions(-) create mode 100644 release-notes/2026.10.22.md diff --git a/package.json b/package.json index 4b901342..7be70c9d 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "thinkwatch-lite", "private": true, "description": "Desktop app for a local AI API gateway on macOS, Windows and Linux", - "version": "2026.10.21", + "version": "2026.10.22", "type": "module", "packageManager": "pnpm@11.13.0", "scripts": { diff --git a/release-notes/2026.10.22.md b/release-notes/2026.10.22.md new file mode 100644 index 00000000..3278ee0b --- /dev/null +++ b/release-notes/2026.10.22.md @@ -0,0 +1,18 @@ +**Upgrade notes:** +- The bundled core is now 0.75.0. The control-plane protocol stays at 48, so remote servers on core 0.74.0 keep working. +- Nothing is cleared; the request history, stored payloads and settings carry over. +- Plugins: changes a hook makes to the request or tool call it receives now take effect without returning it. Before, they were dropped unless the hook returned the object. The two built-in plugins are updated unless their code was edited. + +**Security:** +- The dangerous-command check now looks at every choice of a streamed Chat Completions answer and every candidate of a Gemini answer, not only the first. An upstream could otherwise get a tool call past the check by placing it in a second choice, or by spreading its arguments across two choices. +- In a streamed answer with several choices, placeholders are restored in each choice separately; the choices could get mixed before. + +**Plugins:** +- Plugins have a global `tw` with helpers for common edits: `tw.appendSystem`, `tw.texts`, `tw.toolCalls`, `tw.mapStrings`, `tw.replace`, `tw.streamReplace`, `tw.lines` and `tw.pairs`. `tw.streamReplace` replaces text in streamed answers, including a match that spans two pieces of the stream. The template for a new plugin uses them. See the Plugins page of the documentation. +- A stream-mode plugin that held back text and cut a placeholder in two left the placeholder in the answer instead of the original value. This is fixed. +- A stream-mode plugin that failed and was skipped could lose or reorder the text it was holding. This is fixed. +- In answers with several choices, plugins keep each choice apart, and every choice of a non-streamed answer goes through them. +- A stream-mode plugin that only holds text back, without changing it, is no longer recorded as having changed the answer. + +**Other:** +- rustls 0.23.46 (RUSTSEC-2026-0346 to -0349). diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 3a0f23db..fe443e82 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -82,7 +82,7 @@ dependencies = [ "objc2-foundation", "parking_lot", "percent-encoding", - "windows-sys 0.60.2", + "windows-sys 0.52.0", "wl-clipboard-rs", "x11rb", ] @@ -985,7 +985,7 @@ dependencies = [ "libc", "option-ext", "redox_users 0.5.3", - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -1171,7 +1171,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] @@ -2661,7 +2661,7 @@ version = "0.50.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -2996,7 +2996,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7d8fae84b431384b68627d0f9b3b1245fcf9f46f6c0e3dc902e9dce64edd1967" dependencies = [ "libc", - "windows-sys 0.61.2", + "windows-sys 0.45.0", ] [[package]] @@ -3625,7 +3625,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys", - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] @@ -3681,7 +3681,7 @@ dependencies = [ "security-framework", "security-framework-sys", "webpki-root-certs", - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] @@ -4809,7 +4809,7 @@ dependencies = [ "getrandom 0.4.3", "once_cell", "rustix", - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] @@ -4832,7 +4832,7 @@ dependencies = [ [[package]] name = "thinkwatch-lite" -version = "2026.10.21" +version = "2026.10.22" dependencies = [ "anyhow", "block2", @@ -5335,8 +5335,8 @@ dependencies = [ [[package]] name = "tw-api" -version = "0.74.0" -source = "git+https://github.com/ThinkWatchProject/ThinkWatch-Core.git?tag=v0.74.0#21e560cdfa0cb197d1688b329b18123547ce1d8f" +version = "0.75.0" +source = "git+https://github.com/ThinkWatchProject/ThinkWatch-Core.git?tag=v0.75.0#f040a92a2d509d24c21e8a460e25f6cd3db2cd39" dependencies = [ "serde", "serde_json", @@ -5347,8 +5347,8 @@ dependencies = [ [[package]] name = "tw-dialect" -version = "0.74.0" -source = "git+https://github.com/ThinkWatchProject/ThinkWatch-Core.git?tag=v0.74.0#21e560cdfa0cb197d1688b329b18123547ce1d8f" +version = "0.75.0" +source = "git+https://github.com/ThinkWatchProject/ThinkWatch-Core.git?tag=v0.75.0#f040a92a2d509d24c21e8a460e25f6cd3db2cd39" dependencies = [ "memchr", "serde", @@ -5357,8 +5357,8 @@ dependencies = [ [[package]] name = "tw-guard" -version = "0.74.0" -source = "git+https://github.com/ThinkWatchProject/ThinkWatch-Core.git?tag=v0.74.0#21e560cdfa0cb197d1688b329b18123547ce1d8f" +version = "0.75.0" +source = "git+https://github.com/ThinkWatchProject/ThinkWatch-Core.git?tag=v0.75.0#f040a92a2d509d24c21e8a460e25f6cd3db2cd39" dependencies = [ "aho-corasick", "base64 0.22.1", @@ -5376,8 +5376,8 @@ dependencies = [ [[package]] name = "tw-link" -version = "0.74.0" -source = "git+https://github.com/ThinkWatchProject/ThinkWatch-Core.git?tag=v0.74.0#21e560cdfa0cb197d1688b329b18123547ce1d8f" +version = "0.75.0" +source = "git+https://github.com/ThinkWatchProject/ThinkWatch-Core.git?tag=v0.75.0#f040a92a2d509d24c21e8a460e25f6cd3db2cd39" dependencies = [ "serde", "serde_json", @@ -5403,8 +5403,8 @@ dependencies = [ [[package]] name = "tw-types" -version = "0.74.0" -source = "git+https://github.com/ThinkWatchProject/ThinkWatch-Core.git?tag=v0.74.0#21e560cdfa0cb197d1688b329b18123547ce1d8f" +version = "0.75.0" +source = "git+https://github.com/ThinkWatchProject/ThinkWatch-Core.git?tag=v0.75.0#f040a92a2d509d24c21e8a460e25f6cd3db2cd39" dependencies = [ "serde", "ts-rs", @@ -5412,8 +5412,8 @@ dependencies = [ [[package]] name = "tw-watch" -version = "0.74.0" -source = "git+https://github.com/ThinkWatchProject/ThinkWatch-Core.git?tag=v0.74.0#21e560cdfa0cb197d1688b329b18123547ce1d8f" +version = "0.75.0" +source = "git+https://github.com/ThinkWatchProject/ThinkWatch-Core.git?tag=v0.75.0#f040a92a2d509d24c21e8a460e25f6cd3db2cd39" dependencies = [ "libc", "notify", @@ -5423,8 +5423,8 @@ dependencies = [ [[package]] name = "tw-yaml" -version = "0.74.0" -source = "git+https://github.com/ThinkWatchProject/ThinkWatch-Core.git?tag=v0.74.0#21e560cdfa0cb197d1688b329b18123547ce1d8f" +version = "0.75.0" +source = "git+https://github.com/ThinkWatchProject/ThinkWatch-Core.git?tag=v0.75.0#f040a92a2d509d24c21e8a460e25f6cd3db2cd39" dependencies = [ "saphyr-parser", "thiserror 2.0.21", @@ -5888,7 +5888,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 84641a32..0a269a20 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "thinkwatch-lite" -version = "2026.10.21" +version = "2026.10.22" edition = "2024" # **这个数决定依赖能升到哪一版。**edition 2024 的解析器只挑声明的 Rust # 版本编得动的依赖:写 1.85 的时候,`cargo update` 一直停在旧的 time 和 @@ -26,12 +26,12 @@ license = "MIT" # twcore 二进制必须和这里编译进去的协议镜像来自同一个 core 版本 —— 打包脚本正是 # 从 tw-api 锁到的 tag 去取二进制的(见 scripts/fetch-core.sh)。 [workspace.dependencies] -tw-api = { git = "https://github.com/ThinkWatchProject/ThinkWatch-Core.git", tag = "v0.74.0" } -tw-types = { git = "https://github.com/ThinkWatchProject/ThinkWatch-Core.git", tag = "v0.74.0" } -tw-yaml = { git = "https://github.com/ThinkWatchProject/ThinkWatch-Core.git", tag = "v0.74.0" } -tw-guard = { git = "https://github.com/ThinkWatchProject/ThinkWatch-Core.git", tag = "v0.74.0" } -tw-watch = { git = "https://github.com/ThinkWatchProject/ThinkWatch-Core.git", tag = "v0.74.0" } -tw-link = { git = "https://github.com/ThinkWatchProject/ThinkWatch-Core.git", tag = "v0.74.0" } +tw-api = { git = "https://github.com/ThinkWatchProject/ThinkWatch-Core.git", tag = "v0.75.0" } +tw-types = { git = "https://github.com/ThinkWatchProject/ThinkWatch-Core.git", tag = "v0.75.0" } +tw-yaml = { git = "https://github.com/ThinkWatchProject/ThinkWatch-Core.git", tag = "v0.75.0" } +tw-guard = { git = "https://github.com/ThinkWatchProject/ThinkWatch-Core.git", tag = "v0.75.0" } +tw-watch = { git = "https://github.com/ThinkWatchProject/ThinkWatch-Core.git", tag = "v0.75.0" } +tw-link = { git = "https://github.com/ThinkWatchProject/ThinkWatch-Core.git", tag = "v0.75.0" } [lib] name = "thinkwatch_lite_lib" diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index bf04a9c0..7843a828 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -1,7 +1,7 @@ { "$schema": "https://schema.tauri.app/config/2", "productName": "ThinkWatch Lite", - "version": "2026.10.21", + "version": "2026.10.22", "identifier": "app.thinkwatch.lite", "build": { "beforeDevCommand": "pnpm dev",