devlinker 1.4.0__tar.gz → 1.4.2__tar.gz

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 (34) hide show
  1. {devlinker-1.4.0/devlinker.egg-info → devlinker-1.4.2}/PKG-INFO +189 -41
  2. {devlinker-1.4.0 → devlinker-1.4.2}/README.md +187 -40
  3. devlinker-1.4.2/devlinker/config.py +17 -0
  4. {devlinker-1.4.0 → devlinker-1.4.2}/devlinker/detector_ai.py +6 -1
  5. devlinker-1.4.2/devlinker/main.py +725 -0
  6. {devlinker-1.4.0 → devlinker-1.4.2}/devlinker/proxy.py +310 -42
  7. {devlinker-1.4.0 → devlinker-1.4.2}/devlinker/runner.py +77 -27
  8. {devlinker-1.4.0 → devlinker-1.4.2/devlinker.egg-info}/PKG-INFO +189 -41
  9. {devlinker-1.4.0 → devlinker-1.4.2}/devlinker.egg-info/requires.txt +1 -0
  10. {devlinker-1.4.0 → devlinker-1.4.2}/pyproject.toml +2 -1
  11. devlinker-1.4.0/devlinker/config.py +0 -8
  12. devlinker-1.4.0/devlinker/main.py +0 -399
  13. {devlinker-1.4.0 → devlinker-1.4.2}/LICENSE +0 -0
  14. {devlinker-1.4.0 → devlinker-1.4.2}/MANIFEST.in +0 -0
  15. {devlinker-1.4.0 → devlinker-1.4.2}/devlinker/__init__.py +0 -0
  16. {devlinker-1.4.0 → devlinker-1.4.2}/devlinker/detection_state.py +0 -0
  17. {devlinker-1.4.0 → devlinker-1.4.2}/devlinker/detector.py +0 -0
  18. {devlinker-1.4.0 → devlinker-1.4.2}/devlinker/devlinker_loader_instant.html +0 -0
  19. {devlinker-1.4.0 → devlinker-1.4.2}/devlinker/devlinker_loader_snippet.html +0 -0
  20. {devlinker-1.4.0 → devlinker-1.4.2}/devlinker/doctor.py +0 -0
  21. {devlinker-1.4.0 → devlinker-1.4.2}/devlinker/fix.py +0 -0
  22. {devlinker-1.4.0 → devlinker-1.4.2}/devlinker/fixer.py +0 -0
  23. {devlinker-1.4.0 → devlinker-1.4.2}/devlinker/global_state.py +0 -0
  24. {devlinker-1.4.0 → devlinker-1.4.2}/devlinker/inspect.py +0 -0
  25. {devlinker-1.4.0 → devlinker-1.4.2}/devlinker/logger.py +0 -0
  26. {devlinker-1.4.0 → devlinker-1.4.2}/devlinker/monitor.py +0 -0
  27. {devlinker-1.4.0 → devlinker-1.4.2}/devlinker/share.py +0 -0
  28. {devlinker-1.4.0 → devlinker-1.4.2}/devlinker/tunnel.py +0 -0
  29. {devlinker-1.4.0 → devlinker-1.4.2}/devlinker.egg-info/SOURCES.txt +0 -0
  30. {devlinker-1.4.0 → devlinker-1.4.2}/devlinker.egg-info/dependency_links.txt +0 -0
  31. {devlinker-1.4.0 → devlinker-1.4.2}/devlinker.egg-info/entry_points.txt +0 -0
  32. {devlinker-1.4.0 → devlinker-1.4.2}/devlinker.egg-info/top_level.txt +0 -0
  33. {devlinker-1.4.0 → devlinker-1.4.2}/setup.cfg +0 -0
  34. {devlinker-1.4.0 → devlinker-1.4.2}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: devlinker
3
- Version: 1.4.0
3
+ Version: 1.4.2
4
4
  Summary: A lightweight proxy that combines your frontend and backend into one link for easy development and sharing.
5
5
  Author-email: Mani <mani1028@users.noreply.github.com>
6
6
  Requires-Python: >=3.7
