sourcecode 1.54.0__py3-none-any.whl → 1.55.0__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/contract_pipeline.py +4 -2
- sourcecode/license.py +53 -4
- {sourcecode-1.54.0.dist-info → sourcecode-1.55.0.dist-info}/METADATA +2 -2
- {sourcecode-1.54.0.dist-info → sourcecode-1.55.0.dist-info}/RECORD +8 -8
- {sourcecode-1.54.0.dist-info → sourcecode-1.55.0.dist-info}/WHEEL +0 -0
- {sourcecode-1.54.0.dist-info → sourcecode-1.55.0.dist-info}/entry_points.txt +0 -0
- {sourcecode-1.54.0.dist-info → sourcecode-1.55.0.dist-info}/licenses/LICENSE +0 -0
sourcecode/__init__.py
CHANGED
sourcecode/contract_pipeline.py
CHANGED
|
@@ -634,11 +634,13 @@ def _find_symbol_files(
|
|
|
634
634
|
try:
|
|
635
635
|
result = subprocess.run(
|
|
636
636
|
[
|
|
637
|
-
"grep", "-
|
|
637
|
+
"grep", "-rlF",
|
|
638
638
|
"--include=*.ts", "--include=*.tsx",
|
|
639
639
|
"--include=*.js", "--include=*.jsx",
|
|
640
640
|
"--include=*.py", "--include=*.java",
|
|
641
|
-
symbol
|
|
641
|
+
# -e guards a symbol that begins with '-' from being parsed as a
|
|
642
|
+
# flag; -- terminates options so the search root can't be either.
|
|
643
|
+
"-e", symbol, "--", ".",
|
|
642
644
|
],
|
|
643
645
|
cwd=str(root),
|
|
644
646
|
capture_output=True,
|
sourcecode/license.py
CHANGED
|
@@ -45,7 +45,33 @@ _DEFAULT_SUPABASE_URL: str = "https://qkndlmyekvujjdgthtmz.supabase.co"
|
|
|
45
45
|
# Paste your project's anon key here so `sourcecode activate` works out of the
|
|
46
46
|
# box; env var still overrides for testing against another project.
|
|
47
47
|
_DEFAULT_SUPABASE_ANON_KEY: str = "sb_publishable_qiJFLWjbBbTqjg-fb0mAGA_cl8PBOKH"
|
|
48
|
-
|
|
48
|
+
def _safe_supabase_url(override: "Optional[str]") -> str:
|
|
49
|
+
"""Validate the SOURCECODE_SUPABASE_URL override before trusting it.
|
|
50
|
+
|
|
51
|
+
The license key is POSTed to this host, so a plaintext ``http://`` endpoint
|
|
52
|
+
would expose the credential on the wire. Allow ``https://`` to any host, and
|
|
53
|
+
``http://`` only to loopback (Supabase local dev serves on
|
|
54
|
+
``http://127.0.0.1:54321``). Anything else is rejected back to the default.
|
|
55
|
+
"""
|
|
56
|
+
if not override or override == _DEFAULT_SUPABASE_URL:
|
|
57
|
+
return _DEFAULT_SUPABASE_URL
|
|
58
|
+
from urllib.parse import urlparse
|
|
59
|
+
|
|
60
|
+
parsed = urlparse(override)
|
|
61
|
+
host = (parsed.hostname or "").lower()
|
|
62
|
+
is_loopback = host in {"localhost", "127.0.0.1", "::1"}
|
|
63
|
+
if parsed.scheme == "https" or (parsed.scheme == "http" and is_loopback):
|
|
64
|
+
return override
|
|
65
|
+
sys.stderr.write(
|
|
66
|
+
f"[sourcecode] WARNING: ignoring SOURCECODE_SUPABASE_URL={override!r} — "
|
|
67
|
+
"must be https:// (or http:// to localhost). Using the default endpoint "
|
|
68
|
+
"to avoid sending the license key over plaintext.\n"
|
|
69
|
+
)
|
|
70
|
+
sys.stderr.flush()
|
|
71
|
+
return _DEFAULT_SUPABASE_URL
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
_SUPABASE_URL: str = _safe_supabase_url(os.environ.get("SOURCECODE_SUPABASE_URL"))
|
|
49
75
|
_SUPABASE_ANON_KEY: str = os.environ.get(
|
|
50
76
|
"SOURCECODE_SUPABASE_ANON_KEY",
|
|
51
77
|
_DEFAULT_SUPABASE_ANON_KEY,
|
|
@@ -152,12 +178,35 @@ _license_data: Optional[dict] = None
|
|
|
152
178
|
is_pro: bool = False
|
|
153
179
|
|
|
154
180
|
|
|
181
|
+
def _secure_dir() -> None:
|
|
182
|
+
"""Create ~/.sourcecode owner-only (0700). Holds the license secret.
|
|
183
|
+
|
|
184
|
+
``mkdir(mode=...)`` is ignored when the dir already exists, so chmod
|
|
185
|
+
unconditionally. Best-effort: a chmod failure (e.g. Windows) is non-fatal.
|
|
186
|
+
"""
|
|
187
|
+
try:
|
|
188
|
+
_LICENSE_DIR.mkdir(parents=True, exist_ok=True)
|
|
189
|
+
os.chmod(_LICENSE_DIR, 0o700)
|
|
190
|
+
except OSError:
|
|
191
|
+
pass
|
|
192
|
+
|
|
193
|
+
|
|
155
194
|
def _write_license_file(data: dict) -> None:
|
|
156
|
-
"""Atomically write license data via tmp file + rename.
|
|
195
|
+
"""Atomically write license data via tmp file + rename, owner-only (0600).
|
|
196
|
+
|
|
197
|
+
The payload contains the Pro ``license_key`` and account email, so the file
|
|
198
|
+
must not be world/group-readable on shared hosts. Permissions are set on the
|
|
199
|
+
tmp file *before* the rename so there is no readable window at the final path.
|
|
200
|
+
"""
|
|
201
|
+
_secure_dir()
|
|
157
202
|
payload = json.dumps(data, indent=2, ensure_ascii=False).encode("utf-8")
|
|
158
203
|
tmp = _LICENSE_FILE.with_suffix(".tmp")
|
|
159
204
|
try:
|
|
160
205
|
tmp.write_bytes(payload)
|
|
206
|
+
try:
|
|
207
|
+
os.chmod(tmp, 0o600)
|
|
208
|
+
except OSError:
|
|
209
|
+
pass
|
|
161
210
|
tmp.replace(_LICENSE_FILE)
|
|
162
211
|
except Exception:
|
|
163
212
|
try:
|
|
@@ -192,7 +241,7 @@ def check_delta_free_tier(repo_path: str) -> "tuple[bool, int, int]":
|
|
|
192
241
|
new_used = used + 1
|
|
193
242
|
runs[key] = new_used
|
|
194
243
|
try:
|
|
195
|
-
|
|
244
|
+
_secure_dir()
|
|
196
245
|
tmp = _DELTA_RUNS_FILE.with_suffix(".tmp")
|
|
197
246
|
tmp.write_text(json.dumps(runs, indent=2, ensure_ascii=False), encoding="utf-8")
|
|
198
247
|
tmp.replace(_DELTA_RUNS_FILE)
|
|
@@ -506,7 +555,7 @@ def activate_license(license_key: str) -> None:
|
|
|
506
555
|
_emit_telemetry("activation", feature="key", success=False, error_kind="NotPro")
|
|
507
556
|
_fail("not_pro", "This license is not a Pro license.")
|
|
508
557
|
|
|
509
|
-
|
|
558
|
+
_secure_dir()
|
|
510
559
|
now = datetime.now(timezone.utc).isoformat()
|
|
511
560
|
data = {
|
|
512
561
|
"license_key": license_key,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sourcecode
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.55.0
|
|
4
4
|
Summary: Persistent structural context and ultra-fast repeated analysis for AI coding agents
|
|
5
5
|
License-File: LICENSE
|
|
6
6
|
Keywords: agents,ai,codebase,context,developer-tools,llm
|
|
@@ -40,7 +40,7 @@ Description-Content-Type: text/markdown
|
|
|
40
40
|
|
|
41
41
|
**Persistent structural context and ultra-fast repeated analysis for AI coding agents.**
|
|
42
42
|
|
|
43
|
-

|
|
44
44
|

|
|
45
45
|
|
|
46
46
|
---
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
sourcecode/__init__.py,sha256=
|
|
1
|
+
sourcecode/__init__.py,sha256=Ii3NgTGWcclYkr3nNfo2p3kxEPuBIM33XeG_rUFCIeU,103
|
|
2
2
|
sourcecode/adaptive_scanner.py,sha256=XffluXKzJUXrMtjEiAOnSNPZnztdIcts17T9ouHeID0,10521
|
|
3
3
|
sourcecode/architecture_analyzer.py,sha256=liCwQmLgb5vplohy8arjYxs_HOIv5C9MjLh_gY6bc5Q,44115
|
|
4
4
|
sourcecode/architecture_summary.py,sha256=z34_6v7cSwy98cof2UVciGho7SCrZ93tiqMmq5WNzRQ,20405
|
|
@@ -13,7 +13,7 @@ sourcecode/confidence_analyzer.py,sha256=_jckZSxksV-OU38vbkxfVNBnWCtlCq8Vwfg23x1
|
|
|
13
13
|
sourcecode/context_scorer.py,sha256=QpChSpsmaAYz91rXA4Ue5xzQmNz_ZboZN09YOHScq1U,14679
|
|
14
14
|
sourcecode/context_summarizer.py,sha256=zlbm8ytdvJToohU108-dwBmEl52xl0gXpf6PZBOW_2A,6540
|
|
15
15
|
sourcecode/contract_model.py,sha256=nRxJKPMs1VHwFTa8AVXhGmaLjti3Lr2sjHDpWgv1bfE,3917
|
|
16
|
-
sourcecode/contract_pipeline.py,sha256=
|
|
16
|
+
sourcecode/contract_pipeline.py,sha256=bNn9SYtwfI1CGKlYGxewexlp7_IWhpwSCae-BMuuVwQ,28895
|
|
17
17
|
sourcecode/coverage_parser.py,sha256=q0LeZJaX1bnntLu-ImksdBsMlpsVmk_iUfSaB4eaJGo,19702
|
|
18
18
|
sourcecode/dependency_analyzer.py,sha256=qEnRiKFkleZJyLf_DyznJbWD1GJ881iG4RRDqH9oGQ4,61524
|
|
19
19
|
sourcecode/doc_analyzer.py,sha256=05bjTUbDbmnbajD_cgRnACzS8T7xxBKVX4CjkJlhZg8,24411
|
|
@@ -29,7 +29,7 @@ sourcecode/fqn_utils.py,sha256=XLU7zDkNBXz_RZkIUNfpPmp1nekWtqP-fxV92tDV1vg,2158
|
|
|
29
29
|
sourcecode/git_analyzer.py,sha256=JStxTQXNjBWi_wLdwhsZs9mT-v50cSJIz4Agzn6Kh9I,13362
|
|
30
30
|
sourcecode/graph_analyzer.py,sha256=DHR8fY69oU_Pi4SYaWboX6EoEFrctQKB9dsjpqwGMzw,62403
|
|
31
31
|
sourcecode/integration_detector.py,sha256=ZJqrGwvZ4ee2JTGhlazKk67aZi173HxkhNpl8Yntpd8,6503
|
|
32
|
-
sourcecode/license.py,sha256=
|
|
32
|
+
sourcecode/license.py,sha256=JD-1pnH_2XR9lKr9p9KQZn9U31I9e5o6GYsN1XCVccw,22577
|
|
33
33
|
sourcecode/mcp_nudge.py,sha256=5ELU_ixzh6uA83NXLOZT8h00OhL53okfQdji3jyKOjg,2917
|
|
34
34
|
sourcecode/metrics_analyzer.py,sha256=m0ENgtqKeBL17kUIK3fmGkgo7UfXBNHxCMj0H_Y5K7c,22750
|
|
35
35
|
sourcecode/migrate_check.py,sha256=H8iy7Vk8cGL0dnR3ZkFPS20CtfF5LJWuzQVQE4awQ9s,56192
|
|
@@ -102,8 +102,8 @@ sourcecode/telemetry/consent.py,sha256=wLMvGNJeSSyZoNkQXpoUioY6mMv4Qdvuw7S9jAEWn
|
|
|
102
102
|
sourcecode/telemetry/events.py,sha256=LtzYfaX9Ilckj5PTvAcTpDa9mLqDsYPDUiDkRa58piY,2580
|
|
103
103
|
sourcecode/telemetry/filters.py,sha256=NHa5T-6DaZduQPFuC34jOqHWQgSizM-Ygq8aZ4j19ng,5834
|
|
104
104
|
sourcecode/telemetry/transport.py,sha256=4gGHsq0WeY9VywEZXA3vUxykfiYnw9uuqfjAAec7F8o,1681
|
|
105
|
-
sourcecode-1.
|
|
106
|
-
sourcecode-1.
|
|
107
|
-
sourcecode-1.
|
|
108
|
-
sourcecode-1.
|
|
109
|
-
sourcecode-1.
|
|
105
|
+
sourcecode-1.55.0.dist-info/METADATA,sha256=uMl86Jm5iDPg0LDJ1QTmuLuEuiuqaihtwbuh0D_N06k,37049
|
|
106
|
+
sourcecode-1.55.0.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
|
|
107
|
+
sourcecode-1.55.0.dist-info/entry_points.txt,sha256=ex3F9rmbXeyDIoFQHtkEqTsKSaJow8F0LrVu8XfIktQ,57
|
|
108
|
+
sourcecode-1.55.0.dist-info/licenses/LICENSE,sha256=7DdHrU9Z_3e7dSvq4ISijZNjnuHo5NIHNiHDouMQ9JU,10491
|
|
109
|
+
sourcecode-1.55.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|