完成运行时与启动链路的全面相对路径整改,统一以仓库根为路径基准并移除 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

@ -9,7 +9,7 @@ from oclaw.runtime.tools.base import ToolSpec
def _plugin_cfg() -> dict[str, Any]:
cfg_path = (PROJECT_ROOT / "oclaw" / "oclaw.json").resolve()
cfg_path = (PROJECT_ROOT / "oclaw.json").resolve()
if not cfg_path.exists():
return {}
try:
@ -25,7 +25,7 @@ def _plugin_cfg() -> dict[str, Any]:
def _wiki_handlers() -> dict[str, Callable[[dict[str, Any]], dict[str, Any]]]:
api_path = (PROJECT_ROOT / "oclaw" / "runtime" / "extensions" / "memory-wiki" / "api.py").resolve()
api_path = (PROJECT_ROOT / "runtime" / "extensions" / "memory-wiki" / "api.py").resolve()
spec = importlib.util.spec_from_file_location("memory_wiki_api", str(api_path))
if spec is None or spec.loader is None:
return {}

View file

@ -1,6 +1,7 @@
from __future__ import annotations
import hashlib
from pathlib import Path
from typing import Any
from oclaw.runtime.tools.base import ToolSpec
@ -59,11 +60,30 @@ def read_file_tool() -> ToolSpec:
def write_file_tool() -> ToolSpec:
def _normalize_write_path(path: str) -> str:
raw = str(path or "").strip().strip('"').strip("'")
if not raw:
raise ValueError("path_required")
p = Path(raw)
if p.is_absolute():
return str(p)
# Keep generated files out of repo root: default relative writes go under data/<workspace_name>/...
ws = resolve_workspace_path(".")
ws_name = ws.name or "workspace"
rel = raw.lstrip("./\\")
if not rel:
raise ValueError("path_required")
return str(Path("data") / ws_name / rel)
def handler(args: dict[str, Any]) -> dict[str, Any]:
path = str(args.get("path") or "").strip()
content = str(args.get("content") or "")
mode = str(args.get("mode") or "overwrite").strip().lower()
p = resolve_workspace_path(path)
try:
normalized = _normalize_write_path(path)
except ValueError as exc:
return {"ok": False, "error": str(exc)}
p = resolve_workspace_path(normalized)
p.parent.mkdir(parents=True, exist_ok=True)
if mode not in ("overwrite", "append"):
return {"ok": False, "error": "invalid_mode", "allowed": ["overwrite", "append"]}