claude-threads 1.14.0 → 1.15.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 +10 -0
- package/README.md +42 -31
- package/dist/index.js +370 -25
- package/dist/mcp/mcp-server.js +894 -38
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [1.15.0] - 2026-05-05
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- **Claude can DM channel members directly via the new `send_dm` MCP tool.** When the user asks for a private ping ("DM me when this finishes," "send the report to alice as a DM"), Claude can now call `send_dm(recipient, message)` instead of asking the user to forward the result themselves. The recipient is a Mattermost username (`@anne` or `anne`) or a Slack user id (`U…`/`<@U…>`) — the asymmetry exists because Slack bot tokens can't reverse-look usernames cheaply, and paginating `users.list` per call is wasteful. Six gates run in order: shape (recipient and message non-empty, message under 4000-char cap), recipient resolution (platform API turns the input into a user id + canonical username), self-DM guard, channel membership (recipient must be a current member of the bot channel, fetched once and cached for 60s), rate limit (3 DMs per recipient per session, optimistic counter increment with rollback on deny / timeout / send-error), and a per-recipient interactive permission prompt the first time the session DMs each user. ✅ promotes that recipient — and only that recipient — to no-prompt for the rest of the session; the rate limit still applies. An in-flight set blocks parallel `send_dm` calls to the same recipient from posting duplicate prompts when Claude fans out tool_use blocks in a single turn. Every DM is prefixed with an attribution line — `_(automated message via claude-threads, on behalf of @anne from #channel)_` — so recipients can trace it back to the session that sent it; the channel name is fetched lazily via the platform's channel-info endpoint, the session-owner username is plumbed in from `session.startedBy` through a new `SESSION_OWNER_USERNAME` env var that threads `lifecycle.ts` → `restart-options.ts` → `ClaudeCliOptions` → `buildPermissionArgs` → MCP child (covers all five `new ClaudeCli` sites). New optional `McpPlatformApi` methods `getChannelMembers`, `resolveRecipient`, `sendDirectMessage`; `getChannelInfo` gained a `name?` field. RED-GREEN tests on every load-bearing guard — self-DM check, membership, rate limit, attribution prefix, allow-all-is-per-recipient, counter rollback on deny / timeout, in-flight-prompt deduplication. (#374)
|
|
14
|
+
|
|
15
|
+
## [1.14.1] - 2026-05-05
|
|
16
|
+
|
|
17
|
+
### Fixed
|
|
18
|
+
- **`!update` no longer leaves an interactive bot dead.** The auto-restart path silently broke for users running in a terminal. PR #333 (April) skipped the bash daemon when stdout was a TTY, because the daemon's bash background-job pattern strips the TTY and forces headless mode, but the bot's `!update` flow assumed the daemon was always there to catch exit code 42 and re-exec. Without the daemon, `process.exit(42)` just exited. Install succeeded, sessions persisted, then nothing came back. The fix introduces a `decideRespawn()` step before the exit. When a known supervisor is present (`CLAUDE_THREADS_BIN` from the bash daemon, `pm_id` + `PM2_HOME` from pm2, `INVOCATION_ID` from systemd, `CLAUDE_THREADS_INTERACTIVE` from a TTY-managing wrapper) the bot still exits 42 and lets the supervisor handle the restart so its restart-counters and rate-limits keep working. Otherwise, when there is a TTY, the bot self-respawns. It synchronously resolves `claude-threads` on PATH (with a fallback to `~/.bun/bin` because cron / systemd / launchd `PATH=` is often missing it), then `spawn(binPath, argv, { detached: true, stdio: 'inherit', shell: process.platform === 'win32' })` followed by `unref()` and `exit(0)`. The Node docs cover this combination explicitly: when stdio is inherited, the detached child stays attached to the parent's controlling terminal, so the new process inherits the TUI cleanly. Several footguns are handled. `spawn()` does not throw on ENOENT, it returns a child with `pid === undefined` and fires the `error` event asynchronously, so we check `pid` synchronously instead of trusting a try/catch that never triggers. Bun passes `env: { X: undefined }` as the literal string `"undefined"` (Node correctly omits it), so the auto-restart hand-off vars are removed via `delete` rather than overwrite. Windows `.cmd` shims need `shell: true` since Node 20.12.2 (CVE-2024-27980). Ink's raw mode is reset before the spawn so the new child starts with a clean stdin. If self-respawn cannot launch (no `claude-threads` on PATH at all), the bot broadcasts a clear "could not auto-restart, please run `claude-threads`" message before exiting, so the user is not left wondering what happened. Four prior PRs (#287, #300, #317, #333) chased this in the daemon path. This one fixes the bot side instead. (#372)
|
|
19
|
+
|
|
10
20
|
## [1.14.0] - 2026-05-05
|
|
11
21
|
|
|
12
22
|
### Changed
|
package/README.md
CHANGED
|
@@ -20,20 +20,21 @@
|
|
|
20
20
|
|
|
21
21
|
**Bring Claude Code to your team.** Run Claude Code on your machine, share it live in Mattermost or Slack. Colleagues can watch, collaborate, and run their own sessions—all from chat.
|
|
22
22
|
|
|
23
|
-
>
|
|
23
|
+
> _Think of it as screen-sharing for AI pair programming, but everyone can type._
|
|
24
24
|
|
|
25
25
|
## Features
|
|
26
26
|
|
|
27
27
|
- **Real-time streaming** - Claude's responses stream live to chat
|
|
28
|
-
- **Multi-platform** - Connect to multiple Mattermost and Slack workspaces
|
|
29
|
-
- **Concurrent sessions** - Each thread gets its own Claude session
|
|
30
|
-
- **
|
|
31
|
-
- **Collaboration** - Invite others to participate in your session
|
|
28
|
+
- **Multi-platform** - Connect to multiple Mattermost and Slack workspaces simultaneously
|
|
29
|
+
- **Concurrent sessions** - Each thread gets its own Claude session, persisted across bot restarts
|
|
30
|
+
- **Collaboration** - `!invite` teammates to participate; they get added as `Co-Authored-By:` trailers on Claude's commits
|
|
32
31
|
- **Permission modes** - Three-way control over Claude's tool-use: `default` (every action prompts for 👍/✅/👎 approval via emoji), `auto` (Claude's classifier auto-approves low-risk; high-risk still prompts — recommended), or `bypass` (no prompts, all tools allowed). Set via config, `--permission-mode` CLI flag, or in-session with `!permissions default|auto|bypass`.
|
|
33
|
-
- **
|
|
34
|
-
- **
|
|
35
|
-
- **
|
|
32
|
+
- **Claude posts back to chat** - Claude can call `send_file` to drop screenshots, generated PDFs, plots, or audio directly into the thread, and `read_post` to follow a Mattermost or Slack permalink the user shares
|
|
33
|
+
- **Git worktrees** - Isolate Claude's changes in a branch with `!worktree feature/foo`; supports `list`, `switch`, `remove`, `cleanup`, `off`
|
|
34
|
+
- **File attachments** - Drop images, PDFs, archives, or any file into the chat; Claude reads them from disk via its own `Read`/Bash tools (100 MB cap)
|
|
35
|
+
- **Chrome automation** - Optional integration with Claude in Chrome for web tasks
|
|
36
36
|
- **Multi-account Claude (opt-in)** - Round-robin sessions across multiple Claude subscriptions or API keys with automatic rate-limit cooldown — see [Configuration](docs/CONFIGURATION.md#claude-accounts-optional-multi-account-mode)
|
|
37
|
+
- **Auto-update** - Bot checks npm for new versions and offers to restart; `!update now` / `!update defer` controls the timing
|
|
37
38
|
|
|
38
39
|
## Quick Start
|
|
39
40
|
|
|
@@ -50,6 +51,7 @@ claude-threads
|
|
|
50
51
|
```
|
|
51
52
|
|
|
52
53
|
The **interactive setup wizard** will guide you through everything:
|
|
54
|
+
|
|
53
55
|
- Configure Claude Code CLI (if needed)
|
|
54
56
|
- Set up your Mattermost or Slack bot
|
|
55
57
|
- Test credentials and permissions
|
|
@@ -74,46 +76,49 @@ Mention the bot in your chat:
|
|
|
74
76
|
|
|
75
77
|
Type `!help` in any session thread:
|
|
76
78
|
|
|
77
|
-
| Command
|
|
78
|
-
|
|
79
|
-
| `!help`
|
|
80
|
-
| `!
|
|
81
|
-
| `!
|
|
82
|
-
| `!
|
|
83
|
-
| `!
|
|
84
|
-
| `!
|
|
85
|
-
| `!
|
|
86
|
-
| `!
|
|
87
|
-
| `!
|
|
88
|
-
| `!
|
|
89
|
-
| `!
|
|
79
|
+
| Command | Description |
|
|
80
|
+
| :------------------------------------------ | :--------------------------------------------------------------------------------------- |
|
|
81
|
+
| `!help` | Show available commands |
|
|
82
|
+
| `!release-notes` | Show what changed in the running version |
|
|
83
|
+
| `!context` | Show context usage |
|
|
84
|
+
| `!cost` | Show token usage and cost |
|
|
85
|
+
| `!compact` | Compress context to free up space |
|
|
86
|
+
| `!cd <path>` | Change working directory (restarts Claude) |
|
|
87
|
+
| `!permissions <mode>` | Set permission mode: `default` / `auto` / `bypass` |
|
|
88
|
+
| `!worktree <branch>` | Create and switch to a git worktree (also: `list`, `switch`, `remove`, `cleanup`, `off`) |
|
|
89
|
+
| `!plugin <list\|install\|uninstall> [name]` | Manage Claude Code plugins (restarts Claude) |
|
|
90
|
+
| `!invite @user` | Invite a user to this session (added as `Co-Authored-By:` on commits) |
|
|
91
|
+
| `!kick @user` | Remove an invited user |
|
|
92
|
+
| `!github-email <email>` | Register your GitHub noreply email so `!invite` can attribute commits to you |
|
|
93
|
+
| `!update` | Show auto-update status (`!update now` / `!update defer`) |
|
|
94
|
+
| `!bug <desc>` | Report a bug with context (creates a GitHub issue) |
|
|
95
|
+
| `!approve` | Approve pending plan (alternative to 👍 reaction) |
|
|
96
|
+
| `!escape` | Interrupt current task (session stays active) |
|
|
97
|
+
| `!stop` | Stop this session |
|
|
98
|
+
| `!kill` | Emergency shutdown (kills ALL sessions and exits the bot) |
|
|
90
99
|
|
|
91
100
|
## Interactive Controls
|
|
92
101
|
|
|
93
102
|
**Permission approval** - When Claude wants to execute a tool:
|
|
103
|
+
|
|
94
104
|
- 👍 Allow this action
|
|
95
105
|
- ✅ Allow all future actions
|
|
96
106
|
- 👎 Deny
|
|
97
107
|
|
|
98
108
|
**Plan approval** - When Claude creates a plan:
|
|
109
|
+
|
|
99
110
|
- 👍 Approve and start
|
|
100
111
|
- 👎 Request changes
|
|
101
112
|
|
|
102
113
|
**Questions** - React with 1️⃣ 2️⃣ 3️⃣ 4️⃣ to answer multiple choice
|
|
103
114
|
|
|
104
|
-
**
|
|
115
|
+
**Session control** - ⏸️ to interrupt, ❌ or 🛑 to stop, ↩️ to resume a timed-out session
|
|
105
116
|
|
|
106
117
|
## File Attachments
|
|
107
118
|
|
|
108
|
-
|
|
119
|
+
Drop any file into the chat (image, PDF, archive, source, log, you name it). The bot saves it to a per-thread directory and prepends the path to your message; Claude reads it with its own `Read` tool (full multimodal for images and PDFs) or processes it via Bash. Single 100 MB cap per file. Need to extract a zip? Claude runs `unzip` itself.
|
|
109
120
|
|
|
110
|
-
|
|
111
|
-
|:-----|:--------|:---------|
|
|
112
|
-
| Images | JPEG, PNG, GIF, WebP | - |
|
|
113
|
-
| Documents | PDF | 32 MB |
|
|
114
|
-
| Text | .txt, .md, .json, .csv, .xml, .yaml, source code | 1 MB |
|
|
115
|
-
| Archives | .zip (auto-extracted, max 20 files) | 50 MB |
|
|
116
|
-
| Compressed | .gz (auto-decompressed) | - |
|
|
121
|
+
Going the other way, Claude can post files back into the thread (screenshots, generated PDFs, plots, MP3s) by calling the `send_file` MCP tool. Path is validated against the session working directory; auto-approved so the user doesn't have to 👍 every screenshot.
|
|
117
122
|
|
|
118
123
|
## Collaboration
|
|
119
124
|
|
|
@@ -122,7 +127,13 @@ Attach files to your messages for Claude to analyze:
|
|
|
122
127
|
!kick @colleague # Remove access
|
|
123
128
|
```
|
|
124
129
|
|
|
125
|
-
Unauthorized users can request message approval from the session owner.
|
|
130
|
+
Unauthorized users can request message approval from the session owner with a 👍 reaction.
|
|
131
|
+
|
|
132
|
+
Invited collaborators are added as `Co-Authored-By:` trailers on any commits Claude makes during the session. Each collaborator runs `!github-email <their-noreply-address>` once (find yours at <https://github.com/settings/emails>) and the bot remembers it across sessions.
|
|
133
|
+
|
|
134
|
+
## Sharing Links With Claude
|
|
135
|
+
|
|
136
|
+
Paste a Mattermost or Slack permalink in the thread and Claude can resolve it to the post body (and optional thread context) via the `read_post` MCP tool, instead of asking you to copy-paste. Auto-approved; scoped to channels the bot can already see.
|
|
126
137
|
|
|
127
138
|
## Git Worktrees
|
|
128
139
|
|