retestkit 1.14.0 → 1.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/README.md +46 -352
  2. package/dist/auth/browser.d.ts +14 -0
  3. package/dist/auth/browser.d.ts.map +1 -0
  4. package/dist/auth/browser.js +67 -0
  5. package/dist/auth/browser.js.map +1 -0
  6. package/dist/auth/device-flow.d.ts +80 -0
  7. package/dist/auth/device-flow.d.ts.map +1 -0
  8. package/dist/auth/device-flow.js +243 -0
  9. package/dist/auth/device-flow.js.map +1 -0
  10. package/dist/auth/ensure-auth.d.ts +74 -0
  11. package/dist/auth/ensure-auth.d.ts.map +1 -0
  12. package/dist/auth/ensure-auth.js +118 -0
  13. package/dist/auth/ensure-auth.js.map +1 -0
  14. package/dist/auth/github-stub.d.ts +10 -4
  15. package/dist/auth/github-stub.d.ts.map +1 -1
  16. package/dist/auth/github-stub.js +10 -4
  17. package/dist/auth/github-stub.js.map +1 -1
  18. package/dist/auth/index.d.ts +19 -0
  19. package/dist/auth/index.d.ts.map +1 -0
  20. package/dist/auth/index.js +19 -0
  21. package/dist/auth/index.js.map +1 -0
  22. package/dist/auth/token-manager.d.ts +71 -0
  23. package/dist/auth/token-manager.d.ts.map +1 -0
  24. package/dist/auth/token-manager.js +201 -0
  25. package/dist/auth/token-manager.js.map +1 -0
  26. package/dist/auth/token-storage.d.ts +80 -0
  27. package/dist/auth/token-storage.d.ts.map +1 -0
  28. package/dist/auth/token-storage.js +244 -0
  29. package/dist/auth/token-storage.js.map +1 -0
  30. package/dist/auth/types.d.ts +189 -0
  31. package/dist/auth/types.d.ts.map +1 -0
  32. package/dist/auth/types.js +61 -0
  33. package/dist/auth/types.js.map +1 -0
  34. package/dist/errors/not-configured.js +2 -2
  35. package/dist/errors/not-configured.js.map +1 -1
  36. package/dist/prompts/index.d.ts.map +1 -1
  37. package/dist/prompts/index.js +5 -49
  38. package/dist/prompts/index.js.map +1 -1
  39. package/dist/prompts/templates/mcp/init.md +1 -1
  40. package/dist/prompts/templates/mcp/retest-cover.md +2 -2
  41. package/dist/prompts/templates/mcp/retest-describe.md +6 -6
  42. package/dist/prompts/templates/sampling/feature-discovery.md +1 -1
  43. package/dist/prompts/templates/sampling/flow-discovery.md +1 -1
  44. package/dist/resources/index.js +1 -1
  45. package/dist/schemas/file-config.d.ts +10 -0
  46. package/dist/schemas/file-config.d.ts.map +1 -1
  47. package/dist/schemas/file-config.js +23 -0
  48. package/dist/schemas/file-config.js.map +1 -1
  49. package/dist/server.d.ts.map +1 -1
  50. package/dist/server.js +3 -1
  51. package/dist/server.js.map +1 -1
  52. package/dist/tools/auth.d.ts +21 -0
  53. package/dist/tools/auth.d.ts.map +1 -0
  54. package/dist/tools/auth.js +322 -0
  55. package/dist/tools/auth.js.map +1 -0
  56. package/dist/tools/init.js +3 -3
  57. package/dist/tools/retest/cover.js +3 -3
  58. package/dist/tools/retest/crawl.js +2 -2
  59. package/dist/tools/retest/crawl.js.map +1 -1
  60. package/dist/tools/retest/describe.d.ts +2 -2
  61. package/dist/tools/retest/describe.js +22 -22
  62. package/dist/tools/retest/describe.js.map +1 -1
  63. package/dist/workspace/index.js +3 -3
  64. package/dist/workspace/index.js.map +1 -1
  65. package/dist/workspace/types.d.ts +2 -2
  66. package/package.json +2 -1
  67. package/dist/prompts/templates/mcp/retest-discover-flows.md +0 -11
  68. package/dist/prompts/templates/mcp/retest-discover.md +0 -11