@@ -13,24 +13,101 @@ Requires-Dist: httpx
13
13
  Requires-Dist: pyngrok
14
14
  Requires-Dist: qrcode[pil]
15
15
  Requires-Dist: requests
16
+ Requires-Dist: rich
16
17
  Requires-Dist: uvicorn
17
18
  Requires-Dist: websockets
18
19
  Dynamic: license-file
19
20
 
20
21
  # Dev Linker
21
22
 
22
- Dev Linker runs frontend and backend dev servers, proxies both through a single local port (8000), and creates a single public URL via Cloudflare or ngrok.
23
+ Dev Linker starts your local development stack and routes frontend and backend traffic through one proxy URL, with optional LAN and public sharing.
24
+
25
+ ## ⚡ Quick Start (2 Minutes)
26
+
27
+ Install:
28
+
29
+ ```bash
30
+ pip install devlinker
31
+ ```
32
+
33
+ Run your apps:
34
+
35
+ ```bash
36
+ # Backend (example)
37
+ uvicorn main:app --reload
38
+
39
+ # Frontend (example)
40
+ npm run dev
41
+ ```
42
+
43
+ Run DevLinker:
44
+
45
+ ```bash
46
+ devlinker
47
+ ```
48
+
49
+ Open:
50
+
51
+ ```text
52
+ http://localhost:8001
53
+ ```
54
+
55
+ Done ✅
56
+
57
+ ## 🧠 How DevLinker Works
58
+
59
+ Request flow:
60
+
61
+ ```text
62
+ Browser -> DevLinker Proxy -> Frontend or Backend
63
+ ```
64
+
65
+ Routing rules:
66
+
67
+ - / routes to frontend (React/Vite)
68
+ - /api/* routes to backend (FastAPI/Flask/Node)
69
+
70
+ DevLinker acts as a smart proxy and optional tunnel layer for local, LAN, and public development links.
71
+
72
+ Architecture diagram:
73
+
74
+ ```mermaid
75
+ flowchart LR
76
+ B[Browser / Mobile] --> P[DevLinker Proxy]
77
+ P --> F[Frontend Dev Server\nVite/React]
78
+ P --> A[Backend API\nFastAPI/Flask/Node]
79
+ P --> T[Optional Tunnel\nCloudflare/ngrok]
80
+ ```
81
+
82
+ ## 🎯 Use Cases
83
+
84
+ - Test APIs and UI flows on mobile devices over WLAN
85
+ - Share local work instantly with teammates using one public URL
86
+ - Debug frontend-backend integration from a single entrypoint
87
+ - Reduce CORS/preflight issues during development
88
+
89
+ ## 🖼️ Demo & Screenshots
90
+
91
+ - Terminal startup output: add screenshot at docs/images/terminal-startup.png
92
+ - Browser app via proxy: add screenshot at docs/images/browser-proxy.png
93
+ - Public URL share demo: add screenshot at docs/images/public-url.png
23
94
 
24
95
 
25
96
  ## Features
26
97
 
27
98
  - 🚀 **Unified Dev Proxy:** Combines frontend (Vite/React) and backend (FastAPI/Flask/Node/Docker) into a single local and public URL.
28
99
  - 🔍 **Auto Detection:** Detects frontend/backend ports, runtime, Docker containers, and Vite servers automatically.
100
+ - 📡 **Debug Request Logger:** Live API traffic lines (method, path, status, latency) only in debug mode.
101
+ - 🧩 **Backend-Only Mode:** If no frontend is detected, DevLinker still runs and forwards all traffic to backend.
102
+ - 🔁 **Auto API URL Sync:** Updates `frontend/.env.local` with `VITE_API_URL=http://localhost:<proxy-port>` using a managed block.
103
+ - 🛡️ **Proxy CORS + Preflight:** Handles common CORS/preflight behavior at the proxy layer, including credential-safe Origin handling.
29
104
  - 🧠 **Smart Detection & Doctor:** Real-time request analysis, backend intelligence, log analyzer, and `devlinker doctor` for instant diagnostics.
30
105
  - 🛡️ **Auto-Fix Engine:** `devlinker fix` applies safe fixes (like VITE_API_URL) and suggests code changes.
31
106
  - 🌍 **Public Sharing:** Share your local dev environment instantly with `--url` (startup) or `devlinker share` (runtime, no restart).
32
107
  - 🔄 **Dynamic Tunnel Control:** `devlinker unshare` disables public tunnel at runtime.
33
108
  - 📡 **WLAN Sharing:** Prints LAN URL for same-network device access.
109
+ - 🔒 **Secure Token Linking:** Optional token gate for LAN/public access with `DEVLINKER_LINK_TOKEN`.
110
+ - 📊 **Browser API Logs Dashboard:** Open `/__devlinker/dashboard` for lightweight live API visibility.
34
111
  - 🧑‍💻 **Interactive CLI:** Modern, colorized, emoji-rich terminal UX for all commands.
35
112
  - 🧩 **Zero Config:** Works out-of-the-box for most FastAPI, Flask, Vite, and Docker projects.
36
113
  - 🧪 **Runtime Smoke Test:** Built-in test for end-to-end proxy validation.
@@ -62,8 +139,33 @@ If DevLinker helps you ship faster, consider supporting the project:
62
139
  - `devlinker --no-lan` — Hide WLAN sharing URL
63
140
  - `devlinker --interactive-backend` — Prompt to choose backend if multiple found
64
141
  - `devlinker --proxy-port 18000` — Use custom proxy port
142
+ - `devlinker --debug` — Enable debug mode (turns on live API request logger)
65
143
  - `devlinker --version` — Show version
66
144
 
145
+ Security token (optional):
146
+
147
+ ```bash
148
+ set DEVLINKER_LINK_TOKEN=your-secret-token
149
+ devlinker --url
150
+ ```
151
+
152
+ When enabled, LAN/public requests must include one of:
153
+ - query param `dl_token=...`
154
+ - header `X-DevLinker-Token: ...`
155
+ - header `Authorization: Bearer ...`
156
+
157
+ Built-in API logs dashboard:
158
+
159
+ ```text
160
+ http://localhost:<proxy-port>/__devlinker/dashboard
161
+ ```
162
+
163
+ JSON stream endpoint used by the dashboard:
164
+
165
+ ```text
166
+ http://localhost:<proxy-port>/__devlinker/logs
167
+ ```
168
+
67
169
  ## Project Structure
68
170
 
69
171
  ```text
@@ -88,6 +190,12 @@ For local development:
88
190
  pip install .
89
191
  ```
90
192
 
193
+ For editable local development:
194
+
195
+ ```bash
196
+ pip install -e .
197
+ ```
198
+
91
199
  After publishing to PyPI:
92
200
 
93
201
  ```bash
@@ -100,34 +208,47 @@ pip install devlinker
100
208
  devlinker
101
209
  ```
102
210
 
103
- Typical startup output:
211
+ Direct module run (without installing entrypoint script):
212
+
213
+ ```bash
214
+ python -m devlinker.main
215
+ ```
216
+
217
+ Typical startup output (TTY with Rich available):
104
218
 
105
219
  ```text
106
- Dev Linker v1.2.2
220
+ ╭─────────────────────────────╮
221
+ │ ♾️ DevLinker v1.4.1 │
222
+ │ Smart Local Dev Environment │
223
+ ╰─────────────────────────────╯
224
+
225
+ ✔ Detecting project...
226
+ ⏳ Booting local services...
227
+
228
+ ╭───────── DevLinker Ready ─────────╮
229
+ │ Proxy http://localhost:8001 │
230
+ │ WLAN http://192.168.1.3:8001 │
231
+ │ Public disabled (use --url) │
232
+ ╰───────────────────────────────────╯
233
+
234
+ ✨ Ready in 5.5s
235
+ Powered by DevLinker 🚀
236
+ ```
107
237
 
108
- [INFO] Mode: Auto (FastAPI async proxy + Docker detection)
109
- [INFO] Booting local services...
110
- [INFO] Detecting frontend/backend ports...
111
- [OK] Frontend -> 5173
112
- [OK] Backend -> 5000
238
+ Enable debug mode with live API request logging:
113
239
 
114
- [OK] Proxy ready at http://localhost:8000
240
+ ```bash
241
+ devlinker --debug
242
+ ```
115
243
 
116
- [OK] Tunnel provider: Cloudflare
117
- [OK] Public URL:
118
- https://xxxx.trycloudflare.com
119
- Tip: Press Ctrl+Click to open link
244
+ Debug mode request logger sample:
120
245
 
121
- [INFO] Share this link with collaborators.
246
+ ```text
247
+ 🛠 Debug mode enabled: live API request logger is ON
122
248
 
123
- DevLinker Ready (in 2.4s)
124
- Frontend: http://localhost:5173
125
- Backend: http://localhost:5000
126
- Access Links:
127
- Local: http://localhost:8000
128
- WLAN: http://192.168.1.5:8000
129
- Public: https://xxxx.trycloudflare.com
130
- Tip: Press Ctrl+Click to open link
249
+ 📡 Requests (Live)
250
+ GET /api/users 200 45ms
251
+ POST /api/login 401 120ms
131
252
  ```
132
253
 
133
254
  Version check:
@@ -160,15 +281,6 @@ devlinker --docker
160
281
  By default, DevLinker starts **fast local proxy only** (no tunnel). To enable a public tunnel, use the `--url` flag:
161
282
 
162
283
 
163
- ```bash
164
- devlinker --url
165
- ```
166
-
167
- In your terminal output, you'll see:
168
-
169
-
170
- URL, run:
171
-
172
284
  ```bash
173
285
  devlinker --url
174
286
  ```
@@ -177,11 +289,11 @@ This will start the proxy and open a public tunnel (Cloudflare or ngrok). The ou
177
289
 
178
290
  ```text
179
291
  🌍 Enabling public tunnel...
180
- [OK] Tunnel provider: Cloudflare
181
- [OK] Public URL:
292
+ Tunnel provider: Cloudflare
293
+ Public URL:
182
294
  https://xxxx.trycloudflare.com
183
- Tip: Press Ctrl+Click to open link
184
- [INFO] Share this link with collaborators.
295
+ Tip: Ctrl+Click to open link
296
+ Share this link with collaborators.
185
297
  ```
186
298
 
187
299
  To force tunnel off (even if --url is passed):
@@ -241,13 +353,11 @@ devlinker --frontend 5173 --backend 5000 --proxy-port 18000
241
353
  Default behavior also tries fallback ports automatically when 8000 is busy:
242
354
 
243
355
  ```text
244
- [WARN] Port 8000 in use
245
- [INFO] Using proxy port: 8001
356
+ Port 8000 in use
357
+ Using proxy port: 8001
246
358
  ```
247
359
 
248
- - 8001
249
- - 8002
250
- - 18000
360
+ By default it scans the next 10 ports after the requested one, then tries `18000`.
251
361
 
252
362
  Frontend detection behavior:
253
363
 
@@ -266,6 +376,41 @@ fetch("/api/endpoint")
266
376
 
267
377
  Do not hardcode backend host URLs in frontend code.
268
378
 
379
+ DevLinker also writes/updates a managed block in `frontend/.env.local`:
380
+
381
+ ```env
382
+ # devlinker-managed:start
383
+ VITE_API_URL=http://localhost:8001
384
+ # devlinker-managed:end
385
+ ```
386
+
387
+ This keeps frontend API calls consistently routed through the proxy.
388
+
389
+ Use the proxy URL as your single entry point during development:
390
+
391
+ ```text
392
+ http://localhost:<proxy-port>
393
+ ```
394
+
395
+ Avoid direct backend calls like `http://localhost:5000` from browser-facing code.
396
+
397
+ ## Configuration File
398
+
399
+ DevLinker loads config from the first file found in this order:
400
+
401
+ 1. `devlinker.yaml`
402
+ 2. `devlinker.yml`
403
+ 3. `devlinker.json`
404
+
405
+ Example:
406
+
407
+ ```yaml
408
+ frontend: 5173
409
+ backend: 5000
410
+ proxy_port: 8001
411
+ tunnel: false
412
+ ```
413
+
269
414
  ## Backend Auto-Detection
270
415
 
271
416
  Backend port detection runs in this order:
@@ -321,12 +466,15 @@ For containerized Flask backends, ensure:
321
466
 
322
467
  - runner.py expects frontend project in frontend and Python app in backend/app.py.
323
468
  - If those paths do not exist, Dev Linker skips launch and only tries to detect already-running services.
469
+ - If frontend is missing but backend is available, DevLinker continues in backend-only mode.
324
470
  - Tunnel selection order is: cloudflared (TryCloudflare), then ngrok.
325
471
  - If cloudflared is unavailable and ngrok is not configured, Dev Linker prints one-time setup guidance.
326
472
  - You may need to set ngrok auth once on your machine using ngrok config add-authtoken <token>.
327
473
  - Dev Linker prints a public URL with `ngrok-skip-browser-warning=true` only when ngrok is used.
328
474
  - Startup output includes selected tunnel provider (`cloudflare` or `ngrok`).
329
475
  - Proxy layer now supports WebSocket upgrades, including Vite HMR over shared links.
476
+ - Proxy handles common CORS/preflight behavior and adds camera/mic permissions policy headers.
477
+ - Live API request logging is disabled by default and only enabled with `devlinker --debug`.
330
478
  - Proxy listens on `0.0.0.0` and can print a WLAN URL for same-network sharing.
331
479
  - If WLAN access fails on Windows, allow the proxy port in firewall and confirm devices are on the same network.
332
480
 
@@ -1,17 +1,93 @@
1
1
  # Dev Linker
2
2
 
3
- Dev Linker runs frontend and backend dev servers, proxies both through a single local port (8000), and creates a single public URL via Cloudflare or ngrok.
3
+ Dev Linker starts your local development stack and routes frontend and backend traffic through one proxy URL, with optional LAN and public sharing.
4
+
5
+ ## ⚡ Quick Start (2 Minutes)
6
+
7
+ Install:
8
+
9
+ ```bash
10
+ pip install devlinker
11
+ ```
12
+
13
+ Run your apps:
14
+
15
+ ```bash
16
+ # Backend (example)
17
+ uvicorn main:app --reload
18
+
19
+ # Frontend (example)
20
+ npm run dev
21
+ ```
22
+
23
+ Run DevLinker:
24
+
25
+ ```bash
26
+ devlinker
27
+ ```
28
+
29
+ Open:
30
+
31
+ ```text
32
+ http://localhost:8001
33
+ ```
34
+
35
+ Done ✅
36
+
37
+ ## 🧠 How DevLinker Works
38
+
39
+ Request flow:
40
+
41
+ ```text
42
+ Browser -> DevLinker Proxy -> Frontend or Backend
43
+ ```
44
+
45
+ Routing rules:
46
+
47
+ - / routes to frontend (React/Vite)
48
+ - /api/* routes to backend (FastAPI/Flask/Node)
49
+
50
+ DevLinker acts as a smart proxy and optional tunnel layer for local, LAN, and public development links.
51
+
52
+ Architecture diagram:
53
+
54
+ ```mermaid
55
+ flowchart LR
56
+ B[Browser / Mobile] --> P[DevLinker Proxy]
57
+ P --> F[Frontend Dev Server\nVite/React]
58
+ P --> A[Backend API\nFastAPI/Flask/Node]
59
+ P --> T[Optional Tunnel\nCloudflare/ngrok]
60
+ ```
61
+
62
+ ## 🎯 Use Cases
63
+
64
+ - Test APIs and UI flows on mobile devices over WLAN
65
+ - Share local work instantly with teammates using one public URL
66
+ - Debug frontend-backend integration from a single entrypoint
67
+ - Reduce CORS/preflight issues during development
68
+
69
+ ## 🖼️ Demo & Screenshots
70
+
71
+ - Terminal startup output: add screenshot at docs/images/terminal-startup.png
72
+ - Browser app via proxy: add screenshot at docs/images/browser-proxy.png
73
+ - Public URL share demo: add screenshot at docs/images/public-url.png
4
74
 
5
75
 
6
76
  ## Features
7
77
 
8
78
  - 🚀 **Unified Dev Proxy:** Combines frontend (Vite/React) and backend (FastAPI/Flask/Node/Docker) into a single local and public URL.
9
79
  - 🔍 **Auto Detection:** Detects frontend/backend ports, runtime, Docker containers, and Vite servers automatically.
80
+ - 📡 **Debug Request Logger:** Live API traffic lines (method, path, status, latency) only in debug mode.
81
+ - 🧩 **Backend-Only Mode:** If no frontend is detected, DevLinker still runs and forwards all traffic to backend.
82
+ - 🔁 **Auto API URL Sync:** Updates `frontend/.env.local` with `VITE_API_URL=http://localhost:<proxy-port>` using a managed block.
83
+ - 🛡️ **Proxy CORS + Preflight:** Handles common CORS/preflight behavior at the proxy layer, including credential-safe Origin handling.
10
84
  - 🧠 **Smart Detection & Doctor:** Real-time request analysis, backend intelligence, log analyzer, and `devlinker doctor` for instant diagnostics.
11
85
  - 🛡️ **Auto-Fix Engine:** `devlinker fix` applies safe fixes (like VITE_API_URL) and suggests code changes.
12
86
  - 🌍 **Public Sharing:** Share your local dev environment instantly with `--url` (startup) or `devlinker share` (runtime, no restart).
13
87
  - 🔄 **Dynamic Tunnel Control:** `devlinker unshare` disables public tunnel at runtime.
14
88
  - 📡 **WLAN Sharing:** Prints LAN URL for same-network device access.
89
+ - 🔒 **Secure Token Linking:** Optional token gate for LAN/public access with `DEVLINKER_LINK_TOKEN`.
90
+ - 📊 **Browser API Logs Dashboard:** Open `/__devlinker/dashboard` for lightweight live API visibility.
15
91
  - 🧑‍💻 **Interactive CLI:** Modern, colorized, emoji-rich terminal UX for all commands.
16
92
  - 🧩 **Zero Config:** Works out-of-the-box for most FastAPI, Flask, Vite, and Docker projects.
17
93
  - 🧪 **Runtime Smoke Test:** Built-in test for end-to-end proxy validation.
@@ -43,8 +119,33 @@ If DevLinker helps you ship faster, consider supporting the project:
43
119
  - `devlinker --no-lan` — Hide WLAN sharing URL
44
120
  - `devlinker --interactive-backend` — Prompt to choose backend if multiple found
45
121
  - `devlinker --proxy-port 18000` — Use custom proxy port
122
+ - `devlinker --debug` — Enable debug mode (turns on live API request logger)
46
123
  - `devlinker --version` — Show version
47
124
 
125
+ Security token (optional):
126
+
127
+ ```bash
128
+ set DEVLINKER_LINK_TOKEN=your-secret-token
129
+ devlinker --url
130
+ ```
131
+
132
+ When enabled, LAN/public requests must include one of:
133
+ - query param `dl_token=...`
134
+ - header `X-DevLinker-Token: ...`
135
+ - header `Authorization: Bearer ...`
136
+
137
+ Built-in API logs dashboard:
138
+
139
+ ```text
140
+ http://localhost:<proxy-port>/__devlinker/dashboard
141
+ ```
142
+
143
+ JSON stream endpoint used by the dashboard:
144
+
145
+ ```text
146
+ http://localhost:<proxy-port>/__devlinker/logs
147
+ ```
148
+
48
149
  ## Project Structure
49
150
 
50
151
  ```text
@@ -69,6 +170,12 @@ For local development:
69
170
  pip install .
70
171
  ```
71
172
 
173
+ For editable local development:
174
+
175
+ ```bash
176
+ pip install -e .
177
+ ```
178
+
72
179
  After publishing to PyPI:
73
180
 
74
181
  ```bash
@@ -81,34 +188,47 @@ pip install devlinker
81
188
  devlinker
82
189
  ```
83
190
 
84
- Typical startup output:
191
+ Direct module run (without installing entrypoint script):
192
+
193
+ ```bash
194
+ python -m devlinker.main
195
+ ```
196
+
197
+ Typical startup output (TTY with Rich available):
85
198
 
86
199
  ```text
87
- Dev Linker v1.2.2
200
+ ╭─────────────────────────────╮
201
+ │ ♾️ DevLinker v1.4.1 │
202
+ │ Smart Local Dev Environment │
203
+ ╰─────────────────────────────╯
204
+
205
+ ✔ Detecting project...
206
+ ⏳ Booting local services...
207
+
208
+ ╭───────── DevLinker Ready ─────────╮
209
+ │ Proxy http://localhost:8001 │
210
+ │ WLAN http://192.168.1.3:8001 │
211
+ │ Public disabled (use --url) │
212
+ ╰───────────────────────────────────╯
213
+
214
+ ✨ Ready in 5.5s
215
+ Powered by DevLinker 🚀
216
+ ```
88
217
 
89
- [INFO] Mode: Auto (FastAPI async proxy + Docker detection)
90
- [INFO] Booting local services...
91
- [INFO] Detecting frontend/backend ports...
92
- [OK] Frontend -> 5173
93
- [OK] Backend -> 5000
218
+ Enable debug mode with live API request logging:
94
219
 
95
- [OK] Proxy ready at http://localhost:8000
220
+ ```bash
221
+ devlinker --debug
222
+ ```
96
223
 
97
- [OK] Tunnel provider: Cloudflare
98
- [OK] Public URL:
99
- https://xxxx.trycloudflare.com
100
- Tip: Press Ctrl+Click to open link
224
+ Debug mode request logger sample:
101
225
 
102
- [INFO] Share this link with collaborators.
226
+ ```text
227
+ 🛠 Debug mode enabled: live API request logger is ON
103
228
 
104
- DevLinker Ready (in 2.4s)
105
- Frontend: http://localhost:5173
106
- Backend: http://localhost:5000
107
- Access Links:
108
- Local: http://localhost:8000
109
- WLAN: http://192.168.1.5:8000
110
- Public: https://xxxx.trycloudflare.com
111
- Tip: Press Ctrl+Click to open link
229
+ 📡 Requests (Live)
230
+ GET /api/users 200 45ms
231
+ POST /api/login 401 120ms
112
232
  ```
113
233
 
114
234
  Version check:
@@ -141,15 +261,6 @@ devlinker --docker
141
261
  By default, DevLinker starts **fast local proxy only** (no tunnel). To enable a public tunnel, use the `--url` flag:
142
262
 
143
263
 
144
- ```bash
145
- devlinker --url
146
- ```
147
-
148
- In your terminal output, you'll see:
149
-
150
-
151
- URL, run:
152
-
153
264
  ```bash
154
265
  devlinker --url
155
266
  ```
@@ -158,11 +269,11 @@ This will start the proxy and open a public tunnel (Cloudflare or ngrok). The ou
158
269
 
159
270
  ```text
160
271
  🌍 Enabling public tunnel...
161
- [OK] Tunnel provider: Cloudflare
162
- [OK] Public URL:
272
+ Tunnel provider: Cloudflare
273
+ Public URL:
163
274
  https://xxxx.trycloudflare.com
164
- Tip: Press Ctrl+Click to open link
165
- [INFO] Share this link with collaborators.
275
+ Tip: Ctrl+Click to open link
276
+ Share this link with collaborators.
166
277
  ```
167
278
 
168
279
  To force tunnel off (even if --url is passed):
@@ -222,13 +333,11 @@ devlinker --frontend 5173 --backend 5000 --proxy-port 18000
222
333
  Default behavior also tries fallback ports automatically when 8000 is busy:
223
334
 
224
335
  ```text
225
- [WARN] Port 8000 in use
226
- [INFO] Using proxy port: 8001
336
+ Port 8000 in use
337
+ Using proxy port: 8001
227
338
  ```
228
339
 
229
- - 8001
230
- - 8002
231
- - 18000
340
+ By default it scans the next 10 ports after the requested one, then tries `18000`.
232
341
 
233
342
  Frontend detection behavior:
234
343
 
@@ -247,6 +356,41 @@ fetch("/api/endpoint")
247
356
 
248
357
  Do not hardcode backend host URLs in frontend code.
249
358
 
359
+ DevLinker also writes/updates a managed block in `frontend/.env.local`:
360
+
361
+ ```env
362
+ # devlinker-managed:start
363
+ VITE_API_URL=http://localhost:8001
364
+ # devlinker-managed:end
365
+ ```
366
+
367
+ This keeps frontend API calls consistently routed through the proxy.
368
+
369
+ Use the proxy URL as your single entry point during development:
370
+
371
+ ```text
372
+ http://localhost:<proxy-port>
373
+ ```
374
+
375
+ Avoid direct backend calls like `http://localhost:5000` from browser-facing code.
376
+
377
+ ## Configuration File
378
+
379
+ DevLinker loads config from the first file found in this order:
380
+
381
+ 1. `devlinker.yaml`
382
+ 2. `devlinker.yml`
383
+ 3. `devlinker.json`
384
+
385
+ Example:
386
+
387
+ ```yaml
388
+ frontend: 5173
389
+ backend: 5000
390
+ proxy_port: 8001
391
+ tunnel: false
392
+ ```
393
+
250
394
  ## Backend Auto-Detection
251
395
 
252
396
  Backend port detection runs in this order:
@@ -302,12 +446,15 @@ For containerized Flask backends, ensure:
302
446
 
303
447
  - runner.py expects frontend project in frontend and Python app in backend/app.py.
304
448
  - If those paths do not exist, Dev Linker skips launch and only tries to detect already-running services.
449
+ - If frontend is missing but backend is available, DevLinker continues in backend-only mode.
305
450
  - Tunnel selection order is: cloudflared (TryCloudflare), then ngrok.
306
451
  - If cloudflared is unavailable and ngrok is not configured, Dev Linker prints one-time setup guidance.
307
452
  - You may need to set ngrok auth once on your machine using ngrok config add-authtoken <token>.
308
453
  - Dev Linker prints a public URL with `ngrok-skip-browser-warning=true` only when ngrok is used.
309
454
  - Startup output includes selected tunnel provider (`cloudflare` or `ngrok`).
310
455
  - Proxy layer now supports WebSocket upgrades, including Vite HMR over shared links.
456
+ - Proxy handles common CORS/preflight behavior and adds camera/mic permissions policy headers.
457
+ - Live API request logging is disabled by default and only enabled with `devlinker --debug`.
311
458
  - Proxy listens on `0.0.0.0` and can print a WLAN URL for same-network sharing.
312
459
  - If WLAN access fails on Windows, allow the proxy port in firewall and confirm devices are on the same network.
313
460
 
@@ -0,0 +1,17 @@
1
+ import os
2
+ import json
3
+
4
+ import yaml
5
+
6
+ def load_config(config_path: str = "devlinker.yaml") -> dict:
7
+ candidates = [config_path, "devlinker.yml", "devlinker.json"]
8
+ selected = next((path for path in candidates if os.path.exists(path)), None)
9
+ if not selected:
10
+ return {}
11
+
12
+ with open(selected, "r", encoding="utf-8") as handle:
13
+ if selected.endswith(".json"):
14
+ data = json.load(handle)
15
+ else:
16
+ data = yaml.safe_load(handle)
17
+ return data or {}
@@ -1,16 +1,21 @@
1
1
  class DevLinkerAI:
2
2
  def analyze_failure(self, error_text):
3
+ lowered = error_text.lower()
3
4
  if "CORS" in error_text:
4
5
  return [
5
6
  "Frontend is calling backend directly",
6
7
  "Use /api/* instead of localhost:PORT"
7
8
  ]
8
9
  if "404" in error_text:
10
+ if " get / " in lowered or lowered.strip().startswith("get /"):
11
+ return []
12
+ if "/api" not in lowered:
13
+ return ["Route not found"]
9
14
  return [
10
15
  "Route not found",
11
16
  "Check if '/api' prefix is required"
12
17
  ]
13
- if "connection refused" in error_text.lower():
18
+ if "connection refused" in lowered:
14
19
  return [
15
20
  "Backend not reachable",
16
21
  "Ensure backend is running"