vibetrace 0.1.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.
Files changed (43) hide show
  1. vibetrace/__init__.py +0 -0
  2. vibetrace/cli.py +372 -0
  3. vibetrace/cli_commands.py +357 -0
  4. vibetrace/indexer/db.py +436 -0
  5. vibetrace/indexer/db_queries.py +257 -0
  6. vibetrace/indexer/db_retry.py +36 -0
  7. vibetrace/indexer/embeddings.py +242 -0
  8. vibetrace/indexer/git_utils.py +122 -0
  9. vibetrace/indexer/hooks.py +219 -0
  10. vibetrace/indexer/lsp_bridge.py +300 -0
  11. vibetrace/indexer/main.py +275 -0
  12. vibetrace/indexer/models.py +51 -0
  13. vibetrace/indexer/parser.py +28 -0
  14. vibetrace/indexer/parsers/__init__.py +48 -0
  15. vibetrace/indexer/parsers/base.py +401 -0
  16. vibetrace/indexer/parsers/generic_parser.py +302 -0
  17. vibetrace/indexer/parsers/go_parser.py +279 -0
  18. vibetrace/indexer/parsers/js_ts_parser.py +489 -0
  19. vibetrace/indexer/parsers/python_parser.py +487 -0
  20. vibetrace/indexer/parsers/route_extractor.py +149 -0
  21. vibetrace/indexer/parsers/rust_parser.py +264 -0
  22. vibetrace/indexer/parsers/systems_parser.py +12 -0
  23. vibetrace/indexer/resolver.py +235 -0
  24. vibetrace/indexer/schema.sql +86 -0
  25. vibetrace/indexer/watcher.py +247 -0
  26. vibetrace/mcp/formatters.py +144 -0
  27. vibetrace/mcp/schemas.py +273 -0
  28. vibetrace/mcp/server.py +425 -0
  29. vibetrace/py.typed +0 -0
  30. vibetrace/resources/SKILL.md +70 -0
  31. vibetrace/resources/__init__.py +1 -0
  32. vibetrace/server_api.py +268 -0
  33. vibetrace/services/call_tree_service.py +207 -0
  34. vibetrace/services/graph_service.py +326 -0
  35. vibetrace/services/hybrid_search.py +134 -0
  36. vibetrace/services/saved_traces_service.py +113 -0
  37. vibetrace/services/trace_service.py +471 -0
  38. vibetrace/skill_installer.py +155 -0
  39. vibetrace-0.1.2.dist-info/METADATA +178 -0
  40. vibetrace-0.1.2.dist-info/RECORD +43 -0
  41. vibetrace-0.1.2.dist-info/WHEEL +4 -0
  42. vibetrace-0.1.2.dist-info/entry_points.txt +5 -0
  43. vibetrace-0.1.2.dist-info/licenses/LICENSE +21 -0
