claude-threads 1.23.0 → 1.24.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 +9 -0
- package/dist/index.js +36 -15
- package/dist/mcp/mcp-server.js +19 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,15 @@ 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.24.0] - 2026-08-08
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- **`!model` and `!effort` — switch model or reasoning effort mid-session.** Verified against the real CLI (2.1.226): `/model` and `/effort` work over stream-json (`/model` with no args lists the options; `/model sonnet` switches "for this session only"; `/effort low|medium|high|xhigh|max|auto`), and both are listed in the CLI's `init.slash_commands` — so the bot's dynamic slash-command passthrough forwards `!model sonnet` / `!effort high` as-is and the CLI's confirmation posts to the thread. Both are now first-class registered commands with unconditional forwarding handlers (like `!context`/`!cost`/`!compact` — they work even before the CLI's init event arrives, and forward their argument: `!model sonnet` → `/model sonnet`), and `!help` gained a line pointing out that Claude Code slash commands work with `!`.
|
|
12
|
+
- **The session header now shows the model the session actually runs on.** Previously the header picked the "primary model" by highest cumulative cost — after a `!model` switch the old model keeps the larger spend, so the header kept naming the old model indefinitely. The per-turn `init.model` (re-emitted every turn, per the reference captures) is now authoritative. Model display names also cover the Claude 5 family via generic id parsing (`claude-sonnet-5` → "Sonnet 5", `claude-fable-5` → "Fable 5", dated ids still render as before).
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
- **Latest verified Claude CLI: 2.1.226** (from 2.1.223). The full verification battery ran against it this cycle: the decision-bridge e2e (4/4), all 17 reference captures re-recorded on 2.1.225/2.1.226, and both integration matrices. Install hints updated. Also verified while probing: `/cd` and `/add-dir` report "isn't available in this environment" over stream-json on 2.1.226 — a native in-session directory switch isn't possible, so `!cd` keeps its restart-based implementation.
|
|
16
|
+
|
|
8
17
|
## [1.23.0] - 2026-08-08
|
|
9
18
|
|
|
10
19
|
### Fixed
|
package/dist/index.js
CHANGED
|
@@ -51319,7 +51319,7 @@ var COMMON_CLAUDE_PATHS = process.platform === "win32" ? [
|
|
|
51319
51319
|
var CLAUDE_CLI_MIN_VERSION = "2.0.74";
|
|
51320
51320
|
var CLAUDE_CLI_VERIFIED_RANGE = ">=2.0.74 <2.2.0";
|
|
51321
51321
|
var CLAUDE_CLI_SUPPORTED_MAJOR = 2;
|
|
51322
|
-
var CLAUDE_CLI_LATEST_VERIFIED = "2.1.
|
|
51322
|
+
var CLAUDE_CLI_LATEST_VERIFIED = "2.1.226";
|
|
51323
51323
|
function tryClaudeVersion(claudePath) {
|
|
51324
51324
|
try {
|
|
51325
51325
|
const output = execSync(`"${claudePath}" --version`, {
|
|
@@ -57560,6 +57560,18 @@ var COMMAND_REGISTRY = [
|
|
|
57560
57560
|
description: "Compact conversation",
|
|
57561
57561
|
category: "passthrough",
|
|
57562
57562
|
audience: "both"
|
|
57563
|
+
},
|
|
57564
|
+
{
|
|
57565
|
+
command: "model",
|
|
57566
|
+
description: "Show or switch the model for this session (e.g. !model sonnet)",
|
|
57567
|
+
category: "passthrough",
|
|
57568
|
+
audience: "both"
|
|
57569
|
+
},
|
|
57570
|
+
{
|
|
57571
|
+
command: "effort",
|
|
57572
|
+
description: "Set reasoning effort: low|medium|high|xhigh|max|auto (e.g. !effort high)",
|
|
57573
|
+
category: "passthrough",
|
|
57574
|
+
audience: "both"
|
|
57563
57575
|
}
|
|
57564
57576
|
];
|
|
57565
57577
|
var REACTION_REGISTRY = [
|
|
@@ -57617,6 +57629,8 @@ var COMMAND_PATTERNS = [
|
|
|
57617
57629
|
["context", /^!context\s*$/i],
|
|
57618
57630
|
["cost", /^!cost\s*$/i],
|
|
57619
57631
|
["compact", /^!compact\s*$/i],
|
|
57632
|
+
["model", /^!model(?:\s+(\S+))?\s*$/i],
|
|
57633
|
+
["effort", /^!effort(?:\s+(\S+))?\s*$/i],
|
|
57620
57634
|
["plugin", /^!plugin(?:\s+(.+))?$/i],
|
|
57621
57635
|
["kill", /^!kill\s*$/i],
|
|
57622
57636
|
["bug", /^!bug(?:\s+(.+))?$/i],
|
|
@@ -57741,6 +57755,8 @@ ${formatter.formatBold("Reactions:")}
|
|
|
57741
57755
|
` + `${formatter.formatListItem(approvalReactions)}
|
|
57742
57756
|
` + `${formatter.formatListItem(sessionReactions)}
|
|
57743
57757
|
|
|
57758
|
+
` + `Claude Code slash commands work with ${code("!")} too — e.g. ${code("!model sonnet")}, ${code("!effort high")}, ${code("!compact")}, ${code("!context")}.
|
|
57759
|
+
|
|
57744
57760
|
` + formatSponsorFooter(formatter);
|
|
57745
57761
|
}
|
|
57746
57762
|
|
|
@@ -58122,12 +58138,13 @@ var handlePlugin = async (ctx, args) => {
|
|
|
58122
58138
|
return { handled: true };
|
|
58123
58139
|
};
|
|
58124
58140
|
function createPassthroughHandler(slashCommand) {
|
|
58125
|
-
return async (ctx) => {
|
|
58141
|
+
return async (ctx, args) => {
|
|
58126
58142
|
if (ctx.commandContext === "first-message") {
|
|
58127
58143
|
return { handled: false };
|
|
58128
58144
|
}
|
|
58129
58145
|
if (ctx.isAllowed) {
|
|
58130
|
-
|
|
58146
|
+
const full = args ? `/${slashCommand} ${args}` : `/${slashCommand}`;
|
|
58147
|
+
await ctx.sessionManager.sendFollowUp(ctx.threadId, full, undefined, undefined, undefined, { system: true });
|
|
58131
58148
|
}
|
|
58132
58149
|
return { handled: true };
|
|
58133
58150
|
};
|
|
@@ -58150,6 +58167,8 @@ handlers.set("plugin", handlePlugin);
|
|
|
58150
58167
|
handlers.set("context", createPassthroughHandler("context"));
|
|
58151
58168
|
handlers.set("cost", createPassthroughHandler("cost"));
|
|
58152
58169
|
handlers.set("compact", createPassthroughHandler("compact"));
|
|
58170
|
+
handlers.set("model", createPassthroughHandler("model"));
|
|
58171
|
+
handlers.set("effort", createPassthroughHandler("effort"));
|
|
58153
58172
|
async function executeCommand(command, args, ctx) {
|
|
58154
58173
|
const cmdDef = getCommandDef(command);
|
|
58155
58174
|
if (!cmdDef) {
|
|
@@ -68841,6 +68860,9 @@ function handleEventPreProcessing(session, event, ctx) {
|
|
|
68841
68860
|
}
|
|
68842
68861
|
if (event.type === "system") {
|
|
68843
68862
|
const e = event;
|
|
68863
|
+
if (e.subtype === "init" && typeof e.model === "string") {
|
|
68864
|
+
session.currentModel = e.model;
|
|
68865
|
+
}
|
|
68844
68866
|
if (e.subtype === "init" && e.slash_commands && Array.isArray(e.slash_commands)) {
|
|
68845
68867
|
session.availableSlashCommands = new Set(e.slash_commands.map((cmd) => cmd.startsWith("/") ? cmd.slice(1) : cmd));
|
|
68846
68868
|
sessionLog3(session).info(`Captured ${session.availableSlashCommands.size} slash commands from init: ${[...session.availableSlashCommands].join(", ")}`);
|
|
@@ -68975,20 +68997,15 @@ async function handleCompactionComplete(session, compactMetadata, _ctx) {
|
|
|
68975
68997
|
}
|
|
68976
68998
|
}
|
|
68977
68999
|
function getModelDisplayName(modelId) {
|
|
68978
|
-
|
|
68979
|
-
|
|
68980
|
-
|
|
68981
|
-
return
|
|
68982
|
-
|
|
68983
|
-
return "Opus";
|
|
68984
|
-
if (modelId.includes("sonnet-4"))
|
|
68985
|
-
return "Sonnet 4";
|
|
68986
|
-
if (modelId.includes("sonnet-3-5") || modelId.includes("sonnet-3.5"))
|
|
68987
|
-
return "Sonnet 3.5";
|
|
69000
|
+
const modern = modelId.match(/^claude-([a-z]+)-(\d+)(?:-(\d{1,2}))?(?:-\d{8})?$/);
|
|
69001
|
+
if (modern) {
|
|
69002
|
+
const family = modern[1].charAt(0).toUpperCase() + modern[1].slice(1);
|
|
69003
|
+
return modern[3] ? `${family} ${modern[2]}.${modern[3]}` : `${family} ${modern[2]}`;
|
|
69004
|
+
}
|
|
68988
69005
|
if (modelId.includes("sonnet"))
|
|
68989
69006
|
return "Sonnet";
|
|
68990
|
-
if (modelId.includes("
|
|
68991
|
-
return "
|
|
69007
|
+
if (modelId.includes("opus"))
|
|
69008
|
+
return "Opus";
|
|
68992
69009
|
if (modelId.includes("haiku"))
|
|
68993
69010
|
return "Haiku";
|
|
68994
69011
|
const match = modelId.match(/claude-(\w+)/);
|
|
@@ -69019,6 +69036,10 @@ function updateUsageStats(session, event, ctx) {
|
|
|
69019
69036
|
contextWindowSize = usage.contextWindow;
|
|
69020
69037
|
}
|
|
69021
69038
|
}
|
|
69039
|
+
if (session.currentModel && result.modelUsage[session.currentModel]) {
|
|
69040
|
+
primaryModel = session.currentModel;
|
|
69041
|
+
contextWindowSize = result.modelUsage[session.currentModel].contextWindow;
|
|
69042
|
+
}
|
|
69022
69043
|
let contextTokens = 0;
|
|
69023
69044
|
if (result.usage) {
|
|
69024
69045
|
contextTokens = result.usage.input_tokens + result.usage.cache_creation_input_tokens + result.usage.cache_read_input_tokens;
|
package/dist/mcp/mcp-server.js
CHANGED
|
@@ -56734,6 +56734,18 @@ var COMMAND_REGISTRY = [
|
|
|
56734
56734
|
description: "Compact conversation",
|
|
56735
56735
|
category: "passthrough",
|
|
56736
56736
|
audience: "both"
|
|
56737
|
+
},
|
|
56738
|
+
{
|
|
56739
|
+
command: "model",
|
|
56740
|
+
description: "Show or switch the model for this session (e.g. !model sonnet)",
|
|
56741
|
+
category: "passthrough",
|
|
56742
|
+
audience: "both"
|
|
56743
|
+
},
|
|
56744
|
+
{
|
|
56745
|
+
command: "effort",
|
|
56746
|
+
description: "Set reasoning effort: low|medium|high|xhigh|max|auto (e.g. !effort high)",
|
|
56747
|
+
category: "passthrough",
|
|
56748
|
+
audience: "both"
|
|
56737
56749
|
}
|
|
56738
56750
|
];
|
|
56739
56751
|
var REACTION_REGISTRY = [
|
|
@@ -56806,6 +56818,8 @@ ${formatter.formatBold("Reactions:")}
|
|
|
56806
56818
|
` + `${formatter.formatListItem(approvalReactions)}
|
|
56807
56819
|
` + `${formatter.formatListItem(sessionReactions)}
|
|
56808
56820
|
|
|
56821
|
+
` + `Claude Code slash commands work with ${code("!")} too — e.g. ${code("!model sonnet")}, ${code("!effort high")}, ${code("!compact")}, ${code("!context")}.
|
|
56822
|
+
|
|
56809
56823
|
` + formatSponsorFooter(formatter);
|
|
56810
56824
|
}
|
|
56811
56825
|
|
|
@@ -57072,12 +57086,13 @@ var handlePlugin = async (ctx, args) => {
|
|
|
57072
57086
|
return { handled: true };
|
|
57073
57087
|
};
|
|
57074
57088
|
function createPassthroughHandler(slashCommand) {
|
|
57075
|
-
return async (ctx) => {
|
|
57089
|
+
return async (ctx, args) => {
|
|
57076
57090
|
if (ctx.commandContext === "first-message") {
|
|
57077
57091
|
return { handled: false };
|
|
57078
57092
|
}
|
|
57079
57093
|
if (ctx.isAllowed) {
|
|
57080
|
-
|
|
57094
|
+
const full = args ? `/${slashCommand} ${args}` : `/${slashCommand}`;
|
|
57095
|
+
await ctx.sessionManager.sendFollowUp(ctx.threadId, full, undefined, undefined, undefined, { system: true });
|
|
57081
57096
|
}
|
|
57082
57097
|
return { handled: true };
|
|
57083
57098
|
};
|
|
@@ -57100,6 +57115,8 @@ handlers.set("plugin", handlePlugin);
|
|
|
57100
57115
|
handlers.set("context", createPassthroughHandler("context"));
|
|
57101
57116
|
handlers.set("cost", createPassthroughHandler("cost"));
|
|
57102
57117
|
handlers.set("compact", createPassthroughHandler("compact"));
|
|
57118
|
+
handlers.set("model", createPassthroughHandler("model"));
|
|
57119
|
+
handlers.set("effort", createPassthroughHandler("effort"));
|
|
57103
57120
|
// src/commands/system-prompt-generator.ts
|
|
57104
57121
|
var log9 = createLogger("system-prompt");
|
|
57105
57122
|
function formatUserCommand(cmd) {
|
package/package.json
CHANGED