function(_get_codex_skills_root out_var) # 需要 CMake 3.21+,可展开 ~ file(REAL_PATH "~/.codex/skills" _codex_skills_root EXPAND_TILDE) set(${out_var} "${_codex_skills_root}" PARENT_SCOPE) endfunction() function(codex_load_skill_dir_ex skill_dir _name) if(NOT IS_DIRECTORY "${skill_dir}") message(FATAL_ERROR "load_skill_dir: not a directory: ${skill_dir}") endif() # 取绝对路径 get_filename_component(_src "${skill_dir}" REALPATH) # 目标根目录 ~/.codex/skills set(_skills_root) _get_codex_skills_root(_skills_root) file(MAKE_DIRECTORY "${_skills_root}") set(_dst "${_skills_root}/${_name}") # 已存在时先检查 if(EXISTS "${_dst}" OR IS_SYMLINK "${_dst}") message(STATUS "Skill link already exists, skip: ${_dst}") return() endif() message(STATUS "Create skill symlink:") message(STATUS " from: ${_src}") message(STATUS " to : ${_dst}") file(CREATE_LINK "${_src}" "${_dst}" SYMBOLIC) if(NOT EXISTS "${_dst}" AND NOT IS_SYMLINK "${_dst}") message(FATAL_ERROR "load_skill_dir: failed to create symlink: ${_dst}\n" "On Windows this may require Developer Mode or Administrator privileges." ) endif() endfunction() function(codex_load_skill_dir skill_dir) get_filename_component(_name "${skill_dir}" NAME) codex_load_skill_dir_ex(${skill_dir} ${_name}) endfunction() function(codex_unload_skill_dir skill_dir) if(NOT IS_DIRECTORY "${skill_dir}") message(FATAL_ERROR "unload_skill_dir: not a directory: ${skill_dir}") endif() get_filename_component(_src "${skill_dir}" REALPATH) get_filename_component(_name "${_src}" NAME) set(_skills_root) _get_codex_skills_root(_skills_root) set(_dst "${_skills_root}/${_name}") if(IS_SYMLINK "${_dst}") message(STATUS "Remove skill symlink: ${_dst}") file(REMOVE "${_dst}") elseif(EXISTS "${_dst}") message(FATAL_ERROR "unload_skill_dir: target exists but is not a symlink, refuse to remove: ${_dst}" ) else() message(STATUS "Skill link not found, skip: ${_dst}") endif() endfunction()