@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.
Files changed (48) hide show
  1. package/README.md +281 -0
  2. package/build/cli.js +168 -1
  3. package/build/cli.js.map +1 -0
  4. package/build/commands/addEnv.js +1 -110
  5. package/build/commands/addEnv.js.map +1 -0
  6. package/build/commands/authEncrypt.js +40 -0
  7. package/build/commands/authEncrypt.js.map +1 -0
  8. package/build/commands/clean.js +1 -0
  9. package/build/commands/clean.js.map +1 -0
  10. package/build/commands/config.js +100 -0
  11. package/build/commands/config.js.map +1 -0
  12. package/build/commands/dataMcpServer.js +1 -0
  13. package/build/commands/dataMcpServer.js.map +1 -0
  14. package/build/commands/index.js +6 -0
  15. package/build/commands/index.js.map +1 -0
  16. package/build/commands/skillup.js +112 -0
  17. package/build/commands/skillup.js.map +1 -0
  18. package/build/commands/start.js +1 -72
  19. package/build/commands/start.js.map +1 -0
  20. package/build/commands/status.js +221 -0
  21. package/build/commands/status.js.map +1 -0
  22. package/build/commands/update.js +127 -0
  23. package/build/commands/update.js.map +1 -0
  24. package/build/commands/updateEnv.js +1 -64
  25. package/build/commands/updateEnv.js.map +1 -0
  26. package/build/commands/useEnv.js +1 -28
  27. package/build/commands/useEnv.js.map +1 -0
  28. package/build/commands/utils/browserSessionsApi.js +1 -0
  29. package/build/commands/utils/browserSessionsApi.js.map +1 -0
  30. package/build/commands/utils/crypto.js +42 -0
  31. package/build/commands/utils/crypto.js.map +1 -0
  32. package/build/commands/utils/keychain.js +1 -0
  33. package/build/commands/utils/keychain.js.map +1 -0
  34. package/build/commands/utils/localAgentInstallationsApi.js +1 -0
  35. package/build/commands/utils/localAgentInstallationsApi.js.map +1 -0
  36. package/build/commands/utils/mcpConfig.js +1 -47
  37. package/build/commands/utils/mcpConfig.js.map +1 -0
  38. package/build/commands/utils/reportGenerator.js +130 -0
  39. package/build/commands/utils/reportGenerator.js.map +1 -0
  40. package/build/commands/utils/settings.js +246 -0
  41. package/build/commands/utils/settings.js.map +1 -0
  42. package/build/commands/utils/skills.js +1 -0
  43. package/build/commands/utils/skills.js.map +1 -0
  44. package/build/commands/verifyInBrowser.js +1 -0
  45. package/build/commands/verifyInBrowser.js.map +1 -0
  46. package/build/skills/bug-bash.md +313 -0
  47. package/build/skills/e2e-test-recommender.md +173 -0
  48. 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
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -1,110 +1 @@
1
- import { mkdir, writeFile } from 'fs/promises';
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":"AAAA,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACjE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAChC,OAAO,QAAQ,MAAM,UAAU,CAAC;AAChC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACtE,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAE/C,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,OAAe;IACxC,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;IAEvD,8BAA8B;IAC9B,IAAI,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QACrB,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC;YACxC;gBACI,IAAI,EAAE,SAAS;gBACf,IAAI,EAAE,WAAW;gBACjB,OAAO,EAAE,gBAAgB,OAAO,8BAA8B;gBAC9D,OAAO,EAAE,KAAK;aACjB;SACJ,CAAC,CAAC;QACH,IAAI,CAAC,SAAS,EAAE,CAAC;YACb,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YACxB,OAAO;QACX,CAAC;IACL,CAAC;IAED,8BAA8B;IAC9B,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC;QAC3C;YACI,IAAI,EAAE,SAAS;YACf,IAAI,EAAE,cAAc;YACpB,OAAO,EAAE,+CAA+C;YACxD,OAAO,EAAE,KAAK;SACjB;KACJ,CAAC,CAAC;IAEH,uBAAuB;IACvB,MAAM,KAAK,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAEzC,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAE3C,IAAI,YAAY,EAAE,CAAC;QACf,wDAAwD;QACxD,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC;YAC5C;gBACI,IAAI,EAAE,SAAS;gBACf,IAAI,EAAE,eAAe;gBACrB,OAAO,EACH,qEAAqE;gBACzE,OAAO,EAAE,KAAK;aACjB;SACJ,CAAC,CAAC;QAEH,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;QACzC,OAAO,CAAC,GAAG,CACP,4DAA4D,CAC/D,CAAC;QACF,OAAO,CAAC,GAAG,CAAC,uDAAuD,CAAC,CAAC;QAErE,4BAA4B;QAC5B,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;QAC3D,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,UAAU,EAAE,CAAC;QAC3C,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC;QACrC,MAAM,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAE/B,wCAAwC;QACxC,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;YAChC,oEAAoE;YACpE,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,KAAK,IAAI,EAAE;gBACxB,IAAI,CAAC;oBACD,OAAO,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC;oBAC9C,MAAM,OAAO,CAAC,YAAY,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;gBACnD,CAAC;gBAAC,MAAM,CAAC;oBACL,gCAAgC;gBACpC,CAAC;gBACD,OAAO,EAAE,CAAC;YACd,CAAC,CAAC,CAAC;QACP,CAAC,CAAC,CAAC;QAEH,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;QAEtB,IAAI,aAAa,EAAE,CAAC;YAChB,MAAM,WAAW,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YACtD,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,CAAC,MAAM,QAAQ,EAAE,CAAC,CAAC;YACjE,IAAI,CAAC,KAAK,EAAE,CAAC;gBACT,OAAO,CAAC,KAAK,CACT,iFAAiF,CACpF,CAAC;gBACF,OAAO,CAAC,GAAG,CAAC,0BAA0B,QAAQ,EAAE,CAAC,CAAC;YACtD,CAAC;iBAAM,CAAC;gBACJ,MAAM,SAAS,GAAG,OAAO,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;gBAC9C,MAAM,SAAS,CAAC,QAAQ,GAAG,MAAM,EAAE,SAAS,CAAC,CAAC;gBAC9C,6BAA6B;gBAC7B,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC;gBACvB,OAAO,CAAC,GAAG,CAAC,8BAA8B,QAAQ,MAAM,CAAC,CAAC;gBAC1D,OAAO,CAAC,GAAG,CAAC,2CAA2C,CAAC,CAAC;gBACzD,OAAO,CAAC,GAAG,CACP,qDAAqD,CACxD,CAAC;YACN,CAAC;QACL,CAAC;aAAM,CAAC;YACJ,OAAO,CAAC,GAAG,CAAC,0BAA0B,QAAQ,EAAE,CAAC,CAAC;QACtD,CAAC;IACL,CAAC;IAED,8EAA8E;IAC9E,MAAM,YAAY,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IAChC,OAAO,CAAC,GAAG,CAAC,uBAAuB,IAAI,CAAC,MAAM,EAAE,eAAe,CAAC,EAAE,CAAC,CAAC;IAEpE,uCAAuC;IACvC,MAAM,SAAS,GAAG,MAAM,aAAa,EAAE,CAAC;IACxC,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,EAAE,CAAC;QAC9B,OAAO,CAAC,KAAK,CAAC,wCAAwC,CAAC,CAAC;QACxD,OAAO,CAAC,KAAK,CAAC,6CAA6C,CAAC,CAAC;QAC7D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;IAED,iDAAiD;IACjD,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,gBAAgB,CAAC,CAAC;IACvE,MAAM,SAAS,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;IACxC,OAAO,CAAC,GAAG,CAAC,6BAA6B,OAAO,EAAE,CAAC,CAAC;IAEpD,mCAAmC;IACnC,OAAO,CAAC,GAAG,CACP,mFAAmF,CACtF,CAAC;IAEF,OAAO,CAAC,GAAG,CAAC,oBAAoB,OAAO,cAAc,CAAC,CAAC;IACvD,OAAO,CAAC,GAAG,CAAC,qCAAqC,CAAC,CAAC;IACnD,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;AACvC,CAAC"}
@@ -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();}