ckgraphify 0.1.4__tar.gz → 0.2.1__tar.gz
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.
- {ckgraphify-0.1.4 → ckgraphify-0.2.1}/PKG-INFO +8 -8
- {ckgraphify-0.1.4 → ckgraphify-0.2.1}/README.md +7 -7
- {ckgraphify-0.1.4 → ckgraphify-0.2.1}/graphify/__main__.py +4 -24
- {ckgraphify-0.1.4 → ckgraphify-0.2.1}/graphify/business_map.py +0 -15
- {ckgraphify-0.1.4 → ckgraphify-0.2.1}/graphify/graph_main_frontend.py +32 -3
- {ckgraphify-0.1.4 → ckgraphify-0.2.1}/graphify/graph_main_frontend_sdk.py +311 -22
- {ckgraphify-0.1.4 → ckgraphify-0.2.1}/graphify/graph_main_merge.py +30 -21
- {ckgraphify-0.1.4 → ckgraphify-0.2.1}/graphify/graph_main_trace.py +8 -0
- {ckgraphify-0.1.4 → ckgraphify-0.2.1}/graphify/repo_registry.py +36 -6
- {ckgraphify-0.1.4 → ckgraphify-0.2.1}/pyproject.toml +1 -1
- {ckgraphify-0.1.4 → ckgraphify-0.2.1}/skill/skill-codex.md +6 -6
- {ckgraphify-0.1.4 → ckgraphify-0.2.1}/skill/skill.md +20 -71
- {ckgraphify-0.1.4 → ckgraphify-0.2.1}/LICENSE +0 -0
- {ckgraphify-0.1.4 → ckgraphify-0.2.1}/MANIFEST.in +0 -0
- {ckgraphify-0.1.4 → ckgraphify-0.2.1}/ckgraphify.egg-info/SOURCES.txt +0 -0
- {ckgraphify-0.1.4 → ckgraphify-0.2.1}/graphify/__init__.py +0 -0
- {ckgraphify-0.1.4 → ckgraphify-0.2.1}/graphify/analyze.py +0 -0
- {ckgraphify-0.1.4 → ckgraphify-0.2.1}/graphify/benchmark.py +0 -0
- {ckgraphify-0.1.4 → ckgraphify-0.2.1}/graphify/bridge_mtop.py +0 -0
- {ckgraphify-0.1.4 → ckgraphify-0.2.1}/graphify/build.py +0 -0
- {ckgraphify-0.1.4 → ckgraphify-0.2.1}/graphify/cache.py +0 -0
- {ckgraphify-0.1.4 → ckgraphify-0.2.1}/graphify/callflow_html.py +0 -0
- {ckgraphify-0.1.4 → ckgraphify-0.2.1}/graphify/cluster.py +0 -0
- {ckgraphify-0.1.4 → ckgraphify-0.2.1}/graphify/dedup.py +0 -0
- {ckgraphify-0.1.4 → ckgraphify-0.2.1}/graphify/detect.py +0 -0
- {ckgraphify-0.1.4 → ckgraphify-0.2.1}/graphify/export.py +0 -0
- {ckgraphify-0.1.4 → ckgraphify-0.2.1}/graphify/extract.py +0 -0
- {ckgraphify-0.1.4 → ckgraphify-0.2.1}/graphify/global_graph.py +0 -0
- {ckgraphify-0.1.4 → ckgraphify-0.2.1}/graphify/google_workspace.py +0 -0
- {ckgraphify-0.1.4 → ckgraphify-0.2.1}/graphify/graph_main_backend.py +0 -0
- {ckgraphify-0.1.4 → ckgraphify-0.2.1}/graphify/graph_main_html.py +0 -0
- {ckgraphify-0.1.4 → ckgraphify-0.2.1}/graphify/hooks.py +0 -0
- {ckgraphify-0.1.4 → ckgraphify-0.2.1}/graphify/ingest.py +0 -0
- {ckgraphify-0.1.4 → ckgraphify-0.2.1}/graphify/llm.py +0 -0
- {ckgraphify-0.1.4 → ckgraphify-0.2.1}/graphify/manifest.py +0 -0
- {ckgraphify-0.1.4 → ckgraphify-0.2.1}/graphify/report.py +0 -0
- {ckgraphify-0.1.4 → ckgraphify-0.2.1}/graphify/security.py +0 -0
- {ckgraphify-0.1.4 → ckgraphify-0.2.1}/graphify/serve.py +0 -0
- {ckgraphify-0.1.4 → ckgraphify-0.2.1}/graphify/transcribe.py +0 -0
- {ckgraphify-0.1.4 → ckgraphify-0.2.1}/graphify/tree_html.py +0 -0
- {ckgraphify-0.1.4 → ckgraphify-0.2.1}/graphify/validate.py +0 -0
- {ckgraphify-0.1.4 → ckgraphify-0.2.1}/graphify/watch.py +0 -0
- {ckgraphify-0.1.4 → ckgraphify-0.2.1}/graphify/wiki.py +0 -0
- {ckgraphify-0.1.4 → ckgraphify-0.2.1}/setup.cfg +0 -0
- {ckgraphify-0.1.4 → ckgraphify-0.2.1}/skill/__init__.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ckgraphify
|
|
3
|
-
Version: 0.1
|
|
3
|
+
Version: 0.2.1
|
|
4
4
|
Summary: AI coding assistant skill for Claude Code and Codex - graph-main boundary graphs, multi-repo call chains, business-map concepts, and business search
|
|
5
5
|
License-Expression: MIT
|
|
6
6
|
Project-URL: Homepage, https://github.com/safishamsi/graphify
|
|
@@ -106,17 +106,17 @@ python3 -m pip install -e ./ckgraphify && CLAUDE_PLUGIN_ROOT=/Users/alsc/code/sh
|
|
|
106
106
|
|
|
107
107
|
## 生成并合并仓库图谱
|
|
108
108
|
|
|
109
|
-
下面命令会分别进入 `${CLAUDE_PLUGIN_ROOT}/repos/kl-health` 和 `${CLAUDE_PLUGIN_ROOT}/repos/ele-newretail-health-audit` 生成 `graphify-out/graph-main.json`,然后合并到 `${CLAUDE_PLUGIN_ROOT}/graphify-out/graph
|
|
109
|
+
下面命令会分别进入 `${CLAUDE_PLUGIN_ROOT}/repos/kl-health` 和 `${CLAUDE_PLUGIN_ROOT}/repos/ele-newretail-health-audit` 生成 `graphify-out/graph-main.json`,然后合并到 `${CLAUDE_PLUGIN_ROOT}/graphify-out/graph.json`。
|
|
110
110
|
|
|
111
111
|
```bash
|
|
112
|
-
scripts/graph-main-repos.sh --repos-root "${CLAUDE_PLUGIN_ROOT}/repos" --out "${CLAUDE_PLUGIN_ROOT}/graphify-out/graph
|
|
112
|
+
scripts/graph-main-repos.sh --repos-root "${CLAUDE_PLUGIN_ROOT}/repos" --out "${CLAUDE_PLUGIN_ROOT}/graphify-out/graph.json" kl-health ele-newretail-health-audit
|
|
113
113
|
```
|
|
114
114
|
|
|
115
115
|
也可以传入更多 `${CLAUDE_PLUGIN_ROOT}/repos/` 下的仓库名:
|
|
116
116
|
|
|
117
117
|
```bash
|
|
118
118
|
# 健康卡 init all repos
|
|
119
|
-
scripts/graph-main-repos.sh --repos-root "${CLAUDE_PLUGIN_ROOT}/repos" --out "${CLAUDE_PLUGIN_ROOT}/graphify-out/graph
|
|
119
|
+
scripts/graph-main-repos.sh --repos-root "${CLAUDE_PLUGIN_ROOT}/repos" --out "${CLAUDE_PLUGIN_ROOT}/graphify-out/graph.json" ele-newretail-drug ele-newretail-health-task ele-newretail-drug-grow ele-newretail-health-audit ele-newretail-health-client ele-newretail-drug-trade kl-health health-vip-card medicine-unicore p ele-newretail-venus ele-newretail-summaryx china-alsc-sales-eleme-newretail-app
|
|
120
120
|
```
|
|
121
121
|
|
|
122
122
|
```bash
|
|
@@ -124,7 +124,7 @@ scripts/graph-main-repos.sh --repos-root "${CLAUDE_PLUGIN_ROOT}/repos" --out "${
|
|
|
124
124
|
scripts/graph-main-repos.sh \
|
|
125
125
|
--incremental \
|
|
126
126
|
--repos-root "${CLAUDE_PLUGIN_ROOT}/repos" \
|
|
127
|
-
--out "${CLAUDE_PLUGIN_ROOT}/graphify-out/graph
|
|
127
|
+
--out "${CLAUDE_PLUGIN_ROOT}/graphify-out/graph.json" \
|
|
128
128
|
p medicine-unicore
|
|
129
129
|
```
|
|
130
130
|
|
|
@@ -136,7 +136,7 @@ scripts/graph-main-repos.sh \
|
|
|
136
136
|
关于ehealth-member实体的全部链路
|
|
137
137
|
```bash
|
|
138
138
|
graphify main-trace \
|
|
139
|
-
--graph "${CLAUDE_PLUGIN_ROOT}/graphify-out/graph
|
|
139
|
+
--graph "${CLAUDE_PLUGIN_ROOT}/graphify-out/graph.json" \
|
|
140
140
|
--from ehealth-member \
|
|
141
141
|
--max-depth 8
|
|
142
142
|
```
|
|
@@ -144,7 +144,7 @@ graphify main-trace \
|
|
|
144
144
|
选择ehealth-member实体的/shopping/healthCard/createHealthCard 支线链路
|
|
145
145
|
```bash
|
|
146
146
|
graphify main-trace \
|
|
147
|
-
--graph "${CLAUDE_PLUGIN_ROOT}/graphify-out/graph
|
|
147
|
+
--graph "${CLAUDE_PLUGIN_ROOT}/graphify-out/graph.json" \
|
|
148
148
|
--from ehealth-member \
|
|
149
149
|
--api /shopping/healthCard/createHealthCard \
|
|
150
150
|
--max-depth 8
|
|
@@ -154,7 +154,7 @@ graphify main-trace \
|
|
|
154
154
|
|
|
155
155
|
```bash
|
|
156
156
|
graphify main-trace \
|
|
157
|
-
--graph "${CLAUDE_PLUGIN_ROOT}/graphify-out/graph
|
|
157
|
+
--graph "${CLAUDE_PLUGIN_ROOT}/graphify-out/graph.json" \
|
|
158
158
|
--from ehealth-member \
|
|
159
159
|
--max-depth 8 --sources
|
|
160
160
|
```
|
|
@@ -13,17 +13,17 @@ python3 -m pip install -e ./ckgraphify && CLAUDE_PLUGIN_ROOT=/Users/alsc/code/sh
|
|
|
13
13
|
|
|
14
14
|
## 生成并合并仓库图谱
|
|
15
15
|
|
|
16
|
-
下面命令会分别进入 `${CLAUDE_PLUGIN_ROOT}/repos/kl-health` 和 `${CLAUDE_PLUGIN_ROOT}/repos/ele-newretail-health-audit` 生成 `graphify-out/graph-main.json`,然后合并到 `${CLAUDE_PLUGIN_ROOT}/graphify-out/graph
|
|
16
|
+
下面命令会分别进入 `${CLAUDE_PLUGIN_ROOT}/repos/kl-health` 和 `${CLAUDE_PLUGIN_ROOT}/repos/ele-newretail-health-audit` 生成 `graphify-out/graph-main.json`,然后合并到 `${CLAUDE_PLUGIN_ROOT}/graphify-out/graph.json`。
|
|
17
17
|
|
|
18
18
|
```bash
|
|
19
|
-
scripts/graph-main-repos.sh --repos-root "${CLAUDE_PLUGIN_ROOT}/repos" --out "${CLAUDE_PLUGIN_ROOT}/graphify-out/graph
|
|
19
|
+
scripts/graph-main-repos.sh --repos-root "${CLAUDE_PLUGIN_ROOT}/repos" --out "${CLAUDE_PLUGIN_ROOT}/graphify-out/graph.json" kl-health ele-newretail-health-audit
|
|
20
20
|
```
|
|
21
21
|
|
|
22
22
|
也可以传入更多 `${CLAUDE_PLUGIN_ROOT}/repos/` 下的仓库名:
|
|
23
23
|
|
|
24
24
|
```bash
|
|
25
25
|
# 健康卡 init all repos
|
|
26
|
-
scripts/graph-main-repos.sh --repos-root "${CLAUDE_PLUGIN_ROOT}/repos" --out "${CLAUDE_PLUGIN_ROOT}/graphify-out/graph
|
|
26
|
+
scripts/graph-main-repos.sh --repos-root "${CLAUDE_PLUGIN_ROOT}/repos" --out "${CLAUDE_PLUGIN_ROOT}/graphify-out/graph.json" ele-newretail-drug ele-newretail-health-task ele-newretail-drug-grow ele-newretail-health-audit ele-newretail-health-client ele-newretail-drug-trade kl-health health-vip-card medicine-unicore p ele-newretail-venus ele-newretail-summaryx china-alsc-sales-eleme-newretail-app
|
|
27
27
|
```
|
|
28
28
|
|
|
29
29
|
```bash
|
|
@@ -31,7 +31,7 @@ scripts/graph-main-repos.sh --repos-root "${CLAUDE_PLUGIN_ROOT}/repos" --out "${
|
|
|
31
31
|
scripts/graph-main-repos.sh \
|
|
32
32
|
--incremental \
|
|
33
33
|
--repos-root "${CLAUDE_PLUGIN_ROOT}/repos" \
|
|
34
|
-
--out "${CLAUDE_PLUGIN_ROOT}/graphify-out/graph
|
|
34
|
+
--out "${CLAUDE_PLUGIN_ROOT}/graphify-out/graph.json" \
|
|
35
35
|
p medicine-unicore
|
|
36
36
|
```
|
|
37
37
|
|
|
@@ -43,7 +43,7 @@ scripts/graph-main-repos.sh \
|
|
|
43
43
|
关于ehealth-member实体的全部链路
|
|
44
44
|
```bash
|
|
45
45
|
graphify main-trace \
|
|
46
|
-
--graph "${CLAUDE_PLUGIN_ROOT}/graphify-out/graph
|
|
46
|
+
--graph "${CLAUDE_PLUGIN_ROOT}/graphify-out/graph.json" \
|
|
47
47
|
--from ehealth-member \
|
|
48
48
|
--max-depth 8
|
|
49
49
|
```
|
|
@@ -51,7 +51,7 @@ graphify main-trace \
|
|
|
51
51
|
选择ehealth-member实体的/shopping/healthCard/createHealthCard 支线链路
|
|
52
52
|
```bash
|
|
53
53
|
graphify main-trace \
|
|
54
|
-
--graph "${CLAUDE_PLUGIN_ROOT}/graphify-out/graph
|
|
54
|
+
--graph "${CLAUDE_PLUGIN_ROOT}/graphify-out/graph.json" \
|
|
55
55
|
--from ehealth-member \
|
|
56
56
|
--api /shopping/healthCard/createHealthCard \
|
|
57
57
|
--max-depth 8
|
|
@@ -61,7 +61,7 @@ graphify main-trace \
|
|
|
61
61
|
|
|
62
62
|
```bash
|
|
63
63
|
graphify main-trace \
|
|
64
|
-
--graph "${CLAUDE_PLUGIN_ROOT}/graphify-out/graph
|
|
64
|
+
--graph "${CLAUDE_PLUGIN_ROOT}/graphify-out/graph.json" \
|
|
65
65
|
--from ehealth-member \
|
|
66
66
|
--max-depth 8 --sources
|
|
67
67
|
```
|
|
@@ -92,11 +92,6 @@ _PLATFORM_CONFIG: dict[str, dict] = {
|
|
|
92
92
|
}
|
|
93
93
|
|
|
94
94
|
|
|
95
|
-
def _claude_plugin_root() -> Path | None:
|
|
96
|
-
raw = os.environ.get("CLAUDE_PLUGIN_ROOT", "").strip()
|
|
97
|
-
return Path(raw).expanduser().resolve() if raw else None
|
|
98
|
-
|
|
99
|
-
|
|
100
95
|
def _claude_project_dir() -> Path | None:
|
|
101
96
|
raw = os.environ.get("CLAUDE_PROJECT_DIR", "").strip()
|
|
102
97
|
return Path(raw).expanduser().resolve() if raw else None
|
|
@@ -106,9 +101,6 @@ def _default_repos_root() -> Path:
|
|
|
106
101
|
project_dir = _claude_project_dir()
|
|
107
102
|
if project_dir is not None:
|
|
108
103
|
return project_dir / "repos"
|
|
109
|
-
plugin_root = _claude_plugin_root()
|
|
110
|
-
if plugin_root is not None:
|
|
111
|
-
return plugin_root / "repos"
|
|
112
104
|
return Path.home() / ".graphify" / "repos"
|
|
113
105
|
|
|
114
106
|
|
|
@@ -126,11 +118,7 @@ def install(platform: str = "claude") -> None:
|
|
|
126
118
|
print(f"error: {cfg['skill_file']} not found in package - reinstall ckgraphify", file=sys.stderr)
|
|
127
119
|
sys.exit(1)
|
|
128
120
|
|
|
129
|
-
|
|
130
|
-
installing_to_plugin = plugin_root is not None
|
|
131
|
-
if plugin_root is not None:
|
|
132
|
-
skill_dst = plugin_root / "skills" / "ckgraphify" / "SKILL.md"
|
|
133
|
-
elif platform == "claude" and os.environ.get("CLAUDE_CONFIG_DIR"):
|
|
121
|
+
if platform == "claude" and os.environ.get("CLAUDE_CONFIG_DIR"):
|
|
134
122
|
_claude_base = Path(os.environ["CLAUDE_CONFIG_DIR"])
|
|
135
123
|
skill_dst = _claude_base / "skills" / "ckgraphify" / "SKILL.md"
|
|
136
124
|
else:
|
|
@@ -149,7 +137,7 @@ def install(platform: str = "claude") -> None:
|
|
|
149
137
|
(skill_dst.parent / ".ckgraphify_version").write_text(__version__, encoding="utf-8")
|
|
150
138
|
print(f" skill installed -> {skill_dst}")
|
|
151
139
|
|
|
152
|
-
if cfg["claude_md"]
|
|
140
|
+
if cfg["claude_md"]:
|
|
153
141
|
# Register in ~/.claude/CLAUDE.md (Claude Code only)
|
|
154
142
|
claude_md = Path.home() / ".claude" / "CLAUDE.md"
|
|
155
143
|
if claude_md.exists():
|
|
@@ -163,9 +151,6 @@ def install(platform: str = "claude") -> None:
|
|
|
163
151
|
claude_md.parent.mkdir(parents=True, exist_ok=True)
|
|
164
152
|
claude_md.write_text(_SKILL_REGISTRATION.lstrip(), encoding="utf-8")
|
|
165
153
|
print(f" CLAUDE.md -> created at {claude_md}")
|
|
166
|
-
elif installing_to_plugin:
|
|
167
|
-
print(f" plugin root -> {plugin_root}")
|
|
168
|
-
|
|
169
154
|
# Refresh version stamps in all other previously-installed skill dirs so
|
|
170
155
|
# stale-version warnings don't fire for platforms not explicitly re-installed.
|
|
171
156
|
_refresh_all_version_stamps()
|
|
@@ -485,7 +470,6 @@ def _clone_repo(url: str, branch: str | None = None, out_dir: Path | None = None
|
|
|
485
470
|
|
|
486
471
|
Clones into ~/.graphify/repos/<owner>/<repo> by default so repeated
|
|
487
472
|
runs on the same URL reuse the existing clone (git pull instead of clone).
|
|
488
|
-
In Claude Code plugin mode, the cache lives under ${CLAUDE_PLUGIN_ROOT}/repos.
|
|
489
473
|
"""
|
|
490
474
|
import subprocess as _sp
|
|
491
475
|
import re as _re
|
|
@@ -1330,9 +1314,9 @@ def main() -> None:
|
|
|
1330
1314
|
sys.exit(1)
|
|
1331
1315
|
else:
|
|
1332
1316
|
graph_paths.append(Path(a)); i += 1
|
|
1333
|
-
if len(graph_paths) <
|
|
1317
|
+
if len(graph_paths) < 1:
|
|
1334
1318
|
print(
|
|
1335
|
-
"Usage: graphify merge-main-graphs <graph-main1.json>
|
|
1319
|
+
"Usage: graphify merge-main-graphs <graph-main1.json> [graph-main2.json ...] "
|
|
1336
1320
|
"[--out graph-main-merged.json] [--report report.md]",
|
|
1337
1321
|
file=sys.stderr,
|
|
1338
1322
|
)
|
|
@@ -1887,10 +1871,6 @@ def main() -> None:
|
|
|
1887
1871
|
i += 1
|
|
1888
1872
|
else:
|
|
1889
1873
|
i += 1
|
|
1890
|
-
if repos_root is None:
|
|
1891
|
-
plugin_root = _claude_plugin_root()
|
|
1892
|
-
if plugin_root is not None:
|
|
1893
|
-
repos_root = plugin_root / "repos"
|
|
1894
1874
|
if repos_root is None:
|
|
1895
1875
|
print(
|
|
1896
1876
|
"Usage: graphify bridge-mtop --repos-root <path> [--graph-in in.json] "
|
|
@@ -300,9 +300,6 @@ def find_kg_banks_root(start: Path | None = None) -> Path | None:
|
|
|
300
300
|
|
|
301
301
|
|
|
302
302
|
def default_business_map_path(start: Path | None = None) -> Path:
|
|
303
|
-
plugin_root = os.environ.get("CLAUDE_PLUGIN_ROOT", "").strip()
|
|
304
|
-
if plugin_root:
|
|
305
|
-
return Path(plugin_root).expanduser().resolve() / "graphify-out" / "business-map.json"
|
|
306
303
|
root = find_kg_banks_root(start)
|
|
307
304
|
if root is not None:
|
|
308
305
|
return root / "graphify-out" / "business-map.json"
|
|
@@ -342,18 +339,6 @@ def resolve_bound_graph_path(map_path: Path, graph_ref: str) -> Path:
|
|
|
342
339
|
|
|
343
340
|
|
|
344
341
|
def default_business_graph_path(map_path: Path, start: Path | None = None) -> Path | None:
|
|
345
|
-
plugin_root = os.environ.get("CLAUDE_PLUGIN_ROOT", "").strip()
|
|
346
|
-
if plugin_root:
|
|
347
|
-
graphify_out = Path(plugin_root).expanduser().resolve() / "graphify-out"
|
|
348
|
-
hc_graph = graphify_out / "graph-hc.json"
|
|
349
|
-
if hc_graph.exists():
|
|
350
|
-
return hc_graph
|
|
351
|
-
candidates = sorted(
|
|
352
|
-
p for p in graphify_out.glob("graph*.json")
|
|
353
|
-
if p.name != "business-map.json"
|
|
354
|
-
)
|
|
355
|
-
return candidates[0] if candidates else None
|
|
356
|
-
|
|
357
342
|
if Path(map_path).exists():
|
|
358
343
|
graph_ref = _business_map_graph_ref(load_business_map(Path(map_path)))
|
|
359
344
|
if graph_ref:
|
|
@@ -3,6 +3,7 @@ from __future__ import annotations
|
|
|
3
3
|
import json
|
|
4
4
|
import os
|
|
5
5
|
import re
|
|
6
|
+
import hashlib
|
|
6
7
|
from collections import deque
|
|
7
8
|
from dataclasses import dataclass
|
|
8
9
|
from datetime import datetime, timezone
|
|
@@ -12,6 +13,7 @@ from urllib.parse import urlparse
|
|
|
12
13
|
from graphify.graph_main_frontend_sdk import (
|
|
13
14
|
collect_sdk_dependencies,
|
|
14
15
|
collect_sdk_exports,
|
|
16
|
+
collect_sdk_internal_links,
|
|
15
17
|
detect_frontend_sdk_repo,
|
|
16
18
|
)
|
|
17
19
|
from graphify.repo_registry import repo_metadata_for_root
|
|
@@ -1132,6 +1134,13 @@ def build_graph_main_frontend(*, repo_root: Path, out_path: Path) -> GraphMainFr
|
|
|
1132
1134
|
edge_ids.add(k)
|
|
1133
1135
|
edges.append(e)
|
|
1134
1136
|
|
|
1137
|
+
def unique_node_id(prefix: str, suffix: str, canonical: str) -> str:
|
|
1138
|
+
base = f"{prefix}__{_safe_id(suffix)}"
|
|
1139
|
+
if base not in node_ids:
|
|
1140
|
+
return base
|
|
1141
|
+
digest = hashlib.sha1(canonical.encode("utf-8")).hexdigest()[:8]
|
|
1142
|
+
return f"{base}_{digest}"
|
|
1143
|
+
|
|
1135
1144
|
page_by_key: dict[str, str] = {}
|
|
1136
1145
|
component_by_key: dict[str, str] = {}
|
|
1137
1146
|
mtop_by_key: dict[str, str] = {}
|
|
@@ -1232,7 +1241,7 @@ def build_graph_main_frontend(*, repo_root: Path, out_path: Path) -> GraphMainFr
|
|
|
1232
1241
|
if canonical in sdk_export_by_key:
|
|
1233
1242
|
return sdk_export_by_key[canonical]
|
|
1234
1243
|
suffix = canonical.split(":", 1)[-1]
|
|
1235
|
-
nid =
|
|
1244
|
+
nid = unique_node_id("sdk_export", suffix, canonical)
|
|
1236
1245
|
add_node(
|
|
1237
1246
|
{
|
|
1238
1247
|
"id": nid,
|
|
@@ -1266,7 +1275,7 @@ def build_graph_main_frontend(*, repo_root: Path, out_path: Path) -> GraphMainFr
|
|
|
1266
1275
|
if canonical in sdk_dependency_by_key:
|
|
1267
1276
|
return sdk_dependency_by_key[canonical]
|
|
1268
1277
|
suffix = canonical.split(":", 1)[-1]
|
|
1269
|
-
nid =
|
|
1278
|
+
nid = unique_node_id("sdk_dependency", suffix, canonical)
|
|
1270
1279
|
add_node(
|
|
1271
1280
|
{
|
|
1272
1281
|
"id": nid,
|
|
@@ -1768,7 +1777,8 @@ def build_graph_main_frontend(*, repo_root: Path, out_path: Path) -> GraphMainFr
|
|
|
1768
1777
|
mode = "frontend-sdk"
|
|
1769
1778
|
detection["mode"] = mode
|
|
1770
1779
|
detection["sdk_detection"] = sdk_detection.as_dict()
|
|
1771
|
-
|
|
1780
|
+
sdk_exports = collect_sdk_exports(repo_root)
|
|
1781
|
+
for export in sdk_exports:
|
|
1772
1782
|
ensure_sdk_export(
|
|
1773
1783
|
kind=export.kind,
|
|
1774
1784
|
label=export.label,
|
|
@@ -1779,6 +1789,25 @@ def build_graph_main_frontend(*, repo_root: Path, out_path: Path) -> GraphMainFr
|
|
|
1779
1789
|
source_file=export.source_file,
|
|
1780
1790
|
source_location=export.source_location,
|
|
1781
1791
|
)
|
|
1792
|
+
for link in collect_sdk_internal_links(repo_root, sdk_exports):
|
|
1793
|
+
source_nid = sdk_export_by_key.get(link.source_key)
|
|
1794
|
+
target_nid = sdk_export_by_key.get(link.target_key)
|
|
1795
|
+
if not source_nid or not target_nid:
|
|
1796
|
+
continue
|
|
1797
|
+
add_edge(
|
|
1798
|
+
{
|
|
1799
|
+
"source": source_nid,
|
|
1800
|
+
"target": target_nid,
|
|
1801
|
+
"relation": link.relation,
|
|
1802
|
+
"confidence": "EXTRACTED",
|
|
1803
|
+
"confidence_score": 1.0,
|
|
1804
|
+
"source_file": link.source_file,
|
|
1805
|
+
"source_location": link.source_location,
|
|
1806
|
+
"weight": 1.0,
|
|
1807
|
+
"evidence": link.evidence,
|
|
1808
|
+
**({"resolution_kind": link.resolution_kind} if link.resolution_kind else {}),
|
|
1809
|
+
}
|
|
1810
|
+
)
|
|
1782
1811
|
else:
|
|
1783
1812
|
detection["sdk_detection"] = sdk_detection.as_dict()
|
|
1784
1813
|
propagated_file_owners = propagate_file_owners(max_depth=3)
|