@monster-orange/den 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/CHANGELOG.md +137 -0
  2. package/README.md +1 -1
  3. package/bin/den +7 -0
  4. package/docs/distributions.md +255 -12
  5. package/package.json +4 -2
  6. package/src/pillars/journeys/sandbox.ts +2 -5
  7. package/src/pillars/security/discover.ts +17 -1
  8. package/src/pillars/security/run.ts +31 -3
  9. package/src/shared/agent-actor.ts +77 -0
  10. package/src/shared/den-config.ts +122 -0
  11. package/src/shared/edge/status.ts +74 -0
  12. package/src/shared/environment-manager/health.ts +54 -8
  13. package/src/shared/environment-manager/load-applications.ts +31 -1
  14. package/src/shared/environment-manager/log-tail.ts +5 -4
  15. package/src/shared/environment-manager/opctl.ts +2 -1
  16. package/src/shared/environment-manager/service-container.ts +47 -0
  17. package/src/shared/environment-manager/service-runner.ts +16 -1
  18. package/src/shared/environment-manager/sync-targets.ts +66 -0
  19. package/src/shared/environment-manager/up-plan.ts +25 -1
  20. package/src/shared/manifest/merge-override.ts +75 -0
  21. package/src/shared/manifest/placement.ts +321 -0
  22. package/src/shared/manifest/read-manifest.ts +156 -38
  23. package/src/shared/manifest/schema.ts +14 -0
  24. package/src/shared/manifest/validate-layers.ts +229 -0
  25. package/src/shared/manifest/validate-manifest.ts +66 -6
  26. package/src/shared/paths.ts +12 -0
  27. package/src/shared/redact.ts +107 -0
  28. package/src/shared/stacks/manifest-commands.ts +30 -0
  29. package/src/shared/stacks/status.ts +99 -0
  30. package/src/shared/types/index.ts +23 -0
  31. package/src/ui/cli/applications-command.ts +34 -2
  32. package/src/ui/cli/edge-command.ts +9 -19
  33. package/src/ui/cli/graph-command.ts +50 -4
  34. package/src/ui/cli/index.ts +131 -45
  35. package/src/ui/cli/mcp-main.ts +13 -0
  36. package/src/ui/cli/mcp-stdout-guard.ts +10 -0
  37. package/src/ui/cli/stack-command.ts +13 -40
  38. package/src/ui/cli/test-runner.ts +8 -1
  39. package/src/ui/mcp/api.ts +284 -0
  40. package/src/ui/mcp/guards.ts +141 -0
  41. package/src/ui/mcp/server.ts +147 -0
  42. package/src/ui/mcp/tools.ts +565 -0
  43. package/src/ui/server/audit.ts +71 -0
  44. package/src/ui/server/changelog-parser.ts +11 -0
  45. package/src/ui/server/graph-prefs.ts +89 -0
  46. package/src/ui/server/health-row.ts +15 -0
  47. package/src/ui/server/index.ts +175 -61
  48. package/src/ui/server/log-history.ts +4 -3
  49. package/src/ui/server/public/environments.html +4 -2
  50. package/src/ui/server/public/graph-model.js +416 -0
  51. package/src/ui/server/public/graph.css +976 -0
  52. package/src/ui/server/public/graph.js +986 -0
  53. package/src/ui/server/public/header.js +7 -5
  54. package/src/ui/server/public/local-dev.html +130 -2191
  55. package/src/ui/server/public/logs.html +11 -4
  56. package/src/ui/server/public/panel.js +787 -0
  57. package/src/ui/server/public/services.html +6 -1
  58. package/src/ui/server/readonly-routes.ts +200 -0
  59. package/src/ui/server/ui-assets.ts +73 -0
  60. package/src/ui/server/workspace-routes.ts +39 -8
