sourcecode 1.30.1__py3-none-any.whl → 1.30.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.
- sourcecode/__init__.py +1 -1
- sourcecode/cli.py +2 -0
- sourcecode/flow_analyzer.py +310 -0
- sourcecode/prepare_context.py +13 -0
- {sourcecode-1.30.1.dist-info → sourcecode-1.30.2.dist-info}/METADATA +3 -3
- {sourcecode-1.30.1.dist-info → sourcecode-1.30.2.dist-info}/RECORD +9 -8
- {sourcecode-1.30.1.dist-info → sourcecode-1.30.2.dist-info}/WHEEL +0 -0
- {sourcecode-1.30.1.dist-info → sourcecode-1.30.2.dist-info}/entry_points.txt +0 -0
- {sourcecode-1.30.1.dist-info → sourcecode-1.30.2.dist-info}/licenses/LICENSE +0 -0
sourcecode/__init__.py
CHANGED
sourcecode/cli.py
CHANGED
|
@@ -1866,6 +1866,8 @@ def prepare_context_cmd(
|
|
|
1866
1866
|
out["review_hotspots"] = output.review_hotspots
|
|
1867
1867
|
if output.suggested_review_order:
|
|
1868
1868
|
out["suggested_review_order"] = output.suggested_review_order
|
|
1869
|
+
if output.execution_paths:
|
|
1870
|
+
out["execution_paths"] = output.execution_paths
|
|
1869
1871
|
if output.impact_summary:
|
|
1870
1872
|
out["impact_summary"] = output.impact_summary
|
|
1871
1873
|
if output.why_these_files:
|
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
"""flow_analyzer.py — Evidence-based execution path extraction for PR context.
|
|
2
|
+
|
|
3
|
+
Builds Entry → Service → Repository → EndState ordered sequences using ONLY
|
|
4
|
+
direct code evidence: field injection, constructor params, type annotations,
|
|
5
|
+
method calls, explicit instantiation.
|
|
6
|
+
|
|
7
|
+
V3: execution_paths with runtime_notes — conditional branches, optional execution,
|
|
8
|
+
and async side-effects are surfaced when explicit code signals exist.
|
|
9
|
+
No inference, no naming, no invented behavior.
|
|
10
|
+
"""
|
|
11
|
+
from __future__ import annotations
|
|
12
|
+
|
|
13
|
+
import re
|
|
14
|
+
from pathlib import Path
|
|
15
|
+
from typing import Callable, Optional
|
|
16
|
+
|
|
17
|
+
_ENTRY_ARTIFACT_TYPES = frozenset({"controller", "entrypoint"})
|
|
18
|
+
_SERVICE_ARTIFACT_TYPES = frozenset({"service"})
|
|
19
|
+
_REPO_ARTIFACT_TYPES = frozenset({"repository", "mapper"})
|
|
20
|
+
|
|
21
|
+
_DB_KEYWORDS = frozenset({"repository", "dao", "mapper", "store", "jpa", "jdbc", "sql"})
|
|
22
|
+
_EVENT_KEYWORDS = frozenset({"event", "publish", "emit", "kafka", "queue", "rabbit", "sns", "bus"})
|
|
23
|
+
|
|
24
|
+
_HTTP_ENTRY_RE = re.compile(
|
|
25
|
+
r'@(?:Get|Post|Put|Delete|Patch|Request)Mapping[^)]*\)'
|
|
26
|
+
r'|@(?:Get|Post|Put|Delete|Patch)\([^)]*\)'
|
|
27
|
+
r'|@\w+\.(?:get|post|put|delete|patch)\([^)]*\)',
|
|
28
|
+
re.IGNORECASE,
|
|
29
|
+
)
|
|
30
|
+
_METHOD_NAME_RE = re.compile(
|
|
31
|
+
r'(?:public\s+|async\s+|def\s+|function\s+)*'
|
|
32
|
+
r'(?:[\w<>\[\]]+\s+)?'
|
|
33
|
+
r'(\w+)\s*\(',
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
# Runtime signal patterns: (compiled_regex, note_text)
|
|
37
|
+
# Only signals with explicit code evidence — no inference.
|
|
38
|
+
# Three categories: condition | branch | async
|
|
39
|
+
_RUNTIME_SIGNALS: list[tuple[re.Pattern, str]] = [
|
|
40
|
+
# ── Conditional / auth guards ─────────────────────────────────────────────
|
|
41
|
+
(re.compile(r'@PreAuthorize|@Secured|@RolesAllowed', re.IGNORECASE),
|
|
42
|
+
"condition: authorization check present (@PreAuthorize / @Secured)"),
|
|
43
|
+
(re.compile(r'isAuthenticated\(\)|hasRole\(|hasAuthority\(|SecurityContextHolder', re.IGNORECASE),
|
|
44
|
+
"condition: reads authentication context"),
|
|
45
|
+
(re.compile(r'featureFlag|FeatureToggle|\.isEnabled\s*\(|\.isActive\s*\(', re.IGNORECASE),
|
|
46
|
+
"condition: feature flag gates execution"),
|
|
47
|
+
# Null/empty guard with early return — matches if (...null/empty...) return/throw on same line
|
|
48
|
+
(re.compile(r'if\s*\([^)]*(?:==\s*null|!=\s*null|isEmpty\s*\(\)|isBlank\s*\(\))[^)]*\)'
|
|
49
|
+
r'\s*(?:\{?\s*)?(?:return|throw)\b', re.IGNORECASE),
|
|
50
|
+
"condition: null/empty guard with early return"),
|
|
51
|
+
|
|
52
|
+
# ── Optional execution / branching ────────────────────────────────────────
|
|
53
|
+
(re.compile(r'@Cacheable|@CacheEvict|@CachePut', re.IGNORECASE),
|
|
54
|
+
"branch: Spring cache may short-circuit downstream call"),
|
|
55
|
+
(re.compile(r'\.getIfPresent\s*\(|cache\.get\s*\(|cacheManager\.', re.IGNORECASE),
|
|
56
|
+
"branch: manual cache lookup may short-circuit"),
|
|
57
|
+
(re.compile(r'Optional\s*<|\.orElseThrow\s*\(|\.orElseGet\s*\(|\.orElse\s*\(', re.IGNORECASE),
|
|
58
|
+
"branch: result may be absent (Optional)"),
|
|
59
|
+
|
|
60
|
+
# ── Async / side effects ──────────────────────────────────────────────────
|
|
61
|
+
(re.compile(r'@Async\b'),
|
|
62
|
+
"async: runs in separate thread (@Async)"),
|
|
63
|
+
(re.compile(r'CompletableFuture|\.supplyAsync\s*\(|\.runAsync\s*\('),
|
|
64
|
+
"async: non-blocking future-based execution"),
|
|
65
|
+
(re.compile(r'\basync\s+def\b|\bawait\b', re.IGNORECASE),
|
|
66
|
+
"async: non-blocking (async/await)"),
|
|
67
|
+
(re.compile(r'publishEvent\s*\(|applicationEventPublisher|eventPublisher\.', re.IGNORECASE),
|
|
68
|
+
"async: Spring application event emitted"),
|
|
69
|
+
(re.compile(r'kafkaTemplate\.|KafkaProducer|@KafkaListener', re.IGNORECASE),
|
|
70
|
+
"async: Kafka message produced"),
|
|
71
|
+
(re.compile(r'rabbitTemplate\.|amqpTemplate\.|@RabbitListener', re.IGNORECASE),
|
|
72
|
+
"async: RabbitMQ message sent"),
|
|
73
|
+
]
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def _detect_lang(path: str) -> str:
|
|
77
|
+
return {
|
|
78
|
+
".java": "java", ".kt": "kotlin",
|
|
79
|
+
".py": "python",
|
|
80
|
+
".ts": "typescript", ".tsx": "typescript",
|
|
81
|
+
".js": "javascript", ".jsx": "javascript",
|
|
82
|
+
".go": "go", ".cs": "csharp", ".rb": "ruby", ".php": "php",
|
|
83
|
+
}.get(Path(path).suffix.lower(), "unknown")
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def _strip_comments(content: str, lang: str) -> str:
|
|
87
|
+
content = re.sub(r"/\*.*?\*/", " ", content, flags=re.DOTALL)
|
|
88
|
+
content = re.sub(r"//[^\n]*", " ", content)
|
|
89
|
+
if lang in ("python", "ruby", "go"):
|
|
90
|
+
content = re.sub(r"#[^\n]*", " ", content)
|
|
91
|
+
return content
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def _read_safe(root: Path, rel_path: str) -> str:
|
|
95
|
+
try:
|
|
96
|
+
return (root / rel_path).read_text(encoding="utf-8", errors="ignore")
|
|
97
|
+
except (OSError, ValueError):
|
|
98
|
+
return ""
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def _collect_runtime_notes(content: str, lang: str) -> list[str]:
|
|
102
|
+
"""Scan comment-stripped content for explicit runtime behavior signals.
|
|
103
|
+
|
|
104
|
+
Returns only notes backed by a direct code pattern match.
|
|
105
|
+
Returns [] when no signals are found.
|
|
106
|
+
"""
|
|
107
|
+
clean = _strip_comments(content, lang)
|
|
108
|
+
notes: list[str] = []
|
|
109
|
+
seen: set[str] = set()
|
|
110
|
+
for pattern, note in _RUNTIME_SIGNALS:
|
|
111
|
+
if note not in seen and pattern.search(clean):
|
|
112
|
+
notes.append(note)
|
|
113
|
+
seen.add(note)
|
|
114
|
+
return notes
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def _find_entry_method(clean: str) -> Optional[str]:
|
|
118
|
+
m = _HTTP_ENTRY_RE.search(clean)
|
|
119
|
+
if not m:
|
|
120
|
+
return None
|
|
121
|
+
after = clean[m.end():]
|
|
122
|
+
mn = _METHOD_NAME_RE.match(after.lstrip())
|
|
123
|
+
if mn:
|
|
124
|
+
name = mn.group(1)
|
|
125
|
+
if name.lower() not in ("public", "async", "def", "function", "void", "override"):
|
|
126
|
+
return name
|
|
127
|
+
return None
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def _build_field_map(clean: str) -> dict[str, str]:
|
|
131
|
+
"""Map field_name_lower → ClassName from injection patterns."""
|
|
132
|
+
fmap: dict[str, str] = {}
|
|
133
|
+
for m in re.finditer(r"private\s+(\w+)(?:<[^>]+>)?\s+(\w+)\s*[;=,)]", clean):
|
|
134
|
+
fmap[m.group(2).lower()] = m.group(1)
|
|
135
|
+
for m in re.finditer(r"(?:private|protected|readonly)\s+(\w+)\s*:\s*(\w+)", clean):
|
|
136
|
+
fmap[m.group(1).lower()] = m.group(2)
|
|
137
|
+
for m in re.finditer(r"self\.(\w+)\s*=\s*(\w+)\s*\(", clean):
|
|
138
|
+
fmap[m.group(1).lower()] = m.group(2)
|
|
139
|
+
return fmap
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
def _find_called_method(clean: str, class_name: str, fmap: dict[str, str]) -> Optional[str]:
|
|
143
|
+
fields = [f for f, t in fmap.items() if t.lower() == class_name.lower()]
|
|
144
|
+
for field in fields:
|
|
145
|
+
pat = rf"\bthis\.{re.escape(field)}\.(\w+)\s*\(|\b{re.escape(field)}\.(\w+)\s*\("
|
|
146
|
+
for m in re.finditer(pat, clean, re.IGNORECASE):
|
|
147
|
+
name = m.group(1) or m.group(2)
|
|
148
|
+
if name and name.lower() not in ("class", "new", "super", "get", "set"):
|
|
149
|
+
return name
|
|
150
|
+
for m in re.finditer(rf"\b{re.escape(class_name)}\.(\w+)\s*\(", clean, re.IGNORECASE):
|
|
151
|
+
name = m.group(1)
|
|
152
|
+
if name.lower() not in ("class", "new", "super"):
|
|
153
|
+
return name
|
|
154
|
+
return None
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def _has_code_evidence(clean: str, class_name: str) -> bool:
|
|
158
|
+
"""True only when class_name has direct code evidence in pre-stripped content."""
|
|
159
|
+
esc = re.escape(class_name)
|
|
160
|
+
if re.search(rf"\b(?:private|protected)\s+{esc}\b", clean, re.IGNORECASE):
|
|
161
|
+
return True
|
|
162
|
+
if re.search(rf"[,(]\s*{esc}\s+\w+", clean, re.IGNORECASE):
|
|
163
|
+
return True
|
|
164
|
+
if re.search(rf":\s*{esc}\b", clean, re.IGNORECASE):
|
|
165
|
+
return True
|
|
166
|
+
if re.search(rf"\bnew\s+{esc}\s*\(", clean, re.IGNORECASE):
|
|
167
|
+
return True
|
|
168
|
+
if re.search(rf"\b{esc}\s*\(", clean):
|
|
169
|
+
return True
|
|
170
|
+
if re.search(rf"\b{esc}\b", clean, re.IGNORECASE):
|
|
171
|
+
non_import = re.search(
|
|
172
|
+
rf"^(?!\s*(?:import|require|from|//|#|\*)\b).*\b{esc}\b",
|
|
173
|
+
clean, re.IGNORECASE | re.MULTILINE,
|
|
174
|
+
)
|
|
175
|
+
if non_import:
|
|
176
|
+
return True
|
|
177
|
+
return False
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
def _find_evidenced_ordered(
|
|
181
|
+
root: Path,
|
|
182
|
+
source_path: str,
|
|
183
|
+
candidates: list[str],
|
|
184
|
+
) -> list[tuple[str, Optional[str]]]:
|
|
185
|
+
"""Return (class_name, method_or_None) for candidates with direct code evidence,
|
|
186
|
+
ordered by their first appearance position in the source file."""
|
|
187
|
+
content = _read_safe(root, source_path)
|
|
188
|
+
if not content:
|
|
189
|
+
return []
|
|
190
|
+
lang = _detect_lang(source_path)
|
|
191
|
+
clean = _strip_comments(content, lang)
|
|
192
|
+
fmap = _build_field_map(clean)
|
|
193
|
+
|
|
194
|
+
positioned: list[tuple[int, str, Optional[str]]] = []
|
|
195
|
+
for cand_path in candidates:
|
|
196
|
+
class_name = Path(cand_path).stem
|
|
197
|
+
if not _has_code_evidence(clean, class_name):
|
|
198
|
+
continue
|
|
199
|
+
method = _find_called_method(clean, class_name, fmap)
|
|
200
|
+
m = re.search(rf"\b{re.escape(class_name)}\b", clean, re.IGNORECASE)
|
|
201
|
+
pos = m.start() if m else len(clean)
|
|
202
|
+
positioned.append((pos, class_name, method))
|
|
203
|
+
|
|
204
|
+
positioned.sort(key=lambda x: x[0])
|
|
205
|
+
return [(cls, meth) for _, cls, meth in positioned]
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
def _detect_end_state(path: list[str]) -> str:
|
|
209
|
+
for step in path:
|
|
210
|
+
s = step.lower()
|
|
211
|
+
if any(kw in s for kw in _DB_KEYWORDS):
|
|
212
|
+
return "DB write"
|
|
213
|
+
if any(kw in s for kw in _EVENT_KEYWORDS):
|
|
214
|
+
return "event emitted"
|
|
215
|
+
return "HTTP response"
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
def _step_label(class_name: str, method: Optional[str]) -> str:
|
|
219
|
+
return f"{class_name}.{method}" if method else class_name
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
def _path_name(entry_class: str) -> str:
|
|
223
|
+
domain = re.sub(
|
|
224
|
+
r"(?:RestController|Controller|Resource|Handler|Api|Endpoint|Router|Servlet)$",
|
|
225
|
+
"", entry_class, flags=re.IGNORECASE,
|
|
226
|
+
)
|
|
227
|
+
return re.sub(r"(?<=[a-z])(?=[A-Z])", " ", domain).strip()
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
def analyze_execution_paths(
|
|
231
|
+
changed_files: list[str],
|
|
232
|
+
all_paths: list[str],
|
|
233
|
+
root: Path,
|
|
234
|
+
classify_fn: Callable[[str], dict],
|
|
235
|
+
max_paths: int = 3,
|
|
236
|
+
) -> list[dict]:
|
|
237
|
+
"""Build ordered execution paths with runtime behavior signals.
|
|
238
|
+
|
|
239
|
+
Each path:
|
|
240
|
+
- One service per entry point (most evident, earliest-referenced)
|
|
241
|
+
- Each step requires direct code evidence
|
|
242
|
+
- runtime_notes populated from explicit code signals only (never inferred)
|
|
243
|
+
- Forward-only: Controller → Service → Repository
|
|
244
|
+
|
|
245
|
+
Returns list of: {name, entry_point, path, runtime_notes, end_state}
|
|
246
|
+
Returns [] when no verifiable path exists.
|
|
247
|
+
"""
|
|
248
|
+
entry_files = [
|
|
249
|
+
f for f in changed_files
|
|
250
|
+
if classify_fn(f)["artifact_type"] in _ENTRY_ARTIFACT_TYPES
|
|
251
|
+
]
|
|
252
|
+
if not entry_files:
|
|
253
|
+
return []
|
|
254
|
+
|
|
255
|
+
all_services = [p for p in all_paths if classify_fn(p)["artifact_type"] in _SERVICE_ARTIFACT_TYPES]
|
|
256
|
+
all_repos = [p for p in all_paths if classify_fn(p)["artifact_type"] in _REPO_ARTIFACT_TYPES]
|
|
257
|
+
|
|
258
|
+
result: list[dict] = []
|
|
259
|
+
|
|
260
|
+
for entry_path in entry_files[:max_paths]:
|
|
261
|
+
entry_class = Path(entry_path).stem
|
|
262
|
+
lang = _detect_lang(entry_path)
|
|
263
|
+
|
|
264
|
+
entry_content = _read_safe(root, entry_path)
|
|
265
|
+
entry_clean = _strip_comments(entry_content, lang) if entry_content else ""
|
|
266
|
+
entry_method = _find_entry_method(entry_clean) if entry_clean else None
|
|
267
|
+
entry_point_str = _step_label(entry_class, entry_method)
|
|
268
|
+
|
|
269
|
+
evidenced_svcs = _find_evidenced_ordered(root, entry_path, all_services)
|
|
270
|
+
if not evidenced_svcs:
|
|
271
|
+
continue
|
|
272
|
+
|
|
273
|
+
svc_class, svc_method = evidenced_svcs[0]
|
|
274
|
+
svc_label = _step_label(svc_class, svc_method)
|
|
275
|
+
|
|
276
|
+
svc_path = next((p for p in all_services if Path(p).stem == svc_class), None)
|
|
277
|
+
svc_content = _read_safe(root, svc_path) if svc_path else ""
|
|
278
|
+
svc_lang = _detect_lang(svc_path) if svc_path else "unknown"
|
|
279
|
+
|
|
280
|
+
# Service step — notes scoped to service file only
|
|
281
|
+
path_items: list[dict] = [
|
|
282
|
+
{"step": svc_label,
|
|
283
|
+
"notes": _collect_runtime_notes(svc_content, svc_lang) if svc_content else []},
|
|
284
|
+
]
|
|
285
|
+
|
|
286
|
+
# Repository step — notes scoped to repo file only
|
|
287
|
+
if svc_path:
|
|
288
|
+
evidenced_repos = _find_evidenced_ordered(root, svc_path, all_repos)
|
|
289
|
+
if evidenced_repos:
|
|
290
|
+
repo_class, repo_method = evidenced_repos[0]
|
|
291
|
+
repo_label = _step_label(repo_class, repo_method)
|
|
292
|
+
repo_path = next((p for p in all_repos if Path(p).stem == repo_class), None)
|
|
293
|
+
repo_content = _read_safe(root, repo_path) if repo_path else ""
|
|
294
|
+
repo_lang = _detect_lang(repo_path) if repo_path else "unknown"
|
|
295
|
+
path_items.append(
|
|
296
|
+
{"step": repo_label,
|
|
297
|
+
"notes": _collect_runtime_notes(repo_content, repo_lang) if repo_content else []},
|
|
298
|
+
)
|
|
299
|
+
|
|
300
|
+
# Entry-point notes scoped to controller file
|
|
301
|
+
entry_notes = _collect_runtime_notes(entry_content, lang) if entry_content else []
|
|
302
|
+
|
|
303
|
+
result.append({
|
|
304
|
+
"name": _path_name(entry_class),
|
|
305
|
+
"entry_point": {"step": entry_point_str, "notes": entry_notes},
|
|
306
|
+
"path": path_items,
|
|
307
|
+
"end_state": _detect_end_state([item["step"] for item in path_items]),
|
|
308
|
+
})
|
|
309
|
+
|
|
310
|
+
return result
|
sourcecode/prepare_context.py
CHANGED
|
@@ -351,6 +351,7 @@ class TaskOutput:
|
|
|
351
351
|
test_coverage_risk: dict = field(default_factory=dict)
|
|
352
352
|
review_hotspots: list[str] = field(default_factory=list)
|
|
353
353
|
suggested_review_order: list[str] = field(default_factory=list)
|
|
354
|
+
execution_paths: list[dict] = field(default_factory=list)
|
|
354
355
|
|
|
355
356
|
|
|
356
357
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
@@ -874,6 +875,17 @@ class TaskContextBuilder:
|
|
|
874
875
|
_pr_suggested_review_order.append(_f)
|
|
875
876
|
_seen_order.add(_f)
|
|
876
877
|
|
|
878
|
+
# ── 6d. review-pr: execution paths ──────────────────────────────────
|
|
879
|
+
_execution_paths: list[dict] = []
|
|
880
|
+
if task_name == "review-pr" and _delta_files:
|
|
881
|
+
from sourcecode.flow_analyzer import analyze_execution_paths
|
|
882
|
+
_execution_paths = analyze_execution_paths(
|
|
883
|
+
changed_files=sorted(_delta_files),
|
|
884
|
+
all_paths=all_paths,
|
|
885
|
+
root=self.root,
|
|
886
|
+
classify_fn=self._classify_changed_file,
|
|
887
|
+
)
|
|
888
|
+
|
|
877
889
|
# ── 6c. Symptom keyword boost + related notes (fix-bug + --symptom) ──
|
|
878
890
|
symptom_keywords: list[str] = []
|
|
879
891
|
related_notes: list[dict] = []
|
|
@@ -1104,6 +1116,7 @@ class TaskContextBuilder:
|
|
|
1104
1116
|
test_coverage_risk=_pr_test_coverage_risk,
|
|
1105
1117
|
review_hotspots=_pr_review_hotspots,
|
|
1106
1118
|
suggested_review_order=_pr_suggested_review_order,
|
|
1119
|
+
execution_paths=_execution_paths,
|
|
1107
1120
|
)
|
|
1108
1121
|
|
|
1109
1122
|
def render_prompt(self, output: TaskOutput) -> str:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sourcecode
|
|
3
|
-
Version: 1.30.
|
|
3
|
+
Version: 1.30.2
|
|
4
4
|
Summary: Deterministic codebase context for AI coding agents
|
|
5
5
|
License: Apache License
|
|
6
6
|
Version 2.0, January 2004
|
|
@@ -221,7 +221,7 @@ Description-Content-Type: text/markdown
|
|
|
221
221
|
|
|
222
222
|
**Compressed AI-ready context for Java/Spring enterprise codebases.**
|
|
223
223
|
|
|
224
|
-

|
|
225
225
|

|
|
226
226
|
|
|
227
227
|
---
|
|
@@ -255,7 +255,7 @@ pipx install sourcecode
|
|
|
255
255
|
|
|
256
256
|
```bash
|
|
257
257
|
sourcecode version
|
|
258
|
-
# sourcecode 1.30.
|
|
258
|
+
# sourcecode 1.30.2
|
|
259
259
|
```
|
|
260
260
|
|
|
261
261
|
---
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
sourcecode/__init__.py,sha256=
|
|
1
|
+
sourcecode/__init__.py,sha256=ERxetwuKJX_1UzzbbdymfXL8AXwRFp03HJG6sY-iJO4,103
|
|
2
2
|
sourcecode/adaptive_scanner.py,sha256=RTNExwWPXzjgLaRueT7UuxkPj5ZEToWjGbx1j0LSZ9E,10250
|
|
3
3
|
sourcecode/architecture_analyzer.py,sha256=MyBa0Hf5HmkudZQDLKrjcWDKETXETXl0mQX1swtTwAA,39091
|
|
4
4
|
sourcecode/architecture_summary.py,sha256=z34_6v7cSwy98cof2UVciGho7SCrZ93tiqMmq5WNzRQ,20405
|
|
5
5
|
sourcecode/ast_extractor.py,sha256=XgrZg2DcWcUm9r87cRG3KGO7IK2TIL_N-CvhSbUmmh4,49901
|
|
6
6
|
sourcecode/classifier.py,sha256=pYve2J1LqtYssU3lYLMDz18PT-CjN5c18QYE7R_IG1Q,7507
|
|
7
|
-
sourcecode/cli.py,sha256=
|
|
7
|
+
sourcecode/cli.py,sha256=1qVMsC2swT-OtCK6XziIM0J4xKp8kcRhUzfOaHr7vRU,80743
|
|
8
8
|
sourcecode/code_notes_analyzer.py,sha256=y1MJBnPZHYp4i6cQCXUb9ATIyifS_qMQWjw_8lPkpsU,9215
|
|
9
9
|
sourcecode/confidence_analyzer.py,sha256=xw_Jv8pAd0wd8t2vvQlorw8Ih0rSF3YCoFS8K-_4aXg,15762
|
|
10
10
|
sourcecode/context_scorer.py,sha256=QpChSpsmaAYz91rXA4Ue5xzQmNz_ZboZN09YOHScq1U,14679
|
|
@@ -17,10 +17,11 @@ sourcecode/doc_analyzer.py,sha256=afA4uJFwXZ_uR2l4J0pQwbeTkRkGmKdN9KhRVYePBUw,24
|
|
|
17
17
|
sourcecode/entrypoint_classifier.py,sha256=gvKgl0f5T8ol1r4JMmkeqGHuZTfZJiOwFOWdc7EYwYw,4061
|
|
18
18
|
sourcecode/env_analyzer.py,sha256=GxCidahAAIptTdDFIlVB6URd4HBnBlIX_SqUov3MBRQ,22076
|
|
19
19
|
sourcecode/file_classifier.py,sha256=48ly5Z6exkzBy8lNy1AkdP4-oJqIA1zT3LZfffuTyDo,11572
|
|
20
|
+
sourcecode/flow_analyzer.py,sha256=VQDrItg3NBqOOD8PxHXyntXQnPweUuUn6JtOY8lNWys,12841
|
|
20
21
|
sourcecode/git_analyzer.py,sha256=_pCg2V4d2aa17k9hayTzpexAj8syvyk4y9NYNvvgOAI,12802
|
|
21
22
|
sourcecode/graph_analyzer.py,sha256=iUK-7pSV-cvGqqD2hENdYmhnm0wcXFEyK-xnu5ul8OU,62515
|
|
22
23
|
sourcecode/metrics_analyzer.py,sha256=m0ENgtqKeBL17kUIK3fmGkgo7UfXBNHxCMj0H_Y5K7c,22750
|
|
23
|
-
sourcecode/prepare_context.py,sha256=
|
|
24
|
+
sourcecode/prepare_context.py,sha256=ELrCIIcttip4B3y9aQZdMPqIgzaEJR0evDdG8QYTBLc,129623
|
|
24
25
|
sourcecode/progress.py,sha256=qn30sWaHOkjTgXsSBmiPkz7Rsbwc5oSlIe6JNEMYp_k,3149
|
|
25
26
|
sourcecode/ranking_engine.py,sha256=virVglafZufioHpZpwktjMvUiL0TZELWQCQnQNV8dFo,9360
|
|
26
27
|
sourcecode/redactor.py,sha256=xuGcadGEHaPw4qZXlMDvzMCsr4VOkdp3oBQptHyJk8c,2884
|
|
@@ -61,8 +62,8 @@ sourcecode/telemetry/consent.py,sha256=wLMvGNJeSSyZoNkQXpoUioY6mMv4Qdvuw7S9jAEWn
|
|
|
61
62
|
sourcecode/telemetry/events.py,sha256=oEvvulfsv5GIDWG2174gSS6tNB95w38AIYiYeifGKlE,2294
|
|
62
63
|
sourcecode/telemetry/filters.py,sha256=Asa71oRl7q3Wt_FMwuufIZJFzSYdgRNKS8LHCIyFeYE,4805
|
|
63
64
|
sourcecode/telemetry/transport.py,sha256=KJeIPCPWMdmbCP3ySGs2iUlia34U6vWne2dZsUezesw,1560
|
|
64
|
-
sourcecode-1.30.
|
|
65
|
-
sourcecode-1.30.
|
|
66
|
-
sourcecode-1.30.
|
|
67
|
-
sourcecode-1.30.
|
|
68
|
-
sourcecode-1.30.
|
|
65
|
+
sourcecode-1.30.2.dist-info/METADATA,sha256=3bLQsn6BmYa9Rum0jjejw2627bPdOMaYxbqI2XMyOLY,23417
|
|
66
|
+
sourcecode-1.30.2.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
|
|
67
|
+
sourcecode-1.30.2.dist-info/entry_points.txt,sha256=ex3F9rmbXeyDIoFQHtkEqTsKSaJow8F0LrVu8XfIktQ,57
|
|
68
|
+
sourcecode-1.30.2.dist-info/licenses/LICENSE,sha256=7DdHrU9Z_3e7dSvq4ISijZNjnuHo5NIHNiHDouMQ9JU,10491
|
|
69
|
+
sourcecode-1.30.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|