neux 0.2.0__tar.gz

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.
Files changed (58) hide show
  1. neux-0.2.0/LICENSE +21 -0
  2. neux-0.2.0/PKG-INFO +75 -0
  3. neux-0.2.0/README.md +44 -0
  4. neux-0.2.0/logo.txt +11 -0
  5. neux-0.2.0/neux/__init__.py +8 -0
  6. neux-0.2.0/neux/categorizer.py +141 -0
  7. neux-0.2.0/neux/cli.py +383 -0
  8. neux-0.2.0/neux/context_builder.py +222 -0
  9. neux-0.2.0/neux/dashboard/__init__.py +1 -0
  10. neux-0.2.0/neux/dashboard/api.py +493 -0
  11. neux-0.2.0/neux/dashboard/app/dist/assets/index-BLhvlKpc.js +108 -0
  12. neux-0.2.0/neux/dashboard/app/dist/assets/index-CzFuvGhT.css +1 -0
  13. neux-0.2.0/neux/dashboard/app/dist/index.html +20 -0
  14. neux-0.2.0/neux/dashboard/server.py +319 -0
  15. neux-0.2.0/neux/db.py +519 -0
  16. neux-0.2.0/neux/detectors/__init__.py +62 -0
  17. neux-0.2.0/neux/detectors/api_design.py +94 -0
  18. neux-0.2.0/neux/detectors/base.py +151 -0
  19. neux-0.2.0/neux/detectors/data_access.py +87 -0
  20. neux-0.2.0/neux/detectors/error_handling.py +73 -0
  21. neux-0.2.0/neux/detectors/file_structure.py +103 -0
  22. neux-0.2.0/neux/detectors/imports.py +163 -0
  23. neux-0.2.0/neux/detectors/naming.py +178 -0
  24. neux-0.2.0/neux/detectors/security.py +124 -0
  25. neux-0.2.0/neux/detectors/state_management.py +64 -0
  26. neux-0.2.0/neux/detectors/style.py +118 -0
  27. neux-0.2.0/neux/detectors/testing.py +82 -0
  28. neux-0.2.0/neux/detectors/ui_component.py +87 -0
  29. neux-0.2.0/neux/engine.py +778 -0
  30. neux-0.2.0/neux/generator/__init__.py +1 -0
  31. neux-0.2.0/neux/generator/claude_md.py +169 -0
  32. neux-0.2.0/neux/generator/templates/claude_md.j2 +54 -0
  33. neux-0.2.0/neux/generator/templates/conventions.j2 +22 -0
  34. neux-0.2.0/neux/generator/templates/module.j2 +52 -0
  35. neux-0.2.0/neux/generator/templates/patterns.j2 +22 -0
  36. neux-0.2.0/neux/hook_entry.py +122 -0
  37. neux-0.2.0/neux/hooks.py +197 -0
  38. neux-0.2.0/neux/reviewer.py +68 -0
  39. neux-0.2.0/neux/scanner.py +311 -0
  40. neux-0.2.0/neux/scanners/__init__.py +1 -0
  41. neux-0.2.0/neux/scanners/base.py +72 -0
  42. neux-0.2.0/neux/scanners/python_scanner.py +370 -0
  43. neux-0.2.0/neux/scanners/sql_scanner.py +285 -0
  44. neux-0.2.0/neux/scanners/typescript_scanner.py +421 -0
  45. neux-0.2.0/neux.egg-info/PKG-INFO +75 -0
  46. neux-0.2.0/neux.egg-info/SOURCES.txt +56 -0
  47. neux-0.2.0/neux.egg-info/dependency_links.txt +1 -0
  48. neux-0.2.0/neux.egg-info/entry_points.txt +2 -0
  49. neux-0.2.0/neux.egg-info/requires.txt +11 -0
  50. neux-0.2.0/neux.egg-info/top_level.txt +1 -0
  51. neux-0.2.0/pyproject.toml +82 -0
  52. neux-0.2.0/setup.cfg +4 -0
  53. neux-0.2.0/tests/test_db.py +42 -0
  54. neux-0.2.0/tests/test_detectors.py +99 -0
  55. neux-0.2.0/tests/test_engine.py +73 -0
  56. neux-0.2.0/tests/test_generator_cli.py +67 -0
  57. neux-0.2.0/tests/test_hooks.py +66 -0
  58. neux-0.2.0/tests/test_scanners.py +73 -0
