lwc 0.17.10

Agent-driven proactive memory CLI for AI agents — autonomously recall, maintain, and evolve persistent, source-grounded knowledge across sessions.
use super::*;

pub(super) static COPILOT_JETBRAINS: CopilotJetbrainsTarget = CopilotJetbrainsTarget;
pub(super) struct CopilotJetbrainsTarget;

impl CopilotJetbrainsTarget {
    fn copilot_root(&self, environment: &TargetEnvironment<'_>) -> PathBuf {
        if let Some(xdg) = std::env::var_os("XDG_CONFIG_HOME").filter(|value| !value.is_empty()) {
            return PathBuf::from(xdg).join("github-copilot");
        }
        #[cfg(windows)]
        {
            return std::env::var_os("LOCALAPPDATA")
                .map(PathBuf::from)
                .unwrap_or_else(|| environment.home.join("AppData/Local"))
                .join("github-copilot");
        }
        #[cfg(not(windows))]
        environment.home.join(".config/github-copilot")
    }

    fn paths(&self, environment: &TargetEnvironment<'_>) -> TargetPaths {
        if environment.location == AgentLocation::Local {
            return TargetPaths {
                mcp: None,
                instruction: Some(environment.cwd.join(".github/copilot-instructions.md")),
                hook: None,
                skill_dir: Some(environment.cwd.join(".github/skills/using-lwc")),
                aux: Vec::new(),
            };
        }
        TargetPaths {
            mcp: Some(self.copilot_root(environment).join("intellij/mcp.json")),
            instruction: None,
            hook: None,
            skill_dir: Some(environment.home.join(".copilot/skills/using-lwc")),
            aux: Vec::new(),
        }
    }
}

impl AgentTarget for CopilotJetbrainsTarget {
    fn id(&self) -> &'static str {
        "copilot-jetbrains"
    }
    fn display_name(&self) -> &'static str {
        "JetBrains IDEs (GitHub Copilot plugin)"
    }
    fn lifecycle_mode(&self, _location: AgentLocation) -> &'static str {
        "unsupported"
    }
    fn permissions_mode(&self, _location: AgentLocation) -> &'static str {
        "user_managed"
    }
    fn instructions_mode(&self, _location: AgentLocation) -> &'static str {
        if _location == AgentLocation::Global {
            "user_managed"
        } else {
            "configured_preview"
        }
    }
    fn skills_mode(&self, _location: AgentLocation) -> &'static str {
        "configured_preview"
    }
    fn supports_location(&self, _location: AgentLocation) -> bool {
        true
    }
    fn mcp_mode(&self, location: AgentLocation) -> &'static str {
        if location == AgentLocation::Global {
            "installed"
        } else {
            "user_managed"
        }
    }

    fn detect(&self, environment: &TargetEnvironment<'_>) -> DetectionResult {
        let paths = self.paths(environment);
        DetectionResult {
            installed: self.copilot_root(environment).join("intellij").exists(),
            already_configured: paths.mcp.as_ref().is_some_and(|path| {
                std::fs::read_to_string(path).is_ok_and(|text| text.contains("\"lwc\""))
            }),
            config_path: paths.mcp,
        }
    }

    fn install(
        &self,
        environment: &TargetEnvironment<'_>,
        options: InstallOptions,
    ) -> Result<WriteResult> {
        let mut result = native_install(self, environment, options, self.paths(environment))?;
        result.notes.push("Hooks are unsupported; Skills and project Instructions are preview features whose host activation must be verified.".into());
        if environment.location == AgentLocation::Global {
            result
                .notes
                .push("Restart the JetBrains IDE after an MCP update.".into());
        }
        Ok(result)
    }

    fn uninstall(&self, environment: &TargetEnvironment<'_>) -> Result<WriteResult> {
        native_uninstall(self, environment, self.paths(environment))
    }

    fn configure(&self, paths: &TargetPaths, options: InstallOptions) -> Result<()> {
        install::configure_standard(self.id(), paths, options)
    }

    fn unconfigure(&self, paths: &TargetPaths, executable: &str) -> Result<()> {
        install::unconfigure_standard(self.id(), paths, executable)
    }

    fn print_config(&self, location: AgentLocation) -> String {
        if location == AgentLocation::Global {
            format!(
                "# GitHub Copilot for JetBrains: add to $XDG_CONFIG_HOME|~/.config/github-copilot/intellij/mcp.json.\n{{\"servers\":{{\"lwc\":{{\"type\":\"stdio\",\"command\":\"lwc\",\"args\":[\"serve\",\"--mcp\"]}}}}}}\nHook events: none (unsupported)\n\n{}\n",
                install::guidance()
            )
        } else {
            format!(
                "# JetBrains project preview customizations: .github/copilot-instructions.md and .github/skills/using-lwc. MCP remains user-configured; Hooks are unsupported.\n{}\n",
                install::guidance()
            )
        }
    }

    fn describe_paths(&self, environment: &TargetEnvironment<'_>) -> Vec<PathBuf> {
        install::all_paths(&self.paths(environment))
    }
}