easyeda-mcp-pro 0.2.0 → 0.3.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 (60) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +64 -19
  3. package/dist/bridge/manager.d.ts +18 -11
  4. package/dist/bridge/manager.js +164 -113
  5. package/dist/bridge/manager.js.map +1 -1
  6. package/dist/bridge/protocol.d.ts +2 -4
  7. package/dist/bridge/protocol.js +2 -0
  8. package/dist/bridge/protocol.js.map +1 -1
  9. package/dist/bridge/types.d.ts +11 -42
  10. package/dist/bridge/types.js +3 -0
  11. package/dist/bridge/types.js.map +1 -1
  12. package/dist/config/env.d.ts +1 -0
  13. package/dist/config/env.js +1 -0
  14. package/dist/config/env.js.map +1 -1
  15. package/dist/config/profiles.js +6 -6
  16. package/dist/config/profiles.js.map +1 -1
  17. package/dist/index.d.ts +1 -2
  18. package/dist/index.js +22 -64
  19. package/dist/index.js.map +1 -1
  20. package/dist/schemas/common.d.ts +1 -108
  21. package/dist/schemas/common.js +0 -62
  22. package/dist/schemas/common.js.map +1 -1
  23. package/dist/server/factory.d.ts +6 -3
  24. package/dist/server/factory.js +18 -12
  25. package/dist/server/factory.js.map +1 -1
  26. package/dist/server/transports/http.js +83 -0
  27. package/dist/server/transports/http.js.map +1 -1
  28. package/dist/storage/database.js +5 -4
  29. package/dist/storage/database.js.map +1 -1
  30. package/dist/storage/types.d.ts +0 -9
  31. package/dist/storage/types.js +1 -8
  32. package/dist/storage/types.js.map +1 -1
  33. package/dist/tools/L0_diagnostics.js +28 -7
  34. package/dist/tools/L0_diagnostics.js.map +1 -1
  35. package/dist/tools/L1_board.js +43 -15
  36. package/dist/tools/L1_board.js.map +1 -1
  37. package/dist/tools/L1_bom.js +18 -0
  38. package/dist/tools/L1_bom.js.map +1 -1
  39. package/dist/tools/register.d.ts +3 -0
  40. package/dist/tools/register.js +15 -0
  41. package/dist/tools/register.js.map +1 -0
  42. package/dist/tools/registry.d.ts +2 -2
  43. package/dist/tools/registry.js +17 -16
  44. package/dist/tools/registry.js.map +1 -1
  45. package/dist/tools/types.d.ts +2 -21
  46. package/dist/vendors/jlcpcb/client.d.ts +3 -2
  47. package/dist/vendors/lcsc/client.d.ts +0 -9
  48. package/dist/vendors/lcsc/client.js.map +1 -1
  49. package/dist/vendors/mouser/client.d.ts +2 -5
  50. package/dist/vendors/mouser/client.js.map +1 -1
  51. package/package.json +7 -5
  52. package/dist/bridge/client.d.ts +0 -16
  53. package/dist/bridge/client.js +0 -48
  54. package/dist/bridge/client.js.map +0 -1
  55. package/dist/bridge/extension.d.ts +0 -26
  56. package/dist/bridge/extension.js +0 -556
  57. package/dist/bridge/extension.js.map +0 -1
  58. package/dist/server/errors.d.ts +0 -3
  59. package/dist/server/errors.js +0 -59
  60. package/dist/server/errors.js.map +0 -1
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 oaslananka
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -42,7 +42,7 @@ The server connects to EasyEDA Pro via a WebSocket bridge extension, enabling re
42
42
 
43
43
  - **Node.js** >=24 <27 (required for the latest JavaScript features)
44
44
  - **pnpm** >=11 (for local development; the npm package is self-contained)
