claude-threads 1.35.1 → 1.36.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 +16 -0
- package/README.md +13 -0
- package/dist/index.js +995 -536
- package/dist/mcp/mcp-server.js +715 -278
- package/docs/CONFIGURATION.md +45 -0
- package/package.json +4 -3
package/docs/CONFIGURATION.md
CHANGED
|
@@ -54,11 +54,13 @@ platforms:
|
|
|
54
54
|
| `respondOnlyWhenMentioned` | Start new threads in quiet mode, where the bot only replies to messages that @mention it. Users can still toggle per-thread with `!mentions`. | `false` |
|
|
55
55
|
| `userAttribution` | Prefix each user turn sent to Claude with the sender's `[@username]:` so Claude can tell who is speaking in multi-user threads. Only applied once a thread has more than one participant (after `!invite`); solo threads are left untouched. Set `false` to disable. Applies to new sessions. | `true` |
|
|
56
56
|
| `keepAlive` | Prevent system sleep while sessions are active | `true` |
|
|
57
|
+
| `bugReports` | Whether `!bug` may file a report. ⚠️ A bug report leaves your infrastructure: attached screenshots are uploaded to a public anonymous file host, and the report body — session context plus recent daemon log lines — is filed as an issue on the project's public GitHub repository, behind best-effort redaction. Claude can also invoke `!bug` itself. Set `false` and the whole path is removed: the command is refused, Claude cannot invoke it either, the 🐛 error reaction does nothing, the approval that would file the issue is refused, and `!bug` disappears from `!help`. **Fails closed** — a malformed value disables it rather than defaulting to on. | `true` |
|
|
57
58
|
| `limits` | Resource limits and timeouts (see below) | see below |
|
|
58
59
|
| `threadLogs` | Thread logging (see below) | enabled |
|
|
59
60
|
| `stickyMessage` | Sticky message text customization (see below) | none |
|
|
60
61
|
| `claudeAccounts` | Multi-account pool (see below) | single-account mode |
|
|
61
62
|
| `mcpServers` | MCP servers every platform's sessions get, on top of the bot's own (see [MCP servers and claude.ai connectors](#mcp-servers-and-claudeai-connectors-claudeaiconnectors-mcpservers-strictmcpconfig)) | none |
|
|
63
|
+
| `usage.showEmails` | Print each seat's login email in `!usage` output | `false` |
|
|
62
64
|
|
|
63
65
|
### Resource Limits (`limits`)
|
|
64
66
|
|
|
@@ -172,6 +174,7 @@ What happens: every `audio/*` attachment (or a file with an audio extension when
|
|
|
172
174
|
| `directChannelMode` | No | Direct channel mode: the whole channel is one session, and the bot replies with top-level channel posts instead of thread replies. `true` for defaults, or an options object (`respondTo`). See [Direct Channel Mode](#direct-channel-mode). |
|
|
173
175
|
| `approvals` | No | Who may answer tool-permission prompts and other reaction gates: `owner` (session participants) or `all_users` (everyone on `allowedUsers`). Unset keeps the historical default per mode — `all_users` for thread sessions, `owner` for direct channel mode. See [Approvals](#approvals). |
|
|
174
176
|
| `ackReaction` | No | Read receipt: react to every accepted message (session start, follow-up, resume) the instant it is accepted, before Claude produces output. `true` uses 👀 (`eyes`), a string names a custom emoji. Persistent, unlike the typing indicator — useful in busy channels and for messages queued behind an in-flight session start. The receipt means *accepted*, not *delivered*: a later failure (capacity limit, Claude not coming up) is still reported by its own post. `!commands` are not acked — they have their own immediate feedback, and neither are messages accepted through the message-approval flow (an authorized user approving a non-participant's message) — there the approval reaction is already the visible signal. Note: in direct channel mode this is one reaction API call per accepted message. Default off. |
|
|
177
|
+
| `reconnectPolicy` | No | What happens when reconnection attempts run out: `retry` (default — log, cool down 60s, reset the counter and keep trying; recovers with no supervisor) or `exit` (leave through the graceful shutdown path and exit non-zero, for `Restart=always` deployments). The bot never stays alive with a dead socket either way. |
|
|
175
178
|
| `auditLog` | No | Append-only audit trail of what the bot executed for this platform — tool calls (incl. subagents), session lifecycle, security-relevant commands, plan approvals. One JSONL stream per platform under `~/.claude-threads/audit/` (override: `CLAUDE_THREADS_AUDIT_DIR`), files `0600`. The bot never deletes it — rotation/retention is the operator's job (logrotate, SIEM ingestion). See [Audit log](#audit-log). Default off. |
|
|
176
179
|
| `directMessages` | No | Mattermost only: DM auto-discovery. A direct message from a user on `allowedUsers` spawns a derived direct-channel-mode instance for that DM conversation — no per-DM entry needed. See [DM auto-discovery](#dm-auto-discovery). |
|
|
177
180
|
|
|
@@ -195,6 +198,7 @@ What happens: every `audio/*` attachment (or a file with an audio extension when
|
|
|
195
198
|
| `directChannelMode` | No | Direct channel mode: the whole channel is one session, and the bot replies with top-level channel posts instead of thread replies. `true` for defaults, or an options object (`respondTo`). See [Direct Channel Mode](#direct-channel-mode). |
|
|
196
199
|
| `approvals` | No | Who may answer tool-permission prompts and other reaction gates: `owner` (session participants) or `all_users` (everyone on `allowedUsers`). Unset keeps the historical default per mode — `all_users` for thread sessions, `owner` for direct channel mode. See [Approvals](#approvals). |
|
|
197
200
|
| `ackReaction` | No | Read receipt: react to every accepted message (session start, follow-up, resume) the instant it is accepted, before Claude produces output. `true` uses 👀 (`eyes`), a string names a custom emoji. Persistent, unlike the typing indicator — useful in busy channels and for messages queued behind an in-flight session start. The receipt means *accepted*, not *delivered*: a later failure (capacity limit, Claude not coming up) is still reported by its own post. `!commands` are not acked — they have their own immediate feedback, and neither are messages accepted through the message-approval flow (an authorized user approving a non-participant's message) — there the approval reaction is already the visible signal. Note: in direct channel mode this is one reaction API call per accepted message. Default off. |
|
|
201
|
+
| `reconnectPolicy` | No | What happens when reconnection attempts run out: `retry` (default — log, cool down 60s, reset the counter and keep trying; recovers with no supervisor) or `exit` (leave through the graceful shutdown path and exit non-zero, for `Restart=always` deployments). The bot never stays alive with a dead socket either way. |
|
|
198
202
|
| `auditLog` | No | Append-only audit trail of what the bot executed for this platform — tool calls (incl. subagents), session lifecycle, security-relevant commands, plan approvals. One JSONL stream per platform under `~/.claude-threads/audit/` (override: `CLAUDE_THREADS_AUDIT_DIR`), files `0600`. The bot never deletes it — rotation/retention is the operator's job (logrotate, SIEM ingestion). See [Audit log](#audit-log). Default off. |
|
|
199
203
|
|
|
200
204
|
### Direct Channel Mode
|
|
@@ -715,3 +719,44 @@ The bot prevents system sleep while sessions are active (uses `caffeinate` on ma
|
|
|
715
719
|
---
|
|
716
720
|
|
|
717
721
|
_claude-threads is maintained by [Axolotl Systems](https://axolotl.systems). If it makes your team faster, consider [sponsoring the project](https://github.com/sponsors/axolotl-systems)._
|
|
722
|
+
|
|
723
|
+
## `!usage` output
|
|
724
|
+
|
|
725
|
+
`!usage` reports the subscription windows for the seat the thread is running
|
|
726
|
+
on; `!usage all` reports every account in the `claudeAccounts` pool. The
|
|
727
|
+
numbers come from the same `/usage` probe the account router uses, so what you
|
|
728
|
+
read and what routes can never disagree — it runs zero turns and costs $0.
|
|
729
|
+
|
|
730
|
+
In a thread with **no session yet** there is no seat to report, so plain
|
|
731
|
+
`!usage` behaves like `!usage all` and lists the whole pool — the seats the
|
|
732
|
+
router would be choosing between. Asking before starting a session is the
|
|
733
|
+
common case, and "which seat has headroom" is the useful answer there.
|
|
734
|
+
|
|
735
|
+
`!usage` is restricted to users authorized in the thread — the platform's
|
|
736
|
+
`allowedUsers`, plus anyone invited to that session. It spawns one probe per
|
|
737
|
+
pooled seat and names the accounts, so it is not something a passing channel
|
|
738
|
+
member can trigger inside someone else's thread.
|
|
739
|
+
|
|
740
|
+
```yaml
|
|
741
|
+
usage:
|
|
742
|
+
showEmails: true # default false
|
|
743
|
+
```
|
|
744
|
+
|
|
745
|
+
`showEmails` adds each seat's login address to its row. Off by default: the
|
|
746
|
+
quota bars say nothing about who owns a seat, the address does, and `!usage`
|
|
747
|
+
answers into a channel several people can read and anyone in it can trigger.
|
|
748
|
+
|
|
749
|
+
Turn it on when the pool is your own seats and directory names like `primary`
|
|
750
|
+
and `backup` do not tell you which account is which — that is the case it
|
|
751
|
+
exists for. The plan badge (`Max 20×`) is shown either way; it explains why one
|
|
752
|
+
seat's week is four times another's and identifies nobody.
|
|
753
|
+
|
|
754
|
+
Both the address and the badge are read from the profile's `.claude.json`.
|
|
755
|
+
Nothing in `!usage` opens `.credentials.json` or the macOS Keychain.
|
|
756
|
+
|
|
757
|
+
⚠️ The flag gates the address read from that metadata — it does not sanitize
|
|
758
|
+
labels you chose yourself. A `claudeAccounts` entry whose `id` or `displayName`
|
|
759
|
+
is an email address is printed as the row heading whether or not `showEmails`
|
|
760
|
+
is on, because it is the name the account router uses and a row that cannot be
|
|
761
|
+
matched to a routing decision is worse than useless. Name pool accounts
|
|
762
|
+
`primary` / `backup`, not by address.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-threads",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.36.1",
|
|
4
4
|
"description": "Run Claude Code from Slack or Mattermost. Sessions stream live into threads where your whole team can watch and steer.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -30,7 +30,8 @@
|
|
|
30
30
|
"lint:fix": "eslint src/ --fix",
|
|
31
31
|
"typecheck": "tsc --noEmit",
|
|
32
32
|
"knip": "knip --no-config-hints",
|
|
33
|
-
"prepare": "husky"
|
|
33
|
+
"prepare": "husky",
|
|
34
|
+
"test:node-e2e": "bun run build && bun test tests/node-e2e --timeout 240000"
|
|
34
35
|
},
|
|
35
36
|
"keywords": [
|
|
36
37
|
"claude",
|
|
@@ -99,7 +100,7 @@
|
|
|
99
100
|
"@types/ws": "^8.18.0",
|
|
100
101
|
"eslint": "^10.7.0",
|
|
101
102
|
"husky": "^9.1.7",
|
|
102
|
-
"knip": "6.
|
|
103
|
+
"knip": "6.34.0",
|
|
103
104
|
"lint-staged": "^17.0.4",
|
|
104
105
|
"prettier": "^3.9.5",
|
|
105
106
|
"react-devtools-core": "^7.0.1",
|