securenow 5.3.1 → 5.3.3
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/NPM_README.md +281 -0
- package/README.md +139 -3
- package/cli/apps.js +58 -0
- package/cli.js +1 -1
- package/package.json +1 -1
package/NPM_README.md
CHANGED
|
@@ -16,6 +16,7 @@ OpenTelemetry instrumentation library for Node.js applications. Send distributed
|
|
|
16
16
|
|
|
17
17
|
- [Installation](#installation)
|
|
18
18
|
- [Quick Start](#quick-start)
|
|
19
|
+
- [CLI — Command Line Interface](#cli--command-line-interface)
|
|
19
20
|
- [Framework-Specific Setup](#framework-specific-setup)
|
|
20
21
|
- [Express.js](#expressjs)
|
|
21
22
|
- [Next.js](#nextjs)
|
|
@@ -96,6 +97,286 @@ You'll see confirmation in the console:
|
|
|
96
97
|
|
|
97
98
|
---
|
|
98
99
|
|
|
100
|
+
## CLI — Command Line Interface
|
|
101
|
+
|
|
102
|
+
The `securenow` CLI gives you full access to the SecureNow platform from the terminal — no browser required for day-to-day workflows. Zero additional dependencies.
|
|
103
|
+
|
|
104
|
+
### Getting Started
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
# Log in (opens browser for OAuth)
|
|
108
|
+
npx securenow login
|
|
109
|
+
|
|
110
|
+
# Or use a token for CI/headless environments
|
|
111
|
+
npx securenow login --token <YOUR_JWT>
|
|
112
|
+
|
|
113
|
+
# Check who you're logged in as
|
|
114
|
+
npx securenow whoami
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Managing Applications
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
# List all applications
|
|
121
|
+
npx securenow apps
|
|
122
|
+
|
|
123
|
+
# Create a new application
|
|
124
|
+
npx securenow apps create my-production-app --hosts api.example.com,app.example.com
|
|
125
|
+
|
|
126
|
+
# Get application details (including the app key)
|
|
127
|
+
npx securenow apps info <app-id>
|
|
128
|
+
|
|
129
|
+
# Set a default app so you don't need --app on every command
|
|
130
|
+
npx securenow apps default <app-key>
|
|
131
|
+
|
|
132
|
+
# Delete an application
|
|
133
|
+
npx securenow apps delete <app-id> --force
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Viewing Traces
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
# List recent traces (uses default app, or specify --app)
|
|
140
|
+
npx securenow traces
|
|
141
|
+
npx securenow traces --app <key> --limit 50
|
|
142
|
+
|
|
143
|
+
# Show detailed spans for a trace
|
|
144
|
+
npx securenow traces show <traceId>
|
|
145
|
+
|
|
146
|
+
# AI-powered security analysis of a trace
|
|
147
|
+
npx securenow traces analyze <traceId>
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Viewing Logs
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
# List recent logs
|
|
154
|
+
npx securenow logs
|
|
155
|
+
npx securenow logs --app <key> --minutes 30 --level error
|
|
156
|
+
|
|
157
|
+
# Show logs for a specific trace
|
|
158
|
+
npx securenow logs trace <traceId>
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### Security Issues
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
# List all issues
|
|
165
|
+
npx securenow issues
|
|
166
|
+
npx securenow issues --status open
|
|
167
|
+
|
|
168
|
+
# Show issue details with AI analysis
|
|
169
|
+
npx securenow issues show <issue-id>
|
|
170
|
+
|
|
171
|
+
# Resolve an issue
|
|
172
|
+
npx securenow issues resolve <issue-id>
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### Notifications
|
|
176
|
+
|
|
177
|
+
```bash
|
|
178
|
+
# List notifications
|
|
179
|
+
npx securenow notifications
|
|
180
|
+
|
|
181
|
+
# Check unread count
|
|
182
|
+
npx securenow notifications unread
|
|
183
|
+
|
|
184
|
+
# Mark as read
|
|
185
|
+
npx securenow notifications read <id>
|
|
186
|
+
npx securenow notifications read-all
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### Alerting
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
# View alert rules, channels, and history
|
|
193
|
+
npx securenow alerts rules
|
|
194
|
+
npx securenow alerts channels
|
|
195
|
+
npx securenow alerts history --limit 20
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### IP Intelligence & Blocklist
|
|
199
|
+
|
|
200
|
+
```bash
|
|
201
|
+
# Look up any IP — geo, abuse score, verdict, risk factors
|
|
202
|
+
npx securenow ip 203.0.113.42
|
|
203
|
+
|
|
204
|
+
# Show traces from a specific IP
|
|
205
|
+
npx securenow ip traces 203.0.113.42
|
|
206
|
+
|
|
207
|
+
# Manage the blocklist
|
|
208
|
+
npx securenow blocklist
|
|
209
|
+
npx securenow blocklist add 203.0.113.42 --reason "Brute force scanner"
|
|
210
|
+
npx securenow blocklist remove <id>
|
|
211
|
+
npx securenow blocklist stats
|
|
212
|
+
|
|
213
|
+
# Manage trusted IPs
|
|
214
|
+
npx securenow trusted
|
|
215
|
+
npx securenow trusted add 10.0.0.1 --label "Office VPN"
|
|
216
|
+
npx securenow trusted remove <id>
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
### Forensic Queries
|
|
220
|
+
|
|
221
|
+
Ask questions in plain English — the AI translates them to SQL and runs them against your data.
|
|
222
|
+
|
|
223
|
+
```bash
|
|
224
|
+
# Run a forensic query
|
|
225
|
+
npx securenow forensics "show top 10 attacking IPs in the last hour"
|
|
226
|
+
npx securenow forensics "which endpoints had 5xx errors today"
|
|
227
|
+
|
|
228
|
+
# Browse the saved query library
|
|
229
|
+
npx securenow forensics library
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
### API Map
|
|
233
|
+
|
|
234
|
+
```bash
|
|
235
|
+
# View all discovered API endpoints
|
|
236
|
+
npx securenow api-map
|
|
237
|
+
|
|
238
|
+
# API map statistics
|
|
239
|
+
npx securenow api-map stats
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
### Analytics & Dashboard
|
|
243
|
+
|
|
244
|
+
```bash
|
|
245
|
+
# Response code analytics
|
|
246
|
+
npx securenow analytics --app <key>
|
|
247
|
+
|
|
248
|
+
# Full dashboard overview (apps, protection status, unread alerts)
|
|
249
|
+
npx securenow status
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
### Instances
|
|
253
|
+
|
|
254
|
+
```bash
|
|
255
|
+
# List ClickHouse instances
|
|
256
|
+
npx securenow instances
|
|
257
|
+
|
|
258
|
+
# Test an instance connection
|
|
259
|
+
npx securenow instances test <id>
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
### Configuration
|
|
263
|
+
|
|
264
|
+
```bash
|
|
265
|
+
# View all config
|
|
266
|
+
npx securenow config get
|
|
267
|
+
|
|
268
|
+
# Set values
|
|
269
|
+
npx securenow config set apiUrl https://custom-api.example.com
|
|
270
|
+
npx securenow config set defaultApp <app-key>
|
|
271
|
+
npx securenow config set format json
|
|
272
|
+
|
|
273
|
+
# Show config file paths
|
|
274
|
+
npx securenow config path
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
Config files are stored in `~/.securenow/`:
|
|
278
|
+
|
|
279
|
+
| File | Description |
|
|
280
|
+
|------|-------------|
|
|
281
|
+
| `config.json` | API URL, default app, output format |
|
|
282
|
+
| `credentials.json` | Auth token (file permissions: 0600) |
|
|
283
|
+
|
|
284
|
+
### Initialize Instrumentation
|
|
285
|
+
|
|
286
|
+
```bash
|
|
287
|
+
# Interactive setup — creates instrumentation files for Next.js
|
|
288
|
+
npx securenow init
|
|
289
|
+
npx securenow init --ts --src --force
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
### Global Flags
|
|
293
|
+
|
|
294
|
+
Every command supports these flags:
|
|
295
|
+
|
|
296
|
+
| Flag | Short | Description |
|
|
297
|
+
|------|-------|-------------|
|
|
298
|
+
| `--json` | `-j` | Output as JSON for scripting and CI/CD |
|
|
299
|
+
| `--help` | | Show help for the command |
|
|
300
|
+
| `--app <key>` | | Override the default application key |
|
|
301
|
+
|
|
302
|
+
### Environment Variables
|
|
303
|
+
|
|
304
|
+
| Variable | Description |
|
|
305
|
+
|----------|-------------|
|
|
306
|
+
| `SECURENOW_API_URL` | Override the API base URL |
|
|
307
|
+
| `SECURENOW_DEBUG` | Show stack traces on errors |
|
|
308
|
+
| `NO_COLOR` | Disable colored output |
|
|
309
|
+
|
|
310
|
+
### CI/CD Integration
|
|
311
|
+
|
|
312
|
+
```bash
|
|
313
|
+
# Authenticate with a token in CI
|
|
314
|
+
npx securenow login --token $SECURENOW_TOKEN
|
|
315
|
+
|
|
316
|
+
# Use --json for machine-readable output
|
|
317
|
+
npx securenow issues --json | jq '.[] | select(.severity == "critical")'
|
|
318
|
+
|
|
319
|
+
# Check for critical issues in a pipeline
|
|
320
|
+
ISSUES=$(npx securenow issues --json --status open)
|
|
321
|
+
CRITICAL=$(echo "$ISSUES" | jq '[.[] | select(.severity == "critical")] | length')
|
|
322
|
+
if [ "$CRITICAL" -gt "0" ]; then
|
|
323
|
+
echo "Found $CRITICAL critical issues!"
|
|
324
|
+
exit 1
|
|
325
|
+
fi
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
### Complete Command Reference
|
|
329
|
+
|
|
330
|
+
| Category | Command | Description |
|
|
331
|
+
|----------|---------|-------------|
|
|
332
|
+
| **Auth** | `login` | Authenticate via browser or `--token` |
|
|
333
|
+
| | `logout` | Clear credentials |
|
|
334
|
+
| | `whoami` | Show session info |
|
|
335
|
+
| **Apps** | `apps` | List applications |
|
|
336
|
+
| | `apps create <name>` | Create application |
|
|
337
|
+
| | `apps info <id>` | Application details |
|
|
338
|
+
| | `apps delete <id>` | Delete application |
|
|
339
|
+
| | `apps default <key>` | Set default app |
|
|
340
|
+
| **Observe** | `traces` | List traces |
|
|
341
|
+
| | `traces show <id>` | Trace details |
|
|
342
|
+
| | `traces analyze <id>` | AI trace analysis |
|
|
343
|
+
| | `logs` | List logs |
|
|
344
|
+
| | `logs trace <id>` | Logs for a trace |
|
|
345
|
+
| | `analytics` | Response analytics |
|
|
346
|
+
| | `status` | Dashboard overview |
|
|
347
|
+
| **Detect** | `issues` | List issues |
|
|
348
|
+
| | `issues show <id>` | Issue details |
|
|
349
|
+
| | `issues resolve <id>` | Resolve issue |
|
|
350
|
+
| | `notifications` | List notifications |
|
|
351
|
+
| | `notifications unread` | Unread count |
|
|
352
|
+
| | `notifications read <id>` | Mark read |
|
|
353
|
+
| | `notifications read-all` | Mark all read |
|
|
354
|
+
| | `alerts rules` | Alert rules |
|
|
355
|
+
| | `alerts channels` | Alert channels |
|
|
356
|
+
| | `alerts history` | Alert history |
|
|
357
|
+
| **Investigate** | `ip <addr>` | IP intelligence |
|
|
358
|
+
| | `ip traces <addr>` | Traces from IP |
|
|
359
|
+
| | `forensics "<query>"` | NL forensic query |
|
|
360
|
+
| | `forensics library` | Saved queries |
|
|
361
|
+
| | `api-map` | API endpoints |
|
|
362
|
+
| | `api-map stats` | API stats |
|
|
363
|
+
| **Remediate** | `blocklist` | Blocked IPs |
|
|
364
|
+
| | `blocklist add <ip>` | Block IP |
|
|
365
|
+
| | `blocklist remove <id>` | Unblock IP |
|
|
366
|
+
| | `blocklist stats` | Block stats |
|
|
367
|
+
| | `trusted` | Trusted IPs |
|
|
368
|
+
| | `trusted add <ip>` | Add trusted IP |
|
|
369
|
+
| | `trusted remove <id>` | Remove trusted |
|
|
370
|
+
| **Settings** | `instances` | List instances |
|
|
371
|
+
| | `instances test <id>` | Test connection |
|
|
372
|
+
| | `config get` | Show config |
|
|
373
|
+
| | `config set <k> <v>` | Set config value |
|
|
374
|
+
| | `config path` | Config file paths |
|
|
375
|
+
| | `init` | Setup instrumentation |
|
|
376
|
+
| | `version` | Show version |
|
|
377
|
+
|
|
378
|
+
---
|
|
379
|
+
|
|
99
380
|
## Framework-Specific Setup
|
|
100
381
|
|
|
101
382
|
### Express.js
|
package/README.md
CHANGED
|
@@ -36,7 +36,37 @@ SECURENOW_INSTANCE=http://your-otlp-collector:4318
|
|
|
36
36
|
npx securenow init
|
|
37
37
|
```
|
|
38
38
|
|
|
39
|
-
**Done!**
|
|
39
|
+
**Done!** See [Next.js Complete Guide](./docs/NEXTJS-GUIDE.md) for details.
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
### CLI — Manage Everything from the Terminal
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
# Authenticate
|
|
47
|
+
npx securenow login
|
|
48
|
+
|
|
49
|
+
# Create an app and get the key
|
|
50
|
+
npx securenow apps create my-app
|
|
51
|
+
|
|
52
|
+
# Set it as default so you don't need --app every time
|
|
53
|
+
npx securenow config set defaultApp <key>
|
|
54
|
+
|
|
55
|
+
# View traces, logs, issues
|
|
56
|
+
npx securenow traces
|
|
57
|
+
npx securenow logs
|
|
58
|
+
npx securenow issues
|
|
59
|
+
|
|
60
|
+
# IP intelligence, forensic queries, blocklist
|
|
61
|
+
npx securenow ip 1.2.3.4
|
|
62
|
+
npx securenow forensics "show top attacking IPs in the last hour"
|
|
63
|
+
npx securenow blocklist add 1.2.3.4 --reason "scanner"
|
|
64
|
+
|
|
65
|
+
# Full dashboard overview
|
|
66
|
+
npx securenow status
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Run `npx securenow help` for all commands. See the [CLI Reference](#cli-reference) below.
|
|
40
70
|
|
|
41
71
|
---
|
|
42
72
|
|
|
@@ -173,7 +203,113 @@ SecureNow automatically instruments:
|
|
|
173
203
|
|
|
174
204
|
---
|
|
175
205
|
|
|
176
|
-
##
|
|
206
|
+
## CLI Reference
|
|
207
|
+
|
|
208
|
+
After installing the package, the `securenow` CLI is available via `npx securenow` or globally after `npm install -g securenow`.
|
|
209
|
+
|
|
210
|
+
### Authentication
|
|
211
|
+
|
|
212
|
+
| Command | Description |
|
|
213
|
+
|---------|-------------|
|
|
214
|
+
| `securenow login` | Log in via browser (opens OAuth flow) |
|
|
215
|
+
| `securenow login --token <TOKEN>` | Log in with a token (for CI/headless) |
|
|
216
|
+
| `securenow logout` | Clear stored credentials |
|
|
217
|
+
| `securenow whoami` | Show current session info |
|
|
218
|
+
|
|
219
|
+
### Applications
|
|
220
|
+
|
|
221
|
+
| Command | Description |
|
|
222
|
+
|---------|-------------|
|
|
223
|
+
| `securenow apps` | List all applications |
|
|
224
|
+
| `securenow apps create <name>` | Create app and get the app key |
|
|
225
|
+
| `securenow apps info <id>` | Show application details |
|
|
226
|
+
| `securenow apps delete <id>` | Delete an application |
|
|
227
|
+
| `securenow apps default <key>` | Set default app for all commands |
|
|
228
|
+
|
|
229
|
+
### Observability
|
|
230
|
+
|
|
231
|
+
| Command | Description |
|
|
232
|
+
|---------|-------------|
|
|
233
|
+
| `securenow traces --app <key>` | List recent traces |
|
|
234
|
+
| `securenow traces show <traceId>` | Show trace spans |
|
|
235
|
+
| `securenow traces analyze <traceId>` | AI security analysis of a trace |
|
|
236
|
+
| `securenow logs --app <key>` | View logs (with `--minutes`, `--level`) |
|
|
237
|
+
| `securenow logs trace <traceId>` | View logs for a specific trace |
|
|
238
|
+
| `securenow analytics` | Response code analytics overview |
|
|
239
|
+
| `securenow status` | Full dashboard summary |
|
|
240
|
+
|
|
241
|
+
### Detect & Respond
|
|
242
|
+
|
|
243
|
+
| Command | Description |
|
|
244
|
+
|---------|-------------|
|
|
245
|
+
| `securenow issues` | List security issues |
|
|
246
|
+
| `securenow issues show <id>` | Show issue details and AI analysis |
|
|
247
|
+
| `securenow issues resolve <id>` | Mark an issue as resolved |
|
|
248
|
+
| `securenow notifications` | List notifications |
|
|
249
|
+
| `securenow notifications unread` | Show unread count |
|
|
250
|
+
| `securenow notifications read <id>` | Mark notification as read |
|
|
251
|
+
| `securenow notifications read-all` | Mark all as read |
|
|
252
|
+
| `securenow alerts rules` | List alert rules |
|
|
253
|
+
| `securenow alerts channels` | List alert channels |
|
|
254
|
+
| `securenow alerts history` | View alert history |
|
|
255
|
+
|
|
256
|
+
### Investigate
|
|
257
|
+
|
|
258
|
+
| Command | Description |
|
|
259
|
+
|---------|-------------|
|
|
260
|
+
| `securenow ip <address>` | IP intelligence lookup (geo, abuse score, verdict) |
|
|
261
|
+
| `securenow ip traces <address>` | Show traces originating from an IP |
|
|
262
|
+
| `securenow forensics "<query>"` | Natural language forensic query (NL to SQL) |
|
|
263
|
+
| `securenow forensics library` | View saved query library |
|
|
264
|
+
| `securenow api-map` | View discovered API endpoints |
|
|
265
|
+
| `securenow api-map stats` | API map statistics |
|
|
266
|
+
|
|
267
|
+
### Remediation
|
|
268
|
+
|
|
269
|
+
| Command | Description |
|
|
270
|
+
|---------|-------------|
|
|
271
|
+
| `securenow blocklist` | List blocked IPs |
|
|
272
|
+
| `securenow blocklist add <ip>` | Block an IP (`--reason <reason>`) |
|
|
273
|
+
| `securenow blocklist remove <id>` | Remove from blocklist |
|
|
274
|
+
| `securenow blocklist stats` | Blocklist statistics |
|
|
275
|
+
| `securenow trusted` | List trusted IPs |
|
|
276
|
+
| `securenow trusted add <ip>` | Add trusted IP (`--label <label>`) |
|
|
277
|
+
| `securenow trusted remove <id>` | Remove trusted IP |
|
|
278
|
+
|
|
279
|
+
### Settings
|
|
280
|
+
|
|
281
|
+
| Command | Description |
|
|
282
|
+
|---------|-------------|
|
|
283
|
+
| `securenow instances` | List ClickHouse instances |
|
|
284
|
+
| `securenow instances test <id>` | Test instance connection |
|
|
285
|
+
| `securenow config get` | Show all config values |
|
|
286
|
+
| `securenow config set <key> <value>` | Set a config value |
|
|
287
|
+
| `securenow config path` | Show config file locations |
|
|
288
|
+
| `securenow init` | Initialize instrumentation files |
|
|
289
|
+
| `securenow version` | Show CLI version |
|
|
290
|
+
|
|
291
|
+
### Global Flags
|
|
292
|
+
|
|
293
|
+
| Flag | Description |
|
|
294
|
+
|------|-------------|
|
|
295
|
+
| `--json` | Output as JSON (works on every command) |
|
|
296
|
+
| `--help` | Show help for any command |
|
|
297
|
+
| `--app <key>` | Specify app key (or set default with `config set defaultApp`) |
|
|
298
|
+
|
|
299
|
+
### Configuration
|
|
300
|
+
|
|
301
|
+
Credentials and settings are stored in `~/.securenow/`:
|
|
302
|
+
|
|
303
|
+
| File | Purpose |
|
|
304
|
+
|------|---------|
|
|
305
|
+
| `~/.securenow/config.json` | API URL, default app, preferences |
|
|
306
|
+
| `~/.securenow/credentials.json` | Auth token (restricted permissions) |
|
|
307
|
+
|
|
308
|
+
Override the API URL with `securenow config set apiUrl <url>` or the `SECURENOW_API_URL` environment variable.
|
|
309
|
+
|
|
310
|
+
---
|
|
311
|
+
|
|
312
|
+
## Support
|
|
177
313
|
|
|
178
314
|
- **Website:** [securenow.ai](http://securenow.ai/)
|
|
179
315
|
- **Issues:** Report bugs and request features
|
|
@@ -181,6 +317,6 @@ SecureNow automatically instruments:
|
|
|
181
317
|
|
|
182
318
|
---
|
|
183
319
|
|
|
184
|
-
##
|
|
320
|
+
## License
|
|
185
321
|
|
|
186
322
|
ISC
|
package/cli/apps.js
CHANGED
|
@@ -56,8 +56,11 @@ async function create(args, flags) {
|
|
|
56
56
|
if (flags.hosts) {
|
|
57
57
|
body.hosts = flags.hosts.split(',').map(h => h.trim());
|
|
58
58
|
}
|
|
59
|
+
|
|
59
60
|
if (flags.instance) {
|
|
60
61
|
body.instanceId = flags.instance;
|
|
62
|
+
} else if (process.stdin.isTTY) {
|
|
63
|
+
body.instanceId = await pickInstance();
|
|
61
64
|
}
|
|
62
65
|
|
|
63
66
|
const s = ui.spinner(`Creating application "${name}"`);
|
|
@@ -91,6 +94,61 @@ async function create(args, flags) {
|
|
|
91
94
|
}
|
|
92
95
|
}
|
|
93
96
|
|
|
97
|
+
async function pickInstance() {
|
|
98
|
+
const s = ui.spinner('Loading instances');
|
|
99
|
+
let instances = [];
|
|
100
|
+
try {
|
|
101
|
+
const data = await api.get('/instances');
|
|
102
|
+
instances = data.instances || [];
|
|
103
|
+
s.stop('Instances loaded');
|
|
104
|
+
} catch {
|
|
105
|
+
s.stop('Could not load instances');
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const FREE_TRIAL_LABEL = `${ui.c.green('Free Trial')} ${ui.c.dim('— SecureNow managed instance (no setup needed)')}`;
|
|
110
|
+
|
|
111
|
+
const choices = [{ label: FREE_TRIAL_LABEL, value: null }];
|
|
112
|
+
|
|
113
|
+
for (const inst of instances) {
|
|
114
|
+
const status = inst.status === 'active' ? ui.c.green('●') : ui.c.red('●');
|
|
115
|
+
const apps = inst.linkedApps ? ui.c.dim(` (${inst.linkedApps} app${inst.linkedApps !== 1 ? 's' : ''})`) : '';
|
|
116
|
+
choices.push({
|
|
117
|
+
label: `${status} ${inst.name}${apps} ${ui.c.dim(`[${inst._id}]`)}`,
|
|
118
|
+
value: inst._id,
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const appUrl = config.getAppUrl();
|
|
123
|
+
choices.push({
|
|
124
|
+
label: `${ui.c.cyan('+')} Create a new instance ${ui.c.dim('(opens browser)')}`,
|
|
125
|
+
value: '__new__',
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
const selected = await ui.select('Which instance should this app use?', choices);
|
|
129
|
+
|
|
130
|
+
if (selected === '__new__') {
|
|
131
|
+
const url = `${appUrl}/dashboard/settings/instances`;
|
|
132
|
+
ui.info(`Opening ${ui.c.underline(url)}`);
|
|
133
|
+
openBrowser(url);
|
|
134
|
+
ui.info('Create your instance in the browser, then run this command again.');
|
|
135
|
+
process.exit(0);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
return selected;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function openBrowser(url) {
|
|
142
|
+
const { execSync } = require('child_process');
|
|
143
|
+
try {
|
|
144
|
+
if (process.platform === 'darwin') execSync(`open "${url}"`);
|
|
145
|
+
else if (process.platform === 'win32') execSync(`start "" "${url}"`);
|
|
146
|
+
else execSync(`xdg-open "${url}"`);
|
|
147
|
+
} catch {
|
|
148
|
+
ui.warn(`Could not open browser. Visit: ${url}`);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
94
152
|
async function info(args, flags) {
|
|
95
153
|
requireAuth();
|
|
96
154
|
|
package/cli.js
CHANGED
|
@@ -60,7 +60,7 @@ const COMMANDS = {
|
|
|
60
60
|
usage: 'securenow apps <subcommand> [options]',
|
|
61
61
|
sub: {
|
|
62
62
|
list: { desc: 'List all applications', run: (a, f) => require('./cli/apps').list(a, f) },
|
|
63
|
-
create: { desc: 'Create a new application', usage: 'securenow apps create <name> [--hosts host1,host2] [--instance <id>]', run: (a, f) => require('./cli/apps').create(a, f) },
|
|
63
|
+
create: { desc: 'Create a new application (interactive instance picker)', usage: 'securenow apps create <name> [--hosts host1,host2] [--instance <id>]', run: (a, f) => require('./cli/apps').create(a, f) },
|
|
64
64
|
info: { desc: 'Show application details', usage: 'securenow apps info <id>', run: (a, f) => require('./cli/apps').info(a, f) },
|
|
65
65
|
delete: { desc: 'Delete an application', usage: 'securenow apps delete <id> [--force]', run: (a, f) => require('./cli/apps').remove(a, f) },
|
|
66
66
|
default: { desc: 'Set default application', usage: 'securenow apps default <key>', run: (a, f) => require('./cli/apps').setDefault(a, f) },
|
package/package.json
CHANGED