@@ -0,0 +1,976 @@
1
+ /* Local Dev graph: toolbar, pannable canvas of HTML cards over an SVG edge
2
+ layer, and the details panel (side panel, pop-up, or a bottom sheet on a
3
+ phone). Every class is dg-prefixed so the page's own styles never collide. */
4
+ /* .dg-layer: a layer on <body> that holds the open More menu, so no panel
5
+ (a scrolling side panel, the pop-up) can clip it. */
6
+ .dg,
7
+ .dg-layer {
8
+ --dg-raised: #1c2330;
9
+ --dg-border-strong: #484f58;
10
+ --dg-faint: #6e7681;
11
+ --dg-remote: #39c5cf;
12
+ --dg-event: #bc8cff;
13
+ --dg-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
14
+ font-family: var(--dg-sans);
15
+ font-size: 14px;
16
+ color: var(--text);
17
+ }
18
+ .dg {
19
+ display: grid;
20
+ grid-template-rows: auto 1fr;
21
+ height: 100%;
22
+ min-height: 0;
23
+ cursor: default;
24
+ background: var(--bg);
25
+ }
26
+ :where(.dg, .dg-layer) button {
27
+ font: inherit;
28
+ color: inherit;
29
+ }
30
+ .dg :focus-visible,
31
+ .dg-layer :focus-visible {
32
+ outline: 2px solid var(--accent);
33
+ outline-offset: 2px;
34
+ }
35
+
36
+ /* toolbar */
37
+ .dg-bar {
38
+ display: flex;
39
+ flex-wrap: wrap;
40
+ align-items: center;
41
+ gap: 8px 16px;
42
+ padding: 8px 12px;
43
+ border-bottom: 1px solid var(--border);
44
+ background: var(--surface);
45
+ }
46
+ .dg-ctl {
47
+ display: flex;
48
+ align-items: center;
49
+ gap: 6px;
50
+ }
51
+ .dg-ctl > span {
52
+ color: var(--muted);
53
+ font-size: 11px;
54
+ text-transform: uppercase;
55
+ letter-spacing: 0.06em;
56
+ }
57
+ .dg-seg {
58
+ display: inline-flex;
59
+ border: 1px solid var(--border);
60
+ border-radius: 7px;
61
+ overflow: hidden;
62
+ }
63
+ .dg-seg button {
64
+ background: transparent;
65
+ border: 0;
66
+ padding: 4px 10px;
67
+ font-size: 12.5px;
68
+ color: var(--muted);
69
+ cursor: pointer;
70
+ }
71
+ .dg-seg button + button {
72
+ border-left: 1px solid var(--border);
73
+ }
74
+ .dg-seg button[aria-pressed="true"] {
75
+ background: var(--dg-raised);
76
+ color: var(--text);
77
+ }
78
+ .dg-seg button:hover {
79
+ color: var(--text);
80
+ }
81
+ .dg input[type="search"] {
82
+ background: var(--bg);
83
+ color: var(--text);
84
+ border: 1px solid var(--border);
85
+ border-radius: 7px;
86
+ padding: 4px 8px;
87
+ font-size: 13px;
88
+ }
89
+ .dg-bar input[type="search"] {
90
+ width: 190px;
91
+ }
92
+ .dg-spacer {
93
+ flex: 1;
94
+ }
95
+
96
+ /* canvas */
97
+ /* overflow: clip, not hidden: a focused or scrolled-into-view card must never
98
+ scroll the stage itself (that slid the legend and zoom off their corners). */
99
+ .dg-stage {
100
+ position: relative;
101
+ overflow: clip;
102
+ display: grid;
103
+ grid-template-columns: minmax(0, 1fr) auto;
104
+ grid-template-rows: minmax(0, 1fr);
105
+ min-height: 0;
106
+ }
107
+ .dg-vp {
108
+ position: relative;
109
+ overflow: clip;
110
+ cursor: grab;
111
+ min-width: 0;
112
+ touch-action: none;
113
+ }
114
+ .dg-vp.dragging {
115
+ cursor: grabbing;
116
+ }
117
+ .dg-world {
118
+ position: absolute;
119
+ left: 0;
120
+ top: 0;
121
+ transform-origin: 0 0;
122
+ }
123
+ .dg-world > svg {
124
+ position: absolute;
125
+ left: 0;
126
+ top: 0;
127
+ overflow: visible;
128
+ pointer-events: none;
129
+ }
130
+ .dg-zoom {
131
+ position: absolute;
132
+ right: 12px;
133
+ bottom: 12px;
134
+ display: flex;
135
+ border: 1px solid var(--border);
136
+ border-radius: 8px;
137
+ background: var(--surface);
138
+ overflow: hidden;
139
+ z-index: 5;
140
+ }
141
+ .dg-zoom button {
142
+ background: transparent;
143
+ border: 0;
144
+ padding: 5px 10px;
145
+ cursor: pointer;
146
+ color: var(--muted);
147
+ font-variant-numeric: tabular-nums;
148
+ font-size: 13px;
149
+ }
150
+ .dg-zoom button + button {
151
+ border-left: 1px solid var(--border);
152
+ }
153
+ .dg-zoom button:hover {
154
+ color: var(--text);
155
+ background: var(--dg-raised);
156
+ }
157
+ .dg-legend {
158
+ position: absolute;
159
+ left: 12px;
160
+ bottom: 12px;
161
+ display: flex;
162
+ flex-wrap: wrap;
163
+ gap: 4px 14px;
164
+ padding: 6px 10px;
165
+ border: 1px solid var(--border);
166
+ border-radius: 8px;
167
+ background: color-mix(in srgb, var(--surface) 92%, transparent);
168
+ font-size: 11.5px;
169
+ color: var(--muted);
170
+ z-index: 5;
171
+ max-width: calc(100% - 210px);
172
+ pointer-events: none;
173
+ }
174
+ .dg-legend i {
175
+ display: inline-block;
176
+ width: 22px;
177
+ height: 0;
178
+ border-top: 2px solid;
179
+ vertical-align: middle;
180
+ margin-right: 6px;
181
+ }
182
+ .dg-msg {
183
+ padding: 40px;
184
+ color: var(--muted);
185
+ font-size: 13px;
186
+ }
187
+
188
+ /* groups */
189
+ .dg-grp {
190
+ position: absolute;
191
+ border: 1px solid var(--border);
192
+ border-radius: 12px;
193
+ box-sizing: border-box;
194
+ }
195
+ .dg-grp.dg-org {
196
+ background: color-mix(in srgb, var(--oc) 4%, transparent);
197
+ border-color: color-mix(in srgb, var(--oc) 45%, var(--border));
198
+ }
199
+ .dg-grp.dg-repo {
200
+ background: color-mix(in srgb, var(--surface) 70%, transparent);
201
+ }
202
+ .dg-grp.dg-repo.has-remote {
203
+ border-style: dashed;
204
+ }
205
+ .dg-grp.dg-repo.sel {
206
+ border-color: var(--accent);
207
+ box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent) 45%, transparent);
208
+ }
209
+ .dg-ghead {
210
+ position: absolute;
211
+ left: 14px;
212
+ right: 10px;
213
+ top: 9px;
214
+ display: flex;
215
+ align-items: baseline;
216
+ gap: 10px;
217
+ min-width: 0;
218
+ }
219
+ .dg-org > .dg-ghead b {
220
+ color: var(--oc);
221
+ font-size: 15px;
222
+ font-weight: 600;
223
+ white-space: nowrap;
224
+ }
225
+ .dg-ghead .meta {
226
+ color: var(--muted);
227
+ font-size: 12px;
228
+ white-space: nowrap;
229
+ overflow: hidden;
230
+ text-overflow: ellipsis;
231
+ min-width: 0;
232
+ }
233
+ .dg-ghead .roll {
234
+ margin-left: auto;
235
+ font-size: 12px;
236
+ color: var(--muted);
237
+ white-space: nowrap;
238
+ }
239
+ .dg-lnk {
240
+ background: none;
241
+ border: 0;
242
+ padding: 0;
243
+ color: var(--accent);
244
+ cursor: pointer;
245
+ font-size: 12px;
246
+ white-space: nowrap;
247
+ }
248
+ .dg-lnk:hover {
249
+ text-decoration: underline;
250
+ }
251
+ .dg-gname {
252
+ background: none;
253
+ border: 0;
254
+ padding: 0;
255
+ cursor: pointer;
256
+ font-family: var(--mono);
257
+ font-size: 13px;
258
+ font-weight: 600;
259
+ color: var(--text);
260
+ white-space: nowrap;
261
+ }
262
+ .dg-gname:hover {
263
+ text-decoration: underline;
264
+ }
265
+
266
+ /* cards */
267
+ .dg-card {
268
+ position: absolute;
269
+ display: flex;
270
+ flex-direction: column;
271
+ gap: 5px;
272
+ padding: 10px 12px;
273
+ box-sizing: border-box;
274
+ background: var(--dg-raised);
275
+ border: 1px solid var(--dg-border-strong);
276
+ border-radius: 10px;
277
+ cursor: pointer;
278
+ text-align: left;
279
+ transition:
280
+ opacity 0.15s,
281
+ border-color 0.15s,
282
+ box-shadow 0.15s;
283
+ }
284
+ .dg-card:hover {
285
+ border-color: var(--accent);
286
+ }
287
+ .dg-card.sel {
288
+ border-color: var(--accent);
289
+ box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent) 45%, transparent);
290
+ }
291
+ .dg-card.remote {
292
+ background: color-mix(in srgb, var(--dg-remote) 6%, var(--bg));
293
+ border-style: dashed;
294
+ border-color: color-mix(in srgb, var(--dg-remote) 60%, var(--border));
295
+ }
296
+ .dg-card.down {
297
+ border-color: color-mix(in srgb, var(--red) 70%, var(--border));
298
+ }
299
+ .dg-card .r1 {
300
+ display: flex;
301
+ align-items: flex-start;
302
+ gap: 8px;
303
+ min-width: 0;
304
+ }
305
+ .dg-card .r1 .dg-dot {
306
+ margin-top: 5px;
307
+ }
308
+ .dg-dot {
309
+ display: inline-block;
310
+ width: 9px;
311
+ height: 9px;
312
+ border-radius: 50%;
313
+ flex: none;
314
+ background: var(--dg-faint);
315
+ }
316
+ .dg-dot.ok {
317
+ background: var(--green);
318
+ }
319
+ .dg-dot.bad {
320
+ background: var(--red);
321
+ }
322
+ .dg-card .nm {
323
+ font-weight: 600;
324
+ font-size: 14.5px;
325
+ line-height: 1.25;
326
+ overflow-wrap: anywhere;
327
+ min-width: 0;
328
+ display: -webkit-box;
329
+ -webkit-line-clamp: 2;
330
+ -webkit-box-orient: vertical;
331
+ overflow: hidden;
332
+ }
333
+ .dg-badge {
334
+ margin-left: auto;
335
+ flex: none;
336
+ font-size: 11px;
337
+ padding: 1px 7px;
338
+ border-radius: 99px;
339
+ border: 1px solid var(--border);
340
+ color: var(--muted);
341
+ white-space: nowrap;
342
+ }
343
+ .dg-badge.remote {
344
+ color: var(--dg-remote);
345
+ border-color: color-mix(in srgb, var(--dg-remote) 55%, transparent);
346
+ }
347
+ .dg-badge.hybrid {
348
+ color: var(--yellow);
349
+ border-color: color-mix(in srgb, var(--yellow) 55%, transparent);
350
+ }
351
+ .dg-card .r2 {
352
+ font-family: var(--mono);
353
+ font-size: 12px;
354
+ color: var(--muted);
355
+ white-space: nowrap;
356
+ overflow: hidden;
357
+ text-overflow: ellipsis;
358
+ }
359
+ .dg-card .r3 {
360
+ display: flex;
361
+ align-items: center;
362
+ gap: 8px;
363
+ font-size: 12px;
364
+ color: var(--muted);
365
+ min-width: 0;
366
+ }
367
+ .dg-card .r3 .h {
368
+ white-space: nowrap;
369
+ overflow: hidden;
370
+ text-overflow: ellipsis;
371
+ min-width: 0;
372
+ }
373
+ .dg-card .r3 .h.bad {
374
+ color: var(--red);
375
+ }
376
+ .dg-tag {
377
+ font-size: 11px;
378
+ padding: 0 6px;
379
+ border-radius: 4px;
380
+ background: color-mix(in srgb, var(--text) 8%, transparent);
381
+ color: var(--muted);
382
+ flex: none;
383
+ }
384
+ .dg-tag.entry {
385
+ background: color-mix(in srgb, var(--accent) 16%, transparent);
386
+ color: var(--accent);
387
+ }
388
+ .dg-tag.warn {
389
+ background: color-mix(in srgb, var(--yellow) 16%, transparent);
390
+ color: var(--yellow);
391
+ }
392
+ .dg-acts {
393
+ display: flex;
394
+ gap: 6px;
395
+ margin-top: auto;
396
+ opacity: 0;
397
+ transition: opacity 0.12s;
398
+ }
399
+ .dg-card:hover .dg-acts,
400
+ .dg-card:focus-within .dg-acts,
401
+ .dg-card.sel .dg-acts {
402
+ opacity: 1;
403
+ }
404
+ .dg-btn {
405
+ background: var(--bg);
406
+ border: 1px solid var(--border);
407
+ border-radius: 6px;
408
+ padding: 5px 12px;
409
+ font-size: 13px;
410
+ cursor: pointer;
411
+ color: var(--text);
412
+ text-decoration: none;
413
+ display: inline-block;
414
+ white-space: nowrap;
415
+ }
416
+ .dg-btn:hover {
417
+ border-color: var(--accent);
418
+ }
419
+ .dg-btn:disabled {
420
+ opacity: 0.45;
421
+ cursor: not-allowed;
422
+ }
423
+ .dg-btn.sm {
424
+ padding: 2px 8px;
425
+ font-size: 12px;
426
+ }
427
+ .dg-btn.primary {
428
+ background: var(--accent);
429
+ border-color: var(--accent);
430
+ color: #0d1117;
431
+ font-weight: 600;
432
+ }
433
+ .dg-btn.primary:hover {
434
+ filter: brightness(1.1);
435
+ }
436
+ .dg-btn.armed {
437
+ border-color: var(--red);
438
+ color: var(--red);
439
+ font-weight: 600;
440
+ }
441
+ .dg-card.compact {
442
+ gap: 3px;
443
+ padding: 8px 10px;
444
+ }
445
+ .dg-card.compact .r1 .dg-dot {
446
+ margin-top: 4px;
447
+ }
448
+ .dg-card.compact .nm {
449
+ font-size: 13.5px;
450
+ -webkit-line-clamp: 1;
451
+ }
452
+ .dg-card.compact .r3,
453
+ .dg-card.compact .dg-acts {
454
+ display: none;
455
+ }
456
+ .dg-card .sum {
457
+ display: flex;
458
+ gap: 4px;
459
+ flex-wrap: wrap;
460
+ }
461
+ .dg-card .sum .dg-dot {
462
+ width: 8px;
463
+ height: 8px;
464
+ }
465
+ .dg .dim {
466
+ opacity: 0.22;
467
+ }
468
+ .dg-card.hit {
469
+ box-shadow: 0 0 0 2px var(--yellow);
470
+ }
471
+
472
+ /* edges */
473
+ path.dg-e {
474
+ fill: none;
475
+ stroke: #6e7681;
476
+ stroke-width: 1.4;
477
+ transition: opacity 0.15s;
478
+ }
479
+ path.dg-e.hard {
480
+ stroke: var(--accent);
481
+ stroke-width: 1.8;
482
+ }
483
+ path.dg-e.soft {
484
+ stroke: #8b949e;
485
+ stroke-dasharray: 6 4;
486
+ }
487
+ path.dg-e.event {
488
+ stroke: var(--dg-event);
489
+ stroke-dasharray: 2 4;
490
+ }
491
+ path.dg-e.cross {
492
+ stroke: var(--dg-remote);
493
+ stroke-width: 2;
494
+ stroke-dasharray: 9 4;
495
+ }
496
+ path.dg-e.intra {
497
+ stroke: #8b949e;
498
+ stroke-width: 1.5;
499
+ }
500
+ path.dg-e.hl {
501
+ stroke-width: 2.6;
502
+ }
503
+ path.dg-e.dim {
504
+ opacity: 0.12;
505
+ }
506
+
507
+ /* panel */
508
+ .dg-panel {
509
+ position: relative;
510
+ width: 440px;
511
+ max-width: 100%;
512
+ border-left: 1px solid var(--border);
513
+ background: var(--surface);
514
+ overflow-y: auto;
515
+ min-height: 0;
516
+ font-size: 14px;
517
+ }
518
+ .dg-panel[hidden] {
519
+ display: none !important;
520
+ }
521
+ .dg.dg-modal-back {
522
+ position: fixed;
523
+ inset: 0;
524
+ height: auto;
525
+ grid-template-rows: none;
526
+ background: rgb(1 4 9 / 0.6);
527
+ z-index: 900;
528
+ display: grid;
529
+ place-items: center;
530
+ padding: 24px;
531
+ }
532
+ .dg-modal-back .dg-panel {
533
+ width: min(720px, 100%);
534
+ max-height: min(86vh, 900px);
535
+ border: 1px solid var(--border);
536
+ border-radius: 14px;
537
+ box-shadow: 0 24px 60px rgb(0 0 0 / 0.5);
538
+ }
539
+ .dg-resize {
540
+ position: absolute;
541
+ left: 0;
542
+ top: 0;
543
+ bottom: 0;
544
+ width: 6px;
545
+ cursor: col-resize;
546
+ z-index: 3;
547
+ }
548
+ .dg-resize:hover {
549
+ background: color-mix(in srgb, var(--accent) 40%, transparent);
550
+ }
551
+ .dg-dh {
552
+ position: sticky;
553
+ top: 0;
554
+ background: var(--surface);
555
+ padding: 14px 18px 12px;
556
+ border-bottom: 1px solid var(--border);
557
+ z-index: 2;
558
+ }
559
+ .dg-crumbs {
560
+ font-size: 12px;
561
+ color: var(--muted);
562
+ margin-bottom: 6px;
563
+ display: flex;
564
+ gap: 5px;
565
+ align-items: center;
566
+ flex-wrap: wrap;
567
+ }
568
+ .dg-crumbs button {
569
+ background: none;
570
+ border: 0;
571
+ padding: 0;
572
+ color: var(--accent);
573
+ cursor: pointer;
574
+ font: inherit;
575
+ }
576
+ .dg-crumbs button:hover {
577
+ text-decoration: underline;
578
+ }
579
+ .dg-dh .t {
580
+ display: flex;
581
+ align-items: center;
582
+ gap: 10px;
583
+ flex-wrap: wrap;
584
+ }
585
+ .dg-dh h2 {
586
+ margin: 0;
587
+ font-size: 18px;
588
+ font-weight: 600;
589
+ overflow-wrap: anywhere;
590
+ }
591
+ .dg-dh .dg-badge {
592
+ margin-left: 0;
593
+ }
594
+ .dg-hbtns {
595
+ margin-left: auto;
596
+ display: flex;
597
+ gap: 2px;
598
+ }
599
+ .dg-ib {
600
+ background: none;
601
+ border: 1px solid transparent;
602
+ border-radius: 6px;
603
+ color: var(--muted);
604
+ font-size: 17px;
605
+ line-height: 1;
606
+ padding: 3px 7px;
607
+ cursor: pointer;
608
+ }
609
+ .dg-ib:hover {
610
+ color: var(--text);
611
+ border-color: var(--border);
612
+ }
613
+ .dg-dh .sub {
614
+ margin-top: 4px;
615
+ font-family: var(--mono);
616
+ font-size: 12.5px;
617
+ color: var(--muted);
618
+ overflow-wrap: anywhere;
619
+ }
620
+ .dg-pill {
621
+ display: inline-block;
622
+ font-size: 12px;
623
+ padding: 1px 8px;
624
+ border-radius: 99px;
625
+ border: 1px solid var(--border);
626
+ color: var(--muted);
627
+ white-space: nowrap;
628
+ }
629
+ .dg-pill.ok {
630
+ color: var(--green);
631
+ border-color: color-mix(in srgb, var(--green) 50%, transparent);
632
+ background: color-mix(in srgb, var(--green) 10%, transparent);
633
+ }
634
+ .dg-pill.bad {
635
+ color: var(--red);
636
+ border-color: color-mix(in srgb, var(--red) 55%, transparent);
637
+ background: color-mix(in srgb, var(--red) 10%, transparent);
638
+ }
639
+ .dg-actions {
640
+ display: flex;
641
+ flex-wrap: wrap;
642
+ gap: 6px;
643
+ margin-top: 12px;
644
+ align-items: center;
645
+ }
646
+ .dg-more {
647
+ position: relative;
648
+ }
649
+ .dg-menu {
650
+ position: fixed;
651
+ overflow-y: auto;
652
+ min-width: 230px;
653
+ background: var(--dg-raised);
654
+ border: 1px solid var(--dg-border-strong);
655
+ border-radius: 10px;
656
+ padding: 6px;
657
+ z-index: 1000; /* above the pop-up (900) */
658
+ box-shadow: 0 12px 30px rgb(0 0 0 / 0.45);
659
+ }
660
+ .dg-menu[hidden] {
661
+ display: none;
662
+ }
663
+ .dg-mg + .dg-mg {
664
+ border-top: 1px solid var(--border);
665
+ margin-top: 6px;
666
+ padding-top: 6px;
667
+ }
668
+ .dg-ml {
669
+ font-size: 11px;
670
+ text-transform: uppercase;
671
+ letter-spacing: 0.07em;
672
+ color: var(--dg-faint);
673
+ padding: 2px 8px 4px;
674
+ }
675
+ .dg-menu button {
676
+ display: block;
677
+ width: 100%;
678
+ text-align: left;
679
+ background: none;
680
+ border: 0;
681
+ border-radius: 6px;
682
+ padding: 6px 8px;
683
+ font-size: 13px;
684
+ cursor: pointer;
685
+ }
686
+ .dg-menu button:hover:not(:disabled),
687
+ .dg-menu button:focus-visible {
688
+ background: color-mix(in srgb, var(--text) 8%, transparent);
689
+ }
690
+ .dg-menu button:disabled {
691
+ opacity: 0.45;
692
+ cursor: not-allowed;
693
+ }
694
+ .dg-mg.danger button {
695
+ color: var(--red);
696
+ }
697
+ .dg-menu button.armed {
698
+ background: color-mix(in srgb, var(--red) 18%, transparent);
699
+ font-weight: 600;
700
+ }
701
+ .dg-tabs {
702
+ display: flex;
703
+ gap: 2px;
704
+ margin: 14px -18px -12px;
705
+ padding: 0 12px;
706
+ border-top: 1px solid var(--border);
707
+ overflow-x: auto;
708
+ }
709
+ .dg-tabs button {
710
+ background: none;
711
+ border: 0;
712
+ border-bottom: 2px solid transparent;
713
+ padding: 9px 10px;
714
+ color: var(--muted);
715
+ cursor: pointer;
716
+ font-size: 13px;
717
+ white-space: nowrap;
718
+ }
719
+ .dg-tabs button[aria-selected="true"] {
720
+ color: var(--text);
721
+ border-bottom-color: var(--accent);
722
+ }
723
+ .dg-tabs button:hover {
724
+ color: var(--text);
725
+ }
726
+ .dg-sec {
727
+ padding: 14px 18px;
728
+ border-bottom: 1px solid var(--border);
729
+ }
730
+ .dg-sec h3 {
731
+ margin: 0 0 10px;
732
+ font-size: 11.5px;
733
+ text-transform: uppercase;
734
+ letter-spacing: 0.08em;
735
+ color: var(--muted);
736
+ font-weight: 600;
737
+ }
738
+ .dg-sec a {
739
+ color: var(--accent);
740
+ }
741
+ .dg dl.kv {
742
+ display: grid;
743
+ grid-template-columns: 110px minmax(0, 1fr);
744
+ gap: 7px 12px;
745
+ margin: 0;
746
+ font-size: 13px;
747
+ }
748
+ .dg dl.kv dt {
749
+ color: var(--muted);
750
+ }
751
+ .dg dl.kv dd {
752
+ margin: 0;
753
+ min-width: 0;
754
+ overflow-wrap: anywhere;
755
+ }
756
+ .dg code {
757
+ font-family: var(--mono);
758
+ font-size: 12px;
759
+ background: var(--bg);
760
+ border: 1px solid var(--border);
761
+ border-radius: 5px;
762
+ padding: 1px 5px;
763
+ overflow-wrap: anywhere;
764
+ }
765
+ .dg-chips {
766
+ display: flex;
767
+ flex-wrap: wrap;
768
+ gap: 6px;
769
+ }
770
+ .dg-chip {
771
+ display: inline-flex;
772
+ align-items: center;
773
+ gap: 6px;
774
+ background: var(--bg);
775
+ border: 1px solid var(--border);
776
+ border-radius: 99px;
777
+ padding: 3px 10px;
778
+ font-size: 12.5px;
779
+ cursor: pointer;
780
+ font-family: var(--mono);
781
+ color: var(--text);
782
+ }
783
+ .dg-chip:hover {
784
+ border-color: var(--accent);
785
+ }
786
+ .dg-chip .dg-dot {
787
+ width: 7px;
788
+ height: 7px;
789
+ }
790
+ .dg-none {
791
+ color: var(--dg-faint);
792
+ font-size: 13px;
793
+ }
794
+ .dg-muted {
795
+ color: var(--muted);
796
+ }
797
+ .dg-callout {
798
+ margin: 0;
799
+ padding: 10px 12px;
800
+ border: 1px dashed color-mix(in srgb, var(--dg-remote) 60%, transparent);
801
+ border-radius: 8px;
802
+ font-size: 13px;
803
+ background: color-mix(in srgb, var(--dg-remote) 7%, transparent);
804
+ }
805
+ .dg-conn {
806
+ display: grid;
807
+ gap: 14px;
808
+ }
809
+ .dg-conn h4 {
810
+ margin: 0 0 7px;
811
+ font-size: 12.5px;
812
+ font-weight: 600;
813
+ }
814
+ .dg table.svc {
815
+ width: 100%;
816
+ border-collapse: collapse;
817
+ font-size: 13px;
818
+ }
819
+ .dg table.svc td {
820
+ padding: 7px 4px;
821
+ border-top: 1px solid var(--border);
822
+ vertical-align: middle;
823
+ }
824
+ .dg table.svc td:first-child {
825
+ width: 14px;
826
+ }
827
+ .dg table.svc .h {
828
+ color: var(--muted);
829
+ font-size: 12px;
830
+ }
831
+ .dg table.svc td.a {
832
+ text-align: right;
833
+ white-space: nowrap;
834
+ }
835
+ .dg table.svc button.nm {
836
+ background: none;
837
+ border: 0;
838
+ padding: 0;
839
+ font: inherit;
840
+ font-weight: 600;
841
+ cursor: pointer;
842
+ color: var(--text);
843
+ }
844
+ .dg table.svc button.nm:hover {
845
+ color: var(--accent);
846
+ }
847
+ .dg-logbar {
848
+ display: flex;
849
+ flex-wrap: wrap;
850
+ gap: 6px;
851
+ margin-bottom: 10px;
852
+ }
853
+ .dg-logbar input {
854
+ flex: 1;
855
+ min-width: 120px;
856
+ }
857
+ .dg pre.dg-log {
858
+ margin: 0;
859
+ background: var(--bg);
860
+ border: 1px solid var(--border);
861
+ border-radius: 8px;
862
+ padding: 10px;
863
+ font-family: var(--mono);
864
+ font-size: 12px;
865
+ white-space: pre;
866
+ overflow: auto;
867
+ min-height: 160px;
868
+ max-height: 55vh;
869
+ }
870
+ .dg pre.dg-log.wrap {
871
+ white-space: pre-wrap;
872
+ overflow-wrap: anywhere;
873
+ }
874
+ .dg ul.cmds {
875
+ list-style: none;
876
+ margin: 0;
877
+ padding: 0;
878
+ display: grid;
879
+ gap: 6px;
880
+ }
881
+ .dg ul.cmds li {
882
+ display: flex;
883
+ align-items: center;
884
+ justify-content: space-between;
885
+ gap: 10px;
886
+ }
887
+ .dg ol.act {
888
+ list-style: none;
889
+ margin: 0;
890
+ padding: 0;
891
+ display: grid;
892
+ gap: 8px;
893
+ font-size: 13px;
894
+ }
895
+ .dg ol.act li {
896
+ display: grid;
897
+ grid-template-columns: 48px auto minmax(0, 1fr);
898
+ gap: 10px;
899
+ align-items: baseline;
900
+ }
901
+ .dg ol.act time {
902
+ color: var(--dg-faint);
903
+ font-variant-numeric: tabular-nums;
904
+ font-size: 12px;
905
+ }
906
+ .dg ol.act span:last-child {
907
+ overflow-wrap: anywhere;
908
+ }
909
+ .dg-who {
910
+ font-size: 11.5px;
911
+ padding: 0 7px;
912
+ border-radius: 99px;
913
+ border: 1px solid var(--border);
914
+ color: var(--muted);
915
+ white-space: nowrap;
916
+ }
917
+ .dg-who.agent {
918
+ color: var(--yellow);
919
+ border-color: color-mix(in srgb, var(--yellow) 55%, transparent);
920
+ }
921
+ .dg-layers span {
922
+ font-family: var(--mono);
923
+ font-size: 12px;
924
+ padding: 1px 6px;
925
+ border: 1px solid var(--border);
926
+ border-radius: 5px;
927
+ margin-right: 4px;
928
+ }
929
+ .dg-toast {
930
+ position: fixed;
931
+ left: 50%;
932
+ bottom: 22px;
933
+ transform: translateX(-50%);
934
+ background: var(--dg-raised);
935
+ border: 1px solid var(--dg-border-strong);
936
+ border-radius: 8px;
937
+ padding: 8px 14px;
938
+ font-size: 13px;
939
+ z-index: 950;
940
+ max-width: calc(100vw - 32px);
941
+ color: var(--text);
942
+ }
943
+
944
+ @media (max-width: 760px) {
945
+ .dg-stage {
946
+ grid-template-columns: minmax(0, 1fr);
947
+ }
948
+ .dg-stage > .dg-panel {
949
+ position: fixed;
950
+ left: 0;
951
+ right: 0;
952
+ bottom: 0;
953
+ width: auto !important;
954
+ max-height: 70vh;
955
+ border-left: 0;
956
+ border-top: 1px solid var(--border);
957
+ border-radius: 14px 14px 0 0;
958
+ z-index: 800;
959
+ padding-bottom: env(safe-area-inset-bottom, 0px);
960
+ box-shadow: 0 -12px 30px rgb(0 0 0 / 0.45);
961
+ }
962
+ .dg-stage > .dg-panel .dg-resize {
963
+ display: none;
964
+ }
965
+ .dg-bar input[type="search"] {
966
+ width: 140px;
967
+ }
968
+ .dg-legend {
969
+ display: none;
970
+ }
971
+ }
972
+ @media (prefers-reduced-motion: reduce) {
973
+ .dg * {
974
+ transition: none !important;
975
+ }
976
+ }