mattermost-claude-code 0.8.0 → 0.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 +241 -0
- package/README.md +2 -0
- package/dist/changelog.d.ts +20 -0
- package/dist/changelog.js +134 -0
- package/dist/claude/session.js +6 -0
- package/dist/index.js +13 -0
- package/package.json +2 -1
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [0.8.1] - 2025-12-28
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- **`!release-notes` command** - Show release notes for the current version
|
|
12
|
+
- **"What's new" in session header** - Shows a brief summary of new features when starting a session
|
|
13
|
+
|
|
14
|
+
## [0.8.0] - 2025-12-28
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
- **Image attachment support** - Attach images to your messages and Claude Code will analyze them
|
|
18
|
+
- Supports JPEG, PNG, GIF, and WebP formats
|
|
19
|
+
- Images are downloaded from Mattermost and sent to Claude as base64-encoded content blocks
|
|
20
|
+
- Works for both new sessions and follow-up messages
|
|
21
|
+
- Debug logging shows attached image details (name, type, size)
|
|
22
|
+
|
|
23
|
+
## [0.7.3] - 2025-12-28
|
|
24
|
+
|
|
25
|
+
### Fixed
|
|
26
|
+
- Actually fix `!cd` showing "[Exited: null]" - reset flag in async exit handler, not synchronously
|
|
27
|
+
|
|
28
|
+
## [0.7.2] - 2025-12-28
|
|
29
|
+
|
|
30
|
+
### Fixed
|
|
31
|
+
- Fix `!cd` command showing "[Exited: null]" message - now properly suppresses exit message during intentional restart
|
|
32
|
+
|
|
33
|
+
## [0.7.1] - 2025-12-28
|
|
34
|
+
|
|
35
|
+
### Fixed
|
|
36
|
+
- Fix infinite loop when plan is approved - no longer sends "Continue" message on subsequent ExitPlanMode calls
|
|
37
|
+
|
|
38
|
+
## [0.7.0] - 2025-12-28
|
|
39
|
+
|
|
40
|
+
### Added
|
|
41
|
+
- **`!cd <path>` command** - Change working directory mid-session
|
|
42
|
+
- Restarts Claude Code in the new directory with fresh context
|
|
43
|
+
- Session header updates to show current working directory
|
|
44
|
+
- Validates directory exists before switching
|
|
45
|
+
|
|
46
|
+
## [0.6.1] - 2025-12-28
|
|
47
|
+
|
|
48
|
+
### Changed
|
|
49
|
+
- Cleaner console output: removed verbose `[Session]` prefixes from logs
|
|
50
|
+
- Debug-only logging for internal session state changes (plan approval, question handling)
|
|
51
|
+
- Consistent emoji formatting for all log messages
|
|
52
|
+
|
|
53
|
+
## [0.6.0] - 2025-12-28
|
|
54
|
+
|
|
55
|
+
### Added
|
|
56
|
+
- **Auto-update notifications** - shows banner in session header when new version is available
|
|
57
|
+
- Checks npm registry on startup for latest version
|
|
58
|
+
- Update notice includes install command: `npm install -g mattermost-claude-code`
|
|
59
|
+
|
|
60
|
+
## [0.5.9] - 2025-12-28
|
|
61
|
+
|
|
62
|
+
### Fixed
|
|
63
|
+
- Security fix: sanitize bot username in regex to prevent injection
|
|
64
|
+
|
|
65
|
+
## [0.5.8] - 2025-12-28
|
|
66
|
+
|
|
67
|
+
### Changed
|
|
68
|
+
- Commands now use `!` prefix instead of `/` to avoid Mattermost slash command conflicts
|
|
69
|
+
- `!help`, `!invite`, `!kick`, `!permissions`, `!stop` replace `/` versions
|
|
70
|
+
- Commands without prefix (`help`, `stop`, `cancel`) still work
|
|
71
|
+
|
|
72
|
+
## [0.5.7] - 2025-12-28
|
|
73
|
+
|
|
74
|
+
### Fixed
|
|
75
|
+
- Bot now recognizes mentions with hyphens in username (e.g., `@annes-minion`)
|
|
76
|
+
- Side conversation detection regex updated to handle full Mattermost usernames
|
|
77
|
+
|
|
78
|
+
## [0.5.6] - 2025-12-28
|
|
79
|
+
|
|
80
|
+
### Added
|
|
81
|
+
- Timeout warning 5 minutes before session expires
|
|
82
|
+
- Warning message tells user to send a message to keep session alive
|
|
83
|
+
- Warning resets if activity resumes
|
|
84
|
+
|
|
85
|
+
## [0.5.5] - 2025-12-28
|
|
86
|
+
|
|
87
|
+
### Added
|
|
88
|
+
- `/help` command to show available session commands
|
|
89
|
+
|
|
90
|
+
### Changed
|
|
91
|
+
- Replace ASCII diagram with Mermaid flowchart in README
|
|
92
|
+
|
|
93
|
+
## [0.5.4] - 2025-12-28 (not released)
|
|
94
|
+
|
|
95
|
+
### Added
|
|
96
|
+
- `/help` command to show available session commands
|
|
97
|
+
|
|
98
|
+
## [0.5.3] - 2025-12-28
|
|
99
|
+
|
|
100
|
+
### Added
|
|
101
|
+
- `/permissions interactive` command to enable interactive permissions for a session
|
|
102
|
+
- Can only downgrade permissions (auto → interactive), not upgrade
|
|
103
|
+
- Session header updates to show current permission mode
|
|
104
|
+
|
|
105
|
+
## [0.5.2] - 2025-12-28
|
|
106
|
+
|
|
107
|
+
### Changed
|
|
108
|
+
- Complete README rewrite with full documentation of all features
|
|
109
|
+
|
|
110
|
+
## [0.5.1] - 2025-12-28
|
|
111
|
+
|
|
112
|
+
### Added
|
|
113
|
+
- `--no-skip-permissions` flag to enable interactive permissions even when `SKIP_PERMISSIONS=true` is set in env
|
|
114
|
+
|
|
115
|
+
## [0.5.0] - 2025-12-28
|
|
116
|
+
|
|
117
|
+
### Added
|
|
118
|
+
- **Session collaboration** - invite users to specific sessions without global access
|
|
119
|
+
- **`/invite @username`** - Temporarily allow a user to participate in the current session
|
|
120
|
+
- **`/kick @username`** - Remove an invited user from the current session
|
|
121
|
+
- **Message approval flow** - When unauthorized users send messages in a session thread, the session owner/allowed users can approve via reactions:
|
|
122
|
+
- 👍 Allow this single message
|
|
123
|
+
- ✅ Invite them to the session
|
|
124
|
+
- 👎 Deny the message
|
|
125
|
+
- Per-session allowlist tracked via `sessionAllowedUsers` in each session
|
|
126
|
+
- **Side conversation support** - Messages starting with `@someone-else` are ignored, allowing users to chat without triggering the bot
|
|
127
|
+
- **Dynamic session header** - The session start message updates to show current participants when users are invited or kicked
|
|
128
|
+
|
|
129
|
+
### Changed
|
|
130
|
+
- Session owner is automatically added to session allowlist
|
|
131
|
+
- Authorization checks now use `isUserAllowedInSession()` for follow-ups
|
|
132
|
+
- Globally allowed users can still access all sessions
|
|
133
|
+
|
|
134
|
+
## [0.4.0] - 2025-12-28
|
|
135
|
+
|
|
136
|
+
### Added
|
|
137
|
+
- **CLI arguments** to override all config options (`--url`, `--token`, `--channel`, etc.)
|
|
138
|
+
- **Interactive onboarding** when no `.env` file exists - guided setup with help text
|
|
139
|
+
- Full `--help` output with all available options
|
|
140
|
+
- `--debug` flag to enable verbose logging
|
|
141
|
+
|
|
142
|
+
### Changed
|
|
143
|
+
- Switched from manual arg parsing to `commander` for better CLI experience
|
|
144
|
+
- Config now supports: CLI args > environment variables > defaults
|
|
145
|
+
|
|
146
|
+
## [0.3.4] - 2025-12-27
|
|
147
|
+
|
|
148
|
+
### Added
|
|
149
|
+
- Cancel sessions with `/stop`, `/cancel`, `stop`, or `cancel` commands in thread
|
|
150
|
+
- Cancel sessions by reacting with ❌ or 🛑 to any post in the thread
|
|
151
|
+
|
|
152
|
+
## [0.3.3] - 2025-12-27
|
|
153
|
+
|
|
154
|
+
### Added
|
|
155
|
+
- WebSocket heartbeat to detect dead connections after laptop sleep/idle
|
|
156
|
+
- Automatic reconnection when connection goes silent for 60+ seconds
|
|
157
|
+
- Ping every 30 seconds to keep connection alive
|
|
158
|
+
|
|
159
|
+
### Fixed
|
|
160
|
+
- Connections no longer go "zombie" after laptop sleep - mm-claude now detects and reconnects
|
|
161
|
+
|
|
162
|
+
## [0.3.2] - 2025-12-27
|
|
163
|
+
|
|
164
|
+
### Fixed
|
|
165
|
+
- Session card now correctly shows "mm-claude" instead of "Claude Code"
|
|
166
|
+
|
|
167
|
+
## [0.3.1] - 2025-12-27
|
|
168
|
+
|
|
169
|
+
### Changed
|
|
170
|
+
- Cleaner console output with colors (verbose logs only shown with `DEBUG=1`)
|
|
171
|
+
- Pimped session start card in Mattermost with version, directory, user, session count, permissions mode, and prompt preview
|
|
172
|
+
- Typing indicator starts immediately when session begins
|
|
173
|
+
- Shortened thread IDs in logs for readability
|
|
174
|
+
|
|
175
|
+
## [0.3.0] - 2025-12-27
|
|
176
|
+
|
|
177
|
+
### Added
|
|
178
|
+
- **Multiple concurrent sessions** - each Mattermost thread gets its own Claude CLI process
|
|
179
|
+
- Sessions tracked via `sessions: Map<threadId, Session>` and `postIndex: Map<postId, threadId>`
|
|
180
|
+
- Configurable session limits via `MAX_SESSIONS` env var (default: 5)
|
|
181
|
+
- Automatic idle session cleanup via `SESSION_TIMEOUT_MS` env var (default: 30 min)
|
|
182
|
+
- `killAllSessions()` for graceful shutdown of all sessions
|
|
183
|
+
- Session count logging for monitoring
|
|
184
|
+
|
|
185
|
+
### Changed
|
|
186
|
+
- `SessionManager` now manages multiple sessions instead of single session
|
|
187
|
+
- `sendFollowUp(threadId, message)` takes threadId parameter
|
|
188
|
+
- `isInSessionThread(threadId)` replaces `isInCurrentSessionThread()`
|
|
189
|
+
- `killSession(threadId)` takes threadId parameter
|
|
190
|
+
|
|
191
|
+
### Fixed
|
|
192
|
+
- Reaction routing now uses post index lookup for correct session targeting
|
|
193
|
+
|
|
194
|
+
## [0.2.3] - 2025-12-27
|
|
195
|
+
|
|
196
|
+
### Added
|
|
197
|
+
- GitHub Actions workflow for automated npm publishing on release
|
|
198
|
+
|
|
199
|
+
## [0.2.2] - 2025-12-27
|
|
200
|
+
|
|
201
|
+
### Added
|
|
202
|
+
- Comprehensive `CLAUDE.md` with project documentation for AI assistants
|
|
203
|
+
|
|
204
|
+
## [0.2.1] - 2025-12-27
|
|
205
|
+
|
|
206
|
+
### Added
|
|
207
|
+
- `--version` / `-v` flag to display version
|
|
208
|
+
- Version number shown in `--help` output
|
|
209
|
+
|
|
210
|
+
### Changed
|
|
211
|
+
- Lazy config loading (no .env file needed for --version/--help)
|
|
212
|
+
|
|
213
|
+
## [0.2.0] - 2025-12-27
|
|
214
|
+
|
|
215
|
+
### Added
|
|
216
|
+
- Interactive permission approval via Mattermost reactions
|
|
217
|
+
- Permission prompts forwarded to Mattermost thread
|
|
218
|
+
- React with 👍 to allow, ✅ to allow all, or 👎 to deny
|
|
219
|
+
- Only authorized users (ALLOWED_USERS) can approve permissions
|
|
220
|
+
- MCP-based permission server using Claude Code's `--permission-prompt-tool`
|
|
221
|
+
- `SKIP_PERMISSIONS` env var to control permission behavior
|
|
222
|
+
|
|
223
|
+
### Changed
|
|
224
|
+
- Permissions are now interactive by default (previously skipped)
|
|
225
|
+
- Use `SKIP_PERMISSIONS=true` or `--dangerously-skip-permissions` to skip
|
|
226
|
+
|
|
227
|
+
## [0.1.0] - 2024-12-27
|
|
228
|
+
|
|
229
|
+
### Added
|
|
230
|
+
- Initial release
|
|
231
|
+
- Connect Claude Code CLI to Mattermost channels
|
|
232
|
+
- Real-time streaming of Claude responses
|
|
233
|
+
- Interactive plan approval with emoji reactions
|
|
234
|
+
- Sequential question flow with emoji answers
|
|
235
|
+
- Task list display with live updates
|
|
236
|
+
- Code diffs for Edit operations
|
|
237
|
+
- Content preview for Write operations
|
|
238
|
+
- Subagent status tracking
|
|
239
|
+
- Typing indicator while Claude is processing
|
|
240
|
+
- User allowlist for access control
|
|
241
|
+
- Bot mention detection for triggering sessions
|
package/README.md
CHANGED
|
@@ -116,6 +116,8 @@ Type `!help` in any session thread to see available commands:
|
|
|
116
116
|
| Command | Description |
|
|
117
117
|
|:--------|:------------|
|
|
118
118
|
| `!help` | Show available commands |
|
|
119
|
+
| `!release-notes` | Show release notes for current version |
|
|
120
|
+
| `!cd <path>` | Change working directory (restarts Claude) |
|
|
119
121
|
| `!invite @user` | Invite a user to this session |
|
|
120
122
|
| `!kick @user` | Remove an invited user |
|
|
121
123
|
| `!permissions interactive` | Enable interactive permissions |
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
interface ReleaseNotes {
|
|
2
|
+
version: string;
|
|
3
|
+
date: string;
|
|
4
|
+
sections: {
|
|
5
|
+
[key: string]: string[];
|
|
6
|
+
};
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Parse CHANGELOG.md and extract release notes for a specific version.
|
|
10
|
+
*/
|
|
11
|
+
export declare function getReleaseNotes(version?: string): ReleaseNotes | null;
|
|
12
|
+
/**
|
|
13
|
+
* Format release notes as a Mattermost message.
|
|
14
|
+
*/
|
|
15
|
+
export declare function formatReleaseNotes(notes: ReleaseNotes): string;
|
|
16
|
+
/**
|
|
17
|
+
* Get a short summary of what's new (for session header).
|
|
18
|
+
*/
|
|
19
|
+
export declare function getWhatsNewSummary(notes: ReleaseNotes): string;
|
|
20
|
+
export {};
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { readFileSync, existsSync } from 'fs';
|
|
2
|
+
import { dirname, resolve } from 'path';
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
4
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
5
|
+
/**
|
|
6
|
+
* Parse CHANGELOG.md and extract release notes for a specific version.
|
|
7
|
+
*/
|
|
8
|
+
export function getReleaseNotes(version) {
|
|
9
|
+
// Try to find CHANGELOG.md in various locations
|
|
10
|
+
const possiblePaths = [
|
|
11
|
+
resolve(__dirname, '..', 'CHANGELOG.md'), // dist/../CHANGELOG.md (installed)
|
|
12
|
+
resolve(__dirname, '..', '..', 'CHANGELOG.md'), // src/../CHANGELOG.md (dev)
|
|
13
|
+
];
|
|
14
|
+
let changelogPath = null;
|
|
15
|
+
for (const p of possiblePaths) {
|
|
16
|
+
if (existsSync(p)) {
|
|
17
|
+
changelogPath = p;
|
|
18
|
+
break;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
if (!changelogPath) {
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
try {
|
|
25
|
+
const content = readFileSync(changelogPath, 'utf-8');
|
|
26
|
+
return parseChangelog(content, version);
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Parse changelog content and extract notes for a version.
|
|
34
|
+
* If no version specified, returns the latest (first) version.
|
|
35
|
+
*/
|
|
36
|
+
function parseChangelog(content, targetVersion) {
|
|
37
|
+
const lines = content.split('\n');
|
|
38
|
+
let currentVersion = null;
|
|
39
|
+
let currentDate = null;
|
|
40
|
+
let currentSection = null;
|
|
41
|
+
let sections = {};
|
|
42
|
+
let foundTarget = false;
|
|
43
|
+
for (const line of lines) {
|
|
44
|
+
// Match version header: ## [0.8.0] - 2025-12-28
|
|
45
|
+
const versionMatch = line.match(/^## \[(\d+\.\d+\.\d+)\](?: - (\d{4}-\d{2}-\d{2}))?/);
|
|
46
|
+
if (versionMatch) {
|
|
47
|
+
// If we already found our target, we're done
|
|
48
|
+
if (foundTarget) {
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
51
|
+
currentVersion = versionMatch[1];
|
|
52
|
+
currentDate = versionMatch[2] || '';
|
|
53
|
+
sections = {};
|
|
54
|
+
currentSection = null;
|
|
55
|
+
// Check if this is the version we want
|
|
56
|
+
if (!targetVersion || currentVersion === targetVersion) {
|
|
57
|
+
foundTarget = true;
|
|
58
|
+
}
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
// Only process if we're in the target version
|
|
62
|
+
if (!foundTarget)
|
|
63
|
+
continue;
|
|
64
|
+
// Match section header: ### Added, ### Fixed, ### Changed
|
|
65
|
+
const sectionMatch = line.match(/^### (\w+)/);
|
|
66
|
+
if (sectionMatch) {
|
|
67
|
+
currentSection = sectionMatch[1];
|
|
68
|
+
sections[currentSection] = [];
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
// Match list item: - Item text
|
|
72
|
+
const itemMatch = line.match(/^- (.+)/);
|
|
73
|
+
if (itemMatch && currentSection) {
|
|
74
|
+
sections[currentSection].push(itemMatch[1]);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
if (!foundTarget || !currentVersion) {
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
return {
|
|
81
|
+
version: currentVersion,
|
|
82
|
+
date: currentDate || '',
|
|
83
|
+
sections,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Format release notes as a Mattermost message.
|
|
88
|
+
*/
|
|
89
|
+
export function formatReleaseNotes(notes) {
|
|
90
|
+
let msg = `### 📋 Release Notes - v${notes.version}`;
|
|
91
|
+
if (notes.date) {
|
|
92
|
+
msg += ` (${notes.date})`;
|
|
93
|
+
}
|
|
94
|
+
msg += '\n\n';
|
|
95
|
+
for (const [section, items] of Object.entries(notes.sections)) {
|
|
96
|
+
if (items.length === 0)
|
|
97
|
+
continue;
|
|
98
|
+
const emoji = section === 'Added' ? '✨' :
|
|
99
|
+
section === 'Fixed' ? '🐛' :
|
|
100
|
+
section === 'Changed' ? '🔄' :
|
|
101
|
+
section === 'Removed' ? '🗑️' : '•';
|
|
102
|
+
msg += `**${emoji} ${section}**\n`;
|
|
103
|
+
for (const item of items) {
|
|
104
|
+
msg += `- ${item}\n`;
|
|
105
|
+
}
|
|
106
|
+
msg += '\n';
|
|
107
|
+
}
|
|
108
|
+
return msg.trim();
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Get a short summary of what's new (for session header).
|
|
112
|
+
*/
|
|
113
|
+
export function getWhatsNewSummary(notes) {
|
|
114
|
+
const items = [];
|
|
115
|
+
// Prioritize: Added > Fixed > Changed
|
|
116
|
+
for (const section of ['Added', 'Fixed', 'Changed']) {
|
|
117
|
+
const sectionItems = notes.sections[section] || [];
|
|
118
|
+
for (const item of sectionItems) {
|
|
119
|
+
// Extract just the first part (before any dash or detail)
|
|
120
|
+
const short = item.split(' - ')[0].replace(/\*\*/g, '');
|
|
121
|
+
if (short.length <= 50) {
|
|
122
|
+
items.push(short);
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
items.push(short.substring(0, 47) + '...');
|
|
126
|
+
}
|
|
127
|
+
if (items.length >= 2)
|
|
128
|
+
break;
|
|
129
|
+
}
|
|
130
|
+
if (items.length >= 2)
|
|
131
|
+
break;
|
|
132
|
+
}
|
|
133
|
+
return items.join(', ');
|
|
134
|
+
}
|
package/dist/claude/session.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ClaudeCli } from './cli.js';
|
|
2
2
|
import { getUpdateInfo } from '../update-notifier.js';
|
|
3
|
+
import { getReleaseNotes, getWhatsNewSummary } from '../changelog.js';
|
|
3
4
|
import { readFileSync } from 'fs';
|
|
4
5
|
import { dirname, resolve } from 'path';
|
|
5
6
|
import { fileURLToPath } from 'url';
|
|
@@ -1010,9 +1011,14 @@ export class SessionManager {
|
|
|
1010
1011
|
const updateNotice = updateInfo
|
|
1011
1012
|
? `\n> ⚠️ **Update available:** v${updateInfo.current} → v${updateInfo.latest} - Run \`npm install -g mattermost-claude-code\`\n`
|
|
1012
1013
|
: '';
|
|
1014
|
+
// Get "What's new" from release notes
|
|
1015
|
+
const releaseNotes = getReleaseNotes(pkg.version);
|
|
1016
|
+
const whatsNew = releaseNotes ? getWhatsNewSummary(releaseNotes) : '';
|
|
1017
|
+
const whatsNewLine = whatsNew ? `\n> ✨ **What's new:** ${whatsNew}\n` : '';
|
|
1013
1018
|
const msg = [
|
|
1014
1019
|
`### 🤖 mm-claude \`v${pkg.version}\``,
|
|
1015
1020
|
updateNotice,
|
|
1021
|
+
whatsNewLine,
|
|
1016
1022
|
`| | |`,
|
|
1017
1023
|
`|:--|:--|`,
|
|
1018
1024
|
...rows,
|
package/dist/index.js
CHANGED
|
@@ -8,6 +8,7 @@ import { readFileSync } from 'fs';
|
|
|
8
8
|
import { dirname, resolve } from 'path';
|
|
9
9
|
import { fileURLToPath } from 'url';
|
|
10
10
|
import { checkForUpdates } from './update-notifier.js';
|
|
11
|
+
import { getReleaseNotes, formatReleaseNotes } from './changelog.js';
|
|
11
12
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
12
13
|
const pkg = JSON.parse(readFileSync(resolve(__dirname, '..', 'package.json'), 'utf-8'));
|
|
13
14
|
const dim = (s) => `\x1b[2m${s}\x1b[0m`;
|
|
@@ -101,6 +102,7 @@ async function main() {
|
|
|
101
102
|
`| Command | Description |\n` +
|
|
102
103
|
`|:--------|:------------|\n` +
|
|
103
104
|
`| \`!help\` | Show this help message |\n` +
|
|
105
|
+
`| \`!release-notes\` | Show release notes for current version |\n` +
|
|
104
106
|
`| \`!cd <path>\` | Change working directory (restarts Claude) |\n` +
|
|
105
107
|
`| \`!invite @user\` | Invite a user to this session |\n` +
|
|
106
108
|
`| \`!kick @user\` | Remove an invited user |\n` +
|
|
@@ -111,6 +113,17 @@ async function main() {
|
|
|
111
113
|
`- ❌ or 🛑 on any message to stop session`, threadRoot);
|
|
112
114
|
return;
|
|
113
115
|
}
|
|
116
|
+
// Check for !release-notes command
|
|
117
|
+
if (lowerContent === '!release-notes' || lowerContent === '!changelog') {
|
|
118
|
+
const notes = getReleaseNotes(pkg.version);
|
|
119
|
+
if (notes) {
|
|
120
|
+
await mattermost.createPost(formatReleaseNotes(notes), threadRoot);
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
await mattermost.createPost(`📋 **mm-claude v${pkg.version}**\n\nRelease notes not available. See [GitHub releases](https://github.com/anneschuth/mattermost-claude-code/releases).`, threadRoot);
|
|
124
|
+
}
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
114
127
|
// Check for !invite command
|
|
115
128
|
const inviteMatch = content.match(/^!invite\s+@?([\w.-]+)/i);
|
|
116
129
|
if (inviteMatch) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mattermost-claude-code",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.1",
|
|
4
4
|
"description": "Share Claude Code sessions live in a Mattermost channel with interactive features",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -36,6 +36,7 @@
|
|
|
36
36
|
"files": [
|
|
37
37
|
"dist",
|
|
38
38
|
"README.md",
|
|
39
|
+
"CHANGELOG.md",
|
|
39
40
|
"LICENSE",
|
|
40
41
|
"package.json"
|
|
41
42
|
],
|