codegraphy-lite 1.0.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.
- codegraphy_lite/__init__.py +7 -0
- codegraphy_lite/cli.py +113 -0
- codegraphy_lite/mcp.py +338 -0
- codegraphy_lite/models.py +204 -0
- codegraphy_lite/scanner.py +330 -0
- codegraphy_lite/server.py +414 -0
- codegraphy_lite/storage.py +201 -0
- codegraphy_lite/web/assets/codegraphy-lite-ui.css +323 -0
- codegraphy_lite/web/assets/codegraphy-lite-ui.js +305 -0
- codegraphy_lite/web/assets/graph-D7gaURIl.js +7 -0
- codegraphy_lite/web/assets/icons-CvV5lYnA.js +1 -0
- codegraphy_lite/web/assets/index-BH1KbUBa.css +1 -0
- codegraphy_lite/web/assets/index-BPD6wClD.js +50 -0
- codegraphy_lite/web/assets/markdown-Bj3RCaMp.js +14 -0
- codegraphy_lite/web/favicon.ico +0 -0
- codegraphy_lite/web/favicon.png +0 -0
- codegraphy_lite/web/favicon.svg +1 -0
- codegraphy_lite/web/index.html +22 -0
- codegraphy_lite-1.0.0.dist-info/METADATA +227 -0
- codegraphy_lite-1.0.0.dist-info/RECORD +24 -0
- codegraphy_lite-1.0.0.dist-info/WHEEL +5 -0
- codegraphy_lite-1.0.0.dist-info/entry_points.txt +3 -0
- codegraphy_lite-1.0.0.dist-info/licenses/LICENSE +21 -0
- codegraphy_lite-1.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
/* CodeGraphy Lite - Pro Features & Upgrade Modal Styles */
|
|
2
|
+
|
|
3
|
+
/* -- PRO badge: subtle technical pill (Linear/Raycast style) -- */
|
|
4
|
+
.cg-pro-badge {
|
|
5
|
+
display: inline-flex !important;
|
|
6
|
+
align-items: center !important;
|
|
7
|
+
font-size: 10px !important;
|
|
8
|
+
font-weight: 600 !important;
|
|
9
|
+
letter-spacing: 0.04em !important;
|
|
10
|
+
line-height: 1 !important;
|
|
11
|
+
padding: 1px 5px !important;
|
|
12
|
+
border-radius: 4px !important;
|
|
13
|
+
background: rgba(56, 189, 248, 0.12) !important;
|
|
14
|
+
color: #38BDF8 !important;
|
|
15
|
+
border: 1px solid rgba(56, 189, 248, 0.25) !important;
|
|
16
|
+
text-transform: uppercase !important;
|
|
17
|
+
cursor: pointer !important;
|
|
18
|
+
user-select: none !important;
|
|
19
|
+
vertical-align: middle !important;
|
|
20
|
+
margin-left: 6px !important;
|
|
21
|
+
box-shadow: none !important;
|
|
22
|
+
transition: background 0.15s ease, border-color 0.15s ease !important;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.cg-pro-badge:hover {
|
|
26
|
+
background: rgba(56, 189, 248, 0.2) !important;
|
|
27
|
+
border-color: rgba(56, 189, 248, 0.45) !important;
|
|
28
|
+
transform: none !important;
|
|
29
|
+
filter: none !important;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/* -- Top-bar "PRO Features" button -- */
|
|
33
|
+
.cg-topbar-pro-btn {
|
|
34
|
+
display: inline-flex !important;
|
|
35
|
+
align-items: center !important;
|
|
36
|
+
gap: 6px !important;
|
|
37
|
+
background: transparent !important;
|
|
38
|
+
border: 1px solid rgba(56, 189, 248, 0.2) !important;
|
|
39
|
+
border-radius: 6px !important;
|
|
40
|
+
padding: 4px 10px !important;
|
|
41
|
+
font-size: 11px !important;
|
|
42
|
+
font-weight: 600 !important;
|
|
43
|
+
color: #38BDF8 !important;
|
|
44
|
+
cursor: pointer !important;
|
|
45
|
+
margin-left: 10px !important;
|
|
46
|
+
box-shadow: none !important;
|
|
47
|
+
transition: background 0.15s ease, border-color 0.15s ease !important;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.cg-topbar-pro-btn:hover {
|
|
51
|
+
background: rgba(56, 189, 248, 0.08) !important;
|
|
52
|
+
border-color: rgba(56, 189, 248, 0.4) !important;
|
|
53
|
+
box-shadow: none !important;
|
|
54
|
+
color: #38BDF8 !important;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/* -- Modal backdrop & overlay -- */
|
|
58
|
+
.cg-modal-backdrop,
|
|
59
|
+
.cg-modal-overlay {
|
|
60
|
+
position: fixed !important;
|
|
61
|
+
inset: 0 !important;
|
|
62
|
+
background: rgba(0, 0, 0, 0.72) !important;
|
|
63
|
+
backdrop-filter: blur(6px) !important;
|
|
64
|
+
display: flex !important;
|
|
65
|
+
align-items: center !important;
|
|
66
|
+
justify-content: center !important;
|
|
67
|
+
z-index: 999999 !important;
|
|
68
|
+
animation: cgFadeIn 0.18s ease-out forwards !important;
|
|
69
|
+
padding: 20px !important;
|
|
70
|
+
pointer-events: auto !important;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/* -- Modal card -- */
|
|
74
|
+
.cg-modal-card {
|
|
75
|
+
background: #0E131A !important;
|
|
76
|
+
border: 1px solid #1E293B !important;
|
|
77
|
+
border-radius: 12px !important;
|
|
78
|
+
max-width: 620px !important;
|
|
79
|
+
width: 100% !important;
|
|
80
|
+
max-height: 88vh !important;
|
|
81
|
+
overflow-y: auto !important;
|
|
82
|
+
scrollbar-width: none !important;
|
|
83
|
+
-ms-overflow-style: none !important;
|
|
84
|
+
box-shadow: 0 24px 56px -12px rgba(0, 0, 0, 0.9) !important;
|
|
85
|
+
color: #CBD5E1 !important;
|
|
86
|
+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif !important;
|
|
87
|
+
position: relative !important;
|
|
88
|
+
animation: cgSlideUp 0.22s cubic-bezier(0.16, 1, 0.3, 1) forwards !important;
|
|
89
|
+
pointer-events: auto !important;
|
|
90
|
+
cursor: default !important;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
.cg-modal-card::-webkit-scrollbar {
|
|
94
|
+
display: none !important;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
@keyframes cgFadeIn {
|
|
98
|
+
from { opacity: 0; }
|
|
99
|
+
to { opacity: 1; }
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
@keyframes cgSlideUp {
|
|
103
|
+
from { transform: translateY(16px) scale(0.98); opacity: 0; }
|
|
104
|
+
to { transform: translateY(0) scale(1); opacity: 1; }
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/* -- Modal header -- */
|
|
108
|
+
.cg-modal-header {
|
|
109
|
+
padding: 22px 24px 16px !important;
|
|
110
|
+
border-bottom: 1px solid #1E293B !important;
|
|
111
|
+
display: flex !important;
|
|
112
|
+
align-items: flex-start !important;
|
|
113
|
+
justify-content: space-between !important;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
.cg-modal-title-wrap {
|
|
117
|
+
display: flex !important;
|
|
118
|
+
flex-direction: column !important;
|
|
119
|
+
gap: 4px !important;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
.cg-modal-title-row {
|
|
123
|
+
display: flex !important;
|
|
124
|
+
align-items: center !important;
|
|
125
|
+
gap: 8px !important;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
.cg-modal-title {
|
|
129
|
+
margin: 0 !important;
|
|
130
|
+
font-size: 18px !important;
|
|
131
|
+
font-weight: 700 !important;
|
|
132
|
+
color: #F1F5F9 !important;
|
|
133
|
+
letter-spacing: -0.01em !important;
|
|
134
|
+
background: none !important;
|
|
135
|
+
-webkit-text-fill-color: initial !important;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
.cg-modal-subtitle {
|
|
139
|
+
margin: 0 !important;
|
|
140
|
+
font-size: 12.5px !important;
|
|
141
|
+
color: #64748B !important;
|
|
142
|
+
line-height: 1.4 !important;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
.cg-modal-close-btn {
|
|
146
|
+
background: transparent !important;
|
|
147
|
+
border: none !important;
|
|
148
|
+
color: #475569 !important;
|
|
149
|
+
cursor: pointer !important;
|
|
150
|
+
padding: 6px !important;
|
|
151
|
+
border-radius: 5px !important;
|
|
152
|
+
line-height: 1 !important;
|
|
153
|
+
transition: color 0.12s ease, background 0.12s ease !important;
|
|
154
|
+
flex-shrink: 0 !important;
|
|
155
|
+
pointer-events: auto !important;
|
|
156
|
+
position: relative !important;
|
|
157
|
+
z-index: 10 !important;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
.cg-modal-close-btn svg {
|
|
161
|
+
pointer-events: none !important;
|
|
162
|
+
display: block !important;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
.cg-modal-close-btn:hover {
|
|
166
|
+
color: #CBD5E1 !important;
|
|
167
|
+
background: rgba(255, 255, 255, 0.06) !important;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/* -- Modal body -- */
|
|
171
|
+
.cg-modal-body {
|
|
172
|
+
padding: 20px 24px !important;
|
|
173
|
+
display: flex !important;
|
|
174
|
+
flex-direction: column !important;
|
|
175
|
+
gap: 16px !important;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/* -- Active-feature banner (removed) -- */
|
|
179
|
+
.cg-active-feature-banner {
|
|
180
|
+
display: none !important;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/* -- 2x2 feature grid -- */
|
|
184
|
+
.cg-feature-grid {
|
|
185
|
+
display: grid !important;
|
|
186
|
+
grid-template-columns: 1fr 1fr !important;
|
|
187
|
+
gap: 10px !important;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
@media (max-width: 540px) {
|
|
191
|
+
.cg-feature-grid {
|
|
192
|
+
grid-template-columns: 1fr !important;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
.cg-feature-card {
|
|
197
|
+
background: rgba(255, 255, 255, 0.02) !important;
|
|
198
|
+
border: 1px solid #1E293B !important;
|
|
199
|
+
border-radius: 8px !important;
|
|
200
|
+
padding: 12px 14px !important;
|
|
201
|
+
transition: border-color 0.15s ease !important;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
.cg-feature-card.highlight {
|
|
205
|
+
border-color: rgba(56, 189, 248, 0.3) !important;
|
|
206
|
+
background: rgba(56, 189, 248, 0.04) !important;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
.cg-feature-card:hover {
|
|
210
|
+
border-color: #334155 !important;
|
|
211
|
+
background: rgba(255, 255, 255, 0.03) !important;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
.cg-feature-card-header {
|
|
215
|
+
display: flex !important;
|
|
216
|
+
align-items: center !important;
|
|
217
|
+
gap: 7px !important;
|
|
218
|
+
font-size: 12.5px !important;
|
|
219
|
+
font-weight: 600 !important;
|
|
220
|
+
color: #E2E8F0 !important;
|
|
221
|
+
margin-bottom: 5px !important;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
.cg-feature-card-desc {
|
|
225
|
+
font-size: 11.5px !important;
|
|
226
|
+
color: #64748B !important;
|
|
227
|
+
line-height: 1.45 !important;
|
|
228
|
+
margin: 0 !important;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/* -- Comparison table -- */
|
|
232
|
+
.cg-comparison-box {
|
|
233
|
+
background: rgba(15, 23, 42, 0.5) !important;
|
|
234
|
+
border: 1px solid #1E293B !important;
|
|
235
|
+
border-radius: 8px !important;
|
|
236
|
+
overflow: hidden !important;
|
|
237
|
+
font-size: 12px !important;
|
|
238
|
+
padding: 0 !important;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
.cg-comparison-header {
|
|
242
|
+
display: grid !important;
|
|
243
|
+
grid-template-columns: 1fr 80px 80px !important;
|
|
244
|
+
gap: 0 !important;
|
|
245
|
+
padding: 8px 14px !important;
|
|
246
|
+
background: rgba(255, 255, 255, 0.025) !important;
|
|
247
|
+
border-bottom: 1px solid #1E293B !important;
|
|
248
|
+
font-size: 11px !important;
|
|
249
|
+
font-weight: 600 !important;
|
|
250
|
+
text-transform: uppercase !important;
|
|
251
|
+
letter-spacing: 0.05em !important;
|
|
252
|
+
color: #475569 !important;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
.cg-comparison-row {
|
|
256
|
+
display: grid !important;
|
|
257
|
+
grid-template-columns: 1fr 80px 80px !important;
|
|
258
|
+
gap: 0 !important;
|
|
259
|
+
padding: 8px 14px !important;
|
|
260
|
+
border-bottom: 1px solid #1E293B !important;
|
|
261
|
+
align-items: center !important;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
.cg-comparison-row:last-child {
|
|
265
|
+
border-bottom: none !important;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/* -- Modal footer -- */
|
|
269
|
+
.cg-modal-footer {
|
|
270
|
+
padding: 14px 24px 20px !important;
|
|
271
|
+
border-top: 1px solid #1E293B !important;
|
|
272
|
+
display: flex !important;
|
|
273
|
+
align-items: center !important;
|
|
274
|
+
justify-content: flex-end !important;
|
|
275
|
+
gap: 10px !important;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
.cg-btn-secondary {
|
|
279
|
+
background: transparent !important;
|
|
280
|
+
border: 1px solid #334155 !important;
|
|
281
|
+
border-radius: 7px !important;
|
|
282
|
+
color: #64748B !important;
|
|
283
|
+
padding: 8px 16px !important;
|
|
284
|
+
font-size: 12.5px !important;
|
|
285
|
+
font-weight: 500 !important;
|
|
286
|
+
cursor: pointer !important;
|
|
287
|
+
transition: border-color 0.15s ease, color 0.15s ease !important;
|
|
288
|
+
pointer-events: auto !important;
|
|
289
|
+
position: relative !important;
|
|
290
|
+
z-index: 10 !important;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
.cg-btn-secondary:hover {
|
|
294
|
+
border-color: #475569 !important;
|
|
295
|
+
color: #CBD5E1 !important;
|
|
296
|
+
background: transparent !important;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
.cg-btn-primary {
|
|
300
|
+
background: #0EA5E9 !important;
|
|
301
|
+
border: none !important;
|
|
302
|
+
border-radius: 7px !important;
|
|
303
|
+
color: #ffffff !important;
|
|
304
|
+
padding: 8px 18px !important;
|
|
305
|
+
font-size: 12.5px !important;
|
|
306
|
+
font-weight: 600 !important;
|
|
307
|
+
cursor: pointer !important;
|
|
308
|
+
transition: background 0.15s ease !important;
|
|
309
|
+
text-decoration: none !important;
|
|
310
|
+
display: inline-flex !important;
|
|
311
|
+
align-items: center !important;
|
|
312
|
+
gap: 6px !important;
|
|
313
|
+
letter-spacing: -0.01em !important;
|
|
314
|
+
box-shadow: none !important;
|
|
315
|
+
pointer-events: auto !important;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
.cg-btn-primary:hover {
|
|
319
|
+
background: #0284C7 !important;
|
|
320
|
+
filter: none !important;
|
|
321
|
+
transform: none !important;
|
|
322
|
+
box-shadow: none !important;
|
|
323
|
+
}
|
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CodeGraphy Lite - Pro Features Enhancement & Upgrade Modal
|
|
3
|
+
*
|
|
4
|
+
* Surfaces PRO badges and an upgrade modal for proprietary features.
|
|
5
|
+
* Design: Linear/Raycast developer-tool aesthetic -- no emojis, no gradients.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
(function () {
|
|
9
|
+
'use strict';
|
|
10
|
+
|
|
11
|
+
/* -- Lucide-style 16x16 inline SVG icons -- */
|
|
12
|
+
const ICONS = {
|
|
13
|
+
ast: '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><polyline points="16 18 22 12 16 6"/><polyline points="8 6 2 12 8 18"/></svg>',
|
|
14
|
+
blast: '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="3"/><line x1="12" y1="2" x2="12" y2="5"/><line x1="12" y1="19" x2="12" y2="22"/><line x1="2" y1="12" x2="5" y2="12"/><line x1="19" y1="12" x2="22" y2="12"/><line x1="4.93" y1="4.93" x2="7.05" y2="7.05"/><line x1="16.95" y1="16.95" x2="19.07" y2="19.07"/><line x1="4.93" y1="19.07" x2="7.05" y2="16.95"/><line x1="16.95" y1="7.05" x2="19.07" y2="4.93"/></svg>',
|
|
15
|
+
inspector: '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>',
|
|
16
|
+
mcp: '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="3" width="20" height="14" rx="2"/><line x1="8" y1="21" x2="16" y2="21"/><line x1="12" y1="17" x2="12" y2="21"/></svg>',
|
|
17
|
+
pro: '<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/></svg>',
|
|
18
|
+
close: '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>',
|
|
19
|
+
check: '<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>',
|
|
20
|
+
dash: '<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><line x1="5" y1="12" x2="19" y2="12"/></svg>',
|
|
21
|
+
arrow: '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><line x1="5" y1="12" x2="19" y2="12"/><polyline points="12 5 19 12 12 19"/></svg>',
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const PRO_URL = 'https://github.com/Vindettobkb/codegraphy-pro';
|
|
25
|
+
|
|
26
|
+
const PRO_FEATURES = {
|
|
27
|
+
smart_context: {
|
|
28
|
+
id: 'smart_context',
|
|
29
|
+
title: 'AST Context Compression',
|
|
30
|
+
icon: ICONS.ast,
|
|
31
|
+
desc: 'Strip function bodies while keeping types, imports, and signatures (~85% fewer tokens).',
|
|
32
|
+
},
|
|
33
|
+
blast_radius: {
|
|
34
|
+
id: 'blast_radius',
|
|
35
|
+
title: 'Blast Radius & Git Diff',
|
|
36
|
+
icon: ICONS.blast,
|
|
37
|
+
desc: 'Trace downstream callers before refactoring and spot layer drift across commits.',
|
|
38
|
+
},
|
|
39
|
+
context_inspector: {
|
|
40
|
+
id: 'context_inspector',
|
|
41
|
+
title: 'Hybrid Context Inspector',
|
|
42
|
+
icon: ICONS.inspector,
|
|
43
|
+
desc: 'Switch files between Full, AST, and Excluded with exact token counts.',
|
|
44
|
+
},
|
|
45
|
+
mcp_tools: {
|
|
46
|
+
id: 'mcp_tools',
|
|
47
|
+
title: 'Unlimited Files & 11 MCP Tools',
|
|
48
|
+
icon: ICONS.mcp,
|
|
49
|
+
desc: 'Scan full repositories and expose impact, diff, and test tools over STDIO.',
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
function closeProModal(e) {
|
|
54
|
+
if (e && e.preventDefault) {
|
|
55
|
+
e.preventDefault();
|
|
56
|
+
e.stopPropagation();
|
|
57
|
+
}
|
|
58
|
+
const modals = document.querySelectorAll('.cg-modal-backdrop, .cg-modal-overlay, #cg-pro-modal-backdrop');
|
|
59
|
+
modals.forEach(m => {
|
|
60
|
+
m.style.display = 'none';
|
|
61
|
+
m.remove();
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
window.closeCodeGraphyProModal = closeProModal;
|
|
66
|
+
|
|
67
|
+
function createBadge(featureId) {
|
|
68
|
+
const badge = document.createElement('span');
|
|
69
|
+
badge.className = 'cg-pro-badge';
|
|
70
|
+
badge.textContent = 'PRO';
|
|
71
|
+
badge.title = 'CodeGraphy Pro feature -- click to learn more';
|
|
72
|
+
badge.addEventListener('click', (e) => {
|
|
73
|
+
e.preventDefault();
|
|
74
|
+
e.stopPropagation();
|
|
75
|
+
openProModal(featureId);
|
|
76
|
+
});
|
|
77
|
+
return badge;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function openProModal(featureKeyOrTitle) {
|
|
81
|
+
closeProModal(); // remove any existing modal first
|
|
82
|
+
|
|
83
|
+
let feat = null;
|
|
84
|
+
if (featureKeyOrTitle && PRO_FEATURES[featureKeyOrTitle]) {
|
|
85
|
+
feat = PRO_FEATURES[featureKeyOrTitle];
|
|
86
|
+
} else if (typeof featureKeyOrTitle === 'string') {
|
|
87
|
+
const lower = featureKeyOrTitle.toLowerCase();
|
|
88
|
+
for (const k of Object.keys(PRO_FEATURES)) {
|
|
89
|
+
if (lower.includes(k) || PRO_FEATURES[k].title.toLowerCase().includes(lower)) {
|
|
90
|
+
feat = PRO_FEATURES[k];
|
|
91
|
+
break;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
if (!feat) feat = PRO_FEATURES.smart_context;
|
|
96
|
+
|
|
97
|
+
const featureCards = Object.values(PRO_FEATURES).map(f => `
|
|
98
|
+
<div class="cg-feature-card ${f.id === feat.id ? 'highlight' : ''}">
|
|
99
|
+
<div class="cg-feature-card-header">
|
|
100
|
+
${f.icon}
|
|
101
|
+
<span>${f.title}</span>
|
|
102
|
+
</div>
|
|
103
|
+
<p class="cg-feature-card-desc">${f.desc}</p>
|
|
104
|
+
</div>
|
|
105
|
+
`).join('');
|
|
106
|
+
|
|
107
|
+
const tableRows = [
|
|
108
|
+
{ label: 'Project size', lite: '35 files', pro: 'Unlimited' },
|
|
109
|
+
{ label: 'MCP tools', lite: '3', pro: '11' },
|
|
110
|
+
{ label: 'AST Compression', lite: null, pro: 'Included' },
|
|
111
|
+
{ label: 'Blast Radius & Git Diff', lite: null, pro: 'Included' },
|
|
112
|
+
].map(r => `
|
|
113
|
+
<div class="cg-comparison-row">
|
|
114
|
+
<span style="color:#94A3B8;">${r.label}</span>
|
|
115
|
+
<span style="color:${r.lite ? '#CBD5E1' : '#475569'}; display:inline-flex; align-items:center; gap:4px;">
|
|
116
|
+
${r.lite ? r.lite : ICONS.dash}
|
|
117
|
+
</span>
|
|
118
|
+
<span style="color:#38BDF8; display:inline-flex; align-items:center; gap:4px;">
|
|
119
|
+
${ICONS.check} ${r.pro}
|
|
120
|
+
</span>
|
|
121
|
+
</div>
|
|
122
|
+
`).join('');
|
|
123
|
+
|
|
124
|
+
const backdrop = document.createElement('div');
|
|
125
|
+
backdrop.id = 'cg-pro-modal-backdrop';
|
|
126
|
+
backdrop.className = 'cg-modal-backdrop cg-modal-overlay';
|
|
127
|
+
backdrop.style.display = 'flex';
|
|
128
|
+
|
|
129
|
+
backdrop.innerHTML = `
|
|
130
|
+
<div class="cg-modal-card" role="dialog" aria-modal="true" aria-label="CodeGraphy Pro">
|
|
131
|
+
<div class="cg-modal-header">
|
|
132
|
+
<div class="cg-modal-title-wrap">
|
|
133
|
+
<div class="cg-modal-title-row">
|
|
134
|
+
<h2 class="cg-modal-title">CodeGraphy Pro</h2>
|
|
135
|
+
</div>
|
|
136
|
+
<p class="cg-modal-subtitle">Full AST compression, impact analysis, and unlimited project scanning.</p>
|
|
137
|
+
</div>
|
|
138
|
+
<button type="button" class="cg-modal-close-btn" id="cg-modal-close-btn" aria-label="Close dialog">
|
|
139
|
+
${ICONS.close}
|
|
140
|
+
</button>
|
|
141
|
+
</div>
|
|
142
|
+
|
|
143
|
+
<div class="cg-modal-body">
|
|
144
|
+
<div class="cg-feature-grid">
|
|
145
|
+
${featureCards}
|
|
146
|
+
</div>
|
|
147
|
+
|
|
148
|
+
<div class="cg-comparison-box">
|
|
149
|
+
<div class="cg-comparison-header">
|
|
150
|
+
<span>Capability</span>
|
|
151
|
+
<span>Lite</span>
|
|
152
|
+
<span>Pro</span>
|
|
153
|
+
</div>
|
|
154
|
+
${tableRows}
|
|
155
|
+
</div>
|
|
156
|
+
</div>
|
|
157
|
+
|
|
158
|
+
<div class="cg-modal-footer">
|
|
159
|
+
<button type="button" class="cg-btn-secondary" id="cg-modal-dismiss-btn">Continue with Lite</button>
|
|
160
|
+
<a class="cg-btn-primary" href="${PRO_URL}" target="_blank" rel="noopener noreferrer">
|
|
161
|
+
Get CodeGraphy Pro
|
|
162
|
+
${ICONS.arrow}
|
|
163
|
+
</a>
|
|
164
|
+
</div>
|
|
165
|
+
</div>
|
|
166
|
+
`;
|
|
167
|
+
|
|
168
|
+
// Click handler with bubbling and capture
|
|
169
|
+
function handleDismiss(e) {
|
|
170
|
+
e.preventDefault();
|
|
171
|
+
e.stopPropagation();
|
|
172
|
+
closeProModal(e);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// 1. Outside click
|
|
176
|
+
backdrop.addEventListener('click', (e) => {
|
|
177
|
+
if (e.target === backdrop) {
|
|
178
|
+
handleDismiss(e);
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
document.body.appendChild(backdrop);
|
|
183
|
+
|
|
184
|
+
// 2. Direct event listeners on buttons
|
|
185
|
+
const closeBtn = backdrop.querySelector('#cg-modal-close-btn');
|
|
186
|
+
if (closeBtn) {
|
|
187
|
+
closeBtn.addEventListener('click', handleDismiss, true);
|
|
188
|
+
closeBtn.onclick = handleDismiss;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
const dismissBtn = backdrop.querySelector('#cg-modal-dismiss-btn');
|
|
192
|
+
if (dismissBtn) {
|
|
193
|
+
dismissBtn.addEventListener('click', handleDismiss, true);
|
|
194
|
+
dismissBtn.onclick = handleDismiss;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
window.openCodeGraphyProModal = openProModal;
|
|
199
|
+
|
|
200
|
+
// Global keydown for Escape
|
|
201
|
+
window.addEventListener('keydown', (e) => {
|
|
202
|
+
if (e.key === 'Escape' || e.keyCode === 27) {
|
|
203
|
+
closeProModal(e);
|
|
204
|
+
}
|
|
205
|
+
}, true);
|
|
206
|
+
|
|
207
|
+
function attachBadges() {
|
|
208
|
+
// Git Diff buttons
|
|
209
|
+
document.querySelectorAll('button[title*="Git Architecture Diff"], button[aria-label*="Git Architecture Diff"]').forEach(btn => {
|
|
210
|
+
if (btn.closest('.cg-modal-card') || btn.closest('.cg-modal-overlay') || btn.closest('#cg-pro-modal-backdrop')) return;
|
|
211
|
+
if (!btn.dataset.cgProHandled) {
|
|
212
|
+
btn.dataset.cgProHandled = 'true';
|
|
213
|
+
btn.appendChild(createBadge('blast_radius'));
|
|
214
|
+
btn.addEventListener('click', (e) => {
|
|
215
|
+
if (e.target.closest('.cg-modal-overlay') || e.target.closest('.cg-modal-card')) return;
|
|
216
|
+
e.preventDefault();
|
|
217
|
+
e.stopPropagation();
|
|
218
|
+
openProModal('blast_radius');
|
|
219
|
+
}, true);
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
// Blast Radius text buttons
|
|
224
|
+
document.querySelectorAll('button, [role="button"]').forEach(el => {
|
|
225
|
+
if (el.closest('.cg-modal-card') || el.closest('.cg-modal-overlay') || el.closest('#cg-pro-modal-backdrop')) return;
|
|
226
|
+
const text = el.textContent || '';
|
|
227
|
+
if (text.includes('Blast Radius') && !el.dataset.cgProHandled) {
|
|
228
|
+
el.dataset.cgProHandled = 'true';
|
|
229
|
+
el.appendChild(createBadge('blast_radius'));
|
|
230
|
+
el.addEventListener('click', (e) => {
|
|
231
|
+
if (e.target.closest('.cg-modal-overlay') || e.target.closest('.cg-modal-card')) return;
|
|
232
|
+
e.preventDefault();
|
|
233
|
+
e.stopPropagation();
|
|
234
|
+
openProModal('blast_radius');
|
|
235
|
+
}, true);
|
|
236
|
+
}
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
// Context Inspector buttons
|
|
240
|
+
document.querySelectorAll('button[title*="Inspector"], button[aria-label*="Inspector"]').forEach(btn => {
|
|
241
|
+
if (btn.closest('.cg-modal-card') || btn.closest('.cg-modal-overlay') || btn.closest('#cg-pro-modal-backdrop')) return;
|
|
242
|
+
if (!btn.dataset.cgProHandled) {
|
|
243
|
+
btn.dataset.cgProHandled = 'true';
|
|
244
|
+
btn.appendChild(createBadge('context_inspector'));
|
|
245
|
+
btn.addEventListener('click', (e) => {
|
|
246
|
+
if (e.target.closest('.cg-modal-overlay') || e.target.closest('.cg-modal-card')) return;
|
|
247
|
+
e.preventDefault();
|
|
248
|
+
e.stopPropagation();
|
|
249
|
+
openProModal('context_inspector');
|
|
250
|
+
}, true);
|
|
251
|
+
}
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
// MCP Config headings only
|
|
255
|
+
document.querySelectorAll('h3, h4').forEach(el => {
|
|
256
|
+
if (el.closest('.cg-modal-card') || el.closest('.cg-modal-overlay') || el.closest('#cg-pro-modal-backdrop')) return;
|
|
257
|
+
if ((el.textContent || '').includes('MCP Config') && !el.dataset.cgProHandled) {
|
|
258
|
+
el.dataset.cgProHandled = 'true';
|
|
259
|
+
el.appendChild(createBadge('mcp_tools'));
|
|
260
|
+
}
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
// Top-bar PRO button
|
|
264
|
+
const topBarLeft = document.querySelector('.top-bar-left');
|
|
265
|
+
if (topBarLeft && !document.getElementById('cg-topbar-pro-btn')) {
|
|
266
|
+
const proBtn = document.createElement('button');
|
|
267
|
+
proBtn.id = 'cg-topbar-pro-btn';
|
|
268
|
+
proBtn.className = 'cg-topbar-pro-btn';
|
|
269
|
+
proBtn.type = 'button';
|
|
270
|
+
proBtn.innerHTML = ICONS.pro + '<span>PRO Features</span>';
|
|
271
|
+
proBtn.title = 'View CodeGraphy Pro features';
|
|
272
|
+
proBtn.addEventListener('click', (e) => {
|
|
273
|
+
e.preventDefault();
|
|
274
|
+
e.stopPropagation();
|
|
275
|
+
openProModal('smart_context');
|
|
276
|
+
});
|
|
277
|
+
topBarLeft.appendChild(proBtn);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
// Intercept 402/403 pro-feature responses
|
|
282
|
+
const originalFetch = window.fetch;
|
|
283
|
+
window.fetch = async function (...args) {
|
|
284
|
+
const res = await originalFetch.apply(this, args);
|
|
285
|
+
const clone = res.clone();
|
|
286
|
+
try {
|
|
287
|
+
if (res.status === 402 || res.status === 403) {
|
|
288
|
+
const body = await clone.json();
|
|
289
|
+
if (body && (body.pro_feature || body.feature)) {
|
|
290
|
+
openProModal(body.feature || 'smart_context');
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
} catch { /* ignore non-JSON bodies */ }
|
|
294
|
+
return res;
|
|
295
|
+
};
|
|
296
|
+
|
|
297
|
+
if (document.readyState === 'loading') {
|
|
298
|
+
document.addEventListener('DOMContentLoaded', () => { attachBadges(); setInterval(attachBadges, 800); });
|
|
299
|
+
} else {
|
|
300
|
+
attachBadges();
|
|
301
|
+
setInterval(attachBadges, 800);
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
new MutationObserver(attachBadges).observe(document.documentElement, { childList: true, subtree: true });
|
|
305
|
+
})();
|