feat(ai): add Cursor CLI provider

This commit is contained in:
Guoyu Su authored and GitHub committed 2026-08-08 11:08:18 +08:00
1 parent 25fd5677c7
commit 36e5fa4f4c
36 files changed
+1173 -36

No files matched your search

@@ -118,6 +118,30 @@ describe("useAiModelCatalog", () => {
expect(apiMock.aiListModels).toHaveBeenCalledTimes(2);
});
it("tracks Cursor executable and environment changes without depending on environment key order", async () => {
const initial: AiConfigItem = {
...config(),
provider: "cursor-cli",
endpoint: "",
apiKey: "",
model: "default",
cursorCliPath: "~/.local/bin/agent",
cursorCliEnv: { HTTPS_PROXY: "http://127.0.0.1:7890", NO_PROXY: "localhost" },
};
apiMock.aiListModels.mockResolvedValueOnce([{ id: "first" }]).mockResolvedValueOnce([{ id: "second" }]);
await expect(catalog.loadModels(initial)).resolves.toEqual([{ id: "first" }]);
await expect(
catalog.loadModels({
...initial,
cursorCliEnv: { NO_PROXY: "localhost", HTTPS_PROXY: "http://127.0.0.1:7890" },
}),
).resolves.toEqual([{ id: "first" }]);
await expect(catalog.loadModels({ ...initial, cursorCliPath: "/usr/local/bin/agent" })).resolves.toEqual([{ id: "second" }]);
expect(apiMock.aiListModels).toHaveBeenCalledTimes(2);
});
it("does not let a stale request overwrite a newer provider catalog", async () => {
let resolveInitial: ((models: { id: string }[]) => void) | undefined;
apiMock.aiListModels
@@ -58,6 +58,7 @@ function configSignature(config: AiConfigItem): string {
claudeCodeCliPath: config.claudeCodeCliPath ?? null,
piAgentCliPath: config.piAgentCliPath ?? null,
opencodeCliPath: config.opencodeCliPath ?? null,
cursorCliPath: config.cursorCliPath ?? null,
connectionFingerprint: fingerprint(
JSON.stringify({
apiKey: config.apiKey,
@@ -67,6 +68,7 @@ function configSignature(config: AiConfigItem): string {
claudeCodeCliEnv: sortedRecord(config.claudeCodeCliEnv),
piAgentCliEnv: sortedRecord(config.piAgentCliEnv),
opencodeCliEnv: sortedRecord(config.opencodeCliEnv),
cursorCliEnv: sortedRecord(config.cursorCliEnv),
}),
),
});