Ship MicroPython stubs from repo lib/ and seed workspace lib on startup
Move machine.py and neopixel.py into a tracked /lib/ at the repo root and auto-copy them into WORKSPACE_ROOT/lib whenever files are missing, so empty volumes and fresh per-user workspaces always have the read-only stubs available to Jedi and Pyodide. Allow all users to browse lib/ in the UI (writes still gated by the API), and add tests covering initial seeding and re-population after the dir is wiped. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -15,7 +15,12 @@ def _workspace_root(workspace_root: Path | None = None) -> Path:
|
||||
|
||||
|
||||
def _shared_lib_root() -> Path:
|
||||
return (config.WORKSPACE_ROOT.resolve() / LIB_DIR_NAME).resolve()
|
||||
"""Shared MicroPython stubs live under WORKSPACE_ROOT/lib; seed from bundle if missing (e.g. volume wiped)."""
|
||||
lib = (config.WORKSPACE_ROOT.resolve() / LIB_DIR_NAME).resolve()
|
||||
from editor_app.services.user_workspace import ensure_workspace_lib
|
||||
|
||||
ensure_workspace_lib()
|
||||
return lib
|
||||
|
||||
|
||||
def normalize_relative_path(relative_path: str) -> str:
|
||||
@@ -213,25 +218,24 @@ def delete_folder(folder_path: str, workspace_root: Path | None = None) -> None:
|
||||
|
||||
|
||||
def collect_python_sources(workspace_root: Path | None = None) -> dict[str, str]:
|
||||
"""Return all UTF-8 .py files under the workspace for browser-side Pyodide sync."""
|
||||
"""Return UTF-8 `.py` under the scoped workspace plus shared stubs from `WORKSPACE_ROOT/lib/` (bundled Micropython mocks for Jedi/completion and Pyodide)."""
|
||||
result: dict[str, str] = {}
|
||||
workspace = _workspace_root(workspace_root)
|
||||
if not workspace.exists():
|
||||
return result
|
||||
for path in workspace.rglob("*.py"):
|
||||
try:
|
||||
rel = path.relative_to(workspace)
|
||||
except ValueError:
|
||||
continue
|
||||
if any(part.startswith(".") for part in rel.parts):
|
||||
continue
|
||||
try:
|
||||
key = str(rel).replace("\\", "/")
|
||||
result[key] = path.read_text(encoding="utf-8")
|
||||
except (UnicodeDecodeError, OSError):
|
||||
continue
|
||||
if workspace.exists():
|
||||
for path in workspace.rglob("*.py"):
|
||||
try:
|
||||
rel = path.relative_to(workspace)
|
||||
except ValueError:
|
||||
continue
|
||||
if any(part.startswith(".") for part in rel.parts):
|
||||
continue
|
||||
try:
|
||||
key = str(rel).replace("\\", "/")
|
||||
result[key] = path.read_text(encoding="utf-8")
|
||||
except (UnicodeDecodeError, OSError):
|
||||
continue
|
||||
shared_lib = _shared_lib_root()
|
||||
if shared_lib.exists() and shared_lib.is_dir() and shared_lib != (workspace / LIB_DIR_NAME).resolve():
|
||||
if shared_lib.is_dir():
|
||||
for path in shared_lib.rglob("*.py"):
|
||||
try:
|
||||
rel = path.relative_to(shared_lib)
|
||||
|
||||
Reference in New Issue
Block a user