Fix: Support XDG_CONFIG_HOME for sessions.db on Windows with non-ASCII usernames (#102)

* fix: support XDG_CONFIG_HOME for sessions.db on Windows

Fixes SQLite database opening failure on Windows systems with non-ASCII
usernames (e.g., Chinese characters). The get_db_path() function now
supports the XDG_CONFIG_HOME environment variable, consistent with
get_config_dir() in settings.py.

Closes #101

* fix: auto-resolve Windows Unicode path for sqlite3 via 8.3 short path

Refactor get_db_path() to reuse get_config_dir() (XDG_CONFIG_HOME
support) and add _to_short_path() helper that converts the config
directory to its Windows 8.3 short form via GetShortPathNameW. This
automatically resolves sqlite3 failures on Windows systems with
non-ASCII usernames (e.g., Chinese characters) without requiring
manual environment variable configuration.

The short-path conversion is best-effort: it targets the directory
(which exists after mkdir) rather than the db file, and falls back
gracefully on non-Windows, non-NTFS, or when 8.3 naming is disabled.

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

---------

Co-authored-by: Xi Zhang <106144707+X-iZhang@users.noreply.github.com>
Co-authored-by: X-iZhang <zacharyzhang2022@gmail.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
JackyFan
2026-04-09 01:50:42 +08:00
committed by GitHub
parent 3647ff1afa
commit 632159261c
+32 -3
View File
@@ -39,11 +39,40 @@ AGENT_NAME = "EvoScientist"
# ---------------------------------------------------------------------------
def _to_short_path(path: str) -> str:
"""Try to convert a Windows path to its 8.3 short form.
On Windows, sqlite3 may fail to open databases at paths containing
non-ASCII characters (e.g., Chinese usernames). Short paths are
ASCII-safe when available, but conversion is best-effort: it fails
when 8.3 name generation is disabled, on non-NTFS volumes, or for
nonexistent targets. Returns the original path on non-Windows or
on failure.
"""
import sys
if sys.platform != "win32":
return path
import ctypes
buf = ctypes.create_unicode_buffer(32767)
if ctypes.windll.kernel32.GetShortPathNameW(path, buf, len(buf)):
return buf.value
return path
def get_db_path() -> Path:
"""Return ``~/.config/evoscientist/sessions.db``, creating parents."""
db_dir = Path.home() / ".config" / "evoscientist"
"""Return the sessions database path, creating parents.
Reuses ``get_config_dir()`` for XDG_CONFIG_HOME support, then applies
a best-effort Windows 8.3 short-path conversion on the *directory*
(which exists after ``mkdir``) so sqlite3 can handle non-ASCII paths.
"""
from .config.settings import get_config_dir
db_dir = get_config_dir()
db_dir.mkdir(parents=True, exist_ok=True)
return db_dir / "sessions.db"
return Path(_to_short_path(str(db_dir))) / "sessions.db"
def generate_thread_id() -> str: