codemap-python 0.1.0__py3-none-any.whl → 0.1.1__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: codemap-python
3
- Version: 0.1.0
3
+ Version: 0.1.1
4
4
  Summary: Local Python code analysis tool - understand architecture, dependencies, and call graphs
5
5
  Author-email: ADITYA <aditykushwaha69@gmail.com>
6
6
  License: MIT
@@ -22,8 +22,9 @@ Requires-Python: >=3.10
22
22
  Description-Content-Type: text/markdown
23
23
  Requires-Dist: fastapi>=0.110
24
24
  Requires-Dist: uvicorn>=0.23
25
- Requires-Dist: jinja2>=3.1
25
+ Requires-Dist: jinja2>=3.1.4
26
26
  Requires-Dist: requests>=2.31
27
+ Requires-Dist: starlette==0.40.0
27
28
 
28
29
  # CodeMap
29
30
 
@@ -47,12 +48,8 @@ Requires-Dist: requests>=2.31
47
48
  ### Step 1️⃣: Install CodeMap
48
49
 
49
50
  ```bash
50
- # Clone the repository
51
- git clone https://github.com/ADITYA-kus/codemap_ai.git
52
- cd codemap_ai
53
-
54
- # Install as a local package
55
- pip install -e .
51
+ # Install from PyPI (easiest)
52
+ pip install codemap-python
56
53
  ```
57
54
 
58
55
  **Verify installation:**
@@ -65,6 +62,13 @@ You should see:
65
62
  usage: codemap [-h] {analyze,dashboard,open,cache} ...
66
63
  ```
67
64
 
65
+ > **For developers:** To modify source code or contribute, clone the repository:
66
+ > ```bash
67
+ > git clone https://github.com/ADITYA-kus/codemap_ai.git
68
+ > cd codemap_ai
69
+ > pip install -e .
70
+ > ```
71
+
68
72
  ---
69
73
 
70
74
  ### Step 2️⃣: Analyze Your First Repository
@@ -188,8 +192,10 @@ echo "YOUR_TOKEN" | codemap analyze --github https://github.com/owner/repo --tok
188
192
 
189
193
  ## Directory Structure
190
194
 
195
+ This is the source code structure for developers. **If you installed via pip, these files are automatically installed in your Python environment.**
196
+
191
197
  ```
192
- codemap_ai_clean/
198
+ codemap_ai/ (source code)
193
199
  ├── README.md # This file
194
200
  ├── cli.py # Command-line interface
195
201
  ├── security_utils.py # Security & secret redaction
@@ -44,15 +44,15 @@ analysis/utils/cache_manager.py,sha256=FUuZOO_CSHP_A2cFO4Kk8WQc34AYfqTol2w6n7DmT
44
44
  analysis/utils/path_resolver.py,sha256=NprapbBX8E1c_5jp2R1OLIYMeqrFeNfaxnmIlwqs9hI,27
45
45
  analysis/utils/repo_fetcher.py,sha256=bCUBG0qUypcXXgQPAAdJAaRoQSc75Nd53B7HD72Euno,15105
46
46
  ui/__init__.py,sha256=frcCV1k9oG9oKj3dpUqdJg1PxRT2RSN_XKdLCPjaYaY,2
47
- ui/app.py,sha256=HQQ6oGR-LScaLxXbVklRkZRAF8YIXg3U7JtWymie8js,80878
47
+ ui/app.py,sha256=BDjfHMRzBWBwFuRrMYen-KKFfeotn7RdXHG20gu5_4c,81661
48
48
  ui/device_id.py,sha256=gAan8gMnSY_lDpDSllafK27CSskFT-_OdFw2m8y2QUA,708
