Skip to content

Commit 64ad091

Browse files
dreamrecclaude
andauthored
release: 2.1.4 — Codex P1/P2 follow-ups on v2.1.3 (PR #28) (#29)
Two reliability holes the automated Codex review caught right after v2.1.3 merged. Both are real edge-case bugs in the v2.1.3 fixes themselves; this release closes them. Fixes ----- - P1 — drain inbox queue on EV_ERROR, not just EV_DONE. v2.1.3's FIFO inbox queue (comp.storage["tdpilot_api_chat_inbox"]) drained one entry per EV_DONE, but failed turns emit EV_ERROR without calling _drain_inbox_one(). Queued messages after an errored turn sat in storage indefinitely until a later successful turn happened to fire EV_DONE. Fix in td_component/tdpilot_api_extension.py::_handle_event. - P2 — safety net for the send-button gate when WS drops. v2.1.3 moved the send-button re-enable from the /send fetch resolution onto the WebSocket-driven setAgentStatus() call. If the WS dropped between /send and the terminal status event, awaitingTurnEnd stayed true and the button was permanently disabled. Fix in td_component/tdpilot_api_chat.html: * 90s safety timer (TURN_END_SAFETY_MS) — hard cap on the gate. * ws.onopen reset — every reconnect clears awaitingTurnEnd. If the runtime is genuinely still busy, the next status event re-disables; if the user fires a message while busy, the v2.1.3 FIFO inbox catches it. * Centralised clearAwaitingTurnEnd() helper so future call sites can't forget to clear the timer. Tests ----- 7 new structural assertions in tests/test_v214_codex_followups.py that pin both fixes against future refactors. Pytest 1680 → 1687, 0 failures. Both .tox binaries rebuilt; all 7 version manifests + API_VERSION in callbacks/_header.py at v2.1.4. ruff format + check clean. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent ca548fa commit 64ad091

22 files changed

Lines changed: 310 additions & 28 deletions

.claude-plugin/marketplace.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
{
1111
"name": "tdpilot-dpsk4",
1212
"description": "AI copilot for TouchDesigner with live MCP control (DeepSeek v4 optimized) \u2014 103 tools, focus + locations, hint injection, component notes, POPx inspection, knowledge corpus, project lifecycle, custom parameter authoring, snapshots, undo-block safety, and typed patch sessions. Works with Claude Desktop, Claude Code (DeepSeek v4 backend), and any MCP-compatible client.",
13-
"version": "2.1.3",
13+
"version": "2.1.4",
1414
"author": {
1515
"name": "silviu"
1616
},

.claude-plugin/plugin.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "tdpilot-dpsk4",
3-
"version": "2.1.3",
3+
"version": "2.1.4",
44
"description": "TDPilot DPSK4 \u2014 AI copilot for TouchDesigner (DeepSeek v4 optimized). 103 MCP tools for live node graph control, parameter management, diagnostics, safety, streaming, knowledge corpus, focus + locations, hint injection, component notes, technique memory, and typed patch sessions.",
55
"author": {
66
"name": "silviu"

CHANGELOG.md

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,54 @@
11
# Changelog
22

3+
## 2.1.4 - 2026-05-10
4+
5+
**Patch: Codex review follow-ups on v2.1.3 (PR #28).** Two real
6+
reliability holes that the automated Codex bot caught right after
7+
v2.1.3 merged.
8+
9+
### Fixes
10+
11+
- **P1 — drain inbox queue on `EV_ERROR`**, not just `EV_DONE`.
12+
v2.1.3 added a FIFO inbox queue on `comp.storage` so messages
13+
that arrive while a turn is in flight aren't lost. The queue
14+
drained one entry per `EV_DONE`, but failed turns emit
15+
`EV_ERROR` (and `EV_STATE: idle`) without calling
16+
`_drain_inbox_one()`. So a queued message after an errored turn
17+
sat in storage indefinitely until a later successful turn
18+
happened to fire `EV_DONE`. Fix in
19+
`td_component/tdpilot_api_extension.py::_handle_event`
20+
`EV_ERROR` now drains too. Tests:
21+
`tests/test_v214_codex_followups.py::test_p1_*`.
22+
- **P2 — safety net for the send-button gate when WS drops.**
23+
v2.1.3 moved the send-button re-enable from the `/send` fetch
24+
resolution onto the WebSocket-driven `setAgentStatus()` call.
25+
If the WS dropped between `/send` and the terminal status
26+
event, `awaitingTurnEnd` stayed `true` and the button was
27+
permanently disabled — the user was locked out of the chat
28+
until they reloaded the page. Fix in
29+
`td_component/tdpilot_api_chat.html`:
30+
- **90s safety timer** (`TURN_END_SAFETY_MS`) — a hard cap on
31+
how long the gate can pin the button. If the timer fires
32+
before a status event arrives, the button re-enables and the
33+
UI surfaces "idle (timeout)".
34+
- **`ws.onopen` reset** — every reconnect clears
35+
`awaitingTurnEnd` so a turn that was in flight when the WS
36+
dropped doesn't keep the button locked. If the runtime is
37+
genuinely still busy, the next status event re-disables;
38+
if the user fires a message while the runtime is busy, the
39+
v2.1.3 FIFO inbox queue catches it (no message lost).
40+
- Centralised `clearAwaitingTurnEnd()` helper — resets the
41+
flag, the timer, AND the button's `disabled` attribute in
42+
one call so future call sites can't forget the timer.
43+
Tests: `tests/test_v214_codex_followups.py::test_p2_*`.
44+
45+
### Context
46+
47+
Both bugs were caught by [Codex's automated review on PR #28](https://github.com/dreamrec/TDPilot_deepseekv4/pull/28).
48+
Both were graded P1/P2 by the bot and both are real — the
49+
v2.1.3 fixes regressed reliability on edge paths that the new
50+
queue + gate introduced. v2.1.4 closes them.
51+
352
## 2.1.3 - 2026-05-09
453

554
**Security hardening + chat-pipe queue + path harmonization for

README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
╚═╝ ╚═════╝ ╚═╝ ╚═╝╚══════╝ ╚═════╝ ╚═╝
88
```
99

10-
# TDPilot — DeepSeek v4 · v2.1.3
10+
# TDPilot — DeepSeek v4 · v2.1.4
1111

1212
[![CI](https://github.com/dreamrec/TDPilot_deepseekv4/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/dreamrec/TDPilot_deepseekv4/actions/workflows/ci.yml)
1313
[![npm](https://img.shields.io/npm/v/tdpilot-dpsk4?label=npm)](https://www.npmjs.com/package/tdpilot-dpsk4)
@@ -20,7 +20,7 @@
2020

2121
An AI assistant that lives inside TouchDesigner. It can inspect your network, build new operators, wire them up, debug errors, take screenshots, remember things between sessions, replay successful patterns, surface relevant memories before each turn, batch tool calls, recover from failures with actionable hints, and survive long conversations via context compaction.
2222

23-
> **v2.1.3 just shipped (May 9, 2026)**security hardening + chat-pipe queue + path harmonization. CSRF / drive-by RCE chain in `tdpilot_API.tox` closed (origin gate now enforced even in `TDPILOT_API_INSECURE` mode; `EXEC_MODE=full` clamped to `restricted` when insecure-mode is on; `/send` requires `application/json` to force CORS preflight). Rapid-`/send` message-drop bug fixed via FIFO inbox queue; chat HTML disables send button until the runtime emits turn-end. Storage moved under `~/.tdpilot-dpsk4/api/` with transparent legacy `~/.tdpilot-api/` fallback. See [What's new since v1.5.x](#whats-new-since-v15x) below for the full timeline, or [CHANGELOG](CHANGELOG.md#213---2026-05-09) for the v2.1.3 details.
23+
> **v2.1.4 just shipped (May 10, 2026)**patch on top of v2.1.3 closing two reliability holes that Codex's automated review caught on PR #28. The new inbox queue now drains on `EV_ERROR` (not just `EV_DONE`) so a queued message after a failed turn doesn't sit in storage forever. The chat HTML's send-button gate now has a 90s safety timer + a `ws.onopen` reset so a dropped WS connection mid-turn no longer locks the user out of the chat. See [CHANGELOG](CHANGELOG.md#214---2026-05-10) for the v2.1.4 details, or [v2.1.3 below](#whats-new-since-v15x) for the underlying security/queue/path-harmonization release.
2424
2525
There are two ways to run it. Pick whichever fits — they coexist in the same TD project if you want both.
2626

@@ -210,10 +210,11 @@ The standalone has 91 tools that cover the everyday inspect → build → wire
210210

211211
## What's new since v1.5.x
212212

213-
The line from v1.5.0 (Apr 25, 2026) to v2.1.3 (May 9, 2026) shipped in tight bursts. Most important updates, newest first:
213+
The line from v1.5.0 (Apr 25, 2026) to v2.1.4 (May 10, 2026) shipped in tight bursts. Most important updates, newest first:
214214

215215
| Version | Date | Headline |
216216
|---|---|---|
217+
| **v2.1.4** | May 10 | **Codex follow-ups on v2.1.3.** Two reliability holes the automated Codex review caught on PR #28: (P1) the new inbox queue now drains on `EV_ERROR` too — pre-2.1.4 a queued message after an errored turn sat in storage forever until a later successful turn happened to fire `EV_DONE`; (P2) the chat HTML's send-button gate now has a 90s safety timer + a `ws.onopen` reset, so a dropped WS connection between `/send` and the terminal status event no longer locks the user out of the chat permanently. |
217218
| **v2.1.3** | May 9 | **Security hardening + chat-pipe queue + path harmonization.** Audit found a CSRF / drive-by RCE chain in `tdpilot_API.tox` (insecure-mode bypassed origin checks AND `EXEC_MODE=full` was hardcoded). Closed by always-on origin enforcement (insecure-mode bypasses only the token check), `EXEC_MODE` clamp to `restricted` whenever insecure-mode is active (opt back into full with `TDPILOT_API_ALLOW_INSECURE_FULL_EXEC=1`), `application/json` requirement on `/send` (forces CORS preflight for cross-origin POSTs), and a loud textport banner when insecure-mode is on. Rapid-`/send` message-drop bug fixed via FIFO inbox queue on `comp.storage` + chat HTML send-button gate on the runtime's turn-end signal (not on the fetch resolution). Chat-pipe storage namespaced under `~/.tdpilot-dpsk4/api/` with `~/.tdpilot-api/` legacy fallback in `resolve_user_dir`. |
218219
| **v2.1.2** | May 9 | **Opt-in MCP auth.** `autostart.onStart()` no longer wipes persistent secrets; `TDPILOT_DISABLE_AUTH_BYPASS=1` opts into the env-file-driven shared-secret flow. |
219220
| **v2.1.1** | May 9 | **Paused-TD UX trap + recovery hints + chat red mark.** `start_turn` now warns when `me.time.play=False` so a paused TD doesn't look like the agent is wedged on 60s tool-call timeouts. 4 new `recovery_hints` (`td.Par.rawVal`, renderTOP attr typos, `tdu.Matrix.translation`, `ParCollection.children`) harvested from a 184-message lighting-redesign turn. User messages in the chat now render with a high-contrast white-on-red `[USER]` stamp + thick red rule + red gradient. Parallel CI freshness gate added for `tdpilot_API.tox` so it can no longer silently go stale. |

docs/MANUAL.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# TDPilot v2.1.3 Manual
1+
# TDPilot v2.1.4 Manual
22

33
The full reference. Read the [README](../README.md) first if you haven't installed yet — this manual assumes you've got either the standalone .tox or the Claude Code plugin running.
44

mcp/manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"schema_version": 1,
33
"name": "TDPilot DPSK4",
44
"slug": "tdpilot-dpsk4",
5-
"version": "2.1.3",
5+
"version": "2.1.4",
66
"repository": "https://github.com/dreamrec/TDPilot_deepseekv4",
77
"description": "MCP server for TouchDesigner (DeepSeek v4 optimized) with live graph control, diagnostics, safety, streaming, knowledge corpus, technique memory, and typed patch sessions.",
88
"entrypoints": {

npm/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# TDPilot v2.1.3
1+
# TDPilot v2.1.4
22

33
[![CI](https://github.com/dreamrec/TDPilot_deepseekv4/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/dreamrec/TDPilot_deepseekv4/actions/workflows/ci.yml)
44
[![npm](https://img.shields.io/npm/v/tdpilot-dpsk4?label=npm)](https://www.npmjs.com/package/tdpilot-dpsk4)

npm/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "tdpilot-dpsk4",
3-
"version": "2.1.3",
3+
"version": "2.1.4",
44
"description": "AI copilot for TouchDesigner with live MCP control (DeepSeek v4 optimized) \u2014 103 tools, focus + locations, hint injection, component notes, POPx inspection, knowledge corpus, project lifecycle control, technique memory, typed patch sessions.",
55
"keywords": [
66
"touchdesigner",

plugin_README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# TDPilot v2.1.3 — TouchDesigner AI Assistant Plugin
1+
# TDPilot v2.1.4 — TouchDesigner AI Assistant Plugin
22

33
This plugin installs the **DPSK4 (Claude Code CLI) variant** of TDPilot.
44
Two variants ship in the same repo:
@@ -12,7 +12,7 @@ For the standalone .tox path, see the [main README](https://github.com/dreamrec/
1212

1313
---
1414

15-
TDPilot v2.1.3 provides 103 MCP tools for live control of TouchDesigner projects from Claude Code, optimized for DeepSeek v4. The bundled `.tox` includes a one-button installer (drag-drop into TD, click "Bootstrap All", done) — no manual setup script.
15+
TDPilot v2.1.4 provides 103 MCP tools for live control of TouchDesigner projects from Claude Code, optimized for DeepSeek v4. The bundled `.tox` includes a one-button installer (drag-drop into TD, click "Bootstrap All", done) — no manual setup script.
1616

1717
## Components
1818

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "tdpilot-dpsk4"
3-
version = "2.1.3"
3+
version = "2.1.4"
44
description = "MCP server for live control of TouchDesigner — create, inspect, connect, and manipulate nodes via AI agents"
55
readme = "README.md"
66
license = "MIT"

0 commit comments

Comments
 (0)