safe_chains/targets/
opencode.rs1use std::path::{Path, PathBuf};
2
3use super::{InstallOutcome, Target};
4
5pub struct OpenCodeTarget;
6
7impl Target for OpenCodeTarget {
8 fn name(&self) -> &'static str {
9 "opencode"
10 }
11
12 fn display_name(&self) -> &'static str {
13 "OpenCode"
14 }
15
16 fn detect_paths(&self, home: &Path) -> Vec<PathBuf> {
17 vec![home.join(".config").join("opencode")]
18 }
19
20 fn install(&self, _home: &Path) -> Result<InstallOutcome, String> {
21 Ok(InstallOutcome::Skipped {
29 reason: "OpenCode has no runtime hook safe-chains can drive yet (its plugin hook does not \
30 fire — opencode #7006), and a static permission glob can't represent per-argument \
31 safety. Not integrated — watching for an upstream hook."
32 .to_string(),
33 })
34 }
35}
36
37#[cfg(test)]
38mod tests {
39 use super::*;
40
41 #[test]
42 fn install_returns_skip_explaining_no_integration() {
43 let dir = tempfile::tempdir().unwrap();
44 let outcome = OpenCodeTarget.install(dir.path()).unwrap();
45 match outcome {
46 InstallOutcome::Skipped { reason } => {
47 assert!(reason.to_lowercase().contains("hook"));
48 }
49 other => panic!("expected Skipped, got {:?}", std::mem::discriminant(&other)),
50 }
51 }
52}