mirror of
https://github.com/AutoMaker-Org/automaker.git
synced 2026-01-31 06:42:03 +00:00
feat: Add Cursor CLI configuration and status endpoints
- Implemented new routes for managing Cursor CLI configuration, including getting current settings and updating default models. - Created status endpoint to check Cursor CLI installation and authentication status. - Updated HttpApiClient to include methods for interacting with the new Cursor API endpoints. - Marked completion of the setup routes and status endpoints phase in the integration plan.
This commit is contained in:
@@ -12,6 +12,12 @@ import { createApiKeysHandler } from './routes/api-keys.js';
|
||||
import { createPlatformHandler } from './routes/platform.js';
|
||||
import { createVerifyClaudeAuthHandler } from './routes/verify-claude-auth.js';
|
||||
import { createGhStatusHandler } from './routes/gh-status.js';
|
||||
import { createCursorStatusHandler } from './routes/cursor-status.js';
|
||||
import {
|
||||
createGetCursorConfigHandler,
|
||||
createSetCursorDefaultModelHandler,
|
||||
createSetCursorModelsHandler,
|
||||
} from './routes/cursor-config.js';
|
||||
|
||||
export function createSetupRoutes(): Router {
|
||||
const router = Router();
|
||||
@@ -26,5 +32,11 @@ export function createSetupRoutes(): Router {
|
||||
router.post('/verify-claude-auth', createVerifyClaudeAuthHandler());
|
||||
router.get('/gh-status', createGhStatusHandler());
|
||||
|
||||
// Cursor CLI routes
|
||||
router.get('/cursor-status', createCursorStatusHandler());
|
||||
router.get('/cursor-config', createGetCursorConfigHandler());
|
||||
router.post('/cursor-config/default-model', createSetCursorDefaultModelHandler());
|
||||
router.post('/cursor-config/models', createSetCursorModelsHandler());
|
||||
|
||||
return router;
|
||||
}
|
||||
|
||||
136
apps/server/src/routes/setup/routes/cursor-config.ts
Normal file
136
apps/server/src/routes/setup/routes/cursor-config.ts
Normal file
@@ -0,0 +1,136 @@
|
||||
/**
|
||||
* Cursor CLI configuration routes
|
||||
*
|
||||
* Provides endpoints for managing Cursor CLI configuration:
|
||||
* - GET /api/setup/cursor-config - Get current configuration
|
||||
* - POST /api/setup/cursor-config/default-model - Set default model
|
||||
* - POST /api/setup/cursor-config/models - Set enabled models
|
||||
*/
|
||||
|
||||
import type { Request, Response } from 'express';
|
||||
import { CursorConfigManager } from '../../../providers/cursor-config-manager.js';
|
||||
import { CURSOR_MODEL_MAP, type CursorModelId } from '@automaker/types';
|
||||
import { getErrorMessage, logError } from '../common.js';
|
||||
|
||||
/**
|
||||
* Creates handler for GET /api/setup/cursor-config
|
||||
* Returns current Cursor configuration and available models
|
||||
*/
|
||||
export function createGetCursorConfigHandler() {
|
||||
return async (req: Request, res: Response): Promise<void> => {
|
||||
try {
|
||||
const projectPath = req.query.projectPath as string;
|
||||
|
||||
if (!projectPath) {
|
||||
res.status(400).json({
|
||||
success: false,
|
||||
error: 'projectPath query parameter is required',
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const configManager = new CursorConfigManager(projectPath);
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
config: configManager.getConfig(),
|
||||
availableModels: Object.values(CURSOR_MODEL_MAP),
|
||||
});
|
||||
} catch (error) {
|
||||
logError(error, 'Get Cursor config failed');
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
error: getErrorMessage(error),
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates handler for POST /api/setup/cursor-config/default-model
|
||||
* Sets the default Cursor model
|
||||
*/
|
||||
export function createSetCursorDefaultModelHandler() {
|
||||
return async (req: Request, res: Response): Promise<void> => {
|
||||
try {
|
||||
const { model, projectPath } = req.body;
|
||||
|
||||
if (!projectPath) {
|
||||
res.status(400).json({
|
||||
success: false,
|
||||
error: 'projectPath is required',
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (!model || !(model in CURSOR_MODEL_MAP)) {
|
||||
res.status(400).json({
|
||||
success: false,
|
||||
error: `Invalid model ID. Valid models: ${Object.keys(CURSOR_MODEL_MAP).join(', ')}`,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const configManager = new CursorConfigManager(projectPath);
|
||||
configManager.setDefaultModel(model as CursorModelId);
|
||||
|
||||
res.json({ success: true, model });
|
||||
} catch (error) {
|
||||
logError(error, 'Set Cursor default model failed');
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
error: getErrorMessage(error),
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates handler for POST /api/setup/cursor-config/models
|
||||
* Sets the enabled Cursor models list
|
||||
*/
|
||||
export function createSetCursorModelsHandler() {
|
||||
return async (req: Request, res: Response): Promise<void> => {
|
||||
try {
|
||||
const { models, projectPath } = req.body;
|
||||
|
||||
if (!projectPath) {
|
||||
res.status(400).json({
|
||||
success: false,
|
||||
error: 'projectPath is required',
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Array.isArray(models)) {
|
||||
res.status(400).json({
|
||||
success: false,
|
||||
error: 'Models must be an array',
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// Filter to valid models only
|
||||
const validModels = models.filter((m): m is CursorModelId => m in CURSOR_MODEL_MAP);
|
||||
|
||||
if (validModels.length === 0) {
|
||||
res.status(400).json({
|
||||
success: false,
|
||||
error: 'No valid models provided',
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const configManager = new CursorConfigManager(projectPath);
|
||||
configManager.setEnabledModels(validModels);
|
||||
|
||||
res.json({ success: true, models: validModels });
|
||||
} catch (error) {
|
||||
logError(error, 'Set Cursor models failed');
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
error: getErrorMessage(error),
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
52
apps/server/src/routes/setup/routes/cursor-status.ts
Normal file
52
apps/server/src/routes/setup/routes/cursor-status.ts
Normal file
@@ -0,0 +1,52 @@
|
||||
/**
|
||||
* GET /cursor-status endpoint - Get Cursor CLI installation and auth status
|
||||
*/
|
||||
|
||||
import type { Request, Response } from 'express';
|
||||
import { CursorProvider } from '../../../providers/cursor-provider.js';
|
||||
import { getErrorMessage, logError } from '../common.js';
|
||||
|
||||
/**
|
||||
* Creates handler for GET /api/setup/cursor-status
|
||||
* Returns Cursor CLI installation and authentication status
|
||||
*/
|
||||
export function createCursorStatusHandler() {
|
||||
const installCommand = 'curl https://cursor.com/install -fsS | bash';
|
||||
const loginCommand = 'cursor-agent login';
|
||||
|
||||
return async (_req: Request, res: Response): Promise<void> => {
|
||||
try {
|
||||
const provider = new CursorProvider();
|
||||
|
||||
const [installed, version, auth] = await Promise.all([
|
||||
provider.isInstalled(),
|
||||
provider.getVersion(),
|
||||
provider.checkAuth(),
|
||||
]);
|
||||
|
||||
// Get CLI path from provider (using type assertion since cliPath is private)
|
||||
const cliPath = installed
|
||||
? (provider as unknown as { cliPath: string | null }).cliPath
|
||||
: null;
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
installed,
|
||||
version: version || null,
|
||||
path: cliPath,
|
||||
auth: {
|
||||
authenticated: auth.authenticated,
|
||||
method: auth.method,
|
||||
},
|
||||
installCommand,
|
||||
loginCommand,
|
||||
});
|
||||
} catch (error) {
|
||||
logError(error, 'Get Cursor status failed');
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
error: getErrorMessage(error),
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -508,6 +508,59 @@ export class HttpApiClient implements ElectronAPI {
|
||||
error?: string;
|
||||
}> => this.get('/api/setup/gh-status'),
|
||||
|
||||
// Cursor CLI methods
|
||||
getCursorStatus: (): Promise<{
|
||||
success: boolean;
|
||||
installed?: boolean;
|
||||
version?: string | null;
|
||||
path?: string | null;
|
||||
auth?: {
|
||||
authenticated: boolean;
|
||||
method: string;
|
||||
};
|
||||
installCommand?: string;
|
||||
loginCommand?: string;
|
||||
error?: string;
|
||||
}> => this.get('/api/setup/cursor-status'),
|
||||
|
||||
getCursorConfig: (
|
||||
projectPath: string
|
||||
): Promise<{
|
||||
success: boolean;
|
||||
config?: {
|
||||
defaultModel?: string;
|
||||
models?: string[];
|
||||
mcpServers?: string[];
|
||||
rules?: string[];
|
||||
};
|
||||
availableModels?: Array<{
|
||||
id: string;
|
||||
label: string;
|
||||
description: string;
|
||||
hasThinking: boolean;
|
||||
tier: 'free' | 'pro';
|
||||
}>;
|
||||
error?: string;
|
||||
}> => this.get(`/api/setup/cursor-config?projectPath=${encodeURIComponent(projectPath)}`),
|
||||
|
||||
setCursorDefaultModel: (
|
||||
projectPath: string,
|
||||
model: string
|
||||
): Promise<{
|
||||
success: boolean;
|
||||
model?: string;
|
||||
error?: string;
|
||||
}> => this.post('/api/setup/cursor-config/default-model', { projectPath, model }),
|
||||
|
||||
setCursorModels: (
|
||||
projectPath: string,
|
||||
models: string[]
|
||||
): Promise<{
|
||||
success: boolean;
|
||||
models?: string[];
|
||||
error?: string;
|
||||
}> => this.post('/api/setup/cursor-config/models', { projectPath, models }),
|
||||
|
||||
onInstallProgress: (callback: (progress: unknown) => void) => {
|
||||
return this.subscribeToEvent('agent:stream', callback);
|
||||
},
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
| 1 | [Core Types & Configuration](phases/phase-1-types.md) | `completed` | ✅ |
|
||||
| 2 | [Cursor Provider Implementation](phases/phase-2-provider.md) | `completed` | ✅ |
|
||||
| 3 | [Provider Factory Integration](phases/phase-3-factory.md) | `completed` | ✅ |
|
||||
| 4 | [Setup Routes & Status Endpoints](phases/phase-4-routes.md) | `pending` | - |
|
||||
| 4 | [Setup Routes & Status Endpoints](phases/phase-4-routes.md) | `completed` | ✅ |
|
||||
| 5 | [Log Parser Integration](phases/phase-5-log-parser.md) | `pending` | - |
|
||||
| 6 | [UI Setup Wizard](phases/phase-6-setup-wizard.md) | `pending` | - |
|
||||
| 7 | [Settings View Provider Tabs](phases/phase-7-settings.md) | `pending` | - |
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Phase 4: Setup Routes & Status Endpoints
|
||||
|
||||
**Status:** `pending`
|
||||
**Status:** `completed`
|
||||
**Dependencies:** Phase 3 (Factory)
|
||||
**Estimated Effort:** Medium (API endpoints)
|
||||
|
||||
@@ -16,7 +16,7 @@ Create API endpoints for checking Cursor CLI status and managing configuration.
|
||||
|
||||
### Task 4.1: Create Cursor Status Route
|
||||
|
||||
**Status:** `pending`
|
||||
**Status:** `completed`
|
||||
|
||||
**File:** `apps/server/src/routes/setup/routes/cursor-status.ts`
|
||||
|
||||
@@ -74,7 +74,7 @@ export function createCursorStatusRoute(): Router {
|
||||
|
||||
### Task 4.2: Create Cursor Config Routes
|
||||
|
||||
**Status:** `pending`
|
||||
**Status:** `completed`
|
||||
|
||||
**File:** `apps/server/src/routes/setup/routes/cursor-config.ts`
|
||||
|
||||
@@ -182,7 +182,7 @@ export function createCursorConfigRoutes(dataDir: string): Router {
|
||||
|
||||
### Task 4.3: Register Routes in Setup Index
|
||||
|
||||
**Status:** `pending`
|
||||
**Status:** `completed`
|
||||
|
||||
**File:** `apps/server/src/routes/setup/index.ts`
|
||||
|
||||
@@ -210,7 +210,7 @@ export function createSetupRouter(dataDir: string): Router {
|
||||
|
||||
### Task 4.4: Update HttpApiClient
|
||||
|
||||
**Status:** `pending`
|
||||
**Status:** `completed`
|
||||
|
||||
**File:** `apps/ui/src/lib/http-api-client.ts`
|
||||
|
||||
@@ -320,24 +320,24 @@ curl -X POST http://localhost:3001/api/setup/cursor-config/default-model \
|
||||
|
||||
Before marking this phase complete:
|
||||
|
||||
- [ ] `/api/setup/cursor-status` returns installation status
|
||||
- [ ] `/api/setup/cursor-config` returns current config
|
||||
- [ ] `/api/setup/cursor-config/default-model` updates default
|
||||
- [ ] `/api/setup/cursor-config/models` updates enabled models
|
||||
- [ ] Error responses have correct status codes (400, 500)
|
||||
- [ ] Config persists to file after changes
|
||||
- [ ] SetupAPI type updated (if using Electron IPC)
|
||||
- [x] `/api/setup/cursor-status` returns installation status
|
||||
- [x] `/api/setup/cursor-config` returns current config
|
||||
- [x] `/api/setup/cursor-config/default-model` updates default
|
||||
- [x] `/api/setup/cursor-config/models` updates enabled models
|
||||
- [x] Error responses have correct status codes (400, 500)
|
||||
- [x] Config persists to file after changes
|
||||
- [x] HttpApiClient updated with Cursor methods (using web mode, not Electron IPC)
|
||||
|
||||
---
|
||||
|
||||
## Files Changed
|
||||
|
||||
| File | Action | Description |
|
||||
| ------------------------------------------------------ | ------ | ---------------- |
|
||||
| `apps/server/src/routes/setup/routes/cursor-status.ts` | Create | Status endpoint |
|
||||
| `apps/server/src/routes/setup/routes/cursor-config.ts` | Create | Config endpoints |
|
||||
| `apps/server/src/routes/setup/index.ts` | Modify | Register routes |
|
||||
| `apps/ui/src/lib/electron.ts` | Modify | Add API types |
|
||||
| File | Action | Description |
|
||||
| ------------------------------------------------------ | ------ | ----------------------------- |
|
||||
| `apps/server/src/routes/setup/routes/cursor-status.ts` | Create | Status endpoint |
|
||||
| `apps/server/src/routes/setup/routes/cursor-config.ts` | Create | Config endpoints |
|
||||
| `apps/server/src/routes/setup/index.ts` | Modify | Register routes |
|
||||
| `apps/ui/src/lib/http-api-client.ts` | Modify | Add Cursor API client methods |
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user