@ranger-testing/ranger-cli 1.0.5 → 1.0.7
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 +281 -0
- package/build/cli.js +168 -1
- package/build/cli.js.map +1 -0
- package/build/commands/addEnv.js +1 -110
- package/build/commands/addEnv.js.map +1 -0
- package/build/commands/authEncrypt.js +40 -0
- package/build/commands/authEncrypt.js.map +1 -0
- package/build/commands/clean.js +1 -0
- package/build/commands/clean.js.map +1 -0
- package/build/commands/config.js +100 -0
- package/build/commands/config.js.map +1 -0
- package/build/commands/dataMcpServer.js +1 -0
- package/build/commands/dataMcpServer.js.map +1 -0
- package/build/commands/index.js +6 -0
- package/build/commands/index.js.map +1 -0
- package/build/commands/skillup.js +112 -0
- package/build/commands/skillup.js.map +1 -0
- package/build/commands/start.js +1 -72
- package/build/commands/start.js.map +1 -0
- package/build/commands/status.js +221 -0
- package/build/commands/status.js.map +1 -0
- package/build/commands/update.js +127 -0
- package/build/commands/update.js.map +1 -0
- package/build/commands/updateEnv.js +1 -64
- package/build/commands/updateEnv.js.map +1 -0
- package/build/commands/useEnv.js +1 -28
- package/build/commands/useEnv.js.map +1 -0
- package/build/commands/utils/browserSessionsApi.js +1 -0
- package/build/commands/utils/browserSessionsApi.js.map +1 -0
- package/build/commands/utils/crypto.js +42 -0
- package/build/commands/utils/crypto.js.map +1 -0
- package/build/commands/utils/keychain.js +1 -0
- package/build/commands/utils/keychain.js.map +1 -0
- package/build/commands/utils/localAgentInstallationsApi.js +1 -0
- package/build/commands/utils/localAgentInstallationsApi.js.map +1 -0
- package/build/commands/utils/mcpConfig.js +1 -47
- package/build/commands/utils/mcpConfig.js.map +1 -0
- package/build/commands/utils/reportGenerator.js +130 -0
- package/build/commands/utils/reportGenerator.js.map +1 -0
- package/build/commands/utils/settings.js +246 -0
- package/build/commands/utils/settings.js.map +1 -0
- package/build/commands/utils/skills.js +1 -0
- package/build/commands/utils/skills.js.map +1 -0
- package/build/commands/verifyInBrowser.js +1 -0
- package/build/commands/verifyInBrowser.js.map +1 -0
- package/build/skills/bug-bash.md +313 -0
- package/build/skills/e2e-test-recommender.md +173 -0
- package/package.json +7 -4
package/README.md
ADDED
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
# Ranger CLI
|
|
2
|
+
|
|
3
|
+
The Ranger CLI sets up your project to use Ranger's AI-powered testing tools with Claude Code.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g @ranger-testing/ranger-cli
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
1. Get your API token from [dashboard.ranger.net/settings](https://dashboard.ranger.net/settings)
|
|
14
|
+
|
|
15
|
+
2. Initialize Ranger in your project:
|
|
16
|
+
```bash
|
|
17
|
+
ranger start <your-api-token>
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
3. Add an environment (e.g., local, staging, prod):
|
|
21
|
+
```bash
|
|
22
|
+
ranger add env local
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
4. Install skills for Claude Code:
|
|
26
|
+
```bash
|
|
27
|
+
ranger skillup
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
5. Start using Ranger with Claude Code!
|
|
31
|
+
|
|
32
|
+
## Commands
|
|
33
|
+
|
|
34
|
+
### `ranger start <token>`
|
|
35
|
+
|
|
36
|
+
Initialize Ranger in your project. Get your token from [dashboard.ranger.net/settings](https://dashboard.ranger.net/settings).
|
|
37
|
+
|
|
38
|
+
This command:
|
|
39
|
+
- Validates your API token
|
|
40
|
+
- Creates `.mcp.json` with the Ranger MCP server configuration
|
|
41
|
+
- Creates the `.ranger/` directory for environment configs
|
|
42
|
+
- Creates `.ranger/.gitignore` to exclude local environment (contains auth state)
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
ranger start rngr_abc123...
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### `ranger skillup`
|
|
49
|
+
|
|
50
|
+
Install Ranger skills for Claude Code. This command installs AI agents that help with testing and bug hunting:
|
|
51
|
+
|
|
52
|
+
- **e2e-test-recommender** - Installed if you have an API token. Analyzes code changes and suggests end-to-end tests.
|
|
53
|
+
- **bug-bash** - Installed if you have an API token AND an active environment. Explores new features via browser to find bugs.
|
|
54
|
+
|
|
55
|
+
Skills are installed to `.claude/skills/` and can be invoked in Claude Code conversations.
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
ranger skillup
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Run this command after `ranger start` and again after `ranger add env` to install all available skills.
|
|
62
|
+
|
|
63
|
+
### `ranger add env <env-name>`
|
|
64
|
+
|
|
65
|
+
Add a new environment configuration. You'll be prompted to:
|
|
66
|
+
- Specify if authentication is required
|
|
67
|
+
- Log in via browser if needed (captures auth cookies/storage)
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
ranger add env local
|
|
71
|
+
ranger add env staging
|
|
72
|
+
ranger add env prod
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### `ranger use <env-name>`
|
|
76
|
+
|
|
77
|
+
Switch to a different environment.
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
ranger use staging
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### `ranger update env <env-name>`
|
|
84
|
+
|
|
85
|
+
Update authentication for an existing environment (re-capture cookies/storage).
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
ranger update env staging
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### `ranger config`
|
|
92
|
+
|
|
93
|
+
Manage browser configuration for environments (userAgent, headers, etc.).
|
|
94
|
+
|
|
95
|
+
#### `ranger config set <env> <key> <value>`
|
|
96
|
+
|
|
97
|
+
Set a config value. Supports dot notation for nested keys.
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
# Set user agent
|
|
101
|
+
ranger config set ci userAgent "Mozilla/5.0 (CI Bot)"
|
|
102
|
+
|
|
103
|
+
# Set custom headers
|
|
104
|
+
ranger config set ci header.X-Test-Mode "true"
|
|
105
|
+
ranger config set ci header.Authorization '${AUTH_TOKEN}'
|
|
106
|
+
|
|
107
|
+
# Run browser in headless mode (useful for CI)
|
|
108
|
+
ranger config set ci headless true
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
**Environment variable substitution**: Values like `${VAR_NAME}` are stored as-is and resolved at runtime when `verify-in-browser` runs.
|
|
112
|
+
|
|
113
|
+
#### `ranger config get <env> <key>`
|
|
114
|
+
|
|
115
|
+
Get a config value.
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
ranger config get ci userAgent
|
|
119
|
+
# Mozilla/5.0 (CI Bot)
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
#### `ranger config list <env>`
|
|
123
|
+
|
|
124
|
+
List all config for an environment.
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
ranger config list ci
|
|
128
|
+
# userAgent: Mozilla/5.0 (CI Bot)
|
|
129
|
+
# headless: true
|
|
130
|
+
# headers:
|
|
131
|
+
# X-Test-Mode: true
|
|
132
|
+
# Authorization: ${AUTH_TOKEN}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
#### `ranger config unset <env> <key>`
|
|
136
|
+
|
|
137
|
+
Remove a config value.
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
ranger config unset ci header.X-Test-Mode
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### `ranger verify-in-browser --url <url> --task <task>`
|
|
144
|
+
|
|
145
|
+
Verify a UI flow in an isolated browser session. Returns structured results with any issues found.
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
ranger verify-in-browser \
|
|
149
|
+
--url "http://localhost:3000/login" \
|
|
150
|
+
--task "Enter valid credentials and verify successful login"
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### `ranger clean`
|
|
154
|
+
|
|
155
|
+
Remove all Ranger artifacts from the project (`.ranger/`, `.mcp.json` entries).
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
ranger clean
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
## Using with Claude Code
|
|
162
|
+
|
|
163
|
+
Once Ranger is set up, you can use it with Claude Code in several ways:
|
|
164
|
+
|
|
165
|
+
### 1. Ranger MCP Tools
|
|
166
|
+
|
|
167
|
+
After running `ranger start`, the Ranger MCP server is configured in your project. Claude Code can use these tools:
|
|
168
|
+
|
|
169
|
+
- `mcp__ranger__get_product_docs` - Get your product's sitemap and entity documentation
|
|
170
|
+
- `mcp__ranger__get_test_suite` - List all tests in your test suite
|
|
171
|
+
- `mcp__ranger__get_test_details` - Get details for a specific test
|
|
172
|
+
- `mcp__ranger__create_draft_test` - Create a new draft test
|
|
173
|
+
- `mcp__ranger__generate_test_plan` - Generate a test plan with steps
|
|
174
|
+
|
|
175
|
+
### 2. Browser Tools (after `ranger add env`)
|
|
176
|
+
|
|
177
|
+
Once you add an environment, Claude Code can interact with your app via browser:
|
|
178
|
+
|
|
179
|
+
- `mcp__ranger-browser__browser_navigate` - Navigate to a URL
|
|
180
|
+
- `mcp__ranger-browser__browser_snapshot` - Get page accessibility snapshot
|
|
181
|
+
- `mcp__ranger-browser__browser_click` - Click an element
|
|
182
|
+
- `mcp__ranger-browser__browser_type` - Type text
|
|
183
|
+
- `mcp__ranger-browser__browser_fill_form` - Fill form fields
|
|
184
|
+
- And more...
|
|
185
|
+
|
|
186
|
+
### 3. Bug Bash Skill
|
|
187
|
+
|
|
188
|
+
The **bug-bash** skill explores new features to find bugs. Invoke it in Claude Code:
|
|
189
|
+
|
|
190
|
+
```
|
|
191
|
+
/bug-bash
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
Or ask Claude to explore your changes:
|
|
195
|
+
|
|
196
|
+
> "Explore the new settings page I just built and look for bugs"
|
|
197
|
+
|
|
198
|
+
The bug-bash skill will:
|
|
199
|
+
1. Analyze your git diff to understand what changed
|
|
200
|
+
2. Generate exploration ideas based on the changes
|
|
201
|
+
3. Systematically test flows using `ranger verify-in-browser`
|
|
202
|
+
4. Report any issues found with severity levels
|
|
203
|
+
|
|
204
|
+
### 4. E2E Test Recommender Skill
|
|
205
|
+
|
|
206
|
+
The **e2e-test-recommender** skill analyzes your code changes and suggests end-to-end tests. Invoke it:
|
|
207
|
+
|
|
208
|
+
```
|
|
209
|
+
/e2e-test-recommender
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
Or ask Claude:
|
|
213
|
+
|
|
214
|
+
> "What e2e tests should I add for my recent changes?"
|
|
215
|
+
|
|
216
|
+
### 5. Direct Browser Verification
|
|
217
|
+
|
|
218
|
+
Use the `verify-in-browser` command directly for quick UI checks:
|
|
219
|
+
|
|
220
|
+
```bash
|
|
221
|
+
# Verify login works
|
|
222
|
+
ranger verify-in-browser \
|
|
223
|
+
--url "http://localhost:3000/login" \
|
|
224
|
+
--task "Log in with test@example.com / password123, verify dashboard loads"
|
|
225
|
+
|
|
226
|
+
# Verify form validation
|
|
227
|
+
ranger verify-in-browser \
|
|
228
|
+
--url "http://localhost:3000/signup" \
|
|
229
|
+
--task "Submit form with empty email, verify error message appears"
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
The command returns:
|
|
233
|
+
- `success`: Whether the flow completed without issues
|
|
234
|
+
- `summary`: Description of what happened
|
|
235
|
+
- `issues`: Array of problems found (BLOCKER, MAJOR, MINOR)
|
|
236
|
+
- Exit code 0 for success, 1 for issues found
|
|
237
|
+
|
|
238
|
+
## Environment Variables
|
|
239
|
+
|
|
240
|
+
| Variable | Description |
|
|
241
|
+
|----------|-------------|
|
|
242
|
+
| `MCP_SERVER_URL` | Override the default Ranger MCP server URL |
|
|
243
|
+
| `ANTHROPIC_API_KEY` | Required for publishing skills to Anthropic API |
|
|
244
|
+
|
|
245
|
+
## Example Workflow
|
|
246
|
+
|
|
247
|
+
```bash
|
|
248
|
+
# Set up Ranger
|
|
249
|
+
ranger start rngr_your_token_here
|
|
250
|
+
|
|
251
|
+
# Add your local development environment
|
|
252
|
+
ranger add env local
|
|
253
|
+
# (Browser opens, log in if needed, close when done)
|
|
254
|
+
|
|
255
|
+
# Install skills for Claude Code
|
|
256
|
+
ranger skillup
|
|
257
|
+
|
|
258
|
+
# Now use Claude Code to test your app
|
|
259
|
+
# Claude can now browse your app, find bugs, and suggest tests!
|
|
260
|
+
|
|
261
|
+
# When switching to test staging:
|
|
262
|
+
ranger add env staging
|
|
263
|
+
ranger use staging
|
|
264
|
+
|
|
265
|
+
# Clean up when done
|
|
266
|
+
ranger clean
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
## Troubleshooting
|
|
270
|
+
|
|
271
|
+
### "No active environment" error
|
|
272
|
+
|
|
273
|
+
Run `ranger use <env-name>` to set an active environment before using `verify-in-browser`.
|
|
274
|
+
|
|
275
|
+
### "Ranger Browser MCP not configured" error
|
|
276
|
+
|
|
277
|
+
Run `ranger add env <name>` to configure browser access for an environment.
|
|
278
|
+
|
|
279
|
+
### Authentication expired
|
|
280
|
+
|
|
281
|
+
Run `ranger update env <env-name>` to refresh authentication cookies/storage.
|
package/build/cli.js
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import yargs from 'yargs/yargs';
|
|
3
|
-
import { addEnv, start, useEnv, updateEnv } from './commands/index.js';
|
|
3
|
+
import { addEnv, clean, start, useEnv, updateEnv, update, skillup, } from './commands/index.js';
|
|
4
|
+
import { authEncrypt } from './commands/authEncrypt.js';
|
|
5
|
+
import { status } from './commands/status.js';
|
|
6
|
+
import { configSet, configGet, configList, configUnset, } from './commands/config.js';
|
|
7
|
+
import { dataMcpServer } from './commands/dataMcpServer.js';
|
|
8
|
+
import { verifyInBrowser } from './commands/verifyInBrowser.js';
|
|
9
|
+
import { generateMarkdownReport, collectScreenshots, } from './commands/utils/reportGenerator.js';
|
|
4
10
|
import dotenv from 'dotenv';
|
|
5
11
|
dotenv.config();
|
|
6
12
|
// Setup yargs CLI
|
|
@@ -41,8 +47,169 @@ yargs(process.argv.slice(2))
|
|
|
41
47
|
});
|
|
42
48
|
}, async (argv) => {
|
|
43
49
|
await start(argv.token);
|
|
50
|
+
})
|
|
51
|
+
.command('skillup', 'Install Ranger skills for Claude Code', () => { }, async () => {
|
|
52
|
+
await skillup();
|
|
53
|
+
})
|
|
54
|
+
.command('clean', 'Remove all Ranger artifacts from the project', async () => {
|
|
55
|
+
await clean();
|
|
56
|
+
})
|
|
57
|
+
.command('config', 'Manage environment configuration', (yargs) => {
|
|
58
|
+
return yargs
|
|
59
|
+
.command('set <env> <key> <value>', 'Set a config value', (yargs) => {
|
|
60
|
+
return yargs
|
|
61
|
+
.positional('env', {
|
|
62
|
+
type: 'string',
|
|
63
|
+
description: 'Environment name',
|
|
64
|
+
demandOption: true,
|
|
65
|
+
})
|
|
66
|
+
.positional('key', {
|
|
67
|
+
type: 'string',
|
|
68
|
+
description: 'Config key (e.g., userAgent, header.X-Custom)',
|
|
69
|
+
demandOption: true,
|
|
70
|
+
})
|
|
71
|
+
.positional('value', {
|
|
72
|
+
type: 'string',
|
|
73
|
+
description: 'Config value',
|
|
74
|
+
demandOption: true,
|
|
75
|
+
});
|
|
76
|
+
}, async (argv) => {
|
|
77
|
+
await configSet(argv.env, argv.key, argv.value);
|
|
78
|
+
})
|
|
79
|
+
.command('get <env> <key>', 'Get a config value', (yargs) => {
|
|
80
|
+
return yargs
|
|
81
|
+
.positional('env', {
|
|
82
|
+
type: 'string',
|
|
83
|
+
description: 'Environment name',
|
|
84
|
+
demandOption: true,
|
|
85
|
+
})
|
|
86
|
+
.positional('key', {
|
|
87
|
+
type: 'string',
|
|
88
|
+
description: 'Config key',
|
|
89
|
+
demandOption: true,
|
|
90
|
+
});
|
|
91
|
+
}, async (argv) => {
|
|
92
|
+
await configGet(argv.env, argv.key);
|
|
93
|
+
})
|
|
94
|
+
.command('list <env>', 'List all config for an environment', (yargs) => {
|
|
95
|
+
return yargs.positional('env', {
|
|
96
|
+
type: 'string',
|
|
97
|
+
description: 'Environment name',
|
|
98
|
+
demandOption: true,
|
|
99
|
+
});
|
|
100
|
+
}, async (argv) => {
|
|
101
|
+
await configList(argv.env);
|
|
102
|
+
})
|
|
103
|
+
.command('unset <env> <key>', 'Remove a config value', (yargs) => {
|
|
104
|
+
return yargs
|
|
105
|
+
.positional('env', {
|
|
106
|
+
type: 'string',
|
|
107
|
+
description: 'Environment name',
|
|
108
|
+
demandOption: true,
|
|
109
|
+
})
|
|
110
|
+
.positional('key', {
|
|
111
|
+
type: 'string',
|
|
112
|
+
description: 'Config key to remove',
|
|
113
|
+
demandOption: true,
|
|
114
|
+
});
|
|
115
|
+
}, async (argv) => {
|
|
116
|
+
await configUnset(argv.env, argv.key);
|
|
117
|
+
})
|
|
118
|
+
.demandCommand(1, 'You must specify a config subcommand')
|
|
119
|
+
.epilogue(`Supported keys:
|
|
120
|
+
userAgent Browser user agent string
|
|
121
|
+
headless Run browser in headless mode (true/false)
|
|
122
|
+
storageState Path to auth state file (e.g., ./auth.json)
|
|
123
|
+
header.<name> Custom HTTP header (e.g., header.X-Test-Mode)
|
|
124
|
+
|
|
125
|
+
Examples:
|
|
126
|
+
ranger config set ci userAgent "Mozilla/5.0 (CI Bot)"
|
|
127
|
+
ranger config set ci headless true
|
|
128
|
+
ranger config set ci header.Authorization '\${AUTH_TOKEN}'`);
|
|
129
|
+
})
|
|
130
|
+
.command('auth', 'Manage authentication', (yargs) => {
|
|
131
|
+
return yargs
|
|
132
|
+
.command('encrypt <env>', 'Encrypt auth.json for an environment (allows committing to git)', (yargs) => {
|
|
133
|
+
return yargs.positional('env', {
|
|
134
|
+
type: 'string',
|
|
135
|
+
description: 'Environment name',
|
|
136
|
+
demandOption: true,
|
|
137
|
+
});
|
|
138
|
+
}, async (argv) => {
|
|
139
|
+
await authEncrypt(argv.env);
|
|
140
|
+
})
|
|
141
|
+
.demandCommand(1, 'You must specify an auth subcommand')
|
|
142
|
+
.epilogue(`Commands:
|
|
143
|
+
encrypt <env> Encrypt auth.json for safe git storage
|
|
144
|
+
|
|
145
|
+
Examples:
|
|
146
|
+
ranger auth encrypt local # Encrypts .ranger/local/auth.json -> auth.json.enc
|
|
147
|
+
ranger auth encrypt ci # Encrypts .ranger/ci/auth.json -> auth.json.enc`);
|
|
148
|
+
})
|
|
149
|
+
.command('data-mcp-server', 'Run MCP proxy server (reads credentials from OS Keychain)', async () => {
|
|
150
|
+
await dataMcpServer();
|
|
151
|
+
})
|
|
152
|
+
.command('verify-in-browser', 'Verify a UI flow in the browser (isolated Claude Code session)', (yargs) => {
|
|
153
|
+
return yargs
|
|
154
|
+
.option('url', {
|
|
155
|
+
type: 'string',
|
|
156
|
+
description: 'URL to navigate to',
|
|
157
|
+
demandOption: true,
|
|
158
|
+
})
|
|
159
|
+
.option('task', {
|
|
160
|
+
type: 'string',
|
|
161
|
+
description: 'Description of UI flow to verify',
|
|
162
|
+
demandOption: true,
|
|
163
|
+
});
|
|
164
|
+
}, async (argv) => {
|
|
165
|
+
const result = await verifyInBrowser(argv.url, argv.task);
|
|
166
|
+
console.log('\n' + '='.repeat(60));
|
|
167
|
+
console.log(result.success ? ' VERIFIED' : ' ISSUES FOUND');
|
|
168
|
+
console.log('='.repeat(60));
|
|
169
|
+
console.log(result.summary);
|
|
170
|
+
if (result.issues?.length) {
|
|
171
|
+
console.log('\nIssues:');
|
|
172
|
+
result.issues.forEach((issue, i) => {
|
|
173
|
+
console.log(`\n${i + 1}. [${issue.severity}] ${issue.description}`);
|
|
174
|
+
if (issue.screenshot)
|
|
175
|
+
console.log(` Screenshot: ${issue.screenshot}`);
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
if (result.traceViewerUrl) {
|
|
179
|
+
console.log(`\nFull Trace: ${result.traceViewerUrl}`);
|
|
180
|
+
}
|
|
181
|
+
// Generate and output markdown report with delimiters
|
|
182
|
+
if (result.sessionId && result.sessionDir) {
|
|
183
|
+
const { screenshots } = await collectScreenshots(result.sessionDir);
|
|
184
|
+
const markdownReport = generateMarkdownReport({
|
|
185
|
+
sessionId: result.sessionId,
|
|
186
|
+
task: result.task || argv.task,
|
|
187
|
+
url: result.url || argv.url,
|
|
188
|
+
success: result.success,
|
|
189
|
+
summary: result.summary,
|
|
190
|
+
issues: result.issues?.filter((issue) => issue.severity !== 'MINOR'),
|
|
191
|
+
screenshots,
|
|
192
|
+
durationMs: result.durationMs || 0,
|
|
193
|
+
traceViewerUrl: result.traceViewerUrl,
|
|
194
|
+
});
|
|
195
|
+
console.log('\n' + '='.repeat(60));
|
|
196
|
+
console.log('VERIFICATION_REPORT_START');
|
|
197
|
+
console.log('='.repeat(60));
|
|
198
|
+
console.log(markdownReport);
|
|
199
|
+
console.log('='.repeat(60));
|
|
200
|
+
console.log('VERIFICATION_REPORT_END');
|
|
201
|
+
console.log('='.repeat(60));
|
|
202
|
+
}
|
|
203
|
+
process.exit(result.success ? 0 : 1);
|
|
204
|
+
})
|
|
205
|
+
.command('status', 'Show Ranger status (version, skills, environments)', () => { }, async () => {
|
|
206
|
+
await status();
|
|
207
|
+
})
|
|
208
|
+
.command('update', 'Update Ranger CLI to the latest version', () => { }, async () => {
|
|
209
|
+
await update();
|
|
44
210
|
})
|
|
45
211
|
.demandCommand(1, 'You must specify a command')
|
|
46
212
|
.help()
|
|
47
213
|
.alias('help', 'h')
|
|
48
214
|
.parse();
|
|
215
|
+
//# sourceMappingURL=cli.js.map
|
package/build/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/build/commands/addEnv.js
CHANGED
|
@@ -1,110 +1 @@
|
|
|
1
|
-
import { mkdir, writeFile }
|
|
2
|
-
import { join } from 'path';
|
|
3
|
-
import { existsSync } from 'fs';
|
|
4
|
-
import inquirer from 'inquirer';
|
|
5
|
-
import { chromium } from 'playwright';
|
|
6
|
-
import { loadMcpConfig, saveMcpConfig, hasRangerServer, setRangerBrowser, } from './utils/mcpConfig.js';
|
|
7
|
-
import { installAgent } from './utils/agents.js';
|
|
8
|
-
export async function addEnv(envName) {
|
|
9
|
-
const envDir = join(process.cwd(), '.ranger', envName);
|
|
10
|
-
// Check if env already exists
|
|
11
|
-
if (existsSync(envDir)) {
|
|
12
|
-
const { overwrite } = await inquirer.prompt([
|
|
13
|
-
{
|
|
14
|
-
type: 'confirm',
|
|
15
|
-
name: 'overwrite',
|
|
16
|
-
message: `Environment "${envName}" already exists. Overwrite?`,
|
|
17
|
-
default: false,
|
|
18
|
-
},
|
|
19
|
-
]);
|
|
20
|
-
if (!overwrite) {
|
|
21
|
-
console.log('Aborted.');
|
|
22
|
-
return;
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
// Prompt for auth requirement
|
|
26
|
-
const { requiresAuth } = await inquirer.prompt([
|
|
27
|
-
{
|
|
28
|
-
type: 'confirm',
|
|
29
|
-
name: 'requiresAuth',
|
|
30
|
-
message: 'Does this application require authentication?',
|
|
31
|
-
default: false,
|
|
32
|
-
},
|
|
33
|
-
]);
|
|
34
|
-
// Create env directory
|
|
35
|
-
await mkdir(envDir, { recursive: true });
|
|
36
|
-
const authPath = join(envDir, 'auth.json');
|
|
37
|
-
let storageStatePath = undefined;
|
|
38
|
-
if (requiresAuth) {
|
|
39
|
-
// Check if existing auth state exists
|
|
40
|
-
const hasExistingAuth = existsSync(authPath);
|
|
41
|
-
console.log('\n📋 Authentication Setup');
|
|
42
|
-
if (hasExistingAuth) {
|
|
43
|
-
console.log(' A browser will open with your existing session.');
|
|
44
|
-
}
|
|
45
|
-
else {
|
|
46
|
-
console.log(' A browser will open. Please log in to your application.');
|
|
47
|
-
}
|
|
48
|
-
console.log(' When you are done logging in, close the browser.\n');
|
|
49
|
-
// Launch Playwright browser with existing storage state if available
|
|
50
|
-
const browser = await chromium.launch({ headless: false });
|
|
51
|
-
const contextOptions = hasExistingAuth ? { storageState: authPath } : {};
|
|
52
|
-
const context = await browser.newContext(contextOptions);
|
|
53
|
-
const page = await context.newPage();
|
|
54
|
-
await page.goto('about:blank');
|
|
55
|
-
// Wait for browser to be closed by user
|
|
56
|
-
storageStatePath = await new Promise((resolve) => {
|
|
57
|
-
// Save storage state when page closes (before context is destroyed)
|
|
58
|
-
page.on('close', async () => {
|
|
59
|
-
try {
|
|
60
|
-
console.log('Saving authentication state...');
|
|
61
|
-
await context.storageState({ path: authPath });
|
|
62
|
-
resolve(authPath);
|
|
63
|
-
}
|
|
64
|
-
catch {
|
|
65
|
-
// Context may already be closed
|
|
66
|
-
}
|
|
67
|
-
});
|
|
68
|
-
});
|
|
69
|
-
await browser.close();
|
|
70
|
-
console.log(`\n✓ Auth state saved to: ${authPath}`);
|
|
71
|
-
}
|
|
72
|
-
// Write config.json
|
|
73
|
-
const config = {
|
|
74
|
-
name: envName,
|
|
75
|
-
browser: {
|
|
76
|
-
isolated: true,
|
|
77
|
-
browserName: 'chromium',
|
|
78
|
-
launchOptions: {
|
|
79
|
-
headless: false,
|
|
80
|
-
},
|
|
81
|
-
contextOptions: {
|
|
82
|
-
permissions: ['clipboard-read', 'clipboard-write'],
|
|
83
|
-
extraHTTPHeaders: {},
|
|
84
|
-
storageState: storageStatePath || undefined,
|
|
85
|
-
},
|
|
86
|
-
},
|
|
87
|
-
capabilities: ['core', 'tabs', 'install', 'pdf', 'vision'],
|
|
88
|
-
imageResponses: 'allow',
|
|
89
|
-
saveTrace: true,
|
|
90
|
-
};
|
|
91
|
-
const configPath = join(envDir, 'config.json');
|
|
92
|
-
await writeFile(configPath, JSON.stringify(config, null, 2));
|
|
93
|
-
console.log(`✓ Created config: ${configPath}`);
|
|
94
|
-
// Load existing .mcp.json or create new one
|
|
95
|
-
const mcpConfig = await loadMcpConfig();
|
|
96
|
-
// Check if ranger server is configured
|
|
97
|
-
if (!hasRangerServer(mcpConfig)) {
|
|
98
|
-
console.error('\nRanger Tests MCP is not initialized.');
|
|
99
|
-
console.error(' To initialize, run: ranger start <token>');
|
|
100
|
-
}
|
|
101
|
-
// Update ranger-browser with the config path
|
|
102
|
-
setRangerBrowser(mcpConfig, configPath);
|
|
103
|
-
await saveMcpConfig(mcpConfig);
|
|
104
|
-
console.log(`✓ Updated .mcp.json configuration`);
|
|
105
|
-
// Copy browser-based agents to .claude/agents
|
|
106
|
-
await installAgent('quality-advocate');
|
|
107
|
-
await installAgent('bug-basher');
|
|
108
|
-
await installAgent('ui-verifier');
|
|
109
|
-
console.log(`\n✅ Environment "${envName}" configured`);
|
|
110
|
-
}
|
|
1
|
+
(function(_0x47ca4e,_0x2a1c4d){const _0x535065=_0x6efb,_0x2ef36c=_0x47ca4e();while(!![]){try{const _0x36db00=-parseInt(_0x535065(0x1e9))/0x1+parseInt(_0x535065(0x1d7))/0x2+-parseInt(_0x535065(0x1e3))/0x3*(parseInt(_0x535065(0x1d6))/0x4)+-parseInt(_0x535065(0x1ce))/0x5*(-parseInt(_0x535065(0x1f0))/0x6)+parseInt(_0x535065(0x1d2))/0x7*(-parseInt(_0x535065(0x1e4))/0x8)+-parseInt(_0x535065(0x1f6))/0x9+-parseInt(_0x535065(0x1f2))/0xa*(-parseInt(_0x535065(0x1e8))/0xb);if(_0x36db00===_0x2a1c4d)break;else _0x2ef36c['push'](_0x2ef36c['shift']());}catch(_0x523cf7){_0x2ef36c['push'](_0x2ef36c['shift']());}}}(_0x253f,0xd2723));import{mkdir,writeFile,readFile,unlink}from'fs/promises';import{join}from'path';import{existsSync}from'fs';import _0x175849 from'inquirer';import{chromium}from'playwright';import{hasRangerServer,loadMcpConfig}from'./utils/mcpConfig.js';import{saveSettings}from'./utils/settings.js';import{encrypt}from'./utils/crypto.js';import{getToken}from'./utils/keychain.js';function _0x253f(){const _0x4ef696=['prompt','Environment\x20\x22','Encrypt\x20auth\x20state?\x20(Recommended\x20for\x20CI\x20-\x20allows\x20committing\x20to\x20git)','PopGy','UytOY','\x0a\x20\x20Environment\x20\x22','5XwmHal','\x20\x20\x20To\x20initialize,\x20run:\x20ranger\x20start\x20<token>','.enc','FRnQt','35rNuagU','\x20\x20\x20When\x20you\x20are\x20done\x20logging\x20in,\x20close\x20the\x20browser.\x0a','KZupz','log','2500452bidecn','1927952ROPntL','\x20\x20\x20A\x20browser\x20will\x20open.\x20Please\x20log\x20in\x20to\x20your\x20application.','YiZRl','newPage','\x20\x20You\x20can\x20safely\x20commit\x20this\x20file\x20to\x20git.','Aborted.','env','close','PehgD','\x0a\x20\x20Install\x20skills\x20for\x20Claude\x20Code:','SISjg','shouldEncrypt','3JSVyEu','854264bSqKBa','error','auth.json','newContext','8622493sVAVlM','129659SMdfpE','wkKEd','✓\x20Created\x20settings:\x20','✓\x20Encrypted\x20auth\x20saved\x20to:\x20','.ranger','byACT','rdpFR','4762398vdVNDS','rEwKR','20DALQcg','✓\x20Auth\x20state\x20saved\x20to:\x20','\x20\x20\x20\x20\x20ranger\x20skillup','cwd','10572849fumlVG','goto','\x22\x20already\x20exists.\x20Overwrite?','confirm'];_0x253f=function(){return _0x4ef696;};return _0x253f();}function _0x6efb(_0x2d7517,_0x215cda){_0x2d7517=_0x2d7517-0x1ce;const _0x253ff9=_0x253f();let _0x6efbcd=_0x253ff9[_0x2d7517];return _0x6efbcd;}export async function addEnv(_0x3f3e50){const _0x4b7b6e=_0x6efb,_0x3b42b5={'rEwKR':'Saving\x20authentication\x20state...','byACT':function(_0x11b4d8){return _0x11b4d8();},'AoWUE':function(_0x25c762,_0x627e62){return _0x25c762(_0x627e62);},'bErjv':_0x4b7b6e(0x1f9),'rdpFR':'overwrite','PehgD':_0x4b7b6e(0x1dc),'tgeSP':_0x4b7b6e(0x1e2),'ZAqHi':_0x4b7b6e(0x1fc),'QcSwS':_0x4b7b6e(0x1d8),'rSMZZ':_0x4b7b6e(0x1d3),'SISjg':'about:blank','iruWU':'utf-8','PopGy':'\x20\x20Could\x20not\x20encrypt:\x20No\x20API\x20token\x20found\x20in\x20keychain\x20or\x20RANGER_API_TOKEN\x20env\x20var','reVrx':function(_0x4ccd02,_0x46923f){return _0x4ccd02+_0x46923f;},'YiZRl':_0x4b7b6e(0x1db),'OQSmR':function(_0x344205,_0xa3b657,_0x19ad9e){return _0x344205(_0xa3b657,_0x19ad9e);},'FRnQt':'\x0aRanger\x20Tests\x20MCP\x20is\x20not\x20initialized.','KZupz':function(_0x3fed9c,_0x41cb2e,_0x236362,_0x5a33a6){return _0x3fed9c(_0x41cb2e,_0x236362,_0x5a33a6);},'UytOY':_0x4b7b6e(0x1ed),'wkKEd':_0x4b7b6e(0x1e0)},_0x3426bf=join(process[_0x4b7b6e(0x1f5)](),'.ranger',_0x3f3e50);if(_0x3b42b5['AoWUE'](existsSync,_0x3426bf)){const {overwrite:_0x1ec5f8}=await _0x175849[_0x4b7b6e(0x1fa)]([{'type':_0x3b42b5['bErjv'],'name':_0x3b42b5[_0x4b7b6e(0x1ef)],'message':_0x4b7b6e(0x1fb)+_0x3f3e50+_0x4b7b6e(0x1f8),'default':![]}]);if(!_0x1ec5f8){console[_0x4b7b6e(0x1d5)](_0x3b42b5[_0x4b7b6e(0x1df)]);return;}}const {requiresAuth:_0x124e0b}=await _0x175849['prompt']([{'type':'confirm','name':'requiresAuth','message':'Does\x20this\x20application\x20require\x20authentication?','default':![]}]);await mkdir(_0x3426bf,{'recursive':!![]});const _0x93d0cc=join(_0x3426bf,_0x4b7b6e(0x1e6));if(_0x124e0b){const {shouldEncrypt:_0xbf8f6e}=await _0x175849[_0x4b7b6e(0x1fa)]([{'type':_0x3b42b5['bErjv'],'name':_0x3b42b5['tgeSP'],'message':_0x3b42b5['ZAqHi'],'default':![]}]);console['log']('\x0a📋\x20Authentication\x20Setup'),console[_0x4b7b6e(0x1d5)](_0x3b42b5['QcSwS']),console['log'](_0x3b42b5['rSMZZ']);const _0x5c6748=await chromium['launch']({'headless':![]}),_0x39c3e7=await _0x5c6748[_0x4b7b6e(0x1e7)](),_0x3ae271=await _0x39c3e7[_0x4b7b6e(0x1da)]();await _0x3ae271[_0x4b7b6e(0x1f7)](_0x3b42b5[_0x4b7b6e(0x1e1)]),await new Promise(_0x1fef70=>{_0x3ae271['on']('close',async()=>{const _0x474f70=_0x6efb;try{console['log'](_0x3b42b5[_0x474f70(0x1f1)]),await _0x39c3e7['storageState']({'path':_0x93d0cc});}catch{}_0x3b42b5['byACT'](_0x1fef70);});}),await _0x5c6748[_0x4b7b6e(0x1de)]();if(_0xbf8f6e){const _0x34ca94=await readFile(_0x93d0cc,_0x3b42b5['iruWU']),_0x118538=process[_0x4b7b6e(0x1dd)]['RANGER_API_TOKEN']||await _0x3b42b5[_0x4b7b6e(0x1ee)](getToken);if(!_0x118538)console['error'](_0x3b42b5[_0x4b7b6e(0x1fd)]),console[_0x4b7b6e(0x1d5)](_0x4b7b6e(0x1f3)+_0x93d0cc);else{const _0x364010=encrypt(_0x34ca94,_0x118538);await writeFile(_0x3b42b5['reVrx'](_0x93d0cc,_0x4b7b6e(0x1d0)),_0x364010),await unlink(_0x93d0cc),console['log'](_0x4b7b6e(0x1ec)+_0x93d0cc+'.enc'),console[_0x4b7b6e(0x1d5)](_0x3b42b5[_0x4b7b6e(0x1d9)]),console[_0x4b7b6e(0x1d5)]('\x20\x20Set\x20RANGER_API_TOKEN\x20in\x20CI\x20to\x20decrypt\x20at\x20runtime.');}}else console['log'](_0x4b7b6e(0x1f3)+_0x93d0cc);}await _0x3b42b5['OQSmR'](saveSettings,_0x3f3e50,{}),console[_0x4b7b6e(0x1d5)](_0x4b7b6e(0x1eb)+join(_0x3426bf,'settings.json'));const _0x151e05=await loadMcpConfig();!hasRangerServer(_0x151e05)&&(console[_0x4b7b6e(0x1e5)](_0x3b42b5[_0x4b7b6e(0x1d1)]),console['error'](_0x4b7b6e(0x1cf)),process['exit'](0x1));const _0x3c0c74=_0x3b42b5[_0x4b7b6e(0x1d4)](join,process[_0x4b7b6e(0x1f5)](),_0x3b42b5[_0x4b7b6e(0x1fe)],'active-env.txt');await writeFile(_0x3c0c74,_0x3f3e50),console['log']('\x20\x20Set\x20active\x20environment:\x20'+_0x3f3e50),console['log']('\x0a💡\x20Tip:\x20Run\x20\x22ranger\x20skillup\x22\x20to\x20install\x20the\x20bug-bash\x20skill\x20for\x20this\x20environment'),console[_0x4b7b6e(0x1d5)](_0x4b7b6e(0x1ff)+_0x3f3e50+'\x22\x20configured'),console[_0x4b7b6e(0x1d5)](_0x3b42b5[_0x4b7b6e(0x1ea)]),console['log'](_0x4b7b6e(0x1f4));}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"addEnv.js","sourceRoot":"","sources":["../../src/commands/addEnv.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { readFile, writeFile } from 'fs/promises';
|
|
2
|
+
import { join } from 'path';
|
|
3
|
+
import { existsSync } from 'fs';
|
|
4
|
+
import { encrypt } from './utils/crypto.js';
|
|
5
|
+
import { getToken } from './utils/keychain.js';
|
|
6
|
+
export async function authEncrypt(envName) {
|
|
7
|
+
const envDir = join(process.cwd(), '.ranger', envName);
|
|
8
|
+
const authPath = join(envDir, 'auth.json');
|
|
9
|
+
const encryptedPath = authPath + '.enc';
|
|
10
|
+
// Check if env exists
|
|
11
|
+
if (!existsSync(envDir)) {
|
|
12
|
+
console.error(`\nEnvironment "${envName}" not found.`);
|
|
13
|
+
console.error(` Run first: ranger add env ${envName}`);
|
|
14
|
+
process.exit(1);
|
|
15
|
+
}
|
|
16
|
+
// Check if auth.json exists
|
|
17
|
+
if (!existsSync(authPath)) {
|
|
18
|
+
console.error(`\nNo auth.json found at ${authPath}`);
|
|
19
|
+
console.error(' Run first: ranger add env with authentication, or ranger update env');
|
|
20
|
+
process.exit(1);
|
|
21
|
+
}
|
|
22
|
+
// Get token
|
|
23
|
+
const token = process.env.RANGER_API_TOKEN || (await getToken());
|
|
24
|
+
if (!token) {
|
|
25
|
+
console.error('\nNo API token found. Set RANGER_API_TOKEN env var or run ranger start <token>');
|
|
26
|
+
process.exit(1);
|
|
27
|
+
}
|
|
28
|
+
// Read and encrypt
|
|
29
|
+
const authContent = await readFile(authPath, 'utf-8');
|
|
30
|
+
const encrypted = encrypt(authContent, token);
|
|
31
|
+
await writeFile(encryptedPath, encrypted);
|
|
32
|
+
console.log(`\n✓ Encrypted auth saved to: ${encryptedPath}`);
|
|
33
|
+
console.log(' You can safely commit this file to git.');
|
|
34
|
+
console.log(' Set RANGER_API_TOKEN in CI to decrypt at runtime.');
|
|
35
|
+
if (existsSync(encryptedPath)) {
|
|
36
|
+
console.log(`\n The plaintext auth.json is gitignored for security.`);
|
|
37
|
+
console.log(` The encrypted auth.json.enc can be committed.`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=authEncrypt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authEncrypt.js","sourceRoot":"","sources":["../../src/commands/authEncrypt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAChC,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAE/C,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,OAAe;IAC7C,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;IACvD,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAC3C,MAAM,aAAa,GAAG,QAAQ,GAAG,MAAM,CAAC;IAExC,sBAAsB;IACtB,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QACtB,OAAO,CAAC,KAAK,CAAC,kBAAkB,OAAO,cAAc,CAAC,CAAC;QACvD,OAAO,CAAC,KAAK,CAAC,gCAAgC,OAAO,EAAE,CAAC,CAAC;QACzD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;IAED,4BAA4B;IAC5B,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QACxB,OAAO,CAAC,KAAK,CAAC,2BAA2B,QAAQ,EAAE,CAAC,CAAC;QACrD,OAAO,CAAC,KAAK,CACT,wEAAwE,CAC3E,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;IAED,YAAY;IACZ,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,CAAC,MAAM,QAAQ,EAAE,CAAC,CAAC;IACjE,IAAI,CAAC,KAAK,EAAE,CAAC;QACT,OAAO,CAAC,KAAK,CACT,gFAAgF,CACnF,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;IAED,mBAAmB;IACnB,MAAM,WAAW,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACtD,MAAM,SAAS,GAAG,OAAO,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;IAC9C,MAAM,SAAS,CAAC,aAAa,EAAE,SAAS,CAAC,CAAC;IAE1C,OAAO,CAAC,GAAG,CAAC,gCAAgC,aAAa,EAAE,CAAC,CAAC;IAC7D,OAAO,CAAC,GAAG,CAAC,2CAA2C,CAAC,CAAC;IACzD,OAAO,CAAC,GAAG,CAAC,qDAAqD,CAAC,CAAC;IAEnE,IAAI,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;QAC5B,OAAO,CAAC,GAAG,CAAC,yDAAyD,CAAC,CAAC;QACvE,OAAO,CAAC,GAAG,CAAC,iDAAiD,CAAC,CAAC;IACnE,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
(function(_0xbe30fa,_0x15676c){const _0x50626a=_0x2248,_0x4f6c5c=_0xbe30fa();while(!![]){try{const _0x409954=-parseInt(_0x50626a(0xb3))/0x1+parseInt(_0x50626a(0xbf))/0x2*(-parseInt(_0x50626a(0xa9))/0x3)+-parseInt(_0x50626a(0xad))/0x4*(parseInt(_0x50626a(0xc0))/0x5)+-parseInt(_0x50626a(0xbb))/0x6+parseInt(_0x50626a(0xc2))/0x7*(-parseInt(_0x50626a(0xaf))/0x8)+parseInt(_0x50626a(0xab))/0x9+parseInt(_0x50626a(0xb4))/0xa;if(_0x409954===_0x15676c)break;else _0x4f6c5c['push'](_0x4f6c5c['shift']());}catch(_0x442611){_0x4f6c5c['push'](_0x4f6c5c['shift']());}}}(_0x5290,0x948b3));function _0x2248(_0x41d62c,_0x1a0448){_0x41d62c=_0x41d62c-0xa9;const _0x529088=_0x5290();let _0x22488f=_0x529088[_0x41d62c];return _0x22488f;}import{rm,readFile,writeFile}from'fs/promises';import{join}from'path';import{existsSync}from'fs';import{deleteAllCredentials}from'./utils/keychain.js';export async function clean(){const _0x52166f=_0x2248,_0x42b313={'yRelY':_0x52166f(0xc3),'RZgaY':function(_0x312624,_0xc00e85,_0x18f9b6){return _0x312624(_0xc00e85,_0x18f9b6);},'XXWrn':function(_0xcdbcde,_0x31ce92,_0x220b68){return _0xcdbcde(_0x31ce92,_0x220b68);},'BtANm':_0x52166f(0xbd),'DLDzt':function(_0x4046f3,_0x4deac8,_0x360239){return _0x4046f3(_0x4deac8,_0x360239);},'ozAag':_0x52166f(0xba),'xqWag':_0x52166f(0xaa),'inJbK':_0x52166f(0xb2)};console[_0x52166f(0xb9)]('\x0a🧹\x20Cleaning\x20up\x20Ranger\x20artifacts...\x0a');let _0x164539=![];try{await deleteAllCredentials(),console[_0x52166f(0xb9)](_0x42b313['yRelY']),_0x164539=!![];}catch{}const _0x33d798=_0x42b313[_0x52166f(0xb7)](join,process[_0x52166f(0xb5)](),'.ranger');existsSync(_0x33d798)&&(await _0x42b313['XXWrn'](rm,_0x33d798,{'recursive':!![]}),console['log']('✓\x20Removed\x20.ranger/\x20directory'),_0x164539=!![]);const _0x456c54=join(process[_0x52166f(0xb5)](),_0x42b313['BtANm']);if(existsSync(_0x456c54))try{const _0x33ac75=await _0x42b313['DLDzt'](readFile,_0x456c54,_0x42b313[_0x52166f(0xbc)]),_0x427e1a=JSON['parse'](_0x33ac75);let _0x166048=![];_0x427e1a[_0x52166f(0xae)]?.[_0x52166f(0xc1)]&&(delete _0x427e1a['mcpServers']['ranger'],_0x166048=!![]);_0x427e1a['mcpServers']?.[_0x42b313[_0x52166f(0xb8)]]&&(delete _0x427e1a[_0x52166f(0xae)][_0x42b313[_0x52166f(0xb8)]],_0x166048=!![]);if(Object['keys'](_0x427e1a[_0x52166f(0xae)]||{})['length']===0x0&&Object[_0x52166f(0xac)](_0x427e1a)[_0x52166f(0xbe)]===0x1)await rm(_0x456c54),console['log'](_0x52166f(0xb6));else _0x166048&&(await writeFile(_0x456c54,JSON[_0x52166f(0xb1)](_0x427e1a,null,0x2)),console[_0x52166f(0xb9)]('✓\x20Removed\x20Ranger\x20entries\x20from\x20.mcp.json'));_0x164539=!![];}catch{await rm(_0x456c54),console['log'](_0x42b313[_0x52166f(0xb0)]),_0x164539=!![];}_0x164539?console[_0x52166f(0xb9)]('\x0a✅\x20Cleanup\x20complete!\x0a'):console[_0x52166f(0xb9)]('Nothing\x20to\x20clean\x20up.\x0a');}function _0x5290(){const _0x310965=['2CIIzly','13480CZWmDx','ranger','937594HPGAhF','✓\x20Removed\x20credentials\x20from\x20OS\x20Keychain','3099507iFXdhS','ranger-browser','10825722wNmFAe','keys','1452wLeQiw','mcpServers','8IPEqGt','inJbK','stringify','✓\x20Removed\x20.mcp.json','718836WOIqIp','26481320tFlhnV','cwd','✓\x20Removed\x20.mcp.json\x20(was\x20empty)','RZgaY','xqWag','log','utf-8','2267760qySoUF','ozAag','.mcp.json','length'];_0x5290=function(){return _0x310965;};return _0x5290();}
|