diff --git a/frontend/src/components/common/AppShell.vue b/frontend/src/components/common/AppShell.vue index d6ef9a7..289cfac 100644 --- a/frontend/src/components/common/AppShell.vue +++ b/frontend/src/components/common/AppShell.vue @@ -26,7 +26,7 @@ const router = useRouter() const routeName = computed(() => route.name as string) const secondaryComponent = computed(() => { - switch (routeName) { + switch (routeName.value) { case 'workspace': return 'file-tree' case 'search': return 'search-filters' case 'chat': return 'conversation-list' diff --git a/frontend/src/components/common/SecondarySidebar.vue b/frontend/src/components/common/SecondarySidebar.vue index 34c8a1b..99c5a68 100644 --- a/frontend/src/components/common/SecondarySidebar.vue +++ b/frontend/src/components/common/SecondarySidebar.vue @@ -1,11 +1,6 @@ @@ -109,4 +100,10 @@ const showSkillToggle = computed(() => routeName === 'skills' || routeName === ' overflow-y: auto; overflow-x: hidden; } + +.sidebar-placeholder { + padding: var(--space-lg); + color: var(--color-text-tertiary); + font-size: var(--font-size-sm); +} diff --git a/frontend/src/components/common/StatusBar.vue b/frontend/src/components/common/StatusBar.vue index a7e212d..825b833 100644 --- a/frontend/src/components/common/StatusBar.vue +++ b/frontend/src/components/common/StatusBar.vue @@ -78,7 +78,7 @@ const showEditorInfo = computed(() => route.name === 'workspace') 索引就绪 - + {{ aiCoreStatusText }} diff --git a/frontend/src/contracts/index.ts b/frontend/src/contracts/index.ts index 01e03c9..2497f16 100644 --- a/frontend/src/contracts/index.ts +++ b/frontend/src/contracts/index.ts @@ -247,15 +247,15 @@ export interface Plugin { enabled: boolean permissions: string[] contributions: PluginContribution[] - backend_type?: 'mcp' | 'internal' - transport?: 'stdio' | 'websocket' + backend_type?: 'mcp' | 'internal_rpc' | 'none' + transport?: 'stdio' | 'http' | 'none' last_error?: string dependent_skills?: string[] } // ============ Provider ============ -export type ProviderType = 'openai' | 'anthropic' | 'ollama' | 'openai-compatible' | 'mock' +export type ProviderType = ApiProviderType export interface ModelCapability { chat: boolean @@ -346,10 +346,10 @@ export interface ErrorResponse { } export interface SystemStatus { + status: 'ok' name: string version: string - environment: 'development' | 'production' | 'test' - ai_core_available: boolean + environment: string } export type SaveStatus = @@ -362,3 +362,178 @@ export type SaveStatus = | 'conflict' export type AiCoreStatus = 'starting' | 'running' | 'stopped' | 'error' + +// ============ FastAPI wire contracts ============ +// UI view models above may contain presentation-only fields. Services must use +// these DTOs at the HTTP boundary and explicitly map them to view models. + +export interface PageMeta { + total: number + limit: number + offset: number +} + +export interface OperationResponse { + status: 'accepted' | 'completed' + resource_id?: string | null + message?: string | null +} + +export interface ApiNoteBlock { + block_id: string + note_id: string + heading_path: string[] + start_offset: number + end_offset: number + content: string + content_hash: string + token_count: number +} + +export interface ApiNoteSummary { + note_id: string + title: string + file_path: string + tags: string[] + created_at: string + updated_at: string +} + +export interface ApiNote extends ApiNoteSummary { + markdown: string + blocks: ApiNoteBlock[] +} + +export interface ApiSearchResult { + note_id: string + block_id: string + title: string + file_path: string + heading_path: string[] + snippet?: string | null + score: number + citation: ApiCitation +} + +export interface ApiCitation { + citation_id: string + note_id: string + block_id: string + file_path: string + heading_path: string[] + start_offset?: number | null + end_offset?: number | null + source_audio?: string | null + start_time?: number | null + end_time?: number | null + speaker?: string | null +} + +export interface ApiAgentRun { + run_id: string + status: AgentRunStatus + input: string + provider_id: string + model: string + skill_id?: string | null + current_step: number + max_steps: number + token_budget?: number | null + cancelled: boolean + output?: string | null + error_code?: string | null + error_message?: string | null + token_usage: number + created_at: string + updated_at: string +} + +export interface ApiSkill { + manifest: { + skill_id: string + name: string + version: string + description: string + permissions: string[] + tools: string[] + retrieval: { top_k: number; rerank: boolean; citation: boolean } + model: { required_capabilities: string[] } + } + status: SkillStatus + enabled: boolean + missing_dependencies: string[] +} + +export interface ApiPlugin { + manifest: { + plugin_id: string + name: string + version: string + description: string + permissions: string[] + contributes: { + tools: string[] + commands: string[] + importers: string[] + exporters: string[] + panels: string[] + settings_sections: string[] + } + backend: { type: 'mcp' | 'internal_rpc' | 'none'; transport: 'stdio' | 'http' | 'none' } + } + status: PluginStatus + enabled: boolean + granted_permissions: string[] + error_message?: string | null +} + +export type ApiProviderType = + | 'mock' + | 'openai_responses' + | 'openai_chat' + | 'openai_compatible' + | 'anthropic_messages' + | 'ollama' + +export interface ApiProviderConfig { + provider_id: string + provider_type: ApiProviderType + name: string + base_url?: string | null + default_model?: string | null + credential_id?: string | null + enabled: boolean + capabilities: string[] +} + +export interface ApiModelInfo { + model: string + display_name: string + capabilities: string[] +} + +export interface ApiTask { + task_id: string + title: string + description: string + status: TaskStatus + note_id?: string | null + due_at?: string | null + created_at: string + updated_at: string +} + +export interface ApiIndexStatus { + status: 'idle' | 'queued' | 'running' | 'failed' + pending_jobs: number + active_job_id?: string | null + last_completed_at?: string | null + error_message?: string | null +} + +export interface ApiIndexJob { + job_id: string + status: 'queued' | 'running' | 'completed' | 'failed' + scope: 'all' | 'notes' | 'vectors' + created_at: string +} diff --git a/frontend/src/features/common/PlaceholderView.vue b/frontend/src/features/common/PlaceholderView.vue new file mode 100644 index 0000000..faf015f --- /dev/null +++ b/frontend/src/features/common/PlaceholderView.vue @@ -0,0 +1,34 @@ + + + + + diff --git a/frontend/src/features/editor/EditorHeader.vue b/frontend/src/features/editor/EditorHeader.vue new file mode 100644 index 0000000..42a2801 --- /dev/null +++ b/frontend/src/features/editor/EditorHeader.vue @@ -0,0 +1,26 @@ + + + + + diff --git a/frontend/src/features/editor/EditorPane.vue b/frontend/src/features/editor/EditorPane.vue new file mode 100644 index 0000000..d4a60ba --- /dev/null +++ b/frontend/src/features/editor/EditorPane.vue @@ -0,0 +1,30 @@ + + +