完成运行时与启动链路的全面相对路径整改,统一以仓库根为路径基准并移除 oclaw 双层硬编码。

同时补齐路径回归测试与开源自检文档,确保从非仓库 cwd 启动时 workspace 根、配置和 wiki 路径仍稳定可用。

Made-with: Cursor
This commit is contained in:
oliver 2026-04-26 09:22:42 +08:00
parent dbbe3add6a
commit 9d2900db02
40 changed files with 223 additions and 82 deletions

View file

@ -811,7 +811,7 @@ def build_admin_router() -> APIRouter:
def api_runtime_scan_artifacts(authorization: str | None = Header(default=None)) -> dict[str, Any]:
ctx = _resolve_auth(SqliteStore(db_path()), authorization)
_require_permission(ctx, "admin:read")
root = (PROJECT_ROOT / "oclaw" / "runtime" / "data" / "scan").resolve()
root = (PROJECT_ROOT / "runtime" / "data" / "scan").resolve()
allowed_prefixes = ("history_entries_", "state_scan_")
items: list[dict[str, Any]] = []
if root.exists() and root.is_dir():
@ -836,7 +836,7 @@ def build_admin_router() -> APIRouter:
def api_runtime_scan_artifacts_cleanup(authorization: str | None = Header(default=None)) -> dict[str, Any]:
ctx = _resolve_auth(SqliteStore(db_path()), authorization)
_require_permission(ctx, "admin:runtime:write")
root = (PROJECT_ROOT / "oclaw" / "runtime" / "data" / "scan").resolve()
root = (PROJECT_ROOT / "runtime" / "data" / "scan").resolve()
allowed_prefixes = ("history_entries_", "state_scan_")
removed = 0
if root.exists() and root.is_dir():
@ -858,7 +858,7 @@ def build_admin_router() -> APIRouter:
body = payload or {}
ctx = _resolve_auth(SqliteStore(db_path()), authorization)
_require_permission(ctx, "admin:runtime:write")
root = (PROJECT_ROOT / "oclaw" / "runtime" / "data" / "scan").resolve()
root = (PROJECT_ROOT / "runtime" / "data" / "scan").resolve()
try:
keep_latest = int(body.get("keep_latest", 20))
except Exception:

View file

@ -152,7 +152,7 @@ def _config_open_file_handler(opts: dict[str, Any]) -> Any:
return None
if not assert_valid_params(params, _validate_config_get_params, "config.openFile", respond):
return None
config_path = os.getenv("OCLAW_CONFIG_PATH") or "oclaw/oclaw.json"
config_path = os.getenv("OCLAW_CONFIG_PATH") or "oclaw.json"
respond(True, {"ok": True, "path": config_path}, None, None)
return None

View file

@ -36,11 +36,11 @@ def _resolve_startup_workspace_dir(cfg: dict[str, Any]) -> str:
default_agent_id = resolve_default_agent_id(cfg)
ws = resolve_agent_workspace_dir(cfg, default_agent_id)
ws_text = str(ws or "").strip()
if ws_text:
if ws_text and ws_text not in {".", "./"}:
return ws_text
except Exception:
pass
return str((PROJECT_ROOT / "oclaw" / "runtime" / "workspaces" / "main").resolve())
return str((PROJECT_ROOT / "runtime" / "workspaces" / "main").resolve())
def _resolve_startup_workspace_dirs(cfg: dict[str, Any]) -> list[tuple[str, str]]:
@ -78,7 +78,7 @@ def _relocate_root_scan_artifacts() -> None:
Normalize them into runtime/data/scan on gateway startup.
"""
root = PROJECT_ROOT.resolve()
target_dir = (PROJECT_ROOT / "oclaw" / "runtime" / "data" / "scan").resolve()
target_dir = (PROJECT_ROOT / "runtime" / "data" / "scan").resolve()
target_dir.mkdir(parents=True, exist_ok=True)
patterns = ("history_entries_*.json", "state_scan_*.json")
for pat in patterns: