From cedef87dab0527e9bb70c92f866bccb89b3d65bc Mon Sep 17 00:00:00 2001 From: JOJO <1498581755@qq.com> Date: Thu, 13 Aug 2026 00:21:33 +0800 Subject: [PATCH] =?UTF-8?q?fix(skills):=20/=E8=8F=9C=E5=8D=95=E6=8F=92?= =?UTF-8?q?=E5=85=A5=20skill=20=E6=94=B9=E7=94=A8=E7=9B=B8=E5=AF=B9?= =?UTF-8?q?=E8=B7=AF=E5=BE=84=EF=BC=8C=E9=81=BF=E5=85=8D=E6=9A=B4=E9=9C=B2?= =?UTF-8?q?=E6=9C=8D=E5=8A=A1=E5=99=A8=E7=BB=9D=E5=AF=B9=E8=B7=AF=E5=BE=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - /api/skills 列表 path 从 str(skill_file.resolve()) 改为相对工作区根路径 - 注入对话历史与任务快照的 skill path 同步改为相对路径 - _resolve_workspace_skill_path 本身支持相对路径解析,前端无需改动 - 存量绝对路径仍可解析,向后兼容 --- server/tasks/skills.py | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/server/tasks/skills.py b/server/tasks/skills.py index b50c227e..4413e2af 100644 --- a/server/tasks/skills.py +++ b/server/tasks/skills.py @@ -35,8 +35,19 @@ def _parse_skill_metadata(content: str, fallback_name: str) -> Dict[str, str]: metadata["name"] = metadata.get("name") or fallback_name return metadata +def _workspace_project_root(workspace) -> Path: + """工作区根目录(已 resolve 的绝对路径)。""" + return Path(workspace.project_path).expanduser().resolve() + def _workspace_skills_dir(workspace) -> Path: - return (Path(workspace.project_path).expanduser().resolve() / WORKSPACE_SKILLS_DIRNAME).resolve() + return _workspace_project_root(workspace) / WORKSPACE_SKILLS_DIRNAME + +def _rel_skill_path(skill_file: Path, workspace) -> str: + """把 skill 文件的绝对路径转成相对工作区根的路径(如 `.astrion/skills/xxx/SKILL.md`)。 + + 前端 / 菜单插入、对话历史、任务快照均使用该相对路径,避免暴露服务器绝对路径。 + """ + return str(skill_file.relative_to(_workspace_project_root(workspace)).as_posix()) def _resolve_workspace_skill_path(workspace, raw_path: str) -> Path: try: @@ -83,7 +94,7 @@ def _list_workspace_skills(workspace) -> List[Dict[str, str]]: result.append({ "name": metadata.get("name") or skill_file.parent.name, "description": metadata.get("description") or "", - "path": str(skill_file.resolve()), + "path": _rel_skill_path(skill_file, workspace), }) return result @@ -102,7 +113,7 @@ def _build_skill_context_messages(workspace, raw_refs: Any) -> List[Dict[str, st if not raw_path: continue skill_file = _resolve_workspace_skill_path(workspace, raw_path) - path_key = str(skill_file) + path_key = _rel_skill_path(skill_file, workspace) if path_key in seen_paths: debug_log(f"[SkillsAPI] build_skill_context duplicate path skipped: {path_key}") continue