(dc: &mut DoctorCounters, home: &Path)
| 652 | // --------------------------------------------------------------------------- |
| 653 | |
| 654 | fn doctor_check_plugin(dc: &mut DoctorCounters, home: &Path) { |
| 655 | let plugin_dir = cursor_plugin_install_dir(home); |
| 656 | let manifest_path = cursor_plugin_manifest_path(home); |
| 657 | if !manifest_path.exists() { |
| 658 | dc.warn(&format!( |
| 659 | "{} not found — run `tracedecay install --agent cursor` if you use Cursor", |
| 660 | manifest_path.display() |
| 661 | )); |
| 662 | if legacy_mcp_has_tracedecay(&home.join(".cursor/mcp.json")) { |
| 663 | dc.warn( |
| 664 | "legacy Cursor MCP config is installed; rerun install to use the Cursor plugin", |
| 665 | ); |
| 666 | } |
| 667 | return; |
| 668 | } |
| 669 | |
| 670 | let manifest = load_json_file(&manifest_path); |
| 671 | if manifest.get("name").and_then(|v| v.as_str()) == Some("tracedecay") |
| 672 | && manifest.get("mcpServers").and_then(|v| v.as_str()) == Some("mcp.json") |
| 673 | && manifest.get("hooks").and_then(|v| v.as_str()) == Some("hooks/hooks.json") |
| 674 | { |
| 675 | dc.pass(&format!( |
| 676 | "Cursor plugin manifest active in {}", |
| 677 | manifest_path.display() |
| 678 | )); |
| 679 | } else { |
| 680 | dc.fail(&format!( |
| 681 | "Cursor tracedecay plugin manifest is incomplete in {}", |
| 682 | manifest_path.display() |
| 683 | )); |
| 684 | } |
| 685 | if let Some(message) = |
| 686 | super::cursor_diagnostics::plugin_version_staleness(&manifest, env!("CARGO_PKG_VERSION")) |
| 687 | { |
| 688 | dc.warn(&message); |
| 689 | } |
| 690 | doctor_check_plugin_mcp(dc, &plugin_dir.join("mcp.json")); |
| 691 | doctor_check_plugin_hooks(dc, &plugin_dir.join("hooks/hooks.json")); |
| 692 | doctor_check_plugin_rule(dc, &plugin_dir.join("rules/tracedecay.mdc")); |
| 693 | } |
| 694 | |
| 695 | fn doctor_check_plugin_mcp(dc: &mut DoctorCounters, mcp_path: &Path) { |
| 696 | if !mcp_path.exists() { |
no test coverage detected