claude-threads 1.7.1 → 1.8.1
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 +15 -0
- package/dist/index.js +32 -15
- package/dist/mcp/permission-server.js +20 -14
- package/docs/CONFIGURATION.md +13 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,21 @@ 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.8.1] - 2026-04-21
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
- **Interactive users silently demoted to headless when `autoUpdate` was enabled** — the auto-restart daemon runs the child as a bash background job (`&`), which leaves stdout piped and stdin detached. Ink can't render there, so the TUI dropped out without any error. Three prior patches (#287, #300, #317) each fixed the active crash mode inside the daemon path; none questioned whether interactive users should be routed through the daemon at all. The daemon is now skipped when `process.stdout.isTTY` and `--headless` isn't set. Unattended paths (explicit `--auto-restart`, `--headless`, or no TTY) still go through the daemon. (#333)
|
|
12
|
+
|
|
13
|
+
## [1.8.0] - 2026-04-21
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
- **Pass `MCP_CONNECTION_NONBLOCKING=true` to the Claude child** — caps `--mcp-config` connects at 5s so a slow MCP server never delays session startup. Requires Claude CLI 2.1.89+. Set it explicitly in the bot's own env to override.
|
|
17
|
+
- **Pass `ENABLE_PROMPT_CACHING_1H=true` to the Claude child** — opts into the 1-hour prompt cache TTL, meaningfully reducing re-caching cost on long-lived threads that idle past the default 5-minute window. Requires Claude CLI 2.1.108+. Set it explicitly in the bot's own env to override.
|
|
18
|
+
- **Documented `CLAUDE_CODE_SUBPROCESS_ENV_SCRUB=1`** as an opt-in hardening flag. When set on the bot's env it passes through to Claude, which strips the specific credential env vars `ANTHROPIC_API_KEY`, `ANTHROPIC_AUTH_TOKEN`, `CLAUDE_CODE_OAUTH_TOKEN`, `AWS_SECRET_ACCESS_KEY`, `AWS_SESSION_TOKEN`, `AWS_BEARER_TOKEN_BEDROCK`, and `GOOGLE_APPLICATION_CREDENTIALS` from any Bash, hook, or stdio MCP subprocess it spawns (empirically verified on CLI 2.1.116). Bot-specific vars like `PLATFORM_TOKEN` / `MATTERMOST_TOKEN` / `SLACK_BOT_TOKEN` pass through untouched. **Side effect:** the flag also forces Claude's permission mode to `default` and rejects `--dangerously-skip-permissions`; the bot now warns at startup if the flag is set alongside any platform configured with `skipPermissions: true`. Requires Claude CLI 2.1.83+.
|
|
19
|
+
|
|
20
|
+
### Fixed
|
|
21
|
+
- **Stale Claude CLI version range in `CLAUDE.md`** — the docs said `>=2.0.74 <=2.0.76`, but the actual pin in `version-check.ts` has been `>=2.0.74 <2.2.0` since v1.x. Also bumped the "install a compatible version" hint in the runtime error from `@2.1.1` to `@2.1.116`.
|
|
22
|
+
|
|
8
23
|
## [1.7.1] - 2026-04-21
|
|
9
24
|
|
|
10
25
|
### Fixed
|
package/dist/index.js
CHANGED
|
@@ -50038,7 +50038,7 @@ function validateClaudeCli() {
|
|
|
50038
50038
|
version: result.version,
|
|
50039
50039
|
compatible: false,
|
|
50040
50040
|
message: `Claude CLI version ${result.version} is not compatible. Required: ${CLAUDE_CLI_VERSION_RANGE}
|
|
50041
|
-
` + `Install a compatible version: npm install -g @anthropic-ai/claude-code@2.1.
|
|
50041
|
+
` + `Install a compatible version: npm install -g @anthropic-ai/claude-code@2.1.116`,
|
|
50042
50042
|
rawOutput: result.rawOutput ?? undefined
|
|
50043
50043
|
};
|
|
50044
50044
|
}
|
|
@@ -54260,6 +54260,25 @@ function cleanupBrowserBridgeSockets() {
|
|
|
54260
54260
|
log10.debug(`Browser bridge cleanup failed: ${err}`);
|
|
54261
54261
|
}
|
|
54262
54262
|
}
|
|
54263
|
+
function buildClaudeChildEnv(parentEnv, account) {
|
|
54264
|
+
const env = { ...parentEnv };
|
|
54265
|
+
if (env.MCP_CONNECTION_NONBLOCKING === undefined) {
|
|
54266
|
+
env.MCP_CONNECTION_NONBLOCKING = "true";
|
|
54267
|
+
}
|
|
54268
|
+
if (env.ENABLE_PROMPT_CACHING_1H === undefined) {
|
|
54269
|
+
env.ENABLE_PROMPT_CACHING_1H = "true";
|
|
54270
|
+
}
|
|
54271
|
+
if (account?.home) {
|
|
54272
|
+
env.HOME = account.home;
|
|
54273
|
+
env.USERPROFILE = account.home;
|
|
54274
|
+
delete env.ANTHROPIC_API_KEY;
|
|
54275
|
+
delete env.CLAUDE_CODE_OAUTH_TOKEN;
|
|
54276
|
+
} else if (account?.apiKey) {
|
|
54277
|
+
env.ANTHROPIC_API_KEY = account.apiKey;
|
|
54278
|
+
delete env.CLAUDE_CODE_OAUTH_TOKEN;
|
|
54279
|
+
}
|
|
54280
|
+
return env;
|
|
54281
|
+
}
|
|
54263
54282
|
function isErrorResultEvent(event) {
|
|
54264
54283
|
const ev = event;
|
|
54265
54284
|
if (typeof ev.subtype === "string" && ev.subtype.startsWith("error"))
|
|
@@ -54561,20 +54580,7 @@ class ClaudeCli extends EventEmitter2 {
|
|
|
54561
54580
|
return true;
|
|
54562
54581
|
}
|
|
54563
54582
|
buildChildEnv() {
|
|
54564
|
-
|
|
54565
|
-
if (!account)
|
|
54566
|
-
return process.env;
|
|
54567
|
-
const env = { ...process.env };
|
|
54568
|
-
if (account.home) {
|
|
54569
|
-
env.HOME = account.home;
|
|
54570
|
-
env.USERPROFILE = account.home;
|
|
54571
|
-
delete env.ANTHROPIC_API_KEY;
|
|
54572
|
-
delete env.CLAUDE_CODE_OAUTH_TOKEN;
|
|
54573
|
-
} else if (account.apiKey) {
|
|
54574
|
-
env.ANTHROPIC_API_KEY = account.apiKey;
|
|
54575
|
-
delete env.CLAUDE_CODE_OAUTH_TOKEN;
|
|
54576
|
-
}
|
|
54577
|
-
return env;
|
|
54583
|
+
return buildClaudeChildEnv(process.env, this.options.account);
|
|
54578
54584
|
}
|
|
54579
54585
|
getMcpServerPath() {
|
|
54580
54586
|
const __filename2 = fileURLToPath3(import.meta.url);
|
|
@@ -79894,6 +79900,8 @@ async function main() {
|
|
|
79894
79900
|
return false;
|
|
79895
79901
|
if (opts.autoRestart === true)
|
|
79896
79902
|
return true;
|
|
79903
|
+
if (!isHeadless && process.stdout.isTTY)
|
|
79904
|
+
return false;
|
|
79897
79905
|
if (await configExists()) {
|
|
79898
79906
|
try {
|
|
79899
79907
|
const config = loadConfigWithMigration();
|
|
@@ -80005,6 +80013,15 @@ async function startWithoutDaemon() {
|
|
|
80005
80013
|
console.error("");
|
|
80006
80014
|
process.exit(1);
|
|
80007
80015
|
}
|
|
80016
|
+
if (process.env.CLAUDE_CODE_SUBPROCESS_ENV_SCRUB === "1") {
|
|
80017
|
+
const hasSkipPermissionPlatform = config.platforms.some((p) => p.skipPermissions === true);
|
|
80018
|
+
if (hasSkipPermissionPlatform) {
|
|
80019
|
+
console.error(red(" ⚠️ CLAUDE_CODE_SUBPROCESS_ENV_SCRUB=1 is set but a platform has skipPermissions: true."));
|
|
80020
|
+
console.error(dim(" Claude CLI will force permissionMode: default and reject --dangerously-skip-permissions."));
|
|
80021
|
+
console.error(dim(" Either unset the env var or set skipPermissions: false on all platforms."));
|
|
80022
|
+
console.error("");
|
|
80023
|
+
}
|
|
80024
|
+
}
|
|
80008
80025
|
let triggerShutdown = null;
|
|
80009
80026
|
const updateState = loadUpdateState();
|
|
80010
80027
|
const restoredSettings = updateState.justUpdated ? updateState.runtimeSettings : undefined;
|
|
@@ -53584,6 +53584,25 @@ function cleanupBrowserBridgeSockets() {
|
|
|
53584
53584
|
log7.debug(`Browser bridge cleanup failed: ${err}`);
|
|
53585
53585
|
}
|
|
53586
53586
|
}
|
|
53587
|
+
function buildClaudeChildEnv(parentEnv, account) {
|
|
53588
|
+
const env = { ...parentEnv };
|
|
53589
|
+
if (env.MCP_CONNECTION_NONBLOCKING === undefined) {
|
|
53590
|
+
env.MCP_CONNECTION_NONBLOCKING = "true";
|
|
53591
|
+
}
|
|
53592
|
+
if (env.ENABLE_PROMPT_CACHING_1H === undefined) {
|
|
53593
|
+
env.ENABLE_PROMPT_CACHING_1H = "true";
|
|
53594
|
+
}
|
|
53595
|
+
if (account?.home) {
|
|
53596
|
+
env.HOME = account.home;
|
|
53597
|
+
env.USERPROFILE = account.home;
|
|
53598
|
+
delete env.ANTHROPIC_API_KEY;
|
|
53599
|
+
delete env.CLAUDE_CODE_OAUTH_TOKEN;
|
|
53600
|
+
} else if (account?.apiKey) {
|
|
53601
|
+
env.ANTHROPIC_API_KEY = account.apiKey;
|
|
53602
|
+
delete env.CLAUDE_CODE_OAUTH_TOKEN;
|
|
53603
|
+
}
|
|
53604
|
+
return env;
|
|
53605
|
+
}
|
|
53587
53606
|
function isErrorResultEvent(event) {
|
|
53588
53607
|
const ev = event;
|
|
53589
53608
|
if (typeof ev.subtype === "string" && ev.subtype.startsWith("error"))
|
|
@@ -53885,20 +53904,7 @@ class ClaudeCli extends EventEmitter2 {
|
|
|
53885
53904
|
return true;
|
|
53886
53905
|
}
|
|
53887
53906
|
buildChildEnv() {
|
|
53888
|
-
|
|
53889
|
-
if (!account)
|
|
53890
|
-
return process.env;
|
|
53891
|
-
const env = { ...process.env };
|
|
53892
|
-
if (account.home) {
|
|
53893
|
-
env.HOME = account.home;
|
|
53894
|
-
env.USERPROFILE = account.home;
|
|
53895
|
-
delete env.ANTHROPIC_API_KEY;
|
|
53896
|
-
delete env.CLAUDE_CODE_OAUTH_TOKEN;
|
|
53897
|
-
} else if (account.apiKey) {
|
|
53898
|
-
env.ANTHROPIC_API_KEY = account.apiKey;
|
|
53899
|
-
delete env.CLAUDE_CODE_OAUTH_TOKEN;
|
|
53900
|
-
}
|
|
53901
|
-
return env;
|
|
53907
|
+
return buildClaudeChildEnv(process.env, this.options.account);
|
|
53902
53908
|
}
|
|
53903
53909
|
getMcpServerPath() {
|
|
53904
53910
|
const __filename2 = fileURLToPath3(import.meta.url);
|
package/docs/CONFIGURATION.md
CHANGED
|
@@ -107,6 +107,19 @@ Exactly one of `home` or `apiKey` should be set per account. Persisted sessions
|
|
|
107
107
|
| `SESSION_TIMEOUT_MS` | Idle timeout in milliseconds | `1800000` (30 min) |
|
|
108
108
|
| `NO_UPDATE_NOTIFIER` | Disable update checks | - |
|
|
109
109
|
| `DEBUG` | Enable verbose logging | - |
|
|
110
|
+
| `CLAUDE_CODE_SUBPROCESS_ENV_SCRUB` | Strip `ANTHROPIC_*` / `AWS_*_TOKEN` / `CLAUDE_CODE_OAUTH_TOKEN` / `GOOGLE_APPLICATION_CREDENTIALS` etc. from Bash, hook, and stdio-MCP subprocesses Claude spawns. Bot-specific vars like `PLATFORM_TOKEN` pass through. **Also forces permission mode to `default`** — `--dangerously-skip-permissions` will be rejected. Requires Claude CLI 2.1.83+. | - |
|
|
111
|
+
|
|
112
|
+
### Forwarded to Claude CLI automatically
|
|
113
|
+
|
|
114
|
+
The bot sets two tuning flags on the Claude child process when they aren't
|
|
115
|
+
already present in the bot's environment:
|
|
116
|
+
|
|
117
|
+
| Variable | Effect | Requires |
|
|
118
|
+
|----------|--------|----------|
|
|
119
|
+
| `MCP_CONNECTION_NONBLOCKING=true` | Caps `--mcp-config` connects at 5s so a slow MCP server never delays startup | Claude CLI 2.1.89+ |
|
|
120
|
+
| `ENABLE_PROMPT_CACHING_1H=true` | Opts into 1-hour prompt cache TTL, cutting re-caching cost on long-lived threads | Claude CLI 2.1.108+ |
|
|
121
|
+
|
|
122
|
+
Export either with a different value in the bot's own env to disable.
|
|
110
123
|
|
|
111
124
|
## CLI Options
|
|
112
125
|
|