codegraph-brain 0.23.2__py3-none-any.whl → 0.23.4__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.
- cgis/api/mcp_server.py +91 -21
- cgis/extractors/python_extractor.py +48 -33
- cgis/storage/sqlite_store.py +18 -10
- {codegraph_brain-0.23.2.dist-info → codegraph_brain-0.23.4.dist-info}/METADATA +1 -1
- {codegraph_brain-0.23.2.dist-info → codegraph_brain-0.23.4.dist-info}/RECORD +8 -8
- {codegraph_brain-0.23.2.dist-info → codegraph_brain-0.23.4.dist-info}/WHEEL +0 -0
- {codegraph_brain-0.23.2.dist-info → codegraph_brain-0.23.4.dist-info}/entry_points.txt +0 -0
- {codegraph_brain-0.23.2.dist-info → codegraph_brain-0.23.4.dist-info}/licenses/LICENSE +0 -0
cgis/api/mcp_server.py
CHANGED
|
@@ -17,7 +17,7 @@ from pydantic import Field
|
|
|
17
17
|
from cgis import __version__
|
|
18
18
|
from cgis.core.coverage import TraversalCoverage
|
|
19
19
|
from cgis.core.freshness import Freshness, FreshnessState
|
|
20
|
-
from cgis.core.models import Edge, Node, NodeType
|
|
20
|
+
from cgis.core.models import Edge, EdgeType, Node, NodeType
|
|
21
21
|
from cgis.extractors.python_extractor import PythonExtractor
|
|
22
22
|
from cgis.extractors.typescript_extractor import TypeScriptExtractor
|
|
23
23
|
from cgis.pipeline import IngestionPipeline
|
|
@@ -28,7 +28,7 @@ from cgis.query.context.orphans import find_orphan_classes
|
|
|
28
28
|
from cgis.query.drift.drift_service import analyze_drift
|
|
29
29
|
from cgis.query.drift.fractal import analyze_fractal_db
|
|
30
30
|
from cgis.query.drift.ontology_init import propose_ontology
|
|
31
|
-
from cgis.query.engine import QueryEngine
|
|
31
|
+
from cgis.query.engine import BEHAVIORAL_EDGE_TYPES, QueryEngine
|
|
32
32
|
from cgis.query.fqn import resolve_fqn
|
|
33
33
|
from cgis.query.render.graph_json import graph_to_json
|
|
34
34
|
from cgis.query.render.mermaid import MermaidCompiler
|
|
@@ -65,6 +65,31 @@ Fqn = Annotated[
|
|
|
65
65
|
"to look a name up."
|
|
66
66
|
),
|
|
67
67
|
]
|
|
68
|
+
IncludeStructure = Annotated[
|
|
69
|
+
bool,
|
|
70
|
+
Field(
|
|
71
|
+
description="Also follow containment (CONTAINS/DECLARES): a module's or class's own "
|
|
72
|
+
"members, and the class or file enclosing a symbol. Off by default, as in the CLI; "
|
|
73
|
+
"cgis_get_structure is the tool for members alone."
|
|
74
|
+
),
|
|
75
|
+
]
|
|
76
|
+
IncludeExternal = Annotated[
|
|
77
|
+
bool,
|
|
78
|
+
Field(
|
|
79
|
+
description="Also return stdlib, third-party and unresolved call targets — calls on "
|
|
80
|
+
"values whose type is decided at runtime. Off by default, as in the CLI, because they "
|
|
81
|
+
"dominate the payload; in json, coverage/top_unresolved still counts what was dropped."
|
|
82
|
+
),
|
|
83
|
+
]
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def _traversal_filters(
|
|
87
|
+
include_structure: bool, include_external: bool
|
|
88
|
+
) -> tuple[frozenset[EdgeType] | None, bool]:
|
|
89
|
+
"""Edge-type allowlist and external flag for trace/impact — the CLI's defaults (#481)."""
|
|
90
|
+
return (None if include_structure else BEHAVIORAL_EDGE_TYPES), include_external
|
|
91
|
+
|
|
92
|
+
|
|
68
93
|
OutputFormat = Annotated[
|
|
69
94
|
str,
|
|
70
95
|
Field(
|
|
@@ -363,14 +388,26 @@ def cgis_trace_flow(
|
|
|
363
388
|
depth: Annotated[
|
|
364
389
|
int,
|
|
365
390
|
Field(
|
|
366
|
-
description="Maximum edge hops downstream
|
|
367
|
-
"
|
|
368
|
-
"hops are mostly imports and structure."
|
|
391
|
+
description="Maximum edge hops downstream, over calls, imports, inheritance, DI "
|
|
392
|
+
"dependencies and references (plus containment with include_structure)."
|
|
369
393
|
),
|
|
370
394
|
] = 3,
|
|
371
395
|
output_format: OutputFormat = "mermaid",
|
|
396
|
+
include_structure: IncludeStructure = False,
|
|
397
|
+
include_external: IncludeExternal = False,
|
|
372
398
|
) -> str:
|
|
373
|
-
"""
|
|
399
|
+
"""Downstream subgraph of one FQN: everything it reaches within ``depth`` hops.
|
|
400
|
+
|
|
401
|
+
Follows every edge except containment — in practice calls, imports,
|
|
402
|
+
inheritance, DI dependencies and references — between internal code, so this
|
|
403
|
+
answers "what does X depend on?". Containment and
|
|
404
|
+
stdlib/third-party nodes are left out unless ``include_structure`` /
|
|
405
|
+
``include_external`` ask for them (external covers stdlib, third-party and
|
|
406
|
+
unresolved call targets) — the same view as the CLI's ``trace``.
|
|
407
|
+
For what depends on X use
|
|
408
|
+
``cgis_analyze_impact``; for only the members of a module or class,
|
|
409
|
+
``cgis_get_structure``; for a source-included brief to read before editing
|
|
410
|
+
one symbol, ``cgis_context``.
|
|
374
411
|
|
|
375
412
|
``output_format="mermaid"`` (default) returns a human-readable diagram;
|
|
376
413
|
``"json"`` returns a joinable ``{root, nodes, edges, coverage}`` payload
|
|
@@ -390,8 +427,13 @@ def cgis_trace_flow(
|
|
|
390
427
|
res = resolve_fqn(store, fqn)
|
|
391
428
|
if res.resolved is None:
|
|
392
429
|
return _resolution_error(fqn, res.candidates, res.truncated)
|
|
430
|
+
allowed, show_external = _traversal_filters(include_structure, include_external)
|
|
393
431
|
result = QueryEngine(store).get_flow_result(
|
|
394
|
-
res.resolved,
|
|
432
|
+
res.resolved,
|
|
433
|
+
max_depth=depth,
|
|
434
|
+
allowed_edge_types=allowed,
|
|
435
|
+
show_external=show_external,
|
|
436
|
+
with_coverage=_wants_json(output_format),
|
|
395
437
|
)
|
|
396
438
|
except Exception as exc:
|
|
397
439
|
return f"❌ {exc}"
|
|
@@ -416,16 +458,28 @@ def cgis_analyze_impact(
|
|
|
416
458
|
depth: Annotated[
|
|
417
459
|
int,
|
|
418
460
|
Field(
|
|
419
|
-
description="Maximum edge hops upstream
|
|
420
|
-
"
|
|
421
|
-
"
|
|
461
|
+
description="Maximum edge hops upstream, over callers, importers, subclasses, "
|
|
462
|
+
"type references and DI dependents (plus the enclosing class or file with "
|
|
463
|
+
"include_structure)."
|
|
422
464
|
),
|
|
423
465
|
] = 3,
|
|
424
466
|
output_format: OutputFormat = "mermaid",
|
|
467
|
+
include_structure: IncludeStructure = False,
|
|
468
|
+
include_external: IncludeExternal = False,
|
|
425
469
|
) -> str:
|
|
426
|
-
"""
|
|
427
|
-
|
|
428
|
-
|
|
470
|
+
"""Upstream subgraph of one FQN: everything that reaches it within ``depth`` hops.
|
|
471
|
+
|
|
472
|
+
Follows every edge except containment — in practice callers, importers,
|
|
473
|
+
subclasses, type references and DI dependents — within internal code, so this
|
|
474
|
+
answers "what breaks if I change X?". The
|
|
475
|
+
enclosing class or file and stdlib/third-party nodes are left out unless
|
|
476
|
+
``include_structure`` / ``include_external`` ask for them — the same view as
|
|
477
|
+
the CLI's ``impact``. For what X depends on use
|
|
478
|
+
``cgis_trace_flow``; for only the members of a module or class,
|
|
479
|
+
``cgis_get_structure``; for a source-included brief to read before editing
|
|
480
|
+
one symbol, ``cgis_context``.
|
|
481
|
+
|
|
482
|
+
``output_format="mermaid"`` (default)
|
|
429
483
|
returns a diagram; ``"json"`` returns a joinable ``{root, nodes, edges,
|
|
430
484
|
coverage}`` payload with real FQNs — letting an agent compute set
|
|
431
485
|
differences (e.g. "which route handlers never reach ``verify_ownership``?")
|
|
@@ -443,8 +497,13 @@ def cgis_analyze_impact(
|
|
|
443
497
|
res = resolve_fqn(store, fqn)
|
|
444
498
|
if res.resolved is None:
|
|
445
499
|
return _resolution_error(fqn, res.candidates, res.truncated)
|
|
500
|
+
allowed, show_external = _traversal_filters(include_structure, include_external)
|
|
446
501
|
result = QueryEngine(store).get_impact_result(
|
|
447
|
-
res.resolved,
|
|
502
|
+
res.resolved,
|
|
503
|
+
max_depth=depth,
|
|
504
|
+
allowed_edge_types=allowed,
|
|
505
|
+
show_external=show_external,
|
|
506
|
+
with_coverage=_wants_json(output_format),
|
|
448
507
|
)
|
|
449
508
|
except Exception as exc:
|
|
450
509
|
return f"❌ {exc}"
|
|
@@ -471,10 +530,13 @@ def cgis_get_structure(
|
|
|
471
530
|
] = 2,
|
|
472
531
|
output_format: OutputFormat = "mermaid",
|
|
473
532
|
) -> str:
|
|
474
|
-
"""
|
|
533
|
+
"""Members of a module or class: the classes, functions and methods it contains.
|
|
534
|
+
|
|
535
|
+
Follows containment (CONTAINS/DECLARES) only, so no call or import appears.
|
|
536
|
+
For how the code connects use ``cgis_trace_flow`` (what it depends on) or
|
|
537
|
+
``cgis_analyze_impact`` (what depends on it).
|
|
475
538
|
|
|
476
|
-
|
|
477
|
-
``structure`` command. ``output_format="mermaid"`` (default) returns a
|
|
539
|
+
Matches the CLI ``structure`` command. ``output_format="mermaid"`` (default) returns a
|
|
478
540
|
diagram of the hierarchy rooted at the given FQN; ``"json"`` returns the
|
|
479
541
|
joinable ``{root, nodes, edges}`` payload with real FQNs.
|
|
480
542
|
"""
|
|
@@ -785,7 +847,15 @@ def cgis_context(
|
|
|
785
847
|
),
|
|
786
848
|
] = "",
|
|
787
849
|
) -> str:
|
|
788
|
-
"""
|
|
850
|
+
"""Prompt-ready brief on one FQN: its source, class, direct callers and callees.
|
|
851
|
+
|
|
852
|
+
Call this before editing a symbol, instead of reading its files. It follows
|
|
853
|
+
calls only, one hop by default. Source is included when the file is found
|
|
854
|
+
(see ``source_root``), and the domain when the graph was tagged with one.
|
|
855
|
+
For a multi-hop subgraph
|
|
856
|
+
over calls, imports, inheritance and references without source, use
|
|
857
|
+
``cgis_trace_flow`` (downstream) or
|
|
858
|
+
``cgis_analyze_impact`` (upstream).
|
|
789
859
|
|
|
790
860
|
Returns an XML-tagged prompt — the focal node's source, its enclosing class,
|
|
791
861
|
its architectural domain boundary, direct callers (upstream ripple) and
|
|
@@ -836,7 +906,7 @@ def cgis_metrics(
|
|
|
836
906
|
),
|
|
837
907
|
] = None,
|
|
838
908
|
) -> str:
|
|
839
|
-
"""Whole-graph architectural metrics — coupling bottlenecks
|
|
909
|
+
"""Whole-graph architectural metrics — coupling bottlenecks, God classes, PageRank.
|
|
840
910
|
|
|
841
911
|
Returns JSON ``{bottlenecks, god_classes, critical}`` computed with vectorized
|
|
842
912
|
DuckDB aggregations over the whole graph (fan-in/fan-out coupling,
|
|
@@ -894,7 +964,7 @@ def cgis_find_orphans(
|
|
|
894
964
|
bool, Field(description="Include machine-generated classes, which are hidden by default.")
|
|
895
965
|
] = False,
|
|
896
966
|
) -> str:
|
|
897
|
-
"""Classes nothing in production builds, extends or names — dead-code candidates
|
|
967
|
+
"""Classes nothing in production builds, extends or names — dead-code candidates.
|
|
898
968
|
|
|
899
969
|
Finds classes that no test, type checker or linter flags, because each is
|
|
900
970
|
still imported somewhere: a package re-export keeps a class importable long
|
|
@@ -976,7 +1046,7 @@ def cgis_audit_reachability(
|
|
|
976
1046
|
Field(description="Maximum reachability depth; a longer path is reported as a gap."),
|
|
977
1047
|
] = 5,
|
|
978
1048
|
) -> str:
|
|
979
|
-
"""Reachability/authorization audit — which sources never reach a checkpoint
|
|
1049
|
+
"""Reachability/authorization audit — which sources never reach a checkpoint.
|
|
980
1050
|
|
|
981
1051
|
The headline use is **IDOR/authz coverage**: list every route handler that does
|
|
982
1052
|
NOT transitively reach an ownership check. Reachability follows behavioral edges
|
|
@@ -76,7 +76,10 @@ def _identifiers_outside_imports(root: BaseNode, code_bytes: bytes) -> set[str]:
|
|
|
76
76
|
# strings (parent `type`): scanning every string would let a docstring
|
|
77
77
|
# mentioning a name mask a real re-export.
|
|
78
78
|
text = code_bytes[node.start_byte : node.end_byte].decode("utf8")
|
|
79
|
-
|
|
79
|
+
# `\w`, so a non-ASCII identifier in a quoted annotation counts as a
|
|
80
|
+
# use. Matching more here can only mark an import used, which is the
|
|
81
|
+
# safe direction for the unused-import sweep this feeds.
|
|
82
|
+
used.update(re.findall(r"[^\W\d]\w*", text))
|
|
80
83
|
stack.extend(node.children)
|
|
81
84
|
return used
|
|
82
85
|
|
|
@@ -197,6 +200,47 @@ def _collect_local_type(
|
|
|
197
200
|
)
|
|
198
201
|
|
|
199
202
|
|
|
203
|
+
def _walk_one_decorator(
|
|
204
|
+
functions: FunctionHandler,
|
|
205
|
+
decorator: BaseNode,
|
|
206
|
+
code_bytes: bytes,
|
|
207
|
+
file_path: str,
|
|
208
|
+
edges: list[Edge],
|
|
209
|
+
owner_fqn: str,
|
|
210
|
+
name_refs_acc: list[tuple[str, str, int]] | None,
|
|
211
|
+
) -> None:
|
|
212
|
+
"""Record one decorator's calls and names, skipping its own head (#429).
|
|
213
|
+
|
|
214
|
+
Everything except the decorator's own head name, which
|
|
215
|
+
`process_function_node` already records as `raw_call:<name>` from its
|
|
216
|
+
decorator list — walking that too emitted `router.post` twice under two
|
|
217
|
+
ids, and its name a third time as a REFERENCES.
|
|
218
|
+
|
|
219
|
+
Skipping the *head* rather than "everything but the outermost call's
|
|
220
|
+
arguments" is what keeps the rarer shapes: `@a.b(X)(Y)`, `@registry[X]`
|
|
221
|
+
and `@(deco(X))` all name something the narrower rule walked straight past.
|
|
222
|
+
"""
|
|
223
|
+
head = _decorator_head(decorator)
|
|
224
|
+
stack = [c for c in decorator.children if c.type not in ("comment", "@")]
|
|
225
|
+
while stack:
|
|
226
|
+
current = stack.pop()
|
|
227
|
+
if head is not None and current.id == head.id:
|
|
228
|
+
continue
|
|
229
|
+
if current.type == "call" and _calls_directly(current, head):
|
|
230
|
+
# `@router.post(...)` — the decorator list already recorded this
|
|
231
|
+
# exact call as `raw_call:router.post`. Its arguments still need
|
|
232
|
+
# walking, so recurse without processing it.
|
|
233
|
+
stack.extend(current.children)
|
|
234
|
+
continue
|
|
235
|
+
if current.type == "call":
|
|
236
|
+
functions.process_call_node(
|
|
237
|
+
current, code_bytes, file_path, owner_fqn, edges, emit_di=False
|
|
238
|
+
)
|
|
239
|
+
elif current.type == "identifier" and name_refs_acc is not None and is_name_load(current):
|
|
240
|
+
_append_name_candidates(current, code_bytes, owner_fqn, name_refs_acc)
|
|
241
|
+
stack.extend(current.children)
|
|
242
|
+
|
|
243
|
+
|
|
200
244
|
class PythonExtractor(BaseExtractor):
|
|
201
245
|
"""
|
|
202
246
|
A concrete extractor for Python source code using tree-sitter.
|
|
@@ -589,38 +633,9 @@ class PythonExtractor(BaseExtractor):
|
|
|
589
633
|
else `_walk` would have handled here.
|
|
590
634
|
"""
|
|
591
635
|
for decorator in (c for c in node.children if c.type == "decorator"):
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
# under two ids, and its name a third time as a REFERENCES.
|
|
596
|
-
#
|
|
597
|
-
# Skipping the *head* rather than "everything but the outermost
|
|
598
|
-
# call's arguments" is what keeps the rarer shapes: `@a.b(X)(Y)`,
|
|
599
|
-
# `@registry[X]` and `@(deco(X))` all name something the narrower
|
|
600
|
-
# rule walked straight past.
|
|
601
|
-
head = _decorator_head(decorator)
|
|
602
|
-
stack = [c for c in decorator.children if c.type not in ("comment", "@")]
|
|
603
|
-
while stack:
|
|
604
|
-
current = stack.pop()
|
|
605
|
-
if head is not None and current.id == head.id:
|
|
606
|
-
continue
|
|
607
|
-
if current.type == "call" and _calls_directly(current, head):
|
|
608
|
-
# `@router.post(...)` — the decorator list already recorded
|
|
609
|
-
# this exact call as `raw_call:router.post`. Its arguments
|
|
610
|
-
# still need walking, so recurse without processing it.
|
|
611
|
-
stack.extend(current.children)
|
|
612
|
-
continue
|
|
613
|
-
if current.type == "call":
|
|
614
|
-
self._functions.process_call_node(
|
|
615
|
-
current, code_bytes, file_path, owner_fqn, edges, emit_di=False
|
|
616
|
-
)
|
|
617
|
-
elif (
|
|
618
|
-
current.type == "identifier"
|
|
619
|
-
and name_refs_acc is not None
|
|
620
|
-
and is_name_load(current)
|
|
621
|
-
):
|
|
622
|
-
_append_name_candidates(current, code_bytes, owner_fqn, name_refs_acc)
|
|
623
|
-
stack.extend(current.children)
|
|
636
|
+
_walk_one_decorator(
|
|
637
|
+
self._functions, decorator, code_bytes, file_path, edges, owner_fqn, name_refs_acc
|
|
638
|
+
)
|
|
624
639
|
|
|
625
640
|
def _handle_decorated_definition(
|
|
626
641
|
self,
|
cgis/storage/sqlite_store.py
CHANGED
|
@@ -779,14 +779,25 @@ class SQLiteStore:
|
|
|
779
779
|
reason=f"ingest root {base} no longer exists — {hint}",
|
|
780
780
|
)
|
|
781
781
|
|
|
782
|
-
|
|
782
|
+
changed, missing = self._count_stale(base, self.get_tracked_source_files(), ingested_at)
|
|
783
|
+
if changed or missing:
|
|
784
|
+
return Freshness(state=FreshnessState.STALE, changed=changed, missing=missing)
|
|
785
|
+
return Freshness(state=FreshnessState.FRESH)
|
|
786
|
+
|
|
787
|
+
def _count_stale(self, base: str, tracked: set[str], ingested_at: float) -> tuple[int, int]:
|
|
788
|
+
"""Files newer than the ingest, and files the graph has that the tree no longer does.
|
|
789
|
+
|
|
790
|
+
The two halves are complementary: a file's own mtime catches an edit, and
|
|
791
|
+
its directory's mtime catches an addition, a deletion or a new subdirectory.
|
|
792
|
+
|
|
793
|
+
`os.stat` on joined strings, not pathlib — the PTH rules are suppressed
|
|
794
|
+
deliberately here. Measured on this repository's own graph: the same 811
|
|
795
|
+
files cost 3.7 ms this way and 18.8 ms through `Path.stat()`, which is
|
|
796
|
+
slower than the tree walk this design exists to avoid. Tidying these to
|
|
797
|
+
`Path` would triple a cost paid on every query.
|
|
798
|
+
"""
|
|
783
799
|
changed = 0
|
|
784
800
|
missing = 0
|
|
785
|
-
# `os.stat` on joined strings, not pathlib — the PTH rules are suppressed
|
|
786
|
-
# deliberately here. Measured on this repository's own graph: the same 811
|
|
787
|
-
# files cost 3.7 ms this way and 18.8 ms through `Path.stat()`, which is
|
|
788
|
-
# slower than the tree walk this design exists to avoid. Tidying these to
|
|
789
|
-
# `Path` would triple a cost paid on every query.
|
|
790
801
|
for rel in tracked:
|
|
791
802
|
try:
|
|
792
803
|
if os.stat(os.path.join(base, rel)).st_mtime > ingested_at: # noqa: PTH116,PTH118
|
|
@@ -803,10 +814,7 @@ class SQLiteStore:
|
|
|
803
814
|
# Nothing added: the report says "N missing" of *files*, and every
|
|
804
815
|
# file under a vanished directory has already been counted above.
|
|
805
816
|
continue
|
|
806
|
-
|
|
807
|
-
if changed or missing:
|
|
808
|
-
return Freshness(state=FreshnessState.STALE, changed=changed, missing=missing)
|
|
809
|
-
return Freshness(state=FreshnessState.FRESH)
|
|
817
|
+
return changed, missing
|
|
810
818
|
|
|
811
819
|
def _directory_gained_a_source(
|
|
812
820
|
self, path: str, tracked: set[str], base: str, ingested_at: float
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: codegraph-brain
|
|
3
|
-
Version: 0.23.
|
|
3
|
+
Version: 0.23.4
|
|
4
4
|
Summary: Semantic code graph for AI agents — deterministic FQN resolution, impact analysis and architectural drift gates, exposed over MCP.
|
|
5
5
|
Project-URL: Homepage, https://github.com/zaebee/codegraph-brain
|
|
6
6
|
Project-URL: Repository, https://github.com/zaebee/codegraph-brain
|
|
@@ -5,7 +5,7 @@ cgis/pipeline.py,sha256=c-z6MJb9H06hWZQfvVwGQL2PUN3k0-Am-PCAHfMK0nQ,17048
|
|
|
5
5
|
cgis/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
6
|
cgis/api/.gitkeep,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
7
7
|
cgis/api/__init__.py,sha256=wvFZK6oZspFGmonBz2rDg1aXxK7DHuE87or_w_cwY28,91
|
|
8
|
-
cgis/api/mcp_server.py,sha256=
|
|
8
|
+
cgis/api/mcp_server.py,sha256=b3HiTphKD1UcmKP1XwsawTrRLkvAAPRZLACxy1z1X8Y,47917
|
|
9
9
|
cgis/core/.gitkeep,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10
10
|
cgis/core/coverage.py,sha256=AmeZ_mij5Q382MAqtUmDRmJ_lHLPsV73k0_zksaWc6c,2469
|
|
11
11
|
cgis/core/freshness.py,sha256=s1ahMqizX5jRo5Sj6T-2YfNq1d-jsRqisfne5m4yagw,1395
|
|
@@ -22,7 +22,7 @@ cgis/extractors/_python_imports.py,sha256=qvrO6sUG0O9O4k_P0TzibEu0dPwciW_A25CREy
|
|
|
22
22
|
cgis/extractors/_python_types.py,sha256=N6xIOxVikpwkwrPfv1s_MwX6rw8QwzW2VeBXi7-g328,3462
|
|
23
23
|
cgis/extractors/_typescript_bindings.py,sha256=_G7rN30LVMTeNBuEHY9LeLOM6PZV3J_2qYp42PRNDcg,6099
|
|
24
24
|
cgis/extractors/base.py,sha256=4lhdFRqsj-3vBpeHZjnE3f9IWZ_WhbKQBxVAMuhzTho,1502
|
|
25
|
-
cgis/extractors/python_extractor.py,sha256=
|
|
25
|
+
cgis/extractors/python_extractor.py,sha256=U6MegkLa8rt33DGiv_4rNgNWYEocTqbv5hQ1lctOCb0,29884
|
|
26
26
|
cgis/extractors/registry.py,sha256=SUZmkx34gfrCUa1cT09lWrT_Ngk1OK4fTMm4XJhwFWM,4078
|
|
27
27
|
cgis/extractors/typescript_extractor.py,sha256=fs8l-KsyY35KnnsbWp9c5D_xeWdWRaCSLR_3N_S2ORA,11879
|
|
28
28
|
cgis/guardian/__init__.py,sha256=H6BlKTayCLP34uGRC1zVt9NhN7RGo3tN9oep9Ja5SK0,48
|
|
@@ -86,9 +86,9 @@ cgis/resolver/js_builtins.py,sha256=cZ0F6DyqmPWVGHMgh0PVAv1VqGHO3IHs65cK9sX57CQ,
|
|
|
86
86
|
cgis/resolver/symbols.py,sha256=A88dOb7ciEfWaS4KCK0Ho4cBC2IZisNrBfYp-f1LFYs,12545
|
|
87
87
|
cgis/resolver/uplift.py,sha256=Hkye1q-kI-gKO6GIBYv3gUZj1AC0-_mkpoIpmwVsG4g,9591
|
|
88
88
|
cgis/storage/.gitkeep,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
89
|
-
cgis/storage/sqlite_store.py,sha256=
|
|
90
|
-
codegraph_brain-0.23.
|
|
91
|
-
codegraph_brain-0.23.
|
|
92
|
-
codegraph_brain-0.23.
|
|
93
|
-
codegraph_brain-0.23.
|
|
94
|
-
codegraph_brain-0.23.
|
|
89
|
+
cgis/storage/sqlite_store.py,sha256=AXPlL1RGs38DmpIXuzrBY3JOavpSJDbwP5jorwAlD1c,46112
|
|
90
|
+
codegraph_brain-0.23.4.dist-info/METADATA,sha256=kyI_tand59eW6i0ggOa3KEBMDiagLy07Z5LtdntTjn4,11771
|
|
91
|
+
codegraph_brain-0.23.4.dist-info/WHEEL,sha256=zOwg4jB6zX2kU910N-cMawjivD6tO8NEWvE12je1bVk,87
|
|
92
|
+
codegraph_brain-0.23.4.dist-info/entry_points.txt,sha256=mWajEQlAoWuiLyCQdD1TvvguloKQFmzKb52-g9PB_R4,123
|
|
93
|
+
codegraph_brain-0.23.4.dist-info/licenses/LICENSE,sha256=1X36nOG5VocDaEGzAZqIv7uawy_7sWlFoiwECwx5aBI,1065
|
|
94
|
+
codegraph_brain-0.23.4.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|