adl-toolkit 0.0.0-stage → 0.1.1

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 (104) hide show
  1. package/INSTALL_TOOLKIT.md +163 -0
  2. package/README.md +269 -2
  3. package/adl_drift/__init__.py +6 -0
  4. package/adl_drift/cli/__init__.py +1 -0
  5. package/adl_drift/cli/commands.py +993 -0
  6. package/adl_drift/cli/main.py +744 -0
  7. package/adl_drift/cortex/__init__.py +1 -0
  8. package/adl_drift/cortex/embeddings.py +96 -0
  9. package/adl_drift/cortex/memory.py +1749 -0
  10. package/adl_drift/cortex/patterns.py +89 -0
  11. package/adl_drift/cortex/telemetry.py +192 -0
  12. package/adl_drift/detectors/__init__.py +1 -0
  13. package/adl_drift/detectors/async_patterns.py +115 -0
  14. package/adl_drift/detectors/base.py +121 -0
  15. package/adl_drift/detectors/config.py +122 -0
  16. package/adl_drift/detectors/data_access.py +128 -0
  17. package/adl_drift/detectors/decorators.py +122 -0
  18. package/adl_drift/detectors/dynamic_patterns.py +260 -0
  19. package/adl_drift/detectors/errors.py +134 -0
  20. package/adl_drift/detectors/imports.py +132 -0
  21. package/adl_drift/detectors/logging_patterns.py +108 -0
  22. package/adl_drift/detectors/routes.py +257 -0
  23. package/adl_drift/detectors/security.py +236 -0
  24. package/adl_drift/detectors/taint.py +406 -0
  25. package/adl_drift/detectors/tests.py +95 -0
  26. package/adl_drift/detectors/type_conventions.py +81 -0
  27. package/adl_drift/graph/__init__.py +1 -0
  28. package/adl_drift/graph/builder.py +2670 -0
  29. package/adl_drift/graph/cfg.py +461 -0
  30. package/adl_drift/graph/cluster.py +40 -0
  31. package/adl_drift/graph/edges.py +86 -0
  32. package/adl_drift/graph/node.py +90 -0
  33. package/adl_drift/harness/__init__.py +10 -0
  34. package/adl_drift/harness/setup.py +832 -0
  35. package/adl_drift/harness/skills/drift-antigravity.md +19 -0
  36. package/adl_drift/harness/skills/drift-generic.md +19 -0
  37. package/adl_drift/harness/skills/drift.md +25 -0
  38. package/adl_drift/harness/watch.py +84 -0
  39. package/adl_drift/lang/__init__.py +8 -0
  40. package/adl_drift/lang/base.py +464 -0
  41. package/adl_drift/lang/java/__init__.py +6 -0
  42. package/adl_drift/lang/java/backend.py +97 -0
  43. package/adl_drift/lang/java/cfg.py +1424 -0
  44. package/adl_drift/lang/java/config.py +707 -0
  45. package/adl_drift/lang/java/detectors/__init__.py +29 -0
  46. package/adl_drift/lang/java/detectors/additional.py +445 -0
  47. package/adl_drift/lang/java/detectors/base.py +154 -0
  48. package/adl_drift/lang/java/detectors/data_access.py +148 -0
  49. package/adl_drift/lang/java/detectors/imports.py +53 -0
  50. package/adl_drift/lang/java/detectors/routes.py +159 -0
  51. package/adl_drift/lang/java/detectors/security.py +386 -0
  52. package/adl_drift/lang/java/detectors/tests.py +74 -0
  53. package/adl_drift/lang/java/extractor.py +582 -0
  54. package/adl_drift/lang/java/ids.py +99 -0
  55. package/adl_drift/lang/java/parser.py +49 -0
  56. package/adl_drift/lang/java/resolution/__init__.py +1 -0
  57. package/adl_drift/lang/java/resolution/constants.py +1619 -0
  58. package/adl_drift/lang/java/resolution/constructors.py +278 -0
  59. package/adl_drift/lang/java/resolution/context.py +305 -0
  60. package/adl_drift/lang/java/resolution/dispatch.py +540 -0
  61. package/adl_drift/lang/java/resolution/functional.py +1318 -0
  62. package/adl_drift/lang/java/resolution/generated.py +95 -0
  63. package/adl_drift/lang/java/resolution/model.py +153 -0
  64. package/adl_drift/lang/java/resolution/orchestration.py +866 -0
  65. package/adl_drift/lang/java/resolution/overloads.py +1275 -0
  66. package/adl_drift/lang/java/resolution/scopes.py +1111 -0
  67. package/adl_drift/lang/java/resolution/types.py +2947 -0
  68. package/adl_drift/lang/java/resolver.py +1401 -0
  69. package/adl_drift/lang/java/scopes.py +69 -0
  70. package/adl_drift/lang/java/taint.py +500 -0
  71. package/adl_drift/lang/java/type_provenance.py +342 -0
  72. package/adl_drift/lang/python/__init__.py +8 -0
  73. package/adl_drift/lang/python/backend.py +94 -0
  74. package/adl_drift/lang/python/cfg.py +537 -0
  75. package/adl_drift/lang/python/extractor.py +454 -0
  76. package/adl_drift/lang/python/parser.py +41 -0
  77. package/adl_drift/lang/python/resolver.py +1789 -0
  78. package/adl_drift/lang/python/taint.py +365 -0
  79. package/adl_drift/lang/registry.py +117 -0
  80. package/adl_drift/parser/__init__.py +1 -0
  81. package/adl_drift/parser/cache.py +38 -0
  82. package/adl_drift/parser/core.py +33 -0
  83. package/adl_drift/parser/extractor.py +17 -0
  84. package/adl_drift/parser/literal_eval.py +326 -0
  85. package/adl_drift/scanner/__init__.py +1 -0
  86. package/adl_drift/scanner/discovery.py +338 -0
  87. package/adl_drift/scanner/incremental.py +261 -0
  88. package/adl_drift/scanner/parallel.py +224 -0
  89. package/adl_drift/server/__init__.py +1 -0
  90. package/adl_drift/server/handlers.py +2849 -0
  91. package/adl_drift/server/mcp_server.py +127 -0
  92. package/adl_drift/server/mcp_stdio.py +335 -0
  93. package/adl_drift/server/protocol.py +71 -0
  94. package/adl_drift/server/static/index.html +696 -0
  95. package/adl_drift/server/web.py +350 -0
  96. package/adl_drift/utils/__init__.py +1 -0
  97. package/adl_drift/utils/config.py +77 -0
  98. package/adl_drift/utils/fswalk.py +52 -0
  99. package/adl_drift/utils/types.py +345 -0
  100. package/bin/adl-drift.mjs +35 -0
  101. package/bin/adl-toolkit.mjs +488 -0
  102. package/package.json +29 -4
  103. package/pyproject.toml +49 -0
  104. package/scripts/install_toolkit.py +3584 -0
