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 +83 -11
- package/gateway/README.md +228 -0
- package/gateway/package.json +25 -0
- package/gateway/scripts/install.ps1 +245 -0
- package/gateway/scripts/install.sh +289 -0
- package/gateway/src/adapters/base.js +64 -0
- package/gateway/src/adapters/slack.js +154 -0
- package/gateway/src/adapters/telegram.js +158 -0
- package/gateway/src/bridge.js +350 -0
- package/gateway/src/config.js +197 -0
- package/gateway/src/emitter.js +121 -0
- package/gateway/src/gateway.js +145 -0
- package/gateway/src/index.js +261 -0
- package/gateway/src/router.js +219 -0
- package/gateway/src/utils/auth.js +55 -0
- package/gateway/src/utils/logger.js +80 -0
- package/gateway/tests/auth.test.js +62 -0
- package/gateway/tests/config.test.js +27 -0
- package/gateway/tests/router.test.js +146 -0
- package/package.json +2 -1
package/bin/index.js
CHANGED
|
@@ -129,23 +129,85 @@ async function main() {
|
|
|
129
129
|
}
|
|
130
130
|
}
|
|
131
131
|
|
|
132
|
-
//
|
|
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
|
|
138
|
+
const askYesNo = (question) => {
|
|
139
139
|
return new Promise((resolve) => {
|
|
140
|
-
rl.question(
|
|
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
|
|
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
|
-
|
|
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
|
|
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 ""
|