codebeacon 0.1.2__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.
Files changed (59) hide show
  1. codebeacon/__init__.py +1 -0
  2. codebeacon/__main__.py +3 -0
  3. codebeacon/cache.py +136 -0
  4. codebeacon/cli.py +391 -0
  5. codebeacon/common/__init__.py +0 -0
  6. codebeacon/common/filters.py +170 -0
  7. codebeacon/common/symbols.py +121 -0
  8. codebeacon/common/types.py +98 -0
  9. codebeacon/config.py +144 -0
  10. codebeacon/contextmap/__init__.py +0 -0
  11. codebeacon/contextmap/generator.py +602 -0
  12. codebeacon/discover/__init__.py +0 -0
  13. codebeacon/discover/detector.py +388 -0
  14. codebeacon/discover/scanner.py +192 -0
  15. codebeacon/export/__init__.py +0 -0
  16. codebeacon/export/mcp.py +515 -0
  17. codebeacon/export/obsidian.py +812 -0
  18. codebeacon/extract/__init__.py +22 -0
  19. codebeacon/extract/base.py +372 -0
  20. codebeacon/extract/components.py +357 -0
  21. codebeacon/extract/dependencies.py +140 -0
  22. codebeacon/extract/entities.py +575 -0
  23. codebeacon/extract/queries/README.md +116 -0
  24. codebeacon/extract/queries/actix.scm +115 -0
  25. codebeacon/extract/queries/angular.scm +155 -0
  26. codebeacon/extract/queries/aspnet.scm +159 -0
  27. codebeacon/extract/queries/django.scm +122 -0
  28. codebeacon/extract/queries/express.scm +124 -0
  29. codebeacon/extract/queries/fastapi.scm +152 -0
  30. codebeacon/extract/queries/flask.scm +120 -0
  31. codebeacon/extract/queries/gin.scm +142 -0
  32. codebeacon/extract/queries/ktor.scm +144 -0
  33. codebeacon/extract/queries/laravel.scm +172 -0
  34. codebeacon/extract/queries/nestjs.scm +183 -0
  35. codebeacon/extract/queries/rails.scm +114 -0
  36. codebeacon/extract/queries/react.scm +111 -0
  37. codebeacon/extract/queries/spring_boot.scm +204 -0
  38. codebeacon/extract/queries/svelte.scm +73 -0
  39. codebeacon/extract/queries/vapor.scm +130 -0
  40. codebeacon/extract/queries/vue.scm +123 -0
  41. codebeacon/extract/routes.py +910 -0
  42. codebeacon/extract/semantic.py +280 -0
  43. codebeacon/extract/services.py +597 -0
  44. codebeacon/graph/__init__.py +1 -0
  45. codebeacon/graph/analyze.py +281 -0
  46. codebeacon/graph/build.py +320 -0
  47. codebeacon/graph/cluster.py +160 -0
  48. codebeacon/graph/enrich.py +206 -0
  49. codebeacon/skill/SKILL.md +127 -0
  50. codebeacon/wave.py +292 -0
  51. codebeacon/wiki/__init__.py +0 -0
  52. codebeacon/wiki/generator.py +376 -0
  53. codebeacon/wiki/index.py +95 -0
  54. codebeacon/wiki/templates.py +467 -0
  55. codebeacon-0.1.2.dist-info/METADATA +319 -0
  56. codebeacon-0.1.2.dist-info/RECORD +59 -0
  57. codebeacon-0.1.2.dist-info/WHEEL +4 -0
  58. codebeacon-0.1.2.dist-info/entry_points.txt +2 -0
  59. codebeacon-0.1.2.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,152 @@
