5 Commits

Author SHA1 Message Date
Jiangzhou 05d38f2733 feat: ccc doctor and upgrade cocoindex version (#110) 2026-03-20 21:16:55 -07:00
Jiangzhou a0a5a408ed feat: search pending on load-time indexing (#91) 2026-03-16 19:01:55 -07:00
Jiangzhou 0b30f16451 feat: assorted improvements for CLI/daemon to be resilient and ergonomic (#72)
* feat: assorted improvements for CLI/daemon to be resilient and ergonomic

* tests: add more e2e tests

* fix: resolve path comparison and LMDB cleanup issues on Windows/3.14t

Three root causes fixed:

1. Path resolution mismatch on Windows: init and auto_init_project used
   unresolved Path.cwd() but find_parent_with_marker/find_project_root
   resolve internally, causing comparison failures and daemon key mismatches.

2. LMDB not released on remove_project: The daemon ProjectRegistry
   dropped the Project from dicts without closing its SQLite connection or
   forcing GC of the Rust LMDB environment. On free-threaded Python (3.14t)
   and Windows, deferred GC kept the LMDB open, causing environment already
   open errors and PermissionErrors when deleting db files.

3. Silent connection close on streaming errors: When update_index async
   iteration failed in the daemon, the connection was closed without sending
   an ErrorResponse, causing the client to get an unhelpful EOFError.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: break LMDB reference chain explicitly and resolve cwd in path filter

On 3.14t (free-threaded Python), gc.collect() alone does not release the
Rust LMDB environment because deferred reference counting keeps
core.Environment alive through App._core_env_app, ContextProvider._core_env,
and Environment._core_env.  Explicitly null these internal references in
Project.close() before gc.collect() so the Rust object is freed promptly.

Also resolve Path.cwd() in resolve_default_path() — on Windows, the
unresolved cwd did not match the resolved project_root, causing
relative_to() to fail and the subdirectory path filter to be skipped.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: use double gc.collect() for layered deferred refcount on 3.14t

Revert fragile internal attribute clearing. On free-threaded Python, the
first gc.collect() frees Python wrappers whose Rust Drop implementations
issue further deferred Py_DECREF calls on core.Environment; a second
gc.collect() flushes those and actually drops the LMDB handle.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: add sleep in tests for LMDB release on free-threaded Python

On 3.14t, deferred reference counting means the Rust LMDB environment
is not released immediately after remove_project + gc.collect(). Add a
1-second sleep in the two tests that reset and re-index, giving the
runtime time to process pending deferred Py_DECREF calls.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: restart daemon after reset in tests, increase daemon wait timeout

Instead of sleeping, restart the daemon after reset in the two tests
that re-index after removing databases. This reliably releases the LMDB
environment on all platforms including free-threaded Python (3.14t).

Also increase _wait_for_daemon timeout from 5s to 10s — Windows CI
runners occasionally need longer to start the daemon subprocess.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 23:04:00 -07:00
Jiangzhou 86fca84323 feat: show indexing progress gracefully (#71) 2026-03-15 18:28:15 -07:00
Jiangzhou 9000f1df7e feat: preliminary implementation for daemon + CLI (#67) 2026-03-14 15:57:26 -07:00