@ranger-testing/ranger-cli 1.0.5 → 1.0.6

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":";AACA,OAAO,KAAK,MAAM,aAAa,CAAC;AAChC,OAAO,EACH,MAAM,EACN,KAAK,EACL,KAAK,EACL,MAAM,EACN,SAAS,EACT,MAAM,EACN,OAAO,GACV,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAC9C,OAAO,EACH,SAAS,EACT,SAAS,EACT,UAAU,EACV,WAAW,GACd,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,EACH,sBAAsB,EACtB,kBAAkB,GAErB,MAAM,qCAAqC,CAAC;AAE7C,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,MAAM,CAAC,MAAM,EAAE,CAAC;AAEhB,kBAAkB;AAClB,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;KACvB,OAAO,CAAC,OAAO,CAAC;KAChB,OAAO,CACJ,oBAAoB,EACpB,+BAA+B,EAC/B,CAAC,KAAK,EAAE,EAAE;IACN,OAAO,KAAK,CAAC,UAAU,CAAC,UAAU,EAAE;QAChC,IAAI,EAAE,QAAQ;QACd,WAAW,EACP,sDAAsD;QAC1D,YAAY,EAAE,IAAI;KACrB,CAAC,CAAC;AACP,CAAC,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;IACX,MAAM,MAAM,CAAC,IAAI,CAAC,UAAU,CAAW,CAAC,CAAC;AAC7C,CAAC,CACJ;KACA,OAAO,CACJ,gBAAgB,EAChB,wCAAwC,EACxC,CAAC,KAAK,EAAE,EAAE;IACN,OAAO,KAAK,CAAC,UAAU,CAAC,UAAU,EAAE;QAChC,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,yBAAyB;QACtC,YAAY,EAAE,IAAI;KACrB,CAAC,CAAC;AACP,CAAC,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;IACX,MAAM,MAAM,CAAC,IAAI,CAAC,UAAU,CAAW,CAAC,CAAC;AAC7C,CAAC,CACJ;KACA,OAAO,CACJ,uBAAuB,EACvB,mDAAmD,EACnD,CAAC,KAAK,EAAE,EAAE;IACN,OAAO,KAAK,CAAC,UAAU,CAAC,UAAU,EAAE;QAChC,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,mCAAmC;QAChD,YAAY,EAAE,IAAI;KACrB,CAAC,CAAC;AACP,CAAC,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;IACX,MAAM,SAAS,CAAC,IAAI,CAAC,UAAU,CAAW,CAAC,CAAC;AAChD,CAAC,CACJ;KACA,OAAO,CACJ,eAAe,EACf,mCAAmC,EACnC,CAAC,KAAK,EAAE,EAAE;IACN,OAAO,KAAK,CAAC,UAAU,CAAC,OAAO,EAAE;QAC7B,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,kCAAkC;QAC/C,YAAY,EAAE,IAAI;KACrB,CAAC,CAAC;AACP,CAAC,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;IACX,MAAM,KAAK,CAAC,IAAI,CAAC,KAAe,CAAC,CAAC;AACtC,CAAC,CACJ;KACA,OAAO,CACJ,SAAS,EACT,uCAAuC,EACvC,GAAG,EAAE,GAAE,CAAC,EACR,KAAK,IAAI,EAAE;IACP,MAAM,OAAO,EAAE,CAAC;AACpB,CAAC,CACJ;KACA,OAAO,CACJ,OAAO,EACP,8CAA8C,EAC9C,KAAK,IAAI,EAAE;IACP,MAAM,KAAK,EAAE,CAAC;AAClB,CAAC,CACJ;KACA,OAAO,CAAC,QAAQ,EAAE,kCAAkC,EAAE,CAAC,KAAK,EAAE,EAAE;IAC7D,OAAO,KAAK;SACP,OAAO,CACJ,yBAAyB,EACzB,oBAAoB,EACpB,CAAC,KAAK,EAAE,EAAE;QACN,OAAO,KAAK;aACP,UAAU,CAAC,KAAK,EAAE;YACf,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,kBAAkB;YAC/B,YAAY,EAAE,IAAI;SACrB,CAAC;aACD,UAAU,CAAC,KAAK,EAAE;YACf,IAAI,EAAE,QAAQ;YACd,WAAW,EACP,+CAA+C;YACnD,YAAY,EAAE,IAAI;SACrB,CAAC;aACD,UAAU,CAAC,OAAO,EAAE;YACjB,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,cAAc;YAC3B,YAAY,EAAE,IAAI;SACrB,CAAC,CAAC;IACX,CAAC,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;QACX,MAAM,SAAS,CACX,IAAI,CAAC,GAAa,EAClB,IAAI,CAAC,GAAa,EAClB,IAAI,CAAC,KAAe,CACvB,CAAC;IACN,CAAC,CACJ;SACA,OAAO,CACJ,iBAAiB,EACjB,oBAAoB,EACpB,CAAC,KAAK,EAAE,EAAE;QACN,OAAO,KAAK;aACP,UAAU,CAAC,KAAK,EAAE;YACf,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,kBAAkB;YAC/B,YAAY,EAAE,IAAI;SACrB,CAAC;aACD,UAAU,CAAC,KAAK,EAAE;YACf,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,YAAY;YACzB,YAAY,EAAE,IAAI;SACrB,CAAC,CAAC;IACX,CAAC,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;QACX,MAAM,SAAS,CAAC,IAAI,CAAC,GAAa,EAAE,IAAI,CAAC,GAAa,CAAC,CAAC;IAC5D,CAAC,CACJ;SACA,OAAO,CACJ,YAAY,EACZ,oCAAoC,EACpC,CAAC,KAAK,EAAE,EAAE;QACN,OAAO,KAAK,CAAC,UAAU,CAAC,KAAK,EAAE;YAC3B,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,kBAAkB;YAC/B,YAAY,EAAE,IAAI;SACrB,CAAC,CAAC;IACP,CAAC,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;QACX,MAAM,UAAU,CAAC,IAAI,CAAC,GAAa,CAAC,CAAC;IACzC,CAAC,CACJ;SACA,OAAO,CACJ,mBAAmB,EACnB,uBAAuB,EACvB,CAAC,KAAK,EAAE,EAAE;QACN,OAAO,KAAK;aACP,UAAU,CAAC,KAAK,EAAE;YACf,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,kBAAkB;YAC/B,YAAY,EAAE,IAAI;SACrB,CAAC;aACD,UAAU,CAAC,KAAK,EAAE;YACf,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,sBAAsB;YACnC,YAAY,EAAE,IAAI;SACrB,CAAC,CAAC;IACX,CAAC,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;QACX,MAAM,WAAW,CAAC,IAAI,CAAC,GAAa,EAAE,IAAI,CAAC,GAAa,CAAC,CAAC;IAC9D,CAAC,CACJ;SACA,aAAa,CAAC,CAAC,EAAE,sCAAsC,CAAC;SACxD,QAAQ,CACL;;;;;;;;;6DAS6C,CAChD,CAAC;AACV,CAAC,CAAC;KACD,OAAO,CAAC,MAAM,EAAE,uBAAuB,EAAE,CAAC,KAAK,EAAE,EAAE;IAChD,OAAO,KAAK;SACP,OAAO,CACJ,eAAe,EACf,iEAAiE,EACjE,CAAC,KAAK,EAAE,EAAE;QACN,OAAO,KAAK,CAAC,UAAU,CAAC,KAAK,EAAE;YAC3B,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,kBAAkB;YAC/B,YAAY,EAAE,IAAI;SACrB,CAAC,CAAC;IACP,CAAC,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;QACX,MAAM,WAAW,CAAC,IAAI,CAAC,GAAa,CAAC,CAAC;IAC1C,CAAC,CACJ;SACA,aAAa,CAAC,CAAC,EAAE,qCAAqC,CAAC;SACvD,QAAQ,CACL;;;;;iFAKiE,CACpE,CAAC;AACV,CAAC,CAAC;KACD,OAAO,CACJ,iBAAiB,EACjB,2DAA2D,EAC3D,KAAK,IAAI,EAAE;IACP,MAAM,aAAa,EAAE,CAAC;AAC1B,CAAC,CACJ;KACA,OAAO,CACJ,mBAAmB,EACnB,gEAAgE,EAChE,CAAC,KAAK,EAAE,EAAE;IACN,OAAO,KAAK;SACP,MAAM,CAAC,KAAK,EAAE;QACX,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,oBAAoB;QACjC,YAAY,EAAE,IAAI;KACrB,CAAC;SACD,MAAM,CAAC,MAAM,EAAE;QACZ,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,kCAAkC;QAC/C,YAAY,EAAE,IAAI;KACrB,CAAC,CAAC;AACX,CAAC,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;IACX,MAAM,MAAM,GAAG,MAAM,eAAe,CAChC,IAAI,CAAC,GAAa,EAClB,IAAI,CAAC,IAAc,CACtB,CAAC;IAEF,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;IACnC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC;IAC5D,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;IAC5B,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAE5B,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC;QACxB,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QACzB,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE;YAC/B,OAAO,CAAC,GAAG,CACP,KAAK,CAAC,GAAG,CAAC,MAAM,KAAK,CAAC,QAAQ,KAAK,KAAK,CAAC,WAAW,EAAE,CACzD,CAAC;YACF,IAAI,KAAK,CAAC,UAAU;gBAChB,OAAO,CAAC,GAAG,CAAC,kBAAkB,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC;QAC1D,CAAC,CAAC,CAAC;IACP,CAAC;IAED,IAAI,MAAM,CAAC,cAAc,EAAE,CAAC;QACxB,OAAO,CAAC,GAAG,CAAC,iBAAiB,MAAM,CAAC,cAAc,EAAE,CAAC,CAAC;IAC1D,CAAC;IAED,sDAAsD;IACtD,IAAI,MAAM,CAAC,SAAS,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;QACxC,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,kBAAkB,CAC5C,MAAM,CAAC,UAAU,CACpB,CAAC;QACF,MAAM,cAAc,GAAG,sBAAsB,CAAC;YAC1C,SAAS,EAAE,MAAM,CAAC,SAAS;YAC3B,IAAI,EAAE,MAAM,CAAC,IAAI,IAAK,IAAI,CAAC,IAAe;YAC1C,GAAG,EAAE,MAAM,CAAC,GAAG,IAAK,IAAI,CAAC,GAAc;YACvC,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CACzB,CAAC,KAAK,EAA8B,EAAE,CAClC,KAAK,CAAC,QAAQ,KAAK,OAAO,CACjC;YACD,WAAW;YACX,UAAU,EAAE,MAAM,CAAC,UAAU,IAAI,CAAC;YAClC,cAAc,EAAE,MAAM,CAAC,cAAc;SACxC,CAAC,CAAC;QAEH,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;QACnC,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;QACzC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;QAC5B,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;QAC5B,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;QAC5B,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;QACvC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;IAChC,CAAC;IAED,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACzC,CAAC,CACJ;KACA,OAAO,CACJ,QAAQ,EACR,oDAAoD,EACpD,GAAG,EAAE,GAAE,CAAC,EACR,KAAK,IAAI,EAAE;IACP,MAAM,MAAM,EAAE,CAAC;AACnB,CAAC,CACJ;KACA,OAAO,CACJ,QAAQ,EACR,yCAAyC,EACzC,GAAG,EAAE,GAAE,CAAC,EACR,KAAK,IAAI,EAAE;IACP,MAAM,MAAM,EAAE,CAAC;AACnB,CAAC,CACJ;KACA,aAAa,CAAC,CAAC,EAAE,4BAA4B,CAAC;KAC9C,IAAI,EAAE;KACN,KAAK,CAAC,MAAM,EAAE,GAAG,CAAC;KAClB,KAAK,EAAE,CAAC"}
@@ -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(_0x21b1b6,_0x362c30){const _0x58ed63=_0x1afa,_0x52c67f=_0x21b1b6();while(!![]){try{const _0x14c001=-parseInt(_0x58ed63(0x1d7))/0x1+parseInt(_0x58ed63(0x1d6))/0x2+-parseInt(_0x58ed63(0x1e8))/0x3*(parseInt(_0x58ed63(0x1ea))/0x4)+-parseInt(_0x58ed63(0x1e4))/0x5+-parseInt(_0x58ed63(0x1dd))/0x6+parseInt(_0x58ed63(0x1da))/0x7*(parseInt(_0x58ed63(0x1cd))/0x8)+parseInt(_0x58ed63(0x1d5))/0x9;if(_0x14c001===_0x362c30)break;else _0x52c67f['push'](_0x52c67f['shift']());}catch(_0x11c83d){_0x52c67f['push'](_0x52c67f['shift']());}}}(_0x6d5c,0xc70e7));import{mkdir,writeFile,readFile,unlink}from'fs/promises';function _0x1afa(_0x1ad845,_0x4261fe){_0x1ad845=_0x1ad845-0x1c8;const _0x6d5c88=_0x6d5c();let _0x1afa35=_0x6d5c88[_0x1ad845];return _0x1afa35;}import{join}from'path';import{existsSync}from'fs';import _0x277623 from'inquirer';import{chromium}from'playwright';import{hasRangerServer,loadMcpConfig}from'./utils/mcpConfig.js';function _0x6d5c(){const _0x3c89a5=['close','.ranger','ysOwP','prompt','\x0a\x20\x20Install\x20skills\x20for\x20Claude\x20Code:','11101554rAMAXa','633514biZPrd','53548aSmHWn','✓\x20Auth\x20state\x20saved\x20to:\x20','newPage','4893SKsyhT','GprNl','izIZD','4695630rJTxKh','wOcdA','TEKiV','\x0a📋\x20Authentication\x20Setup','cwd','svGKe','PxCji','6314245uICUCN','log','shouldEncrypt','✓\x20Encrypted\x20auth\x20saved\x20to:\x20','3MqKDfn','\x20\x20\x20A\x20browser\x20will\x20open.\x20Please\x20log\x20in\x20to\x20your\x20application.','798356AjnQZd','MPzik','auth.json','Mqnht','launch','error','\x20\x20\x20When\x20you\x20are\x20done\x20logging\x20in,\x20close\x20the\x20browser.\x0a','\x20\x20\x20To\x20initialize,\x20run:\x20ranger\x20start\x20<token>','about:blank','\x0aRanger\x20Tests\x20MCP\x20is\x20not\x20initialized.','17896dDjDqD','.enc','active-env.txt'];_0x6d5c=function(){return _0x3c89a5;};return _0x6d5c();}import{saveSettings}from'./utils/settings.js';import{encrypt}from'./utils/crypto.js';import{getToken}from'./utils/keychain.js';export async function addEnv(_0x42931e){const _0xde74f7=_0x1afa,_0x4e1ac0={'flKSZ':'Saving\x20authentication\x20state...','xOwAc':function(_0x35d675){return _0x35d675();},'svGKe':'confirm','GprNl':'Aborted.','PxCji':'Does\x20this\x20application\x20require\x20authentication?','ZFSSM':_0xde74f7(0x1ec),'ysOwP':_0xde74f7(0x1e6),'cSZsJ':_0xde74f7(0x1c9),'Mqnht':_0xde74f7(0x1cb),'MPzik':function(_0x19d30e,_0x3c6b29,_0x1bcdb6){return _0x19d30e(_0x3c6b29,_0x1bcdb6);},'BdtCn':'utf-8','wOcdA':'\x20\x20Could\x20not\x20encrypt:\x20No\x20API\x20token\x20found\x20in\x20keychain\x20or\x20RANGER_API_TOKEN\x20env\x20var','TEKiV':function(_0x540576,_0x25b32f){return _0x540576(_0x25b32f);},'izIZD':_0xde74f7(0x1ca),'Yvonj':_0xde74f7(0x1d4)},_0x386c31=join(process[_0xde74f7(0x1e1)](),'.ranger',_0x42931e);if(existsSync(_0x386c31)){const {overwrite:_0x96e8cd}=await _0x277623[_0xde74f7(0x1d3)]([{'type':_0x4e1ac0[_0xde74f7(0x1e2)],'name':'overwrite','message':'Environment\x20\x22'+_0x42931e+'\x22\x20already\x20exists.\x20Overwrite?','default':![]}]);if(!_0x96e8cd){console[_0xde74f7(0x1e5)](_0x4e1ac0[_0xde74f7(0x1db)]);return;}}const {requiresAuth:_0x157b71}=await _0x277623['prompt']([{'type':_0x4e1ac0[_0xde74f7(0x1e2)],'name':'requiresAuth','message':_0x4e1ac0[_0xde74f7(0x1e3)],'default':![]}]);await mkdir(_0x386c31,{'recursive':!![]});const _0x577b77=join(_0x386c31,_0x4e1ac0['ZFSSM']);if(_0x157b71){const {shouldEncrypt:_0x422cd9}=await _0x277623['prompt']([{'type':'confirm','name':_0x4e1ac0[_0xde74f7(0x1d2)],'message':'Encrypt\x20auth\x20state?\x20(Recommended\x20for\x20CI\x20-\x20allows\x20committing\x20to\x20git)','default':![]}]);console['log'](_0xde74f7(0x1e0)),console['log'](_0xde74f7(0x1e9)),console['log'](_0x4e1ac0['cSZsJ']);const _0x268c2c=await chromium[_0xde74f7(0x1ee)]({'headless':![]}),_0x4e7516=await _0x268c2c['newContext'](),_0x5429bc=await _0x4e7516[_0xde74f7(0x1d9)]();await _0x5429bc['goto'](_0x4e1ac0[_0xde74f7(0x1ed)]),await new Promise(_0x3864f4=>{const _0xe5224f={'PFKik':_0x4e1ac0['flKSZ'],'YmxLu':function(_0x2dfecc){return _0x4e1ac0['xOwAc'](_0x2dfecc);}};_0x5429bc['on']('close',async()=>{try{console['log'](_0xe5224f['PFKik']),await _0x4e7516['storageState']({'path':_0x577b77});}catch{}_0xe5224f['YmxLu'](_0x3864f4);});}),await _0x268c2c[_0xde74f7(0x1d0)]();if(_0x422cd9){const _0x55b796=await _0x4e1ac0['MPzik'](readFile,_0x577b77,_0x4e1ac0['BdtCn']),_0x15e33c=process['env']['RANGER_API_TOKEN']||await getToken();if(!_0x15e33c)console['error'](_0x4e1ac0[_0xde74f7(0x1de)]),console['log'](_0xde74f7(0x1d8)+_0x577b77);else{const _0x2feb34=_0x4e1ac0[_0xde74f7(0x1eb)](encrypt,_0x55b796,_0x15e33c);await _0x4e1ac0[_0xde74f7(0x1eb)](writeFile,_0x577b77+'.enc',_0x2feb34),await unlink(_0x577b77),console['log'](_0xde74f7(0x1e7)+_0x577b77+_0xde74f7(0x1ce)),console['log']('\x20\x20You\x20can\x20safely\x20commit\x20this\x20file\x20to\x20git.'),console['log']('\x20\x20Set\x20RANGER_API_TOKEN\x20in\x20CI\x20to\x20decrypt\x20at\x20runtime.');}}else console['log'](_0xde74f7(0x1d8)+_0x577b77);}await saveSettings(_0x42931e,{}),console['log']('✓\x20Created\x20settings:\x20'+join(_0x386c31,'settings.json'));const _0x243c1d=await loadMcpConfig();!_0x4e1ac0[_0xde74f7(0x1df)](hasRangerServer,_0x243c1d)&&(console['error'](_0xde74f7(0x1cc)),console[_0xde74f7(0x1c8)](_0x4e1ac0[_0xde74f7(0x1dc)]),process['exit'](0x1));const _0x2fb7d2=join(process['cwd'](),_0xde74f7(0x1d1),_0xde74f7(0x1cf));await writeFile(_0x2fb7d2,_0x42931e),console['log']('\x20\x20Set\x20active\x20environment:\x20'+_0x42931e),console['log']('\x0a💡\x20Tip:\x20Run\x20\x22ranger\x20skillup\x22\x20to\x20install\x20the\x20bug-bash\x20skill\x20for\x20this\x20environment'),console['log']('\x0a\x20\x20Environment\x20\x22'+_0x42931e+'\x22\x20configured'),console['log'](_0x4e1ac0['Yvonj']),console['log']('\x20\x20\x20\x20\x20ranger\x20skillup');}
@@ -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(_0x5a5e87,_0x1e031a){const _0x74d76e=_0x5cdb,_0x3a68f3=_0x5a5e87();while(!![]){try{const _0x80e729=-parseInt(_0x74d76e(0xd3))/0x1+-parseInt(_0x74d76e(0xce))/0x2+-parseInt(_0x74d76e(0xd4))/0x3*(-parseInt(_0x74d76e(0xc6))/0x4)+-parseInt(_0x74d76e(0xe0))/0x5*(-parseInt(_0x74d76e(0xcd))/0x6)+-parseInt(_0x74d76e(0xd8))/0x7+-parseInt(_0x74d76e(0xc8))/0x8+parseInt(_0x74d76e(0xe2))/0x9;if(_0x80e729===_0x1e031a)break;else _0x3a68f3['push'](_0x3a68f3['shift']());}catch(_0x3c0868){_0x3a68f3['push'](_0x3a68f3['shift']());}}}(_0x2cc6,0x4b336));import{rm,readFile,writeFile}from'fs/promises';import{join}from'path';import{existsSync}from'fs';function _0x5cdb(_0x5ca568,_0x22296f){_0x5ca568=_0x5ca568-0xc6;const _0x2cc66a=_0x2cc6();let _0x5cdb4b=_0x2cc66a[_0x5ca568];return _0x5cdb4b;}function _0x2cc6(){const _0x4a1900=['403070qewTfY','152769huNVqs','✓\x20Removed\x20.ranger/\x20directory','DNzsX','.ranger','3792803JQRZev','length','NtQzS','uCcta','cwd','log','\x0a🧹\x20Cleaning\x20up\x20Ranger\x20artifacts...\x0a','okwBR','5LDnuDf','✓\x20Removed\x20Ranger\x20entries\x20from\x20.mcp.json','15024204taQiSa','16zFkbKL','eecCX','2679864PvFHxB','keys','parse','✓\x20Removed\x20.mcp.json\x20(was\x20empty)','Nothing\x20to\x20clean\x20up.\x0a','860826Bdasep','857230nGDAPR','ranger-browser','✓\x20Removed\x20credentials\x20from\x20OS\x20Keychain','\x0a✅\x20Cleanup\x20complete!\x0a','mcpServers'];_0x2cc6=function(){return _0x4a1900;};return _0x2cc6();}import{deleteAllCredentials}from'./utils/keychain.js';export async function clean(){const _0x25d9cb=_0x5cdb,_0x974c03={'eecCX':function(_0x551e0f){return _0x551e0f();},'RwjqV':_0x25d9cb(0xd0),'rtsej':_0x25d9cb(0xd7),'VbJyX':_0x25d9cb(0xd5),'uCcta':function(_0x25ca86,_0x29ea73,_0x6ca64d){return _0x25ca86(_0x29ea73,_0x6ca64d);},'okwBR':function(_0x23ce42,_0x5da058,_0x79231d){return _0x23ce42(_0x5da058,_0x79231d);},'ywfXg':'utf-8','NtQzS':_0x25d9cb(0xcf),'pFXFx':function(_0x1ab4dc,_0x40f294){return _0x1ab4dc===_0x40f294;},'DNzsX':_0x25d9cb(0xe1),'pmHIr':function(_0x4618ec,_0x2fa6ee){return _0x4618ec(_0x2fa6ee);},'LhbCP':'✓\x20Removed\x20.mcp.json','IqYUR':_0x25d9cb(0xcc)};console[_0x25d9cb(0xdd)](_0x25d9cb(0xde));let _0x488469=![];try{await _0x974c03[_0x25d9cb(0xc7)](deleteAllCredentials),console['log'](_0x974c03['RwjqV']),_0x488469=!![];}catch{}const _0x23d52f=join(process[_0x25d9cb(0xdc)](),_0x974c03['rtsej']);existsSync(_0x23d52f)&&(await rm(_0x23d52f,{'recursive':!![]}),console[_0x25d9cb(0xdd)](_0x974c03['VbJyX']),_0x488469=!![]);const _0x33788e=_0x974c03[_0x25d9cb(0xdb)](join,process['cwd'](),'.mcp.json');if(existsSync(_0x33788e))try{const _0x1ef35b=await _0x974c03['okwBR'](readFile,_0x33788e,_0x974c03['ywfXg']),_0x1cfb6e=JSON[_0x25d9cb(0xca)](_0x1ef35b);let _0x376cf0=![];_0x1cfb6e[_0x25d9cb(0xd2)]?.['ranger']&&(delete _0x1cfb6e['mcpServers']['ranger'],_0x376cf0=!![]);_0x1cfb6e['mcpServers']?.['ranger-browser']&&(delete _0x1cfb6e[_0x25d9cb(0xd2)][_0x974c03[_0x25d9cb(0xda)]],_0x376cf0=!![]);if(_0x974c03['pFXFx'](Object[_0x25d9cb(0xc9)](_0x1cfb6e[_0x25d9cb(0xd2)]||{})[_0x25d9cb(0xd9)],0x0)&&Object['keys'](_0x1cfb6e)['length']===0x1)await rm(_0x33788e),console['log'](_0x25d9cb(0xcb));else _0x376cf0&&(await _0x974c03[_0x25d9cb(0xdf)](writeFile,_0x33788e,JSON['stringify'](_0x1cfb6e,null,0x2)),console[_0x25d9cb(0xdd)](_0x974c03[_0x25d9cb(0xd6)]));_0x488469=!![];}catch{await _0x974c03['pmHIr'](rm,_0x33788e),console[_0x25d9cb(0xdd)](_0x974c03['LhbCP']),_0x488469=!![];}_0x488469?console[_0x25d9cb(0xdd)](_0x25d9cb(0xd1)):console[_0x25d9cb(0xdd)](_0x974c03['IqYUR']);}