claude-threads 1.21.1 → 1.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,18 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [1.22.0] - 2026-08-08
9
+
10
+ ### Changed
11
+ - **A newer Claude CLI no longer takes the bot down — the version check is now a three-tier policy.** Previously the single hard range `>=2.0.74 <2.2.0` meant that the day Anthropic ships CLI 2.2.0, every bot whose CLI auto-updates would refuse to start until a claude-threads release widened the range — the worst failure mode for a bot people depend on. Now: below the floor (`2.0.74`) or on a new major (3.x+) the bot still exits with an error (those genuinely can't work / are a different contract); but a **newer 2.x above the verified range starts normally with a visible warning** — at startup, in the terminal header, and as an "⚠️ untested" marker next to the CLI version in the sticky channel message and session headers. `--skip-version-check` still bypasses the hard exits, and a bypassed hard exit is no longer silent either: the bot warns at startup and marks the version "⚠️ unsupported" in the same places. Onboarding speaks the same policy (warn-and-continue on untested, tier-specific messages on the hard tiers). The verified range (latest verified: 2.1.223) is unchanged; when a new CLI minor ships, it gets verified and the range bumped in a patch release — the warning is the prompt to do that, not a permanent state.
12
+
13
+ ## [1.21.2] - 2026-08-07
14
+
15
+ ### Added
16
+ - **Decision bridge: plan approvals and question answers now flow through one surface.** On modern Claude CLIs (verified 2.1.223), `ExitPlanMode` and `AskUserQuestion` block on the MCP permission prompt — making it the authoritative gate — while the rich UI (plan post with 👍/👎, question posts with option reactions) lives in the main bot. Users saw two competing prompts, and reacting only on the bot's UI let the MCP prompt time out into a plan denial. The bot now opens a per-session local socket (a named pipe on Windows); the MCP server forwards plan/question permission requests over it and waits (default 1h, `DECISION_BRIDGE_TIMEOUT_MS`), and the user's reaction on the bot's existing UI resolves them: plans as allow/deny, question answers riding back in the permission response's `updatedInput.answers` — the CLI then tells Claude "Your questions have been answered" / "User has approved your plan" itself (both verified against the real CLI end-to-end, including through the real built `mcp-server.js`). The stdin sends (`'approved'`/answer JSON) are suppressed when a bridge request consumed the decision, and remain as the fallback for older CLIs that don't route these tools through the permission prompt. The bridge degrades gracefully everywhere: creation failure, connect failure, or timeout falls back to the previous behavior (generic prompt for plans, auto-allow for questions). The bridge is session-scoped — it survives `!cd`/`!permissions` respawns and closes with the session; pending decisions are denied on session end or fresh-CLI restart so the MCP child is never stranded. A manual real-CLI verification script ships in `tests/e2e-real-cli/decision-bridge-e2e.ts` (not run in CI — needs live credentials).
17
+ - **Decision-bridge hardening (from two adversarial review rounds over this change).** `!approve`/`!yes` resolves a pending bridge request instead of sending a stdin message that would queue behind the blocked permission call (previously it converted an approval into an hour-long hang). The bridge server aborts the bot-side pending when the requesting MCP client disconnects (timeout, cancelled tool call, dead child), so a stale pending can never swallow the user's later reaction — it falls back to stdin instead. Claude respawns deny pending decisions unconditionally (the MCP child always dies, resume or not; previously only fresh-session respawns did). The bridge socket lives in a fresh `0700` directory (other local users can't connect regardless of umask) with a short path (safe against macOS's 104-byte `sun_path` truncation), and is closed on every teardown path including start/resume failures. multiSelect questions bypass the bridge (single-select answer format is the only one verified against the real CLI) and take the legacy path. Operator knob `DECISION_BRIDGE_TIMEOUT_MS` is now actually forwarded to the MCP child.
18
+ - **The CLI is spawned with `MCP_TOOL_TIMEOUT=3600000` when a decision bridge is configured.** Delayed-decision testing against the real CLI (2.1.223) showed it abandons a pending MCP permission call after ~2 minutes — one retry, then an error — silently capping how long a plan approval or question answer could wait, regardless of the bridge's 1-hour window. With the flag set, decisions held for 150 seconds complete end-to-end (verified empirically); 1 hour matches the bridge's `DECISION_BRIDGE_TIMEOUT_MS` default, and setting `MCP_TOOL_TIMEOUT` in the bot's own env overrides it, like the other forwarded tuning flags. Should the CLI still give up (older CLI, operator override), the bridge's disconnect-abort clears the bot-side pending state so the user's late reaction falls back to the stdin flow instead of being swallowed.
19
+
8
20
  ## [1.21.1] - 2026-08-07
9
21
 
10
22
  ### Fixed