@auto-engineer/cli 0.9.7 → 0.9.8
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/CHANGELOG.md +10 -0
- package/dist/src/dsl/index.d.ts +5 -1
- package/dist/src/dsl/index.d.ts.map +1 -1
- package/dist/src/dsl/index.js +6 -0
- package/dist/src/dsl/index.js.map +1 -1
- package/dist/src/dsl/types.d.ts +6 -0
- package/dist/src/dsl/types.d.ts.map +1 -1
- package/dist/src/dsl-exports.d.ts +2 -2
- package/dist/src/dsl-exports.d.ts.map +1 -1
- package/dist/src/dsl-exports.js +1 -1
- package/dist/src/dsl-exports.js.map +1 -1
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +8 -8
- package/dist/src/index.js.map +1 -1
- package/dist/src/plugin-loader.d.ts +1 -0
- package/dist/src/plugin-loader.d.ts.map +1 -1
- package/dist/src/plugin-loader.js.map +1 -1
- package/dist/src/server/config-loader.d.ts +2 -17
- package/dist/src/server/config-loader.d.ts.map +1 -1
- package/dist/src/server/config-loader.js +16 -72
- package/dist/src/server/config-loader.js.map +1 -1
- package/dist/src/server/file-syncer/discovery/dts.js +1 -1
- package/dist/src/server/file-syncer/index.js +3 -3
- package/dist/src/server/file-syncer/sync/resolveSyncFileSet.js +3 -3
- package/dist/src/server/http-routes.d.ts.map +1 -1
- package/dist/src/server/http-routes.js +2 -6
- package/dist/src/server/http-routes.js.map +1 -1
- package/dist/src/server/server.js +6 -6
- package/dist/src/utils/analytics.js +1 -1
- package/dist/src/utils/config.js +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +5 -5
- package/dist/src/server/canvas-landing.html +0 -291
- package/dist/src/server/dashboard.html +0 -1774
|
@@ -1,1774 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8">
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
-
<title>Auto Engineer</title>
|
|
7
|
-
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml,%3Csvg width='637' height='637' viewBox='0 0 637 637' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cg clip-path='url(%23clip0_1042_512)'%3E%3Crect width='637' height='637'/%3E%3Cpath d='M693.161 -427.743L-623.632 1532.31L-591.107 1552.06L725.686 -407.988L693.161 -427.743Z' fill='%23EC3F4A'/%3E%3Cpath d='M725.695 -407.962L-591.097 1552.09L-571.511 1563.98L745.281 -396.066L725.695 -407.962Z' fill='%231A1A1A'/%3E%3Cpath d='M745.281 -396.071L-571.511 1563.98L-538.986 1583.73L777.807 -376.315L745.281 -396.071Z' fill='%23FF8A1D'/%3E%3Cpath d='M777.815 -376.302L-538.978 1583.75L-519.391 1595.64L797.402 -364.406L777.815 -376.302Z' fill='%231A1A1A'/%3E%3Cpath d='M797.394 -364.425L-519.399 1595.62L-486.874 1615.38L829.919 -344.67L797.394 -364.425Z' fill='%235EC72D'/%3E%3Cpath d='M829.913 -344.684L-486.879 1615.37L-467.293 1627.26L849.499 -332.787L829.913 -344.684Z' fill='%231A1A1A'/%3E%3Cpath d='M849.467 -332.791L-467.326 1627.26L-434.801 1647.01L881.992 -313.035L849.467 -332.791Z' fill='%2342C3F7'/%3E%3Cpath d='M882 -313.038L-434.792 1647.01L-415.206 1658.91L901.587 -301.142L882 -313.038Z' fill='%231A1A1A'/%3E%3Cpath d='M673.55 -439.635L-643.242 1520.42L-623.656 1532.31L693.136 -427.738L673.55 -439.635Z' fill='%231A1A1A'/%3E%3Cpath d='M512.644 100H121.718C109.652 100 100 109.667 100 121.751V513.277C100 525.361 109.652 535.028 121.718 535.028H512.644C524.71 535.028 534.362 525.361 534.362 513.277V121.751C534.362 109.667 524.71 100 512.644 100Z' fill='white'/%3E%3Cpath d='M413.706 481.86C451.11 481.86 481.274 451.649 481.274 414.189C481.274 376.728 451.11 346.518 413.706 346.518C376.303 346.518 346.139 376.728 346.139 414.189C346.139 451.649 376.303 481.86 413.706 481.86Z' fill='%231A1A1A'/%3E%3Cpath d='M153.089 347.968C153.089 347.243 153.813 346.518 154.537 346.518H287.017C287.741 346.518 288.465 347.243 288.465 347.968V412.98C288.465 413.705 287.741 414.43 287.017 414.43H257.095C256.371 414.43 255.647 415.155 255.647 415.88V480.893C255.647 481.618 254.923 482.343 254.199 482.343H188.321C187.597 482.343 186.873 481.618 186.873 480.893V415.88C186.873 415.155 186.149 414.43 185.425 414.43H154.296C153.572 414.43 152.848 413.705 152.848 412.98V347.968H153.089Z' fill='%231A1A1A'/%3E%3Cpath d='M347.587 153.17C346.863 153.17 346.139 153.895 346.139 154.621V223.017C346.139 259.269 376.303 288.513 413.706 288.513C451.11 288.513 481.274 259.269 481.274 223.017V154.621C481.274 153.895 480.55 153.17 479.826 153.17H347.345H347.587Z' fill='%231A1A1A'/%3E%3Cpath d='M153.33 286.339C152.848 287.306 153.33 288.272 154.537 288.272H286.776C287.742 288.272 288.465 287.306 287.983 286.339L221.863 154.139C221.381 153.172 219.933 153.172 219.45 154.139L153.33 286.339Z' fill='%231A1A1A'/%3E%3C/g%3E%3Cdefs%3E%3CclipPath id='clip0_1042_512'%3E%3Crect width='637' height='637' fill='white'/%3E%3C/clipPath%3E%3C/defs%3E%3C/svg%3E" />
|
|
8
|
-
<style>
|
|
9
|
-
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');
|
|
10
|
-
|
|
11
|
-
* {
|
|
12
|
-
margin: 0;
|
|
13
|
-
padding: 0;
|
|
14
|
-
box-sizing: border-box;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
:root {
|
|
18
|
-
/* Auto Brand Colors */
|
|
19
|
-
--brand-red: #ec3f4a;
|
|
20
|
-
--brand-orange: #ff8a1d;
|
|
21
|
-
--brand-green: #5ec72d;
|
|
22
|
-
--brand-blue: #42c3f7;
|
|
23
|
-
--brand-primary: #0057dd;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/* Dark theme (default) */
|
|
27
|
-
[data-theme="dark"] {
|
|
28
|
-
--bg-primary: #1a1a1a;
|
|
29
|
-
--bg-secondary: #18181b;
|
|
30
|
-
--bg-tertiary: #27272a;
|
|
31
|
-
--bg-hover: #333337;
|
|
32
|
-
--border: #3a3a3d;
|
|
33
|
-
--border-light: #4a4a4d;
|
|
34
|
-
--text-primary: #ffffff;
|
|
35
|
-
--text-secondary: #a1a1aa;
|
|
36
|
-
--text-tertiary: #71717a;
|
|
37
|
-
--accent: #0057dd;
|
|
38
|
-
--accent-hover: #0046b5;
|
|
39
|
-
--success: #5ec72d;
|
|
40
|
-
--error: #ec3f4a;
|
|
41
|
-
--warning: #ff8a1d;
|
|
42
|
-
--code-bg: #0d0e11;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/* Light theme */
|
|
46
|
-
[data-theme="light"] {
|
|
47
|
-
--bg-primary: #fafafa;
|
|
48
|
-
--bg-secondary: #ffffff;
|
|
49
|
-
--bg-tertiary: #f4f4f5;
|
|
50
|
-
--bg-hover: #e4e4e7;
|
|
51
|
-
--border: #e4e4e7;
|
|
52
|
-
--border-light: #d4d4d8;
|
|
53
|
-
--text-primary: #18181b;
|
|
54
|
-
--text-secondary: #52525b;
|
|
55
|
-
--text-tertiary: #71717a;
|
|
56
|
-
--accent: #0057dd;
|
|
57
|
-
--accent-hover: #0046b5;
|
|
58
|
-
--success: #5ec72d;
|
|
59
|
-
--error: #ec3f4a;
|
|
60
|
-
--warning: #ff8a1d;
|
|
61
|
-
--code-bg: #f4f4f5;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
body {
|
|
65
|
-
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
66
|
-
background: var(--bg-primary);
|
|
67
|
-
color: var(--text-primary);
|
|
68
|
-
min-height: 100vh;
|
|
69
|
-
font-size: 14px;
|
|
70
|
-
line-height: 1.6;
|
|
71
|
-
-webkit-font-smoothing: antialiased;
|
|
72
|
-
-moz-osx-font-smoothing: grayscale;
|
|
73
|
-
transition: background-color 0.3s ease, color 0.3s ease;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
/* Header */
|
|
77
|
-
.header {
|
|
78
|
-
background: var(--bg-secondary);
|
|
79
|
-
border-bottom: 1px solid var(--border);
|
|
80
|
-
padding: 0 24px;
|
|
81
|
-
height: 56px;
|
|
82
|
-
display: flex;
|
|
83
|
-
align-items: center;
|
|
84
|
-
justify-content: space-between;
|
|
85
|
-
position: relative;
|
|
86
|
-
transition: background-color 0.3s ease;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
.header-logo {
|
|
90
|
-
display: flex;
|
|
91
|
-
align-items: center;
|
|
92
|
-
gap: 12px;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
.logo-mark {
|
|
96
|
-
width: 40px;
|
|
97
|
-
height: 40px;
|
|
98
|
-
display: flex;
|
|
99
|
-
align-items: center;
|
|
100
|
-
justify-content: center;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
.logo-mark svg {
|
|
104
|
-
width: 40px;
|
|
105
|
-
height: 40px;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
.logo-text {
|
|
109
|
-
font-size: 18px;
|
|
110
|
-
font-weight: 600;
|
|
111
|
-
color: var(--text-primary);
|
|
112
|
-
letter-spacing: -0.02em;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
.header-controls {
|
|
116
|
-
display: flex;
|
|
117
|
-
align-items: center;
|
|
118
|
-
gap: 24px;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
/* Theme switcher dropdown */
|
|
122
|
-
.theme-switcher {
|
|
123
|
-
position: relative;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
.theme-toggle {
|
|
127
|
-
display: flex;
|
|
128
|
-
align-items: center;
|
|
129
|
-
justify-content: center;
|
|
130
|
-
width: 36px;
|
|
131
|
-
height: 36px;
|
|
132
|
-
background: var(--bg-tertiary);
|
|
133
|
-
border: 1px solid var(--border);
|
|
134
|
-
border-radius: 8px;
|
|
135
|
-
cursor: pointer;
|
|
136
|
-
transition: all 0.2s ease;
|
|
137
|
-
padding: 0;
|
|
138
|
-
color: var(--text-secondary);
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
.theme-toggle:hover {
|
|
142
|
-
background: var(--bg-hover);
|
|
143
|
-
border-color: var(--border-light);
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
.theme-toggle:focus {
|
|
147
|
-
outline: none;
|
|
148
|
-
border-color: var(--accent);
|
|
149
|
-
box-shadow: 0 0 0 3px rgba(0, 87, 221, 0.1);
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
.theme-dropdown {
|
|
153
|
-
position: absolute;
|
|
154
|
-
top: calc(100% + 4px);
|
|
155
|
-
right: 0;
|
|
156
|
-
background: var(--bg-secondary);
|
|
157
|
-
border: 1px solid var(--border);
|
|
158
|
-
border-radius: 8px;
|
|
159
|
-
padding: 4px;
|
|
160
|
-
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
|
161
|
-
opacity: 0;
|
|
162
|
-
visibility: hidden;
|
|
163
|
-
transform: translateY(-4px);
|
|
164
|
-
transition: all 0.15s ease;
|
|
165
|
-
z-index: 1000;
|
|
166
|
-
min-width: 140px;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
.theme-dropdown.open {
|
|
170
|
-
opacity: 1;
|
|
171
|
-
visibility: visible;
|
|
172
|
-
transform: translateY(0);
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
.theme-option {
|
|
176
|
-
display: flex;
|
|
177
|
-
align-items: center;
|
|
178
|
-
gap: 10px;
|
|
179
|
-
padding: 8px 12px;
|
|
180
|
-
border: none;
|
|
181
|
-
background: transparent;
|
|
182
|
-
color: var(--text-primary) !important;
|
|
183
|
-
font-size: 12px;
|
|
184
|
-
font-weight: 500;
|
|
185
|
-
cursor: pointer;
|
|
186
|
-
border-radius: 6px;
|
|
187
|
-
transition: all 0.15s ease;
|
|
188
|
-
width: 100%;
|
|
189
|
-
text-align: left;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
.theme-option:hover {
|
|
193
|
-
background: var(--bg-tertiary);
|
|
194
|
-
color: var(--text-primary) !important;
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
.theme-option.active {
|
|
198
|
-
background: var(--bg-tertiary);
|
|
199
|
-
color: var(--text-primary) !important;
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
.theme-icon {
|
|
203
|
-
width: 16px;
|
|
204
|
-
height: 16px;
|
|
205
|
-
flex-shrink: 0;
|
|
206
|
-
color: var(--text-secondary);
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
/* Main layout - split into top and bottom sections */
|
|
210
|
-
.app-layout {
|
|
211
|
-
display: flex;
|
|
212
|
-
flex-direction: column;
|
|
213
|
-
height: calc(100vh - 56px);
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
/* Top section - Command interface (low profile) */
|
|
217
|
-
.command-section {
|
|
218
|
-
background: var(--bg-secondary);
|
|
219
|
-
padding: 16px 24px;
|
|
220
|
-
display: flex;
|
|
221
|
-
flex-direction: column;
|
|
222
|
-
gap: 12px;
|
|
223
|
-
min-height: 60px;
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
/* Command controls row */
|
|
227
|
-
.command-controls {
|
|
228
|
-
display: flex;
|
|
229
|
-
gap: 12px;
|
|
230
|
-
align-items: center;
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
.command-dropdown {
|
|
234
|
-
position: relative;
|
|
235
|
-
min-width: 320px;
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
.command-trigger {
|
|
239
|
-
width: 100%;
|
|
240
|
-
padding: 8px 36px 8px 12px;
|
|
241
|
-
background: var(--bg-tertiary);
|
|
242
|
-
border: 1px solid var(--border);
|
|
243
|
-
border-radius: 6px;
|
|
244
|
-
color: var(--text-primary);
|
|
245
|
-
font-size: 13px;
|
|
246
|
-
font-weight: 500;
|
|
247
|
-
cursor: pointer;
|
|
248
|
-
transition: all 0.15s ease;
|
|
249
|
-
display: flex;
|
|
250
|
-
align-items: center;
|
|
251
|
-
justify-content: space-between;
|
|
252
|
-
min-height: 36px;
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
.command-trigger:hover {
|
|
256
|
-
background: var(--bg-hover);
|
|
257
|
-
border-color: var(--border-light);
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
.command-trigger.open {
|
|
261
|
-
border-color: var(--accent);
|
|
262
|
-
box-shadow: 0 0 0 2px rgba(0, 87, 221, 0.1);
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
.command-trigger-text {
|
|
266
|
-
color: var(--text-secondary);
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
.command-trigger.selected .command-trigger-text {
|
|
270
|
-
color: var(--text-primary);
|
|
271
|
-
font-weight: 600;
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
.command-dropdown-icon {
|
|
275
|
-
color: var(--text-tertiary);
|
|
276
|
-
font-size: 10px;
|
|
277
|
-
transition: transform 0.15s ease;
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
.command-trigger.open .command-dropdown-icon {
|
|
281
|
-
transform: rotate(180deg);
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
.command-options {
|
|
285
|
-
position: absolute;
|
|
286
|
-
top: calc(100% + 4px);
|
|
287
|
-
left: 0;
|
|
288
|
-
right: 0;
|
|
289
|
-
background: var(--bg-secondary);
|
|
290
|
-
border: 1px solid var(--border);
|
|
291
|
-
border-radius: 8px;
|
|
292
|
-
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2);
|
|
293
|
-
opacity: 0;
|
|
294
|
-
visibility: hidden;
|
|
295
|
-
transform: translateY(-4px);
|
|
296
|
-
transition: all 0.15s ease;
|
|
297
|
-
z-index: 1000;
|
|
298
|
-
max-height: 300px;
|
|
299
|
-
overflow-y: auto;
|
|
300
|
-
padding: 4px;
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
.command-options.open {
|
|
304
|
-
opacity: 1;
|
|
305
|
-
visibility: visible;
|
|
306
|
-
transform: translateY(0);
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
.command-option {
|
|
310
|
-
display: flex;
|
|
311
|
-
flex-direction: column;
|
|
312
|
-
padding: 12px 12px 12px 20px;
|
|
313
|
-
margin: 2px 0;
|
|
314
|
-
background: transparent;
|
|
315
|
-
border: none;
|
|
316
|
-
border-radius: 6px;
|
|
317
|
-
cursor: pointer;
|
|
318
|
-
transition: all 0.15s ease;
|
|
319
|
-
width: 100%;
|
|
320
|
-
text-align: left;
|
|
321
|
-
gap: 2px;
|
|
322
|
-
position: relative;
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
.command-option::before {
|
|
326
|
-
content: '';
|
|
327
|
-
position: absolute;
|
|
328
|
-
left: 4px;
|
|
329
|
-
top: 50%;
|
|
330
|
-
transform: translateY(-50%);
|
|
331
|
-
width: 6px;
|
|
332
|
-
height: 6px;
|
|
333
|
-
background: #42c3f7;
|
|
334
|
-
border-radius: 2px;
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
.command-option:hover {
|
|
338
|
-
background: var(--bg-hover);
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
.command-option.selected {
|
|
342
|
-
background: var(--bg-tertiary);
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
.command-option-name {
|
|
346
|
-
font-size: 13px;
|
|
347
|
-
font-weight: 600;
|
|
348
|
-
color: var(--text-primary);
|
|
349
|
-
font-family: 'SF Mono', 'Monaco', 'Inconsolata', 'Fira Code', monospace;
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
.command-option-org {
|
|
353
|
-
font-size: 11px;
|
|
354
|
-
color: var(--text-secondary);
|
|
355
|
-
font-weight: 500;
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
.command-option-package {
|
|
359
|
-
font-size: 11px;
|
|
360
|
-
color: var(--text-tertiary);
|
|
361
|
-
font-weight: 400;
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
.request-id-input {
|
|
365
|
-
padding: 8px 12px;
|
|
366
|
-
background: var(--bg-tertiary);
|
|
367
|
-
border: 1px solid var(--border);
|
|
368
|
-
border-radius: 6px;
|
|
369
|
-
color: var(--text-primary);
|
|
370
|
-
font-size: 12px;
|
|
371
|
-
width: 200px;
|
|
372
|
-
height: 36px;
|
|
373
|
-
box-sizing: border-box;
|
|
374
|
-
transition: all 0.15s ease;
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
.request-id-input:focus {
|
|
378
|
-
outline: none;
|
|
379
|
-
border-color: var(--accent);
|
|
380
|
-
background: var(--bg-secondary);
|
|
381
|
-
box-shadow: 0 0 0 2px rgba(0, 87, 221, 0.1);
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
.send-button {
|
|
385
|
-
padding: 8px 20px;
|
|
386
|
-
background: var(--accent);
|
|
387
|
-
color: white;
|
|
388
|
-
border: none;
|
|
389
|
-
border-radius: 6px;
|
|
390
|
-
font-size: 12px;
|
|
391
|
-
font-weight: 600;
|
|
392
|
-
cursor: pointer;
|
|
393
|
-
height: 36px;
|
|
394
|
-
box-sizing: border-box;
|
|
395
|
-
transition: all 0.15s ease;
|
|
396
|
-
text-transform: uppercase;
|
|
397
|
-
letter-spacing: 0.05em;
|
|
398
|
-
}
|
|
399
|
-
|
|
400
|
-
.send-button:hover:not(:disabled) {
|
|
401
|
-
background: var(--accent-hover);
|
|
402
|
-
transform: translateY(-1px);
|
|
403
|
-
box-shadow: 0 2px 8px rgba(0, 87, 221, 0.3);
|
|
404
|
-
}
|
|
405
|
-
|
|
406
|
-
.send-button:disabled {
|
|
407
|
-
opacity: 0.5;
|
|
408
|
-
cursor: not-allowed;
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
.response-status {
|
|
412
|
-
display: flex;
|
|
413
|
-
align-items: center;
|
|
414
|
-
gap: 8px;
|
|
415
|
-
font-size: 11px;
|
|
416
|
-
font-weight: 600;
|
|
417
|
-
text-transform: uppercase;
|
|
418
|
-
letter-spacing: 0.05em;
|
|
419
|
-
}
|
|
420
|
-
|
|
421
|
-
.status-dot {
|
|
422
|
-
width: 6px;
|
|
423
|
-
height: 6px;
|
|
424
|
-
border-radius: 50%;
|
|
425
|
-
background: var(--text-tertiary);
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
.status-dot.success {
|
|
429
|
-
background: var(--success);
|
|
430
|
-
box-shadow: 0 0 6px rgba(94, 199, 45, 0.5);
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
.status-dot.error {
|
|
434
|
-
background: var(--error);
|
|
435
|
-
box-shadow: 0 0 6px rgba(236, 63, 74, 0.5);
|
|
436
|
-
}
|
|
437
|
-
|
|
438
|
-
.request-body {
|
|
439
|
-
flex: 1;
|
|
440
|
-
height: 36px;
|
|
441
|
-
min-height: 36px;
|
|
442
|
-
max-height: 120px;
|
|
443
|
-
padding: 8px 12px;
|
|
444
|
-
background: var(--bg-tertiary);
|
|
445
|
-
border: 1px solid var(--border);
|
|
446
|
-
border-radius: 6px;
|
|
447
|
-
color: var(--text-primary);
|
|
448
|
-
font-size: 12px;
|
|
449
|
-
font-family: 'SF Mono', 'Monaco', 'Inconsolata', 'Fira Code', monospace;
|
|
450
|
-
resize: vertical;
|
|
451
|
-
box-sizing: border-box;
|
|
452
|
-
transition: all 0.15s ease;
|
|
453
|
-
}
|
|
454
|
-
|
|
455
|
-
.request-body:focus {
|
|
456
|
-
outline: none;
|
|
457
|
-
border-color: var(--accent);
|
|
458
|
-
background: var(--bg-secondary);
|
|
459
|
-
box-shadow: 0 0 0 2px rgba(0, 87, 221, 0.1);
|
|
460
|
-
}
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
/* Bottom section - Messages list */
|
|
464
|
-
.messages-section {
|
|
465
|
-
flex: 1;
|
|
466
|
-
display: flex;
|
|
467
|
-
flex-direction: column;
|
|
468
|
-
overflow: hidden;
|
|
469
|
-
margin-top: 24px;
|
|
470
|
-
border-top: 2px solid var(--border);
|
|
471
|
-
}
|
|
472
|
-
|
|
473
|
-
.messages-header {
|
|
474
|
-
padding: 18px 24px;
|
|
475
|
-
background: var(--bg-primary);
|
|
476
|
-
border-bottom: 1px solid var(--border);
|
|
477
|
-
display: flex;
|
|
478
|
-
justify-content: space-between;
|
|
479
|
-
align-items: center;
|
|
480
|
-
}
|
|
481
|
-
|
|
482
|
-
.messages-title {
|
|
483
|
-
font-size: 14px;
|
|
484
|
-
font-weight: 700;
|
|
485
|
-
text-transform: uppercase;
|
|
486
|
-
letter-spacing: 0.05em;
|
|
487
|
-
color: var(--text-primary);
|
|
488
|
-
display: flex;
|
|
489
|
-
align-items: center;
|
|
490
|
-
gap: 12px;
|
|
491
|
-
}
|
|
492
|
-
|
|
493
|
-
.messages-title span:last-child {
|
|
494
|
-
background: var(--accent);
|
|
495
|
-
color: var(--bg-primary);
|
|
496
|
-
padding: 4px 10px;
|
|
497
|
-
border-radius: 16px;
|
|
498
|
-
font-size: 11px;
|
|
499
|
-
font-weight: 600;
|
|
500
|
-
text-transform: none;
|
|
501
|
-
letter-spacing: normal;
|
|
502
|
-
}
|
|
503
|
-
|
|
504
|
-
.messages-controls {
|
|
505
|
-
display: flex;
|
|
506
|
-
gap: 8px;
|
|
507
|
-
}
|
|
508
|
-
|
|
509
|
-
.button-small {
|
|
510
|
-
padding: 6px 12px;
|
|
511
|
-
background: var(--bg-secondary);
|
|
512
|
-
border: 1px solid var(--border);
|
|
513
|
-
border-radius: 4px;
|
|
514
|
-
font-size: 11px;
|
|
515
|
-
font-weight: 500;
|
|
516
|
-
color: var(--text-primary);
|
|
517
|
-
cursor: pointer;
|
|
518
|
-
transition: all 0.15s ease;
|
|
519
|
-
}
|
|
520
|
-
|
|
521
|
-
.button-small:hover {
|
|
522
|
-
background: var(--bg-hover);
|
|
523
|
-
border-color: var(--border-light);
|
|
524
|
-
}
|
|
525
|
-
|
|
526
|
-
/* Message filters */
|
|
527
|
-
.message-filters {
|
|
528
|
-
padding: 16px 24px;
|
|
529
|
-
background: var(--bg-tertiary);
|
|
530
|
-
border-bottom: 2px solid var(--border);
|
|
531
|
-
display: flex;
|
|
532
|
-
gap: 16px;
|
|
533
|
-
flex-wrap: wrap;
|
|
534
|
-
align-items: center;
|
|
535
|
-
}
|
|
536
|
-
|
|
537
|
-
.filter-control {
|
|
538
|
-
padding: 6px 8px;
|
|
539
|
-
border: 1px solid var(--border);
|
|
540
|
-
border-radius: 4px;
|
|
541
|
-
background: var(--bg-primary);
|
|
542
|
-
color: var(--text-primary);
|
|
543
|
-
font-size: 11px;
|
|
544
|
-
min-width: 120px;
|
|
545
|
-
}
|
|
546
|
-
|
|
547
|
-
.filter-stats {
|
|
548
|
-
font-size: 10px;
|
|
549
|
-
color: var(--text-tertiary);
|
|
550
|
-
margin-left: auto;
|
|
551
|
-
}
|
|
552
|
-
|
|
553
|
-
/* Messages list */
|
|
554
|
-
.messages-list {
|
|
555
|
-
flex: 1;
|
|
556
|
-
overflow-y: auto;
|
|
557
|
-
display: flex;
|
|
558
|
-
flex-direction: column;
|
|
559
|
-
}
|
|
560
|
-
|
|
561
|
-
.messages-table {
|
|
562
|
-
width: 100%;
|
|
563
|
-
border-collapse: separate;
|
|
564
|
-
border-spacing: 0;
|
|
565
|
-
font-family: 'SF Mono', 'Monaco', 'Inconsolata', 'Fira Code', monospace;
|
|
566
|
-
font-size: 11px;
|
|
567
|
-
table-layout: fixed;
|
|
568
|
-
min-width: 800px;
|
|
569
|
-
}
|
|
570
|
-
|
|
571
|
-
.messages-header-row {
|
|
572
|
-
background: var(--bg-tertiary);
|
|
573
|
-
border-bottom: 2px solid var(--border);
|
|
574
|
-
position: sticky;
|
|
575
|
-
top: 0;
|
|
576
|
-
z-index: 10;
|
|
577
|
-
}
|
|
578
|
-
|
|
579
|
-
.messages-header-cell {
|
|
580
|
-
padding: 8px 6px;
|
|
581
|
-
text-align: left;
|
|
582
|
-
font-weight: 600;
|
|
583
|
-
font-size: 10px;
|
|
584
|
-
text-transform: uppercase;
|
|
585
|
-
letter-spacing: 0.05em;
|
|
586
|
-
color: var(--text-secondary);
|
|
587
|
-
border-right: 1px solid var(--border);
|
|
588
|
-
position: relative;
|
|
589
|
-
user-select: none;
|
|
590
|
-
box-sizing: border-box;
|
|
591
|
-
overflow: hidden;
|
|
592
|
-
}
|
|
593
|
-
|
|
594
|
-
.messages-header-cell:last-child {
|
|
595
|
-
border-right: none;
|
|
596
|
-
}
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
.message-details-row {
|
|
600
|
-
background: var(--code-bg);
|
|
601
|
-
}
|
|
602
|
-
|
|
603
|
-
.message-details {
|
|
604
|
-
padding: 16px;
|
|
605
|
-
background: var(--code-bg);
|
|
606
|
-
border-top: 1px solid var(--border);
|
|
607
|
-
font-family: 'SF Mono', 'Monaco', monospace;
|
|
608
|
-
}
|
|
609
|
-
|
|
610
|
-
.message-data {
|
|
611
|
-
background: var(--bg-primary);
|
|
612
|
-
border: 1px solid var(--border);
|
|
613
|
-
border-radius: 4px;
|
|
614
|
-
padding: 12px;
|
|
615
|
-
font-size: 11px;
|
|
616
|
-
line-height: 1.4;
|
|
617
|
-
color: var(--text-primary);
|
|
618
|
-
max-height: 300px;
|
|
619
|
-
overflow-y: auto;
|
|
620
|
-
white-space: pre-wrap;
|
|
621
|
-
word-break: break-word;
|
|
622
|
-
position: relative;
|
|
623
|
-
}
|
|
624
|
-
|
|
625
|
-
.copy-message-btn {
|
|
626
|
-
position: absolute;
|
|
627
|
-
top: 8px;
|
|
628
|
-
right: 8px;
|
|
629
|
-
padding: 4px 8px;
|
|
630
|
-
background: var(--bg-secondary);
|
|
631
|
-
border: 1px solid var(--border);
|
|
632
|
-
border-radius: 4px;
|
|
633
|
-
font-size: 10px;
|
|
634
|
-
color: var(--text-secondary);
|
|
635
|
-
cursor: pointer;
|
|
636
|
-
transition: all 0.15s ease;
|
|
637
|
-
}
|
|
638
|
-
|
|
639
|
-
.copy-message-btn:hover {
|
|
640
|
-
background: var(--bg-hover);
|
|
641
|
-
color: var(--text-primary);
|
|
642
|
-
}
|
|
643
|
-
|
|
644
|
-
.message-row {
|
|
645
|
-
background: var(--bg-secondary);
|
|
646
|
-
border-bottom: 1px solid var(--border);
|
|
647
|
-
transition: background-color 0.15s ease;
|
|
648
|
-
}
|
|
649
|
-
|
|
650
|
-
.message-row:hover {
|
|
651
|
-
background: var(--bg-hover);
|
|
652
|
-
}
|
|
653
|
-
|
|
654
|
-
.message-row.expanded {
|
|
655
|
-
background: var(--bg-tertiary);
|
|
656
|
-
}
|
|
657
|
-
|
|
658
|
-
.message-cell {
|
|
659
|
-
padding: 4px 6px;
|
|
660
|
-
border-right: 1px solid var(--border);
|
|
661
|
-
vertical-align: top;
|
|
662
|
-
font-size: 11px;
|
|
663
|
-
box-sizing: border-box;
|
|
664
|
-
overflow: hidden;
|
|
665
|
-
word-wrap: break-word;
|
|
666
|
-
line-height: 1.3;
|
|
667
|
-
}
|
|
668
|
-
|
|
669
|
-
.message-cell:last-child {
|
|
670
|
-
border-right: none;
|
|
671
|
-
}
|
|
672
|
-
|
|
673
|
-
.expand-cell {
|
|
674
|
-
width: 30px;
|
|
675
|
-
text-align: center;
|
|
676
|
-
cursor: pointer;
|
|
677
|
-
user-select: none;
|
|
678
|
-
}
|
|
679
|
-
|
|
680
|
-
.expand-btn {
|
|
681
|
-
width: 16px;
|
|
682
|
-
height: 16px;
|
|
683
|
-
display: inline-flex;
|
|
684
|
-
align-items: center;
|
|
685
|
-
justify-content: center;
|
|
686
|
-
background: var(--bg-primary);
|
|
687
|
-
border: 1px solid var(--border);
|
|
688
|
-
border-radius: 3px;
|
|
689
|
-
font-size: 9px;
|
|
690
|
-
font-weight: 600;
|
|
691
|
-
color: var(--text-secondary);
|
|
692
|
-
transition: all 0.15s ease;
|
|
693
|
-
}
|
|
694
|
-
|
|
695
|
-
.expand-btn:hover {
|
|
696
|
-
background: var(--bg-hover);
|
|
697
|
-
color: var(--text-primary);
|
|
698
|
-
}
|
|
699
|
-
|
|
700
|
-
.type-cell {
|
|
701
|
-
width: 80px;
|
|
702
|
-
text-align: center;
|
|
703
|
-
}
|
|
704
|
-
|
|
705
|
-
.message-type {
|
|
706
|
-
font-size: 9px;
|
|
707
|
-
font-weight: 600;
|
|
708
|
-
text-transform: uppercase;
|
|
709
|
-
letter-spacing: 0.05em;
|
|
710
|
-
padding: 2px 6px;
|
|
711
|
-
border-radius: 3px;
|
|
712
|
-
display: inline-block;
|
|
713
|
-
min-width: 60px;
|
|
714
|
-
text-align: center;
|
|
715
|
-
}
|
|
716
|
-
|
|
717
|
-
.message-type.command {
|
|
718
|
-
color: #42c3f7;
|
|
719
|
-
background: rgba(66, 195, 247, 0.1);
|
|
720
|
-
}
|
|
721
|
-
|
|
722
|
-
.message-type.event {
|
|
723
|
-
color: #ff8a1d;
|
|
724
|
-
background: rgba(255, 138, 29, 0.1);
|
|
725
|
-
}
|
|
726
|
-
|
|
727
|
-
.name-cell {
|
|
728
|
-
min-width: 120px;
|
|
729
|
-
max-width: 150px;
|
|
730
|
-
}
|
|
731
|
-
|
|
732
|
-
.message-name {
|
|
733
|
-
font-weight: 600;
|
|
734
|
-
color: var(--text-primary);
|
|
735
|
-
}
|
|
736
|
-
|
|
737
|
-
.id-cell {
|
|
738
|
-
width: 100px;
|
|
739
|
-
font-size: 10px;
|
|
740
|
-
color: var(--text-tertiary);
|
|
741
|
-
}
|
|
742
|
-
|
|
743
|
-
.position-cell {
|
|
744
|
-
width: 60px;
|
|
745
|
-
text-align: center;
|
|
746
|
-
font-size: 10px;
|
|
747
|
-
color: var(--text-secondary);
|
|
748
|
-
}
|
|
749
|
-
|
|
750
|
-
.time-cell {
|
|
751
|
-
width: 80px;
|
|
752
|
-
text-align: right;
|
|
753
|
-
font-size: 10px;
|
|
754
|
-
color: var(--text-tertiary);
|
|
755
|
-
}
|
|
756
|
-
|
|
757
|
-
.message-type-icon {
|
|
758
|
-
width: 12px;
|
|
759
|
-
height: 12px;
|
|
760
|
-
display: flex;
|
|
761
|
-
align-items: center;
|
|
762
|
-
justify-content: center;
|
|
763
|
-
font-size: 8px;
|
|
764
|
-
flex-shrink: 0;
|
|
765
|
-
}
|
|
766
|
-
|
|
767
|
-
.message-type {
|
|
768
|
-
min-width: 50px;
|
|
769
|
-
font-size: 10px;
|
|
770
|
-
font-weight: 600;
|
|
771
|
-
text-transform: uppercase;
|
|
772
|
-
letter-spacing: 0.05em;
|
|
773
|
-
flex-shrink: 0;
|
|
774
|
-
}
|
|
775
|
-
|
|
776
|
-
.message-type.command {
|
|
777
|
-
color: #42c3f7;
|
|
778
|
-
}
|
|
779
|
-
|
|
780
|
-
.message-type.event {
|
|
781
|
-
color: #ff8a1d;
|
|
782
|
-
}
|
|
783
|
-
|
|
784
|
-
.message-name {
|
|
785
|
-
min-width: 120px;
|
|
786
|
-
font-weight: 500;
|
|
787
|
-
color: var(--text-primary);
|
|
788
|
-
flex-shrink: 0;
|
|
789
|
-
}
|
|
790
|
-
|
|
791
|
-
.message-meta {
|
|
792
|
-
display: flex;
|
|
793
|
-
gap: 12px;
|
|
794
|
-
align-items: center;
|
|
795
|
-
font-size: 10px;
|
|
796
|
-
color: var(--text-tertiary);
|
|
797
|
-
flex: 1;
|
|
798
|
-
}
|
|
799
|
-
|
|
800
|
-
.message-timestamp {
|
|
801
|
-
font-size: 10px;
|
|
802
|
-
color: var(--text-tertiary);
|
|
803
|
-
min-width: 80px;
|
|
804
|
-
text-align: right;
|
|
805
|
-
flex-shrink: 0;
|
|
806
|
-
}
|
|
807
|
-
|
|
808
|
-
.message-details {
|
|
809
|
-
display: none;
|
|
810
|
-
padding: 16px;
|
|
811
|
-
background: var(--code-bg);
|
|
812
|
-
border-top: 1px solid var(--border);
|
|
813
|
-
}
|
|
814
|
-
|
|
815
|
-
.message-item.expanded .message-details {
|
|
816
|
-
display: block;
|
|
817
|
-
}
|
|
818
|
-
|
|
819
|
-
.message-ids {
|
|
820
|
-
display: grid;
|
|
821
|
-
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
|
822
|
-
gap: 12px;
|
|
823
|
-
margin-bottom: 12px;
|
|
824
|
-
font-size: 10px;
|
|
825
|
-
color: var(--text-tertiary);
|
|
826
|
-
font-family: 'SF Mono', 'Monaco', monospace;
|
|
827
|
-
}
|
|
828
|
-
|
|
829
|
-
.message-id {
|
|
830
|
-
display: flex;
|
|
831
|
-
flex-direction: column;
|
|
832
|
-
gap: 2px;
|
|
833
|
-
}
|
|
834
|
-
|
|
835
|
-
.message-id-label {
|
|
836
|
-
color: var(--text-secondary);
|
|
837
|
-
font-weight: 600;
|
|
838
|
-
text-transform: uppercase;
|
|
839
|
-
letter-spacing: 0.05em;
|
|
840
|
-
}
|
|
841
|
-
|
|
842
|
-
.message-data {
|
|
843
|
-
background: var(--bg-primary);
|
|
844
|
-
border: 1px solid var(--border);
|
|
845
|
-
border-radius: 4px;
|
|
846
|
-
padding: 12px;
|
|
847
|
-
font-family: 'SF Mono', 'Monaco', monospace;
|
|
848
|
-
font-size: 11px;
|
|
849
|
-
line-height: 1.4;
|
|
850
|
-
color: var(--text-primary);
|
|
851
|
-
max-height: 300px;
|
|
852
|
-
overflow-y: auto;
|
|
853
|
-
white-space: pre-wrap;
|
|
854
|
-
word-break: break-word;
|
|
855
|
-
}
|
|
856
|
-
|
|
857
|
-
.empty {
|
|
858
|
-
padding: 32px;
|
|
859
|
-
text-align: center;
|
|
860
|
-
color: var(--text-tertiary);
|
|
861
|
-
font-size: 12px;
|
|
862
|
-
}
|
|
863
|
-
|
|
864
|
-
/* Scrollbar styling */
|
|
865
|
-
::-webkit-scrollbar {
|
|
866
|
-
width: 8px;
|
|
867
|
-
height: 8px;
|
|
868
|
-
}
|
|
869
|
-
|
|
870
|
-
::-webkit-scrollbar-track {
|
|
871
|
-
background: var(--bg-secondary);
|
|
872
|
-
}
|
|
873
|
-
|
|
874
|
-
::-webkit-scrollbar-thumb {
|
|
875
|
-
background: var(--border-light);
|
|
876
|
-
border-radius: 4px;
|
|
877
|
-
}
|
|
878
|
-
|
|
879
|
-
::-webkit-scrollbar-thumb:hover {
|
|
880
|
-
background: var(--text-tertiary);
|
|
881
|
-
}
|
|
882
|
-
</style>
|
|
883
|
-
</head>
|
|
884
|
-
<body data-theme="dark">
|
|
885
|
-
<div class="header">
|
|
886
|
-
<div class="header-logo">
|
|
887
|
-
<div class="logo-mark" id="logoMark">
|
|
888
|
-
</div>
|
|
889
|
-
<div>
|
|
890
|
-
<span class="logo-text">auto engineer</span>
|
|
891
|
-
</div>
|
|
892
|
-
</div>
|
|
893
|
-
<div class="header-controls">
|
|
894
|
-
<div class="theme-switcher">
|
|
895
|
-
<button class="theme-toggle" id="themeToggle" onclick="toggleThemeDropdown()">
|
|
896
|
-
<svg class="theme-icon" id="currentThemeIcon" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
897
|
-
<!-- Icon will be set based on current theme -->
|
|
898
|
-
</svg>
|
|
899
|
-
</button>
|
|
900
|
-
<div class="theme-dropdown" id="themeDropdown">
|
|
901
|
-
<button class="theme-option" onclick="setTheme('light')">
|
|
902
|
-
<svg class="theme-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
903
|
-
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z" />
|
|
904
|
-
</svg>
|
|
905
|
-
<span>Light</span>
|
|
906
|
-
</button>
|
|
907
|
-
<button class="theme-option" onclick="setTheme('dark')">
|
|
908
|
-
<svg class="theme-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
909
|
-
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z" />
|
|
910
|
-
</svg>
|
|
911
|
-
<span>Dark</span>
|
|
912
|
-
</button>
|
|
913
|
-
<button class="theme-option" onclick="setTheme('system')">
|
|
914
|
-
<svg class="theme-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
915
|
-
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9.75 17L9 20l-1 1h8l-1-1-.75-3M3 13h18M5 17h14a2 2 0 002-2V5a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" />
|
|
916
|
-
</svg>
|
|
917
|
-
<span>System</span>
|
|
918
|
-
</button>
|
|
919
|
-
</div>
|
|
920
|
-
</div>
|
|
921
|
-
</div>
|
|
922
|
-
</div>
|
|
923
|
-
|
|
924
|
-
<div class="app-layout">
|
|
925
|
-
<!-- Top section: Command interface -->
|
|
926
|
-
<div class="command-section">
|
|
927
|
-
<!-- Command controls row -->
|
|
928
|
-
<div class="command-controls">
|
|
929
|
-
<div class="command-dropdown">
|
|
930
|
-
<div class="command-trigger" id="commandTrigger" onclick="toggleCommandDropdown()">
|
|
931
|
-
<span class="command-trigger-text">Select a command...</span>
|
|
932
|
-
<span class="command-dropdown-icon">▼</span>
|
|
933
|
-
</div>
|
|
934
|
-
<div class="command-options" id="commandOptions">
|
|
935
|
-
<!-- Command options will be populated by JavaScript -->
|
|
936
|
-
</div>
|
|
937
|
-
</div>
|
|
938
|
-
|
|
939
|
-
<textarea class="request-body" id="requestBody" placeholder='Request body (JSON) Example: {"key": "value"}'>{}</textarea>
|
|
940
|
-
|
|
941
|
-
<input type="text" class="request-id-input" id="requestIdInput" placeholder="Request ID (optional)" />
|
|
942
|
-
|
|
943
|
-
<button class="send-button" onclick="sendRequest()" id="sendButton" disabled>
|
|
944
|
-
Send
|
|
945
|
-
</button>
|
|
946
|
-
|
|
947
|
-
<div class="response-status">
|
|
948
|
-
<div class="status-dot" id="statusDot"></div>
|
|
949
|
-
<span id="statusText">Ready</span>
|
|
950
|
-
<span id="responseTime"></span>
|
|
951
|
-
</div>
|
|
952
|
-
</div>
|
|
953
|
-
</div>
|
|
954
|
-
|
|
955
|
-
<!-- Bottom section: Messages list -->
|
|
956
|
-
<div class="messages-section">
|
|
957
|
-
<div class="messages-header">
|
|
958
|
-
<div class="messages-title">
|
|
959
|
-
<span>Messages</span>
|
|
960
|
-
<span id="messageCount">0</span>
|
|
961
|
-
</div>
|
|
962
|
-
<div class="messages-controls">
|
|
963
|
-
<button class="button-small" onclick="clearFilters()">Clear Filters</button>
|
|
964
|
-
</div>
|
|
965
|
-
</div>
|
|
966
|
-
|
|
967
|
-
<div class="message-filters">
|
|
968
|
-
<select class="filter-control" id="messageTypeFilter" onchange="applyFilters()">
|
|
969
|
-
<option value="">All Types</option>
|
|
970
|
-
<option value="command">Commands</option>
|
|
971
|
-
<option value="event">Events</option>
|
|
972
|
-
</select>
|
|
973
|
-
|
|
974
|
-
<select class="filter-control" id="sessionFilter" onchange="applyFilters()">
|
|
975
|
-
<option value="">All Sessions</option>
|
|
976
|
-
</select>
|
|
977
|
-
|
|
978
|
-
<input type="text" class="filter-control" id="messageNameFilter" placeholder="Message name..." onchange="applyFilters()" />
|
|
979
|
-
|
|
980
|
-
<input type="text" class="filter-control" id="correlationIdFilter" placeholder="Correlation ID..." onchange="applyFilters()" />
|
|
981
|
-
|
|
982
|
-
<div class="filter-stats" id="filterStats">
|
|
983
|
-
Showing all messages
|
|
984
|
-
</div>
|
|
985
|
-
</div>
|
|
986
|
-
|
|
987
|
-
<div class="messages-list" id="messagesList">
|
|
988
|
-
<table class="messages-table">
|
|
989
|
-
<colgroup>
|
|
990
|
-
<col style="width: 40px;">
|
|
991
|
-
<col style="width: 80px;">
|
|
992
|
-
<col style="width: 180px;">
|
|
993
|
-
<col style="width: 120px;">
|
|
994
|
-
<col style="width: 120px;">
|
|
995
|
-
<col style="width: 120px;">
|
|
996
|
-
<col style="width: 60px;">
|
|
997
|
-
<col style="width: 90px;">
|
|
998
|
-
</colgroup>
|
|
999
|
-
<thead>
|
|
1000
|
-
<tr class="messages-header-row">
|
|
1001
|
-
<th class="messages-header-cell expand-cell" data-column="expand">
|
|
1002
|
-
</th>
|
|
1003
|
-
<th class="messages-header-cell type-cell" data-column="type">
|
|
1004
|
-
Type
|
|
1005
|
-
</th>
|
|
1006
|
-
<th class="messages-header-cell name-cell" data-column="name">
|
|
1007
|
-
Message
|
|
1008
|
-
</th>
|
|
1009
|
-
<th class="messages-header-cell id-cell" data-column="requestId">
|
|
1010
|
-
Request ID
|
|
1011
|
-
</th>
|
|
1012
|
-
<th class="messages-header-cell id-cell" data-column="correlationId">
|
|
1013
|
-
Correlation ID
|
|
1014
|
-
</th>
|
|
1015
|
-
<th class="messages-header-cell id-cell" data-column="sessionId">
|
|
1016
|
-
Session ID
|
|
1017
|
-
</th>
|
|
1018
|
-
<th class="messages-header-cell position-cell" data-column="position">
|
|
1019
|
-
Pos
|
|
1020
|
-
</th>
|
|
1021
|
-
<th class="messages-header-cell time-cell" data-column="time">
|
|
1022
|
-
Time
|
|
1023
|
-
</th>
|
|
1024
|
-
</tr>
|
|
1025
|
-
</thead>
|
|
1026
|
-
<tbody id="messagesTableBody">
|
|
1027
|
-
<tr><td colspan="8" style="text-align: center; padding: 32px; color: var(--text-tertiary);">No messages yet</td></tr>
|
|
1028
|
-
</tbody>
|
|
1029
|
-
</table>
|
|
1030
|
-
</div>
|
|
1031
|
-
</div>
|
|
1032
|
-
</div>
|
|
1033
|
-
|
|
1034
|
-
<script>
|
|
1035
|
-
const API_BASE = window.location.origin;
|
|
1036
|
-
let availableCommands = [];
|
|
1037
|
-
let currentMessages = [];
|
|
1038
|
-
let filteredMessages = [];
|
|
1039
|
-
let availableSessions = [];
|
|
1040
|
-
let currentCommand = null;
|
|
1041
|
-
let responseStartTime;
|
|
1042
|
-
let expandedMessages = new Set();
|
|
1043
|
-
let isResizing = false;
|
|
1044
|
-
let currentColumn = null;
|
|
1045
|
-
let startX = 0;
|
|
1046
|
-
let startWidth = 0;
|
|
1047
|
-
|
|
1048
|
-
// Default column widths (percentages for better responsive behavior)
|
|
1049
|
-
const defaultColumnWidths = {
|
|
1050
|
-
expand: 40,
|
|
1051
|
-
type: 80,
|
|
1052
|
-
name: 180,
|
|
1053
|
-
requestId: 120,
|
|
1054
|
-
correlationId: 120,
|
|
1055
|
-
sessionId: 120,
|
|
1056
|
-
position: 60,
|
|
1057
|
-
time: 90
|
|
1058
|
-
};
|
|
1059
|
-
|
|
1060
|
-
let columnWidths = { ...defaultColumnWidths };
|
|
1061
|
-
|
|
1062
|
-
// Logo SVGs
|
|
1063
|
-
const logoLight = `<svg width="637" height="637" viewBox="0 0 637 637" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
1064
|
-
<g clip-path="url(#clip0_1042_573)">
|
|
1065
|
-
<rect width="637" height="637"/>
|
|
1066
|
-
<path d="M693.161 -427.743L-623.632 1532.31L-591.107 1552.06L725.686 -407.988L693.161 -427.743Z" fill="#EC3F4A"/>
|
|
1067
|
-
<path d="M725.695 -407.962L-591.097 1552.09L-571.511 1563.98L745.281 -396.066L725.695 -407.962Z" fill="white"/>
|
|
1068
|
-
<path d="M745.281 -396.071L-571.511 1563.98L-538.986 1583.73L777.807 -376.315L745.281 -396.071Z" fill="#FF8A1D"/>
|
|
1069
|
-
<path d="M777.815 -376.302L-538.978 1583.75L-519.391 1595.64L797.402 -364.406L777.815 -376.302Z" fill="white"/>
|
|
1070
|
-
<path d="M797.394 -364.425L-519.399 1595.62L-486.874 1615.38L829.919 -344.67L797.394 -364.425Z" fill="#5EC72D"/>
|
|
1071
|
-
<path d="M829.913 -344.684L-486.879 1615.37L-467.293 1627.26L849.499 -332.787L829.913 -344.684Z" fill="white"/>
|
|
1072
|
-
<path d="M849.467 -332.791L-467.326 1627.26L-434.801 1647.01L881.992 -313.035L849.467 -332.791Z" fill="#42C3F7"/>
|
|
1073
|
-
<path d="M882 -313.038L-434.792 1647.01L-415.206 1658.91L901.587 -301.142L882 -313.038Z" fill="white"/>
|
|
1074
|
-
<path d="M673.55 -439.635L-643.242 1520.42L-623.656 1532.31L693.136 -427.738L673.55 -439.635Z" fill="white"/>
|
|
1075
|
-
<path d="M512.644 100H121.718C109.652 100 100 109.667 100 121.751V513.277C100 525.361 109.652 535.028 121.718 535.028H512.644C524.71 535.028 534.362 525.361 534.362 513.277V121.751C534.362 109.667 524.71 100 512.644 100Z" fill="#1A1A1A"/>
|
|
1076
|
-
<path d="M413.706 481.86C451.11 481.86 481.274 451.649 481.274 414.189C481.274 376.728 451.11 346.518 413.706 346.518C376.303 346.518 346.139 376.728 346.139 414.189C346.139 451.649 376.303 481.86 413.706 481.86Z" fill="white"/>
|
|
1077
|
-
<path d="M153.089 347.968C153.089 347.243 153.813 346.518 154.537 346.518H287.017C287.741 346.518 288.465 347.243 288.465 347.968V412.98C288.465 413.705 287.741 414.43 287.017 414.43H257.095C256.371 414.43 255.647 415.155 255.647 415.88V480.893C255.647 481.618 254.923 482.343 254.199 482.343H188.321C187.597 482.343 186.873 481.618 186.873 480.893V415.88C186.873 415.155 186.149 414.43 185.425 414.43H154.296C153.572 414.43 152.848 413.705 152.848 412.98V347.968H153.089Z" fill="white"/>
|
|
1078
|
-
<path d="M347.587 153.17C346.863 153.17 346.139 153.895 346.139 154.621V223.017C346.139 259.269 376.303 288.513 413.706 288.513C451.11 288.513 481.274 259.269 481.274 223.017V154.621C481.274 153.895 480.55 153.17 479.826 153.17H347.345H347.587Z" fill="white"/>
|
|
1079
|
-
<path d="M153.33 286.339C152.848 287.306 153.33 288.272 154.537 288.272H286.776C287.742 288.272 288.465 287.306 287.983 286.339L221.863 154.139C221.381 153.172 219.933 153.172 219.45 154.139L153.33 286.339Z" fill="white"/>
|
|
1080
|
-
</g>
|
|
1081
|
-
<defs>
|
|
1082
|
-
<clipPath id="clip0_1042_573">
|
|
1083
|
-
<rect width="637" height="637" fill="white"/>
|
|
1084
|
-
</clipPath>
|
|
1085
|
-
</defs>
|
|
1086
|
-
</svg>`;
|
|
1087
|
-
|
|
1088
|
-
const logoDark = `<svg width="637" height="637" viewBox="0 0 637 637" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
1089
|
-
<g clip-path="url(#clip0_1042_512)">
|
|
1090
|
-
<rect width="637" height="637"/>
|
|
1091
|
-
<path d="M693.161 -427.743L-623.632 1532.31L-591.107 1552.06L725.686 -407.988L693.161 -427.743Z" fill="#EC3F4A"/>
|
|
1092
|
-
<path d="M725.695 -407.962L-591.097 1552.09L-571.511 1563.98L745.281 -396.066L725.695 -407.962Z" fill="#1A1A1A"/>
|
|
1093
|
-
<path d="M745.281 -396.071L-571.511 1563.98L-538.986 1583.73L777.807 -376.315L745.281 -396.071Z" fill="#FF8A1D"/>
|
|
1094
|
-
<path d="M777.815 -376.302L-538.978 1583.75L-519.391 1595.64L797.402 -364.406L777.815 -376.302Z" fill="#1A1A1A"/>
|
|
1095
|
-
<path d="M797.394 -364.425L-519.399 1595.62L-486.874 1615.38L829.919 -344.67L797.394 -364.425Z" fill="#5EC72D"/>
|
|
1096
|
-
<path d="M829.913 -344.684L-486.879 1615.37L-467.293 1627.26L849.499 -332.787L829.913 -344.684Z" fill="#1A1A1A"/>
|
|
1097
|
-
<path d="M849.467 -332.791L-467.326 1627.26L-434.801 1647.01L881.992 -313.035L849.467 -332.791Z" fill="#42C3F7"/>
|
|
1098
|
-
<path d="M882 -313.038L-434.792 1647.01L-415.206 1658.91L901.587 -301.142L882 -313.038Z" fill="#1A1A1A"/>
|
|
1099
|
-
<path d="M673.55 -439.635L-643.242 1520.42L-623.656 1532.31L693.136 -427.738L673.55 -439.635Z" fill="#1A1A1A"/>
|
|
1100
|
-
<path d="M512.644 100H121.718C109.652 100 100 109.667 100 121.751V513.277C100 525.361 109.652 535.028 121.718 535.028H512.644C524.71 535.028 534.362 525.361 534.362 513.277V121.751C534.362 109.667 524.71 100 512.644 100Z" fill="white"/>
|
|
1101
|
-
<path d="M413.706 481.86C451.11 481.86 481.274 451.649 481.274 414.189C481.274 376.728 451.11 346.518 413.706 346.518C376.303 346.518 346.139 376.728 346.139 414.189C346.139 451.649 376.303 481.86 413.706 481.86Z" fill="#1A1A1A"/>
|
|
1102
|
-
<path d="M153.089 347.968C153.089 347.243 153.813 346.518 154.537 346.518H287.017C287.741 346.518 288.465 347.243 288.465 347.968V412.98C288.465 413.705 287.741 414.43 287.017 414.43H257.095C256.371 414.43 255.647 415.155 255.647 415.88V480.893C255.647 481.618 254.923 482.343 254.199 482.343H188.321C187.597 482.343 186.873 481.618 186.873 480.893V415.88C186.873 415.155 186.149 414.43 185.425 414.43H154.296C153.572 414.43 152.848 413.705 152.848 412.98V347.968H153.089Z" fill="#1A1A1A"/>
|
|
1103
|
-
<path d="M347.587 153.17C346.863 153.17 346.139 153.895 346.139 154.621V223.017C346.139 259.269 376.303 288.513 413.706 288.513C451.11 288.513 481.274 259.269 481.274 223.017V154.621C481.274 153.895 480.55 153.17 479.826 153.17H347.345H347.587Z" fill="#1A1A1A"/>
|
|
1104
|
-
<path d="M153.33 286.339C152.848 287.306 153.33 288.272 154.537 288.272H286.776C287.742 288.272 288.465 287.306 287.983 286.339L221.863 154.139C221.381 153.172 219.933 153.172 219.45 154.139L153.33 286.339Z" fill="#1A1A1A"/>
|
|
1105
|
-
</g>
|
|
1106
|
-
<defs>
|
|
1107
|
-
<clipPath id="clip0_1042_512">
|
|
1108
|
-
<rect width="637" height="637" fill="white"/>
|
|
1109
|
-
</clipPath>
|
|
1110
|
-
</defs>
|
|
1111
|
-
</svg>`;
|
|
1112
|
-
|
|
1113
|
-
// Theme management
|
|
1114
|
-
function getSystemTheme() {
|
|
1115
|
-
return window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
|
|
1116
|
-
}
|
|
1117
|
-
|
|
1118
|
-
function applyTheme(theme) {
|
|
1119
|
-
if (theme === 'system') {
|
|
1120
|
-
theme = getSystemTheme();
|
|
1121
|
-
}
|
|
1122
|
-
document.body.setAttribute('data-theme', theme);
|
|
1123
|
-
|
|
1124
|
-
// Update logo based on theme
|
|
1125
|
-
const logoMark = document.getElementById('logoMark');
|
|
1126
|
-
if (logoMark) {
|
|
1127
|
-
logoMark.innerHTML = theme === 'dark' ? logoDark : logoLight;
|
|
1128
|
-
}
|
|
1129
|
-
}
|
|
1130
|
-
|
|
1131
|
-
function getThemeIcon(theme) {
|
|
1132
|
-
const icons = {
|
|
1133
|
-
light: '<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z" />',
|
|
1134
|
-
dark: '<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z" />',
|
|
1135
|
-
system: '<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9.75 17L9 20l-1 1h8l-1-1-.75-3M3 13h18M5 17h14a2 2 0 002-2V5a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" />'
|
|
1136
|
-
};
|
|
1137
|
-
return icons[theme] || icons.system;
|
|
1138
|
-
}
|
|
1139
|
-
|
|
1140
|
-
function updateThemeIcon(theme) {
|
|
1141
|
-
const iconElement = document.getElementById('currentThemeIcon');
|
|
1142
|
-
if (iconElement) {
|
|
1143
|
-
iconElement.innerHTML = getThemeIcon(theme);
|
|
1144
|
-
}
|
|
1145
|
-
}
|
|
1146
|
-
|
|
1147
|
-
function toggleThemeDropdown() {
|
|
1148
|
-
const dropdown = document.getElementById('themeDropdown');
|
|
1149
|
-
dropdown.classList.toggle('open');
|
|
1150
|
-
}
|
|
1151
|
-
|
|
1152
|
-
function setTheme(theme) {
|
|
1153
|
-
localStorage.setItem('theme', theme);
|
|
1154
|
-
applyTheme(theme);
|
|
1155
|
-
updateThemeIcon(theme);
|
|
1156
|
-
|
|
1157
|
-
// Update button states
|
|
1158
|
-
document.querySelectorAll('.theme-option').forEach(btn => {
|
|
1159
|
-
btn.classList.toggle('active', btn.getAttribute('data-theme') === theme);
|
|
1160
|
-
});
|
|
1161
|
-
|
|
1162
|
-
// Close dropdown
|
|
1163
|
-
document.getElementById('themeDropdown').classList.remove('open');
|
|
1164
|
-
}
|
|
1165
|
-
|
|
1166
|
-
// Close dropdown when clicking outside
|
|
1167
|
-
document.addEventListener('click', (e) => {
|
|
1168
|
-
const switcher = document.querySelector('.theme-switcher');
|
|
1169
|
-
if (!switcher.contains(e.target)) {
|
|
1170
|
-
document.getElementById('themeDropdown').classList.remove('open');
|
|
1171
|
-
}
|
|
1172
|
-
});
|
|
1173
|
-
|
|
1174
|
-
// Initialize theme
|
|
1175
|
-
const savedTheme = localStorage.getItem('theme') || 'dark';
|
|
1176
|
-
setTheme(savedTheme);
|
|
1177
|
-
updateThemeIcon(savedTheme);
|
|
1178
|
-
|
|
1179
|
-
// Listen for system theme changes
|
|
1180
|
-
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => {
|
|
1181
|
-
if (localStorage.getItem('theme') === 'system') {
|
|
1182
|
-
applyTheme('system');
|
|
1183
|
-
}
|
|
1184
|
-
});
|
|
1185
|
-
|
|
1186
|
-
// Command selection
|
|
1187
|
-
function selectCommand(command) {
|
|
1188
|
-
if (!command) return;
|
|
1189
|
-
|
|
1190
|
-
currentCommand = command;
|
|
1191
|
-
localStorage.setItem('lastCommand', command);
|
|
1192
|
-
|
|
1193
|
-
// Enable send button
|
|
1194
|
-
document.getElementById('sendButton').disabled = false;
|
|
1195
|
-
|
|
1196
|
-
// Clear response status
|
|
1197
|
-
document.getElementById('statusDot').className = 'status-dot';
|
|
1198
|
-
document.getElementById('statusText').textContent = 'Ready';
|
|
1199
|
-
document.getElementById('responseTime').textContent = '';
|
|
1200
|
-
}
|
|
1201
|
-
|
|
1202
|
-
// Toggle command dropdown
|
|
1203
|
-
function toggleCommandDropdown() {
|
|
1204
|
-
const trigger = document.getElementById('commandTrigger');
|
|
1205
|
-
const options = document.getElementById('commandOptions');
|
|
1206
|
-
|
|
1207
|
-
const isOpen = trigger.classList.contains('open');
|
|
1208
|
-
|
|
1209
|
-
if (isOpen) {
|
|
1210
|
-
trigger.classList.remove('open');
|
|
1211
|
-
options.classList.remove('open');
|
|
1212
|
-
} else {
|
|
1213
|
-
trigger.classList.add('open');
|
|
1214
|
-
options.classList.add('open');
|
|
1215
|
-
}
|
|
1216
|
-
}
|
|
1217
|
-
|
|
1218
|
-
// Select command from custom dropdown
|
|
1219
|
-
function selectCommandFromDropdown(command) {
|
|
1220
|
-
// Update trigger text
|
|
1221
|
-
const trigger = document.getElementById('commandTrigger');
|
|
1222
|
-
const triggerText = trigger.querySelector('.command-trigger-text');
|
|
1223
|
-
|
|
1224
|
-
// Mark trigger as selected
|
|
1225
|
-
trigger.classList.add('selected');
|
|
1226
|
-
triggerText.textContent = command;
|
|
1227
|
-
|
|
1228
|
-
// Update option selection states
|
|
1229
|
-
document.querySelectorAll('.command-option').forEach(option => {
|
|
1230
|
-
option.classList.toggle('selected', option.getAttribute('data-command') === command);
|
|
1231
|
-
});
|
|
1232
|
-
|
|
1233
|
-
// Close dropdown
|
|
1234
|
-
trigger.classList.remove('open');
|
|
1235
|
-
document.getElementById('commandOptions').classList.remove('open');
|
|
1236
|
-
|
|
1237
|
-
// Call original select command logic
|
|
1238
|
-
selectCommand(command);
|
|
1239
|
-
}
|
|
1240
|
-
|
|
1241
|
-
// Close dropdown when clicking outside
|
|
1242
|
-
document.addEventListener('click', (e) => {
|
|
1243
|
-
const dropdown = document.querySelector('.command-dropdown');
|
|
1244
|
-
if (!dropdown.contains(e.target)) {
|
|
1245
|
-
const trigger = document.getElementById('commandTrigger');
|
|
1246
|
-
const options = document.getElementById('commandOptions');
|
|
1247
|
-
trigger.classList.remove('open');
|
|
1248
|
-
options.classList.remove('open');
|
|
1249
|
-
}
|
|
1250
|
-
});
|
|
1251
|
-
|
|
1252
|
-
// Send request
|
|
1253
|
-
async function sendRequest() {
|
|
1254
|
-
if (!currentCommand) {
|
|
1255
|
-
alert('Please select a command first');
|
|
1256
|
-
return;
|
|
1257
|
-
}
|
|
1258
|
-
|
|
1259
|
-
responseStartTime = Date.now();
|
|
1260
|
-
|
|
1261
|
-
// Update status to sending
|
|
1262
|
-
document.getElementById('statusDot').className = 'status-dot';
|
|
1263
|
-
document.getElementById('statusText').textContent = 'Sending...';
|
|
1264
|
-
|
|
1265
|
-
try {
|
|
1266
|
-
const requestId = document.getElementById('requestIdInput').value;
|
|
1267
|
-
const bodyStr = document.getElementById('requestBody').value;
|
|
1268
|
-
|
|
1269
|
-
const commandData = JSON.parse(bodyStr);
|
|
1270
|
-
|
|
1271
|
-
const command = {
|
|
1272
|
-
type: currentCommand,
|
|
1273
|
-
data: commandData
|
|
1274
|
-
};
|
|
1275
|
-
|
|
1276
|
-
if (requestId) {
|
|
1277
|
-
command.requestId = requestId;
|
|
1278
|
-
}
|
|
1279
|
-
|
|
1280
|
-
const response = await fetch(`${API_BASE}/command`, {
|
|
1281
|
-
method: 'POST',
|
|
1282
|
-
headers: {
|
|
1283
|
-
'Content-Type': 'application/json'
|
|
1284
|
-
},
|
|
1285
|
-
body: JSON.stringify(command)
|
|
1286
|
-
});
|
|
1287
|
-
|
|
1288
|
-
const responseTime = Date.now() - responseStartTime;
|
|
1289
|
-
const result = await response.json();
|
|
1290
|
-
|
|
1291
|
-
const statusDot = document.getElementById('statusDot');
|
|
1292
|
-
const statusText = document.getElementById('statusText');
|
|
1293
|
-
|
|
1294
|
-
if (response.ok && result.status === 'ack') {
|
|
1295
|
-
statusDot.className = 'status-dot success';
|
|
1296
|
-
statusText.textContent = 'ACK';
|
|
1297
|
-
} else {
|
|
1298
|
-
statusDot.className = 'status-dot error';
|
|
1299
|
-
statusText.textContent = 'ERROR';
|
|
1300
|
-
}
|
|
1301
|
-
document.getElementById('responseTime').textContent = `${responseTime}ms`;
|
|
1302
|
-
|
|
1303
|
-
// Auto refresh messages after sending
|
|
1304
|
-
setTimeout(loadMessages, 500);
|
|
1305
|
-
|
|
1306
|
-
} catch (error) {
|
|
1307
|
-
const responseTime = Date.now() - responseStartTime;
|
|
1308
|
-
|
|
1309
|
-
document.getElementById('responseTime').textContent = `${responseTime}ms`;
|
|
1310
|
-
document.getElementById('statusDot').className = 'status-dot error';
|
|
1311
|
-
document.getElementById('statusText').textContent = 'ERROR';
|
|
1312
|
-
}
|
|
1313
|
-
}
|
|
1314
|
-
|
|
1315
|
-
// Load registry and populate command dropdown
|
|
1316
|
-
async function loadRegistry() {
|
|
1317
|
-
try {
|
|
1318
|
-
const response = await fetch(`${API_BASE}/registry`);
|
|
1319
|
-
const data = await response.json();
|
|
1320
|
-
|
|
1321
|
-
const commandHandlers = data.commandHandlers || [];
|
|
1322
|
-
const commandsWithMetadata = data.commandsWithMetadata || [];
|
|
1323
|
-
|
|
1324
|
-
availableCommands = commandHandlers;
|
|
1325
|
-
|
|
1326
|
-
// Populate command dropdown with detailed 3-line format
|
|
1327
|
-
const commandOptions = document.getElementById('commandOptions');
|
|
1328
|
-
commandOptions.innerHTML = '';
|
|
1329
|
-
|
|
1330
|
-
commandsWithMetadata.forEach(cmd => {
|
|
1331
|
-
const option = document.createElement('button');
|
|
1332
|
-
option.className = 'command-option';
|
|
1333
|
-
option.setAttribute('data-command', cmd.name);
|
|
1334
|
-
option.onclick = () => selectCommandFromDropdown(cmd.name);
|
|
1335
|
-
|
|
1336
|
-
// Create 3-line format: command name, org, package
|
|
1337
|
-
const packageParts = (cmd.package || 'core').split('/');
|
|
1338
|
-
const org = packageParts.length > 1 ? packageParts[0] : '@auto-engineer';
|
|
1339
|
-
const packageName = packageParts.length > 1 ? packageParts[1] : packageParts[0];
|
|
1340
|
-
|
|
1341
|
-
option.innerHTML = `
|
|
1342
|
-
<div class="command-option-name">${cmd.name}</div>
|
|
1343
|
-
<div class="command-option-org">${org}</div>
|
|
1344
|
-
<div class="command-option-package">${packageName}</div>
|
|
1345
|
-
`;
|
|
1346
|
-
option.title = `${cmd.name}\n\nOrganization: ${org}\nPackage: ${packageName}\nType: ${cmd.type || 'command'}\n\nDescription: ${cmd.description || 'No description available'}`;
|
|
1347
|
-
|
|
1348
|
-
commandOptions.appendChild(option);
|
|
1349
|
-
});
|
|
1350
|
-
|
|
1351
|
-
// Restore last selected command
|
|
1352
|
-
const lastCommand = localStorage.getItem('lastCommand');
|
|
1353
|
-
if (lastCommand && commandHandlers.includes(lastCommand)) {
|
|
1354
|
-
selectCommandFromDropdown(lastCommand);
|
|
1355
|
-
}
|
|
1356
|
-
|
|
1357
|
-
} catch (error) {
|
|
1358
|
-
console.error('Failed to load registry:', error);
|
|
1359
|
-
}
|
|
1360
|
-
}
|
|
1361
|
-
|
|
1362
|
-
// Load messages
|
|
1363
|
-
async function loadMessages() {
|
|
1364
|
-
try {
|
|
1365
|
-
const messagesResponse = await fetch(`${API_BASE}/messages?count=500`);
|
|
1366
|
-
currentMessages = await messagesResponse.json();
|
|
1367
|
-
|
|
1368
|
-
// Load available sessions for filter dropdown
|
|
1369
|
-
const sessionsResponse = await fetch(`${API_BASE}/sessions`);
|
|
1370
|
-
availableSessions = await sessionsResponse.json();
|
|
1371
|
-
updateSessionFilter();
|
|
1372
|
-
|
|
1373
|
-
applyFilters();
|
|
1374
|
-
} catch (error) {
|
|
1375
|
-
console.error('Failed to load messages:', error);
|
|
1376
|
-
document.getElementById('messagesList').innerHTML = '<div class="empty">Failed to load messages</div>';
|
|
1377
|
-
}
|
|
1378
|
-
}
|
|
1379
|
-
|
|
1380
|
-
// Update session filter dropdown
|
|
1381
|
-
function updateSessionFilter() {
|
|
1382
|
-
const sessionFilter = document.getElementById('sessionFilter');
|
|
1383
|
-
const currentValue = sessionFilter.value;
|
|
1384
|
-
|
|
1385
|
-
sessionFilter.innerHTML = '<option value="">All Sessions</option>';
|
|
1386
|
-
|
|
1387
|
-
availableSessions
|
|
1388
|
-
.sort((a, b) => new Date(b.startedAt) - new Date(a.startedAt))
|
|
1389
|
-
.forEach(session => {
|
|
1390
|
-
const startTime = new Date(session.startedAt).toLocaleString();
|
|
1391
|
-
const option = document.createElement('option');
|
|
1392
|
-
option.value = session.sessionId;
|
|
1393
|
-
option.textContent = `${session.sessionId.substr(0, 12)}... (${startTime})`;
|
|
1394
|
-
sessionFilter.appendChild(option);
|
|
1395
|
-
});
|
|
1396
|
-
|
|
1397
|
-
// Restore previous selection
|
|
1398
|
-
sessionFilter.value = currentValue;
|
|
1399
|
-
}
|
|
1400
|
-
|
|
1401
|
-
// Apply message filters
|
|
1402
|
-
function applyFilters() {
|
|
1403
|
-
const messageTypeFilter = document.getElementById('messageTypeFilter').value;
|
|
1404
|
-
const sessionFilter = document.getElementById('sessionFilter').value;
|
|
1405
|
-
const messageNameFilter = document.getElementById('messageNameFilter').value.toLowerCase();
|
|
1406
|
-
const correlationIdFilter = document.getElementById('correlationIdFilter').value.toLowerCase();
|
|
1407
|
-
|
|
1408
|
-
filteredMessages = currentMessages.filter(message => {
|
|
1409
|
-
// Message type filter
|
|
1410
|
-
if (messageTypeFilter && message.messageType !== messageTypeFilter) {
|
|
1411
|
-
return false;
|
|
1412
|
-
}
|
|
1413
|
-
|
|
1414
|
-
// Session filter
|
|
1415
|
-
if (sessionFilter && message.sessionId !== sessionFilter) {
|
|
1416
|
-
return false;
|
|
1417
|
-
}
|
|
1418
|
-
|
|
1419
|
-
// Message name filter
|
|
1420
|
-
if (messageNameFilter && !message.message.type.toLowerCase().includes(messageNameFilter)) {
|
|
1421
|
-
return false;
|
|
1422
|
-
}
|
|
1423
|
-
|
|
1424
|
-
// Correlation ID filter
|
|
1425
|
-
if (correlationIdFilter) {
|
|
1426
|
-
const correlationId = message.message.correlationId || '';
|
|
1427
|
-
if (!correlationId.toLowerCase().includes(correlationIdFilter)) {
|
|
1428
|
-
return false;
|
|
1429
|
-
}
|
|
1430
|
-
}
|
|
1431
|
-
|
|
1432
|
-
return true;
|
|
1433
|
-
});
|
|
1434
|
-
|
|
1435
|
-
displayMessages();
|
|
1436
|
-
}
|
|
1437
|
-
|
|
1438
|
-
// Display messages with preserved expansion state
|
|
1439
|
-
function displayMessages() {
|
|
1440
|
-
const tableBody = document.getElementById('messagesTableBody');
|
|
1441
|
-
const countElement = document.getElementById('messageCount');
|
|
1442
|
-
const statsElement = document.getElementById('filterStats');
|
|
1443
|
-
|
|
1444
|
-
if (filteredMessages.length === 0) {
|
|
1445
|
-
tableBody.innerHTML = '<tr><td colspan="8" style="text-align: center; padding: 32px; color: var(--text-tertiary);">No messages match the current filters</td></tr>';
|
|
1446
|
-
countElement.textContent = '0';
|
|
1447
|
-
statsElement.textContent = `Showing 0 of ${currentMessages.length} messages`;
|
|
1448
|
-
return;
|
|
1449
|
-
}
|
|
1450
|
-
|
|
1451
|
-
// Update count and stats
|
|
1452
|
-
countElement.textContent = filteredMessages.length;
|
|
1453
|
-
const commandCount = filteredMessages.filter(m => m.messageType === 'command').length;
|
|
1454
|
-
const eventCount = filteredMessages.filter(m => m.messageType === 'event').length;
|
|
1455
|
-
statsElement.textContent = `Showing ${filteredMessages.length} of ${currentMessages.length} messages (${commandCount} commands, ${eventCount} events)`;
|
|
1456
|
-
|
|
1457
|
-
// Display messages in chronological order (oldest first)
|
|
1458
|
-
const messagesHtml = filteredMessages
|
|
1459
|
-
.slice()
|
|
1460
|
-
.sort((a, b) => parseInt(a.position) - parseInt(b.position))
|
|
1461
|
-
.map((message) => {
|
|
1462
|
-
const timeObj = new Date(message.timestamp);
|
|
1463
|
-
const time = timeObj.toLocaleTimeString('en-US', {
|
|
1464
|
-
hour12: false,
|
|
1465
|
-
hour: '2-digit',
|
|
1466
|
-
minute: '2-digit',
|
|
1467
|
-
second: '2-digit'
|
|
1468
|
-
}) + '.' + timeObj.getMilliseconds().toString().padStart(3, '0');
|
|
1469
|
-
const isExpanded = expandedMessages.has(String(message.position));
|
|
1470
|
-
|
|
1471
|
-
const correlationId = message.message.correlationId || 'none';
|
|
1472
|
-
const requestId = message.message.requestId || 'none';
|
|
1473
|
-
const sessionId = message.sessionId || 'none';
|
|
1474
|
-
|
|
1475
|
-
let rowsHtml = `
|
|
1476
|
-
<tr class="message-row ${isExpanded ? 'expanded' : ''}" data-position="${message.position}">
|
|
1477
|
-
<td class="message-cell expand-cell">
|
|
1478
|
-
<span class="expand-btn">${isExpanded ? '-' : '+'}</span>
|
|
1479
|
-
</td>
|
|
1480
|
-
<td class="message-cell type-cell">
|
|
1481
|
-
<span class="message-type ${message.messageType}">${message.messageType.toUpperCase()}</span>
|
|
1482
|
-
</td>
|
|
1483
|
-
<td class="message-cell name-cell" title="${message.message.type}">
|
|
1484
|
-
<span class="message-name">${message.message.type}</span>
|
|
1485
|
-
</td>
|
|
1486
|
-
<td class="message-cell id-cell" title="${requestId}">
|
|
1487
|
-
${requestId.length > 35 ? requestId.substring(0, 35) + '...' : requestId}
|
|
1488
|
-
</td>
|
|
1489
|
-
<td class="message-cell id-cell" title="${correlationId}">
|
|
1490
|
-
${correlationId.length > 35 ? correlationId.substring(0, 35) + '...' : correlationId}
|
|
1491
|
-
</td>
|
|
1492
|
-
<td class="message-cell id-cell" title="${sessionId}">
|
|
1493
|
-
${sessionId.length > 35 ? sessionId.substring(0, 35) + '...' : sessionId}
|
|
1494
|
-
</td>
|
|
1495
|
-
<td class="message-cell position-cell">${message.position}</td>
|
|
1496
|
-
<td class="message-cell time-cell">${time}</td>
|
|
1497
|
-
</tr>
|
|
1498
|
-
`;
|
|
1499
|
-
|
|
1500
|
-
if (isExpanded) {
|
|
1501
|
-
const messageDataJson = JSON.stringify(message.message.data, null, 2);
|
|
1502
|
-
rowsHtml += `
|
|
1503
|
-
<tr class="message-details-row" style="background: #1a202c;">
|
|
1504
|
-
<td colspan="8" style="padding: 16px; border-top: 1px solid #4a5568;">
|
|
1505
|
-
<div style="display: flex; flex-direction: column; gap: 8px;">
|
|
1506
|
-
<span style="color: #a0aec0; font-size: 12px; font-weight: 600;">MESSAGE DATA</span>
|
|
1507
|
-
<pre style="background: #2d3748; color: #e2e8f0; padding: 16px; border-radius: 6px; font-family: 'SF Mono', Monaco, monospace; font-size: 12px; line-height: 1.4; overflow-x: auto; border: 1px solid #4a5568; margin: 0;">${messageDataJson}</pre>
|
|
1508
|
-
</div>
|
|
1509
|
-
</td>
|
|
1510
|
-
</tr>
|
|
1511
|
-
`;
|
|
1512
|
-
}
|
|
1513
|
-
|
|
1514
|
-
return rowsHtml;
|
|
1515
|
-
})
|
|
1516
|
-
.join('');
|
|
1517
|
-
|
|
1518
|
-
// Always update to ensure expanded content shows properly
|
|
1519
|
-
tableBody.innerHTML = messagesHtml;
|
|
1520
|
-
autoScrollToBottom();
|
|
1521
|
-
}
|
|
1522
|
-
|
|
1523
|
-
// Toggle message details (like CloudWatch)
|
|
1524
|
-
function toggleMessage(position) {
|
|
1525
|
-
console.log('toggleMessage called with position:', position, 'type:', typeof position);
|
|
1526
|
-
console.log('Current expandedMessages:', Array.from(expandedMessages));
|
|
1527
|
-
|
|
1528
|
-
// Ensure position is a string for consistency
|
|
1529
|
-
const positionStr = String(position);
|
|
1530
|
-
|
|
1531
|
-
if (expandedMessages.has(positionStr)) {
|
|
1532
|
-
expandedMessages.delete(positionStr);
|
|
1533
|
-
console.log('Collapsed message', positionStr);
|
|
1534
|
-
} else {
|
|
1535
|
-
expandedMessages.add(positionStr);
|
|
1536
|
-
console.log('Expanded message', positionStr);
|
|
1537
|
-
}
|
|
1538
|
-
|
|
1539
|
-
console.log('New expandedMessages:', Array.from(expandedMessages));
|
|
1540
|
-
displayMessages();
|
|
1541
|
-
}
|
|
1542
|
-
|
|
1543
|
-
// Handle click events on table for expansion
|
|
1544
|
-
document.addEventListener('click', (e) => {
|
|
1545
|
-
// Check if click is on expand button or expand cell (but not resize handle)
|
|
1546
|
-
const expandBtn = e.target.closest('.expand-btn');
|
|
1547
|
-
const expandCell = e.target.closest('.expand-cell');
|
|
1548
|
-
const resizeHandle = e.target.closest('.resize-handle');
|
|
1549
|
-
|
|
1550
|
-
if ((expandBtn || expandCell) && !resizeHandle) {
|
|
1551
|
-
const row = e.target.closest('tr[data-position]');
|
|
1552
|
-
if (row) {
|
|
1553
|
-
const position = row.getAttribute('data-position');
|
|
1554
|
-
if (position) {
|
|
1555
|
-
e.stopPropagation();
|
|
1556
|
-
e.preventDefault();
|
|
1557
|
-
console.log('Toggling message position:', position);
|
|
1558
|
-
toggleMessage(position);
|
|
1559
|
-
}
|
|
1560
|
-
}
|
|
1561
|
-
}
|
|
1562
|
-
});
|
|
1563
|
-
|
|
1564
|
-
// Column resizing functionality
|
|
1565
|
-
function initColumnResize() {
|
|
1566
|
-
const table = document.querySelector('.messages-table');
|
|
1567
|
-
if (!table) return;
|
|
1568
|
-
|
|
1569
|
-
// Mouse down on resize handle
|
|
1570
|
-
document.addEventListener('mousedown', (e) => {
|
|
1571
|
-
if (!e.target.classList.contains('resize-handle')) return;
|
|
1572
|
-
|
|
1573
|
-
e.preventDefault();
|
|
1574
|
-
isResizing = true;
|
|
1575
|
-
|
|
1576
|
-
const headerCell = e.target.parentElement;
|
|
1577
|
-
const column = headerCell.dataset.column;
|
|
1578
|
-
|
|
1579
|
-
currentColumn = column;
|
|
1580
|
-
startX = e.clientX;
|
|
1581
|
-
startWidth = parseInt(getComputedStyle(headerCell).width);
|
|
1582
|
-
|
|
1583
|
-
document.body.classList.add('resizing');
|
|
1584
|
-
table.classList.add('resizing');
|
|
1585
|
-
});
|
|
1586
|
-
|
|
1587
|
-
// Mouse move during resize
|
|
1588
|
-
document.addEventListener('mousemove', (e) => {
|
|
1589
|
-
if (!isResizing || !currentColumn) return;
|
|
1590
|
-
|
|
1591
|
-
const deltaX = e.clientX - startX;
|
|
1592
|
-
const newWidth = Math.max(30, startWidth + deltaX);
|
|
1593
|
-
|
|
1594
|
-
columnWidths[currentColumn] = newWidth;
|
|
1595
|
-
updateColumnWidths();
|
|
1596
|
-
});
|
|
1597
|
-
|
|
1598
|
-
// Mouse up to end resize
|
|
1599
|
-
document.addEventListener('mouseup', () => {
|
|
1600
|
-
if (isResizing) {
|
|
1601
|
-
isResizing = false;
|
|
1602
|
-
currentColumn = null;
|
|
1603
|
-
|
|
1604
|
-
document.body.classList.remove('resizing');
|
|
1605
|
-
const table = document.querySelector('.messages-table');
|
|
1606
|
-
if (table) table.classList.remove('resizing');
|
|
1607
|
-
|
|
1608
|
-
// Save column widths to localStorage
|
|
1609
|
-
localStorage.setItem('columnWidths', JSON.stringify(columnWidths));
|
|
1610
|
-
}
|
|
1611
|
-
});
|
|
1612
|
-
}
|
|
1613
|
-
|
|
1614
|
-
// Update column widths in the table
|
|
1615
|
-
function updateColumnWidths() {
|
|
1616
|
-
const headers = document.querySelectorAll('.messages-header-cell');
|
|
1617
|
-
headers.forEach((cell, index) => {
|
|
1618
|
-
const column = cell.dataset.column;
|
|
1619
|
-
if (column && columnWidths[column]) {
|
|
1620
|
-
cell.style.width = columnWidths[column] + 'px';
|
|
1621
|
-
cell.style.minWidth = columnWidths[column] + 'px';
|
|
1622
|
-
cell.style.maxWidth = columnWidths[column] + 'px';
|
|
1623
|
-
}
|
|
1624
|
-
});
|
|
1625
|
-
|
|
1626
|
-
// Apply to colgroup if it exists
|
|
1627
|
-
const colgroup = document.querySelector('.messages-table colgroup');
|
|
1628
|
-
if (colgroup) {
|
|
1629
|
-
const cols = colgroup.querySelectorAll('col');
|
|
1630
|
-
headers.forEach((cell, index) => {
|
|
1631
|
-
const column = cell.dataset.column;
|
|
1632
|
-
if (column && columnWidths[column] && cols[index]) {
|
|
1633
|
-
cols[index].style.width = columnWidths[column] + 'px';
|
|
1634
|
-
}
|
|
1635
|
-
});
|
|
1636
|
-
}
|
|
1637
|
-
}
|
|
1638
|
-
|
|
1639
|
-
// Load saved column widths
|
|
1640
|
-
function loadColumnWidths() {
|
|
1641
|
-
const saved = localStorage.getItem('columnWidths');
|
|
1642
|
-
if (saved) {
|
|
1643
|
-
try {
|
|
1644
|
-
const parsed = JSON.parse(saved);
|
|
1645
|
-
columnWidths = { ...defaultColumnWidths, ...parsed };
|
|
1646
|
-
} catch (e) {
|
|
1647
|
-
columnWidths = { ...defaultColumnWidths };
|
|
1648
|
-
}
|
|
1649
|
-
}
|
|
1650
|
-
}
|
|
1651
|
-
|
|
1652
|
-
// Copy message data to request body field
|
|
1653
|
-
function copyMessageData(position, messageData) {
|
|
1654
|
-
try {
|
|
1655
|
-
const requestBodyField = document.getElementById('requestBody');
|
|
1656
|
-
if (requestBodyField) {
|
|
1657
|
-
// Parse and re-stringify to ensure proper formatting
|
|
1658
|
-
const parsed = JSON.parse(messageData);
|
|
1659
|
-
requestBodyField.value = JSON.stringify(parsed, null, 2);
|
|
1660
|
-
|
|
1661
|
-
// Visual feedback
|
|
1662
|
-
const copyBtn = window.event ? window.event.target : null;
|
|
1663
|
-
if (copyBtn) {
|
|
1664
|
-
const originalText = copyBtn.textContent;
|
|
1665
|
-
copyBtn.textContent = 'Copied!';
|
|
1666
|
-
copyBtn.style.background = 'var(--success)';
|
|
1667
|
-
copyBtn.style.color = 'white';
|
|
1668
|
-
|
|
1669
|
-
setTimeout(() => {
|
|
1670
|
-
copyBtn.textContent = originalText;
|
|
1671
|
-
copyBtn.style.background = '';
|
|
1672
|
-
copyBtn.style.color = '';
|
|
1673
|
-
}, 1500);
|
|
1674
|
-
}
|
|
1675
|
-
}
|
|
1676
|
-
} catch (error) {
|
|
1677
|
-
console.error('Failed to copy message data:', error);
|
|
1678
|
-
|
|
1679
|
-
// Error feedback
|
|
1680
|
-
const copyBtn = window.event ? window.event.target : null;
|
|
1681
|
-
if (copyBtn) {
|
|
1682
|
-
const originalText = copyBtn.textContent;
|
|
1683
|
-
copyBtn.textContent = 'Error';
|
|
1684
|
-
copyBtn.style.background = 'var(--error)';
|
|
1685
|
-
copyBtn.style.color = 'white';
|
|
1686
|
-
|
|
1687
|
-
setTimeout(() => {
|
|
1688
|
-
copyBtn.textContent = originalText;
|
|
1689
|
-
copyBtn.style.background = '';
|
|
1690
|
-
copyBtn.style.color = '';
|
|
1691
|
-
}, 1500);
|
|
1692
|
-
}
|
|
1693
|
-
}
|
|
1694
|
-
}
|
|
1695
|
-
|
|
1696
|
-
// Auto-scroll to bottom when new messages arrive
|
|
1697
|
-
let lastMessageCount = 0;
|
|
1698
|
-
function autoScrollToBottom() {
|
|
1699
|
-
if (currentMessages.length > lastMessageCount) {
|
|
1700
|
-
const messagesContainer = document.querySelector('.messages-list');
|
|
1701
|
-
if (messagesContainer) {
|
|
1702
|
-
messagesContainer.scrollTop = messagesContainer.scrollHeight;
|
|
1703
|
-
}
|
|
1704
|
-
lastMessageCount = currentMessages.length;
|
|
1705
|
-
}
|
|
1706
|
-
}
|
|
1707
|
-
|
|
1708
|
-
// Clear filters
|
|
1709
|
-
function clearFilters() {
|
|
1710
|
-
document.getElementById('messageTypeFilter').value = '';
|
|
1711
|
-
document.getElementById('sessionFilter').value = '';
|
|
1712
|
-
document.getElementById('messageNameFilter').value = '';
|
|
1713
|
-
document.getElementById('correlationIdFilter').value = '';
|
|
1714
|
-
applyFilters();
|
|
1715
|
-
}
|
|
1716
|
-
|
|
1717
|
-
// Keyboard shortcuts
|
|
1718
|
-
document.addEventListener('keydown', (e) => {
|
|
1719
|
-
if ((e.metaKey || e.ctrlKey) && e.key === 'Enter') {
|
|
1720
|
-
sendRequest();
|
|
1721
|
-
}
|
|
1722
|
-
});
|
|
1723
|
-
|
|
1724
|
-
// WebSocket connection for real-time updates
|
|
1725
|
-
const ws = new WebSocket(`ws://${window.location.hostname}:${window.location.port}`);
|
|
1726
|
-
|
|
1727
|
-
ws.onopen = () => {
|
|
1728
|
-
console.log('WebSocket connected');
|
|
1729
|
-
};
|
|
1730
|
-
|
|
1731
|
-
ws.onmessage = (event) => {
|
|
1732
|
-
const message = JSON.parse(event.data);
|
|
1733
|
-
if (message.type === 'event' || message.type === 'state') {
|
|
1734
|
-
// Reload messages when events occur
|
|
1735
|
-
loadMessages();
|
|
1736
|
-
} else if (message.type === 'commandError') {
|
|
1737
|
-
// Show command error in response
|
|
1738
|
-
document.getElementById('responsePreview').textContent = JSON.stringify({
|
|
1739
|
-
status: 'error',
|
|
1740
|
-
commandId: message.commandId,
|
|
1741
|
-
error: message.error,
|
|
1742
|
-
timestamp: message.timestamp
|
|
1743
|
-
}, null, 2);
|
|
1744
|
-
document.getElementById('statusDot').className = 'status-dot error';
|
|
1745
|
-
document.getElementById('statusText').textContent = 'Command Failed';
|
|
1746
|
-
document.getElementById('responseTime').textContent = 'Async Error';
|
|
1747
|
-
}
|
|
1748
|
-
};
|
|
1749
|
-
|
|
1750
|
-
ws.onerror = (error) => {
|
|
1751
|
-
console.error('WebSocket error:', error);
|
|
1752
|
-
};
|
|
1753
|
-
|
|
1754
|
-
ws.onclose = () => {
|
|
1755
|
-
console.log('WebSocket disconnected');
|
|
1756
|
-
};
|
|
1757
|
-
|
|
1758
|
-
// Initial load
|
|
1759
|
-
loadColumnWidths();
|
|
1760
|
-
loadRegistry();
|
|
1761
|
-
loadMessages();
|
|
1762
|
-
|
|
1763
|
-
// Initialize column resize functionality
|
|
1764
|
-
setTimeout(() => {
|
|
1765
|
-
initColumnResize();
|
|
1766
|
-
updateColumnWidths();
|
|
1767
|
-
}, 100);
|
|
1768
|
-
|
|
1769
|
-
// Auto-refresh
|
|
1770
|
-
setInterval(loadRegistry, 5000);
|
|
1771
|
-
setInterval(loadMessages, 2000);
|
|
1772
|
-
</script>
|
|
1773
|
-
</body>
|
|
1774
|
-
</html>
|