49
- ui/static/app.js,sha256=Qv7VPyBG2hWyX3PT2A0EO5XYcdImObiUctuqK5jHl50,114003
50
- ui/static/styles.css,sha256=gUEnjAQHh9qy0J2drZEiQyXMYe7y-krK1TX97yi4Q7w,20759
51
- ui/templates/index.html,sha256=h60_WeamhraIrxwAOifVFMeQ_Yzg7zye5etAjypmxjY,10773
49
+ ui/static/app.js,sha256=Nmfgs6pqMkS6Q44CtSBpEV9uW_xks2mS8BIxW7WqAXg,115957
50
+ ui/static/styles.css,sha256=B_QkNK8zziUDl-m8HzcpyO1FFujYf-DdO05Ly7JZbB8,23639
51
+ ui/templates/index.html,sha256=x8isBJyxzt8UdkLJK4NDqBlEjn_FbXdFc1O_llti-R0,11945
52
52
  ui/utils/__init__.py,sha256=8Bo3TpyB49uJs6QpQMTWpUR2hJhqEpbkK_E_GW7tYpU,5
53
53
  ui/utils/registry_manager.py,sha256=jEhWMQJ3H1ZtyUP2ObneqFOVDTdDqiBvUh-46-rGFDw,6730
54
- codemap_python-0.1.0.dist-info/METADATA,sha256=1dcRsNr8nxwc5kkJ0Hb42b7jGKElQ68Fo34aiRnIBuU,10075
55
- codemap_python-0.1.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
56
- codemap_python-0.1.0.dist-info/entry_points.txt,sha256=71TCgwo56CPxSfh-YSmofpNwq4-kSsjmBL_qzJ5kfmk,45
57
- codemap_python-0.1.0.dist-info/top_level.txt,sha256=JOu1LG-DyeBXc4u2Cn7KznNz-bZExhsf1CB7fV4r-t8,43
58
- codemap_python-0.1.0.dist-info/RECORD,,
54
+ codemap_python-0.1.1.dist-info/METADATA,sha256=gd2H56fRIsVq-dtcHVFkHMVyU-Ws7dWGlTGgULwMcCE,10382
55
+ codemap_python-0.1.1.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
56
+ codemap_python-0.1.1.dist-info/entry_points.txt,sha256=71TCgwo56CPxSfh-YSmofpNwq4-kSsjmBL_qzJ5kfmk,45
57
+ codemap_python-0.1.1.dist-info/top_level.txt,sha256=JOu1LG-DyeBXc4u2Cn7KznNz-bZExhsf1CB7fV4r-t8,43
58
+ codemap_python-0.1.1.dist-info/RECORD,,
ui/app.py CHANGED
@@ -35,6 +35,23 @@ from ui.utils.registry_manager import (
35
35
  from security_utils import redact_payload, redact_secrets
36
36
 
37
37
 
38
+ # Custom cache class that doesn't cache (to avoid TypeError with unhashable Request objects)
39
+ class NoCache:
40
+ """A cache implementation that doesn't cache anything.
41
+
42
+ This prevents Jinja2 from trying to cache templates with unhashable objects
43
+ like the Starlette Request in the context.
44
+ """
45
+ def get(self, key: Any, default: Any = None) -> Any:
46
+ return default
47
+
48
+ def set(self, key: Any, value: Any, timeout: Any = None) -> None:
49
+ pass
50
+
51
+ def clear(self) -> None:
52
+ pass
53
+
54
+
38
55
  PROJECT_ROOT = os.path.dirname(os.path.dirname(__file__))
39
56
  ANALYSIS_ROOT = os.path.join(PROJECT_ROOT, "analysis")
40
57
  DEFAULT_REPO = os.getenv("CODEMAP_UI_REPO", "testing_repo")
@@ -50,7 +67,11 @@ _SESSION_WORKSPACE_READY = False
50
67
 
51
68
 
52
69
  app = FastAPI(title="CodeMap UI")
53
- templates = Jinja2Templates(directory=os.path.join(os.path.dirname(__file__), "templates"))
70
+ templates_dir = os.path.join(os.path.dirname(__file__), "templates")
71
+ templates = Jinja2Templates(directory=templates_dir)
72
+ # Disable Jinja2 template caching to prevent TypeError with unhashable Request objects
73
+ # This avoids issues when Jinja2 tries to cache templates containing the Request context
74
+ templates.env.cache = NoCache()
54
75
  app.mount("/static", StaticFiles(directory=os.path.join(os.path.dirname(__file__), "static")), name="static")
55
76
  SEARCH_INDEX_CACHE: Dict[str, List[Dict[str, Any]]] = {}
56
77
  GRAPH_INDEX_CACHE: Dict[str, Dict[str, Any]] = {}
ui/static/app.js CHANGED
@@ -5,6 +5,9 @@
5
5
  const repoSelectEl = document.getElementById("repo-select");
6
6
  const addRepoBtnEl = document.getElementById("add-repo-btn");
7
7
  const aiSettingsBtnEl = document.getElementById("ai-settings-btn");
8
+ const themeToggleBtnEl = document.getElementById("theme-toggle-btn");
9
+ const themeWhiteOptionEl = document.getElementById("theme-white");
10
+ const themeDarkOptionEl = document.getElementById("theme-dark");
8
11
  const repoListModePillEl = document.getElementById("repo-list-mode-pill");
9
12
  const treeStatusEl = document.getElementById("tree-status");
10
13
  const treeEl = document.getElementById("tree");
@@ -2014,6 +2017,53 @@
2014
2017
  }
