@ai2qa/local-agent 0.1.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 (83) hide show
  1. package/README.md +254 -0
  2. package/bin/ai2qa-agent +12 -0
  3. package/dist/browser/connection.d.ts +80 -0
  4. package/dist/browser/connection.d.ts.map +1 -0
  5. package/dist/browser/connection.js +165 -0
  6. package/dist/browser/connection.js.map +1 -0
  7. package/dist/config.d.ts +58 -0
  8. package/dist/config.d.ts.map +1 -0
  9. package/dist/config.js +231 -0
  10. package/dist/config.js.map +1 -0
  11. package/dist/index.d.ts +10 -0
  12. package/dist/index.d.ts.map +1 -0
  13. package/dist/index.js +189 -0
  14. package/dist/index.js.map +1 -0
  15. package/dist/server.d.ts +56 -0
  16. package/dist/server.d.ts.map +1 -0
  17. package/dist/server.js +387 -0
  18. package/dist/server.js.map +1 -0
  19. package/dist/tools/click.d.ts +12 -0
  20. package/dist/tools/click.d.ts.map +1 -0
  21. package/dist/tools/click.js +61 -0
  22. package/dist/tools/click.js.map +1 -0
  23. package/dist/tools/evaluate.d.ts +9 -0
  24. package/dist/tools/evaluate.d.ts.map +1 -0
  25. package/dist/tools/evaluate.js +77 -0
  26. package/dist/tools/evaluate.js.map +1 -0
  27. package/dist/tools/fill.d.ts +9 -0
  28. package/dist/tools/fill.d.ts.map +1 -0
  29. package/dist/tools/fill.js +48 -0
  30. package/dist/tools/fill.js.map +1 -0
  31. package/dist/tools/hover.d.ts +9 -0
  32. package/dist/tools/hover.d.ts.map +1 -0
  33. package/dist/tools/hover.js +44 -0
  34. package/dist/tools/hover.js.map +1 -0
  35. package/dist/tools/index.d.ts +18 -0
  36. package/dist/tools/index.d.ts.map +1 -0
  37. package/dist/tools/index.js +51 -0
  38. package/dist/tools/index.js.map +1 -0
  39. package/dist/tools/knowledge.d.ts +56 -0
  40. package/dist/tools/knowledge.d.ts.map +1 -0
  41. package/dist/tools/knowledge.js +98 -0
  42. package/dist/tools/knowledge.js.map +1 -0
  43. package/dist/tools/navigate.d.ts +9 -0
  44. package/dist/tools/navigate.d.ts.map +1 -0
  45. package/dist/tools/navigate.js +48 -0
  46. package/dist/tools/navigate.js.map +1 -0
  47. package/dist/tools/press-key.d.ts +9 -0
  48. package/dist/tools/press-key.d.ts.map +1 -0
  49. package/dist/tools/press-key.js +38 -0
  50. package/dist/tools/press-key.js.map +1 -0
  51. package/dist/tools/report.d.ts +29 -0
  52. package/dist/tools/report.d.ts.map +1 -0
  53. package/dist/tools/report.js +92 -0
  54. package/dist/tools/report.js.map +1 -0
  55. package/dist/tools/screenshot.d.ts +9 -0
  56. package/dist/tools/screenshot.d.ts.map +1 -0
  57. package/dist/tools/screenshot.js +54 -0
  58. package/dist/tools/screenshot.js.map +1 -0
  59. package/dist/tools/snapshot.d.ts +13 -0
  60. package/dist/tools/snapshot.d.ts.map +1 -0
  61. package/dist/tools/snapshot.js +134 -0
  62. package/dist/tools/snapshot.js.map +1 -0
  63. package/dist/tools/types.d.ts +329 -0
  64. package/dist/tools/types.d.ts.map +1 -0
  65. package/dist/tools/types.js +102 -0
  66. package/dist/tools/types.js.map +1 -0
  67. package/dist/tools/wait.d.ts +9 -0
  68. package/dist/tools/wait.d.ts.map +1 -0
  69. package/dist/tools/wait.js +64 -0
  70. package/dist/tools/wait.js.map +1 -0
  71. package/dist/transports/index.d.ts +8 -0
  72. package/dist/transports/index.d.ts.map +1 -0
  73. package/dist/transports/index.js +14 -0
  74. package/dist/transports/index.js.map +1 -0
  75. package/dist/transports/stdio.d.ts +8 -0
  76. package/dist/transports/stdio.d.ts.map +1 -0
  77. package/dist/transports/stdio.js +12 -0
  78. package/dist/transports/stdio.js.map +1 -0
  79. package/dist/transports/websocket.d.ts +87 -0
  80. package/dist/transports/websocket.d.ts.map +1 -0
  81. package/dist/transports/websocket.js +200 -0
  82. package/dist/transports/websocket.js.map +1 -0
  83. package/package.json +53 -0
