codetraxis 1.0.0 → 1.0.2
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.
- package/README.md +30 -183
- package/client/dist/assets/{index-BMv7qJps.js → index-DxucfvnK.js} +1 -1
- package/client/dist/index.html +1 -1
- package/codetraxisAgent/index.ts +171 -0
- package/codetraxisAgent/interceptors/consoleInterceptor.ts +33 -0
- package/codetraxisAgent/interceptors/fetchInterceptor.ts +93 -0
- package/codetraxisAgent/interceptors/xhrInterceptor.ts +88 -0
- package/codetraxisAgent/shared.ts +97 -0
- package/package.json +3 -2
- package/server/dist/utils/agent/agentInstaller.js +177 -519
package/README.md
CHANGED
|
@@ -14,33 +14,19 @@ Open **http://localhost:3333** — that's it.
|
|
|
14
14
|
|
|
15
15
|
---
|
|
16
16
|
|
|
17
|
-
##
|
|
17
|
+
## 🚀 Features
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
---
|
|
28
|
-
|
|
29
|
-
## Features
|
|
30
|
-
|
|
31
|
-
| | Feature | Description |
|
|
32
|
-
|---|---|---|
|
|
33
|
-
| 📁 | **Live file tree** | Browse your project in real time — respects `.gitignore` |
|
|
34
|
-
| 🧾 | **Code viewer** | Monaco-based syntax-highlighted file viewer |
|
|
35
|
-
| 🌐 | **Network inspector** | `fetch` / `axios` / `XHR` — method, URL, status, body, headers, duration |
|
|
36
|
-
| 🧠 | **Console timeline** | `log` / `info` / `warn` / `error` — persistent, in order |
|
|
37
|
-
| ⚡ | **Real-time updates** | File changes pushed via WebSocket — no refresh needed |
|
|
38
|
-
| 🔌 | **Any project** | React, React Native, Next.js, Expo, Vite, CRA, plain Node |
|
|
39
|
-
| 🔒 | **100% local** | Bound to `127.0.0.1` — no data ever leaves your machine |
|
|
19
|
+
* 📁 **Live file tree**: Browse your project in real time — respects `.gitignore`.
|
|
20
|
+
* 🧾 **Code viewer**: Monaco-based syntax-highlighted file viewer.
|
|
21
|
+
* 🌐 **Network inspector**: `fetch` / `axios` / `XHR` — method, URL, status, body, headers, duration.
|
|
22
|
+
* 🧠 **Console timeline**: `log` / `info` / `warn` / `error` — persistent, in order.
|
|
23
|
+
* ⚡ **Real-time updates**: File changes pushed via WebSocket — no refresh needed.
|
|
24
|
+
* 🔌 **Any project**: React, React Native, Next.js, Expo, Vite, CRA, plain Node.
|
|
25
|
+
* 🔒 **100% local**: Bound to `127.0.0.1` — no data ever leaves your machine.
|
|
40
26
|
|
|
41
27
|
---
|
|
42
28
|
|
|
43
|
-
## Quick start
|
|
29
|
+
## 📦 Quick start
|
|
44
30
|
|
|
45
31
|
```bash
|
|
46
32
|
# No install needed
|
|
@@ -50,66 +36,24 @@ npx codetraxis .
|
|
|
50
36
|
npm install -g codetraxis
|
|
51
37
|
codetraxis .
|
|
52
38
|
|
|
53
|
-
#
|
|
39
|
+
# Specific project
|
|
54
40
|
codetraxis ~/projects/my-app
|
|
55
41
|
|
|
56
42
|
# Custom port
|
|
57
43
|
PORT=4000 codetraxis .
|
|
58
44
|
```
|
|
59
45
|
|
|
60
|
-
Opens **`http://localhost:3333`** automatically.
|
|
61
|
-
|
|
62
|
-
---
|
|
63
|
-
|
|
64
|
-
## How it works
|
|
65
|
-
|
|
66
|
-
```
|
|
67
|
-
Your App (React / React Native / Next.js / Expo / etc.)
|
|
68
|
-
│
|
|
69
|
-
│ codetraxisAgent ← auto-injected into your entry file
|
|
70
|
-
│ intercepts: console.* · fetch · axios · XMLHttpRequest
|
|
71
|
-
│ sends events over WebSocket
|
|
72
|
-
▼
|
|
73
|
-
codetraxis server (Express + WS, 127.0.0.1:3333)
|
|
74
|
-
│ serves the browser UI as static files
|
|
75
|
-
│ exposes REST API + WebSocket endpoints
|
|
76
|
-
│ watches your project for file changes
|
|
77
|
-
▼
|
|
78
|
-
Browser → http://localhost:3333
|
|
79
|
-
file tree · code viewer · network inspector · console timeline
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
---
|
|
83
|
-
|
|
84
|
-
## CLI flags
|
|
85
|
-
|
|
86
|
-
| Flag | Description |
|
|
87
|
-
|---|---|
|
|
88
|
-
| `[path]` | Target project directory (default: current dir) |
|
|
89
|
-
| `--dev` | Dev mode — starts `ts-node-dev` + Vite dev server separately |
|
|
90
|
-
| `--help` | Show usage |
|
|
91
|
-
| `PORT=XXXX` | Override default port `3333` via env var |
|
|
92
|
-
|
|
93
|
-
If port `3333` is busy, codetraxis automatically finds the next available port.
|
|
94
|
-
|
|
95
|
-
If `server/dist` is missing, codetraxis runs `npm run build` automatically before starting.
|
|
96
|
-
|
|
97
46
|
---
|
|
98
47
|
|
|
99
|
-
##
|
|
100
|
-
|
|
101
|
-
Click **Install Agent** in the UI — codetraxis automatically injects a lightweight agent into your project's entry file.
|
|
48
|
+
## 🛠 How it works
|
|
102
49
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
- `XMLHttpRequest` (axios / RN networking)
|
|
107
|
-
|
|
108
|
-
All events are sent over WebSocket and shown in real time.
|
|
50
|
+
1. **Start the server**: Run `codetraxis` in your terminal. It spins up a local UI on port 3333.
|
|
51
|
+
2. **Install the Agent**: Click **Install Agent** in the UI. A lightweight agent (`codetraxisAgent`) is safely injected into your project's entry file.
|
|
52
|
+
3. **Debug**: The agent intercepts `console.*`, `fetch`, and `XMLHttpRequest` and sends events via WebSocket directly to your codetraxis dashboard.
|
|
109
53
|
|
|
110
54
|
**Manual axios attachment** (for `axios.create()` instances):
|
|
111
55
|
|
|
112
|
-
```
|
|
56
|
+
```typescript
|
|
113
57
|
import { attachAxios } from "./codetraxisAgent";
|
|
114
58
|
|
|
115
59
|
attachAxios(myAxiosInstance);
|
|
@@ -117,128 +61,31 @@ attachAxios(myAxiosInstance);
|
|
|
117
61
|
|
|
118
62
|
---
|
|
119
63
|
|
|
120
|
-
##
|
|
121
|
-
|
|
122
|
-
```
|
|
123
|
-
ConsoleEvent { type: "console", level: "log"|"info"|"warn"|"error", args[] }
|
|
124
|
-
NetworkEvent { type: "network", transport: "fetch"|"xhr"|"axios",
|
|
125
|
-
method, url, status, requestBody, responseBody, headers,
|
|
126
|
-
duration, state: "pending"|"success"|"error" }
|
|
127
|
-
```
|
|
128
|
-
|
|
129
|
-
---
|
|
130
|
-
|
|
131
|
-
## WebSocket endpoints
|
|
132
|
-
|
|
133
|
-
| Path | Purpose |
|
|
134
|
-
|---|---|
|
|
135
|
-
| `/agent` | Target app agent sends events here |
|
|
136
|
-
| `/debug` | Browser viewer receives relayed events |
|
|
137
|
-
| `/ws` | File watcher — `tree_changed` / `file_changed` |
|
|
138
|
-
|
|
139
|
-
---
|
|
140
|
-
|
|
141
|
-
## Security
|
|
142
|
-
|
|
143
|
-
codetraxis runs **fully locally** — no data ever leaves your machine.
|
|
64
|
+
## ⚙️ CLI Flags
|
|
144
65
|
|
|
145
|
-
|
|
|
146
|
-
|---|---|
|
|
147
|
-
| Server bind | `127.0.0.1` only — not reachable from other machines |
|
|
148
|
-
| CORS | Localhost origins only — external origins are blocked |
|
|
149
|
-
| File access | Only within the directory you pass as argument |
|
|
150
|
-
| On install | Nothing runs — no `postinstall` script |
|
|
151
|
-
| Telemetry | None. Zero. |
|
|
152
|
-
|
|
153
|
-
---
|
|
154
|
-
|
|
155
|
-
## Common issues
|
|
156
|
-
|
|
157
|
-
| Issue | Fix |
|
|
66
|
+
| Flag | Description |
|
|
158
67
|
|---|---|
|
|
159
|
-
|
|
|
160
|
-
| `
|
|
161
|
-
|
|
|
162
|
-
|
|
|
68
|
+
| `[path]` | Target project directory (default: current dir) |
|
|
69
|
+
| `--dev` | Dev mode — starts `ts-node-dev` + Vite dev server separately |
|
|
70
|
+
| `--help` | Show usage |
|
|
71
|
+
| `PORT=XXXX` | Override default port `3333` via env var |
|
|
163
72
|
|
|
164
73
|
---
|
|
165
74
|
|
|
166
|
-
##
|
|
167
|
-
|
|
168
|
-
```bash
|
|
169
|
-
# Build everything (server TS → JS + Vite → static)
|
|
170
|
-
npm run build
|
|
171
|
-
|
|
172
|
-
# Test locally as a real user would
|
|
173
|
-
npm link
|
|
174
|
-
codetraxis /path/to/some-project
|
|
75
|
+
## 🔒 Security
|
|
175
76
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
npm publish
|
|
181
|
-
```
|
|
182
|
-
|
|
183
|
-
### What gets published
|
|
184
|
-
|
|
185
|
-
```
|
|
186
|
-
bin/ ← CLI entry point
|
|
187
|
-
server/dist/ ← Compiled server JS
|
|
188
|
-
client/dist/ ← Built React app (static)
|
|
189
|
-
```
|
|
190
|
-
|
|
191
|
-
Source files (`src/`, `tsconfig`, `.env`, `node_modules`) are **never** included.
|
|
77
|
+
codetraxis runs fully locally.
|
|
78
|
+
* **Server bind**: `127.0.0.1` only. Not reachable from external networks.
|
|
79
|
+
* **File access**: Restricted to the target directory.
|
|
80
|
+
* **Telemetry**: Zero. No data is collected or sent anywhere.
|
|
192
81
|
|
|
193
82
|
---
|
|
194
83
|
|
|
195
|
-
##
|
|
84
|
+
## ❓ Common issues
|
|
196
85
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
server/src/
|
|
202
|
-
index.ts ← HTTP server, routes, serves client/dist, starts watcher
|
|
203
|
-
routes/
|
|
204
|
-
tree.route.ts ← GET /api/tree
|
|
205
|
-
file.route.ts ← GET /api/file
|
|
206
|
-
agent.route.ts ← POST/DELETE /api/agent
|
|
207
|
-
utils/
|
|
208
|
-
agent/
|
|
209
|
-
agentInstaller.ts ← Detects project type, injects codetraxisAgent
|
|
210
|
-
debugHub.ts ← WS relay: /agent (target) ↔ /debug (viewer)
|
|
211
|
-
watcher/
|
|
212
|
-
watcherService.ts ← chokidar → broadcasts tree_changed / file_changed
|
|
213
|
-
gitignoreWatcher.ts ← Reloads .gitignore rules on change
|
|
214
|
-
file/
|
|
215
|
-
buildTree.ts ← File tree JSON, respects .gitignore
|
|
216
|
-
gitignoreLoader.ts ← Parses .gitignore patterns
|
|
217
|
-
git/
|
|
218
|
-
getGitStatus.ts ← Git status decorations
|
|
219
|
-
|
|
220
|
-
client/src/
|
|
221
|
-
pages/home/Home.tsx ← Root layout
|
|
222
|
-
components/home/
|
|
223
|
-
leftMenu/ ← Icon sidebar
|
|
224
|
-
leftContentTree/ ← File tree panel
|
|
225
|
-
fileViewer/ ← Monaco code viewer + preview
|
|
226
|
-
debugPanel/ ← Network & console timeline
|
|
227
|
-
components/
|
|
228
|
-
TypesPanel/ ← Generate TS interfaces from JSON responses
|
|
229
|
-
NetworkExpanded/ ← Expanded network event view
|
|
230
|
-
ConsoleExpanded/ ← Expanded console event view
|
|
231
|
-
topMenu/ ← Project path + agent controls
|
|
232
|
-
addAgentModal/ ← Agent install modal
|
|
233
|
-
removeAgentModal/ ← Agent uninstall modal
|
|
234
|
-
redux/
|
|
235
|
-
treeSlice/ ← File tree state
|
|
236
|
-
fileSlice/ ← Open file state
|
|
237
|
-
debugSlice/ ← Debug events (max 500, upsert by id)
|
|
238
|
-
hooks/
|
|
239
|
-
useDebugSocket.ts ← ws://host/debug → Redux
|
|
240
|
-
useProjectWatcher.ts ← ws://host/ws → reload tree
|
|
241
|
-
```
|
|
86
|
+
* **White screen in browser?** Ensure you are running the latest version.
|
|
87
|
+
* **Port already in use?** codetraxis will automatically pick the next available port.
|
|
88
|
+
* **Permission denied?** Run `chmod +x bin/cli.js`.
|
|
242
89
|
|
|
243
90
|
---
|
|
244
91
|
|
|
@@ -190,4 +190,4 @@ ${a.join(`
|
|
|
190
190
|
`)}
|
|
191
191
|
}`;return n.set(s,i),s}return"unknown"}function zt(e,t="Root"){if(typeof e!="object"||e===null)return"// Not a JSON object or array";const n=new Map;if(Array.isArray(e)){const s=e.find(a=>a!==null)??e[0];if(typeof s=="object"&&s!==null&&!Array.isArray(s)){ne(s,t,n,0);const a=n.get(t);a&&n.set(t,a)}else return`type ${t} = ${ne(e,t,n,0)};`}else ne(e,t,n,0);return Array.from(n.values()).reverse().join(`
|
|
192
192
|
|
|
193
|
-
`)}const ma="_urlInline_2pclv_1",fa="_urlInlineBtns_2pclv_10",ga="_urlInlineBtn_2pclv_10",ya="_urlInlineBtnActive_2pclv_39",xa="_urlPreviewImg_2pclv_45",_a="_urlPreviewIframe_2pclv_54",K={urlInline:ma,urlInlineBtns:fa,urlInlineBtn:ga,urlInlineBtnActive:ya,urlPreviewImg:xa,urlPreviewIframe:_a},va=({url:e})=>{const t=/\.(png|jpe?g|gif|webp|svg|avif)(\?|$)/i.test(e),[n,o]=c.useState(!1),s=i=>{i.stopPropagation(),window.open(e,"_blank","noopener,noreferrer")},a=i=>{i.stopPropagation(),o(l=>!l)};return r.jsxs("span",{className:K.urlInline,children:[r.jsxs("span",{className:K.urlInlineBtns,children:[r.jsxs("button",{className:K.urlInlineBtn,onClick:s,title:"Open in new tab",children:[r.jsxs("svg",{width:"11",height:"11",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round",children:[r.jsx("path",{d:"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"}),r.jsx("polyline",{points:"15 3 21 3 21 9"}),r.jsx("line",{x1:"10",y1:"14",x2:"21",y2:"3"})]}),"open"]}),r.jsxs("button",{className:`${K.urlInlineBtn} ${n?K.urlInlineBtnActive:""}`,onClick:a,title:n?"Hide preview":"Show preview",children:[n?r.jsxs("svg",{width:"11",height:"11",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round",children:[r.jsx("path",{d:"M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94"}),r.jsx("path",{d:"M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19"}),r.jsx("line",{x1:"1",y1:"1",x2:"23",y2:"23"})]}):r.jsxs("svg",{width:"11",height:"11",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round",children:[r.jsx("path",{d:"M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"}),r.jsx("circle",{cx:"12",cy:"12",r:"3"})]}),n?"hide":"show"]})]}),n&&(t?r.jsx("img",{src:e,alt:"preview",className:K.urlPreviewImg,onClick:i=>i.stopPropagation()}):r.jsx("iframe",{src:e,title:"preview",className:K.urlPreviewIframe,sandbox:"allow-scripts allow-same-origin allow-forms"}))]})},ba="_pre_1m1q3_1",wa={pre:ba},$e=({value:e})=>{const t=_e(e);return t?r.jsx(qe,{value:t,style:{...tn,background:"transparent",fontSize:14,fontFamily:"inherit",lineHeight:1.7,"--w-rjv-color":"#a7a7a7","--w-rjv-key-string":"#7587a6","--w-rjv-type-string-color":"#8f9d6a","--w-rjv-type-int-color":"#cda869","--w-rjv-type-float-color":"#cda869","--w-rjv-type-boolean-color":"#cda869","--w-rjv-type-null-color":"#cf6a4c","--w-rjv-curlybraces-color":"#838184","--w-rjv-brackets-color":"#838184","--w-rjv-colon-color":"#838184","--w-rjv-copied-color":"#8f9d6a","--w-rjv-copied-success-color":"#8f9d6a","--w-rjv-background-color":"transparent"},collapsed:1,displayDataTypes:!1,displayObjectSize:!0,enableClipboard:!0,indentWidth:20,children:r.jsx(qe.String,{render:(n,{type:o,value:s})=>{if(o==="value"&&Ys(s)){const{children:a,...i}=n;return r.jsxs("span",{...i,style:{...i.style,display:"inline-flex",alignItems:"center",gap:4,flexWrap:"wrap"},children:[a,r.jsx(va,{url:s})]})}}})}):r.jsx("pre",{className:wa.pre,children:String(e??"—")})},ja="_headersTable_1c6e1_1",ka="_headerKey_1c6e1_15",Ca="_headerVal_1c6e1_24",Sa="_noData_1c6e1_31",pe={headersTable:ja,headerKey:ka,headerVal:Ca,noData:Sa},dt=({headers:e})=>!e||Object.keys(e).length===0?r.jsx("span",{className:pe.noData,children:"No headers captured"}):r.jsx("table",{className:pe.headersTable,children:r.jsx("tbody",{children:Object.entries(e).map(([t,n])=>r.jsxs("tr",{children:[r.jsx("td",{className:pe.headerKey,children:t}),r.jsx("td",{className:pe.headerVal,children:n})]},t))})}),Ra="_copyBtn_290t0_1",Ea="_copyBtnDone_290t0_23",ut={copyBtn:Ra,copyBtnDone:Ea},Na=({text:e})=>{const[t,n]=c.useState(!1);if(!e)return null;const o=s=>{s.stopPropagation(),navigator.clipboard.writeText(e).then(()=>{n(!0),setTimeout(()=>n(!1),2e3)})};return r.jsx("button",{className:`${ut.copyBtn} ${t?ut.copyBtnDone:""}`,onClick:o,title:"Copy to clipboard",children:t?r.jsxs(r.Fragment,{children:[r.jsx("svg",{width:"13",height:"13",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round",children:r.jsx("polyline",{points:"20 6 9 17 4 12"})}),"Copied"]}):r.jsxs(r.Fragment,{children:[r.jsxs("svg",{width:"13",height:"13",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[r.jsx("rect",{x:"9",y:"9",width:"13",height:"13",rx:"2",ry:"2"}),r.jsx("path",{d:"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"})]}),"Copy"]})})},La="_genBtn_i8cke_1",Ba="_genBtnActive_i8cke_23",pt={genBtn:La,genBtnActive:Ba},$a=({disabled:e,active:t,onClick:n})=>e?null:r.jsxs("button",{className:[pt.genBtn,t?pt.genBtnActive:""].filter(Boolean).join(" "),onClick:n,title:"Generate TypeScript types",children:[r.jsxs("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[r.jsx("polyline",{points:"16 18 22 12 16 6"}),r.jsx("polyline",{points:"8 6 2 12 8 18"})]}),"types"]}),Pa="_overlay_1n3zm_1",Ta="_panel_1n3zm_10",Aa="_resizeHandle_1n3zm_25",Ia="_header_1n3zm_62",Da="_title_1n3zm_73",Ma="_titleBadge_1n3zm_84",Wa="_headerActions_1n3zm_96",Oa="_iconBtn_1n3zm_102",Fa="_iconBtnClose_1n3zm_119",Ha="_copyDone_1n3zm_124",za="_tabs_1n3zm_129",Ua="_tab_1n3zm_129",qa="_tabActive_1n3zm_153",Va="_editorWrap_1n3zm_160",Ga="_customTab_1n3zm_192",Ja="_customSection_1n3zm_201",Ka="_customSectionLabel_1n3zm_213",Xa="_customEditorWrap_1n3zm_224",Ya="_customError_1n3zm_232",Za="_customActions_1n3zm_240",Qa="_genBtn_1n3zm_248",w={overlay:Pa,panel:Ta,resizeHandle:Aa,header:Ia,title:Da,titleBadge:Ma,headerActions:Wa,iconBtn:Oa,iconBtnClose:Fa,copyDone:Ha,tabs:za,tab:Ua,tabActive:qa,editorWrap:Va,customTab:Ga,customSection:Ja,customSectionLabel:Ka,customEditorWrap:Xa,customError:Ya,customActions:Za,genBtn:Qa},Ee={minimap:{enabled:!1},scrollBeyondLastLine:!1,fontSize:13,lineHeight:22,fontFamily:'"Fira Code", "SF Mono", "Consolas", monospace',fontLigatures:!0,readOnly:!1,wordWrap:"on",padding:{top:16,bottom:16},lineNumbers:"off",folding:!0,glyphMargin:!1,renderLineHighlight:"none",scrollbar:{verticalScrollbarSize:6,horizontalScrollbarSize:6},overviewRulerLanes:0},Ut=({code:e="",initialTab:t="generated",onClose:n})=>{const[o,s]=c.useState(t),[a,i]=c.useState(!1),l=c.useRef(null),[d,u]=c.useState(480),p=j=>{var ie;j.preventDefault();const B=j.clientX,q=((ie=l.current)==null?void 0:ie.offsetWidth)??d,V=we=>{const le=B-we.clientX,ce=Math.min(Math.max(q+le,280),window.innerWidth*.9);u(ce)},Y=()=>{window.removeEventListener("mousemove",V),window.removeEventListener("mouseup",Y)};window.addEventListener("mousemove",V),window.addEventListener("mouseup",Y)},[h,m]=c.useState(e),[x,_]=c.useState(""),[f,y]=c.useState(null),[g,b]=c.useState(null);c.useEffect(()=>{m(e)},[e]),c.useEffect(()=>{const j=B=>{B.key==="Escape"&&n()};return window.addEventListener("keydown",j),()=>window.removeEventListener("keydown",j)},[n]);const v=o==="generated"?h:g??"",E=()=>{v&&navigator.clipboard.writeText(v).then(()=>{i(!0),setTimeout(()=>i(!1),2e3)})},R=()=>{y(null),b(null);let j;try{const B=x.trim().replace(/:\s*True\b/g,": true").replace(/:\s*False\b/g,": false").replace(/:\s*None\b/g,": null").replace(/,\s*True\b/g,", true").replace(/,\s*False\b/g,", false").replace(/,\s*None\b/g,", null").replace(/\[\s*True\b/g,"[ true").replace(/\[\s*False\b/g,"[ false").replace(/\[\s*None\b/g,"[ null");j=JSON.parse(B)}catch{y("Invalid JSON — please check the syntax");return}b(zt(j,"Root"))};return r.jsx("div",{className:w.overlay,children:r.jsxs("div",{className:w.panel,ref:l,style:{width:d},children:[r.jsx("div",{className:w.resizeHandle,onMouseDown:p}),r.jsxs("div",{className:w.header,children:[r.jsxs("span",{className:w.title,children:["TS Types",r.jsx("span",{className:w.titleBadge,children:".ts"})]}),r.jsxs("div",{className:w.headerActions,children:[v&&r.jsx("button",{className:`${w.iconBtn} ${a?w.copyDone:""}`,onClick:E,title:"Copy types",children:a?r.jsx("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round",children:r.jsx("polyline",{points:"20 6 9 17 4 12"})}):r.jsxs("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[r.jsx("rect",{x:"9",y:"9",width:"13",height:"13",rx:"2",ry:"2"}),r.jsx("path",{d:"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"})]})}),r.jsx("button",{className:`${w.iconBtn} ${w.iconBtnClose}`,onClick:n,title:"Close (Esc)",children:r.jsxs("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round",children:[r.jsx("line",{x1:"18",y1:"6",x2:"6",y2:"18"}),r.jsx("line",{x1:"6",y1:"6",x2:"18",y2:"18"})]})})]})]}),r.jsxs("div",{className:w.tabs,children:[t!=="custom"&&r.jsx("button",{className:`${w.tab} ${o==="generated"?w.tabActive:""}`,onClick:()=>s("generated"),children:"Generated"}),r.jsx("button",{className:`${w.tab} ${o==="custom"?w.tabActive:""}`,onClick:()=>s("custom"),children:"Custom JSON"})]}),o==="generated"?r.jsx("div",{className:w.editorWrap,children:r.jsx(ye,{language:"typescript",value:h,theme:"vs-dark",options:Ee,onChange:j=>m(j??"")})}):r.jsxs("div",{className:w.customTab,children:[r.jsxs("div",{className:w.customSection,children:[r.jsx("p",{className:w.customSectionLabel,children:"JSON input"}),r.jsx("div",{className:w.customEditorWrap,children:r.jsx(ye,{language:"json",value:x,theme:"vs-dark",options:Ee,onChange:j=>{_(j??""),y(null)}})}),f&&r.jsx("p",{className:w.customError,children:f}),r.jsx("div",{className:w.customActions,children:r.jsxs("button",{className:w.genBtn,onClick:R,children:[r.jsxs("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[r.jsx("polyline",{points:"16 18 22 12 16 6"}),r.jsx("polyline",{points:"8 6 2 12 8 18"})]}),"Generate types"]})})]}),g!==null&&r.jsxs("div",{className:w.customSection,children:[r.jsx("p",{className:w.customSectionLabel,children:"Result"}),r.jsx("div",{className:w.customEditorWrap,children:r.jsx(ye,{language:"typescript",value:g,theme:"vs-dark",options:Ee,onChange:j=>b(j??"")})})]})]})]})})},ei="_expanded_1rwyf_1",ti="_expandedUrl_1rwyf_18",ni="_metaRow_1rwyf_26",ri="_metaItem_1rwyf_33",oi="_metaLabel_1rwyf_42",si="_tabBar_1rwyf_50",ai="_tabBarSpacer_1rwyf_58",ii="_tab_1rwyf_50",li="_tabActive_1rwyf_78",ci="_viewToggle_1rwyf_83",di="_viewToggleBtn_1rwyf_92",ui="_viewToggleBtnActive_1rwyf_118",pi="_htmlPreviewIframe_1rwyf_123",hi="_tabContent_1rwyf_132",mi="_noData_1rwyf_138",k={expanded:ei,expandedUrl:ti,metaRow:ni,metaItem:ri,metaLabel:oi,tabBar:si,tabBarSpacer:ai,tab:ii,tabActive:li,viewToggle:ci,viewToggleBtn:di,viewToggleBtnActive:ui,htmlPreviewIframe:pi,tabContent:hi,noData:mi},fi=({event:e})=>{const t="response",[n,o]=c.useState(t),[s,a]=c.useState("code"),[i,l]=c.useState(null),d=na(e,n),u=n==="response"?e.responseBody:n==="request"?e.requestBody:null,p=_e(u),h=p!==null,m=f=>{if(f.stopPropagation(),!p)return;if(i!==null){l(null);return}l(zt(p,n==="response"?"Response":"RequestBody"))},x=n==="response"&&Zs(e.responseBody),_=String(e.responseBody??"");return r.jsxs("div",{className:k.expanded,children:[r.jsx("div",{className:k.expandedUrl,children:e.url}),r.jsxs("div",{className:k.metaRow,children:[e.status!=null&&r.jsxs("span",{className:k.metaItem,children:[r.jsx("span",{className:k.metaLabel,children:"Status"}),r.jsx("span",{style:{color:la(e.status)},children:e.status})]}),e.duration!=null&&r.jsxs("span",{className:k.metaItem,children:[r.jsx("span",{className:k.metaLabel,children:"Duration"}),r.jsxs("span",{children:[e.duration.toFixed(0)," ms"]})]}),r.jsxs("span",{className:k.metaItem,children:[r.jsx("span",{className:k.metaLabel,children:"Transport"}),r.jsx("span",{children:e.transport.toUpperCase()})]})]}),r.jsxs("div",{className:k.tabBar,children:[ea.map(f=>r.jsx("button",{className:`${k.tab} ${n===f.key?k.tabActive:""}`,onClick:y=>{y.stopPropagation(),o(f.key)},children:f.label},f.key)),r.jsx("span",{className:k.tabBarSpacer}),x&&r.jsxs("span",{className:k.viewToggle,children:[r.jsxs("button",{className:`${k.viewToggleBtn} ${s==="code"?k.viewToggleBtnActive:""}`,onClick:f=>{f.stopPropagation(),a("code")},children:[r.jsxs("svg",{width:"11",height:"11",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round",children:[r.jsx("polyline",{points:"16 18 22 12 16 6"}),r.jsx("polyline",{points:"8 6 2 12 8 18"})]}),"Code"]}),r.jsxs("button",{className:`${k.viewToggleBtn} ${s==="preview"?k.viewToggleBtnActive:""}`,onClick:f=>{f.stopPropagation(),a("preview")},children:[r.jsxs("svg",{width:"11",height:"11",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round",children:[r.jsx("rect",{x:"3",y:"3",width:"18",height:"18",rx:"2"}),r.jsx("path",{d:"M3 9h18"})]}),"Preview"]}),r.jsxs("button",{className:k.viewToggleBtn,onClick:f=>{f.stopPropagation(),window.open(e.url,"_blank","noopener,noreferrer")},title:"Open URL in new tab",children:[r.jsxs("svg",{width:"11",height:"11",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round",children:[r.jsx("path",{d:"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"}),r.jsx("polyline",{points:"15 3 21 3 21 9"}),r.jsx("line",{x1:"10",y1:"14",x2:"21",y2:"3"})]}),"Open"]})]}),r.jsx(Na,{text:x&&s==="preview"?null:d}),r.jsx($a,{disabled:!h,active:i!==null,onClick:m})]}),r.jsxs("div",{className:k.tabContent,children:[n==="response"&&x&&s==="preview"?r.jsx("iframe",{srcDoc:_,title:"HTML Preview",className:k.htmlPreviewIframe,sandbox:"allow-scripts allow-same-origin"}):n==="response"?e.responseBody?r.jsx($e,{value:e.responseBody}):r.jsx("span",{className:k.noData,children:"No response body"}):null,n==="request"&&(e.requestBody?r.jsx($e,{value:e.requestBody}):r.jsx("span",{className:k.noData,children:"No request body"})),n==="responseHeaders"&&r.jsx(dt,{headers:e.responseHeaders}),n==="requestHeaders"&&r.jsx(dt,{headers:e.requestHeaders})]}),i!==null&&ht.createPortal(r.jsx(Ut,{code:i,onClose:()=>l(null)}),document.body)]})},gi="_expanded_9p09c_1",yi="_argRow_9p09c_18",xi="_argIdx_9p09c_29",_i="_argVal_9p09c_38",he={expanded:gi,argRow:yi,argIdx:xi,argVal:_i},vi=({event:e})=>r.jsx("div",{className:he.expanded,children:e.args.map((t,n)=>r.jsxs("div",{className:he.argRow,children:[r.jsx("span",{className:he.argIdx,children:n}),r.jsx("div",{className:he.argVal,children:r.jsx($e,{value:t})})]},n))}),bi="_item_129te_1",wi="_itemOpen_129te_8",ji="_itemHeader_129te_12",ki="_timestamp_129te_24",Ci="_delta_129te_34",Si="_titleBadge_129te_46",Ri="_preview_129te_58",Ei="_spacer_129te_69",Ni="_chevron_129te_73",Li="_chevronOpen_129te_79",W={item:bi,itemOpen:wi,itemHeader:ji,timestamp:ki,delta:Ci,titleBadge:Si,preview:Ri,spacer:Ei,chevron:Ni,chevronOpen:Li},Bi=({event:e,prevTs:t,isOpen:n,onToggle:o})=>{const s=da(e),a=ua(e),i=ca(e),l=t!=null?oa(e.timestamp-t):null;return r.jsxs("div",{className:`${W.item} ${n?W.itemOpen:""}`,children:[r.jsxs("div",{className:W.itemHeader,onClick:o,children:[r.jsx("span",{className:W.timestamp,children:ra(e.timestamp)}),r.jsx("span",{className:W.delta,children:l??""}),r.jsx("span",{className:W.titleBadge,style:{color:i},children:s}),!n&&r.jsx("span",{className:W.preview,children:a}),r.jsx("span",{className:W.spacer}),r.jsx("svg",{className:`${W.chevron} ${n?W.chevronOpen:""}`,width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:r.jsx("polyline",{points:"6 9 12 15 18 9"})})]}),n&&r.jsxs(r.Fragment,{children:[e.type==="network"&&r.jsx(fi,{event:e}),e.type==="console"&&r.jsx(vi,{event:e})]})]})},$i="_emptyState_z2adh_1",Pi="_emptyIcon_z2adh_13",Ti="_emptyTitle_z2adh_18",Ai="_emptySubtitle_z2adh_25",me={emptyState:$i,emptyIcon:Pi,emptyTitle:Ti,emptySubtitle:Ai},Ii=()=>r.jsxs("div",{className:me.emptyState,children:[r.jsxs("svg",{width:"48",height:"48",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1",strokeLinecap:"round",strokeLinejoin:"round",className:me.emptyIcon,children:[r.jsx("rect",{x:"3",y:"3",width:"18",height:"18",rx:"2"}),r.jsx("line",{x1:"3",y1:"9",x2:"21",y2:"9"}),r.jsx("line",{x1:"9",y1:"21",x2:"9",y2:"9"})]}),r.jsx("p",{className:me.emptyTitle,children:"No Activity"}),r.jsx("p",{className:me.emptySubtitle,children:"Once your app connects and starts sending events, they will appear here."})]}),Di="_container_1gdg7_21",Mi="_header_1gdg7_34",Wi="_headerTitle_1gdg7_45",Oi="_filterBar_1gdg7_56",Fi="_filterBtn_1gdg7_62",Hi="_filterBtnActive_1gdg7_82",zi="_filterCount_1gdg7_87",Ui="_filterCountActive_1gdg7_101",qi="_headerActions_1gdg7_107",Vi="_iconBtn_1gdg7_114",Gi="_typesBtn_1gdg7_132",Ji="_typesBtnActive_1gdg7_136",Ki="_timeline_1gdg7_142",$={container:Di,header:Mi,headerTitle:Wi,filterBar:Oi,filterBtn:Fi,filterBtnActive:Hi,filterCount:zi,filterCountActive:Ui,headerActions:qi,iconBtn:Vi,typesBtn:Gi,typesBtnActive:Ji,timeline:Ki},Xi=()=>{const e=X(),t=M(Jt),n=M(Kt),o=Ht(n,t),[s,a]=c.useState(null),[i,l]=c.useState(!1);return r.jsxs("div",{className:$.container,children:[r.jsxs("div",{className:$.header,children:[r.jsx("span",{className:$.headerTitle,children:"Timeline"}),r.jsx("div",{className:$.filterBar,children:Qs.map(d=>{const u=ta(n,d.key);return r.jsxs("button",{className:`${$.filterBtn} ${t===d.key?$.filterBtnActive:""}`,onClick:()=>{e(Xt(d.key)),a(null)},children:[d.label,u>0&&r.jsx("span",{className:`${$.filterCount} ${t===d.key?$.filterCountActive:""}`,children:u>999?"999+":u})]},d.key)})}),r.jsxs("div",{className:$.headerActions,children:[r.jsx("button",{className:`${$.iconBtn} ${$.typesBtn} ${i?$.typesBtnActive:""}`,title:"Open Types panel",onClick:()=>l(d=>!d),children:r.jsxs("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[r.jsx("polyline",{points:"16 18 22 12 16 6"}),r.jsx("polyline",{points:"8 6 2 12 8 18"})]})}),r.jsx("button",{className:$.iconBtn,title:"Clear",onClick:()=>{e(yt()),a(null)},children:r.jsxs("svg",{width:"15",height:"15",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",children:[r.jsx("polyline",{points:"3 6 5 6 21 6"}),r.jsx("path",{d:"M19 6l-1 14H6L5 6"}),r.jsx("path",{d:"M10 11v6M14 11v6"}),r.jsx("path",{d:"M9 6V4h6v2"})]})})]})]}),r.jsx("div",{className:$.timeline,children:o.length===0?r.jsx(Ii,{}):o.map((d,u)=>{var p;return r.jsx(Bi,{event:d,prevTs:(p=o[u+1])==null?void 0:p.timestamp,isOpen:s===d.id,onToggle:()=>a(h=>h===d.id?null:d.id)},d.id)})}),i&&ht.createPortal(r.jsx(Ut,{initialTab:"custom",onClose:()=>l(!1)}),document.body)]})},Yi="_overlay_xpudk_1",Zi="_modal_xpudk_18",Qi="_header_xpudk_35",el="_iconWrap_xpudk_42",tl="_title_xpudk_54",nl="_subtitle_xpudk_61",rl="_body_xpudk_68",ol="_sectionLabel_xpudk_72",sl="_featureList_xpudk_81",al="_featureItem_xpudk_90",il="_dot_xpudk_98",ll="_note_xpudk_106",cl="_noteCode_xpudk_124",dl="_error_xpudk_134",ul="_footer_xpudk_148",pl="_btnCancel_xpudk_156",hl="_btnConfirm_xpudk_177",N={overlay:Yi,modal:Zi,header:Qi,iconWrap:el,title:tl,subtitle:nl,body:rl,sectionLabel:ol,featureList:sl,featureItem:al,dot:il,note:ll,noteCode:cl,error:dl,footer:ul,btnCancel:pl,btnConfirm:hl},ml=[{label:"console.log / info / warn / error",color:"#4a9eff"},{label:"fetch (web & React Native)",color:"#34d399"},{label:"XMLHttpRequest",color:"#34d399"},{label:"axios (via XHR / fetch interception)",color:"#34d399"}],fl=({onClose:e,onInstalled:t})=>{const n=X(),[o,s]=c.useState(!1),[a,i]=c.useState(null),l=async()=>{s(!0),i(null),n(xt("installing"));try{const d=await Ne.install();if(!d.success){i(d.error??"Installation failed"),n(Ue(d.error??"Installation failed"));return}n(_t(d.entryFile??"unknown")),t(),e()}catch(d){const u=d instanceof Error?d.message:"Network error";i(u),n(Ue(u))}finally{s(!1)}};return r.jsx("div",{className:N.overlay,onClick:e,children:r.jsxs("div",{className:N.modal,onClick:d=>d.stopPropagation(),children:[r.jsxs("div",{className:N.header,children:[r.jsx("div",{className:N.iconWrap,children:r.jsx("svg",{width:"15",height:"15",viewBox:"0 0 24 24",fill:"none",stroke:"#4a9eff",strokeWidth:"2.2",strokeLinecap:"round",strokeLinejoin:"round",children:r.jsx("path",{d:"M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"})})}),r.jsxs("div",{children:[r.jsx("div",{className:N.title,children:"Install Debug Agent"}),r.jsx("div",{className:N.subtitle,children:"Auto-injected into your project entry file"})]})]}),r.jsxs("div",{className:N.body,children:[r.jsx("div",{className:N.sectionLabel,children:"Intercepts"}),r.jsx("ul",{className:N.featureList,children:ml.map(d=>r.jsxs("li",{className:N.featureItem,children:[r.jsx("span",{className:N.dot,style:{background:d.color}}),r.jsx("span",{children:d.label})]},d.label))}),r.jsxs("div",{className:N.note,children:[r.jsxs("svg",{width:"13",height:"13",viewBox:"0 0 24 24",fill:"none",stroke:"#555",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[r.jsx("circle",{cx:"12",cy:"12",r:"10"}),r.jsx("line",{x1:"12",y1:"8",x2:"12",y2:"12"}),r.jsx("line",{x1:"12",y1:"16",x2:"12.01",y2:"16"})]}),r.jsxs("span",{children:["Adds"," ",r.jsx("code",{className:N.noteCode,children:'import "./codetraxisAgent"'})," ","to your entry file. Works with React (web) and React Native / Expo."]})]})]}),a&&r.jsxs("div",{className:N.error,children:[r.jsxs("svg",{width:"13",height:"13",viewBox:"0 0 24 24",fill:"none",stroke:"#f87171",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[r.jsx("circle",{cx:"12",cy:"12",r:"10"}),r.jsx("line",{x1:"12",y1:"8",x2:"12",y2:"12"}),r.jsx("line",{x1:"12",y1:"16",x2:"12.01",y2:"16"})]}),a]}),r.jsxs("div",{className:N.footer,children:[r.jsx("button",{className:N.btnCancel,onClick:e,disabled:o,children:"Cancel"}),r.jsx("button",{className:N.btnConfirm,onClick:l,disabled:o,children:o?"Installing…":"Install Agent"})]})]})})},gl="_overlay_1brot_1",yl="_modal_1brot_18",xl="_header_1brot_35",_l="_iconWrap_1brot_42",vl="_title_1brot_54",bl="_subtitle_1brot_61",wl="_body_1brot_68",jl="_code_1brot_75",kl="_error_1brot_85",Cl="_footer_1brot_99",Sl="_btnCancel_1brot_107",Rl="_btnRemove_1brot_128",T={overlay:gl,modal:yl,header:xl,iconWrap:_l,title:vl,subtitle:bl,body:wl,code:jl,error:kl,footer:Cl,btnCancel:Sl,btnRemove:Rl},El=({onClose:e,onConfirm:t})=>{const[n,o]=c.useState(!1),[s,a]=c.useState(null),i=async()=>{o(!0),a(null);try{await t(),e()}catch(l){a(l instanceof Error?l.message:"Removal failed")}finally{o(!1)}};return r.jsx("div",{className:T.overlay,onClick:e,children:r.jsxs("div",{className:T.modal,onClick:l=>l.stopPropagation(),children:[r.jsxs("div",{className:T.header,children:[r.jsx("div",{className:T.iconWrap,children:r.jsxs("svg",{width:"15",height:"15",viewBox:"0 0 24 24",fill:"none",stroke:"#f87171",strokeWidth:"2.2",strokeLinecap:"round",strokeLinejoin:"round",children:[r.jsx("polyline",{points:"3 6 5 6 21 6"}),r.jsx("path",{d:"M19 6l-1 14H6L5 6"}),r.jsx("path",{d:"M10 11v6M14 11v6"}),r.jsx("path",{d:"M9 6V4h6v2"})]})}),r.jsxs("div",{children:[r.jsx("div",{className:T.title,children:"Remove Debug Agent"}),r.jsx("div",{className:T.subtitle,children:"This action cannot be undone"})]})]}),r.jsxs("div",{className:T.body,children:["The agent import line and the"," ",r.jsx("code",{className:T.code,children:"codetraxisAgent/"})," ","folder will be permanently removed from your project. Debug interception will stop immediately."]}),s&&r.jsxs("div",{className:T.error,children:[r.jsxs("svg",{width:"13",height:"13",viewBox:"0 0 24 24",fill:"none",stroke:"#f87171",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[r.jsx("circle",{cx:"12",cy:"12",r:"10"}),r.jsx("line",{x1:"12",y1:"8",x2:"12",y2:"12"}),r.jsx("line",{x1:"12",y1:"16",x2:"12.01",y2:"16"})]}),s]}),r.jsxs("div",{className:T.footer,children:[r.jsx("button",{className:T.btnCancel,onClick:e,disabled:n,children:"Cancel"}),r.jsx("button",{className:T.btnRemove,onClick:i,disabled:n,children:n?"Removing…":"Remove Agent"})]})]})})},Nl=e=>{const t=X(),n=c.useRef(null),o=c.useRef(null);c.useEffect(()=>{if(!e)return;const s=()=>{const a=`ws://${window.location.hostname}:3333/debug`,i=new WebSocket(a);n.current=i,i.onmessage=l=>{try{const d=JSON.parse(l.data);t(Yt(d))}catch{}},i.onclose=()=>{o.current=setTimeout(s,3e3)}};return s(),()=>{var a;(a=n.current)==null||a.close(),o.current&&clearTimeout(o.current)}},[e,t])},Ll=()=>{const e=X(),t=M(Pe),[n,o]=c.useState(!1),[s,a]=c.useState(!1),[i,l]=c.useState("files");c.useEffect(()=>{e(gt())},[e]),c.useEffect(()=>{Ne.status().then(u=>{u.installed&&e(_t(u.entryFile??"unknown"))}).catch(()=>{})},[e]),ko(),Nl(t==="installed");const d=async()=>{try{const u=await Ne.uninstall();if(u.success)e(xt("not-installed")),e(yt()),l("files");else throw new Error(u.error??"Ошибка при удалении агента")}catch(u){throw u}};return r.jsxs("div",{className:Qe.container,style:{backgroundColor:L.background},children:[r.jsx(Hr,{onAddAgent:()=>o(!0),onRemoveAgent:()=>a(!0)}),r.jsxs("div",{className:Qe.content,children:[r.jsx(Gr,{mode:i,onModeChange:l}),i==="files"?r.jsxs(r.Fragment,{children:[r.jsx(wo,{}),r.jsx(Xs,{})]}):r.jsx(Xi,{})]}),n&&r.jsx(fl,{onClose:()=>o(!1),onInstalled:()=>{o(!1),l("debug")}}),s&&r.jsx(El,{onClose:()=>a(!1),onConfirm:d})]})};function Bl(){return r.jsx(Zt,{store:Qt,children:r.jsx(kr,{children:r.jsx(er,{children:r.jsx(At,{path:"/",element:r.jsx(Ll,{})})})})})}qt.createRoot(document.getElementById("root")).render(r.jsx(c.StrictMode,{children:r.jsx(Bl,{})}));
|
|
193
|
+
`)}const ma="_urlInline_2pclv_1",fa="_urlInlineBtns_2pclv_10",ga="_urlInlineBtn_2pclv_10",ya="_urlInlineBtnActive_2pclv_39",xa="_urlPreviewImg_2pclv_45",_a="_urlPreviewIframe_2pclv_54",K={urlInline:ma,urlInlineBtns:fa,urlInlineBtn:ga,urlInlineBtnActive:ya,urlPreviewImg:xa,urlPreviewIframe:_a},va=({url:e})=>{const t=/\.(png|jpe?g|gif|webp|svg|avif)(\?|$)/i.test(e),[n,o]=c.useState(!1),s=i=>{i.stopPropagation(),window.open(e,"_blank","noopener,noreferrer")},a=i=>{i.stopPropagation(),o(l=>!l)};return r.jsxs("span",{className:K.urlInline,children:[r.jsxs("span",{className:K.urlInlineBtns,children:[r.jsxs("button",{className:K.urlInlineBtn,onClick:s,title:"Open in new tab",children:[r.jsxs("svg",{width:"11",height:"11",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round",children:[r.jsx("path",{d:"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"}),r.jsx("polyline",{points:"15 3 21 3 21 9"}),r.jsx("line",{x1:"10",y1:"14",x2:"21",y2:"3"})]}),"open"]}),r.jsxs("button",{className:`${K.urlInlineBtn} ${n?K.urlInlineBtnActive:""}`,onClick:a,title:n?"Hide preview":"Show preview",children:[n?r.jsxs("svg",{width:"11",height:"11",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round",children:[r.jsx("path",{d:"M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94"}),r.jsx("path",{d:"M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19"}),r.jsx("line",{x1:"1",y1:"1",x2:"23",y2:"23"})]}):r.jsxs("svg",{width:"11",height:"11",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round",children:[r.jsx("path",{d:"M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"}),r.jsx("circle",{cx:"12",cy:"12",r:"3"})]}),n?"hide":"show"]})]}),n&&(t?r.jsx("img",{src:e,alt:"preview",className:K.urlPreviewImg,onClick:i=>i.stopPropagation()}):r.jsx("iframe",{src:e,title:"preview",className:K.urlPreviewIframe,sandbox:"allow-scripts allow-same-origin allow-forms"}))]})},ba="_pre_1m1q3_1",wa={pre:ba},$e=({value:e})=>{const t=_e(e);return t?r.jsx(qe,{value:t,style:{...tn,background:"transparent",fontSize:14,fontFamily:"inherit",lineHeight:1.7,"--w-rjv-color":"#a7a7a7","--w-rjv-key-string":"#7587a6","--w-rjv-type-string-color":"#8f9d6a","--w-rjv-type-int-color":"#cda869","--w-rjv-type-float-color":"#cda869","--w-rjv-type-boolean-color":"#cda869","--w-rjv-type-null-color":"#cf6a4c","--w-rjv-curlybraces-color":"#838184","--w-rjv-brackets-color":"#838184","--w-rjv-colon-color":"#838184","--w-rjv-copied-color":"#8f9d6a","--w-rjv-copied-success-color":"#8f9d6a","--w-rjv-background-color":"transparent"},collapsed:!0,displayDataTypes:!1,displayObjectSize:!0,enableClipboard:!0,indentWidth:20,children:r.jsx(qe.String,{render:(n,{type:o,value:s})=>{if(o==="value"&&Ys(s)){const{children:a,...i}=n;return r.jsxs("span",{...i,style:{...i.style,display:"inline-flex",alignItems:"center",gap:4,flexWrap:"wrap"},children:[a,r.jsx(va,{url:s})]})}}})}):r.jsx("pre",{className:wa.pre,children:String(e??"—")})},ja="_headersTable_1c6e1_1",ka="_headerKey_1c6e1_15",Ca="_headerVal_1c6e1_24",Sa="_noData_1c6e1_31",pe={headersTable:ja,headerKey:ka,headerVal:Ca,noData:Sa},dt=({headers:e})=>!e||Object.keys(e).length===0?r.jsx("span",{className:pe.noData,children:"No headers captured"}):r.jsx("table",{className:pe.headersTable,children:r.jsx("tbody",{children:Object.entries(e).map(([t,n])=>r.jsxs("tr",{children:[r.jsx("td",{className:pe.headerKey,children:t}),r.jsx("td",{className:pe.headerVal,children:n})]},t))})}),Ra="_copyBtn_290t0_1",Ea="_copyBtnDone_290t0_23",ut={copyBtn:Ra,copyBtnDone:Ea},Na=({text:e})=>{const[t,n]=c.useState(!1);if(!e)return null;const o=s=>{s.stopPropagation(),navigator.clipboard.writeText(e).then(()=>{n(!0),setTimeout(()=>n(!1),2e3)})};return r.jsx("button",{className:`${ut.copyBtn} ${t?ut.copyBtnDone:""}`,onClick:o,title:"Copy to clipboard",children:t?r.jsxs(r.Fragment,{children:[r.jsx("svg",{width:"13",height:"13",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round",children:r.jsx("polyline",{points:"20 6 9 17 4 12"})}),"Copied"]}):r.jsxs(r.Fragment,{children:[r.jsxs("svg",{width:"13",height:"13",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[r.jsx("rect",{x:"9",y:"9",width:"13",height:"13",rx:"2",ry:"2"}),r.jsx("path",{d:"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"})]}),"Copy"]})})},La="_genBtn_i8cke_1",Ba="_genBtnActive_i8cke_23",pt={genBtn:La,genBtnActive:Ba},$a=({disabled:e,active:t,onClick:n})=>e?null:r.jsxs("button",{className:[pt.genBtn,t?pt.genBtnActive:""].filter(Boolean).join(" "),onClick:n,title:"Generate TypeScript types",children:[r.jsxs("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[r.jsx("polyline",{points:"16 18 22 12 16 6"}),r.jsx("polyline",{points:"8 6 2 12 8 18"})]}),"types"]}),Pa="_overlay_1n3zm_1",Ta="_panel_1n3zm_10",Aa="_resizeHandle_1n3zm_25",Ia="_header_1n3zm_62",Da="_title_1n3zm_73",Ma="_titleBadge_1n3zm_84",Wa="_headerActions_1n3zm_96",Oa="_iconBtn_1n3zm_102",Fa="_iconBtnClose_1n3zm_119",Ha="_copyDone_1n3zm_124",za="_tabs_1n3zm_129",Ua="_tab_1n3zm_129",qa="_tabActive_1n3zm_153",Va="_editorWrap_1n3zm_160",Ga="_customTab_1n3zm_192",Ja="_customSection_1n3zm_201",Ka="_customSectionLabel_1n3zm_213",Xa="_customEditorWrap_1n3zm_224",Ya="_customError_1n3zm_232",Za="_customActions_1n3zm_240",Qa="_genBtn_1n3zm_248",w={overlay:Pa,panel:Ta,resizeHandle:Aa,header:Ia,title:Da,titleBadge:Ma,headerActions:Wa,iconBtn:Oa,iconBtnClose:Fa,copyDone:Ha,tabs:za,tab:Ua,tabActive:qa,editorWrap:Va,customTab:Ga,customSection:Ja,customSectionLabel:Ka,customEditorWrap:Xa,customError:Ya,customActions:Za,genBtn:Qa},Ee={minimap:{enabled:!1},scrollBeyondLastLine:!1,fontSize:13,lineHeight:22,fontFamily:'"Fira Code", "SF Mono", "Consolas", monospace',fontLigatures:!0,readOnly:!1,wordWrap:"on",padding:{top:16,bottom:16},lineNumbers:"off",folding:!0,glyphMargin:!1,renderLineHighlight:"none",scrollbar:{verticalScrollbarSize:6,horizontalScrollbarSize:6},overviewRulerLanes:0},Ut=({code:e="",initialTab:t="generated",onClose:n})=>{const[o,s]=c.useState(t),[a,i]=c.useState(!1),l=c.useRef(null),[d,u]=c.useState(480),p=j=>{var ie;j.preventDefault();const B=j.clientX,q=((ie=l.current)==null?void 0:ie.offsetWidth)??d,V=we=>{const le=B-we.clientX,ce=Math.min(Math.max(q+le,280),window.innerWidth*.9);u(ce)},Y=()=>{window.removeEventListener("mousemove",V),window.removeEventListener("mouseup",Y)};window.addEventListener("mousemove",V),window.addEventListener("mouseup",Y)},[h,m]=c.useState(e),[x,_]=c.useState(""),[f,y]=c.useState(null),[g,b]=c.useState(null);c.useEffect(()=>{m(e)},[e]),c.useEffect(()=>{const j=B=>{B.key==="Escape"&&n()};return window.addEventListener("keydown",j),()=>window.removeEventListener("keydown",j)},[n]);const v=o==="generated"?h:g??"",E=()=>{v&&navigator.clipboard.writeText(v).then(()=>{i(!0),setTimeout(()=>i(!1),2e3)})},R=()=>{y(null),b(null);let j;try{const B=x.trim().replace(/:\s*True\b/g,": true").replace(/:\s*False\b/g,": false").replace(/:\s*None\b/g,": null").replace(/,\s*True\b/g,", true").replace(/,\s*False\b/g,", false").replace(/,\s*None\b/g,", null").replace(/\[\s*True\b/g,"[ true").replace(/\[\s*False\b/g,"[ false").replace(/\[\s*None\b/g,"[ null");j=JSON.parse(B)}catch{y("Invalid JSON — please check the syntax");return}b(zt(j,"Root"))};return r.jsx("div",{className:w.overlay,children:r.jsxs("div",{className:w.panel,ref:l,style:{width:d},children:[r.jsx("div",{className:w.resizeHandle,onMouseDown:p}),r.jsxs("div",{className:w.header,children:[r.jsxs("span",{className:w.title,children:["TS Types",r.jsx("span",{className:w.titleBadge,children:".ts"})]}),r.jsxs("div",{className:w.headerActions,children:[v&&r.jsx("button",{className:`${w.iconBtn} ${a?w.copyDone:""}`,onClick:E,title:"Copy types",children:a?r.jsx("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round",children:r.jsx("polyline",{points:"20 6 9 17 4 12"})}):r.jsxs("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[r.jsx("rect",{x:"9",y:"9",width:"13",height:"13",rx:"2",ry:"2"}),r.jsx("path",{d:"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"})]})}),r.jsx("button",{className:`${w.iconBtn} ${w.iconBtnClose}`,onClick:n,title:"Close (Esc)",children:r.jsxs("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round",children:[r.jsx("line",{x1:"18",y1:"6",x2:"6",y2:"18"}),r.jsx("line",{x1:"6",y1:"6",x2:"18",y2:"18"})]})})]})]}),r.jsxs("div",{className:w.tabs,children:[t!=="custom"&&r.jsx("button",{className:`${w.tab} ${o==="generated"?w.tabActive:""}`,onClick:()=>s("generated"),children:"Generated"}),r.jsx("button",{className:`${w.tab} ${o==="custom"?w.tabActive:""}`,onClick:()=>s("custom"),children:"Custom JSON"})]}),o==="generated"?r.jsx("div",{className:w.editorWrap,children:r.jsx(ye,{language:"typescript",value:h,theme:"vs-dark",options:Ee,onChange:j=>m(j??"")})}):r.jsxs("div",{className:w.customTab,children:[r.jsxs("div",{className:w.customSection,children:[r.jsx("p",{className:w.customSectionLabel,children:"JSON input"}),r.jsx("div",{className:w.customEditorWrap,children:r.jsx(ye,{language:"json",value:x,theme:"vs-dark",options:Ee,onChange:j=>{_(j??""),y(null)}})}),f&&r.jsx("p",{className:w.customError,children:f}),r.jsx("div",{className:w.customActions,children:r.jsxs("button",{className:w.genBtn,onClick:R,children:[r.jsxs("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[r.jsx("polyline",{points:"16 18 22 12 16 6"}),r.jsx("polyline",{points:"8 6 2 12 8 18"})]}),"Generate types"]})})]}),g!==null&&r.jsxs("div",{className:w.customSection,children:[r.jsx("p",{className:w.customSectionLabel,children:"Result"}),r.jsx("div",{className:w.customEditorWrap,children:r.jsx(ye,{language:"typescript",value:g,theme:"vs-dark",options:Ee,onChange:j=>b(j??"")})})]})]})]})})},ei="_expanded_1rwyf_1",ti="_expandedUrl_1rwyf_18",ni="_metaRow_1rwyf_26",ri="_metaItem_1rwyf_33",oi="_metaLabel_1rwyf_42",si="_tabBar_1rwyf_50",ai="_tabBarSpacer_1rwyf_58",ii="_tab_1rwyf_50",li="_tabActive_1rwyf_78",ci="_viewToggle_1rwyf_83",di="_viewToggleBtn_1rwyf_92",ui="_viewToggleBtnActive_1rwyf_118",pi="_htmlPreviewIframe_1rwyf_123",hi="_tabContent_1rwyf_132",mi="_noData_1rwyf_138",k={expanded:ei,expandedUrl:ti,metaRow:ni,metaItem:ri,metaLabel:oi,tabBar:si,tabBarSpacer:ai,tab:ii,tabActive:li,viewToggle:ci,viewToggleBtn:di,viewToggleBtnActive:ui,htmlPreviewIframe:pi,tabContent:hi,noData:mi},fi=({event:e})=>{const t="response",[n,o]=c.useState(t),[s,a]=c.useState("code"),[i,l]=c.useState(null),d=na(e,n),u=n==="response"?e.responseBody:n==="request"?e.requestBody:null,p=_e(u),h=p!==null,m=f=>{if(f.stopPropagation(),!p)return;if(i!==null){l(null);return}l(zt(p,n==="response"?"Response":"RequestBody"))},x=n==="response"&&Zs(e.responseBody),_=String(e.responseBody??"");return r.jsxs("div",{className:k.expanded,children:[r.jsx("div",{className:k.expandedUrl,children:e.url}),r.jsxs("div",{className:k.metaRow,children:[e.status!=null&&r.jsxs("span",{className:k.metaItem,children:[r.jsx("span",{className:k.metaLabel,children:"Status"}),r.jsx("span",{style:{color:la(e.status)},children:e.status})]}),e.duration!=null&&r.jsxs("span",{className:k.metaItem,children:[r.jsx("span",{className:k.metaLabel,children:"Duration"}),r.jsxs("span",{children:[e.duration.toFixed(0)," ms"]})]}),r.jsxs("span",{className:k.metaItem,children:[r.jsx("span",{className:k.metaLabel,children:"Transport"}),r.jsx("span",{children:e.transport.toUpperCase()})]})]}),r.jsxs("div",{className:k.tabBar,children:[ea.map(f=>r.jsx("button",{className:`${k.tab} ${n===f.key?k.tabActive:""}`,onClick:y=>{y.stopPropagation(),o(f.key)},children:f.label},f.key)),r.jsx("span",{className:k.tabBarSpacer}),x&&r.jsxs("span",{className:k.viewToggle,children:[r.jsxs("button",{className:`${k.viewToggleBtn} ${s==="code"?k.viewToggleBtnActive:""}`,onClick:f=>{f.stopPropagation(),a("code")},children:[r.jsxs("svg",{width:"11",height:"11",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round",children:[r.jsx("polyline",{points:"16 18 22 12 16 6"}),r.jsx("polyline",{points:"8 6 2 12 8 18"})]}),"Code"]}),r.jsxs("button",{className:`${k.viewToggleBtn} ${s==="preview"?k.viewToggleBtnActive:""}`,onClick:f=>{f.stopPropagation(),a("preview")},children:[r.jsxs("svg",{width:"11",height:"11",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round",children:[r.jsx("rect",{x:"3",y:"3",width:"18",height:"18",rx:"2"}),r.jsx("path",{d:"M3 9h18"})]}),"Preview"]}),r.jsxs("button",{className:k.viewToggleBtn,onClick:f=>{f.stopPropagation(),window.open(e.url,"_blank","noopener,noreferrer")},title:"Open URL in new tab",children:[r.jsxs("svg",{width:"11",height:"11",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round",children:[r.jsx("path",{d:"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"}),r.jsx("polyline",{points:"15 3 21 3 21 9"}),r.jsx("line",{x1:"10",y1:"14",x2:"21",y2:"3"})]}),"Open"]})]}),r.jsx(Na,{text:x&&s==="preview"?null:d}),r.jsx($a,{disabled:!h,active:i!==null,onClick:m})]}),r.jsxs("div",{className:k.tabContent,children:[n==="response"&&x&&s==="preview"?r.jsx("iframe",{srcDoc:_,title:"HTML Preview",className:k.htmlPreviewIframe,sandbox:"allow-scripts allow-same-origin"}):n==="response"?e.responseBody?r.jsx($e,{value:e.responseBody}):r.jsx("span",{className:k.noData,children:"No response body"}):null,n==="request"&&(e.requestBody?r.jsx($e,{value:e.requestBody}):r.jsx("span",{className:k.noData,children:"No request body"})),n==="responseHeaders"&&r.jsx(dt,{headers:e.responseHeaders}),n==="requestHeaders"&&r.jsx(dt,{headers:e.requestHeaders})]}),i!==null&&ht.createPortal(r.jsx(Ut,{code:i,onClose:()=>l(null)}),document.body)]})},gi="_expanded_9p09c_1",yi="_argRow_9p09c_18",xi="_argIdx_9p09c_29",_i="_argVal_9p09c_38",he={expanded:gi,argRow:yi,argIdx:xi,argVal:_i},vi=({event:e})=>r.jsx("div",{className:he.expanded,children:e.args.map((t,n)=>r.jsxs("div",{className:he.argRow,children:[r.jsx("span",{className:he.argIdx,children:n}),r.jsx("div",{className:he.argVal,children:r.jsx($e,{value:t})})]},n))}),bi="_item_129te_1",wi="_itemOpen_129te_8",ji="_itemHeader_129te_12",ki="_timestamp_129te_24",Ci="_delta_129te_34",Si="_titleBadge_129te_46",Ri="_preview_129te_58",Ei="_spacer_129te_69",Ni="_chevron_129te_73",Li="_chevronOpen_129te_79",W={item:bi,itemOpen:wi,itemHeader:ji,timestamp:ki,delta:Ci,titleBadge:Si,preview:Ri,spacer:Ei,chevron:Ni,chevronOpen:Li},Bi=({event:e,prevTs:t,isOpen:n,onToggle:o})=>{const s=da(e),a=ua(e),i=ca(e),l=t!=null?oa(e.timestamp-t):null;return r.jsxs("div",{className:`${W.item} ${n?W.itemOpen:""}`,children:[r.jsxs("div",{className:W.itemHeader,onClick:o,children:[r.jsx("span",{className:W.timestamp,children:ra(e.timestamp)}),r.jsx("span",{className:W.delta,children:l??""}),r.jsx("span",{className:W.titleBadge,style:{color:i},children:s}),!n&&r.jsx("span",{className:W.preview,children:a}),r.jsx("span",{className:W.spacer}),r.jsx("svg",{className:`${W.chevron} ${n?W.chevronOpen:""}`,width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:r.jsx("polyline",{points:"6 9 12 15 18 9"})})]}),n&&r.jsxs(r.Fragment,{children:[e.type==="network"&&r.jsx(fi,{event:e}),e.type==="console"&&r.jsx(vi,{event:e})]})]})},$i="_emptyState_z2adh_1",Pi="_emptyIcon_z2adh_13",Ti="_emptyTitle_z2adh_18",Ai="_emptySubtitle_z2adh_25",me={emptyState:$i,emptyIcon:Pi,emptyTitle:Ti,emptySubtitle:Ai},Ii=()=>r.jsxs("div",{className:me.emptyState,children:[r.jsxs("svg",{width:"48",height:"48",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1",strokeLinecap:"round",strokeLinejoin:"round",className:me.emptyIcon,children:[r.jsx("rect",{x:"3",y:"3",width:"18",height:"18",rx:"2"}),r.jsx("line",{x1:"3",y1:"9",x2:"21",y2:"9"}),r.jsx("line",{x1:"9",y1:"21",x2:"9",y2:"9"})]}),r.jsx("p",{className:me.emptyTitle,children:"No Activity"}),r.jsx("p",{className:me.emptySubtitle,children:"Once your app connects and starts sending events, they will appear here."})]}),Di="_container_1gdg7_21",Mi="_header_1gdg7_34",Wi="_headerTitle_1gdg7_45",Oi="_filterBar_1gdg7_56",Fi="_filterBtn_1gdg7_62",Hi="_filterBtnActive_1gdg7_82",zi="_filterCount_1gdg7_87",Ui="_filterCountActive_1gdg7_101",qi="_headerActions_1gdg7_107",Vi="_iconBtn_1gdg7_114",Gi="_typesBtn_1gdg7_132",Ji="_typesBtnActive_1gdg7_136",Ki="_timeline_1gdg7_142",$={container:Di,header:Mi,headerTitle:Wi,filterBar:Oi,filterBtn:Fi,filterBtnActive:Hi,filterCount:zi,filterCountActive:Ui,headerActions:qi,iconBtn:Vi,typesBtn:Gi,typesBtnActive:Ji,timeline:Ki},Xi=()=>{const e=X(),t=M(Jt),n=M(Kt),o=Ht(n,t),[s,a]=c.useState(null),[i,l]=c.useState(!1);return r.jsxs("div",{className:$.container,children:[r.jsxs("div",{className:$.header,children:[r.jsx("span",{className:$.headerTitle,children:"Timeline"}),r.jsx("div",{className:$.filterBar,children:Qs.map(d=>{const u=ta(n,d.key);return r.jsxs("button",{className:`${$.filterBtn} ${t===d.key?$.filterBtnActive:""}`,onClick:()=>{e(Xt(d.key)),a(null)},children:[d.label,u>0&&r.jsx("span",{className:`${$.filterCount} ${t===d.key?$.filterCountActive:""}`,children:u>999?"999+":u})]},d.key)})}),r.jsxs("div",{className:$.headerActions,children:[r.jsx("button",{className:`${$.iconBtn} ${$.typesBtn} ${i?$.typesBtnActive:""}`,title:"Open Types panel",onClick:()=>l(d=>!d),children:r.jsxs("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[r.jsx("polyline",{points:"16 18 22 12 16 6"}),r.jsx("polyline",{points:"8 6 2 12 8 18"})]})}),r.jsx("button",{className:$.iconBtn,title:"Clear",onClick:()=>{e(yt()),a(null)},children:r.jsxs("svg",{width:"15",height:"15",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",children:[r.jsx("polyline",{points:"3 6 5 6 21 6"}),r.jsx("path",{d:"M19 6l-1 14H6L5 6"}),r.jsx("path",{d:"M10 11v6M14 11v6"}),r.jsx("path",{d:"M9 6V4h6v2"})]})})]})]}),r.jsx("div",{className:$.timeline,children:o.length===0?r.jsx(Ii,{}):o.map((d,u)=>{var p;return r.jsx(Bi,{event:d,prevTs:(p=o[u+1])==null?void 0:p.timestamp,isOpen:s===d.id,onToggle:()=>a(h=>h===d.id?null:d.id)},d.id)})}),i&&ht.createPortal(r.jsx(Ut,{initialTab:"custom",onClose:()=>l(!1)}),document.body)]})},Yi="_overlay_xpudk_1",Zi="_modal_xpudk_18",Qi="_header_xpudk_35",el="_iconWrap_xpudk_42",tl="_title_xpudk_54",nl="_subtitle_xpudk_61",rl="_body_xpudk_68",ol="_sectionLabel_xpudk_72",sl="_featureList_xpudk_81",al="_featureItem_xpudk_90",il="_dot_xpudk_98",ll="_note_xpudk_106",cl="_noteCode_xpudk_124",dl="_error_xpudk_134",ul="_footer_xpudk_148",pl="_btnCancel_xpudk_156",hl="_btnConfirm_xpudk_177",N={overlay:Yi,modal:Zi,header:Qi,iconWrap:el,title:tl,subtitle:nl,body:rl,sectionLabel:ol,featureList:sl,featureItem:al,dot:il,note:ll,noteCode:cl,error:dl,footer:ul,btnCancel:pl,btnConfirm:hl},ml=[{label:"console.log / info / warn / error",color:"#4a9eff"},{label:"fetch (web & React Native)",color:"#34d399"},{label:"XMLHttpRequest",color:"#34d399"},{label:"axios (via XHR / fetch interception)",color:"#34d399"}],fl=({onClose:e,onInstalled:t})=>{const n=X(),[o,s]=c.useState(!1),[a,i]=c.useState(null),l=async()=>{s(!0),i(null),n(xt("installing"));try{const d=await Ne.install();if(!d.success){i(d.error??"Installation failed"),n(Ue(d.error??"Installation failed"));return}n(_t(d.entryFile??"unknown")),t(),e()}catch(d){const u=d instanceof Error?d.message:"Network error";i(u),n(Ue(u))}finally{s(!1)}};return r.jsx("div",{className:N.overlay,onClick:e,children:r.jsxs("div",{className:N.modal,onClick:d=>d.stopPropagation(),children:[r.jsxs("div",{className:N.header,children:[r.jsx("div",{className:N.iconWrap,children:r.jsx("svg",{width:"15",height:"15",viewBox:"0 0 24 24",fill:"none",stroke:"#4a9eff",strokeWidth:"2.2",strokeLinecap:"round",strokeLinejoin:"round",children:r.jsx("path",{d:"M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"})})}),r.jsxs("div",{children:[r.jsx("div",{className:N.title,children:"Install Debug Agent"}),r.jsx("div",{className:N.subtitle,children:"Auto-injected into your project entry file"})]})]}),r.jsxs("div",{className:N.body,children:[r.jsx("div",{className:N.sectionLabel,children:"Intercepts"}),r.jsx("ul",{className:N.featureList,children:ml.map(d=>r.jsxs("li",{className:N.featureItem,children:[r.jsx("span",{className:N.dot,style:{background:d.color}}),r.jsx("span",{children:d.label})]},d.label))}),r.jsxs("div",{className:N.note,children:[r.jsxs("svg",{width:"13",height:"13",viewBox:"0 0 24 24",fill:"none",stroke:"#555",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[r.jsx("circle",{cx:"12",cy:"12",r:"10"}),r.jsx("line",{x1:"12",y1:"8",x2:"12",y2:"12"}),r.jsx("line",{x1:"12",y1:"16",x2:"12.01",y2:"16"})]}),r.jsxs("span",{children:["Adds"," ",r.jsx("code",{className:N.noteCode,children:'import "./codetraxisAgent"'})," ","to your entry file. Works with React (web) and React Native / Expo."]})]})]}),a&&r.jsxs("div",{className:N.error,children:[r.jsxs("svg",{width:"13",height:"13",viewBox:"0 0 24 24",fill:"none",stroke:"#f87171",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[r.jsx("circle",{cx:"12",cy:"12",r:"10"}),r.jsx("line",{x1:"12",y1:"8",x2:"12",y2:"12"}),r.jsx("line",{x1:"12",y1:"16",x2:"12.01",y2:"16"})]}),a]}),r.jsxs("div",{className:N.footer,children:[r.jsx("button",{className:N.btnCancel,onClick:e,disabled:o,children:"Cancel"}),r.jsx("button",{className:N.btnConfirm,onClick:l,disabled:o,children:o?"Installing…":"Install Agent"})]})]})})},gl="_overlay_1brot_1",yl="_modal_1brot_18",xl="_header_1brot_35",_l="_iconWrap_1brot_42",vl="_title_1brot_54",bl="_subtitle_1brot_61",wl="_body_1brot_68",jl="_code_1brot_75",kl="_error_1brot_85",Cl="_footer_1brot_99",Sl="_btnCancel_1brot_107",Rl="_btnRemove_1brot_128",T={overlay:gl,modal:yl,header:xl,iconWrap:_l,title:vl,subtitle:bl,body:wl,code:jl,error:kl,footer:Cl,btnCancel:Sl,btnRemove:Rl},El=({onClose:e,onConfirm:t})=>{const[n,o]=c.useState(!1),[s,a]=c.useState(null),i=async()=>{o(!0),a(null);try{await t(),e()}catch(l){a(l instanceof Error?l.message:"Removal failed")}finally{o(!1)}};return r.jsx("div",{className:T.overlay,onClick:e,children:r.jsxs("div",{className:T.modal,onClick:l=>l.stopPropagation(),children:[r.jsxs("div",{className:T.header,children:[r.jsx("div",{className:T.iconWrap,children:r.jsxs("svg",{width:"15",height:"15",viewBox:"0 0 24 24",fill:"none",stroke:"#f87171",strokeWidth:"2.2",strokeLinecap:"round",strokeLinejoin:"round",children:[r.jsx("polyline",{points:"3 6 5 6 21 6"}),r.jsx("path",{d:"M19 6l-1 14H6L5 6"}),r.jsx("path",{d:"M10 11v6M14 11v6"}),r.jsx("path",{d:"M9 6V4h6v2"})]})}),r.jsxs("div",{children:[r.jsx("div",{className:T.title,children:"Remove Debug Agent"}),r.jsx("div",{className:T.subtitle,children:"This action cannot be undone"})]})]}),r.jsxs("div",{className:T.body,children:["The agent import line and the"," ",r.jsx("code",{className:T.code,children:"codetraxisAgent/"})," ","folder will be permanently removed from your project. Debug interception will stop immediately."]}),s&&r.jsxs("div",{className:T.error,children:[r.jsxs("svg",{width:"13",height:"13",viewBox:"0 0 24 24",fill:"none",stroke:"#f87171",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[r.jsx("circle",{cx:"12",cy:"12",r:"10"}),r.jsx("line",{x1:"12",y1:"8",x2:"12",y2:"12"}),r.jsx("line",{x1:"12",y1:"16",x2:"12.01",y2:"16"})]}),s]}),r.jsxs("div",{className:T.footer,children:[r.jsx("button",{className:T.btnCancel,onClick:e,disabled:n,children:"Cancel"}),r.jsx("button",{className:T.btnRemove,onClick:i,disabled:n,children:n?"Removing…":"Remove Agent"})]})]})})},Nl=e=>{const t=X(),n=c.useRef(null),o=c.useRef(null);c.useEffect(()=>{if(!e)return;const s=()=>{const a=`ws://${window.location.hostname}:3333/debug`,i=new WebSocket(a);n.current=i,i.onmessage=l=>{try{const d=JSON.parse(l.data);t(Yt(d))}catch{}},i.onclose=()=>{o.current=setTimeout(s,3e3)}};return s(),()=>{var a;(a=n.current)==null||a.close(),o.current&&clearTimeout(o.current)}},[e,t])},Ll=()=>{const e=X(),t=M(Pe),[n,o]=c.useState(!1),[s,a]=c.useState(!1),[i,l]=c.useState("files");c.useEffect(()=>{e(gt())},[e]),c.useEffect(()=>{Ne.status().then(u=>{u.installed&&e(_t(u.entryFile??"unknown"))}).catch(()=>{})},[e]),ko(),Nl(t==="installed");const d=async()=>{try{const u=await Ne.uninstall();if(u.success)e(xt("not-installed")),e(yt()),l("files");else throw new Error(u.error??"Ошибка при удалении агента")}catch(u){throw u}};return r.jsxs("div",{className:Qe.container,style:{backgroundColor:L.background},children:[r.jsx(Hr,{onAddAgent:()=>o(!0),onRemoveAgent:()=>a(!0)}),r.jsxs("div",{className:Qe.content,children:[r.jsx(Gr,{mode:i,onModeChange:l}),i==="files"?r.jsxs(r.Fragment,{children:[r.jsx(wo,{}),r.jsx(Xs,{})]}):r.jsx(Xi,{})]}),n&&r.jsx(fl,{onClose:()=>o(!1),onInstalled:()=>{o(!1),l("debug")}}),s&&r.jsx(El,{onClose:()=>a(!1),onConfirm:d})]})};function Bl(){return r.jsx(Zt,{store:Qt,children:r.jsx(kr,{children:r.jsx(er,{children:r.jsx(At,{path:"/",element:r.jsx(Ll,{})})})})})}qt.createRoot(document.getElementById("root")).render(r.jsx(c.StrictMode,{children:r.jsx(Bl,{})}));
|
package/client/dist/index.html
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
7
|
<title>codetraxis</title>
|
|
8
|
-
<script type="module" crossorigin src="/assets/index-
|
|
8
|
+
<script type="module" crossorigin src="/assets/index-DxucfvnK.js"></script>
|
|
9
9
|
<link rel="modulepreload" crossorigin href="/assets/react-vendor-BhKDh-5n.js">
|
|
10
10
|
<link rel="modulepreload" crossorigin href="/assets/axios-vendor-B_3Om2-t.js">
|
|
11
11
|
<link rel="modulepreload" crossorigin href="/assets/redux-vendor-D-3X9xqH.js">
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* codetraxis debug agent — entry point.
|
|
3
|
+
* __PORT__ is replaced at install time with the actual server port.
|
|
4
|
+
* __XHR_LINE__ is replaced with the appropriate XHR setup line (with/without comment).
|
|
5
|
+
*/
|
|
6
|
+
import { createTreeViewerBridge } from "./shared";
|
|
7
|
+
import { setupConsoleInterceptor } from "./interceptors/consoleInterceptor";
|
|
8
|
+
import { setupFetchInterceptor } from "./interceptors/fetchInterceptor";
|
|
9
|
+
import { setupXhrInterceptor } from "./interceptors/xhrInterceptor";
|
|
10
|
+
|
|
11
|
+
export const treeViewerBridge = createTreeViewerBridge("__PORT__");
|
|
12
|
+
|
|
13
|
+
setupConsoleInterceptor(treeViewerBridge);
|
|
14
|
+
setupFetchInterceptor(treeViewerBridge);
|
|
15
|
+
// @ts-ignore
|
|
16
|
+
__XHR_LINE__
|
|
17
|
+
|
|
18
|
+
// ─── Auto-attach default axios instance ──────────────────────────────────────
|
|
19
|
+
// If the project uses axios, we attach interceptors to the default instance.
|
|
20
|
+
// For axios.create() instances, call attachAxios(instance) manually.
|
|
21
|
+
try {
|
|
22
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
23
|
+
const axiosModule = require("axios");
|
|
24
|
+
const axiosInstance = axiosModule?.default ?? axiosModule;
|
|
25
|
+
if (axiosInstance?.interceptors) {
|
|
26
|
+
attachAxios(axiosInstance);
|
|
27
|
+
}
|
|
28
|
+
} catch { /* axios not installed — skip */ }
|
|
29
|
+
|
|
30
|
+
// ─── attachAxios — for axios.create() instances ───────────────────────────────
|
|
31
|
+
// Usage: import { attachAxios } from "./codetraxisAgent";
|
|
32
|
+
// attachAxios(myAxiosInstance);
|
|
33
|
+
export function attachAxios(instance: any): void {
|
|
34
|
+
if (!instance?.interceptors) return;
|
|
35
|
+
|
|
36
|
+
const INSTALLED_KEY = "__tv_axios_installed__";
|
|
37
|
+
if (instance[INSTALLED_KEY]) return;
|
|
38
|
+
instance[INSTALLED_KEY] = true;
|
|
39
|
+
|
|
40
|
+
const REQ_ID_KEY = "__tv_req_id__";
|
|
41
|
+
const REQ_START_KEY = "__tv_req_start__";
|
|
42
|
+
|
|
43
|
+
const joinUrl = (base?: string, url?: string) => {
|
|
44
|
+
if (!base) return url || "";
|
|
45
|
+
if (!url) return base;
|
|
46
|
+
try { return new URL(url, base).toString(); } catch { return `${base}${url}`; }
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
const normalizeHeaders = (h: unknown): Record<string, string> | undefined => {
|
|
50
|
+
if (!h) return undefined;
|
|
51
|
+
try {
|
|
52
|
+
if (typeof (h as any).toJSON === "function") return (h as any).toJSON() as Record<string, string>;
|
|
53
|
+
return { ...(h as Record<string, string>) };
|
|
54
|
+
} catch { return undefined; }
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
instance.interceptors.request.use(
|
|
58
|
+
(config: any) => {
|
|
59
|
+
const id = treeViewerBridge.uid();
|
|
60
|
+
const start = Date.now();
|
|
61
|
+
config[REQ_ID_KEY] = id;
|
|
62
|
+
config[REQ_START_KEY] = start;
|
|
63
|
+
treeViewerBridge.send({
|
|
64
|
+
id, type: "network", transport: "axios",
|
|
65
|
+
method: (config.method || "get").toUpperCase(),
|
|
66
|
+
url: joinUrl(config.baseURL, config.url),
|
|
67
|
+
requestHeaders: normalizeHeaders(config.headers),
|
|
68
|
+
requestBody: treeViewerBridge.safeSerialize(config.data),
|
|
69
|
+
state: "pending", timestamp: start,
|
|
70
|
+
});
|
|
71
|
+
return config;
|
|
72
|
+
},
|
|
73
|
+
(error: any) => {
|
|
74
|
+
treeViewerBridge.send({
|
|
75
|
+
id: treeViewerBridge.uid(), type: "network", transport: "axios",
|
|
76
|
+
state: "error", timestamp: Date.now(),
|
|
77
|
+
error: treeViewerBridge.safeSerialize(error),
|
|
78
|
+
});
|
|
79
|
+
return Promise.reject(error);
|
|
80
|
+
},
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
instance.interceptors.response.use(
|
|
84
|
+
(response: any) => {
|
|
85
|
+
const id = response.config[REQ_ID_KEY] || treeViewerBridge.uid();
|
|
86
|
+
const start = response.config[REQ_START_KEY] || Date.now();
|
|
87
|
+
treeViewerBridge.send({
|
|
88
|
+
id, type: "network", transport: "axios",
|
|
89
|
+
method: (response.config.method || "get").toUpperCase(),
|
|
90
|
+
url: joinUrl(response.config.baseURL, response.config.url),
|
|
91
|
+
status: response.status,
|
|
92
|
+
requestHeaders: normalizeHeaders(response.config.headers),
|
|
93
|
+
requestBody: treeViewerBridge.safeSerialize(response.config.data),
|
|
94
|
+
responseHeaders: normalizeHeaders(response.headers),
|
|
95
|
+
responseBody: treeViewerBridge.safeSerialize(response.data),
|
|
96
|
+
state: "success", duration: Date.now() - start, timestamp: start,
|
|
97
|
+
});
|
|
98
|
+
return response;
|
|
99
|
+
},
|
|
100
|
+
(error: any) => {
|
|
101
|
+
const cfg = error?.config || {};
|
|
102
|
+
const id = cfg[REQ_ID_KEY] || treeViewerBridge.uid();
|
|
103
|
+
const start = cfg[REQ_START_KEY] || Date.now();
|
|
104
|
+
treeViewerBridge.send({
|
|
105
|
+
id, type: "network", transport: "axios",
|
|
106
|
+
method: (cfg.method || "get").toUpperCase(),
|
|
107
|
+
url: joinUrl(cfg.baseURL, cfg.url),
|
|
108
|
+
status: error?.response?.status,
|
|
109
|
+
requestHeaders: normalizeHeaders(cfg.headers),
|
|
110
|
+
requestBody: treeViewerBridge.safeSerialize(cfg.data),
|
|
111
|
+
responseHeaders: normalizeHeaders(error?.response?.headers),
|
|
112
|
+
responseBody: treeViewerBridge.safeSerialize(error?.response?.data),
|
|
113
|
+
state: "error", duration: Date.now() - start, timestamp: start,
|
|
114
|
+
error: treeViewerBridge.safeSerialize({ message: error?.message, code: error?.code, name: error?.name }),
|
|
115
|
+
});
|
|
116
|
+
return Promise.reject(error);
|
|
117
|
+
},
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// ─── attachSocketIO — for socket.io-client instances ─────────────────────────
|
|
122
|
+
// React Native uses socket.io which doesn't go through globalThis.WebSocket.
|
|
123
|
+
// Usage: import { attachSocketIO } from "./codetraxisAgent";
|
|
124
|
+
// attachSocketIO(socket); // call after getChatSocket() or io()
|
|
125
|
+
export function attachSocketIO(socket: any): void {
|
|
126
|
+
if (!socket) return;
|
|
127
|
+
|
|
128
|
+
const INSTALLED_KEY = "__tv_sio_installed__";
|
|
129
|
+
if (socket[INSTALLED_KEY]) return;
|
|
130
|
+
socket[INSTALLED_KEY] = true;
|
|
131
|
+
|
|
132
|
+
const url: string = socket.io?.uri ?? socket.nsp ?? "socket.io";
|
|
133
|
+
|
|
134
|
+
// ── Incoming events ──────────────────────────────────────────────────────
|
|
135
|
+
socket.onAny((event: string, ...args: unknown[]) => {
|
|
136
|
+
treeViewerBridge.send({
|
|
137
|
+
id: treeViewerBridge.uid(),
|
|
138
|
+
type: "network",
|
|
139
|
+
transport: "websocket",
|
|
140
|
+
url,
|
|
141
|
+
method: "MESSAGE",
|
|
142
|
+
responseBody: treeViewerBridge.truncate(
|
|
143
|
+
JSON.stringify({ event, data: args.length === 1 ? args[0] : args }),
|
|
144
|
+
),
|
|
145
|
+
state: "success",
|
|
146
|
+
timestamp: Date.now(),
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
// ── Outgoing events ──────────────────────────────────────────────────────
|
|
151
|
+
const origEmit = socket.emit.bind(socket);
|
|
152
|
+
socket.emit = (event: string, ...args: unknown[]) => {
|
|
153
|
+
if (!["ping", "pong"].includes(event)) {
|
|
154
|
+
treeViewerBridge.send({
|
|
155
|
+
id: treeViewerBridge.uid(),
|
|
156
|
+
type: "network",
|
|
157
|
+
transport: "websocket",
|
|
158
|
+
url,
|
|
159
|
+
method: "SEND",
|
|
160
|
+
requestBody: treeViewerBridge.truncate(
|
|
161
|
+
JSON.stringify({ event, data: args[0] }),
|
|
162
|
+
),
|
|
163
|
+
state: "success",
|
|
164
|
+
timestamp: Date.now(),
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
return origEmit(event, ...args);
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
export {};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* codetraxis agent — console interceptor.
|
|
3
|
+
*/
|
|
4
|
+
import type { TreeViewerBridge } from "../shared";
|
|
5
|
+
|
|
6
|
+
const INSTALLED_KEY = "__tv_console_installed__";
|
|
7
|
+
|
|
8
|
+
export function setupConsoleInterceptor(bridge: TreeViewerBridge): void {
|
|
9
|
+
const g = globalThis as Record<string, any>;
|
|
10
|
+
if (g[INSTALLED_KEY]) return;
|
|
11
|
+
g[INSTALLED_KEY] = true;
|
|
12
|
+
|
|
13
|
+
const original = {
|
|
14
|
+
log: console.log.bind(console),
|
|
15
|
+
info: console.info.bind(console),
|
|
16
|
+
warn: console.warn.bind(console),
|
|
17
|
+
error: console.error.bind(console),
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
(["log", "info", "warn", "error"] as const).forEach(level => {
|
|
21
|
+
// @ts-ignore
|
|
22
|
+
console[level] = (...args: unknown[]) => {
|
|
23
|
+
original[level](...args);
|
|
24
|
+
bridge.send({
|
|
25
|
+
id: bridge.uid(),
|
|
26
|
+
type: "console",
|
|
27
|
+
level,
|
|
28
|
+
args: args.map(a => bridge.safeSerialize(a)),
|
|
29
|
+
timestamp: Date.now(),
|
|
30
|
+
});
|
|
31
|
+
};
|
|
32
|
+
});
|
|
33
|
+
}
|