Navegador

docs: match planopticon site styling exactly - Copy conflict-logo.svg, conflict-logo-black.svg, favicon.png from planopticon - Replace custom.css with identical CONFLICT brand overrides (dark/light schemes, code blocks, tables, scrollbar, nav active states)

lmata 2026-03-22 21:15 trunk
Commit 3c74e66e3c6246166a5cd6a794ac40068e495990d1301d4bf0cdb4415e105b2f
--- docs/assets/css/custom.css
+++ docs/assets/css/custom.css
@@ -1,16 +1,156 @@
1
-/* Navegador — MkDocs Material custom theme */
1
+/* CONFLICT brand overrides for MkDocs Material */
22
33
:root {
4
- --md-primary-fg-color: #DC394C;
5
- --md-primary-fg-color--light: #e8677a;
6
- --md-primary-fg-color--dark: #8B3138;
7
- --md-accent-fg-color: #DC394C;
4
+ --conflict-red: #DB394C;
5
+ --conflict-dark-red: #9C2633;
6
+ --conflict-pink: #FF1D5D;
7
+ --conflict-black: #1D1D1D;
8
+ --conflict-black-2: #282828;
9
+ --conflict-gray: #A8A8A7;
10
+ --conflict-light: #ECEFF5;
11
+}
12
+
13
+/* Dark scheme (default) */
14
+[data-md-color-scheme="slate"] {
15
+ --md-primary-fg-color: var(--conflict-black);
16
+ --md-primary-bg-color: #fff;
17
+ --md-accent-fg-color: var(--conflict-red);
18
+ --md-default-bg-color: var(--conflict-black);
19
+ --md-typeset-a-color: var(--conflict-red);
20
+}
21
+
22
+[data-md-color-scheme="slate"] .md-header {
23
+ background-color: var(--conflict-black);
24
+ border-bottom: 1px solid rgba(255, 255, 255, 0.08);
25
+}
26
+
27
+[data-md-color-scheme="slate"] .md-tabs {
28
+ background-color: var(--conflict-black-2);
29
+}
30
+
31
+/* Light scheme */
32
+[data-md-color-scheme="default"] {
33
+ --md-primary-fg-color: #fff;
34
+ --md-primary-bg-color: var(--conflict-black);
35
+ --md-accent-fg-color: var(--conflict-red);
36
+ --md-typeset-a-color: var(--conflict-red);
37
+}
38
+
39
+[data-md-color-scheme="default"] .md-header {
40
+ background-color: #fff;
41
+ border-bottom: 1px solid var(--conflict-light);
42
+ color: var(--conflict-black);
43
+}
44
+
45
+[data-md-color-scheme="default"] .md-header .md-header__topic,
46
+[data-md-color-scheme="default"] .md-header .md-header__title,
47
+[data-md-color-scheme="default"] .md-header .md-ellipsis {
48
+ color: var(--conflict-black);
49
+}
50
+
51
+[data-md-color-scheme="default"] .md-tabs {
52
+ background-color: #fafafa;
53
+ border-bottom: 1px solid var(--conflict-light);
54
+}
55
+
56
+[data-md-color-scheme="default"] .md-tabs__link {
57
+ color: var(--conflict-black-2);
58
+}
59
+
60
+[data-md-color-scheme="default"] .md-tabs__link--active,
61
+[data-md-color-scheme="default"] .md-tabs__link:hover {
62
+ color: var(--conflict-red);
63
+}
64
+
65
+[data-md-color-scheme="default"] .md-search__input {
66
+ background-color: var(--conflict-light);
67
+}
68
+
69
+/* Links */
70
+.md-typeset a:hover {
71
+ color: var(--conflict-pink);
72
+}
73
+
74
+/* Nav active items */
75
+.md-nav__link--active,
76
+.md-nav__link:hover {
77
+ color: var(--conflict-red) !important;
78
+}
79
+
80
+/* Code blocks */
81
+[data-md-color-scheme="slate"] .md-typeset code {
82
+ background-color: rgba(255, 255, 255, 0.06);
83
+}
84
+
85
+[data-md-color-scheme="slate"] .highlight pre {
86
+ background-color: #141414 !important;
87
+ border: 1px solid rgba(255, 255, 255, 0.06);
88
+ border-radius: 8px;
89
+}
90
+
91
+[data-md-color-scheme="default"] .highlight pre {
92
+ border: 1px solid var(--conflict-light);
93
+ border-radius: 8px;
94
+}
95
+
96
+/* Tables */
97
+.md-typeset table:not([class]) th {
98
+ background-color: var(--conflict-red);
99
+ color: #fff;
100
+}
101
+
102
+[data-md-color-scheme="default"] .md-typeset table:not([class]) th {
103
+ background-color: var(--conflict-red);
104
+ color: #fff;
105
+}
106
+
107
+/* Buttons / admonitions */
108
+.md-typeset .admonition,
109
+.md-typeset details {
110
+ border-radius: 8px;
111
+}
112
+
113
+/* Footer */
114
+.md-footer {
115
+ border-top: 1px solid rgba(255, 255, 255, 0.08);
116
+}
117
+
118
+[data-md-color-scheme="slate"] .md-footer {
119
+ background-color: var(--conflict-black);
120
+}
121
+
122
+/* Header logo sizing */
123
+.md-header__button.md-logo img,
124
+.md-header__button.md-logo svg {
125
+ height: 1.4rem;
126
+ width: auto;
127
+}
128
+
129
+/* Scrollbar styling for dark mode */
130
+[data-md-color-scheme="slate"] ::-webkit-scrollbar {
131
+ width: 8px;
132
+}
133
+
134
+[data-md-color-scheme="slate"] ::-webkit-scrollbar-track {
135
+ background: var(--conflict-black);
136
+}
137
+
138
+[data-md-color-scheme="slate"] ::-webkit-scrollbar-thumb {
139
+ background: var(--conflict-black-2);
140
+ border-radius: 4px;
141
+}
142
+
143
+[data-md-color-scheme="slate"] ::-webkit-scrollbar-thumb:hover {
144
+ background: #3a3a3a;
145
+}
146
+
147
+/* Content max width for readability */
148
+.md-grid {
149
+ max-width: 1220px;
8150
}
9151
10
-[data-md-color-scheme="slate"] {
11
- --md-primary-fg-color: #DC394C;
12
- --md-primary-fg-color--light: #e8677a;
13
- --md-primary-fg-color--dark: #8B3138;
14
- --md-default-bg-color: #1a1c1b;
15
- --md-code-bg-color: #222423;
152
+/* Hero-style heading on index */
153
+.md-typeset h1 {
154
+ font-weight: 700;
155
+ letter-spacing: -0.02em;
16156
}
17157
18158
ADDED docs/assets/images/conflict-logo-black.svg
19159
ADDED docs/assets/images/conflict-logo.svg
20160
ADDED docs/assets/images/favicon.png
--- docs/assets/css/custom.css
+++ docs/assets/css/custom.css
@@ -1,16 +1,156 @@
1 /* Navegador — MkDocs Material custom theme */
2
3 :root {
4 --md-primary-fg-color: #DC394C;
5 --md-primary-fg-color--light: #e8677a;
6 --md-primary-fg-color--dark: #8B3138;
7 --md-accent-fg-color: #DC394C;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8 }
9
10 [data-md-color-scheme="slate"] {
11 --md-primary-fg-color: #DC394C;
12 --md-primary-fg-color--light: #e8677a;
13 --md-primary-fg-color--dark: #8B3138;
14 --md-default-bg-color: #1a1c1b;
15 --md-code-bg-color: #222423;
16 }
17
18 DDED docs/assets/images/conflict-logo-black.svg
19 DDED docs/assets/images/conflict-logo.svg
20 DDED docs/assets/images/favicon.png
--- docs/assets/css/custom.css
+++ docs/assets/css/custom.css
@@ -1,16 +1,156 @@
1 /* CONFLICT brand overrides for MkDocs Material */
2
3 :root {
4 --conflict-red: #DB394C;
5 --conflict-dark-red: #9C2633;
6 --conflict-pink: #FF1D5D;
7 --conflict-black: #1D1D1D;
8 --conflict-black-2: #282828;
9 --conflict-gray: #A8A8A7;
10 --conflict-light: #ECEFF5;
11 }
12
13 /* Dark scheme (default) */
14 [data-md-color-scheme="slate"] {
15 --md-primary-fg-color: var(--conflict-black);
16 --md-primary-bg-color: #fff;
17 --md-accent-fg-color: var(--conflict-red);
18 --md-default-bg-color: var(--conflict-black);
19 --md-typeset-a-color: var(--conflict-red);
20 }
21
22 [data-md-color-scheme="slate"] .md-header {
23 background-color: var(--conflict-black);
24 border-bottom: 1px solid rgba(255, 255, 255, 0.08);
25 }
26
27 [data-md-color-scheme="slate"] .md-tabs {
28 background-color: var(--conflict-black-2);
29 }
30
31 /* Light scheme */
32 [data-md-color-scheme="default"] {
33 --md-primary-fg-color: #fff;
34 --md-primary-bg-color: var(--conflict-black);
35 --md-accent-fg-color: var(--conflict-red);
36 --md-typeset-a-color: var(--conflict-red);
37 }
38
39 [data-md-color-scheme="default"] .md-header {
40 background-color: #fff;
41 border-bottom: 1px solid var(--conflict-light);
42 color: var(--conflict-black);
43 }
44
45 [data-md-color-scheme="default"] .md-header .md-header__topic,
46 [data-md-color-scheme="default"] .md-header .md-header__title,
47 [data-md-color-scheme="default"] .md-header .md-ellipsis {
48 color: var(--conflict-black);
49 }
50
51 [data-md-color-scheme="default"] .md-tabs {
52 background-color: #fafafa;
53 border-bottom: 1px solid var(--conflict-light);
54 }
55
56 [data-md-color-scheme="default"] .md-tabs__link {
57 color: var(--conflict-black-2);
58 }
59
60 [data-md-color-scheme="default"] .md-tabs__link--active,
61 [data-md-color-scheme="default"] .md-tabs__link:hover {
62 color: var(--conflict-red);
63 }
64
65 [data-md-color-scheme="default"] .md-search__input {
66 background-color: var(--conflict-light);
67 }
68
69 /* Links */
70 .md-typeset a:hover {
71 color: var(--conflict-pink);
72 }
73
74 /* Nav active items */
75 .md-nav__link--active,
76 .md-nav__link:hover {
77 color: var(--conflict-red) !important;
78 }
79
80 /* Code blocks */
81 [data-md-color-scheme="slate"] .md-typeset code {
82 background-color: rgba(255, 255, 255, 0.06);
83 }
84
85 [data-md-color-scheme="slate"] .highlight pre {
86 background-color: #141414 !important;
87 border: 1px solid rgba(255, 255, 255, 0.06);
88 border-radius: 8px;
89 }
90
91 [data-md-color-scheme="default"] .highlight pre {
92 border: 1px solid var(--conflict-light);
93 border-radius: 8px;
94 }
95
96 /* Tables */
97 .md-typeset table:not([class]) th {
98 background-color: var(--conflict-red);
99 color: #fff;
100 }
101
102 [data-md-color-scheme="default"] .md-typeset table:not([class]) th {
103 background-color: var(--conflict-red);
104 color: #fff;
105 }
106
107 /* Buttons / admonitions */
108 .md-typeset .admonition,
109 .md-typeset details {
110 border-radius: 8px;
111 }
112
113 /* Footer */
114 .md-footer {
115 border-top: 1px solid rgba(255, 255, 255, 0.08);
116 }
117
118 [data-md-color-scheme="slate"] .md-footer {
119 background-color: var(--conflict-black);
120 }
121
122 /* Header logo sizing */
123 .md-header__button.md-logo img,
124 .md-header__button.md-logo svg {
125 height: 1.4rem;
126 width: auto;
127 }
128
129 /* Scrollbar styling for dark mode */
130 [data-md-color-scheme="slate"] ::-webkit-scrollbar {
131 width: 8px;
132 }
133
134 [data-md-color-scheme="slate"] ::-webkit-scrollbar-track {
135 background: var(--conflict-black);
136 }
137
138 [data-md-color-scheme="slate"] ::-webkit-scrollbar-thumb {
139 background: var(--conflict-black-2);
140 border-radius: 4px;
141 }
142
143 [data-md-color-scheme="slate"] ::-webkit-scrollbar-thumb:hover {
144 background: #3a3a3a;
145 }
146
147 /* Content max width for readability */
148 .md-grid {
149 max-width: 1220px;
150 }
151
152 /* Hero-style heading on index */
153 .md-typeset h1 {
154 font-weight: 700;
155 letter-spacing: -0.02em;
 
 
156 }
157
158 DDED docs/assets/images/conflict-logo-black.svg
159 DDED docs/assets/images/conflict-logo.svg
160 DDED docs/assets/images/favicon.png
--- a/docs/assets/images/conflict-logo-black.svg
+++ b/docs/assets/images/conflict-logo-black.svg
@@ -0,0 +1,12 @@
1
+<svg width="140" height="36" viewBox="0 0 140 36" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+<path d="M6.7855 3.72976C4.95325 3.5678 3.13434 4.1772 1.71595 5.42806C1.14272 6.02274 0.693822 6.74054 0.399025 7.53429C0.104228 8.32803 -0.0298519 9.17959 0.00562531 10.0328V25.7089C-0.0303331 26.5699 0.10642 27.4293 0.406668 28.2291C0.706915 29.029 1.16373 29.7508 1.74643 30.3463C3.19341 31.5609 5.01199 32.1548 6.84664 32.0119C8.67781 32.1635 10.4933 31.5554 11.9163 30.3137C12.4895 29.719 12.9383 29.0011 13.2331 28.2074C13.5279 27.4137 13.662 26.5621 13.6265 25.7089V22.737H9.53418V25.7089C9.55225 26.0222 9.50704 26.3361 9.40164 26.6291C9.29625 26.9221 9.13312 27.1874 8.92334 27.4071C8.32468 27.8771 7.58641 28.0977 6.84664 28.0276C6.08654 28.1142 5.32368 27.8927 4.70881 27.4071C4.49565 27.1901 4.33027 26.9252 4.22463 26.6315C4.11899 26.3378 4.0758 26.0227 4.09806 25.7089V10.0328C4.07604 9.72186 4.11635 9.40956 4.21643 9.11668C4.3165 8.82379 4.47404 8.55711 4.67833 8.3346C5.28511 7.85685 6.03555 7.63584 6.7855 7.71408C7.54561 7.62753 8.30847 7.84895 8.92334 8.3346C9.13312 8.55424 9.29625 8.81956 9.40164 9.11259C9.50704 9.40562 9.55225 9.71944 9.53418 10.0328V14.5724H13.6265V10.0328C13.6602 9.17393 13.5193 8.31752 13.2135 7.52253C12.9077 6.72754 12.4442 6.01298 11.8552 5.42806C10.4321 4.18636 8.61667 3.57816 6.7855 3.72976Z" fill="#282828"/>
3
+<path d="M54.2915 20.8757L47.4811 4.35059H43.7858V31.457H47.8781V14.8992L54.658 31.457H58.3839V4.35059H54.2915V20.8757Z" fill="#282828"/>
4
+<path d="M63.2212 31.457H67.3135V19.7H73.3605V15.7157H67.3135V8.30225H74.8264V4.35059H63.2212V31.457Z" fill="#282828"/>
5
+<path d="M83.7562 4.35059H79.6638V31.457H90.475V27.4727H83.7562V4.35059Z" fill="#282828"/>
6
+<path d="M95.3127 8.30225H97.1451V27.4727H95.3127V31.457H103.07V27.4727H101.238V8.30225H103.07V4.35059H95.3127V8.30225Z" fill="#282828"/>
7
+<path d="M114.664 3.7298C112.842 3.57303 111.034 4.18231 109.625 5.42809C109.047 6.01892 108.595 6.73614 108.3 7.53084C108.005 8.32553 107.874 9.17891 107.915 10.0328V25.7089C107.879 26.57 108.016 27.4293 108.316 28.2292C108.616 29.029 109.073 29.7509 109.656 30.3464C111.1 31.5667 112.921 32.1613 114.756 32.012C116.587 32.1636 118.403 31.5555 119.826 30.3138C120.399 29.7191 120.848 29.0012 121.142 28.2074C121.437 27.4137 121.571 26.5621 121.536 25.7089V22.737H117.444V25.7089C117.462 26.0223 117.416 26.3361 117.311 26.6291C117.206 26.9222 117.042 27.1875 116.833 27.4071C116.234 27.8771 115.496 28.0977 114.756 28.0276C113.996 28.1142 113.233 27.8928 112.618 27.4071C112.405 27.1902 112.24 26.9252 112.134 26.6315C112.028 26.3378 111.985 26.0227 112.007 25.7089V10.0328C111.985 9.7219 112.026 9.4096 112.126 9.11671C112.226 8.82382 112.383 8.55715 112.588 8.33464C113.186 7.86466 113.925 7.64406 114.664 7.71412C115.435 7.61912 116.21 7.84096 116.833 8.33464C117.042 8.55428 117.206 8.8196 117.311 9.11263C117.416 9.40565 117.462 9.71948 117.444 10.0328V14.5724H121.536V10.0328C121.57 9.17397 121.429 8.31755 121.123 7.52256C120.817 6.72757 120.354 6.01302 119.765 5.42809C118.332 4.18135 116.505 3.57303 114.664 3.7298Z" fill="#282828"/>
8
+<path d="M126.379 4.35059V8.30225H131.143V31.457H135.236V8.30225H140V4.35059H126.379Z" fill="#282828"/>
9
+<path d="M18.4236 36H25.9961V32.3203H22.0123V3.67966H26.0619V0H18.4236V36Z" fill="#DB394C"/>
10
+<path d="M31.2968 0V3.67966H35.3136V32.3203H31.2639V36H38.9023V0H31.2968Z" fill="#DB394C"/>
11
+<path d="M30.4737 10.3562H26.8521V25.3783H30.4737V10.3562Z" fill="#DB394C"/>
12
+</svg>
--- a/docs/assets/images/conflict-logo-black.svg
+++ b/docs/assets/images/conflict-logo-black.svg
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
--- a/docs/assets/images/conflict-logo-black.svg
+++ b/docs/assets/images/conflict-logo-black.svg
@@ -0,0 +1,12 @@
1 <svg width="140" height="36" viewBox="0 0 140 36" fill="none" xmlns="http://www.w3.org/2000/svg">
2 <path d="M6.7855 3.72976C4.95325 3.5678 3.13434 4.1772 1.71595 5.42806C1.14272 6.02274 0.693822 6.74054 0.399025 7.53429C0.104228 8.32803 -0.0298519 9.17959 0.00562531 10.0328V25.7089C-0.0303331 26.5699 0.10642 27.4293 0.406668 28.2291C0.706915 29.029 1.16373 29.7508 1.74643 30.3463C3.19341 31.5609 5.01199 32.1548 6.84664 32.0119C8.67781 32.1635 10.4933 31.5554 11.9163 30.3137C12.4895 29.719 12.9383 29.0011 13.2331 28.2074C13.5279 27.4137 13.662 26.5621 13.6265 25.7089V22.737H9.53418V25.7089C9.55225 26.0222 9.50704 26.3361 9.40164 26.6291C9.29625 26.9221 9.13312 27.1874 8.92334 27.4071C8.32468 27.8771 7.58641 28.0977 6.84664 28.0276C6.08654 28.1142 5.32368 27.8927 4.70881 27.4071C4.49565 27.1901 4.33027 26.9252 4.22463 26.6315C4.11899 26.3378 4.0758 26.0227 4.09806 25.7089V10.0328C4.07604 9.72186 4.11635 9.40956 4.21643 9.11668C4.3165 8.82379 4.47404 8.55711 4.67833 8.3346C5.28511 7.85685 6.03555 7.63584 6.7855 7.71408C7.54561 7.62753 8.30847 7.84895 8.92334 8.3346C9.13312 8.55424 9.29625 8.81956 9.40164 9.11259C9.50704 9.40562 9.55225 9.71944 9.53418 10.0328V14.5724H13.6265V10.0328C13.6602 9.17393 13.5193 8.31752 13.2135 7.52253C12.9077 6.72754 12.4442 6.01298 11.8552 5.42806C10.4321 4.18636 8.61667 3.57816 6.7855 3.72976Z" fill="#282828"/>
3 <path d="M54.2915 20.8757L47.4811 4.35059H43.7858V31.457H47.8781V14.8992L54.658 31.457H58.3839V4.35059H54.2915V20.8757Z" fill="#282828"/>
4 <path d="M63.2212 31.457H67.3135V19.7H73.3605V15.7157H67.3135V8.30225H74.8264V4.35059H63.2212V31.457Z" fill="#282828"/>
5 <path d="M83.7562 4.35059H79.6638V31.457H90.475V27.4727H83.7562V4.35059Z" fill="#282828"/>
6 <path d="M95.3127 8.30225H97.1451V27.4727H95.3127V31.457H103.07V27.4727H101.238V8.30225H103.07V4.35059H95.3127V8.30225Z" fill="#282828"/>
7 <path d="M114.664 3.7298C112.842 3.57303 111.034 4.18231 109.625 5.42809C109.047 6.01892 108.595 6.73614 108.3 7.53084C108.005 8.32553 107.874 9.17891 107.915 10.0328V25.7089C107.879 26.57 108.016 27.4293 108.316 28.2292C108.616 29.029 109.073 29.7509 109.656 30.3464C111.1 31.5667 112.921 32.1613 114.756 32.012C116.587 32.1636 118.403 31.5555 119.826 30.3138C120.399 29.7191 120.848 29.0012 121.142 28.2074C121.437 27.4137 121.571 26.5621 121.536 25.7089V22.737H117.444V25.7089C117.462 26.0223 117.416 26.3361 117.311 26.6291C117.206 26.9222 117.042 27.1875 116.833 27.4071C116.234 27.8771 115.496 28.0977 114.756 28.0276C113.996 28.1142 113.233 27.8928 112.618 27.4071C112.405 27.1902 112.24 26.9252 112.134 26.6315C112.028 26.3378 111.985 26.0227 112.007 25.7089V10.0328C111.985 9.7219 112.026 9.4096 112.126 9.11671C112.226 8.82382 112.383 8.55715 112.588 8.33464C113.186 7.86466 113.925 7.64406 114.664 7.71412C115.435 7.61912 116.21 7.84096 116.833 8.33464C117.042 8.55428 117.206 8.8196 117.311 9.11263C117.416 9.40565 117.462 9.71948 117.444 10.0328V14.5724H121.536V10.0328C121.57 9.17397 121.429 8.31755 121.123 7.52256C120.817 6.72757 120.354 6.01302 119.765 5.42809C118.332 4.18135 116.505 3.57303 114.664 3.7298Z" fill="#282828"/>
8 <path d="M126.379 4.35059V8.30225H131.143V31.457H135.236V8.30225H140V4.35059H126.379Z" fill="#282828"/>
9 <path d="M18.4236 36H25.9961V32.3203H22.0123V3.67966H26.0619V0H18.4236V36Z" fill="#DB394C"/>
10 <path d="M31.2968 0V3.67966H35.3136V32.3203H31.2639V36H38.9023V0H31.2968Z" fill="#DB394C"/>
11 <path d="M30.4737 10.3562H26.8521V25.3783H30.4737V10.3562Z" fill="#DB394C"/>
12 </svg>
--- a/docs/assets/images/conflict-logo.svg
+++ b/docs/assets/images/conflict-logo.svg
@@ -0,0 +1,12 @@
1
+<svg width="141" height="37" viewBox="0 0 141 37" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+<path d="M7.76011 3.9038C5.92786 3.74184 4.10895 4.35124 2.69056 5.6021C2.11733 6.19678 1.66843 6.91459 1.37363 7.70833C1.07884 8.50207 0.944757 9.35363 0.980235 10.2068V25.8829C0.944276 26.744 1.08103 27.6033 1.38128 28.4032C1.68152 29.203 2.13834 29.9249 2.72104 30.5204C4.16802 31.7349 5.9866 32.3289 7.82125 32.186C9.65242 32.3376 11.4679 31.7295 12.8909 30.4878C13.4641 29.8931 13.9129 29.1752 14.2077 28.3814C14.5025 27.5877 14.6366 26.7361 14.6011 25.8829V22.911H10.5088V25.8829C10.5269 26.1963 10.4816 26.5101 10.3763 26.8031C10.2709 27.0962 10.1077 27.3615 9.89795 27.5811C9.29929 28.0511 8.56102 28.2717 7.82125 28.2016C7.06115 28.2882 6.29829 28.0668 5.68342 27.5811C5.47026 27.3642 5.30488 27.0992 5.19924 26.8055C5.0936 26.5118 5.05041 26.1967 5.07267 25.8829V10.2068C5.05065 9.89591 5.09096 9.58361 5.19104 9.29072C5.29111 8.99783 5.44865 8.73115 5.65294 8.50864C6.25972 8.0309 7.01016 7.80989 7.76011 7.88813C8.52022 7.80157 9.28308 8.023 9.89795 8.50864C10.1077 8.72828 10.2709 8.99361 10.3763 9.28663C10.4816 9.57966 10.5269 9.89349 10.5088 10.2068V14.7464H14.6011V10.2068C14.6348 9.34798 14.4939 8.49156 14.1881 7.69657C13.8823 6.90158 13.4188 6.18702 12.8298 5.6021C11.4067 4.3604 9.59128 3.7522 7.76011 3.9038Z" fill="white"/>
3
+<path d="M55.2655 21.0496L48.4551 4.52451H44.7598V31.631H48.8521V15.0732L55.632 31.631H59.3579V4.52451H55.2655V21.0496Z" fill="white"/>
4
+<path d="M64.1953 31.631H68.2877V19.8739H74.3346V15.8896H68.2877V8.47617H75.8005V4.52451H64.1953V31.631Z" fill="white"/>
5
+<path d="M84.731 4.52451H80.6387V31.631H91.4498V27.6466H84.731V4.52451Z" fill="white"/>
6
+<path d="M96.2871 8.47617H98.1195V27.6466H96.2871V31.631H104.044V27.6466H102.212V8.47617H104.044V4.52451H96.2871V8.47617Z" fill="white"/>
7
+<path d="M115.64 3.90374C113.817 3.74697 112.01 4.35626 110.601 5.60204C110.022 6.19287 109.57 6.91008 109.275 7.70478C108.98 8.49948 108.849 9.35285 108.89 10.2068V25.8829C108.854 26.7439 108.991 27.6032 109.291 28.4031C109.592 29.203 110.048 29.9248 110.631 30.5203C112.075 31.7406 113.896 32.3352 115.731 32.1859C117.562 32.3375 119.378 31.7294 120.801 30.4877C121.374 29.893 121.823 29.1751 122.118 28.3814C122.412 27.5876 122.547 26.7361 122.511 25.8829V22.9109H118.419V25.8829C118.437 26.1962 118.392 26.51 118.286 26.8031C118.181 27.0961 118.018 27.3614 117.808 27.5811C117.209 28.051 116.471 28.2716 115.731 28.2016C114.971 28.2881 114.208 28.0667 113.593 27.5811C113.38 27.3641 113.215 27.0992 113.109 26.8055C113.004 26.5118 112.96 26.1966 112.983 25.8829V10.2068C112.961 9.89584 113.001 9.58355 113.101 9.29066C113.201 8.99777 113.359 8.73109 113.563 8.50858C114.162 8.0386 114.9 7.818 115.64 7.88806C116.41 7.79306 117.185 8.01491 117.808 8.50858C118.018 8.72822 118.181 8.99354 118.286 9.28657C118.392 9.5796 118.437 9.89342 118.419 10.2068V14.7463H122.511V10.2068C122.545 9.34791 122.404 8.4915 122.098 7.69651C121.792 6.90152 121.329 6.18696 120.74 5.60204C119.307 4.35529 117.481 3.74697 115.64 3.90374Z" fill="white"/>
8
+<path d="M127.354 4.52451V8.47617H132.118V31.631H136.21V8.47617H140.974V4.52451H127.354Z" fill="white"/>
9
+<path d="M19.3984 36.1741H26.9709V32.4944H22.9871V3.85375H27.0368V0.174088H19.3984V36.1741Z" fill="#DB394C"/>
10
+<path d="M32.2717 0.174088V3.85375H36.2884V32.4944H32.2388V36.1741H39.8771V0.174088H32.2717Z" fill="#DB394C"/>
11
+<path d="M31.4486 10.5303H27.827V25.5524H31.4486V10.5303Z" fill="#DB394C"/>
12
+</svg>
--- a/docs/assets/images/conflict-logo.svg
+++ b/docs/assets/images/conflict-logo.svg
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
--- a/docs/assets/images/conflict-logo.svg
+++ b/docs/assets/images/conflict-logo.svg
@@ -0,0 +1,12 @@
1 <svg width="141" height="37" viewBox="0 0 141 37" fill="none" xmlns="http://www.w3.org/2000/svg">
2 <path d="M7.76011 3.9038C5.92786 3.74184 4.10895 4.35124 2.69056 5.6021C2.11733 6.19678 1.66843 6.91459 1.37363 7.70833C1.07884 8.50207 0.944757 9.35363 0.980235 10.2068V25.8829C0.944276 26.744 1.08103 27.6033 1.38128 28.4032C1.68152 29.203 2.13834 29.9249 2.72104 30.5204C4.16802 31.7349 5.9866 32.3289 7.82125 32.186C9.65242 32.3376 11.4679 31.7295 12.8909 30.4878C13.4641 29.8931 13.9129 29.1752 14.2077 28.3814C14.5025 27.5877 14.6366 26.7361 14.6011 25.8829V22.911H10.5088V25.8829C10.5269 26.1963 10.4816 26.5101 10.3763 26.8031C10.2709 27.0962 10.1077 27.3615 9.89795 27.5811C9.29929 28.0511 8.56102 28.2717 7.82125 28.2016C7.06115 28.2882 6.29829 28.0668 5.68342 27.5811C5.47026 27.3642 5.30488 27.0992 5.19924 26.8055C5.0936 26.5118 5.05041 26.1967 5.07267 25.8829V10.2068C5.05065 9.89591 5.09096 9.58361 5.19104 9.29072C5.29111 8.99783 5.44865 8.73115 5.65294 8.50864C6.25972 8.0309 7.01016 7.80989 7.76011 7.88813C8.52022 7.80157 9.28308 8.023 9.89795 8.50864C10.1077 8.72828 10.2709 8.99361 10.3763 9.28663C10.4816 9.57966 10.5269 9.89349 10.5088 10.2068V14.7464H14.6011V10.2068C14.6348 9.34798 14.4939 8.49156 14.1881 7.69657C13.8823 6.90158 13.4188 6.18702 12.8298 5.6021C11.4067 4.3604 9.59128 3.7522 7.76011 3.9038Z" fill="white"/>
3 <path d="M55.2655 21.0496L48.4551 4.52451H44.7598V31.631H48.8521V15.0732L55.632 31.631H59.3579V4.52451H55.2655V21.0496Z" fill="white"/>
4 <path d="M64.1953 31.631H68.2877V19.8739H74.3346V15.8896H68.2877V8.47617H75.8005V4.52451H64.1953V31.631Z" fill="white"/>
5 <path d="M84.731 4.52451H80.6387V31.631H91.4498V27.6466H84.731V4.52451Z" fill="white"/>
6 <path d="M96.2871 8.47617H98.1195V27.6466H96.2871V31.631H104.044V27.6466H102.212V8.47617H104.044V4.52451H96.2871V8.47617Z" fill="white"/>
7 <path d="M115.64 3.90374C113.817 3.74697 112.01 4.35626 110.601 5.60204C110.022 6.19287 109.57 6.91008 109.275 7.70478C108.98 8.49948 108.849 9.35285 108.89 10.2068V25.8829C108.854 26.7439 108.991 27.6032 109.291 28.4031C109.592 29.203 110.048 29.9248 110.631 30.5203C112.075 31.7406 113.896 32.3352 115.731 32.1859C117.562 32.3375 119.378 31.7294 120.801 30.4877C121.374 29.893 121.823 29.1751 122.118 28.3814C122.412 27.5876 122.547 26.7361 122.511 25.8829V22.9109H118.419V25.8829C118.437 26.1962 118.392 26.51 118.286 26.8031C118.181 27.0961 118.018 27.3614 117.808 27.5811C117.209 28.051 116.471 28.2716 115.731 28.2016C114.971 28.2881 114.208 28.0667 113.593 27.5811C113.38 27.3641 113.215 27.0992 113.109 26.8055C113.004 26.5118 112.96 26.1966 112.983 25.8829V10.2068C112.961 9.89584 113.001 9.58355 113.101 9.29066C113.201 8.99777 113.359 8.73109 113.563 8.50858C114.162 8.0386 114.9 7.818 115.64 7.88806C116.41 7.79306 117.185 8.01491 117.808 8.50858C118.018 8.72822 118.181 8.99354 118.286 9.28657C118.392 9.5796 118.437 9.89342 118.419 10.2068V14.7463H122.511V10.2068C122.545 9.34791 122.404 8.4915 122.098 7.69651C121.792 6.90152 121.329 6.18696 120.74 5.60204C119.307 4.35529 117.481 3.74697 115.64 3.90374Z" fill="white"/>
8 <path d="M127.354 4.52451V8.47617H132.118V31.631H136.21V8.47617H140.974V4.52451H127.354Z" fill="white"/>
9 <path d="M19.3984 36.1741H26.9709V32.4944H22.9871V3.85375H27.0368V0.174088H19.3984V36.1741Z" fill="#DB394C"/>
10 <path d="M32.2717 0.174088V3.85375H36.2884V32.4944H32.2388V36.1741H39.8771V0.174088H32.2717Z" fill="#DB394C"/>
11 <path d="M31.4486 10.5303H27.827V25.5524H31.4486V10.5303Z" fill="#DB394C"/>
12 </svg>
--- navegador/cli/commands.py
+++ navegador/cli/commands.py
@@ -2,11 +2,10 @@
22
Navegador CLI — ingest repos, load context, serve MCP.
33
"""
44
55
import asyncio
66
import logging
7
-from pathlib import Path
87
98
import click
109
from rich.console import Console
1110
from rich.table import Table
1211
@@ -105,19 +104,20 @@
105104
@click.option("--db", default=".navegador/graph.db", show_default=True)
106105
@click.option("--host", default="127.0.0.1", show_default=True)
107106
@click.option("--port", default=8765, show_default=True)
108107
def mcp(db: str, host: str, port: int):
109108
"""Start the MCP server for AI agent integration."""
110
- from navegador.mcp import create_mcp_server
111109
from mcp.server.stdio import stdio_server # type: ignore[import]
110
+
111
+ from navegador.mcp import create_mcp_server
112112
113113
def store_factory():
114114
return _get_store(db)
115115
116116
server = create_mcp_server(store_factory)
117
- console.print(f"[green]Navegador MCP server running[/green] (stdio)")
117
+ console.print("[green]Navegador MCP server running[/green] (stdio)")
118118
119119
async def _run():
120120
async with stdio_server() as (read_stream, write_stream):
121121
await server.run(read_stream, write_stream, server.create_initialization_options())
122122
123123
asyncio.run(_run())
124124
--- navegador/cli/commands.py
+++ navegador/cli/commands.py
@@ -2,11 +2,10 @@
2 Navegador CLI — ingest repos, load context, serve MCP.
3 """
4
5 import asyncio
6 import logging
7 from pathlib import Path
8
9 import click
10 from rich.console import Console
11 from rich.table import Table
12
@@ -105,19 +104,20 @@
105 @click.option("--db", default=".navegador/graph.db", show_default=True)
106 @click.option("--host", default="127.0.0.1", show_default=True)
107 @click.option("--port", default=8765, show_default=True)
108 def mcp(db: str, host: str, port: int):
109 """Start the MCP server for AI agent integration."""
110 from navegador.mcp import create_mcp_server
111 from mcp.server.stdio import stdio_server # type: ignore[import]
 
 
112
113 def store_factory():
114 return _get_store(db)
115
116 server = create_mcp_server(store_factory)
117 console.print(f"[green]Navegador MCP server running[/green] (stdio)")
118
119 async def _run():
120 async with stdio_server() as (read_stream, write_stream):
121 await server.run(read_stream, write_stream, server.create_initialization_options())
122
123 asyncio.run(_run())
124
--- navegador/cli/commands.py
+++ navegador/cli/commands.py
@@ -2,11 +2,10 @@
2 Navegador CLI — ingest repos, load context, serve MCP.
3 """
4
5 import asyncio
6 import logging
 
7
8 import click
9 from rich.console import Console
10 from rich.table import Table
11
@@ -105,19 +104,20 @@
104 @click.option("--db", default=".navegador/graph.db", show_default=True)
105 @click.option("--host", default="127.0.0.1", show_default=True)
106 @click.option("--port", default=8765, show_default=True)
107 def mcp(db: str, host: str, port: int):
108 """Start the MCP server for AI agent integration."""
 
109 from mcp.server.stdio import stdio_server # type: ignore[import]
110
111 from navegador.mcp import create_mcp_server
112
113 def store_factory():
114 return _get_store(db)
115
116 server = create_mcp_server(store_factory)
117 console.print("[green]Navegador MCP server running[/green] (stdio)")
118
119 async def _run():
120 async with stdio_server() as (read_stream, write_stream):
121 await server.run(read_stream, write_stream, server.create_initialization_options())
122
123 asyncio.run(_run())
124
--- navegador/context/loader.py
+++ navegador/context/loader.py
@@ -16,12 +16,11 @@
1616
import logging
1717
from dataclasses import dataclass, field
1818
from pathlib import Path
1919
from typing import Any
2020
21
-from navegador.graph import GraphStore
22
-from navegador.graph import queries
21
+from navegador.graph import GraphStore, queries
2322
2423
logger = logging.getLogger(__name__)
2524
2625
2726
@dataclass
@@ -121,16 +120,20 @@
121120
"""Load context for a function — its callers and callees."""
122121
target = ContextNode(type="Function", name=name, file_path=file_path)
123122
nodes: list[ContextNode] = []
124123
edges: list[dict[str, str]] = []
125124
126
- callees = self.store.query(queries.CALLEES, {"name": name, "file_path": file_path, "depth": depth})
125
+ callees = self.store.query(
126
+ queries.CALLEES, {"name": name, "file_path": file_path, "depth": depth}
127
+ )
127128
for row in (callees.result_set or []):
128129
nodes.append(ContextNode(type=row[0], name=row[1], file_path=row[2], line_start=row[3]))
129130
edges.append({"from": name, "type": "CALLS", "to": row[1]})
130131
131
- callers = self.store.query(queries.CALLERS, {"name": name, "file_path": file_path, "depth": depth})
132
+ callers = self.store.query(
133
+ queries.CALLERS, {"name": name, "file_path": file_path, "depth": depth}
134
+ )
132135
for row in (callers.result_set or []):
133136
nodes.append(ContextNode(type=row[0], name=row[1], file_path=row[2], line_start=row[3]))
134137
edges.append({"from": row[1], "type": "CALLS", "to": name})
135138
136139
return ContextBundle(target=target, nodes=nodes, edges=edges,
137140
--- navegador/context/loader.py
+++ navegador/context/loader.py
@@ -16,12 +16,11 @@
16 import logging
17 from dataclasses import dataclass, field
18 from pathlib import Path
19 from typing import Any
20
21 from navegador.graph import GraphStore
22 from navegador.graph import queries
23
24 logger = logging.getLogger(__name__)
25
26
27 @dataclass
@@ -121,16 +120,20 @@
121 """Load context for a function — its callers and callees."""
122 target = ContextNode(type="Function", name=name, file_path=file_path)
123 nodes: list[ContextNode] = []
124 edges: list[dict[str, str]] = []
125
126 callees = self.store.query(queries.CALLEES, {"name": name, "file_path": file_path, "depth": depth})
 
 
127 for row in (callees.result_set or []):
128 nodes.append(ContextNode(type=row[0], name=row[1], file_path=row[2], line_start=row[3]))
129 edges.append({"from": name, "type": "CALLS", "to": row[1]})
130
131 callers = self.store.query(queries.CALLERS, {"name": name, "file_path": file_path, "depth": depth})
 
 
132 for row in (callers.result_set or []):
133 nodes.append(ContextNode(type=row[0], name=row[1], file_path=row[2], line_start=row[3]))
134 edges.append({"from": row[1], "type": "CALLS", "to": name})
135
136 return ContextBundle(target=target, nodes=nodes, edges=edges,
137
--- navegador/context/loader.py
+++ navegador/context/loader.py
@@ -16,12 +16,11 @@
16 import logging
17 from dataclasses import dataclass, field
18 from pathlib import Path
19 from typing import Any
20
21 from navegador.graph import GraphStore, queries
 
22
23 logger = logging.getLogger(__name__)
24
25
26 @dataclass
@@ -121,16 +120,20 @@
120 """Load context for a function — its callers and callees."""
121 target = ContextNode(type="Function", name=name, file_path=file_path)
122 nodes: list[ContextNode] = []
123 edges: list[dict[str, str]] = []
124
125 callees = self.store.query(
126 queries.CALLEES, {"name": name, "file_path": file_path, "depth": depth}
127 )
128 for row in (callees.result_set or []):
129 nodes.append(ContextNode(type=row[0], name=row[1], file_path=row[2], line_start=row[3]))
130 edges.append({"from": name, "type": "CALLS", "to": row[1]})
131
132 callers = self.store.query(
133 queries.CALLERS, {"name": name, "file_path": file_path, "depth": depth}
134 )
135 for row in (callers.result_set or []):
136 nodes.append(ContextNode(type=row[0], name=row[1], file_path=row[2], line_start=row[3]))
137 edges.append({"from": row[1], "type": "CALLS", "to": name})
138
139 return ContextBundle(target=target, nodes=nodes, edges=edges,
140
--- navegador/graph/schema.py
+++ navegador/graph/schema.py
@@ -38,11 +38,16 @@
3838
NODE_PROPS = {
3939
NodeLabel.Repository: ["name", "path", "language", "description"],
4040
NodeLabel.File: ["name", "path", "language", "size", "line_count"],
4141
NodeLabel.Module: ["name", "file_path", "docstring"],
4242
NodeLabel.Class: ["name", "file_path", "line_start", "line_end", "docstring", "source"],
43
- NodeLabel.Function: ["name", "file_path", "line_start", "line_end", "docstring", "source", "signature"],
44
- NodeLabel.Method: ["name", "file_path", "line_start", "line_end", "docstring", "source", "signature", "class_name"],
43
+ NodeLabel.Function: [
44
+ "name", "file_path", "line_start", "line_end", "docstring", "source", "signature",
45
+ ],
46
+ NodeLabel.Method: [
47
+ "name", "file_path", "line_start", "line_end",
48
+ "docstring", "source", "signature", "class_name",
49
+ ],
4550
NodeLabel.Variable: ["name", "file_path", "line_start", "type_annotation"],
4651
NodeLabel.Import: ["name", "file_path", "line_start", "module", "alias"],
4752
NodeLabel.Decorator: ["name", "file_path", "line_start"],
4853
}
4954
--- navegador/graph/schema.py
+++ navegador/graph/schema.py
@@ -38,11 +38,16 @@
38 NODE_PROPS = {
39 NodeLabel.Repository: ["name", "path", "language", "description"],
40 NodeLabel.File: ["name", "path", "language", "size", "line_count"],
41 NodeLabel.Module: ["name", "file_path", "docstring"],
42 NodeLabel.Class: ["name", "file_path", "line_start", "line_end", "docstring", "source"],
43 NodeLabel.Function: ["name", "file_path", "line_start", "line_end", "docstring", "source", "signature"],
44 NodeLabel.Method: ["name", "file_path", "line_start", "line_end", "docstring", "source", "signature", "class_name"],
 
 
 
 
 
45 NodeLabel.Variable: ["name", "file_path", "line_start", "type_annotation"],
46 NodeLabel.Import: ["name", "file_path", "line_start", "module", "alias"],
47 NodeLabel.Decorator: ["name", "file_path", "line_start"],
48 }
49
--- navegador/graph/schema.py
+++ navegador/graph/schema.py
@@ -38,11 +38,16 @@
38 NODE_PROPS = {
39 NodeLabel.Repository: ["name", "path", "language", "description"],
40 NodeLabel.File: ["name", "path", "language", "size", "line_count"],
41 NodeLabel.Module: ["name", "file_path", "docstring"],
42 NodeLabel.Class: ["name", "file_path", "line_start", "line_end", "docstring", "source"],
43 NodeLabel.Function: [
44 "name", "file_path", "line_start", "line_end", "docstring", "source", "signature",
45 ],
46 NodeLabel.Method: [
47 "name", "file_path", "line_start", "line_end",
48 "docstring", "source", "signature", "class_name",
49 ],
50 NodeLabel.Variable: ["name", "file_path", "line_start", "type_annotation"],
51 NodeLabel.Import: ["name", "file_path", "line_start", "module", "alias"],
52 NodeLabel.Decorator: ["name", "file_path", "line_start"],
53 }
54
--- navegador/ingestion/parser.py
+++ navegador/ingestion/parser.py
@@ -4,11 +4,11 @@
44
"""
55
66
import logging
77
from pathlib import Path
88
9
-from navegador.graph.schema import EdgeType, NodeLabel
9
+from navegador.graph.schema import NodeLabel
1010
from navegador.graph.store import GraphStore
1111
1212
logger = logging.getLogger(__name__)
1313
1414
# File extensions → language key
@@ -80,11 +80,13 @@
8080
repo_path.name, stats["files"], stats["functions"], stats["classes"],
8181
)
8282
return stats
8383
8484
def _iter_source_files(self, repo_path: Path):
85
- skip_dirs = {".git", ".venv", "venv", "node_modules", "__pycache__", "dist", "build", ".next"}
85
+ skip_dirs = {
86
+ ".git", ".venv", "venv", "node_modules", "__pycache__", "dist", "build", ".next"
87
+ }
8688
for path in repo_path.rglob("*"):
8789
if path.is_file() and path.suffix in LANGUAGE_MAP:
8890
if not any(part in skip_dirs for part in path.parts):
8991
yield path
9092
9193
--- navegador/ingestion/parser.py
+++ navegador/ingestion/parser.py
@@ -4,11 +4,11 @@
4 """
5
6 import logging
7 from pathlib import Path
8
9 from navegador.graph.schema import EdgeType, NodeLabel
10 from navegador.graph.store import GraphStore
11
12 logger = logging.getLogger(__name__)
13
14 # File extensions → language key
@@ -80,11 +80,13 @@
80 repo_path.name, stats["files"], stats["functions"], stats["classes"],
81 )
82 return stats
83
84 def _iter_source_files(self, repo_path: Path):
85 skip_dirs = {".git", ".venv", "venv", "node_modules", "__pycache__", "dist", "build", ".next"}
 
 
86 for path in repo_path.rglob("*"):
87 if path.is_file() and path.suffix in LANGUAGE_MAP:
88 if not any(part in skip_dirs for part in path.parts):
89 yield path
90
91
--- navegador/ingestion/parser.py
+++ navegador/ingestion/parser.py
@@ -4,11 +4,11 @@
4 """
5
6 import logging
7 from pathlib import Path
8
9 from navegador.graph.schema import NodeLabel
10 from navegador.graph.store import GraphStore
11
12 logger = logging.getLogger(__name__)
13
14 # File extensions → language key
@@ -80,11 +80,13 @@
80 repo_path.name, stats["files"], stats["functions"], stats["classes"],
81 )
82 return stats
83
84 def _iter_source_files(self, repo_path: Path):
85 skip_dirs = {
86 ".git", ".venv", "venv", "node_modules", "__pycache__", "dist", "build", ".next"
87 }
88 for path in repo_path.rglob("*"):
89 if path.is_file() and path.suffix in LANGUAGE_MAP:
90 if not any(part in skip_dirs for part in path.parts):
91 yield path
92
93
--- navegador/ingestion/python.py
+++ navegador/ingestion/python.py
@@ -40,11 +40,13 @@
4040
if not body:
4141
return None
4242
first_stmt = next((c for c in body.children if c.type == "expression_statement"), None)
4343
if not first_stmt:
4444
return None
45
- string_node = next((c for c in first_stmt.children if c.type in ("string", "string_content")), None)
45
+ string_node = next(
46
+ (c for c in first_stmt.children if c.type in ("string", "string_content")), None
47
+ )
4648
if string_node:
4749
raw = _node_text(string_node, source)
4850
return raw.strip('"""').strip("'''").strip('"').strip("'").strip()
4951
return None
5052
@@ -197,11 +199,14 @@
197199
container_key = (
198200
{"name": class_name, "file_path": file_path}
199201
if class_name
200202
else {"path": file_path}
201203
)
202
- store.create_edge(container_label, container_key, EdgeType.CONTAINS, label, {"name": name, "file_path": file_path})
204
+ store.create_edge(
205
+ container_label, container_key, EdgeType.CONTAINS, label,
206
+ {"name": name, "file_path": file_path},
207
+ )
203208
stats["functions"] += 1
204209
stats["edges"] += 1
205210
206211
# Call edges — find all call expressions in the body
207212
self._extract_calls(node, source, file_path, name, label, store, stats)
@@ -208,11 +213,13 @@
208213
209214
def _extract_calls(self, fn_node, source: bytes, file_path: str, fn_name: str,
210215
fn_label: str, store: GraphStore, stats: dict) -> None:
211216
def walk_calls(node):
212217
if node.type == "call":
213
- func = next((c for c in node.children if c.type in ("identifier", "attribute")), None)
218
+ func = next(
219
+ (c for c in node.children if c.type in ("identifier", "attribute")), None
220
+ )
214221
if func:
215222
callee_name = _node_text(func, source).split(".")[-1]
216223
store.create_edge(
217224
fn_label, {"name": fn_name, "file_path": file_path},
218225
EdgeType.CALLS,
219226
--- navegador/ingestion/python.py
+++ navegador/ingestion/python.py
@@ -40,11 +40,13 @@
40 if not body:
41 return None
42 first_stmt = next((c for c in body.children if c.type == "expression_statement"), None)
43 if not first_stmt:
44 return None
45 string_node = next((c for c in first_stmt.children if c.type in ("string", "string_content")), None)
 
 
46 if string_node:
47 raw = _node_text(string_node, source)
48 return raw.strip('"""').strip("'''").strip('"').strip("'").strip()
49 return None
50
@@ -197,11 +199,14 @@
197 container_key = (
198 {"name": class_name, "file_path": file_path}
199 if class_name
200 else {"path": file_path}
201 )
202 store.create_edge(container_label, container_key, EdgeType.CONTAINS, label, {"name": name, "file_path": file_path})
 
 
 
203 stats["functions"] += 1
204 stats["edges"] += 1
205
206 # Call edges — find all call expressions in the body
207 self._extract_calls(node, source, file_path, name, label, store, stats)
@@ -208,11 +213,13 @@
208
209 def _extract_calls(self, fn_node, source: bytes, file_path: str, fn_name: str,
210 fn_label: str, store: GraphStore, stats: dict) -> None:
211 def walk_calls(node):
212 if node.type == "call":
213 func = next((c for c in node.children if c.type in ("identifier", "attribute")), None)
 
 
214 if func:
215 callee_name = _node_text(func, source).split(".")[-1]
216 store.create_edge(
217 fn_label, {"name": fn_name, "file_path": file_path},
218 EdgeType.CALLS,
219
--- navegador/ingestion/python.py
+++ navegador/ingestion/python.py
@@ -40,11 +40,13 @@
40 if not body:
41 return None
42 first_stmt = next((c for c in body.children if c.type == "expression_statement"), None)
43 if not first_stmt:
44 return None
45 string_node = next(
46 (c for c in first_stmt.children if c.type in ("string", "string_content")), None
47 )
48 if string_node:
49 raw = _node_text(string_node, source)
50 return raw.strip('"""').strip("'''").strip('"').strip("'").strip()
51 return None
52
@@ -197,11 +199,14 @@
199 container_key = (
200 {"name": class_name, "file_path": file_path}
201 if class_name
202 else {"path": file_path}
203 )
204 store.create_edge(
205 container_label, container_key, EdgeType.CONTAINS, label,
206 {"name": name, "file_path": file_path},
207 )
208 stats["functions"] += 1
209 stats["edges"] += 1
210
211 # Call edges — find all call expressions in the body
212 self._extract_calls(node, source, file_path, name, label, store, stats)
@@ -208,11 +213,13 @@
213
214 def _extract_calls(self, fn_node, source: bytes, file_path: str, fn_name: str,
215 fn_label: str, store: GraphStore, stats: dict) -> None:
216 def walk_calls(node):
217 if node.type == "call":
218 func = next(
219 (c for c in node.children if c.type in ("identifier", "attribute")), None
220 )
221 if func:
222 callee_name = _node_text(func, source).split(".")[-1]
223 store.create_edge(
224 fn_label, {"name": fn_name, "file_path": file_path},
225 EdgeType.CALLS,
226
--- navegador/ingestion/typescript.py
+++ navegador/ingestion/typescript.py
@@ -139,8 +139,11 @@
139139
container_key = (
140140
{"name": class_name, "file_path": file_path}
141141
if class_name
142142
else {"path": file_path}
143143
)
144
- store.create_edge(container_label, container_key, EdgeType.CONTAINS, label, {"name": name, "file_path": file_path})
144
+ store.create_edge(
145
+ container_label, container_key, EdgeType.CONTAINS, label,
146
+ {"name": name, "file_path": file_path},
147
+ )
145148
stats["functions"] += 1
146149
stats["edges"] += 1
147150
--- navegador/ingestion/typescript.py
+++ navegador/ingestion/typescript.py
@@ -139,8 +139,11 @@
139 container_key = (
140 {"name": class_name, "file_path": file_path}
141 if class_name
142 else {"path": file_path}
143 )
144 store.create_edge(container_label, container_key, EdgeType.CONTAINS, label, {"name": name, "file_path": file_path})
 
 
 
145 stats["functions"] += 1
146 stats["edges"] += 1
147
--- navegador/ingestion/typescript.py
+++ navegador/ingestion/typescript.py
@@ -139,8 +139,11 @@
139 container_key = (
140 {"name": class_name, "file_path": file_path}
141 if class_name
142 else {"path": file_path}
143 )
144 store.create_edge(
145 container_label, container_key, EdgeType.CONTAINS, label,
146 {"name": name, "file_path": file_path},
147 )
148 stats["functions"] += 1
149 stats["edges"] += 1
150
--- navegador/mcp/server.py
+++ navegador/mcp/server.py
@@ -18,11 +18,10 @@
1818
Args:
1919
store_factory: Callable[[], GraphStore] — called lazily on first request.
2020
"""
2121
try:
2222
from mcp.server import Server # type: ignore[import]
23
- from mcp.server.stdio import stdio_server # type: ignore[import]
2423
from mcp.types import TextContent, Tool # type: ignore[import]
2524
except ImportError as e:
2625
raise ImportError("Install mcp: pip install mcp") from e
2726
2827
from navegador.context import ContextLoader
@@ -45,24 +44,33 @@
4544
name="ingest_repo",
4645
description="Parse and ingest a local code repository into the navegador graph.",
4746
inputSchema={
4847
"type": "object",
4948
"properties": {
50
- "path": {"type": "string", "description": "Absolute path to the repository."},
51
- "clear": {"type": "boolean", "description": "Clear existing graph before ingesting.", "default": False},
49
+ "path": {"type": "string", "description": "Absolute path to the repo."},
50
+ "clear": {
51
+ "type": "boolean",
52
+ "description": "Clear existing graph before ingesting.",
53
+ "default": False,
54
+ },
5255
},
5356
"required": ["path"],
5457
},
5558
),
5659
Tool(
5760
name="load_file_context",
58
- description="Return all symbols (functions, classes, imports) in a file and their relationships.",
61
+ description="Return all symbols (functions, classes, imports) in a file.",
5962
inputSchema={
6063
"type": "object",
6164
"properties": {
62
- "file_path": {"type": "string", "description": "Relative file path within the ingested repo."},
63
- "format": {"type": "string", "enum": ["json", "markdown"], "default": "markdown"},
65
+ "file_path": {
66
+ "type": "string",
67
+ "description": "Relative file path within the ingested repo.",
68
+ },
69
+ "format": {
70
+ "type": "string", "enum": ["json", "markdown"], "default": "markdown",
71
+ },
6472
},
6573
"required": ["file_path"],
6674
},
6775
),
6876
Tool(
@@ -72,11 +80,13 @@
7280
"type": "object",
7381
"properties": {
7482
"name": {"type": "string", "description": "Function name."},
7583
"file_path": {"type": "string", "description": "Relative file path."},
7684
"depth": {"type": "integer", "default": 2},
77
- "format": {"type": "string", "enum": ["json", "markdown"], "default": "markdown"},
85
+ "format": {
86
+ "type": "string", "enum": ["json", "markdown"], "default": "markdown",
87
+ },
7888
},
7989
"required": ["name", "file_path"],
8090
},
8191
),
8292
Tool(
@@ -85,11 +95,13 @@
8595
inputSchema={
8696
"type": "object",
8797
"properties": {
8898
"name": {"type": "string", "description": "Class name."},
8999
"file_path": {"type": "string", "description": "Relative file path."},
90
- "format": {"type": "string", "enum": ["json", "markdown"], "default": "markdown"},
100
+ "format": {
101
+ "type": "string", "enum": ["json", "markdown"], "default": "markdown",
102
+ },
91103
},
92104
"required": ["name", "file_path"],
93105
},
94106
),
95107
Tool(
96108
--- navegador/mcp/server.py
+++ navegador/mcp/server.py
@@ -18,11 +18,10 @@
18 Args:
19 store_factory: Callable[[], GraphStore] — called lazily on first request.
20 """
21 try:
22 from mcp.server import Server # type: ignore[import]
23 from mcp.server.stdio import stdio_server # type: ignore[import]
24 from mcp.types import TextContent, Tool # type: ignore[import]
25 except ImportError as e:
26 raise ImportError("Install mcp: pip install mcp") from e
27
28 from navegador.context import ContextLoader
@@ -45,24 +44,33 @@
45 name="ingest_repo",
46 description="Parse and ingest a local code repository into the navegador graph.",
47 inputSchema={
48 "type": "object",
49 "properties": {
50 "path": {"type": "string", "description": "Absolute path to the repository."},
51 "clear": {"type": "boolean", "description": "Clear existing graph before ingesting.", "default": False},
 
 
 
 
52 },
53 "required": ["path"],
54 },
55 ),
56 Tool(
57 name="load_file_context",
58 description="Return all symbols (functions, classes, imports) in a file and their relationships.",
59 inputSchema={
60 "type": "object",
61 "properties": {
62 "file_path": {"type": "string", "description": "Relative file path within the ingested repo."},
63 "format": {"type": "string", "enum": ["json", "markdown"], "default": "markdown"},
 
 
 
 
 
64 },
65 "required": ["file_path"],
66 },
67 ),
68 Tool(
@@ -72,11 +80,13 @@
72 "type": "object",
73 "properties": {
74 "name": {"type": "string", "description": "Function name."},
75 "file_path": {"type": "string", "description": "Relative file path."},
76 "depth": {"type": "integer", "default": 2},
77 "format": {"type": "string", "enum": ["json", "markdown"], "default": "markdown"},
 
 
78 },
79 "required": ["name", "file_path"],
80 },
81 ),
82 Tool(
@@ -85,11 +95,13 @@
85 inputSchema={
86 "type": "object",
87 "properties": {
88 "name": {"type": "string", "description": "Class name."},
89 "file_path": {"type": "string", "description": "Relative file path."},
90 "format": {"type": "string", "enum": ["json", "markdown"], "default": "markdown"},
 
 
91 },
92 "required": ["name", "file_path"],
93 },
94 ),
95 Tool(
96
--- navegador/mcp/server.py
+++ navegador/mcp/server.py
@@ -18,11 +18,10 @@
18 Args:
19 store_factory: Callable[[], GraphStore] — called lazily on first request.
20 """
21 try:
22 from mcp.server import Server # type: ignore[import]
 
23 from mcp.types import TextContent, Tool # type: ignore[import]
24 except ImportError as e:
25 raise ImportError("Install mcp: pip install mcp") from e
26
27 from navegador.context import ContextLoader
@@ -45,24 +44,33 @@
44 name="ingest_repo",
45 description="Parse and ingest a local code repository into the navegador graph.",
46 inputSchema={
47 "type": "object",
48 "properties": {
49 "path": {"type": "string", "description": "Absolute path to the repo."},
50 "clear": {
51 "type": "boolean",
52 "description": "Clear existing graph before ingesting.",
53 "default": False,
54 },
55 },
56 "required": ["path"],
57 },
58 ),
59 Tool(
60 name="load_file_context",
61 description="Return all symbols (functions, classes, imports) in a file.",
62 inputSchema={
63 "type": "object",
64 "properties": {
65 "file_path": {
66 "type": "string",
67 "description": "Relative file path within the ingested repo.",
68 },
69 "format": {
70 "type": "string", "enum": ["json", "markdown"], "default": "markdown",
71 },
72 },
73 "required": ["file_path"],
74 },
75 ),
76 Tool(
@@ -72,11 +80,13 @@
80 "type": "object",
81 "properties": {
82 "name": {"type": "string", "description": "Function name."},
83 "file_path": {"type": "string", "description": "Relative file path."},
84 "depth": {"type": "integer", "default": 2},
85 "format": {
86 "type": "string", "enum": ["json", "markdown"], "default": "markdown",
87 },
88 },
89 "required": ["name", "file_path"],
90 },
91 ),
92 Tool(
@@ -85,11 +95,13 @@
95 inputSchema={
96 "type": "object",
97 "properties": {
98 "name": {"type": "string", "description": "Class name."},
99 "file_path": {"type": "string", "description": "Relative file path."},
100 "format": {
101 "type": "string", "enum": ["json", "markdown"], "default": "markdown",
102 },
103 },
104 "required": ["name", "file_path"],
105 },
106 ),
107 Tool(
108
+4 -1
--- pyproject.toml
+++ pyproject.toml
@@ -27,11 +27,10 @@
2727
]
2828
2929
dependencies = [
3030
# Graph database
3131
"FalkorDB>=1.5.0", # graph query client
32
- "falkordblite>=0.8.0", # embedded SQLite-backed storage (zero-infra local)
3332
# AST parsing — multi-language via tree-sitter grammars
3433
"tree-sitter>=0.24.0",
3534
"tree-sitter-python>=0.23.0",
3635
"tree-sitter-typescript>=0.23.0",
3736
# CLI
@@ -43,10 +42,14 @@
4342
"pydantic>=2.0.0",
4443
"python-dotenv>=1.0.0",
4544
]
4645
4746
[project.optional-dependencies]
47
+sqlite = [
48
+ # Embedded SQLite backend via falkordblite (requires Python 3.12+)
49
+ "falkordblite>=0.8.0",
50
+]
4851
redis = [
4952
# Use Redis-backed FalkorDB in production
5053
"redis>=5.0.0",
5154
]
5255
dev = [
5356
--- pyproject.toml
+++ pyproject.toml
@@ -27,11 +27,10 @@
27 ]
28
29 dependencies = [
30 # Graph database
31 "FalkorDB>=1.5.0", # graph query client
32 "falkordblite>=0.8.0", # embedded SQLite-backed storage (zero-infra local)
33 # AST parsing — multi-language via tree-sitter grammars
34 "tree-sitter>=0.24.0",
35 "tree-sitter-python>=0.23.0",
36 "tree-sitter-typescript>=0.23.0",
37 # CLI
@@ -43,10 +42,14 @@
43 "pydantic>=2.0.0",
44 "python-dotenv>=1.0.0",
45 ]
46
47 [project.optional-dependencies]
 
 
 
 
48 redis = [
49 # Use Redis-backed FalkorDB in production
50 "redis>=5.0.0",
51 ]
52 dev = [
53
--- pyproject.toml
+++ pyproject.toml
@@ -27,11 +27,10 @@
27 ]
28
29 dependencies = [
30 # Graph database
31 "FalkorDB>=1.5.0", # graph query client
 
32 # AST parsing — multi-language via tree-sitter grammars
33 "tree-sitter>=0.24.0",
34 "tree-sitter-python>=0.23.0",
35 "tree-sitter-typescript>=0.23.0",
36 # CLI
@@ -43,10 +42,14 @@
42 "pydantic>=2.0.0",
43 "python-dotenv>=1.0.0",
44 ]
45
46 [project.optional-dependencies]
47 sqlite = [
48 # Embedded SQLite backend via falkordblite (requires Python 3.12+)
49 "falkordblite>=0.8.0",
50 ]
51 redis = [
52 # Use Redis-backed FalkorDB in production
53 "redis>=5.0.0",
54 ]
55 dev = [
56

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button