test
This commit is contained in:
0
scripts/util/__init__.py
Normal file
0
scripts/util/__init__.py
Normal file
@@ -1,5 +1,4 @@
|
||||
"""argparse 中文错误说明。"""
|
||||
|
||||
"""argparse 中文错误说明(与模板一致)。"""
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
"""技能配置初始化:.env.example 落盘与用户 .env 缺失项合并。"""
|
||||
"""配置初始化:从 .env.example 复制到用户 .env,并合并缺失键。
|
||||
|
||||
行为对齐模板:``main.py`` 与 ``cli.app.main()`` 启动时均会调用一次。
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
@@ -11,8 +13,11 @@ from util.runtime_paths import get_skill_root
|
||||
|
||||
|
||||
def bootstrap_skill_config() -> str:
|
||||
"""确保用户数据目录 .env 存在,并追加 .env.example 中的新配置项。"""
|
||||
"""确保用户 .env 存在,并追加 .env.example 中的新配置项。"""
|
||||
example_path = os.path.join(get_skill_root(), ".env.example")
|
||||
if not os.path.isfile(example_path):
|
||||
# demo 没有强制 .env.example,直接返回空路径
|
||||
return ""
|
||||
env_path = config.ensure_env_file(SKILL_SLUG, example_path)
|
||||
comment = f"{SKILL_SLUG} v{SKILL_VERSION}" if SKILL_VERSION else None
|
||||
config.merge_missing_env_keys(example_path, env_path, comment_skill=comment)
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
"""技能标识、版本与平台公共库约束(复制后请修改 slug/version/logger)。"""
|
||||
"""技能标识与版本(待办事项)。
|
||||
|
||||
真实技能需保证 slug = 目录名 = DB 文件名 = ``metadata.openclaw.slug``。
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
# 英文 kebab-case 机器标识;与目录名、actions.json 的 ``skill`` 字段一致
|
||||
SKILL_SLUG = "add-todo-all"
|
||||
SKILL_VERSION = "1.0.98"
|
||||
LOG_LOGGER_NAME = "openclaw.skill.add_todo_all"
|
||||
SKILL_VERSION = "0.1.0"
|
||||
LOG_LOGGER_NAME = "openclaw.skill.add-todo-all"
|
||||
PLATFORM_KIT_MIN_VERSION = "1.2.11"
|
||||
|
||||
@@ -1,21 +1,33 @@
|
||||
"""Re-export unified logging (implementation: jiangchang_skill_core.unified_logging)."""
|
||||
"""日志:直接用 stdlib logging(真实模板用 jiangchang_skill_core.unified_logging)。
|
||||
|
||||
from jiangchang_skill_core.unified_logging import (
|
||||
attach_unified_file_handler,
|
||||
ensure_trace_for_process,
|
||||
get_skill_log_file_path,
|
||||
get_skill_logger,
|
||||
get_unified_logs_dir,
|
||||
setup_skill_logging,
|
||||
subprocess_env_with_trace,
|
||||
)
|
||||
为保持与模板 ``from util.logging_config import get_skill_logger, setup_skill_logging``
|
||||
一致的调用面,本 demo 提供同名薄封装。
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
__all__ = [
|
||||
"attach_unified_file_handler",
|
||||
"ensure_trace_for_process",
|
||||
"get_skill_log_file_path",
|
||||
"get_skill_logger",
|
||||
"get_unified_logs_dir",
|
||||
"setup_skill_logging",
|
||||
"subprocess_env_with_trace",
|
||||
]
|
||||
import logging
|
||||
|
||||
import jiangchang_skill_core.unified_logging as unified_logging
|
||||
|
||||
from util.constants import LOG_LOGGER_NAME
|
||||
|
||||
_configured = False
|
||||
|
||||
|
||||
def setup_skill_logging(skill_slug: str, logger_name: str) -> None:
|
||||
# global _configured
|
||||
# if _configured:
|
||||
# return
|
||||
# handler = logging.StreamHandler()
|
||||
# handler.setFormatter(logging.Formatter("%(asctime)s %(levelname)s %(name)s: %(message)s"))
|
||||
# logger = logging.getLogger(logger_name)
|
||||
# logger.setLevel(logging.INFO)
|
||||
# if not logger.handlers:
|
||||
# logger.addHandler(handler)
|
||||
# _configured = True
|
||||
unified_logging.setup_skill_logging(skill_slug, logger_name)
|
||||
|
||||
|
||||
def get_skill_logger() -> logging.Logger:
|
||||
#return logging.getLogger(LOG_LOGGER_NAME)
|
||||
return unified_logging.get_skill_logger()
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
"""数据根、技能目录、兄弟技能根路径与用户数据子目录解析。"""
|
||||
"""技能数据目录与 DB 路径解析(简化版)。
|
||||
|
||||
真实模板用 ``jiangchang_skill_core.runtime_env``;本 demo 复用其 mock。
|
||||
数据目录 = ``{data_root}/{user_id}/{slug}/``,DB 即 ``{slug}.db``。
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
|
||||
from jiangchang_skill_core.runtime_env import get_data_root, get_sibling_skills_root, get_user_id
|
||||
from jiangchang_skill_core.runtime_env import get_data_root, get_user_id
|
||||
|
||||
from util.constants import SKILL_SLUG
|
||||
|
||||
@@ -32,28 +35,22 @@ CONFIG_KEY_TEMP_DIR = "SKILL_TEMP_DIR"
|
||||
|
||||
|
||||
def get_skill_root() -> str:
|
||||
"""技能根目录(含 SKILL.md / scripts/ 的目录)。"""
|
||||
return os.path.dirname(_SCRIPTS_DIR)
|
||||
|
||||
|
||||
def get_openclaw_root() -> str:
|
||||
return get_sibling_skills_root(_SCRIPTS_DIR)
|
||||
|
||||
|
||||
def get_skills_root() -> str:
|
||||
return get_sibling_skills_root(_SCRIPTS_DIR)
|
||||
|
||||
|
||||
def get_skill_data_dir() -> str:
|
||||
"""本技能数据目录:``{data_root}/{user_id}/{slug}/``。"""
|
||||
path = os.path.join(get_data_root(), get_user_id(), SKILL_SLUG)
|
||||
os.makedirs(path, exist_ok=True)
|
||||
return path
|
||||
|
||||
|
||||
def get_db_path(filename: str | None = None) -> str:
|
||||
"""SQLite 文件路径,默认 ``{slug}.db``。"""
|
||||
name = filename or f"{SKILL_SLUG}.db"
|
||||
return os.path.join(get_skill_data_dir(), name)
|
||||
|
||||
|
||||
def _normalize_subdir(value: str) -> str:
|
||||
cleaned = value.strip().strip("/\\")
|
||||
if not cleaned or cleaned.startswith(".."):
|
||||
@@ -153,3 +150,4 @@ def list_resolved_data_paths() -> dict[str, str]:
|
||||
"temp_dir": get_temp_dir(create=False),
|
||||
"videos_dir": get_videos_dir(create=False),
|
||||
}
|
||||
|
||||
|
||||
@@ -66,8 +66,8 @@ LEGACY_EXEMPT_SLUGS: frozenset[str] = frozenset(
|
||||
{
|
||||
"account-manager",
|
||||
"skill-template",
|
||||
"add-todo-all",
|
||||
"add_todo_all",
|
||||
"your-skill-slug",
|
||||
"your_skill_slug",
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user