Files
skill-lib/src/skill/mod.rs
木炎 6aad2ce48e feat: restore zhihu browser skills
Reconnect the recovered Zhihu skill flows to the live browser runtime and resolve their resources relative to the executable so they work outside the repo root.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-27 14:29:38 +08:00

86 lines
2.8 KiB
Rust

pub mod router;
pub mod zhihu;
pub mod zhihu_hotlist;
pub mod zhihu_hotlist_store;
pub mod zhihu_navigation;
use std::path::PathBuf;
use crate::pipe::{BrowserPipeTool, PipeError, Transport};
fn relative_skill_resource_path(resource_name: &str) -> PathBuf {
PathBuf::from("resources")
.join("skills")
.join(resource_name)
}
pub(crate) fn skill_resource_path_from_executable(
executable_path: PathBuf,
resource_name: &str,
) -> PathBuf {
executable_path
.parent()
.map(|dir| dir.join("resources").join("skills").join(resource_name))
.unwrap_or_else(|| relative_skill_resource_path(resource_name))
}
pub(crate) fn default_skill_resource_path(resource_name: &str) -> PathBuf {
std::env::current_exe()
.ok()
.map(|path| skill_resource_path_from_executable(path, resource_name))
.filter(|path| path.exists())
.unwrap_or_else(|| relative_skill_resource_path(resource_name))
}
pub fn try_execute_skill<T: Transport>(
transport: &T,
browser_tool: &BrowserPipeTool<T>,
instruction: &str,
) -> Result<Option<String>, PipeError> {
match router::route_instruction(instruction)
.map_err(|err| PipeError::Protocol(err.to_string()))?
{
Some(router::RoutedSkill::ZhihuWrite(req)) => {
let result = zhihu::execute(transport, browser_tool, req)
.map_err(|err| PipeError::Protocol(err.to_string()))?;
Ok(Some(result.summary))
}
Some(router::RoutedSkill::ZhihuHotlistCollect(req)) => {
let result = zhihu_hotlist::execute_collect(transport, browser_tool, req)
.map_err(|err| PipeError::Protocol(err.to_string()))?;
Ok(Some(result.summary))
}
Some(router::RoutedSkill::ZhihuHotlistReport(req)) => {
let result = zhihu_hotlist::execute_report(req)
.map_err(|err| PipeError::Protocol(err.to_string()))?;
Ok(Some(result.summary))
}
Some(router::RoutedSkill::ZhihuNavigate(req)) => {
let result = zhihu_navigation::execute(transport, browser_tool, req)
.map_err(|err| PipeError::Protocol(err.to_string()))?;
Ok(Some(result.summary))
}
None => Ok(None),
}
}
#[cfg(test)]
mod tests {
use std::path::PathBuf;
use super::skill_resource_path_from_executable;
#[test]
fn skill_resource_path_uses_executable_directory_instead_of_cwd() {
let executable_path = PathBuf::from("/tmp/out/KylinRelease/sgclaw");
let resolved =
skill_resource_path_from_executable(executable_path, "zhihu_navigation_pages.json");
assert_eq!(
resolved,
PathBuf::from("/tmp/out/KylinRelease/resources/skills/zhihu_navigation_pages.json")
);
}
}