package/README.md ADDED
@@ -0,0 +1,254 @@
1
+ # AI2QA Local Agent
2
+
3
+ Universal MCP Server for browser automation. Enables both local AI tools (Claude Code, Cursor, Antigravity) and AI2QA cloud to control browsers.
4
+
5
+ ## Features
6
+
7
+ - **Sidecar Mode**: Attach to existing Chrome sessions (preserves cookies, auth, VPN access)
8
+ - **MCP Protocol**: Standard Model Context Protocol for AI tool integration
9
+ - **9 Browser Tools**: navigate, click, fill, hover, press-key, screenshot, snapshot, wait, evaluate
10
+
11
+ ## Quick Start
12
+
13
+ ### 1. Install
14
+
15
+ ```bash
16
+ cd ai2qa-local-agent
17
+ npm install
18
+ npm run build
19
+ ```
20
+
21
+ ### 2. Start Chrome with Remote Debugging
22
+
23
+ ```bash
24
+ # macOS
25
+ /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --remote-debugging-port=9222
26
+
27
+ # Linux
28
+ google-chrome --remote-debugging-port=9222
29
+
30
+ # Windows
31
+ "C:\Program Files\Google\Chrome\Application\chrome.exe" --remote-debugging-port=9222
32
+ ```
33
+
34
+ ### 3. Start the Agent
35
+
36
+ ```bash
37
+ # Sidecar mode (attach to existing Chrome)
38
+ npm start -- start --sidecar
39
+
40
+ # Or with custom port
41
+ npm start -- start --sidecar --port 9222
42
+ ```
43
+
44
+ ## CLI Commands
45
+
46
+ ```bash
47
+ # Start with stdio (for local AI tools like Claude Code)
48
+ ai2qa-agent start
49
+
50
+ # Start with sidecar mode (default) with custom CDP port
51
+ ai2qa-agent start --sidecar --port 9222
52
+
53
+ # Start in headless mode (no visible browser window)
54
+ ai2qa-agent start --headless
55
+
56
+ # Login to AI2QA cloud (for remote orchestration)
57
+ ai2qa-agent login <token>
58
+
59
+ # Start connected to AI2QA cloud
60
+ ai2qa-agent start --cloud
61
+
62
+ # Check agent status
63
+ ai2qa-agent status
64
+
65
+ # Logout and clear credentials
66
+ ai2qa-agent logout
67
+ ```
68
+
69
+ ## Claude Code Integration
70
+
71
+ Add to `~/.config/claude/claude_desktop_config.json`:
72
+
73
+ ```json
74
+ {
75
+ "mcpServers": {
76
+ "ai2qa": {
77
+ "command": "node",
78
+ "args": ["/path/to/ai2qa-local-agent/dist/index.js", "start", "--sidecar"]
79
+ }
80
+ }
81
+ }
82
+ ```
83
+
84
+ Or after global install:
85
+
86
+ ```bash
87
+ npm install -g @ai2qa/local-agent
88
+ ```
89
+
90
+ Then configure:
91
+
92
+ ```json
93
+ {
94
+ "mcpServers": {
95
+ "ai2qa": {
96
+ "command": "ai2qa-agent",
97
+ "args": ["start", "--sidecar"]
98
+ }
99
+ }
100
+ }
101
+ ```
102
+
103
+ ## AI2QA Cloud Integration
104
+
105
+ To connect your local agent to AI2QA cloud for remote test orchestration:
106
+
107
+ 1. **Generate a device token** from the AI2QA web UI at `https://ai2qa.com/agents`
108
+
109
+ 2. **Login with your token**:
110
+ ```bash
111
+ ai2qa-agent login <your-token>
112
+ ```
113
+
114
+ 3. **Start in cloud mode**:
115
+ ```bash
116
+ ai2qa-agent start --cloud
117
+ ```
118
+
119
+ The agent will connect to AI2QA cloud and be available for running test runs from the web interface. This enables testing on internal applications behind VPNs using your local browser session.
120
+
121
+ ## Available Tools
122
+
123
+ ### navigate_page
124
+ Navigate to a URL or perform navigation actions.
125
+
126
+ ```json
127
+ {
128
+ "url": "https://example.com",
129
+ "type": "goto" // goto, reload, back, forward
130
+ }
131
+ ```
132
+
133
+ ### click
134
+ Click on an element by selector or ref.
135
+
136
+ ```json
137
+ {
138
+ "selector": "button#submit"
139
+ }
140
+ ```
141
+
142
+ ### fill
143
+ Fill an input field with text.
144
+
145
+ ```json
146
+ {
147
+ "selector": "input[name='email']",
148
+ "value": "test@example.com"
149
+ }
150
+ ```
151
+
152
+ ### hover
153
+ Hover over an element.
154
+
155
+ ```json
156
+ {
157
+ "selector": ".menu-trigger"
158
+ }
159
+ ```
160
+
161
+ ### press_key
162
+ Press a keyboard key.
163
+
164
+ ```json
165
+ {
166
+ "key": "Enter",
167
+ "modifiers": ["Control"]
168
+ }
169
+ ```
170
+
171
+ ### take_screenshot
172
+ Capture a screenshot.
173
+
174
+ ```json
175
+ {
176
+ "fullPage": true,
177
+ "format": "png"
178
+ }
179
+ ```
180
+
181
+ ### take_snapshot
182
+ Get accessibility tree/DOM snapshot for AI analysis.
183
+
184
+ ```json
185
+ {
186
+ "verbose": true,
187
+ "mode": "accessibility"
188
+ }
189
+ ```
190
+
191
+ ### wait_for
192
+ Wait for element, text, or duration.
193
+
194
+ ```json
195
+ {
196
+ "selector": ".loaded",
197
+ "state": "visible",
198
+ "timeout": 5000
199
+ }
200
+ ```
201
+
202
+ ### evaluate
203
+ Execute JavaScript in page context.
204
+
205
+ ```json
206
+ {
207
+ "script": "document.title"
208
+ }
209
+ ```
210
+
211
+ ## Development
212
+
213
+ ```bash
214
+ # Build
215
+ npm run build
216
+
217
+ # Watch mode
218
+ npm run dev
219
+
220
+ # Run tests
221
+ npm test
222
+
223
+ # Lint
224
+ npm run lint
225
+ ```
226
+
227
+ ## Architecture
228
+
229
+ ```
230
+ ┌─────────────────────────────────────────────────────────┐
231
+ │ AI2QA Local Agent │
232
+ │ │
233
+ │ ┌─────────────┐ ┌──────────────┐ ┌────────────┐ │
234
+ │ │ Stdio │ │ MCP Server │ │ WebSocket │ │
235
+ │ │ Transport │───►│ (9 tools) │◄───│ Transport │ │
236
+ │ └─────────────┘ └──────┬───────┘ └────────────┘ │
237
+ │ ▲ │ ▲ │
238
+ │ │ ▼ │ │
239
+ │ [Claude Code] ┌──────────────┐ [AI2QA Cloud] │
240
+ │ [Cursor] │ Playwright │ │
241
+ │ │ CDP Bridge │ │
242
+ │ └──────┬───────┘ │
243
+ └────────────────────────────┼────────────────────────────┘
244
+
245
+
246
+ ┌────────────────────────────────────────────────────────┐
247
+ │ Chrome (--remote-debugging-port=9222) │
248
+ │ [Already logged into VPN, SSO, internal apps] │
249
+ └────────────────────────────────────────────────────────┘
250
+ ```
251
+
252
+ ## License
253
+
254
+ MIT
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * AI2QA Local Agent CLI Entry Point
5
+ */
6
+
7
+ import('../dist/index.js').catch((err) => {
8
+ console.error('Failed to start ai2qa-agent:', err.message);
9
+ console.error('');
10
+ console.error('If you see "Cannot find module", run: npm run build');
11
+ process.exit(1);
12
+ });
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Browser Connection Manager
3
+ *
4
+ * Handles two connection modes:
5
+ * 1. Sidecar Mode: Attach to existing Chrome via CDP (for cookie/auth bypass)
6
+ * 2. Launch Mode: Start new browser instance (for CI/CD)
7
+ */
8
+ import { Page } from 'playwright';
9
+ /** Connection mode for the browser */
10
+ export type ConnectionMode = 'sidecar' | 'launch';
11
+ /** Configuration for browser connection */
12
+ export interface BrowserConfig {
13
+ readonly mode: ConnectionMode;
14
+ readonly cdpUrl?: string;
15
+ readonly headless?: boolean;
16
+ readonly viewport?: {
17
+ width: number;
18
+ height: number;
19
+ };
20
+ }
21
+ /** Result type for operations that can fail */
22
+ export type Result<T, E = Error> = {
23
+ readonly success: true;
24
+ readonly value: T;
25
+ } | {
26
+ readonly success: false;
27
+ readonly error: E;
28
+ };
29
+ /**
30
+ * Browser Connection Manager
31
+ * Manages browser lifecycle and provides access to the active page.
32
+ */
33
+ export declare class BrowserConnection {
34
+ private state;
35
+ private readonly config;
36
+ constructor(config?: Partial<BrowserConfig>);
37
+ /**
38
+ * Connect to browser based on configured mode.
39
+ * Returns Result to avoid throwing exceptions.
40
+ */
41
+ connect(): Promise<Result<Page>>;
42
+ /**
43
+ * Sidecar mode: Attach to existing Chrome via CDP.
44
+ * Chrome must be started with: --remote-debugging-port=9222
45
+ */
46
+ private connectSidecar;
47
+ /**
48
+ * Launch mode: Start new browser instance.
49
+ */
50
+ private launchBrowser;
51
+ /**
52
+ * Get the active page, connecting if necessary.
53
+ */
54
+ getPage(): Promise<Result<Page>>;
55
+ /**
56
+ * Check if connected to a browser.
57
+ */
58
+ isConnected(): boolean;
59
+ /**
60
+ * Get current page URL, or empty string if not connected.
61
+ */
62
+ getCurrentUrl(): Promise<string>;
63
+ /**
64
+ * Disconnect from browser.
65
+ * In sidecar mode, only disconnects (doesn't close Chrome).
66
+ * In launch mode, closes the browser.
67
+ */
68
+ disconnect(): Promise<void>;
69
+ /**
70
+ * Create a new page in the current context.
71
+ */
72
+ newPage(): Promise<Result<Page>>;
73
+ /**
74
+ * Close current page and switch to another if available.
75
+ */
76
+ closePage(): Promise<void>;
77
+ }
78
+ /** Factory function for creating browser connections */
79
+ export declare function createBrowserConnection(config?: Partial<BrowserConfig>): BrowserConnection;
80
+ //# sourceMappingURL=connection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../../src/browser/connection.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAqC,IAAI,EAAE,MAAM,YAAY,CAAC;AAErE,sCAAsC;AACtC,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,QAAQ,CAAC;AAElD,2CAA2C;AAC3C,MAAM,WAAW,aAAa;IAC1B,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAC9B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,QAAQ,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CACzD;AAED,+CAA+C;AAC/C,MAAM,MAAM,MAAM,CAAC,CAAC,EAAE,CAAC,GAAG,KAAK,IACzB;IAAE,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAA;CAAE,GAC7C;IAAE,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAA;CAAE,CAAC;AAYrD;;;GAGG;AACH,qBAAa,iBAAiB;IAC1B,OAAO,CAAC,KAAK,CAIX;IACF,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;gBAE3B,MAAM,GAAE,OAAO,CAAC,aAAa,CAAM;IAS/C;;;OAGG;IACG,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IA0BtC;;;OAGG;YACW,cAAc;IAM5B;;OAEG;YACW,aAAa;IAO3B;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAOtC;;OAEG;IACH,WAAW,IAAI,OAAO;IAItB;;OAEG;IACG,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC;IAMtC;;;;OAIG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAgBjC;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IActC;;OAEG;IACG,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;CAenC;AAED,wDAAwD;AACxD,wBAAgB,uBAAuB,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,GAAG,iBAAiB,CAE1F"}
@@ -0,0 +1,165 @@
1
+ "use strict";
2
+ /**
3
+ * Browser Connection Manager
4
+ *
5
+ * Handles two connection modes:
6
+ * 1. Sidecar Mode: Attach to existing Chrome via CDP (for cookie/auth bypass)
7
+ * 2. Launch Mode: Start new browser instance (for CI/CD)
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.BrowserConnection = void 0;
11
+ exports.createBrowserConnection = createBrowserConnection;
12
+ const playwright_1 = require("playwright");
13
+ const DEFAULT_VIEWPORT = { width: 1920, height: 1080 };
14
+ const DEFAULT_CDP_URL = 'http://localhost:9222';
15
+ /**
16
+ * Browser Connection Manager
17
+ * Manages browser lifecycle and provides access to the active page.
18
+ */
19
+ class BrowserConnection {
20
+ state = {
21
+ browser: null,
22
+ context: null,
23
+ page: null,
24
+ };
25
+ config;
26
+ constructor(config = {}) {
27
+ this.config = {
28
+ mode: config.mode ?? 'sidecar',
29
+ cdpUrl: config.cdpUrl ?? DEFAULT_CDP_URL,
30
+ headless: config.headless ?? false,
31
+ viewport: config.viewport ?? DEFAULT_VIEWPORT,
32
+ };
33
+ }
34
+ /**
35
+ * Connect to browser based on configured mode.
36
+ * Returns Result to avoid throwing exceptions.
37
+ */
38
+ async connect() {
39
+ try {
40
+ const browser = this.config.mode === 'sidecar'
41
+ ? await this.connectSidecar()
42
+ : await this.launchBrowser();
43
+ this.state.browser = browser;
44
+ // Get or create context and page
45
+ const contexts = browser.contexts();
46
+ this.state.context = contexts.length > 0
47
+ ? contexts[0]
48
+ : await browser.newContext({ viewport: this.config.viewport });
49
+ const pages = this.state.context.pages();
50
+ this.state.page = pages.length > 0
51
+ ? pages[0]
52
+ : await this.state.context.newPage();
53
+ return { success: true, value: this.state.page };
54
+ }
55
+ catch (err) {
56
+ const error = err instanceof Error ? err : new Error(String(err));
57
+ return { success: false, error };
58
+ }
59
+ }
60
+ /**
61
+ * Sidecar mode: Attach to existing Chrome via CDP.
62
+ * Chrome must be started with: --remote-debugging-port=9222
63
+ */
64
+ async connectSidecar() {
65
+ const cdpUrl = this.config.cdpUrl ?? DEFAULT_CDP_URL;
66
+ console.error(`[BrowserConnection] Connecting to Chrome via CDP: ${cdpUrl}`);
67
+ return playwright_1.chromium.connectOverCDP(cdpUrl);
68
+ }
69
+ /**
70
+ * Launch mode: Start new browser instance.
71
+ */
72
+ async launchBrowser() {
73
+ console.error(`[BrowserConnection] Launching new browser (headless: ${this.config.headless})`);
74
+ return playwright_1.chromium.launch({
75
+ headless: this.config.headless,
76
+ });
77
+ }
78
+ /**
79
+ * Get the active page, connecting if necessary.
80
+ */
81
+ async getPage() {
82
+ if (this.state.page && !this.state.page.isClosed()) {
83
+ return { success: true, value: this.state.page };
84
+ }
85
+ return this.connect();
86
+ }
87
+ /**
88
+ * Check if connected to a browser.
89
+ */
90
+ isConnected() {
91
+ return this.state.browser !== null && this.state.browser.isConnected();
92
+ }
93
+ /**
94
+ * Get current page URL, or empty string if not connected.
95
+ */
96
+ async getCurrentUrl() {
97
+ const result = await this.getPage();
98
+ if (!result.success)
99
+ return '';
100
+ return result.value.url();
101
+ }
102
+ /**
103
+ * Disconnect from browser.
104
+ * In sidecar mode, only disconnects (doesn't close Chrome).
105
+ * In launch mode, closes the browser.
106
+ */
107
+ async disconnect() {
108
+ try {
109
+ if (this.state.browser) {
110
+ if (this.config.mode === 'launch') {
111
+ await this.state.browser.close();
112
+ }
113
+ // Sidecar mode: browser.close() just disconnects without closing Chrome
114
+ // For CDP connections, close() is safe and doesn't terminate the browser
115
+ }
116
+ }
117
+ catch (err) {
118
+ console.error('[BrowserConnection] Error during disconnect:', err);
119
+ }
120
+ finally {
121
+ this.state = { browser: null, context: null, page: null };
122
+ }
123
+ }
124
+ /**
125
+ * Create a new page in the current context.
126
+ */
127
+ async newPage() {
128
+ if (!this.state.context) {
129
+ return { success: false, error: new Error('Not connected to browser') };
130
+ }
131
+ try {
132
+ const page = await this.state.context.newPage();
133
+ this.state.page = page;
134
+ return { success: true, value: page };
135
+ }
136
+ catch (err) {
137
+ const error = err instanceof Error ? err : new Error(String(err));
138
+ return { success: false, error };
139
+ }
140
+ }
141
+ /**
142
+ * Close current page and switch to another if available.
143
+ */
144
+ async closePage() {
145
+ if (!this.state.page)
146
+ return;
147
+ try {
148
+ await this.state.page.close();
149
+ }
150
+ catch {
151
+ // Page might already be closed
152
+ }
153
+ // Switch to another page if available
154
+ if (this.state.context) {
155
+ const pages = this.state.context.pages();
156
+ this.state.page = pages.length > 0 ? pages[0] : null;
157
+ }
158
+ }
159
+ }
160
+ exports.BrowserConnection = BrowserConnection;
161
+ /** Factory function for creating browser connections */
162
+ function createBrowserConnection(config) {
163
+ return new BrowserConnection(config);
164
+ }
165
+ //# sourceMappingURL=connection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connection.js","sourceRoot":"","sources":["../../src/browser/connection.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Configuration Management
3
+ *
4
+ * Handles loading/saving agent configuration including:
5
+ * - Cloud connection settings
6
+ * - Device token storage
7
+ * - Agent identity
8
+ */
9
+ /** Agent configuration */
10
+ export interface AgentConfig {
11
+ /** Unique agent identifier */
12
+ agentId: string;
13
+ /** Device name for identification */
14
+ deviceName: string;
15
+ /** AI2QA cloud WebSocket URL */
16
+ cloudUrl: string;
17
+ /** Encrypted device token */
18
+ encryptedToken?: string;
19
+ /** Token expiration timestamp */
20
+ tokenExpiresAt?: string;
21
+ }
22
+ /**
23
+ * Load agent configuration from disk.
24
+ */
25
+ export declare function loadConfig(): AgentConfig;
26
+ /**
27
+ * Save agent configuration to disk.
28
+ */
29
+ export declare function saveConfig(config: Partial<AgentConfig>): void;
30
+ /**
31
+ * Store device token securely.
32
+ */
33
+ export declare function storeToken(token: string, expiresAt?: Date): void;
34
+ /**
35
+ * Retrieve stored device token.
36
+ */
37
+ export declare function getToken(): string | null;
38
+ /**
39
+ * Check if agent is logged in (has valid token).
40
+ */
41
+ export declare function isLoggedIn(): boolean;
42
+ /**
43
+ * Clear stored token (logout).
44
+ */
45
+ export declare function clearToken(): void;
46
+ /**
47
+ * Get cloud connection config.
48
+ */
49
+ export declare function getCloudConfig(): {
50
+ url: string;
51
+ token: string;
52
+ agentId: string;
53
+ } | null;
54
+ /**
55
+ * Set cloud URL.
56
+ */
57
+ export declare function setCloudUrl(url: string): void;
58
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAOH,0BAA0B;AAC1B,MAAM,WAAW,WAAW;IACxB,8BAA8B;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,qCAAqC;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,gCAAgC;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,6BAA6B;IAC7B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,iCAAiC;IACjC,cAAc,CAAC,EAAE,MAAM,CAAC;CAC3B;AAwFD;;GAEG;AACH,wBAAgB,UAAU,IAAI,WAAW,CAkBxC;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,OAAO,CAAC,WAAW,CAAC,GAAG,IAAI,CAO7D;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,IAAI,GAAG,IAAI,CAShE;AAED;;GAEG;AACH,wBAAgB,QAAQ,IAAI,MAAM,GAAG,IAAI,CAwBxC;AAED;;GAEG;AACH,wBAAgB,UAAU,IAAI,OAAO,CAEpC;AAED;;GAEG;AACH,wBAAgB,UAAU,IAAI,IAAI,CAKjC;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAavF;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAE7C"}