45
- - **EasyEDA Pro** with the [bridge extension](https://github.com/oaslananka/easyeda-bridge) installed and running
45
+ - **EasyEDA Pro** with the bundled bridge extension installed and running
46
46
  - For supplier integration: API credentials from JLCPCB, LCSC, Mouser, or DigiKey
47
47
 
48
48
  ---
@@ -70,6 +70,7 @@ cd easyeda-mcp-pro
70
70
  cp .env.example .env
71
71
  pnpm install
72
72
  pnpm build
73
+ pnpm build:extension
73
74
  pnpm start
74
75
  ```
75
76
 
@@ -90,11 +91,14 @@ Copy `.env.example` to `.env` and edit. All variables have safe defaults — onl
90
91
 
91
92
  ### Bridge (EasyEDA Pro connection)
92
93
 
93
- | Variable | Default | Description |
94
- | ------------------- | ----------- | ------------------------ |
95
- | `BRIDGE_HOST` | `127.0.0.1` | Bridge WebSocket host |
96
- | `BRIDGE_PORT` | `18601` | Bridge port |
97
- | `BRIDGE_TIMEOUT_MS` | `15000` | Bridge call timeout (ms) |
94
+ | Variable | Default | Description |
95
+ | --------------------- | ------------------- | -------------------------------- |
96
+ | `BRIDGE_HOST` | `127.0.0.1` | Bridge WebSocket host |
97
+ | `BRIDGE_PORT` | `18601` | Primary bridge port |
98
+ | `BRIDGE_PORT_SCAN` | `18601,49620-49629` | Port scan spec (comma/range) |
99
+ | `BRIDGE_TIMEOUT_MS` | `15000` | Bridge call timeout (ms) |
100
+ | `BRIDGE_HEARTBEAT_MS` | `10000` | Heartbeat interval (ms) |
101
+ | `BRIDGE_TOKEN` | `''` | Session token for extension auth |
98
102
 
99
103
  ### Storage
100
104
 
@@ -124,15 +128,36 @@ Configure an AI provider for LLM-assisted design review:
124
128
 
125
129
  When using `TRANSPORT=http`:
126
130
 
127
- | Variable | Default | Description |
128
- | ------------- | ----------- | ----------------------------------------- |
129
- | `HTTP_HOST` | `127.0.0.1` | Bind address (use `0.0.0.0` with caution) |
130
- | `HTTP_PORT` | `3000` | Port |
131
- | `CORS_ORIGIN` | `''` | Allowed CORS origin |
131
+ | Variable | Default | Description |
132
+ | --------------------- | ----------- | ----------------------------------------- |
133
+ | `HTTP_HOST` | `127.0.0.1` | Bind address (use `0.0.0.0` with caution) |
134
+ | `HTTP_PORT` | `3000` | Port |
135
+ | `HTTP_RATE_LIMIT_MAX` | `100` | Max requests per minute per IP |
136
+ | `CORS_ORIGIN` | `''` | Allowed CORS origin |
132
137
 
133
- For production HTTP deployments, configure OAuth (`OAUTH_ENABLED=true` + issuer/JWKS).
138
+ #### Production HTTP Security
134
139
 
135
- See `.env.example` for the complete list of 42 configuration variables.
140
+ For remote HTTP deployments, OAuth 2.0 / OpenID Connect is strongly recommended:
141
+
142
+ | Variable | Default | Description |
143
+ | ----------------------- | ----------------- | -------------------------------------------- |
144
+ | `OAUTH_ENABLED` | `false` | Enable Bearer token validation |
145
+ | `OAUTH_ISSUER` | `''` | Expected token issuer (`iss` claim) |
146
+ | `OAUTH_AUDIENCE` | `easyeda-mcp-pro` | Expected token audience (`aud` claim) |
147
+ | `OAUTH_JWKS_URI` | `''` | JWKS endpoint for token signature validation |
148
+ | `OAUTH_REQUIRED_SCOPES` | `easyeda:read` | Required token scope |
149
+
150
+ When `OAUTH_ENABLED=true`, every request to `/mcp` must include an `Authorization: Bearer <token>` header. Tokens are validated against the JWKS endpoint if configured, or structurally validated otherwise.
151
+
152
+ The server enforces a safety check at startup: **non-loopback `HTTP_HOST` without OAuth is rejected**.
153
+
154
+ #### HTTP Security Features
155
+
156
+ - **Rate limiting**: Per-IP sliding window (configurable via `HTTP_RATE_LIMIT_MAX`), returns `429 Too Many Requests` with retry-after header
157
+ - **Security headers**: `X-Content-Type-Options: nosniff`, `X-Frame-Options: DENY`, `X-XSS-Protection: 0`, `Referrer-Policy: strict-origin-when-cross-origin`
158
+ - **Health endpoints**: `/healthz` (liveness) and `/readyz` (readiness) return JSON status
159
+
160
+ See `.env.example` for the complete list of configuration variables.
136
161
 
137
162
  ---
138
163
 
@@ -228,6 +253,19 @@ All 25 tools are available via the MCP server. Tools are filtered by the active
228
253
  - **stdio** (default): Standard MCP transport — works with Claude Desktop, Cursor, and most MCP clients
229
254
  - **HTTP**: Streamable HTTP transport with `/healthz`, `/readyz`, `/mcp` endpoints, CORS, and optional OAuth — suitable for remote deployments
230
255
 
256
+ ### Bridge extension
257
+
258
+ ```bash
259
+ pnpm build:extension
260
+ pnpm verify:extension
261
+ ```
262
+
263
+ The extension build writes `easyeda-bridge-extension.eext` at the repository root.
264
+ It contains `extension.json`, the bundled browser script, and the image assets
265
+ required by EasyEDA Pro.
266
+
267
+ Installation: Open EasyEDA Pro → **Settings** → **Extensions** → **Extension Manager...** → **Import Extension**, then select the `.eext` file. Make sure **Allow External Interaction** is enabled for the extension.
268
+
231
269
  ---
232
270
 
233
271
  ## Development
@@ -243,11 +281,13 @@ pnpm typecheck # TypeScript
243
281
  pnpm lint # ESLint
244
282
 
245
283
  # Test
246
- pnpm test # Vitest (73 tests across 12 files)
284
+ pnpm test # Vitest (90 tests across 12 files)
247
285
  pnpm test:coverage # With coverage report
248
286
 
249
287
  # Build & run
250
288
  pnpm build # tsc -> dist/
289
+ pnpm build:extension # Bundle EasyEDA Pro extension
290
+ pnpm verify:extension # Verify extension package contents
251
291
  pnpm dev # Hot-reload dev mode
252
292
  pnpm start # Run compiled build
253
293
 
@@ -259,9 +299,9 @@ pnpm inspector
259
299
 
260
300
  ```
261
301
  src/
262
- ├── index.ts # Entry point
302
+ ├── index.ts # Entry point (stdio or HTTP)
263
303
  ├── bridge/ # EasyEDA Pro WebSocket bridge protocol
264
- │ ├── manager.ts, client.ts, extension.ts, protocol.ts, types.ts
304
+ │ ├── manager.ts, protocol.ts, types.ts
265
305
  ├── config/ # Environment configuration
266
306
  │ ├── env.ts, profiles.ts, feature-flags.ts
267
307
  ├── schemas/ # Shared Zod schemas
@@ -269,13 +309,15 @@ src/
269
309
  │ ├── factory.ts, errors.ts
270
310
  │ └── transports/
271
311
  │ └── http.ts # HTTP/Streamable HTTP transport
272
- ├── storage/ # SQLite storage (cache, artifacts)
312
+ ├── storage/ # Node.js sqlite storage (cache, artifacts)
273
313
  ├── tools/ # 25 MCP tool definitions (6 groups)
274
- │ ├── registry.ts, types.ts
314
+ │ ├── register.ts, registry.ts, types.ts
275
315
  │ ├── L0_diagnostics.ts, L1_schematic.ts, L1_bom.ts
276
316
  │ ├── L1_drc_erc.ts, L1_board.ts, L1_export.ts
277
317
  └── vendors/ # Supplier API clients
278
318
  ├── lcsc/, jlcpcb/, mouser/, digikey/
319
+
320
+ easyeda-bridge-extension/ # EasyEDA Pro bridge extension workspace package
279
321
  ```
280
322
 
281
323
  ---
@@ -283,10 +325,14 @@ src/
283
325
  ## Security
284
326
 
285
327
  - **Production safety**: Validates config at startup — rejects non-loopback HTTP without OAuth, blocks dangerous features in production
328
+ - **OAuth/JWKS**: Optional Bearer token validation via JWKS endpoint for HTTP transport
329
+ - **Rate limiting**: Per-IP sliding window rate limiter on HTTP transport (default 100 req/min)
330
+ - **Path traversal protection**: All file export paths validated against `ARTIFACT_DIR`
286
331
  - **Secret redaction**: API keys, tokens, passwords are redacted from logs and diagnostic output
287
332
  - **Branch protection**: `main` branch requires review and up-to-date status checks
288
333
  - **Code scanning**: CodeQL analysis runs on every push and PR (security-extended + security-and-quality queries)
289
334
  - **Dependency management**: Renovate automatically updates dependencies with security patches
335
+ - **Supply-chain hygiene**: pnpm workspace build, pinned GitHub Actions, and no native SQLite addon dependency
290
336
  - **Reporting**: See [SECURITY.md](SECURITY.md) for vulnerability disclosure
291
337
 
292
338
  ---
@@ -299,6 +345,5 @@ src/
299
345
 
300
346
  ## Related
301
347
 
302
- - [easyeda-bridge](https://github.com/oaslananka/easyeda-bridge) — EasyEDA Pro plugin that exposes the bridge WebSocket API
303
348
  - [Model Context Protocol](https://modelcontextprotocol.io) — Standard protocol for AI tool integration
304
349
  - [EasyEDA Pro](https://pro.easyeda.com) — Professional PCB design tool
@@ -2,36 +2,43 @@ import { EventEmitter } from 'node:events';
2
2
  import { type EnvConfig } from '../config/env.js';
3
3
  import { type BridgeHello } from './protocol.js';
4
4
  export type BridgeState = 'disconnected' | 'connecting' | 'connected' | 'error';
5
- export interface BridgeEvents {
6
- stateChanged: (state: BridgeState, previous: BridgeState) => void;
7
- connected: (hello: BridgeHello) => void;
8
- disconnected: (reason: string) => void;
9
- error: (error: Error) => void;
10
- heartbeat: (timestamp: number) => void;
11
- }
12
5
  export declare class BridgeManager extends EventEmitter {
13
6
  state: BridgeState;
14
7
  hello: BridgeHello | null;
8
+ private wss;
15
9
  private ws;
16
10
  private heartbeatTimer;
17
11
  private reconnectTimer;
12
+ private _activePort;
13
+ private _connectedAtMs;
18
14
  private requestMap;
19
15
  private requestIdCounter;
20
16
  private config;
21
17
  private _lastHeartbeatMs;
22
18
  constructor(config: EnvConfig);
23
19
  get lastHeartbeatMs(): number;
20
+ get activePort(): number;
21
+ get uptimeMs(): number;
24
22
  get connected(): boolean;
25
23
  connect(): Promise<void>;
24
+ private tryListen;
25
+ private handleConnection;
26
26
  call<TParams, TResult>(method: string, params?: TParams, opts?: {
27
27
  timeoutMs?: number;
28
28
  traceparent?: string;
29
29
  }): Promise<TResult>;
30
30
  disconnect(reason?: string): void;
31
- private tryConnect;
32
- private sendHandshake;
33
- private handleHello;
34
31
  private handleResponse;
32
+ private rejectPending;
35
33
  private startHeartbeat;
36
- private parsePortScan;
34
+ private stopHeartbeat;
37
35
  }
36
+ /**
37
+ * Parse a port scan specification string into an ordered array of ports.
38
+ * Supports comma-separated values and dash ranges:
39
+ * "18601" → [18601]
40
+ * "18601,49620" → [18601, 49620]
41
+ * "49620-49629" → [49620, 49621, ..., 49629]
42
+ * "18601,49620-49629" → [18601, 49620, 49621, ..., 49629]
43
+ */
44
+ export declare function parsePortScanSpec(spec: string): number[];
@@ -1,12 +1,17 @@
1
1
  import { EventEmitter } from 'node:events';
2
+ import { WebSocketServer } from 'ws';
2
3
  import { getLogger } from '../utils/logger.js';
3
- import { BridgeHelloSchema } from './protocol.js';
4
+ import { BridgeHandshakeSchema } from './protocol.js';
5
+ import { EasyedaApiMethodSchema } from './types.js';
4
6
  export class BridgeManager extends EventEmitter {
5
7
  state = 'disconnected';
6
8
  hello = null;
9
+ wss = null;
7
10
  ws = null;
8
11
  heartbeatTimer = null;
9
12
  reconnectTimer = null;
13
+ _activePort = 0;
14
+ _connectedAtMs = 0;
10
15
  requestMap = new Map();
11
16
  requestIdCounter = 0;
12
17
  config;
@@ -18,6 +23,14 @@ export class BridgeManager extends EventEmitter {
18
23
  get lastHeartbeatMs() {
19
24
  return this._lastHeartbeatMs;
20
25
  }
26
+ get activePort() {
27
+ return this._activePort;
28
+ }
29
+ get uptimeMs() {
30
+ if (this.state !== 'connected' || this._connectedAtMs === 0)
31
+ return 0;
32
+ return Date.now() - this._connectedAtMs;
33
+ }
21
34
  get connected() {
22
35
  return this.state === 'connected';
23
36
  }
@@ -27,22 +40,113 @@ export class BridgeManager extends EventEmitter {
27
40
  const prev = this.state;
28
41
  this.state = 'connecting';
29
42
  this.emit('stateChanged', this.state, prev);
30
- const ports = this.parsePortScan();
31
43
  const logger = getLogger();
44
+ const ports = parsePortScanSpec(this.config.BRIDGE_PORT_SCAN);
45
+ let lastErr = null;
32
46
  for (const port of ports) {
33
47
  try {
34
- await this.tryConnect(port);
35
- if (this.state === 'connected')
36
- return;
48
+ await this.tryListen(port);
49
+ logger.info({ port }, 'bridge websocket server listening');
50
+ return;
37
51
  }
38
- catch {
39
- logger.debug({ port }, 'bridge connection attempt failed');
52
+ catch (err) {
53
+ lastErr = err instanceof Error ? err : new Error(String(err));
54
+ logger.debug({ port, err: lastErr.message }, 'bridge port unavailable, trying next');
40
55
  }
41
56
  }
42
- const prevState = this.state;
43
- this.state = 'disconnected';
44
- this.emit('stateChanged', this.state, prevState);
45
- logger.warn('no bridge found on any scanned port');
57
+ logger.error({ ports, err: lastErr?.message }, 'failed to start bridge server on any port');
58
+ this.state = 'error';
59
+ this.emit('stateChanged', 'error', 'connecting');
60
+ this.emit('error', lastErr ?? new Error('No available bridge port'));
61
+ throw lastErr ?? new Error('No available bridge port');
62
+ }
63
+ tryListen(port) {
64
+ return new Promise((resolve, reject) => {
65
+ const wss = new WebSocketServer({
66
+ host: this.config.BRIDGE_HOST,
67
+ port,
68
+ });
69
+ this.wss = wss;
70
+ this._activePort = port;
71
+ wss.once('listening', () => resolve());
72
+ wss.once('error', (err) => {
73
+ this.wss = null;
74
+ this._activePort = 0;
75
+ reject(err);
76
+ });
77
+ wss.on('error', (err) => {
78
+ getLogger().error({ err }, 'bridge server error');
79
+ this.emit('error', err);
80
+ });
81
+ wss.on('connection', (ws) => this.handleConnection(ws));
82
+ });
83
+ }
84
+ handleConnection(ws) {
85
+ const logger = getLogger();
86
+ logger.info('new bridge client connection');
87
+ // Only allow one connected client at a time
88
+ if (this.ws) {
89
+ logger.warn('rejecting concurrent bridge connection');
90
+ ws.close(4000, 'Only one client allowed');
91
+ return;
92
+ }
93
+ ws.on('message', (raw) => {
94
+ try {
95
+ const data = JSON.parse(raw.toString());
96
+ if (data.type === 'handshake') {
97
+ const parsed = BridgeHandshakeSchema.safeParse(data);
98
+ if (!parsed.success) {
99
+ logger.warn('bridge handshake validation failed');
100
+ ws.close(4001, 'Invalid handshake');
101
+ return;
102
+ }
103
+ if (this.config.BRIDGE_TOKEN && parsed.data.sessionToken !== this.config.BRIDGE_TOKEN) {
104
+ logger.warn('bridge handshake rejected: invalid session token');
105
+ ws.close(4001, 'Invalid session token');
106
+ return;
107
+ }
108
+ this.ws = ws;
109
+ this.state = 'connected';
110
+ this._connectedAtMs = Date.now();
111
+ this.hello = {
112
+ type: 'hello',
113
+ bridgeVersion: '1.0.0',
114
+ easyedaVersion: parsed.data.easyedaVersion,
115
+ capabilities: EasyedaApiMethodSchema.options,
116
+ methodRegistryHash: 'bridge-1.0.0',
117
+ devMode: parsed.data.devMode ?? false,
118
+ };
119
+ // Reply with hello
120
+ ws.send(JSON.stringify(this.hello));
121
+ this.emit('stateChanged', 'connected', 'connecting');
122
+ this.emit('connected', this.hello);
123
+ this.startHeartbeat();
124
+ }
125
+ else if (data.type === 'response') {
126
+ this.handleResponse(data);
127
+ }
128
+ else if (data.type === 'heartbeat') {
129
+ this._lastHeartbeatMs = Date.now();
130
+ this.emit('heartbeat', data.timestamp);
131
+ }
132
+ }
133
+ catch (err) {
134
+ logger.error({ err }, 'bridge message processing error');
135
+ }
136
+ });
137
+ ws.on('close', (code, reason) => {
138
+ logger.info({ code, reason: reason.toString() }, 'bridge client disconnected');
139
+ this.ws = null;
140
+ const prevState = this.state;
141
+ this.state = 'connecting';
142
+ this.rejectPending(new Error(`Bridge disconnected: ${reason.toString() || 'connection closed'}`));
143
+ this.emit('stateChanged', this.state, prevState);
144
+ this.emit('disconnected', reason.toString() || 'connection closed');
145
+ this.stopHeartbeat();
146
+ });
147
+ ws.on('error', (err) => {
148
+ logger.error({ err }, 'bridge client socket error');
149
+ });
46
150
  }
47
151
  async call(method, params, opts) {
48
152
  const ws = this.ws;
@@ -76,101 +180,20 @@ export class BridgeManager extends EventEmitter {
76
180
  disconnect(reason) {
77
181
  const prev = this.state;
78
182
  this.state = 'disconnected';
79
- if (this.heartbeatTimer) {
80
- clearInterval(this.heartbeatTimer);
81
- this.heartbeatTimer = null;
82
- }
83
- if (this.reconnectTimer) {
84
- clearTimeout(this.reconnectTimer);
85
- this.reconnectTimer = null;
86
- }
87
- for (const [, entry] of this.requestMap) {
88
- clearTimeout(entry.timer);
89
- entry.reject(new Error(`Bridge disconnected: ${reason ?? 'unknown'}`));
90
- }
91
- this.requestMap.clear();
183
+ this.stopHeartbeat();
184
+ this.rejectPending(new Error(`Bridge disconnected: ${reason ?? 'unknown'}`));
92
185
  if (this.ws) {
93
186
  this.ws.close();
94
187
  this.ws = null;
95
188
  }
189
+ if (this.wss) {
190
+ this.wss.close();
191
+ this.wss = null;
192
+ }
96
193
  this.hello = null;
97
194
  this.emit('stateChanged', this.state, prev);
98
195
  this.emit('disconnected', reason ?? 'unknown');
99
196
  }
100
- async tryConnect(port) {
101
- const logger = getLogger();
102
- const url = `ws://${this.config.BRIDGE_HOST}:${port}`;
103
- logger.debug({ url }, 'trying bridge connection');
104
- return new Promise((resolve, reject) => {
105
- const ws = new WebSocket(url);
106
- const timeout = setTimeout(() => {
107
- ws.close();
108
- reject(new Error(`Connection timeout for ${url}`));
109
- }, 5000);
110
- ws.onopen = () => {
111
- clearTimeout(timeout);
112
- this.ws = ws;
113
- this.sendHandshake();
114
- };
115
- ws.onmessage = (event) => {
116
- try {
117
- const data = JSON.parse(event.data);
118
- if (data.type === 'hello') {
119
- const parsed = BridgeHelloSchema.parse(data);
120
- this.handleHello(parsed, port);
121
- resolve();
122
- }
123
- else if (data.type === 'response') {
124
- this.handleResponse(data);
125
- }
126
- else if (data.type === 'heartbeat') {
127
- this._lastHeartbeatMs = Date.now();
128
- }
129
- else if (data.type === 'error') {
130
- logger.error({ data }, 'bridge error message');
131
- }
132
- }
133
- catch (err) {
134
- logger.error({ err, raw: event.data }, 'bridge message parse error');
135
- }
136
- };
137
- ws.onerror = (err) => {
138
- clearTimeout(timeout);
139
- reject(err instanceof Error ? err : new Error('WebSocket error'));
140
- };
141
- ws.onclose = () => {
142
- clearTimeout(timeout);
143
- if (this.state === 'connected') {
144
- this.disconnect('connection closed');
145
- }
146
- };
147
- });
148
- }
149
- sendHandshake() {
150
- const handshake = {
151
- type: 'handshake',
152
- protocol: 'easyeda-mcp-pro.bridge',
153
- protocolVersion: '1.0.0',
154
- clientName: 'easyeda-mcp-pro',
155
- sessionToken: this.config.BRIDGE_TOKEN || undefined,
156
- };
157
- this.ws?.send(JSON.stringify(handshake));
158
- }
159
- handleHello(hello, port) {
160
- const logger = getLogger();
161
- const prev = this.state;
162
- this.state = 'connected';
163
- this.hello = hello;
164
- logger.info({
165
- bridgeVersion: hello.bridgeVersion,
166
- easyedaVersion: hello.easyedaVersion,
167
- capabilities: hello.capabilities,
168
- port,
169
- }, 'bridge connected');
170
- this.emit('stateChanged', this.state, prev);
171
- this.emit('connected', hello);
172
- this.startHeartbeat();
173
- }
174
197
  handleResponse(data) {
175
198
  const entry = this.requestMap.get(data.id);
176
199
  if (!entry) {
@@ -187,6 +210,13 @@ export class BridgeManager extends EventEmitter {
187
210
  entry.reject(error);
188
211
  }
189
212
  }
213
+ rejectPending(error) {
214
+ for (const [, entry] of this.requestMap) {
215
+ clearTimeout(entry.timer);
216
+ entry.reject(error);
217
+ }
218
+ this.requestMap.clear();
219
+ }
190
220
  startHeartbeat() {
191
221
  if (this.heartbeatTimer)
192
222
  clearInterval(this.heartbeatTimer);
@@ -196,30 +226,51 @@ export class BridgeManager extends EventEmitter {
196
226
  this.ws.send(JSON.stringify({ type: 'heartbeat', timestamp: Date.now() }));
197
227
  }
198
228
  catch {
229
+ getLogger().warn('bridge heartbeat send failed, disconnecting');
199
230
  this.disconnect('heartbeat failed');
200
231
  }
201
232
  }
202
233
  }, this.config.BRIDGE_HEARTBEAT_MS);