vibetrace/__init__.py ADDED
File without changes
vibetrace/cli.py ADDED
@@ -0,0 +1,372 @@
1
+ """Unified VibeTrace CLI for AI Agents and Developers."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import argparse
6
+ import sys
7
+
8
+ from vibetrace.cli_commands import (
9
+ cmd_call_tree,
10
+ cmd_hooks,
11
+ cmd_impact,
12
+ cmd_index,
13
+ cmd_init,
14
+ cmd_mcp,
15
+ cmd_search,
16
+ cmd_serve,
17
+ cmd_skill,
18
+ cmd_slice,
19
+ cmd_summary,
20
+ cmd_trace,
21
+ )
22
+
23
+ # Aliases for backward compatibility
24
+ _cmd_index = cmd_index
25
+ _cmd_search = cmd_search
26
+ _cmd_trace = cmd_trace
27
+ _cmd_slice = cmd_slice
28
+ _cmd_call_tree = cmd_call_tree
29
+ _cmd_impact = cmd_impact
30
+ _cmd_summary = cmd_summary
31
+ _cmd_hooks = cmd_hooks
32
+ _cmd_serve = cmd_serve
33
+ _cmd_init = cmd_init
34
+ _cmd_skill = cmd_skill
35
+ _cmd_mcp = cmd_mcp
36
+
37
+
38
+ def build_parser() -> argparse.ArgumentParser:
39
+ epilog = """
40
+ examples:
41
+ vibetrace index . --embed # Full index with AST, FTS5, and 256d vectors
42
+ vibetrace index . --lsp # Index with dynamic LSP type inference
43
+ vibetrace search "upsert_node" # 4-stream hybrid search (AST + BM25 + Vector + PageRank)
44
+ vibetrace trace "GET /graph" get_graph # Bidirectional BFS trace from route to handler
45
+ vibetrace trace "GET /graph" get_graph --save-as "GraphFlow" # Save trace bookmark
46
+ vibetrace trace --list-saved # List saved trace queries
47
+ vibetrace trace --saved "GraphFlow" # Execute saved trace query
48
+ vibetrace slice IndexerDB.upsert_node # Surgical source slice + callee contracts
49
+ vibetrace call-tree hybrid_search # Top-down recursive call tree hierarchy
50
+ vibetrace impact src/vibetrace/db.py # 3-level blast radius impact analysis
51
+ vibetrace hooks status # Inspect git hook background sync status
52
+ vibetrace hooks install # Auto-configure Lefthook or native git hooks
53
+ vibetrace serve # Start Map Room API and WebSocket daemon
54
+ """
55
+ parser = argparse.ArgumentParser(
56
+ prog="vibetrace",
57
+ description="VibeTrace Code Intelligence CLI (AST + FTS5 BM25 + EmbeddingGemma 2)",
58
+ epilog=epilog,
59
+ formatter_class=argparse.RawDescriptionHelpFormatter,
60
+ )
61
+ parser.add_argument("--root", default=None, help="Project root path override")
62
+ parser.add_argument(
63
+ "--no-sync",
64
+ action="store_true",
65
+ help="Disable Lazy JIT auto-sync (skip checking uncommitted file changes)",
66
+ )
67
+ parser.add_argument("--json", action="store_true", help="Emit JSON output for machine parsing")
68
+ sub = parser.add_subparsers(dest="command", required=True)
69
+
70
+ # index
71
+ p_idx = sub.add_parser(
72
+ "index",
73
+ help="Index repository AST, FTS5, and optional embeddings",
74
+ description=(
75
+ "Extract code symbols, references, framework routes, and generate search indices."
76
+ ),
77
+ )
78
+ p_idx.add_argument(
79
+ "path",
80
+ nargs="?",
81
+ default=".",
82
+ help="Directory or file path to index (default: current directory)",
83
+ )
84
+ p_idx.add_argument(
85
+ "--embed", action="store_true", help="Compute EmbeddingGemma 2 256d Matryoshka vectors"
86
+ )
87
+ p_idx.add_argument(
88
+ "--force",
89
+ action="store_true",
90
+ help="Force re-indexing all files (bypass Git-SHA delta cache)",
91
+ )
92
+ p_idx.add_argument(
93
+ "--lsp",
94
+ action="store_true",
95
+ help="Enable LSP hybrid bridge for dynamic types and re-exports",
96
+ )
97
+ p_idx.add_argument("--json", action="store_true", default=False, help="Emit JSON output")
98
+ p_idx.set_defaults(func=_cmd_index)
99
+
100
+ # search
101
+ p_search = sub.add_parser(
102
+ "search",
103
+ help="Hybrid RRF search across AST, FTS5, and vectors",
104
+ description=(
105
+ "Query codebase using 4-stream Reciprocal Rank Fusion with PageRank centrality boost."
106
+ ),
107
+ )
108
+ p_search.add_argument("query", help="Search query symbol name or natural language intent")
109
+ p_search.add_argument(
110
+ "--limit", type=int, default=15, help="Maximum number of results to return (default: 15)"
111
+ )
112
+ p_search.add_argument("--path", default=".", help="Project root directory path")
113
+ p_search.add_argument("--json", action="store_true", default=False, help="Emit JSON output")
114
+ p_search.set_defaults(func=_cmd_search)
115
+
116
+ # trace
117
+ p_trace = sub.add_parser(
118
+ "trace",
119
+ help="Bidirectional BFS execution tracepath between symbols",
120
+ description=(
121
+ "Find execution paths between two symbols (functions, methods, HTTP routes) "
122
+ "with call-site lines."
123
+ ),
124
+ )
125
+ p_trace.add_argument(
126
+ "from_symbol",
127
+ nargs="?",
128
+ default=None,
129
+ help="Source symbol name or HTTP route (e.g. 'GET /graph', 'main')",
130
+ )
131
+ p_trace.add_argument(
132
+ "to_symbol",
133
+ nargs="?",
134
+ default=None,
135
+ help="Target symbol name (e.g. 'IndexerDB.upsert_node')",
136
+ )
137
+ p_trace.add_argument("--saved", default=None, help="Execute a named saved architectural trace")
138
+ p_trace.add_argument(
139
+ "--save-as", default=None, help="Bookmark this trace under a persistent name"
140
+ )
141
+ p_trace.add_argument(
142
+ "--list-saved", action="store_true", help="List all saved trace queries in this project"
143
+ )
144
+ p_trace.add_argument(
145
+ "--depth", type=int, default=6, help="Maximum BFS traversal depth in hops (default: 6)"
146
+ )
147
+ p_trace.add_argument(
148
+ "--engine",
149
+ choices=["bfs", "cte"],
150
+ default="bfs",
151
+ help="Path engine: 'bfs' (bidirectional BFS) or 'cte' (native SQLite CTE)",
152
+ )
153
+ p_trace.add_argument("--path", default=".", help="Project root directory path")
154
+ p_trace.add_argument("--json", action="store_true", default=False, help="Emit JSON output")
155
+ p_trace.set_defaults(func=_cmd_trace)
156
+
157
+ # slice
158
+ p_slice = sub.add_parser(
159
+ "slice",
160
+ help="Read exact symbol source lines and callee contracts",
161
+ description=(
162
+ "Surgically retrieve symbol source code without reading entire files, "
163
+ "including direct outgoing callee contracts."
164
+ ),
165
+ )
166
+ p_slice.add_argument("symbol", help="Target symbol name or ClassName.method_name")
167
+ p_slice.add_argument(
168
+ "--file",
169
+ default=None,
170
+ help="Optional relative file path to disambiguate identical symbol names",
171
+ )
172
+ p_slice.add_argument(
173
+ "--no-callees",
174
+ action="store_true",
175
+ help="Omit outgoing callee contracts (source lines only)",
176
+ )
177
+ p_slice.add_argument("--path", default=".", help="Project root directory path")
178
+ p_slice.add_argument("--json", action="store_true", default=False, help="Emit JSON output")
179
+ p_slice.set_defaults(func=_cmd_slice)
180
+
181
+ # call-tree
182
+ p_tree = sub.add_parser(
183
+ "call-tree",
184
+ help="Explore top-down execution call tree from an entry point",
185
+ description=(
186
+ "Generate recursive ASCII call hierarchy with exact call-site line numbers "
187
+ "and cycle prevention."
188
+ ),
189
+ )
190
+ p_tree.add_argument(
191
+ "symbol", help="Root entry point symbol name (e.g., 'main', 'hybrid_search')"
192
+ )
193
+ p_tree.add_argument(
194
+ "--depth", type=int, default=3, help="Maximum depth of recursive nested calls (default: 3)"
195
+ )
196
+ p_tree.add_argument(
197
+ "--file", default=None, help="Optional relative file path to disambiguate symbol"
198
+ )
199
+ p_tree.add_argument("--path", default=".", help="Project root directory path")
200
+ p_tree.add_argument("--json", action="store_true", default=False, help="Emit JSON output")
201
+ p_tree.set_defaults(func=_cmd_call_tree)
202
+
203
+ # impact
204
+ p_impact = sub.add_parser(
205
+ "impact",
206
+ help="Compute 3-level blast radius for a file",
207
+ description=(
208
+ "Compute upstream blast radius: Level 1 (direct callers), "
209
+ "Level 2 (indirect), Level 3 (deep)."
210
+ ),
211
+ )
212
+ p_impact.add_argument("file_path", help="Relative or absolute file path to analyze")
213
+ p_impact.add_argument("--json", action="store_true", default=False, help="Emit JSON output")
214
+ p_impact.set_defaults(func=_cmd_impact)
215
+
216
+ # summary
217
+ p_sum = sub.add_parser(
218
+ "summary",
219
+ help="Get structural outline of a file",
220
+ description=(
221
+ "Extract all functions, classes, methods, signatures, "
222
+ "and visibility decorators in a file."
223
+ ),
224
+ )
225
+ p_sum.add_argument("file_path", help="File path to summarize")
226
+ p_sum.add_argument(
227
+ "--limit", type=int, default=100, help="Maximum number of symbols to list (default: 100)"
228
+ )
229
+ p_sum.add_argument("--offset", type=int, default=0, help="Pagination offset (default: 0)")
230
+ p_sum.add_argument("--json", action="store_true", default=False, help="Emit JSON output")
231
+ p_sum.set_defaults(func=_cmd_summary)
232
+
233
+ # serve
234
+ p_serve = sub.add_parser(
235
+ "serve",
236
+ help="Start the VibeTrace API & Map Room WebSocket server",
237
+ description=(
238
+ "Launch FastAPI backend with bidirectional WebSocket support "
239
+ "for interactive visualizers and agent tracking."
240
+ ),
241
+ )
242
+ p_serve.add_argument("--host", default="127.0.0.1", help="Bind host (default: 127.0.0.1)")
243
+ p_serve.add_argument("--port", type=int, default=8000, help="Bind port (default: 8000)")
244
+ p_serve.set_defaults(func=_cmd_serve)
245
+
246
+ # hooks
247
+ p_hooks = sub.add_parser(
248
+ "hooks",
249
+ help="Manage automated post-commit and post-merge indexer hooks",
250
+ description=(
251
+ "Inspect, install, and uninstall post-commit and post-merge "
252
+ "background index synchronization."
253
+ ),
254
+ )
255
+ p_hooks.add_argument(
256
+ "action",
257
+ nargs="?",
258
+ choices=["status", "install", "uninstall"],
259
+ default="status",
260
+ help=(
261
+ "Hook action: 'status' (inspect configuration), "
262
+ "'install' (configure hooks), 'uninstall' (remove hooks)"
263
+ ),
264
+ )
265
+ p_hooks.add_argument(
266
+ "--provider",
267
+ choices=["auto", "lefthook", "git"],
268
+ default="auto",
269
+ help=(
270
+ "Hook provider to configure: 'auto' (detect existing), "
271
+ "'lefthook', or 'git' (default: auto)"
272
+ ),
273
+ )
274
+ p_hooks.add_argument("--path", default=".", help="Project root directory path")
275
+ p_hooks.add_argument("--json", action="store_true", default=False, help="Emit JSON output")
276
+ p_hooks.set_defaults(func=_cmd_hooks)
277
+
278
+ # init
279
+ p_init = sub.add_parser(
280
+ "init",
281
+ help="Initialize VibeTrace in workspace (.gitignore, skill, isolated db)",
282
+ description=(
283
+ "Set up a project workspace with local .gitignore rules, install the "
284
+ "vibetrace-navigator agent skill, and perform initial indexing."
285
+ ),
286
+ )
287
+ p_init.add_argument(
288
+ "path",
289
+ nargs="?",
290
+ default=".",
291
+ help="Project workspace path to initialize (default: current directory)",
292
+ )
293
+ p_init.add_argument(
294
+ "--no-index", action="store_true", help="Skip running initial index immediately"
295
+ )
296
+ p_init.add_argument(
297
+ "--global",
298
+ dest="global_skill",
299
+ action="store_true",
300
+ help="Also install skill into user global agent skills directory",
301
+ )
302
+ p_init.add_argument("--json", action="store_true", default=False, help="Emit JSON output")
303
+ p_init.set_defaults(func=_cmd_init)
304
+
305
+ # skill
306
+ p_skill = sub.add_parser(
307
+ "skill",
308
+ help="Manage and install VibeTrace agent skills",
309
+ description="Install the vibetrace-navigator skill for AI agents in workspace or globally.",
310
+ )
311
+ p_skill.add_argument(
312
+ "action",
313
+ nargs="?",
314
+ choices=["install"],
315
+ default="install",
316
+ help="Skill action: 'install' (default: install)",
317
+ )
318
+ p_skill.add_argument(
319
+ "--path", default=".", help="Project root directory path (default: current directory)"
320
+ )
321
+ p_skill.add_argument(
322
+ "--global",
323
+ dest="global_skill",
324
+ action="store_true",
325
+ help="Install into user global agent skills directory",
326
+ )
327
+ p_skill.add_argument("--json", action="store_true", default=False, help="Emit JSON output")
328
+ p_skill.set_defaults(func=_cmd_skill)
329
+
330
+ # mcp
331
+ p_mcp = sub.add_parser(
332
+ "mcp",
333
+ help="Launch VibeTrace Model Context Protocol (MCP) stdio server",
334
+ description="Run the MCP stdio transport server for Claude, Cursor, and other agents.",
335
+ )
336
+ p_mcp.add_argument(
337
+ "--path", default=".", help="Project root directory path (default: current directory)"
338
+ )
339
+ p_mcp.set_defaults(func=_cmd_mcp)
340
+
341
+ return parser
342
+
343
+
344
+ def main(argv: list[str] | None = None) -> int:
345
+ if sys.platform == "win32":
346
+ try:
347
+ reconfig_out = getattr(sys.stdout, "reconfigure", None)
348
+ if callable(reconfig_out):
349
+ reconfig_out(encoding="utf-8")
350
+ reconfig_err = getattr(sys.stderr, "reconfigure", None)
351
+ if callable(reconfig_err):
352
+ reconfig_err(encoding="utf-8")
353
+ except Exception:
354
+ pass
355
+
356
+ top_json = False
357
+ if argv is not None and "--json" in argv:
358
+ top_json = True
359
+ parser = build_parser()
360
+ args = parser.parse_args(argv)
361
+ if top_json:
362
+ args.json = True
363
+ if getattr(args, "root", None) and getattr(args, "path", ".") == ".":
364
+ args.path = args.root
365
+ code = int(args.func(args))
366
+ if argv is None:
367
+ sys.exit(code)
368
+ return code
369
+
370
+
371
+ if __name__ == "__main__":
372
+ main()