代码警告消除和优化
This commit is contained in:
@@ -8,17 +8,16 @@ use sacp::schema::{
|
|||||||
CreateTerminalRequest, CreateTerminalResponse, EmbeddedResource, EmbeddedResourceResource,
|
CreateTerminalRequest, CreateTerminalResponse, EmbeddedResource, EmbeddedResourceResource,
|
||||||
FileSystemCapability, ImageContent, InitializeRequest, KillTerminalCommandRequest,
|
FileSystemCapability, ImageContent, InitializeRequest, KillTerminalCommandRequest,
|
||||||
KillTerminalCommandResponse, LoadSessionRequest, NewSessionRequest, NewSessionResponse,
|
KillTerminalCommandResponse, LoadSessionRequest, NewSessionRequest, NewSessionResponse,
|
||||||
PermissionOptionKind, Plan, PlanEntryPriority, PlanEntryStatus, PromptRequest,
|
PermissionOptionKind, Plan, PlanEntryPriority, PlanEntryStatus, PromptRequest, ProtocolVersion,
|
||||||
ProtocolVersion, ReadTextFileRequest, ReadTextFileResponse, ReleaseTerminalRequest,
|
ReadTextFileRequest, ReadTextFileResponse, ReleaseTerminalRequest, ReleaseTerminalResponse,
|
||||||
ReleaseTerminalResponse, RequestPermissionOutcome, RequestPermissionRequest,
|
RequestPermissionOutcome, RequestPermissionRequest, RequestPermissionResponse, ResourceLink,
|
||||||
RequestPermissionResponse, ResourceLink, SelectedPermissionOutcome, SessionConfigKind,
|
SelectedPermissionOutcome, SessionConfigKind, SessionConfigOption, SessionConfigOptionCategory,
|
||||||
SessionConfigOption, SessionConfigOptionCategory, SessionConfigSelectGroup,
|
SessionConfigSelectGroup, SessionConfigSelectOption, SessionConfigSelectOptions, SessionId,
|
||||||
SessionConfigSelectOption, SessionConfigSelectOptions, SessionId, SessionModeState,
|
SessionModeState, SessionNotification, SessionUpdate, SetSessionConfigOptionRequest,
|
||||||
SessionNotification, SessionUpdate, SetSessionConfigOptionRequest,
|
|
||||||
SetSessionConfigOptionResponse, SetSessionModeRequest, StopReason, TerminalExitStatus,
|
SetSessionConfigOptionResponse, SetSessionModeRequest, StopReason, TerminalExitStatus,
|
||||||
TerminalOutputRequest, TerminalOutputResponse, TextContent, TextResourceContents,
|
TerminalOutputRequest, TerminalOutputResponse, TextContent, TextResourceContents,
|
||||||
ToolCallContent, WaitForTerminalExitRequest, WaitForTerminalExitResponse,
|
ToolCallContent, WaitForTerminalExitRequest, WaitForTerminalExitResponse, WriteTextFileRequest,
|
||||||
WriteTextFileRequest, WriteTextFileResponse,
|
WriteTextFileResponse,
|
||||||
};
|
};
|
||||||
use sacp::util::MatchDispatch;
|
use sacp::util::MatchDispatch;
|
||||||
use sacp::{
|
use sacp::{
|
||||||
@@ -790,7 +789,7 @@ fn respond_terminal_request<T: sacp::JsonRpcResponse>(
|
|||||||
) -> Result<(), sacp::Error> {
|
) -> Result<(), sacp::Error> {
|
||||||
match result {
|
match result {
|
||||||
Ok(response) => responder.respond(response),
|
Ok(response) => responder.respond(response),
|
||||||
Err(error) => responder.respond_with_error(error.to_rpc_error()),
|
Err(error) => responder.respond_with_error(error.into_rpc_error()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -800,7 +799,7 @@ fn respond_file_system_request<T: sacp::JsonRpcResponse>(
|
|||||||
) -> Result<(), sacp::Error> {
|
) -> Result<(), sacp::Error> {
|
||||||
match result {
|
match result {
|
||||||
Ok(response) => responder.respond(response),
|
Ok(response) => responder.respond(response),
|
||||||
Err(error) => responder.respond_with_error(error.to_rpc_error()),
|
Err(error) => responder.respond_with_error(error.into_rpc_error()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1176,7 +1175,8 @@ fn map_prompt_blocks(blocks: Vec<PromptInputBlock>) -> Vec<ContentBlock> {
|
|||||||
EmbeddedResourceResource::BlobResourceContents(content)
|
EmbeddedResourceResource::BlobResourceContents(content)
|
||||||
}
|
}
|
||||||
(None, None) => {
|
(None, None) => {
|
||||||
let content = TextResourceContents::new("", uri.clone()).mime_type(mime_type);
|
let content =
|
||||||
|
TextResourceContents::new("", uri.clone()).mime_type(mime_type);
|
||||||
EmbeddedResourceResource::TextResourceContents(content)
|
EmbeddedResourceResource::TextResourceContents(content)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ pub enum FileSystemRuntimeError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl FileSystemRuntimeError {
|
impl FileSystemRuntimeError {
|
||||||
pub fn to_rpc_error(self) -> sacp::Error {
|
pub fn into_rpc_error(self) -> sacp::Error {
|
||||||
match self {
|
match self {
|
||||||
Self::InvalidParams(message) => sacp::Error::invalid_params().data(message),
|
Self::InvalidParams(message) => sacp::Error::invalid_params().data(message),
|
||||||
Self::Internal(message) => sacp::util::internal_error(message),
|
Self::Internal(message) => sacp::util::internal_error(message),
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ pub enum TerminalRuntimeError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl TerminalRuntimeError {
|
impl TerminalRuntimeError {
|
||||||
pub fn to_rpc_error(self) -> sacp::Error {
|
pub fn into_rpc_error(self) -> sacp::Error {
|
||||||
match self {
|
match self {
|
||||||
Self::InvalidParams(message) => sacp::Error::invalid_params().data(message),
|
Self::InvalidParams(message) => sacp::Error::invalid_params().data(message),
|
||||||
Self::Internal(message) => sacp::util::internal_error(message),
|
Self::Internal(message) => sacp::util::internal_error(message),
|
||||||
|
|||||||
@@ -1126,7 +1126,7 @@ fn list_skills_from_dir(
|
|||||||
}
|
}
|
||||||
by_id.insert(
|
by_id.insert(
|
||||||
id.clone(),
|
id.clone(),
|
||||||
build_skill_item(id, scope.clone(), AgentSkillLayout::SkillDirectory, path),
|
build_skill_item(id, scope, AgentSkillLayout::SkillDirectory, path),
|
||||||
);
|
);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -1145,7 +1145,7 @@ fn list_skills_from_dir(
|
|||||||
}
|
}
|
||||||
by_id.insert(
|
by_id.insert(
|
||||||
stem.clone(),
|
stem.clone(),
|
||||||
build_skill_item(stem, scope.clone(), AgentSkillLayout::MarkdownFile, path),
|
build_skill_item(stem, scope, AgentSkillLayout::MarkdownFile, path),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1167,7 +1167,7 @@ fn locate_existing_skill(
|
|||||||
if skill_dir.is_dir() && skill_dir.join("SKILL.md").is_file() {
|
if skill_dir.is_dir() && skill_dir.join("SKILL.md").is_file() {
|
||||||
return Some(build_skill_item(
|
return Some(build_skill_item(
|
||||||
skill_id.to_string(),
|
skill_id.to_string(),
|
||||||
scope.clone(),
|
scope,
|
||||||
AgentSkillLayout::SkillDirectory,
|
AgentSkillLayout::SkillDirectory,
|
||||||
skill_dir,
|
skill_dir,
|
||||||
));
|
));
|
||||||
@@ -1542,6 +1542,7 @@ pub async fn acp_clear_binary_cache(agent_type: AgentType) -> Result<(), AcpErro
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub async fn acp_update_agent_preferences(
|
pub async fn acp_update_agent_preferences(
|
||||||
agent_type: AgentType,
|
agent_type: AgentType,
|
||||||
enabled: bool,
|
enabled: bool,
|
||||||
@@ -1923,8 +1924,8 @@ pub async fn acp_list_agent_skills(
|
|||||||
|
|
||||||
let mut skills = skills_by_key.into_values().collect::<Vec<_>>();
|
let mut skills = skills_by_key.into_values().collect::<Vec<_>>();
|
||||||
skills.sort_by(|a, b| {
|
skills.sort_by(|a, b| {
|
||||||
scope_rank(a.scope.clone())
|
scope_rank(a.scope)
|
||||||
.cmp(&scope_rank(b.scope.clone()))
|
.cmp(&scope_rank(b.scope))
|
||||||
.then_with(|| a.name.cmp(&b.name))
|
.then_with(|| a.name.cmp(&b.name))
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1953,7 +1954,7 @@ pub async fn acp_read_agent_skill(
|
|||||||
|
|
||||||
let skill = locate_existing_skill_across_dirs(&dirs, spec.kind, &id, scope)
|
let skill = locate_existing_skill_across_dirs(&dirs, spec.kind, &id, scope)
|
||||||
.ok_or_else(|| AcpError::protocol(format!("skill not found: {id}")))?;
|
.ok_or_else(|| AcpError::protocol(format!("skill not found: {id}")))?;
|
||||||
let content_path = skill_content_path(skill.layout.clone(), Path::new(&skill.path));
|
let content_path = skill_content_path(skill.layout, Path::new(&skill.path));
|
||||||
let content = fs::read_to_string(&content_path)
|
let content = fs::read_to_string(&content_path)
|
||||||
.map_err(|e| AcpError::protocol(format!("failed to read skill content: {e}")))?;
|
.map_err(|e| AcpError::protocol(format!("failed to read skill content: {e}")))?;
|
||||||
Ok(AgentSkillContent { skill, content })
|
Ok(AgentSkillContent { skill, content })
|
||||||
@@ -1998,7 +1999,7 @@ pub async fn acp_save_agent_skill(
|
|||||||
};
|
};
|
||||||
|
|
||||||
let skill_path = PathBuf::from(&skill.path);
|
let skill_path = PathBuf::from(&skill.path);
|
||||||
let content_path = skill_content_path(skill.layout.clone(), &skill_path);
|
let content_path = skill_content_path(skill.layout, &skill_path);
|
||||||
|
|
||||||
if skill.layout == AgentSkillLayout::SkillDirectory {
|
if skill.layout == AgentSkillLayout::SkillDirectory {
|
||||||
fs::create_dir_all(&skill_path).map_err(|e| {
|
fs::create_dir_all(&skill_path).map_err(|e| {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
use std::collections::{BTreeMap, BTreeSet};
|
use std::collections::{BTreeMap, BTreeSet};
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
use std::sync::LazyLock;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use serde::de::DeserializeOwned;
|
use serde::de::DeserializeOwned;
|
||||||
@@ -11,6 +12,14 @@ use crate::app_error::AppCommandError;
|
|||||||
|
|
||||||
const MARKETPLACE_OFFICIAL: &str = "official_registry";
|
const MARKETPLACE_OFFICIAL: &str = "official_registry";
|
||||||
const MARKETPLACE_SMITHERY: &str = "smithery";
|
const MARKETPLACE_SMITHERY: &str = "smithery";
|
||||||
|
static MARKETPLACE_HTTP_CLIENT: LazyLock<Result<reqwest::Client, String>> = LazyLock::new(|| {
|
||||||
|
reqwest::Client::builder()
|
||||||
|
.connect_timeout(Duration::from_secs(8))
|
||||||
|
.timeout(Duration::from_secs(20))
|
||||||
|
.user_agent("codeg-mcp-market/1.0")
|
||||||
|
.build()
|
||||||
|
.map_err(|e| format!("failed to initialize marketplace HTTP client: {e}"))
|
||||||
|
});
|
||||||
|
|
||||||
fn mcp_invalid_input(message: impl Into<String>) -> AppCommandError {
|
fn mcp_invalid_input(message: impl Into<String>) -> AppCommandError {
|
||||||
AppCommandError::invalid_input(message)
|
AppCommandError::invalid_input(message)
|
||||||
@@ -588,11 +597,9 @@ fn write_codex_root_toml(root: &toml::Value) -> Result<(), AppCommandError> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn obj_as_string_map(value: Option<&Value>) -> Option<Map<String, Value>> {
|
fn obj_as_string_map(value: Option<&Value>) -> Option<Map<String, Value>> {
|
||||||
let Some(obj) = value.and_then(Value::as_object) else {
|
let obj = value.and_then(Value::as_object)?;
|
||||||
return None;
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut output = Map::new();
|
let mut output = Map::with_capacity(obj.len());
|
||||||
for (key, item) in obj {
|
for (key, item) in obj {
|
||||||
let Some(s) = item.as_str() else {
|
let Some(s) = item.as_str() else {
|
||||||
continue;
|
continue;
|
||||||
@@ -616,12 +623,10 @@ fn contains_unresolved_placeholder(value: &str) -> bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn marketplace_http_client() -> Result<reqwest::Client, AppCommandError> {
|
fn marketplace_http_client() -> Result<reqwest::Client, AppCommandError> {
|
||||||
reqwest::Client::builder()
|
match &*MARKETPLACE_HTTP_CLIENT {
|
||||||
.connect_timeout(Duration::from_secs(8))
|
Ok(client) => Ok(client.clone()),
|
||||||
.timeout(Duration::from_secs(20))
|
Err(err) => Err(mcp_network(err.clone())),
|
||||||
.user_agent("codeg-mcp-market/1.0")
|
}
|
||||||
.build()
|
|
||||||
.map_err(|e| mcp_network(format!("failed to initialize marketplace HTTP client: {e}")))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn should_retry_http_status(status: reqwest::StatusCode) -> bool {
|
fn should_retry_http_status(status: reqwest::StatusCode) -> bool {
|
||||||
@@ -1000,11 +1005,9 @@ fn json_to_toml_value(value: &Value) -> Option<toml::Value> {
|
|||||||
}
|
}
|
||||||
Value::String(v) => Some(toml::Value::String(v.clone())),
|
Value::String(v) => Some(toml::Value::String(v.clone())),
|
||||||
Value::Array(values) => {
|
Value::Array(values) => {
|
||||||
let mut converted = Vec::new();
|
let mut converted = Vec::with_capacity(values.len());
|
||||||
for item in values {
|
for item in values {
|
||||||
let Some(next) = json_to_toml_value(item) else {
|
let next = json_to_toml_value(item)?;
|
||||||
return None;
|
|
||||||
};
|
|
||||||
converted.push(next);
|
converted.push(next);
|
||||||
}
|
}
|
||||||
Some(toml::Value::Array(converted))
|
Some(toml::Value::Array(converted))
|
||||||
|
|||||||
@@ -29,9 +29,9 @@ where
|
|||||||
{
|
{
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
{
|
{
|
||||||
return builder
|
builder
|
||||||
.hidden_title(true)
|
.hidden_title(true)
|
||||||
.title_bar_style(tauri::TitleBarStyle::Overlay);
|
.title_bar_style(tauri::TitleBarStyle::Overlay)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
@@ -216,9 +216,9 @@ pub async fn open_folder_window(
|
|||||||
if let Some(existing) = app.get_webview_window(&label) {
|
if let Some(existing) = app.get_webview_window(&label) {
|
||||||
ensure_windows_undecorated(&existing);
|
ensure_windows_undecorated(&existing);
|
||||||
let _ = existing.unminimize();
|
let _ = existing.unminimize();
|
||||||
existing.set_focus().map_err(|e| {
|
existing
|
||||||
AppCommandError::window("Failed to focus folder window", e.to_string())
|
.set_focus()
|
||||||
})?;
|
.map_err(|e| AppCommandError::window("Failed to focus folder window", e.to_string()))?;
|
||||||
if let Some(w) = app.get_webview_window("welcome") {
|
if let Some(w) = app.get_webview_window("welcome") {
|
||||||
let _ = w.close();
|
let _ = w.close();
|
||||||
}
|
}
|
||||||
@@ -279,7 +279,7 @@ pub async fn open_commit_window(
|
|||||||
|
|
||||||
let url = WebviewUrl::App(format!("commit?folderId={folder_id}").into());
|
let url = WebviewUrl::App(format!("commit?folderId={folder_id}").into());
|
||||||
let builder = WebviewWindowBuilder::new(&app, &label, url)
|
let builder = WebviewWindowBuilder::new(&app, &label, url)
|
||||||
.title(&format!("提交代码 - {}", folder.name))
|
.title(format!("提交代码 - {}", folder.name))
|
||||||
.inner_size(1220.0, 820.0)
|
.inner_size(1220.0, 820.0)
|
||||||
.min_inner_size(980.0, 620.0)
|
.min_inner_size(980.0, 620.0)
|
||||||
.always_on_top(true)
|
.always_on_top(true)
|
||||||
|
|||||||
@@ -194,7 +194,7 @@ async fn reorder_once(conn: &DatabaseConnection, agent_types: &[AgentType]) -> R
|
|||||||
}
|
}
|
||||||
let mut active = model.into_active_model();
|
let mut active = model.into_active_model();
|
||||||
active.sort_order = Set(index as i32);
|
active.sort_order = Set(index as i32);
|
||||||
active.updated_at = Set(now.clone());
|
active.updated_at = Set(now);
|
||||||
active.update(conn).await?;
|
active.update(conn).await?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ pub fn run() {
|
|||||||
{
|
{
|
||||||
let app = window.app_handle();
|
let app = window.app_handle();
|
||||||
if let Some(state) = app.try_state::<windows::SettingsWindowState>() {
|
if let Some(state) = app.try_state::<windows::SettingsWindowState>() {
|
||||||
windows::restore_windows_after_settings(&app, &state);
|
windows::restore_windows_after_settings(app, &state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -109,7 +109,7 @@ pub fn run() {
|
|||||||
{
|
{
|
||||||
let app = window.app_handle();
|
let app = window.app_handle();
|
||||||
if let Some(state) = app.try_state::<windows::CommitWindowState>() {
|
if let Some(state) = app.try_state::<windows::CommitWindowState>() {
|
||||||
windows::restore_window_after_commit(&app, &state, &label);
|
windows::restore_window_after_commit(app, &state, &label);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -246,16 +246,21 @@ fn value_to_preview(value: Option<&serde_json::Value>) -> Option<String> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn is_failed_status(status: &str) -> bool {
|
fn is_failed_status(status: &str) -> bool {
|
||||||
matches!(
|
let status = status.trim();
|
||||||
status.to_ascii_lowercase().as_str(),
|
status.eq_ignore_ascii_case("error")
|
||||||
"error" | "failed" | "failure" | "cancelled" | "canceled"
|
|| status.eq_ignore_ascii_case("failed")
|
||||||
)
|
|| status.eq_ignore_ascii_case("failure")
|
||||||
|
|| status.eq_ignore_ascii_case("cancelled")
|
||||||
|
|| status.eq_ignore_ascii_case("canceled")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_nonzero_exit_code_from_line(line: &str) -> Option<i64> {
|
fn parse_nonzero_exit_code_from_line(line: &str) -> Option<i64> {
|
||||||
let lower = line.trim().to_ascii_lowercase();
|
let trimmed = line.trim();
|
||||||
let rest = lower.strip_prefix("exit code:")?;
|
let (label, rest) = trimmed.split_once(':')?;
|
||||||
let number_text = rest.trim().split_whitespace().next()?;
|
if !label.trim_end().eq_ignore_ascii_case("exit code") {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
let number_text = rest.split_whitespace().next()?;
|
||||||
let code = number_text.parse::<i64>().ok()?;
|
let code = number_text.parse::<i64>().ok()?;
|
||||||
if code == 0 {
|
if code == 0 {
|
||||||
None
|
None
|
||||||
@@ -298,7 +303,9 @@ fn infer_output_text_is_error(text: &str) -> bool {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
trimmed.to_ascii_lowercase().starts_with("error:")
|
trimmed
|
||||||
|
.get(..6)
|
||||||
|
.is_some_and(|prefix| prefix.eq_ignore_ascii_case("error:"))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn infer_output_value_is_error(value: &serde_json::Value, depth: usize) -> bool {
|
fn infer_output_value_is_error(value: &serde_json::Value, depth: usize) -> bool {
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ impl GeminiParser {
|
|||||||
let projects = value.get("projects")?.as_object()?;
|
let projects = value.get("projects")?.as_object()?;
|
||||||
projects
|
projects
|
||||||
.iter()
|
.iter()
|
||||||
.find_map(|(path, mapped_alias)| (mapped_alias.as_str() == Some(alias)).then(|| path))
|
.find_map(|(path, mapped_alias)| (mapped_alias.as_str() == Some(alias)).then_some(path))
|
||||||
.map(|s| s.to_string())
|
.map(|s| s.to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user