diff --git a/eslint.config.js b/eslint.config.js index 5e6b472..16ecca4 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -19,5 +19,12 @@ export default defineConfig([ ecmaVersion: 2020, globals: globals.browser, }, + rules: { + 'react-refresh/only-export-components': [ + 'warn', + { allowExportNames: ['useThemeCustomization', 'useThemePreset', 'useRoom', 'useOptionalRoom', 'resetAllThemeVars', 'loadThemeVars', 'applyThemePreset'] }, + ], + 'react-hooks/exhaustive-deps': 'warn', + }, }, ]) diff --git a/openapi.json b/openapi.json index 17a23b0..28ca416 100644 --- a/openapi.json +++ b/openapi.json @@ -1371,6 +1371,15 @@ "type": "string", "format": "uuid" } + }, + { + "name": "q", + "in": "query", + "description": "Search query (title)", + "required": false, + "schema": { + "type": "string" + } } ], "responses": { @@ -1693,12 +1702,13 @@ } } }, - "/api/ai/conversations/{conversation_id}/messages/{message_id}/fork/{target_message_id}": { + "/api/ai/conversations/{conversation_id}/messages/{message_id}/fork": { "post": { "tags": [ "AI Chat" ], - "operationId": "ai_message_fork", + "summary": "Fork a conversation from a specific message, creating a new conversation\nwith all messages up to and including the source message.", + "operationId": "ai_conversation_fork", "parameters": [ { "name": "conversation_id", @@ -1713,17 +1723,7 @@ { "name": "message_id", "in": "path", - "description": "Source message ID", - "required": true, - "schema": { - "type": "string", - "format": "uuid" - } - }, - { - "name": "target_message_id", - "in": "path", - "description": "Target/fork message ID to create", + "description": "Source message ID to fork from", "required": true, "schema": { "type": "string", @@ -1733,11 +1733,11 @@ ], "responses": { "200": { - "description": "Fork created", + "description": "Conversation forked", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ApiResponse_ForkResponse" + "$ref": "#/components/schemas/ApiResponse_ForkConversationResponse" } } } @@ -7942,6 +7942,45 @@ } } }, + "/api/projects/{project_name}/stats": { + "get": { + "tags": [ + "Project" + ], + "operationId": "project_stats", + "parameters": [ + { + "name": "project_name", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Get project statistics", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiResponse_ProjectStatsResponse" + } + } + } + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Forbidden — no access to this project" + }, + "404": { + "description": "Project not found" + } + } + } + }, "/api/projects/{project_name}/watch": { "get": { "tags": [ @@ -22342,6 +22381,22 @@ } } }, + "ActivityBreakdownItem": { + "type": "object", + "required": [ + "event_type", + "count" + ], + "properties": { + "event_type": { + "type": "string" + }, + "count": { + "type": "integer", + "format": "int64" + } + } + }, "ActivityLogListResponse": { "type": "object", "required": [ @@ -25331,7 +25386,7 @@ } } }, - "ApiResponse_ForkResponse": { + "ApiResponse_ForkConversationResponse": { "type": "object", "required": [ "code", @@ -25349,8 +25404,7 @@ "type": "object", "required": [ "id", - "source_message_id", - "fork_message_id", + "model", "created_at" ], "properties": { @@ -25358,20 +25412,14 @@ "type": "string", "format": "uuid" }, - "conversation_id": { + "title": { "type": [ "string", "null" - ], - "format": "uuid" + ] }, - "source_message_id": { - "type": "string", - "format": "uuid" - }, - "fork_message_id": { - "type": "string", - "format": "uuid" + "model": { + "type": "string" }, "created_at": { "type": "string", @@ -27495,6 +27543,130 @@ } } }, + "ApiResponse_ProjectStatsResponse": { + "type": "object", + "required": [ + "code", + "message" + ], + "properties": { + "code": { + "type": "integer", + "format": "int32" + }, + "message": { + "type": "string" + }, + "data": { + "type": "object", + "description": "Aggregated project statistics for dashboard display.", + "required": [ + "project_id", + "project_name", + "member_count", + "repo_count", + "issue_total", + "issue_open", + "issue_closed", + "pr_total", + "pr_open", + "pr_merged", + "pr_closed", + "room_count", + "ai_call_count", + "ai_input_tokens", + "ai_output_tokens", + "activity_last_30d", + "recent_activities" + ], + "properties": { + "project_id": { + "type": "string", + "format": "uuid" + }, + "project_name": { + "type": "string" + }, + "member_count": { + "type": "integer", + "format": "int64" + }, + "my_role": { + "type": [ + "string", + "null" + ] + }, + "repo_count": { + "type": "integer", + "format": "int64" + }, + "issue_total": { + "type": "integer", + "format": "int64" + }, + "issue_open": { + "type": "integer", + "format": "int64" + }, + "issue_closed": { + "type": "integer", + "format": "int64" + }, + "pr_total": { + "type": "integer", + "format": "int64" + }, + "pr_open": { + "type": "integer", + "format": "int64" + }, + "pr_merged": { + "type": "integer", + "format": "int64" + }, + "pr_closed": { + "type": "integer", + "format": "int64" + }, + "room_count": { + "type": "integer", + "format": "int64" + }, + "ai_call_count": { + "type": "integer", + "format": "int64" + }, + "ai_input_tokens": { + "type": "integer", + "format": "int64" + }, + "ai_output_tokens": { + "type": "integer", + "format": "int64" + }, + "ai_cost_usd": { + "type": [ + "string", + "null" + ] + }, + "activity_last_30d": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ActivityBreakdownItem" + } + }, + "recent_activities": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ProjectStatsActivityItem" + } + } + } + } + } + }, "ApiResponse_PullRequestListResponse": { "type": "object", "required": [ @@ -35838,12 +36010,11 @@ } } }, - "ForkResponse": { + "ForkConversationResponse": { "type": "object", "required": [ "id", - "source_message_id", - "fork_message_id", + "model", "created_at" ], "properties": { @@ -35851,20 +36022,14 @@ "type": "string", "format": "uuid" }, - "conversation_id": { + "title": { "type": [ "string", "null" - ], - "format": "uuid" + ] }, - "source_message_id": { - "type": "string", - "format": "uuid" - }, - "fork_message_id": { - "type": "string", - "format": "uuid" + "model": { + "type": "string" }, "created_at": { "type": "string", @@ -39354,6 +39519,149 @@ } } }, + "ProjectStatsActivityItem": { + "type": "object", + "required": [ + "id", + "event_type", + "title", + "actor_name", + "created_at" + ], + "properties": { + "id": { + "type": "integer", + "format": "int64" + }, + "event_type": { + "type": "string" + }, + "title": { + "type": "string" + }, + "actor_name": { + "type": "string" + }, + "actor_avatar": { + "type": [ + "string", + "null" + ] + }, + "created_at": { + "type": "string", + "format": "date-time" + } + } + }, + "ProjectStatsResponse": { + "type": "object", + "description": "Aggregated project statistics for dashboard display.", + "required": [ + "project_id", + "project_name", + "member_count", + "repo_count", + "issue_total", + "issue_open", + "issue_closed", + "pr_total", + "pr_open", + "pr_merged", + "pr_closed", + "room_count", + "ai_call_count", + "ai_input_tokens", + "ai_output_tokens", + "activity_last_30d", + "recent_activities" + ], + "properties": { + "project_id": { + "type": "string", + "format": "uuid" + }, + "project_name": { + "type": "string" + }, + "member_count": { + "type": "integer", + "format": "int64" + }, + "my_role": { + "type": [ + "string", + "null" + ] + }, + "repo_count": { + "type": "integer", + "format": "int64" + }, + "issue_total": { + "type": "integer", + "format": "int64" + }, + "issue_open": { + "type": "integer", + "format": "int64" + }, + "issue_closed": { + "type": "integer", + "format": "int64" + }, + "pr_total": { + "type": "integer", + "format": "int64" + }, + "pr_open": { + "type": "integer", + "format": "int64" + }, + "pr_merged": { + "type": "integer", + "format": "int64" + }, + "pr_closed": { + "type": "integer", + "format": "int64" + }, + "room_count": { + "type": "integer", + "format": "int64" + }, + "ai_call_count": { + "type": "integer", + "format": "int64" + }, + "ai_input_tokens": { + "type": "integer", + "format": "int64" + }, + "ai_output_tokens": { + "type": "integer", + "format": "int64" + }, + "ai_cost_usd": { + "type": [ + "string", + "null" + ] + }, + "activity_last_30d": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ActivityBreakdownItem" + } + }, + "recent_activities": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ProjectStatsActivityItem" + } + } + } + }, "ProviderResponse": { "type": "object", "required": [