claude-threads 0.12.1 → 0.14.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 +53 -0
- package/README.md +142 -37
- package/dist/claude/cli.d.ts +8 -0
- package/dist/claude/cli.js +16 -8
- package/dist/config/migration.d.ts +45 -0
- package/dist/config/migration.js +35 -0
- package/dist/config.d.ts +12 -18
- package/dist/config.js +7 -94
- package/dist/git/worktree.d.ts +0 -4
- package/dist/git/worktree.js +1 -1
- package/dist/index.js +39 -15
- package/dist/logo.d.ts +3 -20
- package/dist/logo.js +7 -23
- package/dist/mcp/permission-server.js +61 -112
- package/dist/onboarding.d.ts +1 -1
- package/dist/onboarding.js +271 -69
- package/dist/persistence/session-store.d.ts +8 -2
- package/dist/persistence/session-store.js +41 -16
- package/dist/platform/client.d.ts +140 -0
- package/dist/platform/formatter.d.ts +74 -0
- package/dist/platform/index.d.ts +11 -0
- package/dist/platform/index.js +8 -0
- package/dist/platform/mattermost/client.d.ts +70 -0
- package/dist/{mattermost → platform/mattermost}/client.js +117 -34
- package/dist/platform/mattermost/formatter.d.ts +20 -0
- package/dist/platform/mattermost/formatter.js +46 -0
- package/dist/platform/mattermost/permission-api.d.ts +10 -0
- package/dist/platform/mattermost/permission-api.js +139 -0
- package/dist/platform/mattermost/types.js +1 -0
- package/dist/platform/permission-api-factory.d.ts +11 -0
- package/dist/platform/permission-api-factory.js +21 -0
- package/dist/platform/permission-api.d.ts +67 -0
- package/dist/platform/permission-api.js +8 -0
- package/dist/platform/types.d.ts +70 -0
- package/dist/platform/types.js +7 -0
- package/dist/session/commands.d.ts +52 -0
- package/dist/session/commands.js +323 -0
- package/dist/session/events.d.ts +25 -0
- package/dist/session/events.js +368 -0
- package/dist/session/index.d.ts +7 -0
- package/dist/session/index.js +6 -0
- package/dist/session/lifecycle.d.ts +70 -0
- package/dist/session/lifecycle.js +456 -0
- package/dist/session/manager.d.ts +96 -0
- package/dist/session/manager.js +537 -0
- package/dist/session/reactions.d.ts +25 -0
- package/dist/session/reactions.js +151 -0
- package/dist/session/streaming.d.ts +47 -0
- package/dist/session/streaming.js +152 -0
- package/dist/session/types.d.ts +78 -0
- package/dist/session/types.js +9 -0
- package/dist/session/worktree.d.ts +56 -0
- package/dist/session/worktree.js +339 -0
- package/dist/{mattermost → utils}/emoji.d.ts +3 -3
- package/dist/{mattermost → utils}/emoji.js +3 -3
- package/dist/utils/emoji.test.d.ts +1 -0
- package/dist/utils/tool-formatter.d.ts +10 -13
- package/dist/utils/tool-formatter.js +48 -43
- package/dist/utils/tool-formatter.test.js +67 -52
- package/package.json +2 -3
- package/dist/claude/session.d.ts +0 -256
- package/dist/claude/session.js +0 -1964
- package/dist/mattermost/client.d.ts +0 -56
- /package/dist/{mattermost/emoji.test.d.ts → platform/client.js} +0 -0
- /package/dist/{mattermost/types.js → platform/formatter.js} +0 -0
- /package/dist/{mattermost → platform/mattermost}/types.d.ts +0 -0
- /package/dist/{mattermost → utils}/emoji.test.js +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,59 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.14.0] - 2025-12-30
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- **Multi-platform architecture** - Foundation for supporting multiple chat platforms
|
|
14
|
+
- New `PlatformClient` interface abstracts platform differences
|
|
15
|
+
- Normalized types: `PlatformPost`, `PlatformUser`, `PlatformReaction`, `PlatformFile`
|
|
16
|
+
- Mattermost implementation moved to `src/platform/mattermost/`
|
|
17
|
+
- Slack support architecture ready (implementation pending)
|
|
18
|
+
- **YAML-based configuration** - New config format
|
|
19
|
+
- Config file: `~/.config/claude-threads/config.yaml`
|
|
20
|
+
- Support for multiple platform instances simultaneously
|
|
21
|
+
- Interactive onboarding wizard creates YAML config
|
|
22
|
+
|
|
23
|
+
### Changed
|
|
24
|
+
- **Modular session management** - Broke 2,500-line monolith into focused modules
|
|
25
|
+
- `session/manager.ts` (~635 lines) - Thin orchestrator
|
|
26
|
+
- `session/lifecycle.ts` (~590 lines) - Session start/resume/exit
|
|
27
|
+
- `session/events.ts` (~480 lines) - Claude CLI event handling
|
|
28
|
+
- `session/commands.ts` (~510 lines) - User commands
|
|
29
|
+
- `session/reactions.ts` (~210 lines) - Emoji reaction handling
|
|
30
|
+
- `session/worktree.ts` (~520 lines) - Git worktree management
|
|
31
|
+
- `session/streaming.ts` (~180 lines) - Message batching
|
|
32
|
+
- Uses dependency injection for testability
|
|
33
|
+
- **Platform-agnostic utilities** - Moved emoji helpers to `src/utils/emoji.ts`
|
|
34
|
+
- **Cleaner logo exports** - Renamed to generic `getLogo()`, `LOGO`, `LOGO_INLINE`
|
|
35
|
+
|
|
36
|
+
### Removed
|
|
37
|
+
- **Legacy `.env` configuration** - Now uses YAML only (`config.yaml`)
|
|
38
|
+
- **`dotenv` dependency** - No longer needed
|
|
39
|
+
- Deprecated Mattermost-specific exports (`getMattermostLogo`, `MATTERMOST_LOGO`)
|
|
40
|
+
- Internal documentation files (moved to CLAUDE.md)
|
|
41
|
+
|
|
42
|
+
## [0.13.0] - 2025-12-29
|
|
43
|
+
|
|
44
|
+
### Added
|
|
45
|
+
- **`--setup` flag** - Re-run interactive setup wizard to reconfigure settings
|
|
46
|
+
- Existing .env values are used as defaults (press Enter to keep)
|
|
47
|
+
- Token field allows keeping existing token without re-entering
|
|
48
|
+
- New settings added since initial setup are presented with built-in defaults
|
|
49
|
+
- Config saved back to original location
|
|
50
|
+
- **Chrome and worktree settings in onboarding** - New setup prompts for:
|
|
51
|
+
- Chrome integration (yes/no)
|
|
52
|
+
- Git worktree mode (prompt/off/require)
|
|
53
|
+
|
|
54
|
+
### Changed
|
|
55
|
+
- **Improved README** - New tagline and improved intro section
|
|
56
|
+
- **Worktree documentation** - Added comprehensive Git Worktrees section to README
|
|
57
|
+
- **Updated CLI options** - Added `--chrome`, `--no-chrome`, `--worktree-mode`, `--setup` to README
|
|
58
|
+
|
|
59
|
+
### Fixed
|
|
60
|
+
- **Warning icon alignment** - Fixed spacing of ⚠️ icon in CLI startup output
|
|
61
|
+
- **WORKTREE_MODE documentation** - Fixed incorrect values in README (was `always`/`never`, now correctly `off`/`prompt`/`require`)
|
|
62
|
+
|
|
10
63
|
## [0.12.1] - 2025-12-29
|
|
11
64
|
|
|
12
65
|
### Fixed
|
package/README.md
CHANGED
|
@@ -9,7 +9,9 @@
|
|
|
9
9
|
[](https://www.npmjs.com/package/claude-threads)
|
|
10
10
|
[](https://opensource.org/licenses/MIT)
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
**Bring Claude Code to your team.** Run Claude Code on your machine, share it live in Mattermost. Colleagues can watch, collaborate, and run their own sessions—all from chat.
|
|
13
|
+
|
|
14
|
+
> 💡 *Think of it as screen-sharing for AI pair programming, but everyone can type.*
|
|
13
15
|
|
|
14
16
|
## Features
|
|
15
17
|
|
|
@@ -66,25 +68,41 @@ claude-threads
|
|
|
66
68
|
On first run, an interactive setup wizard guides you through configuration:
|
|
67
69
|
|
|
68
70
|
```
|
|
69
|
-
|
|
71
|
+
claude-threads setup
|
|
72
|
+
─────────────────────────────────
|
|
73
|
+
|
|
74
|
+
Welcome! Let's configure claude-threads.
|
|
75
|
+
|
|
76
|
+
? Default working directory: /home/user/projects
|
|
77
|
+
? Enable Chrome integration? No
|
|
78
|
+
? Git worktree mode: Prompt
|
|
70
79
|
|
|
71
|
-
|
|
80
|
+
Now let's add your platform connections.
|
|
72
81
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
82
|
+
? First platform: Mattermost
|
|
83
|
+
? Platform ID: default
|
|
84
|
+
? Display name: Mattermost
|
|
76
85
|
|
|
77
|
-
|
|
86
|
+
Mattermost setup:
|
|
87
|
+
|
|
88
|
+
? Server URL: https://chat.example.com
|
|
78
89
|
? Bot token: ********
|
|
79
90
|
? Channel ID: abc123def456
|
|
80
91
|
? Bot mention name: claude-code
|
|
81
|
-
? Allowed usernames: alice,bob
|
|
82
|
-
?
|
|
92
|
+
? Allowed usernames (optional): alice,bob
|
|
93
|
+
? Auto-approve all actions? No
|
|
94
|
+
|
|
95
|
+
✓ Added Mattermost
|
|
83
96
|
|
|
84
|
-
|
|
85
|
-
~/.config/claude-threads/.env
|
|
97
|
+
? Add another platform? No
|
|
86
98
|
|
|
87
|
-
|
|
99
|
+
✓ Configuration saved!
|
|
100
|
+
~/.config/claude-threads/config.yaml
|
|
101
|
+
|
|
102
|
+
Configured 1 platform(s):
|
|
103
|
+
• Mattermost (mattermost)
|
|
104
|
+
|
|
105
|
+
Starting claude-threads...
|
|
88
106
|
```
|
|
89
107
|
|
|
90
108
|
### 3. Use
|
|
@@ -101,16 +119,20 @@ In Mattermost, mention the bot:
|
|
|
101
119
|
claude-threads [options]
|
|
102
120
|
|
|
103
121
|
Options:
|
|
104
|
-
--url <url>
|
|
105
|
-
--token <token>
|
|
106
|
-
--channel <id>
|
|
107
|
-
--bot-name <name>
|
|
108
|
-
--allowed-users <list>
|
|
109
|
-
--skip-permissions
|
|
110
|
-
--no-skip-permissions
|
|
111
|
-
--
|
|
112
|
-
--
|
|
113
|
-
--
|
|
122
|
+
--url <url> Mattermost server URL
|
|
123
|
+
--token <token> Bot token
|
|
124
|
+
--channel <id> Channel ID
|
|
125
|
+
--bot-name <name> Bot mention name (default: claude-code)
|
|
126
|
+
--allowed-users <list> Comma-separated allowed usernames
|
|
127
|
+
--skip-permissions Skip permission prompts (auto-approve)
|
|
128
|
+
--no-skip-permissions Enable permission prompts (override env)
|
|
129
|
+
--chrome Enable Chrome integration
|
|
130
|
+
--no-chrome Disable Chrome integration
|
|
131
|
+
--worktree-mode <mode> Git worktree mode: off, prompt, require
|
|
132
|
+
--setup Re-run setup wizard (reconfigure settings)
|
|
133
|
+
--debug Enable debug logging
|
|
134
|
+
--version Show version
|
|
135
|
+
--help Show help
|
|
114
136
|
```
|
|
115
137
|
|
|
116
138
|
CLI options override environment variables.
|
|
@@ -123,11 +145,17 @@ Type `!help` in any session thread to see available commands:
|
|
|
123
145
|
|:--------|:------------|
|
|
124
146
|
| `!help` | Show available commands |
|
|
125
147
|
| `!release-notes` | Show release notes for current version |
|
|
148
|
+
| `!context` | Show context usage (tokens used/remaining) |
|
|
149
|
+
| `!cost` | Show token usage and cost for this session |
|
|
150
|
+
| `!compact` | Compress context to free up space |
|
|
126
151
|
| `!cd <path>` | Change working directory (restarts Claude) |
|
|
152
|
+
| `!worktree <branch>` | Create and switch to a git worktree |
|
|
127
153
|
| `!invite @user` | Invite a user to this session |
|
|
128
154
|
| `!kick @user` | Remove an invited user |
|
|
129
155
|
| `!permissions interactive` | Enable interactive permissions |
|
|
156
|
+
| `!escape` | Interrupt current task (keeps session active) |
|
|
130
157
|
| `!stop` | Stop this session |
|
|
158
|
+
| `!kill` | Emergency shutdown (kills ALL sessions, exits bot) |
|
|
131
159
|
|
|
132
160
|
> **Note:** Commands use `!` prefix instead of `/` to avoid conflicts with Mattermost's slash commands.
|
|
133
161
|
|
|
@@ -176,6 +204,47 @@ If the bot is running with `--skip-permissions` (auto mode), you can enable inte
|
|
|
176
204
|
|
|
177
205
|
This allows collaboration by requiring approval for Claude's actions. Note: you can only downgrade (auto → interactive), not upgrade - this ensures security.
|
|
178
206
|
|
|
207
|
+
## Git Worktrees
|
|
208
|
+
|
|
209
|
+
When working on a task that requires code changes, Claude can work in an isolated git worktree. This keeps your main branch clean while Claude works on a feature branch in a separate directory.
|
|
210
|
+
|
|
211
|
+
### Starting a Session with a Worktree
|
|
212
|
+
|
|
213
|
+
Specify a branch when starting:
|
|
214
|
+
|
|
215
|
+
```
|
|
216
|
+
@claude-code on branch feature/add-auth implement user authentication
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
Or use the worktree command:
|
|
220
|
+
|
|
221
|
+
```
|
|
222
|
+
@claude-code !worktree feature/add-auth implement user authentication
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
### Worktree Commands
|
|
226
|
+
|
|
227
|
+
| Command | Description |
|
|
228
|
+
|:--------|:------------|
|
|
229
|
+
| `!worktree <branch>` | Create worktree and switch to it |
|
|
230
|
+
| `!worktree list` | List all worktrees for this repo |
|
|
231
|
+
| `!worktree switch <branch>` | Switch to an existing worktree |
|
|
232
|
+
| `!worktree remove <branch>` | Remove a worktree |
|
|
233
|
+
| `!worktree off` | Disable worktree prompts for this session |
|
|
234
|
+
|
|
235
|
+
### How It Works
|
|
236
|
+
|
|
237
|
+
1. Creates a new worktree at `../<repo>-worktrees/<branch>/`
|
|
238
|
+
2. Creates or checks out the specified branch
|
|
239
|
+
3. Claude works in the worktree directory
|
|
240
|
+
4. Your main working directory stays untouched
|
|
241
|
+
|
|
242
|
+
### Environment Variable
|
|
243
|
+
|
|
244
|
+
| Variable | Description |
|
|
245
|
+
|----------|-------------|
|
|
246
|
+
| `WORKTREE_MODE` | `prompt` (ask on new sessions), `require` (always require branch), `off` (disable) |
|
|
247
|
+
|
|
179
248
|
## Interactive Features
|
|
180
249
|
|
|
181
250
|
### Permission Approval
|
|
@@ -237,10 +306,13 @@ Stop a running session:
|
|
|
237
306
|
|
|
238
307
|
## Access Control
|
|
239
308
|
|
|
240
|
-
Set `
|
|
309
|
+
Set `allowedUsers` in your platform config to restrict who can use the bot:
|
|
241
310
|
|
|
242
|
-
```
|
|
243
|
-
|
|
311
|
+
```yaml
|
|
312
|
+
platforms:
|
|
313
|
+
- id: mattermost-main
|
|
314
|
+
# ...
|
|
315
|
+
allowedUsers: [alice, bob, carol]
|
|
244
316
|
```
|
|
245
317
|
|
|
246
318
|
- Only listed users can start sessions
|
|
@@ -248,24 +320,57 @@ ALLOWED_USERS=alice,bob,carol
|
|
|
248
320
|
- Session owners can `!invite` others temporarily
|
|
249
321
|
- Empty = anyone can use (be careful!)
|
|
250
322
|
|
|
251
|
-
##
|
|
323
|
+
## Configuration
|
|
324
|
+
|
|
325
|
+
Configuration is stored in YAML format at `~/.config/claude-threads/config.yaml`.
|
|
326
|
+
|
|
327
|
+
### Example Config
|
|
328
|
+
|
|
329
|
+
```yaml
|
|
330
|
+
version: 1
|
|
331
|
+
workingDir: /home/user/repos/myproject
|
|
332
|
+
chrome: false
|
|
333
|
+
worktreeMode: prompt
|
|
334
|
+
|
|
335
|
+
platforms:
|
|
336
|
+
- id: mattermost-main
|
|
337
|
+
type: mattermost
|
|
338
|
+
displayName: Main Team
|
|
339
|
+
url: https://chat.example.com
|
|
340
|
+
token: your-bot-token
|
|
341
|
+
channelId: abc123
|
|
342
|
+
botName: claude-code
|
|
343
|
+
allowedUsers: [alice, bob]
|
|
344
|
+
skipPermissions: false
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
### Global Settings
|
|
348
|
+
|
|
349
|
+
| Setting | Description |
|
|
350
|
+
|---------|-------------|
|
|
351
|
+
| `workingDir` | Default working directory for Claude |
|
|
352
|
+
| `chrome` | Enable Chrome integration (`true`/`false`) |
|
|
353
|
+
| `worktreeMode` | Git worktree mode: `off`, `prompt`, or `require` |
|
|
354
|
+
|
|
355
|
+
### Platform Settings (Mattermost)
|
|
356
|
+
|
|
357
|
+
| Setting | Description |
|
|
358
|
+
|---------|-------------|
|
|
359
|
+
| `url` | Mattermost server URL |
|
|
360
|
+
| `token` | Bot access token |
|
|
361
|
+
| `channelId` | Channel to listen in |
|
|
362
|
+
| `botName` | Mention name (default: `claude-code`) |
|
|
363
|
+
| `allowedUsers` | List of usernames who can use the bot |
|
|
364
|
+
| `skipPermissions` | Auto-approve actions (`true`/`false`) |
|
|
365
|
+
|
|
366
|
+
### Environment Variables
|
|
252
367
|
|
|
253
368
|
| Variable | Description |
|
|
254
369
|
|----------|-------------|
|
|
255
|
-
| `MATTERMOST_URL` | Server URL |
|
|
256
|
-
| `MATTERMOST_TOKEN` | Bot token |
|
|
257
|
-
| `MATTERMOST_CHANNEL_ID` | Channel to listen in |
|
|
258
|
-
| `MATTERMOST_BOT_NAME` | Mention name (default: `claude-code`) |
|
|
259
|
-
| `ALLOWED_USERS` | Comma-separated usernames |
|
|
260
|
-
| `SKIP_PERMISSIONS` | `true` to auto-approve actions |
|
|
261
370
|
| `MAX_SESSIONS` | Max concurrent sessions (default: `5`) |
|
|
262
371
|
| `SESSION_TIMEOUT_MS` | Idle timeout in ms (default: `1800000` = 30 min) |
|
|
263
372
|
| `NO_UPDATE_NOTIFIER` | Set to `1` to disable update checks |
|
|
264
|
-
|
|
265
|
-
Config file locations (in priority order):
|
|
266
|
-
1. `./.env` (current directory)
|
|
267
|
-
2. `~/.config/claude-threads/.env`
|
|
268
|
-
3. `~/.claude-threads.env`
|
|
373
|
+
| `DEBUG` | Set to `1` for verbose logging |
|
|
269
374
|
|
|
270
375
|
## Code Display
|
|
271
376
|
|
package/dist/claude/cli.d.ts
CHANGED
|
@@ -16,6 +16,13 @@ export interface ImageContentBlock {
|
|
|
16
16
|
};
|
|
17
17
|
}
|
|
18
18
|
export type ContentBlock = TextContentBlock | ImageContentBlock;
|
|
19
|
+
export interface PlatformMcpConfig {
|
|
20
|
+
type: string;
|
|
21
|
+
url: string;
|
|
22
|
+
token: string;
|
|
23
|
+
channelId: string;
|
|
24
|
+
allowedUsers: string[];
|
|
25
|
+
}
|
|
19
26
|
export interface ClaudeCliOptions {
|
|
20
27
|
workingDir: string;
|
|
21
28
|
threadId?: string;
|
|
@@ -23,6 +30,7 @@ export interface ClaudeCliOptions {
|
|
|
23
30
|
sessionId?: string;
|
|
24
31
|
resume?: boolean;
|
|
25
32
|
chrome?: boolean;
|
|
33
|
+
platformConfig?: PlatformMcpConfig;
|
|
26
34
|
}
|
|
27
35
|
export declare class ClaudeCli extends EventEmitter {
|
|
28
36
|
private process;
|
package/dist/claude/cli.js
CHANGED
|
@@ -36,20 +36,28 @@ export class ClaudeCli extends EventEmitter {
|
|
|
36
36
|
else {
|
|
37
37
|
// Configure the permission MCP server
|
|
38
38
|
const mcpServerPath = this.getMcpServerPath();
|
|
39
|
+
// Platform config is required for MCP permission server
|
|
40
|
+
const platformConfig = this.options.platformConfig;
|
|
41
|
+
if (!platformConfig) {
|
|
42
|
+
throw new Error('platformConfig is required when skipPermissions is false');
|
|
43
|
+
}
|
|
44
|
+
// Platform-agnostic environment variables for MCP permission server
|
|
45
|
+
const mcpEnv = {
|
|
46
|
+
PLATFORM_TYPE: platformConfig.type,
|
|
47
|
+
PLATFORM_URL: platformConfig.url,
|
|
48
|
+
PLATFORM_TOKEN: platformConfig.token,
|
|
49
|
+
PLATFORM_CHANNEL_ID: platformConfig.channelId,
|
|
50
|
+
PLATFORM_THREAD_ID: this.options.threadId || '',
|
|
51
|
+
ALLOWED_USERS: platformConfig.allowedUsers.join(','),
|
|
52
|
+
DEBUG: this.debug ? '1' : '',
|
|
53
|
+
};
|
|
39
54
|
const mcpConfig = {
|
|
40
55
|
mcpServers: {
|
|
41
56
|
'claude-threads-permissions': {
|
|
42
57
|
type: 'stdio',
|
|
43
58
|
command: 'node',
|
|
44
59
|
args: [mcpServerPath],
|
|
45
|
-
env:
|
|
46
|
-
MM_THREAD_ID: this.options.threadId || '',
|
|
47
|
-
MATTERMOST_URL: process.env.MATTERMOST_URL || '',
|
|
48
|
-
MATTERMOST_TOKEN: process.env.MATTERMOST_TOKEN || '',
|
|
49
|
-
MATTERMOST_CHANNEL_ID: process.env.MATTERMOST_CHANNEL_ID || '',
|
|
50
|
-
ALLOWED_USERS: process.env.ALLOWED_USERS || '',
|
|
51
|
-
DEBUG: this.debug ? '1' : '',
|
|
52
|
-
},
|
|
60
|
+
env: mcpEnv,
|
|
53
61
|
},
|
|
54
62
|
},
|
|
55
63
|
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export declare const CONFIG_PATH: string;
|
|
2
|
+
export type WorktreeMode = 'off' | 'prompt' | 'require';
|
|
3
|
+
export interface NewConfig {
|
|
4
|
+
version: number;
|
|
5
|
+
workingDir: string;
|
|
6
|
+
chrome: boolean;
|
|
7
|
+
worktreeMode: WorktreeMode;
|
|
8
|
+
platforms: PlatformInstanceConfig[];
|
|
9
|
+
}
|
|
10
|
+
export interface PlatformInstanceConfig {
|
|
11
|
+
id: string;
|
|
12
|
+
type: 'mattermost' | 'slack';
|
|
13
|
+
displayName: string;
|
|
14
|
+
[key: string]: unknown;
|
|
15
|
+
}
|
|
16
|
+
export interface MattermostPlatformConfig extends PlatformInstanceConfig {
|
|
17
|
+
type: 'mattermost';
|
|
18
|
+
url: string;
|
|
19
|
+
token: string;
|
|
20
|
+
channelId: string;
|
|
21
|
+
botName: string;
|
|
22
|
+
allowedUsers: string[];
|
|
23
|
+
skipPermissions: boolean;
|
|
24
|
+
}
|
|
25
|
+
export interface SlackPlatformConfig extends PlatformInstanceConfig {
|
|
26
|
+
type: 'slack';
|
|
27
|
+
botToken: string;
|
|
28
|
+
appToken: string;
|
|
29
|
+
channelId: string;
|
|
30
|
+
botName: string;
|
|
31
|
+
allowedUsers: string[];
|
|
32
|
+
skipPermissions: boolean;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Load config from YAML file
|
|
36
|
+
*/
|
|
37
|
+
export declare function loadConfigWithMigration(): NewConfig | null;
|
|
38
|
+
/**
|
|
39
|
+
* Save config to YAML file
|
|
40
|
+
*/
|
|
41
|
+
export declare function saveConfig(config: NewConfig): void;
|
|
42
|
+
/**
|
|
43
|
+
* Check if config exists
|
|
44
|
+
*/
|
|
45
|
+
export declare function configExists(): boolean;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'fs';
|
|
2
|
+
import YAML from 'yaml';
|
|
3
|
+
import { resolve, dirname } from 'path';
|
|
4
|
+
import { homedir } from 'os';
|
|
5
|
+
// YAML config path
|
|
6
|
+
export const CONFIG_PATH = resolve(homedir(), '.config', 'claude-threads', 'config.yaml');
|
|
7
|
+
// =============================================================================
|
|
8
|
+
// Config Loading
|
|
9
|
+
// =============================================================================
|
|
10
|
+
/**
|
|
11
|
+
* Load config from YAML file
|
|
12
|
+
*/
|
|
13
|
+
export function loadConfigWithMigration() {
|
|
14
|
+
if (existsSync(CONFIG_PATH)) {
|
|
15
|
+
const content = readFileSync(CONFIG_PATH, 'utf-8');
|
|
16
|
+
return YAML.parse(content);
|
|
17
|
+
}
|
|
18
|
+
return null; // No config found
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Save config to YAML file
|
|
22
|
+
*/
|
|
23
|
+
export function saveConfig(config) {
|
|
24
|
+
const configDir = dirname(CONFIG_PATH);
|
|
25
|
+
if (!existsSync(configDir)) {
|
|
26
|
+
mkdirSync(configDir, { recursive: true });
|
|
27
|
+
}
|
|
28
|
+
writeFileSync(CONFIG_PATH, YAML.stringify(config), 'utf-8');
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Check if config exists
|
|
32
|
+
*/
|
|
33
|
+
export function configExists() {
|
|
34
|
+
return existsSync(CONFIG_PATH);
|
|
35
|
+
}
|
package/dist/config.d.ts
CHANGED
|
@@ -1,7 +1,14 @@
|
|
|
1
|
-
/**
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Configuration type exports
|
|
3
|
+
*
|
|
4
|
+
* Re-exports types from config/migration.ts for convenience.
|
|
5
|
+
* The actual config loading and migration logic is in config/migration.ts.
|
|
6
|
+
*/
|
|
7
|
+
import type { WorktreeMode as WorktreeModeType } from './config/migration.js';
|
|
8
|
+
export type { NewConfig, PlatformInstanceConfig, MattermostPlatformConfig, WorktreeMode, } from './config/migration.js';
|
|
9
|
+
/**
|
|
10
|
+
* CLI arguments that can override config
|
|
11
|
+
*/
|
|
5
12
|
export interface CliArgs {
|
|
6
13
|
url?: string;
|
|
7
14
|
token?: string;
|
|
@@ -10,18 +17,5 @@ export interface CliArgs {
|
|
|
10
17
|
allowedUsers?: string;
|
|
11
18
|
skipPermissions?: boolean;
|
|
12
19
|
chrome?: boolean;
|
|
13
|
-
worktreeMode?:
|
|
20
|
+
worktreeMode?: WorktreeModeType;
|
|
14
21
|
}
|
|
15
|
-
export interface Config {
|
|
16
|
-
mattermost: {
|
|
17
|
-
url: string;
|
|
18
|
-
token: string;
|
|
19
|
-
channelId: string;
|
|
20
|
-
botName: string;
|
|
21
|
-
};
|
|
22
|
-
allowedUsers: string[];
|
|
23
|
-
skipPermissions: boolean;
|
|
24
|
-
chrome: boolean;
|
|
25
|
-
worktreeMode: WorktreeMode;
|
|
26
|
-
}
|
|
27
|
-
export declare function loadConfig(cliArgs?: CliArgs): Config;
|
package/dist/config.js
CHANGED
|
@@ -1,94 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
resolve(process.cwd(), '.env'), // Current directory
|
|
9
|
-
resolve(homedir(), '.config', 'claude-threads', '.env'), // ~/.config/claude-threads/.env
|
|
10
|
-
resolve(homedir(), '.claude-threads.env'), // ~/.claude-threads.env
|
|
11
|
-
];
|
|
12
|
-
function loadEnv() {
|
|
13
|
-
if (envLoaded)
|
|
14
|
-
return;
|
|
15
|
-
envLoaded = true;
|
|
16
|
-
for (const envPath of ENV_PATHS) {
|
|
17
|
-
if (existsSync(envPath)) {
|
|
18
|
-
if (process.env.DEBUG === '1' || process.argv.includes('--debug')) {
|
|
19
|
-
console.log(` [config] Loading from: ${envPath}`);
|
|
20
|
-
}
|
|
21
|
-
config({ path: envPath });
|
|
22
|
-
break;
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
/** Check if any .env config file exists */
|
|
27
|
-
export function configExists() {
|
|
28
|
-
return ENV_PATHS.some(p => existsSync(p));
|
|
29
|
-
}
|
|
30
|
-
function getRequired(cliValue, envName, name) {
|
|
31
|
-
const value = cliValue || process.env[envName];
|
|
32
|
-
if (!value) {
|
|
33
|
-
throw new Error(`Missing required config: ${name}. Set ${envName} in .env or use --${name.toLowerCase().replace(/ /g, '-')} flag.`);
|
|
34
|
-
}
|
|
35
|
-
return value;
|
|
36
|
-
}
|
|
37
|
-
export function loadConfig(cliArgs) {
|
|
38
|
-
loadEnv();
|
|
39
|
-
// CLI args take priority over env vars
|
|
40
|
-
const url = getRequired(cliArgs?.url, 'MATTERMOST_URL', 'url');
|
|
41
|
-
const token = getRequired(cliArgs?.token, 'MATTERMOST_TOKEN', 'token');
|
|
42
|
-
const channelId = getRequired(cliArgs?.channel, 'MATTERMOST_CHANNEL_ID', 'channel');
|
|
43
|
-
const botName = cliArgs?.botName || process.env.MATTERMOST_BOT_NAME || 'claude-code';
|
|
44
|
-
const allowedUsersStr = cliArgs?.allowedUsers || process.env.ALLOWED_USERS || '';
|
|
45
|
-
const allowedUsers = allowedUsersStr
|
|
46
|
-
.split(',')
|
|
47
|
-
.map(u => u.trim())
|
|
48
|
-
.filter(u => u.length > 0);
|
|
49
|
-
// CLI --skip-permissions or --no-skip-permissions takes priority
|
|
50
|
-
// Then env SKIP_PERMISSIONS, then legacy flag
|
|
51
|
-
let skipPermissions;
|
|
52
|
-
if (cliArgs?.skipPermissions !== undefined) {
|
|
53
|
-
// CLI explicitly set (--skip-permissions or --no-skip-permissions)
|
|
54
|
-
skipPermissions = cliArgs.skipPermissions;
|
|
55
|
-
}
|
|
56
|
-
else {
|
|
57
|
-
skipPermissions = process.env.SKIP_PERMISSIONS === 'true' ||
|
|
58
|
-
process.argv.includes('--dangerously-skip-permissions');
|
|
59
|
-
}
|
|
60
|
-
// Chrome integration: CLI flag or env var
|
|
61
|
-
let chrome;
|
|
62
|
-
if (cliArgs?.chrome !== undefined) {
|
|
63
|
-
chrome = cliArgs.chrome;
|
|
64
|
-
}
|
|
65
|
-
else {
|
|
66
|
-
chrome = process.env.CLAUDE_CHROME === 'true';
|
|
67
|
-
}
|
|
68
|
-
// Worktree mode: CLI flag or env var, default to 'prompt'
|
|
69
|
-
let worktreeMode;
|
|
70
|
-
if (cliArgs?.worktreeMode !== undefined) {
|
|
71
|
-
worktreeMode = cliArgs.worktreeMode;
|
|
72
|
-
}
|
|
73
|
-
else {
|
|
74
|
-
const envValue = process.env.WORKTREE_MODE?.toLowerCase();
|
|
75
|
-
if (envValue === 'off' || envValue === 'prompt' || envValue === 'require') {
|
|
76
|
-
worktreeMode = envValue;
|
|
77
|
-
}
|
|
78
|
-
else {
|
|
79
|
-
worktreeMode = 'prompt'; // Default
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
return {
|
|
83
|
-
mattermost: {
|
|
84
|
-
url: url.replace(/\/$/, ''), // Remove trailing slash
|
|
85
|
-
token,
|
|
86
|
-
channelId,
|
|
87
|
-
botName,
|
|
88
|
-
},
|
|
89
|
-
allowedUsers,
|
|
90
|
-
skipPermissions,
|
|
91
|
-
chrome,
|
|
92
|
-
worktreeMode,
|
|
93
|
-
};
|
|
94
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Configuration type exports
|
|
3
|
+
*
|
|
4
|
+
* Re-exports types from config/migration.ts for convenience.
|
|
5
|
+
* The actual config loading and migration logic is in config/migration.ts.
|
|
6
|
+
*/
|
|
7
|
+
export {};
|
package/dist/git/worktree.d.ts
CHANGED
|
@@ -21,10 +21,6 @@ export declare function hasUncommittedChanges(dir: string): Promise<boolean>;
|
|
|
21
21
|
* List all worktrees for a repository
|
|
22
22
|
*/
|
|
23
23
|
export declare function listWorktrees(repoRoot: string): Promise<WorktreeInfo[]>;
|
|
24
|
-
/**
|
|
25
|
-
* Check if a branch exists (local or remote)
|
|
26
|
-
*/
|
|
27
|
-
export declare function branchExists(repoRoot: string, branch: string): Promise<boolean>;
|
|
28
24
|
/**
|
|
29
25
|
* Generate the worktree directory path
|
|
30
26
|
* Creates path like: /path/to/repo-worktrees/branch-name-abc123
|
package/dist/git/worktree.js
CHANGED
|
@@ -119,7 +119,7 @@ export async function listWorktrees(repoRoot) {
|
|
|
119
119
|
/**
|
|
120
120
|
* Check if a branch exists (local or remote)
|
|
121
121
|
*/
|
|
122
|
-
|
|
122
|
+
async function branchExists(repoRoot, branch) {
|
|
123
123
|
try {
|
|
124
124
|
// Check local branches
|
|
125
125
|
await execGit(['rev-parse', '--verify', `refs/heads/${branch}`], repoRoot);
|