1
+ ; ── FastAPI (Python) ──────────────────────────────────────────────────────────
2
+ ; Grammar: tree-sitter-python
3
+ ;
4
+ ; Captures:
5
+ ; @route.decorator - @app.get / @router.post etc. decorator node
6
+ ; @route.object - app/router object name
7
+ ; @route.method - HTTP method (get/post/put/delete/patch)
8
+ ; @route.path - path string
9
+ ; @route.func_name - handler function name
10
+ ; @route.prefix - APIRouter(prefix="...") value
11
+ ; @service.func_name - Depends() dependency function name
12
+ ; @service.class_name - class with methods using Depends
13
+ ; @entity.class_name - BaseModel / SQLAlchemy Base subclass
14
+ ; @entity.field_name - model field name
15
+ ; @entity.field_type - model field type annotation
16
+ ; @router.include - app.include_router(router, prefix="...")
17
+ ; @import.path - import path
18
+
19
+ ; ── @app.get("/path") / @router.post("/path") ────────────────────────────────
20
+
21
+ (decorated_definition
22
+ (decorator
23
+ (call
24
+ function: (attribute
25
+ object: (identifier) @route.object
26
+ attribute: (identifier) @route.method
27
+ (#match? @route.method "^(get|post|put|delete|patch|options|head)$")
28
+ )
29
+ arguments: (argument_list
30
+ (string) @route.path
31
+ )
32
+ )
33
+ )
34
+ definition: (function_definition
35
+ name: (identifier) @route.func_name
36
+ )
37
+ ) @route.handler
38
+
39
+ ; ── APIRouter(prefix="/api/v1") ───────────────────────────────────────────────
40
+
41
+ (assignment
42
+ left: (identifier) @route.router_name
43
+ right: (call
44
+ function: (identifier) @_apiRouter
45
+ (#eq? @_apiRouter "APIRouter")
46
+ arguments: (argument_list
47
+ (keyword_argument
48
+ name: (identifier) @_prefix_key
49
+ (#eq? @_prefix_key "prefix")
50
+ value: (string) @route.prefix
51
+ )
52
+ )
53
+ )
54
+ ) @route.router_decl
55
+
56
+ ; ── app.include_router(router, prefix="...") ─────────────────────────────────
57
+
58
+ ; With prefix keyword argument
59
+ (call
60
+ function: (attribute
61
+ object: (identifier) @_app
62
+ attribute: (identifier) @_include
63
+ (#eq? @_include "include_router")
64
+ )
65
+ arguments: (argument_list
66
+ (identifier) @router.include_router
67
+ (keyword_argument
68
+ name: (identifier) @_pk
69
+ (#eq? @_pk "prefix")
70
+ value: (string) @router.include_prefix
71
+ )
72
+ )
73
+ ) @router.include
74
+
75
+ ; Without prefix keyword argument
76
+ (call
77
+ function: (attribute
78
+ object: (identifier) @_app2
79
+ attribute: (identifier) @_include2
80
+ (#eq? @_include2 "include_router")
81
+ )
82
+ arguments: (argument_list
83
+ (identifier) @router.include_router
84
+ )
85
+ ) @router.include_no_prefix
86
+
87
+ ; ── Depends() function dependency ────────────────────────────────────────────
88
+
89
+ ; Functions that take parameters (potential service functions)
90
+ (function_definition
91
+ name: (identifier) @service.func_name
92
+ parameters: (parameters
93
+ (typed_parameter
94
+ (identifier) @_param
95
+ )
96
+ )
97
+ ) @service.function
98
+
99
+ ; Depends() in function signature
100
+ (call
101
+ function: (identifier) @_depends
102
+ (#eq? @_depends "Depends")
103
+ arguments: (argument_list
104
+ (identifier) @service.depends_func
105
+ )
106
+ ) @service.depends
107
+
108
+ ; ── BaseModel / SQLAlchemy subclass (entity) ─────────────────────────────────
109
+
110
+ ; Direct identifier base class: class User(BaseModel)
111
+ (class_definition
112
+ name: (identifier) @entity.class_name
113
+ superclasses: (argument_list
114
+ (identifier) @_base
115
+ (#match? @_base "^(BaseModel|Base|DeclarativeBase|SQLModel)$")
116
+ )
117
+ ) @entity.class
118
+
119
+ ; Attribute base class: class User(db.Model)
120
+ (class_definition
121
+ name: (identifier) @entity.class_name
122
+ superclasses: (argument_list
123
+ (attribute
124
+ attribute: (identifier) @_base
125
+ (#match? @_base "^(Model|Base)$")
126
+ )
127
+ )
128
+ ) @entity.class_attr
129
+
130
+ ; Entity fields (type-annotated class attributes)
131
+ (class_definition
132
+ body: (block
133
+ (expression_statement
134
+ (assignment
135
+ left: (identifier) @entity.field_name
136
+ type: (type
137
+ (identifier) @entity.field_type
138
+ )
139
+ )
140
+ )
141
+ )
142
+ ) @entity.with_fields
143
+
144
+ ; ── imports ───────────────────────────────────────────────────────────────────
145
+
146
+ (import_from_statement
147
+ module_name: _ @import.path
148
+ ) @import.from
149
+
150
+ (import_statement
151
+ name: _ @import.path
152
+ ) @import.plain
@@ -0,0 +1,120 @@
1
+ ; ── Flask (Python) ────────────────────────────────────────────────────────────
2
+ ; Grammar: tree-sitter-python
3
+ ;
4
+ ; Captures:
5
+ ; @route.decorator - @app.route / @bp.route decorator
6
+ ; @route.object - app/blueprint object name
7
+ ; @route.path - path string
8
+ ; @route.methods - methods list ["GET","POST"]
9
+ ; @route.func_name - handler function name
10
+ ; @blueprint.name - Blueprint variable name
11
+ ; @blueprint.url_prefix - url_prefix value
12
+ ; @blueprint.import_name - blueprint name string
13
+ ; @app.register_bp - app.register_blueprint(bp, url_prefix="...")
14
+ ; @app.register_prefix - url_prefix in register_blueprint
15
+ ; @entity.class_name - db.Model subclass name
16
+ ; @entity.field_name - field name
17
+ ; @entity.field_type - Column(...) type
18
+ ; @import.path - import path
19
+
20
+ ; ── @app.route("/path") / @blueprint.route("/path") ─────────────────────────
21
+
22
+ (decorated_definition
23
+ (decorator
24
+ (call
25
+ function: (attribute
26
+ object: (identifier) @route.object
27
+ attribute: (identifier) @_route_attr
28
+ (#eq? @_route_attr "route")
29
+ )
30
+ arguments: (argument_list
31
+ (string) @route.path
32
+ (keyword_argument
33
+ name: (identifier) @_methods_key
34
+ (#eq? @_methods_key "methods")
35
+ value: (list
36
+ (string) @route.methods
37
+ )
38
+ )?
39
+ )
40
+ )
41
+ )
42
+ definition: (function_definition
43
+ name: (identifier) @route.func_name
44
+ )
45
+ ) @route.handler
46
+
47
+ ; ── Blueprint declaration ─────────────────────────────────────────────────────
48
+
49
+ (assignment
50
+ left: (identifier) @blueprint.name
51
+ right: (call
52
+ function: (identifier) @_bp
53
+ (#eq? @_bp "Blueprint")
54
+ arguments: (argument_list
55
+ (string) @blueprint.import_name
56
+ _
57
+ (keyword_argument
58
+ name: (identifier) @_upk
59
+ (#eq? @_upk "url_prefix")
60
+ value: (string) @blueprint.url_prefix
61
+ )?
62
+ )
63
+ )
64
+ ) @blueprint.decl
65
+
66
+ ; ── app.register_blueprint(bp, url_prefix="/api") ────────────────────────────
67
+
68
+ (call
69
+ function: (attribute
70
+ object: (identifier) @_app
71
+ attribute: (identifier) @_reg
72
+ (#eq? @_reg "register_blueprint")
73
+ )
74
+ arguments: (argument_list
75
+ (identifier) @app.register_bp
76
+ (keyword_argument
77
+ name: (identifier) @_upk
78
+ (#eq? @_upk "url_prefix")
79
+ value: (string) @app.register_prefix
80
+ )?
81
+ )
82
+ ) @app.register
83
+
84
+ ; ── SQLAlchemy / Flask-SQLAlchemy model ───────────────────────────────────────
85
+
86
+ (class_definition
87
+ name: (identifier) @entity.class_name
88
+ superclasses: (argument_list
89
+ [
90
+ (attribute
91
+ attribute: (identifier) @_m
92
+ (#match? @_m "^(Model|Base)$")
93
+ )
94
+ (identifier) @_m
95
+ (#match? @_m "^(Model|Base)$")
96
+ ]
97
+ )
98
+ ) @entity.class
99
+
100
+ ; SQLAlchemy Column fields
101
+ (assignment
102
+ left: (identifier) @entity.field_name
103
+ right: (call
104
+ function: [
105
+ (identifier) @entity.field_type
106
+ (attribute attribute: (identifier) @entity.field_type)
107
+ ]
108
+ (#match? @entity.field_type "^(Column|relationship|backref)$")
109
+ )
110
+ ) @entity.field
111
+
112
+ ; ── imports ───────────────────────────────────────────────────────────────────
113
+
114
+ (import_from_statement
115
+ module_name: _ @import.path
116
+ ) @import.from
117
+
118
+ (import_statement
119
+ name: _ @import.path
120
+ ) @import.plain
@@ -0,0 +1,142 @@
1
+ ; ── Gin / Echo / Fiber (Go) ───────────────────────────────────────────────────
2
+ ; Grammar: tree-sitter-go
3
+ ;
4
+ ; Go struct tag parsing note:
5
+ ; GORM struct tags are raw string literals: `gorm:"primaryKey"`.
6
+ ; These are parsed by extract/entities.py using regex on the raw text,
7
+ ; not by tree-sitter queries (tree-sitter-go does not parse struct tags).
8
+ ;
9
+ ; Captures:
10
+ ; @route.method - GET/POST/PUT/DELETE/PATCH/Any etc.
11
+ ; @route.path - path string
12
+ ; @route.object - router/group variable name
13
+ ; @route.group_prefix - r.Group("/api") prefix string
14
+ ; @route.handler_name - handler function identifier
15
+ ; @service.struct_name - struct name (service)
16
+ ; @service.field_type - field type (for DI via struct embedding)
17
+ ; @entity.struct_name - GORM model struct name
18
+ ; @entity.field_name - struct field name
19
+ ; @entity.field_tag - raw struct tag string (for GORM parsing)
20
+ ; @import.path - import path string
21
+
22
+ ; ── r.GET("/path", handler) ──────────────────────────────────────────────────
23
+
24
+ (expression_statement
25
+ (call_expression
26
+ function: (selector_expression
27
+ operand: (identifier) @route.object
28
+ field: (field_identifier) @route.method
29
+ (#match? @route.method "^(GET|POST|PUT|PATCH|DELETE|OPTIONS|HEAD|Any|Handle|UseWithErr|Use)$")
30
+ )
31
+ arguments: (argument_list
32
+ (interpreted_string_literal) @route.path
33
+ (identifier) @route.handler_name
34
+ )
35
+ )
36
+ ) @route.call
37
+
38
+ ; Case-insensitive method names (Echo: e.GET, Fiber: app.Get)
39
+ (expression_statement
40
+ (call_expression
41
+ function: (selector_expression
42
+ operand: (identifier) @route.object
43
+ field: (field_identifier) @route.method
44
+ (#match? @route.method "^(Get|Post|Put|Patch|Delete|Options|Head|All|Add)$")
45
+ )
46
+ arguments: (argument_list
47
+ (interpreted_string_literal) @route.path
48
+ (identifier) @route.handler_name
49
+ )
50
+ )
51
+ ) @route.call_lower
52
+
53
+ ; ── r.Group("/prefix") ───────────────────────────────────────────────────────
54
+
55
+ (short_var_declaration
56
+ left: (expression_list
57
+ (identifier) @route.group_name
58
+ )
59
+ right: (expression_list
60
+ (call_expression
61
+ function: (selector_expression
62
+ operand: (identifier) @_router
63
+ field: (field_identifier) @_group
64
+ (#eq? @_group "Group")
65
+ )
66
+ arguments: (argument_list
67
+ (interpreted_string_literal) @route.group_prefix
68
+ )
69
+ )
70
+ )
71
+ ) @route.group_decl
72
+
73
+ ; ── Service struct ────────────────────────────────────────────────────────────
74
+
75
+ (type_declaration
76
+ (type_spec
77
+ name: (type_identifier) @service.struct_name
78
+ type: (struct_type
79
+ (field_declaration_list
80
+ (field_declaration
81
+ type: (pointer_type
82
+ (type_identifier) @service.field_type
83
+ )
84
+ )
85
+ )
86
+ )
87
+ )
88
+ ) @service.struct
89
+
90
+ (type_declaration
91
+ (type_spec
92
+ name: (type_identifier) @service.struct_name
93
+ type: (struct_type
94
+ (field_declaration_list
95
+ (field_declaration
96
+ type: (type_identifier) @service.field_type
97
+ )
98
+ )
99
+ )
100
+ )
101
+ ) @service.struct_plain
102
+
103
+ ; ── GORM entity struct ────────────────────────────────────────────────────────
104
+
105
+ (type_declaration
106
+ (type_spec
107
+ name: (type_identifier) @entity.struct_name
108
+ type: (struct_type
109
+ (field_declaration_list
110
+ (field_declaration
111
+ name: (field_identifier) @entity.field_name
112
+ type: _ @entity.field_type
113
+ tag: (raw_string_literal) @entity.field_tag
114
+ )
115
+ )
116
+ )
117
+ )
118
+ ) @entity.struct
119
+
120
+ ; Struct with no tags (still useful for type extraction)
121
+ (type_declaration
122
+ (type_spec
123
+ name: (type_identifier) @entity.struct_name
124
+ type: (struct_type)
125
+ )
126
+ ) @entity.struct_bare
127
+
128
+ ; ── imports ───────────────────────────────────────────────────────────────────
129
+
130
+ (import_declaration
131
+ (import_spec_list
132
+ (import_spec
133
+ path: (interpreted_string_literal) @import.path
134
+ )
135
+ )
136
+ ) @import.block
137
+
138
+ (import_declaration
139
+ (import_spec
140
+ path: (interpreted_string_literal) @import.path
141
+ )
142
+ ) @import.single
@@ -0,0 +1,144 @@
1
+ ; ── Ktor (Kotlin) ─────────────────────────────────────────────────────────────
2
+ ; Grammar: tree-sitter-kotlin
3
+ ;
4
+ ; Kotlin grammar note:
5
+ ; - call_expression: f(args) — can have trailing lambda
6
+ ; - annotated_lambda / lambda_literal: trailing { } block
7
+ ; - value_arguments: (args)
8
+ ; - value_argument → string_literal → string_content: path string
9
+ ; - identifier: function name (get, post, route, routing)
10
+ ; - qualified_identifier: import paths
11
+ ;
12
+ ; Ktor routing DSL nesting:
13
+ ; routing {
14
+ ; get("/a") { } → GET /a
15
+ ; route("/prefix") {
16
+ ; get("/b") { } → GET /prefix/b
17
+ ; }
18
+ ; }
19
+ ; Path composition is done by extract/routes.py by tracking nesting depth
20
+ ; using start_point line numbers. This file captures individual route/method calls.
21
+ ;
22
+ ; Captures:
23
+ ; @route.method - get/post/put/patch/delete (HTTP method)
24
+ ; @route.path - path string content
25
+ ; @route.route_prefix - route("prefix") path — prefix scope
26
+ ; @route.call_line - line number for nesting (via @route.call node)
27
+ ; @service.koin_type - Koin: single/factory/scoped class
28
+ ; @entity.table_name - Exposed Table object name
29
+ ; @entity.column_name - Exposed column name
30
+ ; @import.path - import qualified path
31
+
32
+ ; ── routing { get("/path") { } } ─────────────────────────────────────────────
33
+
34
+ ; Direct HTTP method call: get("/path") { }
35
+ (call_expression
36
+ (call_expression
37
+ (identifier) @route.method
38
+ (#match? @route.method "^(get|post|put|patch|delete|options|head)$")
39
+ (value_arguments
40
+ (value_argument
41
+ (string_literal
42
+ (string_content) @route.path
43
+ )
44
+ )
45
+ )
46
+ )
47
+ (annotated_lambda)?
48
+ ) @route.method_call
49
+
50
+ ; Also handle: get("/path") without trailing lambda
51
+ (call_expression
52
+ (identifier) @route.method
53
+ (#match? @route.method "^(get|post|put|patch|delete|options|head)$")
54
+ (value_arguments
55
+ (value_argument
56
+ (string_literal
57
+ (string_content) @route.path
58
+ )
59
+ )
60
+ )
61
+ ) @route.method_call_simple
62
+
63
+ ; ── route("/prefix") { } — creates a path prefix scope ───────────────────────
64
+
65
+ (call_expression
66
+ (call_expression
67
+ (identifier) @_route_fn
68
+ (#eq? @_route_fn "route")
69
+ (value_arguments
70
+ (value_argument
71
+ (string_literal
72
+ (string_content) @route.route_prefix
73
+ )
74
+ )
75
+ )
76
+ )
77
+ (annotated_lambda)
78
+ ) @route.prefix_scope
79
+
80
+ ; ── Koin DI: single { UserService(get()) } ───────────────────────────────────
81
+
82
+ (call_expression
83
+ (identifier) @_koin_scope
84
+ (#match? @_koin_scope "^(single|factory|scoped|viewModel|worker)$")
85
+ (annotated_lambda
86
+ (lambda_literal
87
+ (call_expression
88
+ (identifier) @service.koin_type
89
+ (value_arguments)?
90
+ )
91
+ )
92
+ )
93
+ ) @service.koin_binding
94
+
95
+ ; ── Exposed ORM: object Users : Table() ──────────────────────────────────────
96
+
97
+ (object_declaration
98
+ (identifier) @entity.table_name
99
+ (delegation_specifier
100
+ (constructor_invocation
101
+ (user_type (identifier) @_table (#match? @_table "^(Table|IntIdTable|LongIdTable|UUIDTable|IdTable)$"))
102
+ )
103
+ )
104
+ ) @entity.table
105
+
106
+ ; Exposed columns: val id = integer("id")
107
+ (property_declaration
108
+ (variable_declaration
109
+ (simple_identifier) @entity.column_name
110
+ )
111
+ (call_expression
112
+ (identifier) @entity.column_type
113
+ (#match? @entity.column_type "^(integer|long|varchar|text|bool|double|float|decimal|uuid|reference|optReference|enumeration|enumerationByName|date|datetime|timestamp)$")
114
+ (value_arguments
115
+ (value_argument
116
+ (string_literal
117
+ (string_content) @entity.column_key
118
+ )
119
+ )
120
+ )
121
+ )
122
+ ) @entity.column
123
+
124
+ ; ── Data class (Kotlin entity / DTO) ─────────────────────────────────────────
125
+
126
+ (class_declaration
127
+ (modifiers
128
+ (class_modifier) @_data
129
+ (#eq? @_data "data")
130
+ )
131
+ (simple_identifier) @entity.class_name
132
+ ) @entity.data_class
133
+
134
+ ; ── Regular class (service) ───────────────────────────────────────────────────
135
+
136
+ (class_declaration
137
+ (simple_identifier) @service.class_name
138
+ ) @service.class
139
+
140
+ ; ── imports ───────────────────────────────────────────────────────────────────
141
+
142
+ (import
143
+ (qualified_identifier) @import.path
144
+ ) @import.decl