{"openapi":"3.1.0","info":{"title":"TODO for AI API","version":"1.0.0"},"servers":[{"url":"https://api.todofor.ai/api/v1","description":"API key / Bearer auth"},{"url":"https://api.todofor.ai/cookie/v1","description":"Browser session (cookie)"},{"url":"https://api.todofor.ai/dst/v1","description":"Device session token (dst_…)"}],"paths":{"/users/profile":{"get":{"operationId":"user_profile","tags":["user"],"description":"Returns the authenticated user profile including settings and preferences.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserProfileFull"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}}},"/users/export":{"get":{"operationId":"user_exportData","tags":["user"],"description":"Returns account records and file metadata as portable JSON. Known credential fields, vault values, and file bytes are omitted; user-authored content is exported as stored.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountDataExport"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}}},"/users/account":{"delete":{"operationId":"user_deleteAccount","tags":["user"],"description":"Permanently deletes the authenticated account and all user-owned data.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessResponse"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyInput"}}}}}},"/users/default-project":{"post":{"operationId":"user_setDefaultProject","tags":["user"],"description":"Sets the project the user lands on at `/`. Accepts any project the user can access, including shared team projects.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"null"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectIdInput"}}}}}},"/users/project-agent-mapping":{"post":{"operationId":"user_updateProjectAgentMapping","tags":["user"],"description":"Updates the default agent settings to use for new todos in a specific project.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"null"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectAgentSelectionInput"}}}}}},"/usage":{"get":{"operationId":"usage_getUsage","tags":["usage"],"description":"Returns usage statistics for the user within the specified date range.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Usage"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}}},"/usage/team":{"get":{"operationId":"usage_getTeamUsage","tags":["usage"],"description":"Per-member spend from the team pool in the date range (owner or admin only).","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TeamUsageResponse"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}}},"/projects":{"get":{"operationId":"project_list","tags":["project"],"description":"Returns all projects the user owns or has access to.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ProjectFull"}}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}},"post":{"operationId":"project_create","tags":["project"],"description":"Creates a new project for organizing todos.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectFull"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectCreateInput"}}}}}},"/projects/{projectId}/brand":{"get":{"operationId":"project_getBrand","tags":["project"],"description":"Returns a project's brand page markdown, readable by anyone with access to the project (including public projects).","parameters":[{"name":"projectId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectBrandResponse"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}}},"/projects/{projectId}":{"get":{"operationId":"project_get","tags":["project"],"description":"Returns a project with its settings.","parameters":[{"name":"projectId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectFull"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}},"put":{"operationId":"project_update","tags":["project"],"description":"Updates project properties like name or description.","parameters":[{"name":"projectId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"null"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectUpdateInput"}}}}},"delete":{"operationId":"project_delete","tags":["project"],"description":"Permanently deletes a project and all its todos.","parameters":[{"name":"projectId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"null"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectIdInput"}}}}}},"/projects/{projectId}/share":{"post":{"operationId":"project_share","tags":["project"],"description":"Shares a project with another user by email.","parameters":[{"name":"projectId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Project"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ShareProjectInput"}}}}}},"/projects/{projectId}/subscribe":{"post":{"operationId":"project_subscribe","tags":["project"],"description":"Subscribes to real-time updates for a project via WebSocket.","parameters":[{"name":"projectId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"null"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectIdInput"}}}}}},"/projects/{projectId}/todos":{"post":{"operationId":"project_createTodo","tags":["project"],"description":"Creates a new todo in the project and optionally starts AI processing.","parameters":[{"name":"projectId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Todo"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTodoInput"}}}}},"get":{"operationId":"todo_list","tags":["todo"],"description":"Returns a page of todos in a project (lightweight, newest-activity-first). Use `cursor` (lastActivityAt of the last item) to fetch older pages; `search` filters by content/status, `agentSettingsId`/`businessContextId` filter by agent/business context.","parameters":[{"name":"projectId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TodoPage"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}}},"/projects/{projectId}/groups":{"get":{"operationId":"project_groups","tags":["project"],"description":"Lists project todo groups, including empty groups.","parameters":[{"name":"projectId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TodoGroup"}}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}}},"/projects/{projectId}/cards":{"get":{"operationId":"project_cards","tags":["project"],"description":"Lists project renderer cards (reusable HTML renderers for show blocks).","parameters":[{"name":"projectId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/RendererCardInfo"}}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}}},"/projects/{projectId}/groups/{slug}":{"put":{"operationId":"project_upsertGroup","tags":["project"],"description":"Creates or renames a project todo group.","parameters":[{"name":"projectId","in":"path","required":true,"schema":{"type":"string"}},{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TodoGroup"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectGroupUpsertInput"}}}}}},"/projects/{projectId}/todos/from-template":{"post":{"operationId":"project_startFromTemplate","tags":["project"],"description":"Start a TODO from a spec (with optional overrides) or from scratch — THE single accept path (start(spec) -> Todo). With `propose: true` the todo is created as PROPOSED (an analyzer suggestion the user accepts or dismisses) instead of starting.","parameters":[{"name":"projectId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Todo"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StartFromSpecInput"}}}}}},"/settings/user":{"get":{"operationId":"settings_getUserSettings","tags":["settings"],"description":"Retrieves the application settings for the authenticated user.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppSettings"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}},"put":{"operationId":"settings_updateUserSettings","tags":["settings"],"description":"Updates the application settings for the authenticated user.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"null"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserSettingsUpdateInput"}}}}}},"/settings/user/billing":{"put":{"operationId":"settings_updateBillingInfo","tags":["settings"],"description":"Updates the billing address and tax information for the user.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingUpdateResult"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingInfoInput"}}}}}},"/settings/projects/{projectId}":{"get":{"operationId":"settings_getProjectSettings","tags":["settings"],"description":"Retrieves the settings for a specific project.","parameters":[{"name":"projectId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectSettingsFull"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}},"put":{"operationId":"settings_updateProjectSettings","tags":["settings"],"description":"Updates the settings for a specific project.","parameters":[{"name":"projectId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"null"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectSettingsUpdateInput"}}}}}},"/apikeys":{"get":{"operationId":"apiKey_list","tags":["apiKey"],"description":"Retrieves all API keys belonging to the authenticated user.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ApiKey"}}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}},"post":{"operationId":"apiKey_create","tags":["apiKey"],"description":"Creates a new API key with the specified name.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKey"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyNameInput"}}}}}},"/apikeys/{name}":{"get":{"operationId":"apiKey_get","tags":["apiKey"],"description":"Retrieves a specific API key by its name.","parameters":[{"name":"name","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKey"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}},"delete":{"operationId":"apiKey_delete","tags":["apiKey"],"description":"Permanently deletes an API key by its name.","parameters":[{"name":"name","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"null"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyNameInput"}}}}}},"/apikeys/default":{"get":{"operationId":"apiKey_getDefault","tags":["apiKey"],"description":"Returns the default API key, creating one if it does not exist.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKey"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}}},"/apikeys/{name}/default":{"put":{"operationId":"apiKey_setDefault","tags":["apiKey"],"description":"Sets the specified API key as the default key for the user.","parameters":[{"name":"name","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"null"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyNameInput"}}}}}},"/apikey/validate":{"get":{"operationId":"apiKey_validate","tags":["apiKey"],"description":"Validates the API key provided in the request headers.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyValidation"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}}},"/todos/{todoId}":{"get":{"operationId":"todo_get","tags":["todo"],"description":"Retrieves a complete todo item including all messages, blocks, and metadata. Pass `messageLimit` to include only the newest N messages (`hasMoreMessages` signals older ones — page them via /todos/{todoId}/messages). Requires read access to the todo (either as owner or through project sharing).","parameters":[{"name":"todoId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Todo"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}},"put":{"operationId":"todo_update","tags":["todo"],"description":"Updates todo properties like content, scheduled time, or assigned agent. Requires write access to the todo.","parameters":[{"name":"todoId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"null"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TodoUpdateInput"}}}}},"delete":{"operationId":"todo_delete","tags":["todo"],"description":"Permanently deletes a todo and all its messages. This action cannot be undone. Requires write access to the todo.","parameters":[{"name":"todoId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"null"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TodoIdInput"}}}}}},"/messages/search":{"get":{"operationId":"todo_searchMessages","tags":["todo"],"description":"Full-text search over message content across all accessible projects (newest first). Optionally scope by projectId, todoId, or role.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageSearchPage"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}}},"/search":{"get":{"operationId":"todo_searchUnified","tags":["todo"],"description":"Unified search over todo conversations and curated memory notes. Exact word matches rank first (grouped per todo, best snippet shown); when exact results are thin, semantic (embedding) matches fill a \"related\" tail, marked by a `score` (cosine distance).","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnifiedSearchPage"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}}},"/todos/{todoId}/messages":{"get":{"operationId":"todo_getMessages","tags":["todo"],"description":"Returns a page of messages in chat order. Omit `before` for the newest page; pass the oldest loaded messageId as `before` to fetch older ones.","parameters":[{"name":"todoId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessagesPage"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}},"post":{"operationId":"todo_addMessage","tags":["todo"],"description":"Adds a new user message to the todo conversation. This can optionally trigger the AI agent to start processing immediately or schedule it for later.","parameters":[{"name":"todoId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Message"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddMessageInput"}}}}}},"/report-ai-output":{"post":{"operationId":"todo_reportAiOutput","tags":["todo"],"description":"Reports offensive or unsafe AI-generated output to the developer for review.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessResponse"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReportAiOutputInput"}}}}}},"/public/todos/{todoId}":{"get":{"operationId":"todo_getPublic","tags":["todo"],"description":"Retrieves a publicly-shared todo (read-only) including its messages. No authentication required; only returns the todo if it has been made public.","parameters":[{"name":"todoId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Todo"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}}},"/todos/{todoId}/status":{"patch":{"operationId":"todo_updateStatus","tags":["todo"],"description":"Changes the status of a todo (e.g., pause, resume, complete, cancel). Use this to control the execution state of a running AI task.","parameters":[{"name":"todoId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"null"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TodoStatusUpdateInput"}}}}}},"/todos/{todoId}/messages/{messageId}":{"patch":{"operationId":"todo_updateMessage","tags":["todo"],"description":"Updates a scheduled message before it starts processing.","parameters":[{"name":"todoId","in":"path","required":true,"schema":{"type":"string"}},{"name":"messageId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"null"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateMessageInput"}}}}}},"/todos/{todoId}/update-start":{"post":{"operationId":"todo_updateAndStart","tags":["todo"],"description":"Updates a message and immediately starts AI processing.","parameters":[{"name":"todoId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"null"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateAndStartMessageInput"}}}}}},"/todos/{todoId}/blocks/{blockId}/subtodo":{"post":{"operationId":"todo_linkBlockSubTodo","tags":["todo"],"description":"Links a spawned sub-agent todo to the block that launched it (appends to subTodoIds, deduplicated), so the UI nests the sub-agent's live run inside that block. One command may link several runs. Used by the tfa-* CLIs.","parameters":[{"name":"todoId","in":"path","required":true,"schema":{"type":"string"}},{"name":"blockId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"null"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TodoBlockSubTodoInput"}}}}}},"/todos/{todoId}/blocks/{blockId}/checked":{"post":{"operationId":"todo_toggleBlockChecked","tags":["todo"],"description":"Toggles the checked/completed state of an actionable block.","parameters":[{"name":"todoId","in":"path","required":true,"schema":{"type":"string"}},{"name":"blockId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"null"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TodoBlockIdInput"}}}}}},"/todos/{todoId}/todo-agent-mapping":{"post":{"operationId":"todo_updateAgentMapping","tags":["todo"],"description":"Updates which AI agent settings to use for this todo.","parameters":[{"name":"todoId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"null"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TodoAgentSelectionInput"}}}}}},"/todos/{todoId}/subscribe":{"post":{"operationId":"todo_subscribe","tags":["todo"],"description":"Subscribes to real-time updates for a todo via WebSocket and returns the full todo with messages. This atomic operation ensures the cache is populated before any WebSocket messages can arrive, eliminating race conditions.","parameters":[{"name":"todoId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Todo"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TodoIdInput"}}}}}},"/todos/{todoId}/workflow":{"get":{"operationId":"todo_getWorkflow","tags":["todo"],"description":"Returns the internal workflow state for debugging.","parameters":[{"name":"todoId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TodoWorkflow"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}},"put":{"operationId":"todo_updateWorkflow","tags":["todo"],"description":"Directly updates the internal workflow state. Set contextSummaryUsed=true to mark pending context summary as used.","parameters":[{"name":"todoId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"null"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowUpdateInput"}}}}}},"/tasks/pending":{"get":{"operationId":"task_getPending","tags":["task"],"description":"Retrieves all pending tasks for the authenticated user.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/PendingTask"}}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}}},"/billing/balance":{"get":{"operationId":"billing_getBalance","tags":["billing"],"description":"Retrieves the current billing balance for the authenticated user.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserBalance"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}}},"/billing/transactions":{"get":{"operationId":"billing_getTransactions","tags":["billing"],"description":"Returns a paginated list of billing transactions for the user.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransactionPage"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}}},"/billing/invoices":{"get":{"operationId":"billing_getInvoices","tags":["billing"],"description":"Returns a paginated list of invoices for the user.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvoicesPage"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}}},"/billing/create-payment-intent":{"post":{"operationId":"billing_createPaymentIntent","tags":["billing"],"description":"Creates a Stripe payment intent for adding credits to the account.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentIntent"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentIntentInput"}}}}}},"/billing/setup-payment-method":{"post":{"operationId":"billing_setupPaymentMethod","tags":["billing"],"description":"Creates a Stripe setup intent for adding a new payment method.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetupIntent"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyInput"}}}}}},"/billing/payment-methods":{"get":{"operationId":"billing_getPaymentMethods","tags":["billing"],"description":"Returns all saved payment methods for the user.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentMethodList"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}}},"/billing/set-default-payment-method":{"post":{"operationId":"billing_setDefaultPaymentMethod","tags":["billing"],"description":"Sets a payment method as the default for future transactions.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"null"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentMethodIdInput"}}}}}},"/billing/payment-methods/{paymentMethodId}":{"delete":{"operationId":"billing_deletePaymentMethod","tags":["billing"],"description":"Removes a saved payment method from the user account.","parameters":[{"name":"paymentMethodId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"null"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentMethodIdInput"}}}}}},"/billing/subscription":{"get":{"operationId":"billing_getSubscription","tags":["billing"],"description":"Get current subscription status for the authenticated user.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionInfo"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}},"post":{"operationId":"billing_createSubscription","tags":["billing"],"description":"Create a new subscription.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionResult"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSubscriptionInput"}}}}},"delete":{"operationId":"billing_cancelSubscription","tags":["billing"],"description":"Cancel the current subscription.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionResult"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CancelSubscriptionInput"}}}}},"patch":{"operationId":"billing_updateSubscription","tags":["billing"],"description":"Update subscription tier (upgrade/downgrade).","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionResult"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSubscriptionInput"}}}}}},"/billing/subscription/plans":{"get":{"operationId":"billing_getSubscriptionPlans","tags":["billing"],"description":"Get available subscription plans with pricing.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionPlansResponse"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}}},"/billing/usage":{"get":{"operationId":"billing_getUsageStatus","tags":["billing"],"description":"Get usage status: balances, monthly plan usage, and anchored session/weekly rate-limit windows.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UsageStatus"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}}},"/billing/team":{"get":{"operationId":"billing_getTeam","tags":["billing"],"description":"Get the team for the authenticated user (as owner or member), or null.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/TeamInfo"}]}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}}},"/billing/team/members":{"post":{"operationId":"billing_addTeamMember","tags":["billing"],"description":"Invite someone to the team by email — emails a join link they must accept.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/TeamInfo"}]}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TeamAddMemberInput"}}}}}},"/billing/team/invites":{"delete":{"operationId":"billing_revokeTeamInvite","tags":["billing"],"description":"Cancel a pending invite (owner or admin).","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/TeamInfo"}]}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TeamRevokeInviteInput"}}}}}},"/billing/team/project":{"patch":{"operationId":"billing_setTeamProject","tags":["billing"],"description":"Set or clear the team's shared project (owner/admin). All members get write access; omitting projectId reverts it to a personal project.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/TeamInfo"}]}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TeamSetProjectInput"}}}}}},"/billing/team/join-domain":{"patch":{"operationId":"billing_setTeamJoinDomain","tags":["billing"],"description":"Enable/disable auto-join for everyone on the owner's company email domain (owner only).","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/TeamInfo"}]}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TeamSetJoinDomainInput"}}}}}},"/billing/team/invites/{token}":{"get":{"operationId":"billing_previewTeamInvite","tags":["billing"],"description":"Preview an invite before signing in. Non-consuming.","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TeamInvitePreview"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}}},"/billing/team/invites/accept":{"post":{"operationId":"billing_acceptTeamInvite","tags":["billing"],"description":"Accept an invite as the signed-in user (email must match the invited address).","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/TeamInfo"}]}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TeamInviteTokenInput"}}}}}},"/billing/team/members/{memberId}/role":{"patch":{"operationId":"billing_setTeamMemberRole","tags":["billing"],"description":"Promote/demote a team member between admin and member (owner only).","parameters":[{"name":"memberId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/TeamInfo"}]}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TeamSetRoleInput"}}}}}},"/billing/team/members/{memberId}":{"delete":{"operationId":"billing_removeTeamMember","tags":["billing"],"description":"Remove a team member (owner) or leave the team (member).","parameters":[{"name":"memberId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"null"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TeamRemoveMemberInput"}}}}}},"/billing/extra-spend":{"patch":{"operationId":"billing_setAllowExtraSpend","tags":["billing"],"description":"Opt in/out of extra usage: when subscription usage windows are exhausted, continue from manual credit.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"null"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AllowExtraSpendInput"}}}}}},"/edges":{"get":{"operationId":"edge_list","tags":["edge"],"description":"Returns all edge devices registered to the authenticated user.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/EdgeData"}}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}}},"/edges/{edgeId}":{"get":{"operationId":"edge_get","tags":["edge"],"description":"Retrieves details of a specific edge device.","parameters":[{"name":"edgeId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EdgeData"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}},"patch":{"operationId":"edge_update","tags":["edge"],"description":"Updates the configuration of an existing edge device.","parameters":[{"name":"edgeId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"null"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EdgeUpdateInput"}}}}},"delete":{"operationId":"edge_delete","tags":["edge"],"description":"Permanently removes an edge device from the user account.","parameters":[{"name":"edgeId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"null"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EdgeIdInput"}}}}}},"/edges/{edgeId}/subscribe":{"post":{"operationId":"edge_subscribe","tags":["edge"],"description":"Subscribes the WebSocket connection to receive real-time updates from an edge device.","parameters":[{"name":"edgeId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"null"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EdgeIdInput"}}}}}},"/devices":{"get":{"operationId":"device_list","tags":["device"],"description":"Returns all devices registered to the authenticated user — bridge-backed machines, online iff the bridge WS is connected.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/DeviceData"}}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}}},"/devices/cloud":{"get":{"operationId":"device_cloud","tags":["device"],"description":"Returns the authenticated user's hosted cloud-native device, or null if none is alive yet (between rotations or during VM boot).","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/DeviceData"}]}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}}},"/devices/cloud/resync":{"post":{"operationId":"device_resyncCloud","tags":["device"],"description":"Force-reconcile the caller's primary cloud device to their tier. Provisions a VM if none is alive. Returns the primary device or null if still mid-boot.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/DeviceData"}]}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyInput"}}}}}},"/devices/{id}":{"delete":{"operationId":"device_delete","tags":["device"],"description":"Permanently removes a device from the user account.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"null"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IdInput"}}}}}},"/devices/{id}/workspacepaths":{"put":{"operationId":"device_setWorkspacePaths","tags":["device"],"description":"Replace the user-authorized filesystem roots for this device. AI shell sessions are scoped to (and start within) one of these paths.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"null"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"paths":{"type":"array","items":{"type":"string"}}},"required":["paths"]}}}}}},"/devices/{id}/exec":{"post":{"operationId":"device_exec","tags":["device"],"description":"Execute a shell command on a device. Returns combined stdout/stderr, exit code, and truncation/timeout flags. Ownership-checked.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeviceExecOutput"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeviceExecInput"}}}}}},"/devices/{id}/name":{"patch":{"operationId":"device_rename","tags":["device"],"description":"Rename a device. Names are not required to be unique; target resolution raises AMBIGUOUS_TARGET if a name matches more than one device.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"null"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[a-zA-Z0-9][a-zA-Z0-9_]*$"}},"required":["name"]}}}}}},"/devices/bridge-version":{"get":{"operationId":"device_latestBridgeVersion","tags":["device"],"description":"Latest published todoforai-bridge release tag (GitHub releases, cached server-side). Compare against a device's `metadata.identity.edge_version` to decide whether an update is available.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"latest":{"oneOf":[{"type":"null"},{"type":"string"}]}},"required":["latest"]}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}}},"/devices/{id}/update":{"post":{"operationId":"device_update","tags":["device"],"description":"Update a bridge device to the latest release. PC bridges re-run the verified installer in place then restart via their supervisor; VM bridges are killed and recreated from the current rootfs image (recovery flow). The device reconnects reporting the new `identity.edge_version`.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"null"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IdInput"}}}}}},"/devices/{id}/reboot":{"post":{"operationId":"device_reboot","tags":["device"],"description":"Reboot a bridge device. Sends `sudo reboot` over the bridge WS run channel; the bridge process dies as the kernel reboots, then /init re-launches it with saved creds.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"null"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IdInput"}}}}}},"/devices/{id}/scan-tools":{"post":{"operationId":"device_scanTools","tags":["device"],"description":"Trigger a `scan_tools` probe on the device over the bridge WS. Refreshes the canonical `metadata.installedTools` (persisted from the reply) and emits a DEVICE_STATUS update. Use after `device.exec`-driven install/uninstall so the optimistic UI patch becomes durable.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"null"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IdInput"}}}}}},"/devices/{id}/cdp-token/rotate":{"post":{"operationId":"device_rotateCdpToken","tags":["device"],"description":"Rotate a WEB_EXTENSION device's secret CDP capability token, revoking the previous `/ws/v2/cdp?token=` value (e.g. if it leaked). Returns the refreshed device; live CDP clients on the old token are dropped and must reconnect with the new one.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/DeviceData"}]}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IdInput"}}}}}},"/agents":{"get":{"operationId":"agentSettings_list","tags":["agentSettings"],"description":"Returns AI agent configurations. Optionally filter by workspacePath or name (returns enriched results).","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AgentSettings"}}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}},"post":{"operationId":"agentSettings_create","tags":["agentSettings"],"description":"Creates a new AI agent configuration with default settings.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentSettings"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyInput"}}}}}},"/agents/{agentSettingsId}":{"get":{"operationId":"agentSettings_get","tags":["agentSettings"],"description":"Returns a specific AI agent configuration.","parameters":[{"name":"agentSettingsId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentSettings"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}},"delete":{"operationId":"agentSettings_delete","tags":["agentSettings"],"description":"Permanently deletes an AI agent configuration.","parameters":[{"name":"agentSettingsId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"null"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentIdInput"}}}}}},"/agents/reorder":{"put":{"operationId":"agentSettings_reorder","tags":["agentSettings"],"description":"Updates the display order of agent configurations.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"null"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentReorderInput"}}}}}},"/agents/{agentSettingsId}/settings":{"put":{"operationId":"agentSettings_update","tags":["agentSettings"],"description":"Updates AI agent settings like model, temperature, and system prompt.","parameters":[{"name":"agentSettingsId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentSettings"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentUpdateInput"}}}}}},"/agents/{agentSettingsId}/mcp-config":{"put":{"operationId":"agentSettings_updateMCPConfig","tags":["agentSettings"],"description":"Updates MCP server activation state for an agent.","parameters":[{"name":"agentSettingsId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"null"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentMCPInput"}}}}}},"/agents/{agentSettingsId}/edge-mcp-config":{"put":{"operationId":"agentSettings_updateEdgeMCPConfig","tags":["agentSettings"],"description":"Updates MCP server activation state for an edge device.","parameters":[{"name":"agentSettingsId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"null"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentEdgeMCPInput"}}}}}},"/agents/{agentSettingsId}/device-config":{"put":{"operationId":"agentSettings_updateDeviceConfig","tags":["agentSettings"],"description":"Updates per-agent config (workspacePaths, enabled) for a bridge device.","parameters":[{"name":"agentSettingsId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"null"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentDeviceConfigInput"}}}}}},"/agents/global":{"get":{"operationId":"agentSettings_getGlobal","tags":["agentSettings"],"description":"Returns global agent settings defaults for the user.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GlobalAgentSettings"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}},"put":{"operationId":"agentSettings_updateGlobal","tags":["agentSettings"],"description":"Updates global agent settings defaults for the user.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GlobalAgentSettings"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GlobalAgentSettings"}}}}}},"/business-context":{"get":{"operationId":"businessContext_list","tags":["businessContext"],"description":"List business context attachments for the user.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/BusinessContextInfoResponse"}}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}},"post":{"operationId":"businessContext_create","tags":["businessContext"],"description":"Create a new business context as a .md attachment.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BusinessContextInfoResponse"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BusinessContextCreateInput"}}}}}},"/business-context/{id}":{"get":{"operationId":"businessContext_get","tags":["businessContext"],"description":"Get business context metadata.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BusinessContextInfoResponse"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}},"put":{"operationId":"businessContext_update","tags":["businessContext"],"description":"Update business context name.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BusinessContextInfoResponse"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BusinessContextUpdateInput"}}}}},"delete":{"operationId":"businessContext_delete","tags":["businessContext"],"description":"Delete a business context attachment.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"null"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContextIdInput"}}}}}},"/business-context/select":{"post":{"operationId":"businessContext_setSelected","tags":["businessContext"],"description":"Set the active business context for the current user.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessResponse"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetSelectedContextInput"}}}}}},"/business-context/suggest-brand-voice-answer":{"post":{"operationId":"businessContext_suggestBrandVoiceAnswer","tags":["businessContext"],"description":"AI-suggest a short answer to a brand-voice question, written as the business would respond.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuggestBrandVoiceAnswerOutput"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuggestBrandVoiceAnswerInput"}}}}}},"/business-context/refine-brand-voice":{"post":{"operationId":"businessContext_refineBrandVoice","tags":["businessContext"],"description":"Learn a company/personal writing voice via a short refinement loop.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefineBrandVoiceOutput"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefineBrandVoiceInput"}}}}}},"/context/{todoId}":{"get":{"operationId":"context_getContextInfo","tags":["context"],"description":"Get context window usage information for a specific todo. Returns current token usage, context window size, and whether compaction is recommended.","parameters":[{"name":"todoId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContextInfo"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}}},"/context/models":{"get":{"operationId":"context_getAvailableModels","tags":["context"],"description":"Get list of all available models with their context window sizes.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AvailableModels"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}}},"/context/{todoId}/compact":{"post":{"operationId":"context_compact","tags":["context"],"description":"Analyze or perform context compaction by summarizing older messages. Use dryRun=true (default) to see what would be compacted without making changes.","parameters":[{"name":"todoId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompactResult"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompactInput"}}}}}},"/context/{todoId}/summaries":{"get":{"operationId":"context_getSummaries","tags":["context"],"description":"Get the history of context compaction events for a todo.","parameters":[{"name":"todoId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ContextSummary"}}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}},"post":{"operationId":"context_addSummary","tags":["context"],"description":"Record a context compaction event. Called by the agent after compacting the context. Include summaryAttachment for the summary to be attached to the next message.","parameters":[{"name":"todoId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessResponse"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddContextSummaryInput"}}}}}},"/attachments/{attachmentId}":{"get":{"operationId":"attachment_get","tags":["attachment"],"description":"Retrieves attachment metadata by its unique identifier.","parameters":[{"name":"attachmentId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Attachment"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}},"delete":{"operationId":"attachment_delete","tags":["attachment"],"description":"Permanently deletes an attachment and its associated file.","parameters":[{"name":"attachmentId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"null"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AttachmentIdInput"}}}}}},"/attachments/todo/{todoId}":{"get":{"operationId":"attachment_getByTodo","tags":["attachment"],"description":"Returns all attachments associated with a specific todo item.","parameters":[{"name":"todoId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Attachment"}}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}}},"/attachments/agent/{agentSettingsId}":{"get":{"operationId":"attachment_getByAgent","tags":["attachment"],"description":"Returns all attachments associated with a specific agent settings.","parameters":[{"name":"agentSettingsId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Attachment"}}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}}},"/attachments/user/{userId}":{"get":{"operationId":"attachment_getByUser","tags":["attachment"],"description":"Returns all attachments uploaded by the authenticated user.","parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Attachment"}}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}}},"/resources/content":{"get":{"operationId":"resource_getContent","tags":["resource"],"description":"Returns the text content of a resource identified by URI.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResourceContentOutput"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}},"delete":{"operationId":"resource_delete","tags":["resource"],"description":"Deletes the resource identified by URI.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResourceDeleteOutput"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResourceUriInput"}}}}},"put":{"operationId":"resource_putContent","tags":["resource"],"description":"Overwrites the text content of a resource identified by URI.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"null"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResourceContentUpdateInput"}}}}}},"/resources/list":{"get":{"operationId":"resource_list","tags":["resource"],"description":"Lists resources under a directory URI, with optional pagination.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResourceListOutput"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}}},"/resources/folders":{"post":{"operationId":"resource_createFolder","tags":["resource"],"description":"Creates a folder under a parent resource URI.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResourceCreateFolderOutput"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResourceCreateFolderInputparentUristringMinLength1namestringMinLength1"}}}}}},"/resources/token":{"post":{"operationId":"resource_getResourceToken","tags":["resource"],"description":"Creates a short-lived token for browser, VM, or terminal resource access.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResourceTokenOutput"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResourceTokenInputttl(numberMinimum60Maximum86400)undefined"}}}}}},"/registry/templates":{"get":{"operationId":"todoRegistry_listTemplates","tags":["todoRegistry"],"description":"List all todo specs (templates). Optionally filter by category.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TodoSpecPublic"}}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}},"post":{"operationId":"todoRegistry_createTemplate","tags":["todoRegistry"],"description":"Create a todo spec in the registry (auth required). Returns the stored spec; its id is what `todoforai-cli recommend` references. Used by `todoregistry-cli create`.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TodoSpec"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SpecCreateInputnamestringMinLength1MaxLength120descriptionstringMinLength1bodystringMinLength..."}}}}}},"/registry/templates/{id}":{"get":{"operationId":"todoRegistry_getTemplate","tags":["todoRegistry"],"description":"Get a single todo spec by ID.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TodoSpecPublic"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}},"patch":{"operationId":"todoRegistry_patchTemplate","tags":["todoRegistry"],"description":"Edit a todo spec. Editing a builtin copies-on-write to an authored spec under the same id.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TodoSpec"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SpecPatchInput"}}}}}},"/registry/packs/list":{"get":{"operationId":"todoRegistry_listPacks","tags":["todoRegistry"],"description":"List all TODO packs.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/RegistryPack"}}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}}},"/registry/stats":{"get":{"operationId":"todoRegistry_getAllStats","tags":["todoRegistry"],"description":"Retrieves statistics for all specs including likes and start counts.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordstringTodoStats"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}}},"/registry/{id}/stats":{"get":{"operationId":"todoRegistry_getStats","tags":["todoRegistry"],"description":"Retrieves statistics for a specific spec.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TodoStats"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}}},"/registry/{id}/like":{"post":{"operationId":"todoRegistry_toggleLike","tags":["todoRegistry"],"description":"Toggles the like status of a spec for the current user.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TodoStats"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IdInput"}}}}}},"/registry/packs/stats":{"get":{"operationId":"todoRegistry_getAllPackStats","tags":["todoRegistry"],"description":"Retrieves statistics for all todo packs including likes.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordstringPackStats"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}}},"/registry/meta":{"get":{"operationId":"todoRegistry_getAllTemplateMeta","tags":["todoRegistry"],"description":"Aggregated usage metadata (runs, messages, cost) for all specs.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordstringSpecMetaPublic"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}}},"/registry/packs/{id}/like":{"post":{"operationId":"todoRegistry_togglePackLike","tags":["todoRegistry"],"description":"Toggles the like status of a todo pack for the current user.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PackStats"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IdInput"}}}}}},"/shares":{"post":{"operationId":"share_create","tags":["share"],"description":"Create a shareable prompt link from raw text OR a TODO id (forks that TODO's first user prompt into a spec). Provide exactly one. Anonymous allowed. Returns the spec + placement ids and open URL (/share/<id>).","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ShareCreateResponse"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ShareCreateInputtext(stringMaxLength100000)undefined"}}}}}},"/shares/{id}":{"get":{"operationId":"share_get","tags":["share"],"description":"Resolve a shared prompt by id (public, read-only).","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"text":{"type":"string"},"sourceTodoId":{"type":"string"},"createdAt":{"type":"number"}},"required":["id","text","createdAt"]}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}}},"/claims/mint":{"post":{"operationId":"claim_mint","tags":["claim"],"description":"Mint single-use claim links for a project you own. Each link (/claim/<token>) lets one recipient fork the project into a private copy owned by their account. Returns { email?, url } per link.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClaimMintResponse"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClaimMintInput"}}}}}},"/claims/preview":{"post":{"operationId":"claim_preview","tags":["claim"],"description":"Read the seed a claim link points at without consuming the link. Returns the workspace name/description so the recipient can confirm before claiming.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClaimPreviewResponse"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClaimPreviewInput"}}}}}},"/claims/redeem":{"post":{"operationId":"claim_redeem","tags":["claim"],"description":"Redeem a claim link: forks the seed into a new private project owned by the authenticated caller. Requires a registered (non-anonymous) sign-in. Returns the new project id.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClaimRedeemResponse"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClaimRedeemInput"}}}}}},"/admin/prewarm/start":{"post":{"operationId":"adminUser_prewarmStart","tags":["adminUser"],"description":"Prewarm a claim seed from a prospect website (headless onboarding): analyze the site, fill the brand page, generate recommendation cards, then mint a claim link.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PrewarmJobOutput"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PrewarmStartInput"}}}}}},"/admin/prewarm/status":{"get":{"operationId":"adminUser_prewarmStatus","tags":["adminUser"],"description":"Poll a running prewarm job by id.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PrewarmJobOutput"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}}},"/admin/users/add-credit":{"post":{"operationId":"adminUser_addCredit","tags":["adminUser"],"description":"Grant manual credit to a user by email.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminAddCreditResult"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminAddCreditInput"}}}}}},"/admin/users/set-subscription":{"post":{"operationId":"adminUser_setSubscription","tags":["adminUser"],"description":"Activate a subscription tier for a user (admin override, bypasses Stripe).","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminSetSubscriptionResult"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminSetSubscriptionInput"}}}}}},"/admin/users/revoke-subscription":{"post":{"operationId":"adminUser_revokeSubscription","tags":["adminUser"],"description":"Revoke a user subscription immediately.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminRevokeSubscriptionResult"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminRevokeSubscriptionInput"}}}}}},"/admin/users/set-seats":{"post":{"operationId":"adminUser_setSeats","tags":["adminUser"],"description":"Override a team owner's seat count. Omit `seats` to restore the plan default.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminSetSeatsResult"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminSetSeatsInput"}}}}}},"/users/by-email/{email}":{"get":{"operationId":"adminUser_getByEmail","tags":["adminUser"],"description":"Retrieves user details by email address for admin purposes.","parameters":[{"name":"email","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminUser"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}}},"/admin/stats":{"get":{"operationId":"adminUser_stats","tags":["adminUser"],"description":"Aggregate user stats (total, registered, anonymous, new in last 7 days). Cached 5 min.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminStats"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}}},"/challenges":{"post":{"operationId":"challenge_create","tags":["challenge"],"description":"Creates a new challenge for passwordless authentication flow.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Challenge"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChallengeCreateInput"}}}}}},"/meta/schema":{"get":{"operationId":"meta_schema","tags":["meta"],"description":"Returns a TypeScript-like API schema for AI consumption with endpoint definitions, parameters, and types.","responses":{"200":{"description":"Successful response"},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}}},"/meta/public-stats":{"get":{"operationId":"meta_publicStats","tags":["meta"],"description":"Public homepage stats: all-time todos started, user messages, estimated hours saved.","responses":{"200":{"description":"Successful response"},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}}},"/projects/{projectId}/hexgrids":{"get":{"operationId":"hexGrid_listGrids","tags":["hexGrid"],"description":"List all hex grids in a project.","parameters":[{"name":"projectId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/HexGrid"}}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}},"post":{"operationId":"hexGrid_createGrid","tags":["hexGrid"],"description":"Create a new hex grid in a project.","parameters":[{"name":"projectId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HexGrid"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HexGridCreateFullInput"}}}}}},"/hexgrids/{gridId}":{"get":{"operationId":"hexGrid_getGrid","tags":["hexGrid"],"description":"Get a hex grid by ID.","parameters":[{"name":"gridId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HexGrid"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}},"put":{"operationId":"hexGrid_updateGrid","tags":["hexGrid"],"description":"Update a hex grid.","parameters":[{"name":"gridId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HexGrid"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HexGridUpdateInput"}}}}},"delete":{"operationId":"hexGrid_deleteGrid","tags":["hexGrid"],"description":"Delete a hex grid and all its tiles.","parameters":[{"name":"gridId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessResponse"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HexGridIdInput"}}}}}},"/hexgrids/{gridId}/tiles":{"get":{"operationId":"hexGrid_listTiles","tags":["hexGrid"],"description":"List all tiles in a hex grid.","parameters":[{"name":"gridId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/GridTile"}}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}},"post":{"operationId":"hexGrid_createTile","tags":["hexGrid"],"description":"Create a tile at coordinates (q, r).","parameters":[{"name":"gridId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GridTile"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GridTileCreateInput"}}}}}},"/hexgrids/{gridId}/tiles/{q}/{r}":{"get":{"operationId":"hexGrid_getTile","tags":["hexGrid"],"description":"Get a tile at coordinates (q, r).","parameters":[{"name":"gridId","in":"path","required":true,"schema":{"type":"string"}},{"name":"q","in":"path","required":true,"schema":{"type":"string"}},{"name":"r","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GridTile"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}},"put":{"operationId":"hexGrid_updateTile","tags":["hexGrid"],"description":"Update a tile at coordinates (q, r).","parameters":[{"name":"gridId","in":"path","required":true,"schema":{"type":"string"}},{"name":"q","in":"path","required":true,"schema":{"type":"string"}},{"name":"r","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GridTile"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GridTileUpdateInput"}}}}},"delete":{"operationId":"hexGrid_deleteTile","tags":["hexGrid"],"description":"Delete a tile at coordinates (q, r).","parameters":[{"name":"gridId","in":"path","required":true,"schema":{"type":"string"}},{"name":"q","in":"path","required":true,"schema":{"type":"string"}},{"name":"r","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessResponse"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GridTileIdInput"}}}}}},"/hexgrids/{gridId}/tiles/{q}/{r}/move":{"post":{"operationId":"hexGrid_moveTile","tags":["hexGrid"],"description":"Move a tile to new coordinates.","parameters":[{"name":"gridId","in":"path","required":true,"schema":{"type":"string"}},{"name":"q","in":"path","required":true,"schema":{"type":"string"}},{"name":"r","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GridTile"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GridTileMoveInput"}}}}}},"/hexgrids/{gridId}/tiles/{q}/{r}/attach":{"post":{"operationId":"hexGrid_attachTodo","tags":["hexGrid"],"description":"Attach a todo to a tile.","parameters":[{"name":"gridId","in":"path","required":true,"schema":{"type":"string"}},{"name":"q","in":"path","required":true,"schema":{"type":"string"}},{"name":"r","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GridTile"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GridTileAttachTodoInput"}}}}}},"/hexgrids/{gridId}/tiles/{q}/{r}/detach":{"post":{"operationId":"hexGrid_detachTodo","tags":["hexGrid"],"description":"Detach the todo from a tile.","parameters":[{"name":"gridId","in":"path","required":true,"schema":{"type":"string"}},{"name":"q","in":"path","required":true,"schema":{"type":"string"}},{"name":"r","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GridTile"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GridTileDetachTodoInput"}}}}}},"/hexgrids/{gridId}/tiles/swap":{"post":{"operationId":"hexGrid_swapTodos","tags":["hexGrid"],"description":"Swap todos between two tiles.","parameters":[{"name":"gridId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessResponse"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GridTileSwapInput"}}}}}},"/projects/{projectId}/hexgrids/seed":{"post":{"operationId":"hexGrid_seedDefaultGrid","tags":["hexGrid"],"description":"Delete all grids and seed default Digital Presence grid with 22 tiles.","parameters":[{"name":"projectId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessResponse"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectIdInput"}}}}}},"/tiles/by-todo/{todoId}":{"get":{"operationId":"hexGrid_findTilesByTodo","tags":["hexGrid"],"description":"Find all tiles associated with a todo across grids.","parameters":[{"name":"todoId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/GridTile"}}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}}},"/projects/{projectId}/recommendations/generate":{"post":{"operationId":"recommendation_generate","tags":["recommendation"],"description":"Ask the Business Analyzer to produce recommendation proposals. `direction` is a free-text steer sent as a chat message; the run reuses the project's ongoing analyzer chat so steering and dismissal feedback accrue.","parameters":[{"name":"projectId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecommendationGenerateResponse"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecommendationGenerateInput"}}}}}},"/projects/{projectId}/recommendations":{"post":{"operationId":"recommendation_create","tags":["recommendation"],"description":"Propose a spec as a PROPOSED todo on a project (used by `todoforai-cli recommend`; the spec must already exist in the registry). Re-proposing the same spec refreshes the open proposal instead of duplicating it.","parameters":[{"name":"projectId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Todo"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlacementCreateInput"}}}}}},"/auth/resolve":{"get":{"operationId":"auth_resolve","tags":["auth"],"description":"Resolve the bearer token to a user identity.","responses":{"200":{"description":"Successful response"},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}}},"/cli/device/token":{"post":{"operationId":"cli_device_token","tags":["cli"],"description":"Exchange deviceId + deviceSecret for a fresh device-session token (dst_). Used by tfa-* CLIs to self-renew an expired apiToken.","responses":{"200":{"description":"Successful response"},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}}},"/cli/login/init":{"post":{"operationId":"cli_login_init","tags":["cli"],"description":"Initiate CLI login flow. Returns a device code and browser URL for the user to approve.","responses":{"200":{"description":"Successful response"},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}}},"/cli/login/poll":{"get":{"operationId":"cli_login_poll","tags":["cli"],"description":"Poll for CLI login completion. Returns apiKey (or device credentials for bridge clients) once the user has approved.","responses":{"200":{"description":"Successful response"},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}}},"/cli/enroll/mint":{"post":{"operationId":"enroll_mint","tags":["enroll"],"description":"Mint a short-lived enrollment token. Use it on a new host with `todoforai-bridge login --token <token>` to provision a device for the same user.","responses":{"200":{"description":"Successful response"},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}}},"/cli/enroll/redeem":{"post":{"operationId":"enroll_redeem","tags":["enroll"],"description":"Redeem an enrollment token for fresh device credentials. Single-use. Redeemer self-identifies via the `identity` bag (deviceType + uname/distro/host info); unknown deviceType falls back to UNKNOWN. Optional `deviceName` overrides the hostname-derived default.","responses":{"200":{"description":"Successful response"},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}}},"/onboarding":{"get":{"operationId":"onboarding_get","tags":["onboarding"],"description":"Get the onboarding doc for the authenticated user (auto-created on first read).","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Onboarding"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}},"put":{"operationId":"onboarding_update","tags":["onboarding"],"description":"Patch the onboarding doc. Last-write-wins via expectedUpdatedAt.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Onboarding"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OnboardingUpdateInput"}}}}}},"/sandboxes":{"get":{"operationId":"sandbox_list","tags":["sandbox"],"description":"List the authenticated user's sandboxes.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SandboxRecord"}}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}},"post":{"operationId":"sandbox_create","tags":["sandbox"],"description":"Create (or recover) the authenticated user's hosted desktop. Idempotent: if an aligned sandbox already exists it is returned, so a dead/missing one is healed rather than 409'd.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"null"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmptyInput"}}}}}},"/sandboxes/{sandboxId}":{"delete":{"operationId":"sandbox_delete","tags":["sandbox"],"description":"Delete a sandbox. Refuses if it is the user's only VM.","parameters":[{"name":"sandboxId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"null"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}}},"/codex/imagegen":{"post":{"operationId":"codex_imageGen","tags":["codex"],"description":"Generate or edit an image via Codex's native image_generation tool. Returns base64 image bytes.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CodexImageGenOutput"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CodexImageGenInput"}}}}}},"/rclone-oauth/start":{"post":{"operationId":"rcloneOauth_start","tags":["rcloneOauth"],"description":"Begin an rclone OAuth flow. Returns the provider authorize URL plus the rclone remote name that will be created on the target device upon successful callback.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RcloneOauthStartOutput"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RcloneOauthStartInput"}}}}}},"/rclone-oauth/complete":{"post":{"operationId":"rcloneOauth_complete","tags":["rcloneOauth"],"description":"Exchange an OAuth authorization code for tokens and write the resulting rclone remote to the target device.","responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RcloneOauthCompleteOutput"}}}},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RcloneOauthCompleteInput"}}}}}},"/frontend/call":{"post":{"operationId":"frontendHost_execute","tags":["frontendHost"],"description":"Execute a capability on the user's live frontend (surface render/clear, control get/set). Used by the tfa-surface CLI.","responses":{"200":{"description":"Successful response"},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}}},"/frontend/catalog":{"get":{"operationId":"frontendHost_catalog","tags":["frontendHost"],"description":"The frontend host's capability catalog (surfaces + controls with effect/permission metadata).","responses":{"200":{"description":"Successful response"},"default":{"description":"Error response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["message","code"]}}}}}}}},"components":{"schemas":{"EmptyInput":{"type":"object","properties":{},"required":[]},"UserProfileFull":{"type":"object","properties":{"user":{"$ref":"#/components/schemas/UserProfile"},"settings":{"$ref":"#/components/schemas/AppSettings"},"onboarding":{"$ref":"#/components/schemas/Onboarding"}},"required":["user","settings","onboarding"],"description":"User profile with app settings + onboarding doc."},"UserProfile":{"type":"object","properties":{"id":{"type":"string"},"lastProjectId":{"type":"string"},"manualBalance":{"type":"number"},"subscriptionBalance":{"type":"number"},"stripeCustomerId":{"type":"string"},"projectIdToAgentId":{"$ref":"#/components/schemas/Recordstringstring"},"selectedBusinessContextId":{"type":"string"}},"required":["id","lastProjectId","manualBalance","subscriptionBalance"]},"Recordstringstring":{"type":"object","properties":{},"required":[],"description":"Construct a type with a set of properties K of type T","additionalProperties":{"type":"string"}},"AppSettings":{"type":"object","properties":{"id":{"type":"string"},"theme":{"type":"string"},"previewAutoColumns":{"type":"number","description":"Preferred column count used by the automatic preview-window layout. Defaults to 3."},"todoListTheme":{"oneOf":[{"const":"terminal"},{"const":"weblike"}]},"diffControl":{"type":"string"},"shellExecution":{"type":"string"},"emailNotifications":{"type":"boolean"},"pushNotifications":{"type":"boolean"},"dataAnalytics":{"type":"boolean"},"playSoundOnTaskComplete":{"type":"boolean"},"showTodoCompletionToast":{"type":"boolean"},"tabNotificationMode":{"oneOf":[{"const":"off","description":"Never show the red dot."},{"const":"until_focus","description":"Keep the dot until you return focus to the tab."},{"const":"until_interact","description":"Keep the dot until you click or type in the tab."}],"description":"How the browser-tab red \"done\" dot behaves after a TODO finishes."},"disabledMentionSources":{"type":"array","items":{"type":"string"},"description":"Disabled"},"keyboardBindings":{"$ref":"#/components/schemas/Recordstringstring"},"keyboardShortcutsEnabled":{"type":"boolean"},"defaultViewMode":{"type":"string"},"modelMentionAliases":{"type":"array","items":{"type":"string"},"description":"Enabled model-mention aliases (e.g. 'claude', 'gpt') for"},"showDiffMergeControls":{"type":"boolean","description":"Show accept/reject chunk controls in the diff (merge) view. Off by\ndefault — with auto-apply the diff is just a record of what got applied,\nso the controls are unnecessary noise."},"showAgentColors":{"type":"boolean"},"showAgentNameInComposer":{"type":"boolean","description":"Show the selected agent's name (with an expand chevron) on the collapsed\ncomposer trigger instead of the plain settings cog icon."},"showAllowAllButton":{"type":"boolean"},"showAutoDoneButton":{"type":"boolean","description":"Show the Auto-Done toggle in the message toolbar. When the toggle is on,\nthe next run's successful completion lands the todo in DONE instead of READY."},"showSystemPrompt":{"type":"boolean"},"showAgentJsonExport":{"type":"boolean","description":"Show the JSON export button in the agent settings modal header."},"showCloudWorkspaceBar":{"type":"boolean","description":"Show the workspace bar on the built-in Cloud device card. Hidden by\ndefault — the cloud workspace is always `/root` and virtually nobody\nshould change it."},"showProjectPickerInSidebar":{"oneOf":[{"const":"auto"},{"const":"off"},{"const":"always"}],"description":"Project picker at the top of the todo sidebar (team plan only). `off`\nhides it, `auto` shows it only when you have more than one project,\n`always` keeps it pinned. Defaults to `auto`."},"toolDisplayVerbosityDesktop":{"oneOf":[{"const":"collapsed"},{"const":"normal"},{"const":"debug"}],"description":"Tool-block display density, resolved per viewport. `collapsed` keeps\nnon-essential tool blocks collapsed (one-line summary, click to expand).\n`normal` opens them by default. `debug` additionally surfaces internal\nfields (pid, timeout, …) on shell/bash blocks. Desktop defaults to\n`normal`, mobile to `collapsed`."},"toolDisplayVerbosityMobile":{"oneOf":[{"const":"collapsed"},{"const":"normal"},{"const":"debug"}]},"groupToolDisplay":{"type":"boolean","description":"Collapse consecutive tool-only assistant messages into a single group row.\nBackend defaults to true (the recommended workflow); set false to render\neach tool block individually. Independent of verbose tool display."},"showThinkingTraces":{"type":"boolean","description":"Show the model's reasoning (\"Thinking\") blocks in the chat. Default off;\nwhen off, reason blocks render nothing, which also lets more consecutive\ntool messages collapse into a single group."},"vaultProvider":{"oneOf":[{"type":"null"},{"const":"custom"},{"const":"onepassword"},{"const":"bitwarden"}]},"vaultConfig":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/Recordstringstring"}]},"vaultProviders":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/Recordstring__type"}]},"hostDesktopItems":{"$ref":"#/components/schemas/RecordstringArrayHostDesktopItem","description":"Per-host desktop layout, keyed by host id (device/edge id, or \"cloud\").\nAn ordered list of items; array index IS the order. Items absent from a\nhost's list are appended (in the host's default order) on render, and\nitems whose key no longer exists are dropped."},"companyName":{"type":"string"},"vatNumber":{"type":"string"},"addressLine1":{"type":"string"},"addressLine2":{"type":"string"},"city":{"type":"string"},"state":{"type":"string"},"postalCode":{"type":"string"},"countryISO":{"type":"string"},"addressValid":{"type":"boolean"}},"required":["id","theme","diffControl","shellExecution","emailNotifications","pushNotifications","dataAnalytics","playSoundOnTaskComplete","showTodoCompletionToast"]},"Recordstring__type":{"type":"object","properties":{},"required":[],"description":"Construct a type with a set of properties K of type T","additionalProperties":{"type":"object","properties":{"config":{"$ref":"#/components/schemas/Recordstringstring"},"enabled":{"type":"boolean"}},"required":["config","enabled"]}},"RecordstringArrayHostDesktopItem":{"type":"object","properties":{},"required":[],"description":"Construct a type with a set of properties K of type T","additionalProperties":{"type":"array","items":{"$ref":"#/components/schemas/HostDesktopItem"}}},"HostDesktopItem":{"type":"object","properties":{"key":{"type":"string","description":"Tile identity.key (e.g. \"filesystem\", \"gh\") or widget id (e.g. \"widget:activity\")."},"w":{"type":"number","description":"Column span (default 1)."},"h":{"type":"number","description":"Row span (default 1)."},"kind":{"oneOf":[{"const":"tile"},{"const":"widget"}],"description":"Discriminates render path. Defaults to 'tile' when omitted."}},"required":["key"],"description":"A single item on a host desktop. Order is the array position. A tile is a\n1×1 item (no span); widgets carry an optional w×h span, rendered via CSS\n`grid-column/row: span N` so the existing auto-flow grid packs them and\nstays responsive to the card's fluid width."},"Onboarding":{"type":"object","properties":{"id":{"type":"string","description":"id === userId"},"version":{"type":"number","description":"Schema version for future migrations"},"updatedAt":{"type":"number","description":"Last server-side write timestamp (last-write-wins)"},"startedAt":{"type":"number"},"completedAt":{"type":"number"},"currentStep":{"type":"string"},"websiteUrl":{"type":"string"},"styleAnswers":{"$ref":"#/components/schemas/Recordstringstring"},"styleAiAnswers":{"$ref":"#/components/schemas/RecordstringRecordstringstring","description":"AI-suggested brand-voice drafts, scoped by businessContextId → question → answer"},"voiceProfiles":{"$ref":"#/components/schemas/RecordstringVoiceProfile","description":"Learned voice profile from the refinement loop, scoped by businessContextId."}},"required":["id","version","updatedAt"],"description":"Per-user onboarding state. Stores draft user input + wizard progress.\nStep \"completion\" is derived from real product state, not stored here.\nNo secrets — vault tokens stay in AppSettings.vaultProviders."},"RecordstringRecordstringstring":{"type":"object","properties":{},"required":[],"description":"Construct a type with a set of properties K of type T","additionalProperties":{"$ref":"#/components/schemas/Recordstringstring"}},"RecordstringVoiceProfile":{"type":"object","properties":{},"required":[],"description":"Construct a type with a set of properties K of type T","additionalProperties":{"$ref":"#/components/schemas/VoiceProfile"}},"VoiceProfile":{"type":"object","properties":{"profile":{"type":"string","description":"One-paragraph description of the voice (tone, formality, quirks, do/don't)."},"match":{"type":"number","description":"0–100 how well the final draft matches the target style."},"source":{"oneOf":[{"const":"social"},{"const":"answers"},{"const":"company"}],"description":"Where the voice was learned from:\n - 'answers'  the user's own answers were usable and drove the profile\n - 'company'  the answers were too thin, so the profile is inferred from company info\n - 'social'   inferred from a (mock) connected social account"},"note":{"type":"string","description":"When source==='company': a short note explaining why the answers weren't used."},"iterations":{"type":"array","items":{"$ref":"#/components/schemas/VoiceIteration"},"description":"The refinement passes, oldest → newest, so the UI can show the loop converging."},"channel":{"type":"string","description":"Optional label of the mock social channel this came from (source==='social')."},"answerFeedback":{"$ref":"#/components/schemas/Recordstringstring","description":"Per-answer feedback (question → hint) for answers too weak to learn a style from."},"updatedAt":{"type":"number"}},"required":["profile","match","source","iterations","updatedAt"],"description":"A learned company/personal writing voice — the distilled output of the voice\nrefinement loop. Used to make agents write in the user's style."},"VoiceIteration":{"type":"object","properties":{"sample":{"type":"string","description":"Sample line rewritten in the learned voice for this pass."},"match":{"type":"number","description":"0–100 self-assessed match to the target style after this pass."},"critique":{"type":"string","description":"What changed / what was still off this pass (one short sentence)."}},"required":["sample","match","critique"],"description":"One pass of the voice refinement loop."},"AccountDataExport":{"type":"object","properties":{"exportedAt":{"type":"string"},"user":{},"profile":{},"settings":{},"onboarding":{},"authSessions":{"type":"array","items":{}},"authAccounts":{"type":"array","items":{}},"projects":{"type":"array","items":{}},"projectSettings":{"type":"array","items":{}},"todos":{"type":"array","items":{}},"messages":{"type":"array","items":{}},"agentSettings":{"type":"array","items":{}},"edges":{"type":"array","items":{}},"devices":{"type":"array","items":{}},"apiKeys":{"type":"array","items":{}},"tasks":{"type":"array","items":{}},"scheduledTasks":{"type":"array","items":{}},"usage":{"type":"array","items":{}},"transactions":{"type":"array","items":{}},"externalDataSources":{"type":"array","items":{}},"todoCosts":{"type":"array","items":{}},"hexGrids":{"type":"array","items":{}},"gridTiles":{"type":"array","items":{}},"attachments":{"type":"array","items":{}},"businessContexts":{"type":"array","items":{}},"vault":{"type":"object","properties":{"paths":{"type":"array","items":{"type":"string"}}},"required":["paths"]}},"required":["exportedAt","user","profile","settings","onboarding","authSessions","authAccounts","projects","projectSettings","todos","messages","agentSettings","edges","devices","apiKeys","tasks","scheduledTasks","usage","transactions","externalDataSources","todoCosts","hexGrids","gridTiles","attachments","businessContexts","vault"],"description":"Portable account-record export. Known credential fields, vault values, and file bytes are omitted."},"SuccessResponse":{"type":"object","properties":{"success":{"type":"boolean"}},"required":["success"]},"ProjectIdInput":{"type":"object","properties":{"projectId":{"type":"string"}},"required":["projectId"]},"ProjectAgentSelectionInput":{"type":"object","properties":{"projectId":{"type":"string"},"agentSettingsId":{"type":"string"}},"required":["projectId","agentSettingsId"],"description":"Input for selecting/assigning an agent to a project."},"UsageQueryInput":{"type":"object","properties":{"startDate":{"type":"string"},"endDate":{"type":"string"}},"required":[]},"Usage":{"type":"object","properties":{"dailyUsages":{"type":"array","items":{"$ref":"#/components/schemas/DailyUsage"}}},"required":["dailyUsages"]},"DailyUsage":{"type":"object","properties":{"dayTS":{"type":"number"},"totalSpent":{"type":"number"},"totalAdded":{"type":"number"},"messageCount":{"type":"number"},"mcpUsageCount":{"type":"number"},"modelUsage":{"$ref":"#/components/schemas/Recordstring__type"},"updatedAt":{"type":"number"}},"required":["dayTS","totalSpent","totalAdded","messageCount","mcpUsageCount","modelUsage","updatedAt"]},"TeamUsageResponse":{"type":"object","properties":{"startTS":{"type":"number","description":"Inclusive day range actually covered, ms timestamps at day start."},"endTS":{"type":"number"},"totalSpent":{"type":"number","description":"Sum of `members[].spent` — what the team pool paid out in the window."},"members":{"type":"array","items":{"$ref":"#/components/schemas/TeamMemberUsage"}}},"required":["startTS","endTS","totalSpent","members"]},"TeamMemberUsage":{"type":"object","properties":{"userId":{"type":"string"},"email":{"type":"string"},"name":{"type":"string"},"role":{"$ref":"#/components/schemas/TeamRole"},"former":{"type":"boolean","description":"Spent from the pool while on the team, but no longer a member."},"spent":{"type":"number","description":"Spend funded by the team pool in the window, in $."},"messageCount":{"type":"number"}},"required":["userId","email","role","spent","messageCount"],"description":"Per-member spend for the team usage dashboard (owner/admin only)."},"TeamRole":{"oneOf":[{"const":"owner"},{"const":"admin"},{"const":"member"}],"description":"Role of a user within a team (IAM). owner: billing + full control;\nadmin: manage members; member: belongs only."},"ProjectFull":{"type":"object","properties":{"project":{"$ref":"#/components/schemas/Project"},"settings":{"$ref":"#/components/schemas/ProjectSettings"},"doneCount":{"type":"number","description":"Count of todos in the DONE stage — O(1) ZCARD, kept accurate independent of\nwhat the paginated todo list has loaded. Todo count = todoIds.length - doneCount."}},"required":["project","settings","doneCount"],"description":"Project with its settings."},"Project":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"projectSettingsId":{"type":"string"},"ownerId":{"type":"string"},"ownerEmail":{"type":"string"},"isPublic":{"type":"boolean"},"todoIds":{"type":"array","items":{"type":"string"}},"readAccessIds":{"type":"array","items":{"type":"string"},"description":"User IDs with read access"},"writeAccessIds":{"type":"array","items":{"type":"string"},"description":"User IDs with write access"},"readAccessEmails":{"type":"array","items":{"type":"string"}},"writeAccessEmails":{"type":"array","items":{"type":"string"}},"status":{"$ref":"#/components/schemas/ProjectStatus"},"isDefault":{"type":"boolean"},"businessContextId":{"type":"string","description":"The brand/business context this project is about (project-scoped brand page)."},"createdAt":{"type":"number"},"updatedAt":{"type":"number"},"archivedAt":{"type":"number"},"deletedAt":{"type":"number"}},"required":["id","name","description","projectSettingsId","ownerId","ownerEmail","isPublic","todoIds","readAccessIds","writeAccessIds","readAccessEmails","writeAccessEmails","status","isDefault","createdAt","updatedAt"],"description":"A project organizes todos."},"ProjectStatus":{"oneOf":[{"const":"ACTIVE"},{"const":"ARCHIVED"},{"const":"MARKED_DELETED"}]},"ProjectSettings":{"type":"object","properties":{"id":{"type":"string"},"projectId":{"type":"string"}},"required":["id","projectId"]},"ProjectBrandResponse":{"type":"object","properties":{"businessContextId":{"type":"string"},"markdown":{"type":"string"}},"required":[],"description":"A project's brand page markdown, read via project access (honors project.isPublic)\nrather than business-context ownership — so a public project's brand is readable by\nnon-owners/anonymous visitors. `markdown` is undefined when the project has no brand."},"ProjectCreateInput":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string"},"isPublic":{"type":"boolean"}},"required":["name","isPublic"]},"ProjectUpdateInput":{"type":"object","properties":{"projectId":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"isPublic":{"type":"boolean"},"status":{"oneOf":[{"const":"ACTIVE"},{"const":"ARCHIVED"},{"const":"MARKED_DELETED"}]},"businessContextId":{"type":"string"}},"required":["projectId"]},"ShareProjectInput":{"type":"object","properties":{"email":{"type":"string","format":"email"},"projectId":{"type":"string"},"canWrite":{"type":"boolean"}},"required":["email","projectId","canWrite"],"description":"ShareProjectInput with email validation"},"CreateTodoInput":{"type":"object","properties":{"projectId":{"type":"string"},"content":{"type":"string"},"agentSettings":{"$ref":"#/components/schemas/AgentSettings"},"attachments":{"type":"array","items":{"$ref":"#/components/schemas/AttachmentFrame"}},"scheduledTimestamp":{"type":"number"},"filteredEdgeTools":{"$ref":"#/components/schemas/RecordstringArrayMCPToolSkeleton"},"todoId":{"type":"string"},"businessContextId":{"type":"string"},"groupTag":{"type":"string","description":"Group slug. Empty/absent means ungrouped."},"groupName":{"type":"string","description":"Optional display name to upsert for groupTag."},"visible":{"type":"boolean","description":"Visible in the project's default todo list. Defaults to true; subagent\nruns (tfa-*) pass false. Hidden todos are still accessible by id."},"autoDone":{"type":"boolean","description":"When true, successful completion lands in DONE (strikethrough/terminal)\ninstead of READY. For plumbing todos that don't need user ack."}},"required":["projectId","content","agentSettings"],"description":"CreateTodoInput - combines projectId with TodoCreateInput fields"},"AgentSettings":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"ownerId":{"type":"string"},"systemMessage":{"type":"string","description":"Custom system prompt for the agent"},"model":{"type":"string","description":"LLM model identifier (e.g., 'claude-3-opus')"},"thinkingLevel":{"oneOf":[{"const":"max"},{"const":"ultra"},{"const":"low"},{"const":"medium"},{"const":"high"},{"const":"xhigh"}]},"temperature":{"type":"number"},"systemMessageMode":{"oneOf":[{"const":"raw"},{"const":"default_coder"},{"const":"custom_w_tools"}],"description":"'default_coder' uses built-in coding prompt, 'custom_w_tools' uses systemMessage + auto-injected\ncapability sections, 'raw' uses systemMessage verbatim (no global prepend, no tool/routing/workspace sections)."},"smartSystemPrompt":{"type":"boolean","description":"Auto-enhance system prompt based on context"},"mcpConfigs":{"$ref":"#/components/schemas/MCPSettings","description":"Cloud MCP server configurations"},"edgesMcpConfigs":{"$ref":"#/components/schemas/MCPEdgesSettings","description":"Edge device MCP configurations by edgeId"},"devicesConfig":{"$ref":"#/components/schemas/DevicesConfig","description":"Bridge device workspace + cwd config by deviceId. Parallel to `edgesMcpConfigs`."},"permissions":{"$ref":"#/components/schemas/ToolPermissions","description":"Tool permission allowlist"},"specId":{"type":"string","description":"Spec this agent was created from"},"color":{"type":"string","description":"Hex color (e.g. '#10b981') used to tint todos assigned to this agent"},"createdAt":{"type":"number"},"updatedAt":{"type":"number"}},"required":["id","name","ownerId","mcpConfigs","edgesMcpConfigs","createdAt","updatedAt"],"description":"AI AgentSettings configuration including model, system prompt, and MCP tools."},"MCPSettings":{"type":"object","properties":{"deviceType":{"oneOf":[{"const":"PC"},{"const":"ANDROID"},{"const":"IOS"},{"const":"WEB_EXTENSION"},{"const":"EXTENSION"},{"const":"cli"},{"const":"SHELL"},{"const":"SANDBOX","description":"Ephemeral Firecracker VM — bridge connects back via enroll_token"},{"const":"BROWSER","description":"In-tab browser edge: File System Access API mounted folder, read+write via WS"},{"const":"UNKNOWN","description":"Redeemer didn't (or couldn't) self-identify — fall back so the device still gets created."}],"description":"Edge device type — used by the Julia agent for capability checks (e.g. has_shell)."},"installedTools":{"$ref":"#/components/schemas/RecordstringCatalogToolState","description":"Catalog tool states injected by the backend at submit time."},"enabled":{"type":"boolean","description":"Per-agent edge on/off. `false` removes this edge from the agent's tool\nspec at run time (filtered in AgentSettingsService.prepareForAgent).\nUndefined/true = on."},"name":{"type":"string","description":"Edge identity surfaced at submit time (enrichWithOnlineEdges) so the agent\ncan use it for the tool-alias suffix (bash_<name>) and the `### <name>`\nheading in `## Available Machines`.\nTODO: revisit — questionable whether this belongs here. (1) For real edges\n`name` is an auto-generated junk label (e.g. \"PC_8814\" = {deviceType}_{rand}),\nwhich gives the agent no useful alias/heading; only bridge devices have a\nmeaningful user-given name. (2) name/metadata duplicate Edge.* and bloat\nevery per-agent record. Consider passing identity out-of-band instead of\nstuffing it into edgesMcpConfigs."},"metadata":{"$ref":"#/components/schemas/Recordstringany"}},"required":[],"description":"Per-edge config bag. Mostly serverId → ServerSettings, but also carries\nedge-level metadata (deviceType, installedTools) used by the agent runtime.\nTODO: rename to EdgeConfig — see plan/edge-config-rename.md","additionalProperties":{"oneOf":[{"type":"string"},{"type":"boolean"},{"$ref":"#/components/schemas/RecordstringCatalogToolState"},{"$ref":"#/components/schemas/ServerSettings"}]}},"RecordstringCatalogToolState":{"type":"object","properties":{},"required":[],"description":"Construct a type with a set of properties K of type T","additionalProperties":{"$ref":"#/components/schemas/CatalogToolState"}},"CatalogToolState":{"type":"object","properties":{"installed":{"type":"boolean","description":"Whether the binary is found on PATH"},"version":{"type":"string","description":"Output of versionCmd (e.g. \"v1.2.3\"), undefined if not run or no versionCmd"},"statusOutput":{"type":"string","description":"Output of statusCmd (e.g. logged-in user), undefined if not run or no statusCmd"},"authenticated":{"type":"boolean","description":"Whether statusCmd exited 0 (authenticated/ready)"},"description":{"type":"string","description":"User description override from the edge's ~/.todoforai/custom_tools.json,\nfolded into the scan result edge-side. Takes precedence over the catalog\ndescription in the agent's bash tool CLI list, and lets non-catalog\nbinaries (found on PATH) be advertised."},"label":{"type":"string","description":"User label override (custom_tools.json), same mechanism as `description`."}},"required":["installed"],"description":"Per-tool state reported by the edge."},"Recordstringany":{"type":"object","properties":{},"required":[],"description":"Construct a type with a set of properties K of type T","additionalProperties":{}},"ServerSettings":{"type":"object","properties":{},"required":[],"additionalProperties":{"oneOf":[{"type":"boolean"},{"type":"array","items":{"type":"string"}},{"$ref":"#/components/schemas/ToolConfiguration"}]}},"ToolConfiguration":{"type":"object","properties":{},"required":[],"additionalProperties":{"$ref":"#/components/schemas/ToolConfigurationValue"}},"ToolConfigurationValue":{"oneOf":[{"type":"null"},{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"array","items":{"type":"string"}},{"$ref":"#/components/schemas/Recordstringstring"}],"description":"JSON-compatible configuration value accepted by MCP tool settings."},"MCPEdgesSettings":{"type":"object","properties":{},"required":[],"additionalProperties":{"$ref":"#/components/schemas/MCPSettings"}},"DevicesConfig":{"type":"object","properties":{},"required":[],"additionalProperties":{"$ref":"#/components/schemas/DeviceConfig"}},"DeviceConfig":{"type":"object","properties":{"workspacePaths":{"type":"array","items":{"type":"string"}},"enabled":{"oneOf":[{"const":"auto"},{"const":"on"},{"type":"boolean"}],"description":"Per-agent device state. For ordinary devices, false disables and every\nother value enables. The hosted cloud VM additionally supports:\n  false              → Off.\n  'auto'             → use only when no local desktop is online.\n  'on'               → explicitly always on (overrides global Auto/Off).\n  true / undefined   → enabled, inheriting the per-user global cloud mode.\n`true` remains the inherited state for compatibility with existing agent\nrecords, where it was written before explicit cloud modes existed."},"deviceType":{"oneOf":[{"const":"PC"},{"const":"ANDROID"},{"const":"IOS"},{"const":"WEB_EXTENSION"},{"const":"EXTENSION"},{"const":"cli"},{"const":"SHELL"},{"const":"SANDBOX","description":"Ephemeral Firecracker VM — bridge connects back via enroll_token"},{"const":"BROWSER","description":"In-tab browser edge: File System Access API mounted folder, read+write via WS"},{"const":"UNKNOWN","description":"Redeemer didn't (or couldn't) self-identify — fall back so the device still gets created."}],"description":"Device type — used by the agent for capability checks (e.g. has_shell vs\nhas_cdp). Surfaced at submit time by enrichWithOnlineDevices."},"name":{"type":"string","description":"Device identity surfaced at submit time so the agent can render the\ndevice in `## Available Machines` (name heading, tool-alias suffix)."},"metadata":{"$ref":"#/components/schemas/Recordstringany"},"installedTools":{"$ref":"#/components/schemas/RecordstringCatalogToolState","description":"Catalog tool states injected by the backend at submit time."}},"required":["workspacePaths"],"description":"Per-device agent config — active workspace selection for bridge devices.\nParallel to `MCPEdgesSettings` but for lightweight bridge-authenticated machines.\n\n`workspacePaths` ⊆ `Device.workspacepaths`. Order matters: `[0]` is the primary\nand is used as the shell `cwd`. To change the cwd, reorder the array.\n\nResolution at exec time:\n  workspacePaths[0] ?? device.metadata.identity.cwd"},"ToolPermissions":{"type":"object","properties":{"allow":{"type":"array","items":{"type":"string"},"description":"Tools/patterns that auto-execute without approval"},"ask":{"type":"array","items":{"type":"string"},"description":"Tools that require user approval (default if not in any list)"},"deny":{"type":"array","items":{"type":"string"},"description":"Tools/patterns blocked from execution"}},"required":["allow"]},"AttachmentFrame":{"type":"object","properties":{"id":{"type":"string"},"uri":{"type":"string","description":"Resource URI - always required. Format: \"todoforai:todos/{todoId}/{id}\""},"originalName":{"type":"string"},"mimeType":{"type":"string"},"fileSize":{"type":"number","description":"In bytes"},"createdAt":{"type":"number"},"isPublic":{"type":"boolean"},"status":{"oneOf":[{"const":"UPDATED"},{"const":"DELETED"},{"const":"NEW"},{"const":"NONE"}]},"modifiedAt":{"type":"number","description":"Last modified time (mtime), milliseconds epoch"},"permissions":{"type":"number","description":"Unix permission bits (e.g. 0o644 = 420 decimal)"},"blockId":{"type":"string","description":"Block ID that produced this attachment (for mapping tool results back to tool_calls)"},"toolCallId":{"type":"string","description":"LLM tool_call ID — for stamping results back to the originating tool call"}},"required":["id","uri","originalName","mimeType","fileSize"],"description":"Base attachment metadata type - reference only, no content.\nURI is always required and is the source of truth reference.\nFormat: \"todoforai:todos/{todoId}/{id}\""},"RecordstringArrayMCPToolSkeleton":{"type":"object","properties":{},"required":[],"description":"Construct a type with a set of properties K of type T","additionalProperties":{"type":"array","items":{"$ref":"#/components/schemas/MCPToolSkeleton"}}},"MCPToolSkeleton":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string"},"inputSchema":{"$ref":"#/components/schemas/Recordstringunknown"}},"required":["name","description","inputSchema"]},"Recordstringunknown":{"type":"object","properties":{},"required":[],"description":"Construct a type with a set of properties K of type T","additionalProperties":{}},"Todo":{"type":"object","properties":{"id":{"type":"string"},"projectId":{"type":"string"},"status":{"$ref":"#/components/schemas/TodoStatus"},"agentSettingsId":{"type":"string"},"businessContextId":{"type":"string","description":"Domain-specific knowledge context"},"groupTag":{"type":"string","description":"Project-scoped group slug."},"systemMessageId":{"type":"string"},"content":{"type":"string"},"messageIds":{"type":"array","items":{"type":"string"}},"messages":{"type":"array","items":{"$ref":"#/components/schemas/Message"}},"checkedBlockIds":{"type":"array","items":{"type":"string"},"description":"User-checked blocks"},"actionableBlockIds":{"type":"array","items":{"type":"string"},"description":"Blocks with code, commands, etc."},"createdAt":{"type":"number"},"archivedAt":{"type":"number"},"deletedAt":{"type":"number"},"dismissedAt":{"type":"number","description":"When the proposal was dismissed — bounds the analyzer's feedback window."},"starredAt":{"type":"number","description":"Star/favorite timestamp; absent/0 = not starred"},"lastActivityAt":{"type":"number"},"scheduledTimestamp":{"type":"number","description":"0 if immediate"},"workflowVersion":{"type":"string","description":"For optimistic concurrency"},"filteredEdgeTools":{"$ref":"#/components/schemas/RecordstringArrayMCPToolSkeleton","description":"Edge tool filter — persisted so flushToolMessage can forward it on continuation"},"visible":{"type":"boolean","description":"Visible in default project listings; defaults to true."},"isPublic":{"type":"boolean","description":"Publicly viewable (read-only) by anyone with the link, no login required."},"hasMoreMessages":{"type":"boolean","description":"True when `messages` holds only the newest page — older ones via todo.getMessages."}},"required":["id","projectId","status","agentSettingsId","content","messageIds","messages","createdAt","lastActivityAt","scheduledTimestamp"],"description":"Full todo with messages and metadata."},"TodoStatus":{"oneOf":[{"const":"PROPOSED"},{"const":"DISMISSED"},{"const":"TODO"},{"const":"SCHEDULED"},{"const":"PAUSED"},{"const":"POSTPONED"},{"const":"REVIEW_REQUESTED"},{"const":"RUNNING"},{"const":"WAITING_FOR_USER"},{"const":"COMPACTING"},{"const":"STOPPING"},{"const":"READY"},{"const":"READY_CHECKED"},{"const":"DONE"},{"const":"CANCELLED"},{"const":"CANCELLED_CHECKED"},{"const":"ERROR"},{"const":"ERROR_CHECKED"},{"const":"ARCHIVED"},{"const":"DELETED"}]},"Message":{"type":"object","properties":{"id":{"type":"string"},"todoId":{"type":"string"},"projectId":{"type":"string","description":"Project the todo belongs to (denormalized for search; absent on legacy messages)."},"content":{"type":"string"},"role":{"type":"string","description":"'user', 'assistant', or 'system'"},"agentSettingsId":{"type":"string"},"stop_sequence":{"type":"string","description":"Stop sequence that ended AI response, if any"},"createdAt":{"type":"number"},"blocks":{"type":"array","items":{"$ref":"#/components/schemas/MessageBlock"},"description":"Parsed content blocks (code, tool calls, text)"},"scheduledTimestamp":{"type":"number","description":"0 if sent immediately"},"attachments":{"type":"array","items":{"$ref":"#/components/schemas/AttachmentFrame"}},"runMeta":{"type":"array","items":{"$ref":"#/components/schemas/RunMeta"},"description":"Token usage, model info, etc."},"systemPrompt":{"type":"string","description":"System prompt used for this assistant message (dev mode)"},"predictedReply":{"type":"string","description":"Predicted next user message (ghost text), computed once per finished assistant turn by\nreusing the warm prompt cache. Set only on assistant messages; throwaway, never fed back."},"parentBlockId":{"type":"string","description":"If set, this message belongs to a sub-agent spawned by the given block"}},"required":["id","todoId","content","role","agentSettingsId","stop_sequence","createdAt","blocks","scheduledTimestamp","attachments"],"description":"A message in a todo conversation."},"MessageBlock":{"oneOf":[{"$ref":"#/components/schemas/ReadBlock"},{"$ref":"#/components/schemas/CreateBlock"},{"$ref":"#/components/schemas/WriteBlock"},{"$ref":"#/components/schemas/EditBlock"},{"$ref":"#/components/schemas/ModifyFileBlock"},{"$ref":"#/components/schemas/BashBlock"},{"$ref":"#/components/schemas/GrepBlock"},{"$ref":"#/components/schemas/ListBlock"},{"$ref":"#/components/schemas/SkillBlock"},{"$ref":"#/components/schemas/ApiBlock"},{"$ref":"#/components/schemas/ImageGenBlock"},{"$ref":"#/components/schemas/ShowBlock"},{"$ref":"#/components/schemas/HtmlSnippetBlock"},{"$ref":"#/components/schemas/LivePreviewBlock"},{"$ref":"#/components/schemas/TextBlock"},{"$ref":"#/components/schemas/ReasonBlock"},{"$ref":"#/components/schemas/ErrorBlock"},{"$ref":"#/components/schemas/CompactBlock"},{"$ref":"#/components/schemas/QuestionBlock"},{"$ref":"#/components/schemas/OpenBrowserBlock"},{"$ref":"#/components/schemas/LoginBlock"},{"$ref":"#/components/schemas/BusinessOnboardingBlock"},{"$ref":"#/components/schemas/RequestMcpAccessBlock"},{"$ref":"#/components/schemas/EdgeNotRunningBlock"},{"$ref":"#/components/schemas/WebFetchBlock"},{"$ref":"#/components/schemas/GoogleSearchBlock"},{"$ref":"#/components/schemas/WebSearchBlock"},{"$ref":"#/components/schemas/VaultSearchBlock"},{"$ref":"#/components/schemas/VaultResolveBlock"},{"$ref":"#/components/schemas/VaultWriteBlock"},{"$ref":"#/components/schemas/VaultWriteBatchBlock"},{"$ref":"#/components/schemas/VaultUpdateBlock"},{"$ref":"#/components/schemas/McpBlock"},{"$ref":"#/components/schemas/ExploreBlock"},{"$ref":"#/components/schemas/PlanBlock"},{"$ref":"#/components/schemas/ReviewBlock"},{"$ref":"#/components/schemas/DeviceListBlock"}]},"ReadBlock":{"type":"object","properties":{"type":{"const":"read"},"limit":{"type":"number"},"offset":{"type":"number"},"id":{"type":"string"},"content":{"type":"string"},"status":{"$ref":"#/components/schemas/BlockStatus"},"generationCompleted":{"type":"boolean"},"result":{"type":"string"},"results":{"type":"array","items":{"$ref":"#/components/schemas/RunResult"}},"runMeta":{"type":"array","items":{"$ref":"#/components/schemas/RunMeta"}},"generalized_pattern":{"oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Generalized permission pattern for \"remember\" feature (e.g., \"BASH(cmd: npm *)\")"},"toolCallId":{"type":"string","description":"LLM API tool_call id — durable mapping from block to the tool_call that created it"},"parentBlockId":{"type":"string","description":"Parent block ID — present on sub-agent child blocks (e.g., read blocks inside explore)"},"deviceId":{"type":"string","description":"Device that executed this tool call. Edges and bridges both map to a device id.\nStamped from internal routing context, not provided by the LLM."},"_issue":{"type":"string","description":"Read-time schema issue: set by the tRPC soft-output validator when this\nblock failed output validation (e.g. legacy/malformed data). Derived on\nevery read from the failing typia path — NEVER persisted to Redis."},"approvalContext":{"type":"object","properties":{"source":{"type":"string"},"toolInstalls":{"type":"array","items":{"type":"string"}},"workspace":{"type":"string"},"edgeId":{"type":"string"}},"required":["source"],"description":"Edge approval context — present when edge requests tool install approval"},"path":{"type":"string"},"language":{"type":"string"}},"required":["type","id","content","status","generationCompleted"]},"BlockStatus":{"oneOf":[{"const":"PENDING"},{"const":"AWAITING_APPROVAL"},{"const":"RUNNING"},{"const":"COMPLETED"},{"const":"DENIED"},{"const":"ERROR"}],"description":"BlockStatus - lifecycle states"},"RunResult":{"type":"object","properties":{"attachments":{"type":"array","items":{"$ref":"#/components/schemas/AttachmentFrame"}},"meta":{"$ref":"#/components/schemas/RunResultMeta"}},"required":["attachments","meta"]},"RunResultMeta":{"type":"object","properties":{"timestamp":{"type":"number"},"tool_name":{"type":"string"},"success":{"type":"boolean"},"error":{"type":"string"},"elapsed":{"type":"number"},"arguments":{},"inputTokens":{"type":"number"},"outputTokens":{"type":"number"}},"required":[]},"RunMeta":{"type":"object","properties":{"cost":{"type":"number"},"type":{"type":"string"},"description":{"type":"string"},"timestamp":{"type":"number"},"elapsed":{"type":"number"},"extras":{"type":"object","properties":{"model":{"type":"string"},"inputTokens":{"type":"number"},"outputTokens":{"type":"number"},"cacheReadTokens":{"type":"number"},"cacheWriteTokens":{"type":"number"},"contextTokens":{"type":"number","description":"Absolute current context size (full prompt tokens) as the agent sees it.\nUnlike inputTokens (a per-turn delta on AI meta), this is the authoritative\ntotal used for the context indicator and resets automatically after compaction."},"fundedBy":{"oneOf":[{"const":"starter"},{"const":"pro"},{"const":"ultra"},{"const":"team"},{"const":"scale"},{"const":"credits"}],"description":"Funding source resolved at charge time: a paid subscription tier name\nwhen plan-funded (window-paced), or 'credits' (real money: manual top-up,\npay-as-you-go, free tier, or overflow). Unset on legacy/pre-feature meta."}},"required":[]}},"required":["cost","timestamp"]},"CreateBlock":{"type":"object","properties":{"type":{"const":"create"},"id":{"type":"string"},"content":{"type":"string"},"status":{"$ref":"#/components/schemas/BlockStatus"},"generationCompleted":{"type":"boolean"},"result":{"type":"string"},"results":{"type":"array","items":{"$ref":"#/components/schemas/RunResult"}},"runMeta":{"type":"array","items":{"$ref":"#/components/schemas/RunMeta"}},"generalized_pattern":{"oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Generalized permission pattern for \"remember\" feature (e.g., \"BASH(cmd: npm *)\")"},"toolCallId":{"type":"string","description":"LLM API tool_call id — durable mapping from block to the tool_call that created it"},"parentBlockId":{"type":"string","description":"Parent block ID — present on sub-agent child blocks (e.g., read blocks inside explore)"},"deviceId":{"type":"string","description":"Device that executed this tool call. Edges and bridges both map to a device id.\nStamped from internal routing context, not provided by the LLM."},"_issue":{"type":"string","description":"Read-time schema issue: set by the tRPC soft-output validator when this\nblock failed output validation (e.g. legacy/malformed data). Derived on\nevery read from the failing typia path — NEVER persisted to Redis."},"approvalContext":{"type":"object","properties":{"source":{"type":"string"},"toolInstalls":{"type":"array","items":{"type":"string"}},"workspace":{"type":"string"},"edgeId":{"type":"string"}},"required":["source"],"description":"Edge approval context — present when edge requests tool install approval"},"path":{"type":"string"},"language":{"type":"string"}},"required":["type","id","content","status","generationCompleted"]},"WriteBlock":{"type":"object","properties":{"type":{"const":"write"},"id":{"type":"string"},"content":{"type":"string"},"status":{"$ref":"#/components/schemas/BlockStatus"},"generationCompleted":{"type":"boolean"},"result":{"type":"string"},"results":{"type":"array","items":{"$ref":"#/components/schemas/RunResult"}},"runMeta":{"type":"array","items":{"$ref":"#/components/schemas/RunMeta"}},"generalized_pattern":{"oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Generalized permission pattern for \"remember\" feature (e.g., \"BASH(cmd: npm *)\")"},"toolCallId":{"type":"string","description":"LLM API tool_call id — durable mapping from block to the tool_call that created it"},"parentBlockId":{"type":"string","description":"Parent block ID — present on sub-agent child blocks (e.g., read blocks inside explore)"},"deviceId":{"type":"string","description":"Device that executed this tool call. Edges and bridges both map to a device id.\nStamped from internal routing context, not provided by the LLM."},"_issue":{"type":"string","description":"Read-time schema issue: set by the tRPC soft-output validator when this\nblock failed output validation (e.g. legacy/malformed data). Derived on\nevery read from the failing typia path — NEVER persisted to Redis."},"approvalContext":{"type":"object","properties":{"source":{"type":"string"},"toolInstalls":{"type":"array","items":{"type":"string"}},"workspace":{"type":"string"},"edgeId":{"type":"string"}},"required":["source"],"description":"Edge approval context — present when edge requests tool install approval"},"path":{"type":"string"},"language":{"type":"string"}},"required":["type","id","content","status","generationCompleted"]},"EditBlock":{"type":"object","properties":{"type":{"const":"edit"},"changes":{"type":"string"},"id":{"type":"string"},"content":{"type":"string"},"status":{"$ref":"#/components/schemas/BlockStatus"},"generationCompleted":{"type":"boolean"},"result":{"type":"string"},"results":{"type":"array","items":{"$ref":"#/components/schemas/RunResult"}},"runMeta":{"type":"array","items":{"$ref":"#/components/schemas/RunMeta"}},"generalized_pattern":{"oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Generalized permission pattern for \"remember\" feature (e.g., \"BASH(cmd: npm *)\")"},"toolCallId":{"type":"string","description":"LLM API tool_call id — durable mapping from block to the tool_call that created it"},"parentBlockId":{"type":"string","description":"Parent block ID — present on sub-agent child blocks (e.g., read blocks inside explore)"},"deviceId":{"type":"string","description":"Device that executed this tool call. Edges and bridges both map to a device id.\nStamped from internal routing context, not provided by the LLM."},"_issue":{"type":"string","description":"Read-time schema issue: set by the tRPC soft-output validator when this\nblock failed output validation (e.g. legacy/malformed data). Derived on\nevery read from the failing typia path — NEVER persisted to Redis."},"approvalContext":{"type":"object","properties":{"source":{"type":"string"},"toolInstalls":{"type":"array","items":{"type":"string"}},"workspace":{"type":"string"},"edgeId":{"type":"string"}},"required":["source"],"description":"Edge approval context — present when edge requests tool install approval"},"path":{"type":"string"},"language":{"type":"string"},"originalContent":{"type":"string"},"modifiedContent":{"type":"string"},"initialOriginalContent":{"type":"string"}},"required":["type","id","content","status","generationCompleted"]},"ModifyFileBlock":{"type":"object","properties":{"type":{"const":"modify_file"},"changes":{"type":"string"},"id":{"type":"string"},"content":{"type":"string"},"status":{"$ref":"#/components/schemas/BlockStatus"},"generationCompleted":{"type":"boolean"},"result":{"type":"string"},"results":{"type":"array","items":{"$ref":"#/components/schemas/RunResult"}},"runMeta":{"type":"array","items":{"$ref":"#/components/schemas/RunMeta"}},"generalized_pattern":{"oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Generalized permission pattern for \"remember\" feature (e.g., \"BASH(cmd: npm *)\")"},"toolCallId":{"type":"string","description":"LLM API tool_call id — durable mapping from block to the tool_call that created it"},"parentBlockId":{"type":"string","description":"Parent block ID — present on sub-agent child blocks (e.g., read blocks inside explore)"},"deviceId":{"type":"string","description":"Device that executed this tool call. Edges and bridges both map to a device id.\nStamped from internal routing context, not provided by the LLM."},"_issue":{"type":"string","description":"Read-time schema issue: set by the tRPC soft-output validator when this\nblock failed output validation (e.g. legacy/malformed data). Derived on\nevery read from the failing typia path — NEVER persisted to Redis."},"approvalContext":{"type":"object","properties":{"source":{"type":"string"},"toolInstalls":{"type":"array","items":{"type":"string"}},"workspace":{"type":"string"},"edgeId":{"type":"string"}},"required":["source"],"description":"Edge approval context — present when edge requests tool install approval"},"path":{"type":"string"},"language":{"type":"string"},"originalContent":{"type":"string"},"modifiedContent":{"type":"string"},"initialOriginalContent":{"type":"string"}},"required":["type","id","content","status","generationCompleted"]},"BashBlock":{"type":"object","properties":{"type":{"const":"bash"},"cmd":{"type":"string"},"timeout":{"type":"number"},"language":{"type":"string"},"fileChanges":{"type":"array","items":{"$ref":"#/components/schemas/FileChange"},"description":"Files changed by this command (edge git tracking; overwritten on re-run)."},"target":{"type":"string"},"cwd":{"type":"string"},"pid":{"type":"number","description":"OS PID of the persistent shell inside the bridge PTY. Surfaced on\nRUN_STARTED so the UI can address the session for stdin / force-kill.\nSIGINT is delivered as `\\x03` through the regular stdin path — the\nkernel TTY line discipline forwards it to the foreground process group,\nso no separate fg pid is needed on the block."},"awaitingInput":{"type":"boolean","description":"Bridge reported STEP_AWAITING_INPUT — foreground command parked in\nn_tty_read, waiting on stdin. The shell itself is alive."},"passwordPrompt":{"type":"boolean","description":"Only meaningful when `awaitingInput === true`: PTY slave has ECHO\ndisabled (sudo / getpass / ssh / git credential). UI should mask input."},"subTodoIds":{"type":"array","items":{"type":"string"},"description":"Sub-agent runs spawned by the command as real (hidden) todos — tfa-* CLIs\nstamp these via POST /todos/{id}/blocks/{id}/subtodo. One command can\nspawn several (`a & b & wait`), so each gets its own nested trace in the\nUI, in link order."},"subTodoId":{"type":"string","deprecated":true},"id":{"type":"string"},"content":{"type":"string"},"status":{"$ref":"#/components/schemas/BlockStatus"},"generationCompleted":{"type":"boolean"},"result":{"type":"string"},"results":{"type":"array","items":{"$ref":"#/components/schemas/RunResult"}},"runMeta":{"type":"array","items":{"$ref":"#/components/schemas/RunMeta"}},"generalized_pattern":{"oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Generalized permission pattern for \"remember\" feature (e.g., \"BASH(cmd: npm *)\")"},"toolCallId":{"type":"string","description":"LLM API tool_call id — durable mapping from block to the tool_call that created it"},"parentBlockId":{"type":"string","description":"Parent block ID — present on sub-agent child blocks (e.g., read blocks inside explore)"},"deviceId":{"type":"string","description":"Device that executed this tool call. Edges and bridges both map to a device id.\nStamped from internal routing context, not provided by the LLM."},"_issue":{"type":"string","description":"Read-time schema issue: set by the tRPC soft-output validator when this\nblock failed output validation (e.g. legacy/malformed data). Derived on\nevery read from the failing typia path — NEVER persisted to Redis."},"approvalContext":{"type":"object","properties":{"source":{"type":"string"},"toolInstalls":{"type":"array","items":{"type":"string"}},"workspace":{"type":"string"},"edgeId":{"type":"string"}},"required":["source"],"description":"Edge approval context — present when edge requests tool install approval"},"title":{"type":"string"}},"required":["type","id","content","status","generationCompleted"]},"FileChange":{"type":"object","properties":{"path":{"type":"string"},"originalContent":{"oneOf":[{"type":"null"},{"type":"string"}]},"modifiedContent":{"oneOf":[{"type":"null"},{"type":"string"}]},"status":{"oneOf":[{"const":"created"},{"const":"modified"},{"const":"deleted"}],"description":"What happened to the file (resolved from git pre/post state)."},"omitted":{"oneOf":[{"const":"binary"},{"const":"too-large"}],"description":"Why content is null even though the file exists on that side."},"size":{"type":"number","description":"Bytes of the post-command file (pre-command size when deleted)."}},"required":["path","originalContent","modifiedContent"],"description":"One file touched by a shell command, as detected by edge-side git tracking."},"GrepBlock":{"type":"object","properties":{"type":{"const":"grep"},"pattern":{"type":"string"},"path":{"type":"string"},"glob":{"type":"string"},"ignore_case":{"type":"boolean"},"head":{"type":"number"},"max_count":{"type":"number"},"timeout":{"type":"number"},"output":{"type":"string"},"id":{"type":"string"},"content":{"type":"string"},"status":{"$ref":"#/components/schemas/BlockStatus"},"generationCompleted":{"type":"boolean"},"result":{"type":"string"},"results":{"type":"array","items":{"$ref":"#/components/schemas/RunResult"}},"runMeta":{"type":"array","items":{"$ref":"#/components/schemas/RunMeta"}},"generalized_pattern":{"oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Generalized permission pattern for \"remember\" feature (e.g., \"BASH(cmd: npm *)\")"},"toolCallId":{"type":"string","description":"LLM API tool_call id — durable mapping from block to the tool_call that created it"},"parentBlockId":{"type":"string","description":"Parent block ID — present on sub-agent child blocks (e.g., read blocks inside explore)"},"deviceId":{"type":"string","description":"Device that executed this tool call. Edges and bridges both map to a device id.\nStamped from internal routing context, not provided by the LLM."},"_issue":{"type":"string","description":"Read-time schema issue: set by the tRPC soft-output validator when this\nblock failed output validation (e.g. legacy/malformed data). Derived on\nevery read from the failing typia path — NEVER persisted to Redis."},"approvalContext":{"type":"object","properties":{"source":{"type":"string"},"toolInstalls":{"type":"array","items":{"type":"string"}},"workspace":{"type":"string"},"edgeId":{"type":"string"}},"required":["source"],"description":"Edge approval context — present when edge requests tool install approval"}},"required":["type","id","content","status","generationCompleted"]},"ListBlock":{"type":"object","properties":{"type":{"const":"list"},"path":{"type":"string"},"id":{"type":"string"},"content":{"type":"string"},"status":{"$ref":"#/components/schemas/BlockStatus"},"generationCompleted":{"type":"boolean"},"result":{"type":"string"},"results":{"type":"array","items":{"$ref":"#/components/schemas/RunResult"}},"runMeta":{"type":"array","items":{"$ref":"#/components/schemas/RunMeta"}},"generalized_pattern":{"oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Generalized permission pattern for \"remember\" feature (e.g., \"BASH(cmd: npm *)\")"},"toolCallId":{"type":"string","description":"LLM API tool_call id — durable mapping from block to the tool_call that created it"},"parentBlockId":{"type":"string","description":"Parent block ID — present on sub-agent child blocks (e.g., read blocks inside explore)"},"deviceId":{"type":"string","description":"Device that executed this tool call. Edges and bridges both map to a device id.\nStamped from internal routing context, not provided by the LLM."},"_issue":{"type":"string","description":"Read-time schema issue: set by the tRPC soft-output validator when this\nblock failed output validation (e.g. legacy/malformed data). Derived on\nevery read from the failing typia path — NEVER persisted to Redis."},"approvalContext":{"type":"object","properties":{"source":{"type":"string"},"toolInstalls":{"type":"array","items":{"type":"string"}},"workspace":{"type":"string"},"edgeId":{"type":"string"}},"required":["source"],"description":"Edge approval context — present when edge requests tool install approval"}},"required":["type","id","content","status","generationCompleted"]},"SkillBlock":{"type":"object","properties":{"type":{"const":"skill"},"name":{"type":"string"},"id":{"type":"string"},"content":{"type":"string"},"status":{"$ref":"#/components/schemas/BlockStatus"},"generationCompleted":{"type":"boolean"},"result":{"type":"string"},"results":{"type":"array","items":{"$ref":"#/components/schemas/RunResult"}},"runMeta":{"type":"array","items":{"$ref":"#/components/schemas/RunMeta"}},"generalized_pattern":{"oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Generalized permission pattern for \"remember\" feature (e.g., \"BASH(cmd: npm *)\")"},"toolCallId":{"type":"string","description":"LLM API tool_call id — durable mapping from block to the tool_call that created it"},"parentBlockId":{"type":"string","description":"Parent block ID — present on sub-agent child blocks (e.g., read blocks inside explore)"},"deviceId":{"type":"string","description":"Device that executed this tool call. Edges and bridges both map to a device id.\nStamped from internal routing context, not provided by the LLM."},"_issue":{"type":"string","description":"Read-time schema issue: set by the tRPC soft-output validator when this\nblock failed output validation (e.g. legacy/malformed data). Derived on\nevery read from the failing typia path — NEVER persisted to Redis."},"approvalContext":{"type":"object","properties":{"source":{"type":"string"},"toolInstalls":{"type":"array","items":{"type":"string"}},"workspace":{"type":"string"},"edgeId":{"type":"string"}},"required":["source"],"description":"Edge approval context — present when edge requests tool install approval"}},"required":["type","id","content","status","generationCompleted"]},"ApiBlock":{"type":"object","properties":{"type":{"$ref":"#/components/schemas/ApiToolType"},"id":{"type":"string"},"content":{"type":"string"},"status":{"$ref":"#/components/schemas/BlockStatus"},"generationCompleted":{"type":"boolean"},"result":{"type":"string"},"results":{"type":"array","items":{"$ref":"#/components/schemas/RunResult"}},"runMeta":{"type":"array","items":{"$ref":"#/components/schemas/RunMeta"}},"generalized_pattern":{"oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Generalized permission pattern for \"remember\" feature (e.g., \"BASH(cmd: npm *)\")"},"toolCallId":{"type":"string","description":"LLM API tool_call id — durable mapping from block to the tool_call that created it"},"parentBlockId":{"type":"string","description":"Parent block ID — present on sub-agent child blocks (e.g., read blocks inside explore)"},"deviceId":{"type":"string","description":"Device that executed this tool call. Edges and bridges both map to a device id.\nStamped from internal routing context, not provided by the LLM."},"_issue":{"type":"string","description":"Read-time schema issue: set by the tRPC soft-output validator when this\nblock failed output validation (e.g. legacy/malformed data). Derived on\nevery read from the failing typia path — NEVER persisted to Redis."},"approvalContext":{"type":"object","properties":{"source":{"type":"string"},"toolInstalls":{"type":"array","items":{"type":"string"}},"workspace":{"type":"string"},"edgeId":{"type":"string"}},"required":["source"],"description":"Edge approval context — present when edge requests tool install approval"},"title":{"type":"string"},"tool_name":{"type":"string"}},"required":["type","id","content","status","generationCompleted"]},"ApiToolType":{"oneOf":[{"const":"api_get_current_context"},{"const":"api_get_todo"},{"const":"api_add_todo_message"},{"const":"api_update_todo_status"},{"const":"api_delete_todo"},{"const":"api_list_projects"},{"const":"api_get_project"},{"const":"api_create_project"},{"const":"api_list_project_todos"},{"const":"api_create_todo"},{"const":"api_list_agents"},{"const":"api_get_agent"},{"const":"api_update_agent"},{"const":"api_list_business_contexts"},{"const":"api_get_context_item"},{"const":"api_create_context_item"},{"const":"api_update_context_item"},{"const":"api_delete_context_item"},{"const":"api_list_edges"},{"const":"api_get_edge"},{"const":"api_list_mcps"},{"const":"api_get_usage"},{"const":"api_get_balance"},{"const":"api_get_api_schema"}]},"ImageGenBlock":{"type":"object","properties":{"type":{"const":"image_gen"},"prompt":{"type":"string"},"model":{"type":"string"},"id":{"type":"string"},"content":{"type":"string"},"status":{"$ref":"#/components/schemas/BlockStatus"},"generationCompleted":{"type":"boolean"},"result":{"type":"string"},"results":{"type":"array","items":{"$ref":"#/components/schemas/RunResult"}},"runMeta":{"type":"array","items":{"$ref":"#/components/schemas/RunMeta"}},"generalized_pattern":{"oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Generalized permission pattern for \"remember\" feature (e.g., \"BASH(cmd: npm *)\")"},"toolCallId":{"type":"string","description":"LLM API tool_call id — durable mapping from block to the tool_call that created it"},"parentBlockId":{"type":"string","description":"Parent block ID — present on sub-agent child blocks (e.g., read blocks inside explore)"},"deviceId":{"type":"string","description":"Device that executed this tool call. Edges and bridges both map to a device id.\nStamped from internal routing context, not provided by the LLM."},"_issue":{"type":"string","description":"Read-time schema issue: set by the tRPC soft-output validator when this\nblock failed output validation (e.g. legacy/malformed data). Derived on\nevery read from the failing typia path — NEVER persisted to Redis."},"approvalContext":{"type":"object","properties":{"source":{"type":"string"},"toolInstalls":{"type":"array","items":{"type":"string"}},"workspace":{"type":"string"},"edgeId":{"type":"string"}},"required":["source"],"description":"Edge approval context — present when edge requests tool install approval"},"attachment_id":{"type":"string"},"attachment_ids":{"type":"array","items":{"type":"string"}}},"required":["type","id","content","status","generationCompleted"]},"ShowBlock":{"type":"object","properties":{"type":{"const":"show"},"filename":{"type":"string","description":"Original filename, shown in the block header."},"title":{"type":"string","description":"Short label shown in the block header, overriding `filename`."},"alias":{"type":"string","description":"Stable short address within the todo (`<todoId>:<alias>`), for later update/lookup."},"mime":{"type":"string","description":"Mimetype of the shown bytes — decides how the block renders."},"url":{"type":"string","description":"Live target for `todoforai-cli open <url>` (rendered as a preview instead of bytes)."},"cardRef":{"type":"string","description":"Name of a project-scoped card (reusable HTML renderer) to render the shown\nbytes through (`todoforai-cli show data.json --card <name>`). Resolved live\nper-project at render time, so updating the card updates every instance."},"id":{"type":"string"},"content":{"type":"string"},"status":{"$ref":"#/components/schemas/BlockStatus"},"generationCompleted":{"type":"boolean"},"result":{"type":"string"},"results":{"type":"array","items":{"$ref":"#/components/schemas/RunResult"}},"runMeta":{"type":"array","items":{"$ref":"#/components/schemas/RunMeta"}},"generalized_pattern":{"oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Generalized permission pattern for \"remember\" feature (e.g., \"BASH(cmd: npm *)\")"},"toolCallId":{"type":"string","description":"LLM API tool_call id — durable mapping from block to the tool_call that created it"},"parentBlockId":{"type":"string","description":"Parent block ID — present on sub-agent child blocks (e.g., read blocks inside explore)"},"deviceId":{"type":"string","description":"Device that executed this tool call. Edges and bridges both map to a device id.\nStamped from internal routing context, not provided by the LLM."},"_issue":{"type":"string","description":"Read-time schema issue: set by the tRPC soft-output validator when this\nblock failed output validation (e.g. legacy/malformed data). Derived on\nevery read from the failing typia path — NEVER persisted to Redis."},"approvalContext":{"type":"object","properties":{"source":{"type":"string"},"toolInstalls":{"type":"array","items":{"type":"string"}},"workspace":{"type":"string"},"edgeId":{"type":"string"}},"required":["source"],"description":"Edge approval context — present when edge requests tool install approval"}},"required":["type","id","content","status","generationCompleted"],"description":"A file surfaced into the chat (e.g. `todoforai-cli show <file>`), rendered by mimetype.\nThe file itself is the single attachment in `results[0]`.\n`text/html` renders as a live sandboxed surface; `url` renders as a live preview."},"HtmlSnippetBlock":{"type":"object","properties":{"type":{"const":"html_snippet"},"html":{"type":"string","description":"Bare HTML fragment authored by the LLM (no doctype/html/head/body)."},"title":{"type":"string","description":"Short label shown in the block header."},"id":{"type":"string"},"content":{"type":"string"},"status":{"$ref":"#/components/schemas/BlockStatus"},"generationCompleted":{"type":"boolean"},"result":{"type":"string"},"results":{"type":"array","items":{"$ref":"#/components/schemas/RunResult"}},"runMeta":{"type":"array","items":{"$ref":"#/components/schemas/RunMeta"}},"generalized_pattern":{"oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Generalized permission pattern for \"remember\" feature (e.g., \"BASH(cmd: npm *)\")"},"toolCallId":{"type":"string","description":"LLM API tool_call id — durable mapping from block to the tool_call that created it"},"parentBlockId":{"type":"string","description":"Parent block ID — present on sub-agent child blocks (e.g., read blocks inside explore)"},"deviceId":{"type":"string","description":"Device that executed this tool call. Edges and bridges both map to a device id.\nStamped from internal routing context, not provided by the LLM."},"_issue":{"type":"string","description":"Read-time schema issue: set by the tRPC soft-output validator when this\nblock failed output validation (e.g. legacy/malformed data). Derived on\nevery read from the failing typia path — NEVER persisted to Redis."},"approvalContext":{"type":"object","properties":{"source":{"type":"string"},"toolInstalls":{"type":"array","items":{"type":"string"}},"workspace":{"type":"string"},"edgeId":{"type":"string"}},"required":["source"],"description":"Edge approval context — present when edge requests tool install approval"}},"required":["type","id","content","status","generationCompleted"]},"LivePreviewBlock":{"type":"object","properties":{"type":{"const":"live_preview"},"url":{"type":"string","description":"A directly-openable URL. For a remote target it's the http(s) URL the\nagent was given; for a tunnel it's https://<session>.preview.todofor.ai\nonce the frontend has lazily minted a session."},"localUrl":{"type":"string","description":"Direct URL (http://127.0.0.1:<port>) for an edge-local target. The\nfrontend probes it first and, only if unreachable, mints a tunnel session\n(see edgeId/port) via POST /preview/session."},"edgeId":{"type":"string","description":"Edge + port backing localUrl — the frontend needs them to lazily mint a\ntunnel session when the direct URL isn't reachable."},"port":{"type":"number"},"title":{"type":"string","description":"Short label shown in the block header."},"id":{"type":"string"},"content":{"type":"string"},"status":{"$ref":"#/components/schemas/BlockStatus"},"generationCompleted":{"type":"boolean"},"result":{"type":"string"},"results":{"type":"array","items":{"$ref":"#/components/schemas/RunResult"}},"runMeta":{"type":"array","items":{"$ref":"#/components/schemas/RunMeta"}},"generalized_pattern":{"oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Generalized permission pattern for \"remember\" feature (e.g., \"BASH(cmd: npm *)\")"},"toolCallId":{"type":"string","description":"LLM API tool_call id — durable mapping from block to the tool_call that created it"},"parentBlockId":{"type":"string","description":"Parent block ID — present on sub-agent child blocks (e.g., read blocks inside explore)"},"deviceId":{"type":"string","description":"Device that executed this tool call. Edges and bridges both map to a device id.\nStamped from internal routing context, not provided by the LLM."},"_issue":{"type":"string","description":"Read-time schema issue: set by the tRPC soft-output validator when this\nblock failed output validation (e.g. legacy/malformed data). Derived on\nevery read from the failing typia path — NEVER persisted to Redis."},"approvalContext":{"type":"object","properties":{"source":{"type":"string"},"toolInstalls":{"type":"array","items":{"type":"string"}},"workspace":{"type":"string"},"edgeId":{"type":"string"}},"required":["source"],"description":"Edge approval context — present when edge requests tool install approval"}},"required":["type","id","content","status","generationCompleted"]},"TextBlock":{"type":"object","properties":{"type":{"const":"text"},"id":{"type":"string"},"content":{"type":"string"},"status":{"$ref":"#/components/schemas/BlockStatus"},"generationCompleted":{"type":"boolean"},"result":{"type":"string"},"results":{"type":"array","items":{"$ref":"#/components/schemas/RunResult"}},"runMeta":{"type":"array","items":{"$ref":"#/components/schemas/RunMeta"}},"generalized_pattern":{"oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Generalized permission pattern for \"remember\" feature (e.g., \"BASH(cmd: npm *)\")"},"toolCallId":{"type":"string","description":"LLM API tool_call id — durable mapping from block to the tool_call that created it"},"parentBlockId":{"type":"string","description":"Parent block ID — present on sub-agent child blocks (e.g., read blocks inside explore)"},"deviceId":{"type":"string","description":"Device that executed this tool call. Edges and bridges both map to a device id.\nStamped from internal routing context, not provided by the LLM."},"_issue":{"type":"string","description":"Read-time schema issue: set by the tRPC soft-output validator when this\nblock failed output validation (e.g. legacy/malformed data). Derived on\nevery read from the failing typia path — NEVER persisted to Redis."},"approvalContext":{"type":"object","properties":{"source":{"type":"string"},"toolInstalls":{"type":"array","items":{"type":"string"}},"workspace":{"type":"string"},"edgeId":{"type":"string"}},"required":["source"],"description":"Edge approval context — present when edge requests tool install approval"}},"required":["type","id","content","status","generationCompleted"]},"ReasonBlock":{"type":"object","properties":{"type":{"const":"reason"},"id":{"type":"string"},"content":{"type":"string"},"status":{"$ref":"#/components/schemas/BlockStatus"},"generationCompleted":{"type":"boolean"},"result":{"type":"string"},"results":{"type":"array","items":{"$ref":"#/components/schemas/RunResult"}},"runMeta":{"type":"array","items":{"$ref":"#/components/schemas/RunMeta"}},"generalized_pattern":{"oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Generalized permission pattern for \"remember\" feature (e.g., \"BASH(cmd: npm *)\")"},"toolCallId":{"type":"string","description":"LLM API tool_call id — durable mapping from block to the tool_call that created it"},"parentBlockId":{"type":"string","description":"Parent block ID — present on sub-agent child blocks (e.g., read blocks inside explore)"},"deviceId":{"type":"string","description":"Device that executed this tool call. Edges and bridges both map to a device id.\nStamped from internal routing context, not provided by the LLM."},"_issue":{"type":"string","description":"Read-time schema issue: set by the tRPC soft-output validator when this\nblock failed output validation (e.g. legacy/malformed data). Derived on\nevery read from the failing typia path — NEVER persisted to Redis."},"approvalContext":{"type":"object","properties":{"source":{"type":"string"},"toolInstalls":{"type":"array","items":{"type":"string"}},"workspace":{"type":"string"},"edgeId":{"type":"string"}},"required":["source"],"description":"Edge approval context — present when edge requests tool install approval"}},"required":["type","id","content","status","generationCompleted"]},"ErrorBlock":{"type":"object","properties":{"type":{"const":"error"},"error_message":{"type":"string"},"stacktrace":{"type":"string"},"id":{"type":"string"},"content":{"type":"string"},"status":{"$ref":"#/components/schemas/BlockStatus"},"generationCompleted":{"type":"boolean"},"result":{"type":"string"},"results":{"type":"array","items":{"$ref":"#/components/schemas/RunResult"}},"runMeta":{"type":"array","items":{"$ref":"#/components/schemas/RunMeta"}},"generalized_pattern":{"oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Generalized permission pattern for \"remember\" feature (e.g., \"BASH(cmd: npm *)\")"},"toolCallId":{"type":"string","description":"LLM API tool_call id — durable mapping from block to the tool_call that created it"},"parentBlockId":{"type":"string","description":"Parent block ID — present on sub-agent child blocks (e.g., read blocks inside explore)"},"deviceId":{"type":"string","description":"Device that executed this tool call. Edges and bridges both map to a device id.\nStamped from internal routing context, not provided by the LLM."},"_issue":{"type":"string","description":"Read-time schema issue: set by the tRPC soft-output validator when this\nblock failed output validation (e.g. legacy/malformed data). Derived on\nevery read from the failing typia path — NEVER persisted to Redis."},"approvalContext":{"type":"object","properties":{"source":{"type":"string"},"toolInstalls":{"type":"array","items":{"type":"string"}},"workspace":{"type":"string"},"edgeId":{"type":"string"}},"required":["source"],"description":"Edge approval context — present when edge requests tool install approval"}},"required":["type","id","content","status","generationCompleted"]},"CompactBlock":{"type":"object","properties":{"type":{"const":"compact"},"keep":{"type":"number"},"mode":{"type":"string"},"id":{"type":"string"},"content":{"type":"string"},"status":{"$ref":"#/components/schemas/BlockStatus"},"generationCompleted":{"type":"boolean"},"result":{"type":"string"},"results":{"type":"array","items":{"$ref":"#/components/schemas/RunResult"}},"runMeta":{"type":"array","items":{"$ref":"#/components/schemas/RunMeta"}},"generalized_pattern":{"oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Generalized permission pattern for \"remember\" feature (e.g., \"BASH(cmd: npm *)\")"},"toolCallId":{"type":"string","description":"LLM API tool_call id — durable mapping from block to the tool_call that created it"},"parentBlockId":{"type":"string","description":"Parent block ID — present on sub-agent child blocks (e.g., read blocks inside explore)"},"deviceId":{"type":"string","description":"Device that executed this tool call. Edges and bridges both map to a device id.\nStamped from internal routing context, not provided by the LLM."},"_issue":{"type":"string","description":"Read-time schema issue: set by the tRPC soft-output validator when this\nblock failed output validation (e.g. legacy/malformed data). Derived on\nevery read from the failing typia path — NEVER persisted to Redis."},"approvalContext":{"type":"object","properties":{"source":{"type":"string"},"toolInstalls":{"type":"array","items":{"type":"string"}},"workspace":{"type":"string"},"edgeId":{"type":"string"}},"required":["source"],"description":"Edge approval context — present when edge requests tool install approval"}},"required":["type","id","content","status","generationCompleted"]},"QuestionBlock":{"type":"object","properties":{"type":{"const":"question"},"questions":{"type":"array","items":{"$ref":"#/components/schemas/QuestionItem"}},"answer":{"type":"string","description":"Pre-formatted user response (set by backend on approval)."},"id":{"type":"string"},"content":{"type":"string"},"status":{"$ref":"#/components/schemas/BlockStatus"},"generationCompleted":{"type":"boolean"},"result":{"type":"string"},"results":{"type":"array","items":{"$ref":"#/components/schemas/RunResult"}},"runMeta":{"type":"array","items":{"$ref":"#/components/schemas/RunMeta"}},"generalized_pattern":{"oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Generalized permission pattern for \"remember\" feature (e.g., \"BASH(cmd: npm *)\")"},"toolCallId":{"type":"string","description":"LLM API tool_call id — durable mapping from block to the tool_call that created it"},"parentBlockId":{"type":"string","description":"Parent block ID — present on sub-agent child blocks (e.g., read blocks inside explore)"},"deviceId":{"type":"string","description":"Device that executed this tool call. Edges and bridges both map to a device id.\nStamped from internal routing context, not provided by the LLM."},"_issue":{"type":"string","description":"Read-time schema issue: set by the tRPC soft-output validator when this\nblock failed output validation (e.g. legacy/malformed data). Derived on\nevery read from the failing typia path — NEVER persisted to Redis."},"approvalContext":{"type":"object","properties":{"source":{"type":"string"},"toolInstalls":{"type":"array","items":{"type":"string"}},"workspace":{"type":"string"},"edgeId":{"type":"string"}},"required":["source"],"description":"Edge approval context — present when edge requests tool install approval"}},"required":["type","id","content","status","generationCompleted"]},"QuestionItem":{"type":"object","properties":{"id":{"type":"string"},"header":{"type":"string"},"question":{"type":"string"},"options":{"type":"array","items":{"$ref":"#/components/schemas/QuestionOption"}}},"required":["id","header","question","options"],"description":"One question in a QuestionBlock — Codex `request_user_input`-style."},"QuestionOption":{"type":"object","properties":{"label":{"type":"string"},"description":{"type":"string"}},"required":["label","description"],"description":"A single multi-choice option presented to the user."},"OpenBrowserBlock":{"type":"object","properties":{"type":{"const":"open_browser"},"url":{"type":"string","description":"First page to load (the tool's `url` arg)."},"cdp_url":{"type":"string","description":"agent-browser CDP connect URL of the enrolled resource (set on approval → tool result)."},"id":{"type":"string"},"content":{"type":"string"},"status":{"$ref":"#/components/schemas/BlockStatus"},"generationCompleted":{"type":"boolean"},"result":{"type":"string"},"results":{"type":"array","items":{"$ref":"#/components/schemas/RunResult"}},"runMeta":{"type":"array","items":{"$ref":"#/components/schemas/RunMeta"}},"generalized_pattern":{"oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Generalized permission pattern for \"remember\" feature (e.g., \"BASH(cmd: npm *)\")"},"toolCallId":{"type":"string","description":"LLM API tool_call id — durable mapping from block to the tool_call that created it"},"parentBlockId":{"type":"string","description":"Parent block ID — present on sub-agent child blocks (e.g., read blocks inside explore)"},"deviceId":{"type":"string","description":"Device that executed this tool call. Edges and bridges both map to a device id.\nStamped from internal routing context, not provided by the LLM."},"_issue":{"type":"string","description":"Read-time schema issue: set by the tRPC soft-output validator when this\nblock failed output validation (e.g. legacy/malformed data). Derived on\nevery read from the failing typia path — NEVER persisted to Redis."},"approvalContext":{"type":"object","properties":{"source":{"type":"string"},"toolInstalls":{"type":"array","items":{"type":"string"}},"workspace":{"type":"string"},"edgeId":{"type":"string"}},"required":["source"],"description":"Edge approval context — present when edge requests tool install approval"}},"required":["type","id","content","status","generationCompleted"],"description":"open_browser: launches the in-page Scramjet browser scoped to this todo.\nThe block is a compact launcher — it opens the browser side panel (which\nhosts the actual view) and, once the CDP resource enrolls, sets `cdp_token`\nand approves so the waiting tool returns the connect URL to the agent."},"LoginBlock":{"type":"object","properties":{"type":{"const":"login_prompt"},"reason":{"type":"string"},"logged_in":{"type":"boolean"},"user":{"type":"string"},"id":{"type":"string"},"content":{"type":"string"},"status":{"$ref":"#/components/schemas/BlockStatus"},"generationCompleted":{"type":"boolean"},"result":{"type":"string"},"results":{"type":"array","items":{"$ref":"#/components/schemas/RunResult"}},"runMeta":{"type":"array","items":{"$ref":"#/components/schemas/RunMeta"}},"generalized_pattern":{"oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Generalized permission pattern for \"remember\" feature (e.g., \"BASH(cmd: npm *)\")"},"toolCallId":{"type":"string","description":"LLM API tool_call id — durable mapping from block to the tool_call that created it"},"parentBlockId":{"type":"string","description":"Parent block ID — present on sub-agent child blocks (e.g., read blocks inside explore)"},"deviceId":{"type":"string","description":"Device that executed this tool call. Edges and bridges both map to a device id.\nStamped from internal routing context, not provided by the LLM."},"_issue":{"type":"string","description":"Read-time schema issue: set by the tRPC soft-output validator when this\nblock failed output validation (e.g. legacy/malformed data). Derived on\nevery read from the failing typia path — NEVER persisted to Redis."},"approvalContext":{"type":"object","properties":{"source":{"type":"string"},"toolInstalls":{"type":"array","items":{"type":"string"}},"workspace":{"type":"string"},"edgeId":{"type":"string"}},"required":["source"],"description":"Edge approval context — present when edge requests tool install approval"}},"required":["type","id","content","status","generationCompleted"],"description":"Onboarding: prompt anonymous user to log in. User clicks \"Sign in\", the auth\nflow runs externally, the block sets `logged_in` + `user` then approves."},"BusinessOnboardingBlock":{"type":"object","properties":{"type":{"const":"business_onboarding"},"reason":{"type":"string"},"website":{"type":"string"},"id":{"type":"string"},"content":{"type":"string"},"status":{"$ref":"#/components/schemas/BlockStatus"},"generationCompleted":{"type":"boolean"},"result":{"type":"string"},"results":{"type":"array","items":{"$ref":"#/components/schemas/RunResult"}},"runMeta":{"type":"array","items":{"$ref":"#/components/schemas/RunMeta"}},"generalized_pattern":{"oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Generalized permission pattern for \"remember\" feature (e.g., \"BASH(cmd: npm *)\")"},"toolCallId":{"type":"string","description":"LLM API tool_call id — durable mapping from block to the tool_call that created it"},"parentBlockId":{"type":"string","description":"Parent block ID — present on sub-agent child blocks (e.g., read blocks inside explore)"},"deviceId":{"type":"string","description":"Device that executed this tool call. Edges and bridges both map to a device id.\nStamped from internal routing context, not provided by the LLM."},"_issue":{"type":"string","description":"Read-time schema issue: set by the tRPC soft-output validator when this\nblock failed output validation (e.g. legacy/malformed data). Derived on\nevery read from the failing typia path — NEVER persisted to Redis."},"approvalContext":{"type":"object","properties":{"source":{"type":"string"},"toolInstalls":{"type":"array","items":{"type":"string"}},"workspace":{"type":"string"},"edgeId":{"type":"string"}},"required":["source"],"description":"Edge approval context — present when edge requests tool install approval"}},"required":["type","id","content","status","generationCompleted"],"description":"Onboarding: ask the user for their business website URL. The agent then\nfetches/analyzes it and writes the business context autonomously."},"RequestMcpAccessBlock":{"type":"object","properties":{"type":{"const":"request_mcp_access"},"mcp_name":{"type":"string"},"id":{"type":"string"},"content":{"type":"string"},"status":{"$ref":"#/components/schemas/BlockStatus"},"generationCompleted":{"type":"boolean"},"result":{"type":"string"},"results":{"type":"array","items":{"$ref":"#/components/schemas/RunResult"}},"runMeta":{"type":"array","items":{"$ref":"#/components/schemas/RunMeta"}},"generalized_pattern":{"oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Generalized permission pattern for \"remember\" feature (e.g., \"BASH(cmd: npm *)\")"},"toolCallId":{"type":"string","description":"LLM API tool_call id — durable mapping from block to the tool_call that created it"},"parentBlockId":{"type":"string","description":"Parent block ID — present on sub-agent child blocks (e.g., read blocks inside explore)"},"deviceId":{"type":"string","description":"Device that executed this tool call. Edges and bridges both map to a device id.\nStamped from internal routing context, not provided by the LLM."},"_issue":{"type":"string","description":"Read-time schema issue: set by the tRPC soft-output validator when this\nblock failed output validation (e.g. legacy/malformed data). Derived on\nevery read from the failing typia path — NEVER persisted to Redis."},"approvalContext":{"type":"object","properties":{"source":{"type":"string"},"toolInstalls":{"type":"array","items":{"type":"string"}},"workspace":{"type":"string"},"edgeId":{"type":"string"}},"required":["source"],"description":"Edge approval context — present when edge requests tool install approval"},"tool_name":{"type":"string"}},"required":["type","id","content","status","generationCompleted"]},"EdgeNotRunningBlock":{"type":"object","properties":{"type":{"const":"edge_not_running"},"id":{"type":"string"},"content":{"type":"string"},"status":{"$ref":"#/components/schemas/BlockStatus"},"generationCompleted":{"type":"boolean"},"result":{"type":"string"},"results":{"type":"array","items":{"$ref":"#/components/schemas/RunResult"}},"runMeta":{"type":"array","items":{"$ref":"#/components/schemas/RunMeta"}},"generalized_pattern":{"oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Generalized permission pattern for \"remember\" feature (e.g., \"BASH(cmd: npm *)\")"},"toolCallId":{"type":"string","description":"LLM API tool_call id — durable mapping from block to the tool_call that created it"},"parentBlockId":{"type":"string","description":"Parent block ID — present on sub-agent child blocks (e.g., read blocks inside explore)"},"deviceId":{"type":"string","description":"Device that executed this tool call. Edges and bridges both map to a device id.\nStamped from internal routing context, not provided by the LLM."},"_issue":{"type":"string","description":"Read-time schema issue: set by the tRPC soft-output validator when this\nblock failed output validation (e.g. legacy/malformed data). Derived on\nevery read from the failing typia path — NEVER persisted to Redis."},"approvalContext":{"type":"object","properties":{"source":{"type":"string"},"toolInstalls":{"type":"array","items":{"type":"string"}},"workspace":{"type":"string"},"edgeId":{"type":"string"}},"required":["source"],"description":"Edge approval context — present when edge requests tool install approval"},"tool_name":{"type":"string"}},"required":["type","id","content","status","generationCompleted"]},"WebFetchBlock":{"type":"object","properties":{"type":{"const":"webfetch"},"id":{"type":"string"},"content":{"type":"string"},"status":{"$ref":"#/components/schemas/BlockStatus"},"generationCompleted":{"type":"boolean"},"result":{"type":"string"},"results":{"type":"array","items":{"$ref":"#/components/schemas/RunResult"}},"runMeta":{"type":"array","items":{"$ref":"#/components/schemas/RunMeta"}},"generalized_pattern":{"oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Generalized permission pattern for \"remember\" feature (e.g., \"BASH(cmd: npm *)\")"},"toolCallId":{"type":"string","description":"LLM API tool_call id — durable mapping from block to the tool_call that created it"},"parentBlockId":{"type":"string","description":"Parent block ID — present on sub-agent child blocks (e.g., read blocks inside explore)"},"deviceId":{"type":"string","description":"Device that executed this tool call. Edges and bridges both map to a device id.\nStamped from internal routing context, not provided by the LLM."},"_issue":{"type":"string","description":"Read-time schema issue: set by the tRPC soft-output validator when this\nblock failed output validation (e.g. legacy/malformed data). Derived on\nevery read from the failing typia path — NEVER persisted to Redis."},"approvalContext":{"type":"object","properties":{"source":{"type":"string"},"toolInstalls":{"type":"array","items":{"type":"string"}},"workspace":{"type":"string"},"edgeId":{"type":"string"}},"required":["source"],"description":"Edge approval context — present when edge requests tool install approval"},"url":{"type":"string"}},"required":["type","id","content","status","generationCompleted","url"]},"GoogleSearchBlock":{"type":"object","properties":{"type":{"const":"google_search"},"sources":{"type":"array","items":{"type":"object","properties":{"title":{"type":"string"},"url":{"type":"string"}},"required":["title","url"]},"description":"Raw search hits pushed via BLOCK_UPDATE as soon as the search API returns,\nbefore the summarizer sub-agent finishes — lets the UI show sources live."},"id":{"type":"string"},"content":{"type":"string"},"status":{"$ref":"#/components/schemas/BlockStatus"},"generationCompleted":{"type":"boolean"},"result":{"type":"string"},"results":{"type":"array","items":{"$ref":"#/components/schemas/RunResult"}},"runMeta":{"type":"array","items":{"$ref":"#/components/schemas/RunMeta"}},"generalized_pattern":{"oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Generalized permission pattern for \"remember\" feature (e.g., \"BASH(cmd: npm *)\")"},"toolCallId":{"type":"string","description":"LLM API tool_call id — durable mapping from block to the tool_call that created it"},"parentBlockId":{"type":"string","description":"Parent block ID — present on sub-agent child blocks (e.g., read blocks inside explore)"},"deviceId":{"type":"string","description":"Device that executed this tool call. Edges and bridges both map to a device id.\nStamped from internal routing context, not provided by the LLM."},"_issue":{"type":"string","description":"Read-time schema issue: set by the tRPC soft-output validator when this\nblock failed output validation (e.g. legacy/malformed data). Derived on\nevery read from the failing typia path — NEVER persisted to Redis."},"approvalContext":{"type":"object","properties":{"source":{"type":"string"},"toolInstalls":{"type":"array","items":{"type":"string"}},"workspace":{"type":"string"},"edgeId":{"type":"string"}},"required":["source"],"description":"Edge approval context — present when edge requests tool install approval"},"query":{"type":"string"}},"required":["type","id","content","status","generationCompleted","query"]},"WebSearchBlock":{"type":"object","properties":{"type":{"const":"web_search"},"id":{"type":"string"},"content":{"type":"string"},"status":{"$ref":"#/components/schemas/BlockStatus"},"generationCompleted":{"type":"boolean"},"result":{"type":"string"},"results":{"type":"array","items":{"$ref":"#/components/schemas/RunResult"}},"runMeta":{"type":"array","items":{"$ref":"#/components/schemas/RunMeta"}},"generalized_pattern":{"oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Generalized permission pattern for \"remember\" feature (e.g., \"BASH(cmd: npm *)\")"},"toolCallId":{"type":"string","description":"LLM API tool_call id — durable mapping from block to the tool_call that created it"},"parentBlockId":{"type":"string","description":"Parent block ID — present on sub-agent child blocks (e.g., read blocks inside explore)"},"deviceId":{"type":"string","description":"Device that executed this tool call. Edges and bridges both map to a device id.\nStamped from internal routing context, not provided by the LLM."},"_issue":{"type":"string","description":"Read-time schema issue: set by the tRPC soft-output validator when this\nblock failed output validation (e.g. legacy/malformed data). Derived on\nevery read from the failing typia path — NEVER persisted to Redis."},"approvalContext":{"type":"object","properties":{"source":{"type":"string"},"toolInstalls":{"type":"array","items":{"type":"string"}},"workspace":{"type":"string"},"edgeId":{"type":"string"}},"required":["source"],"description":"Edge approval context — present when edge requests tool install approval"},"query":{"type":"string"}},"required":["type","id","content","status","generationCompleted","query"]},"VaultSearchBlock":{"type":"object","properties":{"type":{"const":"vault_search"},"id":{"type":"string"},"content":{"type":"string"},"status":{"$ref":"#/components/schemas/BlockStatus"},"generationCompleted":{"type":"boolean"},"result":{"type":"string"},"results":{"type":"array","items":{"$ref":"#/components/schemas/RunResult"}},"runMeta":{"type":"array","items":{"$ref":"#/components/schemas/RunMeta"}},"generalized_pattern":{"oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Generalized permission pattern for \"remember\" feature (e.g., \"BASH(cmd: npm *)\")"},"toolCallId":{"type":"string","description":"LLM API tool_call id — durable mapping from block to the tool_call that created it"},"parentBlockId":{"type":"string","description":"Parent block ID — present on sub-agent child blocks (e.g., read blocks inside explore)"},"deviceId":{"type":"string","description":"Device that executed this tool call. Edges and bridges both map to a device id.\nStamped from internal routing context, not provided by the LLM."},"_issue":{"type":"string","description":"Read-time schema issue: set by the tRPC soft-output validator when this\nblock failed output validation (e.g. legacy/malformed data). Derived on\nevery read from the failing typia path — NEVER persisted to Redis."},"approvalContext":{"type":"object","properties":{"source":{"type":"string"},"toolInstalls":{"type":"array","items":{"type":"string"}},"workspace":{"type":"string"},"edgeId":{"type":"string"}},"required":["source"],"description":"Edge approval context — present when edge requests tool install approval"},"query":{"type":"string"}},"required":["type","id","content","status","generationCompleted","query"]},"VaultResolveBlock":{"type":"object","properties":{"type":{"const":"vault_resolve"},"ref":{"type":"string","description":"Vault reference being resolved (e.g. `vault://path#field`)"},"id":{"type":"string"},"content":{"type":"string"},"status":{"$ref":"#/components/schemas/BlockStatus"},"generationCompleted":{"type":"boolean"},"result":{"type":"string"},"results":{"type":"array","items":{"$ref":"#/components/schemas/RunResult"}},"runMeta":{"type":"array","items":{"$ref":"#/components/schemas/RunMeta"}},"generalized_pattern":{"oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Generalized permission pattern for \"remember\" feature (e.g., \"BASH(cmd: npm *)\")"},"toolCallId":{"type":"string","description":"LLM API tool_call id — durable mapping from block to the tool_call that created it"},"parentBlockId":{"type":"string","description":"Parent block ID — present on sub-agent child blocks (e.g., read blocks inside explore)"},"deviceId":{"type":"string","description":"Device that executed this tool call. Edges and bridges both map to a device id.\nStamped from internal routing context, not provided by the LLM."},"_issue":{"type":"string","description":"Read-time schema issue: set by the tRPC soft-output validator when this\nblock failed output validation (e.g. legacy/malformed data). Derived on\nevery read from the failing typia path — NEVER persisted to Redis."},"approvalContext":{"type":"object","properties":{"source":{"type":"string"},"toolInstalls":{"type":"array","items":{"type":"string"}},"workspace":{"type":"string"},"edgeId":{"type":"string"}},"required":["source"],"description":"Edge approval context — present when edge requests tool install approval"}},"required":["type","id","content","status","generationCompleted"]},"VaultWriteBlock":{"type":"object","properties":{"type":{"const":"vault_write"},"scheme":{"type":"string"},"id":{"type":"string"},"content":{"type":"string"},"status":{"$ref":"#/components/schemas/BlockStatus"},"generationCompleted":{"type":"boolean"},"result":{"type":"string"},"results":{"type":"array","items":{"$ref":"#/components/schemas/RunResult"}},"runMeta":{"type":"array","items":{"$ref":"#/components/schemas/RunMeta"}},"generalized_pattern":{"oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Generalized permission pattern for \"remember\" feature (e.g., \"BASH(cmd: npm *)\")"},"toolCallId":{"type":"string","description":"LLM API tool_call id — durable mapping from block to the tool_call that created it"},"parentBlockId":{"type":"string","description":"Parent block ID — present on sub-agent child blocks (e.g., read blocks inside explore)"},"deviceId":{"type":"string","description":"Device that executed this tool call. Edges and bridges both map to a device id.\nStamped from internal routing context, not provided by the LLM."},"_issue":{"type":"string","description":"Read-time schema issue: set by the tRPC soft-output validator when this\nblock failed output validation (e.g. legacy/malformed data). Derived on\nevery read from the failing typia path — NEVER persisted to Redis."},"approvalContext":{"type":"object","properties":{"source":{"type":"string"},"toolInstalls":{"type":"array","items":{"type":"string"}},"workspace":{"type":"string"},"edgeId":{"type":"string"}},"required":["source"],"description":"Edge approval context — present when edge requests tool install approval"},"title":{"type":"string"}},"required":["type","id","content","status","generationCompleted"]},"VaultWriteBatchBlock":{"type":"object","properties":{"type":{"const":"vault_write_batch"},"scheme":{"type":"string"},"id":{"type":"string"},"content":{"type":"string"},"status":{"$ref":"#/components/schemas/BlockStatus"},"generationCompleted":{"type":"boolean"},"result":{"type":"string"},"results":{"type":"array","items":{"$ref":"#/components/schemas/RunResult"}},"runMeta":{"type":"array","items":{"$ref":"#/components/schemas/RunMeta"}},"generalized_pattern":{"oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Generalized permission pattern for \"remember\" feature (e.g., \"BASH(cmd: npm *)\")"},"toolCallId":{"type":"string","description":"LLM API tool_call id — durable mapping from block to the tool_call that created it"},"parentBlockId":{"type":"string","description":"Parent block ID — present on sub-agent child blocks (e.g., read blocks inside explore)"},"deviceId":{"type":"string","description":"Device that executed this tool call. Edges and bridges both map to a device id.\nStamped from internal routing context, not provided by the LLM."},"_issue":{"type":"string","description":"Read-time schema issue: set by the tRPC soft-output validator when this\nblock failed output validation (e.g. legacy/malformed data). Derived on\nevery read from the failing typia path — NEVER persisted to Redis."},"approvalContext":{"type":"object","properties":{"source":{"type":"string"},"toolInstalls":{"type":"array","items":{"type":"string"}},"workspace":{"type":"string"},"edgeId":{"type":"string"}},"required":["source"],"description":"Edge approval context — present when edge requests tool install approval"}},"required":["type","id","content","status","generationCompleted"]},"VaultUpdateBlock":{"type":"object","properties":{"type":{"const":"vault_update"},"uri":{"type":"string","description":"Vault item URI being updated"},"id":{"type":"string"},"content":{"type":"string"},"status":{"$ref":"#/components/schemas/BlockStatus"},"generationCompleted":{"type":"boolean"},"result":{"type":"string"},"results":{"type":"array","items":{"$ref":"#/components/schemas/RunResult"}},"runMeta":{"type":"array","items":{"$ref":"#/components/schemas/RunMeta"}},"generalized_pattern":{"oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Generalized permission pattern for \"remember\" feature (e.g., \"BASH(cmd: npm *)\")"},"toolCallId":{"type":"string","description":"LLM API tool_call id — durable mapping from block to the tool_call that created it"},"parentBlockId":{"type":"string","description":"Parent block ID — present on sub-agent child blocks (e.g., read blocks inside explore)"},"deviceId":{"type":"string","description":"Device that executed this tool call. Edges and bridges both map to a device id.\nStamped from internal routing context, not provided by the LLM."},"_issue":{"type":"string","description":"Read-time schema issue: set by the tRPC soft-output validator when this\nblock failed output validation (e.g. legacy/malformed data). Derived on\nevery read from the failing typia path — NEVER persisted to Redis."},"approvalContext":{"type":"object","properties":{"source":{"type":"string"},"toolInstalls":{"type":"array","items":{"type":"string"}},"workspace":{"type":"string"},"edgeId":{"type":"string"}},"required":["source"],"description":"Edge approval context — present when edge requests tool install approval"}},"required":["type","id","content","status","generationCompleted"]},"McpBlock":{"type":"object","properties":{"type":{"const":"mcp"},"server_name":{"type":"string"},"method":{"type":"string"},"name":{"type":"string"},"id":{"type":"string"},"content":{"type":"string"},"status":{"$ref":"#/components/schemas/BlockStatus"},"generationCompleted":{"type":"boolean"},"result":{"type":"string"},"results":{"type":"array","items":{"$ref":"#/components/schemas/RunResult"}},"runMeta":{"type":"array","items":{"$ref":"#/components/schemas/RunMeta"}},"generalized_pattern":{"oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Generalized permission pattern for \"remember\" feature (e.g., \"BASH(cmd: npm *)\")"},"toolCallId":{"type":"string","description":"LLM API tool_call id — durable mapping from block to the tool_call that created it"},"parentBlockId":{"type":"string","description":"Parent block ID — present on sub-agent child blocks (e.g., read blocks inside explore)"},"deviceId":{"type":"string","description":"Device that executed this tool call. Edges and bridges both map to a device id.\nStamped from internal routing context, not provided by the LLM."},"_issue":{"type":"string","description":"Read-time schema issue: set by the tRPC soft-output validator when this\nblock failed output validation (e.g. legacy/malformed data). Derived on\nevery read from the failing typia path — NEVER persisted to Redis."},"approvalContext":{"type":"object","properties":{"source":{"type":"string"},"toolInstalls":{"type":"array","items":{"type":"string"}},"workspace":{"type":"string"},"edgeId":{"type":"string"}},"required":["source"],"description":"Edge approval context — present when edge requests tool install approval"},"title":{"type":"string"},"tool_name":{"type":"string"}},"required":["type","server_name","method","id","content","status","generationCompleted"]},"ExploreBlock":{"type":"object","properties":{"type":{"const":"explore"},"prompt":{"type":"string"},"subTodoId":{"type":"string","description":"When the sub-agent runs as a real hidden sub-todo, its todoId."},"id":{"type":"string"},"content":{"type":"string"},"status":{"$ref":"#/components/schemas/BlockStatus"},"generationCompleted":{"type":"boolean"},"result":{"type":"string"},"results":{"type":"array","items":{"$ref":"#/components/schemas/RunResult"}},"runMeta":{"type":"array","items":{"$ref":"#/components/schemas/RunMeta"}},"generalized_pattern":{"oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Generalized permission pattern for \"remember\" feature (e.g., \"BASH(cmd: npm *)\")"},"toolCallId":{"type":"string","description":"LLM API tool_call id — durable mapping from block to the tool_call that created it"},"parentBlockId":{"type":"string","description":"Parent block ID — present on sub-agent child blocks (e.g., read blocks inside explore)"},"deviceId":{"type":"string","description":"Device that executed this tool call. Edges and bridges both map to a device id.\nStamped from internal routing context, not provided by the LLM."},"_issue":{"type":"string","description":"Read-time schema issue: set by the tRPC soft-output validator when this\nblock failed output validation (e.g. legacy/malformed data). Derived on\nevery read from the failing typia path — NEVER persisted to Redis."},"approvalContext":{"type":"object","properties":{"source":{"type":"string"},"toolInstalls":{"type":"array","items":{"type":"string"}},"workspace":{"type":"string"},"edgeId":{"type":"string"}},"required":["source"],"description":"Edge approval context — present when edge requests tool install approval"}},"required":["type","id","content","status","generationCompleted"]},"PlanBlock":{"type":"object","properties":{"type":{"const":"plan"},"prompt":{"type":"string"},"id":{"type":"string"},"content":{"type":"string"},"status":{"$ref":"#/components/schemas/BlockStatus"},"generationCompleted":{"type":"boolean"},"result":{"type":"string"},"results":{"type":"array","items":{"$ref":"#/components/schemas/RunResult"}},"runMeta":{"type":"array","items":{"$ref":"#/components/schemas/RunMeta"}},"generalized_pattern":{"oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Generalized permission pattern for \"remember\" feature (e.g., \"BASH(cmd: npm *)\")"},"toolCallId":{"type":"string","description":"LLM API tool_call id — durable mapping from block to the tool_call that created it"},"parentBlockId":{"type":"string","description":"Parent block ID — present on sub-agent child blocks (e.g., read blocks inside explore)"},"deviceId":{"type":"string","description":"Device that executed this tool call. Edges and bridges both map to a device id.\nStamped from internal routing context, not provided by the LLM."},"_issue":{"type":"string","description":"Read-time schema issue: set by the tRPC soft-output validator when this\nblock failed output validation (e.g. legacy/malformed data). Derived on\nevery read from the failing typia path — NEVER persisted to Redis."},"approvalContext":{"type":"object","properties":{"source":{"type":"string"},"toolInstalls":{"type":"array","items":{"type":"string"}},"workspace":{"type":"string"},"edgeId":{"type":"string"}},"required":["source"],"description":"Edge approval context — present when edge requests tool install approval"}},"required":["type","id","content","status","generationCompleted"]},"ReviewBlock":{"type":"object","properties":{"type":{"const":"review"},"prompt":{"type":"string"},"subTodoId":{"type":"string","description":"When the sub-agent runs as a real hidden sub-todo, its todoId."},"id":{"type":"string"},"content":{"type":"string"},"status":{"$ref":"#/components/schemas/BlockStatus"},"generationCompleted":{"type":"boolean"},"result":{"type":"string"},"results":{"type":"array","items":{"$ref":"#/components/schemas/RunResult"}},"runMeta":{"type":"array","items":{"$ref":"#/components/schemas/RunMeta"}},"generalized_pattern":{"oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Generalized permission pattern for \"remember\" feature (e.g., \"BASH(cmd: npm *)\")"},"toolCallId":{"type":"string","description":"LLM API tool_call id — durable mapping from block to the tool_call that created it"},"parentBlockId":{"type":"string","description":"Parent block ID — present on sub-agent child blocks (e.g., read blocks inside explore)"},"deviceId":{"type":"string","description":"Device that executed this tool call. Edges and bridges both map to a device id.\nStamped from internal routing context, not provided by the LLM."},"_issue":{"type":"string","description":"Read-time schema issue: set by the tRPC soft-output validator when this\nblock failed output validation (e.g. legacy/malformed data). Derived on\nevery read from the failing typia path — NEVER persisted to Redis."},"approvalContext":{"type":"object","properties":{"source":{"type":"string"},"toolInstalls":{"type":"array","items":{"type":"string"}},"workspace":{"type":"string"},"edgeId":{"type":"string"}},"required":["source"],"description":"Edge approval context — present when edge requests tool install approval"}},"required":["type","id","content","status","generationCompleted"]},"DeviceListBlock":{"type":"object","properties":{"type":{"const":"device_list"},"id":{"type":"string"},"content":{"type":"string"},"status":{"$ref":"#/components/schemas/BlockStatus"},"generationCompleted":{"type":"boolean"},"result":{"type":"string"},"results":{"type":"array","items":{"$ref":"#/components/schemas/RunResult"}},"runMeta":{"type":"array","items":{"$ref":"#/components/schemas/RunMeta"}},"generalized_pattern":{"oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Generalized permission pattern for \"remember\" feature (e.g., \"BASH(cmd: npm *)\")"},"toolCallId":{"type":"string","description":"LLM API tool_call id — durable mapping from block to the tool_call that created it"},"parentBlockId":{"type":"string","description":"Parent block ID — present on sub-agent child blocks (e.g., read blocks inside explore)"},"deviceId":{"type":"string","description":"Device that executed this tool call. Edges and bridges both map to a device id.\nStamped from internal routing context, not provided by the LLM."},"_issue":{"type":"string","description":"Read-time schema issue: set by the tRPC soft-output validator when this\nblock failed output validation (e.g. legacy/malformed data). Derived on\nevery read from the failing typia path — NEVER persisted to Redis."},"approvalContext":{"type":"object","properties":{"source":{"type":"string"},"toolInstalls":{"type":"array","items":{"type":"string"}},"workspace":{"type":"string"},"edgeId":{"type":"string"}},"required":["source"],"description":"Edge approval context — present when edge requests tool install approval"}},"required":["type","id","content","status","generationCompleted"]},"TodoGroup":{"type":"object","properties":{"slug":{"type":"string"},"name":{"type":"string"},"description":{"type":"string","description":"One-line strategic intent of the group — shown on the card and fed to the\nsemantic router so future todos/recommendations land here."},"pinned":{"type":"boolean","description":"Pinned cards sort first on the wall."},"archived":{"type":"boolean","description":"Archived cards leave the wall (still listed here so the picker can offer them)."},"order":{"type":"number","description":"Explicit wall position (ascending). Unset groups trail in listing (creation) order."}},"required":["slug","name"],"description":"A project-scoped todo group. The slug is the stable identity; name falls back to slug."},"RendererCardInfo":{"type":"object","properties":{"name":{"type":"string"},"attachmentId":{"type":"string","description":"Attachment id of the card's HTML body."},"title":{"type":"string"},"description":{"type":"string"},"updatedAt":{"type":"number"}},"required":["name","attachmentId","updatedAt"],"description":"A project-scoped renderer card (CUSTOM_CARDS.design.md) as listed to clients."},"ProjectGroupUpsertInput":{"type":"object","properties":{"projectId":{"type":"string"},"slug":{"type":"string"},"name":{"type":"string"},"description":{"type":"string","description":"One-line strategic intent; empty string clears it, omitted = unchanged."},"pinned":{"type":"boolean","description":"Toggle pinned; omitted = unchanged."},"archived":{"type":"boolean","description":"Toggle archived; omitted = unchanged."},"order":{"type":"number","description":"Explicit wall position; omitted = unchanged."}},"required":["projectId","slug"],"description":"Input for starting a TODO from a spec or from scratch — THE single accept path."},"StartFromSpecInput":{"type":"object","properties":{"projectId":{"type":"string","description":"Project to create the TODO in"},"specId":{"type":"string","description":"Optional spec ID — if provided, the spec is the base"},"propose":{"type":"boolean","description":"Create as a PROPOSED todo (analyzer suggestion): first message queued like a\ndraft, not yours until accepted (Start) or dismissed. Requires specId."},"note":{"type":"string","description":"Why this is proposed — folded into the todo content as a \"Why this matters\"\nline (propose only; no dedicated field on the todo)."},"title":{"type":"string","description":"Proposal title override — becomes the content's first line, i.e. the ✧ row\ntitle (propose only; defaults to the spec name)."},"priority":{"oneOf":[{"const":"low"},{"const":"medium"},{"const":"high"}],"description":"Proposal priority — folded into the content's \"Why this matters\" line when\nnot medium (propose only)."},"groupDescription":{"type":"string","description":"One-line strategic intent to upsert for groupTag (propose only)."},"content":{"type":"string","description":"User message / TODO content. Falls back to spec name+description if omitted"},"systemMessage":{"type":"string","description":"System message override. If omitted and specId provided, uses the spec's body"},"agentName":{"type":"string","description":"Agent name for on-the-fly TODOs (no specId). Defaults to \"Custom Agent\""},"scheduledTimestamp":{"type":"number","description":"Scheduling: omit for immediate start"},"attachments":{"type":"array","items":{"$ref":"#/components/schemas/AttachmentFrame"},"description":"Attachments"},"businessContextId":{"type":"string","description":"Business context ID"},"groupTag":{"type":"string","description":"Group slug. Empty/absent means ungrouped."},"groupName":{"type":"string","description":"Optional display name to upsert for groupTag."}},"required":["projectId"]},"UserSettingsUpdateInput":{"type":"object","properties":{"settings":{"$ref":"#/components/schemas/PartialOmitAppSettingsid"}},"required":["settings"]},"PartialOmitAppSettingsid":{"type":"object","properties":{"theme":{"type":"string"},"previewAutoColumns":{"type":"number","description":"Preferred column count used by the automatic preview-window layout. Defaults to 3."},"todoListTheme":{"oneOf":[{"const":"terminal"},{"const":"weblike"}]},"diffControl":{"type":"string"},"shellExecution":{"type":"string"},"emailNotifications":{"type":"boolean"},"pushNotifications":{"type":"boolean"},"dataAnalytics":{"type":"boolean"},"playSoundOnTaskComplete":{"type":"boolean"},"showTodoCompletionToast":{"type":"boolean"},"tabNotificationMode":{"oneOf":[{"const":"off","description":"Never show the red dot."},{"const":"until_focus","description":"Keep the dot until you return focus to the tab."},{"const":"until_interact","description":"Keep the dot until you click or type in the tab."}],"description":"How the browser-tab red \"done\" dot behaves after a TODO finishes."},"disabledMentionSources":{"type":"array","items":{"type":"string"},"description":"Disabled"},"keyboardBindings":{"$ref":"#/components/schemas/Recordstringstring"},"keyboardShortcutsEnabled":{"type":"boolean"},"defaultViewMode":{"type":"string"},"modelMentionAliases":{"type":"array","items":{"type":"string"},"description":"Enabled model-mention aliases (e.g. 'claude', 'gpt') for"},"showDiffMergeControls":{"type":"boolean","description":"Show accept/reject chunk controls in the diff (merge) view. Off by\ndefault — with auto-apply the diff is just a record of what got applied,\nso the controls are unnecessary noise."},"showAgentColors":{"type":"boolean"},"showAgentNameInComposer":{"type":"boolean","description":"Show the selected agent's name (with an expand chevron) on the collapsed\ncomposer trigger instead of the plain settings cog icon."},"showAllowAllButton":{"type":"boolean"},"showAutoDoneButton":{"type":"boolean","description":"Show the Auto-Done toggle in the message toolbar. When the toggle is on,\nthe next run's successful completion lands the todo in DONE instead of READY."},"showSystemPrompt":{"type":"boolean"},"showAgentJsonExport":{"type":"boolean","description":"Show the JSON export button in the agent settings modal header."},"showCloudWorkspaceBar":{"type":"boolean","description":"Show the workspace bar on the built-in Cloud device card. Hidden by\ndefault — the cloud workspace is always `/root` and virtually nobody\nshould change it."},"showProjectPickerInSidebar":{"oneOf":[{"const":"auto"},{"const":"off"},{"const":"always"}],"description":"Project picker at the top of the todo sidebar (team plan only). `off`\nhides it, `auto` shows it only when you have more than one project,\n`always` keeps it pinned. Defaults to `auto`."},"toolDisplayVerbosityDesktop":{"oneOf":[{"const":"collapsed"},{"const":"normal"},{"const":"debug"}],"description":"Tool-block display density, resolved per viewport. `collapsed` keeps\nnon-essential tool blocks collapsed (one-line summary, click to expand).\n`normal` opens them by default. `debug` additionally surfaces internal\nfields (pid, timeout, …) on shell/bash blocks. Desktop defaults to\n`normal`, mobile to `collapsed`."},"toolDisplayVerbosityMobile":{"oneOf":[{"const":"collapsed"},{"const":"normal"},{"const":"debug"}]},"groupToolDisplay":{"type":"boolean","description":"Collapse consecutive tool-only assistant messages into a single group row.\nBackend defaults to true (the recommended workflow); set false to render\neach tool block individually. Independent of verbose tool display."},"showThinkingTraces":{"type":"boolean","description":"Show the model's reasoning (\"Thinking\") blocks in the chat. Default off;\nwhen off, reason blocks render nothing, which also lets more consecutive\ntool messages collapse into a single group."},"vaultProvider":{"oneOf":[{"type":"null"},{"const":"custom"},{"const":"onepassword"},{"const":"bitwarden"}]},"vaultConfig":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/Recordstringstring"}]},"vaultProviders":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/Recordstring__type"}]},"hostDesktopItems":{"$ref":"#/components/schemas/RecordstringArrayHostDesktopItem","description":"Per-host desktop layout, keyed by host id (device/edge id, or \"cloud\").\nAn ordered list of items; array index IS the order. Items absent from a\nhost's list are appended (in the host's default order) on render, and\nitems whose key no longer exists are dropped."},"companyName":{"type":"string"},"vatNumber":{"type":"string"},"addressLine1":{"type":"string"},"addressLine2":{"type":"string"},"city":{"type":"string"},"state":{"type":"string"},"postalCode":{"type":"string"},"countryISO":{"type":"string"},"addressValid":{"type":"boolean"}},"required":[],"description":"Make all properties in T optional"},"BillingInfoInput":{"type":"object","properties":{"companyName":{"type":"string"},"vatNumber":{"type":"string"},"addressLine1":{"type":"string"},"addressLine2":{"type":"string"},"city":{"type":"string"},"state":{"type":"string"},"postalCode":{"type":"string"},"countryISO":{"type":"string"},"addressValid":{"type":"boolean"}},"required":[]},"BillingUpdateResult":{"type":"object","properties":{"success":{"type":"boolean"},"addressValid":{"type":"boolean"},"message":{"type":"string"}},"required":["success"],"description":"Result of updating billing info."},"ProjectSettingsFull":{"type":"object","properties":{"id":{"type":"string"},"projectId":{"type":"string"},"llmModel":{"type":"string"},"llmConfig":{"$ref":"#/components/schemas/Recordstringany"},"workspacePaths":{"type":"array","items":{"type":"string"}},"skills":{"$ref":"#/components/schemas/Recordstringany"},"diff":{"type":"string"},"preferences":{"$ref":"#/components/schemas/Recordstringany"}},"required":["id","projectId"],"description":"Extended project settings with LLM config and preferences."},"ProjectSettingsUpdateInput":{"type":"object","properties":{"projectId":{"type":"string"},"settings":{"$ref":"#/components/schemas/Recordstringunknown"}},"required":["projectId","settings"]},"ApiKey":{"type":"object","properties":{"name":{"type":"string"},"id":{"type":"string","description":"Not the secret key itself"},"createdAt":{"type":"number"},"isDefault":{"type":"boolean"}},"required":["name","id","createdAt","isDefault"],"description":"An API key for programmatic access."},"ApiKeyNameInput":{"type":"object","properties":{"name":{"type":"string"}},"required":["name"]},"ApiKeyValidation":{"type":"object","properties":{"valid":{"type":"boolean"},"error":{"oneOf":[{"type":"null"},{"type":"string"}]},"userId":{"type":"string"}},"required":["valid","error"],"description":"Result of validating an API key."},"TodoListInput":{"type":"object","properties":{"projectId":{"type":"string"},"limit":{"type":"number","description":"Page size (default 25, max 100)."},"cursor":{"type":"number","description":"`lastActivityAt` of the last item from the previous page (exclusive). Omit for first page."},"search":{"type":"string","description":"Optional content/status substring filter; switches to a full-project scan."},"starredOnly":{"type":"boolean","description":"If true, only return starred/favorite todos."},"agentSettingsId":{"type":"string","description":"Only todos run by this agent; served from the per-agent index."},"groupTag":{"type":"string","description":"Only todos in this board group (slug); served from the per-group index."},"businessContextId":{"type":"string","description":"Only todos bound to this business context; switches to a full-project scan."}},"required":["projectId"],"description":"Input for the paginated todo list."},"TodoPage":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/TodoSummary"}},"nextCursor":{"type":"number","description":"`lastActivityAt` of the last item; pass as `cursor` for the next page. Absent = last page."}},"required":["items"],"description":"Cursor-paginated page of lightweight todos, newest-activity-first (by lastActivityAt)."},"TodoSummary":{"type":"object","properties":{"id":{"type":"string"},"projectId":{"type":"string"},"status":{"$ref":"#/components/schemas/TodoStatus"},"agentSettingsId":{"type":"string"},"businessContextId":{"type":"string","description":"Domain-specific knowledge context"},"groupTag":{"type":"string","description":"Project-scoped group slug."},"content":{"type":"string"},"messageIds":{"type":"array","items":{"type":"string"}},"createdAt":{"type":"number"},"lastActivityAt":{"type":"number"},"starredAt":{"type":"number","description":"Star/favorite timestamp; absent/0 = not starred"},"scheduledTimestamp":{"type":"number","description":"0 if immediate"}},"required":["id","projectId","status","agentSettingsId","messageIds","createdAt","lastActivityAt","scheduledTimestamp"],"description":"Lightweight todo without full message content."},"TodoGetInput":{"type":"object","properties":{"todoId":{"type":"string"},"messageLimit":{"type":"number","description":"If set, include only the newest N messages (`hasMoreMessages` signals older ones). Omit for the full conversation."}},"required":["todoId"],"description":"Input for fetching a todo. `messageLimit` (opt-in) returns only the newest N messages."},"MessageSearchInput":{"type":"object","properties":{"query":{"type":"string","description":"Words to match in message content (AND semantics, punctuation ignored)."},"projectId":{"type":"string","description":"Restrict to one project (must be accessible). Omit to search all accessible projects."},"todoId":{"type":"string","description":"Restrict to one todo."},"role":{"oneOf":[{"const":"system"},{"const":"user"},{"const":"assistant"}],"description":"Restrict by message role."},"limit":{"type":"number","description":"Max hits (default 20, max 50)."},"semantic":{"type":"boolean","description":"Semantic (embedding KNN) search instead of full-text. Slower (~100ms), finds meaning not just keywords."}},"required":["query"],"description":"Full-text search over message content (scoped to the caller's accessible projects)."},"MessageSearchPage":{"type":"object","properties":{"hits":{"type":"array","items":{"$ref":"#/components/schemas/MessageSearchHit"}},"total":{"type":"number","description":"Total matches (may exceed hits.length)."}},"required":["hits","total"]},"MessageSearchHit":{"type":"object","properties":{"messageId":{"type":"string"},"todoId":{"type":"string"},"projectId":{"type":"string"},"role":{"type":"string"},"createdAt":{"type":"number"},"snippet":{"type":"string","description":"Leading portion of the message's searchable text (content + block texts/commands) (truncated)."},"score":{"type":"number","description":"Semantic search only: cosine distance to the query (0 = identical, 2 = opposite). Absent on full-text hits."}},"required":["messageId","todoId","projectId","role","createdAt","snippet"],"description":"One message matching a search query."},"UnifiedSearchInput":{"type":"object","properties":{"query":{"type":"string","description":"Words to match (AND semantics); semantic fill kicks in when exact results are thin."},"projectId":{"type":"string","description":"Restrict todo hits to one project (must be accessible). Omit for all accessible projects."},"limit":{"type":"number","description":"Max hits (default 20, max 50)."}},"required":["query"],"description":"Unified search over todo conversations (message index) and curated memory rows."},"UnifiedSearchPage":{"type":"object","properties":{"hits":{"type":"array","items":{"$ref":"#/components/schemas/UnifiedSearchHit"}}},"required":["hits"]},"UnifiedSearchHit":{"type":"object","properties":{"kind":{"oneOf":[{"const":"todo"},{"const":"memory"}]},"snippet":{"type":"string","description":"Why it matched: snippet centred on the first query word found."},"createdAt":{"type":"number"},"score":{"type":"number","description":"Semantic hits only: cosine distance to the query (0 = identical)."},"todoId":{"type":"string"},"projectId":{"type":"string"},"status":{"type":"string"},"title":{"type":"string","description":"First line of the todo's content."},"matchCount":{"type":"number","description":"How many messages in this todo matched."},"role":{"type":"string","description":"Role of the best-matching message."},"messageId":{"type":"string"},"address":{"type":"string","description":"Memory address `source/ref`."},"source":{"type":"string"},"content":{"type":"string","description":"Full note content (capped) for inline expansion."}},"required":["kind","snippet","createdAt"],"description":"One unified search hit. `kind` decides which optional fields are present:\n`todo` hits carry todoId/status/title, `memory` hits carry address/source/content.\nA present `score` (cosine distance) marks a semantic \"related\" hit — the query\nwords may not occur verbatim, so don't highlight them."},"TodoMessagesInput":{"type":"object","properties":{"todoId":{"type":"string"},"limit":{"type":"number","description":"Page size (default 50, max 200)."},"before":{"type":"string","description":"Fetch messages strictly OLDER than this messageId (the oldest already loaded). Omit for the newest page."}},"required":["todoId"],"description":"Input for paginated message fetch (newest-first pages, walking backwards)."},"MessagesPage":{"type":"object","properties":{"messages":{"type":"array","items":{"$ref":"#/components/schemas/Message"}},"hasMore":{"type":"boolean","description":"True if older messages exist before this page."}},"required":["messages","hasMore"],"description":"A page of messages in chat order (oldest → newest within the page)."},"ReportAiOutputInput":{"type":"object","properties":{"todoId":{"type":"string"},"messageId":{"type":"string"},"details":{"type":"string","maxLength":2000}},"required":["details"]},"TodoIdInput":{"type":"object","properties":{"todoId":{"type":"string","description":"The unique identifier of the todo item."}},"required":["todoId"],"description":"Input for identifying a specific todo item."},"TodoUpdateInput":{"type":"object","properties":{"todoId":{"type":"string","description":"The unique identifier of the todo to update"},"content":{"type":"string","description":"New content/prompt for the todo"},"scheduledTimestamp":{"type":"number","description":"Unix timestamp to schedule the todo (0 or omit for immediate)"},"agentSettingsId":{"type":"string","description":"ID of the agent settings to use for processing"},"businessContextId":{"type":"string","description":"ID of the business context to associate with this todo"},"groupTag":{"type":"string","description":"Group slug. Pass an empty string to make the todo ungrouped."},"starredAt":{"type":"number","description":"Star/favorite timestamp; pass a timestamp to star, 0 to unstar"},"isPublic":{"type":"boolean","description":"Make the todo publicly viewable (read-only) by anyone with the link"}},"required":["todoId"],"description":"Input for updating a todo's properties."},"TodoStatusUpdateInput":{"type":"object","properties":{"todoId":{"type":"string","description":"The unique identifier of the todo to update"},"status":{"$ref":"#/components/schemas/TodoStatus","description":"The new status to set. Valid values: 'idle', 'running', 'paused', 'completed', 'failed'"}},"required":["todoId","status"],"description":"Input for updating a todo's status.\nUse this to pause, resume, complete, or cancel a running todo."},"AddMessageInput":{"type":"object","properties":{"todoId":{"type":"string"},"projectId":{"type":"string"},"content":{"type":"string"},"agentSettings":{"$ref":"#/components/schemas/AgentSettings"},"attachments":{"type":"array","items":{"$ref":"#/components/schemas/AttachmentFrame"},"description":"Attachments metadata (content arrives separately via binary WebSocket frames or current attachments buffer)."},"scheduledTimestamp":{"type":"number"},"filteredEdgeTools":{"$ref":"#/components/schemas/RecordstringArrayMCPToolSkeleton"},"afterMessageId":{"type":"string"},"businessContextId":{"type":"string"},"autoDone":{"type":"boolean","description":"When true, the next successful agent completion lands in DONE (strikethrough)\ninstead of READY. Per-run flag — does not persist on the todo."}},"required":["todoId","projectId","content","agentSettings"]},"UpdateMessageInput":{"type":"object","properties":{"todoId":{"type":"string"},"messageId":{"type":"string"},"content":{"type":"string"},"attachments":{"type":"array","items":{"$ref":"#/components/schemas/AttachmentFrame"}},"scheduledTimestamp":{"type":"number"},"agentSettingsId":{"type":"string"},"filteredEdgeTools":{"$ref":"#/components/schemas/RecordstringArrayMCPToolSkeleton"}},"required":["todoId","messageId","agentSettingsId"]},"UpdateAndStartMessageInput":{"type":"object","properties":{"todoId":{"type":"string"},"messageId":{"type":"string","description":"The message to update and run. Omit for an unstarted draft — the server then starts the\ntodo's own first (and only) message, so callers that just want \"press Start\" don't have to\nfetch it first. Required when targeting a specific turn (e.g. a scheduled message)."},"content":{"type":"string"},"attachments":{"type":"array","items":{"$ref":"#/components/schemas/AttachmentFrame"}},"agentSettings":{"$ref":"#/components/schemas/AgentSettings"},"filteredEdgeTools":{"$ref":"#/components/schemas/RecordstringArrayMCPToolSkeleton"},"autoDone":{"type":"boolean","description":"When true, the next successful agent completion lands in DONE (strikethrough)\ninstead of READY. Per-run flag — does not persist on the todo."}},"required":["todoId","agentSettings"]},"TodoBlockSubTodoInput":{"type":"object","properties":{"todoId":{"type":"string"},"messageId":{"type":"string"},"blockId":{"type":"string"},"subTodoId":{"type":"string","description":"Todo id of the sub-agent run to nest inside the block."}},"required":["todoId","messageId","blockId","subTodoId"],"description":"Input for linking a spawned sub-agent todo to the block that launched it."},"TodoBlockIdInput":{"type":"object","properties":{"todoId":{"type":"string"},"blockId":{"type":"string"}},"required":["todoId","blockId"]},"TodoAgentSelectionInput":{"type":"object","properties":{"todoId":{"type":"string"},"agentSettingsId":{"type":"string"}},"required":["todoId","agentSettingsId"],"description":"Input for selecting/assigning an agent to a todo."},"TodoWorkflow":{"type":"object","properties":{"workflowMeta":{"oneOf":[{"type":"null"},{"type":"string"}]},"workflowVersion":{"oneOf":[{"type":"null"},{"type":"string"}]},"lastContextSummary":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/ContextSummary"}],"description":"The most recent context summary (if any compaction occurred)"}},"required":["workflowMeta","workflowVersion"],"description":"Workflow metadata for a todo."},"ContextSummary":{"type":"object","properties":{"outputTokens":{"type":"number","description":"Token count after compaction"},"timestamp":{"type":"number","description":"When compaction happened"},"messageIds":{"type":"array","items":{"type":"string"},"description":"Which messages were summarized"},"summary":{"type":"string","description":"Plain summary text. Kept so the divider can display the compaction result directly."},"summaryAttachment":{"$ref":"#/components/schemas/AttachmentFrame","description":"The summary as an attachment frame, ready to be attached to a message"},"status":{"oneOf":[{"const":"ready"},{"const":"used"}],"description":"Status: 'ready' = waiting to be used, 'used' = already attached to a message"}},"required":["outputTokens","timestamp","messageIds"],"description":"Represents a context compaction event - when old messages are summarized"},"WorkflowUpdateInput":{"type":"object","properties":{"todoId":{"type":"string"},"workflowMeta":{"type":"string"},"workflowVersion":{"type":"string"},"contextSummaryUsed":{"type":"boolean","description":"Set to true to mark the pending context summary as 'used'"}},"required":["todoId","workflowMeta","workflowVersion"]},"PendingTask":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string"},"content":{"type":"string"},"createdAt":{"type":"number"}},"required":["id","type","createdAt"]},"UserBalance":{"type":"object","properties":{"manualBalance":{"type":"number"},"subscriptionBalance":{"type":"number"}},"required":["manualBalance","subscriptionBalance"]},"PaginationInput":{"type":"object","properties":{"page":{"type":"number"},"limit":{"type":"number"}},"required":[]},"TransactionPage":{"type":"object","properties":{"transactions":{"type":"array","items":{"$ref":"#/components/schemas/Transaction"}},"total":{"type":"number"},"page":{"type":"number"},"limit":{"type":"number"},"totalPages":{"type":"number"}},"required":["transactions","total","page","limit","totalPages"]},"Transaction":{"type":"object","properties":{"id":{"type":"string"},"type":{"$ref":"#/components/schemas/TransactionType"},"amount":{"type":"number"},"totalAmount":{"type":"number"},"description":{"type":"string"},"source":{"type":"string"},"createdAt":{"type":"number"}},"required":["id","type","amount","description","createdAt"]},"TransactionType":{"oneOf":[{"const":"CREDIT"},{"const":"DEBIT"}]},"InvoicesInput":{"type":"object","properties":{"limit":{"type":"number"},"cursor":{"type":"string"}},"required":[]},"InvoicesPage":{"type":"object","properties":{"invoices":{"type":"array","items":{"$ref":"#/components/schemas/Invoice"}},"hasMore":{"type":"boolean"},"nextCursor":{"type":"string"}},"required":["invoices","hasMore"],"description":"Paginated list of invoices."},"Invoice":{"type":"object","properties":{"id":{"type":"string"},"invoiceNumber":{"type":"string"},"stripeInvoiceId":{"type":"string"},"stripeInvoiceUrl":{"type":"string"},"totalAmount":{"type":"number"},"currency":{"type":"string"},"status":{"type":"string"},"dueDate":{"type":"number"},"paidDate":{"type":"number"},"items":{"type":"string"},"notes":{"type":"string"},"createdAt":{"type":"number"},"updatedAt":{"type":"number"}},"required":["id","invoiceNumber","totalAmount","currency","status","dueDate","items","createdAt","updatedAt"]},"PaymentIntentInput":{"type":"object","properties":{"amount":{"type":"number"},"paymentMethodId":{"type":"string"}},"required":["amount"]},"PaymentIntent":{"type":"object","properties":{"clientSecret":{"type":"string"},"subtotal":{"type":"number"},"taxAmount":{"type":"number"},"totalAmount":{"type":"number"}},"required":["clientSecret","subtotal","taxAmount","totalAmount"]},"SetupIntent":{"type":"object","properties":{"clientSecret":{"type":"string"}},"required":["clientSecret"]},"PaymentMethodList":{"type":"object","properties":{"paymentMethods":{"type":"array","items":{"$ref":"#/components/schemas/PaymentMethod"}},"defaultPaymentMethodId":{"oneOf":[{"type":"null"},{"type":"string"}]}},"required":["paymentMethods"]},"PaymentMethod":{"type":"object","properties":{"id":{"type":"string"},"card":{"type":"object","properties":{"brand":{"type":"string"},"last4":{"type":"string"},"exp_month":{"type":"number"},"exp_year":{"type":"number"}},"required":["brand","last4","exp_month","exp_year"]},"isDefault":{"type":"boolean"}},"required":["id","card","isDefault"],"description":"A saved payment method."},"PaymentMethodIdInput":{"type":"object","properties":{"paymentMethodId":{"type":"string"}},"required":["paymentMethodId"]},"SubscriptionInfo":{"type":"object","properties":{"subscriptionId":{"oneOf":[{"type":"null"},{"type":"string"}]},"tier":{"$ref":"#/components/schemas/SubscriptionTier"},"status":{"oneOf":[{"type":"null"},{"const":"active"},{"const":"past_due"},{"const":"canceled"},{"const":"trialing"}]},"currentPeriodEnd":{"oneOf":[{"type":"null"},{"type":"number"}]},"usageThisMonth":{"type":"number"},"usageLimit":{"oneOf":[{"type":"null"},{"type":"number"}]},"billingCycleStart":{"oneOf":[{"type":"null"},{"type":"number"}]},"interval":{"oneOf":[{"type":"null"},{"const":"monthly"},{"const":"yearly"}],"description":"How the active subscription is billed; null for free/none. Plan changes must\nstay on this interval, so the pricing toggle follows it."}},"required":["subscriptionId","tier","status","currentPeriodEnd","usageThisMonth","usageLimit","billingCycleStart","interval"],"description":"Current subscription status for a user"},"SubscriptionTier":{"oneOf":[{"const":"none"},{"const":"hobby"},{"const":"starter"},{"const":"pro"},{"const":"ultra"},{"const":"team_free"},{"const":"team"},{"const":"scale"}]},"SubscriptionPlansResponse":{"type":"object","properties":{"plans":{"type":"array","items":{"$ref":"#/components/schemas/SubscriptionPlan"}}},"required":["plans"],"description":"Available subscription plans response"},"SubscriptionPlan":{"type":"object","properties":{"tier":{"$ref":"#/components/schemas/SubscriptionTier"},"name":{"type":"string"},"priceMonthly":{"type":"number"},"priceYearly":{"type":"number"},"usageLimit":{"type":"number"},"description":{"type":"string"},"features":{"type":"array","items":{"type":"string"}},"isFree":{"type":"boolean"},"maxSeats":{"type":"number"}},"required":["tier","name","priceMonthly","priceYearly","usageLimit","features"]},"CreateSubscriptionInput":{"type":"object","properties":{"tier":{"oneOf":[{"const":"hobby"},{"const":"starter"},{"const":"pro"},{"const":"ultra"},{"const":"team_free"},{"const":"team"},{"const":"scale"}]},"interval":{"$ref":"#/components/schemas/BillingInterval"},"couponCode":{"type":"string","description":"Optional Stripe promotion code (customer-facing, e.g. \"LAUNCH100\") to pre-apply at checkout."}},"required":["tier","interval"],"description":"Input for creating a subscription"},"BillingInterval":{"oneOf":[{"const":"monthly"},{"const":"yearly"}]},"SubscriptionResult":{"type":"object","properties":{"success":{"type":"boolean"},"subscriptionId":{"type":"string"},"clientSecret":{"type":"string"},"checkoutUrl":{"type":"string"},"message":{"type":"string"}},"required":["success"],"description":"Result of a subscription operation"},"CancelSubscriptionInput":{"type":"object","properties":{"cancelAtPeriodEnd":{"type":"boolean"}},"required":["cancelAtPeriodEnd"],"description":"Input for canceling a subscription"},"UpdateSubscriptionInput":{"type":"object","properties":{"newTier":{"oneOf":[{"const":"hobby"},{"const":"starter"},{"const":"pro"},{"const":"ultra"},{"const":"team_free"},{"const":"team"},{"const":"scale"}]},"interval":{"oneOf":[{"const":"monthly"},{"const":"yearly"}]},"couponCode":{"type":"string","description":"Optional promo code — only applied when upgrading from a free tier to a first paid plan."}},"required":["newTier"],"description":"Input for updating a subscription"},"UsageStatus":{"type":"object","properties":{"totalBalance":{"type":"number"},"manualBalance":{"type":"number"},"subscriptionBalance":{"type":"number"},"tier":{"$ref":"#/components/schemas/SubscriptionTier"},"hasActivePaidSubscription":{"type":"boolean"},"allowExtraSpend":{"type":"boolean"},"creditLimit":{"type":"number"},"monthlyTopUp":{"oneOf":[{"type":"null"},{"type":"number"}]},"percentUsed":{"type":"number"},"usageThisMonth":{"type":"number"},"billingCycleStart":{"oneOf":[{"type":"null"},{"type":"number"}]},"session":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/UsageWindow"}]},"weekly":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/UsageWindow"}]}},"required":["totalBalance","manualBalance","subscriptionBalance","tier","hasActivePaidSubscription","allowExtraSpend","creditLimit","monthlyTopUp","percentUsed","usageThisMonth","billingCycleStart","session","weekly"],"description":"Usage status showing current usage vs limit"},"UsageWindow":{"type":"object","properties":{"usedPercent":{"type":"number"},"resetsAt":{"type":"number"},"pacePercent":{"type":"number"}},"required":["usedPercent","resetsAt"],"description":"A usage window's state for display (no $ exposed in the UI)."},"TeamInfo":{"type":"object","properties":{"ownerId":{"type":"string"},"ownerEmail":{"type":"string"},"maxSeats":{"type":"number"},"isOwner":{"type":"boolean"},"myRole":{"$ref":"#/components/schemas/TeamRole"},"canManage":{"type":"boolean"},"active":{"type":"boolean"},"promoBoost":{"type":"boolean"},"members":{"type":"array","items":{"$ref":"#/components/schemas/TeamMemberInfo"}},"invites":{"type":"array","items":{"$ref":"#/components/schemas/TeamInviteInfo"}},"joinDomain":{"type":"string","description":"Email domain that auto-joins this team on signup/sign-in; undefined = off."},"eligibleDomain":{"type":"string","description":"Domain the owner is eligible to enable (their own, when not a public mail provider)."},"teamProjectId":{"type":"string","description":"The team's shared project: every member holds write access; new members are\nauto-granted on join and stripped on leave. Undefined = not set up yet."}},"required":["ownerId","ownerEmail","maxSeats","isOwner","myRole","canManage","active","promoBoost","members","invites"],"description":"Team view for owner or member."},"TeamMemberInfo":{"type":"object","properties":{"id":{"type":"string"},"email":{"type":"string"},"name":{"type":"string"},"role":{"$ref":"#/components/schemas/TeamRole"}},"required":["id","email","role"]},"TeamInviteInfo":{"type":"object","properties":{"email":{"type":"string"},"role":{"$ref":"#/components/schemas/TeamRole"},"invitedAt":{"type":"number"},"expiresAt":{"type":"number"}},"required":["email","role","invitedAt","expiresAt"],"description":"A sent-but-not-yet-accepted invite. Holds no seat until accepted."},"TeamAddMemberInput":{"type":"object","properties":{"email":{"type":"string"},"role":{"oneOf":[{"const":"owner"},{"const":"admin"},{"const":"member"}]}},"required":["email"]},"TeamRevokeInviteInput":{"type":"object","properties":{"email":{"type":"string"}},"required":["email"]},"TeamSetProjectInput":{"type":"object","properties":{"projectId":{"type":"string","description":"Project to convert — must be owned by the team owner. Omit to unset (revert to personal)."}},"required":[],"description":"Designate (convert) a project as the team's shared project, or clear it."},"TeamSetJoinDomainInput":{"type":"object","properties":{"enabled":{"type":"boolean","description":"true = auto-join on the owner's verified email domain, false = off."}},"required":["enabled"]},"TeamInviteTokenInput":{"type":"object","properties":{"token":{"type":"string"}},"required":["token"]},"TeamInvitePreview":{"type":"object","properties":{"ownerEmail":{"type":"string","description":"Masked (`j***@acme.com`) — a forwarded link must not leak the owner's address."},"email":{"type":"string","description":"Full invited address — the invite email already contains it, and the\nsign-in form prefills from it."},"role":{"$ref":"#/components/schemas/TeamRole"},"teamName":{"type":"string"}},"required":["ownerEmail","email","role","teamName"],"description":"What an invite recipient sees before signing in. Public, non-consuming."},"TeamSetRoleInput":{"type":"object","properties":{"memberId":{"type":"string"},"role":{"$ref":"#/components/schemas/TeamRole"}},"required":["memberId","role"]},"TeamRemoveMemberInput":{"type":"object","properties":{"memberId":{"type":"string"}},"required":["memberId"]},"AllowExtraSpendInput":{"type":"object","properties":{"allow":{"type":"boolean"}},"required":["allow"],"description":"Opt-in \"extra usage\": exhausted windows fall through to manual credit."},"EdgeData":{"type":"object","properties":{"id":{"type":"string"},"deviceType":{"$ref":"#/components/schemas/DeviceType"},"metadata":{"$ref":"#/components/schemas/Recordstringany"},"name":{"type":"string"},"workspacepaths":{"type":"array","items":{"type":"string"},"description":"Local filesystem paths the agent can access"},"installedMCPs":{"$ref":"#/components/schemas/RecordstringInstalledMCP","description":"MCP servers installed on this device"},"installedTools":{"$ref":"#/components/schemas/RecordstringCatalogToolState","description":"Catalog tool states (installed, authenticated) reported by the edge"},"mcp_json":{"$ref":"#/components/schemas/Recordstringany","description":"Raw MCP config JSON"},"mcp_config_path":{"type":"string"},"ownerId":{"type":"string"},"status":{"$ref":"#/components/schemas/EdgeStatus"},"createdAt":{"type":"number"}},"required":["id","deviceType","metadata","name","workspacepaths","installedMCPs","ownerId","status","createdAt"],"description":"A connected edge device (local computer, phone, extension)."},"DeviceType":{"oneOf":[{"const":"PC"},{"const":"ANDROID"},{"const":"IOS"},{"const":"WEB_EXTENSION"},{"const":"EXTENSION"},{"const":"cli"},{"const":"SHELL"},{"const":"SANDBOX","description":"Ephemeral Firecracker VM — bridge connects back via enroll_token"},{"const":"BROWSER","description":"In-tab browser edge: File System Access API mounted folder, read+write via WS"},{"const":"UNKNOWN","description":"Redeemer didn't (or couldn't) self-identify — fall back so the device still gets created."}]},"RecordstringInstalledMCP":{"type":"object","properties":{},"required":[],"description":"Construct a type with a set of properties K of type T","additionalProperties":{"$ref":"#/components/schemas/InstalledMCP"}},"InstalledMCP":{"type":"object","properties":{"id":{"type":"string"},"serverId":{"type":"string"},"tools":{"type":"array","items":{"$ref":"#/components/schemas/MCPToolSkeleton"}},"status":{"type":"string"},"registryId":{"type":"string"},"command":{"type":"string"},"args":{"type":"array","items":{"type":"string"}},"env":{"$ref":"#/components/schemas/MCPEnv"}},"required":["serverId","registryId","command"]},"MCPEnv":{"type":"object","properties":{},"required":[],"additionalProperties":{"type":"string"}},"EdgeStatus":{"oneOf":[{"const":"ONLINE"},{"const":"OFFLINE"}]},"EdgeIdInput":{"type":"object","properties":{"edgeId":{"type":"string"}},"required":["edgeId"]},"EdgeUpdateInput":{"type":"object","properties":{"edgeId":{"type":"string"},"updates":{"$ref":"#/components/schemas/EdgeUpdateFields"}},"required":["edgeId","updates"]},"EdgeUpdateFields":{"type":"object","properties":{"name":{"type":"string"},"workspacepaths":{"type":"array","items":{"type":"string"}},"installedMCPs":{"$ref":"#/components/schemas/RecordstringInstalledMCP"},"installedTools":{"$ref":"#/components/schemas/RecordstringCatalogToolState"}},"required":[],"description":"Fields for updating an edge."},"DeviceData":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"userId":{"type":"string"},"deviceType":{"type":"string"},"metadata":{"$ref":"#/components/schemas/Recordstringany","description":"Bridge identity fields (os, arch, hostname, user, shell, home, ...) persisted on auth."},"workspacepaths":{"type":"array","items":{"type":"string"},"description":"Filesystem roots the user has authorized AI shell sessions to operate within."},"status":{"$ref":"#/components/schemas/DeviceStatus"},"createdAt":{"type":"number"},"lastSeenAt":{"type":"number"}},"required":["id","name","userId","deviceType","metadata","workspacepaths","status","createdAt","lastSeenAt"],"description":"Public device view returned by `trpc.device.list` and injected into agent context."},"DeviceStatus":{"oneOf":[{"const":"ONLINE"},{"const":"OFFLINE"},{"const":"STOPPED"}]},"IdInput":{"type":"object","properties":{"id":{"type":"string"}},"required":["id"]},"DeviceExecInput":{"type":"object","properties":{"id":{"type":"string"},"cmd":{"type":"string","description":"Shell command to run on the device. Frontend is responsible for quoting/escaping."},"cwd":{"type":"string","description":"Optional working directory for the command."},"timeoutMs":{"type":"number","description":"Per-call timeout (ms). Defaults to 10s server-side."}},"required":["id","cmd"]},"DeviceExecOutput":{"type":"object","properties":{"stdout":{"type":"string","description":"Combined stdout/stderr, merged at the bridge PTY."},"exitCode":{"oneOf":[{"type":"null"},{"type":"number"}],"description":"Process exit code, or null if the run was killed/timed out before exit."},"truncated":{"type":"boolean","description":"True iff output exceeded the transport's output cap and was truncated."},"timedOut":{"type":"boolean","description":"True iff the run hit `timeoutMs` and was killed."}},"required":["stdout","exitCode","truncated","timedOut"]},"AgentListInput":{"type":"object","properties":{"workspacePath":{"type":"string"},"name":{"type":"string"}},"required":[]},"AgentIdInput":{"type":"object","properties":{"agentSettingsId":{"type":"string"}},"required":["agentSettingsId"]},"AgentReorderInput":{"type":"object","properties":{"agentSettingsIds":{"type":"array","items":{"type":"string"}}},"required":["agentSettingsIds"]},"AgentUpdateInput":{"type":"object","properties":{"agentSettingsId":{"type":"string"},"updates":{"$ref":"#/components/schemas/PartialAgentSettingsUpdate"}},"required":["agentSettingsId","updates"]},"PartialAgentSettingsUpdate":{"type":"object","properties":{"name":{"type":"string"},"color":{"type":"string","description":"Hex color (e.g. '#10b981') used to tint todos assigned to this agent"},"model":{"type":"string","description":"LLM model identifier (e.g., 'claude-3-opus')"},"systemMessage":{"type":"string","description":"Custom system prompt for the agent"},"thinkingLevel":{"oneOf":[{"const":"max"},{"const":"ultra"},{"const":"low"},{"const":"medium"},{"const":"high"},{"const":"xhigh"}]},"temperature":{"type":"number"},"systemMessageMode":{"oneOf":[{"const":"raw"},{"const":"default_coder"},{"const":"custom_w_tools"}],"description":"'default_coder' uses built-in coding prompt, 'custom_w_tools' uses systemMessage + auto-injected\ncapability sections, 'raw' uses systemMessage verbatim (no global prepend, no tool/routing/workspace sections)."},"smartSystemPrompt":{"type":"boolean","description":"Auto-enhance system prompt based on context"},"mcpConfigs":{"$ref":"#/components/schemas/MCPSettings","description":"Cloud MCP server configurations"},"edgesMcpConfigs":{"$ref":"#/components/schemas/MCPEdgesSettings","description":"Edge device MCP configurations by edgeId"},"devicesConfig":{"$ref":"#/components/schemas/DevicesConfig","description":"Bridge device workspace + cwd config by deviceId. Parallel to `edgesMcpConfigs`."},"permissions":{"$ref":"#/components/schemas/ToolPermissions","description":"Tool permission allowlist"},"specId":{"type":"string","description":"Spec this agent was created from"}},"required":[],"description":"Make all properties in T optional"},"AgentMCPInput":{"type":"object","properties":{"agentSettingsId":{"type":"string"},"mcpName":{"type":"string"},"config":{"$ref":"#/components/schemas/ServerSettings"}},"required":["agentSettingsId","mcpName","config"]},"AgentEdgeMCPInput":{"type":"object","properties":{"agentSettingsId":{"type":"string"},"edgeId":{"type":"string"},"mcpName":{"type":"string"},"config":{"$ref":"#/components/schemas/ServerSettings"}},"required":["agentSettingsId","edgeId","mcpName","config"]},"AgentDeviceConfigInput":{"type":"object","properties":{"agentSettingsId":{"type":"string"},"deviceId":{"type":"string"},"config":{"$ref":"#/components/schemas/PartialDeviceConfig","description":"Partial — merged over the existing per-device entry, so callers can flip\na single field (e.g. `{ enabled: false }`) without re-sending paths."}},"required":["agentSettingsId","deviceId","config"]},"PartialDeviceConfig":{"type":"object","properties":{"workspacePaths":{"type":"array","items":{"type":"string"}},"enabled":{"oneOf":[{"const":"auto"},{"const":"on"},{"type":"boolean"}],"description":"Per-agent device state. For ordinary devices, false disables and every\nother value enables. The hosted cloud VM additionally supports:\n  false              → Off.\n  'auto'             → use only when no local desktop is online.\n  'on'               → explicitly always on (overrides global Auto/Off).\n  true / undefined   → enabled, inheriting the per-user global cloud mode.\n`true` remains the inherited state for compatibility with existing agent\nrecords, where it was written before explicit cloud modes existed."},"deviceType":{"oneOf":[{"const":"PC"},{"const":"ANDROID"},{"const":"IOS"},{"const":"WEB_EXTENSION"},{"const":"EXTENSION"},{"const":"cli"},{"const":"SHELL"},{"const":"SANDBOX","description":"Ephemeral Firecracker VM — bridge connects back via enroll_token"},{"const":"BROWSER","description":"In-tab browser edge: File System Access API mounted folder, read+write via WS"},{"const":"UNKNOWN","description":"Redeemer didn't (or couldn't) self-identify — fall back so the device still gets created."}],"description":"Device type — used by the agent for capability checks (e.g. has_shell vs\nhas_cdp). Surfaced at submit time by enrichWithOnlineDevices."},"name":{"type":"string","description":"Device identity surfaced at submit time so the agent can render the\ndevice in `## Available Machines` (name heading, tool-alias suffix)."},"metadata":{"$ref":"#/components/schemas/Recordstringany"},"installedTools":{"$ref":"#/components/schemas/RecordstringCatalogToolState","description":"Catalog tool states injected by the backend at submit time."}},"required":[],"description":"Make all properties in T optional"},"GlobalAgentSettings":{"type":"object","properties":{"systemMessage":{"type":"string"},"model":{"type":"string"},"thinkingLevel":{"oneOf":[{"const":"max"},{"const":"ultra"},{"const":"low"},{"const":"medium"},{"const":"high"},{"const":"xhigh"}]},"temperature":{"type":"number"},"permissions":{"$ref":"#/components/schemas/ToolPermissions"},"mcpConfigs":{"$ref":"#/components/schemas/MCPSettings"},"edgesMcpConfigs":{"$ref":"#/components/schemas/MCPEdgesSettings"},"devicesConfig":{"$ref":"#/components/schemas/DevicesConfig"}},"required":[],"description":"Global agent defaults (subset of AgentSettings)"},"BusinessContextInfoResponse":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"createdAt":{"type":"number"},"uri":{"type":"string"}},"required":["id","name","createdAt","uri"]},"ContextIdInput":{"type":"object","properties":{"id":{"type":"string"}},"required":["id"]},"BusinessContextCreateInput":{"type":"object","properties":{"name":{"type":"string"}},"required":["name"]},"BusinessContextUpdateInput":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id"]},"SetSelectedContextInput":{"type":"object","properties":{"contextId":{"oneOf":[{"type":"null"},{"type":"string"}]}},"required":["contextId"]},"SuggestBrandVoiceAnswerInput":{"type":"object","properties":{"businessContextId":{"type":"string"},"question":{"type":"string"}},"required":["businessContextId","question"],"description":"Input for AI-suggesting an answer to a brand-voice question using business context"},"SuggestBrandVoiceAnswerOutput":{"type":"object","properties":{"answer":{"type":"string"}},"required":["answer"],"description":"Output: the AI-suggested answer, or empty string if unavailable"},"RefineBrandVoiceInput":{"type":"object","properties":{"businessContextId":{"type":"string"},"answers":{"$ref":"#/components/schemas/Recordstringstring","description":"The user's answers to the brand-voice questions (question → answer)."},"source":{"oneOf":[{"const":"social"},{"const":"answers"},{"const":"company"}],"description":"Force a source. Omit to auto-detect (usable answers → 'answers', else 'company').\n'social' learns from a public page/handle (`sourceUrl`), labelled by `channel`."},"channel":{"type":"string","description":"Social channel label when source==='social' (e.g. 'X', 'LinkedIn')."},"sourceUrl":{"type":"string","description":"Public link or handle to read for source==='social' (e.g. an X/LinkedIn profile URL).\nNot a connection — we just fetch the page's public text. If empty or unreadable, the\nvoice falls back to company info."}},"required":["businessContextId","answers"],"description":"Input for the voice refinement loop — learns the user's/company's writing\nstyle from their answers (or a mock social import) and returns a voice profile."},"RefineBrandVoiceOutput":{"type":"object","properties":{"profile":{"type":"string"},"match":{"type":"number"},"source":{"oneOf":[{"const":"social"},{"const":"answers"},{"const":"company"}]},"note":{"type":"string"},"iterations":{"type":"array","items":{"$ref":"#/components/schemas/VoiceIteration"}},"channel":{"type":"string"},"answerFeedback":{"$ref":"#/components/schemas/Recordstringstring","description":"Per-answer feedback (question → hint) for answers the arbiter judged too weak to\nlearn a style from — why it fell short + how to make it usable. Only present when\nsome answers were provided but not used."}},"required":["profile","match","source","iterations"],"description":"Output of the voice refinement loop — a learned VoiceProfile."},"PredictReplyInput":{"type":"object","properties":{"todoId":{"type":"string"},"afterMessageId":{"type":"string","description":"The assistant message id the prediction is for (the current tail). The server predicts only\nif this still matches the live tail, so a stale request for an old turn returns ''."}},"required":["todoId","afterMessageId"],"description":"Input for predicting the user's next message (ghost-text suggestion) in a chat."},"PredictReplyOutput":{"type":"object","properties":{"suggestion":{"type":"string"}},"required":["suggestion"],"description":"Output: the predicted next user message, or '' when no useful prediction."},"ContextInfoInput":{"type":"object","properties":{"todoId":{"type":"string"},"model":{"type":"string"}},"required":["todoId"],"description":"Input for getting context info"},"ContextInfo":{"type":"object","properties":{"todoId":{"type":"string","description":"The todo ID this context info belongs to"},"model":{"type":"string","description":"The model being used"},"contextWindow":{"type":"number","description":"Maximum context window size in tokens"},"usedTokens":{"type":"number","description":"Current tokens used"},"utilizationPercent":{"type":"number","description":"Percentage of context window used (0-100)"},"messageCount":{"type":"number","description":"Number of messages in the conversation"},"shouldCompact":{"type":"boolean","description":"Whether context compaction is recommended"},"warningLevel":{"oneOf":[{"const":"normal"},{"const":"warning"},{"const":"critical"}],"description":"Warning level based on utilization"},"breakdown":{"$ref":"#/components/schemas/ContextTokenBreakdown","description":"Detailed token breakdown"}},"required":["todoId","model","contextWindow","usedTokens","utilizationPercent","messageCount","shouldCompact","warningLevel","breakdown"],"description":"Context usage information for a conversation/todo"},"ContextTokenBreakdown":{"type":"object","properties":{"inputTokens":{"type":"number"},"outputTokens":{"type":"number"},"cacheReadTokens":{"type":"number"},"cacheWriteTokens":{"type":"number"}},"required":["inputTokens","outputTokens","cacheReadTokens","cacheWriteTokens"],"description":"Token breakdown for context tracking"},"AvailableModels":{"type":"object","properties":{"models":{"type":"array","items":{"$ref":"#/components/schemas/ModelContextInfo"}}},"required":["models"],"description":"List of available models"},"ModelContextInfo":{"type":"object","properties":{"name":{"type":"string"},"contextWindow":{"type":"number"}},"required":["name","contextWindow"],"description":"Available model with its context window"},"CompactInput":{"type":"object","properties":{"todoId":{"type":"string"},"dryRun":{"type":"boolean","description":"If true, only simulate compaction without making changes"},"targetUtilization":{"type":"number","description":"Target utilization percentage after compaction (0-1, default 0.5 = 50%)"}},"required":["todoId"],"description":"Input for context compaction"},"CompactResult":{"type":"object","properties":{"success":{"type":"boolean"},"originalMessages":{"type":"number"},"compactedMessages":{"type":"number"},"savedMessages":{"type":"number"},"summary":{"type":"string"},"message":{"type":"string"}},"required":["success","originalMessages","compactedMessages","savedMessages"],"description":"Result of a context compaction operation"},"AddContextSummaryInput":{"type":"object","properties":{"todoId":{"type":"string"},"outputTokens":{"type":"number","description":"Token count after compaction"},"timestamp":{"type":"number","description":"When compaction happened"},"messageIds":{"type":"array","items":{"type":"string"},"description":"Which messages were summarized"},"summary":{"type":"string","description":"Plain summary text"},"summaryAttachment":{"$ref":"#/components/schemas/AttachmentFrame","description":"The summary as an attachment frame"},"status":{"oneOf":[{"const":"ready"},{"const":"used"}],"description":"Status: 'ready' = waiting to be used, defaults to 'ready'"}},"required":["todoId","outputTokens","timestamp","messageIds"],"description":"Input for adding a context summary"},"AttachmentIdInput":{"type":"object","properties":{"attachmentId":{"type":"string"}},"required":["attachmentId"]},"Attachment":{"type":"object","properties":{"userId":{"type":"string","description":"Owner user ID"},"agentSettingsId":{"type":"string","description":"Scoped to agent settings"},"todoId":{"type":"string","description":"Scoped to todo"},"symlinkTo":{"type":"string","description":"If this is a symlink share, the attachment ID of the owner's original file"},"metadata":{"$ref":"#/components/schemas/AttachmentMetadata","description":"Storage metadata (checksum, etc.)"},"id":{"type":"string"},"uri":{"type":"string","description":"Resource URI - always required. Format: \"todoforai:todos/{todoId}/{id}\""},"originalName":{"type":"string"},"mimeType":{"type":"string"},"fileSize":{"type":"number","description":"In bytes"},"createdAt":{"type":"number"},"isPublic":{"type":"boolean"},"status":{"oneOf":[{"const":"UPDATED"},{"const":"DELETED"},{"const":"NEW"},{"const":"NONE"}]},"modifiedAt":{"type":"number","description":"Last modified time (mtime), milliseconds epoch"},"permissions":{"type":"number","description":"Unix permission bits (e.g. 0o644 = 420 decimal)"},"blockId":{"type":"string","description":"Block ID that produced this attachment (for mapping tool results back to tool_calls)"},"toolCallId":{"type":"string","description":"LLM tool_call ID — for stamping results back to the originating tool call"}},"required":["metadata","id","uri","originalName","mimeType","fileSize"],"description":"Storage model for attachments. Extends AttachmentFrame with scoping and metadata."},"AttachmentMetadata":{"type":"object","properties":{"checksum":{"type":"string"},"fieldnameTruncated":{"type":"boolean"},"valueTruncated":{"type":"boolean"}},"required":[]},"AttachmentByTodoInput":{"type":"object","properties":{"todoId":{"type":"string"},"limit":{"type":"number"},"offset":{"type":"number"}},"required":["todoId"]},"AttachmentByAgentInput":{"type":"object","properties":{"agentSettingsId":{"type":"string"},"limit":{"type":"number"},"offset":{"type":"number"}},"required":["agentSettingsId"]},"AttachmentByUserInput":{"type":"object","properties":{"userId":{"type":"string"},"limit":{"type":"number"},"offset":{"type":"number"}},"required":["userId"]},"ResourceUriInput":{"type":"object","properties":{"uri":{"type":"string"}},"required":["uri"]},"ResourceContentOutput":{"type":"object","properties":{"content":{"type":"string"}},"required":["content"]},"ResourceListInput":{"type":"object","properties":{"uri":{"type":"string"},"pageSize":{"type":"number"},"pageToken":{"type":"string"}},"required":["uri"]},"ResourceListOutput":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/AttachmentFrame"}},"nextPageToken":{"type":"string"}},"required":["items"]},"ResourceDeleteOutput":{"type":"object","properties":{"success":{"type":"boolean"},"uri":{"type":"string"}},"required":["success","uri"]},"ResourceContentUpdateInput":{"type":"object","properties":{"uri":{"type":"string"},"content":{"type":"string"}},"required":["uri","content"]},"ResourceCreateFolderInputparentUristringMinLength1namestringMinLength1":{"type":"object","properties":{"parentUri":{"type":"string","minLength":1},"name":{"type":"string","minLength":1}},"required":["parentUri","name"]},"ResourceCreateFolderOutput":{"type":"object","properties":{"uri":{"type":"string"}},"required":["uri"]},"ResourceTokenInputttl(numberMinimum60Maximum86400)undefined":{"type":"object","properties":{"ttl":{"type":"number","minimum":60,"maximum":86400,"description":"Token lifetime in seconds. Defaults to 3600."}},"required":[]},"ResourceTokenOutput":{"type":"object","properties":{"token":{"type":"string"},"expiresAt":{"type":"number","description":"Unix timestamp in milliseconds."}},"required":["token","expiresAt"]},"TemplateCategoryInput":{"type":"object","properties":{"category":{"type":"string"}},"required":[],"description":"Optional category filter for template listing"},"TodoSpecPublic":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string"},"id":{"type":"string"},"source":{"$ref":"#/components/schemas/TodoSpecSource"},"updatedAt":{"type":"number"},"createdAt":{"type":"number"},"short":{"type":"string"},"categories":{"type":"array","items":{"type":"string"}},"requirements":{"type":"array","items":{"type":"string"},"description":"Capability requirements, e.g. \"cli:gh\", \"extension:chrome\"."},"body":{"type":"string","description":"The agent prompt body (markdown) — split into system/user via splitTemplateBody."},"forkedFrom":{"type":"string","description":"Spec id or todo id this was forked from (set by share / save-as-template)."}},"required":["name","description","id","source","updatedAt","createdAt","categories","body"],"description":"Public read shape of a spec — internal user ids and visibility internals stripped."},"TodoSpecSource":{"oneOf":[{"const":"builtin"},{"const":"authored"}],"description":"Who owns a spec's content. 'builtin' = seeded from todo-registry.json and\nrefreshed on deploy; editing copies-on-write to 'authored' (user-owned, never\nreseeded). Fork provenance lives in `forkedFrom`, not here."},"SpecCreateInputnamestringMinLength1MaxLength120descriptionstringMinLength1bodystringMinLength...":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":120},"description":{"type":"string","minLength":1},"body":{"type":"string","minLength":1,"description":"The agent prompt body (markdown)."},"short":{"type":"string"},"categories":{"type":"array","items":{"type":"string"}},"requirements":{"type":"array","items":{"type":"string"}},"visibility":{"oneOf":[{"const":"public"},{"const":"private"}]}},"required":["name","description","body"]},"TodoSpec":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"short":{"type":"string"},"description":{"type":"string"},"categories":{"type":"array","items":{"type":"string"}},"requirements":{"type":"array","items":{"type":"string"},"description":"Capability requirements, e.g. \"cli:gh\", \"extension:chrome\"."},"body":{"type":"string","description":"The agent prompt body (markdown) — split into system/user via splitTemplateBody."},"source":{"$ref":"#/components/schemas/TodoSpecSource"},"forkedFrom":{"type":"string","description":"Spec id or todo id this was forked from (set by share / save-as-template)."},"visibility":{"oneOf":[{"const":"public"},{"const":"private"}]},"createdBy":{"type":"string"},"createdAt":{"type":"number"},"updatedAt":{"type":"number"}},"required":["id","name","description","categories","body","source","visibility","createdBy","createdAt","updatedAt"],"description":"The reusable todo definition — single source of truth for a todo's content."},"SpecPatchInput":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"body":{"type":"string"},"short":{"type":"string"},"categories":{"type":"array","items":{"type":"string"}},"requirements":{"type":"array","items":{"type":"string"}},"visibility":{"oneOf":[{"const":"public"},{"const":"private"}]}},"required":["id"],"description":"Partial edit of a spec (PATCH /specs/{id}). Editing a builtin copies-on-write to 'authored'."},"RegistryPack":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"short":{"type":"string"},"description":{"type":"string"},"categories":{"type":"array","items":{"type":"string"}},"todoIds":{"type":"array","items":{"type":"string"}},"createdAt":{"type":"number"},"updatedAt":{"type":"number"}},"required":["id","name","description","todoIds","createdAt","updatedAt"],"description":"Pack as returned by GET /registry/packs — a curated list of spec ids."},"RecordstringTodoStats":{"type":"object","properties":{},"required":[],"description":"Construct a type with a set of properties K of type T","additionalProperties":{"$ref":"#/components/schemas/TodoStats"}},"TodoStats":{"type":"object","properties":{"id":{"type":"string"},"starts":{"type":"number","description":"Times started/forked"},"likes":{"type":"number"},"completionRate":{"type":"number","description":"0-100"},"avgCompletionTime":{"type":"number","description":"In milliseconds"},"isLiked":{"type":"boolean","description":"Current user has liked"}},"required":["id","starts","likes","completionRate","avgCompletionTime","isLiked"],"description":"Public statistics for a todo in the registry."},"RecordstringPackStats":{"type":"object","properties":{},"required":[],"description":"Construct a type with a set of properties K of type T","additionalProperties":{"$ref":"#/components/schemas/PackStats"}},"PackStats":{"type":"object","properties":{"id":{"type":"string"},"likes":{"type":"number"},"isLiked":{"type":"boolean"}},"required":["id","likes","isLiked"]},"RecordstringSpecMetaPublic":{"type":"object","properties":{},"required":[],"description":"Construct a type with a set of properties K of type T","additionalProperties":{"$ref":"#/components/schemas/SpecMetaPublic"}},"SpecMetaPublic":{"type":"object","properties":{"id":{"type":"string"},"todoCount":{"type":"number","description":"How many TODOs created from this spec"},"messageCount":{"type":"number","description":"Total messages across all TODOs"},"totalCost":{"type":"number","description":"Total cost across all TODOs (USD)"},"totalDuration":{"type":"number","description":"Total AI processing duration across all TODOs (ms), summed from RunMeta.elapsed"}},"required":["id","todoCount","messageCount","totalCost","totalDuration"],"description":"Public-facing aggregated usage metadata for a registry spec."},"ShareCreateInputtext(stringMaxLength100000)undefined":{"type":"object","properties":{"text":{"type":"string","maxLength":100000},"todoId":{"type":"string","description":"Fork the first user prompt of this TODO into a spec instead of raw text."}},"required":[]},"ShareCreateResponse":{"type":"object","properties":{"specId":{"type":"string"},"placementId":{"type":"string"},"url":{"type":"string"}},"required":["specId","placementId","url"],"description":"Response from POST /shares — the forked spec + placement, and a ready-to-copy open URL."},"ClaimMintInput":{"type":"object","properties":{"seedProjectId":{"type":"string","description":"Public project recipients fork on claim (must be owned by the caller)."},"emails":{"type":"array","items":{"type":"string"},"description":"One link per email (attribution only, not a gate). Omit for a single anonymous link."},"ttlSec":{"type":"number","description":"Link lifetime in seconds."}},"required":["seedProjectId"],"description":"Input for POST /claims/mint. Mints one single-use link per email (or one anonymous link when `emails` is omitted)."},"ClaimMintResponse":{"type":"object","properties":{"links":{"type":"array","items":{"$ref":"#/components/schemas/ClaimLink"}}},"required":["links"],"description":"Response from POST /claims/mint."},"ClaimLink":{"type":"object","properties":{"email":{"type":"string"},"url":{"type":"string"}},"required":["url"],"description":"A single minted claim link."},"ClaimPreviewInput":{"type":"object","properties":{"token":{"type":"string"}},"required":["token"],"description":"Input for POST /claims/preview — read the seed a claim link points at (non-consuming)."},"ClaimPreviewResponse":{"type":"object","properties":{"seedProjectId":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"email":{"type":"string","description":"Attribution email the link was minted for, if any."},"brandMarkdown":{"type":"string","description":"The seed's brand page markdown (growth-plan block included), if it has one."},"cards":{"type":"array","items":{"$ref":"#/components/schemas/ClaimPreviewCard"},"description":"The seed's suggested recommendation cards."}},"required":["seedProjectId","name"],"description":"Response from POST /claims/preview — enough to render the claim confirmation."},"ClaimPreviewCard":{"type":"object","properties":{"specId":{"type":"string"},"title":{"type":"string"},"note":{"type":"string"},"priority":{"oneOf":[{"const":"low"},{"const":"medium"},{"const":"high"}]},"group":{"type":"string","description":"Board group slug (strategic workstream) the card belongs to, if any."}},"required":["specId","title"],"description":"One recommendation card on the claim preview (title resolved server-side)."},"ClaimRedeemInput":{"type":"object","properties":{"token":{"type":"string"}},"required":["token"],"description":"Input for POST /claims/redeem."},"ClaimRedeemResponse":{"type":"object","properties":{"newProjectId":{"type":"string"}},"required":["newProjectId"],"description":"Response from POST /claims/redeem — the id of the freshly forked, owned project."},"PrewarmStartInput":{"type":"object","properties":{"url":{"type":"string","format":"url"},"email":{"type":"string","format":"email"},"noMint":{"type":"boolean"}},"required":["url"],"description":"Prewarm: build a claim seed from a prospect website (headless onboarding).\n`name`/`timeoutSec` are intentionally CLI-only, not exposed over the API."},"PrewarmJobOutput":{"type":"object","properties":{"id":{"type":"string"},"status":{"oneOf":[{"const":"error"},{"const":"running"},{"const":"done"}]},"projectId":{"type":"string"},"claimLinks":{"type":"array","items":{"type":"string"}},"log":{"type":"array","items":{"type":"string"}},"error":{"type":"string"}},"required":["id","status","claimLinks","log"],"description":"Mirrors PrewarmJob in PrewarmService."},"PrewarmStatusInput":{"type":"object","properties":{"id":{"type":"string"}},"required":["id"]},"AdminAddCreditInput":{"type":"object","properties":{"email":{"type":"string","format":"email"},"amount":{"type":"number","exclusiveMinimum":0},"description":{"type":"string"}},"required":["email","amount"],"description":"AdminAddCreditInput with email + positive amount validation"},"AdminAddCreditResult":{"type":"object","properties":{"userId":{"type":"string"},"email":{"type":"string"},"previousBalance":{"type":"number"},"newBalance":{"type":"number"},"amount":{"type":"number"}},"required":["userId","email","previousBalance","newBalance","amount"],"description":"Result of an admin manual credit grant."},"AdminSetSubscriptionInput":{"type":"object","properties":{"email":{"type":"string","format":"email"},"tier":{"oneOf":[{"const":"hobby"},{"const":"starter"},{"const":"pro"},{"const":"ultra"},{"const":"team_free"},{"const":"team"},{"const":"scale"}]}},"required":["email","tier"],"description":"AdminSetSubscriptionInput with email validation"},"AdminSetSubscriptionResult":{"type":"object","properties":{"userId":{"type":"string"},"email":{"type":"string"},"tier":{"$ref":"#/components/schemas/SubscriptionTier"},"subscriptionBalance":{"type":"number"}},"required":["userId","email","tier","subscriptionBalance"],"description":"Result of an admin subscription activation."},"AdminRevokeSubscriptionInput":{"type":"object","properties":{"email":{"type":"string","format":"email"}},"required":["email"],"description":"AdminRevokeSubscriptionInput with email validation"},"AdminRevokeSubscriptionResult":{"type":"object","properties":{"userId":{"type":"string"},"email":{"type":"string"},"message":{"type":"string"}},"required":["userId","email","message"],"description":"Result of an admin subscription revoke."},"AdminSetSeatsInput":{"type":"object","properties":{"email":{"type":"string","format":"email"},"seats":{"type":"integer","minimum":1,"maximum":1000}},"required":["email"],"description":"AdminSetSeatsInput with email + sane seat bounds"},"AdminSetSeatsResult":{"type":"object","properties":{"userId":{"type":"string"},"email":{"type":"string"},"seats":{"type":"number"},"isOverride":{"type":"boolean"}},"required":["userId","email","seats","isOverride"],"description":"Result of an admin seat override."},"AdminEmailInput":{"type":"object","properties":{"email":{"type":"string","format":"email"}},"required":["email"],"description":"AdminEmailInput with email validation"},"AdminUser":{"type":"object","properties":{"id":{"type":"string"},"email":{"type":"string"},"name":{"type":"string"},"image":{"oneOf":[{"type":"null"},{"type":"string"}]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"isAnonymous":{"type":"boolean"}},"required":["id","email","createdAt","updatedAt","isAnonymous"],"description":"User info for admin views."},"AdminStats":{"type":"object","properties":{"totalUsers":{"type":"number"},"registeredUsers":{"type":"number"},"anonymousUsers":{"type":"number"},"newUsers7d":{"type":"number"},"daily":{"type":"array","items":{"$ref":"#/components/schemas/DailyUserCount"}},"generatedAt":{"type":"number"}},"required":["totalUsers","registeredUsers","anonymousUsers","newUsers7d","daily","generatedAt"],"description":"Aggregate user stats for the admin dashboard."},"DailyUserCount":{"type":"object","properties":{"date":{"type":"string"},"registered":{"type":"number"},"anonymous":{"type":"number"}},"required":["date","registered","anonymous"],"description":"New signups on a single UTC day."},"ChallengeCreateInput":{"type":"object","properties":{"email":{"type":"string","format":"email"},"challenge":{"type":"string"}},"required":["challenge"],"description":"ChallengeCreateInput with optional email validation"},"Challenge":{"type":"object","properties":{"id":{"type":"string"},"challenge":{"type":"string"},"email":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}},"required":["id","challenge","createdAt"],"description":"A verification challenge."},"HexGrid":{"type":"object","properties":{"id":{"type":"string"},"projectId":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"createdAt":{"type":"number"},"updatedAt":{"type":"number"}},"required":["id","projectId","name","createdAt","updatedAt"],"description":"A hex grid associated with a project."},"HexGridIdInput":{"type":"object","properties":{"gridId":{"type":"string"}},"required":["gridId"]},"HexGridCreateFullInput":{"type":"object","properties":{"projectId":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"}},"required":["projectId","name"],"description":"Input for creating a hex grid within a project."},"HexGridUpdateInput":{"type":"object","properties":{"gridId":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"}},"required":["gridId"]},"GridTile":{"type":"object","properties":{"id":{"type":"string"},"gridId":{"type":"string"},"q":{"type":"number"},"r":{"type":"number"},"todoId":{"type":"string"},"label":{"type":"string"},"metadata":{"$ref":"#/components/schemas/Recordstringany"},"createdAt":{"type":"number"},"updatedAt":{"type":"number"}},"required":["id","gridId","q","r","createdAt","updatedAt"],"description":"A tile at axial coordinates (q, r) within a hex grid."},"GridTileIdInput":{"type":"object","properties":{"gridId":{"type":"string"},"q":{"type":"number"},"r":{"type":"number"}},"required":["gridId","q","r"]},"GridTileCreateInput":{"type":"object","properties":{"gridId":{"type":"string"},"q":{"type":"number"},"r":{"type":"number"},"label":{"type":"string"},"metadata":{"$ref":"#/components/schemas/Recordstringany"}},"required":["gridId","q","r"]},"GridTileUpdateInput":{"type":"object","properties":{"gridId":{"type":"string"},"q":{"type":"number"},"r":{"type":"number"},"label":{"type":"string"},"metadata":{"$ref":"#/components/schemas/Recordstringany"}},"required":["gridId","q","r"]},"GridTileMoveInput":{"type":"object","properties":{"gridId":{"type":"string"},"q":{"type":"number"},"r":{"type":"number"},"newQ":{"type":"number"},"newR":{"type":"number"}},"required":["gridId","q","r","newQ","newR"]},"GridTileAttachTodoInput":{"type":"object","properties":{"gridId":{"type":"string"},"q":{"type":"number"},"r":{"type":"number"},"todoId":{"type":"string"}},"required":["gridId","q","r","todoId"]},"GridTileDetachTodoInput":{"type":"object","properties":{"gridId":{"type":"string"},"q":{"type":"number"},"r":{"type":"number"}},"required":["gridId","q","r"]},"GridTileSwapInput":{"type":"object","properties":{"gridId":{"type":"string"},"q1":{"type":"number"},"r1":{"type":"number"},"q2":{"type":"number"},"r2":{"type":"number"}},"required":["gridId","q1","r1","q2","r2"]},"GridTilesByTodoInput":{"type":"object","properties":{"todoId":{"type":"string"}},"required":["todoId"]},"RecommendationGenerateInput":{"type":"object","properties":{"projectId":{"type":"string"},"businessContextId":{"type":"string","description":"Business context to analyse; falls back to the user's selected context."},"direction":{"type":"string","description":"Free-text steer sent to the analyzer as a chat message (e.g. \"focus on TikTok\", \"more B2B leads\")."}},"required":["projectId"],"description":"Input to trigger a steered recommendation generation run for a project."},"RecommendationGenerateResponse":{"type":"object","properties":{"todoId":{"type":"string"}},"required":["todoId"],"description":"Result of a generation run: the Business Analyzer todo producing the cards."},"PlacementCreateInput":{"type":"object","properties":{"kind":{"const":"recommendation"},"specId":{"type":"string"},"projectId":{"type":"string"},"businessContextId":{"type":"string"},"title":{"type":"string"},"note":{"type":"string"},"priority":{"oneOf":[{"const":"low"},{"const":"medium"},{"const":"high"}]},"group":{"type":"string","description":"Board group slug (strategic workstream) for the card; upserted on creation."},"groupName":{"type":"string","description":"Optional display name to upsert for `group`."},"groupDescription":{"type":"string","description":"One-line strategic intent to upsert for `group` (routes future todos into it)."}},"required":["specId","projectId"],"description":"Input for proposing a spec as a PROPOSED todo (todoforai-cli recommend + trpc).\n`kind` is a legacy wire field old CLIs still send; it carries no meaning."},"OnboardingUpdateInput":{"type":"object","properties":{"expectedUpdatedAt":{"type":"number","description":"Client's last known updatedAt; reject if server doc is newer"},"patch":{"$ref":"#/components/schemas/PartialOmitOnboardingversionidupdatedAt"}},"required":["patch"],"description":"Patch input for PUT /onboarding — all fields optional, replaces the doc."},"PartialOmitOnboardingversionidupdatedAt":{"type":"object","properties":{"startedAt":{"type":"number"},"completedAt":{"type":"number"},"currentStep":{"type":"string"},"websiteUrl":{"type":"string"},"styleAnswers":{"$ref":"#/components/schemas/Recordstringstring"},"styleAiAnswers":{"$ref":"#/components/schemas/RecordstringRecordstringstring","description":"AI-suggested brand-voice drafts, scoped by businessContextId → question → answer"},"voiceProfiles":{"$ref":"#/components/schemas/RecordstringVoiceProfile","description":"Learned voice profile from the refinement loop, scoped by businessContextId."}},"required":[],"description":"Make all properties in T optional"},"SandboxRecord":{"type":"object","properties":{"id":{"type":"string"},"user_id":{"type":"string"},"kind":{"oneOf":[{"const":"vm"},{"const":"lite"}],"description":"Defaults to 'vm' for legacy records that pre-date the field."},"template":{"type":"string"},"size":{"description":"VmSize tier; not modelled in TS — frontend passes through as-is."},"state":{"$ref":"#/components/schemas/SandboxStateValue"},"ip_address":{"oneOf":[{"type":"null"},{"type":"string"}]},"tap_device":{"oneOf":[{"type":"null"},{"type":"string"}]},"pid":{"oneOf":[{"type":"null"},{"type":"number"}]},"device_id":{"type":"string","description":"Id of the backend Device row representing this sandbox's bridge.\nLite: set at create time. VM: set after the bridge enrolls and the\nbackend calls `attach-device`. Absent when not yet linked."},"created_at":{"type":"number"},"last_activity":{"type":"number"},"error":{"oneOf":[{"type":"null"},{"type":"string"}]}},"required":["id","user_id","template","state","ip_address","tap_device","pid","created_at","last_activity","error"]},"SandboxStateValue":{"oneOf":[{"const":"error"},{"const":"creating"},{"const":"running"},{"const":"paused"},{"const":"terminating"},{"const":"terminated"}],"description":"Sandbox lifecycle state change. Published by sandbox-manager on Redis\n(`sandbox:events:<userId>`), re-emitted by backend to subscribed frontends.\n\n- On create/pause/resume/error/terminate: `sandbox` holds the full record.\n- On delete: `deleted: true` and `sandbox` is omitted; frontend drops the row."},"CodexImageGenInput":{"type":"object","properties":{"content":{"type":"array","items":{"$ref":"#/components/schemas/CodexImageGenContent"}},"model":{"type":"string"},"size":{"$ref":"#/components/schemas/CodexImageSize","description":"Required for billing — `auto` is rejected since we can't price the result deterministically."},"quality":{"oneOf":[{"const":"low"},{"const":"medium"},{"const":"high"}]},"background":{"oneOf":[{"const":"auto"},{"const":"transparent"},{"const":"opaque"}]},"outputFormat":{"oneOf":[{"const":"png"},{"const":"jpeg"},{"const":"webp"}]},"instructions":{"type":"string"}},"required":["content","size"],"description":"Input for the /codex/imagegen endpoint — runs Codex's native image_generation tool."},"CodexImageGenContent":{"oneOf":[{"type":"object","properties":{"type":{"const":"input_text"},"text":{"type":"string"}},"required":["type","text"]},{"type":"object","properties":{"type":{"const":"input_image"},"imageUrl":{"type":"string"}},"required":["type","imageUrl"]}],"description":"Content item for Codex image_generation tool. `imageUrl` accepts data URLs or http(s) URLs."},"CodexImageSize":{"oneOf":[{"const":"1024x1024"},{"const":"1536x1024"},{"const":"1024x1536"},{"const":"2048x2048"},{"const":"4096x4096"}]},"CodexImageGenOutput":{"type":"object","properties":{"image":{"type":"string","description":"Base64-encoded image bytes (no data URL prefix)."},"format":{"type":"string","description":"Output format: png | webp | jpeg"},"cost":{"type":"number"},"elapsed":{"type":"number"},"revisedPrompt":{"type":"string"}},"required":["image","format"],"description":"Output from /codex/imagegen — base64 image + metadata."},"RcloneOauthStartInput":{"type":"object","properties":{"provider":{"type":"string","description":"Catalog key — must be a registered OAuth provider (see `rcloneProviders.ts`)."},"deviceId":{"type":"string","description":"Device the remote is configured on — the host whose rclone panel opened\nthe flow. Must be owned by the caller and online."}},"required":["provider","deviceId"],"description":"Start an OAuth flow for a configured provider."},"RcloneOauthStartOutput":{"type":"object","properties":{"authUrl":{"type":"string","description":"Provider's authorization URL — open in a popup."},"remoteName":{"type":"string","description":"The rclone remote name we'll create on success — frontend can pre-display it."}},"required":["authUrl","remoteName"]},"RcloneOauthCompleteInput":{"type":"object","properties":{"code":{"type":"string","description":"Authorization code from the provider's redirect."},"state":{"type":"string","description":"Signed state token — verified, replay-checked, and decoded server-side."}},"required":["code","state"],"description":"Complete the flow after the callback fires."},"RcloneOauthCompleteOutput":{"type":"object","properties":{"remoteName":{"type":"string","description":"The rclone remote name now configured on the target device."},"provider":{"type":"string","description":"Catalog provider key, echoed so the frontend can invalidate the right queries."}},"required":["remoteName","provider"]}},"securitySchemes":{"ApiKey":{"type":"apiKey","in":"header","name":"X-API-Key","description":"User API key from Settings → API Keys"},"Bearer":{"type":"http","scheme":"bearer","description":"BetterAuth session / OAuth access token"}}},"security":[{"ApiKey":[]},{"Bearer":[]}],"tags":[{"name":"adminUser"},{"name":"agentSettings"},{"name":"apiKey"},{"name":"attachment"},{"name":"auth"},{"name":"billing"},{"name":"businessContext"},{"name":"challenge"},{"name":"claim"},{"name":"cli"},{"name":"codex"},{"name":"context"},{"name":"device"},{"name":"edge"},{"name":"enroll"},{"name":"frontendHost"},{"name":"hexGrid"},{"name":"meta"},{"name":"onboarding"},{"name":"project"},{"name":"rcloneOauth"},{"name":"recommendation"},{"name":"resource"},{"name":"sandbox"},{"name":"settings"},{"name":"share"},{"name":"task"},{"name":"todo"},{"name":"todoRegistry"},{"name":"usage"},{"name":"user"}]}