feat(opencode): sync all providers to live config on directory change

Add additive mode support for OpenCode in sync_current_to_live:
- Add AppType::is_additive_mode() to distinguish switch vs additive mode
- Add AppType::all() iterator to avoid hardcoding app lists
- Add sync_all_providers_to_live() for additive mode apps
- Refactor sync_current_to_live to handle both modes

Frontend changes (directory settings):
- Track opencodeDirChanged in useDirectorySettings
- Trigger syncCurrentProvidersLiveSafe when OpenCode dir changes
- Add i18n strings for OpenCode directory settings
This commit is contained in:
Jason
2026-01-26 15:46:51 +08:00
parent 29a0643d74
commit c00f431d67
12 changed files with 180 additions and 28 deletions
+16 -5
View File
@@ -64,9 +64,12 @@ describe("useDirectorySettings", () => {
);
getAppConfigDirOverrideMock.mockResolvedValue(null);
getConfigDirMock.mockImplementation(async (app: string) =>
app === "claude" ? "/remote/claude" : "/remote/codex",
);
getConfigDirMock.mockImplementation(async (app: string) => {
if (app === "claude") return "/remote/claude";
if (app === "codex") return "/remote/codex";
if (app === "gemini") return "/remote/gemini";
return "/remote/opencode";
});
selectConfigDirectoryMock.mockReset();
});
@@ -84,7 +87,8 @@ describe("useDirectorySettings", () => {
appConfig: "/override/app",
claude: "/remote/claude",
codex: "/remote/codex",
gemini: "/remote/codex", // Gemini 使用 codex 作为默认
gemini: "/remote/gemini",
opencode: "/remote/opencode",
});
});
@@ -214,10 +218,17 @@ describe("useDirectorySettings", () => {
await waitFor(() => expect(result.current.isLoading).toBe(false));
act(() => {
result.current.resetAllDirectories("/server/claude", "/server/codex");
result.current.resetAllDirectories(
"/server/claude",
"/server/codex",
"/server/gemini",
"/server/opencode",
);
});
expect(result.current.resolvedDirs.claude).toBe("/server/claude");
expect(result.current.resolvedDirs.codex).toBe("/server/codex");
expect(result.current.resolvedDirs.gemini).toBe("/server/gemini");
expect(result.current.resolvedDirs.opencode).toBe("/server/opencode");
});
});
+1
View File
@@ -381,6 +381,7 @@ describe("useSettings hook", () => {
"/server/claude",
undefined,
undefined, // geminiConfigDir
undefined, // opencodeConfigDir
);
expect(metadataMock.setRequiresRestart).toHaveBeenCalledWith(false);
});