Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions occm_core/config_paths.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ class ConfigPaths:
支持 .json 和 .jsonc 扩展名,支持自定义路径
"""

# 自定义路径持久化文件
_CUSTOM_PATHS_FILE = ".occm_custom_paths.json"

# 自定义路径存储(None 表示使用默认路径)
_custom_opencode_path: Optional[Path] = None
_custom_ohmyopencode_path: Optional[Path] = None
Expand Down Expand Up @@ -111,6 +114,7 @@ def get_opencode_config(cls) -> Path:
def set_opencode_config(cls, path: Optional[Path]) -> None:
"""设置自定义 OpenCode 配置路径"""
cls._custom_opencode_path = path
cls._persist_custom_paths()

@classmethod
def get_ohmyopencode_config(cls) -> Path:
Expand All @@ -123,6 +127,50 @@ def get_ohmyopencode_config(cls) -> Path:
def set_ohmyopencode_config(cls, path: Optional[Path]) -> None:
"""设置自定义 Oh My OpenCode 配置路径"""
cls._custom_ohmyopencode_path = path
cls._persist_custom_paths()

@classmethod
def _get_settings_path(cls) -> Path:
"""持久化文件路径"""
return cls.get_config_base_dir() / cls._CUSTOM_PATHS_FILE

@classmethod
def _persist_custom_paths(cls) -> None:
"""将自定义路径持久化到磁盘"""
import json
data = {}
if cls._custom_opencode_path is not None:
data["custom_opencode_path"] = str(cls._custom_opencode_path)
if cls._custom_ohmyopencode_path is not None:
data["custom_ohmyopencode_path"] = str(cls._custom_ohmyopencode_path)
if cls._custom_backup_path is not None:
data["custom_backup_dir"] = str(cls._custom_backup_path)
settings_path = cls._get_settings_path()
try:
settings_path.parent.mkdir(parents=True, exist_ok=True)
with open(settings_path, "w", encoding="utf-8") as f:
json.dump(data, f, indent=2)
except Exception as e:
print(f"[OCCM] Failed to persist custom paths: {e}")

@classmethod
def _load_custom_paths(cls) -> None:
"""从磁盘恢复自定义路径"""
import json
settings_path = cls._get_settings_path()
if not settings_path.exists():
return
try:
with open(settings_path, "r", encoding="utf-8") as f:
data = json.load(f)
if data.get("custom_opencode_path"):
cls._custom_opencode_path = Path(data["custom_opencode_path"])
if data.get("custom_ohmyopencode_path"):
cls._custom_ohmyopencode_path = Path(data["custom_ohmyopencode_path"])
if data.get("custom_backup_dir"):
cls._custom_backup_dir = Path(data["custom_backup_dir"])
except Exception as e:
print(f"[OCCM] Failed to load custom paths: {e}")

@classmethod
def is_custom_path(cls, config_type: str) -> bool:
Expand All @@ -144,6 +192,7 @@ def reset_to_default(cls, config_type: str) -> None:
cls._custom_ohmyopencode_path = None
elif config_type == "backup":
cls._custom_backup_path = None
cls._persist_custom_paths()

@classmethod
def get_claude_settings(cls) -> Path:
Expand All @@ -168,6 +217,7 @@ def get_backup_dir(cls) -> Path:
def set_backup_dir(cls, path: Optional[Path]) -> None:
"""设置自定义备份目录"""
cls._custom_backup_path = path
cls._persist_custom_paths()

@classmethod
def get_import_path(cls, source_type: str) -> Optional[Path]:
Expand Down
73 changes: 63 additions & 10 deletions opencode_config_manager_fluent.py
Original file line number Diff line number Diff line change
Expand Up @@ -3768,6 +3768,9 @@ class ConfigPaths:
支持 .json 和 .jsonc 扩展名,支持自定义路径
"""

# 自定义路径持久化文件
_CUSTOM_PATHS_FILE = ".occm_custom_paths.json"

# 自定义路径存储(None 表示使用默认路径)
_custom_opencode_path: Optional[Path] = None
_custom_ohmyopencode_path: Optional[Path] = None
Expand Down Expand Up @@ -3863,6 +3866,7 @@ def get_opencode_config(cls) -> Path:
def set_opencode_config(cls, path: Optional[Path]) -> None:
"""设置自定义 OpenCode 配置路径"""
cls._custom_opencode_path = path
cls._persist_custom_paths()

@classmethod
def get_ohmyopencode_config(cls) -> Path:
Expand All @@ -3875,6 +3879,50 @@ def get_ohmyopencode_config(cls) -> Path:
def set_ohmyopencode_config(cls, path: Optional[Path]) -> None:
"""设置自定义 Oh My OpenCode 配置路径"""
cls._custom_ohmyopencode_path = path
cls._persist_custom_paths()

@classmethod
def _get_settings_path(cls) -> Path:
"""持久化文件路径"""
return cls.get_config_base_dir() / cls._CUSTOM_PATHS_FILE

@classmethod
def _persist_custom_paths(cls) -> None:
"""将自定义路径持久化到磁盘"""
import json
data = {}
if cls._custom_opencode_path is not None:
data["custom_opencode_path"] = str(cls._custom_opencode_path)
if cls._custom_ohmyopencode_path is not None:
data["custom_ohmyopencode_path"] = str(cls._custom_ohmyopencode_path)
if cls._custom_backup_path is not None:
data["custom_backup_dir"] = str(cls._custom_backup_path)
settings_path = cls._get_settings_path()
try:
settings_path.parent.mkdir(parents=True, exist_ok=True)
with open(settings_path, "w", encoding="utf-8") as f:
json.dump(data, f, indent=2)
except Exception as e:
print(f"[OCCM] Failed to persist custom paths: {e}")

