@modelriver/cli 1.0.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/README.md +406 -0
- package/bin/modelriver +5 -0
- package/package.json +52 -0
- package/src/commands/forward.js +61 -0
- package/src/commands/listen.js +315 -0
- package/src/commands/login.js +176 -0
- package/src/commands/test-webhook.js +289 -0
- package/src/commands/trigger.js +77 -0
- package/src/commands/webhook.js +101 -0
- package/src/commands/websocket.js +249 -0
- package/src/index.js +154 -0
- package/src/lib/api-client.js +173 -0
- package/src/lib/api-client.test.js +101 -0
- package/src/lib/cli-websocket-client.js +249 -0
- package/src/lib/config.js +137 -0
- package/src/lib/config.test.js +98 -0
- package/src/lib/webhook-verifier.js +56 -0
- package/src/lib/webhook-verifier.test.js +90 -0
- package/src/lib/websocket-client.js +225 -0
- package/src/utils/formatter.js +43 -0
- package/src/utils/formatter.test.js +84 -0
- package/src/utils/logger.js +39 -0
- package/src/utils/url-helpers.js +98 -0
- package/src/utils/url-helpers.test.js +84 -0
package/README.md
ADDED
|
@@ -0,0 +1,406 @@
|
|
|
1
|
+
# ModelRiver CLI
|
|
2
|
+
|
|
3
|
+
A command-line tool for testing webhooks and WebSockets from live/production ModelRiver, similar to Stripe CLI.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
### From npm (when published)
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install -g @modelriver/cli
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
### From source
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
cd modelriver-cli
|
|
17
|
+
npm install
|
|
18
|
+
npm link # Makes `modelriver` command available globally
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Quick Start
|
|
22
|
+
|
|
23
|
+
### Step 1: Login (One-Time Setup)
|
|
24
|
+
|
|
25
|
+
Run the interactive login command to configure your API key and forward URL:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
modelriver login
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
You'll be prompted for:
|
|
32
|
+
1. **API Key**: Your ModelRiver API key (starts with `mr_live_` or `mr_test_`)
|
|
33
|
+
2. **Forward URL**: Where to forward webhooks (e.g., `http://localhost:4000`)
|
|
34
|
+
|
|
35
|
+
The URL will be automatically normalized to include `/webhook/modelriver`.
|
|
36
|
+
|
|
37
|
+
### Step 2: Start Forwarding
|
|
38
|
+
|
|
39
|
+
After login, simply run:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
modelriver forward
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
That's it! Webhooks will be forwarded to your configured URL.
|
|
46
|
+
|
|
47
|
+
## Command Aliases
|
|
48
|
+
|
|
49
|
+
For convenience, the CLI supports short aliases:
|
|
50
|
+
|
|
51
|
+
| Command | Alias | Description |
|
|
52
|
+
|---------|-------|-------------|
|
|
53
|
+
| `listen` | `l` | Listen for webhooks |
|
|
54
|
+
| `forward` | `f` | Forward using saved config |
|
|
55
|
+
| `trigger` | `t` | Send async request |
|
|
56
|
+
| `websocket` | `ws` | Test WebSocket connection |
|
|
57
|
+
|
|
58
|
+
Example:
|
|
59
|
+
```bash
|
|
60
|
+
modelriver l --print # Same as: modelriver listen --print
|
|
61
|
+
modelriver f # Same as: modelriver forward
|
|
62
|
+
modelriver t -w my-workflow -m "Hello" # Same as: modelriver trigger ...
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Configuration
|
|
66
|
+
|
|
67
|
+
### Interactive Setup (Recommended)
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
modelriver login
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
This saves your configuration to `~/.modelriver/config.json`.
|
|
74
|
+
|
|
75
|
+
### Environment Variables
|
|
76
|
+
|
|
77
|
+
Set these environment variables for convenience:
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
export MODELRIVER_API_KEY=mr_live_YOUR_API_KEY
|
|
81
|
+
export MODELRIVER_API_URL=https://api.modelriver.com # Optional, defaults to production
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Config File
|
|
85
|
+
|
|
86
|
+
Create a config file at `~/.modelriver/config.json` or `.modelriverrc` in your project:
|
|
87
|
+
|
|
88
|
+
```json
|
|
89
|
+
{
|
|
90
|
+
"api_key": "mr_live_YOUR_API_KEY",
|
|
91
|
+
"api_url": "https://api.modelriver.com",
|
|
92
|
+
"forward_url": "http://localhost:4000/webhook/modelriver"
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
**Priority**: CLI arguments > Environment variables > Config file > Defaults
|
|
97
|
+
|
|
98
|
+
## Commands
|
|
99
|
+
|
|
100
|
+
### `modelriver login` - Interactive Setup
|
|
101
|
+
|
|
102
|
+
Configure your API key and forward URL interactively:
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
modelriver login
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Example session:
|
|
109
|
+
```
|
|
110
|
+
ModelRiver CLI Login
|
|
111
|
+
─────────────────────
|
|
112
|
+
Configure your ModelRiver CLI credentials.
|
|
113
|
+
|
|
114
|
+
Enter your ModelRiver API key: mr_live_abc123...
|
|
115
|
+
Enter your webhook forward URL (e.g. http://localhost:4000/webhook/modelriver): http://localhost:4000
|
|
116
|
+
|
|
117
|
+
✓ Configuration saved!
|
|
118
|
+
|
|
119
|
+
Saved Configuration
|
|
120
|
+
───────────────────
|
|
121
|
+
✓ API Key: mr_live_abc123...
|
|
122
|
+
✓ Forward URL: http://localhost:4000/webhook/modelriver
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### `modelriver forward` - Quick Webhook Forwarding
|
|
126
|
+
|
|
127
|
+
Forward webhooks using your saved configuration:
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
# Simple - uses saved config from login
|
|
131
|
+
modelriver forward
|
|
132
|
+
|
|
133
|
+
# Override port
|
|
134
|
+
modelriver forward --port 4001
|
|
135
|
+
|
|
136
|
+
# Verbose output
|
|
137
|
+
modelriver forward --verbose
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### `modelriver listen` - Receive Webhooks via WebSocket
|
|
141
|
+
|
|
142
|
+
Like Stripe CLI, receive webhook events directly via WebSocket - no public URL needed.
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
# Start listening for webhooks (like `stripe listen`)
|
|
146
|
+
modelriver listen --print
|
|
147
|
+
# Or use alias: modelriver l --print
|
|
148
|
+
|
|
149
|
+
# Forward to local server
|
|
150
|
+
modelriver listen --port 3001 --print
|
|
151
|
+
|
|
152
|
+
# With custom API key
|
|
153
|
+
modelriver listen --api-key mr_live_YOUR_KEY --print
|
|
154
|
+
|
|
155
|
+
# Forward to external server (without starting local server)
|
|
156
|
+
modelriver listen --port 3002 --forward --print
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
**How it works (like Stripe CLI):**
|
|
160
|
+
1. Authenticates with your API key
|
|
161
|
+
2. Gets a secure WebSocket token (valid for 24 hours)
|
|
162
|
+
3. Connects to ModelRiver via WebSocket
|
|
163
|
+
4. Receives webhook events in real-time - no public URL or ngrok required!
|
|
164
|
+
5. Optionally forwards to local server
|
|
165
|
+
|
|
166
|
+
**Example Output:**
|
|
167
|
+
```
|
|
168
|
+
✓ Connecting to ModelRiver...
|
|
169
|
+
✓ WebSocket connected
|
|
170
|
+
✓ Joined webhook channel
|
|
171
|
+
|
|
172
|
+
> Ready! Listening for webhook events
|
|
173
|
+
> User ID: user-id-123
|
|
174
|
+
> Channel: cli_webhooks:user-id-123
|
|
175
|
+
> Local port: 3001
|
|
176
|
+
|
|
177
|
+
> Press Ctrl+C to stop
|
|
178
|
+
|
|
179
|
+
[2026-01-07 15:20:30] Webhook received via WebSocket:
|
|
180
|
+
Channel ID: abc-123-def
|
|
181
|
+
Status: success
|
|
182
|
+
Data: {"result": "..."}
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### `modelriver websocket` - Test WebSocket Connection
|
|
186
|
+
|
|
187
|
+
Test WebSocket connections to production and receive real-time responses.
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
# Test with workflow
|
|
191
|
+
modelriver websocket --workflow my-workflow --message "Hello from CLI"
|
|
192
|
+
|
|
193
|
+
# With custom payload
|
|
194
|
+
modelriver websocket --workflow my-workflow --payload '{"messages": [{"role": "user", "content": "Test"}]}'
|
|
195
|
+
|
|
196
|
+
# Connect to existing channel
|
|
197
|
+
modelriver websocket --channel-id abc-123 --project-id xyz-789
|
|
198
|
+
|
|
199
|
+
# Verbose output
|
|
200
|
+
modelriver websocket --workflow my-workflow --message "Test" --verbose
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
**Example Output:**
|
|
204
|
+
```
|
|
205
|
+
✓ Making async request...
|
|
206
|
+
✓ Request queued: abc-123-def
|
|
207
|
+
|
|
208
|
+
> Channel ID: abc-123-def
|
|
209
|
+
> Project ID: xyz-789
|
|
210
|
+
|
|
211
|
+
✓ Connecting to WebSocket...
|
|
212
|
+
✓ WebSocket connected
|
|
213
|
+
✓ Channel joined
|
|
214
|
+
|
|
215
|
+
> Waiting for response...
|
|
216
|
+
|
|
217
|
+
✅ Response received:
|
|
218
|
+
{
|
|
219
|
+
"status": "success",
|
|
220
|
+
"data": { ... },
|
|
221
|
+
"meta": { ... }
|
|
222
|
+
}
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
### `modelriver trigger` - Send Async Request
|
|
226
|
+
|
|
227
|
+
Send a test async request and get channel details.
|
|
228
|
+
|
|
229
|
+
```bash
|
|
230
|
+
# Basic trigger
|
|
231
|
+
modelriver trigger --workflow my-workflow --message "Test message"
|
|
232
|
+
|
|
233
|
+
# With custom payload
|
|
234
|
+
modelriver trigger --workflow my-workflow --payload '{"messages": [...]}'
|
|
235
|
+
|
|
236
|
+
# Create webhook to receive response
|
|
237
|
+
modelriver trigger --workflow my-workflow --message "Test" --webhook-url https://webhook.site/your-id
|
|
238
|
+
|
|
239
|
+
# Print channel details
|
|
240
|
+
modelriver trigger --workflow my-workflow --message "Test" --print-channel
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
**Example Output:**
|
|
244
|
+
```
|
|
245
|
+
✓ Async request created
|
|
246
|
+
|
|
247
|
+
Channel Details
|
|
248
|
+
{
|
|
249
|
+
"channel_id": "abc-123-def",
|
|
250
|
+
"project_id": "xyz-789",
|
|
251
|
+
"websocket_url": "wss://api.modelriver.com/socket",
|
|
252
|
+
"websocket_channel": "ai_response:xyz-789:abc-123-def",
|
|
253
|
+
"status": "pending"
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
> Use --webhook-url to automatically receive responses via webhook
|
|
257
|
+
> Or use "modelriver websocket" to connect and receive responses
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
### `modelriver webhook list` - List Webhooks
|
|
261
|
+
|
|
262
|
+
List all webhooks for your project.
|
|
263
|
+
|
|
264
|
+
```bash
|
|
265
|
+
# List webhooks
|
|
266
|
+
modelriver webhook list
|
|
267
|
+
|
|
268
|
+
# Verbose output
|
|
269
|
+
modelriver webhook list --verbose
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
### `modelriver webhook verify` - Verify Signature
|
|
273
|
+
|
|
274
|
+
Verify a webhook signature locally.
|
|
275
|
+
|
|
276
|
+
```bash
|
|
277
|
+
# From file
|
|
278
|
+
modelriver webhook verify \
|
|
279
|
+
--payload webhook.json \
|
|
280
|
+
--signature abc123... \
|
|
281
|
+
--timestamp 1234567890 \
|
|
282
|
+
--secret your-webhook-secret
|
|
283
|
+
|
|
284
|
+
# From JSON string
|
|
285
|
+
modelriver webhook verify \
|
|
286
|
+
--payload '{"channel_id": "...", "data": {...}}' \
|
|
287
|
+
--signature abc123... \
|
|
288
|
+
--timestamp 1234567890 \
|
|
289
|
+
--secret your-webhook-secret
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
## Usage Examples
|
|
293
|
+
|
|
294
|
+
### Example 1: Listen for Webhooks (like Stripe CLI)
|
|
295
|
+
|
|
296
|
+
```bash
|
|
297
|
+
# Terminal 1: Start listening for webhooks via WebSocket
|
|
298
|
+
export MODELRIVER_API_KEY=mr_live_YOUR_KEY
|
|
299
|
+
modelriver listen --print
|
|
300
|
+
|
|
301
|
+
# Terminal 2: Trigger an async AI request
|
|
302
|
+
# Webhook events will appear in Terminal 1 via WebSocket (no public URL needed!)
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
### Example 2: Test WebSocket Connection
|
|
306
|
+
|
|
307
|
+
```bash
|
|
308
|
+
export MODELRIVER_API_KEY=mr_live_YOUR_KEY
|
|
309
|
+
modelriver websocket --workflow my-workflow --message "Hello from CLI" --verbose
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
### Example 3: Send Test Request and Get Channel Info
|
|
313
|
+
|
|
314
|
+
```bash
|
|
315
|
+
export MODELRIVER_API_KEY=mr_live_YOUR_KEY
|
|
316
|
+
modelriver trigger --workflow my-workflow --message "Test" --print-channel
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
## Webhook Payload Format
|
|
320
|
+
|
|
321
|
+
Webhooks are sent as HTTP POST requests with the following format:
|
|
322
|
+
|
|
323
|
+
**Body:**
|
|
324
|
+
```json
|
|
325
|
+
{
|
|
326
|
+
"channel_id": "uuid",
|
|
327
|
+
"timestamp": 1234567890,
|
|
328
|
+
"data": {
|
|
329
|
+
"status": "success|error",
|
|
330
|
+
"data": { ... },
|
|
331
|
+
"meta": { ... }
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
**Headers:**
|
|
337
|
+
- `X-ModelRiver-Signature`: HMAC-SHA256 hex signature
|
|
338
|
+
- `X-ModelRiver-Timestamp`: Unix timestamp string
|
|
339
|
+
- `X-ModelRiver-Webhook-Id`: Webhook UUID
|
|
340
|
+
- `Content-Type`: `application/json`
|
|
341
|
+
|
|
342
|
+
## WebSocket Protocol
|
|
343
|
+
|
|
344
|
+
The CLI connects to ModelRiver WebSockets using the Phoenix protocol:
|
|
345
|
+
|
|
346
|
+
1. Connect to `wss://api.modelriver.com/socket?token={ws_token}`
|
|
347
|
+
2. Join channel: `ai_response:{project_id}:{channel_id}`
|
|
348
|
+
3. Listen for `response` event containing the AI response
|
|
349
|
+
|
|
350
|
+
## Troubleshooting
|
|
351
|
+
|
|
352
|
+
### "API key is required"
|
|
353
|
+
|
|
354
|
+
Set the API key via:
|
|
355
|
+
- Environment variable: `export MODELRIVER_API_KEY=mr_live_YOUR_KEY`
|
|
356
|
+
- CLI flag: `--api-key mr_live_YOUR_KEY`
|
|
357
|
+
- Config file: `~/.modelriver/config.json`
|
|
358
|
+
|
|
359
|
+
### "WebSocket connection failed"
|
|
360
|
+
|
|
361
|
+
- Verify the API URL is correct
|
|
362
|
+
- Check that the `ws_token` hasn't expired (24-hour limit for CLI tokens)
|
|
363
|
+
- Check network connectivity
|
|
364
|
+
- If using production, ensure you're using `wss://` (secure WebSocket)
|
|
365
|
+
|
|
366
|
+
### "Webhook signature verification failed"
|
|
367
|
+
|
|
368
|
+
- Ensure the secret matches exactly (no extra spaces)
|
|
369
|
+
- Verify timestamp is recent (within 5 minutes)
|
|
370
|
+
- Check that payload structure matches expected format
|
|
371
|
+
|
|
372
|
+
**Note**: The CLI does not support creating permanent webhooks. Use the ModelRiver dashboard to create webhooks for production use. The CLI only creates temporary webhooks for testing (via `listen` and `test-webhook` commands), which are automatically cleaned up.
|
|
373
|
+
|
|
374
|
+
## API Endpoints
|
|
375
|
+
|
|
376
|
+
The CLI uses these ModelRiver API endpoints:
|
|
377
|
+
|
|
378
|
+
- `POST /v1/ai/async` - Create async request (production)
|
|
379
|
+
- `POST /api/v1/ai/async` - Create async request (dev/test)
|
|
380
|
+
- `POST /v1/ai/reconnect` - Get reconnect token (production)
|
|
381
|
+
- `POST /api/v1/ai/reconnect` - Get reconnect token (dev/test)
|
|
382
|
+
- `GET /v1/webhooks` - List webhooks (production)
|
|
383
|
+
- `GET /api/v1/webhooks` - List webhooks (dev/test)
|
|
384
|
+
|
|
385
|
+
## Development
|
|
386
|
+
|
|
387
|
+
### Running Tests
|
|
388
|
+
|
|
389
|
+
The CLI includes a Jest test suite. To run the tests:
|
|
390
|
+
|
|
391
|
+
```bash
|
|
392
|
+
npm test
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
Tests cover critical components including:
|
|
396
|
+
- Webhook signature verification
|
|
397
|
+
- Configuration loading
|
|
398
|
+
- API client validation
|
|
399
|
+
- Output formatting
|
|
400
|
+
|
|
401
|
+
|
|
402
|
+
## License
|
|
403
|
+
|
|
404
|
+
MIT
|
|
405
|
+
|
|
406
|
+
|
package/bin/modelriver
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@modelriver/cli",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "ModelRiver CLI for testing webhooks and WebSockets from production",
|
|
5
|
+
"main": "src/index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"modelriver": "./bin/modelriver"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"start": "node bin/modelriver",
|
|
11
|
+
"test": "jest"
|
|
12
|
+
},
|
|
13
|
+
"keywords": [
|
|
14
|
+
"modelriver",
|
|
15
|
+
"cli",
|
|
16
|
+
"webhook",
|
|
17
|
+
"websocket",
|
|
18
|
+
"testing",
|
|
19
|
+
"ai",
|
|
20
|
+
"llm",
|
|
21
|
+
"api"
|
|
22
|
+
],
|
|
23
|
+
"author": "ModelRiver",
|
|
24
|
+
"license": "MIT",
|
|
25
|
+
"repository": {
|
|
26
|
+
"type": "git",
|
|
27
|
+
"url": "https://github.com/modelriver/modelriver-cli.git"
|
|
28
|
+
},
|
|
29
|
+
"homepage": "https://modelriver.com",
|
|
30
|
+
"bugs": {
|
|
31
|
+
"url": "https://github.com/modelriver/modelriver-cli/issues"
|
|
32
|
+
},
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"commander": "^11.1.0",
|
|
35
|
+
"axios": "^1.6.0",
|
|
36
|
+
"ws": "^8.14.2",
|
|
37
|
+
"chalk": "^4.1.2",
|
|
38
|
+
"ora": "^5.4.1",
|
|
39
|
+
"express": "^4.18.2"
|
|
40
|
+
},
|
|
41
|
+
"devDependencies": {
|
|
42
|
+
"jest": "^29.7.0"
|
|
43
|
+
},
|
|
44
|
+
"engines": {
|
|
45
|
+
"node": ">=16.0.0"
|
|
46
|
+
},
|
|
47
|
+
"files": [
|
|
48
|
+
"bin/",
|
|
49
|
+
"src/",
|
|
50
|
+
"README.md"
|
|
51
|
+
]
|
|
52
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
const config = require('../lib/config');
|
|
2
|
+
const Logger = require('../utils/logger');
|
|
3
|
+
const { extractPort } = require('../utils/url-helpers');
|
|
4
|
+
const { listenCommand } = require('./listen');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Forward command - simplified webhook forwarding using saved config
|
|
8
|
+
* This is a user-friendly shortcut for: modelriver listen --forward --print
|
|
9
|
+
*/
|
|
10
|
+
async function forwardCommand(options) {
|
|
11
|
+
const { port, verbose } = options;
|
|
12
|
+
|
|
13
|
+
// Get saved configuration
|
|
14
|
+
const apiKey = config.getApiKey();
|
|
15
|
+
const forwardUrl = config.getForwardUrl();
|
|
16
|
+
|
|
17
|
+
if (!apiKey) {
|
|
18
|
+
Logger.error('No API key configured.');
|
|
19
|
+
Logger.info('Run "modelriver login" first to configure your credentials.');
|
|
20
|
+
process.exit(1);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (!forwardUrl) {
|
|
24
|
+
Logger.error('No forward URL configured.');
|
|
25
|
+
Logger.info('Run "modelriver login" first to configure your forward URL.');
|
|
26
|
+
process.exit(1);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Check if env var is overriding the config
|
|
30
|
+
if (process.env.MODELRIVER_API_KEY) {
|
|
31
|
+
Logger.warning('NOTICE: Using API key from MODELRIVER_API_KEY environment variable.');
|
|
32
|
+
Logger.warning('This overrides your logged-in user configuration.');
|
|
33
|
+
Logger.warning('Run `unset MODELRIVER_API_KEY` to use your saved login credentials.\n');
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Extract port from forward URL or use provided port
|
|
37
|
+
let targetPort = port;
|
|
38
|
+
if (!targetPort) {
|
|
39
|
+
targetPort = extractPort(forwardUrl);
|
|
40
|
+
}
|
|
41
|
+
if (!targetPort) {
|
|
42
|
+
targetPort = 4000; // Default port
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
Logger.info(`Using saved configuration:`);
|
|
46
|
+
Logger.info(` Forward URL: ${forwardUrl}`);
|
|
47
|
+
Logger.info(` Target Port: ${targetPort}`);
|
|
48
|
+
console.log('');
|
|
49
|
+
|
|
50
|
+
// Call listen command with forward options
|
|
51
|
+
await listenCommand({
|
|
52
|
+
apiKey,
|
|
53
|
+
apiUrl: config.getApiUrl(),
|
|
54
|
+
port: targetPort,
|
|
55
|
+
forward: true,
|
|
56
|
+
print: true,
|
|
57
|
+
verbose
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
module.exports = { forwardCommand };
|