feat: Add branch-based beta toggle for switching between stable and beta versions
Adds Version Channel section to Settings sidebar allowing users to: - See current branch (main or beta/7.0) and stability status - Switch to beta branch to access Endless Mode features - Switch back to stable for production use - Pull updates for current branch Implementation: - BranchManager.ts: Git operations for branch detection/switching - worker-service.ts: /api/branch/* endpoints (status, switch, update) - Sidebar.tsx: Version Channel UI with branch state and handlers 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -29,6 +29,7 @@ import { SSEBroadcaster } from './worker/SSEBroadcaster.js';
|
||||
import { SDKAgent } from './worker/SDKAgent.js';
|
||||
import { PaginationHelper } from './worker/PaginationHelper.js';
|
||||
import { SettingsManager } from './worker/SettingsManager.js';
|
||||
import { getBranchInfo, switchBranch, pullUpdates, type BranchInfo, type SwitchResult } from './worker/BranchManager.js';
|
||||
|
||||
export class WorkerService {
|
||||
private app: express.Application;
|
||||
@@ -173,6 +174,11 @@ export class WorkerService {
|
||||
this.app.get('/api/mcp/status', this.handleGetMcpStatus.bind(this));
|
||||
this.app.post('/api/mcp/toggle', this.handleToggleMcp.bind(this));
|
||||
|
||||
// Branch switching (beta toggle)
|
||||
this.app.get('/api/branch/status', this.handleGetBranchStatus.bind(this));
|
||||
this.app.post('/api/branch/switch', this.handleSwitchBranch.bind(this));
|
||||
this.app.post('/api/branch/update', this.handleUpdateBranch.bind(this));
|
||||
|
||||
// Search API endpoints (for skill-based search)
|
||||
// Unified endpoints (new consolidated API)
|
||||
this.app.get('/api/search', this.handleUnifiedSearch.bind(this));
|
||||
@@ -1035,6 +1041,89 @@ export class WorkerService {
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Branch Switching Handlers (Beta Toggle)
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* GET /api/branch/status - Get current branch information
|
||||
*/
|
||||
private handleGetBranchStatus(req: Request, res: Response): void {
|
||||
try {
|
||||
const info = getBranchInfo();
|
||||
res.json(info);
|
||||
} catch (error) {
|
||||
logger.failure('WORKER', 'Failed to get branch status', {}, error as Error);
|
||||
res.status(500).json({ error: (error as Error).message });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* POST /api/branch/switch - Switch to a different branch
|
||||
* Body: { branch: "main" | "beta/7.0" }
|
||||
*/
|
||||
private async handleSwitchBranch(req: Request, res: Response): Promise<void> {
|
||||
try {
|
||||
const { branch } = req.body;
|
||||
|
||||
if (!branch) {
|
||||
res.status(400).json({ success: false, error: 'Missing branch parameter' });
|
||||
return;
|
||||
}
|
||||
|
||||
// Validate branch name
|
||||
const allowedBranches = ['main', 'beta/7.0'];
|
||||
if (!allowedBranches.includes(branch)) {
|
||||
res.status(400).json({
|
||||
success: false,
|
||||
error: `Invalid branch. Allowed: ${allowedBranches.join(', ')}`
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
logger.info('WORKER', 'Branch switch requested', { branch });
|
||||
|
||||
const result = await switchBranch(branch);
|
||||
|
||||
if (result.success) {
|
||||
// Schedule worker restart after response is sent
|
||||
setTimeout(() => {
|
||||
logger.info('WORKER', 'Restarting worker after branch switch');
|
||||
process.exit(0); // PM2 will restart the worker
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
res.json(result);
|
||||
} catch (error) {
|
||||
logger.failure('WORKER', 'Branch switch failed', {}, error as Error);
|
||||
res.status(500).json({ success: false, error: (error as Error).message });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* POST /api/branch/update - Pull latest updates for current branch
|
||||
*/
|
||||
private async handleUpdateBranch(req: Request, res: Response): Promise<void> {
|
||||
try {
|
||||
logger.info('WORKER', 'Branch update requested');
|
||||
|
||||
const result = await pullUpdates();
|
||||
|
||||
if (result.success) {
|
||||
// Schedule worker restart after response is sent
|
||||
setTimeout(() => {
|
||||
logger.info('WORKER', 'Restarting worker after branch update');
|
||||
process.exit(0); // PM2 will restart the worker
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
res.json(result);
|
||||
} catch (error) {
|
||||
logger.failure('WORKER', 'Branch update failed', {}, error as Error);
|
||||
res.status(500).json({ success: false, error: (error as Error).message });
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Search API Handlers (for skill-based search)
|
||||
// ============================================================================
|
||||
|
||||
Reference in New Issue
Block a user