mirror of
https://github.com/different-ai/openwork
synced 2026-05-10 17:22:05 +02:00
feat: support opencode.jsonc configs
This commit is contained in:
63
packages/desktop/src-tauri/Cargo.lock
generated
63
packages/desktop/src-tauri/Cargo.lock
generated
@@ -1818,6 +1818,17 @@ dependencies = [
|
||||
"thiserror 1.0.69",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "json5"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "96b0db21af676c1ce64250b5f40f3ce2cf27e4e47cb91ed91eb6fe9350b430c1"
|
||||
dependencies = [
|
||||
"pest",
|
||||
"pest_derive",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jsonptr"
|
||||
version = "0.6.3"
|
||||
@@ -2370,8 +2381,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "openwork"
|
||||
version = "0.3.0"
|
||||
version = "0.3.2"
|
||||
dependencies = [
|
||||
"json5",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tauri",
|
||||
@@ -2478,6 +2490,49 @@ version = "2.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220"
|
||||
|
||||
[[package]]
|
||||
name = "pest"
|
||||
version = "2.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2c9eb05c21a464ea704b53158d358a31e6425db2f63a1a7312268b05fe2b75f7"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"ucd-trie",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pest_derive"
|
||||
version = "2.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "68f9dbced329c441fa79d80472764b1a2c7e57123553b8519b36663a2fb234ed"
|
||||
dependencies = [
|
||||
"pest",
|
||||
"pest_generator",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pest_generator"
|
||||
version = "2.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3bb96d5051a78f44f43c8f712d8e810adb0ebf923fc9ed2655a7f66f63ba8ee5"
|
||||
dependencies = [
|
||||
"pest",
|
||||
"pest_meta",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.114",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pest_meta"
|
||||
version = "2.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "602113b5b5e8621770cfd490cfd90b9f84ab29bd2b0e49ad83eb6d186cef2365"
|
||||
dependencies = [
|
||||
"pest",
|
||||
"sha2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf"
|
||||
version = "0.8.0"
|
||||
@@ -4467,6 +4522,12 @@ version = "1.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb"
|
||||
|
||||
[[package]]
|
||||
name = "ucd-trie"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971"
|
||||
|
||||
[[package]]
|
||||
name = "uds_windows"
|
||||
version = "1.1.0"
|
||||
|
||||
@@ -9,6 +9,7 @@ edition = "2021"
|
||||
tauri-build = { version = "2", features = [] }
|
||||
|
||||
[dependencies]
|
||||
json5 = "0.4"
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
serde_json = "1"
|
||||
tauri = { version = "2", features = [] }
|
||||
|
||||
@@ -4,13 +4,14 @@ use std::path::PathBuf;
|
||||
|
||||
use crate::types::{ExecResult, OpencodeConfigFile};
|
||||
|
||||
pub fn resolve_opencode_config_path(scope: &str, project_dir: &str) -> Result<PathBuf, String> {
|
||||
fn opencode_config_candidates(scope: &str, project_dir: &str) -> Result<(PathBuf, PathBuf), String> {
|
||||
match scope {
|
||||
"project" => {
|
||||
if project_dir.trim().is_empty() {
|
||||
return Err("projectDir is required".to_string());
|
||||
}
|
||||
Ok(PathBuf::from(project_dir).join("opencode.json"))
|
||||
let root = PathBuf::from(project_dir);
|
||||
Ok((root.join("opencode.jsonc"), root.join("opencode.json")))
|
||||
}
|
||||
"global" => {
|
||||
let base = if let Ok(dir) = env::var("XDG_CONFIG_HOME") {
|
||||
@@ -21,12 +22,27 @@ pub fn resolve_opencode_config_path(scope: &str, project_dir: &str) -> Result<Pa
|
||||
return Err("Unable to resolve config directory".to_string());
|
||||
};
|
||||
|
||||
Ok(base.join("opencode").join("opencode.json"))
|
||||
let root = base.join("opencode");
|
||||
Ok((root.join("opencode.jsonc"), root.join("opencode.json")))
|
||||
}
|
||||
_ => Err("scope must be 'project' or 'global'".to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn resolve_opencode_config_path(scope: &str, project_dir: &str) -> Result<PathBuf, String> {
|
||||
let (jsonc_path, json_path) = opencode_config_candidates(scope, project_dir)?;
|
||||
|
||||
if jsonc_path.exists() {
|
||||
return Ok(jsonc_path);
|
||||
}
|
||||
|
||||
if json_path.exists() {
|
||||
return Ok(json_path);
|
||||
}
|
||||
|
||||
Ok(jsonc_path)
|
||||
}
|
||||
|
||||
pub fn read_opencode_config(scope: &str, project_dir: &str) -> Result<OpencodeConfigFile, String> {
|
||||
let path = resolve_opencode_config_path(scope.trim(), project_dir)?;
|
||||
let exists = path.exists();
|
||||
|
||||
@@ -38,11 +38,20 @@ pub fn build_engine_command(program: &Path, hostname: &str, port: u16, project_d
|
||||
command.env("XDG_DATA_HOME", xdg_data_home);
|
||||
}
|
||||
|
||||
if let Some(xdg_config_home) = maybe_infer_xdg_home(
|
||||
let xdg_config_home = maybe_infer_xdg_home(
|
||||
"XDG_CONFIG_HOME",
|
||||
candidate_xdg_config_dirs(),
|
||||
Path::new("opencode/opencode.json"),
|
||||
) {
|
||||
Path::new("opencode/opencode.jsonc"),
|
||||
)
|
||||
.or_else(|| {
|
||||
maybe_infer_xdg_home(
|
||||
"XDG_CONFIG_HOME",
|
||||
candidate_xdg_config_dirs(),
|
||||
Path::new("opencode/opencode.json"),
|
||||
)
|
||||
});
|
||||
|
||||
if let Some(xdg_config_home) = xdg_config_home {
|
||||
command.env("XDG_CONFIG_HOME", xdg_config_home);
|
||||
}
|
||||
|
||||
|
||||
@@ -158,11 +158,22 @@ pub fn ensure_workspace_files(workspace_path: &str, preset: &str) -> Result<(),
|
||||
.map_err(|e| format!("Failed to create .openwork/templates: {e}"))?;
|
||||
seed_templates(&templates_dir)?;
|
||||
|
||||
let config_path = root.join("opencode.json");
|
||||
let mut config: serde_json::Value = if config_path.exists() {
|
||||
let config_path_jsonc = root.join("opencode.jsonc");
|
||||
let config_path_json = root.join("opencode.json");
|
||||
let config_path = if config_path_jsonc.exists() {
|
||||
config_path_jsonc
|
||||
} else if config_path_json.exists() {
|
||||
config_path_json
|
||||
} else {
|
||||
config_path_jsonc
|
||||
};
|
||||
|
||||
let config_exists = config_path.exists();
|
||||
let mut config_changed = !config_exists;
|
||||
let mut config: serde_json::Value = if config_exists {
|
||||
let raw = fs::read_to_string(&config_path)
|
||||
.map_err(|e| format!("Failed to read {}: {e}", config_path.display()))?;
|
||||
serde_json::from_str(&raw).unwrap_or_else(|_| serde_json::json!({}))
|
||||
json5::from_str(&raw).unwrap_or_else(|_| serde_json::json!({}))
|
||||
} else {
|
||||
serde_json::json!({
|
||||
"$schema": "https://opencode.ai/config.json"
|
||||
@@ -173,6 +184,7 @@ pub fn ensure_workspace_files(workspace_path: &str, preset: &str) -> Result<(),
|
||||
config = serde_json::json!({
|
||||
"$schema": "https://opencode.ai/config.json"
|
||||
});
|
||||
config_changed = true;
|
||||
}
|
||||
|
||||
let required_plugins: Vec<&str> = match preset {
|
||||
@@ -196,7 +208,10 @@ pub fn ensure_workspace_files(workspace_path: &str, preset: &str) -> Result<(),
|
||||
_ => vec![],
|
||||
};
|
||||
|
||||
let merged = merge_plugins(existing_plugins, &required_plugins);
|
||||
let merged = merge_plugins(existing_plugins.clone(), &required_plugins);
|
||||
if merged != existing_plugins {
|
||||
config_changed = true;
|
||||
}
|
||||
if let Some(obj) = config.as_object_mut() {
|
||||
obj.insert(
|
||||
"plugin".to_string(),
|
||||
@@ -205,8 +220,10 @@ pub fn ensure_workspace_files(workspace_path: &str, preset: &str) -> Result<(),
|
||||
}
|
||||
}
|
||||
|
||||
fs::write(&config_path, serde_json::to_string_pretty(&config).map_err(|e| e.to_string())?)
|
||||
.map_err(|e| format!("Failed to write {}: {e}", config_path.display()))?;
|
||||
if config_changed {
|
||||
fs::write(&config_path, serde_json::to_string_pretty(&config).map_err(|e| e.to_string())?)
|
||||
.map_err(|e| format!("Failed to write {}: {e}", config_path.display()))?;
|
||||
}
|
||||
|
||||
let openwork_path = root.join(".opencode").join("openwork.json");
|
||||
if !openwork_path.exists() {
|
||||
|
||||
Reference in New Issue
Block a user