@classmethod
def _load_custom_paths(cls) -> None:
"""从磁盘恢复自定义路径"""
import json
settings_path = cls._get_settings_path()
if not settings_path.exists():
return
try:
with open(settings_path, "r", encoding="utf-8") as f:
data = json.load(f)
if data.get("custom_opencode_path"):
cls._custom_opencode_path = Path(data["custom_opencode_path"])
if data.get("custom_ohmyopencode_path"):
cls._custom_ohmyopencode_path = Path(data["custom_ohmyopencode_path"])
if data.get("custom_backup_dir"):
cls._custom_backup_dir = Path(data["custom_backup_dir"])
except Exception as e:
print(f"[OCCM] Failed to load custom paths: {e}")

@classmethod
def is_custom_path(cls, config_type: str) -> bool:
Expand All @@ -3896,6 +3944,7 @@ def reset_to_default(cls, config_type: str) -> None:
cls._custom_ohmyopencode_path = None
elif config_type == "backup":
cls._custom_backup_path = None
cls._persist_custom_paths()

@classmethod
def get_claude_settings(cls) -> Path:
Expand All @@ -3920,6 +3969,7 @@ def get_backup_dir(cls) -> Path:
def set_backup_dir(cls, path: Optional[Path]) -> None:
"""设置自定义备份目录"""
cls._custom_backup_path = path
cls._persist_custom_paths()

@classmethod
def get_import_path(cls, source_type: str) -> Optional[Path]:
Expand Down Expand Up @@ -15616,6 +15666,9 @@ def __init__(self):
# 检测配置文件冲突(同时存在 .json 和 .jsonc)
self._check_config_conflicts()

# 恢复上次保存的自定义路径
ConfigPaths._load_custom_paths()

# 加载配置
self.opencode_config = ConfigManager.load_json(
ConfigPaths.get_opencode_config()
Expand Down Expand Up @@ -23634,18 +23687,18 @@ def _on_toggle_ohmy_enable(self):
plugins = []

if self._ohmy_enabled:
# 禁用:从plugins中移除oh-my-opencode
# 禁用:从plugins中移除oh-my-opencode/oh-my-openagent
new_plugins = []
for plugin in plugins:
if isinstance(plugin, str):
# 去掉连字符后比较
# 去掉连字符后比较(兼容新旧包名)
plugin_normalized = plugin.lower().replace("-", "")
if "ohmyopencode" not in plugin_normalized:
if "ohmyopencode" not in plugin_normalized and "ohmyopenagent" not in plugin_normalized:
new_plugins.append(plugin)
elif isinstance(plugin, dict):
plugin_name = plugin.get("name", "") or plugin.get("package", "")
plugin_normalized = plugin_name.lower().replace("-", "")
if "ohmyopencode" not in plugin_normalized:
if "ohmyopencode" not in plugin_normalized and "ohmyopenagent" not in plugin_normalized:
new_plugins.append(plugin)
else:
new_plugins.append(plugin)
Expand All @@ -23654,15 +23707,15 @@ def _on_toggle_ohmy_enable(self):
self.show_success("成功", "Oh My OpenCode 已禁用")
elif self._ohmy_installed:
# 已安装但未启用:添加到plugins
plugins.append("oh-my-opencode")
plugins.append("oh-my-openagent")
config[field_name] = plugins
self.main_window.save_opencode_config()
self.show_success("成功", "Oh My OpenCode 已启用")
else:
# 未安装:提示安装
self.show_warning(
"提示",
"请先通过npm安装oh-my-opencode插件:\nnpm install -g oh-my-opencode",
"请先通过npm安装oh-my-openagent插件:\nbun oh-my-opencode install",
)

# 刷新状态
Expand Down Expand Up @@ -23829,8 +23882,8 @@ def _load_ohmy_data(self):
config_path = ConfigPaths.get_ohmyopencode_config()
ohmy_installed = config_path.exists() # 配置文件存在 = 已安装

# 检测启用状态:plugins数组中是否有oh-my-opencode
# 注意:需要同时检测 "oh-my-opencode" 和 "ohmyopencode" 两种写法
# 检测启用状态:plugins数组中是否有oh-my-opencode/oh-my-openagent
# 注意:兼容新旧包名 "oh-my-opencode" 和 "oh-my-openagent"
# 注意:字段名可能是 "plugins"(复数)或 "plugin"(单数)
ohmy_enabled = False
config = self.main_window.opencode_config or {}
Expand All @@ -23840,13 +23893,13 @@ def _load_ohmy_data(self):
if isinstance(plugin, str):
# 去掉连字符后比较,兼容两种写法
plugin_normalized = plugin.lower().replace("-", "")
if "ohmyopencode" in plugin_normalized:
if "ohmyopencode" in plugin_normalized or "ohmyopenagent" in plugin_normalized:
ohmy_enabled = True
break
elif isinstance(plugin, dict):
plugin_name = plugin.get("name", "") or plugin.get("package", "")
plugin_normalized = plugin_name.lower().replace("-", "")
if "ohmyopencode" in plugin_normalized:
if "ohmyopencode" in plugin_normalized or "ohmyopenagent" in plugin_normalized:
ohmy_enabled = True
break

Expand Down