2015
2018
 
2016
2019
  function bindAiSettingsControls() {
2020
+ // Theme toggle handlers
2021
+ const setTheme = (themeName) => {
2022
+ localStorage.setItem("codemap-theme", themeName);
2023
+ if (themeName === "dark") {
2024
+ document.documentElement.classList.add("dark-theme");
2025
+ document.body.classList.add("dark-theme");
2026
+ if (themeToggleBtnEl) themeToggleBtnEl.textContent = "☀️ Light";
2027
+ if (themeDarkOptionEl) {
2028
+ themeDarkOptionEl.classList.add("active");
2029
+ }
2030
+ if (themeWhiteOptionEl) {
2031
+ themeWhiteOptionEl.classList.remove("active");
2032
+ }
2033
+ } else {
2034
+ document.documentElement.classList.remove("dark-theme");
2035
+ document.body.classList.remove("dark-theme");
2036
+ if (themeToggleBtnEl) themeToggleBtnEl.textContent = "🌙 Dark";
2037
+ if (themeWhiteOptionEl) {
2038
+ themeWhiteOptionEl.classList.add("active");
2039
+ }
2040
+ if (themeDarkOptionEl) {
2041
+ themeDarkOptionEl.classList.remove("active");
2042
+ }
2043
+ }
2044
+ };
2045
+
2046
+ // Initialize theme from localStorage (default is DARK)
2047
+ const savedTheme = localStorage.getItem("codemap-theme") || "dark";
2048
+ setTheme(savedTheme);
2049
+
2050
+ // Theme toggle button (top bar)
2051
+ if (themeToggleBtnEl) {
2052
+ themeToggleBtnEl.addEventListener("click", () => {
2053
+ const isDark = document.documentElement.classList.contains("dark-theme");
2054
+ setTheme(isDark ? "light" : "dark");
2055
+ });
2056
+ }
2057
+
2058
+ // Theme option buttons (settings modal)
2059
+ if (themeWhiteOptionEl) {
2060
+ themeWhiteOptionEl.addEventListener("click", () => setTheme("light"));
2061
+ }
2062
+ if (themeDarkOptionEl) {
2063
+ themeDarkOptionEl.addEventListener("click", () => setTheme("dark"));
2064
+ }
2065
+
2066
+ // Original AI settings handlers
2017
2067
  if (aiSettingsBtnEl) {
2018
2068
  aiSettingsBtnEl.addEventListener("click", async () => {
2019
2069
  await openAiSettingsModal();
ui/static/styles.css CHANGED
@@ -9,6 +9,18 @@
9
9
  --active-border: #4f84ff;
10
10
  }
11
11
 
12
+ html.dark-theme,
13
+ body.dark-theme {
14
+ --bg: #1a1a1a;
15
+ --panel: #252525;
16
+ --line: #404040;
17
+ --text: #e5e5e5;
18
+ --muted: #a0a0a0;
19
+ --accent: #4fa3ff;
20
+ --active-bg: #2a3a4a;
21
+ --active-border: #5fa3ff;
22
+ }
23
+
12
24
  * {
13
25
  box-sizing: border-box;
14
26
  }
@@ -1200,6 +1212,121 @@ body.modal-open {
1200
1212
  margin: 10px 0;
1201
1213
  }
1202
1214
 
1215
+ .theme-selector {
1216
+ display: flex;
1217
+ gap: 10px;
1218
+ margin-bottom: 10px;
1219
+ padding: 8px;
1220
+ background: var(--panel);
1221
+ border-radius: 8px;
1222
+ border: 1px solid var(--line);
1223
+ }
1224
+
1225
+ .theme-option {
1226
+ flex: 1;
1227
+ display: flex;
1228
+ flex-direction: column;
1229
+ align-items: center;
1230
+ gap: 6px;
1231
+ padding: 12px;
1232
+ border: 2px solid var(--line);
1233
+ border-radius: 8px;
1234
+ background: var(--panel);
1235
+ color: var(--text);
1236
+ cursor: pointer;
1237
+ transition: all 200ms ease;
1238
+ font-size: 12px;
1239
+ font-weight: 500;
1240
+ }
1241
+
1242
+ .theme-option:hover {
1243
+ border-color: var(--accent);
1244
+ box-shadow: 0 0 0 3px rgba(79, 132, 255, 0.15);
1245
+ transform: translateY(-1px);
1246
+ }
1247
+
1248
+ .theme-option.active {
1249
+ border-color: var(--accent);
1250
+ background: var(--active-bg);
1251
+ color: #0f3f9c;
1252
+ font-weight: 600;
1253
+ box-shadow: 0 0 0 3px rgba(79, 132, 255, 0.2);
1254
+ }
1255
+
1256
+ body.dark-theme .theme-option.active {
1257
+ background: #3a4a5f;
1258
+ color: #4fa3ff;
1259
+ border-color: #4fa3ff;
1260
+ }
1261
+
1262
+ .theme-icon {
1263
+ font-size: 20px;
1264
+ line-height: 1;
1265
+ }
1266
+
1267
+ .theme-label {
1268
+ font-size: 11px;
1269
+ text-transform: uppercase;
1270
+ letter-spacing: 0.04em;
1271
+ font-weight: 600;
1272
+ }
1273
+
1274
+ /* Dark theme specific styles */
1275
+ html.dark-theme .topbar,
1276
+ body.dark-theme .topbar {
1277
+ background: #2a2a2a;
1278
+ }
1279
+
1280
+ html.dark-theme .card,
1281
+ html.dark-theme .repo-row,
1282
+ html.dark-theme .confirm-card,
1283
+ html.dark-theme .modal-form input,
1284
+ html.dark-theme .modal-form select,
1285
+ html.dark-theme .repo-select,
1286
+ html.dark-theme .repo-btn,
1287
+ html.dark-theme .tab-btn,
1288
+ html.dark-theme .graph-controls select,
1289
+ html.dark-theme .graph-controls input[type="text"],
1290
+ html.dark-theme .search-results,
1291
+ html.dark-theme .graph-node,
1292
+ html.dark-theme .kpi-card,
1293
+ html.dark-theme .risk-file-row,
1294
+ html.dark-theme .risk-target,
1295
+ html.dark-theme .impact-file-row,
1296
+ body.dark-theme .card,
1297
+ body.dark-theme .repo-row,
1298
+ body.dark-theme .confirm-card,
1299
+ body.dark-theme .modal-form input,
1300
+ body.dark-theme .modal-form select,
1301
+ body.dark-theme .repo-select,
1302
+ body.dark-theme .repo-btn,
1303
+ body.dark-theme .tab-btn,
1304
+ body.dark-theme .graph-controls select,
1305
+ body.dark-theme .graph-controls input[type="text"],
1306
+ body.dark-theme .search-results,
1307
+ body.dark-theme .graph-node,
1308
+ body.dark-theme .kpi-card,
1309
+ body.dark-theme .risk-file-row,
1310
+ body.dark-theme .risk-target,
1311
+ body.dark-theme .impact-file-row {
1312
+ background: var(--panel);
1313
+ color: var(--text);
1314
+ border-color: var(--line);
1315
+ }
1316
+
1317
+ html.dark-theme #symbol-search-input,
1318
+ body.dark-theme #symbol-search-input {
1319
+ background: var(--panel);
1320
+ color: var(--text);
1321
+ border-color: var(--line);
1322
+ }
1323
+
1324
+ html.dark-theme .toast,
1325
+ body.dark-theme .toast {
1326
+ background: #2a2a2a;
1327
+ color: #e5e5e5;
1328
+ }
1329
+
1203
1330
  @media (max-width: 1000px) {
1204
1331
  .layout {
1205
1332
  grid-template-columns: 1fr;
ui/templates/index.html CHANGED
@@ -5,6 +5,20 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <title>CodeMap UI</title>
7
7
  <link rel="stylesheet" href="/static/styles.css" />
8
+ <script>
9
+ // Apply theme IMMEDIATELY on page load, before rendering
10
+ (function() {
11
+ try {
12
+ const theme = localStorage.getItem("codemap-theme") || "dark";
13
+ if (theme === "dark") {
14
+ document.documentElement.classList.add("dark-theme");
15
+ }
16
+ } catch (e) {
17
+ // fallback: use dark as default
18
+ document.documentElement.classList.add("dark-theme");
19
+ }
20
+ })();
21
+ </script>
8
22
  </head>
9
23
  <body>
10
24
  <header class="topbar">
@@ -18,6 +32,7 @@
18
32
  <div class="workspace-controls">
19
33
  <select id="repo-select" class="repo-select"></select>
20
34
  <button id="add-repo-btn" class="repo-btn" type="button">+ Add repo...</button>
35
+ <button id="theme-toggle-btn" class="repo-btn" type="button" title="Toggle theme">🌙 Dark</button>
21
36
  <button id="ai-settings-btn" class="repo-btn" type="button" onclick="var m=document.getElementById('ai-settings-modal'); if(m){ m.classList.remove('hidden'); document.body.classList.add('modal-open'); }">Settings</button>
22
37
  <span id="repo-list-mode-pill" class="repo-badge">Session Mode</span>
23
38
  </div>
@@ -73,6 +88,21 @@
73
88
  <div id="ai-settings-modal" class="confirm-modal hidden">
74
89
  <div class="confirm-card settings-card">
75
90
  <div class="section-title">Settings</div>
91
+ <div class="path">Appearance</div>
92
+ <label class="path">
93
+ <span>Theme</span>
94
+ </label>
95
+ <div class="theme-selector">
96
+ <button id="theme-white" class="theme-option" type="button" data-theme="light">
97
+ <span class="theme-icon">☀️</span>
98
+ <span class="theme-label">Light</span>
99
+ </button>
100
+ <button id="theme-dark" class="theme-option active" type="button" data-theme="dark">
101
+ <span class="theme-icon">🌙</span>
102
+ <span class="theme-label">Dark</span>
103
+ </button>
104
+ </div>
105
+ <div class="divider"></div>
76
106
  <div class="path">General</div>
77
107
  <label class="path">
78
108
  <input id="ai-settings-remember-repos" type="checkbox" />