@@ -0,0 +1 @@
1
+ """Memory layer - persistent pattern storage."""
@@ -0,0 +1,96 @@
1
+ """Vector embedding generation for semantic search.
2
+
3
+ Uses sentence-transformers to convert code patterns and knowledge into
4
+ dense vectors for similarity search.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import os
10
+
11
+ # Loading model weights emits a tqdm progress bar ("Loading weights: 0%|...")
12
+ # straight to stdout the first time a model is materialized. Fatal wherever
13
+ # stdout is a strict channel — MCP JSON-RPC framing, or a `--json`/`--baseline`
14
+ # CLI payload — since the bar interleaves with the real output and breaks
15
+ # parsing. `transformers`/`huggingface_hub` only consult this env var once, at
16
+ # import time, so it must be set before either is ever imported — hence
17
+ # module-top, ahead of the sentence-transformers import below.
18
+ os.environ.setdefault("HF_HUB_DISABLE_PROGRESS_BARS", "1")
19
+
20
+ from typing import List, Optional
21
+ import numpy as np
22
+
23
+ try:
24
+ from sentence_transformers import SentenceTransformer
25
+ HAS_SENTENCE_TRANSFORMERS = True
26
+ except ImportError:
27
+ HAS_SENTENCE_TRANSFORMERS = False
28
+
29
+
30
+ class EmbeddingEngine:
31
+ """Generates and compares embeddings for code patterns.
32
+
33
+ Uses 'all-MiniLM-L6-v2' by default (small, fast, good for code).
34
+ For better code understanding, use 'intfloat/e5-base-v2' or
35
+ a code-specific model like 'jinaai/jina-embeddings-v2-base-code'.
36
+ """
37
+
38
+ DEFAULT_MODEL = "all-MiniLM-L6-v2"
39
+
40
+ def __init__(self, model_name: Optional[str] = None):
41
+ self.model_name = model_name or self.DEFAULT_MODEL
42
+ self._model: Optional[SentenceTransformer] = None
43
+
44
+ if HAS_SENTENCE_TRANSFORMERS:
45
+ self._load_model()
46
+
47
+ def _load_model(self) -> None:
48
+ """Lazy-load the embedding model."""
49
+ if self._model is not None or not HAS_SENTENCE_TRANSFORMERS:
50
+ return
51
+ try:
52
+ # An already-cached model still pays a network round-trip here
53
+ # by default (Hugging Face Hub checking for a newer revision on
54
+ # every single load) — slow, and occasionally stalls hard enough
55
+ # to blow past a caller's timeout (e.g. a fresh MCP server
56
+ # subprocess per tool call). Try local-only first; only reach
57
+ # the network if the model truly isn't cached yet.
58
+ self._model = SentenceTransformer(self.model_name, local_files_only=True)
59
+ except Exception:
60
+ self._model = SentenceTransformer(self.model_name)
61
+
62
+ def embed(self, texts: List[str]) -> np.ndarray:
63
+ """Generate embeddings for a list of texts.
64
+
65
+ Returns:
66
+ numpy array of shape (len(texts), embedding_dim)
67
+ """
68
+ if not HAS_SENTENCE_TRANSFORMERS or self._model is None:
69
+ # Fallback: random embeddings for testing
70
+ return np.random.randn(len(texts), 384).astype(np.float32)
71
+
72
+ return self._model.encode(texts, convert_to_numpy=True, show_progress_bar=False)
73
+
74
+ def embed_single(self, text: str) -> np.ndarray:
75
+ """Generate embedding for a single text."""
76
+ return self.embed([text])[0]
77
+
78
+ def similarity(self, a: np.ndarray, b: np.ndarray) -> float:
79
+ """Compute cosine similarity between two embeddings."""
80
+ return float(np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b)))
81
+
82
+ def search(self, query: str, corpus: List[str], top_k: int = 5) -> List[tuple[int, float]]:
83
+ """Find most similar texts to query.
84
+
85
+ Returns:
86
+ List of (index, similarity_score) tuples, sorted by score.
87
+ """
88
+ query_emb = self.embed_single(query)
89
+ corpus_emb = self.embed(corpus)
90
+
91
+ similarities = np.dot(corpus_emb, query_emb) / (
92
+ np.linalg.norm(corpus_emb, axis=1) * np.linalg.norm(query_emb)
93
+ )
94
+
95
+ top_indices = np.argsort(similarities)[::-1][:top_k]
96
+ return [(int(i), float(similarities[i])) for i in top_indices]