dev-guru 0.1.0__py3-none-any.whl
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.
- dev_guru/__init__.py +21 -0
- dev_guru/__main__.py +3 -0
- dev_guru/cli.py +149 -0
- dev_guru/client/__init__.py +22 -0
- dev_guru/client/inprocess.py +122 -0
- dev_guru/client/negotiation.py +69 -0
- dev_guru/client/port.py +87 -0
- dev_guru/errors.py +44 -0
- dev_guru/reports/__init__.py +1 -0
- dev_guru/reports/assets/explorer.css +218 -0
- dev_guru/reports/assets/explorer.html +75 -0
- dev_guru/reports/assets/explorer.js +822 -0
- dev_guru/reports/model.py +264 -0
- dev_guru/reports/render.py +137 -0
- dev_guru/sdk.py +56 -0
- dev_guru/service.py +53 -0
- dev_guru/version.py +3 -0
- dev_guru-0.1.0.dist-info/METADATA +113 -0
- dev_guru-0.1.0.dist-info/RECORD +22 -0
- dev_guru-0.1.0.dist-info/WHEEL +4 -0
- dev_guru-0.1.0.dist-info/entry_points.txt +2 -0
- dev_guru-0.1.0.dist-info/licenses/LICENSE +201 -0
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
/* Dev Guru explorer — "Lantern" theme. Inlined into a single offline file: system fonts only, no URLs. */
|
|
2
|
+
:root, [data-theme="night"] {
|
|
3
|
+
--bg: #0b0c18; --bg-2: #10122a; --panel: rgba(22, 24, 48, .86); --panel-solid: #15172f; --raise: #1d2042;
|
|
4
|
+
--ink: #eceaf8; --muted: #9b9dc4; --faint: #63668e; --line: rgba(160, 165, 255, .12); --line-2: rgba(160, 165, 255, .22);
|
|
5
|
+
--saffron: #ffb347; --ember: #ff6b3d; --teal: #3dd6c6; --violet: #9b87ff; --rose: #ff6f91; --lime: #b7ef6a;
|
|
6
|
+
--glow: 0 0 0 1px rgba(255, 179, 71, .35), 0 0 22px rgba(255, 140, 50, .25);
|
|
7
|
+
--shadow: 0 18px 50px rgba(0, 0, 0, .45); --code: #0e1024; --sel: rgba(255, 179, 71, .18);
|
|
8
|
+
color-scheme: dark;
|
|
9
|
+
}
|
|
10
|
+
[data-theme="day"] {
|
|
11
|
+
--bg: #fbf6ec; --bg-2: #f4ecdc; --panel: rgba(255, 255, 255, .9); --panel-solid: #ffffff; --raise: #fff7ea;
|
|
12
|
+
--ink: #1e1c33; --muted: #5e5a7a; --faint: #a19cb8; --line: rgba(40, 30, 90, .1); --line-2: rgba(40, 30, 90, .2);
|
|
13
|
+
--saffron: #d97a00; --ember: #d9481c; --teal: #0e9b8d; --violet: #6a52e0; --rose: #d43d68; --lime: #4f8f0b;
|
|
14
|
+
--glow: 0 0 0 1px rgba(217, 122, 0, .4), 0 0 18px rgba(217, 122, 0, .18);
|
|
15
|
+
--shadow: 0 14px 40px rgba(60, 40, 10, .14); --code: #fff8ec; --sel: rgba(217, 122, 0, .14);
|
|
16
|
+
color-scheme: light;
|
|
17
|
+
}
|
|
18
|
+
* { box-sizing: border-box; }
|
|
19
|
+
[hidden] { display: none !important; }
|
|
20
|
+
html, body { margin: 0; height: 100%; }
|
|
21
|
+
body {
|
|
22
|
+
font: 14px/1.45 ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
|
23
|
+
color: var(--ink); background:
|
|
24
|
+
radial-gradient(1200px 700px at 78% -10%, rgba(255, 140, 50, .10), transparent 60%),
|
|
25
|
+
radial-gradient(900px 600px at -10% 110%, rgba(61, 214, 198, .08), transparent 60%), var(--bg);
|
|
26
|
+
overflow: hidden;
|
|
27
|
+
}
|
|
28
|
+
code, pre, kbd, .mono { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace; }
|
|
29
|
+
button { font: inherit; color: inherit; }
|
|
30
|
+
.skip { position: absolute; left: -999px; top: 0; }
|
|
31
|
+
.skip:focus { left: 12px; top: 12px; z-index: 50; background: var(--panel-solid); padding: 8px 12px; border-radius: 10px; }
|
|
32
|
+
:focus-visible { outline: 2px solid var(--saffron); outline-offset: 2px; }
|
|
33
|
+
.muted { color: var(--muted); }
|
|
34
|
+
.app { display: grid; grid-template-rows: auto auto 1fr auto; height: 100vh; }
|
|
35
|
+
|
|
36
|
+
/* top bar */
|
|
37
|
+
.top { display: flex; align-items: center; gap: 14px; padding: 10px 16px; border-bottom: 1px solid var(--line); background: linear-gradient(180deg, rgba(255, 179, 71, .05), transparent); }
|
|
38
|
+
.brand { display: flex; align-items: center; gap: 10px; min-width: 0; }
|
|
39
|
+
.mark { width: 30px; height: 30px; color: var(--muted); filter: drop-shadow(0 0 8px rgba(255, 150, 60, .55)); animation: flicker 4s ease-in-out infinite; }
|
|
40
|
+
@keyframes flicker { 0%, 100% { transform: scale(1); } 45% { transform: scale(1.04) rotate(-1deg); } 60% { transform: scale(.98) rotate(1deg); } }
|
|
41
|
+
.brand-text { display: flex; flex-direction: column; line-height: 1.1; min-width: 0; }
|
|
42
|
+
.brand-text strong { letter-spacing: .02em; }
|
|
43
|
+
.brand-text span { color: var(--muted); font-size: 12px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 26ch; }
|
|
44
|
+
.tabs { display: flex; gap: 4px; padding: 4px; border-radius: 14px; background: var(--bg-2); border: 1px solid var(--line); margin: 0 auto; overflow-x: auto; max-width: 100%; }
|
|
45
|
+
.tab { border: 0; background: transparent; padding: 7px 12px; border-radius: 10px; cursor: pointer; color: var(--muted); white-space: nowrap; display: flex; gap: 6px; align-items: center; }
|
|
46
|
+
.tab:hover { color: var(--ink); background: var(--raise); }
|
|
47
|
+
.tab[aria-selected="true"] { color: var(--ink); background: var(--raise); box-shadow: var(--glow); }
|
|
48
|
+
.tab .ic { color: var(--saffron); }
|
|
49
|
+
.top-actions { display: flex; gap: 6px; }
|
|
50
|
+
.btn { border: 1px solid var(--line-2); background: var(--panel-solid); padding: 6px 11px; border-radius: 10px; cursor: pointer; display: inline-flex; align-items: center; gap: 6px; }
|
|
51
|
+
.btn:hover { border-color: var(--saffron); }
|
|
52
|
+
.btn.ghost { background: transparent; }
|
|
53
|
+
.btn.icon { width: 32px; height: 32px; justify-content: center; padding: 0; }
|
|
54
|
+
.btn.primary { background: linear-gradient(135deg, var(--saffron), var(--ember)); color: #1b1206; border: 0; font-weight: 650; }
|
|
55
|
+
kbd { font-size: 11px; padding: 1px 6px; border-radius: 6px; border: 1px solid var(--line-2); color: var(--muted); }
|
|
56
|
+
|
|
57
|
+
/* stats ribbon */
|
|
58
|
+
.stats { display: flex; gap: 10px; padding: 8px 16px; overflow-x: auto; border-bottom: 1px solid var(--line); }
|
|
59
|
+
.stat { flex: none; display: flex; align-items: baseline; gap: 6px; padding: 4px 12px; border-radius: 999px; background: var(--bg-2); border: 1px solid var(--line); }
|
|
60
|
+
.stat b { font-size: 15px; font-variant-numeric: tabular-nums; }
|
|
61
|
+
.stat span { color: var(--muted); font-size: 12px; }
|
|
62
|
+
.stat.warn b { color: var(--rose); }
|
|
63
|
+
|
|
64
|
+
/* three columns */
|
|
65
|
+
.workspace { display: grid; grid-template-columns: 290px 1fr 360px; min-height: 0; }
|
|
66
|
+
.sidebar, .inspector { min-height: 0; overflow: auto; padding: 14px; background: var(--panel); backdrop-filter: blur(8px); }
|
|
67
|
+
.sidebar { border-right: 1px solid var(--line); }
|
|
68
|
+
.inspector { border-left: 1px solid var(--line); }
|
|
69
|
+
.eyebrow { font-size: 11px; text-transform: uppercase; letter-spacing: .12em; color: var(--faint); margin: 16px 0 8px; font-weight: 600; }
|
|
70
|
+
.search { display: flex; align-items: center; gap: 8px; padding: 8px 10px; border-radius: 12px; background: var(--bg-2); border: 1px solid var(--line); }
|
|
71
|
+
.search input { flex: 1; border: 0; background: transparent; color: var(--ink); outline: none; font: inherit; min-width: 0; }
|
|
72
|
+
.results { margin-top: 6px; border: 1px solid var(--line); border-radius: 12px; overflow: hidden; }
|
|
73
|
+
.result, .tree-item, .pl-item { display: flex; gap: 8px; align-items: center; width: 100%; text-align: left; border: 0; background: transparent; padding: 6px 8px; border-radius: 8px; cursor: pointer; color: var(--ink); }
|
|
74
|
+
.result:hover, .tree-item:hover, .pl-item:hover, .result[aria-selected="true"], .pl-item[aria-selected="true"] { background: var(--sel); }
|
|
75
|
+
.tree-item[aria-current="true"] { background: var(--sel); box-shadow: inset 2px 0 0 var(--saffron); }
|
|
76
|
+
.tree-item .count, .result .where { margin-left: auto; color: var(--faint); font-size: 12px; }
|
|
77
|
+
.tree-pkg { font-weight: 600; color: var(--muted); }
|
|
78
|
+
.tree-children { margin-left: 12px; border-left: 1px dashed var(--line-2); padding-left: 6px; }
|
|
79
|
+
.dot { width: 9px; height: 9px; border-radius: 50%; flex: none; box-shadow: 0 0 8px currentColor; background: currentColor; }
|
|
80
|
+
.kind { font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; padding: 1px 6px; border-radius: 6px; border: 1px solid var(--line-2); color: var(--muted); flex: none; }
|
|
81
|
+
.kind.class { color: var(--violet); } .kind.function { color: var(--teal); } .kind.method { color: var(--saffron); } .kind.file { color: var(--ink); }
|
|
82
|
+
.insight { display: block; width: 100%; text-align: left; border: 1px solid var(--line); background: linear-gradient(135deg, var(--bg-2), transparent); padding: 9px 11px; border-radius: 12px; margin-bottom: 6px; cursor: pointer; }
|
|
83
|
+
.insight:hover { border-color: var(--saffron); }
|
|
84
|
+
.insight b { display: block; font-size: 12px; color: var(--muted); font-weight: 600; }
|
|
85
|
+
.insight span { font-size: 13px; }
|
|
86
|
+
|
|
87
|
+
/* stage */
|
|
88
|
+
.stage-wrap { display: grid; grid-template-rows: auto 1fr auto; min-height: 0; min-width: 0; }
|
|
89
|
+
.stage-head { display: flex; justify-content: space-between; align-items: flex-end; gap: 12px; padding: 12px 16px 8px; }
|
|
90
|
+
.stage-head h1 { margin: 0; font-size: 18px; letter-spacing: .01em; }
|
|
91
|
+
.stage-head p { margin: 2px 0 0; font-size: 13px; }
|
|
92
|
+
.stage-tools { display: flex; gap: 6px; flex-wrap: wrap; justify-content: flex-end; }
|
|
93
|
+
.chip { border: 1px solid var(--line-2); background: transparent; border-radius: 999px; padding: 4px 10px; font-size: 12px; cursor: pointer; color: var(--muted); }
|
|
94
|
+
.chip[aria-pressed="true"] { color: var(--ink); background: var(--sel); border-color: var(--saffron); }
|
|
95
|
+
.stage { position: relative; margin: 0 12px 12px; border-radius: 18px; border: 1px solid var(--line); overflow: hidden; min-height: 0;
|
|
96
|
+
background: radial-gradient(circle at 50% 50%, rgba(155, 135, 255, .07), transparent 70%), var(--bg-2); }
|
|
97
|
+
.stage::before { content: ""; position: absolute; inset: 0; pointer-events: none; opacity: .5;
|
|
98
|
+
background-image: radial-gradient(1px 1px at 20% 30%, var(--faint), transparent), radial-gradient(1px 1px at 70% 80%, var(--faint), transparent),
|
|
99
|
+
radial-gradient(1px 1px at 40% 70%, var(--faint), transparent), radial-gradient(1px 1px at 85% 25%, var(--faint), transparent),
|
|
100
|
+
radial-gradient(1.5px 1.5px at 55% 15%, var(--muted), transparent); background-size: 260px 260px; }
|
|
101
|
+
.canvas { width: 100%; height: 100%; display: block; cursor: grab; touch-action: none; }
|
|
102
|
+
.canvas.dragging { cursor: grabbing; }
|
|
103
|
+
.zoom { position: absolute; right: 12px; bottom: 12px; display: flex; flex-direction: column; gap: 6px; }
|
|
104
|
+
.legend { position: absolute; left: 12px; bottom: 12px; display: flex; gap: 10px; flex-wrap: wrap; font-size: 12px; color: var(--muted); background: var(--panel); padding: 6px 10px; border-radius: 10px; border: 1px solid var(--line); max-width: 70%; }
|
|
105
|
+
.legend i { display: inline-block; width: 18px; height: 2px; vertical-align: middle; margin-right: 5px; border-radius: 2px; }
|
|
106
|
+
.hint:empty { display: none; }
|
|
107
|
+
.hint { position: absolute; left: 50%; top: 10px; transform: translateX(-50%); font-size: 12px; color: var(--muted); background: var(--panel); padding: 5px 12px; border-radius: 999px; border: 1px solid var(--line); pointer-events: none; white-space: nowrap; max-width: 90%; overflow: hidden; text-overflow: ellipsis; }
|
|
108
|
+
|
|
109
|
+
/* svg graph */
|
|
110
|
+
.edge { fill: none; stroke: var(--line-2); stroke-width: 1.2; transition: opacity .25s, stroke .25s; }
|
|
111
|
+
.edge.imports { stroke: rgba(155, 135, 255, .35); }
|
|
112
|
+
.edge.calls { stroke: rgba(61, 214, 198, .5); }
|
|
113
|
+
.edge.inherits { stroke: rgba(255, 111, 145, .6); stroke-dasharray: 5 4; }
|
|
114
|
+
.edge.cycle { stroke: var(--rose); stroke-width: 2; }
|
|
115
|
+
.edge.hot { stroke: var(--saffron); stroke-width: 2.2; stroke-dasharray: 7 6; animation: flow 1.1s linear infinite; opacity: 1 !important; }
|
|
116
|
+
.edge.hot.calls { stroke: var(--teal); }
|
|
117
|
+
@keyframes flow { to { stroke-dashoffset: -26; } }
|
|
118
|
+
.node { cursor: pointer; transition: opacity .25s; }
|
|
119
|
+
.node circle.core { stroke: rgba(255, 255, 255, .55); stroke-width: 1; transition: r .25s; }
|
|
120
|
+
.node .halo { opacity: 0; transition: opacity .25s; }
|
|
121
|
+
.node:hover .halo, .node.hot .halo, .node.selected .halo { opacity: .9; }
|
|
122
|
+
.node.selected circle.core { stroke: var(--saffron); stroke-width: 3; }
|
|
123
|
+
.node text { fill: var(--ink); font-size: 11px; paint-order: stroke; stroke: var(--bg-2); stroke-width: 3px; pointer-events: none; }
|
|
124
|
+
.node text.sub { fill: var(--muted); font-size: 9.5px; }
|
|
125
|
+
.dim .node:not(.hot):not(.selected) { opacity: .16; }
|
|
126
|
+
.dim .edge:not(.hot) { opacity: .06; }
|
|
127
|
+
.pkg-halo { fill: var(--line); stroke: var(--line-2); stroke-dasharray: 2 6; }
|
|
128
|
+
.pkg-label { fill: var(--faint); font-size: 12px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; }
|
|
129
|
+
.ring { fill: none; stroke: var(--line-2); stroke-dasharray: 3 7; }
|
|
130
|
+
.ring-label { fill: var(--faint); font-size: 11px; }
|
|
131
|
+
.ripple { fill: none; stroke: var(--saffron); stroke-width: 2; opacity: 0; }
|
|
132
|
+
.ripple.go { animation: ripple 1.6s ease-out forwards; }
|
|
133
|
+
@keyframes ripple { 0% { opacity: .9; r: 10; } 100% { opacity: 0; r: 420; } }
|
|
134
|
+
.pulse { fill: var(--saffron); filter: drop-shadow(0 0 6px var(--saffron)); }
|
|
135
|
+
.lane-label { fill: var(--faint); font-size: 11px; letter-spacing: .1em; text-transform: uppercase; }
|
|
136
|
+
.box rect { stroke: var(--line-2); rx: 10; }
|
|
137
|
+
.box text { fill: var(--ink); font-size: 11px; pointer-events: none; }
|
|
138
|
+
|
|
139
|
+
/* treemap */
|
|
140
|
+
.treemap { position: absolute; inset: 0; }
|
|
141
|
+
.tm-cell { position: absolute; border: 1px solid var(--bg-2); border-radius: 6px; overflow: hidden; padding: 4px 6px; cursor: pointer; font-size: 11px; color: #160f05; transition: transform .2s, filter .2s; }
|
|
142
|
+
.tm-cell:hover, .tm-cell.selected { filter: brightness(1.15); z-index: 2; outline: 2px solid var(--ink); }
|
|
143
|
+
.tm-cell b { display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
144
|
+
.tm-cell small { opacity: .75; }
|
|
145
|
+
|
|
146
|
+
/* inspector */
|
|
147
|
+
.ins-head { display: flex; gap: 10px; align-items: flex-start; }
|
|
148
|
+
.ins-head h2 { margin: 0; font-size: 16px; word-break: break-word; }
|
|
149
|
+
.ins-path { color: var(--muted); font-size: 12px; word-break: break-all; margin-top: 2px; }
|
|
150
|
+
.ins-doc { margin: 10px 0; padding: 10px 12px; border-radius: 12px; background: var(--bg-2); border-left: 3px solid var(--saffron); color: var(--ink); }
|
|
151
|
+
.facts { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; margin: 10px 0; }
|
|
152
|
+
.fact { background: var(--bg-2); border: 1px solid var(--line); border-radius: 12px; padding: 8px; text-align: center; }
|
|
153
|
+
.fact b { display: block; font-size: 17px; font-variant-numeric: tabular-nums; }
|
|
154
|
+
.fact span { font-size: 11px; color: var(--muted); }
|
|
155
|
+
.sig { font-size: 12px; padding: 8px 10px; background: var(--code); border-radius: 10px; border: 1px solid var(--line); white-space: pre-wrap; word-break: break-word; color: var(--teal); }
|
|
156
|
+
pre.src { margin: 0; font-size: 12px; line-height: 1.55; background: var(--code); border: 1px solid var(--line); border-radius: 12px; padding: 10px 0; overflow: auto; max-height: 340px; counter-reset: ln; }
|
|
157
|
+
pre.src span { display: block; padding: 0 12px 0 0; white-space: pre; }
|
|
158
|
+
pre.src span::before { counter-increment: ln; content: attr(data-ln); display: inline-block; width: 3.6em; padding-right: .9em; text-align: right; color: var(--faint); user-select: none; }
|
|
159
|
+
.links { display: flex; flex-direction: column; gap: 2px; }
|
|
160
|
+
.link { display: flex; gap: 8px; align-items: center; border: 0; background: transparent; padding: 5px 6px; border-radius: 8px; text-align: left; cursor: pointer; color: var(--ink); }
|
|
161
|
+
.link:hover { background: var(--sel); }
|
|
162
|
+
.link .where { margin-left: auto; color: var(--faint); font-size: 11px; }
|
|
163
|
+
.actions { display: flex; gap: 6px; flex-wrap: wrap; margin: 10px 0; }
|
|
164
|
+
.tagline { display: flex; gap: 6px; flex-wrap: wrap; }
|
|
165
|
+
.tag { font-size: 11px; padding: 2px 8px; border-radius: 999px; background: var(--bg-2); border: 1px solid var(--line); color: var(--muted); }
|
|
166
|
+
.empty { color: var(--muted); padding: 20px 6px; text-align: center; }
|
|
167
|
+
.empty .big { font-size: 34px; display: block; margin-bottom: 6px; filter: drop-shadow(0 0 10px rgba(255, 150, 60, .5)); }
|
|
168
|
+
|
|
169
|
+
/* narration (tour) */
|
|
170
|
+
.narration { display: grid; grid-template-columns: 1fr auto; gap: 8px 14px; align-items: center; margin: 0 12px 12px; padding: 12px 16px; border-radius: 16px; border: 1px solid var(--line-2); background: linear-gradient(135deg, rgba(255, 179, 71, .12), rgba(155, 135, 255, .08)); box-shadow: var(--shadow); }
|
|
171
|
+
.narration-text p { margin: 2px 0 0; font-size: 15px; }
|
|
172
|
+
.step { font-size: 11px; letter-spacing: .12em; text-transform: uppercase; color: var(--saffron); font-weight: 700; }
|
|
173
|
+
.narration-ctl { display: flex; gap: 6px; }
|
|
174
|
+
.dots { grid-column: 1 / -1; display: flex; gap: 5px; }
|
|
175
|
+
.dots i { height: 3px; flex: 1; border-radius: 3px; background: var(--line-2); }
|
|
176
|
+
.dots i.on { background: linear-gradient(90deg, var(--saffron), var(--ember)); }
|
|
177
|
+
|
|
178
|
+
/* footer, palette, modal, toast */
|
|
179
|
+
.foot { display: flex; gap: 14px; flex-wrap: wrap; padding: 6px 16px; border-top: 1px solid var(--line); font-size: 11.5px; color: var(--faint); }
|
|
180
|
+
.foot b { color: var(--muted); font-weight: 600; }
|
|
181
|
+
.palette, .modal { position: fixed; inset: 0; background: rgba(5, 5, 15, .55); backdrop-filter: blur(3px); display: grid; place-items: start center; padding-top: 12vh; z-index: 40; }
|
|
182
|
+
.palette[hidden], .modal[hidden] { display: none; }
|
|
183
|
+
.palette-box, .modal-box { width: min(640px, 92vw); background: var(--panel-solid); border: 1px solid var(--line-2); border-radius: 16px; box-shadow: var(--shadow); overflow: hidden; }
|
|
184
|
+
.palette-box input { width: 100%; border: 0; border-bottom: 1px solid var(--line); background: transparent; color: var(--ink); padding: 14px 16px; font-size: 15px; outline: none; }
|
|
185
|
+
.palette-list { max-height: 50vh; overflow: auto; padding: 6px; }
|
|
186
|
+
.modal-box { padding: 18px 20px; max-height: 76vh; overflow: auto; }
|
|
187
|
+
.modal-box h2 { margin-top: 0; }
|
|
188
|
+
.modal-box li { margin: 4px 0; }
|
|
189
|
+
.manifest { font-size: 12px; background: var(--code); border-radius: 10px; padding: 10px; overflow: auto; border: 1px solid var(--line); }
|
|
190
|
+
.toast { position: fixed; left: 50%; bottom: 22px; transform: translateX(-50%) translateY(30px); background: var(--panel-solid); border: 1px solid var(--saffron); padding: 8px 16px; border-radius: 999px; opacity: 0; transition: .25s; z-index: 60; pointer-events: none; }
|
|
191
|
+
.toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }
|
|
192
|
+
|
|
193
|
+
/* responsive */
|
|
194
|
+
.hide-sm { }
|
|
195
|
+
@media (max-width: 1180px) { .workspace { grid-template-columns: 250px 1fr; } .inspector { position: fixed; right: 0; top: 0; bottom: 0; width: min(380px, 92vw); z-index: 30; transform: translateX(100%); transition: transform .25s; box-shadow: var(--shadow); } .inspector.open { transform: none; } }
|
|
196
|
+
@media (max-width: 760px) {
|
|
197
|
+
body { overflow: auto; }
|
|
198
|
+
.app { height: auto; min-height: 100vh; }
|
|
199
|
+
.top { flex-wrap: wrap; } .tabs { order: 3; width: 100%; margin: 0; } .hide-sm { display: none; }
|
|
200
|
+
.workspace { grid-template-columns: 1fr; }
|
|
201
|
+
.sidebar { border-right: 0; border-bottom: 1px solid var(--line); max-height: 40vh; min-width: 0; }
|
|
202
|
+
.stage-wrap { min-width: 0; }
|
|
203
|
+
.stage { height: 62vh; } .stage-head { flex-direction: column; align-items: flex-start; }
|
|
204
|
+
}
|
|
205
|
+
@media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation: none !important; transition: none !important; } }
|
|
206
|
+
|
|
207
|
+
/* embed mode (#embed=1): a report framed inside another page shows only the tabs and the stage */
|
|
208
|
+
.embed .sidebar, .embed .inspector, .embed .stats, .embed .foot, .embed .top-actions, .embed .stage-head p, .embed .legend, .embed .brand-text { display: none !important; }
|
|
209
|
+
html.embed, .embed body { height: 100%; overflow: hidden; }
|
|
210
|
+
.embed .app { height: 100vh; min-height: 0; grid-template-rows: auto minmax(0, 1fr); }
|
|
211
|
+
.embed .workspace { grid-template-columns: minmax(0, 1fr) !important; grid-template-rows: minmax(0, 1fr); min-height: 0; }
|
|
212
|
+
.embed .stage-wrap { min-width: 0; min-height: 0; grid-template-rows: auto minmax(0, 1fr) auto; }
|
|
213
|
+
.embed .top { flex-wrap: nowrap; padding: 6px 10px; gap: 8px; }
|
|
214
|
+
.embed .tabs { order: 0; flex: 1; min-width: 0; width: auto; margin: 0; }
|
|
215
|
+
.embed .tab { padding: 5px 8px; font-size: 12px; }
|
|
216
|
+
.embed .stage-head { padding: 6px 10px 4px; flex-direction: row; align-items: center; }
|
|
217
|
+
.embed .stage-head h1 { font-size: 14px; }
|
|
218
|
+
.embed .stage { margin: 0 8px 8px; height: auto !important; min-height: 0; }
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en" data-theme="night">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
|
+
<meta name="generator" content="Dev Guru explorer">
|
|
7
|
+
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; style-src 'unsafe-inline'; script-src 'unsafe-inline'; img-src data: blob:; connect-src 'none'; form-action 'none'; base-uri 'none'">
|
|
8
|
+
<title>{{TITLE}}</title>
|
|
9
|
+
<style>{{CSS}}</style>
|
|
10
|
+
</head>
|
|
11
|
+
<body>
|
|
12
|
+
<a class="skip" href="#inspector">Skip to inspector</a>
|
|
13
|
+
<div class="app" id="app">
|
|
14
|
+
<header class="top">
|
|
15
|
+
<div class="brand">
|
|
16
|
+
<svg class="mark" viewBox="0 0 32 32" aria-hidden="true"><defs><radialGradient id="flame" cx="50%" cy="60%" r="60%"><stop offset="0" stop-color="#fff3c4"/><stop offset=".45" stop-color="#ffb347"/><stop offset="1" stop-color="#ff6b3d"/></radialGradient></defs><path d="M16 3c3 5 8 8 8 15a8 8 0 0 1-16 0c0-4 2-6 3-8 1 3 2 4 4 4-1-4 0-8 1-11z" fill="url(#flame)"/><path d="M6 25h20l-2 4H8z" fill="currentColor" opacity=".7"/></svg>
|
|
17
|
+
<div class="brand-text"><strong>Dev Guru</strong><span id="projectName">explorer</span></div>
|
|
18
|
+
</div>
|
|
19
|
+
<nav class="tabs" role="tablist" aria-label="Views" id="tabs"></nav>
|
|
20
|
+
<div class="top-actions">
|
|
21
|
+
<button class="btn ghost" id="searchBtn" title="Search (/)"><span aria-hidden="true">⌕</span><span class="hide-sm"> Search</span><kbd class="hide-sm">/</kbd></button>
|
|
22
|
+
<button class="btn ghost" id="paletteBtn" title="Command palette (Ctrl/⌘ K)"><span aria-hidden="true">⌘</span><span class="hide-sm"> Commands</span></button>
|
|
23
|
+
<button class="btn ghost icon" id="themeBtn" aria-label="Toggle light and dark theme" title="Theme">◐</button>
|
|
24
|
+
<button class="btn ghost icon" id="infoBtn" aria-label="About this report and its limitations" title="About">ⓘ</button>
|
|
25
|
+
</div>
|
|
26
|
+
</header>
|
|
27
|
+
<div class="stats" id="stats" aria-label="Project summary"></div>
|
|
28
|
+
<div class="workspace">
|
|
29
|
+
<aside class="sidebar" id="sidebar" aria-label="Repository">
|
|
30
|
+
<label class="search"><span aria-hidden="true">⌕</span><input id="search" type="search" placeholder="Find files, classes, functions…" autocomplete="off" aria-label="Find files and symbols"></label>
|
|
31
|
+
<div id="results" class="results" role="listbox" aria-label="Search results" hidden></div>
|
|
32
|
+
<section class="insights" id="insights" aria-label="Insights"></section>
|
|
33
|
+
<h2 class="eyebrow">Packages</h2>
|
|
34
|
+
<div id="tree" class="tree" role="tree" aria-label="Packages and files"></div>
|
|
35
|
+
</aside>
|
|
36
|
+
<main class="stage-wrap" id="main">
|
|
37
|
+
<div class="stage-head">
|
|
38
|
+
<div><h1 id="viewTitle">Constellation</h1><p id="viewDesc" class="muted"></p></div>
|
|
39
|
+
<div class="stage-tools" id="stageTools"></div>
|
|
40
|
+
</div>
|
|
41
|
+
<div class="stage" id="stage" tabindex="0" aria-label="Interactive graph. Use the sidebar for keyboard navigation.">
|
|
42
|
+
<svg id="svg" class="canvas" role="img" aria-labelledby="viewTitle"></svg>
|
|
43
|
+
<div id="treemap" class="treemap" hidden></div>
|
|
44
|
+
<div class="zoom" id="zoomTools">
|
|
45
|
+
<button class="btn icon" id="zoomIn" aria-label="Zoom in">+</button>
|
|
46
|
+
<button class="btn icon" id="zoomOut" aria-label="Zoom out">−</button>
|
|
47
|
+
<button class="btn icon" id="fitBtn" aria-label="Fit to screen">⤢</button>
|
|
48
|
+
</div>
|
|
49
|
+
<div class="legend" id="legend" aria-hidden="true"></div>
|
|
50
|
+
<div class="hint" id="hint"></div>
|
|
51
|
+
</div>
|
|
52
|
+
<div class="narration" id="narration" aria-live="polite" hidden>
|
|
53
|
+
<div class="narration-text"><span class="step" id="tourStep"></span><p id="tourText"></p></div>
|
|
54
|
+
<div class="narration-ctl">
|
|
55
|
+
<button class="btn icon" id="tourPrev" aria-label="Previous step">‹</button>
|
|
56
|
+
<button class="btn" id="tourPlay">❚❚ Pause</button>
|
|
57
|
+
<button class="btn icon" id="tourNext" aria-label="Next step">›</button>
|
|
58
|
+
</div>
|
|
59
|
+
<div class="dots" id="tourDots" aria-hidden="true"></div>
|
|
60
|
+
</div>
|
|
61
|
+
</main>
|
|
62
|
+
<aside class="inspector" id="inspector" aria-label="Inspector" tabindex="-1"><div id="inspectBody"></div></aside>
|
|
63
|
+
</div>
|
|
64
|
+
<footer class="foot" id="foot"></footer>
|
|
65
|
+
</div>
|
|
66
|
+
<div class="palette" id="palette" role="dialog" aria-modal="true" aria-label="Command palette" hidden>
|
|
67
|
+
<div class="palette-box"><input id="paletteInput" placeholder="Jump to a file or symbol, or type a command…" aria-label="Command"><div id="paletteList" class="palette-list" role="listbox"></div></div>
|
|
68
|
+
</div>
|
|
69
|
+
<div class="modal" id="about" role="dialog" aria-modal="true" aria-labelledby="aboutTitle" hidden><div class="modal-box" id="aboutBody"></div></div>
|
|
70
|
+
<div class="toast" id="toast" role="status" aria-live="polite"></div>
|
|
71
|
+
<script type="application/json" id="dg-data">{{DATA}}</script>
|
|
72
|
+
<script type="application/json" id="dg-manifest">{{MANIFEST}}</script>
|
|
73
|
+
<script>{{JS}}</script>
|
|
74
|
+
</body>
|
|
75
|
+
</html>
|