refactor: root-package imports (svc/runtime/interfaces) and fix PYTHONPATH

- Rename platform/ to svc/ to avoid shadowing stdlib platform.
- Replace from oclaw.* with from svc/runtime/interfaces; update -m CLI paths.
- tests/conftest: prepend repo root to sys.path (no parent-folder package name).
- CI: paths and offline_eval script under repo root.
- Ops scripts: PYTHONPATH must be repo root for python -m runtime.* (fixes gateway/WhatsApp sidecar startup).
- Fix default oclaw.json path in tabular/file attachment limits; stabilize attachment test config.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
oliver 2026-05-13 14:51:17 +08:00
parent 7941b27f58
commit 420abac9f1
405 changed files with 1316 additions and 1345 deletions

View file

@ -59,7 +59,7 @@ For role-specific behavior, contributors can add files under `data/wiki/experts/
#### Quick check
```bash
python -m oclaw.runtime.operations hooks info session-bootstrap --workspace "D:/project/chatgpt/oclaw" --json
python -m runtime.operations hooks info session-bootstrap --workspace "D:/project/chatgpt/oclaw" --json
```
Expected key fields: `enabled_by_config=true`, `eligible=true`, `loadable=true`.
@ -99,7 +99,7 @@ Legend: **Done** / **Partial** / **TODO**
| package.json `openclaw.hooks` / `oclaw.hooks` | Done |
| plugin hook dirs (`.codex-plugin` + `hooks`) | Done |
| legacy `hooks.internal.handlers` | Done |
| `hooks list/check/info` CLI (`python -m oclaw.runtime.operations hooks …`) | Done |
| `hooks list/check/info` CLI (`python -m runtime.operations hooks …`) | Done |
| `hooks enable` / `hooks disable` (config file patch) | Done |
| install / update hook packs (npm/git; TS `install.ts` / `update.ts`) | Partial (`hooks install` / `hooks update` print deprecation + manual/OpenClaw guidance; no npm/git runner) |
| gmail watcher family | Partial (config gates + ``initialize_hooks_runtime`` → ``start_gmail_watcher_with_logs``; ``gog``/API loop not ported). Set ``OCLAW_SKIP_GMAIL_WATCHER=1`` (or ``OPENCLAW_SKIP_GMAIL_WATCHER``) to no-op. |
@ -122,14 +122,14 @@ pytest tests/test_oclaw_hooks_bundled_parity.py tests/test_oclaw_hooks_runtime.p
### Operations CLI (from parent of this repo on `sys.path`, see `tests/conftest.py`)
```bash
python -m oclaw.runtime.operations hooks list
python -m oclaw.runtime.operations hooks list --eligible --verbose
python -m oclaw.runtime.operations hooks check --json
python -m oclaw.runtime.operations hooks info session-memory --workspace /path/to/workspace
python -m oclaw.runtime.operations hooks enable session-memory --workspace /path/to/workspace
python -m oclaw.runtime.operations hooks disable command-logger --workspace /path/to/workspace
python -m oclaw.runtime.operations hooks install ./path-or-npm-spec # deprecated, exit 2 + hints
python -m oclaw.runtime.operations hooks update --dry-run # deprecated, exit 2 + hints
python -m runtime.operations hooks list
python -m runtime.operations hooks list --eligible --verbose
python -m runtime.operations hooks check --json
python -m runtime.operations hooks info session-memory --workspace /path/to/workspace
python -m runtime.operations hooks enable session-memory --workspace /path/to/workspace
python -m runtime.operations hooks disable command-logger --workspace /path/to/workspace
python -m runtime.operations hooks install ./path-or-npm-spec # deprecated, exit 2 + hints
python -m runtime.operations hooks update --dry-run # deprecated, exit 2 + hints
```
Uses the same merged config as the agent runtime (including skill `hooks/` extra dirs via `merge_skill_hook_extra_dirs_into_config`).

View file

@ -9,8 +9,8 @@ OCLAW_DIR = HOOKS_PY_DIR.parent
if str(OCLAW_DIR) not in sys.path:
sys.path.insert(0, str(OCLAW_DIR))
from oclaw.runtime.hooks.internal_hooks import create_hook_event, trigger_hook # noqa: E402
from oclaw.runtime.hooks.loader import load_internal_hooks # noqa: E402
from runtime.hooks.internal_hooks import create_hook_event, trigger_hook # noqa: E402
from runtime.hooks.loader import load_internal_hooks # noqa: E402
def main() -> int:

View file

@ -122,8 +122,8 @@ def handle(event: Any) -> None:
# Fetch recent messages from sqlite.
try:
_ensure_repo_imports()
from oclaw.platform.config.paths import db_path # type: ignore
from oclaw.platform.persistence.sqlite_store import SqliteStore # type: ignore
from svc.config.paths import db_path # type: ignore
from svc.persistence.sqlite_store import SqliteStore # type: ignore
store = SqliteStore(db_path())
msgs = store.get_messages(session_id=session_id, limit=max_msgs_n)

View file

@ -3,7 +3,7 @@ from __future__ import annotations
from pathlib import Path
from typing import Any
from oclaw.runtime.skills import discover_workspace_skill_manifests
from runtime.skills import discover_workspace_skill_manifests
def merge_skill_hook_extra_dirs_into_config(cfg: dict[str, Any]) -> dict[str, Any]:

View file

@ -5,7 +5,7 @@ import os
from pathlib import Path
from typing import Any
from oclaw.platform.config.paths import PROJECT_ROOT
from svc.config.paths import PROJECT_ROOT
def resolve_hooks_config_storage_path() -> Path: