基于forgecode二开的agent cli
0

Configure Feed

Select the types of activity you want to include in your feed.

feat(command): add github PR description command (#2470)

authored by

laststylebender and committed by
GitHub
(Mar 2, 2026, 5:40 PM +0530) 4d11b0c8 a7684e83

+51 -4
+1 -1
.forge/commands/pr_description.md commands/github-pr-description.md
··· 1 1 --- 2 - name: pr-description 2 + name: github-pr-description 3 3 description: Updates the description of the PR 4 4 --- 5 5
.forge/skills/pr-description/SKILL.md crates/forge_repo/src/skills/pr-description/SKILL.md
+17 -1
crates/forge_repo/src/skill.rs
··· 52 52 "forge://skills/execute-plan/SKILL.md", 53 53 include_str!("skills/execute-plan/SKILL.md"), 54 54 ), 55 + ( 56 + "forge://skills/pr-description/SKILL.md", 57 + include_str!("skills/pr-description/SKILL.md"), 58 + ), 55 59 ]; 56 60 57 61 builtin_skills ··· 334 338 let actual = repo.load_builtin_skills(); 335 339 336 340 // Assert 337 - assert_eq!(actual.len(), 2); 341 + assert_eq!(actual.len(), 3); 338 342 339 343 // Check create-skill 340 344 let create_skill = actual.iter().find(|s| s.name == "create-skill").unwrap(); ··· 361 365 .contains("Execute structured task plans") 362 366 ); 363 367 assert!(execute_plan.command.contains("Execute Plan")); 368 + 369 + // Check pr-description 370 + let pr_description = actual 371 + .iter() 372 + .find(|s| s.name == "create-pr-description") 373 + .unwrap(); 374 + assert_eq!( 375 + pr_description.path, 376 + Some(std::path::Path::new("forge://skills/pr-description/SKILL.md").to_path_buf()) 377 + ); 378 + assert!(!pr_description.description.is_empty()); 379 + assert!(pr_description.command.contains("Create PR Description")); 364 380 } 365 381 366 382 #[tokio::test]
+33 -2
crates/forge_services/src/command.rs
··· 22 22 pub fn new(infra: Arc<F>) -> Self { 23 23 Self { infra, cache: Default::default() } 24 24 } 25 + 26 + /// Load built-in commands that are embedded in the application binary. 27 + fn init_default(&self) -> anyhow::Result<Vec<Command>> { 28 + parse_command_iter( 29 + [( 30 + "github-pr-description", 31 + include_str!("../../../commands/github-pr-description.md"), 32 + )] 33 + .into_iter() 34 + .map(|(name, content)| (name.to_string(), content.to_string())), 35 + ) 36 + } 25 37 } 26 38 27 39 #[async_trait::async_trait] ··· 42 54 } 43 55 44 56 async fn init(&self) -> anyhow::Result<Vec<Command>> { 45 - // Load built-in commands 46 - let mut commands = vec![]; 57 + // Load built-in commands first (lowest precedence) 58 + let mut commands = self.init_default()?; 47 59 48 60 // Load custom commands from global directory 49 61 let dir = self.infra.get_environment().command_path(); ··· 192 204 assert!(!command.description.is_empty()); 193 205 assert!(command.prompt.is_some()); 194 206 } 207 + } 208 + 209 + #[test] 210 + fn test_init_default_contains_builtin_commands() { 211 + // Fixture 212 + let service = CommandLoaderService::<()> { infra: Arc::new(()), cache: Default::default() }; 213 + 214 + // Execute 215 + let actual = service.init_default().unwrap(); 216 + 217 + // Verify github-pr-description 218 + let command = actual 219 + .iter() 220 + .find(|c| c.name.as_str() == "github-pr-description") 221 + .expect("github-pr-description should be a built-in command"); 222 + 223 + assert_eq!(command.name.as_str(), "github-pr-description"); 224 + assert!(!command.description.is_empty()); 225 + assert!(command.prompt.is_some()); 195 226 } 196 227 197 228 #[test]