cocoindex-code 0.2.4__tar.gz → 0.2.5__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.
- {cocoindex_code-0.2.4 → cocoindex_code-0.2.5}/PKG-INFO +1 -1
- {cocoindex_code-0.2.4 → cocoindex_code-0.2.5}/src/cocoindex_code/_version.py +2 -2
- {cocoindex_code-0.2.4 → cocoindex_code-0.2.5}/src/cocoindex_code/cli.py +28 -71
- {cocoindex_code-0.2.4 → cocoindex_code-0.2.5}/src/cocoindex_code/client.py +201 -184
- cocoindex_code-0.2.5/src/cocoindex_code/daemon.py +429 -0
- {cocoindex_code-0.2.4 → cocoindex_code-0.2.5}/src/cocoindex_code/indexer.py +7 -7
- cocoindex_code-0.2.5/src/cocoindex_code/project.py +285 -0
- {cocoindex_code-0.2.4 → cocoindex_code-0.2.5}/src/cocoindex_code/server.py +20 -45
- {cocoindex_code-0.2.4 → cocoindex_code-0.2.5}/src/cocoindex_code/settings.py +0 -4
- {cocoindex_code-0.2.4 → cocoindex_code-0.2.5}/src/cocoindex_code/shared.py +3 -5
- cocoindex_code-0.2.4/src/cocoindex_code/daemon.py +0 -642
- cocoindex_code-0.2.4/src/cocoindex_code/project.py +0 -124
- {cocoindex_code-0.2.4 → cocoindex_code-0.2.5}/.gitignore +0 -0
- {cocoindex_code-0.2.4 → cocoindex_code-0.2.5}/LICENSE +0 -0
- {cocoindex_code-0.2.4 → cocoindex_code-0.2.5}/README.md +0 -0
- {cocoindex_code-0.2.4 → cocoindex_code-0.2.5}/pyproject.toml +0 -0
- {cocoindex_code-0.2.4 → cocoindex_code-0.2.5}/src/cocoindex_code/__init__.py +0 -0
- {cocoindex_code-0.2.4 → cocoindex_code-0.2.5}/src/cocoindex_code/__main__.py +0 -0
- {cocoindex_code-0.2.4 → cocoindex_code-0.2.5}/src/cocoindex_code/config.py +0 -0
- {cocoindex_code-0.2.4 → cocoindex_code-0.2.5}/src/cocoindex_code/protocol.py +0 -0
- {cocoindex_code-0.2.4 → cocoindex_code-0.2.5}/src/cocoindex_code/query.py +0 -0
- {cocoindex_code-0.2.4 → cocoindex_code-0.2.5}/src/cocoindex_code/schema.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cocoindex-code
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.5
|
|
4
4
|
Summary: MCP server for indexing and querying codebases using CocoIndex
|
|
5
5
|
Project-URL: Homepage, https://github.com/cocoindex-io/cocoindex-code
|
|
6
6
|
Project-URL: Repository, https://github.com/cocoindex-io/cocoindex-code
|
|
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
|
|
|
28
28
|
commit_id: COMMIT_ID
|
|
29
29
|
__commit_id__: COMMIT_ID
|
|
30
30
|
|
|
31
|
-
__version__ = version = '0.2.
|
|
32
|
-
__version_tuple__ = version_tuple = (0, 2,
|
|
31
|
+
__version__ = version = '0.2.5'
|
|
32
|
+
__version_tuple__ = version_tuple = (0, 2, 5)
|
|
33
33
|
|
|
34
34
|
__commit_id__ = commit_id = None
|
|
@@ -3,13 +3,9 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
from pathlib import Path
|
|
6
|
-
from typing import TYPE_CHECKING
|
|
7
6
|
|
|
8
7
|
import typer as _typer
|
|
9
8
|
|
|
10
|
-
if TYPE_CHECKING:
|
|
11
|
-
from .client import DaemonClient
|
|
12
|
-
|
|
13
9
|
from .protocol import IndexingProgress, ProjectStatusResponse, SearchResponse
|
|
14
10
|
from .settings import (
|
|
15
11
|
default_project_settings,
|
|
@@ -52,22 +48,6 @@ def require_project_root() -> Path:
|
|
|
52
48
|
return root
|
|
53
49
|
|
|
54
50
|
|
|
55
|
-
def require_daemon_for_project() -> tuple[DaemonClient, str]:
|
|
56
|
-
"""Resolve project root, then connect to daemon (auto-starting if needed).
|
|
57
|
-
|
|
58
|
-
Returns ``(client, project_root_str)``. Exits on failure.
|
|
59
|
-
"""
|
|
60
|
-
from .client import ensure_daemon
|
|
61
|
-
|
|
62
|
-
project_root = require_project_root()
|
|
63
|
-
try:
|
|
64
|
-
client = ensure_daemon()
|
|
65
|
-
except Exception as e:
|
|
66
|
-
_typer.echo(f"Error: Failed to connect to daemon: {e}", err=True)
|
|
67
|
-
raise _typer.Exit(code=1)
|
|
68
|
-
return client, str(project_root)
|
|
69
|
-
|
|
70
|
-
|
|
71
51
|
def resolve_default_path(project_root: Path) -> str | None:
|
|
72
52
|
"""Compute default ``--path`` filter from CWD relative to project root."""
|
|
73
53
|
cwd = Path.cwd().resolve()
|
|
@@ -101,7 +81,7 @@ def print_index_stats(status: ProjectStatusResponse) -> None:
|
|
|
101
81
|
if status.progress is not None:
|
|
102
82
|
_typer.echo(f"Indexing in progress: {_format_progress(status.progress)}")
|
|
103
83
|
if not status.index_exists:
|
|
104
|
-
_typer.echo("\nIndex not created yet.
|
|
84
|
+
_typer.echo("\nIndex not created yet.")
|
|
105
85
|
return
|
|
106
86
|
_typer.echo("\nIndex stats:")
|
|
107
87
|
_typer.echo(f" Chunks: {status.total_chunks}")
|
|
@@ -128,12 +108,14 @@ def print_search_results(response: SearchResponse) -> None:
|
|
|
128
108
|
_typer.echo(r.content)
|
|
129
109
|
|
|
130
110
|
|
|
131
|
-
def _run_index_with_progress(
|
|
111
|
+
def _run_index_with_progress(project_root: str) -> None:
|
|
132
112
|
"""Run indexing with streaming progress display. Exits on failure."""
|
|
133
113
|
from rich.console import Console as _Console
|
|
134
114
|
from rich.live import Live as _Live
|
|
135
115
|
from rich.spinner import Spinner as _Spinner
|
|
136
116
|
|
|
117
|
+
from . import client as _client
|
|
118
|
+
|
|
137
119
|
err_console = _Console(stderr=True)
|
|
138
120
|
last_progress_line: str | None = None
|
|
139
121
|
|
|
@@ -153,7 +135,7 @@ def _run_index_with_progress(client: DaemonClient, project_root: str) -> None:
|
|
|
153
135
|
live.update(_Spinner("dots", last_progress_line))
|
|
154
136
|
|
|
155
137
|
try:
|
|
156
|
-
resp =
|
|
138
|
+
resp = _client.index(project_root, on_progress=_on_progress, on_waiting=_on_waiting)
|
|
157
139
|
except RuntimeError as e:
|
|
158
140
|
live.stop()
|
|
159
141
|
_typer.echo(f"Indexing failed: {e}", err=True)
|
|
@@ -169,7 +151,6 @@ def _run_index_with_progress(client: DaemonClient, project_root: str) -> None:
|
|
|
169
151
|
|
|
170
152
|
|
|
171
153
|
def _search_with_wait_spinner(
|
|
172
|
-
client: DaemonClient,
|
|
173
154
|
project_root: str,
|
|
174
155
|
query: str,
|
|
175
156
|
languages: list[str] | None = None,
|
|
@@ -182,6 +163,8 @@ def _search_with_wait_spinner(
|
|
|
182
163
|
from rich.live import Live as _Live
|
|
183
164
|
from rich.spinner import Spinner as _Spinner
|
|
184
165
|
|
|
166
|
+
from . import client as _client
|
|
167
|
+
|
|
185
168
|
err_console = _Console(stderr=True)
|
|
186
169
|
|
|
187
170
|
with _Live(_Spinner("dots", "Searching..."), console=err_console, transient=True) as live:
|
|
@@ -192,7 +175,7 @@ def _search_with_wait_spinner(
|
|
|
192
175
|
refresh=True,
|
|
193
176
|
)
|
|
194
177
|
|
|
195
|
-
resp =
|
|
178
|
+
resp = _client.search(
|
|
196
179
|
project_root=project_root,
|
|
197
180
|
query=query,
|
|
198
181
|
languages=languages,
|
|
@@ -305,13 +288,12 @@ def init(
|
|
|
305
288
|
@app.command()
|
|
306
289
|
def index() -> None:
|
|
307
290
|
"""Create/update index for the codebase."""
|
|
308
|
-
client
|
|
309
|
-
print_project_header(project_root)
|
|
291
|
+
from . import client as _client
|
|
310
292
|
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
print_index_stats(
|
|
293
|
+
project_root = str(require_project_root())
|
|
294
|
+
print_project_header(project_root)
|
|
295
|
+
_run_index_with_progress(project_root)
|
|
296
|
+
print_index_stats(_client.project_status(project_root))
|
|
315
297
|
|
|
316
298
|
|
|
317
299
|
@app.command()
|
|
@@ -324,12 +306,11 @@ def search(
|
|
|
324
306
|
refresh: bool = _typer.Option(False, "--refresh", help="Refresh index before searching"),
|
|
325
307
|
) -> None:
|
|
326
308
|
"""Semantic search across the codebase."""
|
|
327
|
-
|
|
309
|
+
project_root = str(require_project_root())
|
|
328
310
|
query_str = " ".join(query)
|
|
329
311
|
|
|
330
|
-
# Refresh index with progress display before searching
|
|
331
312
|
if refresh:
|
|
332
|
-
_run_index_with_progress(
|
|
313
|
+
_run_index_with_progress(project_root)
|
|
333
314
|
|
|
334
315
|
# Default path filter from CWD
|
|
335
316
|
paths: list[str] | None = None
|
|
@@ -341,7 +322,6 @@ def search(
|
|
|
341
322
|
paths = [default]
|
|
342
323
|
|
|
343
324
|
resp = _search_with_wait_spinner(
|
|
344
|
-
client,
|
|
345
325
|
project_root=project_root,
|
|
346
326
|
query=query_str,
|
|
347
327
|
languages=lang or None,
|
|
@@ -355,10 +335,11 @@ def search(
|
|
|
355
335
|
@app.command()
|
|
356
336
|
def status() -> None:
|
|
357
337
|
"""Show project status."""
|
|
358
|
-
client
|
|
338
|
+
from . import client as _client
|
|
339
|
+
|
|
340
|
+
project_root = str(require_project_root())
|
|
359
341
|
print_project_header(project_root)
|
|
360
|
-
|
|
361
|
-
print_index_stats(resp)
|
|
342
|
+
print_index_stats(_client.project_status(project_root))
|
|
362
343
|
|
|
363
344
|
|
|
364
345
|
@app.command()
|
|
@@ -400,12 +381,9 @@ def reset(
|
|
|
400
381
|
|
|
401
382
|
# Remove project from daemon first so it releases file handles
|
|
402
383
|
try:
|
|
403
|
-
from .
|
|
384
|
+
from . import client as _client
|
|
404
385
|
|
|
405
|
-
|
|
406
|
-
client.handshake()
|
|
407
|
-
client.remove_project(str(project_root))
|
|
408
|
-
client.close()
|
|
386
|
+
_client.remove_project(str(project_root))
|
|
409
387
|
except (ConnectionRefusedError, OSError, RuntimeError):
|
|
410
388
|
pass # Daemon not running — that's fine
|
|
411
389
|
|
|
@@ -442,13 +420,12 @@ def mcp() -> None:
|
|
|
442
420
|
"""Run as MCP server (stdio mode)."""
|
|
443
421
|
import asyncio
|
|
444
422
|
|
|
445
|
-
|
|
423
|
+
project_root = str(require_project_root())
|
|
446
424
|
|
|
447
425
|
async def _run_mcp() -> None:
|
|
448
426
|
from .server import create_mcp_server
|
|
449
427
|
|
|
450
|
-
mcp_server = create_mcp_server(
|
|
451
|
-
# Trigger initial indexing in background
|
|
428
|
+
mcp_server = create_mcp_server(project_root)
|
|
452
429
|
asyncio.create_task(_bg_index(project_root))
|
|
453
430
|
await mcp_server.run_stdio_async()
|
|
454
431
|
|
|
@@ -456,27 +433,14 @@ def mcp() -> None:
|
|
|
456
433
|
|
|
457
434
|
|
|
458
435
|
async def _bg_index(project_root: str) -> None:
|
|
459
|
-
"""Index in background
|
|
460
|
-
|
|
461
|
-
A fresh DaemonClient is used so that background indexing does not share
|
|
462
|
-
the multiprocessing connection used by foreground MCP requests, which
|
|
463
|
-
would corrupt data ("Input data was truncated").
|
|
464
|
-
"""
|
|
436
|
+
"""Index in background. Each call opens its own daemon connection."""
|
|
465
437
|
import asyncio
|
|
466
438
|
|
|
467
|
-
from .
|
|
439
|
+
from . import client as _client
|
|
468
440
|
|
|
469
441
|
loop = asyncio.get_event_loop()
|
|
470
|
-
|
|
471
|
-
def _run_index() -> None:
|
|
472
|
-
bg_client = ensure_daemon()
|
|
473
|
-
try:
|
|
474
|
-
bg_client.index(project_root)
|
|
475
|
-
finally:
|
|
476
|
-
bg_client.close()
|
|
477
|
-
|
|
478
442
|
try:
|
|
479
|
-
await loop.run_in_executor(None,
|
|
443
|
+
await loop.run_in_executor(None, lambda: _client.index(project_root))
|
|
480
444
|
except Exception:
|
|
481
445
|
pass
|
|
482
446
|
|
|
@@ -487,15 +451,9 @@ async def _bg_index(project_root: str) -> None:
|
|
|
487
451
|
@daemon_app.command("status")
|
|
488
452
|
def daemon_status() -> None:
|
|
489
453
|
"""Show daemon status."""
|
|
490
|
-
from .
|
|
491
|
-
|
|
492
|
-
try:
|
|
493
|
-
client = ensure_daemon()
|
|
494
|
-
except Exception as e:
|
|
495
|
-
_typer.echo(f"Error: {e}", err=True)
|
|
496
|
-
raise _typer.Exit(code=1)
|
|
454
|
+
from . import client as _client
|
|
497
455
|
|
|
498
|
-
resp =
|
|
456
|
+
resp = _client.daemon_status()
|
|
499
457
|
_typer.echo(f"Daemon version: {resp.version}")
|
|
500
458
|
_typer.echo(f"Uptime: {resp.uptime_seconds:.1f}s")
|
|
501
459
|
if resp.projects:
|
|
@@ -505,7 +463,6 @@ def daemon_status() -> None:
|
|
|
505
463
|
_typer.echo(f" {p.project_root} [{state}]")
|
|
506
464
|
else:
|
|
507
465
|
_typer.echo("No projects loaded.")
|
|
508
|
-
client.close()
|
|
509
466
|
|
|
510
467
|
|
|
511
468
|
@daemon_app.command("restart")
|