package/README.md CHANGED
@@ -1,91 +1,27 @@
1
- # retestkit
1
+ # retest:kit
2
2
 
3
- > **Proprietary software. No public license is granted.**
4
- > Use, copying, modification, or distribution is permitted **only** under a separate written agreement with the Licensor.
5
- > See: **[LICENSE](./LICENSE)**
3
+ **AI-powered web testing that actually understands your app.**
6
4
 
7
- ## Overview
5
+ `retest:kit` is an MCP server that brings intelligent, autonomous testing to your web applications. Point it at your app, tell it what to explore, and watch it identify features, generate tests, and catch regressions—all through natural conversation with your AI assistant.
8
6
 
9
- This repository contains an **MCP server** for **AI-powered web application testing**. It provides tools for automated crawling, application analysis, test generation, and test execution using the Model Context Protocol (MCP).
10
7
 
11
- The server integrates with:
12
- - **MCP-compatible clients** (Claude Desktop, custom clients)
13
- - **Playwright MCP** for browser automation
14
- - **MCP Sampling** for AI-powered decision making
15
- - **MCP Elicitation** for interactive user input
8
+ ## What It Does
16
9
 
17
- ## Authorized Use Only
10
+ - **Explores your app** — AI navigates your application like a real user would
11
+ - **Identifies features** — Automatically finds and documents what your app can do
12
+ - **Generates tests** — Creates meaningful test cases based on real user flows
13
+ - **Catches regressions** — Runs tests and reports what broke (with screenshots)
18
14
 
19
- You may use this Software **only** if:
20
- - you have a **separate written agreement** with the Licensor, and
21
- - you test only systems you are **authorized to test**.
22
15
 
23
- Any other use is prohibited. See **[LICENSE](./LICENSE)**.
16
+ ## Quick Install
24
17
 
25
- ## Features
26
-
27
- - **Goal-directed crawling** - AI navigates web applications to achieve specified goals
28
- - **Application analysis** - Automatic discovery of entities, user flows, and assertions
29
- - **Test generation** - AI-generated test cases based on application analysis
30
- - **Test execution** - Automated test running with evidence capture
31
- - **Progress tracking** - Real-time progress notifications with budget status
32
- - **Checkpoint & resume** - Crawl checkpointing for resumable operations
33
- - **Security features** - Domain allowlists, injection protection, exfiltration blocking
34
- - **Resource management** - `retest://` URI scheme for artifact access
35
-
36
- ## Installation
37
-
38
- ```bash
39
- npm install
40
- npm run build
41
- ```
42
-
43
- ## Testing
44
-
45
- The project includes multiple test tiers:
46
-
47
- ```bash
48
- # Unit tests (fast, uses mocks)
49
- npm test
50
-
51
- # Integration tests (MCP protocol, mock Playwright)
52
- npm run test:integration
53
-
54
- # E2E tests (real browser, real external sites)
55
- npm run test:e2e
56
- ```
57
-
58
- ### E2E Testing
59
-
60
- E2E tests exercise complete workflows with real Playwright MCP against external test sites (demo.playwright.dev/todomvc). They validate:
61
-
62
- - **Init + Cover workflow**: Shortcut setup, workspace creation, crawl → describe → generate
63
- - **Retest workflow**: Plan → run → summarize cycle
64
- - **Error handling**: Budget limits, domain security, input validation
65
-
66
- **Requirements for E2E tests:**
67
- - Node.js 22+
68
- - Network access to demo.playwright.dev
69
- - Playwright browsers (installed automatically via @playwright/mcp)
70
-
71
- **Run E2E tests:**
72
- ```bash
73
- npm run test:e2e
74
- ```
75
-
76
- E2E tests have extended timeouts (5 minutes per test) and run serially to avoid resource contention. They create isolated temporary workspaces that are cleaned up after each test.
77
-
78
- ## Quick Start
79
-
80
- RetestKit is designed for **zero-configuration installation**. Just add the server to your MCP client and run `/init` to configure.
81
-
82
- ### Adding to MCP Clients
18
+ Add retest:kit to your MCP client. No configuration needed—just add the server and run `:init` command.
83
19
 