neux-0.2.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 IronDevz
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
neux-0.2.0/PKG-INFO ADDED
@@ -0,0 +1,75 @@
1
+ Metadata-Version: 2.4
2
+ Name: neux
3
+ Version: 0.2.0
4
+ Summary: Codebase nervous system — knowledge graph for AI-assisted development
5
+ Author: IronDevz
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/IronDevz/neux
8
+ Project-URL: Repository, https://github.com/IronDevz/neux
9
+ Keywords: claude-code,codebase,graph,ast,context,ai
10
+ Classifier: Development Status :: 3 - Alpha
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Topic :: Software Development
17
+ Requires-Python: >=3.11
18
+ Description-Content-Type: text/markdown
19
+ License-File: LICENSE
20
+ Requires-Dist: typer>=0.9.0
21
+ Requires-Dist: rich>=13.0
22
+ Requires-Dist: jinja2>=3.1
23
+ Requires-Dist: tree-sitter>=0.23
24
+ Requires-Dist: tree-sitter-language-pack>=0.4
25
+ Provides-Extra: dev
26
+ Requires-Dist: pytest>=8.0; extra == "dev"
27
+ Requires-Dist: pytest-cov>=5.0; extra == "dev"
28
+ Requires-Dist: ruff>=0.6; extra == "dev"
29
+ Requires-Dist: mypy>=1.10; extra == "dev"
30
+ Dynamic: license-file
31
+
32
+ # NEUX
33
+
34
+ > Codebase nervous system — knowledge graph for AI-assisted development.
35
+
36
+ NEUX is a Python CLI that builds a relationship graph of your codebase in SQLite,
37
+ detects patterns and conventions automatically (no LLM, pure AST), and integrates
38
+ with [Claude Code](https://claude.com/claude-code) via hooks to inject precise context
39
+ at the moment a tool call is about to modify a file.
40
+
41
+ Companion of [ANVL](https://github.com/juanlumanmx29/anvl). ANVL monitors tokens per
42
+ session. NEUX maps project intelligence.
43
+
44
+ ⚒ forged by **IronDevz**
45
+
46
+ ---
47
+
48
+ ## Features (v0.1)
49
+
50
+ - SQLite knowledge graph with FTS5 full-text search
51
+ - Language scanners: Python (`ast`), React/JS/TS/JSX/TSX (tree-sitter), SQL
52
+ - 12 pattern/convention detectors (naming, imports, security, style, UI, API, data, state, errors, file structure, testing)
53
+ - Claude Code hooks that inject contextual rules before `Write`/`Edit`
54
+ - Auto-generated `CLAUDE.md` with module sub-manuals
55
+ - Impact analysis via recursive CTE (no networkx)
56
+
57
+ ## Install
58
+
59
+ ```bash
60
+ pip install -e .
61
+ ```
62
+
63
+ ## Usage
64
+
65
+ ```bash
66
+ cd your-project
67
+ neux init # initial scan, generates CLAUDE.md, installs hooks
68
+ neux status # graph stats
69
+ neux impact <target> # what breaks if you change this
70
+ neux scan --changed # incremental rescan
71
+ ```
72
+
73
+ ## License
74
+
75
+ MIT © IronDevz
neux-0.2.0/README.md ADDED
@@ -0,0 +1,44 @@
1
+ # NEUX
2
+
3
+ > Codebase nervous system — knowledge graph for AI-assisted development.
4
+
5
+ NEUX is a Python CLI that builds a relationship graph of your codebase in SQLite,
6
+ detects patterns and conventions automatically (no LLM, pure AST), and integrates
7
+ with [Claude Code](https://claude.com/claude-code) via hooks to inject precise context
8
+ at the moment a tool call is about to modify a file.
9
+
10
+ Companion of [ANVL](https://github.com/juanlumanmx29/anvl). ANVL monitors tokens per
11
+ session. NEUX maps project intelligence.
12
+
13
+ ⚒ forged by **IronDevz**
14
+
15
+ ---
16
+
17
+ ## Features (v0.1)
18
+
19
+ - SQLite knowledge graph with FTS5 full-text search
20
+ - Language scanners: Python (`ast`), React/JS/TS/JSX/TSX (tree-sitter), SQL
21
+ - 12 pattern/convention detectors (naming, imports, security, style, UI, API, data, state, errors, file structure, testing)
22
+ - Claude Code hooks that inject contextual rules before `Write`/`Edit`
23
+ - Auto-generated `CLAUDE.md` with module sub-manuals
24
+ - Impact analysis via recursive CTE (no networkx)
25
+
26
+ ## Install
27
+
28
+ ```bash
29
+ pip install -e .
30
+ ```
31
+
32
+ ## Usage
33
+
34
+ ```bash
35
+ cd your-project
36
+ neux init # initial scan, generates CLAUDE.md, installs hooks
37
+ neux status # graph stats
38
+ neux impact <target> # what breaks if you change this
39
+ neux scan --changed # incremental rescan
40
+ ```
41
+
42
+ ## License
43
+
44
+ MIT © IronDevz
neux-0.2.0/logo.txt ADDED
@@ -0,0 +1,11 @@
1
+ ███▄ █ ▓█████ █ ██ ▒██ ██▒
2
+ ██ ▀█ █ ▓█ ▀ ██ ▓██▒▒▒ █ █ ▒░
3
+ ▓██ ▀█ ██▒▒███ ▓██ ▒██░░░ █ ░
4
+ ▓██▒ ▐▌██▒▒▓█ ▄ ▓▓█ ░██░ ░ █ █ ▒
5
+ ▒██░ ▓██░░▒████▒▒▒█████▓ ▒██▒ ▒██▒
6
+ ░ ▒░ ▒ ▒ ░░ ▒░ ░░▒▓▒ ▒ ▒ ▒▒ ░ ░▓ ░
7
+ ░ ░░ ░ ▒░ ░ ░ ░░░▒░ ░ ░ ░░ ░▒ ░
8
+ ░ ░ ░ ░ ░░░ ░ ░ ░ ░
9
+ ░ ░ ░ ░ ░ ░
10
+ ⚒ forged by IronDevz
11
+ codebase nervous system v0.1.0
@@ -0,0 +1,8 @@
1
+ """NEUX — codebase nervous system.
2
+
3
+ Python CLI that builds a knowledge graph of your codebase in SQLite,
4
+ detects patterns automatically, and integrates with Claude Code via hooks.
5
+ """
6
+
7
+ __version__ = "0.1.0"
8
+ __author__ = "IronDevz"
@@ -0,0 +1,141 @@
1
+ """TaskCategorizer — classify a user prompt + file path into a task category.
2
+
3
+ Returns one of:
4
+ ``style_change`` | ``logic_change`` | ``new_feature`` | ``bug_fix`` | ``refactor`` |
5
+ ``test_writing`` | ``api_change`` | ``database_change`` | ``config_change`` | ``general``
6
+
7
+ The categorization is score-based: count keyword hits in the prompt, add a
8
+ path hint (e.g. ``components/`` → ``style_change`` weight bump). No NLP, no LLM.
9
+ Kept deliberately simple so the hook entrypoint can run it without any heavy imports.
10
+ """
11
+
12
+ from __future__ import annotations
13
+
14
+ from dataclasses import dataclass, field
15
+
16
+ # Keywords per category — bilingual (Spanish + English) to match how IronDevz
17
+ # developers usually phrase requests.
18
+ CATEGORY_KEYWORDS: dict[str, list[str]] = {
19
+ "style_change": [
20
+ "color", "colour", "style", "styles", "estilo", "estilos", "css", "scss",
21
+ "sass", "theme", "tema", "font", "fuente", "tailwind", "responsive",
22
+ "padding", "margin", "layout", "design", "diseño", "ui", "visual",
23
+ "dark mode", "tipograf", "hover", "border",
24
+ ],
25
+ "new_feature": [
26
+ "crear", "nuevo", "nueva", "agregar", "añadir", "implementar",
27
+ "construir", "create", "add", "build", "implement", "feature",
28
+ "introduce", "support for", "soporte para",
29
+ ],
30
+ "logic_change": [
31
+ "función", "function", "cambiar", "modificar", "change", "modify",
32
+ "update", "actualizar", "adjust", "ajustar", "transform", "lógica",
33
+ "logic", "algorithm", "algoritmo", "flow", "flujo",
34
+ ],
35
+ "bug_fix": [
36
+ "bug", "error", "errors", "errores", "fix", "arreglar", "crash",
37
+ "falla", "broken", "roto", "issue", "problema", "incorrect",
38
+ "incorrecto", "no funciona", "not working", "regression", "regresión",
39
+ ],
40
+ "refactor": [
41
+ "refactor", "refactoring", "rename", "renombrar", "reorganizar",
42
+ "reorganize", "cleanup", "limpiar", "extract", "extraer", "simplify",
43
+ "simplificar", "dry", "deduplicate",
44
+ ],
45
+ "test_writing": [
46
+ "test", "tests", "prueba", "pruebas", "mock", "fixture", "coverage",
47
+ "spec", "unit test", "integration test", "pytest", "jest", "vitest",
48
+ "assert", "expect",
49
+ ],
50
+ "api_change": [
51
+ "endpoint", "endpoints", "api", "ruta", "rutas", "route", "routes",
52
+ "middleware", "auth", "authorization", "rest", "graphql", "request",
53
+ "response", "http", "get", "post", "put", "delete", "patch",
54
+ ],
55
+ "database_change": [
56
+ "tabla", "table", "migración", "migration", "modelo", "model",
57
+ "schema", "query", "sql", "database", "base de datos", "column",
58
+ "columna", "index", "índice", "foreign key", "constraint",
59
+ ],
60
+ "config_change": [
61
+ "config", "configuration", "configuración", "env", ".env", "docker",
62
+ "deploy", "deployment", "ci", "cd", "workflow", "pipeline",
63
+ "environment variable", "variable de entorno", "pyproject",
64
+ "package.json", "tsconfig", "settings",
65
+ ],
66
+ }
67
+
68
+ # Path hints: substring → category score bonus
69
+ PATH_HINTS: dict[str, str] = {
70
+ "/components/": "style_change",
71
+ "/styles/": "style_change",
72
+ "/css/": "style_change",
73
+ "theme": "style_change",
74
+ "tailwind": "style_change",
75
+ "/api/": "api_change",
76
+ "/routes/": "api_change",
77
+ "/endpoints/": "api_change",
78
+ "/migrations/": "database_change",
79
+ ".sql": "database_change",
80
+ "/models/": "database_change",
81
+ "/tests/": "test_writing",
82
+ "test_": "test_writing",
83
+ ".test.": "test_writing",
84
+ ".spec.": "test_writing",
85
+ "dockerfile": "config_change",
86
+ ".env": "config_change",
87
+ "config": "config_change",
88
+ }
89
+
90
+
91
+ @dataclass(slots=True)
92
+ class Categorization:
93
+ category: str
94
+ score: float
95
+ matched_keywords: list[str] = field(default_factory=list)
96
+ path_hint: str | None = None
97
+
98
+
99
+ class TaskCategorizer:
100
+ """Score-based categorizer. No external dependencies."""
101
+
102
+ def __init__(
103
+ self,
104
+ keywords: dict[str, list[str]] | None = None,
105
+ path_hints: dict[str, str] | None = None,
106
+ ):
107
+ self.keywords = keywords or CATEGORY_KEYWORDS
108
+ self.path_hints = path_hints or PATH_HINTS
109
+
110
+ def categorize(self, prompt: str, file_path: str | None = None) -> Categorization:
111
+ if not prompt and not file_path:
112
+ return Categorization("general", 0.0)
113
+
114
+ lower_prompt = (prompt or "").lower()
115
+ scores: dict[str, float] = {k: 0.0 for k in self.keywords}
116
+ matched: dict[str, list[str]] = {k: [] for k in self.keywords}
117
+
118
+ for category, kws in self.keywords.items():
119
+ for kw in kws:
120
+ if kw in lower_prompt:
121
+ scores[category] += 1.0
122
+ matched[category].append(kw)
123
+
124
+ hint_category: str | None = None
125
+ if file_path:
126
+ lower_path = file_path.lower()
127
+ for substr, cat in self.path_hints.items():
128
+ if substr in lower_path:
129
+ scores[cat] = scores.get(cat, 0.0) + 0.5
130
+ hint_category = cat
131
+ break
132
+
133
+ best = max(scores.items(), key=lambda kv: kv[1])
134
+ if best[1] == 0:
135
+ return Categorization("general", 0.0, path_hint=hint_category)
136
+ return Categorization(
137
+ category=best[0],
138
+ score=best[1],
139
+ matched_keywords=matched[best[0]],
140
+ path_hint=hint_category,
141
+ )