@aiready/visualizer 0.1.37 → 0.1.40

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.
@@ -2,15 +2,15 @@ import { ThemeColors, GraphData, Theme, BusinessMetrics } from '../types';
2
2
 
3
3
  // Icons as inline SVG components for the theme toggle
4
4
  const SunIcon = ({ className }: { className?: string }) => (
5
- <svg
5
+ <svg
6
6
  className={className}
7
- width="16"
8
- height="16"
9
- viewBox="0 0 24 24"
10
- fill="none"
11
- stroke="currentColor"
12
- strokeWidth="2"
13
- strokeLinecap="round"
7
+ width="16"
8
+ height="16"
9
+ viewBox="0 0 24 24"
10
+ fill="none"
11
+ stroke="currentColor"
12
+ strokeWidth="2"
13
+ strokeLinecap="round"
14
14
  strokeLinejoin="round"
15
15
  >
16
16
  <circle cx="12" cy="12" r="4" />
@@ -26,15 +26,15 @@ const SunIcon = ({ className }: { className?: string }) => (
26
26
  );
27
27
 
28
28
  const MoonIcon = ({ className }: { className?: string }) => (
29
- <svg
29
+ <svg
30
30
  className={className}
31
- width="16"
32
- height="16"
33
- viewBox="0 0 24 24"
34
- fill="none"
35
- stroke="currentColor"
36
- strokeWidth="2"
37
- strokeLinecap="round"
31
+ width="16"
32
+ height="16"
33
+ viewBox="0 0 24 24"
34
+ fill="none"
35
+ stroke="currentColor"
36
+ strokeWidth="2"
37
+ strokeLinecap="round"
38
38
  strokeLinejoin="round"
39
39
  >
40
40
  <path d="M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z" />
@@ -42,15 +42,15 @@ const MoonIcon = ({ className }: { className?: string }) => (
42
42
  );
43
43
 
44
44
  const SystemIcon = ({ className }: { className?: string }) => (
45
- <svg
45
+ <svg
46
46
  className={className}
47
- width="16"
48
- height="16"
49
- viewBox="0 0 24 24"
50
- fill="none"
51
- stroke="currentColor"
52
- strokeWidth="2"
53
- strokeLinecap="round"
47
+ width="16"
48
+ height="16"
49
+ viewBox="0 0 24 24"
50
+ fill="none"
51
+ stroke="currentColor"
52
+ strokeWidth="2"
53
+ strokeLinecap="round"
54
54
  strokeLinejoin="round"
55
55
  >
56
56
  <rect width="20" height="14" x="2" y="3" rx="2" />
@@ -67,37 +67,43 @@ interface NavbarProps {
67
67
  metadata?: BusinessMetrics;
68
68
  }
69
69
 
70
- export function Navbar({ colors, theme, setTheme, data, metadata }: NavbarProps) {
70
+ export function Navbar({
71
+ colors,
72
+ theme,
73
+ setTheme,
74
+ data,
75
+ metadata,
76
+ }: NavbarProps) {
71
77
  return (
72
- <nav
78
+ <nav
73
79
  className="h-16 backdrop-blur-md border-b flex items-center justify-between px-6 z-50 relative"
74
- style={{
75
- backgroundColor: `${colors.panel}f5`,
76
- borderColor: colors.panelBorder
80
+ style={{
81
+ backgroundColor: `${colors.panel}f5`,
82
+ borderColor: colors.panelBorder,
77
83
  }}
78
84
  >
79
85
  {/* Subtle gradient overlay */}
80
- <div
86
+ <div
81
87
  className="absolute inset-0 pointer-events-none"
82
88
  style={{
83
89
  background: `linear-gradient(90deg, ${colors.panel}80 0%, transparent 50%, ${colors.panel}80 100%)`,
84
90
  }}
85
91
  />
86
-
92
+
87
93
  <div className="flex items-center gap-5 relative z-10">
88
94
  <div className="flex items-center justify-center">
89
- <img
90
- src="/logo-transparent-bg.png"
91
- alt="AIReady"
92
- className="h-9 w-auto"
95
+ <img
96
+ src="/logo-transparent-bg.png"
97
+ alt="AIReady"
98
+ className="h-9 w-auto"
93
99
  />
94
100
  </div>
95
- <div
96
- className="h-7 w-px"
97
- style={{ backgroundColor: colors.panelBorder }}
101
+ <div
102
+ className="h-7 w-px"
103
+ style={{ backgroundColor: colors.panelBorder }}
98
104
  />
99
- <h1
100
- className="text-sm font-semibold tracking-wide uppercase"
105
+ <h1
106
+ className="text-sm font-semibold tracking-wide uppercase"
101
107
  style={{ color: colors.textMuted }}
102
108
  >
103
109
  Codebase
@@ -106,7 +112,14 @@ export function Navbar({ colors, theme, setTheme, data, metadata }: NavbarProps)
106
112
 
107
113
  <div className="flex items-center gap-6 relative z-10">
108
114
  {/* Modern Theme Toggle */}
109
- <div className="flex items-center rounded-lg border px-4 py-3" style={{ borderColor: colors.panelBorder, backgroundColor: `${colors.panel}80`, gap: '12px' }}>
115
+ <div
116
+ className="flex items-center rounded-lg border px-4 py-3"
117
+ style={{
118
+ borderColor: colors.panelBorder,
119
+ backgroundColor: `${colors.panel}80`,
120
+ gap: '12px',
121
+ }}
122
+ >
110
123
  {[
111
124
  { key: 'dark', icon: MoonIcon, label: 'Dark' },
112
125
  { key: 'light', icon: SunIcon, label: 'Light' },
@@ -125,7 +138,7 @@ export function Navbar({ colors, theme, setTheme, data, metadata }: NavbarProps)
125
138
  }}
126
139
  title={`Switch to ${label} theme`}
127
140
  >
128
- <Icon
141
+ <Icon
129
142
  className="transition-transform duration-200"
130
143
  style={{ transform: theme === key ? 'scale(1.1)' : 'scale(1)' }}
131
144
  />
@@ -136,10 +149,10 @@ export function Navbar({ colors, theme, setTheme, data, metadata }: NavbarProps)
136
149
 
137
150
  {data && (
138
151
  <div className="flex items-center" style={{ gap: '12px' }}>
139
- <div
152
+ <div
140
153
  className="rounded-lg border text-xs font-medium flex items-center"
141
- style={{
142
- backgroundColor: `${colors.cardBg}cc`,
154
+ style={{
155
+ backgroundColor: `${colors.cardBg}cc`,
143
156
  borderColor: colors.cardBorder,
144
157
  padding: '8px 14px',
145
158
  gap: '8px',
@@ -149,10 +162,10 @@ export function Navbar({ colors, theme, setTheme, data, metadata }: NavbarProps)
149
162
  <span style={{ color: colors.textMuted }}>Files</span>
150
163
  <span style={{ color: colors.text }}>{data.nodes.length}</span>
151
164
  </div>
152
- <div
165
+ <div
153
166
  className="rounded-lg border text-xs font-medium flex items-center"
154
- style={{
155
- backgroundColor: `${colors.cardBg}cc`,
167
+ style={{
168
+ backgroundColor: `${colors.cardBg}cc`,
156
169
  borderColor: colors.cardBorder,
157
170
  padding: '8px 14px',
158
171
  gap: '8px',
@@ -163,10 +176,10 @@ export function Navbar({ colors, theme, setTheme, data, metadata }: NavbarProps)
163
176
  <span style={{ color: colors.text }}>{data.edges.length}</span>
164
177
  </div>
165
178
  {metadata?.estimatedMonthlyCost !== undefined && (
166
- <div
179
+ <div
167
180
  className="rounded-lg border text-xs font-medium flex items-center"
168
- style={{
169
- backgroundColor: `${colors.cardBg}cc`,
181
+ style={{
182
+ backgroundColor: `${colors.cardBg}cc`,
170
183
  borderColor: colors.cardBorder,
171
184
  padding: '8px 14px',
172
185
  gap: '8px',
@@ -178,7 +191,8 @@ export function Navbar({ colors, theme, setTheme, data, metadata }: NavbarProps)
178
191
  <span style={{ color: '#f59e0b', fontWeight: 600 }}>
179
192
  {metadata.estimatedMonthlyCost >= 1000
180
193
  ? `$${(metadata.estimatedMonthlyCost / 1000).toFixed(1)}k`
181
- : `$${metadata.estimatedMonthlyCost.toFixed(0)}`}/mo
194
+ : `$${metadata.estimatedMonthlyCost.toFixed(0)}`}
195
+ /mo
182
196
  </span>
183
197
  </div>
184
198
  )}
@@ -1,34 +1,29 @@
1
1
  import { ThemeColors, FileNode } from '../types';
2
2
 
3
3
  // Info Row Component for consistent styling
4
- function InfoRow({
5
- label,
6
- value,
4
+ function InfoRow({
5
+ label,
6
+ value,
7
7
  valueColor = 'inherit',
8
8
  highlight = false,
9
- colors
10
- }: {
11
- label: string;
9
+ colors,
10
+ }: {
11
+ label: string;
12
12
  value: string | number;
13
13
  valueColor?: string;
14
14
  highlight?: boolean;
15
15
  colors: ThemeColors;
16
16
  }) {
17
17
  return (
18
- <div
19
- className="flex justify-between items-center py-2.5 px-3 rounded-lg transition-colors hover:bg-white/5"
20
- >
21
- <span
22
- className="text-xs font-medium"
23
- style={{ color: colors.textMuted }}
24
- >
18
+ <div className="flex justify-between items-center py-2.5 px-3 rounded-lg transition-colors hover:bg-white/5">
19
+ <span className="text-xs font-medium" style={{ color: colors.textMuted }}>
25
20
  {label}
26
21
  </span>
27
- <span
22
+ <span
28
23
  className={`text-xs font-semibold ${highlight ? 'px-3 py-1 rounded-full' : ''}`}
29
- style={{
24
+ style={{
30
25
  color: valueColor,
31
- backgroundColor: highlight ? `${valueColor}25` : 'transparent'
26
+ backgroundColor: highlight ? `${valueColor}25` : 'transparent',
32
27
  }}
33
28
  >
34
29
  {value}
@@ -43,128 +38,163 @@ interface NodeDetailsProps {
43
38
  onClose?: () => void;
44
39
  }
45
40
 
46
- export function NodeDetails({ colors, selectedNode, onClose }: NodeDetailsProps) {
41
+ export function NodeDetails({
42
+ colors,
43
+ selectedNode,
44
+ onClose,
45
+ }: NodeDetailsProps) {
47
46
  return (
48
- <div
49
- style={{
47
+ <div
48
+ style={{
50
49
  padding: '16px 16px',
51
50
  height: '100%',
52
51
  overflowY: 'auto',
53
52
  overflowX: 'hidden',
54
- animation: 'fadeIn 0.2s ease-in'
53
+ animation: 'fadeIn 0.2s ease-in',
55
54
  }}
56
55
  >
57
56
  {/* Header */}
58
- <div className="flex justify-between items-center" style={{ marginBottom: '16px' }}>
57
+ <div
58
+ className="flex justify-between items-center"
59
+ style={{ marginBottom: '16px' }}
60
+ >
59
61
  <div className="flex items-center gap-2">
60
- <div
61
- className="w-2 h-2 rounded-full bg-cyan-400 animate-pulse"
62
- />
63
- <h3
64
- className="text-xs font-bold uppercase tracking-widest"
62
+ <div className="w-2 h-2 rounded-full bg-cyan-400 animate-pulse" />
63
+ <h3
64
+ className="text-xs font-bold uppercase tracking-widest"
65
65
  style={{ color: colors.textMuted }}
66
66
  >
67
67
  Selected Node
68
68
  </h3>
69
69
  </div>
70
70
  {onClose && (
71
- <button
71
+ <button
72
72
  onClick={onClose}
73
73
  className="p-2 rounded-lg hover:bg-white/10 transition-colors"
74
74
  style={{ color: colors.textMuted }}
75
75
  title="Close details"
76
76
  >
77
- <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
77
+ <svg
78
+ width="14"
79
+ height="14"
80
+ viewBox="0 0 24 24"
81
+ fill="none"
82
+ stroke="currentColor"
83
+ strokeWidth="2"
84
+ >
78
85
  <path d="M18 6L6 18M6 6l12 12" />
79
86
  </svg>
80
87
  </button>
81
88
  )}
82
89
  </div>
83
-
90
+
84
91
  {selectedNode ? (
85
92
  <div style={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>
86
93
  {/* File Name - No border, just padding */}
87
- <div className="p-4 rounded-xl"
88
- style={{
89
- backgroundColor: `${colors.cardBg}80`
94
+ <div
95
+ className="p-4 rounded-xl"
96
+ style={{
97
+ backgroundColor: `${colors.cardBg}80`,
90
98
  }}
91
99
  >
92
100
  <div className="flex items-center gap-2 mb-2">
93
- <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" className="text-amber-400">
101
+ <svg
102
+ width="16"
103
+ height="16"
104
+ viewBox="0 0 24 24"
105
+ fill="none"
106
+ stroke="currentColor"
107
+ strokeWidth="2"
108
+ className="text-amber-400"
109
+ >
94
110
  <path d="M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z" />
95
111
  <polyline points="14,2 14,8 20,8" />
96
112
  </svg>
97
- <h4 className="font-semibold text-sm truncate" style={{ color: colors.text }}>
113
+ <h4
114
+ className="font-semibold text-sm truncate"
115
+ style={{ color: colors.text }}
116
+ >
98
117
  {selectedNode.label}
99
118
  </h4>
100
119
  </div>
101
- <p
102
- className="text-xs break-all truncate"
120
+ <p
121
+ className="text-xs break-all truncate"
103
122
  style={{ color: colors.textMuted }}
104
123
  title={selectedNode.id}
105
124
  >
106
125
  {selectedNode.label}
107
126
  </p>
108
127
  </div>
109
-
128
+
110
129
  {/* Metrics - No border */}
111
130
  <div className="rounded-xl p-1">
112
131
  <div className="px-3 py-2">
113
- <span className="text-xs font-semibold uppercase tracking-wider" style={{ color: colors.textMuted }}>
132
+ <span
133
+ className="text-xs font-semibold uppercase tracking-wider"
134
+ style={{ color: colors.textMuted }}
135
+ >
114
136
  Metrics
115
137
  </span>
116
138
  </div>
117
139
  <div className="p-1">
118
- <InfoRow
119
- label="Severity"
120
- value={selectedNode.severity || 'none'}
140
+ <InfoRow
141
+ label="Severity"
142
+ value={selectedNode.severity || 'none'}
121
143
  valueColor={selectedNode.color}
122
144
  highlight
123
145
  colors={colors}
124
146
  />
125
- <InfoRow
126
- label="Token Cost"
127
- value={selectedNode.tokenCost?.toLocaleString() || '0'}
147
+ <InfoRow
148
+ label="Token Cost"
149
+ value={selectedNode.tokenCost?.toLocaleString() || '0'}
128
150
  valueColor="#22d3ee"
129
151
  colors={colors}
130
152
  />
131
153
  {selectedNode.duplicates !== undefined && (
132
- <InfoRow
133
- label="Issues Found"
134
- value={selectedNode.duplicates}
154
+ <InfoRow
155
+ label="Issues Found"
156
+ value={selectedNode.duplicates}
135
157
  valueColor="#c084fc"
136
158
  colors={colors}
137
159
  />
138
160
  )}
139
161
  </div>
140
162
  </div>
141
-
163
+
142
164
  {/* Description/Details - No border */}
143
165
  {selectedNode.title && (
144
- <div
166
+ <div
145
167
  className="rounded-xl p-4"
146
- style={{
147
- backgroundColor: `${colors.cardBg}80`
168
+ style={{
169
+ backgroundColor: `${colors.cardBg}80`,
148
170
  }}
149
171
  >
150
172
  <div className="flex items-center gap-2 mb-3">
151
- <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" style={{ color: colors.textMuted }}>
173
+ <svg
174
+ width="14"
175
+ height="14"
176
+ viewBox="0 0 24 24"
177
+ fill="none"
178
+ stroke="currentColor"
179
+ strokeWidth="2"
180
+ style={{ color: colors.textMuted }}
181
+ >
152
182
  <circle cx="12" cy="12" r="10" />
153
183
  <path d="M12 16v-4M12 8h.01" />
154
184
  </svg>
155
- <h5
156
- className="text-xs font-semibold uppercase tracking-wider"
185
+ <h5
186
+ className="text-xs font-semibold uppercase tracking-wider"
157
187
  style={{ color: colors.textMuted }}
158
188
  >
159
189
  Details
160
190
  </h5>
161
191
  </div>
162
- <pre
192
+ <pre
163
193
  className="text-xs whitespace-pre-wrap font-mono leading-relaxed p-3 rounded-lg"
164
- style={{
194
+ style={{
165
195
  color: colors.textMuted,
166
196
  backgroundColor: colors.panel,
167
- overflow: 'auto'
197
+ overflow: 'auto',
168
198
  }}
169
199
  >
170
200
  {selectedNode.title}
@@ -173,18 +203,18 @@ export function NodeDetails({ colors, selectedNode, onClose }: NodeDetailsProps)
173
203
  )}
174
204
  </div>
175
205
  ) : (
176
- <div
206
+ <div
177
207
  className="flex flex-col items-center justify-center py-10 text-center rounded-xl"
178
- style={{
179
- backgroundColor: `${colors.cardBg}50`
208
+ style={{
209
+ backgroundColor: `${colors.cardBg}50`,
180
210
  }}
181
211
  >
182
- <svg
183
- width="48"
184
- height="48"
185
- viewBox="0 0 24 24"
186
- fill="none"
187
- stroke="currentColor"
212
+ <svg
213
+ width="48"
214
+ height="48"
215
+ viewBox="0 0 24 24"
216
+ fill="none"
217
+ stroke="currentColor"
188
218
  strokeWidth="1.5"
189
219
  className="mb-3 opacity-40"
190
220
  style={{ color: colors.textMuted }}
@@ -192,8 +222,8 @@ export function NodeDetails({ colors, selectedNode, onClose }: NodeDetailsProps)
192
222
  <circle cx="11" cy="11" r="8" />
193
223
  <path d="m21 21-4.3-4.3" />
194
224
  </svg>
195
- <p
196
- className="text-sm font-medium"
225
+ <p
226
+ className="text-sm font-medium"
197
227
  style={{ color: colors.textMuted }}
198
228
  >
199
229
  Click a node to view details
@@ -3,11 +3,14 @@ import { Theme, EffectiveTheme } from '../types';
3
3
 
4
4
  export function useTheme() {
5
5
  const getSystemTheme = (): EffectiveTheme => {
6
- return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
6
+ return window.matchMedia('(prefers-color-scheme: dark)').matches
7
+ ? 'dark'
8
+ : 'light';
7
9
  };
8
10
 
9
11
  const [theme, setTheme] = useState<Theme>('system');
10
- const [systemTheme, setSystemTheme] = useState<EffectiveTheme>(getSystemTheme());
12
+ const [systemTheme, setSystemTheme] =
13
+ useState<EffectiveTheme>(getSystemTheme());
11
14
 
12
15
  useEffect(() => {
13
16
  const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
package/web/src/main.tsx CHANGED
@@ -8,4 +8,4 @@ createRoot(rootEl).render(
8
8
  <StrictMode>
9
9
  <App />
10
10
  </StrictMode>
11
- );
11
+ );
package/web/src/style.css CHANGED
@@ -1,2 +1,14 @@
1
- html,body,#app{height:100%;margin:0}
2
- #app{font-family:Inter,system-ui,Segoe UI,Roboto,sans-serif}
1
+ html,
2
+ body,
3
+ #app {
4
+ height: 100%;
5
+ margin: 0;
6
+ }
7
+ #app {
8
+ font-family:
9
+ Inter,
10
+ system-ui,
11
+ Segoe UI,
12
+ Roboto,
13
+ sans-serif;
14
+ }
@@ -1,4 +1,4 @@
1
- @import "tailwindcss";
1
+ @import 'tailwindcss';
2
2
 
3
3
  /* Base styles */
4
4
  * {
@@ -7,7 +7,9 @@
7
7
  padding: 0;
8
8
  }
9
9
 
10
- html, body, #root {
10
+ html,
11
+ body,
12
+ #root {
11
13
  height: 100%;
12
14
  width: 100%;
13
15
  overflow: hidden;
@@ -15,9 +17,9 @@ html, body, #root {
15
17
 
16
18
  body {
17
19
  margin: 0;
18
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
19
- 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
20
- sans-serif;
20
+ font-family:
21
+ -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu',
22
+ 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
21
23
  -webkit-font-smoothing: antialiased;
22
24
  -moz-osx-font-smoothing: grayscale;
23
25
  }