Files
CodePilot/src/types/index.ts
T
7418andClaude Opus 4.6 164f730da1 feat: add file upload and preview support (images and documents)
- Support image (JPEG/PNG/GIF/WebP, max 5MB) and document uploads
- Images sent as multimodal content blocks to Claude SDK
- Documents saved to temp dir for Claude's Read tool
- Emerald capsule badges in input for attached files
- Drag-and-drop, paste, and file picker support via PromptInput
- Chat display: image thumbnails with lightbox, file cards
- Lightbox uses Radix Dialog with prev/next navigation
- File metadata embedded in message content as HTML comments
- Compatible with existing slash command badge system

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 21:35:45 +08:00

435 lines
9.5 KiB
TypeScript

// ==========================================
// 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;
}
// ==========================================
// API Provider Types
// ==========================================
export interface ApiProvider {
id: string;
name: string;
provider_type: string; // 'anthropic' | 'openrouter' | 'bedrock' | 'vertex' | 'custom'
base_url: string;
api_key: string;
is_active: number; // SQLite boolean: 0 or 1
sort_order: number;
extra_env: string; // JSON string of Record<string, string>
notes: string;
created_at: string;
updated_at: string;
}
export interface CreateProviderRequest {
name: string;
provider_type?: string;
base_url?: string;
api_key?: string;
extra_env?: string;
notes?: string;
}
export interface UpdateProviderRequest {
name?: string;
provider_type?: string;
base_url?: string;
api_key?: string;
extra_env?: string;
notes?: string;
sort_order?: number;
}
export interface ProvidersResponse {
providers: ApiProvider[];
}
export interface ProviderResponse {
provider: ApiProvider;
}
// ==========================================
// 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;
// ==========================================
// File Attachment Types
// ==========================================
export interface FileAttachment {
id: string;
name: string;
type: string; // MIME type
size: number;
data: string; // base64 encoded content
}
// Check if a MIME type is an image
export function isImageFile(type: string): boolean {
return type.startsWith('image/');
}
// Format bytes into human-readable size
export function formatFileSize(bytes: number): string {
if (bytes < 1024) return bytes + ' B';
if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + ' KB';
return (bytes / (1024 * 1024)).toFixed(1) + ' MB';
}
// ==========================================
// 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;
files?: FileAttachment[];
}