tscode-kg 0.2.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.
@@ -0,0 +1,369 @@
1
+ """
2
+ viz3d_timeline.py — Temporal Metrics Visualization for TypeScriptKG Snapshots
3
+
4
+ Visualizes codebase metrics evolution across commits using 3D plotting.
5
+ Shows trends in nodes, edges, coverage, and critical issues over time.
6
+
7
+ Features:
8
+ - Interactive 3D line charts for metric trends
9
+ - Side-by-side comparison of multiple metrics
10
+ - Commit-based X-axis with version labels
11
+ - Color-coded risk assessment (green→yellow→red)
12
+ - Hover tooltips with snapshot details
13
+ """
14
+
15
+ from __future__ import annotations
16
+
17
+ from pathlib import Path
18
+ from typing import Any
19
+
20
+ import plotly.graph_objects as go
21
+ import plotly.subplots as subplots
22
+
23
+ from tscode_kg.snapshots import SnapshotManager
24
+
25
+
26
+ def load_snapshots_timeline(snapshots_dir: Path) -> dict[str, Any]:
27
+ """
28
+ Load all snapshots and extract timeline data.
29
+
30
+ :param snapshots_dir: Path to .tscodekg/snapshots/
31
+ :return: Dict with timeline data indexed by metric name.
32
+ """
33
+ mgr = SnapshotManager(snapshots_dir)
34
+ snapshots = mgr.list_snapshots() # Chronological order
35
+
36
+ if not snapshots:
37
+ return {}
38
+
39
+ # Extract timeline data
40
+ timeline: dict[str, list[Any]] = {
41
+ "commits": [],
42
+ "versions": [],
43
+ "timestamps": [],
44
+ "nodes": [],
45
+ "edges": [],
46
+ "coverage": [],
47
+ "critical_issues": [],
48
+ "complexity_median": [],
49
+ }
50
+
51
+ for snap in snapshots:
52
+ metrics = snap.get("metrics", {})
53
+ timeline["commits"].append(snap["key"][:7]) # Short hash
54
+ timeline["versions"].append(snap["version"])
55
+ timeline["timestamps"].append(snap["timestamp"])
56
+ timeline["nodes"].append(metrics.get("total_nodes", 0))
57
+ timeline["edges"].append(metrics.get("total_edges", 0))
58
+ timeline["coverage"].append((metrics.get("docstring_coverage") or 0.0) * 100) # Percentage
59
+ timeline["critical_issues"].append(metrics.get("critical_issues", 0))
60
+ timeline["complexity_median"].append(metrics.get("complexity_median", 0))
61
+
62
+ return timeline
63
+
64
+
65
+ def create_timeline_figure(snapshots_dir: Path) -> go.Figure:
66
+ """
67
+ Create interactive 3D timeline visualization.
68
+
69
+ Shows 4 metrics:
70
+ 1. Nodes (absolute count)
71
+ 2. Edges (absolute count)
72
+ 3. Coverage (percentage)
73
+ 4. Critical Issues (count)
74
+
75
+ :param snapshots_dir: Path to .tscodekg/snapshots/
76
+ :return: Plotly Figure ready for display.
77
+ """
78
+ timeline = load_snapshots_timeline(snapshots_dir)
79
+
80
+ if not timeline or not timeline["commits"]:
81
+ return go.Figure().add_annotation(text="No snapshots found")
82
+
83
+ # Create subplot figure with 2x2 layout
84
+ fig = subplots.make_subplots(
85
+ rows=2,
86
+ cols=2,
87
+ subplot_titles=("Total Nodes", "Total Edges", "JSDoc Coverage %", "Critical Issues"),
88
+ specs=[
89
+ [{"secondary_y": False}, {"secondary_y": False}],
90
+ [{"secondary_y": False}, {"secondary_y": False}],
91
+ ],
92
+ vertical_spacing=0.15,
93
+ horizontal_spacing=0.12,
94
+ )
95
+
96
+ # Hover text for all traces
97
+ hover_text = [
98
+ f"<b>{v}</b> ({c})<br>Timestamp: {t}"
99
+ for v, c, t in zip(timeline["versions"], timeline["commits"], timeline["timestamps"])
100
+ ]
101
+
102
+ # 1. Total Nodes (green trend)
103
+ fig.add_trace(
104
+ go.Scatter(
105
+ x=timeline["commits"],
106
+ y=timeline["nodes"],
107
+ mode="lines+markers",
108
+ name="Nodes",
109
+ line=dict(color="#22c55e", width=3),
110
+ marker=dict(size=8),
111
+ hovertemplate="<b>Nodes:</b> %{y}<br>" + "%{customdata}<extra></extra>",
112
+ customdata=hover_text,
113
+ ),
114
+ row=1,
115
+ col=1,
116
+ )
117
+
118
+ # 2. Total Edges (blue trend)
119
+ fig.add_trace(
120
+ go.Scatter(
121
+ x=timeline["commits"],
122
+ y=timeline["edges"],
123
+ mode="lines+markers",
124
+ name="Edges",
125
+ line=dict(color="#3b82f6", width=3),
126
+ marker=dict(size=8),
127
+ hovertemplate="<b>Edges:</b> %{y}<br>" + "%{customdata}<extra></extra>",
128
+ customdata=hover_text,
129
+ ),
130
+ row=1,
131
+ col=2,
132
+ )
133
+
134
+ # 3. Coverage % (cyan trend, with target line)
135
+ fig.add_trace(
136
+ go.Scatter(
137
+ x=timeline["commits"],
138
+ y=timeline["coverage"],
139
+ mode="lines+markers",
140
+ name="Coverage %",
141
+ line=dict(color="#06b6d4", width=3),
142
+ marker=dict(size=8),
143
+ hovertemplate="<b>Coverage:</b> %{y:.1f}%<br>" + "%{customdata}<extra></extra>",
144
+ customdata=hover_text,
145
+ ),
146
+ row=2,
147
+ col=1,
148
+ )
149
+
150
+ # Add 90% target line for coverage
151
+ fig.add_hline(
152
+ y=90,
153
+ line_dash="dash",
154
+ line_color="orange",
155
+ annotation_text="90% Target",
156
+ row=2,
157
+ col=1,
158
+ )
159
+
160
+ # 4. Critical Issues (red risk indicator, lower is better)
161
+ fig.add_trace(
162
+ go.Scatter(
163
+ x=timeline["commits"],
164
+ y=timeline["critical_issues"],
165
+ mode="lines+markers",
166
+ name="Critical Issues",
167
+ line=dict(color="#ef4444", width=3),
168
+ marker=dict(size=8),
169
+ hovertemplate="<b>Issues:</b> %{y}<br>" + "%{customdata}<extra></extra>",
170
+ customdata=hover_text,
171
+ ),
172
+ row=2,
173
+ col=2,
174
+ )
175
+
176
+ # Update layout
177
+ fig.update_layout(
178
+ title_text=(
179
+ "<b>TypeScriptKG Temporal Metrics Evolution</b><br><sub>Snapshots across commits</sub>"
180
+ ),
181
+ title_font_size=20,
182
+ height=800,
183
+ width=1400,
184
+ hovermode="x unified",
185
+ template="plotly_dark",
186
+ showlegend=False,
187
+ )
188
+
189
+ # Update X axes
190
+ for i in range(1, 5):
191
+ row = (i - 1) // 2 + 1
192
+ col = (i - 1) % 2 + 1
193
+ fig.update_xaxes(title_text="Commit", row=row, col=col)
194
+
195
+ # Update Y axes
196
+ fig.update_yaxes(title_text="Count", row=1, col=1)
197
+ fig.update_yaxes(title_text="Count", row=1, col=2)
198
+ fig.update_yaxes(title_text="Percentage", row=2, col=1)
199
+ fig.update_yaxes(title_text="Count", row=2, col=2)
200
+
201
+ return fig
202
+
203
+
204
+ def create_3d_timeline_figure(snapshots_dir: Path) -> go.Figure:
205
+ """
206
+ Create 3D surface plot showing metrics evolution.
207
+
208
+ X: Commit index
209
+ Y: Metric value (normalized)
210
+ Z: Different metrics stacked
211
+
212
+ :param snapshots_dir: Path to .tscodekg/snapshots/
213
+ :return: Plotly 3D Figure.
214
+ """
215
+ timeline = load_snapshots_timeline(snapshots_dir)
216
+
217
+ if not timeline or not timeline["commits"]:
218
+ return go.Figure().add_annotation(text="No snapshots found")
219
+
220
+ # Normalize metrics to 0-100 scale for comparison
221
+ max_nodes = max(timeline["nodes"]) if timeline["nodes"] else 100
222
+ max_edges = max(timeline["edges"]) if timeline["edges"] else 100
223
+ max_issues = max(timeline["critical_issues"]) if timeline["critical_issues"] else 1
224
+
225
+ normalized_nodes = [n / max_nodes * 100 for n in timeline["nodes"]]
226
+ normalized_edges = [e / max_edges * 100 for e in timeline["edges"]]
227
+ normalized_coverage = timeline["coverage"] # Already 0-100
228
+ normalized_issues = [i / max_issues * 100 for i in timeline["critical_issues"]]
229
+
230
+ fig = go.Figure()
231
+
232
+ # Commit indices for X axis
233
+ commits_idx = list(range(len(timeline["commits"])))
234
+
235
+ # Add surface traces for each metric
236
+ # Nodes (green)
237
+ fig.add_trace(
238
+ go.Scatter3d(
239
+ x=commits_idx,
240
+ y=normalized_nodes,
241
+ z=[0] * len(commits_idx),
242
+ mode="lines+markers",
243
+ name="Nodes (normalized)",
244
+ line=dict(color="#22c55e", width=4),
245
+ marker=dict(size=6),
246
+ hovertemplate="<b>Commit:</b> %{customdata}<br><b>Nodes:</b> %{y:.0f}%<extra></extra>",
247
+ customdata=timeline["commits"],
248
+ )
249
+ )
250
+
251
+ # Edges (blue)
252
+ fig.add_trace(
253
+ go.Scatter3d(
254
+ x=commits_idx,
255
+ y=normalized_edges,
256
+ z=[1] * len(commits_idx),
257
+ mode="lines+markers",
258
+ name="Edges (normalized)",
259
+ line=dict(color="#3b82f6", width=4),
260
+ marker=dict(size=6),
261
+ hovertemplate="<b>Commit:</b> %{customdata}<br><b>Edges:</b> %{y:.0f}%<extra></extra>",
262
+ customdata=timeline["commits"],
263
+ )
264
+ )
265
+
266
+ # Coverage (cyan)
267
+ fig.add_trace(
268
+ go.Scatter3d(
269
+ x=commits_idx,
270
+ y=normalized_coverage,
271
+ z=[2] * len(commits_idx),
272
+ mode="lines+markers",
273
+ name="Coverage %",
274
+ line=dict(color="#06b6d4", width=4),
275
+ marker=dict(size=6),
276
+ hovertemplate=(
277
+ "<b>Commit:</b> %{customdata}<br><b>Coverage:</b> %{y:.0f}%<extra></extra>"
278
+ ),
279
+ customdata=timeline["commits"],
280
+ )
281
+ )
282
+
283
+ # Critical Issues (red - inverted so lower is up)
284
+ fig.add_trace(
285
+ go.Scatter3d(
286
+ x=commits_idx,
287
+ y=[100 - v for v in normalized_issues], # Invert so lower is better (up)
288
+ z=[3] * len(commits_idx),
289
+ mode="lines+markers",
290
+ name="Health (inverse issues)",
291
+ line=dict(color="#ef4444", width=4),
292
+ marker=dict(size=6),
293
+ hovertemplate="<b>Commit:</b> %{customdata}<br><b>Health:</b> %{y:.0f}%<extra></extra>",
294
+ customdata=timeline["commits"],
295
+ )
296
+ )
297
+
298
+ fig.update_layout(
299
+ title="<b>TypeScriptKG 3D Temporal Metrics</b><br><sub>Evolution across commits</sub>",
300
+ scene=dict(
301
+ xaxis_title="Commit Index",
302
+ yaxis_title="Metric (0-100%)",
303
+ zaxis=dict(
304
+ title="Metric Type",
305
+ tickvals=[0, 1, 2, 3],
306
+ ticktext=["Nodes", "Edges", "Coverage", "Health"],
307
+ ),
308
+ camera=dict(
309
+ eye=dict(x=1.5, y=1.5, z=1.3),
310
+ ),
311
+ ),
312
+ width=1200,
313
+ height=800,
314
+ template="plotly_dark",
315
+ hovermode="closest",
316
+ )
317
+
318
+ return fig
319
+
320
+
321
+ def display_timeline_summary(snapshots_dir: Path) -> str:
322
+ """
323
+ Generate text summary of timeline metrics.
324
+
325
+ :param snapshots_dir: Path to .tscodekg/snapshots/
326
+ :return: Formatted summary string.
327
+ """
328
+ timeline = load_snapshots_timeline(snapshots_dir)
329
+
330
+ if not timeline or not timeline["commits"]:
331
+ return "No snapshots found"
332
+
333
+ # Calculate deltas
334
+ nodes_delta = timeline["nodes"][-1] - timeline["nodes"][0]
335
+ edges_delta = timeline["edges"][-1] - timeline["edges"][0]
336
+ coverage_delta = timeline["coverage"][-1] - timeline["coverage"][0]
337
+ issues_delta = timeline["critical_issues"][-1] - timeline["critical_issues"][0]
338
+
339
+ summary = f"""
340
+ +================================================================+
341
+ | TypeScriptKG Temporal Metrics Summary |
342
+ +================================================================+
343
+ | Snapshots Captured: {len(timeline["commits"]):<41} |
344
+ | Time Range: {timeline["commits"][0]} → {timeline["commits"][-1]:<44} |
345
+ | Versions: {timeline["versions"][0]} → {timeline["versions"][-1]:<48} |
346
+ +================================================================+
347
+ | NODES: |
348
+ | First: {timeline["nodes"][0]:<47} |
349
+ | Latest: {timeline["nodes"][-1]:<47} |
350
+ | Δ: {f"{nodes_delta:+d}":<46} |
351
+ +================================================================+
352
+ | EDGES: |
353
+ | First: {timeline["edges"][0]:<47} |
354
+ | Latest: {timeline["edges"][-1]:<47} |
355
+ | Δ: {f"{edges_delta:+d}":<46} |
356
+ +================================================================+
357
+ | JSDOC COVERAGE: |
358
+ | First: {f"{timeline['coverage'][0]:.1f}%":<46} |
359
+ | Latest: {f"{timeline['coverage'][-1]:.1f}%":<46} |
360
+ | Δ: {f"{coverage_delta:+.1f}%":<46} |
361
+ +================================================================+
362
+ | CRITICAL ISSUES: |
363
+ | First: {timeline["critical_issues"][0]:<47} |
364
+ | Latest: {timeline["critical_issues"][-1]:<47} |
365
+ | Δ: {f"{issues_delta:+d}":<46} |
366
+ | Trend: {"Improving" if issues_delta <= 0 else "Regressing":<43} |
367
+ +================================================================+
368
+ """
369
+ return summary
@@ -0,0 +1,196 @@
1
+ Metadata-Version: 2.4
2
+ Name: tscode-kg
3
+ Version: 0.2.0
4
+ Summary: Knowledge graph for TypeScript/JavaScript codebases — AST extraction, hybrid semantic+structural search
5
+ License-Expression: Elastic-2.0
6
+ License-File: LICENSE
7
+ Keywords: knowledge-graph,typescript,javascript,ast,sqlite-vec,sqlite,semantic-search
8
+ Author: Eric G. Suchanek, PhD
9
+ Author-email: suchanek@mac.com
10
+ Requires-Python: >=3.12,<3.14
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
14
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Provides-Extra: dev
19
+ Provides-Extra: kgdeps
20
+ Provides-Extra: viz
21
+ Provides-Extra: viz3d
22
+ Requires-Dist: PyQt5 (>=5.15.11,<5.16) ; extra == "viz3d"
23
+ Requires-Dist: click (>=8.1.0,<9)
24
+ Requires-Dist: detect-secrets (>=1.5.0) ; extra == "dev"
25
+ Requires-Dist: doc-kg (>=0.18.1) ; extra == "kgdeps"
26
+ Requires-Dist: kgmodule-utils[semantic,sqlite-vec] (>=0.8.0)
27
+ Requires-Dist: markdown (>=3.10,<3.11) ; extra == "viz3d"
28
+ Requires-Dist: mcp (>=1.0.0,<2)
29
+ Requires-Dist: networkx (>=3.0)
30
+ Requires-Dist: param (>=2.4,<2.5) ; extra == "viz3d"
31
+ Requires-Dist: plotly (>=6.8.0,<6.9) ; extra == "viz"
32
+ Requires-Dist: pre-commit (>=4.5.1) ; extra == "dev"
33
+ Requires-Dist: pycode-kg (>=0.20.0,<0.21) ; extra == "dev"
34
+ Requires-Dist: pycode-kg (>=0.20.0,<0.21) ; extra == "kgdeps"
35
+ Requires-Dist: pylint (>=4.0.5) ; extra == "dev"
36
+ Requires-Dist: pytest (>=8.0.0) ; extra == "dev"
37
+ Requires-Dist: pytest-cov (>=5.0.0) ; extra == "dev"
38
+ Requires-Dist: pyvis (>=0.3.2,<0.4) ; extra == "viz"
39
+ Requires-Dist: pyvista (>=0.48.4,<0.49) ; extra == "viz3d"
40
+ Requires-Dist: pyvistaqt (>=0.12,<0.13) ; extra == "viz3d"
41
+ Requires-Dist: rich (>=14.3.3,<15)
42
+ Requires-Dist: ruff (>=0.4.0) ; extra == "dev"
43
+ Requires-Dist: streamlit (>=1.59.0,<1.60) ; extra == "viz"
44
+ Requires-Dist: trame-vtk (>=2.11.8,<2.12) ; extra == "viz3d"
45
+ Requires-Dist: tree-sitter (>=0.25.0)
46
+ Requires-Dist: tree-sitter-typescript (>=0.23.2)
47
+ Requires-Dist: ty (>=0.0.41) ; extra == "dev"
48
+ Project-URL: Homepage, https://github.com/Flux-Frontiers/tscode_kg
49
+ Project-URL: Repository, https://github.com/Flux-Frontiers/tscode_kg
50
+ Description-Content-Type: text/markdown
51
+
52
+ # TypeScriptKG
53
+
54
+ Knowledge graph for TypeScript and JavaScript codebases — deterministic AST extraction, hybrid semantic + structural search.
55
+
56
+ ## Overview
57
+
58
+ TypeScriptKG builds a queryable knowledge graph from TypeScript/JavaScript source code using:
59
+
60
+ - **tree-sitter** for deterministic, parser-level AST extraction (no LLM inference during indexing)
61
+ - **SQLite** for the structural graph (nodes, edges, provenance)
62
+ - **sqlite-vec** for the semantic vector index (embeddings via `BAAI/bge-small-en-v1.5`)
63
+ - **Hybrid retrieval**: semantic seed → graph hop expansion → lexical re-ranking
64
+
65
+ ## Node types
66
+
67
+ | Kind | Description |
68
+ |------|-------------|
69
+ | `module` | Every indexed `.ts`/`.tsx`/`.js`/`.jsx` file |
70
+ | `class` | Class declaration |
71
+ | `interface` | TypeScript interface |
72
+ | `type_alias` | TypeScript type alias |
73
+ | `enum` | TypeScript enum |
74
+ | `namespace` | TypeScript namespace / module declaration |
75
+ | `function` | Module-level function (declaration or `const` arrow) |
76
+ | `method` | Method or accessor within a class |
77
+ | `symbol` | Unresolved external import stub |
78
+
79
+ ## Edge types
80
+
81
+ | Relation | Description |
82
+ |----------|-------------|
83
+ | `CONTAINS` | module → class/function/interface… |
84
+ | `IMPORTS` | module → module |
85
+ | `CALLS` | function/method → function |
86
+ | `INHERITS` | class extends class |
87
+ | `IMPLEMENTS` | class implements interface |
88
+ | `EXTENDS` | interface extends interface |
89
+
90
+ ## Quick start
91
+
92
+ ```bash
93
+ pip install tscode-kg
94
+
95
+ # First-time setup (downloads model, builds graph, installs hooks, snapshots)
96
+ tscodekg init --repo /path/to/ts-repo
97
+
98
+ # Build the KG for a TypeScript repo
99
+ tscodekg build --repo /path/to/ts-repo
100
+
101
+ # Query
102
+ tscodekg query "authentication middleware"
103
+ tscodekg pack "error handling utilities" --hop 2
104
+
105
+ # Thorough architectural analysis (fan-in/out, CodeRank, SIR centrality, JSDoc coverage)
106
+ tscodekg analyze /path/to/ts-repo --report analysis.md
107
+
108
+ # Structural rankings and node explanations
109
+ tscodekg centrality --top 20
110
+ tscodekg bridges --top 20
111
+ tscodekg framework-nodes --top 20
112
+ tscodekg explain "fn:src/utils/helpers.ts:formatDate"
113
+
114
+ # Temporal metric snapshots
115
+ tscodekg snapshot save --repo /path/to/ts-repo
116
+ tscodekg snapshot list
117
+
118
+ # Interactive visualizers (install extras: tscode-kg[viz] / tscode-kg[viz3d])
119
+ tscodekg viz --port 8500
120
+ tscodekg viz3d --layout allium
121
+ tscodekg viz-timeline --type 2d
122
+
123
+ # Install the pre-commit snapshot hook
124
+ tscodekg install-hooks --repo /path/to/ts-repo
125
+
126
+ # MCP server (Claude Desktop, Cursor, etc.)
127
+ tscodekg mcp --repo /path/to/ts-repo
128
+ ```
129
+
130
+ Each subcommand is also available as a dedicated script alias — `tscodekg-init`,
131
+ `tscodekg-build`, `tscodekg-query`, `tscodekg-pack`, `tscodekg-analyze`,
132
+ `tscodekg-centrality`, `tscodekg-viz`, `tscodekg-viz3d`, `tscodekg-viz-timeline`,
133
+ `tscodekg-install-hooks`, `tscodekg-download-model`, `tscodekg-mcp` — both forms
134
+ are equivalent.
135
+
136
+ ## MCP tools
137
+
138
+ The MCP server exposes the full PyCodeKG toolkit, applied to TypeScript/JavaScript
139
+ codebases: `graph_stats`, `query_codebase`, `pack_snippets`, `callers`, `get_node`,
140
+ `list_nodes`, `find_node`, `centrality`, `bridge_centrality`, `framework_nodes`,
141
+ `find_definition_at`, `analyze_repo`, `explain`, `rank_nodes`, `query_ranked`,
142
+ `explain_rank`, `snapshot_list`, `snapshot_show`, and `snapshot_diff`.
143
+
144
+ See `docs/MCP.md` for setup and `docs/CHEATSHEET.md` for a query cookbook.
145
+ Repo-local Claude Code skills live in `skills/`.
146
+
147
+ ## Snapshots & git hook
148
+
149
+ `tscodekg snapshot save` captures graph metrics (nodes, edges, JSDoc coverage,
150
+ issues, hotspots) keyed by git tree hash into `.tscodekg/snapshots/`, with
151
+ deltas computed against the previous and baseline snapshots.
152
+ `tscodekg install-hooks` installs a pre-commit hook that rebuilds the index,
153
+ captures a snapshot, stages the snapshot directory, and then runs the
154
+ pre-commit framework checks — so every commit records the state of the
155
+ knowledge graph. Skip it for one commit with `TSCODEKG_SKIP_SNAPSHOT=1`.
156
+
157
+ ## Python API
158
+
159
+ ```python
160
+ from tscode_kg import TypeScriptKG
161
+
162
+ kg = TypeScriptKG(repo_root="/path/to/ts-repo")
163
+ stats = kg.build(wipe=True)
164
+
165
+ result = kg.query("authentication middleware", k=8)
166
+ result.print_summary()
167
+
168
+ pack = kg.pack("error handling", k=8, hop=1)
169
+ pack.save("context.md")
170
+ ```
171
+
172
+ ## Architecture
173
+
174
+ TypeScriptKG is a domain implementation of the `KGModule` base class from `kgmodule-utils`.
175
+ Only the TypeScript/JS-specific extraction layer is implemented here — all generic
176
+ infrastructure (SQLite, sqlite-vec, hybrid query, snippet packing) is inherited from
177
+ `KGModule`.
178
+
179
+ ## Configuration
180
+
181
+ In your project's `pyproject.toml`:
182
+
183
+ ```toml
184
+ [tool.tscodekg]
185
+ include = ["src"] # top-level dirs to index (empty = all)
186
+ exclude = ["__tests__"] # extra dirs to skip
187
+ ```
188
+
189
+ ## Author
190
+
191
+ Eric G. Suchanek, PhD — Flux Frontiers
192
+
193
+ ## License
194
+
195
+ Elastic-2.0
196
+
@@ -0,0 +1,37 @@
1
+ tscode_kg/__init__.py,sha256=cdUlNY7uKea53Cvgc7Ha4cR5EBzxwwbJX2x2BPDiqEo,1035
2
+ tscode_kg/__main__.py,sha256=FiCO653Mu7_vJ6SCARqROXhpCknekM9EhCu2giHjzcw,129
3
+ tscode_kg/analysis.py,sha256=A-Ba4v5OoAD9gircdXDgVfIeQCPr3lDR0aOGRvm2tkM,76816
4
+ tscode_kg/app.py,sha256=_9fPufwGQUGNU9mTAB_6HMqmlsvb2OnDTsfh27mVejE,46162
5
+ tscode_kg/bridge.py,sha256=Ic_mswPTil1aDZlIe2GqMoSoMI_0Rrs2aAfMgrLl1BQ,4366
6
+ tscode_kg/centrality.py,sha256=52FUx8NZZSB2iztO04UoZq6FKnkhhYbL6zrhWSE8FKo,16292
7
+ tscode_kg/cli/__init__.py,sha256=bTtLOOv9P0WCVQShmlTp_xQz8IcNKuJncDYNv-A9v5o,32
8
+ tscode_kg/cli/cmd_analyze.py,sha256=CkOO7QK1532uqcwZiARJs1kWUK0B9zTnN4tYnNGrP6g,1937
9
+ tscode_kg/cli/cmd_bridges.py,sha256=v3Ot9gpO3Ky0AnorsAz1329JZMA1NnmTExmX98yVxSw,1108
10
+ tscode_kg/cli/cmd_build.py,sha256=8BE4AGiIsBpFopQ0icwUTTXj-INbZa_5DyWfEt1js0M,2485
11
+ tscode_kg/cli/cmd_centrality.py,sha256=hk4unUncO7M1XT-xxpflqW4fnz_d8xNdmVsZiygROG4,3702
12
+ tscode_kg/cli/cmd_explain.py,sha256=fFM7-8FtsshAts136hGWIoCNEnZ4rFEBfzg2tfzn7gc,1634
13
+ tscode_kg/cli/cmd_framework_nodes.py,sha256=bci67JxrMTOmZeMw_4eqxGXc7FGnobtETY7h_e-QE6o,1538
14
+ tscode_kg/cli/cmd_hooks.py,sha256=DGzdeyLqpnn_VIKxRpa98esNddcq9Sc-0ZUvx5yiANs,3944
15
+ tscode_kg/cli/cmd_init.py,sha256=IWMEUAjikDNAoICl2nOlFVL2qEYfPJbax1UWzBFSUh4,7987
16
+ tscode_kg/cli/cmd_mcp.py,sha256=NeabSeOdoHUGFvi658Tst8JVgtZ53uPUXIWwZC8ts2E,921
17
+ tscode_kg/cli/cmd_model.py,sha256=Gw8-73ks5XYaJ3HYdXSTudp2kEAVJmESE24FM0LFung,1632
18
+ tscode_kg/cli/cmd_query.py,sha256=LyWKwr55SrfhnVRVriQNBhRu4qeXqSfLv_S24Au5QVA,2548
19
+ tscode_kg/cli/cmd_snapshot.py,sha256=mIbGRSWwW4X1Ft5rrGkZdQgzhzB-E9UKbvGcZuYAWGM,14440
20
+ tscode_kg/cli/cmd_viz.py,sha256=NphzsCyw5riXF2qVZBW0UVRIp0cx5EhVaZG5rrOEoxk,4578
21
+ tscode_kg/cli/main.py,sha256=wgHyT33J1MRxzyqKpqQkk13ZF6p3tKlc1xiWaRXEmA4,1716
22
+ tscode_kg/coderank.py,sha256=bdU8mnoFJxul0NUHyLNudWbrqWZiZOHcw0DIwS3KSQo,17402
23
+ tscode_kg/config.py,sha256=ZHrI1uJuyWs-5C-U9N7K0WM7BnCX3kkT_weZSxKyT6Q,1085
24
+ tscode_kg/explain.py,sha256=fFtIvr3Kz4d16RxwnYQlU6VZXZfMnQsuFeh4iic_xw0,10067
25
+ tscode_kg/extractor.py,sha256=1SJDnbhhU7BPQroUSKmhxBY00enEUo9HaUSFZrP0Iq8,29742
26
+ tscode_kg/framework_detector.py,sha256=YtcEEJjyPclMBeI51soUfLbohFKGeC9igdq8X9tbONQ,3919
27
+ tscode_kg/kg.py,sha256=KeYuMPwDfR4tetkwByEobV5Y0-__m8iurAuO91WXac4,6665
28
+ tscode_kg/layout3d.py,sha256=ZL578G3EPcU2q1b8ztZeBjrx6R_lCV3xA5ZwsXwg-jg,16979
29
+ tscode_kg/mcp_server.py,sha256=IRfciQBPhMXih_M0ntAHOHDyFAjRarIqh3DC-_H1OHA,55658
30
+ tscode_kg/snapshots.py,sha256=L7shuUWMLW1LNDTs1GgvSyWy1_zZzva43js4T8eSynI,2142
31
+ tscode_kg/viz3d.py,sha256=aSthXYPw4PT0EcbHX1fRJ-SEw9nAYIT8_y6Haqs8NCI,56267
32
+ tscode_kg/viz3d_timeline.py,sha256=feqWELI5DXQiKVtUMmdyiblHblSzq4kXbHVoQ97DJ4g,12251
33
+ tscode_kg-0.2.0.dist-info/METADATA,sha256=EsyXpBHhQPtylpljl0dr_4TwYB1urnGWY0ZTvcpQSPs,7160
34
+ tscode_kg-0.2.0.dist-info/WHEEL,sha256=kJCRJT_g0adfAJzTx2GUMmS80rTJIVHRCfG0DQgLq3o,88
35
+ tscode_kg-0.2.0.dist-info/entry_points.txt,sha256=zcrgBfQ8FTXlgw2xU-QACrcmvEXFnptm9ic0M1CuEl8,639
36
+ tscode_kg-0.2.0.dist-info/licenses/LICENSE,sha256=f9d894ZAQEKirrRaTcG0QdysjKyCydXFLzWuheGrroA,1303
37
+ tscode_kg-0.2.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: poetry-core 2.3.1
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,15 @@
1
+ [console_scripts]
2
+ tscodekg=tscode_kg.cli.main:cli
3
+ tscodekg-analyze=tscode_kg.cli.cmd_analyze:analyze
4
+ tscodekg-build=tscode_kg.cli.cmd_build:build
5
+ tscodekg-centrality=tscode_kg.cli.cmd_centrality:centrality
6
+ tscodekg-download-model=tscode_kg.cli.cmd_model:download_model
7
+ tscodekg-init=tscode_kg.cli.cmd_init:init
8
+ tscodekg-install-hooks=tscode_kg.cli.cmd_hooks:install_hooks
9
+ tscodekg-mcp=tscode_kg.mcp_server:main
10
+ tscodekg-pack=tscode_kg.cli.cmd_query:pack
11
+ tscodekg-query=tscode_kg.cli.cmd_query:query
12
+ tscodekg-viz=tscode_kg.cli.cmd_viz:viz
13
+ tscodekg-viz-timeline=tscode_kg.cli.cmd_viz:viz_timeline
14
+ tscodekg-viz3d=tscode_kg.cli.cmd_viz:viz3d
15
+
@@ -0,0 +1,24 @@
1
+ BSD 2-Clause License
2
+
3
+ Copyright (c) 2026, Flux-Frontiers
4
+
5
+ Redistribution and use in source and binary forms, with or without
6
+ modification, are permitted provided that the following conditions are met:
7
+
8
+ 1. Redistributions of source code must retain the above copyright notice, this
9
+ list of conditions and the following disclaimer.
10
+
11
+ 2. Redistributions in binary form must reproduce the above copyright notice,
12
+ this list of conditions and the following disclaimer in the documentation
13
+ and/or other materials provided with the distribution.
14
+
15
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
19
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
22
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.