claude-threads 1.29.0 → 1.30.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 +52 -0
- package/dist/index.js +3157 -2790
- package/dist/mcp/mcp-server.js +890 -753
- package/docs/CONFIGURATION.md +21 -0
- package/docs/MCP-TOOLS.md +45 -0
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,58 @@ 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.30.0] - 2026-08-28
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- **Agent tools — Claude can now use the bot's own features from inside a session.** Six new MCP tools, executed in the bot process over the session's decision bridge:
|
|
12
|
+
- `remember_fact` saves one durable team fact to channel memory with a new `agent` provenance label. No approval prompt (the end-of-session distiller already writes ungated) — instead every save is **announced in the thread**, audit-logged, capped at 5 per session, and can never displace a user-written entry (supersede/dedupe/eviction rank agent entries with distilled ones). `list_memory` lists what's stored.
|
|
13
|
+
- `propose_routine` / `propose_watch` post the **existing confirmation card** (badged "Claude proposes…") and save **nothing** — only a human 👍 persists the routine/watch, which is then owned by the session owner like a hand-typed one. `list_routines` / `list_watches` are read-only.
|
|
14
|
+
- **Loop prevention:** sessions started by routine/watch fires are marked `unattended` (persisted across restarts); such sessions cannot propose new routines or watches **or write channel memory** — the tools aren't offered there, and the bot refuses regardless (a prompt-injected fire must not seed future sessions' context).
|
|
15
|
+
- **Approval is owner-gated for agent proposals:** an `!invite`d guest can react on the card, but only the session owner or a platform-allowlisted user may decide it — an unauthorized reaction is refused *without consuming the proposal* (and warned about once, not per toggle), so a guest can neither approve nor veto. Card text Claude authors is collapsed to a single line so it cannot restyle the approval card, and a proposal never displaces a pending human confirmation.
|
|
16
|
+
- Tool availability follows the platform's `memory`/`routines`/`watches` config (advisory env gates on the MCP child; authoritative re-checks in the bot). Destructive operations (forget, pause, delete, manual run) are never exposed to Claude.
|
|
17
|
+
|
|
18
|
+
### Fixed
|
|
19
|
+
- **Bot-to-bot loops are broken at every link (#491).** Two claude-threads bots on one server could lock into an unbounded refusal loop (observed in the wild: 1,941 messages in 37 minutes) because the "not authorized to resume" refusal @-mentioned the bot it was refusing. Three independent fixes, any one of which stops that incident: refusals render the refused user as inline code instead of an @-mention (reads the same, notifies nobody); refusals are rate-limited to once per (thread, user) per 5 minutes instead of once per message; and claude-threads now recognizes another instance's own status posts (refusals, timeout/idle notices, cancellations, emergency shutdowns, resume announcements) and never treats them as a request — even when they carry a mention. A human message that merely starts with one of the status emojis still gets through. Thanks to @theprsi for the excellent incident analysis.
|
|
20
|
+
- A signal death of the Claude process (exit code `null`) can no longer be labeled `exit:null` on the registry-removal path — it's a clean end like code 0, matching every sibling teardown site. (Independently found by @Jadefalkner.)
|
|
21
|
+
|
|
22
|
+
### Security
|
|
23
|
+
- **Watch prefilter keywords are collapsed to single-line** before rendering into the human-approval card — an embedded newline could otherwise smuggle multi-line markdown past the card's single-line guard (second-pass review follow-up to the agent tools).
|
|
24
|
+
- **The decision bridge drops connections that stream more than 1MB without a newline** instead of buffering indefinitely — closes the cheapest local memory-exhaustion path against the bot process.
|
|
25
|
+
- The single-line sanitizers (memory entries, agent card text, watch keywords) now also collapse U+0085 (NEL), which JS `\s` does not cover.
|
|
26
|
+
|
|
27
|
+
## [1.29.3] - 2026-08-28
|
|
28
|
+
|
|
29
|
+
Re-release of 1.29.2 — no code changes. The 1.29.2 npm publish failed the same
|
|
30
|
+
way as 1.29.1 (npm masked-auth E404): the NPM_TOKEN repository secret had
|
|
31
|
+
expired. The token has been rotated and this version ships what 1.29.2 was
|
|
32
|
+
meant to ship, plus the release.yml retry fix (#496).
|
|
33
|
+
|
|
34
|
+
## [1.29.2] - 2026-08-24
|
|
35
|
+
|
|
36
|
+
Re-release of 1.29.1 — no code changes. The 1.29.1 npm publish step failed
|
|
37
|
+
(the registry rejected the publish with npm's masked-auth E404); the v1.29.1
|
|
38
|
+
tag and GitHub release exist, but the package never reached npm. This version
|
|
39
|
+
re-runs the publish.
|
|
40
|
+
|
|
41
|
+
## [1.29.1] - 2026-08-24
|
|
42
|
+
|
|
43
|
+
### Fixed
|
|
44
|
+
- **DCM: a channel message addressed to another user no longer starts a session.** With no session running, `@bob did you deploy?` in a direct-channel-mode channel used to start a full Claude session in a human-to-human exchange — the side-conversation guard the active/paused paths already had now covers the new-session path too.
|
|
45
|
+
- **The side-conversation guard now works on Slack.** Slack delivers mentions as raw `<@U0…>` tokens (labeled `<@U0…|name>` included), never `@name`, so the guard (active sessions, paused sessions, and the new DCM path) silently never matched there — every human-to-human aside in a session thread was fed to Claude as a follow-up. A message that *also* @mentions the bot still reaches Claude (it explicitly asks the bot), and on Mattermost a literal `<@…>` token stays ordinary text.
|
|
46
|
+
- **DCM: non-allowlisted members no longer trigger an unauthorized-warning post per message.** The warning now only fires on an explicit @mention — previously every message from a non-allowlisted member produced channel spam, and two bots could warn at each other in a loop on Mattermost.
|
|
47
|
+
- **`!watches` works in direct channel mode again** — only *creation* is refused there; watches that predate a switch to DCM stay listable/pausable/deletable (matches routines).
|
|
48
|
+
- **Slack thread history keeps the newest messages for arbitrarily long threads** — the pagination walk now retains a sliding window instead of stopping after 10 pages with the oldest content, and the truncation warning is honest about what was dropped.
|
|
49
|
+
- **Audit trail: routine/watch creation confirmations now record the user whose reaction decided them** (the requester is carried in the detail) — matching how plan approvals are attributed.
|
|
50
|
+
- **sessions.json and the GitHub-emails store can no longer be wiped by a transient read failure.** Every mutation is a read-modify-write; when the existing file cannot be read faithfully (corruption, EMFILE), reads degrade to empty but writes now refuse — previously the next persist atomically replaced the file with the degraded empty view, destroying every paused session across all platforms. A parseable file that merely lacks the collection key (e.g. a bare `{}`) provably holds nothing and stays writable — as does a zero-length or whitespace-only file, so a crashed first write can never leave a store permanently read-only.
|
|
51
|
+
- Mattermost thread history resolves usernames only for the messages the limit keeps (matches the Slack client).
|
|
52
|
+
- **Slack MCP tools now normalize literal Unicode emoji to shortcodes** for `react_to_post` and interactive-post reactions — `reactions.add` rejects raw 👍; the client path already normalized, the MCP path was the odd one out.
|
|
53
|
+
- **Worktree commands honor `approvals: owner`.** `!worktree` create/switch/remove/cleanup and worktree-prompt disabling now go through the same owner gate as every other owner-gated command: under owner-scoped approvals a platform-allowlisted non-participant could previously switch the session's working directory.
|
|
54
|
+
- **All haiku one-shots (routine/watch parses, watch confirms, memory distillation) now resolve the claude binary like sessions do** — `quickQuery` used a bare `claude` from PATH while sessions fall back to common install locations, so on some hosts sessions worked while every one-shot silently failed.
|
|
55
|
+
|
|
56
|
+
### Changed
|
|
57
|
+
- Internal restructuring after three feature waves: the user-commands module splits by domain (guards/memory/automation), lifecycle sheds the out-of-band metadata-suggestions domain into its own module, and the last two stores (sessions, GitHub emails) migrate onto the shared atomic-write primitives.
|
|
58
|
+
- A wide DRY + dead-code sweep (net −800 lines): shared WebSocket close/permalink formatting/post-list rendering/limit clamping across the platform and MCP layers, one canonical legacy-allowlist helper for the six hand-copied authorization fallbacks, nine MCP tool registrations collapsed into one helper, ~380 lines of dead test helpers deleted, and the client test files adopt the shared fetch harness.
|
|
59
|
+
|
|
8
60
|
## [1.29.0] - 2026-08-24
|
|
9
61
|
|
|
10
62
|
### Added
|