diff --git "a/openapi.json" "b/openapi.json" --- "a/openapi.json" +++ "b/openapi.json" @@ -2,7 +2,7 @@ "openapi": "3.1.0", "info": { "title": "Mission Control API", - "version": "1.2.0", + "version": "1.3.0", "description": "AI Agent Orchestration Platform API" }, "servers": [ @@ -75,121 +75,122 @@ { "name": "Connections", "description": "Direct CLI tool connections" + }, + { + "name": "Projects", + "description": "Project management and task grouping" + }, + { + "name": "Mentions", + "description": "User and agent mention autocomplete" + }, + { + "name": "Quality", + "description": "Quality review gate for tasks" + }, + { + "name": "Releases", + "description": "Release and version checking" + }, + { + "name": "Docs", + "description": "API documentation" } ], "paths": { - "/api/auth/login": { - "post": { + "/api/activities": { + "get": { "tags": [ - "Auth" + "Monitoring" ], - "summary": "Login with credentials", - "operationId": "login", - "security": [], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "type": "object", - "required": [ - "username", - "password" - ], - "properties": { - "username": { - "type": "string" - }, - "password": { - "type": "string" - } - } - } - } - } - }, - "responses": { - "200": { - "description": "Login successful. Sets mc-session cookie.", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "user": { - "$ref": "#/components/schemas/User" - } - } - } - } - }, - "headers": { - "Set-Cookie": { - "schema": { - "type": "string" - }, - "description": "mc-session cookie" - } + "summary": "List activities", + "operationId": "listActivities", + "parameters": [ + { + "name": "type", + "in": "query", + "schema": { + "type": "string" } }, - "400": { - "$ref": "#/components/responses/BadRequest" + { + "name": "actor", + "in": "query", + "schema": { + "type": "string" + } }, - "401": { - "description": "Invalid credentials", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } + { + "name": "entity_type", + "in": "query", + "schema": { + "type": "string" } }, - "429": { - "$ref": "#/components/responses/RateLimited" - } - } - } - }, - "/api/auth/logout": { - "post": { - "tags": [ - "Auth" - ], - "summary": "Logout and clear session", - "operationId": "logout", - "responses": { - "200": { - "description": "Session cleared" + { + "name": "limit", + "in": "query", + "schema": { + "type": "integer", + "default": 50 + } }, - "401": { - "$ref": "#/components/responses/Unauthorized" + { + "name": "offset", + "in": "query", + "schema": { + "type": "integer", + "default": 0 + } } - } - } - }, - "/api/auth/me": { - "get": { - "tags": [ - "Auth" ], - "summary": "Get current user info", - "operationId": "getCurrentUser", "responses": { "200": { + "description": "Activity list", "content": { "application/json": { "schema": { "type": "object", "properties": { - "user": { - "$ref": "#/components/schemas/User" + "activities": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "integer" + }, + "type": { + "type": "string" + }, + "entity_type": { + "type": "string" + }, + "entity_id": { + "type": "integer" + }, + "actor": { + "type": "string" + }, + "description": { + "type": "string" + }, + "metadata": { + "type": "object" + }, + "created_at": { + "type": "integer" + } + } + } + }, + "total": { + "type": "integer" } } } } - }, - "description": "Current user" + } }, "401": { "$ref": "#/components/responses/Unauthorized" @@ -197,26 +198,75 @@ } } }, - "/api/auth/users": { + "/api/agents": { "get": { "tags": [ - "Auth" + "Agents" + ], + "summary": "List agents", + "operationId": "listAgents", + "parameters": [ + { + "name": "status", + "in": "query", + "schema": { + "type": "string", + "enum": [ + "online", + "offline", + "busy", + "idle", + "error" + ] + } + }, + { + "name": "role", + "in": "query", + "schema": { + "type": "string" + } + }, + { + "name": "limit", + "in": "query", + "schema": { + "type": "integer", + "default": 50, + "maximum": 200 + } + }, + { + "name": "offset", + "in": "query", + "schema": { + "type": "integer", + "default": 0 + } + } ], - "summary": "List users", - "operationId": "listUsers", "responses": { "200": { - "description": "User list", + "description": "Paginated agent list", "content": { "application/json": { "schema": { "type": "object", "properties": { - "users": { + "agents": { "type": "array", "items": { - "$ref": "#/components/schemas/User" + "$ref": "#/components/schemas/Agent" } + }, + "total": { + "type": "integer" + }, + "page": { + "type": "integer" + }, + "limit": { + "type": "integer" } } } @@ -225,18 +275,15 @@ }, "401": { "$ref": "#/components/responses/Unauthorized" - }, - "403": { - "$ref": "#/components/responses/Forbidden" } } }, "post": { "tags": [ - "Auth" + "Agents" ], - "summary": "Create user", - "operationId": "createUser", + "summary": "Create agent", + "operationId": "createAgent", "requestBody": { "required": true, "content": { @@ -244,30 +291,44 @@ "schema": { "type": "object", "required": [ - "username", - "password", + "name", "role" ], "properties": { - "username": { + "name": { "type": "string" }, - "password": { + "role": { "type": "string" }, - "display_name": { + "session_key": { "type": "string" }, - "role": { - "type": "string", + "soul_content": { + "type": "string" + }, + "status": { + "type": "string", "enum": [ - "admin", - "operator", - "viewer" - ] + "online", + "offline", + "busy", + "idle", + "error" + ], + "default": "offline" }, - "email": { + "config": { + "type": "object" + }, + "template": { "type": "string" + }, + "gateway_config": { + "type": "object" + }, + "write_to_gateway": { + "type": "boolean" } } } @@ -276,14 +337,14 @@ }, "responses": { "201": { - "description": "User created", + "description": "Agent created", "content": { "application/json": { "schema": { "type": "object", "properties": { - "user": { - "$ref": "#/components/schemas/User" + "agent": { + "$ref": "#/components/schemas/Agent" } } } @@ -300,7 +361,7 @@ "$ref": "#/components/responses/Forbidden" }, "409": { - "description": "Username already exists", + "description": "Agent name already exists", "content": { "application/json": { "schema": { @@ -308,15 +369,18 @@ } } } + }, + "429": { + "$ref": "#/components/responses/RateLimited" } } }, "put": { "tags": [ - "Auth" + "Agents" ], - "summary": "Update user", - "operationId": "updateUser", + "summary": "Update agent by name", + "operationId": "updateAgentByName", "requestBody": { "required": true, "content": { @@ -324,27 +388,35 @@ "schema": { "type": "object", "required": [ - "id" + "name" ], "properties": { - "id": { - "type": "integer" - }, - "display_name": { + "name": { "type": "string" }, - "role": { + "status": { "type": "string", "enum": [ - "admin", - "operator", - "viewer" + "online", + "offline", + "busy", + "idle", + "error" ] }, - "email": { + "last_activity": { "type": "string" }, - "password": { + "config": { + "type": "object" + }, + "session_key": { + "type": "string" + }, + "soul_content": { + "type": "string" + }, + "role": { "type": "string" } } @@ -354,14 +426,14 @@ }, "responses": { "200": { - "description": "User updated", + "description": "Agent updated", "content": { "application/json": { "schema": { "type": "object", "properties": { - "user": { - "$ref": "#/components/schemas/User" + "success": { + "type": "boolean" } } } @@ -379,77 +451,46 @@ }, "404": { "$ref": "#/components/responses/NotFound" - } - } - }, - "delete": { - "tags": [ - "Auth" - ], - "summary": "Delete user", - "operationId": "deleteUser", - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "type": "object", - "required": [ - "id" - ], - "properties": { - "id": { - "type": "integer" - } - } - } - } - } - }, - "responses": { - "200": { - "description": "User deleted", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean" - } - } - } - } - } - }, - "401": { - "$ref": "#/components/responses/Unauthorized" - }, - "403": { - "$ref": "#/components/responses/Forbidden" }, - "404": { - "$ref": "#/components/responses/NotFound" + "429": { + "$ref": "#/components/responses/RateLimited" } } } }, - "/api/auth/access-requests": { + "/api/agents/comms": { "get": { "tags": [ - "Auth" + "Agents" + ], + "summary": "Get agent communications", + "operationId": "getAgentComms", + "parameters": [ + { + "name": "agent", + "in": "query", + "schema": { + "type": "string" + } + }, + { + "name": "limit", + "in": "query", + "schema": { + "type": "integer", + "default": 50 + } + } ], - "summary": "List access requests", - "operationId": "listAccessRequests", "responses": { "200": { - "description": "Access request list", + "description": "Agent communication log", "content": { "application/json": { "schema": { "type": "object", "properties": { - "requests": { + "messages": { "type": "array", "items": { "type": "object", @@ -457,22 +498,17 @@ "id": { "type": "integer" }, - "username": { + "from_agent": { "type": "string" }, - "email": { + "to_agent": { "type": "string" }, - "reason": { + "content": { "type": "string" }, - "status": { - "type": "string", - "enum": [ - "pending", - "approved", - "rejected" - ] + "type": { + "type": "string" }, "created_at": { "type": "integer" @@ -487,18 +523,17 @@ }, "401": { "$ref": "#/components/responses/Unauthorized" - }, - "403": { - "$ref": "#/components/responses/Forbidden" } } - }, + } + }, + "/api/agents/message": { "post": { "tags": [ - "Auth" + "Agents" ], - "summary": "Approve or reject access request", - "operationId": "handleAccessRequest", + "summary": "Send message between agents", + "operationId": "sendAgentMessage", "requestBody": { "required": true, "content": { @@ -506,27 +541,22 @@ "schema": { "type": "object", "required": [ - "id", - "action" + "from", + "to", + "content" ], "properties": { - "id": { - "type": "integer" + "from": { + "type": "string" }, - "action": { - "type": "string", - "enum": [ - "approve", - "reject" - ] + "to": { + "type": "string" }, - "role": { - "type": "string", - "enum": [ - "admin", - "operator", - "viewer" - ] + "content": { + "type": "string" + }, + "type": { + "type": "string" } } } @@ -535,7 +565,7 @@ }, "responses": { "200": { - "description": "Request processed", + "description": "Message sent", "content": { "application/json": { "schema": { @@ -543,6 +573,9 @@ "properties": { "success": { "type": "boolean" + }, + "id": { + "type": "integer" } } } @@ -561,108 +594,28 @@ } } }, - "/api/auth/google": { - "get": { + "/api/agents/sync": { + "post": { "tags": [ - "Auth" - ], - "summary": "Google OAuth callback", - "operationId": "googleOAuthCallback", - "security": [], - "parameters": [ - { - "name": "code", - "in": "query", - "schema": { - "type": "string" - } - }, - { - "name": "state", - "in": "query", - "schema": { - "type": "string" - } - } - ], - "responses": { - "302": { - "description": "Redirects to dashboard after successful auth" - }, - "400": { - "$ref": "#/components/responses/BadRequest" - } - } - } - }, - "/api/agents": { - "get": { - "tags": [ - "Agents" - ], - "summary": "List agents", - "operationId": "listAgents", - "parameters": [ - { - "name": "status", - "in": "query", - "schema": { - "type": "string", - "enum": [ - "online", - "offline", - "busy", - "idle", - "error" - ] - } - }, - { - "name": "role", - "in": "query", - "schema": { - "type": "string" - } - }, - { - "name": "limit", - "in": "query", - "schema": { - "type": "integer", - "default": 50, - "maximum": 200 - } - }, - { - "name": "offset", - "in": "query", - "schema": { - "type": "integer", - "default": 0 - } - } + "Agents" ], + "summary": "Sync agents from gateway config", + "operationId": "syncAgents", "responses": { "200": { - "description": "Paginated agent list", + "description": "Sync results", "content": { "application/json": { "schema": { "type": "object", "properties": { - "agents": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Agent" - } - }, - "total": { + "synced": { "type": "integer" }, - "page": { + "created": { "type": "integer" }, - "limit": { + "updated": { "type": "integer" } } @@ -670,187 +623,11 @@ } } }, - "401": { - "$ref": "#/components/responses/Unauthorized" - } - } - }, - "post": { - "tags": [ - "Agents" - ], - "summary": "Create agent", - "operationId": "createAgent", - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "type": "object", - "required": [ - "name", - "role" - ], - "properties": { - "name": { - "type": "string" - }, - "role": { - "type": "string" - }, - "session_key": { - "type": "string" - }, - "soul_content": { - "type": "string" - }, - "status": { - "type": "string", - "enum": [ - "online", - "offline", - "busy", - "idle", - "error" - ], - "default": "offline" - }, - "config": { - "type": "object" - }, - "template": { - "type": "string" - }, - "gateway_config": { - "type": "object" - }, - "write_to_gateway": { - "type": "boolean" - } - } - } - } - } - }, - "responses": { - "201": { - "description": "Agent created", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "agent": { - "$ref": "#/components/schemas/Agent" - } - } - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "401": { - "$ref": "#/components/responses/Unauthorized" - }, - "403": { - "$ref": "#/components/responses/Forbidden" - }, - "409": { - "description": "Agent name already exists", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "429": { - "$ref": "#/components/responses/RateLimited" - } - } - }, - "put": { - "tags": [ - "Agents" - ], - "summary": "Update agent by name", - "operationId": "updateAgentByName", - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "type": "object", - "required": [ - "name" - ], - "properties": { - "name": { - "type": "string" - }, - "status": { - "type": "string", - "enum": [ - "online", - "offline", - "busy", - "idle", - "error" - ] - }, - "last_activity": { - "type": "string" - }, - "config": { - "type": "object" - }, - "session_key": { - "type": "string" - }, - "soul_content": { - "type": "string" - }, - "role": { - "type": "string" - } - } - } - } - } - }, - "responses": { - "200": { - "description": "Agent updated", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean" - } - } - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" - }, - "404": { - "$ref": "#/components/responses/NotFound" - }, - "429": { - "$ref": "#/components/responses/RateLimited" } } } @@ -1016,73 +793,177 @@ } } }, - "/api/agents/{id}/attribution": { + "/api/agents/{id}/heartbeat": { "get": { "tags": [ "Agents" ], - "summary": "Get attribution report for an agent", - "description": "Self-scope by default. Requester must match target agent (`x-agent-name` or username), unless admin uses `?privileged=1`.", - "operationId": "getAgentAttribution", + "summary": "Check agent work items", + "operationId": "getAgentHeartbeat", "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { - "type": "string" + "type": "integer" } - }, - { - "name": "hours", - "in": "query", - "required": false, - "description": "Time window in hours, integer range 1..720. Defaults to 24.", - "schema": { - "type": "integer", - "minimum": 1, - "maximum": 720, - "default": 24 + } + ], + "responses": { + "200": { + "description": "Heartbeat data with pending work items", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "agent": { + "type": "string" + }, + "pending_tasks": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Task" + } + }, + "messages": { + "type": "array", + "items": { + "type": "object" + } + } + } + } + } } }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "404": { + "$ref": "#/components/responses/NotFound" + } + } + }, + "post": { + "tags": [ + "Agents" + ], + "summary": "Trigger manual heartbeat", + "operationId": "triggerAgentHeartbeat", + "parameters": [ { - "name": "section", - "in": "query", - "required": false, - "description": "Comma-separated subset of identity,audit,mutations,cost. Defaults to all.", + "name": "id", + "in": "path", + "required": true, "schema": { - "type": "string", - "example": "identity,audit" + "type": "integer" + } + } + ], + "responses": { + "200": { + "description": "Heartbeat triggered", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean" + } + } + } + } } }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "404": { + "$ref": "#/components/responses/NotFound" + } + } + } + }, + "/api/agents/{id}/memory": { + "get": { + "tags": [ + "Agents" + ], + "summary": "Get agent memory", + "operationId": "getAgentMemory", + "parameters": [ { - "name": "privileged", - "in": "query", - "required": false, - "description": "Set to 1 for admin override of self-scope checks.", + "name": "id", + "in": "path", + "required": true, "schema": { - "type": "string", - "enum": [ - "1" - ] + "type": "integer" } + } + ], + "responses": { + "200": { + "description": "Agent memory data", + "content": { + "application/json": { + "schema": { + "type": "object" + } + } + } + }, + "401": { + "$ref": "#/components/responses/Unauthorized" }, + "404": { + "$ref": "#/components/responses/NotFound" + } + } + }, + "put": { + "tags": [ + "Agents" + ], + "summary": "Update agent memory", + "operationId": "updateAgentMemory", + "parameters": [ { - "name": "x-agent-name", - "in": "header", - "required": false, - "description": "Attribution identity header used for self-scope authorization.", + "name": "id", + "in": "path", + "required": true, "schema": { - "type": "string" + "type": "integer" } } ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object" + } + } + } + }, "responses": { "200": { - "description": "Attribution report" - }, - "400": { - "$ref": "#/components/responses/BadRequest" + "description": "Memory updated", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean" + } + } + } + } + } }, "401": { "$ref": "#/components/responses/Unauthorized" @@ -1096,13 +977,13 @@ } } }, - "/api/agents/{id}/heartbeat": { + "/api/agents/{id}/soul": { "get": { "tags": [ "Agents" ], - "summary": "Check agent work items", - "operationId": "getAgentHeartbeat", + "summary": "Get agent soul config", + "operationId": "getAgentSoul", "parameters": [ { "name": "id", @@ -1115,26 +996,14 @@ ], "responses": { "200": { - "description": "Heartbeat data with pending work items", + "description": "Soul configuration", "content": { "application/json": { "schema": { "type": "object", "properties": { - "agent": { + "soul_content": { "type": "string" - }, - "pending_tasks": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Task" - } - }, - "messages": { - "type": "array", - "items": { - "type": "object" - } } } } @@ -1149,12 +1018,75 @@ } } }, + "put": { + "tags": [ + "Agents" + ], + "summary": "Update agent soul config", + "operationId": "updateAgentSoul", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "soul_content" + ], + "properties": { + "soul_content": { + "type": "string" + } + } + } + } + } + }, + "responses": { + "200": { + "description": "Soul updated", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean" + } + } + } + } + } + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "403": { + "$ref": "#/components/responses/Forbidden" + }, + "404": { + "$ref": "#/components/responses/NotFound" + } + } + } + }, + "/api/agents/{id}/wake": { "post": { "tags": [ "Agents" ], - "summary": "Trigger manual heartbeat", - "operationId": "triggerAgentHeartbeat", + "summary": "Wake an agent", + "operationId": "wakeAgent", "parameters": [ { "name": "id", @@ -1165,9 +1097,23 @@ } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "reason": { + "type": "string" + } + } + } + } + } + }, "responses": { "200": { - "description": "Heartbeat triggered", + "description": "Agent woken", "content": { "application/json": { "schema": { @@ -1180,73 +1126,299 @@ } } } - }, - "401": { - "$ref": "#/components/responses/Unauthorized" - }, - "404": { - "$ref": "#/components/responses/NotFound" - } - } - } - }, - "/api/agents/{id}/soul": { - "get": { - "tags": [ - "Agents" - ], - "summary": "Get agent soul config", - "operationId": "getAgentSoul", - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer" - } + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "403": { + "$ref": "#/components/responses/Forbidden" + }, + "404": { + "$ref": "#/components/responses/NotFound" + } + } + } + }, + "/api/alerts": { + "get": { + "tags": [ + "Alerts" + ], + "summary": "List alert rules", + "operationId": "listAlertRules", + "responses": { + "200": { + "description": "Alert rule list", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "rules": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AlertRule" + } + } + } + } + } + } + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + } + } + }, + "post": { + "tags": [ + "Alerts" + ], + "summary": "Create alert rule or evaluate rules", + "operationId": "createAlertRule", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "oneOf": [ + { + "type": "object", + "title": "CreateRule", + "required": [ + "name", + "entity_type", + "condition_field", + "condition_operator", + "condition_value" + ], + "properties": { + "name": { + "type": "string" + }, + "description": { + "type": "string" + }, + "entity_type": { + "type": "string", + "enum": [ + "agent", + "task", + "session", + "activity" + ] + }, + "condition_field": { + "type": "string" + }, + "condition_operator": { + "type": "string", + "enum": [ + "equals", + "not_equals", + "greater_than", + "less_than", + "contains", + "count_above", + "count_below", + "age_minutes_above" + ] + }, + "condition_value": { + "type": "string" + }, + "action_type": { + "type": "string", + "default": "notification" + }, + "action_config": { + "type": "object" + }, + "cooldown_minutes": { + "type": "integer", + "default": 60 + } + } + }, + { + "type": "object", + "title": "EvaluateRules", + "required": [ + "action" + ], + "properties": { + "action": { + "type": "string", + "const": "evaluate" + } + } + } + ] + } + } + } + }, + "responses": { + "201": { + "description": "Rule created", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "rule": { + "$ref": "#/components/schemas/AlertRule" + } + } + } + } + } + }, + "200": { + "description": "Rules evaluated", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "evaluated": { + "type": "integer" + }, + "triggered": { + "type": "integer" + }, + "results": { + "type": "array", + "items": { + "type": "object", + "properties": { + "rule_id": { + "type": "integer" + }, + "rule_name": { + "type": "string" + }, + "triggered": { + "type": "boolean" + }, + "reason": { + "type": "string" + } + } + } + } + } + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "403": { + "$ref": "#/components/responses/Forbidden" + }, + "429": { + "$ref": "#/components/responses/RateLimited" + } + } + }, + "put": { + "tags": [ + "Alerts" + ], + "summary": "Update alert rule", + "operationId": "updateAlertRule", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "id" + ], + "properties": { + "id": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "description": { + "type": "string" + }, + "enabled": { + "type": "boolean" + }, + "entity_type": { + "type": "string" + }, + "condition_field": { + "type": "string" + }, + "condition_operator": { + "type": "string" + }, + "condition_value": { + "type": "string" + }, + "action_type": { + "type": "string" + }, + "action_config": { + "type": "object" + }, + "cooldown_minutes": { + "type": "integer" + } + } + } + } } - ], + }, "responses": { "200": { - "description": "Soul configuration", + "description": "Rule updated", "content": { "application/json": { "schema": { "type": "object", "properties": { - "soul_content": { - "type": "string" + "rule": { + "$ref": "#/components/schemas/AlertRule" } } } } } }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, "401": { "$ref": "#/components/responses/Unauthorized" }, + "403": { + "$ref": "#/components/responses/Forbidden" + }, "404": { "$ref": "#/components/responses/NotFound" + }, + "429": { + "$ref": "#/components/responses/RateLimited" } } }, - "put": { + "delete": { "tags": [ - "Agents" - ], - "summary": "Update agent soul config", - "operationId": "updateAgentSoul", - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer" - } - } + "Alerts" ], + "summary": "Delete alert rule", + "operationId": "deleteAlertRule", "requestBody": { "required": true, "content": { @@ -1254,11 +1426,11 @@ "schema": { "type": "object", "required": [ - "soul_content" + "id" ], "properties": { - "soul_content": { - "type": "string" + "id": { + "type": "integer" } } } @@ -1267,13 +1439,13 @@ }, "responses": { "200": { - "description": "Soul updated", + "description": "Rule deleted", "content": { "application/json": { "schema": { "type": "object", "properties": { - "success": { + "deleted": { "type": "boolean" } } @@ -1281,90 +1453,102 @@ } } }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" }, - "404": { - "$ref": "#/components/responses/NotFound" + "429": { + "$ref": "#/components/responses/RateLimited" } } } }, - "/api/agents/{id}/memory": { + "/api/audit": { "get": { "tags": [ - "Agents" + "Monitoring" ], - "summary": "Get agent memory", - "operationId": "getAgentMemory", + "summary": "Get audit log", + "operationId": "getAuditLog", "parameters": [ { - "name": "id", - "in": "path", - "required": true, + "name": "action", + "in": "query", "schema": { - "type": "integer" + "type": "string" } - } - ], - "responses": { - "200": { - "description": "Agent memory data", - "content": { - "application/json": { - "schema": { - "type": "object" - } - } + }, + { + "name": "actor", + "in": "query", + "schema": { + "type": "string" } }, - "401": { - "$ref": "#/components/responses/Unauthorized" + { + "name": "limit", + "in": "query", + "schema": { + "type": "integer", + "default": 100 + } }, - "404": { - "$ref": "#/components/responses/NotFound" - } - } - }, - "put": { - "tags": [ - "Agents" - ], - "summary": "Update agent memory", - "operationId": "updateAgentMemory", - "parameters": [ { - "name": "id", - "in": "path", - "required": true, + "name": "offset", + "in": "query", "schema": { - "type": "integer" + "type": "integer", + "default": 0 } } ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "type": "object" - } - } - } - }, "responses": { "200": { - "description": "Memory updated", + "description": "Audit log entries", "content": { "application/json": { "schema": { "type": "object", "properties": { - "success": { - "type": "boolean" + "entries": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "integer" + }, + "action": { + "type": "string" + }, + "actor": { + "type": "string" + }, + "target_type": { + "type": "string" + }, + "target_id": { + "type": "integer" + }, + "detail": { + "type": "object" + }, + "ip_address": { + "type": "string" + }, + "created_at": { + "type": "integer" + } + } + } + }, + "total": { + "type": "integer" } } } @@ -1376,54 +1560,55 @@ }, "403": { "$ref": "#/components/responses/Forbidden" - }, - "404": { - "$ref": "#/components/responses/NotFound" } } } }, - "/api/agents/{id}/wake": { - "post": { + "/api/auth/access-requests": { + "get": { "tags": [ - "Agents" - ], - "summary": "Wake an agent", - "operationId": "wakeAgent", - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer" - } - } + "Auth" ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "reason": { - "type": "string" - } - } - } - } - } - }, + "summary": "List access requests", + "operationId": "listAccessRequests", "responses": { "200": { - "description": "Agent woken", + "description": "Access request list", "content": { "application/json": { "schema": { "type": "object", "properties": { - "success": { - "type": "boolean" + "requests": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "integer" + }, + "username": { + "type": "string" + }, + "email": { + "type": "string" + }, + "reason": { + "type": "string" + }, + "status": { + "type": "string", + "enum": [ + "pending", + "approved", + "rejected" + ] + }, + "created_at": { + "type": "integer" + } + } + } } } } @@ -1435,20 +1620,15 @@ }, "403": { "$ref": "#/components/responses/Forbidden" - }, - "404": { - "$ref": "#/components/responses/NotFound" } } - } - }, - "/api/agents/message": { + }, "post": { "tags": [ - "Agents" + "Auth" ], - "summary": "Send message between agents", - "operationId": "sendAgentMessage", + "summary": "Approve or reject access request", + "operationId": "handleAccessRequest", "requestBody": { "required": true, "content": { @@ -1456,22 +1636,27 @@ "schema": { "type": "object", "required": [ - "from", - "to", - "content" + "id", + "action" ], "properties": { - "from": { - "type": "string" - }, - "to": { - "type": "string" + "id": { + "type": "integer" }, - "content": { - "type": "string" + "action": { + "type": "string", + "enum": [ + "approve", + "reject" + ] }, - "type": { - "type": "string" + "role": { + "type": "string", + "enum": [ + "admin", + "operator", + "viewer" + ] } } } @@ -1480,7 +1665,7 @@ }, "responses": { "200": { - "description": "Message sent", + "description": "Request processed", "content": { "application/json": { "schema": { @@ -1488,9 +1673,6 @@ "properties": { "success": { "type": "boolean" - }, - "id": { - "type": "integer" } } } @@ -1509,195 +1691,179 @@ } } }, - "/api/agents/comms": { + "/api/auth/google": { "get": { "tags": [ - "Agents" + "Auth" ], - "summary": "Get agent communications", - "operationId": "getAgentComms", + "summary": "Google OAuth callback", + "operationId": "googleOAuthCallback", + "security": [], "parameters": [ { - "name": "agent", + "name": "code", "in": "query", "schema": { "type": "string" } }, { - "name": "limit", + "name": "state", "in": "query", "schema": { - "type": "integer", - "default": 50 + "type": "string" } } ], "responses": { - "200": { - "description": "Agent communication log", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "messages": { - "type": "array", - "items": { - "type": "object", - "properties": { - "id": { - "type": "integer" - }, - "from_agent": { - "type": "string" - }, - "to_agent": { - "type": "string" - }, - "content": { - "type": "string" - }, - "type": { - "type": "string" - }, - "created_at": { - "type": "integer" - } - } - } - } - } - } - } - } + "302": { + "description": "Redirects to dashboard after successful auth" }, - "401": { - "$ref": "#/components/responses/Unauthorized" + "400": { + "$ref": "#/components/responses/BadRequest" } } } }, - "/api/agents/sync": { + "/api/auth/login": { "post": { "tags": [ - "Agents" + "Auth" ], - "summary": "Sync agents from gateway config", - "operationId": "syncAgents", + "summary": "Login with credentials", + "operationId": "login", + "security": [], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "username", + "password" + ], + "properties": { + "username": { + "type": "string" + }, + "password": { + "type": "string" + } + } + } + } + } + }, "responses": { "200": { - "description": "Sync results", + "description": "Login successful. Sets mc-session cookie.", "content": { "application/json": { "schema": { "type": "object", "properties": { - "synced": { - "type": "integer" - }, - "created": { - "type": "integer" - }, - "updated": { - "type": "integer" + "user": { + "$ref": "#/components/schemas/User" } } } } + }, + "headers": { + "Set-Cookie": { + "schema": { + "type": "string" + }, + "description": "mc-session cookie" + } } }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, "401": { - "$ref": "#/components/responses/Unauthorized" + "description": "Invalid credentials", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } }, - "403": { - "$ref": "#/components/responses/Forbidden" + "429": { + "$ref": "#/components/responses/RateLimited" } } } }, - "/api/tasks": { - "get": { + "/api/auth/logout": { + "post": { "tags": [ - "Tasks" + "Auth" ], - "summary": "List tasks", - "operationId": "listTasks", - "parameters": [ - { - "name": "status", - "in": "query", - "schema": { - "type": "string", - "enum": [ - "inbox", - "assigned", - "in_progress", - "quality_review", - "done" - ] - } - }, - { - "name": "assigned_to", - "in": "query", - "schema": { - "type": "string" - } - }, - { - "name": "priority", - "in": "query", - "schema": { - "type": "string", - "enum": [ - "critical", - "high", - "medium", - "low" - ] - } + "summary": "Logout and clear session", + "operationId": "logout", + "responses": { + "200": { + "description": "Session cleared" }, - { - "name": "limit", - "in": "query", - "schema": { - "type": "integer", - "default": 50, - "maximum": 200 - } + "401": { + "$ref": "#/components/responses/Unauthorized" + } + } + } + }, + "/api/auth/me": { + "get": { + "tags": [ + "Auth" + ], + "summary": "Get current user info", + "operationId": "getCurrentUser", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "user": { + "$ref": "#/components/schemas/User" + } + } + } + } + }, + "description": "Current user" }, - { - "name": "offset", - "in": "query", - "schema": { - "type": "integer", - "default": 0 - } + "401": { + "$ref": "#/components/responses/Unauthorized" } + } + } + }, + "/api/auth/users": { + "get": { + "tags": [ + "Auth" ], + "summary": "List users", + "operationId": "listUsers", "responses": { "200": { - "description": "Paginated task list", + "description": "User list", "content": { "application/json": { "schema": { "type": "object", "properties": { - "tasks": { + "users": { "type": "array", "items": { - "$ref": "#/components/schemas/Task" + "$ref": "#/components/schemas/User" } - }, - "total": { - "type": "integer" - }, - "page": { - "type": "integer" - }, - "limit": { - "type": "integer" } } } @@ -1706,15 +1872,18 @@ }, "401": { "$ref": "#/components/responses/Unauthorized" + }, + "403": { + "$ref": "#/components/responses/Forbidden" } } }, "post": { "tags": [ - "Tasks" + "Auth" ], - "summary": "Create task", - "operationId": "createTask", + "summary": "Create user", + "operationId": "createUser", "requestBody": { "required": true, "content": { @@ -1722,56 +1891,30 @@ "schema": { "type": "object", "required": [ - "title" + "username", + "password", + "role" ], "properties": { - "title": { + "username": { "type": "string" }, - "description": { + "password": { "type": "string" }, - "status": { - "type": "string", - "enum": [ - "inbox", - "assigned", - "in_progress", - "quality_review", - "done" - ], - "default": "inbox" + "display_name": { + "type": "string" }, - "priority": { + "role": { "type": "string", "enum": [ - "critical", - "high", - "medium", - "low" - ], - "default": "medium" - }, - "assigned_to": { - "type": "string" - }, - "created_by": { - "type": "string" + "admin", + "operator", + "viewer" + ] }, - "due_date": { + "email": { "type": "string" - }, - "estimated_hours": { - "type": "number" - }, - "tags": { - "type": "array", - "items": { - "type": "string" - } - }, - "metadata": { - "type": "object" } } } @@ -1780,14 +1923,14 @@ }, "responses": { "201": { - "description": "Task created", + "description": "User created", "content": { "application/json": { "schema": { "type": "object", "properties": { - "task": { - "$ref": "#/components/schemas/Task" + "user": { + "$ref": "#/components/schemas/User" } } } @@ -1804,7 +1947,7 @@ "$ref": "#/components/responses/Forbidden" }, "409": { - "description": "Task title already exists", + "description": "Username already exists", "content": { "application/json": { "schema": { @@ -1812,18 +1955,15 @@ } } } - }, - "429": { - "$ref": "#/components/responses/RateLimited" } } }, "put": { "tags": [ - "Tasks" + "Auth" ], - "summary": "Bulk update task statuses", - "operationId": "bulkUpdateTasks", + "summary": "Update user", + "operationId": "updateUser", "requestBody": { "required": true, "content": { @@ -1831,33 +1971,28 @@ "schema": { "type": "object", "required": [ - "tasks" + "id" ], "properties": { - "tasks": { - "type": "array", - "items": { - "type": "object", - "required": [ - "id", - "status" - ], - "properties": { - "id": { - "type": "integer" - }, - "status": { - "type": "string", - "enum": [ - "inbox", - "assigned", - "in_progress", - "quality_review", - "done" - ] - } - } - } + "id": { + "type": "integer" + }, + "display_name": { + "type": "string" + }, + "role": { + "type": "string", + "enum": [ + "admin", + "operator", + "viewer" + ] + }, + "email": { + "type": "string" + }, + "password": { + "type": "string" } } } @@ -1866,17 +2001,14 @@ }, "responses": { "200": { - "description": "Tasks updated", + "description": "User updated", "content": { "application/json": { "schema": { "type": "object", "properties": { - "success": { - "type": "boolean" - }, - "updated": { - "type": "integer" + "user": { + "$ref": "#/components/schemas/User" } } } @@ -1886,111 +2018,35 @@ "400": { "$ref": "#/components/responses/BadRequest" }, - "401": { - "$ref": "#/components/responses/Unauthorized" - }, - "403": { - "$ref": "#/components/responses/Forbidden" - }, - "429": { - "$ref": "#/components/responses/RateLimited" - } - } - } - }, - "/api/tasks/{id}": { - "get": { - "tags": [ - "Tasks" - ], - "summary": "Get task by ID", - "operationId": "getTask", - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer" - } - } - ], - "responses": { - "200": { - "description": "Task details", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "task": { - "$ref": "#/components/schemas/Task" - } - } - } - } - } - }, - "401": { - "$ref": "#/components/responses/Unauthorized" - }, - "404": { - "$ref": "#/components/responses/NotFound" - } - } - }, - "put": { - "tags": [ - "Tasks" - ], - "summary": "Update task", - "operationId": "updateTask", - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer" - } + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "403": { + "$ref": "#/components/responses/Forbidden" + }, + "404": { + "$ref": "#/components/responses/NotFound" } + } + }, + "delete": { + "tags": [ + "Auth" ], + "summary": "Delete user", + "operationId": "deleteUser", "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", + "required": [ + "id" + ], "properties": { - "title": { - "type": "string" - }, - "description": { - "type": "string" - }, - "status": { - "type": "string" - }, - "priority": { - "type": "string" - }, - "assigned_to": { - "type": "string" - }, - "due_date": { - "type": "string" - }, - "estimated_hours": { - "type": "number" - }, - "tags": { - "type": "array", - "items": { - "type": "string" - } - }, - "metadata": { - "type": "object" + "id": { + "type": "integer" } } } @@ -1999,14 +2055,14 @@ }, "responses": { "200": { - "description": "Task updated", + "description": "User deleted", "content": { "application/json": { "schema": { "type": "object", "properties": { - "task": { - "$ref": "#/components/schemas/Task" + "success": { + "type": "boolean" } } } @@ -2021,31 +2077,20 @@ }, "404": { "$ref": "#/components/responses/NotFound" - }, - "429": { - "$ref": "#/components/responses/RateLimited" } } - }, - "delete": { + } + }, + "/api/backup": { + "post": { "tags": [ - "Tasks" - ], - "summary": "Delete task", - "operationId": "deleteTask", - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer" - } - } + "Admin" ], + "summary": "Trigger backup", + "operationId": "triggerBackup", "responses": { "200": { - "description": "Task deleted", + "description": "Backup completed", "content": { "application/json": { "schema": { @@ -2053,6 +2098,12 @@ "properties": { "success": { "type": "boolean" + }, + "path": { + "type": "string" + }, + "size_bytes": { + "type": "integer" } } } @@ -2064,39 +2115,100 @@ }, "403": { "$ref": "#/components/responses/Forbidden" + } + } + } + }, + "/api/chat/conversations": { + "get": { + "tags": [ + "Chat" + ], + "summary": "List conversations", + "operationId": "listConversations", + "responses": { + "200": { + "description": "Conversation list", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "conversations": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "integer" + }, + "participants": { + "type": "array", + "items": { + "type": "string" + } + }, + "last_message": { + "type": "string" + }, + "updated_at": { + "type": "integer" + } + } + } + } + } + } + } + } }, - "404": { - "$ref": "#/components/responses/NotFound" + "401": { + "$ref": "#/components/responses/Unauthorized" } } } }, - "/api/tasks/{id}/comments": { + "/api/chat/messages": { "get": { "tags": [ - "Tasks" + "Chat" ], - "summary": "List task comments", - "operationId": "listTaskComments", + "summary": "List messages", + "operationId": "listMessages", "parameters": [ { - "name": "id", - "in": "path", - "required": true, + "name": "conversation_id", + "in": "query", "schema": { "type": "integer" } + }, + { + "name": "limit", + "in": "query", + "schema": { + "type": "integer", + "default": 50 + } + }, + { + "name": "offset", + "in": "query", + "schema": { + "type": "integer", + "default": 0 + } } ], "responses": { "200": { - "description": "Comment list", + "description": "Message list", "content": { "application/json": { "schema": { "type": "object", "properties": { - "comments": { + "messages": { "type": "array", "items": { "type": "object", @@ -2104,10 +2216,10 @@ "id": { "type": "integer" }, - "task_id": { + "conversation_id": { "type": "integer" }, - "author": { + "sender": { "type": "string" }, "content": { @@ -2126,28 +2238,15 @@ }, "401": { "$ref": "#/components/responses/Unauthorized" - }, - "404": { - "$ref": "#/components/responses/NotFound" } } }, "post": { "tags": [ - "Tasks" - ], - "summary": "Add comment to task", - "operationId": "addTaskComment", - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer" - } - } + "Chat" ], + "summary": "Send message", + "operationId": "sendMessage", "requestBody": { "required": true, "content": { @@ -2158,10 +2257,13 @@ "content" ], "properties": { + "conversation_id": { + "type": "integer" + }, "content": { "type": "string" }, - "author": { + "recipient": { "type": "string" } } @@ -2171,13 +2273,13 @@ }, "responses": { "201": { - "description": "Comment added", + "description": "Message sent", "content": { "application/json": { "schema": { "type": "object", "properties": { - "comment": { + "message": { "type": "object" } } @@ -2193,20 +2295,17 @@ }, "403": { "$ref": "#/components/responses/Forbidden" - }, - "404": { - "$ref": "#/components/responses/NotFound" } } } }, - "/api/tasks/{id}/broadcast": { - "post": { + "/api/chat/messages/{id}": { + "get": { "tags": [ - "Tasks" + "Chat" ], - "summary": "Broadcast task to agents", - "operationId": "broadcastTask", + "summary": "Get message by ID", + "operationId": "getMessage", "parameters": [ { "name": "id", @@ -2217,29 +2316,44 @@ } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "agents": { - "type": "array", - "items": { - "type": "string" - } - }, - "message": { - "type": "string" - } + "responses": { + "200": { + "description": "Message details", + "content": { + "application/json": { + "schema": { + "type": "object" } } } + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "404": { + "$ref": "#/components/responses/NotFound" + } + } + }, + "delete": { + "tags": [ + "Chat" + ], + "summary": "Delete message", + "operationId": "deleteMessage", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "integer" + } } - }, + ], "responses": { "200": { - "description": "Task broadcast sent", + "description": "Message deleted", "content": { "application/json": { "schema": { @@ -2247,12 +2361,6 @@ "properties": { "success": { "type": "boolean" - }, - "delivered_to": { - "type": "array", - "items": { - "type": "string" - } } } } @@ -2271,117 +2379,88 @@ } } }, - "/api/chat/conversations": { + "/api/claude/sessions": { "get": { "tags": [ - "Chat" + "Sessions" ], - "summary": "List conversations", - "operationId": "listConversations", + "summary": "List Claude CLI sessions", + "operationId": "listClaudeSessions", "responses": { "200": { - "description": "Conversation list", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "conversations": { - "type": "array", - "items": { - "type": "object", - "properties": { - "id": { - "type": "integer" - }, - "participants": { - "type": "array", - "items": { - "type": "string" - } - }, - "last_message": { - "type": "string" - }, - "updated_at": { - "type": "integer" - } - } - } - } + "description": "Session list" + } + } + }, + "post": { + "tags": [ + "Sessions" + ], + "summary": "Register a Claude CLI session", + "operationId": "registerClaudeSession", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "session_id": { + "type": "string" + }, + "agent_name": { + "type": "string" + }, + "model": { + "type": "string" } } } } - }, - "401": { - "$ref": "#/components/responses/Unauthorized" + } + }, + "responses": { + "200": { + "description": "Session registered" } } } }, - "/api/chat/messages": { - "get": { + "/api/cleanup": { + "post": { "tags": [ - "Chat" + "Admin" ], - "summary": "List messages", - "operationId": "listMessages", - "parameters": [ - { - "name": "conversation_id", - "in": "query", - "schema": { - "type": "integer" - } - }, - { - "name": "limit", - "in": "query", - "schema": { - "type": "integer", - "default": 50 - } - }, - { - "name": "offset", - "in": "query", - "schema": { - "type": "integer", - "default": 0 + "summary": "Trigger cleanup of old data", + "operationId": "triggerCleanup", + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "older_than_days": { + "type": "integer", + "default": 30 + } + } + } } } - ], + }, "responses": { "200": { - "description": "Message list", + "description": "Cleanup results", "content": { "application/json": { "schema": { "type": "object", "properties": { - "messages": { - "type": "array", - "items": { - "type": "object", - "properties": { - "id": { - "type": "integer" - }, - "conversation_id": { - "type": "integer" - }, - "sender": { - "type": "string" - }, - "content": { - "type": "string" - }, - "created_at": { - "type": "integer" - } - } - } + "success": { + "type": "boolean" + }, + "deleted": { + "type": "object" } } } @@ -2390,15 +2469,21 @@ }, "401": { "$ref": "#/components/responses/Unauthorized" + }, + "403": { + "$ref": "#/components/responses/Forbidden" } } - }, + } + }, + "/api/connect": { "post": { "tags": [ - "Chat" + "Connections" ], - "summary": "Send message", - "operationId": "sendMessage", + "summary": "Register a direct CLI connection", + "description": "Registers a CLI tool directly without a gateway. Auto-creates agent if name doesn't exist.", + "operationId": "registerConnection", "requestBody": { "required": true, "content": { @@ -2406,17 +2491,24 @@ "schema": { "type": "object", "required": [ - "content" + "tool_name", + "agent_name" ], "properties": { - "conversation_id": { - "type": "integer" + "tool_name": { + "type": "string" }, - "content": { + "tool_version": { "type": "string" }, - "recipient": { + "agent_name": { + "type": "string" + }, + "agent_role": { "type": "string" + }, + "metadata": { + "type": "object" } } } @@ -2424,15 +2516,37 @@ } }, "responses": { - "201": { - "description": "Message sent", + "200": { + "description": "Connection registered", "content": { "application/json": { "schema": { "type": "object", "properties": { - "message": { - "type": "object" + "connection_id": { + "type": "string", + "format": "uuid" + }, + "agent_id": { + "type": "integer" + }, + "agent_name": { + "type": "string" + }, + "status": { + "type": "string", + "enum": [ + "connected" + ] + }, + "sse_url": { + "type": "string" + }, + "heartbeat_url": { + "type": "string" + }, + "token_report_url": { + "type": "string" } } } @@ -2444,100 +2558,139 @@ }, "401": { "$ref": "#/components/responses/Unauthorized" - }, - "403": { - "$ref": "#/components/responses/Forbidden" } } - } - }, - "/api/chat/messages/{id}": { + }, "get": { "tags": [ - "Chat" - ], - "summary": "Get message by ID", - "operationId": "getMessage", - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer" - } - } + "Connections" ], + "summary": "List all direct connections", + "operationId": "listConnections", "responses": { "200": { - "description": "Message details", + "description": "List of connections", "content": { "application/json": { "schema": { - "type": "object" + "type": "object", + "properties": { + "connections": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "integer" + }, + "agent_id": { + "type": "integer" + }, + "agent_name": { + "type": "string" + }, + "tool_name": { + "type": "string" + }, + "tool_version": { + "type": "string" + }, + "connection_id": { + "type": "string", + "format": "uuid" + }, + "status": { + "type": "string", + "enum": [ + "connected", + "disconnected" + ] + }, + "last_heartbeat": { + "type": "integer" + }, + "created_at": { + "type": "integer" + } + } + } + } + } } } } }, "401": { "$ref": "#/components/responses/Unauthorized" - }, - "404": { - "$ref": "#/components/responses/NotFound" } } }, "delete": { "tags": [ - "Chat" + "Connections" ], - "summary": "Delete message", - "operationId": "deleteMessage", - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer" + "summary": "Disconnect a CLI connection", + "operationId": "disconnectConnection", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "connection_id" + ], + "properties": { + "connection_id": { + "type": "string", + "format": "uuid" + } + } + } } } - ], + }, "responses": { "200": { - "description": "Message deleted", + "description": "Disconnected", "content": { "application/json": { "schema": { "type": "object", "properties": { - "success": { - "type": "boolean" + "status": { + "type": "string", + "enum": [ + "disconnected" + ] + }, + "connection_id": { + "type": "string" } } } } } }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, "401": { "$ref": "#/components/responses/Unauthorized" }, - "403": { - "$ref": "#/components/responses/Forbidden" - }, "404": { "$ref": "#/components/responses/NotFound" } } } }, - "/api/tokens": { + "/api/cron": { "get": { "tags": [ - "Tokens" + "Admin" ], - "summary": "Query token usage", - "operationId": "getTokenUsage", + "summary": "Get cron jobs", + "operationId": "getCronJobs", "parameters": [ { "name": "action", @@ -2546,149 +2699,62 @@ "type": "string", "enum": [ "list", - "stats", - "agent-costs", - "export", - "trends" + "logs" ], "default": "list" } - }, - { - "name": "timeframe", - "in": "query", - "schema": { - "type": "string", - "enum": [ - "hour", - "day", - "week", - "month", - "all" - ], - "default": "all" - } - }, - { - "name": "format", - "in": "query", - "description": "Export format (only for action=export)", - "schema": { - "type": "string", - "enum": [ - "json", - "csv" - ], - "default": "json" - } } ], "responses": { "200": { - "description": "Token usage data. Shape varies by action.", + "description": "Cron job list or logs", "content": { "application/json": { "schema": { - "oneOf": [ - { - "type": "object", - "title": "ListResponse", - "properties": { - "usage": { - "type": "array", - "items": { - "$ref": "#/components/schemas/TokenUsageRecord" - } - }, - "total": { - "type": "integer" - }, - "timeframe": { - "type": "string" - } - } - }, - { - "type": "object", - "title": "StatsResponse", - "properties": { - "summary": { - "$ref": "#/components/schemas/TokenStats" - }, - "models": { - "type": "object", - "additionalProperties": { - "$ref": "#/components/schemas/TokenStats" - } - }, - "sessions": { - "type": "object", - "additionalProperties": { - "$ref": "#/components/schemas/TokenStats" - } - }, - "agents": { - "type": "object", - "additionalProperties": { - "$ref": "#/components/schemas/TokenStats" - } - }, - "timeframe": { - "type": "string" - }, - "recordCount": { - "type": "integer" - } - } - }, - { - "type": "object", - "title": "TrendsResponse", - "properties": { - "trends": { - "type": "array", - "items": { - "type": "object", - "properties": { - "timestamp": { - "type": "string" - }, - "tokens": { - "type": "integer" - }, - "cost": { - "type": "number" - }, - "requests": { - "type": "integer" - } - } + "type": "object", + "properties": { + "jobs": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "schedule": { + "type": "string" + }, + "enabled": { + "type": "boolean" + }, + "last_run": { + "type": "integer" + }, + "last_status": { + "type": "string" } - }, - "timeframe": { - "type": "string" } } } - ] + } } } } }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, "401": { "$ref": "#/components/responses/Unauthorized" + }, + "403": { + "$ref": "#/components/responses/Forbidden" } } }, "post": { "tags": [ - "Tokens" + "Admin" ], - "summary": "Record token usage", - "operationId": "recordTokenUsage", + "summary": "Manage cron jobs", + "operationId": "manageCronJobs", "requestBody": { "required": true, "content": { @@ -2696,30 +2762,29 @@ "schema": { "type": "object", "required": [ - "model", - "sessionId", - "inputTokens", - "outputTokens" + "action" ], "properties": { - "model": { - "type": "string" + "action": { + "type": "string", + "enum": [ + "toggle", + "trigger", + "add", + "remove" + ] }, - "sessionId": { + "name": { "type": "string" }, - "inputTokens": { - "type": "integer" - }, - "outputTokens": { - "type": "integer" + "schedule": { + "type": "string" }, - "operation": { - "type": "string", - "default": "chat_completion" + "command": { + "type": "string" }, - "duration": { - "type": "number" + "enabled": { + "type": "boolean" } } } @@ -2728,7 +2793,7 @@ }, "responses": { "200": { - "description": "Usage recorded", + "description": "Action applied", "content": { "application/json": { "schema": { @@ -2736,9 +2801,6 @@ "properties": { "success": { "type": "boolean" - }, - "record": { - "$ref": "#/components/schemas/TokenUsageRecord" } } } @@ -2757,82 +2819,112 @@ } } }, - "/api/sessions": { + "/api/docs": { "get": { "tags": [ - "Sessions" + "Docs" ], - "summary": "List gateway sessions", - "operationId": "listSessions", + "summary": "Get OpenAPI specification", + "operationId": "getOpenApiSpec", + "security": [], + "responses": { + "200": { + "description": "OpenAPI 3.1 JSON spec" + } + } + } + }, + "/api/events": { + "get": { + "tags": [ + "Monitoring" + ], + "summary": "SSE stream for real-time events", + "operationId": "getEventStream", + "responses": { + "200": { + "description": "Server-Sent Events stream", + "content": { + "text/event-stream": { + "schema": { + "type": "string" + } + } + } + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + } + } + } + }, + "/api/export": { + "get": { + "tags": [ + "Admin" + ], + "summary": "Export data", + "operationId": "exportData", "parameters": [ { - "name": "agent", + "name": "type", "in": "query", "schema": { - "type": "string" + "type": "string", + "enum": [ + "tasks", + "agents", + "activities", + "all" + ] } }, { - "name": "limit", + "name": "format", "in": "query", "schema": { - "type": "integer", - "default": 50 + "type": "string", + "enum": [ + "json", + "csv" + ], + "default": "json" } } ], "responses": { "200": { - "description": "Session list", + "description": "Exported data", "content": { "application/json": { "schema": { - "type": "object", - "properties": { - "sessions": { - "type": "array", - "items": { - "type": "object", - "properties": { - "key": { - "type": "string" - }, - "agent": { - "type": "string" - }, - "model": { - "type": "string" - }, - "status": { - "type": "string" - }, - "totalTokens": { - "type": "integer" - }, - "updatedAt": { - "type": "integer" - } - } - } - } - } + "type": "object" + } + }, + "text/csv": { + "schema": { + "type": "string" } } } }, "401": { "$ref": "#/components/responses/Unauthorized" + }, + "403": { + "$ref": "#/components/responses/Forbidden" } } } }, - "/api/sessions/{id}/control": { - "post": { + "/api/agents/{id}/attribution": { + "get": { "tags": [ - "Sessions" + "Agents" ], - "summary": "Control session (pause/resume/kill)", - "operationId": "controlSession", + "summary": "Get attribution report for an agent", + "description": "Self-scope by default. Requester must match target agent (`x-agent-name` or username), unless admin uses `?privileged=1`.", + "operationId": "getAgentAttribution", "parameters": [ { "name": "id", @@ -2841,34 +2933,115 @@ "schema": { "type": "string" } + }, + { + "name": "hours", + "in": "query", + "required": false, + "description": "Time window in hours, integer range 1..720. Defaults to 24.", + "schema": { + "type": "integer", + "minimum": 1, + "maximum": 720, + "default": 24 + } + }, + { + "name": "section", + "in": "query", + "required": false, + "description": "Comma-separated subset of identity,audit,mutations,cost. Defaults to all.", + "schema": { + "type": "string", + "example": "identity,audit" + } + }, + { + "name": "privileged", + "in": "query", + "required": false, + "description": "Set to 1 for admin override of self-scope checks.", + "schema": { + "type": "string", + "enum": [ + "1" + ] + } + }, + { + "name": "x-agent-name", + "in": "header", + "required": false, + "description": "Attribution identity header used for self-scope authorization.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Attribution report" + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "403": { + "$ref": "#/components/responses/Forbidden" + }, + "404": { + "$ref": "#/components/responses/NotFound" + } + } + } + }, + "/api/gateway-config": { + "get": { + "tags": [ + "Admin" + ], + "summary": "Read gateway config", + "operationId": "getGatewayConfig", + "responses": { + "200": { + "description": "Gateway configuration", + "content": { + "application/json": { + "schema": { + "type": "object" + } + } + } + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "403": { + "$ref": "#/components/responses/Forbidden" } + } + }, + "post": { + "tags": [ + "Admin" ], + "summary": "Update gateway config", + "operationId": "updateGatewayConfig", "requestBody": { "required": true, "content": { "application/json": { "schema": { - "type": "object", - "required": [ - "action" - ], - "properties": { - "action": { - "type": "string", - "enum": [ - "pause", - "resume", - "kill" - ] - } - } + "type": "object" } } } }, "responses": { "200": { - "description": "Action applied", + "description": "Config updated", "content": { "application/json": { "schema": { @@ -2882,40 +3055,51 @@ } } }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" - }, - "404": { - "$ref": "#/components/responses/NotFound" } } } }, - "/api/webhooks": { + "/api/gateways": { "get": { "tags": [ - "Webhooks" + "Admin" ], - "summary": "List webhooks", - "operationId": "listWebhooks", + "summary": "List gateways", + "operationId": "listGateways", "responses": { "200": { - "description": "Webhook list with delivery stats", + "description": "Gateway list", "content": { "application/json": { "schema": { "type": "object", "properties": { - "webhooks": { + "gateways": { "type": "array", "items": { - "$ref": "#/components/schemas/Webhook" + "type": "object", + "properties": { + "id": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "url": { + "type": "string" + }, + "status": { + "type": "string" + }, + "last_health_check": { + "type": "integer" + } + } } } } @@ -2925,18 +3109,15 @@ }, "401": { "$ref": "#/components/responses/Unauthorized" - }, - "403": { - "$ref": "#/components/responses/Forbidden" } } }, "post": { "tags": [ - "Webhooks" + "Admin" ], - "summary": "Create webhook", - "operationId": "createWebhook", + "summary": "Add gateway", + "operationId": "addGateway", "requestBody": { "required": true, "content": { @@ -2954,16 +3135,6 @@ "url": { "type": "string", "format": "uri" - }, - "events": { - "type": "array", - "items": { - "type": "string" - } - }, - "generate_secret": { - "type": "boolean", - "default": true } } } @@ -2971,38 +3142,12 @@ } }, "responses": { - "200": { - "description": "Webhook created. Secret is only shown in full on creation.", + "201": { + "description": "Gateway added", "content": { "application/json": { "schema": { - "type": "object", - "properties": { - "id": { - "type": "integer" - }, - "name": { - "type": "string" - }, - "url": { - "type": "string" - }, - "secret": { - "type": "string" - }, - "events": { - "type": "array", - "items": { - "type": "string" - } - }, - "enabled": { - "type": "boolean" - }, - "message": { - "type": "string" - } - } + "type": "object" } } } @@ -3015,18 +3160,15 @@ }, "403": { "$ref": "#/components/responses/Forbidden" - }, - "429": { - "$ref": "#/components/responses/RateLimited" } } }, "put": { "tags": [ - "Webhooks" + "Admin" ], - "summary": "Update webhook", - "operationId": "updateWebhook", + "summary": "Update gateway", + "operationId": "updateGateway", "requestBody": { "required": true, "content": { @@ -3044,20 +3186,7 @@ "type": "string" }, "url": { - "type": "string", - "format": "uri" - }, - "events": { - "type": "array", - "items": { - "type": "string" - } - }, - "enabled": { - "type": "boolean" - }, - "regenerate_secret": { - "type": "boolean" + "type": "string" } } } @@ -3066,7 +3195,7 @@ }, "responses": { "200": { - "description": "Webhook updated", + "description": "Gateway updated", "content": { "application/json": { "schema": { @@ -3074,22 +3203,12 @@ "properties": { "success": { "type": "boolean" - }, - "secret": { - "type": "string", - "description": "Only present when regenerate_secret is true" - }, - "message": { - "type": "string" } } } } } }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, "401": { "$ref": "#/components/responses/Unauthorized" }, @@ -3098,18 +3217,15 @@ }, "404": { "$ref": "#/components/responses/NotFound" - }, - "429": { - "$ref": "#/components/responses/RateLimited" } } }, "delete": { "tags": [ - "Webhooks" + "Admin" ], - "summary": "Delete webhook", - "operationId": "deleteWebhook", + "summary": "Delete gateway", + "operationId": "deleteGateway", "requestBody": { "required": true, "content": { @@ -3130,7 +3246,7 @@ }, "responses": { "200": { - "description": "Webhook deleted", + "description": "Gateway deleted", "content": { "application/json": { "schema": { @@ -3138,90 +3254,6 @@ "properties": { "success": { "type": "boolean" - }, - "deleted": { - "type": "integer" - } - } - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "401": { - "$ref": "#/components/responses/Unauthorized" - }, - "403": { - "$ref": "#/components/responses/Forbidden" - }, - "404": { - "$ref": "#/components/responses/NotFound" - }, - "429": { - "$ref": "#/components/responses/RateLimited" - } - } - } - }, - "/api/webhooks/deliveries": { - "get": { - "tags": [ - "Webhooks" - ], - "summary": "Get webhook delivery history", - "operationId": "getWebhookDeliveries", - "parameters": [ - { - "name": "webhook_id", - "in": "query", - "schema": { - "type": "integer" - } - }, - { - "name": "limit", - "in": "query", - "schema": { - "type": "integer", - "default": 50 - } - } - ], - "responses": { - "200": { - "description": "Delivery history", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "deliveries": { - "type": "array", - "items": { - "type": "object", - "properties": { - "id": { - "type": "integer" - }, - "webhook_id": { - "type": "integer" - }, - "event": { - "type": "string" - }, - "status_code": { - "type": "integer" - }, - "error": { - "type": "string" - }, - "created_at": { - "type": "integer" - } - } - } } } } @@ -3237,24 +3269,20 @@ } } }, - "/api/webhooks/test": { + "/api/gateways/health": { "post": { "tags": [ - "Webhooks" + "Admin" ], - "summary": "Test webhook", - "operationId": "testWebhook", + "summary": "Probe gateway health", + "operationId": "probeGatewayHealth", "requestBody": { - "required": true, "content": { "application/json": { "schema": { "type": "object", - "required": [ - "id" - ], "properties": { - "id": { + "gateway_id": { "type": "integer" } } @@ -3264,20 +3292,20 @@ }, "responses": { "200": { - "description": "Test result", + "description": "Health check results", "content": { "application/json": { "schema": { "type": "object", "properties": { - "success": { + "healthy": { "type": "boolean" }, - "status_code": { - "type": "integer" - }, - "response_time_ms": { + "latency_ms": { "type": "number" + }, + "details": { + "type": "object" } } } @@ -3289,32 +3317,72 @@ }, "403": { "$ref": "#/components/responses/Forbidden" - }, - "404": { - "$ref": "#/components/responses/NotFound" } } } }, - "/api/alerts": { + "/api/github": { "get": { "tags": [ - "Alerts" + "Admin" ], - "summary": "List alert rules", - "operationId": "listAlertRules", + "summary": "Get GitHub integration status", + "operationId": "getGithubStatus", + "responses": { + "200": { + "description": "GitHub integration status" + } + } + }, + "post": { + "tags": [ + "Admin" + ], + "summary": "Sync GitHub issues", + "operationId": "syncGithubIssues", + "responses": { + "200": { + "description": "Sync result" + } + } + } + }, + "/api/integrations": { + "get": { + "tags": [ + "Admin" + ], + "summary": "List integrations", + "operationId": "listIntegrations", "responses": { "200": { - "description": "Alert rule list", + "description": "Integration list", "content": { "application/json": { "schema": { "type": "object", "properties": { - "rules": { + "integrations": { "type": "array", "items": { - "$ref": "#/components/schemas/AlertRule" + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "type": { + "type": "string" + }, + "enabled": { + "type": "boolean" + }, + "config": { + "type": "object" + } + } } } } @@ -3329,136 +3397,122 @@ }, "post": { "tags": [ - "Alerts" + "Admin" ], - "summary": "Create alert rule or evaluate rules", - "operationId": "createAlertRule", + "summary": "Integration actions (enable, disable, test, configure)", + "operationId": "integrationAction", "requestBody": { "required": true, "content": { "application/json": { "schema": { - "oneOf": [ - { - "type": "object", - "title": "CreateRule", - "required": [ - "name", - "entity_type", - "condition_field", - "condition_operator", - "condition_value" - ], - "properties": { - "name": { - "type": "string" - }, - "description": { - "type": "string" - }, - "entity_type": { - "type": "string", - "enum": [ - "agent", - "task", - "session", - "activity" - ] - }, - "condition_field": { - "type": "string" - }, - "condition_operator": { - "type": "string", - "enum": [ - "equals", - "not_equals", - "greater_than", - "less_than", - "contains", - "count_above", - "count_below", - "age_minutes_above" - ] - }, - "condition_value": { - "type": "string" - }, - "action_type": { - "type": "string", - "default": "notification" - }, - "action_config": { - "type": "object" - }, - "cooldown_minutes": { - "type": "integer", - "default": 60 - } - } + "type": "object", + "required": [ + "action", + "id" + ], + "properties": { + "action": { + "type": "string", + "enum": [ + "enable", + "disable", + "test", + "configure" + ] }, - { - "type": "object", - "title": "EvaluateRules", - "required": [ - "action" - ], - "properties": { - "action": { - "type": "string", - "const": "evaluate" - } - } + "id": { + "type": "string" + }, + "config": { + "type": "object" } - ] + } } } } }, "responses": { - "201": { - "description": "Rule created", + "200": { + "description": "Action applied", "content": { "application/json": { "schema": { "type": "object", "properties": { - "rule": { - "$ref": "#/components/schemas/AlertRule" + "success": { + "type": "boolean" } } } } } }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "403": { + "$ref": "#/components/responses/Forbidden" + } + } + } + }, + "/api/logs": { + "get": { + "tags": [ + "Monitoring" + ], + "summary": "Get system logs", + "operationId": "getSystemLogs", + "parameters": [ + { + "name": "level", + "in": "query", + "schema": { + "type": "string", + "enum": [ + "info", + "warn", + "error", + "debug" + ] + } + }, + { + "name": "limit", + "in": "query", + "schema": { + "type": "integer", + "default": 100 + } + } + ], + "responses": { "200": { - "description": "Rules evaluated", + "description": "Log entries", "content": { "application/json": { "schema": { "type": "object", "properties": { - "evaluated": { - "type": "integer" - }, - "triggered": { - "type": "integer" - }, - "results": { + "logs": { "type": "array", "items": { "type": "object", "properties": { - "rule_id": { - "type": "integer" + "timestamp": { + "type": "string" }, - "rule_name": { + "level": { "type": "string" }, - "triggered": { - "type": "boolean" + "message": { + "type": "string" }, - "reason": { + "source": { "type": "string" } } @@ -3469,113 +3523,53 @@ } } }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { - "$ref": "#/components/responses/Forbidden" - }, - "429": { - "$ref": "#/components/responses/RateLimited" - } - } - }, - "put": { - "tags": [ - "Alerts" - ], - "summary": "Update alert rule", - "operationId": "updateAlertRule", - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "type": "object", - "required": [ - "id" - ], - "properties": { - "id": { - "type": "integer" - }, - "name": { - "type": "string" - }, - "description": { - "type": "string" - }, - "enabled": { - "type": "boolean" - }, - "entity_type": { - "type": "string" - }, - "condition_field": { - "type": "string" - }, - "condition_operator": { - "type": "string" - }, - "condition_value": { - "type": "string" - }, - "action_type": { - "type": "string" - }, - "action_config": { - "type": "object" - }, - "cooldown_minutes": { - "type": "integer" - } - } - } + "$ref": "#/components/responses/Forbidden" + } + } + } + }, + "/api/memory": { + "get": { + "tags": [ + "Admin" + ], + "summary": "Get memory files", + "operationId": "getMemoryFiles", + "parameters": [ + { + "name": "path", + "in": "query", + "schema": { + "type": "string" } } - }, + ], "responses": { "200": { - "description": "Rule updated", + "description": "Memory file contents", "content": { "application/json": { "schema": { - "type": "object", - "properties": { - "rule": { - "$ref": "#/components/schemas/AlertRule" - } - } + "type": "object" } } } }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, "401": { "$ref": "#/components/responses/Unauthorized" - }, - "403": { - "$ref": "#/components/responses/Forbidden" - }, - "404": { - "$ref": "#/components/responses/NotFound" - }, - "429": { - "$ref": "#/components/responses/RateLimited" } } }, - "delete": { + "post": { "tags": [ - "Alerts" + "Admin" ], - "summary": "Delete alert rule", - "operationId": "deleteAlertRule", + "summary": "Update memory file", + "operationId": "updateMemoryFile", "requestBody": { "required": true, "content": { @@ -3583,11 +3577,15 @@ "schema": { "type": "object", "required": [ - "id" + "path", + "content" ], "properties": { - "id": { - "type": "integer" + "path": { + "type": "string" + }, + "content": { + "type": "string" } } } @@ -3596,13 +3594,13 @@ }, "responses": { "200": { - "description": "Rule deleted", + "description": "Memory updated", "content": { "application/json": { "schema": { "type": "object", "properties": { - "deleted": { + "success": { "type": "boolean" } } @@ -3610,37 +3608,100 @@ } } }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" + } + } + } + }, + "/api/mentions": { + "get": { + "tags": [ + "Mentions" + ], + "summary": "Get mention autocomplete targets", + "operationId": "getMentionTargets", + "parameters": [ + { + "name": "q", + "in": "query", + "schema": { + "type": "string" + }, + "description": "Search query" }, - "429": { - "$ref": "#/components/responses/RateLimited" + { + "name": "type", + "in": "query", + "schema": { + "type": "string", + "enum": [ + "user", + "agent" + ] + }, + "description": "Filter by type" + }, + { + "name": "limit", + "in": "query", + "schema": { + "type": "integer", + "default": 20 + }, + "description": "Max results" + } + ], + "responses": { + "200": { + "description": "Mention targets list" } } } }, - "/api/workflows": { + "/api/notifications": { "get": { "tags": [ - "Workflows" + "Monitoring" + ], + "summary": "List notifications", + "operationId": "listNotifications", + "parameters": [ + { + "name": "recipient", + "in": "query", + "schema": { + "type": "string" + } + }, + { + "name": "unread", + "in": "query", + "schema": { + "type": "boolean" + } + }, + { + "name": "limit", + "in": "query", + "schema": { + "type": "integer", + "default": 50 + } + } ], - "summary": "List workflow templates", - "operationId": "listWorkflows", "responses": { "200": { - "description": "Workflow template list", + "description": "Notification list", "content": { "application/json": { "schema": { "type": "object", "properties": { - "templates": { + "notifications": { "type": "array", "items": { "type": "object", @@ -3648,28 +3709,28 @@ "id": { "type": "integer" }, - "name": { + "recipient": { "type": "string" }, - "description": { + "type": { "type": "string" }, - "steps": { - "type": "array", - "items": { - "type": "object" - } + "title": { + "type": "string" }, - "created_by": { + "message": { "type": "string" }, - "use_count": { - "type": "integer" + "read": { + "type": "boolean" }, - "created_at": { + "source_type": { + "type": "string" + }, + "source_id": { "type": "integer" }, - "updated_at": { + "created_at": { "type": "integer" } } @@ -3687,85 +3748,10 @@ }, "post": { "tags": [ - "Workflows" - ], - "summary": "Create workflow template", - "operationId": "createWorkflow", - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "type": "object", - "required": [ - "name", - "steps" - ], - "properties": { - "name": { - "type": "string" - }, - "description": { - "type": "string" - }, - "steps": { - "type": "array", - "items": { - "type": "object", - "properties": { - "agent": { - "type": "string" - }, - "action": { - "type": "string" - }, - "params": { - "type": "object" - } - } - } - } - } - } - } - } - }, - "responses": { - "201": { - "description": "Template created", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "template": { - "type": "object" - } - } - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "401": { - "$ref": "#/components/responses/Unauthorized" - }, - "403": { - "$ref": "#/components/responses/Forbidden" - }, - "429": { - "$ref": "#/components/responses/RateLimited" - } - } - }, - "put": { - "tags": [ - "Workflows" + "Monitoring" ], - "summary": "Update workflow template", - "operationId": "updateWorkflow", + "summary": "Notification actions (mark read, dismiss)", + "operationId": "notificationAction", "requestBody": { "required": true, "content": { @@ -3773,23 +3759,22 @@ "schema": { "type": "object", "required": [ - "id" + "action" ], "properties": { - "id": { - "type": "integer" + "action": { + "type": "string", + "enum": [ + "mark_read", + "mark_all_read", + "dismiss" + ] }, - "name": { - "type": "string" + "id": { + "type": "integer" }, - "description": { + "recipient": { "type": "string" - }, - "steps": { - "type": "array", - "items": { - "type": "object" - } } } } @@ -3798,14 +3783,14 @@ }, "responses": { "200": { - "description": "Template updated", + "description": "Action applied", "content": { "application/json": { "schema": { "type": "object", "properties": { - "template": { - "type": "object" + "success": { + "type": "boolean" } } } @@ -3815,6 +3800,120 @@ "400": { "$ref": "#/components/responses/BadRequest" }, + "401": { + "$ref": "#/components/responses/Unauthorized" + } + } + } + }, + "/api/agents/{id}/diagnostics": { + "get": { + "tags": [ + "Agents" + ], + "summary": "Get self diagnostics for an agent", + "description": "Self-scoped diagnostics by default. Cross-agent access requires `privileged=1` with admin credentials. Trend alerts are informational signals derived from current-vs-previous window deltas (error spikes, throughput drops, activity stalls).", + "operationId": "getAgentDiagnostics", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string" + }, + "description": "Agent numeric ID or name." + }, + { + "name": "hours", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "minimum": 1, + "maximum": 720, + "default": 24 + }, + "description": "Diagnostics window in hours." + }, + { + "name": "section", + "in": "query", + "required": false, + "schema": { + "type": "string" + }, + "description": "Comma-separated sections: summary,tasks,errors,activity,trends,tokens." + }, + { + "name": "privileged", + "in": "query", + "required": false, + "schema": { + "type": "string", + "enum": [ + "1" + ] + }, + "description": "Set to `1` to allow explicit admin cross-agent diagnostics access." + } + ], + "responses": { + "200": { + "description": "Diagnostics payload", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "agent": { + "type": "object", + "properties": { + "id": { "type": "integer" }, + "name": { "type": "string" }, + "role": { "type": "string" }, + "status": { "type": "string" } + } + }, + "timeframe": { + "type": "object", + "properties": { + "hours": { "type": "integer" }, + "since": { "type": "integer" }, + "until": { "type": "integer" } + } + }, + "summary": { "type": "object" }, + "tasks": { "type": "object" }, + "errors": { "type": "object" }, + "activity": { "type": "object" }, + "trends": { + "type": "object", + "properties": { + "current_period": { "type": "object" }, + "previous_period": { "type": "object" }, + "change": { "type": "object" }, + "alerts": { + "type": "array", + "items": { + "type": "object", + "properties": { + "level": { "type": "string", "enum": ["info", "warning"] }, + "message": { "type": "string" } + } + } + } + } + }, + "tokens": { "type": "object" } + } + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, "401": { "$ref": "#/components/responses/Unauthorized" }, @@ -3825,13 +3924,15 @@ "$ref": "#/components/responses/NotFound" } } - }, - "delete": { + } + }, + "/api/notifications/deliver": { + "post": { "tags": [ - "Workflows" + "Monitoring" ], - "summary": "Delete workflow template", - "operationId": "deleteWorkflow", + "summary": "Deliver notification to agent", + "operationId": "deliverNotification", "requestBody": { "required": true, "content": { @@ -3839,11 +3940,22 @@ "schema": { "type": "object", "required": [ - "id" + "agent", + "title", + "message" ], "properties": { - "id": { - "type": "integer" + "agent": { + "type": "string" + }, + "title": { + "type": "string" + }, + "message": { + "type": "string" + }, + "type": { + "type": "string" } } } @@ -3852,7 +3964,7 @@ }, "responses": { "200": { - "description": "Template deleted", + "description": "Notification delivered", "content": { "application/json": { "schema": { @@ -3866,14 +3978,14 @@ } } }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" - }, - "404": { - "$ref": "#/components/responses/NotFound" } } } @@ -4044,18 +4156,137 @@ }, "403": { "$ref": "#/components/responses/Forbidden" - }, - "429": { - "$ref": "#/components/responses/RateLimited" + }, + "429": { + "$ref": "#/components/responses/RateLimited" + } + } + }, + "put": { + "tags": [ + "Pipelines" + ], + "summary": "Update pipeline", + "operationId": "updatePipeline", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "id" + ], + "properties": { + "id": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "description": { + "type": "string" + }, + "steps": { + "type": "array", + "items": { + "type": "object" + } + } + } + } + } + } + }, + "responses": { + "200": { + "description": "Pipeline updated", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "pipeline": { + "type": "object" + } + } + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "403": { + "$ref": "#/components/responses/Forbidden" + }, + "404": { + "$ref": "#/components/responses/NotFound" + } + } + }, + "delete": { + "tags": [ + "Pipelines" + ], + "summary": "Delete pipeline", + "operationId": "deletePipeline", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "id" + ], + "properties": { + "id": { + "type": "integer" + } + } + } + } + } + }, + "responses": { + "200": { + "description": "Pipeline deleted", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { + "type": "boolean" + } + } + } + } + } + }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "403": { + "$ref": "#/components/responses/Forbidden" } } - }, - "put": { + } + }, + "/api/pipelines/run": { + "post": { "tags": [ "Pipelines" ], - "summary": "Update pipeline", - "operationId": "updatePipeline", + "summary": "Run a pipeline", + "operationId": "runPipeline", "requestBody": { "required": true, "content": { @@ -4063,23 +4294,14 @@ "schema": { "type": "object", "required": [ - "id" + "pipeline_id" ], "properties": { - "id": { + "pipeline_id": { "type": "integer" }, - "name": { - "type": "string" - }, - "description": { - "type": "string" - }, - "steps": { - "type": "array", - "items": { - "type": "object" - } + "params": { + "type": "object" } } } @@ -4088,14 +4310,17 @@ }, "responses": { "200": { - "description": "Pipeline updated", + "description": "Pipeline run started", "content": { "application/json": { "schema": { "type": "object", "properties": { - "pipeline": { - "type": "object" + "run_id": { + "type": "integer" + }, + "status": { + "type": "string" } } } @@ -4115,13 +4340,193 @@ "$ref": "#/components/responses/NotFound" } } + } + }, + "/api/projects": { + "get": { + "tags": [ + "Projects" + ], + "summary": "List all projects", + "operationId": "listProjects", + "responses": { + "200": { + "description": "Project list" + } + } + }, + "post": { + "tags": [ + "Projects" + ], + "summary": "Create a new project", + "operationId": "createProject", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "name" + ], + "properties": { + "name": { + "type": "string" + }, + "description": { + "type": "string" + } + } + } + } + } + }, + "responses": { + "201": { + "description": "Project created" + } + } + } + }, + "/api/projects/{id}": { + "get": { + "tags": [ + "Projects" + ], + "summary": "Get project by ID", + "operationId": "getProject", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "description": "Project details" + } + } + }, + "patch": { + "tags": [ + "Projects" + ], + "summary": "Update a project", + "operationId": "updateProject", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "description": { + "type": "string" + } + } + } + } + } + }, + "responses": { + "200": { + "description": "Updated" + } + } }, "delete": { "tags": [ - "Pipelines" + "Projects" ], - "summary": "Delete pipeline", - "operationId": "deletePipeline", + "summary": "Delete a project", + "operationId": "deleteProject", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "description": "Deleted" + } + } + } + }, + "/api/projects/{id}/tasks": { + "get": { + "tags": [ + "Projects" + ], + "summary": "List tasks in a project", + "operationId": "listProjectTasks", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "description": "Tasks in project" + } + } + } + }, + "/api/quality-review": { + "get": { + "tags": [ + "Quality" + ], + "summary": "List quality reviews", + "operationId": "listQualityReviews", + "parameters": [ + { + "name": "task_id", + "in": "query", + "schema": { + "type": "integer" + }, + "description": "Filter by task" + } + ], + "responses": { + "200": { + "description": "Quality review list" + } + } + }, + "post": { + "tags": [ + "Quality" + ], + "summary": "Submit a quality review", + "operationId": "submitQualityReview", "requestBody": { "required": true, "content": { @@ -4129,11 +4534,22 @@ "schema": { "type": "object", "required": [ - "id" + "task_id", + "status" ], "properties": { - "id": { + "task_id": { "type": "integer" + }, + "status": { + "type": "string", + "enum": [ + "approved", + "rejected" + ] + }, + "notes": { + "type": "string" } } } @@ -4142,23 +4558,69 @@ }, "responses": { "200": { - "description": "Pipeline deleted", + "description": "Review submitted" + } + } + } + }, + "/api/releases/check": { + "get": { + "tags": [ + "Releases" + ], + "summary": "Check for new releases", + "operationId": "checkReleases", + "security": [], + "responses": { + "200": { + "description": "Release info with version comparison" + } + } + } + }, + "/api/scheduler": { + "get": { + "tags": [ + "Admin" + ], + "summary": "Get scheduler status", + "operationId": "getSchedulerStatus", + "responses": { + "200": { + "description": "Scheduler status and registered tasks", "content": { "application/json": { "schema": { "type": "object", "properties": { - "success": { + "running": { "type": "boolean" + }, + "tasks": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "interval": { + "type": "string" + }, + "last_run": { + "type": "integer" + }, + "next_run": { + "type": "integer" + } + } + } } } } } } }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, "401": { "$ref": "#/components/responses/Unauthorized" }, @@ -4166,15 +4628,13 @@ "$ref": "#/components/responses/Forbidden" } } - } - }, - "/api/pipelines/run": { + }, "post": { "tags": [ - "Pipelines" + "Admin" ], - "summary": "Run a pipeline", - "operationId": "runPipeline", + "summary": "Trigger scheduled task", + "operationId": "triggerScheduledTask", "requestBody": { "required": true, "content": { @@ -4182,14 +4642,11 @@ "schema": { "type": "object", "required": [ - "pipeline_id" + "task" ], "properties": { - "pipeline_id": { - "type": "integer" - }, - "params": { - "type": "object" + "task": { + "type": "string" } } } @@ -4198,17 +4655,17 @@ }, "responses": { "200": { - "description": "Pipeline run started", + "description": "Task triggered", "content": { "application/json": { "schema": { "type": "object", "properties": { - "run_id": { - "type": "integer" + "success": { + "type": "boolean" }, - "status": { - "type": "string" + "result": { + "type": "object" } } } @@ -4223,40 +4680,37 @@ }, "403": { "$ref": "#/components/responses/Forbidden" - }, - "404": { - "$ref": "#/components/responses/NotFound" } } } }, - "/api/activities": { + "/api/search": { "get": { "tags": [ - "Monitoring" + "Admin" ], - "summary": "List activities", - "operationId": "listActivities", + "summary": "Full-text search", + "operationId": "search", "parameters": [ { - "name": "type", - "in": "query", - "schema": { - "type": "string" - } - }, - { - "name": "actor", + "name": "q", "in": "query", + "required": true, "schema": { "type": "string" } }, { - "name": "entity_type", + "name": "type", "in": "query", "schema": { - "type": "string" + "type": "string", + "enum": [ + "tasks", + "agents", + "activities", + "all" + ] } }, { @@ -4264,54 +4718,37 @@ "in": "query", "schema": { "type": "integer", - "default": 50 - } - }, - { - "name": "offset", - "in": "query", - "schema": { - "type": "integer", - "default": 0 + "default": 20 } } ], "responses": { "200": { - "description": "Activity list", + "description": "Search results", "content": { "application/json": { "schema": { "type": "object", "properties": { - "activities": { + "results": { "type": "array", "items": { "type": "object", "properties": { - "id": { - "type": "integer" - }, "type": { "type": "string" }, - "entity_type": { - "type": "string" - }, - "entity_id": { + "id": { "type": "integer" }, - "actor": { + "title": { "type": "string" }, - "description": { + "snippet": { "type": "string" }, - "metadata": { - "type": "object" - }, - "created_at": { - "type": "integer" + "score": { + "type": "number" } } } @@ -4324,29 +4761,25 @@ } } }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, "401": { "$ref": "#/components/responses/Unauthorized" } } } }, - "/api/audit": { + "/api/sessions": { "get": { "tags": [ - "Monitoring" + "Sessions" ], - "summary": "Get audit log", - "operationId": "getAuditLog", + "summary": "List gateway sessions", + "operationId": "listSessions", "parameters": [ { - "name": "action", - "in": "query", - "schema": { - "type": "string" - } - }, - { - "name": "actor", + "name": "agent", "in": "query", "schema": { "type": "string" @@ -4357,60 +4790,43 @@ "in": "query", "schema": { "type": "integer", - "default": 100 - } - }, - { - "name": "offset", - "in": "query", - "schema": { - "type": "integer", - "default": 0 + "default": 50 } } ], "responses": { "200": { - "description": "Audit log entries", + "description": "Session list", "content": { "application/json": { "schema": { "type": "object", "properties": { - "entries": { + "sessions": { "type": "array", "items": { "type": "object", "properties": { - "id": { - "type": "integer" + "key": { + "type": "string" }, - "action": { + "agent": { "type": "string" }, - "actor": { + "model": { "type": "string" }, - "target_type": { + "status": { "type": "string" }, - "target_id": { + "totalTokens": { "type": "integer" }, - "detail": { - "type": "object" - }, - "ip_address": { - "type": "string" - }, - "created_at": { + "updatedAt": { "type": "integer" } } } - }, - "total": { - "type": "integer" } } } @@ -4419,158 +4835,98 @@ }, "401": { "$ref": "#/components/responses/Unauthorized" - }, - "403": { - "$ref": "#/components/responses/Forbidden" } } } }, - "/api/logs": { - "get": { + "/api/sessions/{id}/control": { + "post": { "tags": [ - "Monitoring" + "Sessions" ], - "summary": "Get system logs", - "operationId": "getSystemLogs", + "summary": "Control session (pause/resume/kill)", + "operationId": "controlSession", "parameters": [ { - "name": "level", - "in": "query", - "schema": { - "type": "string", - "enum": [ - "info", - "warn", - "error", - "debug" - ] - } - }, - { - "name": "limit", - "in": "query", + "name": "id", + "in": "path", + "required": true, "schema": { - "type": "integer", - "default": 100 + "type": "string" } } ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "action" + ], + "properties": { + "action": { + "type": "string", + "enum": [ + "pause", + "resume", + "kill" + ] + } + } + } + } + } + }, "responses": { "200": { - "description": "Log entries", + "description": "Action applied", "content": { "application/json": { "schema": { "type": "object", "properties": { - "logs": { - "type": "array", - "items": { - "type": "object", - "properties": { - "timestamp": { - "type": "string" - }, - "level": { - "type": "string" - }, - "message": { - "type": "string" - }, - "source": { - "type": "string" - } - } - } + "success": { + "type": "boolean" } - } - } - } - } - }, - "401": { - "$ref": "#/components/responses/Unauthorized" - }, - "403": { - "$ref": "#/components/responses/Forbidden" - } - } - } - }, - "/api/notifications": { - "get": { - "tags": [ - "Monitoring" - ], - "summary": "List notifications", - "operationId": "listNotifications", - "parameters": [ - { - "name": "recipient", - "in": "query", - "schema": { - "type": "string" - } - }, - { - "name": "unread", - "in": "query", - "schema": { - "type": "boolean" + } + } + } } }, - { - "name": "limit", - "in": "query", - "schema": { - "type": "integer", - "default": 50 - } + "400": { + "$ref": "#/components/responses/BadRequest" + }, + "401": { + "$ref": "#/components/responses/Unauthorized" + }, + "403": { + "$ref": "#/components/responses/Forbidden" + }, + "404": { + "$ref": "#/components/responses/NotFound" } + } + } + }, + "/api/settings": { + "get": { + "tags": [ + "Admin" ], + "summary": "Get application settings", + "operationId": "getSettings", "responses": { "200": { - "description": "Notification list", + "description": "Current settings", "content": { "application/json": { "schema": { "type": "object", "properties": { - "notifications": { - "type": "array", - "items": { - "type": "object", - "properties": { - "id": { - "type": "integer" - }, - "recipient": { - "type": "string" - }, - "type": { - "type": "string" - }, - "title": { - "type": "string" - }, - "message": { - "type": "string" - }, - "read": { - "type": "boolean" - }, - "source_type": { - "type": "string" - }, - "source_id": { - "type": "integer" - }, - "created_at": { - "type": "integer" - } - } - } + "settings": { + "type": "object" } } } @@ -4579,47 +4935,31 @@ }, "401": { "$ref": "#/components/responses/Unauthorized" + }, + "403": { + "$ref": "#/components/responses/Forbidden" } } }, "post": { "tags": [ - "Monitoring" + "Admin" ], - "summary": "Notification actions (mark read, dismiss)", - "operationId": "notificationAction", + "summary": "Update settings", + "operationId": "updateSettings", "requestBody": { "required": true, "content": { "application/json": { "schema": { - "type": "object", - "required": [ - "action" - ], - "properties": { - "action": { - "type": "string", - "enum": [ - "mark_read", - "mark_all_read", - "dismiss" - ] - }, - "id": { - "type": "integer" - }, - "recipient": { - "type": "string" - } - } + "type": "object" } } } }, "responses": { "200": { - "description": "Action applied", + "description": "Settings updated", "content": { "application/json": { "schema": { @@ -4633,22 +4973,22 @@ } } }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, "401": { "$ref": "#/components/responses/Unauthorized" + }, + "403": { + "$ref": "#/components/responses/Forbidden" } } } }, - "/api/notifications/deliver": { + "/api/spawn": { "post": { "tags": [ - "Monitoring" + "Admin" ], - "summary": "Deliver notification to agent", - "operationId": "deliverNotification", + "summary": "Spawn agent process", + "operationId": "spawnAgent", "requestBody": { "required": true, "content": { @@ -4656,22 +4996,17 @@ "schema": { "type": "object", "required": [ - "agent", - "title", - "message" + "agent" ], "properties": { "agent": { "type": "string" }, - "title": { - "type": "string" - }, - "message": { + "task": { "type": "string" }, - "type": { - "type": "string" + "params": { + "type": "object" } } } @@ -4680,7 +5015,7 @@ }, "responses": { "200": { - "description": "Notification delivered", + "description": "Agent spawned", "content": { "application/json": { "schema": { @@ -4688,6 +5023,9 @@ "properties": { "success": { "type": "boolean" + }, + "session_id": { + "type": "string" } } } @@ -4706,20 +5044,53 @@ } } }, - "/api/events": { + "/api/standup": { "get": { "tags": [ - "Monitoring" + "Admin" + ], + "summary": "Get standup report", + "operationId": "getStandupReport", + "parameters": [ + { + "name": "date", + "in": "query", + "schema": { + "type": "string", + "format": "date" + } + } ], - "summary": "SSE stream for real-time events", - "operationId": "getEventStream", "responses": { "200": { - "description": "Server-Sent Events stream", + "description": "Standup report", "content": { - "text/event-stream": { + "application/json": { "schema": { - "type": "string" + "type": "object", + "properties": { + "date": { + "type": "string" + }, + "agents": { + "type": "array", + "items": { + "type": "object" + } + }, + "tasks_completed": { + "type": "integer" + }, + "tasks_in_progress": { + "type": "integer" + }, + "highlights": { + "type": "array", + "items": { + "type": "string" + } + } + } } } } @@ -4770,131 +5141,71 @@ "type": "integer" } } - }, - "tasks": { - "type": "object", - "properties": { - "total": { - "type": "integer" - }, - "in_progress": { - "type": "integer" - } - } - } - } - } - } - } - } - } - } - }, - "/api/settings": { - "get": { - "tags": [ - "Admin" - ], - "summary": "Get application settings", - "operationId": "getSettings", - "responses": { - "200": { - "description": "Current settings", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "settings": { - "type": "object" - } - } - } - } - } - }, - "401": { - "$ref": "#/components/responses/Unauthorized" - }, - "403": { - "$ref": "#/components/responses/Forbidden" - } - } - }, - "post": { - "tags": [ - "Admin" - ], - "summary": "Update settings", - "operationId": "updateSettings", - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "type": "object" - } - } - } - }, - "responses": { - "200": { - "description": "Settings updated", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean" + }, + "tasks": { + "type": "object", + "properties": { + "total": { + "type": "integer" + }, + "in_progress": { + "type": "integer" + } + } } } } } } - }, - "401": { - "$ref": "#/components/responses/Unauthorized" - }, - "403": { - "$ref": "#/components/responses/Forbidden" } } } }, - "/api/scheduler": { + "/api/super/provision-jobs": { "get": { "tags": [ - "Admin" + "Super Admin" ], - "summary": "Get scheduler status", - "operationId": "getSchedulerStatus", + "summary": "List provision jobs", + "operationId": "listProvisionJobs", "responses": { "200": { - "description": "Scheduler status and registered tasks", + "description": "Provision job list", "content": { "application/json": { "schema": { "type": "object", "properties": { - "running": { - "type": "boolean" - }, - "tasks": { + "jobs": { "type": "array", "items": { "type": "object", "properties": { - "name": { + "id": { + "type": "integer" + }, + "tenant_id": { + "type": "integer" + }, + "type": { "type": "string" }, - "interval": { + "status": { + "type": "string", + "enum": [ + "pending", + "running", + "completed", + "failed" + ] + }, + "output": { "type": "string" }, - "last_run": { + "created_at": { "type": "integer" }, - "next_run": { + "completed_at": { "type": "integer" } } @@ -4915,10 +5226,10 @@ }, "post": { "tags": [ - "Admin" + "Super Admin" ], - "summary": "Trigger scheduled task", - "operationId": "triggerScheduledTask", + "summary": "Create provision job", + "operationId": "createProvisionJob", "requestBody": { "required": true, "content": { @@ -4926,11 +5237,18 @@ "schema": { "type": "object", "required": [ - "task" + "tenant_id", + "type" ], "properties": { - "task": { + "tenant_id": { + "type": "integer" + }, + "type": { "type": "string" + }, + "params": { + "type": "object" } } } @@ -4938,20 +5256,12 @@ } }, "responses": { - "200": { - "description": "Task triggered", + "201": { + "description": "Job created", "content": { "application/json": { "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean" - }, - "result": { - "type": "object" - } - } + "type": "object" } } } @@ -4968,59 +5278,30 @@ } } }, - "/api/cron": { + "/api/super/provision-jobs/{id}": { "get": { "tags": [ - "Admin" + "Super Admin" ], - "summary": "Get cron jobs", - "operationId": "getCronJobs", + "summary": "Get provision job details", + "operationId": "getProvisionJob", "parameters": [ { - "name": "action", - "in": "query", + "name": "id", + "in": "path", + "required": true, "schema": { - "type": "string", - "enum": [ - "list", - "logs" - ], - "default": "list" + "type": "integer" } } ], "responses": { "200": { - "description": "Cron job list or logs", + "description": "Job details", "content": { "application/json": { "schema": { - "type": "object", - "properties": { - "jobs": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "schedule": { - "type": "string" - }, - "enabled": { - "type": "boolean" - }, - "last_run": { - "type": "integer" - }, - "last_status": { - "type": "string" - } - } - } - } - } + "type": "object" } } } @@ -5030,54 +5311,33 @@ }, "403": { "$ref": "#/components/responses/Forbidden" + }, + "404": { + "$ref": "#/components/responses/NotFound" } } - }, + } + }, + "/api/super/provision-jobs/{id}/run": { "post": { "tags": [ - "Admin" + "Super Admin" ], - "summary": "Manage cron jobs", - "operationId": "manageCronJobs", - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "type": "object", - "required": [ - "action" - ], - "properties": { - "action": { - "type": "string", - "enum": [ - "toggle", - "trigger", - "add", - "remove" - ] - }, - "name": { - "type": "string" - }, - "schedule": { - "type": "string" - }, - "command": { - "type": "string" - }, - "enabled": { - "type": "boolean" - } - } - } + "summary": "Run provision job", + "operationId": "runProvisionJob", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "integer" } } - }, + ], "responses": { "200": { - "description": "Action applied", + "description": "Job started", "content": { "application/json": { "schema": { @@ -5085,40 +5345,43 @@ "properties": { "success": { "type": "boolean" + }, + "status": { + "type": "string" } } } } } }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" + }, + "404": { + "$ref": "#/components/responses/NotFound" } } } }, - "/api/gateways": { + "/api/super/tenants": { "get": { "tags": [ - "Admin" + "Super Admin" ], - "summary": "List gateways", - "operationId": "listGateways", + "summary": "List tenants", + "operationId": "listTenants", "responses": { "200": { - "description": "Gateway list", + "description": "Tenant list", "content": { "application/json": { "schema": { "type": "object", "properties": { - "gateways": { + "tenants": { "type": "array", "items": { "type": "object", @@ -5126,16 +5389,19 @@ "id": { "type": "integer" }, - "name": { + "slug": { "type": "string" }, - "url": { + "name": { "type": "string" }, "status": { "type": "string" }, - "last_health_check": { + "linux_user": { + "type": "string" + }, + "created_at": { "type": "integer" } } @@ -5148,15 +5414,18 @@ }, "401": { "$ref": "#/components/responses/Unauthorized" + }, + "403": { + "$ref": "#/components/responses/Forbidden" } } }, "post": { "tags": [ - "Admin" + "Super Admin" ], - "summary": "Add gateway", - "operationId": "addGateway", + "summary": "Create tenant and bootstrap job", + "operationId": "createTenant", "requestBody": { "required": true, "content": { @@ -5164,16 +5433,21 @@ "schema": { "type": "object", "required": [ - "name", - "url" + "slug", + "name" ], "properties": { + "slug": { + "type": "string" + }, "name": { "type": "string" }, - "url": { - "type": "string", - "format": "uri" + "linux_user": { + "type": "string" + }, + "config": { + "type": "object" } } } @@ -5182,7 +5456,7 @@ }, "responses": { "201": { - "description": "Gateway added", + "description": "Tenant created with bootstrap job", "content": { "application/json": { "schema": { @@ -5199,42 +5473,40 @@ }, "403": { "$ref": "#/components/responses/Forbidden" + }, + "409": { + "description": "Tenant slug or linux user already exists", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } } } - }, - "put": { + } + }, + "/api/super/tenants/{id}/decommission": { + "post": { "tags": [ - "Admin" + "Super Admin" ], - "summary": "Update gateway", - "operationId": "updateGateway", - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "type": "object", - "required": [ - "id" - ], - "properties": { - "id": { - "type": "integer" - }, - "name": { - "type": "string" - }, - "url": { - "type": "string" - } - } - } + "summary": "Decommission tenant", + "operationId": "decommissionTenant", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "integer" } } - }, + ], "responses": { "200": { - "description": "Gateway updated", + "description": "Tenant decommissioned", "content": { "application/json": { "schema": { @@ -5258,41 +5530,90 @@ "$ref": "#/components/responses/NotFound" } } - }, - "delete": { + } + }, + "/api/tasks": { + "get": { "tags": [ - "Admin" + "Tasks" ], - "summary": "Delete gateway", - "operationId": "deleteGateway", - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "type": "object", - "required": [ - "id" - ], - "properties": { - "id": { - "type": "integer" - } - } - } + "summary": "List tasks", + "operationId": "listTasks", + "parameters": [ + { + "name": "status", + "in": "query", + "schema": { + "type": "string", + "enum": [ + "inbox", + "assigned", + "in_progress", + "quality_review", + "done" + ] + } + }, + { + "name": "assigned_to", + "in": "query", + "schema": { + "type": "string" + } + }, + { + "name": "priority", + "in": "query", + "schema": { + "type": "string", + "enum": [ + "critical", + "high", + "medium", + "low" + ] + } + }, + { + "name": "limit", + "in": "query", + "schema": { + "type": "integer", + "default": 50, + "maximum": 200 + } + }, + { + "name": "offset", + "in": "query", + "schema": { + "type": "integer", + "default": 0 } } - }, + ], "responses": { "200": { - "description": "Gateway deleted", + "description": "Paginated task list", "content": { "application/json": { "schema": { "type": "object", "properties": { - "success": { - "type": "boolean" + "tasks": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Task" + } + }, + "total": { + "type": "integer" + }, + "page": { + "type": "integer" + }, + "limit": { + "type": "integer" } } } @@ -5301,28 +5622,72 @@ }, "401": { "$ref": "#/components/responses/Unauthorized" - }, - "403": { - "$ref": "#/components/responses/Forbidden" } } - } - }, - "/api/gateways/health": { + }, "post": { "tags": [ - "Admin" + "Tasks" ], - "summary": "Probe gateway health", - "operationId": "probeGatewayHealth", + "summary": "Create task", + "operationId": "createTask", "requestBody": { + "required": true, "content": { "application/json": { "schema": { "type": "object", + "required": [ + "title" + ], "properties": { - "gateway_id": { - "type": "integer" + "title": { + "type": "string" + }, + "description": { + "type": "string" + }, + "status": { + "type": "string", + "enum": [ + "inbox", + "assigned", + "in_progress", + "quality_review", + "done" + ], + "default": "inbox" + }, + "priority": { + "type": "string", + "enum": [ + "critical", + "high", + "medium", + "low" + ], + "default": "medium" + }, + "assigned_to": { + "type": "string" + }, + "created_by": { + "type": "string" + }, + "due_date": { + "type": "string" + }, + "estimated_hours": { + "type": "number" + }, + "tags": { + "type": "array", + "items": { + "type": "string" + } + }, + "metadata": { + "type": "object" } } } @@ -5330,81 +5695,94 @@ } }, "responses": { - "200": { - "description": "Health check results", + "201": { + "description": "Task created", "content": { "application/json": { "schema": { "type": "object", "properties": { - "healthy": { - "type": "boolean" - }, - "latency_ms": { - "type": "number" - }, - "details": { - "type": "object" + "task": { + "$ref": "#/components/schemas/Task" } } } } } }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" - } - } - } - }, - "/api/gateway-config": { - "get": { - "tags": [ - "Admin" - ], - "summary": "Read gateway config", - "operationId": "getGatewayConfig", - "responses": { - "200": { - "description": "Gateway configuration", + }, + "409": { + "description": "Task title already exists", "content": { "application/json": { "schema": { - "type": "object" + "$ref": "#/components/schemas/Error" } } } }, - "401": { - "$ref": "#/components/responses/Unauthorized" - }, - "403": { - "$ref": "#/components/responses/Forbidden" + "429": { + "$ref": "#/components/responses/RateLimited" } } }, - "post": { + "put": { "tags": [ - "Admin" + "Tasks" ], - "summary": "Update gateway config", - "operationId": "updateGatewayConfig", + "summary": "Bulk update task statuses", + "operationId": "bulkUpdateTasks", "requestBody": { "required": true, "content": { "application/json": { "schema": { - "type": "object" + "type": "object", + "required": [ + "tasks" + ], + "properties": { + "tasks": { + "type": "array", + "items": { + "type": "object", + "required": [ + "id", + "status" + ], + "properties": { + "id": { + "type": "integer" + }, + "status": { + "type": "string", + "enum": [ + "inbox", + "assigned", + "in_progress", + "quality_review", + "done" + ] + } + } + } + } + } } } } }, "responses": { "200": { - "description": "Config updated", + "description": "Tasks updated", "content": { "application/json": { "schema": { @@ -5412,58 +5790,57 @@ "properties": { "success": { "type": "boolean" + }, + "updated": { + "type": "integer" } } } } } }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" + }, + "429": { + "$ref": "#/components/responses/RateLimited" } } } }, - "/api/integrations": { + "/api/tasks/{id}": { "get": { "tags": [ - "Admin" + "Tasks" + ], + "summary": "Get task by ID", + "operationId": "getTask", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "integer" + } + } ], - "summary": "List integrations", - "operationId": "listIntegrations", "responses": { "200": { - "description": "Integration list", + "description": "Task details", "content": { "application/json": { "schema": { "type": "object", "properties": { - "integrations": { - "type": "array", - "items": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "name": { - "type": "string" - }, - "type": { - "type": "string" - }, - "enabled": { - "type": "boolean" - }, - "config": { - "type": "object" - } - } - } + "task": { + "$ref": "#/components/schemas/Task" } } } @@ -5472,39 +5849,63 @@ }, "401": { "$ref": "#/components/responses/Unauthorized" + }, + "404": { + "$ref": "#/components/responses/NotFound" } } }, - "post": { + "put": { "tags": [ - "Admin" + "Tasks" + ], + "summary": "Update task", + "operationId": "updateTask", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "integer" + } + } ], - "summary": "Integration actions (enable, disable, test, configure)", - "operationId": "integrationAction", "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", - "required": [ - "action", - "id" - ], "properties": { - "action": { - "type": "string", - "enum": [ - "enable", - "disable", - "test", - "configure" - ] + "title": { + "type": "string" }, - "id": { + "description": { "type": "string" }, - "config": { + "status": { + "type": "string" + }, + "priority": { + "type": "string" + }, + "assigned_to": { + "type": "string" + }, + "due_date": { + "type": "string" + }, + "estimated_hours": { + "type": "number" + }, + "tags": { + "type": "array", + "items": { + "type": "string" + } + }, + "metadata": { "type": "object" } } @@ -5514,66 +5915,53 @@ }, "responses": { "200": { - "description": "Action applied", + "description": "Task updated", "content": { "application/json": { "schema": { "type": "object", "properties": { - "success": { - "type": "boolean" + "task": { + "$ref": "#/components/schemas/Task" } } } } } }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" + }, + "404": { + "$ref": "#/components/responses/NotFound" + }, + "429": { + "$ref": "#/components/responses/RateLimited" } } - } - }, - "/api/spawn": { - "post": { + }, + "delete": { "tags": [ - "Admin" + "Tasks" ], - "summary": "Spawn agent process", - "operationId": "spawnAgent", - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "type": "object", - "required": [ - "agent" - ], - "properties": { - "agent": { - "type": "string" - }, - "task": { - "type": "string" - }, - "params": { - "type": "object" - } - } - } + "summary": "Delete task", + "operationId": "deleteTask", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "integer" } } - }, + ], "responses": { "200": { - "description": "Agent spawned", + "description": "Task deleted", "content": { "application/json": { "schema": { @@ -5581,68 +5969,73 @@ "properties": { "success": { "type": "boolean" - }, - "session_id": { - "type": "string" } } } } } }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" + }, + "404": { + "$ref": "#/components/responses/NotFound" } } } }, - "/api/standup": { - "get": { + "/api/tasks/{id}/broadcast": { + "post": { "tags": [ - "Admin" + "Tasks" ], - "summary": "Get standup report", - "operationId": "getStandupReport", + "summary": "Broadcast task to agents", + "operationId": "broadcastTask", "parameters": [ { - "name": "date", - "in": "query", + "name": "id", + "in": "path", + "required": true, "schema": { - "type": "string", - "format": "date" + "type": "integer" } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "agents": { + "type": "array", + "items": { + "type": "string" + } + }, + "message": { + "type": "string" + } + } + } + } + } + }, "responses": { "200": { - "description": "Standup report", + "description": "Task broadcast sent", "content": { "application/json": { "schema": { "type": "object", "properties": { - "date": { - "type": "string" - }, - "agents": { - "type": "array", - "items": { - "type": "object" - } - }, - "tasks_completed": { - "type": "integer" - }, - "tasks_in_progress": { - "type": "integer" + "success": { + "type": "boolean" }, - "highlights": { + "delivered_to": { "type": "array", "items": { "type": "string" @@ -5655,48 +6048,93 @@ }, "401": { "$ref": "#/components/responses/Unauthorized" + }, + "403": { + "$ref": "#/components/responses/Forbidden" + }, + "404": { + "$ref": "#/components/responses/NotFound" } } } }, - "/api/memory": { + "/api/tasks/{id}/comments": { "get": { "tags": [ - "Admin" + "Tasks" ], - "summary": "Get memory files", - "operationId": "getMemoryFiles", + "summary": "List task comments", + "operationId": "listTaskComments", "parameters": [ { - "name": "path", - "in": "query", + "name": "id", + "in": "path", + "required": true, "schema": { - "type": "string" + "type": "integer" } } ], "responses": { "200": { - "description": "Memory file contents", + "description": "Comment list", "content": { "application/json": { "schema": { - "type": "object" + "type": "object", + "properties": { + "comments": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "integer" + }, + "task_id": { + "type": "integer" + }, + "author": { + "type": "string" + }, + "content": { + "type": "string" + }, + "created_at": { + "type": "integer" + } + } + } + } + } } } } }, "401": { "$ref": "#/components/responses/Unauthorized" + }, + "404": { + "$ref": "#/components/responses/NotFound" } } }, "post": { "tags": [ - "Admin" + "Tasks" + ], + "summary": "Add comment to task", + "operationId": "addTaskComment", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "integer" + } + } ], - "summary": "Update memory file", - "operationId": "updateMemoryFile", "requestBody": { "required": true, "content": { @@ -5704,14 +6142,13 @@ "schema": { "type": "object", "required": [ - "path", "content" ], "properties": { - "path": { + "content": { "type": "string" }, - "content": { + "author": { "type": "string" } } @@ -5720,103 +6157,176 @@ } }, "responses": { - "200": { - "description": "Memory updated", + "201": { + "description": "Comment added", "content": { "application/json": { "schema": { "type": "object", "properties": { - "success": { - "type": "boolean" + "comment": { + "type": "object" } } } } } }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" + }, + "404": { + "$ref": "#/components/responses/NotFound" } } } }, - "/api/search": { + "/api/tokens": { "get": { "tags": [ - "Admin" + "Tokens" ], - "summary": "Full-text search", - "operationId": "search", + "summary": "Query token usage", + "operationId": "getTokenUsage", "parameters": [ { - "name": "q", + "name": "action", "in": "query", - "required": true, "schema": { - "type": "string" + "type": "string", + "enum": [ + "list", + "stats", + "agent-costs", + "export", + "trends" + ], + "default": "list" } }, { - "name": "type", + "name": "timeframe", "in": "query", "schema": { "type": "string", "enum": [ - "tasks", - "agents", - "activities", + "hour", + "day", + "week", + "month", "all" - ] + ], + "default": "all" } }, { - "name": "limit", + "name": "format", "in": "query", + "description": "Export format (only for action=export)", "schema": { - "type": "integer", - "default": 20 + "type": "string", + "enum": [ + "json", + "csv" + ], + "default": "json" } } ], "responses": { "200": { - "description": "Search results", + "description": "Token usage data. Shape varies by action.", "content": { "application/json": { "schema": { - "type": "object", - "properties": { - "results": { - "type": "array", - "items": { - "type": "object", - "properties": { - "type": { - "type": "string" - }, - "id": { - "type": "integer" - }, - "title": { - "type": "string" - }, - "snippet": { - "type": "string" - }, - "score": { - "type": "number" + "oneOf": [ + { + "type": "object", + "title": "ListResponse", + "properties": { + "usage": { + "type": "array", + "items": { + "$ref": "#/components/schemas/TokenUsageRecord" } + }, + "total": { + "type": "integer" + }, + "timeframe": { + "type": "string" } } }, - "total": { - "type": "integer" + { + "type": "object", + "title": "StatsResponse", + "properties": { + "summary": { + "$ref": "#/components/schemas/TokenStats" + }, + "models": { + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/TokenStats" + } + }, + "sessions": { + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/TokenStats" + } + }, + "agents": { + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/TokenStats" + } + }, + "timeframe": { + "type": "string" + }, + "recordCount": { + "type": "integer" + } + } + }, + { + "type": "object", + "title": "TrendsResponse", + "properties": { + "trends": { + "type": "array", + "items": { + "type": "object", + "properties": { + "timestamp": { + "type": "string" + }, + "tokens": { + "type": "integer" + }, + "cost": { + "type": "number" + }, + "requests": { + "type": "integer" + } + } + } + }, + "timeframe": { + "type": "string" + } + } } - } + ] } } } @@ -5828,62 +6338,44 @@ "$ref": "#/components/responses/Unauthorized" } } - } - }, - "/api/backup": { - "post": { - "tags": [ - "Admin" - ], - "summary": "Trigger backup", - "operationId": "triggerBackup", - "responses": { - "200": { - "description": "Backup completed", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "success": { - "type": "boolean" - }, - "path": { - "type": "string" - }, - "size_bytes": { - "type": "integer" - } - } - } - } - } - }, - "401": { - "$ref": "#/components/responses/Unauthorized" - }, - "403": { - "$ref": "#/components/responses/Forbidden" - } - } - } - }, - "/api/cleanup": { + }, "post": { "tags": [ - "Admin" + "Tokens" ], - "summary": "Trigger cleanup of old data", - "operationId": "triggerCleanup", + "summary": "Record token usage", + "operationId": "recordTokenUsage", "requestBody": { + "required": true, "content": { "application/json": { "schema": { "type": "object", + "required": [ + "model", + "sessionId", + "inputTokens", + "outputTokens" + ], "properties": { - "older_than_days": { - "type": "integer", - "default": 30 + "model": { + "type": "string" + }, + "sessionId": { + "type": "string" + }, + "inputTokens": { + "type": "integer" + }, + "outputTokens": { + "type": "integer" + }, + "operation": { + "type": "string", + "default": "chat_completion" + }, + "duration": { + "type": "number" } } } @@ -5892,7 +6384,7 @@ }, "responses": { "200": { - "description": "Cleanup results", + "description": "Usage recorded", "content": { "application/json": { "schema": { @@ -5901,14 +6393,17 @@ "success": { "type": "boolean" }, - "deleted": { - "type": "object" + "record": { + "$ref": "#/components/schemas/TokenUsageRecord" } } } } } }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, "401": { "$ref": "#/components/responses/Unauthorized" }, @@ -5918,52 +6413,28 @@ } } }, - "/api/export": { + "/api/webhooks": { "get": { "tags": [ - "Admin" - ], - "summary": "Export data", - "operationId": "exportData", - "parameters": [ - { - "name": "type", - "in": "query", - "schema": { - "type": "string", - "enum": [ - "tasks", - "agents", - "activities", - "all" - ] - } - }, - { - "name": "format", - "in": "query", - "schema": { - "type": "string", - "enum": [ - "json", - "csv" - ], - "default": "json" - } - } + "Webhooks" ], + "summary": "List webhooks", + "operationId": "listWebhooks", "responses": { "200": { - "description": "Exported data", + "description": "Webhook list with delivery stats", "content": { "application/json": { "schema": { - "type": "object" - } - }, - "text/csv": { - "schema": { - "type": "string" + "type": "object", + "properties": { + "webhooks": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Webhook" + } + } + } } } } @@ -5975,68 +6446,103 @@ "$ref": "#/components/responses/Forbidden" } } - } - }, - "/api/super/tenants": { - "get": { + }, + "post": { "tags": [ - "Super Admin" + "Webhooks" ], - "summary": "List tenants", - "operationId": "listTenants", + "summary": "Create webhook", + "operationId": "createWebhook", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "name", + "url" + ], + "properties": { + "name": { + "type": "string" + }, + "url": { + "type": "string", + "format": "uri" + }, + "events": { + "type": "array", + "items": { + "type": "string" + } + }, + "generate_secret": { + "type": "boolean", + "default": true + } + } + } + } + } + }, "responses": { "200": { - "description": "Tenant list", + "description": "Webhook created. Secret is only shown in full on creation.", "content": { "application/json": { "schema": { "type": "object", "properties": { - "tenants": { + "id": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "url": { + "type": "string" + }, + "secret": { + "type": "string" + }, + "events": { "type": "array", "items": { - "type": "object", - "properties": { - "id": { - "type": "integer" - }, - "slug": { - "type": "string" - }, - "name": { - "type": "string" - }, - "status": { - "type": "string" - }, - "linux_user": { - "type": "string" - }, - "created_at": { - "type": "integer" - } - } + "type": "string" } + }, + "enabled": { + "type": "boolean" + }, + "message": { + "type": "string" } } } } } }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, "401": { "$ref": "#/components/responses/Unauthorized" }, "403": { "$ref": "#/components/responses/Forbidden" + }, + "429": { + "$ref": "#/components/responses/RateLimited" } } }, - "post": { + "put": { "tags": [ - "Super Admin" + "Webhooks" ], - "summary": "Create tenant and bootstrap job", - "operationId": "createTenant", + "summary": "Update webhook", + "operationId": "updateWebhook", "requestBody": { "required": true, "content": { @@ -6044,21 +6550,30 @@ "schema": { "type": "object", "required": [ - "slug", - "name" + "id" ], "properties": { - "slug": { - "type": "string" + "id": { + "type": "integer" }, "name": { "type": "string" }, - "linux_user": { - "type": "string" + "url": { + "type": "string", + "format": "uri" + }, + "events": { + "type": "array", + "items": { + "type": "string" + } + }, + "enabled": { + "type": "boolean" }, - "config": { - "type": "object" + "regenerate_secret": { + "type": "boolean" } } } @@ -6066,12 +6581,24 @@ } }, "responses": { - "201": { - "description": "Tenant created with bootstrap job", + "200": { + "description": "Webhook updated", "content": { "application/json": { "schema": { - "type": "object" + "type": "object", + "properties": { + "success": { + "type": "boolean" + }, + "secret": { + "type": "string", + "description": "Only present when regenerate_secret is true" + }, + "message": { + "type": "string" + } + } } } } @@ -6085,39 +6612,41 @@ "403": { "$ref": "#/components/responses/Forbidden" }, - "409": { - "description": "Tenant slug or linux user already exists", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } + "404": { + "$ref": "#/components/responses/NotFound" + }, + "429": { + "$ref": "#/components/responses/RateLimited" } } - } - }, - "/api/super/tenants/{id}/decommission": { - "post": { + }, + "delete": { "tags": [ - "Super Admin" + "Webhooks" ], - "summary": "Decommission tenant", - "operationId": "decommissionTenant", - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer" + "summary": "Delete webhook", + "operationId": "deleteWebhook", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "id" + ], + "properties": { + "id": { + "type": "integer" + } + } + } } } - ], + }, "responses": { "200": { - "description": "Tenant decommissioned", + "description": "Webhook deleted", "content": { "application/json": { "schema": { @@ -6125,12 +6654,18 @@ "properties": { "success": { "type": "boolean" + }, + "deleted": { + "type": "integer" } } } } } }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, "401": { "$ref": "#/components/responses/Unauthorized" }, @@ -6139,26 +6674,46 @@ }, "404": { "$ref": "#/components/responses/NotFound" + }, + "429": { + "$ref": "#/components/responses/RateLimited" } } } }, - "/api/super/provision-jobs": { + "/api/webhooks/deliveries": { "get": { "tags": [ - "Super Admin" + "Webhooks" + ], + "summary": "Get webhook delivery history", + "operationId": "getWebhookDeliveries", + "parameters": [ + { + "name": "webhook_id", + "in": "query", + "schema": { + "type": "integer" + } + }, + { + "name": "limit", + "in": "query", + "schema": { + "type": "integer", + "default": 50 + } + } ], - "summary": "List provision jobs", - "operationId": "listProvisionJobs", "responses": { "200": { - "description": "Provision job list", + "description": "Delivery history", "content": { "application/json": { "schema": { "type": "object", "properties": { - "jobs": { + "deliveries": { "type": "array", "items": { "type": "object", @@ -6166,29 +6721,20 @@ "id": { "type": "integer" }, - "tenant_id": { + "webhook_id": { "type": "integer" }, - "type": { + "event": { "type": "string" }, - "status": { - "type": "string", - "enum": [ - "pending", - "running", - "completed", - "failed" - ] + "status_code": { + "type": "integer" }, - "output": { + "error": { "type": "string" }, "created_at": { "type": "integer" - }, - "completed_at": { - "type": "integer" } } } @@ -6205,13 +6751,15 @@ "$ref": "#/components/responses/Forbidden" } } - }, + } + }, + "/api/webhooks/retry": { "post": { "tags": [ - "Super Admin" + "Webhooks" ], - "summary": "Create provision job", - "operationId": "createProvisionJob", + "summary": "Retry a failed webhook delivery", + "operationId": "retryWebhookDelivery", "requestBody": { "required": true, "content": { @@ -6219,18 +6767,11 @@ "schema": { "type": "object", "required": [ - "tenant_id", - "type" + "delivery_id" ], "properties": { - "tenant_id": { + "delivery_id": { "type": "integer" - }, - "type": { - "type": "string" - }, - "params": { - "type": "object" } } } @@ -6238,52 +6779,55 @@ } }, "responses": { - "201": { - "description": "Job created", - "content": { - "application/json": { - "schema": { - "type": "object" - } - } - } - }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, - "401": { - "$ref": "#/components/responses/Unauthorized" - }, - "403": { - "$ref": "#/components/responses/Forbidden" + "200": { + "description": "Delivery retried" } } } }, - "/api/super/provision-jobs/{id}": { - "get": { + "/api/webhooks/test": { + "post": { "tags": [ - "Super Admin" + "Webhooks" ], - "summary": "Get provision job details", - "operationId": "getProvisionJob", - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer" + "summary": "Test webhook", + "operationId": "testWebhook", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "id" + ], + "properties": { + "id": { + "type": "integer" + } + } + } } } - ], + }, "responses": { "200": { - "description": "Job details", + "description": "Test result", "content": { "application/json": { "schema": { - "type": "object" + "type": "object", + "properties": { + "success": { + "type": "boolean" + }, + "status_code": { + "type": "integer" + }, + "response_time_ms": { + "type": "number" + } + } } } } @@ -6300,36 +6844,69 @@ } } }, - "/api/super/provision-jobs/{id}/run": { - "post": { + "/api/webhooks/verify-docs": { + "get": { "tags": [ - "Super Admin" + "Webhooks" ], - "summary": "Run provision job", - "operationId": "runProvisionJob", - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer" - } + "summary": "Get webhook verification documentation", + "operationId": "getWebhookVerifyDocs", + "responses": { + "200": { + "description": "Verification guide and examples" } + } + } + }, + "/api/workflows": { + "get": { + "tags": [ + "Workflows" ], + "summary": "List workflow templates", + "operationId": "listWorkflows", "responses": { "200": { - "description": "Job started", + "description": "Workflow template list", "content": { "application/json": { "schema": { "type": "object", "properties": { - "success": { - "type": "boolean" - }, - "status": { - "type": "string" + "templates": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "description": { + "type": "string" + }, + "steps": { + "type": "array", + "items": { + "type": "object" + } + }, + "created_by": { + "type": "string" + }, + "use_count": { + "type": "integer" + }, + "created_at": { + "type": "integer" + }, + "updated_at": { + "type": "integer" + } + } + } } } } @@ -6338,24 +6915,15 @@ }, "401": { "$ref": "#/components/responses/Unauthorized" - }, - "403": { - "$ref": "#/components/responses/Forbidden" - }, - "404": { - "$ref": "#/components/responses/NotFound" } } - } - }, - "/api/connect": { + }, "post": { "tags": [ - "Connections" + "Workflows" ], - "summary": "Register a direct CLI connection", - "description": "Registers a CLI tool directly without a gateway. Auto-creates agent if name doesn't exist.", - "operationId": "registerConnection", + "summary": "Create workflow template", + "operationId": "createWorkflow", "requestBody": { "required": true, "content": { @@ -6363,24 +6931,32 @@ "schema": { "type": "object", "required": [ - "tool_name", - "agent_name" + "name", + "steps" ], "properties": { - "tool_name": { - "type": "string" - }, - "tool_version": { - "type": "string" - }, - "agent_name": { + "name": { "type": "string" }, - "agent_role": { + "description": { "type": "string" }, - "metadata": { - "type": "object" + "steps": { + "type": "array", + "items": { + "type": "object", + "properties": { + "agent": { + "type": "string" + }, + "action": { + "type": "string" + }, + "params": { + "type": "object" + } + } + } } } } @@ -6388,37 +6964,15 @@ } }, "responses": { - "200": { - "description": "Connection registered", + "201": { + "description": "Template created", "content": { "application/json": { "schema": { "type": "object", "properties": { - "connection_id": { - "type": "string", - "format": "uuid" - }, - "agent_id": { - "type": "integer" - }, - "agent_name": { - "type": "string" - }, - "status": { - "type": "string", - "enum": [ - "connected" - ] - }, - "sse_url": { - "type": "string" - }, - "heartbeat_url": { - "type": "string" - }, - "token_report_url": { - "type": "string" + "template": { + "type": "object" } } } @@ -6430,79 +6984,87 @@ }, "401": { "$ref": "#/components/responses/Unauthorized" + }, + "403": { + "$ref": "#/components/responses/Forbidden" + }, + "429": { + "$ref": "#/components/responses/RateLimited" } } }, - "get": { + "put": { "tags": [ - "Connections" + "Workflows" ], - "summary": "List all direct connections", - "operationId": "listConnections", + "summary": "Update workflow template", + "operationId": "updateWorkflow", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "id" + ], + "properties": { + "id": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "description": { + "type": "string" + }, + "steps": { + "type": "array", + "items": { + "type": "object" + } + } + } + } + } + } + }, "responses": { "200": { - "description": "List of connections", + "description": "Template updated", "content": { "application/json": { "schema": { "type": "object", "properties": { - "connections": { - "type": "array", - "items": { - "type": "object", - "properties": { - "id": { - "type": "integer" - }, - "agent_id": { - "type": "integer" - }, - "agent_name": { - "type": "string" - }, - "tool_name": { - "type": "string" - }, - "tool_version": { - "type": "string" - }, - "connection_id": { - "type": "string", - "format": "uuid" - }, - "status": { - "type": "string", - "enum": [ - "connected", - "disconnected" - ] - }, - "last_heartbeat": { - "type": "integer" - }, - "created_at": { - "type": "integer" - } - } - } + "template": { + "type": "object" } } } } } }, + "400": { + "$ref": "#/components/responses/BadRequest" + }, "401": { "$ref": "#/components/responses/Unauthorized" + }, + "403": { + "$ref": "#/components/responses/Forbidden" + }, + "404": { + "$ref": "#/components/responses/NotFound" } } }, "delete": { "tags": [ - "Connections" + "Workflows" ], - "summary": "Disconnect a CLI connection", - "operationId": "disconnectConnection", + "summary": "Delete workflow template", + "operationId": "deleteWorkflow", "requestBody": { "required": true, "content": { @@ -6510,12 +7072,11 @@ "schema": { "type": "object", "required": [ - "connection_id" + "id" ], "properties": { - "connection_id": { - "type": "string", - "format": "uuid" + "id": { + "type": "integer" } } } @@ -6524,32 +7085,26 @@ }, "responses": { "200": { - "description": "Disconnected", + "description": "Template deleted", "content": { "application/json": { "schema": { "type": "object", "properties": { - "status": { - "type": "string", - "enum": [ - "disconnected" - ] - }, - "connection_id": { - "type": "string" + "success": { + "type": "boolean" } } } } } }, - "400": { - "$ref": "#/components/responses/BadRequest" - }, "401": { "$ref": "#/components/responses/Unauthorized" }, + "403": { + "$ref": "#/components/responses/Forbidden" + }, "404": { "$ref": "#/components/responses/NotFound" } @@ -6902,6 +7457,26 @@ "type": "integer" } } + }, + "Project": { + "type": "object", + "properties": { + "id": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "description": { + "type": "string" + }, + "created_at": { + "type": "integer" + }, + "updated_at": { + "type": "integer" + } + } } }, "responses": {