get-claudia 1.9.3 → 1.9.4

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/bin/index.js CHANGED
@@ -129,23 +129,85 @@ async function main() {
129
129
  }
130
130
  }
131
131
 
132
- // Ask about enhanced memory system
132
+ // Interactive setup prompts
133
133
  const rl = createInterface({
134
134
  input: process.stdin,
135
135
  output: process.stdout
136
136
  });
137
137
 
138
- const askMemory = () => {
138
+ const askYesNo = (question) => {
139
139
  return new Promise((resolve) => {
140
- rl.question(`\n${colors.yellow}?${colors.reset} Set up enhanced memory system? (recommended) [y/n]: `, (answer) => {
140
+ rl.question(question, (answer) => {
141
141
  resolve(answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes');
142
142
  });
143
143
  });
144
144
  };
145
145
 
146
- const setupMemory = await askMemory();
146
+ const setupMemory = await askYesNo(`\n${colors.yellow}?${colors.reset} Set up enhanced memory system? (recommended) [y/n]: `);
147
+ const setupGateway = await askYesNo(`${colors.yellow}?${colors.reset} Set up messaging gateway (Telegram/Slack)? [y/n]: `);
147
148
  rl.close();
148
149
 
150
+ // Helper: run gateway install script and call back when done
151
+ function runGatewaySetup(callback) {
152
+ console.log(`\n${colors.cyan}Setting up messaging gateway...${colors.reset}`);
153
+
154
+ const gatewayScriptPath = isWindows
155
+ ? join(__dirname, '..', 'gateway', 'scripts', 'install.ps1')
156
+ : join(__dirname, '..', 'gateway', 'scripts', 'install.sh');
157
+
158
+ if (!existsSync(gatewayScriptPath)) {
159
+ console.log(`${colors.yellow}!${colors.reset} Gateway files not found. Skipping.`);
160
+ callback(false);
161
+ return;
162
+ }
163
+
164
+ try {
165
+ const spawnCmd = isWindows ? powershellPath : 'bash';
166
+ const spawnArgs = isWindows
167
+ ? ['-ExecutionPolicy', 'Bypass', '-File', gatewayScriptPath]
168
+ : [gatewayScriptPath];
169
+ const gwResult = spawn(spawnCmd, spawnArgs, {
170
+ stdio: 'inherit',
171
+ env: {
172
+ ...process.env,
173
+ CLAUDIA_GATEWAY_UPGRADE: isUpgrade ? '1' : '0'
174
+ }
175
+ });
176
+
177
+ gwResult.on('close', (code) => {
178
+ if (code === 0) {
179
+ console.log(`${colors.green}✓${colors.reset} Gateway installed`);
180
+ callback(true);
181
+ } else {
182
+ console.log(`${colors.yellow}!${colors.reset} Gateway setup had issues. You can run it later with:`);
183
+ if (isWindows) {
184
+ console.log(` ${colors.cyan}powershell.exe -ExecutionPolicy Bypass -File "${gatewayScriptPath}"${colors.reset}`);
185
+ } else {
186
+ console.log(` ${colors.cyan}bash ${gatewayScriptPath}${colors.reset}`);
187
+ }
188
+ callback(false);
189
+ }
190
+ });
191
+ } catch (error) {
192
+ console.log(`${colors.yellow}!${colors.reset} Could not set up gateway: ${error.message}`);
193
+ callback(false);
194
+ }
195
+ }
196
+
197
+ // Helper: finish install after optional components
198
+ function finishInstall(memoryInstalled, gatewayInstalled) {
199
+ showNextSteps(memoryInstalled, gatewayInstalled);
200
+ }
201
+
202
+ // Helper: run gateway if requested, then finish
203
+ function maybeRunGateway(memoryInstalled) {
204
+ if (setupGateway) {
205
+ runGatewaySetup((gatewayOk) => finishInstall(memoryInstalled, gatewayOk));
206
+ } else {
207
+ finishInstall(memoryInstalled, false);
208
+ }
209
+ }
210
+
149
211
  if (setupMemory) {
150
212
  console.log(`\n${colors.cyan}Setting up enhanced memory system...${colors.reset}`);
151
213
 
@@ -169,8 +231,10 @@ async function main() {
169
231
  });
170
232
 
171
233
  result.on('close', (code) => {
234
+ let memoryOk = false;
172
235
  if (code === 0) {
173
236
  console.log(`${colors.green}✓${colors.reset} Memory system installed`);
237
+ memoryOk = true;
174
238
 
175
239
  // Update .mcp.json if it exists
176
240
  const mcpPath = join(targetPath, '.mcp.json');
@@ -194,7 +258,6 @@ async function main() {
194
258
  writeFileSync(mcpPath, JSON.stringify(mcpConfig, null, 2));
195
259
  console.log(`${colors.green}✓${colors.reset} Created .mcp.json with memory server`);
196
260
  }
197
- showNextSteps(true); // Memory installed - emphasize restart
198
261
  } else {
199
262
  console.log(`${colors.yellow}!${colors.reset} Memory setup had issues. You can run it later with:`);
200
263
  if (isWindows) {
@@ -202,8 +265,10 @@ async function main() {
202
265
  } else {
203
266
  console.log(` ${colors.cyan}bash ${memoryDaemonPath}${colors.reset}`);
204
267
  }
205
- showNextSteps(false);
206
268
  }
269
+
270
+ // Chain gateway setup (or finish)
271
+ maybeRunGateway(memoryOk);
207
272
  });
208
273
 
209
274
  return; // Wait for spawn to complete
@@ -216,14 +281,14 @@ async function main() {
216
281
  }
217
282
  }
218
283
 
219
- showNextSteps(false);
284
+ // Memory skipped or failed to spawn -- continue with gateway
285
+ maybeRunGateway(false);
220
286
 
221
- function showNextSteps(memoryInstalled) {
222
- // Show next steps - different message if memory was installed
287
+ function showNextSteps(memoryInstalled, gatewayInstalled) {
288
+ // Show next steps - different message based on what was installed
223
289
  const cdStep = isCurrentDir ? '' : ` ${colors.cyan}cd ${targetDir}${colors.reset}\n`;
224
290
 
225
291
  if (memoryInstalled) {
226
- // Memory was installed
227
292
  console.log(`
228
293
  ${colors.bold}Next:${colors.reset}
229
294
  ${cdStep} ${colors.cyan}claude${colors.reset}
@@ -233,13 +298,20 @@ ${colors.dim}If Claude was already running elsewhere, restart it to activate mem
233
298
  ${colors.dim}Troubleshooting: ${isWindows ? '%USERPROFILE%\\.claudia\\diagnose.ps1' : '~/.claudia/diagnose.sh'}${colors.reset}
234
299
  `);
235
300
  } else {
236
- // No memory - standard message
237
301
  console.log(`
238
302
  ${colors.bold}Next:${colors.reset}
239
303
  ${cdStep} ${colors.cyan}claude${colors.reset}
240
304
  ${colors.dim}Say hi!${colors.reset}
241
305
 
242
306
  ${colors.dim}She'll introduce herself and set things up for you.${colors.reset}
307
+ `);
308
+ }
309
+
310
+ if (gatewayInstalled) {
311
+ console.log(`${colors.bold}Gateway:${colors.reset}
312
+ ${colors.dim}Configure API keys and allowlist, then:${colors.reset}
313
+ ${colors.cyan}claudia-gateway start${colors.reset}
314
+ ${colors.dim}See ~/.claudia/gateway.json for settings.${colors.reset}
243
315
  `);
244
316
  }
245
317
  }
@@ -0,0 +1,228 @@
1
+ # Claudia Gateway
2
+
3
+ The messaging gateway lets you talk to Claudia from Telegram and Slack on your phone or desktop. Messages flow from your chat app to the gateway running on your machine, where they're processed by Claude with full access to Claudia's memory system. Everything runs locally except the Anthropic API call itself.
4
+
5
+ ## Quick Start
6
+
7
+ 1. Run the installer (done automatically via `npx get-claudia`):
8
+ ```bash
9
+ bash gateway/scripts/install.sh
10
+ ```
11
+
12
+ 2. Set your API keys as environment variables:
13
+ ```bash
14
+ export ANTHROPIC_API_KEY="sk-ant-..."
15
+ export TELEGRAM_BOT_TOKEN="123456:ABC-DEF..."
16
+ ```
17
+
18
+ 3. Edit `~/.claudia/gateway.json` to enable your channel and set your user ID:
19
+ ```json
20
+ {
21
+ "channels": {
22
+ "telegram": {
23
+ "enabled": true,
24
+ "allowedUsers": ["YOUR_TELEGRAM_USER_ID"]
25
+ }
26
+ }
27
+ }
28
+ ```
29
+
30
+ 4. Start the gateway:
31
+ ```bash
32
+ claudia-gateway start
33
+ ```
34
+
35
+ ## Telegram Setup
36
+
37
+ 1. Open Telegram and message [@BotFather](https://t.me/BotFather)
38
+ 2. Send `/newbot` and follow the prompts to create your bot
39
+ 3. Copy the bot token BotFather gives you
40
+ 4. Get your Telegram user ID (message [@userinfobot](https://t.me/userinfobot) or check in Telegram settings)
41
+ 5. Set environment variables:
42
+ ```bash
43
+ export TELEGRAM_BOT_TOKEN="123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11"
44
+ ```
45
+ 6. Edit `~/.claudia/gateway.json`:
46
+ ```json
47
+ {
48
+ "channels": {
49
+ "telegram": {
50
+ "enabled": true,
51
+ "allowedUsers": ["123456789"]
52
+ }
53
+ }
54
+ }
55
+ ```
56
+ 7. Start the gateway: `claudia-gateway start`
57
+ 8. Open your bot in Telegram and send a message
58
+
59
+ ## Slack Setup
60
+
61
+ 1. Go to [api.slack.com/apps](https://api.slack.com/apps) and click **Create New App** > **From scratch**
62
+ 2. Enable **Socket Mode** under Settings (generates an app-level token starting with `xapp-`)
63
+ 3. Under **OAuth & Permissions**, add these bot token scopes:
64
+ - `app_mentions:read`
65
+ - `chat:write`
66
+ - `im:history`
67
+ - `im:read`
68
+ - `im:write`
69
+ 4. Under **Event Subscriptions**, enable events and subscribe to:
70
+ - `message.im`
71
+ - `app_mention`
72
+ 5. Install the app to your workspace (generates a bot token starting with `xoxb-`)
73
+ 6. Set environment variables:
74
+ ```bash
75
+ export SLACK_BOT_TOKEN="xoxb-..."
76
+ export SLACK_APP_TOKEN="xapp-..."
77
+ ```
78
+ 7. Edit `~/.claudia/gateway.json`:
79
+ ```json
80
+ {
81
+ "channels": {
82
+ "slack": {
83
+ "enabled": true,
84
+ "allowedUsers": ["U01ABCDEF"]
85
+ }
86
+ }
87
+ }
88
+ ```
89
+ 8. Start the gateway: `claudia-gateway start`
90
+ 9. DM the bot or mention it in a channel
91
+
92
+ ## Configuration Reference
93
+
94
+ Config lives at `~/.claudia/gateway.json`. All API keys/tokens should be set as environment variables, not stored in this file.
95
+
96
+ | Key | Env Override | Description |
97
+ |-----|-------------|-------------|
98
+ | `anthropicApiKey` | `ANTHROPIC_API_KEY` | Your Anthropic API key |
99
+ | `model` | | Claude model to use (default: `claude-sonnet-4-20250514`) |
100
+ | `maxTokens` | | Max response tokens (default: `2048`) |
101
+ | `channels.telegram.enabled` | | Enable Telegram adapter |
102
+ | `channels.telegram.token` | `TELEGRAM_BOT_TOKEN` | Bot token from BotFather |
103
+ | `channels.telegram.allowedUsers` | | Array of allowed Telegram user IDs |
104
+ | `channels.slack.enabled` | | Enable Slack adapter |
105
+ | `channels.slack.botToken` | `SLACK_BOT_TOKEN` | Bot OAuth token (`xoxb-...`) |
106
+ | `channels.slack.appToken` | `SLACK_APP_TOKEN` | App-level token (`xapp-...`) |
107
+ | `channels.slack.signingSecret` | `SLACK_SIGNING_SECRET` | Slack signing secret |
108
+ | `channels.slack.allowedUsers` | | Array of allowed Slack user IDs |
109
+ | `globalAllowedUsers` | | User IDs allowed across all channels |
110
+ | `proactive.enabled` | | Enable proactive notifications |
111
+ | `proactive.pollIntervalMs` | | How often to check for notifications (ms) |
112
+ | `proactive.defaultChannel` | | Channel for proactive messages |
113
+ | `proactive.defaultUserId` | | User to receive proactive messages |
114
+ | `memoryDaemon.healthPort` | | Memory daemon health port (default: `3848`) |
115
+ | `gateway.port` | | Gateway service port (default: `3849`) |
116
+ | `gateway.logLevel` | | Log level: `debug`, `info`, `warn`, `error` |
117
+
118
+ ## Security
119
+
120
+ ### Deny-by-default allowlist
121
+
122
+ The gateway rejects all messages from users not in the `allowedUsers` array. No allowlist entries = nobody can talk to your Claudia. This is the primary security boundary.
123
+
124
+ Per-channel `allowedUsers` and `globalAllowedUsers` are both checked. A user must appear in at least one to be authorized.
125
+
126
+ ### API key handling
127
+
128
+ - **Environment variables only.** The `saveConfig` function actively strips secrets before writing `gateway.json` to disk. Even if you put a token in the JSON, it gets removed on next save.
129
+ - Supported env vars: `ANTHROPIC_API_KEY`, `TELEGRAM_BOT_TOKEN`, `SLACK_BOT_TOKEN`, `SLACK_APP_TOKEN`, `SLACK_SIGNING_SECRET`
130
+ - Never commit `.env` files or gateway.json with tokens to version control.
131
+
132
+ ### Data flow
133
+
134
+ ```
135
+ Phone/Desktop Your Machine Cloud
136
+ ┌──────────┐ encrypted ┌──────────────────┐ ┌───────────┐
137
+ │ Telegram │───(TLS)──────▶│ Claudia Gateway │──────▶│ Anthropic │
138
+ │ or Slack │◀──(TLS)───────│ (localhost) │◀──────│ API │
139
+ └──────────┘ │ │ └───────────┘
140
+ │ ┌──────────────┐ │
141
+ │ │ Memory Daemon │ │
142
+ │ │ (localhost) │ │
143
+ │ └──────────────┘ │
144
+ └──────────────────────┘
145
+ ```
146
+
147
+ - **Your message** travels from your chat app through the platform's servers (Telegram/Slack) to the gateway running on your machine.
148
+ - **The gateway** processes your message locally, reads/writes to Claudia's memory (local SQLite), and sends only the conversation to the Anthropic API.
149
+ - **Anthropic** returns a response; the gateway relays it back through the chat platform to your device.
150
+ - **Memory stays local.** The memory daemon runs on your machine, stores data in `~/.claudia/memory/`, and never sends data to any external service except when explicitly included in a Claude API call.
151
+
152
+ ### What goes where
153
+
154
+ | Data | Where it goes |
155
+ |------|--------------|
156
+ | Your messages | Telegram/Slack servers (platform routing), Anthropic API |
157
+ | Claude's responses | Anthropic API, Telegram/Slack servers (delivery) |
158
+ | Memory (facts, entities, relationships) | Local SQLite only (`~/.claudia/memory/`) |
159
+ | API keys | Environment variables on your machine only |
160
+ | Gateway config | `~/.claudia/gateway.json` on your machine (secrets stripped) |
161
+ | Logs | `~/.claudia/gateway.log` on your machine |
162
+
163
+ ## CLI Commands
164
+
165
+ ```bash
166
+ claudia-gateway start [--channels telegram,slack] [--debug]
167
+ claudia-gateway stop
168
+ claudia-gateway status
169
+ claudia-gateway logs [--lines N]
170
+ claudia-gateway init
171
+ ```
172
+
173
+ | Command | Description |
174
+ |---------|-------------|
175
+ | `start` | Start the gateway. Use `--channels` to override which channels to enable. Use `--debug` for verbose logging. |
176
+ | `stop` | Send SIGTERM to the running gateway process. |
177
+ | `status` | Show whether the gateway is running, which channels are configured, and memory daemon health. |
178
+ | `logs` | Print the last N lines from the gateway log (default: 50). |
179
+ | `init` | Generate an example `~/.claudia/gateway.json` config file. |
180
+
181
+ ## Proactive Notifications
182
+
183
+ Claudia can send you messages unprompted when she detects something worth flagging (overdue commitments, meeting reminders, pattern alerts).
184
+
185
+ To enable:
186
+
187
+ 1. Edit `~/.claudia/gateway.json`:
188
+ ```json
189
+ {
190
+ "proactive": {
191
+ "enabled": true,
192
+ "defaultChannel": "telegram",
193
+ "defaultUserId": "YOUR_USER_ID"
194
+ }
195
+ }
196
+ ```
197
+
198
+ 2. The gateway polls the memory daemon for pending predictions and notifications at the configured interval (default: 5 minutes).
199
+
200
+ 3. Requires the memory daemon to be running and healthy.
201
+
202
+ ## Troubleshooting
203
+
204
+ **Gateway won't start**
205
+ - Check Node.js version: `node --version` (must be 18+)
206
+ - Verify API key is set: `echo $ANTHROPIC_API_KEY`
207
+ - Check config: `cat ~/.claudia/gateway.json`
208
+ - Look at logs: `claudia-gateway logs --lines 100`
209
+
210
+ **Bot doesn't respond**
211
+ - Verify the bot token is correct
212
+ - Check that your user ID is in `allowedUsers`
213
+ - Run with `--debug` for detailed logs: `claudia-gateway start --debug`
214
+
215
+ **Memory not available**
216
+ - Check memory daemon: `curl http://localhost:3848/health`
217
+ - The gateway works without memory (just no persistent context)
218
+
219
+ **Auto-start**
220
+ - macOS: `launchctl load ~/Library/LaunchAgents/com.claudia.gateway.plist`
221
+ - Linux: `systemctl --user enable --now claudia-gateway`
222
+ - Windows: `Enable-ScheduledTask -TaskName ClaudiaGateway`
223
+
224
+ **Reinstall**
225
+ - Run the installer again with upgrade mode:
226
+ ```bash
227
+ CLAUDIA_GATEWAY_UPGRADE=1 bash ~/.claudia/gateway/scripts/install.sh
228
+ ```
@@ -0,0 +1,25 @@
1
+ {
2
+ "name": "@claudia/gateway",
3
+ "version": "0.1.0",
4
+ "description": "Multi-channel messaging gateway for Claudia - Telegram, Slack, and more",
5
+ "type": "module",
6
+ "main": "src/index.js",
7
+ "bin": {
8
+ "claudia-gateway": "./src/index.js"
9
+ },
10
+ "scripts": {
11
+ "start": "node src/index.js start",
12
+ "test": "node --test tests/"
13
+ },
14
+ "dependencies": {
15
+ "@anthropic-ai/sdk": "^0.39.0",
16
+ "@modelcontextprotocol/sdk": "^1.12.1",
17
+ "grammy": "^1.35.0",
18
+ "@slack/bolt": "^4.3.0",
19
+ "@slack/web-api": "^7.9.1"
20
+ },
21
+ "engines": {
22
+ "node": ">=18.0.0"
23
+ },
24
+ "private": true
25
+ }
@@ -0,0 +1,245 @@
1
+ # Claudia Gateway Installer (Windows)
2
+ # Sets up the messaging gateway with all dependencies
3
+
4
+ $ErrorActionPreference = "Continue"
5
+
6
+ # Colors via ANSI escape sequences
7
+ $ESC = [char]27
8
+ $RED = "$ESC[0;31m"
9
+ $GREEN = "$ESC[0;32m"
10
+ $YELLOW = "$ESC[1;33m"
11
+ $CYAN = "$ESC[0;36m"
12
+ $MAGENTA = "$ESC[0;35m"
13
+ $BOLD = "$ESC[1m"
14
+ $DIM = "$ESC[2m"
15
+ $NC = "$ESC[0m"
16
+
17
+ # Paths
18
+ $CLAUDIA_DIR = Join-Path $env:USERPROFILE ".claudia"
19
+ $GATEWAY_DIR = Join-Path $CLAUDIA_DIR "gateway"
20
+ $BIN_DIR = Join-Path $CLAUDIA_DIR "bin"
21
+
22
+ # Upgrade mode
23
+ $IS_UPGRADE = $env:CLAUDIA_GATEWAY_UPGRADE -eq "1"
24
+
25
+ # Banner
26
+ Clear-Host
27
+ Write-Host ""
28
+ Write-Host "${CYAN}████${NC} ${CYAN}██${NC} ${CYAN}██${NC} ${CYAN}██${NC} ${CYAN}██${NC} ${CYAN}████${NC} ${CYAN}██${NC} ${CYAN}██${NC}"
29
+ Write-Host "${CYAN}██${NC} ${CYAN}██${NC} ${CYAN}██${NC} ${CYAN}██${NC} ${CYAN}██${NC} ${CYAN}██${NC} ${CYAN}██${NC} ${CYAN}██${NC} ${CYAN}██${NC} ${CYAN}██${NC} ${CYAN}██${NC}"
30
+ Write-Host "${CYAN}████${NC} ${CYAN}████${NC} ${CYAN}██${NC} ${CYAN}██${NC} ${CYAN}██${NC} ${CYAN}████${NC} ${CYAN}██${NC} ${CYAN}██${NC} ${CYAN}██${NC}"
31
+ Write-Host ""
32
+ Write-Host "${DIM}Messaging Gateway Installer (Windows)${NC}"
33
+ Write-Host "${DIM}Talk to Claudia from Telegram and Slack${NC}"
34
+ Write-Host ""
35
+ Write-Host "${DIM}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
36
+ Write-Host ""
37
+
38
+ # ============================================================
39
+ # Step 1: Check Node.js >= 18
40
+ # ============================================================
41
+ Write-Host "${BOLD}Step 1/6: Environment Check${NC}"
42
+ Write-Host ""
43
+
44
+ $NODE_BIN = $null
45
+ try {
46
+ $nodeVersion = & node --version 2>&1
47
+ if ($nodeVersion -match "v(\d+)") {
48
+ $major = [int]$Matches[1]
49
+ if ($major -ge 18) {
50
+ $NODE_BIN = (Get-Command node).Source
51
+ Write-Host " ${GREEN}✓${NC} Node.js $nodeVersion"
52
+ } else {
53
+ Write-Host " ${RED}✗${NC} Node.js 18+ required (found: $nodeVersion)"
54
+ Write-Host " ${DIM}Install from https://nodejs.org${NC}"
55
+ exit 1
56
+ }
57
+ }
58
+ } catch {
59
+ Write-Host " ${RED}✗${NC} Node.js not found"
60
+ Write-Host " Please install Node.js 18 or later"
61
+ Write-Host " ${DIM}https://nodejs.org${NC}"
62
+ exit 1
63
+ }
64
+
65
+ Write-Host ""
66
+ Write-Host "${DIM}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
67
+ Write-Host ""
68
+
69
+ # ============================================================
70
+ # Step 2: Copy gateway source
71
+ # ============================================================
72
+ Write-Host "${BOLD}Step 2/6: Installing Gateway${NC}"
73
+ Write-Host ""
74
+
75
+ $SCRIPT_DIR = Split-Path -Parent $MyInvocation.MyCommand.Path
76
+ $SOURCE_DIR = Split-Path -Parent $SCRIPT_DIR
77
+
78
+ New-Item -ItemType Directory -Force -Path $GATEWAY_DIR | Out-Null
79
+
80
+ Write-Host " ${CYAN}◐${NC} Copying gateway files..."
81
+ Copy-Item -Recurse -Force (Join-Path $SOURCE_DIR "src") $GATEWAY_DIR
82
+ Copy-Item -Force (Join-Path $SOURCE_DIR "package.json") $GATEWAY_DIR
83
+ Write-Host " ${GREEN}✓${NC} Gateway source installed"
84
+
85
+ Write-Host ""
86
+ Write-Host "${DIM}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
87
+ Write-Host ""
88
+
89
+ # ============================================================
90
+ # Step 3: npm install --production
91
+ # ============================================================
92
+ Write-Host "${BOLD}Step 3/6: Installing Dependencies${NC}"
93
+ Write-Host ""
94
+
95
+ Write-Host " ${CYAN}◐${NC} Running npm install..."
96
+ Push-Location $GATEWAY_DIR
97
+ try {
98
+ & npm install --production 2>&1 | Out-Null
99
+ Write-Host " ${GREEN}✓${NC} Dependencies installed"
100
+ } catch {
101
+ Write-Host " ${RED}✗${NC} npm install failed"
102
+ Write-Host " ${DIM}Try running manually: cd $GATEWAY_DIR && npm install --production${NC}"
103
+ Pop-Location
104
+ exit 1
105
+ }
106
+ Pop-Location
107
+
108
+ Write-Host ""
109
+ Write-Host "${DIM}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
110
+ Write-Host ""
111
+
112
+ # ============================================================
113
+ # Step 4: Generate config
114
+ # ============================================================
115
+ Write-Host "${BOLD}Step 4/6: Configuration${NC}"
116
+ Write-Host ""
117
+
118
+ $CONFIG_FILE = Join-Path $CLAUDIA_DIR "gateway.json"
119
+
120
+ if ((Test-Path $CONFIG_FILE) -and $IS_UPGRADE) {
121
+ Write-Host " ${GREEN}✓${NC} Existing config preserved"
122
+ } else {
123
+ & node (Join-Path $GATEWAY_DIR "src" "index.js") init 2>&1 | Out-Null
124
+ Write-Host " ${GREEN}✓${NC} Config created at $CONFIG_FILE"
125
+ }
126
+
127
+ Write-Host ""
128
+ Write-Host "${DIM}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
129
+ Write-Host ""
130
+
131
+ # ============================================================
132
+ # Step 5: Create CLI wrapper
133
+ # ============================================================
134
+ Write-Host "${BOLD}Step 5/6: CLI Wrapper${NC}"
135
+ Write-Host ""
136
+
137
+ New-Item -ItemType Directory -Force -Path $BIN_DIR | Out-Null
138
+
139
+ # Create batch wrapper
140
+ $wrapperPath = Join-Path $BIN_DIR "claudia-gateway.cmd"
141
+ $wrapperContent = @"
142
+ @echo off
143
+ node "%USERPROFILE%\.claudia\gateway\src\index.js" %*
144
+ "@
145
+ Set-Content -Path $wrapperPath -Value $wrapperContent
146
+ Write-Host " ${GREEN}✓${NC} CLI installed at $wrapperPath"
147
+
148
+ # PATH hint
149
+ $currentPath = [System.Environment]::GetEnvironmentVariable("PATH", "User")
150
+ if ($currentPath -notlike "*$BIN_DIR*") {
151
+ Write-Host " ${YELLOW}!${NC} Add to your PATH if not already present:"
152
+ Write-Host " ${DIM}[Environment]::SetEnvironmentVariable('PATH', `$env:PATH + ';$BIN_DIR', 'User')${NC}"
153
+ }
154
+
155
+ # Create scheduled task (disabled by default)
156
+ $taskName = "ClaudiaGateway"
157
+ try {
158
+ $existingTask = Get-ScheduledTask -TaskName $taskName -ErrorAction SilentlyContinue
159
+ if ($existingTask) {
160
+ Unregister-ScheduledTask -TaskName $taskName -Confirm:$false -ErrorAction SilentlyContinue
161
+ }
162
+
163
+ $action = New-ScheduledTaskAction `
164
+ -Execute $NODE_BIN `
165
+ -Argument "$GATEWAY_DIR\src\index.js start" `
166
+ -WorkingDirectory $GATEWAY_DIR
167
+
168
+ $trigger = New-ScheduledTaskTrigger -AtLogOn -User $env:USERNAME
169
+
170
+ $settings = New-ScheduledTaskSettingsSet `
171
+ -AllowStartIfOnBatteries `
172
+ -DontStopIfGoingOnBatteries `
173
+ -RestartCount 3 `
174
+ -RestartInterval (New-TimeSpan -Minutes 1) `
175
+ -ExecutionTimeLimit (New-TimeSpan -Days 0) `
176
+ -StartWhenAvailable
177
+
178
+ Register-ScheduledTask `
179
+ -TaskName $taskName `
180
+ -Description "Claudia Messaging Gateway" `
181
+ -Action $action `
182
+ -Trigger $trigger `
183
+ -Settings $settings `
184
+ -RunLevel Limited `
185
+ -Force | Out-Null
186
+
187
+ # Disable the task (requires API keys first)
188
+ Disable-ScheduledTask -TaskName $taskName | Out-Null
189
+
190
+ Write-Host " ${GREEN}✓${NC} Windows Task Scheduler entry created (disabled)"
191
+ Write-Host " ${DIM}Enable after configuring API keys:${NC}"
192
+ Write-Host " ${DIM}Enable-ScheduledTask -TaskName ClaudiaGateway${NC}"
193
+ } catch {
194
+ Write-Host " ${YELLOW}!${NC} Could not configure auto-start: $_"
195
+ Write-Host " ${DIM}You can start the gateway manually: claudia-gateway start${NC}"
196
+ }
197
+
198
+ Write-Host ""
199
+ Write-Host "${DIM}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
200
+ Write-Host ""
201
+
202
+ # ============================================================
203
+ # Step 6: Security checklist and next steps
204
+ # ============================================================
205
+ Write-Host "${BOLD}Step 6/6: What's Next${NC}"
206
+ Write-Host ""
207
+
208
+ Write-Host "${GREEN}"
209
+ Write-Host " ╔═══════════════════════════════════════════════════════════╗"
210
+ Write-Host " ║ ║"
211
+ Write-Host " ║ ✨ Gateway installed successfully! ✨ ║"
212
+ Write-Host " ║ ║"
213
+ Write-Host " ╚═══════════════════════════════════════════════════════════╝"
214
+ Write-Host "${NC}"
215
+
216
+ Write-Host "${BOLD}Security checklist (do these before starting):${NC}"
217
+ Write-Host ""
218
+ Write-Host " ${YELLOW}□${NC} Set ANTHROPIC_API_KEY as an environment variable"
219
+ Write-Host " ${YELLOW}□${NC} Set TELEGRAM_BOT_TOKEN (or SLACK_BOT_TOKEN + SLACK_APP_TOKEN)"
220
+ Write-Host " ${YELLOW}□${NC} Add your user ID(s) to allowedUsers in gateway.json"
221
+ Write-Host " ${YELLOW}□${NC} Never commit API keys to git or store them in gateway.json"
222
+ Write-Host ""
223
+ Write-Host "${BOLD}Quick start:${NC}"
224
+ Write-Host ""
225
+ Write-Host " ${CYAN}1.${NC} `$env:ANTHROPIC_API_KEY = 'sk-ant-...'"
226
+ Write-Host " ${CYAN}2.${NC} `$env:TELEGRAM_BOT_TOKEN = '123456:ABC...'"
227
+ Write-Host " ${CYAN}3.${NC} Edit $CONFIG_FILE (enable channel, set allowedUsers)"
228
+ Write-Host " ${CYAN}4.${NC} claudia-gateway start"
229
+ Write-Host ""
230
+ Write-Host "${BOLD}Installed:${NC}"
231
+ Write-Host ""
232
+ Write-Host " ${CYAN}◆${NC} Gateway source ${DIM}$GATEWAY_DIR${NC}"
233
+ Write-Host " ${CYAN}◆${NC} Config ${DIM}$CONFIG_FILE${NC}"
234
+ Write-Host " ${CYAN}◆${NC} CLI ${DIM}$wrapperPath${NC}"
235
+ Write-Host " ${CYAN}◆${NC} Logs ${DIM}$CLAUDIA_DIR\gateway.log${NC}"
236
+ Write-Host ""
237
+ Write-Host "${BOLD}CLI commands:${NC}"
238
+ Write-Host ""
239
+ Write-Host " ${DIM}claudia-gateway start${NC} Start the gateway"
240
+ Write-Host " ${DIM}claudia-gateway stop${NC} Stop the gateway"
241
+ Write-Host " ${DIM}claudia-gateway status${NC} Check status"
242
+ Write-Host " ${DIM}claudia-gateway logs${NC} View recent logs"
243
+ Write-Host ""
244
+ Write-Host "${MAGENTA}${DIM}$([char]34)Now you can reach me anywhere.$([char]34) -- Claudia${NC}"
245
+ Write-Host ""