diff --git a/README.md b/README.md index df7f822..99c73c0 100644 --- a/README.md +++ b/README.md @@ -191,3 +191,15 @@ MIT ### 收到的 Calendar 邀請 `event show`/`event agenda` 的 JSON 保留 optional `invitation`(外部 UID/Organizer);Imported Event 的 `event set` 回 `IMPORTED_EVENT_READ_ONLY`,刪除與還原不寄 attendee email。`email show` 保留 optional `calendar_sync`,event_id 僅在同時具備 Calendar read 權限時回傳。此版 upstream 收件同步預設停用,須待 provider 信任驗證後才啟用。 + +### Recurring Todo 固定 assignee + +建立 rule 時可用 `--assignee-user-id` 指定目前 Workspace Member;省略時指派給 creator。Rule 建立後不能修改 assignee。 + +```bash +wspc todo rule add "Weekly review" --rrule "FREQ=WEEKLY" --dtstart 2026-09-15 --project prj_xxx --assignee-user-id usr_xxx +wspc todo rule ls --project-id prj_xxx +wspc todo rule show tdr_xxx --json +``` + +List/show 的 pretty 與 JSON 輸出顯示 creator、assignee 及 `assignee_status`。`not_member` 與 `unknown` 暫停產生或重建,保留既有 Todos。需要換人時先刪除舊 rule,再以適當起始日期建立新 rule,避免重複工作。 diff --git a/spec/openapi.json b/spec/openapi.json index 65a6020..58bc4fb 100644 --- a/spec/openapi.json +++ b/spec/openapi.json @@ -2623,6 +2623,29 @@ ], "description": "Request body for POST `/calendar/events`. `start` and `end` must be the same kind (both timed ISO datetimes with offset, or both ISO date-only for all-day) and `end` must be strictly after `start`." }, + "CalendarSubscription": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + }, + "version": { + "type": "integer", + "minimum": 0 + }, + "url": { + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "enabled", + "version", + "url" + ] + }, "DeleteEventResponse": { "type": "object", "properties": { @@ -5033,6 +5056,17 @@ "RecurrenceRule": { "type": "object", "properties": { + "assignee_user_id": { + "type": "string" + }, + "assignee_status": { + "type": "string", + "enum": [ + "valid", + "not_member", + "unknown" + ] + }, "id": { "type": "string" }, @@ -5073,6 +5107,7 @@ } }, "required": [ + "assignee_user_id", "id", "user_id", "project_id", @@ -5087,6 +5122,10 @@ "CreateRecurrenceRuleBody": { "type": "object", "properties": { + "assignee_user_id": { + "type": "string", + "minLength": 1 + }, "rrule": { "type": "string", "minLength": 1 @@ -5953,7 +5992,8 @@ } ] } - } + }, + "additionalProperties": {} }, "UpdateTodoBody": { "type": "object", @@ -22883,10 +22923,10 @@ { "schema": { "type": "string", - "description": "Optional full-text search across title, description, and location (case-insensitive substring)." + "description": "Optional literal substring search across title, description, and location. ASCII case-insensitive; UTF-8 text is supported. Percent and underscore are literal characters, not wildcards." }, "required": false, - "description": "Optional full-text search across title, description, and location (case-insensitive substring).", + "description": "Optional literal substring search across title, description, and location. ASCII case-insensitive; UTF-8 text is supported. Percent and underscore are literal characters, not wildcards.", "name": "q", "in": "query" }, @@ -22977,7 +23017,7 @@ "in": "query" } ], - "description": "### Overview\nReturn the authenticated user's events, ordered by `start` ascending, with cursor pagination.\n\n### When to Use\nRender calendar list/grid views, search for specific terms using full-text search, query events within a specific time window, or retrieve historically past events.\n\n### Constraints\n- **Default Visibility**: By default, soft-deleted events and past events (events where `end` is before the current time) are automatically hidden.\n- **Time Bounds Override**: Supplying any explicit time bound query parameter (`start_from`, `start_to`, `end_from`, `end_to`) or passing `include_past=true` overrides and disables the implicit past filter.\n- **Calendar Trash**: `deleted_only=true` returns only soft-deleted events for the current user and Workspace. It overrides `include_deleted` and disables the implicit past filter regardless of `include_past`. Explicit time bounds and `q` still apply. Series Masters remain single rows; cancelled occurrences are not Trash.\n- **Search Scope**: `q` performs a case-insensitive substring search across `title`, `description`, and `location`.\n- **Pagination**: Default `limit` is 50, clamped to `[1, 200]`. Matching events are ordered by `start ASC, id ASC` before cursor pagination. Cursor is a page position, not a Consistency bookmark or snapshot.\n\n### Troubleshooting\n- Returns 400 `VALIDATION_ERROR` if date query bounds are invalid (e.g. `start_from > start_to` or `end_from > end_to`).", + "description": "### Overview\nReturn the authenticated user's events, ordered by `start` ascending, with cursor pagination.\n\n### When to Use\nRender calendar list/grid views, search for literal text, query events within a specific time window, or retrieve historically past events.\n\n### Constraints\n- **Default Visibility**: By default, soft-deleted events and past events (events where `end` is before the current time) are automatically hidden.\n- **Time Bounds Override**: Supplying any explicit time bound query parameter (`start_from`, `start_to`, `end_from`, `end_to`) or passing `include_past=true` overrides and disables the implicit past filter.\n- **Calendar Trash**: `deleted_only=true` returns only soft-deleted events for the current user and Workspace. It overrides `include_deleted` and disables the implicit past filter regardless of `include_past`. Explicit time bounds and `q` still apply. Series Masters remain single rows; cancelled occurrences are not Trash.\n- **Search Scope**: `q` performs a literal substring search across `title`, `description`, and `location`. ASCII case-insensitive; UTF-8 text is supported. Percent and underscore are literal characters, not wildcards.\n- **Pagination**: Default `limit` is 50, clamped to `[1, 200]`. Matching events are ordered by `start ASC, id ASC` before cursor pagination. Cursor is a page position, not a Consistency bookmark or snapshot.\n\n### Troubleshooting\n- Returns 400 `VALIDATION_ERROR` if date query bounds are invalid (e.g. `start_from > start_to` or `end_from > end_to`).", "security": [ { "bearerAuth": [] @@ -23354,115 +23394,28 @@ } } }, - "/calendar/events/{id}": { - "delete": { - "operationId": "event_delete", - "tags": [ - "Events" - ], - "x-cli": { - "command": "event rm", - "positional": [ - "id" - ], - "examples": [ - "wspc event rm evt_xxx" - ], - "display": { - "shape": "object", - "format": { - "id": "id-short", - "deleted_at": "relative-time" - } - } - }, - "summary": "Soft-delete a calendar event", - "parameters": [ - { - "name": "x-cb-cal", - "in": "header", - "required": false, - "description": "Optional opaque consistency bookmark returned by a previous calendar response. Send it back unchanged to continue read-after-write consistency for calendar D1 data.", - "schema": { - "type": "string" - }, - "example": "opaque-consistency-bookmark" - }, - { - "schema": { - "type": "string", - "description": "Event id (`evt_` for new rows; legacy UUID ids remain accepted)." - }, - "required": true, - "description": "Event id (`evt_` for new rows; legacy UUID ids remain accepted).", - "name": "id", - "in": "path" - } - ], - "description": "### Overview\nSoft-delete an existing calendar event, hiding it from default listings.\n\n### When to Use\nRemove an event entirely from the user's historical view and calendar client. If the meeting was cancelled but should remain in history (notifying participants of cancellation), use `PATCH /calendar/events/{id}` with `status: cancelled` instead.\n\n### Constraints\n- **Optimistic Locking**: Supports optional optimistic locking via `expected_version` in the request body.\n- **Side Effects**: When soft-deleting an event with attendees, all participants will asynchronously receive a cancellation email containing an `.ics` CANCEL attachment via Cloudflare `waitUntil`.\n- **Recovery**: The record is preserved in the database as a soft-deleted row and can be brought back using `POST /calendar/events/{id}/restore`.\n\n### Troubleshooting\n- Returns 404 `NOT_FOUND` if the event does not exist, or has already been soft-deleted.\n- Returns 409 `VERSION_CONFLICT` if `expected_version` does not match the database value.", - "security": [ - { - "bearerAuth": [] - } - ], + "/calendar/subscription": { + "post": { + "operationId": "calendar_create_subscription", "x-codeSamples": [ { - "lang": "shell", + "lang": "Shell", "label": "curl", - "source": "curl -X DELETE https://api.wspc.ai/calendar/events/evt_01HW3K4N9V5G6Z8C2Q7B1Y0M3F \\\n -H \"Authorization: Bearer $WSPC_API_KEY\" \\\n -H \"Content-Type: application/json\" \\\n -d '{}'" - }, - { - "lang": "bash", - "label": "wspc CLI", - "source": "wspc event rm evt_01HW3K4N9V5G6Z8C2Q7B1Y0M3F" + "source": "curl -X POST \"https://api.wspc.ai/calendar/subscription\" -H \"Authorization: Bearer $WSPC_API_KEY\"" } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/VersionBody" - }, - "examples": { - "minimal": { - "summary": "Delete without optimistic lock", - "value": {} - }, - "full": { - "summary": "Delete only if still at the version we last read", - "value": { - "expected_version": 3 - } - } - } - } - } - }, + "tags": [ + "Events" + ], + "summary": "Create a private calendar subscription", + "description": "Create a subscription or return the same active link. A private read-only link to all your event details in the current Workspace. Anyone with the link can read them. External calendar updates depend on that app's refresh schedule and can be delayed.", "responses": { "200": { - "description": "The event was soft-deleted. Response carries `id`, `deleted_at`, and the post-delete `version`. Cancellation emails are sent asynchronously.", - "headers": { - "x-cb-cal": { - "description": "Opaque consistency bookmark for the latest calendar database position observed by this request. Store and send it on the next calendar request to continue read-after-write consistency.", - "schema": { - "type": "string" - } - } - }, + "description": "Current subscription state", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/DeleteEventResponse" - }, - "examples": { - "happyPath": { - "summary": "Soft-delete acknowledged", - "value": { - "id": "evt_01HW3K4N9V5G6Z8C2Q7B1Y0M3F", - "deleted_at": 1748822400000, - "version": 2 - } - } + "$ref": "#/components/schemas/CalendarSubscription" } } } @@ -23632,7 +23585,7 @@ } }, "409": { - "description": "Optimistic-lock conflict. The supplied `expected_version` does not match the server's current version. Refetch the resource and retry.", + "description": "VERSION_CONFLICT: read the current state before retrying. SUBSCRIPTION_DISABLED: create a link before resetting it.", "content": { "application/json": { "schema": { @@ -23657,17 +23610,6 @@ "required": [ "error" ] - }, - "examples": { - "versionConflict": { - "summary": "expected_version does not match server version", - "value": { - "error": { - "code": "VERSION_CONFLICT", - "message": "expected_version 3 but current is 4" - } - } - } } } } @@ -23753,133 +23695,1252 @@ } } } - } - } - }, - "get": { - "operationId": "event_get", - "tags": [ - "Events" - ], - "x-cli": { - "command": "event show", - "positional": [ - "id" - ], - "examples": [ - "wspc event show evt_xxx" - ], - "display": { - "shape": "object", - "format": { - "id": "id-short", - "user_id": "id-short", - "status": "status-badge", - "start": "relative-time", - "end": "relative-time", - "created_at": "relative-time", - "updated_at": "relative-time", - "deleted_at": "relative-time" - } - } - }, - "summary": "Get a calendar event by id", - "parameters": [ - { - "name": "x-cb-cal", - "in": "header", - "required": false, - "description": "Optional opaque consistency bookmark returned by a previous calendar response. Send it back unchanged to continue read-after-write consistency for calendar D1 data.", - "schema": { - "type": "string" - }, - "example": "opaque-consistency-bookmark" - }, - { - "schema": { - "type": "string", - "description": "Event id (`evt_` for new rows; legacy UUID ids remain accepted)." - }, - "required": true, - "description": "Event id (`evt_` for new rows; legacy UUID ids remain accepted).", - "name": "id", - "in": "path" - }, - { - "schema": { - "type": "string", - "description": "When `true`, return the row even if soft-deleted. Default `false` (returns 404)." - }, - "required": false, - "description": "When `true`, return the row even if soft-deleted. Default `false` (returns 404).", - "name": "include_deleted", - "in": "query" - } - ], - "description": "### Overview\nFetch a single calendar event by its unique ID, returning the complete record including all attendees.\n\n### When to Use\nDisplay a detailed view of an event, or read the latest database state (capturing `version`) prior to executing an optimistic-locked PATCH update.\n\n### Constraints\n- **Deleted Events**: Soft-deleted events return 404 `NOT_FOUND` by default. You must explicitly pass `include_deleted=true` in the query parameters to retrieve a soft-deleted row.\n- **ICS Format**: To download the RFC 5545 iCalendar text representation of this event, use `GET /calendar/events/{id}.ics` instead.\n\n### Troubleshooting\n- Returns 404 `NOT_FOUND` if the event does not exist, is soft-deleted (without `include_deleted=true`), or is owned by another user.", - "security": [ - { - "bearerAuth": [] - } - ], - "x-codeSamples": [ - { - "lang": "shell", - "label": "curl", - "source": "curl https://api.wspc.ai/calendar/events/evt_01HW3K4N9V5G6Z8C2Q7B1Y0M3F \\\n -H \"Authorization: Bearer $WSPC_API_KEY\"" - }, - { - "lang": "bash", - "label": "wspc CLI", - "source": "wspc event show evt_01HW3K4N9V5G6Z8C2Q7B1Y0M3F" - } - ], - "responses": { - "200": { - "description": "The requested event. Includes `deleted_at` only when fetched with `include_deleted=true` on a soft-deleted row.", - "headers": { - "x-cb-cal": { - "description": "Opaque consistency bookmark for the latest calendar database position observed by this request. Store and send it on the next calendar request to continue read-after-write consistency.", - "schema": { - "type": "string" - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Event" - }, - "examples": { - "happyPath": { - "summary": "Timed event with one attendee", - "value": { - "id": "evt_01HW3K4N9V5G6Z8C2Q7B1Y0M3F", - "user_id": "usr_01HW3K4N9V5G6Z8C2Q7B1Y0M3F", - "title": "Lunch with Alice", - "description": "Use the lobby entrance", - "start": "2026-06-01T12:30:00+08:00", - "end": "2026-06-01T13:30:00+08:00", - "location": "Taipei HQ", - "status": "confirmed", - "all_day": false, - "version": 1, - "created_at": 1748736000000, - "updated_at": 1748736000000, - "attendees": [ - { - "email": "alice@example.com", - "display_name": "Alice" - } - ] - } - } - } - } - } }, - "400": { - "description": "Request validation failed. The body, query, or path parameters did not match the operation's schema.", + "503": { + "description": "SUBSCRIPTION_UNAVAILABLE: the feature is disabled or Auth is unavailable.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "code", + "message" + ] + } + }, + "required": [ + "error" + ] + } + } + } + } + } + }, + "delete": { + "operationId": "calendar_disable_subscription", + "x-codeSamples": [ + { + "lang": "Shell", + "label": "curl", + "source": "curl -X DELETE \"https://api.wspc.ai/calendar/subscription\" -H \"Authorization: Bearer $WSPC_API_KEY\" -H \"Content-Type: application/json\" -d '{\"expected_version\":1}'" + } + ], + "tags": [ + "Events" + ], + "summary": "Disable the private calendar link", + "description": "Disable the link using expected_version. External copies cannot be removed. A private read-only link to all your event details in the current Workspace. Anyone with the link can read them. External calendar updates depend on that app's refresh schedule and can be delayed.", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "expected_version": { + "type": "integer", + "minimum": 0 + } + }, + "required": [ + "expected_version" + ], + "additionalProperties": false + } + } + } + }, + "responses": { + "200": { + "description": "Current subscription state", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CalendarSubscription" + } + } + } + }, + "400": { + "description": "Request validation failed. The body, query, or path parameters did not match the operation's schema.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "code", + "message" + ] + } + }, + "required": [ + "error" + ] + }, + "examples": { + "validationError": { + "summary": "Body failed schema validation", + "value": { + "error": { + "code": "VALIDATION_ERROR", + "message": "title must not be empty" + } + } + } + } + } + } + }, + "401": { + "description": "Authentication is required but missing or invalid. The Bearer token (API key or OAuth access token) was absent, malformed, or rejected.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "code", + "message" + ] + } + }, + "required": [ + "error" + ] + }, + "examples": { + "authRequired": { + "summary": "Missing Authorization header", + "value": { + "error": { + "code": "AUTH_REQUIRED", + "message": "missing bearer token" + } + } + } + } + } + } + }, + "403": { + "description": "The caller is authenticated but not permitted to perform this operation on the target resource.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "code", + "message" + ] + } + }, + "required": [ + "error" + ] + }, + "examples": { + "forbidden": { + "summary": "Caller does not own the resource", + "value": { + "error": { + "code": "FORBIDDEN", + "message": "not allowed" + } + } + } + } + } + } + }, + "404": { + "description": "The target resource does not exist or is not visible to the caller. Soft-deleted resources are treated as not found unless an `include_deleted` flag is set.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "code", + "message" + ] + } + }, + "required": [ + "error" + ] + }, + "examples": { + "notFound": { + "summary": "Resource id is unknown to the service", + "value": { + "error": { + "code": "NOT_FOUND", + "message": "todo not found" + } + } + } + } + } + } + }, + "409": { + "description": "VERSION_CONFLICT: read the current state before retrying. SUBSCRIPTION_DISABLED: create a link before resetting it.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "code", + "message" + ] + } + }, + "required": [ + "error" + ] + } + } + } + }, + "429": { + "description": "Rate limit exceeded. Use the HTTP `Retry-After` header for machine-readable retry timing.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "code", + "message" + ] + } + }, + "required": [ + "error" + ] + }, + "examples": { + "rateLimited": { + "summary": "Per-key rate limit hit", + "value": { + "error": { + "code": "RATE_LIMITED", + "message": "Too many requests, please retry after 60 seconds." + } + } + } + } + } + } + }, + "500": { + "description": "Unhandled server error. The request was well-formed but the service failed unexpectedly. Safe to retry idempotent operations.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "code", + "message" + ] + } + }, + "required": [ + "error" + ] + }, + "examples": { + "internalError": { + "summary": "Unhandled exception", + "value": { + "error": { + "code": "INTERNAL_ERROR", + "message": "internal error" + } + } + } + } + } + } + }, + "503": { + "description": "SUBSCRIPTION_UNAVAILABLE: the feature is disabled or Auth is unavailable.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "code", + "message" + ] + } + }, + "required": [ + "error" + ] + } + } + } + } + } + }, + "get": { + "operationId": "calendar_get_subscription", + "x-codeSamples": [ + { + "lang": "Shell", + "label": "curl", + "source": "curl -X GET \"https://api.wspc.ai/calendar/subscription\" -H \"Authorization: Bearer $WSPC_API_KEY\"" + } + ], + "tags": [ + "Events" + ], + "summary": "Read the private calendar subscription", + "description": "Read the current subscription state without creating a link. A private read-only link to all your event details in the current Workspace. Anyone with the link can read them. External calendar updates depend on that app's refresh schedule and can be delayed.", + "responses": { + "200": { + "description": "Current subscription state", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CalendarSubscription" + } + } + } + }, + "400": { + "description": "Request validation failed. The body, query, or path parameters did not match the operation's schema.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "code", + "message" + ] + } + }, + "required": [ + "error" + ] + }, + "examples": { + "validationError": { + "summary": "Body failed schema validation", + "value": { + "error": { + "code": "VALIDATION_ERROR", + "message": "title must not be empty" + } + } + } + } + } + } + }, + "401": { + "description": "Authentication is required but missing or invalid. The Bearer token (API key or OAuth access token) was absent, malformed, or rejected.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "code", + "message" + ] + } + }, + "required": [ + "error" + ] + }, + "examples": { + "authRequired": { + "summary": "Missing Authorization header", + "value": { + "error": { + "code": "AUTH_REQUIRED", + "message": "missing bearer token" + } + } + } + } + } + } + }, + "403": { + "description": "The caller is authenticated but not permitted to perform this operation on the target resource.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "code", + "message" + ] + } + }, + "required": [ + "error" + ] + }, + "examples": { + "forbidden": { + "summary": "Caller does not own the resource", + "value": { + "error": { + "code": "FORBIDDEN", + "message": "not allowed" + } + } + } + } + } + } + }, + "404": { + "description": "The target resource does not exist or is not visible to the caller. Soft-deleted resources are treated as not found unless an `include_deleted` flag is set.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "code", + "message" + ] + } + }, + "required": [ + "error" + ] + }, + "examples": { + "notFound": { + "summary": "Resource id is unknown to the service", + "value": { + "error": { + "code": "NOT_FOUND", + "message": "todo not found" + } + } + } + } + } + } + }, + "409": { + "description": "VERSION_CONFLICT: read the current state before retrying. SUBSCRIPTION_DISABLED: create a link before resetting it.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "code", + "message" + ] + } + }, + "required": [ + "error" + ] + } + } + } + }, + "429": { + "description": "Rate limit exceeded. Use the HTTP `Retry-After` header for machine-readable retry timing.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "code", + "message" + ] + } + }, + "required": [ + "error" + ] + }, + "examples": { + "rateLimited": { + "summary": "Per-key rate limit hit", + "value": { + "error": { + "code": "RATE_LIMITED", + "message": "Too many requests, please retry after 60 seconds." + } + } + } + } + } + } + }, + "500": { + "description": "Unhandled server error. The request was well-formed but the service failed unexpectedly. Safe to retry idempotent operations.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "code", + "message" + ] + } + }, + "required": [ + "error" + ] + }, + "examples": { + "internalError": { + "summary": "Unhandled exception", + "value": { + "error": { + "code": "INTERNAL_ERROR", + "message": "internal error" + } + } + } + } + } + } + }, + "503": { + "description": "SUBSCRIPTION_UNAVAILABLE: the feature is disabled or Auth is unavailable.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "code", + "message" + ] + } + }, + "required": [ + "error" + ] + } + } + } + } + } + } + }, + "/calendar/events/{id}": { + "delete": { + "operationId": "event_delete", + "tags": [ + "Events" + ], + "x-cli": { + "command": "event rm", + "positional": [ + "id" + ], + "examples": [ + "wspc event rm evt_xxx" + ], + "display": { + "shape": "object", + "format": { + "id": "id-short", + "deleted_at": "relative-time" + } + } + }, + "summary": "Soft-delete a calendar event", + "parameters": [ + { + "name": "x-cb-cal", + "in": "header", + "required": false, + "description": "Optional opaque consistency bookmark returned by a previous calendar response. Send it back unchanged to continue read-after-write consistency for calendar D1 data.", + "schema": { + "type": "string" + }, + "example": "opaque-consistency-bookmark" + }, + { + "schema": { + "type": "string", + "description": "Event id (`evt_` for new rows; legacy UUID ids remain accepted)." + }, + "required": true, + "description": "Event id (`evt_` for new rows; legacy UUID ids remain accepted).", + "name": "id", + "in": "path" + } + ], + "description": "### Overview\nSoft-delete an existing calendar event, hiding it from default listings.\n\n### When to Use\nRemove an event entirely from the user's historical view and calendar client. If the meeting was cancelled but should remain in history (notifying participants of cancellation), use `PATCH /calendar/events/{id}` with `status: cancelled` instead.\n\n### Constraints\n- **Optimistic Locking**: Supports optional optimistic locking via `expected_version` in the request body.\n- **Side Effects**: When soft-deleting an event with attendees, all participants will asynchronously receive a cancellation email containing an `.ics` CANCEL attachment via Cloudflare `waitUntil`.\n- **Recovery**: The record is preserved in the database as a soft-deleted row and can be brought back using `POST /calendar/events/{id}/restore`.\n\n### Troubleshooting\n- Returns 404 `NOT_FOUND` if the event does not exist, or has already been soft-deleted.\n- Returns 409 `VERSION_CONFLICT` if `expected_version` does not match the database value.", + "security": [ + { + "bearerAuth": [] + } + ], + "x-codeSamples": [ + { + "lang": "shell", + "label": "curl", + "source": "curl -X DELETE https://api.wspc.ai/calendar/events/evt_01HW3K4N9V5G6Z8C2Q7B1Y0M3F \\\n -H \"Authorization: Bearer $WSPC_API_KEY\" \\\n -H \"Content-Type: application/json\" \\\n -d '{}'" + }, + { + "lang": "bash", + "label": "wspc CLI", + "source": "wspc event rm evt_01HW3K4N9V5G6Z8C2Q7B1Y0M3F" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/VersionBody" + }, + "examples": { + "minimal": { + "summary": "Delete without optimistic lock", + "value": {} + }, + "full": { + "summary": "Delete only if still at the version we last read", + "value": { + "expected_version": 3 + } + } + } + } + } + }, + "responses": { + "200": { + "description": "The event was soft-deleted. Response carries `id`, `deleted_at`, and the post-delete `version`. Cancellation emails are sent asynchronously.", + "headers": { + "x-cb-cal": { + "description": "Opaque consistency bookmark for the latest calendar database position observed by this request. Store and send it on the next calendar request to continue read-after-write consistency.", + "schema": { + "type": "string" + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeleteEventResponse" + }, + "examples": { + "happyPath": { + "summary": "Soft-delete acknowledged", + "value": { + "id": "evt_01HW3K4N9V5G6Z8C2Q7B1Y0M3F", + "deleted_at": 1748822400000, + "version": 2 + } + } + } + } + } + }, + "400": { + "description": "Request validation failed. The body, query, or path parameters did not match the operation's schema.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "code", + "message" + ] + } + }, + "required": [ + "error" + ] + }, + "examples": { + "validationError": { + "summary": "Body failed schema validation", + "value": { + "error": { + "code": "VALIDATION_ERROR", + "message": "title must not be empty" + } + } + } + } + } + } + }, + "401": { + "description": "Authentication is required but missing or invalid. The Bearer token (API key or OAuth access token) was absent, malformed, or rejected.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "code", + "message" + ] + } + }, + "required": [ + "error" + ] + }, + "examples": { + "authRequired": { + "summary": "Missing Authorization header", + "value": { + "error": { + "code": "AUTH_REQUIRED", + "message": "missing bearer token" + } + } + } + } + } + } + }, + "403": { + "description": "The caller is authenticated but not permitted to perform this operation on the target resource.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "code", + "message" + ] + } + }, + "required": [ + "error" + ] + }, + "examples": { + "forbidden": { + "summary": "Caller does not own the resource", + "value": { + "error": { + "code": "FORBIDDEN", + "message": "not allowed" + } + } + } + } + } + } + }, + "404": { + "description": "The target resource does not exist or is not visible to the caller. Soft-deleted resources are treated as not found unless an `include_deleted` flag is set.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "code", + "message" + ] + } + }, + "required": [ + "error" + ] + }, + "examples": { + "notFound": { + "summary": "Resource id is unknown to the service", + "value": { + "error": { + "code": "NOT_FOUND", + "message": "todo not found" + } + } + } + } + } + } + }, + "409": { + "description": "Optimistic-lock conflict. The supplied `expected_version` does not match the server's current version. Refetch the resource and retry.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "code", + "message" + ] + } + }, + "required": [ + "error" + ] + }, + "examples": { + "versionConflict": { + "summary": "expected_version does not match server version", + "value": { + "error": { + "code": "VERSION_CONFLICT", + "message": "expected_version 3 but current is 4" + } + } + } + } + } + } + }, + "429": { + "description": "Rate limit exceeded. Use the HTTP `Retry-After` header for machine-readable retry timing.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "code", + "message" + ] + } + }, + "required": [ + "error" + ] + }, + "examples": { + "rateLimited": { + "summary": "Per-key rate limit hit", + "value": { + "error": { + "code": "RATE_LIMITED", + "message": "Too many requests, please retry after 60 seconds." + } + } + } + } + } + } + }, + "500": { + "description": "Unhandled server error. The request was well-formed but the service failed unexpectedly. Safe to retry idempotent operations.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "code", + "message" + ] + } + }, + "required": [ + "error" + ] + }, + "examples": { + "internalError": { + "summary": "Unhandled exception", + "value": { + "error": { + "code": "INTERNAL_ERROR", + "message": "internal error" + } + } + } + } + } + } + } + } + }, + "get": { + "operationId": "event_get", + "tags": [ + "Events" + ], + "x-cli": { + "command": "event show", + "positional": [ + "id" + ], + "examples": [ + "wspc event show evt_xxx" + ], + "display": { + "shape": "object", + "format": { + "id": "id-short", + "user_id": "id-short", + "status": "status-badge", + "start": "relative-time", + "end": "relative-time", + "created_at": "relative-time", + "updated_at": "relative-time", + "deleted_at": "relative-time" + } + } + }, + "summary": "Get a calendar event by id", + "parameters": [ + { + "name": "x-cb-cal", + "in": "header", + "required": false, + "description": "Optional opaque consistency bookmark returned by a previous calendar response. Send it back unchanged to continue read-after-write consistency for calendar D1 data.", + "schema": { + "type": "string" + }, + "example": "opaque-consistency-bookmark" + }, + { + "schema": { + "type": "string", + "description": "Event id (`evt_` for new rows; legacy UUID ids remain accepted)." + }, + "required": true, + "description": "Event id (`evt_` for new rows; legacy UUID ids remain accepted).", + "name": "id", + "in": "path" + }, + { + "schema": { + "type": "string", + "description": "When `true`, return the row even if soft-deleted. Default `false` (returns 404)." + }, + "required": false, + "description": "When `true`, return the row even if soft-deleted. Default `false` (returns 404).", + "name": "include_deleted", + "in": "query" + } + ], + "description": "### Overview\nFetch a single calendar event by its unique ID, returning the complete record including all attendees.\n\n### When to Use\nDisplay a detailed view of an event, or read the latest database state (capturing `version`) prior to executing an optimistic-locked PATCH update.\n\n### Constraints\n- **Deleted Events**: Soft-deleted events return 404 `NOT_FOUND` by default. You must explicitly pass `include_deleted=true` in the query parameters to retrieve a soft-deleted row.\n- **ICS Format**: To download the RFC 5545 iCalendar text representation of this event, use `GET /calendar/events/{id}.ics` instead.\n\n### Troubleshooting\n- Returns 404 `NOT_FOUND` if the event does not exist, is soft-deleted (without `include_deleted=true`), or is owned by another user.", + "security": [ + { + "bearerAuth": [] + } + ], + "x-codeSamples": [ + { + "lang": "shell", + "label": "curl", + "source": "curl https://api.wspc.ai/calendar/events/evt_01HW3K4N9V5G6Z8C2Q7B1Y0M3F \\\n -H \"Authorization: Bearer $WSPC_API_KEY\"" + }, + { + "lang": "bash", + "label": "wspc CLI", + "source": "wspc event show evt_01HW3K4N9V5G6Z8C2Q7B1Y0M3F" + } + ], + "responses": { + "200": { + "description": "The requested event. Includes `deleted_at` only when fetched with `include_deleted=true` on a soft-deleted row.", + "headers": { + "x-cb-cal": { + "description": "Opaque consistency bookmark for the latest calendar database position observed by this request. Store and send it on the next calendar request to continue read-after-write consistency.", + "schema": { + "type": "string" + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Event" + }, + "examples": { + "happyPath": { + "summary": "Timed event with one attendee", + "value": { + "id": "evt_01HW3K4N9V5G6Z8C2Q7B1Y0M3F", + "user_id": "usr_01HW3K4N9V5G6Z8C2Q7B1Y0M3F", + "title": "Lunch with Alice", + "description": "Use the lobby entrance", + "start": "2026-06-01T12:30:00+08:00", + "end": "2026-06-01T13:30:00+08:00", + "location": "Taipei HQ", + "status": "confirmed", + "all_day": false, + "version": 1, + "created_at": 1748736000000, + "updated_at": 1748736000000, + "attendees": [ + { + "email": "alice@example.com", + "display_name": "Alice" + } + ] + } + } + } + } + } + }, + "400": { + "description": "Request validation failed. The body, query, or path parameters did not match the operation's schema.", "content": { "application/json": { "schema": { @@ -24644,17 +25705,362 @@ } } }, - "/calendar/export": { + "/calendar/export": { + "get": { + "operationId": "calendar_export", + "tags": [ + "Events" + ], + "x-cli": { + "command": "_internal", + "hidden": true + }, + "summary": "Export the whole calendar as `.ics`", + "parameters": [ + { + "name": "x-cb-cal", + "in": "header", + "required": false, + "description": "Optional opaque consistency bookmark returned by a previous calendar response. Send it back unchanged to continue read-after-write consistency for calendar D1 data.", + "schema": { + "type": "string" + }, + "example": "opaque-consistency-bookmark" + } + ], + "description": "### Overview\nStream every event of the current Workspace as a single RFC 5545 `VCALENDAR` document, one `VEVENT` per event.\n\n### When to Use\nTake a copy of the calendar out of wspc, or import it into Google Calendar, Apple Calendar, or any other iCalendar client.\n\n### Constraints\n- **Response Payload**: Plain iCalendar text with `Content-Type: text/calendar; charset=utf-8` and `Content-Disposition: attachment; filename=\"wspc-calendar.ics\"`, so browsers save it as a file.\n- **Scope**: Only events owned by the authenticated user in the current Workspace. Soft-deleted (trashed) events are left out; past events are included.\n- **Delivery**: The body is streamed while the events are read page by page. Nothing is stored server-side and there is nothing to expire.\n- **Method**: The document carries `METHOD:PUBLISH`; cancelled events carry `STATUS:CANCELLED`.\n- **Consistency**: send `x-cb-cal` to anchor the read at a known bookmark. No bookmark comes back — the body is streamed after the response headers are already out.", + "security": [ + { + "bearerAuth": [] + } + ], + "x-codeSamples": [ + { + "lang": "shell", + "label": "curl", + "source": "curl https://api.wspc.ai/calendar/export \\\n -H \"Authorization: Bearer $WSPC_API_KEY\" \\\n -o wspc-calendar.ics" + } + ], + "responses": { + "200": { + "description": "RFC 5545 iCalendar payload as plain text. Content-Type `text/calendar; charset=utf-8`. One `BEGIN:VCALENDAR` wrapping one `VEVENT` per event.", + "content": { + "text/calendar": { + "schema": { + "type": "string" + } + } + } + }, + "400": { + "description": "Request validation failed. The body, query, or path parameters did not match the operation's schema.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "code", + "message" + ] + } + }, + "required": [ + "error" + ] + }, + "examples": { + "validationError": { + "summary": "Body failed schema validation", + "value": { + "error": { + "code": "VALIDATION_ERROR", + "message": "title must not be empty" + } + } + } + } + } + } + }, + "401": { + "description": "Authentication is required but missing or invalid. The Bearer token (API key or OAuth access token) was absent, malformed, or rejected.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "code", + "message" + ] + } + }, + "required": [ + "error" + ] + }, + "examples": { + "authRequired": { + "summary": "Missing Authorization header", + "value": { + "error": { + "code": "AUTH_REQUIRED", + "message": "missing bearer token" + } + } + } + } + } + } + }, + "403": { + "description": "The caller is authenticated but not permitted to perform this operation on the target resource.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "code", + "message" + ] + } + }, + "required": [ + "error" + ] + }, + "examples": { + "forbidden": { + "summary": "Caller does not own the resource", + "value": { + "error": { + "code": "FORBIDDEN", + "message": "not allowed" + } + } + } + } + } + } + }, + "404": { + "description": "The target resource does not exist or is not visible to the caller. Soft-deleted resources are treated as not found unless an `include_deleted` flag is set.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "code", + "message" + ] + } + }, + "required": [ + "error" + ] + }, + "examples": { + "notFound": { + "summary": "Resource id is unknown to the service", + "value": { + "error": { + "code": "NOT_FOUND", + "message": "todo not found" + } + } + } + } + } + } + }, + "409": { + "description": "Optimistic-lock conflict. The supplied `expected_version` does not match the server's current version. Refetch the resource and retry.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "code", + "message" + ] + } + }, + "required": [ + "error" + ] + }, + "examples": { + "versionConflict": { + "summary": "expected_version does not match server version", + "value": { + "error": { + "code": "VERSION_CONFLICT", + "message": "expected_version 3 but current is 4" + } + } + } + } + } + } + }, + "429": { + "description": "Rate limit exceeded. Use the HTTP `Retry-After` header for machine-readable retry timing.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "code", + "message" + ] + } + }, + "required": [ + "error" + ] + }, + "examples": { + "rateLimited": { + "summary": "Per-key rate limit hit", + "value": { + "error": { + "code": "RATE_LIMITED", + "message": "Too many requests, please retry after 60 seconds." + } + } + } + } + } + } + }, + "500": { + "description": "Unhandled server error. The request was well-formed but the service failed unexpectedly. Safe to retry idempotent operations.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "code", + "message" + ] + } + }, + "required": [ + "error" + ] + }, + "examples": { + "internalError": { + "summary": "Unhandled exception", + "value": { + "error": { + "code": "INTERNAL_ERROR", + "message": "internal error" + } + } + } + } + } + } + } + } + } + }, + "/calendar/events/{filename}": { "get": { - "operationId": "calendar_export", + "operationId": "event_ics_download", "tags": [ "Events" ], "x-cli": { - "command": "_internal", - "hidden": true + "command": "event ics", + "positional": [ + "id" + ], + "examples": [ + "wspc event ics evt_xxx > event.ics" + ], + "display": { + "shape": "raw" + } }, - "summary": "Export the whole calendar as `.ics`", + "summary": "Download event as `.ics`", "parameters": [ { "name": "x-cb-cal", @@ -24665,9 +26071,19 @@ "type": "string" }, "example": "opaque-consistency-bookmark" + }, + { + "schema": { + "type": "string", + "description": "`.ics`. The `.ics` suffix is required so the router matches this endpoint ahead of the JSON detail route." + }, + "required": true, + "description": "`.ics`. The `.ics` suffix is required so the router matches this endpoint ahead of the JSON detail route.", + "name": "filename", + "in": "path" } ], - "description": "### Overview\nStream every event of the current Workspace as a single RFC 5545 `VCALENDAR` document, one `VEVENT` per event.\n\n### When to Use\nTake a copy of the calendar out of wspc, or import it into Google Calendar, Apple Calendar, or any other iCalendar client.\n\n### Constraints\n- **Response Payload**: Plain iCalendar text with `Content-Type: text/calendar; charset=utf-8` and `Content-Disposition: attachment; filename=\"wspc-calendar.ics\"`, so browsers save it as a file.\n- **Scope**: Only events owned by the authenticated user in the current Workspace. Soft-deleted (trashed) events are left out; past events are included.\n- **Delivery**: The body is streamed while the events are read page by page. Nothing is stored server-side and there is nothing to expire.\n- **Method**: The document carries `METHOD:PUBLISH`; cancelled events carry `STATUS:CANCELLED`.\n- **Consistency**: send `x-cb-cal` to anchor the read at a known bookmark. No bookmark comes back — the body is streamed after the response headers are already out.", + "description": "### Overview\nReturn a single event rendered as an RFC 5545 `.ics` file suitable for import into major calendar clients.\n\n### When to Use\nExpose a 'Save to my calendar' link in email notifications, show a download button in a UI, or programmatically forward raw iCalendar text to third parties.\n\n### Constraints\n- **Router Match**: The path parameter `filename` must be exactly `.ics`. The `.ics` suffix is strictly required for the router to match this endpoint ahead of the JSON detail endpoint.\n- **Response Payload**: The response is plain text containing the iCalendar specification, NOT JSON. The `Content-Type` is set to `text/calendar; charset=utf-8` with `Content-Disposition: inline; filename=\".ics\"`.\n- **Authentication**: Standard authentication is required (Bearer API key or OAuth access token), as this endpoint is secure.\n\n### Troubleshooting\n- Returns 404 `NOT_FOUND` if the event does not exist, is soft-deleted, or is owned by another user.", "security": [ { "bearerAuth": [] @@ -24677,12 +26093,25 @@ { "lang": "shell", "label": "curl", - "source": "curl https://api.wspc.ai/calendar/export \\\n -H \"Authorization: Bearer $WSPC_API_KEY\" \\\n -o wspc-calendar.ics" + "source": "curl https://api.wspc.ai/calendar/events/evt_01HW3K4N9V5G6Z8C2Q7B1Y0M3F.ics \\\n -H \"Authorization: Bearer $WSPC_API_KEY\" \\\n -o event.ics" + }, + { + "lang": "bash", + "label": "wspc CLI", + "source": "wspc event ics evt_01HW3K4N9V5G6Z8C2Q7B1Y0M3F > event.ics" } ], "responses": { "200": { - "description": "RFC 5545 iCalendar payload as plain text. Content-Type `text/calendar; charset=utf-8`. One `BEGIN:VCALENDAR` wrapping one `VEVENT` per event.", + "description": "RFC 5545 iCalendar payload as plain text. Content-Type `text/calendar; charset=utf-8`. Body begins with `BEGIN:VCALENDAR` and contains a single `VEVENT` for this event.", + "headers": { + "x-cb-cal": { + "description": "Opaque consistency bookmark for the latest calendar database position observed by this request. Store and send it on the next calendar request to continue read-after-write consistency.", + "schema": { + "type": "string" + } + } + }, "content": { "text/calendar": { "schema": { @@ -24965,102 +26394,241 @@ ] }, "examples": { - "internalError": { - "summary": "Unhandled exception", + "internalError": { + "summary": "Unhandled exception", + "value": { + "error": { + "code": "INTERNAL_ERROR", + "message": "internal error" + } + } + } + } + } + } + } + } + } + }, + "/calendar/agenda": { + "get": { + "operationId": "event_agenda", + "tags": [ + "Events" + ], + "x-cli": { + "command": "event agenda", + "booleanFlags": [ + "include_cancelled" + ], + "options": { + "from": { + "parser": "agenda-boundary", + "mapsTo": "start", + "required": true + }, + "to": { + "parser": "agenda-boundary", + "mapsTo": "end", + "required": true + }, + "tz": { + "parser": "agenda-time-zone", + "mapsTo": "view_time_zone" + } + }, + "examples": [ + "wspc event agenda --from \"this Monday\" --to \"next Monday\"" + ], + "display": { + "shape": "list", + "columns": [ + "kind", + "start", + "end", + "title", + "status", + "event_id", + "series_id", + "recurrence_id", + "time_zone" + ], + "format": { + "start": "relative-time", + "end": "relative-time", + "title": "truncate", + "status": "status-badge", + "event_id": "id-short", + "series_id": "id-short", + "recurrence_id": "truncate" + }, + "emptyMessage": "no agenda items" + } + }, + "summary": "List a bounded calendar agenda", + "parameters": [ + { + "name": "x-cb-cal", + "in": "header", + "required": false, + "description": "Optional opaque consistency bookmark returned by a previous calendar response. Send it back unchanged to continue read-after-write consistency for calendar D1 data.", + "schema": { + "type": "string" + }, + "example": "opaque-consistency-bookmark" + }, + { + "schema": { + "type": "string", + "pattern": "T.*(?:Z|[+-]\\d{2}:\\d{2})$", + "description": "Offset-bearing ISO 8601 date-time boundary for the half-open agenda window." + }, + "required": true, + "description": "Offset-bearing ISO 8601 date-time boundary for the half-open agenda window.", + "name": "start", + "in": "query" + }, + { + "schema": { + "type": "string", + "pattern": "T.*(?:Z|[+-]\\d{2}:\\d{2})$", + "description": "Offset-bearing ISO 8601 date-time boundary for the half-open agenda window." + }, + "required": true, + "description": "Offset-bearing ISO 8601 date-time boundary for the half-open agenda window.", + "name": "end", + "in": "query" + }, + { + "schema": { + "type": "string", + "minLength": 1, + "description": "UTC or a supported IANA time zone. Aliases are accepted and the response returns the canonical zone." + }, + "required": true, + "description": "UTC or a supported IANA time zone. Aliases are accepted and the response returns the canonical zone.", + "name": "view_time_zone", + "in": "query" + }, + { + "schema": { + "type": "string", + "enum": [ + "true", + "false" + ], + "default": "false", + "description": "Include cancelled single events and whole-series occurrences. Default false." + }, + "required": false, + "description": "Include cancelled single events and whole-series occurrences. Default false.", + "name": "include_cancelled", + "in": "query" + }, + { + "schema": { + "type": "integer", + "minimum": 1, + "maximum": 200, + "default": 100, + "description": "Maximum agenda items on this page. Default 100; range 1 to 200." + }, + "required": false, + "description": "Maximum agenda items on this page. Default 100; range 1 to 200.", + "name": "limit", + "in": "query" + }, + { + "schema": { + "type": "string", + "description": "Opaque agenda pagination cursor." + }, + "required": false, + "description": "Opaque agenda pagination cursor.", + "name": "cursor", + "in": "query" + } + ], + "description": "Merge overlapping single events and recurring occurrences in a required bounded instant window. The view time zone controls all-day overlap and ordering; event lists remain master-only.", + "security": [ + { + "bearerAuth": [] + } + ], + "x-codeSamples": [ + { + "lang": "shell", + "label": "curl", + "source": "curl -G https://api.wspc.ai/calendar/agenda \\\n -H \"Authorization: Bearer $WSPC_API_KEY\" \\\n --data-urlencode \"start=2026-08-10T00:00:00+08:00\" \\\n --data-urlencode \"end=2026-08-17T00:00:00+08:00\" \\\n --data-urlencode \"view_time_zone=Asia/Taipei\"" + }, + { + "lang": "bash", + "label": "wspc CLI", + "source": "wspc event agenda --from \"this Monday\" --to \"next Monday\" --tz Asia/Taipei" + } + ], + "responses": { + "200": { + "description": "Stable agenda page with canonical view time zone.", + "headers": { + "x-cb-cal": { + "description": "Opaque consistency bookmark for the latest calendar database position observed by this request. Store and send it on the next calendar request to continue read-after-write consistency.", + "schema": { + "type": "string" + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ListAgendaResponse" + } + } + } + }, + "400": { + "description": "Request validation failed. The body, query, or path parameters did not match the operation's schema.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "code", + "message" + ] + } + }, + "required": [ + "error" + ] + }, + "examples": { + "validationError": { + "summary": "Body failed schema validation", "value": { "error": { - "code": "INTERNAL_ERROR", - "message": "internal error" + "code": "VALIDATION_ERROR", + "message": "title must not be empty" } } } } } } - } - } - } - }, - "/calendar/events/{filename}": { - "get": { - "operationId": "event_ics_download", - "tags": [ - "Events" - ], - "x-cli": { - "command": "event ics", - "positional": [ - "id" - ], - "examples": [ - "wspc event ics evt_xxx > event.ics" - ], - "display": { - "shape": "raw" - } - }, - "summary": "Download event as `.ics`", - "parameters": [ - { - "name": "x-cb-cal", - "in": "header", - "required": false, - "description": "Optional opaque consistency bookmark returned by a previous calendar response. Send it back unchanged to continue read-after-write consistency for calendar D1 data.", - "schema": { - "type": "string" - }, - "example": "opaque-consistency-bookmark" - }, - { - "schema": { - "type": "string", - "description": "`.ics`. The `.ics` suffix is required so the router matches this endpoint ahead of the JSON detail route." - }, - "required": true, - "description": "`.ics`. The `.ics` suffix is required so the router matches this endpoint ahead of the JSON detail route.", - "name": "filename", - "in": "path" - } - ], - "description": "### Overview\nReturn a single event rendered as an RFC 5545 `.ics` file suitable for import into major calendar clients.\n\n### When to Use\nExpose a 'Save to my calendar' link in email notifications, show a download button in a UI, or programmatically forward raw iCalendar text to third parties.\n\n### Constraints\n- **Router Match**: The path parameter `filename` must be exactly `.ics`. The `.ics` suffix is strictly required for the router to match this endpoint ahead of the JSON detail endpoint.\n- **Response Payload**: The response is plain text containing the iCalendar specification, NOT JSON. The `Content-Type` is set to `text/calendar; charset=utf-8` with `Content-Disposition: inline; filename=\".ics\"`.\n- **Authentication**: Standard authentication is required (Bearer API key or OAuth access token), as this endpoint is secure.\n\n### Troubleshooting\n- Returns 404 `NOT_FOUND` if the event does not exist, is soft-deleted, or is owned by another user.", - "security": [ - { - "bearerAuth": [] - } - ], - "x-codeSamples": [ - { - "lang": "shell", - "label": "curl", - "source": "curl https://api.wspc.ai/calendar/events/evt_01HW3K4N9V5G6Z8C2Q7B1Y0M3F.ics \\\n -H \"Authorization: Bearer $WSPC_API_KEY\" \\\n -o event.ics" - }, - { - "lang": "bash", - "label": "wspc CLI", - "source": "wspc event ics evt_01HW3K4N9V5G6Z8C2Q7B1Y0M3F > event.ics" - } - ], - "responses": { - "200": { - "description": "RFC 5545 iCalendar payload as plain text. Content-Type `text/calendar; charset=utf-8`. Body begins with `BEGIN:VCALENDAR` and contains a single `VEVENT` for this event.", - "headers": { - "x-cb-cal": { - "description": "Opaque consistency bookmark for the latest calendar database position observed by this request. Store and send it on the next calendar request to continue read-after-write consistency.", - "schema": { - "type": "string" - } - } - }, - "content": { - "text/calendar": { - "schema": { - "type": "string" - } - } - } }, - "400": { - "description": "Request validation failed. The body, query, or path parameters did not match the operation's schema.", + "401": { + "description": "Authentication is required but missing or invalid. The Bearer token (API key or OAuth access token) was absent, malformed, or rejected.", "content": { "application/json": { "schema": { @@ -25087,12 +26655,12 @@ ] }, "examples": { - "validationError": { - "summary": "Body failed schema validation", + "authRequired": { + "summary": "Missing Authorization header", "value": { "error": { - "code": "VALIDATION_ERROR", - "message": "title must not be empty" + "code": "AUTH_REQUIRED", + "message": "missing bearer token" } } } @@ -25100,8 +26668,8 @@ } } }, - "401": { - "description": "Authentication is required but missing or invalid. The Bearer token (API key or OAuth access token) was absent, malformed, or rejected.", + "403": { + "description": "The caller is authenticated but not permitted to perform this operation on the target resource.", "content": { "application/json": { "schema": { @@ -25128,12 +26696,12 @@ ] }, "examples": { - "authRequired": { - "summary": "Missing Authorization header", + "forbidden": { + "summary": "Caller does not own the resource", "value": { "error": { - "code": "AUTH_REQUIRED", - "message": "missing bearer token" + "code": "FORBIDDEN", + "message": "not allowed" } } } @@ -25141,8 +26709,8 @@ } } }, - "403": { - "description": "The caller is authenticated but not permitted to perform this operation on the target resource.", + "404": { + "description": "The target resource does not exist or is not visible to the caller. Soft-deleted resources are treated as not found unless an `include_deleted` flag is set.", "content": { "application/json": { "schema": { @@ -25169,12 +26737,12 @@ ] }, "examples": { - "forbidden": { - "summary": "Caller does not own the resource", + "notFound": { + "summary": "Resource id is unknown to the service", "value": { "error": { - "code": "FORBIDDEN", - "message": "not allowed" + "code": "NOT_FOUND", + "message": "todo not found" } } } @@ -25182,8 +26750,8 @@ } } }, - "404": { - "description": "The target resource does not exist or is not visible to the caller. Soft-deleted resources are treated as not found unless an `include_deleted` flag is set.", + "409": { + "description": "Optimistic-lock conflict. The supplied `expected_version` does not match the server's current version. Refetch the resource and retry.", "content": { "application/json": { "schema": { @@ -25210,12 +26778,12 @@ ] }, "examples": { - "notFound": { - "summary": "Resource id is unknown to the service", + "versionConflict": { + "summary": "expected_version does not match server version", "value": { "error": { - "code": "NOT_FOUND", - "message": "todo not found" + "code": "VERSION_CONFLICT", + "message": "expected_version 3 but current is 4" } } } @@ -25223,8 +26791,8 @@ } } }, - "409": { - "description": "Optimistic-lock conflict. The supplied `expected_version` does not match the server's current version. Refetch the resource and retry.", + "422": { + "description": "Agenda candidate or expanded-item budget exceeded.", "content": { "application/json": { "schema": { @@ -25250,15 +26818,10 @@ "error" ] }, - "examples": { - "versionConflict": { - "summary": "expected_version does not match server version", - "value": { - "error": { - "code": "VERSION_CONFLICT", - "message": "expected_version 3 but current is 4" - } - } + "example": { + "error": { + "code": "AGENDA_LIMIT_EXCEEDED", + "message": "Agenda expansion limit exceeded; use a smaller window" } } } @@ -25349,62 +26912,55 @@ } } }, - "/calendar/agenda": { + "/calendar/events/{id}/occurrences": { "get": { - "operationId": "event_agenda", + "operationId": "event_occurrences", "tags": [ "Events" ], "x-cli": { - "command": "event agenda", + "command": "event occurrences", + "positional": [ + "id" + ], "booleanFlags": [ "include_cancelled" ], "options": { "from": { - "parser": "agenda-boundary", + "parser": "occurrence-boundary", "mapsTo": "start", "required": true }, "to": { - "parser": "agenda-boundary", + "parser": "occurrence-boundary", "mapsTo": "end", "required": true - }, - "tz": { - "parser": "agenda-time-zone", - "mapsTo": "view_time_zone" } }, "examples": [ - "wspc event agenda --from \"this Monday\" --to \"next Monday\"" + "wspc event occurrences evt_xxx --from \"this Monday\" --to \"next Monday\"" ], "display": { "shape": "list", "columns": [ - "kind", + "recurrence_id", "start", "end", - "title", "status", - "event_id", - "series_id", - "recurrence_id", + "exception_version", "time_zone" ], "format": { + "recurrence_id": "truncate", "start": "relative-time", "end": "relative-time", - "title": "truncate", - "status": "status-badge", - "event_id": "id-short", - "series_id": "id-short", - "recurrence_id": "truncate" + "status": "status-badge" }, - "emptyMessage": "no agenda items" + "emptyMessage": "no occurrences" } }, - "summary": "List a bounded calendar agenda", + "summary": "List occurrences of one recurring series", "parameters": [ { "name": "x-cb-cal", @@ -25419,76 +26975,62 @@ { "schema": { "type": "string", - "pattern": "T.*(?:Z|[+-]\\d{2}:\\d{2})$", - "description": "Offset-bearing ISO 8601 date-time boundary for the half-open agenda window." + "minLength": 1 }, "required": true, - "description": "Offset-bearing ISO 8601 date-time boundary for the half-open agenda window.", - "name": "start", - "in": "query" + "name": "id", + "in": "path" }, { "schema": { - "type": "string", - "pattern": "T.*(?:Z|[+-]\\d{2}:\\d{2})$", - "description": "Offset-bearing ISO 8601 date-time boundary for the half-open agenda window." + "type": "string" }, "required": true, - "description": "Offset-bearing ISO 8601 date-time boundary for the half-open agenda window.", - "name": "end", + "name": "start", "in": "query" }, { "schema": { - "type": "string", - "minLength": 1, - "description": "UTC or a supported IANA time zone. Aliases are accepted and the response returns the canonical zone." + "type": "string" }, "required": true, - "description": "UTC or a supported IANA time zone. Aliases are accepted and the response returns the canonical zone.", - "name": "view_time_zone", + "name": "end", "in": "query" }, { "schema": { - "type": "string", - "enum": [ - "true", - "false" - ], - "default": "false", - "description": "Include cancelled single events and whole-series occurrences. Default false." + "type": "integer", + "minimum": 1, + "maximum": 200, + "default": 100 }, "required": false, - "description": "Include cancelled single events and whole-series occurrences. Default false.", - "name": "include_cancelled", + "name": "limit", "in": "query" }, { "schema": { - "type": "integer", - "minimum": 1, - "maximum": 200, - "default": 100, - "description": "Maximum agenda items on this page. Default 100; range 1 to 200." + "type": "string" }, "required": false, - "description": "Maximum agenda items on this page. Default 100; range 1 to 200.", - "name": "limit", + "name": "cursor", "in": "query" }, { "schema": { "type": "string", - "description": "Opaque agenda pagination cursor." + "enum": [ + "true", + "false" + ], + "default": "false" }, "required": false, - "description": "Opaque agenda pagination cursor.", - "name": "cursor", + "name": "include_cancelled", "in": "query" } ], - "description": "Merge overlapping single events and recurring occurrences in a required bounded instant window. The view time zone controls all-day overlap and ordering; event lists remain master-only.", + "description": "Expand one recurring series in the required bounded start-based half-open window `[start, end)`. This read does not materialize occurrence rows or change the series master.", "security": [ { "bearerAuth": [] @@ -25498,17 +27040,17 @@ { "lang": "shell", "label": "curl", - "source": "curl -G https://api.wspc.ai/calendar/agenda \\\n -H \"Authorization: Bearer $WSPC_API_KEY\" \\\n --data-urlencode \"start=2026-08-10T00:00:00+08:00\" \\\n --data-urlencode \"end=2026-08-17T00:00:00+08:00\" \\\n --data-urlencode \"view_time_zone=Asia/Taipei\"" + "source": "curl -G https://api.wspc.ai/calendar/events/evt_xxx/occurrences \\\n -H \"Authorization: Bearer $WSPC_API_KEY\" \\\n --data-urlencode \"start=2026-06-01\" \\\n --data-urlencode \"end=2026-07-01\"" }, { "lang": "bash", "label": "wspc CLI", - "source": "wspc event agenda --from \"this Monday\" --to \"next Monday\" --tz Asia/Taipei" + "source": "wspc event occurrences evt_xxx --from 2026-06-01 --to 2026-07-01" } ], "responses": { "200": { - "description": "Stable agenda page with canonical view time zone.", + "description": "Occurrence page ordered by recurrence_id.", "headers": { "x-cb-cal": { "description": "Opaque consistency bookmark for the latest calendar database position observed by this request. Store and send it on the next calendar request to continue read-after-write consistency.", @@ -25520,7 +27062,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ListAgendaResponse" + "$ref": "#/components/schemas/ListEventOccurrencesResponse" } } } @@ -25730,42 +27272,6 @@ } } }, - "422": { - "description": "Agenda candidate or expanded-item budget exceeded.", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "error": { - "type": "object", - "properties": { - "code": { - "type": "string" - }, - "message": { - "type": "string" - } - }, - "required": [ - "code", - "message" - ] - } - }, - "required": [ - "error" - ] - }, - "example": { - "error": { - "code": "AGENDA_LIMIT_EXCEEDED", - "message": "Agenda expansion limit exceeded; use a smaller window" - } - } - } - } - }, "429": { "description": "Rate limit exceeded. Use the HTTP `Retry-After` header for machine-readable retry timing.", "content": { @@ -25851,157 +27357,48 @@ } } }, - "/calendar/events/{id}/occurrences": { - "get": { - "operationId": "event_occurrences", + "/calendar/subscription/reset": { + "post": { + "operationId": "calendar_reset_subscription", + "x-codeSamples": [ + { + "lang": "Shell", + "label": "curl", + "source": "curl -X POST \"https://api.wspc.ai/calendar/subscription/reset\" -H \"Authorization: Bearer $WSPC_API_KEY\" -H \"Content-Type: application/json\" -d '{\"expected_version\":1}'" + } + ], "tags": [ "Events" ], - "x-cli": { - "command": "event occurrences", - "positional": [ - "id" - ], - "booleanFlags": [ - "include_cancelled" - ], - "options": { - "from": { - "parser": "occurrence-boundary", - "mapsTo": "start", - "required": true - }, - "to": { - "parser": "occurrence-boundary", - "mapsTo": "end", - "required": true + "summary": "Reset the private calendar link", + "description": "Replace the link using expected_version. The old link stops working; external copies cannot be removed. Subscribe again with the new link. After an uncertain response, read the current state before retrying. A private read-only link to all your event details in the current Workspace. Anyone with the link can read them. External calendar updates depend on that app's refresh schedule and can be delayed.", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "expected_version": { + "type": "integer", + "minimum": 0 + } + }, + "required": [ + "expected_version" + ], + "additionalProperties": false + } } - }, - "examples": [ - "wspc event occurrences evt_xxx --from \"this Monday\" --to \"next Monday\"" - ], - "display": { - "shape": "list", - "columns": [ - "recurrence_id", - "start", - "end", - "status", - "exception_version", - "time_zone" - ], - "format": { - "recurrence_id": "truncate", - "start": "relative-time", - "end": "relative-time", - "status": "status-badge" - }, - "emptyMessage": "no occurrences" } }, - "summary": "List occurrences of one recurring series", - "parameters": [ - { - "name": "x-cb-cal", - "in": "header", - "required": false, - "description": "Optional opaque consistency bookmark returned by a previous calendar response. Send it back unchanged to continue read-after-write consistency for calendar D1 data.", - "schema": { - "type": "string" - }, - "example": "opaque-consistency-bookmark" - }, - { - "schema": { - "type": "string", - "minLength": 1 - }, - "required": true, - "name": "id", - "in": "path" - }, - { - "schema": { - "type": "string" - }, - "required": true, - "name": "start", - "in": "query" - }, - { - "schema": { - "type": "string" - }, - "required": true, - "name": "end", - "in": "query" - }, - { - "schema": { - "type": "integer", - "minimum": 1, - "maximum": 200, - "default": 100 - }, - "required": false, - "name": "limit", - "in": "query" - }, - { - "schema": { - "type": "string" - }, - "required": false, - "name": "cursor", - "in": "query" - }, - { - "schema": { - "type": "string", - "enum": [ - "true", - "false" - ], - "default": "false" - }, - "required": false, - "name": "include_cancelled", - "in": "query" - } - ], - "description": "Expand one recurring series in the required bounded start-based half-open window `[start, end)`. This read does not materialize occurrence rows or change the series master.", - "security": [ - { - "bearerAuth": [] - } - ], - "x-codeSamples": [ - { - "lang": "shell", - "label": "curl", - "source": "curl -G https://api.wspc.ai/calendar/events/evt_xxx/occurrences \\\n -H \"Authorization: Bearer $WSPC_API_KEY\" \\\n --data-urlencode \"start=2026-06-01\" \\\n --data-urlencode \"end=2026-07-01\"" - }, - { - "lang": "bash", - "label": "wspc CLI", - "source": "wspc event occurrences evt_xxx --from 2026-06-01 --to 2026-07-01" - } - ], "responses": { "200": { - "description": "Occurrence page ordered by recurrence_id.", - "headers": { - "x-cb-cal": { - "description": "Opaque consistency bookmark for the latest calendar database position observed by this request. Store and send it on the next calendar request to continue read-after-write consistency.", - "schema": { - "type": "string" - } - } - }, + "description": "Current subscription state", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ListEventOccurrencesResponse" + "$ref": "#/components/schemas/CalendarSubscription" } } } @@ -26171,7 +27568,7 @@ } }, "409": { - "description": "Optimistic-lock conflict. The supplied `expected_version` does not match the server's current version. Refetch the resource and retry.", + "description": "VERSION_CONFLICT: read the current state before retrying. SUBSCRIPTION_DISABLED: create a link before resetting it.", "content": { "application/json": { "schema": { @@ -26196,17 +27593,6 @@ "required": [ "error" ] - }, - "examples": { - "versionConflict": { - "summary": "expected_version does not match server version", - "value": { - "error": { - "code": "VERSION_CONFLICT", - "message": "expected_version 3 but current is 4" - } - } - } } } } @@ -26292,6 +27678,36 @@ } } } + }, + "503": { + "description": "SUBSCRIPTION_UNAVAILABLE: the feature is disabled or Auth is unavailable.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "code", + "message" + ] + } + }, + "required": [ + "error" + ] + } + } + } } } } @@ -46330,7 +47746,7 @@ ] }, "summary": "Create a recurring todo rule", - "description": "### 🎯 Overview & Purpose\nCreate a recurrence rule that materializes upcoming todo instances on a repeating schedule.\n\n### 🔍 When to Use\n* Use this to set up recurring work like a weekly Standup, monthly reporting, or cyclical maintenance. The server automatically materializes upcoming todo instances on a 14-day rolling horizon.\n\n### 💡 Key Features & Constraints\n* **RFC-5545 Conformity**: The `rrule` parameter must be a valid RFC-5545 schedule string (e.g., `FREQ=WEEKLY;BYDAY=MO`) and must **not** include the `DTSTART` or `TZID` directive.\n* **Anchor Date**: `dtstart` specifies the local calendar starting date (`YYYY-MM-DD`) where the schedule rule is anchored.\n* **Nesting Constraints**: Recurrence rules can only be bound to root-level tasks. Child tasks (subtasks) cannot have recurrence rules. Setting a child task as a parent will trigger `PARENT_IS_CHILD`.\n* **Instance Independence**: Once materialized, each todo instance is fully independent with its own `status` and `due_at`.\n\n### ⚠️ Common Errors & Troubleshooting\n* **`RRULE_INVALID` (HTTP 400)**: Thrown if the `rrule` schedule string is broken or contains illegal `DTSTART` directives.\n* **`PARENT_IS_CHILD` (HTTP 400)**: Thrown if the specified `parent_id` points to a child task.\n* **`VALIDATION_ERROR` (HTTP 400)**: Thrown if date format is invalid or required fields are missing.", + "description": "### 🎯 Overview & Purpose\nCreate a recurrence rule that materializes upcoming todo instances on a repeating schedule.\n\n### 🔍 When to Use\n* Use this to set up recurring work like a weekly Standup, monthly reporting, or cyclical maintenance. The server automatically materializes upcoming todo instances on a 14-day rolling horizon.\n\n### 💡 Key Features & Constraints\n* **RFC-5545 Conformity**: The `rrule` parameter must be a valid RFC-5545 schedule string (e.g., `FREQ=WEEKLY;BYDAY=MO`) and must **not** include the `DTSTART` or `TZID` directive.\n* **Anchor Date**: `dtstart` specifies the local calendar starting date (`YYYY-MM-DD`) where the schedule rule is anchored.\n* **Nesting Constraints**: Recurrence rules can only be bound to root-level tasks. Child tasks (subtasks) cannot have recurrence rules. Setting a child task as a parent will trigger `PARENT_IS_CHILD`.\n* **Fixed Assignee**: Optional `assignee_user_id` assigns every occurrence and subtask to a current Workspace Member. Omit to use the creator. Assignment cannot change after rule creation. To change assignee, delete the old rule and create a new one; existing instances remain, so choose a start date that avoids overlap. If membership is absent or unavailable, materialization pauses and existing instances stay intact.\n* **Instance Independence**: Once materialized, each todo instance is fully independent with its own `status` and `due_at`.\n\n### ⚠️ Common Errors & Troubleshooting\n* **`RRULE_INVALID` (HTTP 400)**: Thrown if the `rrule` schedule string is broken or contains illegal `DTSTART` directives.\n* **`PARENT_IS_CHILD` (HTTP 400)**: Thrown if the specified `parent_id` points to a child task.\n* **`VALIDATION_ERROR` (HTTP 400)**: Thrown if date format is invalid or required fields are missing.", "security": [ { "bearerAuth": [] @@ -46357,7 +47773,7 @@ { "lang": "bash", "label": "wspc CLI", - "source": "wspc todo rule add \"Draft weekly review\" --rrule \"FREQ=WEEKLY;BYDAY=MO\" --dtstart 2026-05-18 --project prj_01HW3K4N9V5G6Z8C2Q7B1Y0M3F --type typ_01HW3K4N9V5G6Z8C2Q7B1Y0M3F" + "source": "wspc todo rule add \"Draft weekly review\" --rrule \"FREQ=WEEKLY;BYDAY=MO\" --dtstart 2026-05-18 --project prj_01HW3K4N9V5G6Z8C2Q7B1Y0M3F --assignee-user-id usr_01HW3K4N9V5G6Z8C2Q7B1Y0M3F" } ], "requestBody": { @@ -46412,6 +47828,8 @@ "summary": "Weekly rule with 2 instances materialized in the 14-day window", "value": { "rule": { + "assignee_user_id": "usr_01HW3K4N9V5G6Z8C2Q7B1Y0M3F", + "assignee_status": "valid", "id": "tdr_01HW3K4N9V5G6Z8C2Q7B1Y0M3F", "user_id": "usr_01HW3K4N9V5G6Z8C2Q7B1Y0M3F", "project_id": "prj_01HW3K4N9V5G6Z8C2Q7B1Y0M3F", @@ -46635,6 +48053,36 @@ } } }, + "422": { + "description": "INVALID_ASSIGNEE: the assignee is not a current Workspace Member.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "code", + "message" + ] + } + }, + "required": [ + "error" + ] + } + } + } + }, "429": { "description": "Rate limit exceeded. Use the HTTP `Retry-After` header for machine-readable retry timing.", "content": { @@ -46716,6 +48164,36 @@ } } } + }, + "503": { + "description": "ASSIGNEE_CHECK_UNAVAILABLE: membership verification failed. No rule or instances were created.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "error": { + "type": "object", + "properties": { + "code": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "required": [ + "code", + "message" + ] + } + }, + "required": [ + "error" + ] + } + } + } } } }, @@ -46735,7 +48213,10 @@ "id", "rrule", "dtstart", - "type_id" + "type_id", + "user_id", + "assignee_user_id", + "assignee_status" ], "format": { "id": "id-short", @@ -46817,6 +48298,8 @@ "value": { "rules": [ { + "assignee_user_id": "usr_01HW3K4N9V5G6Z8C2Q7B1Y0M3F", + "assignee_status": "valid", "id": "tdr_01HW3K4N9V5G6Z8C2Q7B1Y0M3F", "user_id": "usr_01HW3K4N9V5G6Z8C2Q7B1Y0M3F", "project_id": "prj_01HW3K4N9V5G6Z8C2Q7B1Y0M3F", @@ -51273,6 +52756,7 @@ ], "display": { "shape": "object", + "dataPath": "rule", "format": { "id": "id-short", "type_id": "id-short" @@ -51280,7 +52764,7 @@ } }, "summary": "Get a recurring todo rule", - "description": "### 🎯 Overview & Purpose\nFetch a single recurrence rule along with its template todo snapshot and the count of materialized instances.\n\n### 🔍 When to Use\n* Use this to inspect rule details before editing, preview the task template that future occurrences will copy, or check the current materialization metrics.\n\n### 💡 Key Features & Constraints\n* **Snapshot Integrity**: The returned template represents a schema template snapshot — modifying the rule (PATCH) only alters future occurrences; already-materialized tasks are never mutated retroactively.\n\n### ⚠️ Common Errors & Troubleshooting\n* **`NOT_FOUND` (HTTP 404)**: Thrown if the specified rule ID does not exist.", + "description": "### 🎯 Overview & Purpose\nFetch a single recurrence rule along with its template todo snapshot and the count of materialized instances.\n\n### 🔍 When to Use\n* Use this to inspect rule details before editing, preview the task template that future occurrences will copy, or check the current materialization metrics.\n\n### 💡 Key Features & Constraints\n* **Snapshot Integrity**: The returned template represents a schema template snapshot — rule edits rebuild eligible open instances from today when membership is valid; modified roots are preserved.\n\n### ⚠️ Common Errors & Troubleshooting\n* **`NOT_FOUND` (HTTP 404)**: Thrown if the specified rule ID does not exist.", "security": [ { "bearerAuth": [] @@ -51339,6 +52823,8 @@ "summary": "Weekly rule with template snapshot", "value": { "rule": { + "assignee_user_id": "usr_01HW3K4N9V5G6Z8C2Q7B1Y0M3F", + "assignee_status": "valid", "id": "tdr_01HW3K4N9V5G6Z8C2Q7B1Y0M3F", "user_id": "usr_01HW3K4N9V5G6Z8C2Q7B1Y0M3F", "project_id": "prj_01HW3K4N9V5G6Z8C2Q7B1Y0M3F", @@ -51667,7 +53153,7 @@ "hidden": true }, "summary": "Update a recurring todo rule", - "description": "### 🎯 Overview & Purpose\nUpdate the schedule parameters (`rrule`, `dtstart`) or task template attributes (`title`, `description`, `parent_id`) of a recurrence rule.\n\n🔍 When to Use\n* Use this to shift standup schedules (e.g., from Monday to Friday), update template text details, or change the parent todo mapping for future generated tasks.\n\n### 💡 Key Features & Constraints\n* **Future-Only Effect**: Modifying the rule only applies to future materialized todo tasks; previously generated tasks remain unaffected.\n* **Optimistic Locking**: Supports `expected_version` to prevent concurrent modifications from overwriting workspace rule parameters.\n\n### ⚠️ Common Errors & Troubleshooting\n* **`VERSION_CONFLICT` (HTTP 409)**: Thrown if the provided `expected_version` mismatches the database.\n* **`RRULE_INVALID` (HTTP 400)**: Thrown if the updated schedule string contains illegal syntax or includes `DTSTART`.\n* **`NOT_FOUND` (HTTP 404)**: Thrown if the target rule ID does not exist.", + "description": "### 🎯 Overview & Purpose\nUpdate the schedule parameters (`rrule`, `dtstart`) or task template attributes (`title`, `description`, `parent_id`) of a recurrence rule.\n\n🔍 When to Use\n* Use this to shift standup schedules (e.g., from Monday to Friday), update template text details, or change the parent todo mapping for future generated tasks.\n\n### 💡 Key Features & Constraints\n* **Fixed Assignee**: Any PATCH with `assignee_user_id`, including the same value or null, fails with `ASSIGNEE_IMMUTABLE` (HTTP 400).\n* **Rebuild**: Rule edits rebuild open instances from today whose root Todo is unmodified. Membership must be valid before clearing instances; otherwise edits save and rebuilding is deferred.\n* **Optimistic Locking**: Supports `expected_version` to prevent concurrent modifications from overwriting workspace rule parameters.\n\n### ⚠️ Common Errors & Troubleshooting\n* **`VERSION_CONFLICT` (HTTP 409)**: Thrown if the provided `expected_version` mismatches the database.\n* **`RRULE_INVALID` (HTTP 400)**: Thrown if the updated schedule string contains illegal syntax or includes `DTSTART`.\n* **`NOT_FOUND` (HTTP 404)**: Thrown if the target rule ID does not exist.", "security": [ { "bearerAuth": [] @@ -51735,7 +53221,7 @@ }, "responses": { "200": { - "description": "The rule was updated. Returns the post-update rule with a bumped `version` and refreshed `updated_at`. Future materializations follow the new schedule; existing instances are untouched.", + "description": "The rule was updated. Returns the post-update rule with a bumped `version` and refreshed `updated_at`. Eligible future instances are rebuilt when membership is valid.", "headers": { "x-cb-todo": { "description": "Opaque consistency bookmark for the latest todo database position observed by this request. Store and send it on the next todo request to continue read-after-write consistency.", @@ -51753,6 +53239,8 @@ "happyPath": { "summary": "Rule moved to Fridays", "value": { + "assignee_user_id": "usr_01HW3K4N9V5G6Z8C2Q7B1Y0M3F", + "assignee_status": "valid", "id": "tdr_01HW3K4N9V5G6Z8C2Q7B1Y0M3F", "user_id": "usr_01HW3K4N9V5G6Z8C2Q7B1Y0M3F", "project_id": "prj_01HW3K4N9V5G6Z8C2Q7B1Y0M3F", diff --git a/src/generated/cli/event/ls.ts b/src/generated/cli/event/ls.ts index eba8e1f..d884b14 100644 --- a/src/generated/cli/event/ls.ts +++ b/src/generated/cli/event/ls.ts @@ -6,8 +6,8 @@ import { parseTimeInput, resolveTimezone } from "../../../handwritten/utils/pars export const eventListCommand = new Command("ls") .description("List calendar events") - .addHelpText("after", "\n### Overview\nReturn the authenticated user's events, ordered by `start` ascending, with cursor pagination.\n\n### When to Use\nRender calendar list/grid views, search for specific terms using full-text search, query events within a specific time window, or retrieve historically past events.\n\n### Constraints\n- **Default Visibility**: By default, soft-deleted events and past events (events where `end` is before the current time) are automatically hidden.\n- **Time Bounds Override**: Supplying any explicit time bound query parameter (`start_from`, `start_to`, `end_from`, `end_to`) or passing `include_past=true` overrides and disables the implicit past filter.\n- **Calendar Trash**: `deleted_only=true` returns only soft-deleted events for the current user and Workspace. It overrides `include_deleted` and disables the implicit past filter regardless of `include_past`. Explicit time bounds and `q` still apply. Series Masters remain single rows; cancelled occurrences are not Trash.\n- **Search Scope**: `q` performs a case-insensitive substring search across `title`, `description`, and `location`.\n- **Pagination**: Default `limit` is 50, clamped to `[1, 200]`. Matching events are ordered by `start ASC, id ASC` before cursor pagination. Cursor is a page position, not a Consistency bookmark or snapshot.\n\n### Troubleshooting\n- Returns 400 `VALIDATION_ERROR` if date query bounds are invalid (e.g. `start_from > start_to` or `end_from > end_to`).\n\nExamples:\n $ wspc event ls\n $ wspc event ls --deleted-only\n $ wspc event ls --from \"today\" --to \"next week\"\n") - .option("--q ", "Optional full-text search across title, description, and location (case-insensitive substring).") + .addHelpText("after", "\n### Overview\nReturn the authenticated user's events, ordered by `start` ascending, with cursor pagination.\n\n### When to Use\nRender calendar list/grid views, search for literal text, query events within a specific time window, or retrieve historically past events.\n\n### Constraints\n- **Default Visibility**: By default, soft-deleted events and past events (events where `end` is before the current time) are automatically hidden.\n- **Time Bounds Override**: Supplying any explicit time bound query parameter (`start_from`, `start_to`, `end_from`, `end_to`) or passing `include_past=true` overrides and disables the implicit past filter.\n- **Calendar Trash**: `deleted_only=true` returns only soft-deleted events for the current user and Workspace. It overrides `include_deleted` and disables the implicit past filter regardless of `include_past`. Explicit time bounds and `q` still apply. Series Masters remain single rows; cancelled occurrences are not Trash.\n- **Search Scope**: `q` performs a literal substring search across `title`, `description`, and `location`. ASCII case-insensitive; UTF-8 text is supported. Percent and underscore are literal characters, not wildcards.\n- **Pagination**: Default `limit` is 50, clamped to `[1, 200]`. Matching events are ordered by `start ASC, id ASC` before cursor pagination. Cursor is a page position, not a Consistency bookmark or snapshot.\n\n### Troubleshooting\n- Returns 400 `VALIDATION_ERROR` if date query bounds are invalid (e.g. `start_from > start_to` or `end_from > end_to`).\n\nExamples:\n $ wspc event ls\n $ wspc event ls --deleted-only\n $ wspc event ls --from \"today\" --to \"next week\"\n") + .option("--q ", "Optional literal substring search across title, description, and location. ASCII case-insensitive; UTF-8 text is supported. Percent and underscore are literal characters, not wildcards.") .option("--from ", "Inclusive lower bound on the event `start` (ISO datetime with offset, or ISO date-only). When ANY of `start_from`/`start_to`/`end_from`/`end_to` is provided, the implicit past filter is disabled.") .option("--to ", "Inclusive upper bound on the event `start`.") .option("--end-from ", "Inclusive lower bound on the event `end`.") diff --git a/src/generated/cli/todo/rule/add.ts b/src/generated/cli/todo/rule/add.ts index 06713c5..ef76744 100644 --- a/src/generated/cli/todo/rule/add.ts +++ b/src/generated/cli/todo/rule/add.ts @@ -5,8 +5,9 @@ import { runSdkCommand } from "../../../../handwritten/commands/run-sdk-command. export const recurrenceRuleCreateCommand = new Command("add") .description("Create a recurring todo rule") - .addHelpText("after", "\n### 🎯 Overview & Purpose\nCreate a recurrence rule that materializes upcoming todo instances on a repeating schedule.\n\n### 🔍 When to Use\n* Use this to set up recurring work like a weekly Standup, monthly reporting, or cyclical maintenance. The server automatically materializes upcoming todo instances on a 14-day rolling horizon.\n\n### 💡 Key Features & Constraints\n* **RFC-5545 Conformity**: The `rrule` parameter must be a valid RFC-5545 schedule string (e.g., `FREQ=WEEKLY;BYDAY=MO`) and must **not** include the `DTSTART` or `TZID` directive.\n* **Anchor Date**: `dtstart` specifies the local calendar starting date (`YYYY-MM-DD`) where the schedule rule is anchored.\n* **Nesting Constraints**: Recurrence rules can only be bound to root-level tasks. Child tasks (subtasks) cannot have recurrence rules. Setting a child task as a parent will trigger `PARENT_IS_CHILD`.\n* **Instance Independence**: Once materialized, each todo instance is fully independent with its own `status` and `due_at`.\n\n### ⚠️ Common Errors & Troubleshooting\n* **`RRULE_INVALID` (HTTP 400)**: Thrown if the `rrule` schedule string is broken or contains illegal `DTSTART` directives.\n* **`PARENT_IS_CHILD` (HTTP 400)**: Thrown if the specified `parent_id` points to a child task.\n* **`VALIDATION_ERROR` (HTTP 400)**: Thrown if date format is invalid or required fields are missing.\n\nExamples:\n $ wspc todo rule add \"Weekly review\" --rrule \"FREQ=WEEKLY;BYDAY=MO\" --dtstart 2026-05-18 --project prj_xxx\n $ wspc todo rule add \"Weekly review\" --rrule \"FREQ=WEEKLY;BYDAY=MO\" --dtstart 2026-05-18 --project prj_xxx --type typ_xxx\n") + .addHelpText("after", "\n### 🎯 Overview & Purpose\nCreate a recurrence rule that materializes upcoming todo instances on a repeating schedule.\n\n### 🔍 When to Use\n* Use this to set up recurring work like a weekly Standup, monthly reporting, or cyclical maintenance. The server automatically materializes upcoming todo instances on a 14-day rolling horizon.\n\n### 💡 Key Features & Constraints\n* **RFC-5545 Conformity**: The `rrule` parameter must be a valid RFC-5545 schedule string (e.g., `FREQ=WEEKLY;BYDAY=MO`) and must **not** include the `DTSTART` or `TZID` directive.\n* **Anchor Date**: `dtstart` specifies the local calendar starting date (`YYYY-MM-DD`) where the schedule rule is anchored.\n* **Nesting Constraints**: Recurrence rules can only be bound to root-level tasks. Child tasks (subtasks) cannot have recurrence rules. Setting a child task as a parent will trigger `PARENT_IS_CHILD`.\n* **Fixed Assignee**: Optional `assignee_user_id` assigns every occurrence and subtask to a current Workspace Member. Omit to use the creator. Assignment cannot change after rule creation. To change assignee, delete the old rule and create a new one; existing instances remain, so choose a start date that avoids overlap. If membership is absent or unavailable, materialization pauses and existing instances stay intact.\n* **Instance Independence**: Once materialized, each todo instance is fully independent with its own `status` and `due_at`.\n\n### ⚠️ Common Errors & Troubleshooting\n* **`RRULE_INVALID` (HTTP 400)**: Thrown if the `rrule` schedule string is broken or contains illegal `DTSTART` directives.\n* **`PARENT_IS_CHILD` (HTTP 400)**: Thrown if the specified `parent_id` points to a child task.\n* **`VALIDATION_ERROR` (HTTP 400)**: Thrown if date format is invalid or required fields are missing.\n\nExamples:\n $ wspc todo rule add \"Weekly review\" --rrule \"FREQ=WEEKLY;BYDAY=MO\" --dtstart 2026-05-18 --project prj_xxx\n $ wspc todo rule add \"Weekly review\" --rrule \"FREQ=WEEKLY;BYDAY=MO\" --dtstart 2026-05-18 --project prj_xxx --type typ_xxx\n") .argument("", "title") + .option("--assignee-user-id <value>", "assignee_user_id") .option("--rrule <value>", "rrule") .option("--dtstart <value>", "dtstart") .option("--description <value>", "description") @@ -19,6 +20,7 @@ export const recurrenceRuleCreateCommand = new Command("add") input: { body: { title, + assignee_user_id: opts.assigneeUserId, rrule: opts.rrule, dtstart: opts.dtstart, description: opts.description, diff --git a/src/generated/cli/todo/rule/ls.ts b/src/generated/cli/todo/rule/ls.ts index 04bd994..5109f2d 100644 --- a/src/generated/cli/todo/rule/ls.ts +++ b/src/generated/cli/todo/rule/ls.ts @@ -17,6 +17,6 @@ export const recurrenceRuleListCommand = new Command("ls") user_id: opts.userId, }, }, - context: { kind: "recurrence_rule_list", display: {"shape":"list","columns":["id","rrule","dtstart","type_id"],"format":{"id":"id-short","rrule":"truncate","type_id":"id-short"},"emptyMessage":"no recurrence rules"} }, + context: { kind: "recurrence_rule_list", display: {"shape":"list","columns":["id","rrule","dtstart","type_id","user_id","assignee_user_id","assignee_status"],"format":{"id":"id-short","rrule":"truncate","type_id":"id-short"},"emptyMessage":"no recurrence rules"} }, }) }) diff --git a/src/generated/cli/todo/rule/show.ts b/src/generated/cli/todo/rule/show.ts index b857419..dbf6d23 100644 --- a/src/generated/cli/todo/rule/show.ts +++ b/src/generated/cli/todo/rule/show.ts @@ -5,7 +5,7 @@ import { runSdkCommand } from "../../../../handwritten/commands/run-sdk-command. export const recurrenceRuleGetCommand = new Command("show") .description("Get a recurring todo rule") - .addHelpText("after", "\n### 🎯 Overview & Purpose\nFetch a single recurrence rule along with its template todo snapshot and the count of materialized instances.\n\n### 🔍 When to Use\n* Use this to inspect rule details before editing, preview the task template that future occurrences will copy, or check the current materialization metrics.\n\n### 💡 Key Features & Constraints\n* **Snapshot Integrity**: The returned template represents a schema template snapshot — modifying the rule (PATCH) only alters future occurrences; already-materialized tasks are never mutated retroactively.\n\n### ⚠️ Common Errors & Troubleshooting\n* **`NOT_FOUND` (HTTP 404)**: Thrown if the specified rule ID does not exist.\n\nExamples:\n $ wspc todo rule show tdr_xxx\n") + .addHelpText("after", "\n### 🎯 Overview & Purpose\nFetch a single recurrence rule along with its template todo snapshot and the count of materialized instances.\n\n### 🔍 When to Use\n* Use this to inspect rule details before editing, preview the task template that future occurrences will copy, or check the current materialization metrics.\n\n### 💡 Key Features & Constraints\n* **Snapshot Integrity**: The returned template represents a schema template snapshot — rule edits rebuild eligible open instances from today when membership is valid; modified roots are preserved.\n\n### ⚠️ Common Errors & Troubleshooting\n* **`NOT_FOUND` (HTTP 404)**: Thrown if the specified rule ID does not exist.\n\nExamples:\n $ wspc todo rule show tdr_xxx\n") .argument("<id>", "id") .action(async (id, opts) => { await runSdkCommand({ @@ -15,6 +15,6 @@ export const recurrenceRuleGetCommand = new Command("show") id, }, }, - context: { kind: "recurrence_rule_get", display: {"shape":"object","format":{"id":"id-short","type_id":"id-short"}} }, + context: { kind: "recurrence_rule_get", display: {"shape":"object","dataPath":"rule","format":{"id":"id-short","type_id":"id-short"}} }, }) }) diff --git a/src/generated/sdk/index.ts b/src/generated/sdk/index.ts index 3d030b6..d7b69d9 100644 --- a/src/generated/sdk/index.ts +++ b/src/generated/sdk/index.ts @@ -1,4 +1,4 @@ // This file is auto-generated by @hey-api/openapi-ts -export { accountDeletionCancel, accountDeletionGet, accountDeletionRequest, authMe, authRequestCode, authVerifyCode, billingCheckoutSessionsCreate, billingCustomDomainAddOnPreview, billingCustomDomainAddOnsChange, billingEmailUsageGet, billingEnforcementReadinessGet, billingEntitlementsGet, billingInboundProtectionGet, billingPaddleWebhookReceive, billingPortalSessionsCreate, billingPublicRolloutGet, billingStorageUsageGet, billingSubscriptionCancellationUpdate, billingSubscriptionDowngradePreview, billingSubscriptionDowngradesCreate, billingSubscriptionIntervalChangesCreate, billingSubscriptionIntervalPreviewsCreate, billingSubscriptionStateGet, billingSubscriptionUpgradePreviewsCreate, billingSubscriptionUpgradesCreate, calendarExport, driveExportCancel, driveExportCreate, driveExportDownload, driveExportGet, driveFileDelete, driveFileDownload, driveFileEdit, driveFileHistory, driveFileMove, driveFileRestore, driveFileRestoreDeleted, driveFileUpload, driveLibraryCreate, driveLibraryDelete, driveLibraryGet, driveLibraryList, driveLibraryUpdate, driveManifestGet, driveSearch, emailAliasCreate, emailAliasDelete, emailAliasList, emailAliasRestore, emailAttachmentGet, emailDelete, emailDomainCreate, emailDomainDelete, emailDomainGet, emailDomainList, emailDomainVerify, emailGet, emailList, emailMarkRead, emailMarkUnread, emailRestore, emailSend, emailSentDelete, emailSentGet, emailSentList, emailSentRestore, emailTrashEmpty, emailTrashSummary, eventAgenda, eventCreate, eventDelete, eventGet, eventIcsDownload, eventList, eventOccurrenceCancel, eventOccurrenceRestore, eventOccurrences, eventOccurrenceSet, eventRestore, eventUpdate, inviteAccept, inviteGet, inviteReject, invitesList, keyCreate, keyList, keyRevoke, keyUpdate, oauthAuthorizeGrant, oauthClientRegister, oauthDeviceAuthorize, oauthDeviceConfirm, oauthDeviceVerify, oauthMetadata, oauthMetadataOpenidAlias, oauthTokenExchange, oauthTokenRevoke, type Options, orgGet, orgInviteCreate, orgInviteRevoke, orgInvitesList, orgMemberRemove, orgMemberRoleUpdate, orgMembersList, orgUpdate, projectCreate, projectDelete, projectGet, projectList, projectRestore, projectUpdate, pushConfigDelete, pushConfigGet, pushConfigSet, pushTest, recurrenceRuleCreate, recurrenceRuleDelete, recurrenceRuleGet, recurrenceRuleList, recurrenceRuleUpdate, todoCommentCreate, todoCommentDelete, todoCommentList, todoCommentUpdate, todoCreate, todoDelete, todoExport, todoGet, todoList, todoRestore, todoTypeCreate, todoTypeDelete, todoTypeGet, todoTypeList, todoTypeRestore, todoTypeUpdate, todoUpdate } from './sdk.gen'; -export type { AccountDeletionCancelData, AccountDeletionCancelError, AccountDeletionCancelErrors, AccountDeletionCancelResponse, AccountDeletionCancelResponses, AccountDeletionGetData, AccountDeletionGetError, AccountDeletionGetErrors, AccountDeletionGetResponse, AccountDeletionGetResponses, AccountDeletionRequestData, AccountDeletionRequestError, AccountDeletionRequestErrors, AccountDeletionRequestResponse, AccountDeletionRequestResponses, Alias, ApplyDowngradeResult, ApplySubscriptionDowngradeInput, ApplySubscriptionIntervalInput, AuthMeData, AuthMeError, AuthMeErrors, AuthMeResponse, AuthMeResponses, AuthRequestCodeData, AuthRequestCodeError, AuthRequestCodeErrors, AuthRequestCodeResponse, AuthRequestCodeResponses, AuthVerifyCodeData, AuthVerifyCodeError, AuthVerifyCodeErrors, AuthVerifyCodeResponse, AuthVerifyCodeResponses, BatchIdsBody, BillingCheckoutSessionsCreateData, BillingCheckoutSessionsCreateError, BillingCheckoutSessionsCreateErrors, BillingCheckoutSessionsCreateResponse, BillingCheckoutSessionsCreateResponses, BillingCustomDomainAddOnPreviewData, BillingCustomDomainAddOnPreviewError, BillingCustomDomainAddOnPreviewErrors, BillingCustomDomainAddOnPreviewResponse, BillingCustomDomainAddOnPreviewResponses, BillingCustomDomainAddOnsChangeData, BillingCustomDomainAddOnsChangeError, BillingCustomDomainAddOnsChangeErrors, BillingCustomDomainAddOnsChangeResponse, BillingCustomDomainAddOnsChangeResponses, BillingEmailUsageGetData, BillingEmailUsageGetError, BillingEmailUsageGetErrors, BillingEmailUsageGetResponse, BillingEmailUsageGetResponses, BillingEnforcementReadinessGetData, BillingEnforcementReadinessGetError, BillingEnforcementReadinessGetErrors, BillingEnforcementReadinessGetResponse, BillingEnforcementReadinessGetResponses, BillingEntitlementsGetData, BillingEntitlementsGetError, BillingEntitlementsGetErrors, BillingEntitlementsGetResponse, BillingEntitlementsGetResponses, BillingInboundProtectionGetData, BillingInboundProtectionGetError, BillingInboundProtectionGetErrors, BillingInboundProtectionGetResponse, BillingInboundProtectionGetResponses, BillingPaddleWebhookReceiveData, BillingPaddleWebhookReceiveError, BillingPaddleWebhookReceiveErrors, BillingPaddleWebhookReceiveResponse, BillingPaddleWebhookReceiveResponses, BillingPortalSessionsCreateData, BillingPortalSessionsCreateError, BillingPortalSessionsCreateErrors, BillingPortalSessionsCreateResponse, BillingPortalSessionsCreateResponses, BillingPublicRolloutGetData, BillingPublicRolloutGetResponse, BillingPublicRolloutGetResponses, BillingStorageUsageGetData, BillingStorageUsageGetError, BillingStorageUsageGetErrors, BillingStorageUsageGetResponse, BillingStorageUsageGetResponses, BillingSubscriptionCancellationUpdateData, BillingSubscriptionCancellationUpdateError, BillingSubscriptionCancellationUpdateErrors, BillingSubscriptionCancellationUpdateResponse, BillingSubscriptionCancellationUpdateResponses, BillingSubscriptionDowngradePreviewData, BillingSubscriptionDowngradePreviewError, BillingSubscriptionDowngradePreviewErrors, BillingSubscriptionDowngradePreviewResponse, BillingSubscriptionDowngradePreviewResponses, BillingSubscriptionDowngradesCreateData, BillingSubscriptionDowngradesCreateError, BillingSubscriptionDowngradesCreateErrors, BillingSubscriptionDowngradesCreateResponse, BillingSubscriptionDowngradesCreateResponses, BillingSubscriptionIntervalChangesCreateData, BillingSubscriptionIntervalChangesCreateError, BillingSubscriptionIntervalChangesCreateErrors, BillingSubscriptionIntervalChangesCreateResponse, BillingSubscriptionIntervalChangesCreateResponses, BillingSubscriptionIntervalPreviewsCreateData, BillingSubscriptionIntervalPreviewsCreateError, BillingSubscriptionIntervalPreviewsCreateErrors, BillingSubscriptionIntervalPreviewsCreateResponse, BillingSubscriptionIntervalPreviewsCreateResponses, BillingSubscriptionStateGetData, BillingSubscriptionStateGetError, BillingSubscriptionStateGetErrors, BillingSubscriptionStateGetResponse, BillingSubscriptionStateGetResponses, BillingSubscriptionUpgradePreviewsCreateData, BillingSubscriptionUpgradePreviewsCreateError, BillingSubscriptionUpgradePreviewsCreateErrors, BillingSubscriptionUpgradePreviewsCreateResponse, BillingSubscriptionUpgradePreviewsCreateResponses, BillingSubscriptionUpgradesCreateData, BillingSubscriptionUpgradesCreateError, BillingSubscriptionUpgradesCreateErrors, BillingSubscriptionUpgradesCreateResponse, BillingSubscriptionUpgradesCreateResponses, CalendarExportData, CalendarExportError, CalendarExportErrors, CalendarExportResponse, CalendarExportResponses, ChangeCustomDomainAddOnInput, CheckoutSessionResult, ClientOptions, Comment, CreateAliasBody, CreateApiKeyBody, CreateApiKeyResponse, CreateCommentBody, CreateDomainBody, CreateDriveLibraryBody, CreateEventBody, CreateOrgInviteInput, CreateProjectBody, CreateRecurrenceRuleBody, CreateRecurrenceRuleResponse, CreateTodoBody, CreateTodoTypeBody, CustomDomainAddOnPreviewResult, CustomDomainAddOnResult, CustomerPortalSessionInput, CustomerPortalSessionResult, DeleteBatchResponse, DeleteDriveFileBody, DeleteDriveFileResponse, DeleteDriveLibraryBody, DeleteEventResponse, DeleteRecurrenceRuleBody, DeleteRecurrenceRuleResponse, DeleteTodoBody, DeleteTodoResponse, DowngradePreviewResult, DriveExportCancelData, DriveExportCancelError, DriveExportCancelErrors, DriveExportCancelResponse, DriveExportCancelResponses, DriveExportCreateData, DriveExportCreateError, DriveExportCreateErrors, DriveExportCreateResponse, DriveExportCreateResponses, DriveExportDownloadData, DriveExportDownloadError, DriveExportDownloadErrors, DriveExportDownloadResponse, DriveExportDownloadResponses, DriveExportGetData, DriveExportGetError, DriveExportGetErrors, DriveExportGetResponse, DriveExportGetResponses, DriveFileDeleteData, DriveFileDeleteError, DriveFileDeleteErrors, DriveFileDeleteResponse, DriveFileDeleteResponses, DriveFileDownloadData, DriveFileDownloadError, DriveFileDownloadErrors, DriveFileDownloadResponse, DriveFileDownloadResponses, DriveFileEditData, DriveFileEditError, DriveFileEditErrors, DriveFileEditResponse, DriveFileEditResponses, DriveFileHistoryData, DriveFileHistoryError, DriveFileHistoryErrors, DriveFileHistoryResponse, DriveFileHistoryResponse2, DriveFileHistoryResponses, DriveFileMoveData, DriveFileMoveError, DriveFileMoveErrors, DriveFileMoveResponse, DriveFileMoveResponses, DriveFileRestoreData, DriveFileRestoreDeletedData, DriveFileRestoreDeletedError, DriveFileRestoreDeletedErrors, DriveFileRestoreDeletedResponse, DriveFileRestoreDeletedResponses, DriveFileRestoreError, DriveFileRestoreErrors, DriveFileRestoreResponse, DriveFileRestoreResponses, DriveFileUploadData, DriveFileUploadError, DriveFileUploadErrors, DriveFileUploadResponse, DriveFileUploadResponses, DriveLibrary, DriveLibraryCreateData, DriveLibraryCreateError, DriveLibraryCreateErrors, DriveLibraryCreateResponse, DriveLibraryCreateResponses, DriveLibraryDeleteData, DriveLibraryDeleteError, DriveLibraryDeleteErrors, DriveLibraryDeleteResponse, DriveLibraryDeleteResponses, DriveLibraryGetData, DriveLibraryGetError, DriveLibraryGetErrors, DriveLibraryGetResponse, DriveLibraryGetResponses, DriveLibraryListData, DriveLibraryListError, DriveLibraryListErrors, DriveLibraryListResponse, DriveLibraryListResponses, DriveLibraryUpdateData, DriveLibraryUpdateError, DriveLibraryUpdateErrors, DriveLibraryUpdateResponse, DriveLibraryUpdateResponses, DriveManifestGetData, DriveManifestGetError, DriveManifestGetErrors, DriveManifestGetResponse, DriveManifestGetResponses, DriveManifestResponse, DriveSearchData, DriveSearchError, DriveSearchErrors, DriveSearchResponse, DriveSearchResponse2, DriveSearchResponses, EditDriveFileBody, EffectiveEntitlements, EmailAliasCreateData, EmailAliasCreateError, EmailAliasCreateErrors, EmailAliasCreateResponse, EmailAliasCreateResponses, EmailAliasDeleteData, EmailAliasDeleteError, EmailAliasDeleteErrors, EmailAliasDeleteResponse, EmailAliasDeleteResponses, EmailAliasListData, EmailAliasListError, EmailAliasListErrors, EmailAliasListResponse, EmailAliasListResponses, EmailAliasRestoreData, EmailAliasRestoreError, EmailAliasRestoreErrors, EmailAliasRestoreResponse, EmailAliasRestoreResponses, EmailAttachmentGetData, EmailAttachmentGetError, EmailAttachmentGetErrors, EmailAttachmentGetResponse, EmailAttachmentGetResponses, EmailDeleteData, EmailDeleteError, EmailDeleteErrors, EmailDeleteResponse, EmailDeleteResponses, EmailDomainCreateData, EmailDomainCreateError, EmailDomainCreateErrors, EmailDomainCreateResponse, EmailDomainCreateResponses, EmailDomainDeleteData, EmailDomainDeleteError, EmailDomainDeleteErrors, EmailDomainDeleteResponse, EmailDomainDeleteResponses, EmailDomainGetData, EmailDomainGetError, EmailDomainGetErrors, EmailDomainGetResponse, EmailDomainGetResponses, EmailDomainListData, EmailDomainListError, EmailDomainListErrors, EmailDomainListResponse, EmailDomainListResponse2, EmailDomainListResponses, EmailDomainObjectResponse, EmailDomainVerifyData, EmailDomainVerifyError, EmailDomainVerifyErrors, EmailDomainVerifyResponse, EmailDomainVerifyResponses, EmailGetData, EmailGetError, EmailGetErrors, EmailGetResponse, EmailGetResponses, EmailListData, EmailListError, EmailListErrors, EmailListResponse, EmailListResponses, EmailMarkReadData, EmailMarkReadError, EmailMarkReadErrors, EmailMarkReadResponse, EmailMarkReadResponses, EmailMarkUnreadData, EmailMarkUnreadError, EmailMarkUnreadErrors, EmailMarkUnreadResponse, EmailMarkUnreadResponses, EmailRestoreData, EmailRestoreError, EmailRestoreErrors, EmailRestoreResponse, EmailRestoreResponses, EmailSendData, EmailSendError, EmailSendErrors, EmailSendResponse, EmailSendResponses, EmailSentDeleteData, EmailSentDeleteError, EmailSentDeleteErrors, EmailSentDeleteResponse, EmailSentDeleteResponses, EmailSentGetData, EmailSentGetError, EmailSentGetErrors, EmailSentGetResponse, EmailSentGetResponses, EmailSentListData, EmailSentListError, EmailSentListErrors, EmailSentListResponse, EmailSentListResponses, EmailSentRestoreData, EmailSentRestoreError, EmailSentRestoreErrors, EmailSentRestoreResponse, EmailSentRestoreResponses, EmailTrashEmptyData, EmailTrashEmptyError, EmailTrashEmptyErrors, EmailTrashEmptyResponse, EmailTrashEmptyResponses, EmailTrashSummaryData, EmailTrashSummaryError, EmailTrashSummaryErrors, EmailTrashSummaryResponse, EmailTrashSummaryResponses, EmailUsage, EnforcementReadiness, Event, EventAgendaData, EventAgendaError, EventAgendaErrors, EventAgendaResponse, EventAgendaResponses, EventCreateData, EventCreateError, EventCreateErrors, EventCreateResponse, EventCreateResponses, EventDeleteData, EventDeleteError, EventDeleteErrors, EventDeleteResponse, EventDeleteResponses, EventGetData, EventGetError, EventGetErrors, EventGetResponse, EventGetResponses, EventIcsDownloadData, EventIcsDownloadError, EventIcsDownloadErrors, EventIcsDownloadResponse, EventIcsDownloadResponses, EventListData, EventListError, EventListErrors, EventListResponse, EventListResponses, EventOccurrence, EventOccurrenceCancelData, EventOccurrenceCancelError, EventOccurrenceCancelErrors, EventOccurrenceCancelResponse, EventOccurrenceCancelResponses, EventOccurrenceRestoreData, EventOccurrenceRestoreError, EventOccurrenceRestoreErrors, EventOccurrenceRestoreResponse, EventOccurrenceRestoreResponses, EventOccurrencesData, EventOccurrencesError, EventOccurrencesErrors, EventOccurrenceSetData, EventOccurrenceSetError, EventOccurrenceSetErrors, EventOccurrenceSetResponse, EventOccurrenceSetResponses, EventOccurrencesResponse, EventOccurrencesResponses, EventRestoreData, EventRestoreError, EventRestoreErrors, EventRestoreResponse, EventRestoreResponses, EventUpdateData, EventUpdateError, EventUpdateErrors, EventUpdateResponse, EventUpdateResponses, GetMeResponse, InboundProtection, InviteAcceptData, InviteAcceptError, InviteAcceptErrors, InviteAcceptResponse, InviteAcceptResponses, InviteGetData, InviteGetError, InviteGetErrors, InviteGetResponse, InviteGetResponses, InviteRejectData, InviteRejectError, InviteRejectErrors, InviteRejectResponse, InviteRejectResponses, InvitesListData, InvitesListError, InvitesListErrors, InvitesListResponse, InvitesListResponses, KeyCreateData, KeyCreateError, KeyCreateErrors, KeyCreateResponse, KeyCreateResponses, KeyListData, KeyListError, KeyListErrors, KeyListResponse, KeyListResponses, KeyRevokeData, KeyRevokeError, KeyRevokeErrors, KeyRevokeResponse, KeyRevokeResponses, KeyUpdateData, KeyUpdateError, KeyUpdateErrors, KeyUpdateResponse, KeyUpdateResponses, ListAgendaResponse, ListApiKeysResponse, ListDriveLibrariesResponse, ListEventOccurrencesResponse, ListEventsResponse, ListMyInvitesResponse, ListOrgInvitesResponse, ListOrgMembersResponse, ListRecurrenceRulesResponse, ListTodosResponse, MarkBatchResponse, MoveDriveFileBody, MoveDriveFileResponse, OauthAuthorizeGrantData, OauthAuthorizeGrantError, OauthAuthorizeGrantErrors, OauthAuthorizeGrantResponse, OauthAuthorizeGrantResponses, OAuthAuthServerMetadata, OauthClientRegisterData, OauthClientRegisterError, OauthClientRegisterErrors, OauthClientRegisterResponse, OauthClientRegisterResponses, OauthDeviceAuthorizeData, OauthDeviceAuthorizeError, OauthDeviceAuthorizeErrors, OauthDeviceAuthorizeResponse, OauthDeviceAuthorizeResponses, OAuthDeviceBody, OauthDeviceConfirmData, OauthDeviceConfirmError, OauthDeviceConfirmErrors, OauthDeviceConfirmResponse, OauthDeviceConfirmResponses, OAuthDeviceResponse, OauthDeviceVerifyData, OauthDeviceVerifyError, OauthDeviceVerifyErrors, OauthDeviceVerifyResponse, OauthDeviceVerifyResponses, OauthMetadataData, OauthMetadataError, OauthMetadataErrors, OauthMetadataOpenidAliasData, OauthMetadataOpenidAliasError, OauthMetadataOpenidAliasErrors, OauthMetadataOpenidAliasResponse, OauthMetadataOpenidAliasResponses, OauthMetadataResponse, OauthMetadataResponses, OAuthRegisterBody, OAuthRegisterResponse, OAuthRevokeBody, OAuthTokenBody, OauthTokenExchangeData, OauthTokenExchangeError, OauthTokenExchangeErrors, OauthTokenExchangeResponse, OauthTokenExchangeResponses, OAuthTokenResponse, OauthTokenRevokeData, OauthTokenRevokeError, OauthTokenRevokeErrors, OauthTokenRevokeResponse, OauthTokenRevokeResponses, OccurrenceVersionBody, Org, OrgGetData, OrgGetError, OrgGetErrors, OrgGetResponse, OrgGetResponses, OrgInviteCreateData, OrgInviteCreateError, OrgInviteCreateErrors, OrgInviteCreateResponse, OrgInviteCreateResponses, OrgInviteRevokeData, OrgInviteRevokeError, OrgInviteRevokeErrors, OrgInviteRevokeResponse, OrgInviteRevokeResponses, OrgInvitesListData, OrgInvitesListError, OrgInvitesListErrors, OrgInvitesListResponse, OrgInvitesListResponses, OrgInviteSummary, OrgInviteView, OrgMember, OrgMemberRemoveData, OrgMemberRemoveError, OrgMemberRemoveErrors, OrgMemberRemoveResponse, OrgMemberRemoveResponses, OrgMemberRoleUpdateData, OrgMemberRoleUpdateError, OrgMemberRoleUpdateErrors, OrgMemberRoleUpdateResponse, OrgMemberRoleUpdateResponses, OrgMembersListData, OrgMembersListError, OrgMembersListErrors, OrgMembersListResponse, OrgMembersListResponses, OrgUpdateData, OrgUpdateError, OrgUpdateErrors, OrgUpdateResponse, OrgUpdateResponses, PaddleWebhookResult, PreviewCustomDomainAddOnInput, PreviewSubscriptionDowngradeInput, PreviewSubscriptionIntervalInput, PreviewSubscriptionUpgradeInput, Project, ProjectCreateData, ProjectCreateError, ProjectCreateErrors, ProjectCreateResponse, ProjectCreateResponses, ProjectDeleteData, ProjectDeleteError, ProjectDeleteErrors, ProjectDeleteResponse, ProjectDeleteResponses, ProjectGetData, ProjectGetError, ProjectGetErrors, ProjectGetResponse, ProjectGetResponses, ProjectListData, ProjectListError, ProjectListErrors, ProjectListResponse, ProjectListResponses, ProjectRestoreData, ProjectRestoreError, ProjectRestoreErrors, ProjectRestoreResponse, ProjectRestoreResponses, ProjectUpdateData, ProjectUpdateError, ProjectUpdateErrors, ProjectUpdateResponse, ProjectUpdateResponses, PushConfigDeleteData, PushConfigDeleteError, PushConfigDeleteErrors, PushConfigDeleteResponse, PushConfigDeleteResponses, PushConfigGetData, PushConfigGetError, PushConfigGetErrors, PushConfigGetResponse, PushConfigGetResponses, PushConfigSetData, PushConfigSetError, PushConfigSetErrors, PushConfigSetResponse, PushConfigSetResponses, PushTestData, PushTestError, PushTestErrors, PushTestResponse, PushTestResponses, ReceivedEmailDetail, RecurrenceRule, RecurrenceRuleCreateData, RecurrenceRuleCreateError, RecurrenceRuleCreateErrors, RecurrenceRuleCreateResponse, RecurrenceRuleCreateResponses, RecurrenceRuleDeleteData, RecurrenceRuleDeleteError, RecurrenceRuleDeleteErrors, RecurrenceRuleDeleteResponse, RecurrenceRuleDeleteResponses, RecurrenceRuleDetail, RecurrenceRuleGetData, RecurrenceRuleGetError, RecurrenceRuleGetErrors, RecurrenceRuleGetResponse, RecurrenceRuleGetResponses, RecurrenceRuleListData, RecurrenceRuleListError, RecurrenceRuleListErrors, RecurrenceRuleListResponse, RecurrenceRuleListResponses, RecurrenceRuleUpdateData, RecurrenceRuleUpdateError, RecurrenceRuleUpdateErrors, RecurrenceRuleUpdateResponse, RecurrenceRuleUpdateResponses, RequestCodeBody, RequestCodeResponse, RestoreBatchResponse, RestoreDriveFileBody, RestoreDriveFileResponse, RestoreTodoBody, RestoreTodoResponse, RevokeApiKeyResponse, SendEmailBody, SendEmailResponse, SentEmailDetail, SetPushConfigBody, ShowPushConfigResponse, StartInitialCheckoutInput, StartSubscriptionUpgradeInput, StorageUsage, SubscriptionCancellationResult, SubscriptionState, TestPushBody, TestPushResponse, Todo, TodoCommentCreateData, TodoCommentCreateError, TodoCommentCreateErrors, TodoCommentCreateResponse, TodoCommentCreateResponses, TodoCommentDeleteData, TodoCommentDeleteError, TodoCommentDeleteErrors, TodoCommentDeleteResponse, TodoCommentDeleteResponses, TodoCommentListData, TodoCommentListError, TodoCommentListErrors, TodoCommentListResponse, TodoCommentListResponses, TodoCommentUpdateData, TodoCommentUpdateError, TodoCommentUpdateErrors, TodoCommentUpdateResponse, TodoCommentUpdateResponses, TodoCreateData, TodoCreateError, TodoCreateErrors, TodoCreateResponse, TodoCreateResponses, TodoDeleteData, TodoDeleteError, TodoDeleteErrors, TodoDeleteResponse, TodoDeleteResponses, TodoExportData, TodoExportDocument, TodoExportError, TodoExportErrors, TodoExportResponse, TodoExportResponses, TodoGetData, TodoGetError, TodoGetErrors, TodoGetResponse, TodoGetResponses, TodoListData, TodoListError, TodoListErrors, TodoListResponse, TodoListResponses, TodoRestoreData, TodoRestoreError, TodoRestoreErrors, TodoRestoreResponse, TodoRestoreResponses, TodoType, TodoTypeCreateData, TodoTypeCreateError, TodoTypeCreateErrors, TodoTypeCreateResponse, TodoTypeCreateResponses, TodoTypeDeleteData, TodoTypeDeleteError, TodoTypeDeleteErrors, TodoTypeDeleteResponse, TodoTypeDeleteResponses, TodoTypeGetData, TodoTypeGetError, TodoTypeGetErrors, TodoTypeGetResponse, TodoTypeGetResponses, TodoTypeListData, TodoTypeListError, TodoTypeListErrors, TodoTypeListResponse, TodoTypeListResponses, TodoTypeRestoreData, TodoTypeRestoreError, TodoTypeRestoreErrors, TodoTypeRestoreResponse, TodoTypeRestoreResponses, TodoTypeUpdateData, TodoTypeUpdateError, TodoTypeUpdateErrors, TodoTypeUpdateResponse, TodoTypeUpdateResponses, TodoUpdateData, TodoUpdateError, TodoUpdateErrors, TodoUpdateResponse, TodoUpdateResponses, TodoWithRelations, UpdateApiKeyBody, UpdateApiKeyResponse, UpdateCommentBody, UpdateDriveLibraryBody, UpdateEventBody, UpdateOccurrenceBody, UpdateOrgInput, UpdateOrgMemberRole, UpdateProjectBody, UpdateRecurrenceRuleBody, UpdateTodoBody, UpdateTodoTypeBody, UpgradePreviewResult, UpgradeSubscriptionResult, UploadDriveFileResponse, VerifyCodeBody, VerifyCodeResponse, VersionBody } from './types.gen'; +export { accountDeletionCancel, accountDeletionGet, accountDeletionRequest, authMe, authRequestCode, authVerifyCode, billingCheckoutSessionsCreate, billingCustomDomainAddOnPreview, billingCustomDomainAddOnsChange, billingEmailUsageGet, billingEnforcementReadinessGet, billingEntitlementsGet, billingInboundProtectionGet, billingPaddleWebhookReceive, billingPortalSessionsCreate, billingPublicRolloutGet, billingStorageUsageGet, billingSubscriptionCancellationUpdate, billingSubscriptionDowngradePreview, billingSubscriptionDowngradesCreate, billingSubscriptionIntervalChangesCreate, billingSubscriptionIntervalPreviewsCreate, billingSubscriptionStateGet, billingSubscriptionUpgradePreviewsCreate, billingSubscriptionUpgradesCreate, calendarCreateSubscription, calendarDisableSubscription, calendarExport, calendarGetSubscription, calendarResetSubscription, driveExportCancel, driveExportCreate, driveExportDownload, driveExportGet, driveFileDelete, driveFileDownload, driveFileEdit, driveFileHistory, driveFileMove, driveFileRestore, driveFileRestoreDeleted, driveFileUpload, driveLibraryCreate, driveLibraryDelete, driveLibraryGet, driveLibraryList, driveLibraryUpdate, driveManifestGet, driveSearch, emailAliasCreate, emailAliasDelete, emailAliasList, emailAliasRestore, emailAttachmentGet, emailDelete, emailDomainCreate, emailDomainDelete, emailDomainGet, emailDomainList, emailDomainVerify, emailGet, emailList, emailMarkRead, emailMarkUnread, emailRestore, emailSend, emailSentDelete, emailSentGet, emailSentList, emailSentRestore, emailTrashEmpty, emailTrashSummary, eventAgenda, eventCreate, eventDelete, eventGet, eventIcsDownload, eventList, eventOccurrenceCancel, eventOccurrenceRestore, eventOccurrences, eventOccurrenceSet, eventRestore, eventUpdate, inviteAccept, inviteGet, inviteReject, invitesList, keyCreate, keyList, keyRevoke, keyUpdate, oauthAuthorizeGrant, oauthClientRegister, oauthDeviceAuthorize, oauthDeviceConfirm, oauthDeviceVerify, oauthMetadata, oauthMetadataOpenidAlias, oauthTokenExchange, oauthTokenRevoke, type Options, orgGet, orgInviteCreate, orgInviteRevoke, orgInvitesList, orgMemberRemove, orgMemberRoleUpdate, orgMembersList, orgUpdate, projectCreate, projectDelete, projectGet, projectList, projectRestore, projectUpdate, pushConfigDelete, pushConfigGet, pushConfigSet, pushTest, recurrenceRuleCreate, recurrenceRuleDelete, recurrenceRuleGet, recurrenceRuleList, recurrenceRuleUpdate, todoCommentCreate, todoCommentDelete, todoCommentList, todoCommentUpdate, todoCreate, todoDelete, todoExport, todoGet, todoList, todoRestore, todoTypeCreate, todoTypeDelete, todoTypeGet, todoTypeList, todoTypeRestore, todoTypeUpdate, todoUpdate } from './sdk.gen'; +export type { AccountDeletionCancelData, AccountDeletionCancelError, AccountDeletionCancelErrors, AccountDeletionCancelResponse, AccountDeletionCancelResponses, AccountDeletionGetData, AccountDeletionGetError, AccountDeletionGetErrors, AccountDeletionGetResponse, AccountDeletionGetResponses, AccountDeletionRequestData, AccountDeletionRequestError, AccountDeletionRequestErrors, AccountDeletionRequestResponse, AccountDeletionRequestResponses, Alias, ApplyDowngradeResult, ApplySubscriptionDowngradeInput, ApplySubscriptionIntervalInput, AuthMeData, AuthMeError, AuthMeErrors, AuthMeResponse, AuthMeResponses, AuthRequestCodeData, AuthRequestCodeError, AuthRequestCodeErrors, AuthRequestCodeResponse, AuthRequestCodeResponses, AuthVerifyCodeData, AuthVerifyCodeError, AuthVerifyCodeErrors, AuthVerifyCodeResponse, AuthVerifyCodeResponses, BatchIdsBody, BillingCheckoutSessionsCreateData, BillingCheckoutSessionsCreateError, BillingCheckoutSessionsCreateErrors, BillingCheckoutSessionsCreateResponse, BillingCheckoutSessionsCreateResponses, BillingCustomDomainAddOnPreviewData, BillingCustomDomainAddOnPreviewError, BillingCustomDomainAddOnPreviewErrors, BillingCustomDomainAddOnPreviewResponse, BillingCustomDomainAddOnPreviewResponses, BillingCustomDomainAddOnsChangeData, BillingCustomDomainAddOnsChangeError, BillingCustomDomainAddOnsChangeErrors, BillingCustomDomainAddOnsChangeResponse, BillingCustomDomainAddOnsChangeResponses, BillingEmailUsageGetData, BillingEmailUsageGetError, BillingEmailUsageGetErrors, BillingEmailUsageGetResponse, BillingEmailUsageGetResponses, BillingEnforcementReadinessGetData, BillingEnforcementReadinessGetError, BillingEnforcementReadinessGetErrors, BillingEnforcementReadinessGetResponse, BillingEnforcementReadinessGetResponses, BillingEntitlementsGetData, BillingEntitlementsGetError, BillingEntitlementsGetErrors, BillingEntitlementsGetResponse, BillingEntitlementsGetResponses, BillingInboundProtectionGetData, BillingInboundProtectionGetError, BillingInboundProtectionGetErrors, BillingInboundProtectionGetResponse, BillingInboundProtectionGetResponses, BillingPaddleWebhookReceiveData, BillingPaddleWebhookReceiveError, BillingPaddleWebhookReceiveErrors, BillingPaddleWebhookReceiveResponse, BillingPaddleWebhookReceiveResponses, BillingPortalSessionsCreateData, BillingPortalSessionsCreateError, BillingPortalSessionsCreateErrors, BillingPortalSessionsCreateResponse, BillingPortalSessionsCreateResponses, BillingPublicRolloutGetData, BillingPublicRolloutGetResponse, BillingPublicRolloutGetResponses, BillingStorageUsageGetData, BillingStorageUsageGetError, BillingStorageUsageGetErrors, BillingStorageUsageGetResponse, BillingStorageUsageGetResponses, BillingSubscriptionCancellationUpdateData, BillingSubscriptionCancellationUpdateError, BillingSubscriptionCancellationUpdateErrors, BillingSubscriptionCancellationUpdateResponse, BillingSubscriptionCancellationUpdateResponses, BillingSubscriptionDowngradePreviewData, BillingSubscriptionDowngradePreviewError, BillingSubscriptionDowngradePreviewErrors, BillingSubscriptionDowngradePreviewResponse, BillingSubscriptionDowngradePreviewResponses, BillingSubscriptionDowngradesCreateData, BillingSubscriptionDowngradesCreateError, BillingSubscriptionDowngradesCreateErrors, BillingSubscriptionDowngradesCreateResponse, BillingSubscriptionDowngradesCreateResponses, BillingSubscriptionIntervalChangesCreateData, BillingSubscriptionIntervalChangesCreateError, BillingSubscriptionIntervalChangesCreateErrors, BillingSubscriptionIntervalChangesCreateResponse, BillingSubscriptionIntervalChangesCreateResponses, BillingSubscriptionIntervalPreviewsCreateData, BillingSubscriptionIntervalPreviewsCreateError, BillingSubscriptionIntervalPreviewsCreateErrors, BillingSubscriptionIntervalPreviewsCreateResponse, BillingSubscriptionIntervalPreviewsCreateResponses, BillingSubscriptionStateGetData, BillingSubscriptionStateGetError, BillingSubscriptionStateGetErrors, BillingSubscriptionStateGetResponse, BillingSubscriptionStateGetResponses, BillingSubscriptionUpgradePreviewsCreateData, BillingSubscriptionUpgradePreviewsCreateError, BillingSubscriptionUpgradePreviewsCreateErrors, BillingSubscriptionUpgradePreviewsCreateResponse, BillingSubscriptionUpgradePreviewsCreateResponses, BillingSubscriptionUpgradesCreateData, BillingSubscriptionUpgradesCreateError, BillingSubscriptionUpgradesCreateErrors, BillingSubscriptionUpgradesCreateResponse, BillingSubscriptionUpgradesCreateResponses, CalendarCreateSubscriptionData, CalendarCreateSubscriptionError, CalendarCreateSubscriptionErrors, CalendarCreateSubscriptionResponse, CalendarCreateSubscriptionResponses, CalendarDisableSubscriptionData, CalendarDisableSubscriptionError, CalendarDisableSubscriptionErrors, CalendarDisableSubscriptionResponse, CalendarDisableSubscriptionResponses, CalendarExportData, CalendarExportError, CalendarExportErrors, CalendarExportResponse, CalendarExportResponses, CalendarGetSubscriptionData, CalendarGetSubscriptionError, CalendarGetSubscriptionErrors, CalendarGetSubscriptionResponse, CalendarGetSubscriptionResponses, CalendarResetSubscriptionData, CalendarResetSubscriptionError, CalendarResetSubscriptionErrors, CalendarResetSubscriptionResponse, CalendarResetSubscriptionResponses, CalendarSubscription, ChangeCustomDomainAddOnInput, CheckoutSessionResult, ClientOptions, Comment, CreateAliasBody, CreateApiKeyBody, CreateApiKeyResponse, CreateCommentBody, CreateDomainBody, CreateDriveLibraryBody, CreateEventBody, CreateOrgInviteInput, CreateProjectBody, CreateRecurrenceRuleBody, CreateRecurrenceRuleResponse, CreateTodoBody, CreateTodoTypeBody, CustomDomainAddOnPreviewResult, CustomDomainAddOnResult, CustomerPortalSessionInput, CustomerPortalSessionResult, DeleteBatchResponse, DeleteDriveFileBody, DeleteDriveFileResponse, DeleteDriveLibraryBody, DeleteEventResponse, DeleteRecurrenceRuleBody, DeleteRecurrenceRuleResponse, DeleteTodoBody, DeleteTodoResponse, DowngradePreviewResult, DriveExportCancelData, DriveExportCancelError, DriveExportCancelErrors, DriveExportCancelResponse, DriveExportCancelResponses, DriveExportCreateData, DriveExportCreateError, DriveExportCreateErrors, DriveExportCreateResponse, DriveExportCreateResponses, DriveExportDownloadData, DriveExportDownloadError, DriveExportDownloadErrors, DriveExportDownloadResponse, DriveExportDownloadResponses, DriveExportGetData, DriveExportGetError, DriveExportGetErrors, DriveExportGetResponse, DriveExportGetResponses, DriveFileDeleteData, DriveFileDeleteError, DriveFileDeleteErrors, DriveFileDeleteResponse, DriveFileDeleteResponses, DriveFileDownloadData, DriveFileDownloadError, DriveFileDownloadErrors, DriveFileDownloadResponse, DriveFileDownloadResponses, DriveFileEditData, DriveFileEditError, DriveFileEditErrors, DriveFileEditResponse, DriveFileEditResponses, DriveFileHistoryData, DriveFileHistoryError, DriveFileHistoryErrors, DriveFileHistoryResponse, DriveFileHistoryResponse2, DriveFileHistoryResponses, DriveFileMoveData, DriveFileMoveError, DriveFileMoveErrors, DriveFileMoveResponse, DriveFileMoveResponses, DriveFileRestoreData, DriveFileRestoreDeletedData, DriveFileRestoreDeletedError, DriveFileRestoreDeletedErrors, DriveFileRestoreDeletedResponse, DriveFileRestoreDeletedResponses, DriveFileRestoreError, DriveFileRestoreErrors, DriveFileRestoreResponse, DriveFileRestoreResponses, DriveFileUploadData, DriveFileUploadError, DriveFileUploadErrors, DriveFileUploadResponse, DriveFileUploadResponses, DriveLibrary, DriveLibraryCreateData, DriveLibraryCreateError, DriveLibraryCreateErrors, DriveLibraryCreateResponse, DriveLibraryCreateResponses, DriveLibraryDeleteData, DriveLibraryDeleteError, DriveLibraryDeleteErrors, DriveLibraryDeleteResponse, DriveLibraryDeleteResponses, DriveLibraryGetData, DriveLibraryGetError, DriveLibraryGetErrors, DriveLibraryGetResponse, DriveLibraryGetResponses, DriveLibraryListData, DriveLibraryListError, DriveLibraryListErrors, DriveLibraryListResponse, DriveLibraryListResponses, DriveLibraryUpdateData, DriveLibraryUpdateError, DriveLibraryUpdateErrors, DriveLibraryUpdateResponse, DriveLibraryUpdateResponses, DriveManifestGetData, DriveManifestGetError, DriveManifestGetErrors, DriveManifestGetResponse, DriveManifestGetResponses, DriveManifestResponse, DriveSearchData, DriveSearchError, DriveSearchErrors, DriveSearchResponse, DriveSearchResponse2, DriveSearchResponses, EditDriveFileBody, EffectiveEntitlements, EmailAliasCreateData, EmailAliasCreateError, EmailAliasCreateErrors, EmailAliasCreateResponse, EmailAliasCreateResponses, EmailAliasDeleteData, EmailAliasDeleteError, EmailAliasDeleteErrors, EmailAliasDeleteResponse, EmailAliasDeleteResponses, EmailAliasListData, EmailAliasListError, EmailAliasListErrors, EmailAliasListResponse, EmailAliasListResponses, EmailAliasRestoreData, EmailAliasRestoreError, EmailAliasRestoreErrors, EmailAliasRestoreResponse, EmailAliasRestoreResponses, EmailAttachmentGetData, EmailAttachmentGetError, EmailAttachmentGetErrors, EmailAttachmentGetResponse, EmailAttachmentGetResponses, EmailDeleteData, EmailDeleteError, EmailDeleteErrors, EmailDeleteResponse, EmailDeleteResponses, EmailDomainCreateData, EmailDomainCreateError, EmailDomainCreateErrors, EmailDomainCreateResponse, EmailDomainCreateResponses, EmailDomainDeleteData, EmailDomainDeleteError, EmailDomainDeleteErrors, EmailDomainDeleteResponse, EmailDomainDeleteResponses, EmailDomainGetData, EmailDomainGetError, EmailDomainGetErrors, EmailDomainGetResponse, EmailDomainGetResponses, EmailDomainListData, EmailDomainListError, EmailDomainListErrors, EmailDomainListResponse, EmailDomainListResponse2, EmailDomainListResponses, EmailDomainObjectResponse, EmailDomainVerifyData, EmailDomainVerifyError, EmailDomainVerifyErrors, EmailDomainVerifyResponse, EmailDomainVerifyResponses, EmailGetData, EmailGetError, EmailGetErrors, EmailGetResponse, EmailGetResponses, EmailListData, EmailListError, EmailListErrors, EmailListResponse, EmailListResponses, EmailMarkReadData, EmailMarkReadError, EmailMarkReadErrors, EmailMarkReadResponse, EmailMarkReadResponses, EmailMarkUnreadData, EmailMarkUnreadError, EmailMarkUnreadErrors, EmailMarkUnreadResponse, EmailMarkUnreadResponses, EmailRestoreData, EmailRestoreError, EmailRestoreErrors, EmailRestoreResponse, EmailRestoreResponses, EmailSendData, EmailSendError, EmailSendErrors, EmailSendResponse, EmailSendResponses, EmailSentDeleteData, EmailSentDeleteError, EmailSentDeleteErrors, EmailSentDeleteResponse, EmailSentDeleteResponses, EmailSentGetData, EmailSentGetError, EmailSentGetErrors, EmailSentGetResponse, EmailSentGetResponses, EmailSentListData, EmailSentListError, EmailSentListErrors, EmailSentListResponse, EmailSentListResponses, EmailSentRestoreData, EmailSentRestoreError, EmailSentRestoreErrors, EmailSentRestoreResponse, EmailSentRestoreResponses, EmailTrashEmptyData, EmailTrashEmptyError, EmailTrashEmptyErrors, EmailTrashEmptyResponse, EmailTrashEmptyResponses, EmailTrashSummaryData, EmailTrashSummaryError, EmailTrashSummaryErrors, EmailTrashSummaryResponse, EmailTrashSummaryResponses, EmailUsage, EnforcementReadiness, Event, EventAgendaData, EventAgendaError, EventAgendaErrors, EventAgendaResponse, EventAgendaResponses, EventCreateData, EventCreateError, EventCreateErrors, EventCreateResponse, EventCreateResponses, EventDeleteData, EventDeleteError, EventDeleteErrors, EventDeleteResponse, EventDeleteResponses, EventGetData, EventGetError, EventGetErrors, EventGetResponse, EventGetResponses, EventIcsDownloadData, EventIcsDownloadError, EventIcsDownloadErrors, EventIcsDownloadResponse, EventIcsDownloadResponses, EventListData, EventListError, EventListErrors, EventListResponse, EventListResponses, EventOccurrence, EventOccurrenceCancelData, EventOccurrenceCancelError, EventOccurrenceCancelErrors, EventOccurrenceCancelResponse, EventOccurrenceCancelResponses, EventOccurrenceRestoreData, EventOccurrenceRestoreError, EventOccurrenceRestoreErrors, EventOccurrenceRestoreResponse, EventOccurrenceRestoreResponses, EventOccurrencesData, EventOccurrencesError, EventOccurrencesErrors, EventOccurrenceSetData, EventOccurrenceSetError, EventOccurrenceSetErrors, EventOccurrenceSetResponse, EventOccurrenceSetResponses, EventOccurrencesResponse, EventOccurrencesResponses, EventRestoreData, EventRestoreError, EventRestoreErrors, EventRestoreResponse, EventRestoreResponses, EventUpdateData, EventUpdateError, EventUpdateErrors, EventUpdateResponse, EventUpdateResponses, GetMeResponse, InboundProtection, InviteAcceptData, InviteAcceptError, InviteAcceptErrors, InviteAcceptResponse, InviteAcceptResponses, InviteGetData, InviteGetError, InviteGetErrors, InviteGetResponse, InviteGetResponses, InviteRejectData, InviteRejectError, InviteRejectErrors, InviteRejectResponse, InviteRejectResponses, InvitesListData, InvitesListError, InvitesListErrors, InvitesListResponse, InvitesListResponses, KeyCreateData, KeyCreateError, KeyCreateErrors, KeyCreateResponse, KeyCreateResponses, KeyListData, KeyListError, KeyListErrors, KeyListResponse, KeyListResponses, KeyRevokeData, KeyRevokeError, KeyRevokeErrors, KeyRevokeResponse, KeyRevokeResponses, KeyUpdateData, KeyUpdateError, KeyUpdateErrors, KeyUpdateResponse, KeyUpdateResponses, ListAgendaResponse, ListApiKeysResponse, ListDriveLibrariesResponse, ListEventOccurrencesResponse, ListEventsResponse, ListMyInvitesResponse, ListOrgInvitesResponse, ListOrgMembersResponse, ListRecurrenceRulesResponse, ListTodosResponse, MarkBatchResponse, MoveDriveFileBody, MoveDriveFileResponse, OauthAuthorizeGrantData, OauthAuthorizeGrantError, OauthAuthorizeGrantErrors, OauthAuthorizeGrantResponse, OauthAuthorizeGrantResponses, OAuthAuthServerMetadata, OauthClientRegisterData, OauthClientRegisterError, OauthClientRegisterErrors, OauthClientRegisterResponse, OauthClientRegisterResponses, OauthDeviceAuthorizeData, OauthDeviceAuthorizeError, OauthDeviceAuthorizeErrors, OauthDeviceAuthorizeResponse, OauthDeviceAuthorizeResponses, OAuthDeviceBody, OauthDeviceConfirmData, OauthDeviceConfirmError, OauthDeviceConfirmErrors, OauthDeviceConfirmResponse, OauthDeviceConfirmResponses, OAuthDeviceResponse, OauthDeviceVerifyData, OauthDeviceVerifyError, OauthDeviceVerifyErrors, OauthDeviceVerifyResponse, OauthDeviceVerifyResponses, OauthMetadataData, OauthMetadataError, OauthMetadataErrors, OauthMetadataOpenidAliasData, OauthMetadataOpenidAliasError, OauthMetadataOpenidAliasErrors, OauthMetadataOpenidAliasResponse, OauthMetadataOpenidAliasResponses, OauthMetadataResponse, OauthMetadataResponses, OAuthRegisterBody, OAuthRegisterResponse, OAuthRevokeBody, OAuthTokenBody, OauthTokenExchangeData, OauthTokenExchangeError, OauthTokenExchangeErrors, OauthTokenExchangeResponse, OauthTokenExchangeResponses, OAuthTokenResponse, OauthTokenRevokeData, OauthTokenRevokeError, OauthTokenRevokeErrors, OauthTokenRevokeResponse, OauthTokenRevokeResponses, OccurrenceVersionBody, Org, OrgGetData, OrgGetError, OrgGetErrors, OrgGetResponse, OrgGetResponses, OrgInviteCreateData, OrgInviteCreateError, OrgInviteCreateErrors, OrgInviteCreateResponse, OrgInviteCreateResponses, OrgInviteRevokeData, OrgInviteRevokeError, OrgInviteRevokeErrors, OrgInviteRevokeResponse, OrgInviteRevokeResponses, OrgInvitesListData, OrgInvitesListError, OrgInvitesListErrors, OrgInvitesListResponse, OrgInvitesListResponses, OrgInviteSummary, OrgInviteView, OrgMember, OrgMemberRemoveData, OrgMemberRemoveError, OrgMemberRemoveErrors, OrgMemberRemoveResponse, OrgMemberRemoveResponses, OrgMemberRoleUpdateData, OrgMemberRoleUpdateError, OrgMemberRoleUpdateErrors, OrgMemberRoleUpdateResponse, OrgMemberRoleUpdateResponses, OrgMembersListData, OrgMembersListError, OrgMembersListErrors, OrgMembersListResponse, OrgMembersListResponses, OrgUpdateData, OrgUpdateError, OrgUpdateErrors, OrgUpdateResponse, OrgUpdateResponses, PaddleWebhookResult, PreviewCustomDomainAddOnInput, PreviewSubscriptionDowngradeInput, PreviewSubscriptionIntervalInput, PreviewSubscriptionUpgradeInput, Project, ProjectCreateData, ProjectCreateError, ProjectCreateErrors, ProjectCreateResponse, ProjectCreateResponses, ProjectDeleteData, ProjectDeleteError, ProjectDeleteErrors, ProjectDeleteResponse, ProjectDeleteResponses, ProjectGetData, ProjectGetError, ProjectGetErrors, ProjectGetResponse, ProjectGetResponses, ProjectListData, ProjectListError, ProjectListErrors, ProjectListResponse, ProjectListResponses, ProjectRestoreData, ProjectRestoreError, ProjectRestoreErrors, ProjectRestoreResponse, ProjectRestoreResponses, ProjectUpdateData, ProjectUpdateError, ProjectUpdateErrors, ProjectUpdateResponse, ProjectUpdateResponses, PushConfigDeleteData, PushConfigDeleteError, PushConfigDeleteErrors, PushConfigDeleteResponse, PushConfigDeleteResponses, PushConfigGetData, PushConfigGetError, PushConfigGetErrors, PushConfigGetResponse, PushConfigGetResponses, PushConfigSetData, PushConfigSetError, PushConfigSetErrors, PushConfigSetResponse, PushConfigSetResponses, PushTestData, PushTestError, PushTestErrors, PushTestResponse, PushTestResponses, ReceivedEmailDetail, RecurrenceRule, RecurrenceRuleCreateData, RecurrenceRuleCreateError, RecurrenceRuleCreateErrors, RecurrenceRuleCreateResponse, RecurrenceRuleCreateResponses, RecurrenceRuleDeleteData, RecurrenceRuleDeleteError, RecurrenceRuleDeleteErrors, RecurrenceRuleDeleteResponse, RecurrenceRuleDeleteResponses, RecurrenceRuleDetail, RecurrenceRuleGetData, RecurrenceRuleGetError, RecurrenceRuleGetErrors, RecurrenceRuleGetResponse, RecurrenceRuleGetResponses, RecurrenceRuleListData, RecurrenceRuleListError, RecurrenceRuleListErrors, RecurrenceRuleListResponse, RecurrenceRuleListResponses, RecurrenceRuleUpdateData, RecurrenceRuleUpdateError, RecurrenceRuleUpdateErrors, RecurrenceRuleUpdateResponse, RecurrenceRuleUpdateResponses, RequestCodeBody, RequestCodeResponse, RestoreBatchResponse, RestoreDriveFileBody, RestoreDriveFileResponse, RestoreTodoBody, RestoreTodoResponse, RevokeApiKeyResponse, SendEmailBody, SendEmailResponse, SentEmailDetail, SetPushConfigBody, ShowPushConfigResponse, StartInitialCheckoutInput, StartSubscriptionUpgradeInput, StorageUsage, SubscriptionCancellationResult, SubscriptionState, TestPushBody, TestPushResponse, Todo, TodoCommentCreateData, TodoCommentCreateError, TodoCommentCreateErrors, TodoCommentCreateResponse, TodoCommentCreateResponses, TodoCommentDeleteData, TodoCommentDeleteError, TodoCommentDeleteErrors, TodoCommentDeleteResponse, TodoCommentDeleteResponses, TodoCommentListData, TodoCommentListError, TodoCommentListErrors, TodoCommentListResponse, TodoCommentListResponses, TodoCommentUpdateData, TodoCommentUpdateError, TodoCommentUpdateErrors, TodoCommentUpdateResponse, TodoCommentUpdateResponses, TodoCreateData, TodoCreateError, TodoCreateErrors, TodoCreateResponse, TodoCreateResponses, TodoDeleteData, TodoDeleteError, TodoDeleteErrors, TodoDeleteResponse, TodoDeleteResponses, TodoExportData, TodoExportDocument, TodoExportError, TodoExportErrors, TodoExportResponse, TodoExportResponses, TodoGetData, TodoGetError, TodoGetErrors, TodoGetResponse, TodoGetResponses, TodoListData, TodoListError, TodoListErrors, TodoListResponse, TodoListResponses, TodoRestoreData, TodoRestoreError, TodoRestoreErrors, TodoRestoreResponse, TodoRestoreResponses, TodoType, TodoTypeCreateData, TodoTypeCreateError, TodoTypeCreateErrors, TodoTypeCreateResponse, TodoTypeCreateResponses, TodoTypeDeleteData, TodoTypeDeleteError, TodoTypeDeleteErrors, TodoTypeDeleteResponse, TodoTypeDeleteResponses, TodoTypeGetData, TodoTypeGetError, TodoTypeGetErrors, TodoTypeGetResponse, TodoTypeGetResponses, TodoTypeListData, TodoTypeListError, TodoTypeListErrors, TodoTypeListResponse, TodoTypeListResponses, TodoTypeRestoreData, TodoTypeRestoreError, TodoTypeRestoreErrors, TodoTypeRestoreResponse, TodoTypeRestoreResponses, TodoTypeUpdateData, TodoTypeUpdateError, TodoTypeUpdateErrors, TodoTypeUpdateResponse, TodoTypeUpdateResponses, TodoUpdateData, TodoUpdateError, TodoUpdateErrors, TodoUpdateResponse, TodoUpdateResponses, TodoWithRelations, UpdateApiKeyBody, UpdateApiKeyResponse, UpdateCommentBody, UpdateDriveLibraryBody, UpdateEventBody, UpdateOccurrenceBody, UpdateOrgInput, UpdateOrgMemberRole, UpdateProjectBody, UpdateRecurrenceRuleBody, UpdateTodoBody, UpdateTodoTypeBody, UpgradePreviewResult, UpgradeSubscriptionResult, UploadDriveFileResponse, VerifyCodeBody, VerifyCodeResponse, VersionBody } from './types.gen'; diff --git a/src/generated/sdk/sdk.gen.ts b/src/generated/sdk/sdk.gen.ts index 5440237..ba19e4c 100644 --- a/src/generated/sdk/sdk.gen.ts +++ b/src/generated/sdk/sdk.gen.ts @@ -2,7 +2,7 @@ import type { Client, Options as Options2, TDataShape } from './client'; import { client } from './client.gen'; -import type { AccountDeletionCancelData, AccountDeletionCancelErrors, AccountDeletionCancelResponses, AccountDeletionGetData, AccountDeletionGetErrors, AccountDeletionGetResponses, AccountDeletionRequestData, AccountDeletionRequestErrors, AccountDeletionRequestResponses, AuthMeData, AuthMeErrors, AuthMeResponses, AuthRequestCodeData, AuthRequestCodeErrors, AuthRequestCodeResponses, AuthVerifyCodeData, AuthVerifyCodeErrors, AuthVerifyCodeResponses, BillingCheckoutSessionsCreateData, BillingCheckoutSessionsCreateErrors, BillingCheckoutSessionsCreateResponses, BillingCustomDomainAddOnPreviewData, BillingCustomDomainAddOnPreviewErrors, BillingCustomDomainAddOnPreviewResponses, BillingCustomDomainAddOnsChangeData, BillingCustomDomainAddOnsChangeErrors, BillingCustomDomainAddOnsChangeResponses, BillingEmailUsageGetData, BillingEmailUsageGetErrors, BillingEmailUsageGetResponses, BillingEnforcementReadinessGetData, BillingEnforcementReadinessGetErrors, BillingEnforcementReadinessGetResponses, BillingEntitlementsGetData, BillingEntitlementsGetErrors, BillingEntitlementsGetResponses, BillingInboundProtectionGetData, BillingInboundProtectionGetErrors, BillingInboundProtectionGetResponses, BillingPaddleWebhookReceiveData, BillingPaddleWebhookReceiveErrors, BillingPaddleWebhookReceiveResponses, BillingPortalSessionsCreateData, BillingPortalSessionsCreateErrors, BillingPortalSessionsCreateResponses, BillingPublicRolloutGetData, BillingPublicRolloutGetResponses, BillingStorageUsageGetData, BillingStorageUsageGetErrors, BillingStorageUsageGetResponses, BillingSubscriptionCancellationUpdateData, BillingSubscriptionCancellationUpdateErrors, BillingSubscriptionCancellationUpdateResponses, BillingSubscriptionDowngradePreviewData, BillingSubscriptionDowngradePreviewErrors, BillingSubscriptionDowngradePreviewResponses, BillingSubscriptionDowngradesCreateData, BillingSubscriptionDowngradesCreateErrors, BillingSubscriptionDowngradesCreateResponses, BillingSubscriptionIntervalChangesCreateData, BillingSubscriptionIntervalChangesCreateErrors, BillingSubscriptionIntervalChangesCreateResponses, BillingSubscriptionIntervalPreviewsCreateData, BillingSubscriptionIntervalPreviewsCreateErrors, BillingSubscriptionIntervalPreviewsCreateResponses, BillingSubscriptionStateGetData, BillingSubscriptionStateGetErrors, BillingSubscriptionStateGetResponses, BillingSubscriptionUpgradePreviewsCreateData, BillingSubscriptionUpgradePreviewsCreateErrors, BillingSubscriptionUpgradePreviewsCreateResponses, BillingSubscriptionUpgradesCreateData, BillingSubscriptionUpgradesCreateErrors, BillingSubscriptionUpgradesCreateResponses, CalendarExportData, CalendarExportErrors, CalendarExportResponses, DriveExportCancelData, DriveExportCancelErrors, DriveExportCancelResponses, DriveExportCreateData, DriveExportCreateErrors, DriveExportCreateResponses, DriveExportDownloadData, DriveExportDownloadErrors, DriveExportDownloadResponses, DriveExportGetData, DriveExportGetErrors, DriveExportGetResponses, DriveFileDeleteData, DriveFileDeleteErrors, DriveFileDeleteResponses, DriveFileDownloadData, DriveFileDownloadErrors, DriveFileDownloadResponses, DriveFileEditData, DriveFileEditErrors, DriveFileEditResponses, DriveFileHistoryData, DriveFileHistoryErrors, DriveFileHistoryResponses, DriveFileMoveData, DriveFileMoveErrors, DriveFileMoveResponses, DriveFileRestoreData, DriveFileRestoreDeletedData, DriveFileRestoreDeletedErrors, DriveFileRestoreDeletedResponses, DriveFileRestoreErrors, DriveFileRestoreResponses, DriveFileUploadData, DriveFileUploadErrors, DriveFileUploadResponses, DriveLibraryCreateData, DriveLibraryCreateErrors, DriveLibraryCreateResponses, DriveLibraryDeleteData, DriveLibraryDeleteErrors, DriveLibraryDeleteResponses, DriveLibraryGetData, DriveLibraryGetErrors, DriveLibraryGetResponses, DriveLibraryListData, DriveLibraryListErrors, DriveLibraryListResponses, DriveLibraryUpdateData, DriveLibraryUpdateErrors, DriveLibraryUpdateResponses, DriveManifestGetData, DriveManifestGetErrors, DriveManifestGetResponses, DriveSearchData, DriveSearchErrors, DriveSearchResponses, EmailAliasCreateData, EmailAliasCreateErrors, EmailAliasCreateResponses, EmailAliasDeleteData, EmailAliasDeleteErrors, EmailAliasDeleteResponses, EmailAliasListData, EmailAliasListErrors, EmailAliasListResponses, EmailAliasRestoreData, EmailAliasRestoreErrors, EmailAliasRestoreResponses, EmailAttachmentGetData, EmailAttachmentGetErrors, EmailAttachmentGetResponses, EmailDeleteData, EmailDeleteErrors, EmailDeleteResponses, EmailDomainCreateData, EmailDomainCreateErrors, EmailDomainCreateResponses, EmailDomainDeleteData, EmailDomainDeleteErrors, EmailDomainDeleteResponses, EmailDomainGetData, EmailDomainGetErrors, EmailDomainGetResponses, EmailDomainListData, EmailDomainListErrors, EmailDomainListResponses, EmailDomainVerifyData, EmailDomainVerifyErrors, EmailDomainVerifyResponses, EmailGetData, EmailGetErrors, EmailGetResponses, EmailListData, EmailListErrors, EmailListResponses, EmailMarkReadData, EmailMarkReadErrors, EmailMarkReadResponses, EmailMarkUnreadData, EmailMarkUnreadErrors, EmailMarkUnreadResponses, EmailRestoreData, EmailRestoreErrors, EmailRestoreResponses, EmailSendData, EmailSendErrors, EmailSendResponses, EmailSentDeleteData, EmailSentDeleteErrors, EmailSentDeleteResponses, EmailSentGetData, EmailSentGetErrors, EmailSentGetResponses, EmailSentListData, EmailSentListErrors, EmailSentListResponses, EmailSentRestoreData, EmailSentRestoreErrors, EmailSentRestoreResponses, EmailTrashEmptyData, EmailTrashEmptyErrors, EmailTrashEmptyResponses, EmailTrashSummaryData, EmailTrashSummaryErrors, EmailTrashSummaryResponses, EventAgendaData, EventAgendaErrors, EventAgendaResponses, EventCreateData, EventCreateErrors, EventCreateResponses, EventDeleteData, EventDeleteErrors, EventDeleteResponses, EventGetData, EventGetErrors, EventGetResponses, EventIcsDownloadData, EventIcsDownloadErrors, EventIcsDownloadResponses, EventListData, EventListErrors, EventListResponses, EventOccurrenceCancelData, EventOccurrenceCancelErrors, EventOccurrenceCancelResponses, EventOccurrenceRestoreData, EventOccurrenceRestoreErrors, EventOccurrenceRestoreResponses, EventOccurrencesData, EventOccurrencesErrors, EventOccurrenceSetData, EventOccurrenceSetErrors, EventOccurrenceSetResponses, EventOccurrencesResponses, EventRestoreData, EventRestoreErrors, EventRestoreResponses, EventUpdateData, EventUpdateErrors, EventUpdateResponses, InviteAcceptData, InviteAcceptErrors, InviteAcceptResponses, InviteGetData, InviteGetErrors, InviteGetResponses, InviteRejectData, InviteRejectErrors, InviteRejectResponses, InvitesListData, InvitesListErrors, InvitesListResponses, KeyCreateData, KeyCreateErrors, KeyCreateResponses, KeyListData, KeyListErrors, KeyListResponses, KeyRevokeData, KeyRevokeErrors, KeyRevokeResponses, KeyUpdateData, KeyUpdateErrors, KeyUpdateResponses, OauthAuthorizeGrantData, OauthAuthorizeGrantErrors, OauthAuthorizeGrantResponses, OauthClientRegisterData, OauthClientRegisterErrors, OauthClientRegisterResponses, OauthDeviceAuthorizeData, OauthDeviceAuthorizeErrors, OauthDeviceAuthorizeResponses, OauthDeviceConfirmData, OauthDeviceConfirmErrors, OauthDeviceConfirmResponses, OauthDeviceVerifyData, OauthDeviceVerifyErrors, OauthDeviceVerifyResponses, OauthMetadataData, OauthMetadataErrors, OauthMetadataOpenidAliasData, OauthMetadataOpenidAliasErrors, OauthMetadataOpenidAliasResponses, OauthMetadataResponses, OauthTokenExchangeData, OauthTokenExchangeErrors, OauthTokenExchangeResponses, OauthTokenRevokeData, OauthTokenRevokeErrors, OauthTokenRevokeResponses, OrgGetData, OrgGetErrors, OrgGetResponses, OrgInviteCreateData, OrgInviteCreateErrors, OrgInviteCreateResponses, OrgInviteRevokeData, OrgInviteRevokeErrors, OrgInviteRevokeResponses, OrgInvitesListData, OrgInvitesListErrors, OrgInvitesListResponses, OrgMemberRemoveData, OrgMemberRemoveErrors, OrgMemberRemoveResponses, OrgMemberRoleUpdateData, OrgMemberRoleUpdateErrors, OrgMemberRoleUpdateResponses, OrgMembersListData, OrgMembersListErrors, OrgMembersListResponses, OrgUpdateData, OrgUpdateErrors, OrgUpdateResponses, ProjectCreateData, ProjectCreateErrors, ProjectCreateResponses, ProjectDeleteData, ProjectDeleteErrors, ProjectDeleteResponses, ProjectGetData, ProjectGetErrors, ProjectGetResponses, ProjectListData, ProjectListErrors, ProjectListResponses, ProjectRestoreData, ProjectRestoreErrors, ProjectRestoreResponses, ProjectUpdateData, ProjectUpdateErrors, ProjectUpdateResponses, PushConfigDeleteData, PushConfigDeleteErrors, PushConfigDeleteResponses, PushConfigGetData, PushConfigGetErrors, PushConfigGetResponses, PushConfigSetData, PushConfigSetErrors, PushConfigSetResponses, PushTestData, PushTestErrors, PushTestResponses, RecurrenceRuleCreateData, RecurrenceRuleCreateErrors, RecurrenceRuleCreateResponses, RecurrenceRuleDeleteData, RecurrenceRuleDeleteErrors, RecurrenceRuleDeleteResponses, RecurrenceRuleGetData, RecurrenceRuleGetErrors, RecurrenceRuleGetResponses, RecurrenceRuleListData, RecurrenceRuleListErrors, RecurrenceRuleListResponses, RecurrenceRuleUpdateData, RecurrenceRuleUpdateErrors, RecurrenceRuleUpdateResponses, TodoCommentCreateData, TodoCommentCreateErrors, TodoCommentCreateResponses, TodoCommentDeleteData, TodoCommentDeleteErrors, TodoCommentDeleteResponses, TodoCommentListData, TodoCommentListErrors, TodoCommentListResponses, TodoCommentUpdateData, TodoCommentUpdateErrors, TodoCommentUpdateResponses, TodoCreateData, TodoCreateErrors, TodoCreateResponses, TodoDeleteData, TodoDeleteErrors, TodoDeleteResponses, TodoExportData, TodoExportErrors, TodoExportResponses, TodoGetData, TodoGetErrors, TodoGetResponses, TodoListData, TodoListErrors, TodoListResponses, TodoRestoreData, TodoRestoreErrors, TodoRestoreResponses, TodoTypeCreateData, TodoTypeCreateErrors, TodoTypeCreateResponses, TodoTypeDeleteData, TodoTypeDeleteErrors, TodoTypeDeleteResponses, TodoTypeGetData, TodoTypeGetErrors, TodoTypeGetResponses, TodoTypeListData, TodoTypeListErrors, TodoTypeListResponses, TodoTypeRestoreData, TodoTypeRestoreErrors, TodoTypeRestoreResponses, TodoTypeUpdateData, TodoTypeUpdateErrors, TodoTypeUpdateResponses, TodoUpdateData, TodoUpdateErrors, TodoUpdateResponses } from './types.gen'; +import type { AccountDeletionCancelData, AccountDeletionCancelErrors, AccountDeletionCancelResponses, AccountDeletionGetData, AccountDeletionGetErrors, AccountDeletionGetResponses, AccountDeletionRequestData, AccountDeletionRequestErrors, AccountDeletionRequestResponses, AuthMeData, AuthMeErrors, AuthMeResponses, AuthRequestCodeData, AuthRequestCodeErrors, AuthRequestCodeResponses, AuthVerifyCodeData, AuthVerifyCodeErrors, AuthVerifyCodeResponses, BillingCheckoutSessionsCreateData, BillingCheckoutSessionsCreateErrors, BillingCheckoutSessionsCreateResponses, BillingCustomDomainAddOnPreviewData, BillingCustomDomainAddOnPreviewErrors, BillingCustomDomainAddOnPreviewResponses, BillingCustomDomainAddOnsChangeData, BillingCustomDomainAddOnsChangeErrors, BillingCustomDomainAddOnsChangeResponses, BillingEmailUsageGetData, BillingEmailUsageGetErrors, BillingEmailUsageGetResponses, BillingEnforcementReadinessGetData, BillingEnforcementReadinessGetErrors, BillingEnforcementReadinessGetResponses, BillingEntitlementsGetData, BillingEntitlementsGetErrors, BillingEntitlementsGetResponses, BillingInboundProtectionGetData, BillingInboundProtectionGetErrors, BillingInboundProtectionGetResponses, BillingPaddleWebhookReceiveData, BillingPaddleWebhookReceiveErrors, BillingPaddleWebhookReceiveResponses, BillingPortalSessionsCreateData, BillingPortalSessionsCreateErrors, BillingPortalSessionsCreateResponses, BillingPublicRolloutGetData, BillingPublicRolloutGetResponses, BillingStorageUsageGetData, BillingStorageUsageGetErrors, BillingStorageUsageGetResponses, BillingSubscriptionCancellationUpdateData, BillingSubscriptionCancellationUpdateErrors, BillingSubscriptionCancellationUpdateResponses, BillingSubscriptionDowngradePreviewData, BillingSubscriptionDowngradePreviewErrors, BillingSubscriptionDowngradePreviewResponses, BillingSubscriptionDowngradesCreateData, BillingSubscriptionDowngradesCreateErrors, BillingSubscriptionDowngradesCreateResponses, BillingSubscriptionIntervalChangesCreateData, BillingSubscriptionIntervalChangesCreateErrors, BillingSubscriptionIntervalChangesCreateResponses, BillingSubscriptionIntervalPreviewsCreateData, BillingSubscriptionIntervalPreviewsCreateErrors, BillingSubscriptionIntervalPreviewsCreateResponses, BillingSubscriptionStateGetData, BillingSubscriptionStateGetErrors, BillingSubscriptionStateGetResponses, BillingSubscriptionUpgradePreviewsCreateData, BillingSubscriptionUpgradePreviewsCreateErrors, BillingSubscriptionUpgradePreviewsCreateResponses, BillingSubscriptionUpgradesCreateData, BillingSubscriptionUpgradesCreateErrors, BillingSubscriptionUpgradesCreateResponses, CalendarCreateSubscriptionData, CalendarCreateSubscriptionErrors, CalendarCreateSubscriptionResponses, CalendarDisableSubscriptionData, CalendarDisableSubscriptionErrors, CalendarDisableSubscriptionResponses, CalendarExportData, CalendarExportErrors, CalendarExportResponses, CalendarGetSubscriptionData, CalendarGetSubscriptionErrors, CalendarGetSubscriptionResponses, CalendarResetSubscriptionData, CalendarResetSubscriptionErrors, CalendarResetSubscriptionResponses, DriveExportCancelData, DriveExportCancelErrors, DriveExportCancelResponses, DriveExportCreateData, DriveExportCreateErrors, DriveExportCreateResponses, DriveExportDownloadData, DriveExportDownloadErrors, DriveExportDownloadResponses, DriveExportGetData, DriveExportGetErrors, DriveExportGetResponses, DriveFileDeleteData, DriveFileDeleteErrors, DriveFileDeleteResponses, DriveFileDownloadData, DriveFileDownloadErrors, DriveFileDownloadResponses, DriveFileEditData, DriveFileEditErrors, DriveFileEditResponses, DriveFileHistoryData, DriveFileHistoryErrors, DriveFileHistoryResponses, DriveFileMoveData, DriveFileMoveErrors, DriveFileMoveResponses, DriveFileRestoreData, DriveFileRestoreDeletedData, DriveFileRestoreDeletedErrors, DriveFileRestoreDeletedResponses, DriveFileRestoreErrors, DriveFileRestoreResponses, DriveFileUploadData, DriveFileUploadErrors, DriveFileUploadResponses, DriveLibraryCreateData, DriveLibraryCreateErrors, DriveLibraryCreateResponses, DriveLibraryDeleteData, DriveLibraryDeleteErrors, DriveLibraryDeleteResponses, DriveLibraryGetData, DriveLibraryGetErrors, DriveLibraryGetResponses, DriveLibraryListData, DriveLibraryListErrors, DriveLibraryListResponses, DriveLibraryUpdateData, DriveLibraryUpdateErrors, DriveLibraryUpdateResponses, DriveManifestGetData, DriveManifestGetErrors, DriveManifestGetResponses, DriveSearchData, DriveSearchErrors, DriveSearchResponses, EmailAliasCreateData, EmailAliasCreateErrors, EmailAliasCreateResponses, EmailAliasDeleteData, EmailAliasDeleteErrors, EmailAliasDeleteResponses, EmailAliasListData, EmailAliasListErrors, EmailAliasListResponses, EmailAliasRestoreData, EmailAliasRestoreErrors, EmailAliasRestoreResponses, EmailAttachmentGetData, EmailAttachmentGetErrors, EmailAttachmentGetResponses, EmailDeleteData, EmailDeleteErrors, EmailDeleteResponses, EmailDomainCreateData, EmailDomainCreateErrors, EmailDomainCreateResponses, EmailDomainDeleteData, EmailDomainDeleteErrors, EmailDomainDeleteResponses, EmailDomainGetData, EmailDomainGetErrors, EmailDomainGetResponses, EmailDomainListData, EmailDomainListErrors, EmailDomainListResponses, EmailDomainVerifyData, EmailDomainVerifyErrors, EmailDomainVerifyResponses, EmailGetData, EmailGetErrors, EmailGetResponses, EmailListData, EmailListErrors, EmailListResponses, EmailMarkReadData, EmailMarkReadErrors, EmailMarkReadResponses, EmailMarkUnreadData, EmailMarkUnreadErrors, EmailMarkUnreadResponses, EmailRestoreData, EmailRestoreErrors, EmailRestoreResponses, EmailSendData, EmailSendErrors, EmailSendResponses, EmailSentDeleteData, EmailSentDeleteErrors, EmailSentDeleteResponses, EmailSentGetData, EmailSentGetErrors, EmailSentGetResponses, EmailSentListData, EmailSentListErrors, EmailSentListResponses, EmailSentRestoreData, EmailSentRestoreErrors, EmailSentRestoreResponses, EmailTrashEmptyData, EmailTrashEmptyErrors, EmailTrashEmptyResponses, EmailTrashSummaryData, EmailTrashSummaryErrors, EmailTrashSummaryResponses, EventAgendaData, EventAgendaErrors, EventAgendaResponses, EventCreateData, EventCreateErrors, EventCreateResponses, EventDeleteData, EventDeleteErrors, EventDeleteResponses, EventGetData, EventGetErrors, EventGetResponses, EventIcsDownloadData, EventIcsDownloadErrors, EventIcsDownloadResponses, EventListData, EventListErrors, EventListResponses, EventOccurrenceCancelData, EventOccurrenceCancelErrors, EventOccurrenceCancelResponses, EventOccurrenceRestoreData, EventOccurrenceRestoreErrors, EventOccurrenceRestoreResponses, EventOccurrencesData, EventOccurrencesErrors, EventOccurrenceSetData, EventOccurrenceSetErrors, EventOccurrenceSetResponses, EventOccurrencesResponses, EventRestoreData, EventRestoreErrors, EventRestoreResponses, EventUpdateData, EventUpdateErrors, EventUpdateResponses, InviteAcceptData, InviteAcceptErrors, InviteAcceptResponses, InviteGetData, InviteGetErrors, InviteGetResponses, InviteRejectData, InviteRejectErrors, InviteRejectResponses, InvitesListData, InvitesListErrors, InvitesListResponses, KeyCreateData, KeyCreateErrors, KeyCreateResponses, KeyListData, KeyListErrors, KeyListResponses, KeyRevokeData, KeyRevokeErrors, KeyRevokeResponses, KeyUpdateData, KeyUpdateErrors, KeyUpdateResponses, OauthAuthorizeGrantData, OauthAuthorizeGrantErrors, OauthAuthorizeGrantResponses, OauthClientRegisterData, OauthClientRegisterErrors, OauthClientRegisterResponses, OauthDeviceAuthorizeData, OauthDeviceAuthorizeErrors, OauthDeviceAuthorizeResponses, OauthDeviceConfirmData, OauthDeviceConfirmErrors, OauthDeviceConfirmResponses, OauthDeviceVerifyData, OauthDeviceVerifyErrors, OauthDeviceVerifyResponses, OauthMetadataData, OauthMetadataErrors, OauthMetadataOpenidAliasData, OauthMetadataOpenidAliasErrors, OauthMetadataOpenidAliasResponses, OauthMetadataResponses, OauthTokenExchangeData, OauthTokenExchangeErrors, OauthTokenExchangeResponses, OauthTokenRevokeData, OauthTokenRevokeErrors, OauthTokenRevokeResponses, OrgGetData, OrgGetErrors, OrgGetResponses, OrgInviteCreateData, OrgInviteCreateErrors, OrgInviteCreateResponses, OrgInviteRevokeData, OrgInviteRevokeErrors, OrgInviteRevokeResponses, OrgInvitesListData, OrgInvitesListErrors, OrgInvitesListResponses, OrgMemberRemoveData, OrgMemberRemoveErrors, OrgMemberRemoveResponses, OrgMemberRoleUpdateData, OrgMemberRoleUpdateErrors, OrgMemberRoleUpdateResponses, OrgMembersListData, OrgMembersListErrors, OrgMembersListResponses, OrgUpdateData, OrgUpdateErrors, OrgUpdateResponses, ProjectCreateData, ProjectCreateErrors, ProjectCreateResponses, ProjectDeleteData, ProjectDeleteErrors, ProjectDeleteResponses, ProjectGetData, ProjectGetErrors, ProjectGetResponses, ProjectListData, ProjectListErrors, ProjectListResponses, ProjectRestoreData, ProjectRestoreErrors, ProjectRestoreResponses, ProjectUpdateData, ProjectUpdateErrors, ProjectUpdateResponses, PushConfigDeleteData, PushConfigDeleteErrors, PushConfigDeleteResponses, PushConfigGetData, PushConfigGetErrors, PushConfigGetResponses, PushConfigSetData, PushConfigSetErrors, PushConfigSetResponses, PushTestData, PushTestErrors, PushTestResponses, RecurrenceRuleCreateData, RecurrenceRuleCreateErrors, RecurrenceRuleCreateResponses, RecurrenceRuleDeleteData, RecurrenceRuleDeleteErrors, RecurrenceRuleDeleteResponses, RecurrenceRuleGetData, RecurrenceRuleGetErrors, RecurrenceRuleGetResponses, RecurrenceRuleListData, RecurrenceRuleListErrors, RecurrenceRuleListResponses, RecurrenceRuleUpdateData, RecurrenceRuleUpdateErrors, RecurrenceRuleUpdateResponses, TodoCommentCreateData, TodoCommentCreateErrors, TodoCommentCreateResponses, TodoCommentDeleteData, TodoCommentDeleteErrors, TodoCommentDeleteResponses, TodoCommentListData, TodoCommentListErrors, TodoCommentListResponses, TodoCommentUpdateData, TodoCommentUpdateErrors, TodoCommentUpdateResponses, TodoCreateData, TodoCreateErrors, TodoCreateResponses, TodoDeleteData, TodoDeleteErrors, TodoDeleteResponses, TodoExportData, TodoExportErrors, TodoExportResponses, TodoGetData, TodoGetErrors, TodoGetResponses, TodoListData, TodoListErrors, TodoListResponses, TodoRestoreData, TodoRestoreErrors, TodoRestoreResponses, TodoTypeCreateData, TodoTypeCreateErrors, TodoTypeCreateResponses, TodoTypeDeleteData, TodoTypeDeleteErrors, TodoTypeDeleteResponses, TodoTypeGetData, TodoTypeGetErrors, TodoTypeGetResponses, TodoTypeListData, TodoTypeListErrors, TodoTypeListResponses, TodoTypeRestoreData, TodoTypeRestoreErrors, TodoTypeRestoreResponses, TodoTypeUpdateData, TodoTypeUpdateErrors, TodoTypeUpdateResponses, TodoUpdateData, TodoUpdateErrors, TodoUpdateResponses } from './types.gen'; export type Options<TData extends TDataShape = TDataShape, ThrowOnError extends boolean = boolean, TResponse = unknown> = Options2<TData, ThrowOnError, TResponse> & { /** @@ -899,13 +899,13 @@ export const eventOccurrenceCancel = <ThrowOnError extends boolean = false>(opti * Return the authenticated user's events, ordered by `start` ascending, with cursor pagination. * * ### When to Use - * Render calendar list/grid views, search for specific terms using full-text search, query events within a specific time window, or retrieve historically past events. + * Render calendar list/grid views, search for literal text, query events within a specific time window, or retrieve historically past events. * * ### Constraints * - **Default Visibility**: By default, soft-deleted events and past events (events where `end` is before the current time) are automatically hidden. * - **Time Bounds Override**: Supplying any explicit time bound query parameter (`start_from`, `start_to`, `end_from`, `end_to`) or passing `include_past=true` overrides and disables the implicit past filter. * - **Calendar Trash**: `deleted_only=true` returns only soft-deleted events for the current user and Workspace. It overrides `include_deleted` and disables the implicit past filter regardless of `include_past`. Explicit time bounds and `q` still apply. Series Masters remain single rows; cancelled occurrences are not Trash. - * - **Search Scope**: `q` performs a case-insensitive substring search across `title`, `description`, and `location`. + * - **Search Scope**: `q` performs a literal substring search across `title`, `description`, and `location`. ASCII case-insensitive; UTF-8 text is supported. Percent and underscore are literal characters, not wildcards. * - **Pagination**: Default `limit` is 50, clamped to `[1, 200]`. Matching events are ordered by `start ASC, id ASC` before cursor pagination. Cursor is a page position, not a Consistency bookmark or snapshot. * * ### Troubleshooting @@ -951,6 +951,34 @@ export const eventCreate = <ThrowOnError extends boolean = false>(options?: Opti } }); +/** + * Disable the private calendar link + * + * Disable the link using expected_version. External copies cannot be removed. A private read-only link to all your event details in the current Workspace. Anyone with the link can read them. External calendar updates depend on that app's refresh schedule and can be delayed. + */ +export const calendarDisableSubscription = <ThrowOnError extends boolean = false>(options: Options<CalendarDisableSubscriptionData, ThrowOnError>) => (options.client ?? client).delete<CalendarDisableSubscriptionResponses, CalendarDisableSubscriptionErrors, ThrowOnError>({ + url: '/calendar/subscription', + ...options, + headers: { + 'Content-Type': 'application/json', + ...options.headers + } +}); + +/** + * Read the private calendar subscription + * + * Read the current subscription state without creating a link. A private read-only link to all your event details in the current Workspace. Anyone with the link can read them. External calendar updates depend on that app's refresh schedule and can be delayed. + */ +export const calendarGetSubscription = <ThrowOnError extends boolean = false>(options?: Options<CalendarGetSubscriptionData, ThrowOnError>) => (options?.client ?? client).get<CalendarGetSubscriptionResponses, CalendarGetSubscriptionErrors, ThrowOnError>({ url: '/calendar/subscription', ...options }); + +/** + * Create a private calendar subscription + * + * Create a subscription or return the same active link. A private read-only link to all your event details in the current Workspace. Anyone with the link can read them. External calendar updates depend on that app's refresh schedule and can be delayed. + */ +export const calendarCreateSubscription = <ThrowOnError extends boolean = false>(options?: Options<CalendarCreateSubscriptionData, ThrowOnError>) => (options?.client ?? client).post<CalendarCreateSubscriptionResponses, CalendarCreateSubscriptionErrors, ThrowOnError>({ url: '/calendar/subscription', ...options }); + /** * Soft-delete a calendar event * @@ -1108,6 +1136,20 @@ export const eventOccurrences = <ThrowOnError extends boolean = false>(options: ...options }); +/** + * Reset the private calendar link + * + * Replace the link using expected_version. The old link stops working; external copies cannot be removed. Subscribe again with the new link. After an uncertain response, read the current state before retrying. A private read-only link to all your event details in the current Workspace. Anyone with the link can read them. External calendar updates depend on that app's refresh schedule and can be delayed. + */ +export const calendarResetSubscription = <ThrowOnError extends boolean = false>(options: Options<CalendarResetSubscriptionData, ThrowOnError>) => (options.client ?? client).post<CalendarResetSubscriptionResponses, CalendarResetSubscriptionErrors, ThrowOnError>({ + url: '/calendar/subscription/reset', + ...options, + headers: { + 'Content-Type': 'application/json', + ...options.headers + } +}); + /** * Restore a soft-deleted event * @@ -2193,6 +2235,7 @@ export const recurrenceRuleList = <ThrowOnError extends boolean = false>(options * * **RFC-5545 Conformity**: The `rrule` parameter must be a valid RFC-5545 schedule string (e.g., `FREQ=WEEKLY;BYDAY=MO`) and must **not** include the `DTSTART` or `TZID` directive. * * **Anchor Date**: `dtstart` specifies the local calendar starting date (`YYYY-MM-DD`) where the schedule rule is anchored. * * **Nesting Constraints**: Recurrence rules can only be bound to root-level tasks. Child tasks (subtasks) cannot have recurrence rules. Setting a child task as a parent will trigger `PARENT_IS_CHILD`. + * * **Fixed Assignee**: Optional `assignee_user_id` assigns every occurrence and subtask to a current Workspace Member. Omit to use the creator. Assignment cannot change after rule creation. To change assignee, delete the old rule and create a new one; existing instances remain, so choose a start date that avoids overlap. If membership is absent or unavailable, materialization pauses and existing instances stay intact. * * **Instance Independence**: Once materialized, each todo instance is fully independent with its own `status` and `due_at`. * * ### ⚠️ Common Errors & Troubleshooting @@ -2472,7 +2515,7 @@ export const recurrenceRuleDelete = <ThrowOnError extends boolean = false>(optio * * Use this to inspect rule details before editing, preview the task template that future occurrences will copy, or check the current materialization metrics. * * ### 💡 Key Features & Constraints - * * **Snapshot Integrity**: The returned template represents a schema template snapshot — modifying the rule (PATCH) only alters future occurrences; already-materialized tasks are never mutated retroactively. + * * **Snapshot Integrity**: The returned template represents a schema template snapshot — rule edits rebuild eligible open instances from today when membership is valid; modified roots are preserved. * * ### ⚠️ Common Errors & Troubleshooting * * **`NOT_FOUND` (HTTP 404)**: Thrown if the specified rule ID does not exist. @@ -2493,7 +2536,8 @@ export const recurrenceRuleGet = <ThrowOnError extends boolean = false>(options: * * Use this to shift standup schedules (e.g., from Monday to Friday), update template text details, or change the parent todo mapping for future generated tasks. * * ### 💡 Key Features & Constraints - * * **Future-Only Effect**: Modifying the rule only applies to future materialized todo tasks; previously generated tasks remain unaffected. + * * **Fixed Assignee**: Any PATCH with `assignee_user_id`, including the same value or null, fails with `ASSIGNEE_IMMUTABLE` (HTTP 400). + * * **Rebuild**: Rule edits rebuild open instances from today whose root Todo is unmodified. Membership must be valid before clearing instances; otherwise edits save and rebuilding is deferred. * * **Optimistic Locking**: Supports `expected_version` to prevent concurrent modifications from overwriting workspace rule parameters. * * ### ⚠️ Common Errors & Troubleshooting diff --git a/src/generated/sdk/types.gen.ts b/src/generated/sdk/types.gen.ts index 162f1ae..16d375e 100644 --- a/src/generated/sdk/types.gen.ts +++ b/src/generated/sdk/types.gen.ts @@ -1018,6 +1018,12 @@ export type CreateEventBody = { time_zone?: string; }; +export type CalendarSubscription = { + enabled: boolean; + version: number; + url: string | null; +}; + /** * Minimal response for DELETE `/calendar/events/{id}`. Use GET with `?include_deleted=true` to fetch the full soft-deleted row. */ @@ -2104,6 +2110,8 @@ export type CreateRecurrenceRuleResponse = { }; export type RecurrenceRule = { + assignee_user_id: string; + assignee_status?: 'valid' | 'not_member' | 'unknown'; id: string; user_id: string; /** @@ -2121,6 +2129,7 @@ export type RecurrenceRule = { }; export type CreateRecurrenceRuleBody = { + assignee_user_id?: string; rrule: string; dtstart: string; title: string; @@ -2366,6 +2375,7 @@ export type UpdateRecurrenceRuleBody = { title?: string; description?: string; parent_id?: string | null; + [key: string]: unknown; }; export type UpdateTodoBody = { @@ -6672,7 +6682,7 @@ export type EventListData = { path?: never; query?: { /** - * Optional full-text search across title, description, and location (case-insensitive substring). + * Optional literal substring search across title, description, and location. ASCII case-insensitive; UTF-8 text is supported. Percent and underscore are literal characters, not wildcards. */ q?: string; /** @@ -6876,6 +6886,287 @@ export type EventCreateResponses = { export type EventCreateResponse = EventCreateResponses[keyof EventCreateResponses]; +export type CalendarDisableSubscriptionData = { + body: { + expected_version: number; + }; + path?: never; + query?: never; + url: '/calendar/subscription'; +}; + +export type CalendarDisableSubscriptionErrors = { + /** + * Request validation failed. The body, query, or path parameters did not match the operation's schema. + */ + 400: { + error: { + code: string; + message: string; + }; + }; + /** + * Authentication is required but missing or invalid. The Bearer token (API key or OAuth access token) was absent, malformed, or rejected. + */ + 401: { + error: { + code: string; + message: string; + }; + }; + /** + * The caller is authenticated but not permitted to perform this operation on the target resource. + */ + 403: { + error: { + code: string; + message: string; + }; + }; + /** + * The target resource does not exist or is not visible to the caller. Soft-deleted resources are treated as not found unless an `include_deleted` flag is set. + */ + 404: { + error: { + code: string; + message: string; + }; + }; + /** + * VERSION_CONFLICT: read the current state before retrying. SUBSCRIPTION_DISABLED: create a link before resetting it. + */ + 409: { + error: { + code: string; + message: string; + }; + }; + /** + * Rate limit exceeded. Use the HTTP `Retry-After` header for machine-readable retry timing. + */ + 429: { + error: { + code: string; + message: string; + }; + }; + /** + * Unhandled server error. The request was well-formed but the service failed unexpectedly. Safe to retry idempotent operations. + */ + 500: { + error: { + code: string; + message: string; + }; + }; + /** + * SUBSCRIPTION_UNAVAILABLE: the feature is disabled or Auth is unavailable. + */ + 503: { + error: { + code: string; + message: string; + }; + }; +}; + +export type CalendarDisableSubscriptionError = CalendarDisableSubscriptionErrors[keyof CalendarDisableSubscriptionErrors]; + +export type CalendarDisableSubscriptionResponses = { + /** + * Current subscription state + */ + 200: CalendarSubscription; +}; + +export type CalendarDisableSubscriptionResponse = CalendarDisableSubscriptionResponses[keyof CalendarDisableSubscriptionResponses]; + +export type CalendarGetSubscriptionData = { + body?: never; + path?: never; + query?: never; + url: '/calendar/subscription'; +}; + +export type CalendarGetSubscriptionErrors = { + /** + * Request validation failed. The body, query, or path parameters did not match the operation's schema. + */ + 400: { + error: { + code: string; + message: string; + }; + }; + /** + * Authentication is required but missing or invalid. The Bearer token (API key or OAuth access token) was absent, malformed, or rejected. + */ + 401: { + error: { + code: string; + message: string; + }; + }; + /** + * The caller is authenticated but not permitted to perform this operation on the target resource. + */ + 403: { + error: { + code: string; + message: string; + }; + }; + /** + * The target resource does not exist or is not visible to the caller. Soft-deleted resources are treated as not found unless an `include_deleted` flag is set. + */ + 404: { + error: { + code: string; + message: string; + }; + }; + /** + * VERSION_CONFLICT: read the current state before retrying. SUBSCRIPTION_DISABLED: create a link before resetting it. + */ + 409: { + error: { + code: string; + message: string; + }; + }; + /** + * Rate limit exceeded. Use the HTTP `Retry-After` header for machine-readable retry timing. + */ + 429: { + error: { + code: string; + message: string; + }; + }; + /** + * Unhandled server error. The request was well-formed but the service failed unexpectedly. Safe to retry idempotent operations. + */ + 500: { + error: { + code: string; + message: string; + }; + }; + /** + * SUBSCRIPTION_UNAVAILABLE: the feature is disabled or Auth is unavailable. + */ + 503: { + error: { + code: string; + message: string; + }; + }; +}; + +export type CalendarGetSubscriptionError = CalendarGetSubscriptionErrors[keyof CalendarGetSubscriptionErrors]; + +export type CalendarGetSubscriptionResponses = { + /** + * Current subscription state + */ + 200: CalendarSubscription; +}; + +export type CalendarGetSubscriptionResponse = CalendarGetSubscriptionResponses[keyof CalendarGetSubscriptionResponses]; + +export type CalendarCreateSubscriptionData = { + body?: never; + path?: never; + query?: never; + url: '/calendar/subscription'; +}; + +export type CalendarCreateSubscriptionErrors = { + /** + * Request validation failed. The body, query, or path parameters did not match the operation's schema. + */ + 400: { + error: { + code: string; + message: string; + }; + }; + /** + * Authentication is required but missing or invalid. The Bearer token (API key or OAuth access token) was absent, malformed, or rejected. + */ + 401: { + error: { + code: string; + message: string; + }; + }; + /** + * The caller is authenticated but not permitted to perform this operation on the target resource. + */ + 403: { + error: { + code: string; + message: string; + }; + }; + /** + * The target resource does not exist or is not visible to the caller. Soft-deleted resources are treated as not found unless an `include_deleted` flag is set. + */ + 404: { + error: { + code: string; + message: string; + }; + }; + /** + * VERSION_CONFLICT: read the current state before retrying. SUBSCRIPTION_DISABLED: create a link before resetting it. + */ + 409: { + error: { + code: string; + message: string; + }; + }; + /** + * Rate limit exceeded. Use the HTTP `Retry-After` header for machine-readable retry timing. + */ + 429: { + error: { + code: string; + message: string; + }; + }; + /** + * Unhandled server error. The request was well-formed but the service failed unexpectedly. Safe to retry idempotent operations. + */ + 500: { + error: { + code: string; + message: string; + }; + }; + /** + * SUBSCRIPTION_UNAVAILABLE: the feature is disabled or Auth is unavailable. + */ + 503: { + error: { + code: string; + message: string; + }; + }; +}; + +export type CalendarCreateSubscriptionError = CalendarCreateSubscriptionErrors[keyof CalendarCreateSubscriptionErrors]; + +export type CalendarCreateSubscriptionResponses = { + /** + * Current subscription state + */ + 200: CalendarSubscription; +}; + +export type CalendarCreateSubscriptionResponse = CalendarCreateSubscriptionResponses[keyof CalendarCreateSubscriptionResponses]; + export type EventDeleteData = { body?: VersionBody; headers?: { @@ -7573,6 +7864,101 @@ export type EventOccurrencesResponses = { export type EventOccurrencesResponse = EventOccurrencesResponses[keyof EventOccurrencesResponses]; +export type CalendarResetSubscriptionData = { + body: { + expected_version: number; + }; + path?: never; + query?: never; + url: '/calendar/subscription/reset'; +}; + +export type CalendarResetSubscriptionErrors = { + /** + * Request validation failed. The body, query, or path parameters did not match the operation's schema. + */ + 400: { + error: { + code: string; + message: string; + }; + }; + /** + * Authentication is required but missing or invalid. The Bearer token (API key or OAuth access token) was absent, malformed, or rejected. + */ + 401: { + error: { + code: string; + message: string; + }; + }; + /** + * The caller is authenticated but not permitted to perform this operation on the target resource. + */ + 403: { + error: { + code: string; + message: string; + }; + }; + /** + * The target resource does not exist or is not visible to the caller. Soft-deleted resources are treated as not found unless an `include_deleted` flag is set. + */ + 404: { + error: { + code: string; + message: string; + }; + }; + /** + * VERSION_CONFLICT: read the current state before retrying. SUBSCRIPTION_DISABLED: create a link before resetting it. + */ + 409: { + error: { + code: string; + message: string; + }; + }; + /** + * Rate limit exceeded. Use the HTTP `Retry-After` header for machine-readable retry timing. + */ + 429: { + error: { + code: string; + message: string; + }; + }; + /** + * Unhandled server error. The request was well-formed but the service failed unexpectedly. Safe to retry idempotent operations. + */ + 500: { + error: { + code: string; + message: string; + }; + }; + /** + * SUBSCRIPTION_UNAVAILABLE: the feature is disabled or Auth is unavailable. + */ + 503: { + error: { + code: string; + message: string; + }; + }; +}; + +export type CalendarResetSubscriptionError = CalendarResetSubscriptionErrors[keyof CalendarResetSubscriptionErrors]; + +export type CalendarResetSubscriptionResponses = { + /** + * Current subscription state + */ + 200: CalendarSubscription; +}; + +export type CalendarResetSubscriptionResponse = CalendarResetSubscriptionResponses[keyof CalendarResetSubscriptionResponses]; + export type EventRestoreData = { body?: VersionBody; headers?: { @@ -12564,6 +12950,15 @@ export type RecurrenceRuleCreateErrors = { message: string; }; }; + /** + * INVALID_ASSIGNEE: the assignee is not a current Workspace Member. + */ + 422: { + error: { + code: string; + message: string; + }; + }; /** * Rate limit exceeded. Use the HTTP `Retry-After` header for machine-readable retry timing. */ @@ -12582,6 +12977,15 @@ export type RecurrenceRuleCreateErrors = { message: string; }; }; + /** + * ASSIGNEE_CHECK_UNAVAILABLE: membership verification failed. No rule or instances were created. + */ + 503: { + error: { + code: string; + message: string; + }; + }; }; export type RecurrenceRuleCreateError = RecurrenceRuleCreateErrors[keyof RecurrenceRuleCreateErrors]; @@ -13735,7 +14139,7 @@ export type RecurrenceRuleUpdateError = RecurrenceRuleUpdateErrors[keyof Recurre export type RecurrenceRuleUpdateResponses = { /** - * The rule was updated. Returns the post-update rule with a bumped `version` and refreshed `updated_at`. Future materializations follow the new schedule; existing instances are untouched. + * The rule was updated. Returns the post-update rule with a bumped `version` and refreshed `updated_at`. Eligible future instances are rebuilt when membership is valid. */ 200: RecurrenceRule; }; diff --git a/test/recurrence-assignee.test.ts b/test/recurrence-assignee.test.ts new file mode 100644 index 0000000..e90dd36 --- /dev/null +++ b/test/recurrence-assignee.test.ts @@ -0,0 +1,67 @@ +import { afterAll, beforeAll, expect, it } from "vitest" +import { execFile } from "node:child_process" +import { createServer } from "node:http" +import { mkdtemp, mkdir, writeFile, rm } from "node:fs/promises" +import { tmpdir } from "node:os" +import { join } from "node:path" + +let directory: string +let body: unknown +let status = 200 +const rule = { id: "tdr_fixture", user_id: "usr_creator", assignee_user_id: "usr_assignee", assignee_status: "valid", rrule: "FREQ=WEEKLY", dtstart: "2026-09-15" } +const server = createServer(async (req, res) => { + const chunks = [] + for await (const chunk of req) chunks.push(chunk) + if (chunks.length) body = JSON.parse(Buffer.concat(chunks).toString()) + res.writeHead(status, { "content-type": "application/json" }) + res.end(JSON.stringify(status !== 200 ? { error: { code: status === 422 ? "INVALID_ASSIGNEE" : "ASSIGNEE_CHECK_UNAVAILABLE" } } : req.method === "POST" ? { rule, template_todo_id: "tod_template", materialized_instance_count: 3 } : req.url?.includes("tdr_fixture") ? { rule, template: { id: "tod_template" }, materialized_instance_count: 3 } : { rules: [rule] })) +}) +beforeAll(async () => { + directory = await mkdtemp(join(tmpdir(), "wspc-rule-")) + await mkdir(join(directory, ".wspc")) + await new Promise<void>(resolve => server.listen(0, "127.0.0.1", resolve)) + const address = server.address() + if (!address || typeof address === "string") throw new Error("Missing server port") + await writeFile(join(directory, ".wspc/config.json"), JSON.stringify({ current_env: "fixture", envs: { fixture: { api_base: `http://127.0.0.1:${address.port}`, current_account: "fixture@example.com", accounts: { "fixture@example.com": { email: "fixture@example.com", api_key: "wspc_fixture" } } } } })) +}) +afterAll(async () => { + server.closeAllConnections() + await new Promise<void>(resolve => server.close(() => resolve())) + await rm(directory, { recursive: true, force: true }) +}) +function run(args: string[], output = "json") { + const bootstrap = `import os from 'node:os'; import {syncBuiltinESMExports} from 'node:module'; os.homedir=()=>${JSON.stringify(directory)}; syncBuiltinESMExports(); const {dispatch}=await import('./src/cli.ts'); await dispatch(['node','wspc',...process.argv.slice(1)]);` + return new Promise<{ code: number; stdout: string; stderr: string }>(resolve => { + execFile(process.execPath, ["--import", "tsx", "--input-type=module", "-e", bootstrap, "--", ...args], { env: { ...process.env, WSPC_ENV: "fixture", WSPC_ACCOUNT: "fixture@example.com", WSPC_OUTPUT: output }, timeout: 15000 }, (error, stdout, stderr) => resolve({ code: error ? Number(error.code) || 1 : 0, stdout, stderr })) + }) +} +it("sends a fixed assignee and explains that it is immutable", async () => { + status = 200 + const result = await run(["todo", "rule", "add", "Weekly", "--rrule", "FREQ=WEEKLY", "--dtstart", "2026-09-15", "--project", "prj_fixture", "--assignee-user-id", "usr_assignee"]) + expect(result.code, result.stderr).toBe(0) + expect(body).toEqual({ title: "Weekly", rrule: "FREQ=WEEKLY", dtstart: "2026-09-15", project_id: "prj_fixture", assignee_user_id: "usr_assignee" }) + const help = await run(["todo", "rule", "add", "--help"]) + expect(help.stdout).toContain("--assignee-user-id") + expect(help.stdout).toContain("Assignment cannot change after rule creation") +}) +it.each(["ls", "show"])("shows creator, assignee and status in %s JSON and pretty output", async command => { + status = 200 + const args = ["todo", "rule", command, ...(command === "ls" ? ["--project-id", "prj_fixture"] : ["tdr_fixture"])] + for (const output of ["json", "pretty"]) { + const result = await run(args, output) + expect(result.code, result.stderr).toBe(0) + for (const value of ["usr_creator", "usr_assignee", "valid"]) expect(result.stdout).toContain(value) + } +}) +it.each([422, 503])("returns a nonzero exit for membership HTTP %i", async code => { + status = code + const result = await run(["todo", "rule", "add", "Weekly", "--rrule", "FREQ=WEEKLY", "--dtstart", "2026-09-15", "--project", "prj_fixture", "--assignee-user-id", "usr_assignee"]) + expect(result.code).toBe(1) + expect(result.stderr).toContain(code === 422 ? "INVALID_ASSIGNEE" : "ASSIGNEE_CHECK_UNAVAILABLE") +}) +it("omits assignment when the caller uses the existing add command", async () => { + status = 200 + const result = await run(["todo", "rule", "add", "Weekly", "--rrule", "FREQ=WEEKLY", "--dtstart", "2026-09-15", "--project", "prj_fixture"]) + expect(result.code, result.stderr).toBe(0) + expect(body).toEqual({ title: "Weekly", rrule: "FREQ=WEEKLY", dtstart: "2026-09-15", project_id: "prj_fixture" }) +})