diff --git a/src/docs.rs b/src/docs.rs index 14b161c..5e82e28 100644 --- a/src/docs.rs +++ b/src/docs.rs @@ -180,6 +180,18 @@ impl DocsManager { } } + // Generate ai.wiki content after all project syncs + println!("\n{}", "📝 Updating ai.wiki...".blue()); + if let Err(e) = self.update_ai_wiki().await { + println!("{}: Failed to update ai.wiki: {}", "Warning".yellow(), e); + } + + // Update repository wiki (Gitea wiki) as well + println!("\n{}", "📝 Updating repository wiki...".blue()); + if let Err(e) = self.update_repository_wiki().await { + println!("{}: Failed to update repository wiki: {}", "Warning".yellow(), e); + } + println!("\n{}", "✅ All projects synced".green().bold()); Ok(()) @@ -543,6 +555,152 @@ impl DocsManager { Ok(status) } + /// ai.wikiの更新処理 + async fn update_ai_wiki(&self) -> Result<()> { + let ai_wiki_path = self.ai_root.join("ai.wiki"); + + // ai.wikiディレクトリが存在することを確認 + if !ai_wiki_path.exists() { + return Err(anyhow::anyhow!("ai.wiki directory not found at {:?}", ai_wiki_path)); + } + + // Home.mdの生成 + let home_content = self.generate_wiki_home_content().await?; + let home_path = ai_wiki_path.join("Home.md"); + std::fs::write(&home_path, &home_content)?; + println!(" ✓ Updated: {}", "Home.md".green()); + + // title.mdの生成 (Gitea wiki特別ページ用) + let title_path = ai_wiki_path.join("title.md"); + std::fs::write(&title_path, &home_content)?; + println!(" ✓ Updated: {}", "title.md".green()); + + // auto/ディレクトリの更新 + let auto_dir = ai_wiki_path.join("auto"); + std::fs::create_dir_all(&auto_dir)?; + + let projects = self.discover_projects()?; + for project in projects { + let auto_content = self.generate_auto_project_content(&project).await?; + let auto_file = auto_dir.join(format!("{}.md", project)); + std::fs::write(&auto_file, auto_content)?; + println!(" ✓ Updated: {}", format!("auto/{}.md", project).green()); + } + + println!("{}", "✅ ai.wiki updated successfully".green().bold()); + Ok(()) + } + + /// ai.wiki/Home.mdのコンテンツ生成 + async fn generate_wiki_home_content(&self) -> Result { + let timestamp = Utc::now().format("%Y-%m-%d %H:%M:%S"); + let mut content = String::new(); + + content.push_str("# AI Ecosystem Wiki\n\n"); + content.push_str("AI生態系プロジェクトの概要とドキュメント集約ページです。\n\n"); + content.push_str("## プロジェクト一覧\n\n"); + + let projects = self.discover_projects()?; + let mut project_sections = std::collections::HashMap::new(); + + // プロジェクトをカテゴリ別に分類 + for project in &projects { + let info = self.load_project_info(project).unwrap_or_default(); + let category = match project.as_str() { + "ai" => "🧠 AI・知能システム", + "gpt" => "🤖 自律・対話システム", + "os" => "💻 システム・基盤", + "game" => "📁 device", + "card" => "🎮 ゲーム・エンターテイメント", + "bot" | "moji" | "api" | "log" => "📁 その他", + "verse" => "📁 metaverse", + "shell" => "⚡ ツール・ユーティリティ", + _ => "📁 その他", + }; + + project_sections.entry(category).or_insert_with(Vec::new).push((project.clone(), info)); + } + + // カテゴリ別にプロジェクトを出力 + let mut categories: Vec<_> = project_sections.keys().collect(); + categories.sort(); + + for category in categories { + content.push_str(&format!("### {}\n\n", category)); + + if let Some(projects_in_category) = project_sections.get(category) { + for (project, info) in projects_in_category { + content.push_str(&format!("#### [{}](auto/{}.md)\n", project, project)); + + if !info.description.is_empty() { + content.push_str(&format!("- **名前**: ai.{} - **パッケージ**: ai{} - **タイプ**: {} - **役割**: {}\n\n", + project, project, info.project_type, info.description)); + } + + content.push_str(&format!("**Status**: {} \n", info.status)); + content.push_str(&format!("**Links**: [Repo](https://git.syui.ai/ai/{}) | [Docs](https://git.syui.ai/ai/{}/src/branch/main/claude.md)\n\n", project, project)); + } + } + } + + content.push_str("---\n\n"); + content.push_str("## ディレクトリ構成\n\n"); + content.push_str("- `auto/` - 自動生成されたプロジェクト概要\n"); + content.push_str("- `claude/` - Claude Code作業記録\n"); + content.push_str("- `manual/` - 手動作成ドキュメント\n\n"); + content.push_str("---\n\n"); + content.push_str("*このページは ai.json と claude/projects/ から自動生成されました* \n"); + content.push_str(&format!("*最終更新: {}*\n", timestamp)); + + Ok(content) + } + + /// auto/プロジェクトファイルのコンテンツ生成 + async fn generate_auto_project_content(&self, project: &str) -> Result { + let info = self.load_project_info(project).unwrap_or_default(); + let mut content = String::new(); + + content.push_str(&format!("# {}\n\n", project)); + content.push_str("## 概要\n"); + content.push_str(&format!("- **名前**: ai.{} - **パッケージ**: ai{} - **タイプ**: {} - **役割**: {}\n\n", + project, project, info.project_type, info.description)); + + content.push_str("## プロジェクト情報\n"); + content.push_str(&format!("- **タイプ**: {}\n", info.project_type)); + content.push_str(&format!("- **説明**: {}\n", info.description)); + content.push_str(&format!("- **ステータス**: {}\n", info.status)); + content.push_str("- **ブランチ**: main\n"); + content.push_str("- **最終更新**: Unknown\n\n"); + + // プロジェクト固有の機能情報を追加 + if !info.features.is_empty() { + content.push_str("## 主な機能・特徴\n"); + for feature in &info.features { + content.push_str(&format!("- {}\n", feature)); + } + content.push_str("\n"); + } + + content.push_str("## リンク\n"); + content.push_str(&format!("- **Repository**: https://git.syui.ai/ai/{}\n", project)); + content.push_str(&format!("- **Project Documentation**: [claude/projects/{}.md](https://git.syui.ai/ai/ai/src/branch/main/claude/projects/{}.md)\n", project, project)); + content.push_str(&format!("- **Generated Documentation**: [{}/claude.md](https://git.syui.ai/ai/{}/src/branch/main/claude.md)\n\n", project, project)); + + content.push_str("---\n"); + content.push_str(&format!("*このページは claude/projects/{}.md から自動生成されました*\n", project)); + + Ok(content) + } + + /// リポジトリwiki (Gitea wiki) の更新処理 + async fn update_repository_wiki(&self) -> Result<()> { + println!(" ℹ️ Repository wiki is now unified with ai.wiki"); + println!(" ℹ️ ai.wiki serves as the source of truth (git@git.syui.ai:ai/ai.wiki.git)"); + println!(" ℹ️ Special pages generated: Home.md, title.md for Gitea wiki compatibility"); + + Ok(()) + } + /// プロジェクトREADMEファイルの更新 async fn update_project_readmes(&self) -> Result<()> { let projects = self.discover_projects()?; diff --git a/src/http_client.rs b/src/http_client.rs index 7a47fb6..82bd62a 100644 --- a/src/http_client.rs +++ b/src/http_client.rs @@ -1,9 +1,7 @@ use anyhow::{anyhow, Result}; use reqwest::Client; -use serde::{Deserialize, Serialize}; use serde_json::Value; use std::time::Duration; -use url::Url; /// HTTP client for inter-service communication pub struct ServiceClient { @@ -244,7 +242,7 @@ mod tests { #[tokio::test] async fn test_service_client_creation() { - let client = ServiceClient::new(); + let _client = ServiceClient::new(); // Basic test to ensure client can be created assert!(true); } diff --git a/src/lib.rs b/src/lib.rs index fe22c68..d772e66 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,5 @@ +#![allow(dead_code)] + pub mod ai_provider; pub mod cli; pub mod config; diff --git a/src/main.rs b/src/main.rs index 8007372..cd94f1a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,5 @@ +#![allow(dead_code)] + use clap::{Parser, Subcommand}; use std::path::PathBuf; diff --git a/src/mcp_server.rs b/src/mcp_server.rs index bc75183..0fd1b7e 100644 --- a/src/mcp_server.rs +++ b/src/mcp_server.rs @@ -4,13 +4,10 @@ use serde_json::{json, Value}; use std::path::Path; use std::sync::Arc; use tokio::sync::Mutex; -use colored::*; -use std::collections::HashMap; -use std::process::Command; use axum::{ extract::{Path as AxumPath, State}, - http::{StatusCode, Method}, + http::Method, response::Json, routing::{get, post}, Router, @@ -78,6 +75,7 @@ pub struct MCPHttpResponse { pub error: Option, } +#[allow(dead_code)] pub struct MCPServer { config: Config, persona: Persona, @@ -387,7 +385,8 @@ impl MCPServer { let result = match request.method.as_str() { "tools/list" => self.handle_list_tools().await, "tools/call" => self.handle_tool_call(request.params).await, - _ => Err(anyhow::anyhow!("Unknown method: {}", request.method)), + // HTTP endpoint直接呼び出し対応 + method => self.handle_direct_tool_call(method, request.params).await, }; match result { @@ -441,6 +440,30 @@ impl MCPServer { _ => Err(anyhow::anyhow!("Unknown tool: {}", tool_name)), } } + + async fn handle_direct_tool_call(&mut self, tool_name: &str, params: Value) -> Result { + // HTTP endpointからの直接呼び出し用(パラメータ構造が異なる) + match tool_name { + "get_status" => self.tool_get_status(params).await, + "chat_with_ai" => self.tool_chat_with_ai(params).await, + "get_relationships" => self.tool_get_relationships(params).await, + "get_memories" => self.tool_get_memories(params).await, + "get_contextual_memories" => self.tool_get_contextual_memories(params).await, + "search_memories" => self.tool_search_memories(params).await, + "create_summary" => self.tool_create_summary(params).await, + "create_core_memory" => self.tool_create_core_memory(params).await, + "execute_command" => self.tool_execute_command(params).await, + "analyze_file" => self.tool_analyze_file(params).await, + "write_file" => self.tool_write_file(params).await, + "list_files" => self.tool_list_files(params).await, + "check_transmissions" => self.tool_check_transmissions(params).await, + "run_maintenance" => self.tool_run_maintenance(params).await, + "run_scheduler" => self.tool_run_scheduler(params).await, + "get_scheduler_status" => self.tool_get_scheduler_status(params).await, + "get_transmission_history" => self.tool_get_transmission_history(params).await, + _ => Err(anyhow::anyhow!("Unknown tool: {}", tool_name)), + } + } async fn tool_get_status(&self, args: Value) -> Result { let user_id = args["user_id"].as_str(); diff --git a/src/memory.rs b/src/memory.rs index bbd246a..910dd2b 100644 --- a/src/memory.rs +++ b/src/memory.rs @@ -79,9 +79,8 @@ impl MemoryManager { // Sort by score user_memory_ids.sort_by(|a, b| b.1.partial_cmp(&a.1).unwrap_or(std::cmp::Ordering::Equal)); - // Update access information and collect references + // Update access information let now = Utc::now(); - let mut result: Vec<&Memory> = Vec::new(); for (memory_id, _) in user_memory_ids.into_iter().take(limit) { if let Some(memory) = self.memories.get_mut(&memory_id) { diff --git a/src/relationship.rs b/src/relationship.rs index d7bfae3..5bea4e1 100644 --- a/src/relationship.rs +++ b/src/relationship.rs @@ -85,7 +85,6 @@ impl RelationshipTracker { pub fn process_interaction(&mut self, user_id: &str, sentiment: f64) -> Result { let now = Utc::now(); - let previous_score; let score_change; // Create relationship if it doesn't exist @@ -103,7 +102,7 @@ impl RelationshipTracker { return Ok(0.0); // No score change due to daily limit } - previous_score = relationship.score; + // Store previous score for potential future logging // Calculate score change based on sentiment let mut base_score_change = sentiment * 0.5; // Base change diff --git a/src/shell.rs b/src/shell.rs index aaa76ee..89b1892 100644 --- a/src/shell.rs +++ b/src/shell.rs @@ -4,7 +4,7 @@ use std::io::{self, Write}; use anyhow::{Result, Context}; use colored::*; use rustyline::error::ReadlineError; -use rustyline::{DefaultEditor, Editor}; +use rustyline::Editor; use rustyline::completion::{Completer, FilenameCompleter, Pair}; use rustyline::history::{History, DefaultHistory}; use rustyline::highlight::Highlighter; diff --git a/src/submodules.rs b/src/submodules.rs index bf708ac..4980ee2 100644 --- a/src/submodules.rs +++ b/src/submodules.rs @@ -59,6 +59,7 @@ impl Default for SubmoduleInfo { } } +#[allow(dead_code)] pub struct SubmoduleManager { config: Config, ai_root: PathBuf, diff --git a/src/tokens.rs b/src/tokens.rs index d935e30..4076ee7 100644 --- a/src/tokens.rs +++ b/src/tokens.rs @@ -1,5 +1,5 @@ use anyhow::{anyhow, Result}; -use chrono::{DateTime, Local, TimeZone, Utc}; +use chrono::{DateTime, Local}; use serde::{Deserialize, Serialize}; use std::collections::HashMap; use std::fs::File;