claude-threads 0.12.0 → 0.13.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 +27 -0
- package/README.md +73 -12
- package/dist/index.js +9 -3
- package/dist/logo.d.ts +1 -1
- package/dist/logo.js +3 -3
- package/dist/onboarding.d.ts +1 -1
- package/dist/onboarding.js +96 -19
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,33 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.13.0] - 2025-12-29
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- **`--setup` flag** - Re-run interactive setup wizard to reconfigure settings
|
|
14
|
+
- Existing .env values are used as defaults (press Enter to keep)
|
|
15
|
+
- Token field allows keeping existing token without re-entering
|
|
16
|
+
- New settings added since initial setup are presented with built-in defaults
|
|
17
|
+
- Config saved back to original location
|
|
18
|
+
- **Chrome and worktree settings in onboarding** - New setup prompts for:
|
|
19
|
+
- Chrome integration (yes/no)
|
|
20
|
+
- Git worktree mode (prompt/off/require)
|
|
21
|
+
|
|
22
|
+
### Changed
|
|
23
|
+
- **Improved README** - New tagline and improved intro section
|
|
24
|
+
- **Worktree documentation** - Added comprehensive Git Worktrees section to README
|
|
25
|
+
- **Updated CLI options** - Added `--chrome`, `--no-chrome`, `--worktree-mode`, `--setup` to README
|
|
26
|
+
|
|
27
|
+
### Fixed
|
|
28
|
+
- **Warning icon alignment** - Fixed spacing of ⚠️ icon in CLI startup output
|
|
29
|
+
- **WORKTREE_MODE documentation** - Fixed incorrect values in README (was `always`/`never`, now correctly `off`/`prompt`/`require`)
|
|
30
|
+
|
|
31
|
+
## [0.12.1] - 2025-12-29
|
|
32
|
+
|
|
33
|
+
### Fixed
|
|
34
|
+
- **Fix logo star positioning** - Right bottom star shifted left as intended
|
|
35
|
+
- **Update README** - Title changed to "Claude Threads" and logo added
|
|
36
|
+
|
|
10
37
|
## [0.12.0] - 2025-12-29
|
|
11
38
|
|
|
12
39
|
### Changed
|
package/README.md
CHANGED
|
@@ -1,9 +1,17 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Claude Threads
|
|
2
|
+
|
|
3
|
+
```
|
|
4
|
+
✴ ▄█▀ ███ ✴ claude-threads
|
|
5
|
+
✴ █▀ █ ✴ Mattermost × Claude Code
|
|
6
|
+
✴ ▀█▄ █ ✴
|
|
7
|
+
```
|
|
2
8
|
|
|
3
9
|
[](https://www.npmjs.com/package/claude-threads)
|
|
4
10
|
[](https://opensource.org/licenses/MIT)
|
|
5
11
|
|
|
6
|
-
|
|
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.*
|
|
7
15
|
|
|
8
16
|
## Features
|
|
9
17
|
|
|
@@ -95,16 +103,20 @@ In Mattermost, mention the bot:
|
|
|
95
103
|
claude-threads [options]
|
|
96
104
|
|
|
97
105
|
Options:
|
|
98
|
-
--url <url>
|
|
99
|
-
--token <token>
|
|
100
|
-
--channel <id>
|
|
101
|
-
--bot-name <name>
|
|
102
|
-
--allowed-users <list>
|
|
103
|
-
--skip-permissions
|
|
104
|
-
--no-skip-permissions
|
|
105
|
-
--
|
|
106
|
-
--
|
|
107
|
-
--
|
|
106
|
+
--url <url> Mattermost server URL
|
|
107
|
+
--token <token> Bot token
|
|
108
|
+
--channel <id> Channel ID
|
|
109
|
+
--bot-name <name> Bot mention name (default: claude-code)
|
|
110
|
+
--allowed-users <list> Comma-separated allowed usernames
|
|
111
|
+
--skip-permissions Skip permission prompts (auto-approve)
|
|
112
|
+
--no-skip-permissions Enable permission prompts (override env)
|
|
113
|
+
--chrome Enable Chrome integration
|
|
114
|
+
--no-chrome Disable Chrome integration
|
|
115
|
+
--worktree-mode <mode> Git worktree mode: off, prompt, require
|
|
116
|
+
--setup Re-run setup wizard (reconfigure settings)
|
|
117
|
+
--debug Enable debug logging
|
|
118
|
+
--version Show version
|
|
119
|
+
--help Show help
|
|
108
120
|
```
|
|
109
121
|
|
|
110
122
|
CLI options override environment variables.
|
|
@@ -117,11 +129,17 @@ Type `!help` in any session thread to see available commands:
|
|
|
117
129
|
|:--------|:------------|
|
|
118
130
|
| `!help` | Show available commands |
|
|
119
131
|
| `!release-notes` | Show release notes for current version |
|
|
132
|
+
| `!context` | Show context usage (tokens used/remaining) |
|
|
133
|
+
| `!cost` | Show token usage and cost for this session |
|
|
134
|
+
| `!compact` | Compress context to free up space |
|
|
120
135
|
| `!cd <path>` | Change working directory (restarts Claude) |
|
|
136
|
+
| `!worktree <branch>` | Create and switch to a git worktree |
|
|
121
137
|
| `!invite @user` | Invite a user to this session |
|
|
122
138
|
| `!kick @user` | Remove an invited user |
|
|
123
139
|
| `!permissions interactive` | Enable interactive permissions |
|
|
140
|
+
| `!escape` | Interrupt current task (keeps session active) |
|
|
124
141
|
| `!stop` | Stop this session |
|
|
142
|
+
| `!kill` | Emergency shutdown (kills ALL sessions, exits bot) |
|
|
125
143
|
|
|
126
144
|
> **Note:** Commands use `!` prefix instead of `/` to avoid conflicts with Mattermost's slash commands.
|
|
127
145
|
|
|
@@ -170,6 +188,47 @@ If the bot is running with `--skip-permissions` (auto mode), you can enable inte
|
|
|
170
188
|
|
|
171
189
|
This allows collaboration by requiring approval for Claude's actions. Note: you can only downgrade (auto → interactive), not upgrade - this ensures security.
|
|
172
190
|
|
|
191
|
+
## Git Worktrees
|
|
192
|
+
|
|
193
|
+
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.
|
|
194
|
+
|
|
195
|
+
### Starting a Session with a Worktree
|
|
196
|
+
|
|
197
|
+
Specify a branch when starting:
|
|
198
|
+
|
|
199
|
+
```
|
|
200
|
+
@claude-code on branch feature/add-auth implement user authentication
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
Or use the worktree command:
|
|
204
|
+
|
|
205
|
+
```
|
|
206
|
+
@claude-code !worktree feature/add-auth implement user authentication
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### Worktree Commands
|
|
210
|
+
|
|
211
|
+
| Command | Description |
|
|
212
|
+
|:--------|:------------|
|
|
213
|
+
| `!worktree <branch>` | Create worktree and switch to it |
|
|
214
|
+
| `!worktree list` | List all worktrees for this repo |
|
|
215
|
+
| `!worktree switch <branch>` | Switch to an existing worktree |
|
|
216
|
+
| `!worktree remove <branch>` | Remove a worktree |
|
|
217
|
+
| `!worktree off` | Disable worktree prompts for this session |
|
|
218
|
+
|
|
219
|
+
### How It Works
|
|
220
|
+
|
|
221
|
+
1. Creates a new worktree at `../<repo>-worktrees/<branch>/`
|
|
222
|
+
2. Creates or checks out the specified branch
|
|
223
|
+
3. Claude works in the worktree directory
|
|
224
|
+
4. Your main working directory stays untouched
|
|
225
|
+
|
|
226
|
+
### Environment Variable
|
|
227
|
+
|
|
228
|
+
| Variable | Description |
|
|
229
|
+
|----------|-------------|
|
|
230
|
+
| `WORKTREE_MODE` | `prompt` (ask on new sessions), `require` (always require branch), `off` (disable) |
|
|
231
|
+
|
|
173
232
|
## Interactive Features
|
|
174
233
|
|
|
175
234
|
### Permission Approval
|
|
@@ -252,6 +311,8 @@ ALLOWED_USERS=alice,bob,carol
|
|
|
252
311
|
| `MATTERMOST_BOT_NAME` | Mention name (default: `claude-code`) |
|
|
253
312
|
| `ALLOWED_USERS` | Comma-separated usernames |
|
|
254
313
|
| `SKIP_PERMISSIONS` | `true` to auto-approve actions |
|
|
314
|
+
| `CLAUDE_CHROME` | `true` to enable Chrome integration |
|
|
315
|
+
| `WORKTREE_MODE` | `off`, `prompt`, or `require` (default: `prompt`) |
|
|
255
316
|
| `MAX_SESSIONS` | Max concurrent sessions (default: `5`) |
|
|
256
317
|
| `SESSION_TIMEOUT_MS` | Idle timeout in ms (default: `1800000` = 30 min) |
|
|
257
318
|
| `NO_UPDATE_NOTIFIER` | Set to `1` to disable update checks |
|
package/dist/index.js
CHANGED
|
@@ -29,6 +29,8 @@ program
|
|
|
29
29
|
.option('--no-skip-permissions', 'Enable interactive permission prompts (override env)')
|
|
30
30
|
.option('--chrome', 'Enable Claude in Chrome integration')
|
|
31
31
|
.option('--no-chrome', 'Disable Claude in Chrome integration')
|
|
32
|
+
.option('--worktree-mode <mode>', 'Git worktree mode: off, prompt, require (default: prompt)')
|
|
33
|
+
.option('--setup', 'Run interactive setup wizard (reconfigure existing settings)')
|
|
32
34
|
.option('--debug', 'Enable debug logging')
|
|
33
35
|
.parse();
|
|
34
36
|
const opts = program.opts();
|
|
@@ -52,10 +54,14 @@ async function main() {
|
|
|
52
54
|
allowedUsers: opts.allowedUsers,
|
|
53
55
|
skipPermissions: opts.skipPermissions,
|
|
54
56
|
chrome: opts.chrome,
|
|
57
|
+
worktreeMode: opts.worktreeMode,
|
|
55
58
|
};
|
|
56
59
|
// Check if we need onboarding
|
|
57
|
-
if (
|
|
58
|
-
await runOnboarding();
|
|
60
|
+
if (opts.setup) {
|
|
61
|
+
await runOnboarding(true); // reconfigure mode
|
|
62
|
+
}
|
|
63
|
+
else if (!configExists() && !hasRequiredCliArgs(opts)) {
|
|
64
|
+
await runOnboarding(false); // first-time mode
|
|
59
65
|
}
|
|
60
66
|
const workingDir = process.cwd();
|
|
61
67
|
const config = loadConfig(cliArgs);
|
|
@@ -68,7 +74,7 @@ async function main() {
|
|
|
68
74
|
console.log(` 💬 ${cyan('@' + config.mattermost.botName)}`);
|
|
69
75
|
console.log(` 🌐 ${dim(config.mattermost.url)}`);
|
|
70
76
|
if (config.skipPermissions) {
|
|
71
|
-
console.log(` ⚠️
|
|
77
|
+
console.log(` ⚠️ ${dim('Permissions disabled')}`);
|
|
72
78
|
}
|
|
73
79
|
else {
|
|
74
80
|
console.log(` 🔐 ${dim('Interactive permissions')}`);
|
package/dist/logo.d.ts
CHANGED
|
@@ -12,7 +12,7 @@ export declare const CLI_LOGO: string;
|
|
|
12
12
|
* ASCII logo for Mattermost (plain text, no ANSI codes)
|
|
13
13
|
* Use getMattermostLogo(version) instead to include version
|
|
14
14
|
*/
|
|
15
|
-
export declare const MATTERMOST_LOGO = "```\n \u2734 \u2584\u2588\u2580 \u2588\u2588\u2588 \u2734 claude-threads\n\u2734 \u2588\u2580 \u2588 \u2734 Mattermost \u00D7 Claude Code\n\u2734
|
|
15
|
+
export declare const MATTERMOST_LOGO = "```\n \u2734 \u2584\u2588\u2580 \u2588\u2588\u2588 \u2734 claude-threads\n\u2734 \u2588\u2580 \u2588 \u2734 Mattermost \u00D7 Claude Code\n \u2734 \u2580\u2588\u2584 \u2588 \u2734\n```";
|
|
16
16
|
/**
|
|
17
17
|
* Get ASCII logo for Mattermost with version included
|
|
18
18
|
*/
|
package/dist/logo.js
CHANGED
|
@@ -20,7 +20,7 @@ const colors = {
|
|
|
20
20
|
export const CLI_LOGO = `
|
|
21
21
|
${colors.orange} ✴${colors.reset} ${colors.blue}▄█▀ ███${colors.reset} ${colors.orange}✴${colors.reset} ${colors.bold}claude-threads${colors.reset}
|
|
22
22
|
${colors.orange}✴${colors.reset} ${colors.blue}█▀ █${colors.reset} ${colors.orange}✴${colors.reset} ${colors.dim}Mattermost × Claude Code${colors.reset}
|
|
23
|
-
${colors.orange}✴${colors.reset}
|
|
23
|
+
${colors.orange}✴${colors.reset} ${colors.blue}▀█▄ █${colors.reset} ${colors.orange}✴${colors.reset}
|
|
24
24
|
`;
|
|
25
25
|
/**
|
|
26
26
|
* ASCII logo for Mattermost (plain text, no ANSI codes)
|
|
@@ -29,7 +29,7 @@ ${colors.orange}✴${colors.reset} ${colors.blue}▀█▄ █${colors.reset}
|
|
|
29
29
|
export const MATTERMOST_LOGO = `\`\`\`
|
|
30
30
|
✴ ▄█▀ ███ ✴ claude-threads
|
|
31
31
|
✴ █▀ █ ✴ Mattermost × Claude Code
|
|
32
|
-
✴
|
|
32
|
+
✴ ▀█▄ █ ✴
|
|
33
33
|
\`\`\``;
|
|
34
34
|
/**
|
|
35
35
|
* Get ASCII logo for Mattermost with version included
|
|
@@ -38,7 +38,7 @@ export function getMattermostLogo(version) {
|
|
|
38
38
|
return `\`\`\`
|
|
39
39
|
✴ ▄█▀ ███ ✴ claude-threads v${version}
|
|
40
40
|
✴ █▀ █ ✴ Mattermost × Claude Code
|
|
41
|
-
✴
|
|
41
|
+
✴ ▀█▄ █ ✴
|
|
42
42
|
\`\`\``;
|
|
43
43
|
}
|
|
44
44
|
/**
|
package/dist/onboarding.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare function runOnboarding(): Promise<void>;
|
|
1
|
+
export declare function runOnboarding(reconfigure?: boolean): Promise<void>;
|
package/dist/onboarding.js
CHANGED
|
@@ -1,16 +1,47 @@
|
|
|
1
1
|
import prompts from 'prompts';
|
|
2
|
-
import { writeFileSync, mkdirSync } from 'fs';
|
|
2
|
+
import { writeFileSync, mkdirSync, readFileSync, existsSync } from 'fs';
|
|
3
3
|
import { homedir } from 'os';
|
|
4
|
-
import { resolve } from 'path';
|
|
4
|
+
import { resolve, dirname } from 'path';
|
|
5
|
+
import { parse } from 'dotenv';
|
|
5
6
|
const bold = (s) => `\x1b[1m${s}\x1b[0m`;
|
|
6
7
|
const dim = (s) => `\x1b[2m${s}\x1b[0m`;
|
|
7
8
|
const green = (s) => `\x1b[32m${s}\x1b[0m`;
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
// Paths to search for .env files (in order of priority)
|
|
10
|
+
const ENV_PATHS = [
|
|
11
|
+
resolve(process.cwd(), '.env'),
|
|
12
|
+
resolve(homedir(), '.config', 'claude-threads', '.env'),
|
|
13
|
+
resolve(homedir(), '.claude-threads.env'),
|
|
14
|
+
];
|
|
15
|
+
function loadExistingConfig() {
|
|
16
|
+
for (const envPath of ENV_PATHS) {
|
|
17
|
+
if (existsSync(envPath)) {
|
|
18
|
+
try {
|
|
19
|
+
const content = readFileSync(envPath, 'utf-8');
|
|
20
|
+
return { path: envPath, values: parse(content) };
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return { path: null, values: {} };
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return { path: null, values: {} };
|
|
28
|
+
}
|
|
29
|
+
export async function runOnboarding(reconfigure = false) {
|
|
30
|
+
const { path: existingPath, values: existing } = reconfigure ? loadExistingConfig() : { path: null, values: {} };
|
|
31
|
+
const hasExisting = Object.keys(existing).length > 0;
|
|
12
32
|
console.log('');
|
|
13
|
-
|
|
33
|
+
if (reconfigure && hasExisting) {
|
|
34
|
+
console.log(bold(' Reconfiguring claude-threads'));
|
|
35
|
+
console.log(dim(' ─────────────────────────────────'));
|
|
36
|
+
console.log('');
|
|
37
|
+
console.log(dim(' Press Enter to keep existing values.'));
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
console.log(bold(' Welcome to claude-threads!'));
|
|
41
|
+
console.log(dim(' ─────────────────────────────────'));
|
|
42
|
+
console.log('');
|
|
43
|
+
console.log(' No configuration found. Let\'s set things up.');
|
|
44
|
+
}
|
|
14
45
|
console.log('');
|
|
15
46
|
console.log(dim(' You\'ll need:'));
|
|
16
47
|
console.log(dim(' • A Mattermost bot account with a token'));
|
|
@@ -23,25 +54,41 @@ export async function runOnboarding() {
|
|
|
23
54
|
console.log(dim(' Setup cancelled.'));
|
|
24
55
|
process.exit(0);
|
|
25
56
|
};
|
|
57
|
+
// Helper to get worktree mode index
|
|
58
|
+
const worktreeModeIndex = (mode) => {
|
|
59
|
+
if (mode === 'off')
|
|
60
|
+
return 1;
|
|
61
|
+
if (mode === 'require')
|
|
62
|
+
return 2;
|
|
63
|
+
return 0; // default to 'prompt'
|
|
64
|
+
};
|
|
26
65
|
const response = await prompts([
|
|
27
66
|
{
|
|
28
67
|
type: 'text',
|
|
29
68
|
name: 'url',
|
|
30
69
|
message: 'Mattermost URL',
|
|
31
|
-
initial: 'https://your-mattermost-server.com',
|
|
70
|
+
initial: existing.MATTERMOST_URL || 'https://your-mattermost-server.com',
|
|
32
71
|
validate: (v) => v.startsWith('http') ? true : 'URL must start with http:// or https://',
|
|
33
72
|
},
|
|
34
73
|
{
|
|
35
74
|
type: 'password',
|
|
36
75
|
name: 'token',
|
|
37
76
|
message: 'Bot token',
|
|
38
|
-
hint:
|
|
39
|
-
|
|
77
|
+
hint: existing.MATTERMOST_TOKEN
|
|
78
|
+
? 'Enter to keep existing, or type new token'
|
|
79
|
+
: 'Create at: Integrations > Bot Accounts > Add Bot Account',
|
|
80
|
+
validate: (v) => {
|
|
81
|
+
// Allow empty if we have an existing token (user wants to keep it)
|
|
82
|
+
if (!v && existing.MATTERMOST_TOKEN)
|
|
83
|
+
return true;
|
|
84
|
+
return v.length > 0 ? true : 'Token is required';
|
|
85
|
+
},
|
|
40
86
|
},
|
|
41
87
|
{
|
|
42
88
|
type: 'text',
|
|
43
89
|
name: 'channelId',
|
|
44
90
|
message: 'Channel ID',
|
|
91
|
+
initial: existing.MATTERMOST_CHANNEL_ID || '',
|
|
45
92
|
hint: 'Click channel name > View Info > copy ID from URL',
|
|
46
93
|
validate: (v) => v.length > 0 ? true : 'Channel ID is required',
|
|
47
94
|
},
|
|
@@ -49,26 +96,48 @@ export async function runOnboarding() {
|
|
|
49
96
|
type: 'text',
|
|
50
97
|
name: 'botName',
|
|
51
98
|
message: 'Bot mention name',
|
|
52
|
-
initial: 'claude-code',
|
|
99
|
+
initial: existing.MATTERMOST_BOT_NAME || 'claude-code',
|
|
53
100
|
hint: 'Users will @mention this name',
|
|
54
101
|
},
|
|
55
102
|
{
|
|
56
103
|
type: 'text',
|
|
57
104
|
name: 'allowedUsers',
|
|
58
105
|
message: 'Allowed usernames',
|
|
59
|
-
initial: '',
|
|
106
|
+
initial: existing.ALLOWED_USERS || '',
|
|
60
107
|
hint: 'Comma-separated, or empty for all users',
|
|
61
108
|
},
|
|
62
109
|
{
|
|
63
110
|
type: 'confirm',
|
|
64
111
|
name: 'skipPermissions',
|
|
65
112
|
message: 'Skip permission prompts?',
|
|
66
|
-
initial:
|
|
113
|
+
initial: existing.SKIP_PERMISSIONS !== undefined
|
|
114
|
+
? existing.SKIP_PERMISSIONS === 'true'
|
|
115
|
+
: true,
|
|
67
116
|
hint: 'If no, you\'ll approve each action via emoji reactions',
|
|
68
117
|
},
|
|
118
|
+
{
|
|
119
|
+
type: 'confirm',
|
|
120
|
+
name: 'chrome',
|
|
121
|
+
message: 'Enable Chrome integration?',
|
|
122
|
+
initial: existing.CLAUDE_CHROME === 'true',
|
|
123
|
+
hint: 'Requires Claude in Chrome extension',
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
type: 'select',
|
|
127
|
+
name: 'worktreeMode',
|
|
128
|
+
message: 'Git worktree mode',
|
|
129
|
+
hint: 'Isolate changes in separate worktrees',
|
|
130
|
+
choices: [
|
|
131
|
+
{ title: 'Prompt', value: 'prompt', description: 'Ask when starting new sessions' },
|
|
132
|
+
{ title: 'Off', value: 'off', description: 'Never use worktrees' },
|
|
133
|
+
{ title: 'Require', value: 'require', description: 'Always require a branch name' },
|
|
134
|
+
],
|
|
135
|
+
initial: worktreeModeIndex(existing.WORKTREE_MODE),
|
|
136
|
+
},
|
|
69
137
|
], { onCancel });
|
|
70
|
-
// Check if user cancelled
|
|
71
|
-
|
|
138
|
+
// Check if user cancelled - token can be empty if keeping existing
|
|
139
|
+
const finalToken = response.token || existing.MATTERMOST_TOKEN;
|
|
140
|
+
if (!response.url || !finalToken || !response.channelId) {
|
|
72
141
|
console.log('');
|
|
73
142
|
console.log(dim(' Setup incomplete. Run claude-threads again to retry.'));
|
|
74
143
|
process.exit(1);
|
|
@@ -81,7 +150,7 @@ export async function runOnboarding() {
|
|
|
81
150
|
MATTERMOST_URL=${response.url}
|
|
82
151
|
|
|
83
152
|
# Bot token (from Integrations > Bot Accounts)
|
|
84
|
-
MATTERMOST_TOKEN=${
|
|
153
|
+
MATTERMOST_TOKEN=${finalToken}
|
|
85
154
|
|
|
86
155
|
# Channel ID where the bot listens
|
|
87
156
|
MATTERMOST_CHANNEL_ID=${response.channelId}
|
|
@@ -94,10 +163,18 @@ ALLOWED_USERS=${response.allowedUsers || ''}
|
|
|
94
163
|
|
|
95
164
|
# Skip permission prompts (true = auto-approve, false = require emoji approval)
|
|
96
165
|
SKIP_PERMISSIONS=${response.skipPermissions ? 'true' : 'false'}
|
|
166
|
+
|
|
167
|
+
# Chrome integration (requires Claude in Chrome extension)
|
|
168
|
+
CLAUDE_CHROME=${response.chrome ? 'true' : 'false'}
|
|
169
|
+
|
|
170
|
+
# Git worktree mode (off, prompt, require)
|
|
171
|
+
WORKTREE_MODE=${response.worktreeMode || 'prompt'}
|
|
97
172
|
`;
|
|
98
|
-
// Save to
|
|
99
|
-
const
|
|
100
|
-
const
|
|
173
|
+
// Save to same location if reconfiguring, otherwise default location
|
|
174
|
+
const defaultConfigDir = resolve(homedir(), '.config', 'claude-threads');
|
|
175
|
+
const defaultEnvPath = resolve(defaultConfigDir, '.env');
|
|
176
|
+
const envPath = existingPath || defaultEnvPath;
|
|
177
|
+
const configDir = dirname(envPath);
|
|
101
178
|
try {
|
|
102
179
|
mkdirSync(configDir, { recursive: true });
|
|
103
180
|
writeFileSync(envPath, envContent, { mode: 0o600 }); // Secure permissions
|