feat: CodePilot - desktop GUI for Claude Code

Full-featured desktop application built with Next.js + Electron:
- Streaming chat with Claude Code via Agent SDK
- Session management with SQLite persistence
- Project file tree and file preview
- MCP server and custom skills management
- Permission controls with Code/Plan/Ask modes
- Dark/light theme, token tracking
- macOS DMG packaging with electron-builder

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
7418andClaude Opus 4.6 committed 2026-02-06 21:04:05 +08:00
1 parent 6776cc6297
commit ff1fb38735
149 files changed
+31117 -122

No files matched your search

+364
View File
@@ -0,0 +1,364 @@
// ==========================================
// Database Models
// ==========================================
export interface ChatSession {
id: string;
title: string;
created_at: string;
updated_at: string;
model: string;
system_prompt: string;
working_directory: string;
sdk_session_id: string; // Claude Agent SDK session ID for resume
project_name: string;
status: 'active' | 'archived';
mode?: 'code' | 'plan' | 'ask';
needs_approval?: boolean;
}
// ==========================================
// Project / File Types
// ==========================================
export interface ProjectInfo {
path: string;
name: string;
files_count: number;
last_modified: string;
}
export interface FileTreeNode {
name: string;
path: string;
type: 'file' | 'directory';
children?: FileTreeNode[];
size?: number;
extension?: string;
}
export interface FilePreview {
path: string;
content: string;
language: string;
line_count: number;
}
// ==========================================
// Task Types
// ==========================================
export type TaskStatus = 'pending' | 'in_progress' | 'completed' | 'failed';
export interface TaskItem {
id: string;
session_id: string;
title: string;
status: TaskStatus;
description: string | null;
created_at: string;
updated_at: string;
}
export interface Message {
id: string;
session_id: string;
role: 'user' | 'assistant';
content: string; // JSON string of MessageContentBlock[] for structured content
created_at: string;
token_usage: string | null; // JSON string of TokenUsage
}
// Structured message content blocks (stored as JSON in messages.content)
export type MessageContentBlock =
| { type: 'text'; text: string }
| { type: 'tool_use'; id: string; name: string; input: unknown }
| { type: 'tool_result'; tool_use_id: string; content: string; is_error?: boolean }
| { type: 'code'; language: string; code: string };
// Helper to parse message content - returns blocks or wraps plain text
export function parseMessageContent(content: string): MessageContentBlock[] {
try {
const parsed = JSON.parse(content);
if (Array.isArray(parsed)) return parsed;
} catch {
// Not JSON, treat as plain text
}
return [{ type: 'text', text: content }];
}
export interface Setting {
id: number;
key: string;
value: string;
}
// ==========================================
// Token Usage
// ==========================================
export interface TokenUsage {
input_tokens: number;
output_tokens: number;
cache_read_input_tokens?: number;
cache_creation_input_tokens?: number;
cost_usd?: number;
}
// ==========================================
// API Request Types
// ==========================================
export interface CreateSessionRequest {
title?: string;
model?: string;
system_prompt?: string;
working_directory?: string;
mode?: string;
}
export interface SendMessageRequest {
session_id: string;
content: string;
model?: string;
mode?: string;
}
export interface UpdateMCPConfigRequest {
mcpServers: Record<string, MCPServerConfig>;
}
export interface AddMCPServerRequest {
name: string;
server: MCPServerConfig;
}
export interface UpdateSettingsRequest {
settings: SettingsMap;
}
// --- File API ---
export interface FileTreeRequest {
dir: string;
depth?: number; // default 3
}
export interface FilePreviewRequest {
path: string;
maxLines?: number; // default 200
}
// --- Task API ---
export interface CreateTaskRequest {
session_id: string;
title: string;
description?: string;
}
export interface UpdateTaskRequest {
title?: string;
status?: TaskStatus;
description?: string;
}
// --- Skill API ---
export interface SkillDefinition {
name: string;
description: string;
prompt: string;
enabled: boolean;
}
export interface CreateSkillRequest {
name: string;
description: string;
prompt: string;
}
export interface UpdateSkillRequest {
description?: string;
prompt?: string;
enabled?: boolean;
}
// ==========================================
// API Response Types
// ==========================================
export interface SessionsResponse {
sessions: ChatSession[];
}
export interface SessionResponse {
session: ChatSession;
}
export interface MessagesResponse {
messages: Message[];
}
export interface SuccessResponse {
success: true;
}
export interface ErrorResponse {
error: string;
}
export interface SettingsResponse {
settings: SettingsMap;
}
export interface PluginsResponse {
plugins: PluginInfo[];
}
export interface MCPConfigResponse {
mcpServers: Record<string, MCPServerConfig>;
}
// --- File API Responses ---
export interface FileTreeResponse {
tree: FileTreeNode[];
root: string;
}
export interface FilePreviewResponse {
preview: FilePreview;
}
// --- Task API Responses ---
export interface TasksResponse {
tasks: TaskItem[];
}
export interface TaskResponse {
task: TaskItem;
}
// --- Skill API Responses ---
export interface SkillsResponse {
skills: SkillDefinition[];
}
export interface SkillResponse {
skill: SkillDefinition;
}
// ==========================================
// SSE Event Types (streaming chat response)
// ==========================================
export type SSEEventType =
| 'text' // text content delta
| 'tool_use' // tool invocation info
| 'tool_result' // tool execution result
| 'tool_output' // streaming tool output (stderr from SDK process)
| 'status' // status update (compacting, etc.)
| 'result' // final result with usage stats
| 'error' // error occurred
| 'permission_request' // permission approval needed
| 'done'; // stream complete
export interface SSEEvent {
type: SSEEventType;
data: string;
}
// ==========================================
// Permission Types
// ==========================================
export interface PermissionSuggestion {
type: string;
rules?: Array<{ toolName: string; ruleContent?: string }>;
behavior?: string;
destination?: string;
}
export interface PermissionRequestEvent {
permissionRequestId: string;
toolName: string;
toolInput: Record<string, unknown>;
suggestions?: PermissionSuggestion[];
decisionReason?: string;
blockedPath?: string;
toolUseId: string;
description?: string;
}
export interface PermissionResponseRequest {
permissionRequestId: string;
decision: {
behavior: 'allow';
updatedPermissions?: PermissionSuggestion[];
} | {
behavior: 'deny';
message?: string;
};
}
// ==========================================
// Plugin / MCP Types
// ==========================================
export interface PluginInfo {
name: string;
description: string;
enabled: boolean;
}
export interface MCPServerConfig {
command: string;
args?: string[];
env?: Record<string, string>;
type?: 'stdio' | 'sse' | 'http';
url?: string;
headers?: Record<string, string>;
}
export interface MCPConfig {
mcpServers: Record<string, MCPServerConfig>;
}
// Backward-compatible alias
export type MCPServer = MCPServerConfig;
// ==========================================
// Settings Types
// ==========================================
export interface SettingsMap {
[key: string]: string;
}
// Well-known setting keys
export const SETTING_KEYS = {
DEFAULT_MODEL: 'default_model',
DEFAULT_SYSTEM_PROMPT: 'default_system_prompt',
THEME: 'theme',
PERMISSION_MODE: 'permission_mode',
MAX_THINKING_TOKENS: 'max_thinking_tokens',
} as const;
// ==========================================
// Claude Client Types
// ==========================================
export interface ClaudeStreamOptions {
prompt: string;
sessionId: string;
sdkSessionId?: string; // SDK session ID for resuming conversations
model?: string;
systemPrompt?: string;
workingDirectory?: string;
mcpServers?: Record<string, MCPServerConfig>;
abortController?: AbortController;
permissionMode?: string;
}