203
234
  }
204
- parsePortScan() {
205
- const ports = [];
206
- const parts = this.config.BRIDGE_PORT_SCAN.split(',');
207
- for (const part of parts) {
208
- const trimmed = part.trim();
209
- if (trimmed.includes('-')) {
210
- const [start, end] = trimmed.split('-').map((s) => parseInt(s.trim(), 10));
211
- if (start && end && !isNaN(start) && !isNaN(end)) {
212
- for (let p = start; p <= end; p++)
213
- ports.push(p);
235
+ stopHeartbeat() {
236
+ if (this.heartbeatTimer) {
237
+ clearInterval(this.heartbeatTimer);
238
+ this.heartbeatTimer = null;
239
+ }
240
+ }
241
+ }
242
+ /**
243
+ * Parse a port scan specification string into an ordered array of ports.
244
+ * Supports comma-separated values and dash ranges:
245
+ * "18601" → [18601]
246
+ * "18601,49620" → [18601, 49620]
247
+ * "49620-49629" → [49620, 49621, ..., 49629]
248
+ * "18601,49620-49629" → [18601, 49620, 49621, ..., 49629]
249
+ */
250
+ export function parsePortScanSpec(spec) {
251
+ const ports = [];
252
+ const parts = spec.split(',');
253
+ for (const part of parts) {
254
+ const trimmed = part.trim();
255
+ if (!trimmed)
256
+ continue;
257
+ const rangeMatch = trimmed.match(/^(\d+)\s*-\s*(\d+)$/);
258
+ if (rangeMatch && rangeMatch[1] !== undefined && rangeMatch[2] !== undefined) {
259
+ const start = parseInt(rangeMatch[1], 10);
260
+ const end = parseInt(rangeMatch[2], 10);
261
+ if (start > 0 && end > 0 && start <= end && end <= 65535) {
262
+ for (let p = start; p <= end; p++) {
263
+ ports.push(p);
214
264
  }
215
265
  }
216
- else {
217
- const p = parseInt(trimmed, 10);
218
- if (!isNaN(p))
219
- ports.push(p);
266
+ }
267
+ else {
268
+ const port = parseInt(trimmed, 10);
269
+ if (port > 0 && port <= 65535) {
270
+ ports.push(port);
220
271
  }
221
272
  }
222
- return [...new Set(ports)].sort((a, b) => a - b);
223
273
  }
274
+ return ports;
224
275
  }
225
276
  //# sourceMappingURL=manager.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"manager.js","sourceRoot":"","sources":["../../src/bridge/manager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"manager.js","sourceRoot":"","sources":["../../src/bridge/manager.ts"],"names":[],"mappings":"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"}