84
20
  **VS Code / GitHub Copilot** (`.vscode/mcp.json`):
85
21
  ```json
86
22
  {
87
23
  "servers": {
88
- "retestkit": {
24
+ "retest": {
89
25
  "type": "stdio",
90
26
  "command": "npx",
91
27
  "args": ["retestkit"]
@@ -98,7 +34,7 @@ RetestKit is designed for **zero-configuration installation**. Just add the serv
98
34
  ```json
99
35
  {
100
36
  "mcpServers": {
101
- "retestkit": {
37
+ "retest": {
102
38
  "command": "npx",
103
39
  "args": ["retestkit"]
104
40
  }
@@ -106,11 +42,11 @@ RetestKit is designed for **zero-configuration installation**. Just add the serv
106
42
  }
107
43
  ```
108
44
 
109
- **Cursor / Cline** (settings):
45
+ **Cursor / Cline** (MCP settings):
110
46
  ```json
111
47
  {
112
48
  "mcpServers": {
113
- "retestkit": {
49
+ "retest": {
114
50
  "command": "npx",
115
51
  "args": ["retestkit"]
116
52
  }
@@ -118,306 +54,64 @@ RetestKit is designed for **zero-configuration installation**. Just add the serv
118
54
  }
119
55
  ```
120
56
 
121
- > **Note:** No `env` or `inputs` sections needed. All configuration happens via the `/init` prompt after the server starts.
122
-
123
- ### First-Time Setup
124
-
125
- After adding the server to your MCP client:
126
-
127
- 1. **Run `/init`** - The init prompt guides you through configuration
128
- 2. **Provide target URL** - The URL of the web application to test
129
- 3. **Configuration saved** - Settings are stored in `.mcp/retestkit.json`
130
-
131
- The `/init` prompt handles:
132
- - Creating the config file (`.mcp/retestkit.json`)
133
- - Setting up shortcuts (e.g., `/retest` command)
134
- - Guiding you to start testing with `/cover`
135
57
 
136
- ## Configuration
58
+ ## Your First Test
137
59
 
138
- RetestKit uses `.mcp/retestkit.json` for all configuration. This file is created automatically when you run `/init`.
60
+ Once installed, getting started is three commands:
139
61
 
140
- **Example `.mcp/retestkit.json`:**
141
- ```json
142
- {
143
- "version": 1,
144
- "targetUrl": "https://myapp.com",
145
- "specsPath": "./specs",
146
- "allowedDomains": ["myapp.com", "*.myapp.com"],
147
- "transport": "stdio",
148
- "port": 3000,
149
- "workspaceDir": "./retest",
150
- "limits": {
151
- "maxSteps": 50,
152
- "maxMinutes": 30,
153
- "maxPages": 20
154
- },
155
- "logging": {
156
- "level": "info"
157
- },
158
- "playwright": {
159
- "command": "npx",
160
- "args": ["@playwright/mcp@latest"]
161
- },
162
- "checkpointInterval": 5,
163
- "screenshotFormat": "png",
164
- "screenshotQuality": 80
165
- }
62
+ ### 1. Initialize
166
63
  ```
167
-
168
- **Config file discovery order:**
169
- 1. CLI flag: `--config /path/to/config.json`
170
- 2. Environment: `RETESTKIT_CONFIG=/path/to/config.json`
171
- 3. Workspace: `./.mcp/retestkit.json`
172
- 4. User-level: `~/.config/retestkit/config.json`
173
- 5. Built-in defaults
174
-
175
- > **Note:** Environment variables are **not supported** for configuration values. Only `RETESTKIT_CONFIG` is recognized (to specify the config file path for CI/CD pipelines).
176
-
177
- ## Available Tools
178
-
179
- ### `retest_init`
180
-
181
- Initialize a new web testing analysis workspace.
182
-
183
- **Input:**
184
- ```json
185
- {
186
- "url": "https://example.com",
187
- "focus": "User authentication flow",
188
- "limits": {
189
- "maxSteps": 50,
190
- "maxMinutes": 30,
191
- "maxPages": 20
192
- },
193
- "allowedDomains": ["example.com", "*.example.com"]
194
- }
64
+ /retest:init
195
65
  ```
66
+ Tell retest:kit your target URL and it sets everything up.
196
67
 
197
- **Output:** `analysisId` (e.g., `2025-01-15_10-30`), `workspacePath`
198
-
199
- ### `retest_crawl`
200
-
201
- Perform goal-directed crawling of a web application.
202
-
203
- **Input:**
204
- ```json
205
- {
206
- "analysisId": "2025-01-15_10-30",
207
- "goal": "Navigate to login page and explore authentication options",
208
- "strategy": "goal_directed",
209
- "limits": { "maxSteps": 30 },
210
- "artifacts": { "captureScreenshots": true, "captureSnapshots": true, "captureDom": true },
211
- "resume": false
212
- }
68
+ ### 2. Explore & Generate
213
69
  ```
214
-
215
- **Features:**
216
- - AI-powered navigation decisions via MCP Sampling
217
- - Loop detection (DOM signatures, URL cycles, action repeats)
218
- - Budget enforcement (steps, time, pages)
219
- - Checkpointing every N steps (configurable)
220
- - Elicitation for user decisions (cookie consent, modals, auth)
221
- - Domain validation and security checks
222
-
223
- **Output:** `crawlId` (e.g., `2025-01-15_10-30-45`), `crawlPath`, page artifacts
224
-
225
- ### `retest_describe`
226
-
227
- Discover application features, modules, and user flows from crawl data.
228
-
229
- **Input:**
230
- ```json
231
- {
232
- "analysisId": "2025-01-15_10-30",
233
- "crawlId": "2025-01-15_10-30-45",
234
- "discoverFlows": true
235
- }
70
+ /retest:cover
236
71
  ```
72
+ The AI crawls your app, identifies features, and generates test cases.
237
73
 
238
- **Output:** `featuresUri`, `featuresFilePath` containing:
239
- - Application purpose and type
240
- - Discovered features with descriptions
241
- - Entities and entry points per feature
242
- - User flows within each feature
243
- - Security and accessibility observations
244
-
245
- ### `retest_generate`
246
-
247
- Generate test cases from application analysis.
248
-
249
- **Input:**
250
- ```json
251
- {
252
- "analysisId": "2025-01-15_10-30",
253
- "testStrategy": "comprehensive",
254
- "maxTests": 20,
255
- "focusFlows": ["checkout-flow", "login-flow"]
256
- }
74
+ ### 3. Run Tests
257
75
  ```
258
-
259
- **Output:** `testsUri`, `testsFilePath` containing test cases with:
260
- - ID, name, purpose, category
261
- - Preconditions and steps
262
- - Expected outcomes
263
-
264
- ### `retest_run_test`
265
-
266
- Execute a generated test case.
267
-
268
- **Input:**
269
- ```json
270
- {
271
- "analysisId": "2025-01-15_10-30",
272
- "testCaseId": "TC-001",
273
- "runOptions": {
274
- "captureEvidence": true,
275
- "stopOnFailure": true,
276
- "retryFailedSteps": false
277
- }
278
- }
76
+ /retest
279
77
  ```
78
+ Execute your tests and get a summary of what passed (and what didn't).
280
79
 
281
- **Output:** `runId`, `reportUri`, step results with:
282
- - Pass/fail status per step
283
- - Evidence (screenshots, DOM state)
284
- - Failure reasoning and discrepancies
285
-
286
- ## Resources
80
+ That's it. You now have AI-powered tests for your web app.
287
81
 
288
- The server exposes resources via the `retest://` URI scheme:
289
82
 
290
- - `retest://{analysisId}/index.md` - Workspace metadata and summary
291
- - `retest://{analysisId}/crawls/{crawlId}/index.md` - Crawl index with action history
292
- - `retest://{analysisId}/crawls/{crawlId}/checkpoint.md` - Crawl checkpoint state
293
- - `retest://{analysisId}/crawls/{crawlId}/pages/{pageId}/snapshot.md` - Page accessibility snapshot
294
- - `retest://{analysisId}/crawls/{crawlId}/pages/{pageId}/screenshot.png` - Page screenshot
295
- - `retest://{analysisId}/crawls/{crawlId}/pages/{pageId}/dom.html` - Page DOM
296
- - `retest://{analysisId}/features/features.md` - Discovered features
297
- - `retest://{analysisId}/features/{featureSlug}/flows.md` - User flows for a feature
298
- - `retest://{analysisId}/tests/tests.md` - Generated test cases
299
- - `retest://{analysisId}/runs/{runId}/report.md` - Test run report
300
- - `retest://{analysisId}/runs/{runId}/steps/{n}/snapshot.md` - Step evidence snapshot
83
+ ## Learn More
301
84
 
302
- ### Artifact Format
85
+ | Topic | Link |
86
+ |-------|------|
87
+ | Full configuration options | [docs/configuration.md](docs/configuration.md) |
88
+ | All MCP tools | [docs/tools-reference.md](docs/tools-reference.md) |
89
+ | Authentication | [docs/authentication.md](docs/authentication.md) |
90
+ | Security | [docs/security.md](docs/security.md) |
91
+ | Contributing | [docs/development.md](docs/development.md) |
303
92
 
304
- All artifacts (except screenshots and DOM) use **Markdown with YAML frontmatter**:
93
+ Full documentation: [docs/](docs/)
305
94
 
306
- ```markdown
307
- ---
308
- analysisId: "2025-01-15_10-30"
309
- url: "https://example.com"
310
- status: "active"
311
- # ... structured data in YAML ...
312
95
  ---
313
96
 
314
- # Human-Readable Content
315
-
316
- This section contains formatted markdown for easy browsing.
317
- ```
318
-
319
- **Benefits:**
320
- - Human-readable without special tools
321
- - Structured data accessible via frontmatter parsing
322
- - Works with any markdown viewer or IDE
323
- - Git-friendly diffs
324
-
325
- **Parsing frontmatter programmatically:**
326
- ```typescript
327
- import matter from "gray-matter";
328
-
329
- const { data, content } = matter(markdownContent);
330
- // data = parsed YAML frontmatter object
331
- // content = markdown body
332
- ```
333
-
334
- ### Workspace Folder Naming
335
-
336
- Workspaces use date-time based folder names for easy identification:
337
- - **Workspace ID**: `YYYY-MM-DD_HH-mm` (e.g., `2025-01-15_10-30`)
338
- - **Crawl ID**: `YYYY-MM-DD_HH-mm-ss` (e.g., `2025-01-15_10-30-45`)
339
-
340
- Legacy UUID-format IDs are still supported for backwards compatibility.
341
-
342
- ## Prompts
343
-
344
- The server provides prompts for guided workflows:
345
-
346
- - **cover** - Expand test coverage by crawling, describing, and generating tests
347
- - **crawl** - Start or continue crawling
348
- - **describe** - Discover features and flows (unified discovery)
349
- - **discover** - Discover features, or flows for a specific feature
350
- - **generate** - Generate test cases
351
- - **init** - Initialize a new analysis or set up shortcuts
352
- - **kit** - Complete testing workflow (plan, run, summarize, update)
353
- - **plan** - Create a test plan based on changes
354
- - **run** - Execute a test case
355
- - **summarize** - Generate test result summary with suggestions
356
-
357
- ## Example Workflow
358
-
359
- ```
360
- 1. Start analysis:
361
- retest_init({ url: "https://myapp.com", focus: "checkout flow" })
362
- → Returns analysisId
363
-
364
- 2. Crawl the application:
365
- retest_crawl({ analysisId, goal: "Explore product catalog and checkout" })
366
- → Returns crawlId, artifacts
367
-
368
- 3. Describe features and flows:
369
- retest_describe({ analysisId, crawlId, discoverFlows: true })
370
- → Returns discovered features and flows
371
-
372
- 4. Generate test cases:
373
- retest_generate({ analysisId })
374
- → Returns test cases
375
-
376
- 5. Run tests:
377
- retest_run_test({ analysisId, testCaseId })
378
- → Returns test results with evidence
379
- ```
380
-
381
- ## MCP Client Requirements
382
-
383
- For full functionality, the MCP client should support:
97
+ ## License
384
98
 
385
- | Capability | Required | Used For |
386
- |------------|----------|----------|
387
- | `sampling` | Recommended | AI-powered crawling, analysis, test generation |
388
- | `elicitation` | Optional | User decisions during crawl (cookie consent, auth) |
389
- | `logging` | Optional | Structured log delivery via MCP notifications |
390
- | `resources.listChanged` | Optional | Real-time resource update notifications |
391
- | `resources.subscribe` | Optional | Resource subscription support |
99
+ **Proprietary software.** Use requires a separate written agreement.
392
100
 
393
- **Fallback modes:** When sampling is unavailable, tools return prompt resources for manual execution. When elicitation is unavailable, questions are returned in tool output.
101
+ You may use this software only if:
102
+ - You have a written agreement with the Licensor
103
+ - You test only systems you are authorized to test
394
104
 
395
- ## Security
105
+ See [LICENSE](./LICENSE) for details.
396
106
 
397
- The server implements multiple security layers:
107
+ ---
398
108
 
399
- - **Domain allowlists** - Restrict navigation to authorized domains
400
- - **Prompt injection protection** - Untrusted content demarcation in AI prompts
401
- - **Data exfiltration blocking** - Prevents sensitive data leakage
402
- - **Credential elicitation blocking** - Refuses to ask for passwords
403
- - **Audit logging** - All AI inputs/outputs logged for review
404
- - **Sensitive data redaction** - URL params, cookies, passwords redacted in logs
109
+ ## Get Access
405
110
 
406
- ## Getting Access
111
+ To request commercial access or licensing:
407
112
 
408
- To request commercial access or a license agreement, contact:
409
113
  **Ing. Jan Beránek** — honza@beranku.cz
410
114
 
411
- ## Security & Responsible Use
412
-
413
- If you discover a security issue, please report it privately to the contact above.
414
- Do not open public issues containing sensitive details.
415
-
416
- ## Repository Status
417
-
418
- Unless explicitly stated in a separate agreement, this repository is provided **without warranty** and **without support obligations**.
419
-
420
- ## License
115
+ ---
421
116
 
422
- Copyright (c) 2025 Ing. Jan Beránek.
423
- All rights reserved. See **[LICENSE](./LICENSE)**.
117
+ <sub>Built with care for teams who believe testing should be intelligent, not tedious.</sub>
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Best-effort browser opening utility.
3
+ *
4
+ * Attempts to open a URL in the user's default browser.
5
+ * Fails gracefully if no browser is available.
6
+ */
7
+ /**
8
+ * Attempt to open a URL in the user's default browser.
9
+ *
10
+ * @param url URL to open
11
+ * @returns true if browser was opened, false otherwise
12
+ */
13
+ export declare function openBrowser(url: string): Promise<boolean>;
14
+ //# sourceMappingURL=browser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../../src/auth/browser.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAkBH;;;;;GAKG;AACH,wBAAsB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CA8B/D"}
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Best-effort browser opening utility.
3
+ *
4
+ * Attempts to open a URL in the user's default browser.
5
+ * Fails gracefully if no browser is available.
6
+ */
7
+ import { exec } from "node:child_process";
8
+ import { promisify } from "node:util";
9
+ const execAsync = promisify(exec);
10
+ /**
11
+ * Platform-specific browser open commands.
12
+ */
13
+ const OPEN_COMMANDS = {
14
+ darwin: ["open"],
15
+ win32: ["cmd", "/c", "start", '""'],
16
+ linux: ["xdg-open"],
17
+ freebsd: ["xdg-open"],
18
+ openbsd: ["xdg-open"],
19
+ };
20
+ /**
21
+ * Attempt to open a URL in the user's default browser.
22
+ *
23
+ * @param url URL to open
24
+ * @returns true if browser was opened, false otherwise
25
+ */
26
+ export async function openBrowser(url) {
27
+ const platform = process.platform;
28
+ const cmdParts = OPEN_COMMANDS[platform];
29
+ if (!cmdParts) {
30
+ // Unsupported platform
31
+ return false;
32
+ }
33
+ try {
34
+ // Validate URL to prevent command injection
35
+ const parsedUrl = new URL(url);
36
+ if (!["http:", "https:"].includes(parsedUrl.protocol)) {
37
+ return false;
38
+ }
39
+ // Escape URL for shell (different escaping per platform)
40
+ const escapedUrl = escapeUrlForPlatform(url, platform);
41
+ const command = [...cmdParts, escapedUrl].join(" ");
42
+ await execAsync(command, {
43
+ timeout: 5000, // 5 second timeout
44
+ windowsHide: true, // Don't show command window on Windows
45
+ });
46
+ return true;
47
+ }
48
+ catch {
49
+ // Browser open failed - this is non-fatal
50
+ return false;
51
+ }
52
+ }
53
+ /**
54
+ * Escape URL for shell command based on platform.
55
+ */
56
+ function escapeUrlForPlatform(url, platform) {
57
+ if (platform === "win32") {
58
+ // Windows: wrap in quotes, escape special characters
59
+ // The URL is already reasonably safe since we validated it
60
+ return `"${url.replace(/"/g, "")}"`;
61
+ }
62
+ else {
63
+ // Unix-like: wrap in single quotes, escape single quotes
64
+ return `'${url.replace(/'/g, "'\\''")}'`;
65
+ }
66
+ }
67
+ //# sourceMappingURL=browser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser.js","sourceRoot":"","sources":["../../src/auth/browser.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,MAAM,SAAS,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;AAElC;;GAEG;AACH,MAAM,aAAa,GAA6B;IAC9C,MAAM,EAAE,CAAC,MAAM,CAAC;IAChB,KAAK,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC;IACnC,KAAK,EAAE,CAAC,UAAU,CAAC;IACnB,OAAO,EAAE,CAAC,UAAU,CAAC;IACrB,OAAO,EAAE,CAAC,UAAU,CAAC;CACtB,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,GAAW;IAC3C,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;IAClC,MAAM,QAAQ,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAC;IAEzC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,uBAAuB;QACvB,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,CAAC;QACH,4CAA4C;QAC5C,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;QAC/B,IAAI,CAAC,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC;YACtD,OAAO,KAAK,CAAC;QACf,CAAC;QAED,yDAAyD;QACzD,MAAM,UAAU,GAAG,oBAAoB,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;QACvD,MAAM,OAAO,GAAG,CAAC,GAAG,QAAQ,EAAE,UAAU,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAEpD,MAAM,SAAS,CAAC,OAAO,EAAE;YACvB,OAAO,EAAE,IAAI,EAAE,mBAAmB;YAClC,WAAW,EAAE,IAAI,EAAE,uCAAuC;SAC3D,CAAC,CAAC;QAEH,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,0CAA0C;QAC1C,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAS,oBAAoB,CAAC,GAAW,EAAE,QAAgB;IACzD,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;QACzB,qDAAqD;QACrD,2DAA2D;QAC3D,OAAO,IAAI,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,CAAC;IACtC,CAAC;SAAM,CAAC;QACN,yDAAyD;QACzD,OAAO,IAAI,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC;IAC3C,CAAC;AACH,CAAC"}
@@ -0,0 +1,80 @@
1
+ /**
2
+ * OAuth 2.0 Device Authorization Grant flow manager.
3
+ *
4
+ * Implements RFC 8628 for STDIO-compatible authentication.
5
+ */
6
+ import type { AuthConfig, PendingDeviceFlowSession } from "./types.js";
7
+ import { TokenManager } from "./token-manager.js";
8
+ /**
9
+ * Result of a device flow start operation.
10
+ */
11
+ export interface DeviceFlowStartResult {
12
+ /** User code for display */
13
+ userCode: string;
14
+ /** Verification URL for manual entry */
15
+ verificationUri: string;
16
+ /** Complete verification URL (with embedded code) */
17
+ verificationUriComplete?: string;
18
+ /** When the code expires */
19
+ expiresAt: string;
20
+ /** Whether browser was opened */
21
+ browserOpened: boolean;
22
+ }
23
+ /**
24
+ * Result of polling for token completion.
25
+ */
26
+ export interface DeviceFlowPollResult {
27
+ /** Whether polling completed successfully */
28
+ completed: boolean;
29
+ /** Whether flow is still pending */
30
+ pending: boolean;
31
+ /** Error if flow failed */
32
+ error?: {
33
+ code: string;
34
+ message: string;
35
+ };
36
+ }
37
+ /**
38
+ * Device Flow Manager for handling OAuth device code flow.
39
+ */
40
+ export declare class DeviceFlowManager {
41
+ private config;
42
+ private tokenManager;
43
+ private pendingSession;
44
+ constructor(tokenManager: TokenManager, config?: Partial<AuthConfig>);
45
+ /**
46
+ * Start a new device authorization flow.
47
+ *
48
+ * @param openBrowserWindow Whether to attempt opening the browser
49
+ * @returns Start result with verification URLs and codes
50
+ */
51
+ startFlow(openBrowserWindow?: boolean): Promise<DeviceFlowStartResult>;
52
+ /**
53
+ * Poll for token completion.
54
+ *
55
+ * @param maxWaitSeconds Maximum time to wait
56
+ * @returns Poll result
57
+ */
58
+ pollToken(maxWaitSeconds?: number): Promise<DeviceFlowPollResult>;
59
+ /**
60
+ * Get the current pending session state.
61
+ */
62
+ getPending(): PendingDeviceFlowSession | null;
63
+ /**
64
+ * Clear the pending session.
65
+ */
66
+ clearPending(): void;
67
+ /**
68
+ * Check if there's an active pending session.
69
+ */
70
+ hasPending(): boolean;
71
+ /**
72
+ * Sleep helper for polling.
73
+ */
74
+ private sleep;
75
+ }
76
+ /**
77
+ * Create a device flow manager instance.
78
+ */
79
+ export declare function createDeviceFlowManager(tokenManager: TokenManager, config?: Partial<AuthConfig>): DeviceFlowManager;
80
+ //# sourceMappingURL=device-flow.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"device-flow.d.ts","sourceRoot":"","sources":["../../src/auth/device-flow.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EACV,UAAU,EAGV,wBAAwB,EAGzB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AASlD;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,4BAA4B;IAC5B,QAAQ,EAAE,MAAM,CAAC;IAEjB,wCAAwC;IACxC,eAAe,EAAE,MAAM,CAAC;IAExB,qDAAqD;IACrD,uBAAuB,CAAC,EAAE,MAAM,CAAC;IAEjC,4BAA4B;IAC5B,SAAS,EAAE,MAAM,CAAC;IAElB,iCAAiC;IACjC,aAAa,EAAE,OAAO,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,6CAA6C;IAC7C,SAAS,EAAE,OAAO,CAAC;IAEnB,oCAAoC;IACpC,OAAO,EAAE,OAAO,CAAC;IAEjB,2BAA2B;IAC3B,KAAK,CAAC,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;CACH;AAED;;GAEG;AACH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,MAAM,CAAa;IAC3B,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,cAAc,CAAyC;gBAEnD,YAAY,EAAE,YAAY,EAAE,MAAM,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC;IAKpE;;;;;OAKG;IACG,SAAS,CAAC,iBAAiB,UAAO,GAAG,OAAO,CAAC,qBAAqB,CAAC;IAuEzE;;;;;OAKG;IACG,SAAS,CAAC,cAAc,SAAK,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAyInE;;OAEG;IACH,UAAU,IAAI,wBAAwB,GAAG,IAAI;IAc7C;;OAEG;IACH,YAAY,IAAI,IAAI;IAIpB;;OAEG;IACH,UAAU,IAAI,OAAO;IAIrB;;OAEG;IACH,OAAO,CAAC,KAAK;CAGd;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,YAAY,EAAE,YAAY,EAC1B,MAAM,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,GAC3B,iBAAiB,CAEnB"}