diff --git a/package-lock.json b/package-lock.json index f88f7bd..9cb0777 100644 --- a/package-lock.json +++ b/package-lock.json @@ -979,9 +979,9 @@ "license": "MIT" }, "node_modules/fast-uri": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-4.1.5.tgz", - "integrity": "sha512-vZeoMRB4epNr7QfdHxel7te/RcX16CxyXI07JCCTFWZA2s4v1azGNESRj+2EoaHSaWFL/Z3GmKT2jF6A202jLg==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-4.2.3.tgz", + "integrity": "sha512-I1PXwP5eAhlNlcdpjt9CgB59op2ZvZfxw+BkqGFVIUOgNpCVTcTqp3HhTX7brxj5vsip+nSY4nTvff+eIA76hg==", "dev": true, "funding": [ { @@ -2025,9 +2025,9 @@ } }, "node_modules/qs": { - "version": "6.16.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.16.0.tgz", - "integrity": "sha512-h6fhOIaRrID2CbEY2fqs+7t+UXZo+MLAnU5gRIq85uFtdiUPCdsApMlHhXogKVM4HM2DVbIjGNTTYH2OcmP1vA==", + "version": "6.17.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.17.1.tgz", + "integrity": "sha512-jd3COkaKVgGUW+ZHyEHCG9bH7RoaaiWuMgzsIBjUMVjLAaWGWpoUAVwljVvBHxRu/2qEHnadLGZrkutYUBPQJA==", "dev": true, "license": "BSD-3-Clause", "dependencies": { diff --git a/package.json b/package.json index df2ada9..9fe5546 100644 --- a/package.json +++ b/package.json @@ -16,11 +16,11 @@ "@stoplight/prism-http": "5.16.0", "@stoplight/prism-http-server": "5.16.0", "@tootallnate/once": "2.0.1", - "fast-uri": "4.1.5", + "fast-uri": "4.2.3", "fast-xml-parser": "5.8.0", "js-yaml": "5.4.1", "lodash": "4.18.1", - "qs": "6.16.0", + "qs": "6.17.1", "uuid": "11.1.1", "ws": "8.21.0" }, diff --git a/scripts/audit-js-tooling.mjs b/scripts/audit-js-tooling.mjs index 2882b77..e997187 100755 --- a/scripts/audit-js-tooling.mjs +++ b/scripts/audit-js-tooling.mjs @@ -29,18 +29,6 @@ const ALLOWED = { "--dynamic flag, so no Postman collection is parsed and faker generates " + "nothing. Prism is a devDependency and is never part of the published wheel.", }, - "GHSA-vfj7-8cjw-p6xm": { - package: "braces", - expires: "2026-12-31", - reason: - "Stack-exhaustion DoS when braces expands a deeply nested caller-supplied " + - "pattern. No patched release exists (all versions <= 3.0.3 affected). " + - "Reaches us only as chokidar 3.6.0 under @stoplight/prism-cli, which " + - "watches the single spec path we pass to `prism mock` with " + - "disableGlobbing: true (prism-cli dist/util/runner.js), so no pattern is " + - "ever expanded. Prism is a devDependency and is never part of the " + - "published wheel. Re-review when braces ships a fix.", - }, }; function auditReport() { diff --git a/specs/platform-openapi.json b/specs/platform-openapi.json index 1b72868..ff5c18c 100644 --- a/specs/platform-openapi.json +++ b/specs/platform-openapi.json @@ -808,6 +808,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -818,11 +838,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "properties": { @@ -833,6 +860,20 @@ }, "type": "array" }, + "add_denies": { + "description": "Patch mode: denies to add or merge, replacing any grant for the same principal.", + "items": { + "$ref": "#/components/schemas/AclGrant" + }, + "type": "array" + }, + "denies": { + "description": "Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support.", + "items": { + "$ref": "#/components/schemas/AclGrant" + }, + "type": "array" + }, "grants": { "description": "Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", "items": { @@ -840,12 +881,24 @@ }, "type": "array" }, + "preserve_denies": { + "description": "Retain current server denies atomically in replacement or patch mode; current denies win.", + "example": true, + "type": "boolean" + }, "remove": { "description": "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", "items": { "$ref": "#/components/schemas/AclRemoveTarget" }, "type": "array" + }, + "remove_denies": { + "description": "Patch mode: principals whose denies should be removed.", + "items": { + "$ref": "#/components/schemas/AclRemoveTarget" + }, + "type": "array" } }, "type": "object" @@ -962,6 +1015,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -972,11 +1045,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -1151,6 +1231,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -1161,11 +1261,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "nullable": true, @@ -1223,6 +1330,112 @@ }, "type": "array" }, + "add_denies": { + "description": "Patch mode: denies to add or merge, replacing any grant for the same principal.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, + "denies": { + "description": "Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, "grants": { "description": "Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", "example": [ @@ -1276,6 +1489,11 @@ }, "type": "array" }, + "preserve_denies": { + "description": "Retain current server denies atomically in replacement or patch mode; current denies win.", + "example": true, + "type": "boolean" + }, "remove": { "description": "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", "example": [ @@ -1308,6 +1526,39 @@ "type": "object" }, "type": "array" + }, + "remove_denies": { + "description": "Patch mode: principals whose denies should be removed.", + "example": [ + { + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "Identifies a principal to be removed from an access-control list.", + "example": { + "principal": "string", + "principal_type": "user" + }, + "properties": { + "principal": { + "description": "The identifier of the principal to remove. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`. Omit when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal to remove. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type" + ], + "type": "object" + }, + "type": "array" } }, "type": "object" @@ -3129,6 +3380,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -3139,11 +3410,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -3323,6 +3601,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -3333,11 +3631,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "nullable": true @@ -3613,6 +3918,7 @@ "example": { "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", + "bootstrap": {}, "config": { "key": "value" }, @@ -3628,6 +3934,12 @@ "name": "Example Name", "provider": "sprites", "region": "us-east-1", + "repositories": [ + { + "ref": "string", + "repository": "string" + } + ], "sprite_url": "https://example.com", "status": "ready", "thread_id": "string", @@ -3645,6 +3957,11 @@ "example": "dap_0aBcDeFgHiJkLmNoPqRsTu", "type": "string" }, + "bootstrap": { + "description": "Bootstrap results, including each repository's status, commit and error.", + "example": {}, + "type": "object" + }, "config": { "description": "Provider-specific configuration key-value pairs for the computer. Structure depends on the underlying compute provider.", "example": { @@ -3701,7 +4018,7 @@ "type": "string" }, "provider": { - "description": "Compute backend powering this computer: `\"sprites\"` (Fly Sprites), `\"vercel\"` (Vercel Sandbox) or `\"e2b\"` (E2B).", + "description": "Compute backend powering this computer: `\"sprites\"` (Fly Sprites), `\"vercel\"` (Vercel Sandbox), `\"e2b\"` (E2B) or `\"devbox\"` (an ArchAstro devbox owned by the computer's user).", "example": "sprites", "type": "string" }, @@ -3711,6 +4028,13 @@ "nullable": true, "type": "string" }, + "repositories": { + "description": "Ordered GitHub checkouts with repository and nullable ref; the first checkout is primary.", + "items": { + "$ref": "#/components/schemas/ComputerRepository" + }, + "type": "array" + }, "sprite_url": { "description": "URL of the live screenshot sprite used to render a real-time preview of the computer's screen. `null` when no sprite is available.", "example": "https://example.com", @@ -3718,7 +4042,7 @@ "type": "string" }, "status": { - "description": "Current lifecycle state of the computer. Common values include `\"provisioning\"`, `\"ready\"`, `\"error\"`, and `\"terminated\"`.", + "description": "Current lifecycle state of the computer. Common values include `\"provisioning\"`, `\"ready\"`, `\"paused\"` (resumes on use), `\"error\"`, and `\"destroyed\"`.", "example": "ready", "nullable": true, "type": "string" @@ -3748,6 +4072,7 @@ { "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", + "bootstrap": {}, "config": { "key": "value" }, @@ -3763,6 +4088,12 @@ "name": "Example Name", "provider": "sprites", "region": "us-east-1", + "repositories": [ + { + "ref": "string", + "repository": "string" + } + ], "sprite_url": "https://example.com", "status": "ready", "thread_id": "string", @@ -3798,6 +4129,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -3808,11 +4159,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -3861,6 +4219,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -3871,11 +4249,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "nullable": true @@ -4145,6 +4530,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -4155,11 +4560,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -4577,6 +4989,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -4587,11 +5019,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -4824,11 +5263,32 @@ "thread_id": "string" }, "payload": { - "question": "string" + "changes": [ + { + "action": "string", + "class": "string", + "path": "string", + "tier": "string" + } + ], + "from_version": "string", + "instructions_md": "string", + "key": "string", + "overwrite": true, + "prompt": "string", + "proposal_id": "string", + "question": "string", + "rationale": "string", + "to_version": "string", + "validate_script": "string" }, "resolution": { "answer": "string", - "reason": "string" + "key": "string", + "reason": "string", + "set": true, + "status": "string", + "to_version": "string" }, "resolved_at": "2024-01-01T00:00:00Z", "resolved_by": "usr_0aBcDeFgHiJkLmNoPqRsTu", @@ -4876,7 +5336,7 @@ }, "payload": { "$ref": "#/components/schemas/Payload", - "description": "Question request payload." + "description": "Kind-safe request payload." }, "resolution": { "allOf": [ @@ -4887,7 +5347,11 @@ "description": "Answer or rejection reason; null before resolution.", "example": { "answer": "string", - "reason": "string" + "key": "string", + "reason": "string", + "set": true, + "status": "string", + "to_version": "string" }, "nullable": true }, @@ -4961,11 +5425,32 @@ "thread_id": "string" }, "payload": { - "question": "string" + "changes": [ + { + "action": "string", + "class": "string", + "path": "string", + "tier": "string" + } + ], + "from_version": "string", + "instructions_md": "string", + "key": "string", + "overwrite": true, + "prompt": "string", + "proposal_id": "string", + "question": "string", + "rationale": "string", + "to_version": "string", + "validate_script": "string" }, "resolution": { "answer": "string", - "reason": "string" + "key": "string", + "reason": "string", + "set": true, + "status": "string", + "to_version": "string" }, "resolved_at": "2024-01-01T00:00:00Z", "resolved_by": "usr_0aBcDeFgHiJkLmNoPqRsTu", @@ -5013,6 +5498,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -5023,11 +5528,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", @@ -5223,6 +5735,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -5233,11 +5765,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", @@ -5314,6 +5853,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -5324,11 +5883,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", @@ -5539,6 +6105,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -5549,11 +6135,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", @@ -6508,7 +7101,7 @@ "type": "object" }, "resource_type": { - "description": "Type of the resource being changed. One of `\"agent\"`, `\"tool\"`, `\"routine\"`, `\"skill\"`, `\"computer\"`, or `\"knowledge\"`.", + "description": "Type of the resource being changed. One of `\"agent\"`, `\"tool\"`, `\"routine\"`, `\"skill\"`, `\"computer\"`, `\"endpoint\"`, or `\"knowledge\"`.", "example": "tool", "type": "string" }, @@ -6571,6 +7164,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -6581,11 +7194,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -7058,6 +7678,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -7068,11 +7708,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "agent": "agt_0aBcDeFgHiJkLmNoPqRsTu", @@ -7123,6 +7770,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -7133,11 +7800,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "nullable": true @@ -7881,12 +8555,12 @@ "type": "object" }, "payload": { - "description": "The input event payload that triggered this run. Structure varies by automation type. Defaults to an empty object if no payload was provided.", + "description": "The input event payload that triggered this run. Structure varies by automation type. Defaults to an empty object if no payload was provided. Omitted on retrieval when include_payload=false.", "example": {}, "type": "object" }, "result": { - "description": "The output produced after the automation finished executing. Contains workflow-defined keys alongside any returned output. `null` if the run has not yet completed.", + "description": "The output produced after the automation finished executing. Contains workflow-defined keys alongside any returned output. `null` if the run has not yet completed. Omitted on retrieval when include_payload=false.", "example": {}, "nullable": true, "type": "object" @@ -8171,6 +8845,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -8181,11 +8875,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -8362,6 +9063,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -8372,11 +9093,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -8577,7 +9305,7 @@ "principal_type": "user" } ], - "grants": [ + "add_denies": [ { "actions": [ "read", @@ -8587,202 +9315,7 @@ "principal_type": "user" } ], - "remove": [ - { - "principal": "string", - "principal_type": "user" - } - ] - }, - "actors": [ - { - "alias": "alice", - "id": "user-usr_01j3k5m7n9p2r4s6t8v0w1x2", - "name": "Example Name", - "profile_picture": { - "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", - "height": 600, - "media": "med_0aBcDeFgHiJkLmNoPqRsTu", - "mime_type": "application/json", - "refresh_url": "https://example.com", - "url": "https://example.com", - "width": 800 - } - } - ], - "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", - "agent_mode": "cli", - "attachments": [ - { - "content_type": "application/json", - "description": "An example description.", - "filename": "string", - "height": 1, - "id": "string", - "image_height": 1, - "image_source": { - "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", - "height": 600, - "media": "med_0aBcDeFgHiJkLmNoPqRsTu", - "mime_type": "application/json", - "refresh_url": "https://example.com", - "url": "https://example.com", - "width": 800 - }, - "image_url": "https://example.com", - "image_width": 1, - "key": "string", - "media_type": "application/json", - "name": "Example Name", - "object": {}, - "title": "Example Title", - "type": "file", - "url": "https://example.com", - "variants": [ - { - "byte_size": 1, - "content_type": "application/json", - "created_at": "2024-01-01T00:00:00Z", - "duration_ms": 1, - "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", - "filename": "string", - "height": 600, - "id": "mvr_0aBcDeFgHiJkLmNoPqRsTu", - "image_source": { - "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", - "height": 600, - "media": "med_0aBcDeFgHiJkLmNoPqRsTu", - "mime_type": "application/json", - "refresh_url": "https://example.com", - "url": "https://example.com", - "width": 800 - }, - "sha256": "string", - "updated_at": "2024-01-01T00:00:00Z", - "url": "https://example.com", - "url_expires_at": "2024-01-01T00:00:00Z", - "variant_key": "original", - "width": 800 - } - ], - "version": 1, - "width": 1 - } - ], - "branched_thread": "string", - "content": "Hello, how can I help you today?", - "context": [ - { - "attributes": {}, - "content": "string", - "title": "PR #10458", - "type": "myapp.pull_request" - } - ], - "created_at": "2024-01-01T00:00:00Z", - "has_replies": true, - "id": "msg_0aBcDeFgHiJkLmNoPqRsTu", - "idempotency_key": "01234567-89ab-cdef-0123-456789abcdef", - "is_deleted": true, - "legacy_agent": "string", - "metadata": { - "key": "value" - }, - "org": "org_0aBcDeFgHiJkLmNoPqRsTu", - "reactions": [ - { - "payload": { - "key": "value" - }, - "type": "emoji_reaction", - "user": "string" - } - ], - "rendering_mode": "reply", - "replies": [ - {} - ], - "replies_after_cursor": "string", - "replies_before_cursor": "string", - "reply_count": 1, - "reply_to": {}, - "root_message_id": "string", - "sandbox": "string", - "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", - "thread": "string", - "type": "note", - "user": "usr_0aBcDeFgHiJkLmNoPqRsTu", - "visibility": "default" - } - ], - "messages_loaded_on_last_update": 1, - "team": { - "acl": { - "add": [ - { - "actions": [ - "read", - "write" - ], - "principal": "string", - "principal_type": "user" - } - ], - "grants": [ - { - "actions": [ - "read", - "write" - ], - "principal": "string", - "principal_type": "user" - } - ], - "remove": [ - { - "principal": "string", - "principal_type": "user" - } - ] - }, - "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", - "badges": {}, - "created_at": "2024-01-01T00:00:00Z", - "description": "An example description.", - "id": "tem_0aBcDeFgHiJkLmNoPqRsTu", - "membership_status": "member", - "metadata": { - "key": "value" - }, - "name": "Example Name", - "org": "org_0aBcDeFgHiJkLmNoPqRsTu", - "sandbox": "dsb_0aBcDeFgHiJkLmNoPqRsTu", - "slug": "example-slug", - "updated_at": "2024-01-01T00:00:00Z" - }, - "thread": { - "agent_user": "agi_0aBcDeFgHiJkLmNoPqRsTu", - "created_at": "2024-01-01T00:00:00Z", - "creator": "usr_0aBcDeFgHiJkLmNoPqRsTu", - "description": "An example description.", - "id": "string", - "is_channel": true, - "is_default": true, - "is_transient": true, - "is_unlisted": true, - "key": "string", - "kind": "string", - "last_activity": "2024-01-01T00:00:00Z", - "last_message_preview": "Sounds good — I'll ship the fix tomorrow.", - "last_message_sender": "Alice Chen", - "metadata": { - "key": "value" - }, - "muted": true, - "org": "org_0aBcDeFgHiJkLmNoPqRsTu", - "parent_message": { - "acl": { - "add": [ + "denies": [ { "actions": [ "read", @@ -8802,11 +9335,287 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } + ] + }, + "actors": [ + { + "alias": "alice", + "id": "user-usr_01j3k5m7n9p2r4s6t8v0w1x2", + "name": "Example Name", + "profile_picture": { + "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", + "height": 600, + "media": "med_0aBcDeFgHiJkLmNoPqRsTu", + "mime_type": "application/json", + "refresh_url": "https://example.com", + "url": "https://example.com", + "width": 800 + } + } + ], + "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", + "agent_mode": "cli", + "attachments": [ + { + "content_type": "application/json", + "description": "An example description.", + "filename": "string", + "height": 1, + "id": "string", + "image_height": 1, + "image_source": { + "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", + "height": 600, + "media": "med_0aBcDeFgHiJkLmNoPqRsTu", + "mime_type": "application/json", + "refresh_url": "https://example.com", + "url": "https://example.com", + "width": 800 + }, + "image_url": "https://example.com", + "image_width": 1, + "key": "string", + "media_type": "application/json", + "name": "Example Name", + "object": {}, + "title": "Example Title", + "type": "file", + "url": "https://example.com", + "variants": [ + { + "byte_size": 1, + "content_type": "application/json", + "created_at": "2024-01-01T00:00:00Z", + "duration_ms": 1, + "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", + "filename": "string", + "height": 600, + "id": "mvr_0aBcDeFgHiJkLmNoPqRsTu", + "image_source": { + "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", + "height": 600, + "media": "med_0aBcDeFgHiJkLmNoPqRsTu", + "mime_type": "application/json", + "refresh_url": "https://example.com", + "url": "https://example.com", + "width": 800 + }, + "sha256": "string", + "updated_at": "2024-01-01T00:00:00Z", + "url": "https://example.com", + "url_expires_at": "2024-01-01T00:00:00Z", + "variant_key": "original", + "width": 800 + } + ], + "version": 1, + "width": 1 + } + ], + "branched_thread": "string", + "content": "Hello, how can I help you today?", + "context": [ + { + "attributes": {}, + "content": "string", + "title": "PR #10458", + "type": "myapp.pull_request" + } + ], + "created_at": "2024-01-01T00:00:00Z", + "has_replies": true, + "id": "msg_0aBcDeFgHiJkLmNoPqRsTu", + "idempotency_key": "01234567-89ab-cdef-0123-456789abcdef", + "is_deleted": true, + "legacy_agent": "string", + "metadata": { + "key": "value" + }, + "org": "org_0aBcDeFgHiJkLmNoPqRsTu", + "reactions": [ + { + "payload": { + "key": "value" + }, + "type": "emoji_reaction", + "user": "string" + } + ], + "rendering_mode": "reply", + "replies": [ + {} + ], + "replies_after_cursor": "string", + "replies_before_cursor": "string", + "reply_count": 1, + "reply_to": {}, + "root_message_id": "string", + "sandbox": "string", + "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", + "thread": "string", + "type": "note", + "user": "usr_0aBcDeFgHiJkLmNoPqRsTu", + "visibility": "default" + } + ], + "messages_loaded_on_last_update": 1, + "team": { + "acl": { + "add": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "grants": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "preserve_denies": true, + "remove": [ + { + "principal": "string", + "principal_type": "user" + } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } + ] + }, + "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", + "badges": {}, + "created_at": "2024-01-01T00:00:00Z", + "description": "An example description.", + "id": "tem_0aBcDeFgHiJkLmNoPqRsTu", + "membership_status": "member", + "metadata": { + "key": "value" + }, + "name": "Example Name", + "org": "org_0aBcDeFgHiJkLmNoPqRsTu", + "sandbox": "dsb_0aBcDeFgHiJkLmNoPqRsTu", + "slug": "example-slug", + "updated_at": "2024-01-01T00:00:00Z" + }, + "thread": { + "agent_user": "agi_0aBcDeFgHiJkLmNoPqRsTu", + "created_at": "2024-01-01T00:00:00Z", + "creator": "usr_0aBcDeFgHiJkLmNoPqRsTu", + "description": "An example description.", + "id": "string", + "is_channel": true, + "is_default": true, + "is_transient": true, + "is_unlisted": true, + "key": "string", + "kind": "string", + "last_activity": "2024-01-01T00:00:00Z", + "last_message_preview": "Sounds good — I'll ship the fix tomorrow.", + "last_message_sender": "Alice Chen", + "metadata": { + "key": "value" + }, + "muted": true, + "org": "org_0aBcDeFgHiJkLmNoPqRsTu", + "parent_message": { + "acl": { + "add": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "grants": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "preserve_denies": true, + "remove": [ + { + "principal": "string", + "principal_type": "user" + } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -8973,6 +9782,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -8983,11 +9812,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -9163,6 +9999,7 @@ "needs-review" ], "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", + "thread_template_key": "string", "title": "Example Title", "ttl": "2026-08-15T12:00:00", "unread_count": 5, @@ -9183,6 +10020,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -9193,11 +10050,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -9247,6 +10111,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -9257,11 +10141,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -9428,6 +10319,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -9438,11 +10349,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -9618,6 +10536,7 @@ "needs-review" ], "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", + "thread_template_key": "string", "title": "Example Title", "ttl": "2026-08-15T12:00:00", "unread_count": 5, @@ -9662,6 +10581,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -9672,11 +10611,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -9853,6 +10799,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -9863,11 +10829,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -10068,6 +11041,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -10078,11 +11071,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -10219,6 +11219,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -10229,11 +11249,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -10283,6 +11310,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -10293,11 +11340,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -10464,6 +11518,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -10474,11 +11548,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -10654,6 +11735,7 @@ "needs-review" ], "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", + "thread_template_key": "string", "title": "Example Title", "ttl": "2026-08-15T12:00:00", "unread_count": 5, @@ -10902,6 +11984,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -10912,11 +12014,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -11144,6 +12253,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -11154,11 +12283,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -11312,6 +12448,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -11322,11 +12478,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -11477,6 +12640,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -11487,11 +12670,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -11668,6 +12858,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -11678,11 +12888,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -11883,6 +13100,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -11893,11 +13130,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -12034,6 +13278,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -12044,11 +13308,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -12098,6 +13369,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -12108,11 +13399,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -12279,6 +13577,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -12289,11 +13607,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -12469,6 +13794,7 @@ "needs-review" ], "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", + "thread_template_key": "string", "title": "Example Title", "ttl": "2026-08-15T12:00:00", "unread_count": 5, @@ -12602,6 +13928,30 @@ }, "type": "object" }, + "ComputerRepository": { + "description": "A GitHub repository checkout recorded for later computer bootstrap.", + "example": { + "ref": "string", + "repository": "string" + }, + "properties": { + "ref": { + "description": "Optional checkout ref; null selects the repository's default branch.", + "example": "string", + "nullable": true, + "type": "string" + }, + "repository": { + "description": "GitHub owner/name; supported GitHub URLs are normalized on creation.", + "example": "string", + "type": "string" + } + }, + "required": [ + "repository" + ], + "type": "object" + }, "Config": { "description": "A versioned config file owned by a team or user, representing a typed artifact such as an agent definition or API tool specification.", "example": { @@ -13247,6 +14597,7 @@ "alias": "string", "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", "app_name": "Example Name", + "avatar_url": "https://example.com", "effective_access": { "billing": [ { @@ -13323,6 +14674,12 @@ "nullable": true, "type": "string" }, + "avatar_url": { + "description": "Stable public URL of the profile picture. Unlike `profile_picture.url` it does not expire, so clients can store it; it stops resolving when the picture is replaced. `null` when the user has no profile picture.", + "example": "https://example.com", + "nullable": true, + "type": "string" + }, "effective_access": { "$ref": "#/components/schemas/EffectiveAccess", "description": "Present only when the request supplies one or more `entitlement[]` values." @@ -13458,6 +14815,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -13468,11 +14845,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", @@ -13643,6 +15027,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -13653,11 +15057,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", @@ -16268,6 +17679,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -16278,11 +17709,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -16408,6 +17846,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -16418,11 +17876,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -16572,6 +18037,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -16582,11 +18067,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "nullable": true @@ -16739,6 +18231,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -16749,11 +18261,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -17616,6 +19135,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -17626,11 +19165,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -17791,19 +19337,75 @@ "type": "object" }, "Payload": { - "description": "Question request payload.", + "description": "Kind-safe request payload.", "example": { - "question": "string" + "changes": [ + { + "action": "string", + "class": "string", + "path": "string", + "tier": "string" + } + ], + "from_version": "string", + "instructions_md": "string", + "key": "string", + "overwrite": true, + "prompt": "string", + "proposal_id": "string", + "question": "string", + "rationale": "string", + "to_version": "string", + "validate_script": "string" }, "properties": { + "changes": { + "items": { + "$ref": "#/components/schemas/SelfUpdateChange" + }, + "type": "array" + }, + "from_version": { + "example": "string", + "type": "string" + }, + "instructions_md": { + "example": "string", + "type": "string" + }, + "key": { + "example": "string", + "type": "string" + }, + "overwrite": { + "example": true, + "type": "boolean" + }, + "prompt": { + "example": "string", + "type": "string" + }, + "proposal_id": { + "example": "string", + "type": "string" + }, "question": { "example": "string", "type": "string" + }, + "rationale": { + "example": "string", + "type": "string" + }, + "to_version": { + "example": "string", + "type": "string" + }, + "validate_script": { + "example": "string", + "type": "string" } }, - "required": [ - "question" - ], "type": "object" }, "PresetConfig": { @@ -18254,16 +19856,36 @@ "description": "Answer or rejection reason; null before resolution.", "example": { "answer": "string", - "reason": "string" + "key": "string", + "reason": "string", + "set": true, + "status": "string", + "to_version": "string" }, "properties": { "answer": { "example": "string", "type": "string" }, + "key": { + "example": "string", + "type": "string" + }, "reason": { "example": "string", "type": "string" + }, + "set": { + "example": true, + "type": "boolean" + }, + "status": { + "example": "string", + "type": "string" + }, + "to_version": { + "example": "string", + "type": "string" } }, "type": "object" @@ -19224,6 +20846,34 @@ ], "type": "object" }, + "SelfUpdateChange": { + "description": "Public review fields for one proposed self-update change.", + "example": { + "action": "string", + "class": "string", + "path": "string", + "tier": "string" + }, + "properties": { + "action": { + "example": "string", + "type": "string" + }, + "class": { + "example": "string", + "type": "string" + }, + "path": { + "example": "string", + "type": "string" + }, + "tier": { + "example": "string", + "type": "string" + } + }, + "type": "object" + }, "Setup": { "description": "Current MCP setup assessment, not a historical downgrade reason or upstream protocol probe.", "example": { @@ -21957,6 +23607,9 @@ "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", "aggregate_version": 1, "blocked_by_count": 1, + "blockers": [ + "string" + ], "closed_at": "2024-01-01T00:00:00Z", "comments_count": 1, "created_at": "2024-01-01T00:00:00Z", @@ -21984,12 +23637,14 @@ "description": "An example description.", "due_date": "2024-01-01T00:00:00Z", "epic": "string", + "human_answer_receipts": {}, "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, "is_stalled": true, "links": { "key": "value" }, + "machine_rescope_receipts": {}, "metadata": { "key": "value" }, @@ -22026,6 +23681,7 @@ ], "target_binary": "string", "target_version": "string", + "task_epic": "string", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -22049,6 +23705,16 @@ "example": 1, "type": "integer" }, + "blockers": { + "description": "Visible blocker IDs when requested with include=blockers.", + "example": [ + "string" + ], + "items": { + "type": "string" + }, + "type": "array" + }, "closed_at": { "description": "When the task was marked as done or otherwise closed (ISO 8601). `null` if the task is still open.", "example": "2024-01-01T00:00:00Z", @@ -22135,6 +23801,11 @@ "nullable": true, "type": "string" }, + "human_answer_receipts": { + "description": "Server-owned authenticated human answer intent, keyed by question version. Not infrastructure permission.", + "example": {}, + "type": "object" + }, "id": { "description": "Task ID (`tsk_...`).", "example": "tsk_0aBcDeFgHiJkLmNoPqRsTu", @@ -22157,6 +23828,11 @@ }, "type": "object" }, + "machine_rescope_receipts": { + "description": "Server-owned records of machine-applied local rescopes, keyed by question version. Never evidence that a human answered.", + "example": {}, + "type": "object" + }, "metadata": { "description": "Arbitrary key-value map of application-specific data stored alongside the task. Returns an empty object when no metadata has been set.", "example": { @@ -22290,6 +23966,12 @@ "nullable": true, "type": "string" }, + "task_epic": { + "description": "First-class Epic membership; does not grant access to the task.", + "example": "string", + "nullable": true, + "type": "string" + }, "team": { "description": "ID of the team that owns this task (`tem_...`). `null` if the task is not scoped to a team.", "example": "tem_0aBcDeFgHiJkLmNoPqRsTu", @@ -22414,6 +24096,28 @@ ], "type": "object" }, + "TaskDeletion": { + "description": "A retained visible task deletion.", + "example": { + "deleted_at": "string", + "task": "string" + }, + "properties": { + "deleted_at": { + "example": "string", + "type": "string" + }, + "task": { + "example": "string", + "type": "string" + } + }, + "required": [ + "task", + "deleted_at" + ], + "type": "object" + }, "TaskEnsureResult": { "description": "The current source task and whether this request created it.", "example": { @@ -22422,6 +24126,9 @@ "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", "aggregate_version": 1, "blocked_by_count": 1, + "blockers": [ + "string" + ], "closed_at": "2024-01-01T00:00:00Z", "comments_count": 1, "created_at": "2024-01-01T00:00:00Z", @@ -22449,12 +24156,14 @@ "description": "An example description.", "due_date": "2024-01-01T00:00:00Z", "epic": "string", + "human_answer_receipts": {}, "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, "is_stalled": true, "links": { "key": "value" }, + "machine_rescope_receipts": {}, "metadata": { "key": "value" }, @@ -22491,6 +24200,7 @@ ], "target_binary": "string", "target_version": "string", + "task_epic": "string", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -22514,6 +24224,195 @@ ], "type": "object" }, + "TaskEpicDrafts": { + "example": { + "drafts_version": 1, + "frozen": true, + "tasks": [ + {} + ] + }, + "properties": { + "drafts_version": { + "example": 1, + "type": "integer" + }, + "frozen": { + "example": true, + "type": "boolean" + }, + "tasks": { + "example": [ + {} + ], + "items": { + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "drafts_version", + "frozen", + "tasks" + ], + "type": "object" + }, + "TaskEpicEntity": { + "description": "A first-class Epic, with counts restricted to tasks visible to the caller.", + "example": { + "app_id": "string", + "description": "An example description.", + "drafts_version": 1, + "id": "string", + "links": [ + {} + ], + "metadata": { + "key": "value" + }, + "name": "Example Name", + "owner": {}, + "publish_state": "string", + "rollup": {}, + "sandbox_id": "string", + "state": "string", + "version": 1 + }, + "properties": { + "app_id": { + "example": "string", + "type": "string" + }, + "description": { + "example": "An example description.", + "nullable": true, + "type": "string" + }, + "drafts_version": { + "example": 1, + "type": "integer" + }, + "id": { + "example": "string", + "type": "string" + }, + "links": { + "example": [ + {} + ], + "items": { + "type": "object" + }, + "type": "array" + }, + "metadata": { + "example": { + "key": "value" + }, + "type": "object" + }, + "name": { + "example": "Example Name", + "type": "string" + }, + "owner": { + "example": {}, + "type": "object" + }, + "publish_state": { + "example": "string", + "type": "string" + }, + "rollup": { + "example": {}, + "type": "object" + }, + "sandbox_id": { + "example": "string", + "nullable": true, + "type": "string" + }, + "state": { + "example": "string", + "type": "string" + }, + "version": { + "example": 1, + "type": "integer" + } + }, + "required": [ + "id", + "name", + "state", + "owner", + "app_id", + "metadata", + "links", + "rollup", + "version", + "drafts_version", + "publish_state" + ], + "type": "object" + }, + "TaskEpicEntityCollection": { + "description": "Entity representation of an owner's Epic collection; not a label-summary page.", + "example": { + "after_cursor": "string", + "before_cursor": "string", + "data": [ + { + "app_id": "string", + "description": "An example description.", + "drafts_version": 1, + "id": "string", + "links": [ + {} + ], + "metadata": { + "key": "value" + }, + "name": "Example Name", + "owner": {}, + "publish_state": "string", + "rollup": {}, + "sandbox_id": "string", + "state": "string", + "version": 1 + } + ], + "has_more": true + }, + "properties": { + "after_cursor": { + "example": "string", + "nullable": true, + "type": "string" + }, + "before_cursor": { + "example": "string", + "nullable": true, + "type": "string" + }, + "data": { + "items": { + "$ref": "#/components/schemas/TaskEpicEntity" + }, + "type": "array" + }, + "has_more": { + "example": true, + "type": "boolean" + } + }, + "required": [ + "data", + "has_more" + ], + "type": "object" + }, "TaskExternalLink": { "description": "An indexed external object linked to a task.", "example": { @@ -22546,7 +24445,7 @@ "type": "object" }, "TaskOwnershipJob": { - "description": "The background job accepted for a task ownership conversion.", + "description": "The background job accepted for a task ownership conversion.\nAcceptance authorizes the root only. The worker validates and checkpoints the\nconnected graph before transferring ownership; validation can fail after 202.\n", "example": { "job_id": 1, "projection_pending": true, @@ -22559,7 +24458,7 @@ "type": "integer" }, "projection_pending": { - "description": "Completed transfers are still reaching task read models.", + "description": "Completed transfers are still reaching task read models. False when preparation failed or the job was cancelled before selecting tasks.", "example": true, "type": "boolean" }, @@ -22696,6 +24595,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -22706,11 +24625,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -22747,6 +24673,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -22757,11 +24703,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "nullable": true @@ -22898,6 +24851,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -22908,11 +24881,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -23137,6 +25117,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -23147,11 +25147,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -23439,6 +25446,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -23449,11 +25476,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -23744,6 +25778,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -23754,11 +25808,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -23925,6 +25986,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -23935,11 +26016,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -24115,6 +26203,7 @@ "needs-review" ], "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", + "thread_template_key": "string", "title": "Example Title", "ttl": "2026-08-15T12:00:00", "unread_count": 5, @@ -24388,6 +26477,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -24398,11 +26507,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -24612,6 +26728,12 @@ "nullable": true, "type": "string" }, + "thread_template_key": { + "description": "Read-only key of the template used to create this thread. `null` for threads not created from a template.", + "example": "string", + "nullable": true, + "type": "string" + }, "title": { "description": "Human-readable name of the thread. `null` if no title has been set.", "example": "Example Title", @@ -24673,6 +26795,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -24683,11 +26825,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "admin": {}, @@ -26150,6 +28299,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -26160,11 +28329,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -26339,6 +28515,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -26349,11 +28545,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "nullable": true, @@ -26411,6 +28614,112 @@ }, "type": "array" }, + "add_denies": { + "description": "Patch mode: denies to add or merge, replacing any grant for the same principal.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, + "denies": { + "description": "Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, "grants": { "description": "Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", "example": [ @@ -26464,6 +28773,11 @@ }, "type": "array" }, + "preserve_denies": { + "description": "Retain current server denies atomically in replacement or patch mode; current denies win.", + "example": true, + "type": "boolean" + }, "remove": { "description": "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", "example": [ @@ -26496,6 +28810,39 @@ "type": "object" }, "type": "array" + }, + "remove_denies": { + "description": "Patch mode: principals whose denies should be removed.", + "example": [ + { + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "Identifies a principal to be removed from an access-control list.", + "example": { + "principal": "string", + "principal_type": "user" + }, + "properties": { + "principal": { + "description": "The identifier of the principal to remove. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`. Omit when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal to remove. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type" + ], + "type": "object" + }, + "type": "array" } }, "type": "object" @@ -28326,6 +30673,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -28336,11 +30703,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] } }, @@ -28358,6 +30732,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -28368,11 +30762,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "properties": { @@ -28429,6 +30830,112 @@ }, "type": "array" }, + "add_denies": { + "description": "Patch mode: denies to add or merge, replacing any grant for the same principal.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, + "denies": { + "description": "Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, "grants": { "description": "Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", "example": [ @@ -28482,6 +30989,11 @@ }, "type": "array" }, + "preserve_denies": { + "description": "Retain current server denies atomically in replacement or patch mode; current denies win.", + "example": true, + "type": "boolean" + }, "remove": { "description": "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", "example": [ @@ -28514,6 +31026,39 @@ "type": "object" }, "type": "array" + }, + "remove_denies": { + "description": "Patch mode: principals whose denies should be removed.", + "example": [ + { + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "Identifies a principal to be removed from an access-control list.", + "example": { + "principal": "string", + "principal_type": "user" + }, + "properties": { + "principal": { + "description": "The identifier of the principal to remove. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`. Omit when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal to remove. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type" + ], + "type": "object" + }, + "type": "array" } }, "type": "object" @@ -28697,6 +31242,9 @@ }, "404": { "description": "Not found" + }, + "409": { + "description": "Managed by the agent's template; change the template's endpoints instead" } }, "summary": "Delete an agent environment variable", @@ -28808,6 +31356,9 @@ "404": { "description": "Not found" }, + "409": { + "description": "Managed by the agent's template; change the template's endpoints instead" + }, "422": { "description": "Validation failed" } @@ -29446,6 +31997,51 @@ ] } }, + "/api/v1/agent_requests/{agent_request}/oauth_start": { + "post": { + "operationId": "post_api_v1_agent_requests__agent_request_oauth_start", + "parameters": [ + { + "description": "OAuth request ID", + "example": "string", + "in": "path", + "name": "agent_request", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "description": "OAuth handoff", + "example": { + "authorization_url": "https://example.com" + }, + "properties": { + "authorization_url": { + "description": "Connector browser handoff URL", + "example": "https://example.com", + "type": "string" + } + }, + "type": "object" + } + } + }, + "description": "Successful response" + } + }, + "summary": "Start an agent OAuth connection", + "x-auth": [ + "publishable_key", + "bearer" + ] + } + }, "/api/v1/agent_requests/{agent_request}/reject": { "post": { "description": "Uses the request context visibility and approver policy. Agents cannot resolve or reject requests.", @@ -30039,6 +32635,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -30049,11 +32665,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "config": "string", @@ -30128,6 +32751,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -30138,11 +32781,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "properties": { @@ -30199,6 +32849,112 @@ }, "type": "array" }, + "add_denies": { + "description": "Patch mode: denies to add or merge, replacing any grant for the same principal.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, + "denies": { + "description": "Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, "grants": { "description": "Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", "example": [ @@ -30252,6 +33008,11 @@ }, "type": "array" }, + "preserve_denies": { + "description": "Retain current server denies atomically in replacement or patch mode; current denies win.", + "example": true, + "type": "boolean" + }, "remove": { "description": "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", "example": [ @@ -30284,6 +33045,39 @@ "type": "object" }, "type": "array" + }, + "remove_denies": { + "description": "Patch mode: principals whose denies should be removed.", + "example": [ + { + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "Identifies a principal to be removed from an access-control list.", + "example": { + "principal": "string", + "principal_type": "user" + }, + "properties": { + "principal": { + "description": "The identifier of the principal to remove. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`. Omit when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal to remove. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type" + ], + "type": "object" + }, + "type": "array" } }, "type": "object" @@ -32499,6 +35293,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -32509,11 +35323,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "description": "An example description.", @@ -32598,6 +35419,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -32608,11 +35449,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "properties": { @@ -32669,6 +35517,112 @@ }, "type": "array" }, + "add_denies": { + "description": "Patch mode: denies to add or merge, replacing any grant for the same principal.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, + "denies": { + "description": "Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, "grants": { "description": "Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", "example": [ @@ -32722,6 +35676,11 @@ }, "type": "array" }, + "preserve_denies": { + "description": "Retain current server denies atomically in replacement or patch mode; current denies win.", + "example": true, + "type": "boolean" + }, "remove": { "description": "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", "example": [ @@ -32754,6 +35713,39 @@ "type": "object" }, "type": "array" + }, + "remove_denies": { + "description": "Patch mode: principals whose denies should be removed.", + "example": [ + { + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "Identifies a principal to be removed from an access-control list.", + "example": { + "principal": "string", + "principal_type": "user" + }, + "properties": { + "principal": { + "description": "The identifier of the principal to remove. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`. Omit when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal to remove. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type" + ], + "type": "object" + }, + "type": "array" } }, "type": "object" @@ -33334,6 +36326,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -33344,11 +36356,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "description": "An example description.", @@ -33385,6 +36404,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -33395,11 +36434,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "properties": { @@ -33456,6 +36502,112 @@ }, "type": "array" }, + "add_denies": { + "description": "Patch mode: denies to add or merge, replacing any grant for the same principal.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, + "denies": { + "description": "Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, "grants": { "description": "Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", "example": [ @@ -33509,6 +36661,11 @@ }, "type": "array" }, + "preserve_denies": { + "description": "Retain current server denies atomically in replacement or patch mode; current denies win.", + "example": true, + "type": "boolean" + }, "remove": { "description": "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", "example": [ @@ -33541,6 +36698,39 @@ "type": "object" }, "type": "array" + }, + "remove_denies": { + "description": "Patch mode: principals whose denies should be removed.", + "example": [ + { + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "Identifies a principal to be removed from an access-control list.", + "example": { + "principal": "string", + "principal_type": "user" + }, + "properties": { + "principal": { + "description": "The identifier of the principal to remove. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`. Omit when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal to remove. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type" + ], + "type": "object" + }, + "type": "array" } }, "type": "object" @@ -33755,6 +36945,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -33765,11 +36975,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "config": {}, @@ -33779,7 +36996,13 @@ }, "name": "Example Name", "provider": "string", - "region": "string" + "region": "string", + "repositories": [ + { + "ref": "string", + "repository": "string" + } + ] }, "properties": { "acl": { @@ -33795,6 +37018,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -33805,11 +37048,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "properties": { @@ -33866,6 +37116,112 @@ }, "type": "array" }, + "add_denies": { + "description": "Patch mode: denies to add or merge, replacing any grant for the same principal.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, + "denies": { + "description": "Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, "grants": { "description": "Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", "example": [ @@ -33919,6 +37275,11 @@ }, "type": "array" }, + "preserve_denies": { + "description": "Retain current server denies atomically in replacement or patch mode; current denies win.", + "example": true, + "type": "boolean" + }, "remove": { "description": "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", "example": [ @@ -33951,6 +37312,39 @@ "type": "object" }, "type": "array" + }, + "remove_denies": { + "description": "Patch mode: principals whose denies should be removed.", + "example": [ + { + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "Identifies a principal to be removed from an access-control list.", + "example": { + "principal": "string", + "principal_type": "user" + }, + "properties": { + "principal": { + "description": "The identifier of the principal to remove. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`. Omit when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal to remove. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type" + ], + "type": "object" + }, + "type": "array" } }, "type": "object" @@ -33986,6 +37380,40 @@ "description": "Region in which to provision the computer, e.g. `\"iad\"`. Defaults to `\"iad\"` when omitted.", "example": "string", "type": "string" + }, + "repositories": { + "description": "Ordered GitHub checkouts (maximum 16): {repository: owner/name, ref: optional ref}. First is primary.", + "example": [ + { + "ref": "string", + "repository": "string" + } + ], + "items": { + "description": "A GitHub repository checkout recorded for later computer bootstrap.", + "example": { + "ref": "string", + "repository": "string" + }, + "properties": { + "ref": { + "description": "Optional checkout ref; null selects the repository's default branch.", + "example": "string", + "nullable": true, + "type": "string" + }, + "repository": { + "description": "GitHub owner/name; supported GitHub URLs are normalized on creation.", + "example": "string", + "type": "string" + } + }, + "required": [ + "repository" + ], + "type": "object" + }, + "type": "array" } }, "required": [ @@ -34496,6 +37924,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -34506,11 +37954,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "config": "string", @@ -34585,6 +38040,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -34595,11 +38070,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "properties": { @@ -34656,6 +38138,112 @@ }, "type": "array" }, + "add_denies": { + "description": "Patch mode: denies to add or merge, replacing any grant for the same principal.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, + "denies": { + "description": "Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, "grants": { "description": "Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", "example": [ @@ -34709,6 +38297,11 @@ }, "type": "array" }, + "preserve_denies": { + "description": "Retain current server denies atomically in replacement or patch mode; current denies win.", + "example": true, + "type": "boolean" + }, "remove": { "description": "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", "example": [ @@ -34741,6 +38334,39 @@ "type": "object" }, "type": "array" + }, + "remove_denies": { + "description": "Patch mode: principals whose denies should be removed.", + "example": [ + { + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "Identifies a principal to be removed from an access-control list.", + "example": { + "principal": "string", + "principal_type": "user" + }, + "properties": { + "principal": { + "description": "The identifier of the principal to remove. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`. Omit when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal to remove. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type" + ], + "type": "object" + }, + "type": "array" } }, "type": "object" @@ -39252,6 +42878,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -39262,11 +42908,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "agent": "string", @@ -39301,6 +42954,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -39311,11 +42984,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "properties": { @@ -39372,6 +43052,112 @@ }, "type": "array" }, + "add_denies": { + "description": "Patch mode: denies to add or merge, replacing any grant for the same principal.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, + "denies": { + "description": "Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, "grants": { "description": "Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", "example": [ @@ -39425,6 +43211,11 @@ }, "type": "array" }, + "preserve_denies": { + "description": "Retain current server denies atomically in replacement or patch mode; current denies win.", + "example": true, + "type": "boolean" + }, "remove": { "description": "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", "example": [ @@ -39457,6 +43248,39 @@ "type": "object" }, "type": "array" + }, + "remove_denies": { + "description": "Patch mode: principals whose denies should be removed.", + "example": [ + { + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "Identifies a principal to be removed from an access-control list.", + "example": { + "principal": "string", + "principal_type": "user" + }, + "properties": { + "principal": { + "description": "The identifier of the principal to remove. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`. Omit when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal to remove. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type" + ], + "type": "object" + }, + "type": "array" } }, "type": "object" @@ -39581,7 +43405,7 @@ "description": "Forbidden" }, "422": { - "description": "Validation error" + "description": "Validation error; ACL denies are not supported by this resource" } }, "summary": "Create an artifact", @@ -39700,6 +43524,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -39710,11 +43554,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "description": "An example description.", @@ -39745,6 +43596,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -39755,11 +43626,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "properties": { @@ -39816,6 +43694,112 @@ }, "type": "array" }, + "add_denies": { + "description": "Patch mode: denies to add or merge, replacing any grant for the same principal.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, + "denies": { + "description": "Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, "grants": { "description": "Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", "example": [ @@ -39869,6 +43853,11 @@ }, "type": "array" }, + "preserve_denies": { + "description": "Retain current server denies atomically in replacement or patch mode; current denies win.", + "example": true, + "type": "boolean" + }, "remove": { "description": "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", "example": [ @@ -39901,6 +43890,39 @@ "type": "object" }, "type": "array" + }, + "remove_denies": { + "description": "Patch mode: principals whose denies should be removed.", + "example": [ + { + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "Identifies a principal to be removed from an access-control list.", + "example": { + "principal": "string", + "principal_type": "user" + }, + "properties": { + "principal": { + "description": "The identifier of the principal to remove. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`. Omit when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal to remove. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type" + ], + "type": "object" + }, + "type": "array" } }, "type": "object" @@ -40014,7 +44036,7 @@ "description": "Version conflict" }, "422": { - "description": "Validation error" + "description": "Validation error; ACL denies are not supported by this resource" } }, "summary": "Update an artifact", @@ -40873,6 +44895,16 @@ "schema": { "type": "string" } + }, + { + "description": "Include payload and result. Set to false for a lightweight status response.", + "example": true, + "in": "query", + "name": "include_payload", + "required": false, + "schema": { + "type": "boolean" + } } ], "responses": { @@ -40884,7 +44916,7 @@ } } }, - "description": "The requested automation run." + "description": "The requested automation run; payload and result are omitted when include_payload is false." }, "401": { "description": "Unauthorized" @@ -40900,6 +44932,9 @@ "x-auth": [ "publishable_key", "bearer" + ], + "x-required-scopes": [ + "automations:read" ] } }, @@ -41180,6 +45215,490 @@ ] } }, + "/api/v1/computers": { + "get": { + "description": "Returns the authenticated user's live computers, oldest first, without pagination. Thread and agent computers are not included. Requires the `devbox_access` entitlement.", + "operationId": "get_api_v1_computers", + "parameters": [], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AgentComputerListResponse" + } + } + }, + "description": "The user's live computers." + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Devbox access is required" + } + }, + "summary": "List your computers", + "x-auth": [ + "publishable_key", + "bearer" + ] + }, + "post": { + "description": "Provisions a computer owned by the authenticated user. Only that user can see or use it. Requires the `devbox_access` entitlement.", + "operationId": "post_api_v1_computers", + "parameters": [], + "requestBody": { + "content": { + "application/json": { + "schema": { + "example": { + "key": "string", + "metadata": { + "key": "value" + }, + "name": "Example Name", + "provider": "string", + "region": "string", + "repositories": [ + { + "ref": "string", + "repository": "string" + } + ], + "setup_bundle": "string" + }, + "properties": { + "key": { + "description": "Stable key unique among your computers.", + "example": "string", + "type": "string" + }, + "metadata": { + "description": "Arbitrary computer metadata.", + "example": { + "key": "value" + }, + "type": "object" + }, + "name": { + "description": "Human-readable computer name.", + "example": "Example Name", + "type": "string" + }, + "provider": { + "description": "Compute backend: devbox (default), sprites, vercel, or e2b.", + "example": "string", + "type": "string" + }, + "region": { + "description": "Provider region.", + "example": "string", + "type": "string" + }, + "repositories": { + "description": "Ordered GitHub checkouts (maximum 16): {repository: owner/name, ref: optional ref}. First is primary.", + "example": [ + { + "ref": "string", + "repository": "string" + } + ], + "items": { + "description": "A GitHub repository checkout recorded for later computer bootstrap.", + "example": { + "ref": "string", + "repository": "string" + }, + "properties": { + "ref": { + "description": "Optional checkout ref; null selects the repository's default branch.", + "example": "string", + "nullable": true, + "type": "string" + }, + "repository": { + "description": "GitHub owner/name; supported GitHub URLs are normalized on creation.", + "example": "string", + "type": "string" + } + }, + "required": [ + "repository" + ], + "type": "object" + }, + "type": "array" + }, + "setup_bundle": { + "description": "Base64 tar.gz repository setup bundle (maximum 512 KiB).", + "example": "string", + "type": "string" + } + }, + "required": [ + "name" + ], + "type": "object" + } + } + }, + "required": true + }, + "responses": { + "201": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AgentComputer" + } + } + }, + "description": "The newly created computer. Returns HTTP 201." + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Devbox access is required" + }, + "422": { + "description": "Invalid computer" + } + }, + "summary": "Create a computer", + "x-auth": [ + "publishable_key", + "bearer" + ] + } + }, + "/api/v1/computers/{computer}": { + "delete": { + "description": "Destroys one of the authenticated user's computers and releases its infrastructure. Irreversible. Requires the `devbox_access` entitlement.", + "operationId": "delete_api_v1_computers__computer", + "parameters": [ + { + "description": "Computer ID (`cmp_...`).", + "example": "string", + "in": "path", + "name": "computer", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "204": { + "description": "Empty response body. Returns HTTP 204 on success." + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Devbox access is required" + }, + "404": { + "description": "Computer not found" + } + }, + "summary": "Delete your computer", + "x-auth": [ + "publishable_key", + "bearer" + ] + }, + "get": { + "description": "Returns a computer the caller can see: their own, a team or agent computer\nvisible to them, or a computer of a thread they can see. A computer the caller\ncannot see is reported as not found.\n\nFor a `ready` or `paused` computer whose provider can pause, `status` is\nchecked against the provider first, so a computer that paused while idle is\nreturned as `paused`.\n", + "operationId": "get_api_v1_computers__computer", + "parameters": [ + { + "description": "Computer ID (`cmp_...`).", + "example": "string", + "in": "path", + "name": "computer", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AgentComputer" + } + } + }, + "description": "The requested computer." + }, + "401": { + "description": "Unauthorized" + }, + "404": { + "description": "Computer not found" + } + }, + "summary": "Retrieve a computer", + "x-auth": [ + "publishable_key", + "bearer" + ] + } + }, + "/api/v1/computers/{computer}/exec": { + "post": { + "description": "Runs a shell command on one of the authenticated user's computers and returns\nits combined output and exit code. The computer must be `ready`; otherwise the\nendpoint returns 409 `computer_not_ready`. A non-zero `exit_code` is not an\nHTTP error. Requires the `devbox_access` entitlement.\n", + "operationId": "post_api_v1_computers__computer_exec", + "parameters": [ + { + "description": "Computer ID (`cmp_...`).", + "example": "string", + "in": "path", + "name": "computer", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "example": { + "command": "string", + "timeout_seconds": 1, + "working_directory": "string" + }, + "properties": { + "command": { + "description": "Shell command to execute.", + "example": "string", + "type": "string" + }, + "timeout_seconds": { + "description": "Command timeout in seconds. Defaults to 60; at most 300.", + "example": 1, + "type": "integer" + }, + "working_directory": { + "description": "Absolute working directory. Defaults to the computer's home directory.", + "example": "string", + "type": "string" + } + }, + "required": [ + "command" + ], + "type": "object" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ComputerExecResult" + } + } + }, + "description": "The output and exit code produced by the command." + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Devbox access is required" + }, + "404": { + "description": "Computer not found" + }, + "409": { + "description": "Computer is not ready" + }, + "422": { + "description": "Invalid timeout or execution failed" + } + }, + "summary": "Run a command on your computer", + "x-auth": [ + "publishable_key", + "bearer" + ] + } + }, + "/api/v1/computers/{computer}/pause": { + "post": { + "description": "Powers a computer down while keeping its disk, and returns it with status\n`paused`. The next command run on it resumes it. Works for any computer the\ncaller can manage: their own, a team computer they administer, an agent's\ncomputer they manage, or a computer of a thread they manage. Pausing a paused\ncomputer succeeds.\n\nReturns 403 when the caller can see the computer but not manage it, 409 when\nit is neither `ready` nor `paused`, and 422 `unsupported` when its provider\ncannot pause.\n", + "operationId": "post_api_v1_computers__computer_pause", + "parameters": [ + { + "description": "Computer ID (`cmp_...`).", + "example": "string", + "in": "path", + "name": "computer", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AgentComputer" + } + } + }, + "description": "The computer in its `\"paused\"` state." + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Not allowed to manage this computer" + }, + "404": { + "description": "Computer not found" + }, + "409": { + "description": "Computer is not ready" + }, + "422": { + "description": "Unsupported provider or provider failure" + } + }, + "summary": "Pause a computer", + "x-auth": [ + "publishable_key", + "bearer" + ] + } + }, + "/api/v1/computers/{computer}/resume": { + "post": { + "description": "Starts a paused computer from its kept disk and returns it with status\n`ready`. Authorized like pause: any computer the caller can manage. Resuming a\nrunning computer succeeds.\n\nReturns 403 when the caller can see the computer but not manage it, 409 when\nit is neither `ready` nor `paused`, and 422 `unsupported` when its provider\ncannot pause or resume.\n", + "operationId": "post_api_v1_computers__computer_resume", + "parameters": [ + { + "description": "Computer ID (`cmp_...`).", + "example": "string", + "in": "path", + "name": "computer", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AgentComputer" + } + } + }, + "description": "The computer in its `\"ready\"` state." + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Not allowed to manage this computer" + }, + "404": { + "description": "Computer not found" + }, + "409": { + "description": "Computer is not ready" + }, + "422": { + "description": "Unsupported provider or provider failure" + } + }, + "summary": "Resume a computer", + "x-auth": [ + "publishable_key", + "bearer" + ] + } + }, + "/api/v1/computers/{computer}/setup": { + "post": { + "operationId": "post_api_v1_computers__computer_setup", + "parameters": [ + { + "example": "string", + "in": "path", + "name": "computer", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "example": { + "force": true, + "setup_bundle": "string" + }, + "properties": { + "force": { + "description": "Run again even when commit and bundle are unchanged.", + "example": true, + "type": "boolean" + }, + "setup_bundle": { + "description": "Replacement base64 tar.gz setup bundle.", + "example": "string", + "type": "string" + } + }, + "type": "object" + } + } + }, + "required": true + }, + "responses": { + "202": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AgentComputer" + } + } + }, + "description": "Successful response" + }, + "409": { + "description": "setup_running" + }, + "422": { + "description": "Invalid setup bundle" + } + }, + "summary": "Run repository setup", + "x-auth": [ + "publishable_key", + "bearer" + ] + } + }, "/api/v1/config": { "get": { "description": "Returns all configs owned by the specified owner. Exactly one owner selector\n(`team`, `user`, or `agent`) must be provided. Passing an unknown or\ninaccessible owner returns an empty `data` array rather than an error, to\navoid leaking information about which teams, users, or agents exist.\n\nUse the `kind`, `lookup_key`, `path_prefix`, `parents`, and\n`parent_solutions` params to narrow results. Private config kinds are always\nexcluded from the response regardless of the viewer's permissions.\n\nResults are not paginated; all matching configs are returned in a single\nresponse.\n", @@ -43874,6 +48393,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -43884,11 +48423,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "agent": "string", @@ -43917,6 +48463,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -43927,11 +48493,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "properties": { @@ -43988,6 +48561,112 @@ }, "type": "array" }, + "add_denies": { + "description": "Patch mode: denies to add or merge, replacing any grant for the same principal.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, + "denies": { + "description": "Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, "grants": { "description": "Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", "example": [ @@ -44041,6 +48720,11 @@ }, "type": "array" }, + "preserve_denies": { + "description": "Retain current server denies atomically in replacement or patch mode; current denies win.", + "example": true, + "type": "boolean" + }, "remove": { "description": "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", "example": [ @@ -44073,6 +48757,39 @@ "type": "object" }, "type": "array" + }, + "remove_denies": { + "description": "Patch mode: principals whose denies should be removed.", + "example": [ + { + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "Identifies a principal to be removed from an access-control list.", + "example": { + "principal": "string", + "principal_type": "user" + }, + "properties": { + "principal": { + "description": "The identifier of the principal to remove. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`. Omit when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal to remove. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type" + ], + "type": "object" + }, + "type": "array" } }, "type": "object" @@ -44294,6 +49011,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -44304,11 +49041,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", @@ -44344,6 +49088,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -44354,11 +49118,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", @@ -44391,6 +49162,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -44401,11 +49192,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "properties": { @@ -44462,6 +49260,112 @@ }, "type": "array" }, + "add_denies": { + "description": "Patch mode: denies to add or merge, replacing any grant for the same principal.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, + "denies": { + "description": "Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, "grants": { "description": "Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", "example": [ @@ -44515,6 +49419,11 @@ }, "type": "array" }, + "preserve_denies": { + "description": "Retain current server denies atomically in replacement or patch mode; current denies win.", + "example": true, + "type": "boolean" + }, "remove": { "description": "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", "example": [ @@ -44547,6 +49456,39 @@ "type": "object" }, "type": "array" + }, + "remove_denies": { + "description": "Patch mode: principals whose denies should be removed.", + "example": [ + { + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "Identifies a principal to be removed from an access-control list.", + "example": { + "principal": "string", + "principal_type": "user" + }, + "properties": { + "principal": { + "description": "The identifier of the principal to remove. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`. Omit when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal to remove. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type" + ], + "type": "object" + }, + "type": "array" } }, "type": "object" @@ -44811,6 +49753,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -44821,11 +49783,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "expected_version": 1, @@ -44849,6 +49818,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -44859,11 +49848,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "properties": { @@ -44920,6 +49916,112 @@ }, "type": "array" }, + "add_denies": { + "description": "Patch mode: denies to add or merge, replacing any grant for the same principal.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, + "denies": { + "description": "Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, "grants": { "description": "Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", "example": [ @@ -44973,6 +50075,11 @@ }, "type": "array" }, + "preserve_denies": { + "description": "Retain current server denies atomically in replacement or patch mode; current denies win.", + "example": true, + "type": "boolean" + }, "remove": { "description": "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", "example": [ @@ -45005,6 +50112,39 @@ "type": "object" }, "type": "array" + }, + "remove_denies": { + "description": "Patch mode: principals whose denies should be removed.", + "example": [ + { + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "Identifies a principal to be removed from an access-control list.", + "example": { + "principal": "string", + "principal_type": "user" + }, + "properties": { + "principal": { + "description": "The identifier of the principal to remove. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`. Omit when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal to remove. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type" + ], + "type": "object" + }, + "type": "array" } }, "type": "object" @@ -45067,6 +50207,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -45077,11 +50237,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", @@ -45117,6 +50284,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -45127,11 +50314,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", @@ -45164,6 +50358,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -45174,11 +50388,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "properties": { @@ -45235,6 +50456,112 @@ }, "type": "array" }, + "add_denies": { + "description": "Patch mode: denies to add or merge, replacing any grant for the same principal.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, + "denies": { + "description": "Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, "grants": { "description": "Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", "example": [ @@ -45288,6 +50615,11 @@ }, "type": "array" }, + "preserve_denies": { + "description": "Retain current server denies atomically in replacement or patch mode; current denies win.", + "example": true, + "type": "boolean" + }, "remove": { "description": "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", "example": [ @@ -45320,6 +50652,39 @@ "type": "object" }, "type": "array" + }, + "remove_denies": { + "description": "Patch mode: principals whose denies should be removed.", + "example": [ + { + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "Identifies a principal to be removed from an access-control list.", + "example": { + "principal": "string", + "principal_type": "user" + }, + "properties": { + "principal": { + "description": "The identifier of the principal to remove. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`. Omit when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal to remove. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type" + ], + "type": "object" + }, + "type": "array" } }, "type": "object" @@ -47014,7 +52379,7 @@ }, "/api/v1/files": { "post": { - "description": "Creates a new file from base64-encoded content and returns the resulting file object,\nincluding a signed download URL. Use this endpoint to store images, documents, or\nother binary assets that can then be referenced by agents, teams, or users.\n\nThe JSON body uses Platform's default 8,000,000-byte parser budget; the\nan upstream proxy in front of Platform may have a separate 32 MiB request cap. Base64 requires\n`4 * ceil(binary_bytes / 3)` bytes, plus the UTF-8 JSON envelope (including\nfilename, owner IDs, escaping and other fields). For an envelope of E bytes,\nbudget at most `3 * floor((8,000,000 - E) / 4)` binary bytes: less than\n6,000,000 bytes (about 5.72 MiB). Do not rely on parser chunk overshoot.\nOversized JSON requests are rejected with HTTP 413 before upload processing.\n\nApp scope is derived from the authenticated viewer's bearer token or publishable key.\nYou may optionally associate the file with an organization, team, user, or agent by\npassing the corresponding ID. If no owner is specified and the viewer is a user, the\nfile is automatically attributed to that user.\n\nPass `share: true` to additionally mint a stable public URL for the file\n(returned as `share_url`), fetchable by anyone without authentication — for\nexample to embed an uploaded image in a GitHub PR body or other external\nmarkdown. The URL does not expire. Sharing is revoked by setting\n`share: false` on `PATCH /api/v1/files/:file` with the same credential\n(or `archastro update file --unshare`); re-enabling sharing\nreactivates previously issued URLs. Only image content types can be\nshared.\n\nReturns `422` when the `data` field is not valid base64, the changeset is\ninvalid, or `share` is requested for a non-image content type.\nReturns `403` when the request lacks the required app scope.\n", + "description": "Creates a new file from base64-encoded content and returns the resulting file object,\nincluding a signed download URL. Use this endpoint to store images, documents, or\nother binary assets that can then be referenced by agents, teams, or users.\n\nThe JSON body uses Platform's default 8,000,000-byte parser budget; the\nan upstream proxy in front of Platform may have a separate 32 MiB request cap. Base64 requires\n`4 * ceil(binary_bytes / 3)` bytes, plus the UTF-8 JSON envelope (including\nfilename, owner IDs, escaping and other fields). For an envelope of E bytes,\nbudget at most `3 * floor((8,000,000 - E) / 4)` binary bytes: less than\n6,000,000 bytes (about 5.72 MiB). Do not rely on parser chunk overshoot.\nOversized JSON requests are rejected with HTTP 413 before upload processing.\n\nPlan editors may opt in with `?plan_image=true`. This route/mode permits a\n13,398,872-byte JSON envelope (base64 for 10,000,000 decoded bytes plus 64 KiB\nmetadata). Plan images must declare PNG, JPEG, GIF or WebP MIME types and\ncontain at most 10,000,000 decoded bytes. Other uploads retain the default\nparser budget and arbitrary content types.\n\nApp scope is derived from the authenticated viewer's bearer token or publishable key.\nYou may optionally associate the file with an organization, team, user, or agent by\npassing the corresponding ID. If no owner is specified and the viewer is a user, the\nfile is automatically attributed to that user.\n\nPass `share: true` to additionally mint a stable public URL for the file\n(returned as `share_url`), fetchable by anyone without authentication — for\nexample to embed an uploaded image in a GitHub PR body or other external\nmarkdown. The URL does not expire. Sharing is revoked by setting\n`share: false` on `PATCH /api/v1/files/:file` with the same credential\n(or `archastro update file --unshare`); re-enabling sharing\nreactivates previously issued URLs. Only image content types can be\nshared.\n\nReturns `422` when the `data` field is not valid base64, the changeset is\ninvalid, or `share` is requested for a non-image content type.\nReturns `403` when the request lacks the required app scope.\n", "operationId": "post_api_v1_files", "parameters": [], "requestBody": { @@ -47033,6 +52398,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -47043,18 +52428,27 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "agent": "string", + "artifact": "string", "content_type": "application/json", "data": "string", "filename": "string", "org": "string", + "plan_image": true, "share": true, "team": "string", "user": "string" @@ -47073,6 +52467,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -47083,11 +52497,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "properties": { @@ -47144,6 +52565,112 @@ }, "type": "array" }, + "add_denies": { + "description": "Patch mode: denies to add or merge, replacing any grant for the same principal.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, + "denies": { + "description": "Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, "grants": { "description": "Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", "example": [ @@ -47197,6 +52724,11 @@ }, "type": "array" }, + "preserve_denies": { + "description": "Retain current server denies atomically in replacement or patch mode; current denies win.", + "example": true, + "type": "boolean" + }, "remove": { "description": "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", "example": [ @@ -47229,6 +52761,39 @@ "type": "object" }, "type": "array" + }, + "remove_denies": { + "description": "Patch mode: principals whose denies should be removed.", + "example": [ + { + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "Identifies a principal to be removed from an access-control list.", + "example": { + "principal": "string", + "principal_type": "user" + }, + "properties": { + "principal": { + "description": "The identifier of the principal to remove. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`. Omit when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal to remove. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type" + ], + "type": "object" + }, + "type": "array" } }, "type": "object" @@ -47238,6 +52803,11 @@ "example": "string", "type": "string" }, + "artifact": { + "description": "Artifact whose current readers may download this attachment. Requires write access; cannot be publicly shared.", + "example": "string", + "type": "string" + }, "content_type": { "description": "MIME type of the file, e.g. `\"image/png\"` or `\"application/pdf\"`.", "example": "application/json", @@ -47258,6 +52828,11 @@ "example": "string", "type": "string" }, + "plan_image": { + "description": "Opt in to plan-image validation: PNG, JPEG, GIF or WebP up to 10,000,000 decoded bytes. Pass as a query parameter to enable the larger request budget.", + "example": true, + "type": "boolean" + }, "share": { "description": "When `true`, marks the file publicly shareable and returns a stable, non-expiring `share_url` fetchable without authentication. Only image content types can be shared.", "example": true, @@ -50690,6 +56265,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -50700,11 +56295,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "agent": "agt_0aBcDeFgHiJkLmNoPqRsTu", @@ -50765,6 +56367,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -50775,11 +56397,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "agent": "agt_0aBcDeFgHiJkLmNoPqRsTu", @@ -50826,6 +56455,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -50836,11 +56485,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "agent": "agt_0aBcDeFgHiJkLmNoPqRsTu", @@ -50886,6 +56542,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -50896,11 +56572,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "nullable": true, @@ -50958,6 +56641,112 @@ }, "type": "array" }, + "add_denies": { + "description": "Patch mode: denies to add or merge, replacing any grant for the same principal.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, + "denies": { + "description": "Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, "grants": { "description": "Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", "example": [ @@ -51011,6 +56800,11 @@ }, "type": "array" }, + "preserve_denies": { + "description": "Retain current server denies atomically in replacement or patch mode; current denies win.", + "example": true, + "type": "boolean" + }, "remove": { "description": "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", "example": [ @@ -51043,6 +56837,39 @@ "type": "object" }, "type": "array" + }, + "remove_denies": { + "description": "Patch mode: principals whose denies should be removed.", + "example": [ + { + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "Identifies a principal to be removed from an access-control list.", + "example": { + "principal": "string", + "principal_type": "user" + }, + "properties": { + "principal": { + "description": "The identifier of the principal to remove. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`. Omit when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal to remove. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type" + ], + "type": "object" + }, + "type": "array" } }, "type": "object" @@ -51400,11 +57227,161 @@ ] } }, + "/api/v1/orgs/{org}/task_deletions": { + "get": { + "description": "Returns visible task tombstones in ascending (deleted_at, task) order.\nTombstones are retained for seven days. Clients must fully resynchronize after\nretention gaps, and periodically reconcile delayed projections. This is not an\nimmutable mutation log. Upsert live tasks by ID and aggregate version.\n", + "operationId": "get_api_v1_orgs__org_task_deletions", + "parameters": [ + { + "description": "Organization ID (`org_...`).", + "example": "string", + "in": "path", + "name": "org", + "required": true, + "schema": { + "type": "string" + } + }, + { + "description": "Page size, capped at 100.", + "example": 1, + "in": "query", + "name": "limit", + "required": false, + "schema": { + "type": "integer" + } + }, + { + "description": "Opaque cursor from the previous page.", + "example": "string", + "in": "query", + "name": "after_cursor", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "example": { + "after_cursor": "string", + "before_cursor": "string", + "data": [ + { + "deleted_at": "string", + "task": "string" + } + ], + "has_more": true + }, + "properties": { + "after_cursor": { + "example": "string", + "nullable": true, + "type": "string" + }, + "before_cursor": { + "example": "string", + "nullable": true, + "type": "string" + }, + "data": { + "example": [ + { + "deleted_at": "string", + "task": "string" + } + ], + "items": { + "description": "A retained visible task deletion.", + "example": { + "deleted_at": "string", + "task": "string" + }, + "properties": { + "deleted_at": { + "example": "string", + "type": "string" + }, + "task": { + "example": "string", + "type": "string" + } + }, + "required": [ + "task", + "deleted_at" + ], + "type": "object" + }, + "type": "array" + }, + "has_more": { + "example": true, + "type": "boolean" + } + }, + "required": [ + "data", + "has_more" + ], + "type": "object" + } + } + }, + "description": "Successful response" + }, + "401": { + "description": "Unauthorized" + }, + "404": { + "description": "Organization not found" + }, + "422": { + "description": "Invalid cursor" + } + }, + "summary": "List visible task deletions", + "x-auth": [ + "publishable_key", + "bearer", + "device_flow" + ], + "x-required-scopes": [ + "tasks:read" + ] + } + }, "/api/v1/orgs/{org}/task_epics": { "get": { "description": "Groups org-owned tasks by their exact epic label, ordered by label. Closed tasks include cancelled tasks, but cancelled prerequisites still block. Source filters select the tasks summarized; blockers outside that selection still affect readiness. Root ranking is capped per epic and root_blockers_partial is true when that graph is truncated. No epic entity is created.", "operationId": "get_api_v1_orgs__org_task_epics", "parameters": [ + { + "description": "labels (default) or entities.", + "example": "string", + "in": "query", + "name": "representation", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "Exact entity name; only used for entities.", + "example": "Example Name", + "in": "query", + "name": "name", + "required": false, + "schema": { + "type": "string" + } + }, { "description": "Organization ID (`org_...`) owning the tasks.", "example": "string", @@ -51455,6 +57432,16 @@ "type": "integer" } }, + { + "description": "Keep only epics with at least one non-closed task owned by this user: `me` or a user public ID (`usr_...`).", + "example": "string", + "in": "query", + "name": "owner", + "required": false, + "schema": { + "type": "string" + } + }, { "description": "Include epics with no non-closed tasks; defaults to false.", "example": true, @@ -51491,260 +57478,459 @@ "content": { "application/json": { "schema": { - "example": { - "after_cursor": "string", - "before_cursor": "string", - "data": [ - { - "blocked_count": 1, - "counts": {}, - "epic": "string", - "next_ready": [ - { - "id": "string", - "name": "Example Name", - "priority": 1, - "status": "string" - } - ], - "root_blockers": [ + "anyOf": [ + { + "example": { + "after_cursor": "string", + "before_cursor": "string", + "data": [ { - "downstream_count": 1, - "id": "string", - "name": "Example Name", - "priority": 1, - "status": "string" - } - ], - "root_blockers_partial": true, - "top_open_priority": 1, - "updated_at": "2024-01-01T00:00:00Z" - } - ], - "has_more": true, - "no_epic_open_count": 1 - }, - "properties": { - "after_cursor": { - "example": "string", - "nullable": true, - "type": "string" - }, - "before_cursor": { - "example": "string", - "nullable": true, - "type": "string" - }, - "data": { - "example": [ - { - "blocked_count": 1, - "counts": {}, - "epic": "string", - "next_ready": [ - { - "id": "string", - "name": "Example Name", - "priority": 1, - "status": "string" - } - ], - "root_blockers": [ - { - "downstream_count": 1, - "id": "string", - "name": "Example Name", - "priority": 1, - "status": "string" - } - ], - "root_blockers_partial": true, - "top_open_priority": 1, - "updated_at": "2024-01-01T00:00:00Z" - } - ], - "items": { - "description": "Read-only progress and scheduling summary for an epic label.", - "example": { - "blocked_count": 1, - "counts": {}, - "epic": "string", - "next_ready": [ - { - "id": "string", + "blocked_count": 1, + "counts": {}, + "epic": "string", + "next_ready": [ + { + "id": "string", + "name": "Example Name", + "priority": 1, + "status": "string" + } + ], + "owner": { + "alias": "alice", + "id": "user-usr_01j3k5m7n9p2r4s6t8v0w1x2", "name": "Example Name", - "priority": 1, - "status": "string" - } - ], - "root_blockers": [ - { - "downstream_count": 1, + "profile_picture": { + "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", + "height": 600, + "media": "med_0aBcDeFgHiJkLmNoPqRsTu", + "mime_type": "application/json", + "refresh_url": "https://example.com", + "url": "https://example.com", + "width": 800 + } + }, + "primary_task": { "id": "string", "name": "Example Name", "priority": 1, "status": "string" - } - ], - "root_blockers_partial": true, - "top_open_priority": 1, - "updated_at": "2024-01-01T00:00:00Z" - }, - "properties": { - "blocked_count": { - "example": 1, - "type": "integer" - }, - "counts": { - "description": "Task counts keyed by status, including closed tasks.", - "example": {}, - "type": "object" - }, - "epic": { - "example": "string", - "type": "string" - }, - "next_ready": { - "example": [ + }, + "root_blockers": [ { + "downstream_count": 1, "id": "string", "name": "Example Name", "priority": 1, "status": "string" } ], - "items": { - "description": "An open task with no unfinished prerequisite or active lease.", - "example": { + "root_blockers_partial": true, + "top_open_priority": 1, + "updated_at": "2024-01-01T00:00:00Z" + } + ], + "has_more": true, + "no_epic_open_count": 1 + }, + "properties": { + "after_cursor": { + "example": "string", + "nullable": true, + "type": "string" + }, + "before_cursor": { + "example": "string", + "nullable": true, + "type": "string" + }, + "data": { + "example": [ + { + "blocked_count": 1, + "counts": {}, + "epic": "string", + "next_ready": [ + { + "id": "string", + "name": "Example Name", + "priority": 1, + "status": "string" + } + ], + "owner": { + "alias": "alice", + "id": "user-usr_01j3k5m7n9p2r4s6t8v0w1x2", + "name": "Example Name", + "profile_picture": { + "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", + "height": 600, + "media": "med_0aBcDeFgHiJkLmNoPqRsTu", + "mime_type": "application/json", + "refresh_url": "https://example.com", + "url": "https://example.com", + "width": 800 + } + }, + "primary_task": { "id": "string", "name": "Example Name", "priority": 1, "status": "string" }, - "properties": { - "id": { - "example": "string", - "type": "string" - }, - "name": { - "example": "Example Name", - "type": "string" - }, - "priority": { - "example": 1, - "type": "integer" - }, - "status": { - "example": "string", - "type": "string" + "root_blockers": [ + { + "downstream_count": 1, + "id": "string", + "name": "Example Name", + "priority": 1, + "status": "string" } - }, - "required": [ - "id", - "name", - "status", - "priority" ], - "type": "object" - }, - "type": "array" - }, - "root_blockers": { - "example": [ - { - "downstream_count": 1, - "id": "string", + "root_blockers_partial": true, + "top_open_priority": 1, + "updated_at": "2024-01-01T00:00:00Z" + } + ], + "items": { + "description": "Read-only progress and scheduling summary for an epic label.", + "example": { + "blocked_count": 1, + "counts": {}, + "epic": "string", + "next_ready": [ + { + "id": "string", + "name": "Example Name", + "priority": 1, + "status": "string" + } + ], + "owner": { + "alias": "alice", + "id": "user-usr_01j3k5m7n9p2r4s6t8v0w1x2", "name": "Example Name", - "priority": 1, - "status": "string" - } - ], - "items": { - "description": "An unblocked root and the number of open tasks downstream within its epic.", - "example": { - "downstream_count": 1, + "profile_picture": { + "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", + "height": 600, + "media": "med_0aBcDeFgHiJkLmNoPqRsTu", + "mime_type": "application/json", + "refresh_url": "https://example.com", + "url": "https://example.com", + "width": 800 + } + }, + "primary_task": { "id": "string", "name": "Example Name", "priority": 1, "status": "string" }, - "properties": { - "downstream_count": { - "example": 1, - "type": "integer" + "root_blockers": [ + { + "downstream_count": 1, + "id": "string", + "name": "Example Name", + "priority": 1, + "status": "string" + } + ], + "root_blockers_partial": true, + "top_open_priority": 1, + "updated_at": "2024-01-01T00:00:00Z" + }, + "properties": { + "blocked_count": { + "example": 1, + "type": "integer" + }, + "counts": { + "description": "Task counts keyed by status, including closed tasks.", + "example": {}, + "type": "object" + }, + "epic": { + "example": "string", + "type": "string" + }, + "next_ready": { + "example": [ + { + "id": "string", + "name": "Example Name", + "priority": 1, + "status": "string" + } + ], + "items": { + "description": "An open task with no unfinished prerequisite or active lease.", + "example": { + "id": "string", + "name": "Example Name", + "priority": 1, + "status": "string" + }, + "properties": { + "id": { + "example": "string", + "type": "string" + }, + "name": { + "example": "Example Name", + "type": "string" + }, + "priority": { + "example": 1, + "type": "integer" + }, + "status": { + "example": "string", + "type": "string" + } + }, + "required": [ + "id", + "name", + "status", + "priority" + ], + "type": "object" }, - "id": { - "example": "string", - "type": "string" + "type": "array" + }, + "owner": { + "description": "Owner of the epic's primary task, as `id`, `name`, `alias` and `profile_picture`. The primary task is the top-ranked root blocker (the open task that unblocks the most work), or when no task blocks another, the highest-priority open task (lowest priority number, then ID). `null` when that task is unassigned or the epic has no open task.", + "example": { + "alias": "alice", + "id": "user-usr_01j3k5m7n9p2r4s6t8v0w1x2", + "name": "Example Name", + "profile_picture": { + "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", + "height": 600, + "media": "med_0aBcDeFgHiJkLmNoPqRsTu", + "mime_type": "application/json", + "refresh_url": "https://example.com", + "url": "https://example.com", + "width": 800 + } }, - "name": { - "example": "Example Name", - "type": "string" + "nullable": true, + "properties": { + "alias": { + "description": "Short handle or alias for the actor, used as an alternate display identifier. `null` if not configured.", + "example": "alice", + "nullable": true, + "type": "string" + }, + "id": { + "description": "Composite actor identifier. Format is `\"user-\"` for human users or `\"agent-\"` for agents.", + "example": "user-usr_01j3k5m7n9p2r4s6t8v0w1x2", + "nullable": true, + "type": "string" + }, + "name": { + "description": "Display name of the actor shown in the UI. `null` if no name is set.", + "example": "Example Name", + "nullable": true, + "type": "string" + }, + "profile_picture": { + "description": "Profile picture for the actor. `null` if the actor has no profile picture.", + "example": { + "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", + "height": 600, + "media": "med_0aBcDeFgHiJkLmNoPqRsTu", + "mime_type": "application/json", + "refresh_url": "https://example.com", + "url": "https://example.com", + "width": 800 + }, + "nullable": true, + "properties": { + "file": { + "description": "ID of the underlying storage file (`fil_...`). `null` when the image is not backed by a platform storage file.", + "example": "fil_0aBcDeFgHiJkLmNoPqRsTu", + "nullable": true, + "type": "string" + }, + "height": { + "description": "Height of the image in pixels. `null` if not known.", + "example": 600, + "nullable": true, + "type": "integer" + }, + "media": { + "description": "ID of the associated media record (`med_...`). `null` when the image is not linked to a media entity.", + "example": "med_0aBcDeFgHiJkLmNoPqRsTu", + "nullable": true, + "type": "string" + }, + "mime_type": { + "description": "MIME type of the image, e.g. `\"image/png\"` or `\"image/jpeg\"`. `null` if not known.", + "example": "application/json", + "nullable": true, + "type": "string" + }, + "refresh_url": { + "description": "Endpoint URL you can call to obtain a fresh signed `url` when the current one has expired. `null` if the URL does not require refreshing.", + "example": "https://example.com", + "nullable": true, + "type": "string" + }, + "url": { + "description": "Signed or public URL for downloading the image. May be time-limited; use `refresh_url` to obtain a new URL when this one expires.", + "example": "https://example.com", + "nullable": true, + "type": "string" + }, + "width": { + "description": "Width of the image in pixels. `null` if not known.", + "example": 800, + "nullable": true, + "type": "integer" + } + }, + "type": "object" + } }, - "priority": { - "example": 1, - "type": "integer" + "type": "object" + }, + "primary_task": { + "description": "The primary task whose owner is reported in `owner`. `null` when the epic has no open task.", + "example": { + "id": "string", + "name": "Example Name", + "priority": 1, + "status": "string" }, - "status": { - "example": "string", - "type": "string" - } + "nullable": true, + "properties": { + "id": { + "example": "string", + "type": "string" + }, + "name": { + "example": "Example Name", + "type": "string" + }, + "priority": { + "example": 1, + "type": "integer" + }, + "status": { + "example": "string", + "type": "string" + } + }, + "required": [ + "id", + "name", + "status", + "priority" + ], + "type": "object" }, - "required": [ - "id", - "name", - "status", - "priority", - "downstream_count" - ], - "type": "object" + "root_blockers": { + "example": [ + { + "downstream_count": 1, + "id": "string", + "name": "Example Name", + "priority": 1, + "status": "string" + } + ], + "items": { + "description": "An unblocked root and the number of open tasks downstream within its epic.", + "example": { + "downstream_count": 1, + "id": "string", + "name": "Example Name", + "priority": 1, + "status": "string" + }, + "properties": { + "downstream_count": { + "example": 1, + "type": "integer" + }, + "id": { + "example": "string", + "type": "string" + }, + "name": { + "example": "Example Name", + "type": "string" + }, + "priority": { + "example": 1, + "type": "integer" + }, + "status": { + "example": "string", + "type": "string" + } + }, + "required": [ + "id", + "name", + "status", + "priority", + "downstream_count" + ], + "type": "object" + }, + "type": "array" + }, + "root_blockers_partial": { + "description": "True when root ranking used a truncated in-epic graph.", + "example": true, + "type": "boolean" + }, + "top_open_priority": { + "example": 1, + "nullable": true, + "type": "integer" + }, + "updated_at": { + "example": "2024-01-01T00:00:00Z", + "format": "date-time", + "type": "string" + } }, - "type": "array" - }, - "root_blockers_partial": { - "description": "True when root ranking used a truncated in-epic graph.", - "example": true, - "type": "boolean" - }, - "top_open_priority": { - "example": 1, - "nullable": true, - "type": "integer" + "required": [ + "epic", + "counts", + "blocked_count", + "updated_at", + "root_blockers", + "root_blockers_partial", + "next_ready" + ], + "type": "object" }, - "updated_at": { - "example": "2024-01-01T00:00:00Z", - "format": "date-time", - "type": "string" - } + "type": "array" }, - "required": [ - "epic", - "counts", - "blocked_count", - "updated_at", - "root_blockers", - "root_blockers_partial", - "next_ready" - ], - "type": "object" + "has_more": { + "example": true, + "type": "boolean" + }, + "no_epic_open_count": { + "example": 1, + "type": "integer" + } }, - "type": "array" - }, - "has_more": { - "example": true, - "type": "boolean" + "required": [ + "data", + "has_more", + "no_epic_open_count" + ], + "type": "object" }, - "no_epic_open_count": { - "example": 1, - "type": "integer" + { + "$ref": "#/components/schemas/TaskEpicEntityCollection" } - }, - "required": [ - "data", - "has_more", - "no_epic_open_count" - ], - "type": "object" + ] } } }, @@ -51765,6 +57951,84 @@ "publishable_key", "bearer" ] + }, + "post": { + "operationId": "post_api_v1_orgs__org_task_epics", + "parameters": [ + { + "example": "string", + "in": "path", + "name": "org", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "example": { + "description": "An example description.", + "metadata": { + "key": "value" + }, + "name": "Example Name", + "state": "string" + }, + "properties": { + "description": { + "example": "An example description.", + "type": "string" + }, + "metadata": { + "example": { + "key": "value" + }, + "type": "object" + }, + "name": { + "example": "Example Name", + "type": "string" + }, + "state": { + "example": "string", + "type": "string" + } + }, + "required": [ + "name" + ], + "type": "object" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TaskEpicEntity" + } + } + }, + "description": "Successful response" + }, + "404": { + "description": "Organization not found or Epics disabled" + }, + "422": { + "description": "Invalid Epic" + } + }, + "summary": "Create an organization task Epic", + "x-auth": [ + "publishable_key", + "bearer" + ] } }, "/api/v1/orgs/{org}/tasks": { @@ -51812,6 +58076,36 @@ "type": "string" } }, + { + "description": "Return only tasks owned by this user: `me` or a user public ID (`usr_...`).", + "example": "string", + "in": "query", + "name": "owner", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "Return only tasks owned or created by this user: `me` or a user public ID (`usr_...`). The \"My work\" predicate.", + "example": "string", + "in": "query", + "name": "involving", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "When true, omit `description` from every task. Use for list views.", + "example": true, + "in": "query", + "name": "summary", + "required": false, + "schema": { + "type": "boolean" + } + }, { "description": "Filter tasks by priority, from 0 (highest) to 4 (lowest).", "example": 1, @@ -51893,7 +58187,17 @@ } }, { - "description": "Sort key. One of `\"created\"` (default — most recently created first), `\"due_date\"` (soonest due first; tasks without a due date always sort last), or `\"priority\"` (most urgent first). Ties break by most recently created.", + "description": "Set to `blockers` to include visible blocker task IDs.", + "example": "string", + "in": "query", + "name": "include", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "Sort key. One of `\"created\"` (default — most recently created first), `\"due_date\"` (soonest due first; tasks without a due date always sort last), `\"priority\"` (most urgent first), or `\"updated\"` (latest-state sync, ties by ID). Updated rows can coalesce or reappear: upsert by ID and aggregate version. Delayed/backdated or equal-time updates behind a cursor require periodic reconciliation. This is not a lossless mutation log.", "example": "string", "in": "query", "name": "sort", @@ -51903,7 +58207,7 @@ } }, { - "description": "Sort direction, `\"asc\"` or `\"desc\"`. Defaults to `\"desc\"` for `created` and `\"asc\"` for `due_date` and `priority`.", + "description": "Sort direction, `\"asc\"` or `\"desc\"`. Defaults to `\"desc\"` for `created` and `\"asc\"` for `updated`, `due_date` and `priority`.", "example": "string", "in": "query", "name": "order", @@ -51997,6 +58301,9 @@ "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", "aggregate_version": 1, "blocked_by_count": 1, + "blockers": [ + "string" + ], "closed_at": "2024-01-01T00:00:00Z", "comments_count": 1, "created_at": "2024-01-01T00:00:00Z", @@ -52024,12 +58331,14 @@ "description": "An example description.", "due_date": "2024-01-01T00:00:00Z", "epic": "string", + "human_answer_receipts": {}, "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, "is_stalled": true, "links": { "key": "value" }, + "machine_rescope_receipts": {}, "metadata": { "key": "value" }, @@ -52066,6 +58375,7 @@ ], "target_binary": "string", "target_version": "string", + "task_epic": "string", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -52092,6 +58402,9 @@ "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", "aggregate_version": 1, "blocked_by_count": 1, + "blockers": [ + "string" + ], "closed_at": "2024-01-01T00:00:00Z", "comments_count": 1, "created_at": "2024-01-01T00:00:00Z", @@ -52119,12 +58432,14 @@ "description": "An example description.", "due_date": "2024-01-01T00:00:00Z", "epic": "string", + "human_answer_receipts": {}, "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, "is_stalled": true, "links": { "key": "value" }, + "machine_rescope_receipts": {}, "metadata": { "key": "value" }, @@ -52161,6 +58476,7 @@ ], "target_binary": "string", "target_version": "string", + "task_epic": "string", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -52173,6 +58489,9 @@ "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", "aggregate_version": 1, "blocked_by_count": 1, + "blockers": [ + "string" + ], "closed_at": "2024-01-01T00:00:00Z", "comments_count": 1, "created_at": "2024-01-01T00:00:00Z", @@ -52200,12 +58519,14 @@ "description": "An example description.", "due_date": "2024-01-01T00:00:00Z", "epic": "string", + "human_answer_receipts": {}, "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, "is_stalled": true, "links": { "key": "value" }, + "machine_rescope_receipts": {}, "metadata": { "key": "value" }, @@ -52242,6 +58563,7 @@ ], "target_binary": "string", "target_version": "string", + "task_epic": "string", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -52265,6 +58587,16 @@ "example": 1, "type": "integer" }, + "blockers": { + "description": "Visible blocker IDs when requested with include=blockers.", + "example": [ + "string" + ], + "items": { + "type": "string" + }, + "type": "array" + }, "closed_at": { "description": "When the task was marked as done or otherwise closed (ISO 8601). `null` if the task is still open.", "example": "2024-01-01T00:00:00Z", @@ -52444,6 +58776,11 @@ "nullable": true, "type": "string" }, + "human_answer_receipts": { + "description": "Server-owned authenticated human answer intent, keyed by question version. Not infrastructure permission.", + "example": {}, + "type": "object" + }, "id": { "description": "Task ID (`tsk_...`).", "example": "tsk_0aBcDeFgHiJkLmNoPqRsTu", @@ -52466,6 +58803,11 @@ }, "type": "object" }, + "machine_rescope_receipts": { + "description": "Server-owned records of machine-applied local rescopes, keyed by question version. Never evidence that a human answered.", + "example": {}, + "type": "object" + }, "metadata": { "description": "Arbitrary key-value map of application-specific data stored alongside the task. Returns an empty object when no metadata has been set.", "example": { @@ -52673,6 +59015,12 @@ "nullable": true, "type": "string" }, + "task_epic": { + "description": "First-class Epic membership; does not grant access to the task.", + "example": "string", + "nullable": true, + "type": "string" + }, "team": { "description": "ID of the team that owns this task (`tem_...`). `null` if the task is not scoped to a team.", "example": "tem_0aBcDeFgHiJkLmNoPqRsTu", @@ -52764,9 +59112,13 @@ "example": { "agent": "string", "task": { + "blockers": [ + "string" + ], "description": "An example description.", "due_date": "2024-01-01T00:00:00Z", "epic": "billing-cadence", + "epic_id": "string", "id": "string", "links": { "key": "value" @@ -52803,9 +59155,13 @@ "task": { "description": "Attributes for the task to create. `name` is required; all other fields are optional.", "example": { + "blockers": [ + "string" + ], "description": "An example description.", "due_date": "2024-01-01T00:00:00Z", "epic": "billing-cadence", + "epic_id": "string", "id": "string", "links": { "key": "value" @@ -52832,6 +59188,16 @@ "thread": "thr_01j3k5m7n9p2r4s6t8v0w1x2" }, "properties": { + "blockers": { + "description": "Existing task IDs (`tsk_...`) that block this task. Recorded atomically with creation; the task is not ready until these blockers are done.", + "example": [ + "string" + ], + "items": { + "type": "string" + }, + "type": "array" + }, "description": { "description": "Optional long-form description or notes for the task. Supports plain text.", "example": "An example description.", @@ -52848,6 +59214,11 @@ "example": "billing-cadence", "type": "string" }, + "epic_id": { + "description": "First-class Epic ID (`epc_...`).", + "example": "string", + "type": "string" + }, "id": { "description": "Optional caller-generated task public ID (`tsk_...`). Persist it before creating a task when creation must survive a lost response. An existing ID returns 409 without modifying the task; read the task by ID to reconcile. Omit for a server-generated ID.", "example": "string", @@ -53047,6 +59418,9 @@ "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", "aggregate_version": 1, "blocked_by_count": 1, + "blockers": [ + "string" + ], "closed_at": "2024-01-01T00:00:00Z", "comments_count": 1, "created_at": "2024-01-01T00:00:00Z", @@ -53074,12 +59448,14 @@ "description": "An example description.", "due_date": "2024-01-01T00:00:00Z", "epic": "string", + "human_answer_receipts": {}, "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, "is_stalled": true, "links": { "key": "value" }, + "machine_rescope_receipts": {}, "metadata": { "key": "value" }, @@ -53116,6 +59492,7 @@ ], "target_binary": "string", "target_version": "string", + "task_epic": "string", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -53143,6 +59520,9 @@ "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", "aggregate_version": 1, "blocked_by_count": 1, + "blockers": [ + "string" + ], "closed_at": "2024-01-01T00:00:00Z", "comments_count": 1, "created_at": "2024-01-01T00:00:00Z", @@ -53170,12 +59550,14 @@ "description": "An example description.", "due_date": "2024-01-01T00:00:00Z", "epic": "string", + "human_answer_receipts": {}, "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, "is_stalled": true, "links": { "key": "value" }, + "machine_rescope_receipts": {}, "metadata": { "key": "value" }, @@ -53212,6 +59594,7 @@ ], "target_binary": "string", "target_version": "string", + "task_epic": "string", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -53228,6 +59611,9 @@ "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", "aggregate_version": 1, "blocked_by_count": 1, + "blockers": [ + "string" + ], "closed_at": "2024-01-01T00:00:00Z", "comments_count": 1, "created_at": "2024-01-01T00:00:00Z", @@ -53255,12 +59641,14 @@ "description": "An example description.", "due_date": "2024-01-01T00:00:00Z", "epic": "string", + "human_answer_receipts": {}, "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, "is_stalled": true, "links": { "key": "value" }, + "machine_rescope_receipts": {}, "metadata": { "key": "value" }, @@ -53297,6 +59685,7 @@ ], "target_binary": "string", "target_version": "string", + "task_epic": "string", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -53312,6 +59701,9 @@ "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", "aggregate_version": 1, "blocked_by_count": 1, + "blockers": [ + "string" + ], "closed_at": "2024-01-01T00:00:00Z", "comments_count": 1, "created_at": "2024-01-01T00:00:00Z", @@ -53339,12 +59731,14 @@ "description": "An example description.", "due_date": "2024-01-01T00:00:00Z", "epic": "string", + "human_answer_receipts": {}, "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, "is_stalled": true, "links": { "key": "value" }, + "machine_rescope_receipts": {}, "metadata": { "key": "value" }, @@ -53381,6 +59775,7 @@ ], "target_binary": "string", "target_version": "string", + "task_epic": "string", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -53393,6 +59788,9 @@ "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", "aggregate_version": 1, "blocked_by_count": 1, + "blockers": [ + "string" + ], "closed_at": "2024-01-01T00:00:00Z", "comments_count": 1, "created_at": "2024-01-01T00:00:00Z", @@ -53420,12 +59818,14 @@ "description": "An example description.", "due_date": "2024-01-01T00:00:00Z", "epic": "string", + "human_answer_receipts": {}, "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, "is_stalled": true, "links": { "key": "value" }, + "machine_rescope_receipts": {}, "metadata": { "key": "value" }, @@ -53462,6 +59862,7 @@ ], "target_binary": "string", "target_version": "string", + "task_epic": "string", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -53485,6 +59886,16 @@ "example": 1, "type": "integer" }, + "blockers": { + "description": "Visible blocker IDs when requested with include=blockers.", + "example": [ + "string" + ], + "items": { + "type": "string" + }, + "type": "array" + }, "closed_at": { "description": "When the task was marked as done or otherwise closed (ISO 8601). `null` if the task is still open.", "example": "2024-01-01T00:00:00Z", @@ -53664,6 +60075,11 @@ "nullable": true, "type": "string" }, + "human_answer_receipts": { + "description": "Server-owned authenticated human answer intent, keyed by question version. Not infrastructure permission.", + "example": {}, + "type": "object" + }, "id": { "description": "Task ID (`tsk_...`).", "example": "tsk_0aBcDeFgHiJkLmNoPqRsTu", @@ -53686,6 +60102,11 @@ }, "type": "object" }, + "machine_rescope_receipts": { + "description": "Server-owned records of machine-applied local rescopes, keyed by question version. Never evidence that a human answered.", + "example": {}, + "type": "object" + }, "metadata": { "description": "Arbitrary key-value map of application-specific data stored alongside the task. Returns an empty object when no metadata has been set.", "example": { @@ -53893,6 +60314,12 @@ "nullable": true, "type": "string" }, + "task_epic": { + "description": "First-class Epic membership; does not grant access to the task.", + "example": "string", + "nullable": true, + "type": "string" + }, "team": { "description": "ID of the team that owns this task (`tem_...`). `null` if the task is not scoped to a team.", "example": "tem_0aBcDeFgHiJkLmNoPqRsTu", @@ -53967,334 +60394,67 @@ ] } }, - "/api/v1/orgs/{org}/tasks/by-source": { - "put": { - "description": "Atomically creates one task per owner, tenant and source. Retries return the current task without updating it. Historical tasks created through ordinary create are not adopted.", - "operationId": "put_api_v1_orgs__org_tasks_by-source", - "parameters": [ - { - "description": "Explicit organization for privileged callers.", - "example": "string", - "in": "path", - "name": "org", - "required": true, - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "example": { - "agent": "string", - "description": "An example description.", - "epic": "string", - "name": "Example Name", - "source_id": "string", - "source_scope": "string", - "source_type": "string", - "status": "string", - "team": "string", - "user": "string" - }, - "properties": { - "agent": { - "description": "Explicit acting agent for privileged callers.", - "example": "string", - "type": "string" - }, - "description": { - "description": "Initial task description.", - "example": "An example description.", - "type": "string" - }, - "epic": { - "description": "Initial epic grouping.", - "example": "string", - "type": "string" - }, - "name": { - "description": "Initial task name.", - "example": "Example Name", - "type": "string" - }, - "source_id": { - "description": "Source identity, for example owner/repo#123.", - "example": "string", - "type": "string" - }, - "source_scope": { - "description": "Source scope, for example github.", - "example": "string", - "type": "string" - }, - "source_type": { - "description": "Source type, for example pull_request.", - "example": "string", - "type": "string" - }, - "status": { - "description": "Initial task status.", - "example": "string", - "type": "string" - }, - "team": { - "description": "Team owner.", - "example": "string", - "type": "string" - }, - "user": { - "description": "User owner, or explicit acting user on a team route.", - "example": "string", - "type": "string" - } - }, - "required": [ - "source_scope", - "source_type", - "source_id", - "name" - ], - "type": "object" - } - } - }, - "required": true - }, - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/TaskEnsureResult" - } - } - }, - "description": "The task and whether this request created it." - }, - "401": { - "description": "Unauthorized" - }, - "404": { - "description": "Task owner not found" - }, - "422": { - "description": "Validation error" - } - }, - "summary": "Find or create a task by source", - "x-auth": [ - "publishable_key", - "bearer" - ] - } - }, - "/api/v1/orgs/{org}/tasks/metrics": { + "/api/v1/orgs/{org}/tasks/by-external-reference": { "get": { - "description": "Returns task activity metrics scoped to org-owned tasks (org tenant, no\nnarrower user/team/agent scope). `open` counts currently open or\nin-progress org tasks, `created` counts tasks inserted in the UTC-day\nwindow, and `completed` counts tasks whose `closed_at` falls in that window\nwhile still in a closed status. Hard-deleted tasks are absent from the\nprojection and therefore omitted. The daily series is zero-filled across\nthe requested window and includes reconstructed end-of-day `open` stock.\n\nAny organization member may read this count-only summary. Requests from\ncallers without org access return 404 so organization existence is not\ndisclosed.\n", - "operationId": "get_api_v1_orgs__org_tasks_metrics", + "description": "Returns all exact external-reference matches owned by the requested principal. Multiple matches remain explicit; callers must not choose an arbitrary task.", + "operationId": "get_api_v1_orgs__org_tasks_by-external-reference", "parameters": [ { - "description": "Organization ID (`org_...`) whose task metrics should be returned.", + "description": "User owner.", "example": "string", - "in": "path", - "name": "org", - "required": true, - "schema": { - "type": "string" - } - }, - { - "description": "UTC-day window. One of 7, 30, 90, or 365; defaults to 30.", - "example": 1, "in": "query", - "name": "days", + "name": "user", "required": false, - "schema": { - "type": "integer" - } - } - ], - "responses": { - "200": { - "content": { - "application/json": { - "schema": { - "description": "Organization-scoped task activity metrics.", - "example": { - "completed": 1, - "created": 1, - "days": 1, - "end_at": "2024-01-01T00:00:00Z", - "open": 1, - "series": [ - {} - ], - "start_at": "2024-01-01T00:00:00Z" - }, - "properties": { - "completed": { - "example": 1, - "type": "integer" - }, - "created": { - "example": 1, - "type": "integer" - }, - "days": { - "example": 1, - "type": "integer" - }, - "end_at": { - "example": "2024-01-01T00:00:00Z", - "format": "date-time", - "type": "string" - }, - "open": { - "example": 1, - "type": "integer" - }, - "series": { - "description": "Zero-filled UTC-day buckets with `date`, end-of-day `open`, `created`, and `completed`.", - "example": [ - {} - ], - "items": { - "type": "object" - }, - "type": "array" - }, - "start_at": { - "example": "2024-01-01T00:00:00Z", - "format": "date-time", - "type": "string" - } - }, - "required": [ - "days", - "start_at", - "end_at", - "open", - "created", - "completed", - "series" - ], - "type": "object" - } - } - }, - "description": "Successful response" - }, - "401": { - "description": "Unauthorized" - }, - "404": { - "description": "Organization not found" - }, - "422": { - "description": "Invalid parameters" - } - }, - "summary": "Get task activity metrics for an organization", - "x-auth": [ - "publishable_key", - "bearer" - ] - } - }, - "/api/v1/orgs/{org}/tasks/ready": { - "get": { - "description": "Returns open org-owned tasks with no unfinished blockers and no active\nsession lease. Readiness is calculated by the server from the current task\nprojection. It is a snapshot, not a reservation; claim a task lease before\nstarting work.\n\nResults are ordered by priority (0, the most urgent, first), then oldest\nfirst, so the first page is always the most urgent ready work.\n\nPass `explain=true` to include every open task with a stable readiness reason.\n", - "operationId": "get_api_v1_orgs__org_tasks_ready", - "parameters": [ - { - "description": "Organization ID (`org_...`) owning the tasks.", - "example": "string", - "in": "path", - "name": "org", - "required": true, "schema": { "type": "string" } }, { - "description": "Include blocked and actively leased open tasks with exclusion reasons.", - "example": true, - "in": "query", - "name": "explain", - "required": false, - "schema": { - "type": "boolean" - } - }, - { - "description": "Only include tasks assigned to the authenticated user.", - "example": true, - "in": "query", - "name": "assigned_to_me", - "required": false, - "schema": { - "type": "boolean" - } - }, - { - "description": "Only include tasks whose source matches this container. Must be supplied with `source_type` and `source_id`.", + "description": "Team owner.", "example": "string", "in": "query", - "name": "source_scope", + "name": "team", "required": false, "schema": { "type": "string" } }, { - "description": "Only include tasks whose source matches this object kind.", + "description": "Organization consistency check.", "example": "string", - "in": "query", - "name": "source_type", - "required": false, + "in": "path", + "name": "org", + "required": true, "schema": { "type": "string" } }, { - "description": "Only include tasks whose source matches this object identity.", + "description": "External host.", "example": "string", "in": "query", - "name": "source_id", - "required": false, + "name": "external_scope", + "required": true, "schema": { "type": "string" } }, { - "description": "Only include tasks with this exact epic label.", + "description": "External object type.", "example": "string", "in": "query", - "name": "epic", - "required": false, + "name": "object_type", + "required": true, "schema": { "type": "string" } }, { - "description": "Maximum number of readiness entries to return. Capped at 100.", - "example": 1, - "in": "query", - "name": "limit", - "required": false, - "schema": { - "type": "integer" - } - }, - { - "description": "Opaque cursor returned by the previous page.", + "description": "External object identity.", "example": "string", "in": "query", - "name": "after_cursor", - "required": false, + "name": "object_id", + "required": true, "schema": { "type": "string" } @@ -54305,19 +60465,105 @@ "content": { "application/json": { "schema": { - "description": "Cursor-paginated readiness results for the organization.", + "description": "Owner-isolated matching tasks.", "example": { - "after_cursor": "string", - "authoritative": true, - "before_cursor": "string", "data": [ { - "readiness": "ready", - "reason": "open_blockers", - "task": { + "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", + "aggregate_version": 1, + "blocked_by_count": 1, + "blockers": [ + "string" + ], + "closed_at": "2024-01-01T00:00:00Z", + "comments_count": 1, + "created_at": "2024-01-01T00:00:00Z", + "created_by_actor": { + "alias": "alice", + "id": "user-usr_01j3k5m7n9p2r4s6t8v0w1x2", + "name": "Example Name", + "profile_picture": { + "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", + "height": 600, + "media": "med_0aBcDeFgHiJkLmNoPqRsTu", + "mime_type": "application/json", + "refresh_url": "https://example.com", + "url": "https://example.com", + "width": 800 + } + }, + "created_by_agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", + "created_by_user": "usr_0aBcDeFgHiJkLmNoPqRsTu", + "current_lease": { + "expires_at": "2024-01-01T00:00:00Z", + "harness": "string", + "session_name": "Example Name" + }, + "description": "An example description.", + "due_date": "2024-01-01T00:00:00Z", + "epic": "string", + "human_answer_receipts": {}, + "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", + "is_blocked": true, + "is_stalled": true, + "links": { + "key": "value" + }, + "machine_rescope_receipts": {}, + "metadata": { + "key": "value" + }, + "name": "Example Name", + "org": "org_0aBcDeFgHiJkLmNoPqRsTu", + "owner_actor": { + "alias": "alice", + "id": "user-usr_01j3k5m7n9p2r4s6t8v0w1x2", + "name": "Example Name", + "profile_picture": { + "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", + "height": 600, + "media": "med_0aBcDeFgHiJkLmNoPqRsTu", + "mime_type": "application/json", + "refresh_url": "https://example.com", + "url": "https://example.com", + "width": 800 + } + }, + "owner_agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", + "owner_user": "usr_0aBcDeFgHiJkLmNoPqRsTu", + "parent": "tsk_0aBcDeFgHiJkLmNoPqRsTu", + "priority": 2, + "project_id": "string", + "sandbox": "dsb_0aBcDeFgHiJkLmNoPqRsTu", + "source_id": "string", + "source_scope": "string", + "source_type": "string", + "stalled_since": "2024-01-01T00:00:00Z", + "status": "open", + "subtasks_count": 1, + "tags": [ + "string" + ], + "target_binary": "string", + "target_version": "string", + "task_epic": "string", + "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", + "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", + "updated_at": "2024-01-01T00:00:00Z", + "user": "usr_0aBcDeFgHiJkLmNoPqRsTu" + } + ] + }, + "properties": { + "data": { + "example": [ + { "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", "aggregate_version": 1, "blocked_by_count": 1, + "blockers": [ + "string" + ], "closed_at": "2024-01-01T00:00:00Z", "comments_count": 1, "created_at": "2024-01-01T00:00:00Z", @@ -54345,12 +60591,14 @@ "description": "An example description.", "due_date": "2024-01-01T00:00:00Z", "epic": "string", + "human_answer_receipts": {}, "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, "is_stalled": true, "links": { "key": "value" }, + "machine_rescope_receipts": {}, "metadata": { "key": "value" }, @@ -54387,6 +60635,1059 @@ ], "target_binary": "string", "target_version": "string", + "task_epic": "string", + "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", + "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", + "updated_at": "2024-01-01T00:00:00Z", + "user": "usr_0aBcDeFgHiJkLmNoPqRsTu" + } + ], + "items": { + "description": "A task representing a unit of work, optionally assignable to a user or agent.", + "example": { + "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", + "aggregate_version": 1, + "blocked_by_count": 1, + "blockers": [ + "string" + ], + "closed_at": "2024-01-01T00:00:00Z", + "comments_count": 1, + "created_at": "2024-01-01T00:00:00Z", + "created_by_actor": { + "alias": "alice", + "id": "user-usr_01j3k5m7n9p2r4s6t8v0w1x2", + "name": "Example Name", + "profile_picture": { + "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", + "height": 600, + "media": "med_0aBcDeFgHiJkLmNoPqRsTu", + "mime_type": "application/json", + "refresh_url": "https://example.com", + "url": "https://example.com", + "width": 800 + } + }, + "created_by_agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", + "created_by_user": "usr_0aBcDeFgHiJkLmNoPqRsTu", + "current_lease": { + "expires_at": "2024-01-01T00:00:00Z", + "harness": "string", + "session_name": "Example Name" + }, + "description": "An example description.", + "due_date": "2024-01-01T00:00:00Z", + "epic": "string", + "human_answer_receipts": {}, + "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", + "is_blocked": true, + "is_stalled": true, + "links": { + "key": "value" + }, + "machine_rescope_receipts": {}, + "metadata": { + "key": "value" + }, + "name": "Example Name", + "org": "org_0aBcDeFgHiJkLmNoPqRsTu", + "owner_actor": { + "alias": "alice", + "id": "user-usr_01j3k5m7n9p2r4s6t8v0w1x2", + "name": "Example Name", + "profile_picture": { + "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", + "height": 600, + "media": "med_0aBcDeFgHiJkLmNoPqRsTu", + "mime_type": "application/json", + "refresh_url": "https://example.com", + "url": "https://example.com", + "width": 800 + } + }, + "owner_agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", + "owner_user": "usr_0aBcDeFgHiJkLmNoPqRsTu", + "parent": "tsk_0aBcDeFgHiJkLmNoPqRsTu", + "priority": 2, + "project_id": "string", + "sandbox": "dsb_0aBcDeFgHiJkLmNoPqRsTu", + "source_id": "string", + "source_scope": "string", + "source_type": "string", + "stalled_since": "2024-01-01T00:00:00Z", + "status": "open", + "subtasks_count": 1, + "tags": [ + "string" + ], + "target_binary": "string", + "target_version": "string", + "task_epic": "string", + "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", + "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", + "updated_at": "2024-01-01T00:00:00Z", + "user": "usr_0aBcDeFgHiJkLmNoPqRsTu" + }, + "properties": { + "agent": { + "description": "ID of the agent that owns this task (`agi_...`). `null` if the task is scoped to a team or user.", + "example": "agi_0aBcDeFgHiJkLmNoPqRsTu", + "nullable": true, + "type": "string" + }, + "aggregate_version": { + "description": "Event-stream version for optimistic update fencing. Pass this value as `expected_version` on an update to reject concurrent writes.", + "example": 1, + "nullable": true, + "type": "integer" + }, + "blocked_by_count": { + "description": "Number of readable tasks marked as blocking this task, whether or not they are done (see `GET /tasks/{task}/blockers`). Computed on list/show reads; create/update responses may lag one read behind.", + "example": 1, + "type": "integer" + }, + "blockers": { + "description": "Visible blocker IDs when requested with include=blockers.", + "example": [ + "string" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "closed_at": { + "description": "When the task was marked as done or otherwise closed (ISO 8601). `null` if the task is still open.", + "example": "2024-01-01T00:00:00Z", + "format": "date-time", + "nullable": true, + "type": "string" + }, + "comments_count": { + "description": "Total number of comments posted on this task.", + "example": 1, + "type": "integer" + }, + "created_at": { + "description": "When the task was created (ISO 8601).", + "example": "2024-01-01T00:00:00Z", + "format": "date-time", + "type": "string" + }, + "created_by_actor": { + "description": "Resolved creator details including `id`, `name`, `alias`, and `profile_picture`. `null` if no creator is set or the creator cannot be resolved (e.g. creating agent was deleted).", + "example": { + "alias": "alice", + "id": "user-usr_01j3k5m7n9p2r4s6t8v0w1x2", + "name": "Example Name", + "profile_picture": { + "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", + "height": 600, + "media": "med_0aBcDeFgHiJkLmNoPqRsTu", + "mime_type": "application/json", + "refresh_url": "https://example.com", + "url": "https://example.com", + "width": 800 + } + }, + "nullable": true, + "properties": { + "alias": { + "description": "Short handle or alias for the actor, used as an alternate display identifier. `null` if not configured.", + "example": "alice", + "nullable": true, + "type": "string" + }, + "id": { + "description": "Composite actor identifier. Format is `\"user-\"` for human users or `\"agent-\"` for agents.", + "example": "user-usr_01j3k5m7n9p2r4s6t8v0w1x2", + "nullable": true, + "type": "string" + }, + "name": { + "description": "Display name of the actor shown in the UI. `null` if no name is set.", + "example": "Example Name", + "nullable": true, + "type": "string" + }, + "profile_picture": { + "description": "Profile picture for the actor. `null` if the actor has no profile picture.", + "example": { + "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", + "height": 600, + "media": "med_0aBcDeFgHiJkLmNoPqRsTu", + "mime_type": "application/json", + "refresh_url": "https://example.com", + "url": "https://example.com", + "width": 800 + }, + "nullable": true, + "properties": { + "file": { + "description": "ID of the underlying storage file (`fil_...`). `null` when the image is not backed by a platform storage file.", + "example": "fil_0aBcDeFgHiJkLmNoPqRsTu", + "nullable": true, + "type": "string" + }, + "height": { + "description": "Height of the image in pixels. `null` if not known.", + "example": 600, + "nullable": true, + "type": "integer" + }, + "media": { + "description": "ID of the associated media record (`med_...`). `null` when the image is not linked to a media entity.", + "example": "med_0aBcDeFgHiJkLmNoPqRsTu", + "nullable": true, + "type": "string" + }, + "mime_type": { + "description": "MIME type of the image, e.g. `\"image/png\"` or `\"image/jpeg\"`. `null` if not known.", + "example": "application/json", + "nullable": true, + "type": "string" + }, + "refresh_url": { + "description": "Endpoint URL you can call to obtain a fresh signed `url` when the current one has expired. `null` if the URL does not require refreshing.", + "example": "https://example.com", + "nullable": true, + "type": "string" + }, + "url": { + "description": "Signed or public URL for downloading the image. May be time-limited; use `refresh_url` to obtain a new URL when this one expires.", + "example": "https://example.com", + "nullable": true, + "type": "string" + }, + "width": { + "description": "Width of the image in pixels. `null` if not known.", + "example": 800, + "nullable": true, + "type": "integer" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "created_by_agent": { + "description": "ID of the agent that created this task (`agi_...`). `null` if the task was created by a human user, or if the creating agent was later deleted.", + "example": "agi_0aBcDeFgHiJkLmNoPqRsTu", + "nullable": true, + "type": "string" + }, + "created_by_user": { + "description": "ID of the user who created this task (`usr_...`). `null` if the task was created by an agent, or if creator provenance was cleared after the creator was deleted.", + "example": "usr_0aBcDeFgHiJkLmNoPqRsTu", + "nullable": true, + "type": "string" + }, + "current_lease": { + "description": "Viewer-safe live coding-session lease summary. `null` when the task is unleased or the projected lease has expired. Fencing identifiers are never included.", + "example": { + "expires_at": "2024-01-01T00:00:00Z", + "harness": "string", + "session_name": "Example Name" + }, + "nullable": true, + "properties": { + "expires_at": { + "description": "Server-calculated lease expiry in ISO 8601 format.", + "example": "2024-01-01T00:00:00Z", + "format": "date-time", + "type": "string" + }, + "harness": { + "description": "Bounded harness identifier for the coding session.", + "example": "string", + "type": "string" + }, + "session_name": { + "description": "Display name supplied by the coding session that holds the lease.", + "example": "Example Name", + "type": "string" + } + }, + "required": [ + "session_name", + "harness", + "expires_at" + ], + "type": "object" + }, + "description": { + "description": "Long-form description or notes for the task. `null` if no description has been provided.", + "example": "An example description.", + "nullable": true, + "type": "string" + }, + "due_date": { + "description": "Date and time by which the task should be completed (ISO 8601). `null` if no due date is set.", + "example": "2024-01-01T00:00:00Z", + "format": "date-time", + "nullable": true, + "type": "string" + }, + "epic": { + "description": "Free-form grouping label. `null` when the task is not in an epic.", + "example": "string", + "nullable": true, + "type": "string" + }, + "human_answer_receipts": { + "description": "Server-owned authenticated human answer intent, keyed by question version. Not infrastructure permission.", + "example": {}, + "type": "object" + }, + "id": { + "description": "Task ID (`tsk_...`).", + "example": "tsk_0aBcDeFgHiJkLmNoPqRsTu", + "type": "string" + }, + "is_blocked": { + "description": "`true` while at least one blocking task is not yet done. Informational only - a blocked task can still change status - and derived at read time, so the task un-blocks automatically when its last open blocker completes. Computed on reads, including mutation responses.", + "example": true, + "type": "boolean" + }, + "is_stalled": { + "description": "True exactly when status is in_progress and the task has no lease or its lease expiry is in the past. Derived at read time from status and lease expiry, including on unannotated reads.", + "example": true, + "type": "boolean" + }, + "links": { + "description": "Key-value map of named URLs or references associated with the task. Returns an empty object when no links have been set.", + "example": { + "key": "value" + }, + "type": "object" + }, + "machine_rescope_receipts": { + "description": "Server-owned records of machine-applied local rescopes, keyed by question version. Never evidence that a human answered.", + "example": {}, + "type": "object" + }, + "metadata": { + "description": "Arbitrary key-value map of application-specific data stored alongside the task. Returns an empty object when no metadata has been set.", + "example": { + "key": "value" + }, + "type": "object" + }, + "name": { + "description": "Human-readable title of the task.", + "example": "Example Name", + "type": "string" + }, + "org": { + "description": "ID of the organization this task belongs to (`org_...`). `null` for tasks outside an org context.", + "example": "org_0aBcDeFgHiJkLmNoPqRsTu", + "nullable": true, + "type": "string" + }, + "owner_actor": { + "description": "Resolved owner details including `id`, `name`, `alias`, and `profile_picture`. `null` if the task is unassigned or the owner cannot be resolved (e.g. assigned agent was deleted).", + "example": { + "alias": "alice", + "id": "user-usr_01j3k5m7n9p2r4s6t8v0w1x2", + "name": "Example Name", + "profile_picture": { + "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", + "height": 600, + "media": "med_0aBcDeFgHiJkLmNoPqRsTu", + "mime_type": "application/json", + "refresh_url": "https://example.com", + "url": "https://example.com", + "width": 800 + } + }, + "nullable": true, + "properties": { + "alias": { + "description": "Short handle or alias for the actor, used as an alternate display identifier. `null` if not configured.", + "example": "alice", + "nullable": true, + "type": "string" + }, + "id": { + "description": "Composite actor identifier. Format is `\"user-\"` for human users or `\"agent-\"` for agents.", + "example": "user-usr_01j3k5m7n9p2r4s6t8v0w1x2", + "nullable": true, + "type": "string" + }, + "name": { + "description": "Display name of the actor shown in the UI. `null` if no name is set.", + "example": "Example Name", + "nullable": true, + "type": "string" + }, + "profile_picture": { + "description": "Profile picture for the actor. `null` if the actor has no profile picture.", + "example": { + "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", + "height": 600, + "media": "med_0aBcDeFgHiJkLmNoPqRsTu", + "mime_type": "application/json", + "refresh_url": "https://example.com", + "url": "https://example.com", + "width": 800 + }, + "nullable": true, + "properties": { + "file": { + "description": "ID of the underlying storage file (`fil_...`). `null` when the image is not backed by a platform storage file.", + "example": "fil_0aBcDeFgHiJkLmNoPqRsTu", + "nullable": true, + "type": "string" + }, + "height": { + "description": "Height of the image in pixels. `null` if not known.", + "example": 600, + "nullable": true, + "type": "integer" + }, + "media": { + "description": "ID of the associated media record (`med_...`). `null` when the image is not linked to a media entity.", + "example": "med_0aBcDeFgHiJkLmNoPqRsTu", + "nullable": true, + "type": "string" + }, + "mime_type": { + "description": "MIME type of the image, e.g. `\"image/png\"` or `\"image/jpeg\"`. `null` if not known.", + "example": "application/json", + "nullable": true, + "type": "string" + }, + "refresh_url": { + "description": "Endpoint URL you can call to obtain a fresh signed `url` when the current one has expired. `null` if the URL does not require refreshing.", + "example": "https://example.com", + "nullable": true, + "type": "string" + }, + "url": { + "description": "Signed or public URL for downloading the image. May be time-limited; use `refresh_url` to obtain a new URL when this one expires.", + "example": "https://example.com", + "nullable": true, + "type": "string" + }, + "width": { + "description": "Width of the image in pixels. `null` if not known.", + "example": 800, + "nullable": true, + "type": "integer" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "owner_agent": { + "description": "ID of the agent assigned as owner (`agi_...`). `null` if the owner is a human user, the task is unassigned, or the assigned agent was deleted.", + "example": "agi_0aBcDeFgHiJkLmNoPqRsTu", + "nullable": true, + "type": "string" + }, + "owner_user": { + "description": "ID of the user assigned as owner (`usr_...`). `null` if the owner is an agent, the task is unassigned, or the assigned agent was deleted.", + "example": "usr_0aBcDeFgHiJkLmNoPqRsTu", + "nullable": true, + "type": "string" + }, + "parent": { + "description": "ID of the parent task when this task is a subtask (`tsk_...`). `null` for top-level tasks or when the parent is not readable. Subtasks nest exactly one level.", + "example": "tsk_0aBcDeFgHiJkLmNoPqRsTu", + "nullable": true, + "type": "string" + }, + "priority": { + "description": "Priority level of the task from `0` (highest) to `4` (lowest). Defaults to `2` (medium) when not explicitly set.", + "example": 2, + "type": "integer" + }, + "project_id": { + "description": "Optional project ID (`prj_...`). Membership does not change task visibility.", + "example": "string", + "nullable": true, + "type": "string" + }, + "sandbox": { + "description": "ID of the developer sandbox this task is scoped to (`dsb_...`). `null` for tasks outside a sandbox environment.", + "example": "dsb_0aBcDeFgHiJkLmNoPqRsTu", + "nullable": true, + "type": "string" + }, + "source_id": { + "description": "Source object identity (for example `ArchAstro/firstlanding`). `null` when the task has no source.", + "example": "string", + "nullable": true, + "type": "string" + }, + "source_scope": { + "description": "Container of the work this task is about (for example `github.com`). `null` when the task has no source. Set together with `source_type` and `source_id`.", + "example": "string", + "nullable": true, + "type": "string" + }, + "source_type": { + "description": "Kind of source object (for example `repository`). `null` when the task has no source.", + "example": "string", + "nullable": true, + "type": "string" + }, + "stalled_since": { + "description": "Lease expiry for a stalled task, or its last update when no lease expiry exists. Null when not stalled.", + "example": "2024-01-01T00:00:00Z", + "format": "date-time", + "nullable": true, + "type": "string" + }, + "status": { + "description": "Current status of the task. One of `\"open\"`, `\"in_progress\"`, `\"in_review\"`, `\"paused\"`, `\"failed\"`, `\"superseding\"`, `\"done\"`, or `\"cancelled\"`.", + "example": "open", + "type": "string" + }, + "subtasks_count": { + "description": "Number of readable subtasks under this task. Computed on list/show reads; create/update responses may report 0 until the next read. Always 0 for subtasks.", + "example": 1, + "type": "integer" + }, + "tags": { + "description": "Labels for grouping and filtering, stored lowercase and de-duplicated. Empty array when untagged.", + "example": [ + "string" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "target_binary": { + "description": "Binary that must run this work (for example `my-cli`). A worker should take the task only when its own `target_binary` build is at least `target_version`. `null` when the task has no target. Set together with `target_version`.", + "example": "string", + "nullable": true, + "type": "string" + }, + "target_version": { + "description": "Minimum semantic version of `target_binary` that can run this work (for example `0.48.9`), in canonical `MAJOR.MINOR.PATCH[-prerelease][+build]` form. `null` when the task has no target.", + "example": "string", + "nullable": true, + "type": "string" + }, + "task_epic": { + "description": "First-class Epic membership; does not grant access to the task.", + "example": "string", + "nullable": true, + "type": "string" + }, + "team": { + "description": "ID of the team that owns this task (`tem_...`). `null` if the task is not scoped to a team.", + "example": "tem_0aBcDeFgHiJkLmNoPqRsTu", + "nullable": true, + "type": "string" + }, + "thread": { + "description": "ID of the thread this task is bound to (`thr_...`) - the conversation it was filed from, or the thread passed at creation. `null` for tasks not tied to a thread.", + "example": "thr_0aBcDeFgHiJkLmNoPqRsTu", + "nullable": true, + "type": "string" + }, + "updated_at": { + "description": "When the task was last modified (ISO 8601).", + "example": "2024-01-01T00:00:00Z", + "format": "date-time", + "type": "string" + }, + "user": { + "description": "ID of the user that owns this task (`usr_...`). `null` if the task is scoped to a team.", + "example": "usr_0aBcDeFgHiJkLmNoPqRsTu", + "nullable": true, + "type": "string" + } + }, + "required": [ + "id", + "name", + "status" + ], + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "data" + ], + "type": "object" + } + } + }, + "description": "Successful response" + }, + "401": { + "description": "Unauthorized" + }, + "404": { + "description": "Task owner not found" + }, + "422": { + "description": "Validation error" + } + }, + "summary": "Find an owner's tasks by external reference", + "x-auth": [ + "publishable_key", + "bearer" + ] + } + }, + "/api/v1/orgs/{org}/tasks/by-source": { + "put": { + "description": "Atomically creates one task per owner, tenant and source. Retries return the current task without updating it. Historical tasks created through ordinary create are not adopted.", + "operationId": "put_api_v1_orgs__org_tasks_by-source", + "parameters": [ + { + "description": "Explicit organization for privileged callers.", + "example": "string", + "in": "path", + "name": "org", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "example": { + "agent": "string", + "description": "An example description.", + "epic": "string", + "name": "Example Name", + "owner_user": "string", + "source_id": "string", + "source_scope": "string", + "source_type": "string", + "status": "string", + "team": "string", + "user": "string" + }, + "properties": { + "agent": { + "description": "Explicit acting agent for privileged callers.", + "example": "string", + "type": "string" + }, + "description": { + "description": "Initial task description.", + "example": "An example description.", + "type": "string" + }, + "epic": { + "description": "Initial epic grouping.", + "example": "string", + "type": "string" + }, + "name": { + "description": "Initial task name.", + "example": "Example Name", + "type": "string" + }, + "owner_user": { + "description": "Initial assigned user; immutable on retries.", + "example": "string", + "type": "string" + }, + "source_id": { + "description": "Source identity, for example owner/repo#123.", + "example": "string", + "type": "string" + }, + "source_scope": { + "description": "Source scope, for example github.", + "example": "string", + "type": "string" + }, + "source_type": { + "description": "Source type, for example pull_request.", + "example": "string", + "type": "string" + }, + "status": { + "description": "Initial task status.", + "example": "string", + "type": "string" + }, + "team": { + "description": "Team owner.", + "example": "string", + "type": "string" + }, + "user": { + "description": "User owner, or explicit acting user on a team route.", + "example": "string", + "type": "string" + } + }, + "required": [ + "source_scope", + "source_type", + "source_id", + "name" + ], + "type": "object" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TaskEnsureResult" + } + } + }, + "description": "The task and whether this request created it." + }, + "401": { + "description": "Unauthorized" + }, + "404": { + "description": "Task owner not found" + }, + "422": { + "description": "Validation error" + } + }, + "summary": "Find or create a task by source", + "x-auth": [ + "publishable_key", + "bearer" + ] + } + }, + "/api/v1/orgs/{org}/tasks/metrics": { + "get": { + "description": "Returns task activity metrics scoped to org-owned tasks (org tenant, no\nnarrower user/team/agent scope). `open` counts currently open or\nin-progress org tasks, `created` counts tasks inserted in the UTC-day\nwindow, and `completed` counts tasks whose `closed_at` falls in that window\nwhile still in a closed status. Hard-deleted tasks are absent from the\nprojection and therefore omitted. The daily series is zero-filled across\nthe requested window and includes reconstructed end-of-day `open` stock.\n\nAny organization member may read this count-only summary. Requests from\ncallers without org access return 404 so organization existence is not\ndisclosed.\n", + "operationId": "get_api_v1_orgs__org_tasks_metrics", + "parameters": [ + { + "description": "Organization ID (`org_...`) whose task metrics should be returned.", + "example": "string", + "in": "path", + "name": "org", + "required": true, + "schema": { + "type": "string" + } + }, + { + "description": "UTC-day window. One of 7, 30, 90, or 365; defaults to 30.", + "example": 1, + "in": "query", + "name": "days", + "required": false, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "description": "Organization-scoped task activity metrics.", + "example": { + "completed": 1, + "created": 1, + "days": 1, + "end_at": "2024-01-01T00:00:00Z", + "open": 1, + "series": [ + {} + ], + "start_at": "2024-01-01T00:00:00Z" + }, + "properties": { + "completed": { + "example": 1, + "type": "integer" + }, + "created": { + "example": 1, + "type": "integer" + }, + "days": { + "example": 1, + "type": "integer" + }, + "end_at": { + "example": "2024-01-01T00:00:00Z", + "format": "date-time", + "type": "string" + }, + "open": { + "example": 1, + "type": "integer" + }, + "series": { + "description": "Zero-filled UTC-day buckets with `date`, end-of-day `open`, `created`, and `completed`.", + "example": [ + {} + ], + "items": { + "type": "object" + }, + "type": "array" + }, + "start_at": { + "example": "2024-01-01T00:00:00Z", + "format": "date-time", + "type": "string" + } + }, + "required": [ + "days", + "start_at", + "end_at", + "open", + "created", + "completed", + "series" + ], + "type": "object" + } + } + }, + "description": "Successful response" + }, + "401": { + "description": "Unauthorized" + }, + "404": { + "description": "Organization not found" + }, + "422": { + "description": "Invalid parameters" + } + }, + "summary": "Get task activity metrics for an organization", + "x-auth": [ + "publishable_key", + "bearer" + ] + } + }, + "/api/v1/orgs/{org}/tasks/ready": { + "get": { + "description": "Returns open org-owned tasks with no unfinished blockers and no active\nsession lease. Readiness is calculated by the server from the current task\nprojection. It is a snapshot, not a reservation; claim a task lease before\nstarting work.\n\nResults are ordered by priority (0, the most urgent, first), then oldest\nfirst, so the first page is always the most urgent ready work.\n\nPass `explain=true` to include every open task with a stable readiness reason.\n", + "operationId": "get_api_v1_orgs__org_tasks_ready", + "parameters": [ + { + "description": "Organization ID (`org_...`) owning the tasks.", + "example": "string", + "in": "path", + "name": "org", + "required": true, + "schema": { + "type": "string" + } + }, + { + "description": "Include blocked and actively leased open tasks with exclusion reasons.", + "example": true, + "in": "query", + "name": "explain", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "description": "Only include tasks assigned to the authenticated user. Equivalent to `owner[]=me`; sending it together with `owner` returns 422.", + "example": true, + "in": "query", + "name": "assigned_to_me", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "description": "Owner kinds to include; the result is the union of the listed kinds. Accepted values: `me` (assigned to the authenticated user) and `unassigned` (no user or agent owner). Agent-assigned tasks match neither value. Omit to include every owner.", + "example": [ + "string" + ], + "in": "query", + "name": "owner", + "required": false, + "schema": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + { + "description": "Only include tasks whose source matches this container. Must be supplied with `source_type` and `source_id`.", + "example": "string", + "in": "query", + "name": "source_scope", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "Only include tasks whose source matches this object kind.", + "example": "string", + "in": "query", + "name": "source_type", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "Only include tasks whose source matches this object identity.", + "example": "string", + "in": "query", + "name": "source_id", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "Only include tasks with this exact epic label.", + "example": "string", + "in": "query", + "name": "epic", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "Maximum number of readiness entries to return. Capped at 100.", + "example": 1, + "in": "query", + "name": "limit", + "required": false, + "schema": { + "type": "integer" + } + }, + { + "description": "Opaque cursor returned by the previous page.", + "example": "string", + "in": "query", + "name": "after_cursor", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "description": "Cursor-paginated readiness results for the organization.", + "example": { + "after_cursor": "string", + "authoritative": true, + "before_cursor": "string", + "data": [ + { + "readiness": "ready", + "reason": "open_blockers", + "task": { + "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", + "aggregate_version": 1, + "blocked_by_count": 1, + "blockers": [ + "string" + ], + "closed_at": "2024-01-01T00:00:00Z", + "comments_count": 1, + "created_at": "2024-01-01T00:00:00Z", + "created_by_actor": { + "alias": "alice", + "id": "user-usr_01j3k5m7n9p2r4s6t8v0w1x2", + "name": "Example Name", + "profile_picture": { + "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", + "height": 600, + "media": "med_0aBcDeFgHiJkLmNoPqRsTu", + "mime_type": "application/json", + "refresh_url": "https://example.com", + "url": "https://example.com", + "width": 800 + } + }, + "created_by_agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", + "created_by_user": "usr_0aBcDeFgHiJkLmNoPqRsTu", + "current_lease": { + "expires_at": "2024-01-01T00:00:00Z", + "harness": "string", + "session_name": "Example Name" + }, + "description": "An example description.", + "due_date": "2024-01-01T00:00:00Z", + "epic": "string", + "human_answer_receipts": {}, + "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", + "is_blocked": true, + "is_stalled": true, + "links": { + "key": "value" + }, + "machine_rescope_receipts": {}, + "metadata": { + "key": "value" + }, + "name": "Example Name", + "org": "org_0aBcDeFgHiJkLmNoPqRsTu", + "owner_actor": { + "alias": "alice", + "id": "user-usr_01j3k5m7n9p2r4s6t8v0w1x2", + "name": "Example Name", + "profile_picture": { + "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", + "height": 600, + "media": "med_0aBcDeFgHiJkLmNoPqRsTu", + "mime_type": "application/json", + "refresh_url": "https://example.com", + "url": "https://example.com", + "width": 800 + } + }, + "owner_agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", + "owner_user": "usr_0aBcDeFgHiJkLmNoPqRsTu", + "parent": "tsk_0aBcDeFgHiJkLmNoPqRsTu", + "priority": 2, + "project_id": "string", + "sandbox": "dsb_0aBcDeFgHiJkLmNoPqRsTu", + "source_id": "string", + "source_scope": "string", + "source_type": "string", + "stalled_since": "2024-01-01T00:00:00Z", + "status": "open", + "subtasks_count": 1, + "tags": [ + "string" + ], + "target_binary": "string", + "target_version": "string", + "task_epic": "string", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -54419,6 +61720,9 @@ "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", "aggregate_version": 1, "blocked_by_count": 1, + "blockers": [ + "string" + ], "closed_at": "2024-01-01T00:00:00Z", "comments_count": 1, "created_at": "2024-01-01T00:00:00Z", @@ -54446,12 +61750,14 @@ "description": "An example description.", "due_date": "2024-01-01T00:00:00Z", "epic": "string", + "human_answer_receipts": {}, "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, "is_stalled": true, "links": { "key": "value" }, + "machine_rescope_receipts": {}, "metadata": { "key": "value" }, @@ -54488,6 +61794,7 @@ ], "target_binary": "string", "target_version": "string", + "task_epic": "string", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -54504,6 +61811,9 @@ "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", "aggregate_version": 1, "blocked_by_count": 1, + "blockers": [ + "string" + ], "closed_at": "2024-01-01T00:00:00Z", "comments_count": 1, "created_at": "2024-01-01T00:00:00Z", @@ -54531,12 +61841,14 @@ "description": "An example description.", "due_date": "2024-01-01T00:00:00Z", "epic": "string", + "human_answer_receipts": {}, "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, "is_stalled": true, "links": { "key": "value" }, + "machine_rescope_receipts": {}, "metadata": { "key": "value" }, @@ -54573,6 +61885,7 @@ ], "target_binary": "string", "target_version": "string", + "task_epic": "string", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -54606,6 +61919,9 @@ "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", "aggregate_version": 1, "blocked_by_count": 1, + "blockers": [ + "string" + ], "closed_at": "2024-01-01T00:00:00Z", "comments_count": 1, "created_at": "2024-01-01T00:00:00Z", @@ -54633,12 +61949,14 @@ "description": "An example description.", "due_date": "2024-01-01T00:00:00Z", "epic": "string", + "human_answer_receipts": {}, "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, "is_stalled": true, "links": { "key": "value" }, + "machine_rescope_receipts": {}, "metadata": { "key": "value" }, @@ -54675,6 +61993,7 @@ ], "target_binary": "string", "target_version": "string", + "task_epic": "string", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -54698,6 +62017,16 @@ "example": 1, "type": "integer" }, + "blockers": { + "description": "Visible blocker IDs when requested with include=blockers.", + "example": [ + "string" + ], + "items": { + "type": "string" + }, + "type": "array" + }, "closed_at": { "description": "When the task was marked as done or otherwise closed (ISO 8601). `null` if the task is still open.", "example": "2024-01-01T00:00:00Z", @@ -54877,6 +62206,11 @@ "nullable": true, "type": "string" }, + "human_answer_receipts": { + "description": "Server-owned authenticated human answer intent, keyed by question version. Not infrastructure permission.", + "example": {}, + "type": "object" + }, "id": { "description": "Task ID (`tsk_...`).", "example": "tsk_0aBcDeFgHiJkLmNoPqRsTu", @@ -54899,6 +62233,11 @@ }, "type": "object" }, + "machine_rescope_receipts": { + "description": "Server-owned records of machine-applied local rescopes, keyed by question version. Never evidence that a human answered.", + "example": {}, + "type": "object" + }, "metadata": { "description": "Arbitrary key-value map of application-specific data stored alongside the task. Returns an empty object when no metadata has been set.", "example": { @@ -55106,6 +62445,12 @@ "nullable": true, "type": "string" }, + "task_epic": { + "description": "First-class Epic membership; does not grant access to the task.", + "example": "string", + "nullable": true, + "type": "string" + }, "team": { "description": "ID of the team that owns this task (`tem_...`). `null` if the task is not scoped to a team.", "example": "tem_0aBcDeFgHiJkLmNoPqRsTu", @@ -55166,11 +62511,14 @@ "401": { "description": "Unauthorized" }, + "403": { + "description": "`owner` includes `me` but the caller is not a user" + }, "404": { "description": "Organization not found" }, "422": { - "description": "Invalid owner context or pagination cursor" + "description": "Invalid owner value, owner combined with assigned_to_me, or invalid pagination cursor" } }, "summary": "List an organization's ready tasks", @@ -55350,6 +62698,9 @@ "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", "aggregate_version": 1, "blocked_by_count": 1, + "blockers": [ + "string" + ], "closed_at": "2024-01-01T00:00:00Z", "comments_count": 1, "created_at": "2024-01-01T00:00:00Z", @@ -55377,12 +62728,14 @@ "description": "An example description.", "due_date": "2024-01-01T00:00:00Z", "epic": "string", + "human_answer_receipts": {}, "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, "is_stalled": true, "links": { "key": "value" }, + "machine_rescope_receipts": {}, "metadata": { "key": "value" }, @@ -55419,6 +62772,7 @@ ], "target_binary": "string", "target_version": "string", + "task_epic": "string", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -55444,6 +62798,9 @@ "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", "aggregate_version": 1, "blocked_by_count": 1, + "blockers": [ + "string" + ], "closed_at": "2024-01-01T00:00:00Z", "comments_count": 1, "created_at": "2024-01-01T00:00:00Z", @@ -55471,12 +62828,14 @@ "description": "An example description.", "due_date": "2024-01-01T00:00:00Z", "epic": "string", + "human_answer_receipts": {}, "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, "is_stalled": true, "links": { "key": "value" }, + "machine_rescope_receipts": {}, "metadata": { "key": "value" }, @@ -55513,6 +62872,7 @@ ], "target_binary": "string", "target_version": "string", + "task_epic": "string", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -55525,6 +62885,9 @@ "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", "aggregate_version": 1, "blocked_by_count": 1, + "blockers": [ + "string" + ], "closed_at": "2024-01-01T00:00:00Z", "comments_count": 1, "created_at": "2024-01-01T00:00:00Z", @@ -55552,12 +62915,14 @@ "description": "An example description.", "due_date": "2024-01-01T00:00:00Z", "epic": "string", + "human_answer_receipts": {}, "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, "is_stalled": true, "links": { "key": "value" }, + "machine_rescope_receipts": {}, "metadata": { "key": "value" }, @@ -55594,6 +62959,7 @@ ], "target_binary": "string", "target_version": "string", + "task_epic": "string", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -55617,6 +62983,16 @@ "example": 1, "type": "integer" }, + "blockers": { + "description": "Visible blocker IDs when requested with include=blockers.", + "example": [ + "string" + ], + "items": { + "type": "string" + }, + "type": "array" + }, "closed_at": { "description": "When the task was marked as done or otherwise closed (ISO 8601). `null` if the task is still open.", "example": "2024-01-01T00:00:00Z", @@ -55796,6 +63172,11 @@ "nullable": true, "type": "string" }, + "human_answer_receipts": { + "description": "Server-owned authenticated human answer intent, keyed by question version. Not infrastructure permission.", + "example": {}, + "type": "object" + }, "id": { "description": "Task ID (`tsk_...`).", "example": "tsk_0aBcDeFgHiJkLmNoPqRsTu", @@ -55818,6 +63199,11 @@ }, "type": "object" }, + "machine_rescope_receipts": { + "description": "Server-owned records of machine-applied local rescopes, keyed by question version. Never evidence that a human answered.", + "example": {}, + "type": "object" + }, "metadata": { "description": "Arbitrary key-value map of application-specific data stored alongside the task. Returns an empty object when no metadata has been set.", "example": { @@ -56025,6 +63411,12 @@ "nullable": true, "type": "string" }, + "task_epic": { + "description": "First-class Epic membership; does not grant access to the task.", + "example": "string", + "nullable": true, + "type": "string" + }, "team": { "description": "ID of the team that owns this task (`tem_...`). `null` if the task is not scoped to a team.", "example": "tem_0aBcDeFgHiJkLmNoPqRsTu", @@ -56096,6 +63488,179 @@ ] } }, + "/api/v1/orgs/{org}/tasks/stream": { + "get": { + "description": "Organization task hints, not a lossless mutation log. Subscribe before reading\nready cursors. Resume tasks with sort=updated&order=asc and deletions with their\nown cursor, retaining each page's after_cursor. Rows may coalesce or reappear;\nupsert by ID/version and periodically reconcile late/backdated/equal-time rows\nbehind a cursor. Gaps beyond seven-day tombstone retention require full resync.\nProjector commit/ack failures can lose hints, so clients must reconcile too.\nCross-batch deduplication retains at most 1024 task IDs in FIFO order; hints\nfor evicted IDs can reappear, so clients must discard older/equal versions.\nPending batches admit at most 512 distinct IDs, bounding visibility queries\nand emitted event lists. Overflow closes the stream; reconnect and reconcile.\n\nThe independently released Rust Factory panel and assignment sweeps consume\nthis contract in https://archdev.ai/tasks/tsk_6ttk2gUwttt6wwkiprwui7.\nThat consumer must not roll out until this provider endpoint and the cursor /\ndeletion contracts are deployed and verified on Platform. Its old-server 404\npolling fallback is compatibility protection, not a substitute for this gate.\n", + "operationId": "get_api_v1_orgs__org_tasks_stream", + "parameters": [ + { + "description": "Organization ID.", + "example": "string", + "in": "path", + "name": "org", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "text/event-stream": { + "schema": { + "oneOf": [ + { + "description": false, + "example": { + "deletions_after_cursor": "string", + "tasks_after_cursor": "string" + }, + "properties": { + "deletions_after_cursor": { + "example": "string", + "nullable": true, + "type": "string" + }, + "tasks_after_cursor": { + "example": "string", + "nullable": true, + "type": "string" + } + }, + "required": [ + "tasks_after_cursor", + "deletions_after_cursor" + ], + "type": "object" + }, + { + "description": false, + "example": { + "aggregate_version": 1, + "id": "string", + "status": "string", + "updated_at": "string" + }, + "properties": { + "aggregate_version": { + "example": 1, + "type": "integer" + }, + "id": { + "example": "string", + "type": "string" + }, + "status": { + "example": "string", + "type": "string" + }, + "updated_at": { + "example": "string", + "type": "string" + } + }, + "required": [ + "id", + "aggregate_version", + "status", + "updated_at" + ], + "type": "object" + }, + { + "$ref": "#/components/schemas/TaskDeletion" + } + ] + } + } + }, + "description": "Server-Sent Events stream" + }, + "401": { + "description": "Unauthorized" + }, + "404": { + "description": "Organization not found" + } + }, + "summary": "Stream organization task changes", + "x-auth": [ + "publishable_key", + "bearer", + "device_flow" + ], + "x-required-scopes": [ + "tasks:read" + ], + "x-sdk-streaming": { + "events": { + "ready": { + "description": false, + "example": { + "deletions_after_cursor": "string", + "tasks_after_cursor": "string" + }, + "properties": { + "deletions_after_cursor": { + "example": "string", + "nullable": true, + "type": "string" + }, + "tasks_after_cursor": { + "example": "string", + "nullable": true, + "type": "string" + } + }, + "required": [ + "tasks_after_cursor", + "deletions_after_cursor" + ], + "type": "object" + }, + "task_changed": { + "description": false, + "example": { + "aggregate_version": 1, + "id": "string", + "status": "string", + "updated_at": "string" + }, + "properties": { + "aggregate_version": { + "example": 1, + "type": "integer" + }, + "id": { + "example": "string", + "type": "string" + }, + "status": { + "example": "string", + "type": "string" + }, + "updated_at": { + "example": "string", + "type": "string" + } + }, + "required": [ + "id", + "aggregate_version", + "status", + "updated_at" + ], + "type": "object" + }, + "task_deleted": { + "$ref": "#/components/schemas/TaskDeletion" + } + }, + "type": "sse" + } + } + }, "/api/v1/orgs/{org}/threads": { "get": { "description": "Returns org-visibility threads for the specified organization. Every member\nof the organization can list these threads; they require no team membership.\nApp-scoped developer tokens for the organization's app can list them too.\n", @@ -56162,6 +63727,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -56172,11 +63757,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -56343,6 +63935,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -56353,11 +63965,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -56533,6 +64152,7 @@ "needs-review" ], "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", + "thread_template_key": "string", "title": "Example Title", "ttl": "2026-08-15T12:00:00", "unread_count": 5, @@ -56578,6 +64198,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -56588,11 +64228,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -56759,6 +64406,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -56769,11 +64436,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -56949,6 +64623,7 @@ "needs-review" ], "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", + "thread_template_key": "string", "title": "Example Title", "ttl": "2026-08-15T12:00:00", "unread_count": 5, @@ -56991,6 +64666,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -57001,11 +64696,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -57172,6 +64874,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -57182,11 +64904,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -57362,6 +65091,7 @@ "needs-review" ], "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", + "thread_template_key": "string", "title": "Example Title", "ttl": "2026-08-15T12:00:00", "unread_count": 5, @@ -57630,6 +65360,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -57640,11 +65390,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -57782,6 +65539,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -57792,11 +65569,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "nullable": true, @@ -57854,6 +65638,112 @@ }, "type": "array" }, + "add_denies": { + "description": "Patch mode: denies to add or merge, replacing any grant for the same principal.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, + "denies": { + "description": "Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, "grants": { "description": "Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", "example": [ @@ -57907,6 +65797,11 @@ }, "type": "array" }, + "preserve_denies": { + "description": "Retain current server denies atomically in replacement or patch mode; current denies win.", + "example": true, + "type": "boolean" + }, "remove": { "description": "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", "example": [ @@ -57939,6 +65834,39 @@ "type": "object" }, "type": "array" + }, + "remove_denies": { + "description": "Patch mode: principals whose denies should be removed.", + "example": [ + { + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "Identifies a principal to be removed from an access-control list.", + "example": { + "principal": "string", + "principal_type": "user" + }, + "properties": { + "principal": { + "description": "The identifier of the principal to remove. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`. Omit when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal to remove. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type" + ], + "type": "object" + }, + "type": "array" } }, "type": "object" @@ -58761,6 +66689,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -58771,11 +66719,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -59309,6 +67264,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -59319,11 +67294,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -59499,6 +67481,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -59509,11 +67511,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -59688,6 +67697,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -59698,11 +67727,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "nullable": true, @@ -59760,6 +67796,112 @@ }, "type": "array" }, + "add_denies": { + "description": "Patch mode: denies to add or merge, replacing any grant for the same principal.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, + "denies": { + "description": "Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, "grants": { "description": "Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", "example": [ @@ -59813,6 +67955,11 @@ }, "type": "array" }, + "preserve_denies": { + "description": "Retain current server denies atomically in replacement or patch mode; current denies win.", + "example": true, + "type": "boolean" + }, "remove": { "description": "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", "example": [ @@ -59845,6 +67992,39 @@ "type": "object" }, "type": "array" + }, + "remove_denies": { + "description": "Patch mode: principals whose denies should be removed.", + "example": [ + { + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "Identifies a principal to be removed from an access-control list.", + "example": { + "principal": "string", + "principal_type": "user" + }, + "properties": { + "principal": { + "description": "The identifier of the principal to remove. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`. Omit when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal to remove. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type" + ], + "type": "object" + }, + "type": "array" } }, "type": "object" @@ -61334,6 +69514,12 @@ "nullable": true, "type": "string" }, + "thread_template_key": { + "description": "Read-only key of the template used to create this thread. `null` for threads not created from a template.", + "example": "string", + "nullable": true, + "type": "string" + }, "title": { "description": "Human-readable name of the thread. `null` if no title has been set.", "example": "Example Title", @@ -64906,6 +73092,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -64916,11 +73122,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "allow_auto_import": true, @@ -64948,6 +73161,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -64958,11 +73191,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "properties": { @@ -65019,6 +73259,112 @@ }, "type": "array" }, + "add_denies": { + "description": "Patch mode: denies to add or merge, replacing any grant for the same principal.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, + "denies": { + "description": "Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, "grants": { "description": "Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", "example": [ @@ -65072,6 +73418,11 @@ }, "type": "array" }, + "preserve_denies": { + "description": "Retain current server denies atomically in replacement or patch mode; current denies win.", + "example": true, + "type": "boolean" + }, "remove": { "description": "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", "example": [ @@ -65104,6 +73455,39 @@ "type": "object" }, "type": "array" + }, + "remove_denies": { + "description": "Patch mode: principals whose denies should be removed.", + "example": [ + { + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "Identifies a principal to be removed from an access-control list.", + "example": { + "principal": "string", + "principal_type": "user" + }, + "properties": { + "principal": { + "description": "The identifier of the principal to remove. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`. Omit when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal to remove. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type" + ], + "type": "object" + }, + "type": "array" } }, "type": "object" @@ -66120,6 +74504,652 @@ ] } }, + "/api/v1/task_epics/{epic}": { + "get": { + "operationId": "get_api_v1_task_epics__epic", + "parameters": [ + { + "example": "string", + "in": "path", + "name": "epic", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TaskEpicEntity" + } + } + }, + "description": "Successful response" + }, + "404": { + "description": "Epic not found" + } + }, + "summary": "Retrieve a task Epic", + "x-auth": [ + "publishable_key", + "bearer" + ] + }, + "patch": { + "operationId": "patch_api_v1_task_epics__epic", + "parameters": [ + { + "example": "string", + "in": "path", + "name": "epic", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "example": { + "description": "An example description.", + "metadata": { + "key": "value" + }, + "name": "Example Name", + "state": "string" + }, + "properties": { + "description": { + "example": "An example description.", + "type": "string" + }, + "metadata": { + "example": { + "key": "value" + }, + "type": "object" + }, + "name": { + "example": "Example Name", + "type": "string" + }, + "state": { + "example": "string", + "type": "string" + } + }, + "type": "object" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TaskEpicEntity" + } + } + }, + "description": "Successful response" + }, + "404": { + "description": "Epic not found" + }, + "422": { + "description": "Invalid Epic" + } + }, + "summary": "Edit a task Epic", + "x-auth": [ + "publishable_key", + "bearer" + ] + } + }, + "/api/v1/task_epics/{epic}/cancel": { + "post": { + "operationId": "post_api_v1_task_epics__epic_cancel", + "parameters": [ + { + "example": "string", + "in": "path", + "name": "epic", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "204": { + "description": "No content" + }, + "404": { + "description": "Epic not found" + } + }, + "summary": "Cancel a task Epic", + "x-auth": [ + "publishable_key", + "bearer" + ] + } + }, + "/api/v1/task_epics/{epic}/drafts": { + "get": { + "operationId": "get_api_v1_task_epics__epic_drafts", + "parameters": [ + { + "example": "string", + "in": "path", + "name": "epic", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TaskEpicDrafts" + } + } + }, + "description": "Successful response" + }, + "404": { + "description": "Epic not found" + }, + "409": { + "description": "Draft conflict" + }, + "422": { + "description": "Invalid drafts" + } + }, + "summary": "Drafts task Epic drafts", + "x-auth": [ + "publishable_key", + "bearer" + ] + }, + "put": { + "operationId": "put_api_v1_task_epics__epic_drafts", + "parameters": [ + { + "example": "string", + "in": "path", + "name": "epic", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "example": { + "expected_drafts_version": 1, + "removes": [ + "string" + ], + "upserts": [ + { + "blocker_keys": [ + "string" + ], + "blocker_tasks": [ + "string" + ], + "description": "An example description.", + "file_ids": [ + "string" + ], + "initial_status": "open", + "key": "string", + "metadata": { + "key": "value" + }, + "name": "Example Name", + "priority": 1, + "tags": [ + "string" + ] + } + ] + }, + "properties": { + "expected_drafts_version": { + "example": 1, + "type": "integer" + }, + "removes": { + "example": [ + "string" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "upserts": { + "example": [ + { + "blocker_keys": [ + "string" + ], + "blocker_tasks": [ + "string" + ], + "description": "An example description.", + "file_ids": [ + "string" + ], + "initial_status": "open", + "key": "string", + "metadata": { + "key": "value" + }, + "name": "Example Name", + "priority": 1, + "tags": [ + "string" + ] + } + ], + "items": { + "description": "Shared input boundary for batch and single Epic draft writes.", + "example": { + "blocker_keys": [ + "string" + ], + "blocker_tasks": [ + "string" + ], + "description": "An example description.", + "file_ids": [ + "string" + ], + "initial_status": "open", + "key": "string", + "metadata": { + "key": "value" + }, + "name": "Example Name", + "priority": 1, + "tags": [ + "string" + ] + }, + "properties": { + "blocker_keys": { + "example": [ + "string" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "blocker_tasks": { + "example": [ + "string" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "description": { + "example": "An example description.", + "type": "string" + }, + "file_ids": { + "example": [ + "string" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "initial_status": { + "enum": [ + "open", + "paused" + ], + "example": "open", + "type": "string" + }, + "key": { + "example": "string", + "type": "string" + }, + "metadata": { + "example": { + "key": "value" + }, + "type": "object" + }, + "name": { + "example": "Example Name", + "type": "string" + }, + "priority": { + "example": 1, + "type": "integer" + }, + "tags": { + "example": [ + "string" + ], + "items": { + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "expected_drafts_version" + ], + "type": "object" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TaskEpicDrafts" + } + } + }, + "description": "Successful response" + }, + "404": { + "description": "Epic not found" + }, + "409": { + "description": "Draft conflict" + }, + "422": { + "description": "Invalid drafts" + } + }, + "summary": "ApplyDrafts task Epic drafts", + "x-auth": [ + "publishable_key", + "bearer" + ] + } + }, + "/api/v1/task_epics/{epic}/drafts/{key}": { + "delete": { + "operationId": "delete_api_v1_task_epics__epic_drafts__key", + "parameters": [ + { + "example": "string", + "in": "path", + "name": "epic", + "required": true, + "schema": { + "type": "string" + } + }, + { + "example": "string", + "in": "path", + "name": "key", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TaskEpicDrafts" + } + } + }, + "description": "Successful response" + }, + "404": { + "description": "Epic not found" + }, + "409": { + "description": "Draft conflict" + }, + "422": { + "description": "Invalid drafts" + } + }, + "summary": "DeleteDraft task Epic drafts", + "x-auth": [ + "publishable_key", + "bearer" + ] + }, + "put": { + "operationId": "put_api_v1_task_epics__epic_drafts__key", + "parameters": [ + { + "example": "string", + "in": "path", + "name": "epic", + "required": true, + "schema": { + "type": "string" + } + }, + { + "example": "string", + "in": "path", + "name": "key", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "example": { + "draft": { + "blocker_keys": [ + "string" + ], + "blocker_tasks": [ + "string" + ], + "description": "An example description.", + "file_ids": [ + "string" + ], + "initial_status": "open", + "key": "string", + "metadata": { + "key": "value" + }, + "name": "Example Name", + "priority": 1, + "tags": [ + "string" + ] + }, + "expected_drafts_version": 1 + }, + "properties": { + "draft": { + "description": "Shared input boundary for batch and single Epic draft writes.", + "example": { + "blocker_keys": [ + "string" + ], + "blocker_tasks": [ + "string" + ], + "description": "An example description.", + "file_ids": [ + "string" + ], + "initial_status": "open", + "key": "string", + "metadata": { + "key": "value" + }, + "name": "Example Name", + "priority": 1, + "tags": [ + "string" + ] + }, + "properties": { + "blocker_keys": { + "example": [ + "string" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "blocker_tasks": { + "example": [ + "string" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "description": { + "example": "An example description.", + "type": "string" + }, + "file_ids": { + "example": [ + "string" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "initial_status": { + "enum": [ + "open", + "paused" + ], + "example": "open", + "type": "string" + }, + "key": { + "example": "string", + "type": "string" + }, + "metadata": { + "example": { + "key": "value" + }, + "type": "object" + }, + "name": { + "example": "Example Name", + "type": "string" + }, + "priority": { + "example": 1, + "type": "integer" + }, + "tags": { + "example": [ + "string" + ], + "items": { + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "expected_drafts_version": { + "example": 1, + "type": "integer" + } + }, + "required": [ + "expected_drafts_version", + "draft" + ], + "type": "object" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TaskEpicDrafts" + } + } + }, + "description": "Successful response" + }, + "404": { + "description": "Epic not found" + }, + "409": { + "description": "Draft conflict" + }, + "422": { + "description": "Invalid drafts" + } + }, + "summary": "PutDraft task Epic drafts", + "x-auth": [ + "publishable_key", + "bearer" + ] + } + }, "/api/v1/task_ownership_conversions/{job_id}": { "get": { "description": "Returns only the requesting user's job status, even after task visibility changes.", @@ -66320,6 +75350,7 @@ "description": "An example description.", "due_date": "2024-01-01T00:00:00Z", "epic": "string", + "epic_id": "string", "expected_version": 1, "lease_id": "string", "lease_session_id": "string", @@ -66369,6 +75400,11 @@ "example": "string", "type": "string" }, + "epic_id": { + "description": "First-class Epic ID; null clears membership.", + "example": "string", + "type": "string" + }, "expected_version": { "description": "Aggregate version returned by the latest task read. The update fails with `task_version_conflict` if the task changed first.", "example": 1, @@ -66789,6 +75825,9 @@ "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", "aggregate_version": 1, "blocked_by_count": 1, + "blockers": [ + "string" + ], "closed_at": "2024-01-01T00:00:00Z", "comments_count": 1, "created_at": "2024-01-01T00:00:00Z", @@ -66816,12 +75855,14 @@ "description": "An example description.", "due_date": "2024-01-01T00:00:00Z", "epic": "string", + "human_answer_receipts": {}, "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, "is_stalled": true, "links": { "key": "value" }, + "machine_rescope_receipts": {}, "metadata": { "key": "value" }, @@ -66858,6 +75899,7 @@ ], "target_binary": "string", "target_version": "string", + "task_epic": "string", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -66881,6 +75923,9 @@ "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", "aggregate_version": 1, "blocked_by_count": 1, + "blockers": [ + "string" + ], "closed_at": "2024-01-01T00:00:00Z", "comments_count": 1, "created_at": "2024-01-01T00:00:00Z", @@ -66908,12 +75953,14 @@ "description": "An example description.", "due_date": "2024-01-01T00:00:00Z", "epic": "string", + "human_answer_receipts": {}, "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, "is_stalled": true, "links": { "key": "value" }, + "machine_rescope_receipts": {}, "metadata": { "key": "value" }, @@ -66950,6 +75997,7 @@ ], "target_binary": "string", "target_version": "string", + "task_epic": "string", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -66962,6 +76010,9 @@ "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", "aggregate_version": 1, "blocked_by_count": 1, + "blockers": [ + "string" + ], "closed_at": "2024-01-01T00:00:00Z", "comments_count": 1, "created_at": "2024-01-01T00:00:00Z", @@ -66989,12 +76040,14 @@ "description": "An example description.", "due_date": "2024-01-01T00:00:00Z", "epic": "string", + "human_answer_receipts": {}, "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, "is_stalled": true, "links": { "key": "value" }, + "machine_rescope_receipts": {}, "metadata": { "key": "value" }, @@ -67031,6 +76084,7 @@ ], "target_binary": "string", "target_version": "string", + "task_epic": "string", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -67054,6 +76108,16 @@ "example": 1, "type": "integer" }, + "blockers": { + "description": "Visible blocker IDs when requested with include=blockers.", + "example": [ + "string" + ], + "items": { + "type": "string" + }, + "type": "array" + }, "closed_at": { "description": "When the task was marked as done or otherwise closed (ISO 8601). `null` if the task is still open.", "example": "2024-01-01T00:00:00Z", @@ -67233,6 +76297,11 @@ "nullable": true, "type": "string" }, + "human_answer_receipts": { + "description": "Server-owned authenticated human answer intent, keyed by question version. Not infrastructure permission.", + "example": {}, + "type": "object" + }, "id": { "description": "Task ID (`tsk_...`).", "example": "tsk_0aBcDeFgHiJkLmNoPqRsTu", @@ -67255,6 +76324,11 @@ }, "type": "object" }, + "machine_rescope_receipts": { + "description": "Server-owned records of machine-applied local rescopes, keyed by question version. Never evidence that a human answered.", + "example": {}, + "type": "object" + }, "metadata": { "description": "Arbitrary key-value map of application-specific data stored alongside the task. Returns an empty object when no metadata has been set.", "example": { @@ -67462,6 +76536,12 @@ "nullable": true, "type": "string" }, + "task_epic": { + "description": "First-class Epic membership; does not grant access to the task.", + "example": "string", + "nullable": true, + "type": "string" + }, "team": { "description": "ID of the team that owns this task (`tem_...`). `null` if the task is not scoped to a team.", "example": "tem_0aBcDeFgHiJkLmNoPqRsTu", @@ -67754,6 +76834,9 @@ "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", "aggregate_version": 1, "blocked_by_count": 1, + "blockers": [ + "string" + ], "closed_at": "2024-01-01T00:00:00Z", "comments_count": 1, "created_at": "2024-01-01T00:00:00Z", @@ -67781,12 +76864,14 @@ "description": "An example description.", "due_date": "2024-01-01T00:00:00Z", "epic": "string", + "human_answer_receipts": {}, "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, "is_stalled": true, "links": { "key": "value" }, + "machine_rescope_receipts": {}, "metadata": { "key": "value" }, @@ -67823,6 +76908,7 @@ ], "target_binary": "string", "target_version": "string", + "task_epic": "string", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -67846,6 +76932,9 @@ "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", "aggregate_version": 1, "blocked_by_count": 1, + "blockers": [ + "string" + ], "closed_at": "2024-01-01T00:00:00Z", "comments_count": 1, "created_at": "2024-01-01T00:00:00Z", @@ -67873,12 +76962,14 @@ "description": "An example description.", "due_date": "2024-01-01T00:00:00Z", "epic": "string", + "human_answer_receipts": {}, "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, "is_stalled": true, "links": { "key": "value" }, + "machine_rescope_receipts": {}, "metadata": { "key": "value" }, @@ -67915,6 +77006,7 @@ ], "target_binary": "string", "target_version": "string", + "task_epic": "string", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -67927,6 +77019,9 @@ "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", "aggregate_version": 1, "blocked_by_count": 1, + "blockers": [ + "string" + ], "closed_at": "2024-01-01T00:00:00Z", "comments_count": 1, "created_at": "2024-01-01T00:00:00Z", @@ -67954,12 +77049,14 @@ "description": "An example description.", "due_date": "2024-01-01T00:00:00Z", "epic": "string", + "human_answer_receipts": {}, "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, "is_stalled": true, "links": { "key": "value" }, + "machine_rescope_receipts": {}, "metadata": { "key": "value" }, @@ -67996,6 +77093,7 @@ ], "target_binary": "string", "target_version": "string", + "task_epic": "string", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -68019,6 +77117,16 @@ "example": 1, "type": "integer" }, + "blockers": { + "description": "Visible blocker IDs when requested with include=blockers.", + "example": [ + "string" + ], + "items": { + "type": "string" + }, + "type": "array" + }, "closed_at": { "description": "When the task was marked as done or otherwise closed (ISO 8601). `null` if the task is still open.", "example": "2024-01-01T00:00:00Z", @@ -68198,6 +77306,11 @@ "nullable": true, "type": "string" }, + "human_answer_receipts": { + "description": "Server-owned authenticated human answer intent, keyed by question version. Not infrastructure permission.", + "example": {}, + "type": "object" + }, "id": { "description": "Task ID (`tsk_...`).", "example": "tsk_0aBcDeFgHiJkLmNoPqRsTu", @@ -68220,6 +77333,11 @@ }, "type": "object" }, + "machine_rescope_receipts": { + "description": "Server-owned records of machine-applied local rescopes, keyed by question version. Never evidence that a human answered.", + "example": {}, + "type": "object" + }, "metadata": { "description": "Arbitrary key-value map of application-specific data stored alongside the task. Returns an empty object when no metadata has been set.", "example": { @@ -68427,6 +77545,12 @@ "nullable": true, "type": "string" }, + "task_epic": { + "description": "First-class Epic membership; does not grant access to the task.", + "example": "string", + "nullable": true, + "type": "string" + }, "team": { "description": "ID of the team that owns this task (`tem_...`). `null` if the task is not scoped to a team.", "example": "tem_0aBcDeFgHiJkLmNoPqRsTu", @@ -69077,6 +78201,119 @@ ] } }, + "/api/v1/tasks/{task}/human-answer": { + "post": { + "description": "Records authenticated human owner intent. The receipt does not grant infrastructure authority.", + "operationId": "post_api_v1_tasks__task_human-answer", + "parameters": [ + { + "description": "Task ID.", + "example": "string", + "in": "path", + "name": "task", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "example": { + "drop_acceptance": "string", + "drop_verification": [ + "string" + ], + "evidence": "string", + "expected_version": 1, + "outcome": "string", + "standing": true, + "text": "string" + }, + "properties": { + "drop_acceptance": { + "description": "Exact unique acceptance item to defer for rescope_local.", + "example": "string", + "type": "string" + }, + "drop_verification": { + "description": "Exact associated verification items to defer. Entries identical to the acceptance item move automatically.", + "example": [ + "string" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "evidence": { + "description": "Evidence link or attachment reference.", + "example": "string", + "type": "string" + }, + "expected_version": { + "description": "Version of the question answered.", + "example": 1, + "type": "integer" + }, + "outcome": { + "description": "evidence, access_granted, or rescope_local.", + "example": "string", + "type": "string" + }, + "standing": { + "description": "Apply this explicit instruction to matching future pauses.", + "example": true, + "type": "boolean" + }, + "text": { + "description": "Optional answer or required access note.", + "example": "string", + "type": "string" + } + }, + "required": [ + "expected_version" + ], + "type": "object" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "type": "object" + } + } + }, + "description": "Server-owned answer receipt." + }, + "401": { + "description": "Unauthorized" + }, + "404": { + "description": "Task not found" + }, + "409": { + "description": "Task changed since it was read" + }, + "422": { + "description": "Invalid parameters" + } + }, + "summary": "Submit a structured human answer", + "x-auth": [ + "publishable_key", + "bearer" + ] + } + }, "/api/v1/tasks/{task}/lease": { "delete": { "description": "Releases the authenticated assignee's matching live task lease. Repeating a\nrelease after the lease is absent succeeds. A different live successor lease\nreturns a mismatch.\n", @@ -69189,6 +78426,7 @@ "application/json": { "schema": { "example": { + "assign_if_ownerless": true, "force": true, "harness": "string", "lease_duration_seconds": 1, @@ -69198,6 +78436,12 @@ "session_name": "Example Name" }, "properties": { + "assign_if_ownerless": { + "default": false, + "description": "Assign an ownerless task to the authenticated system user while claiming its lease.", + "example": true, + "type": "boolean" + }, "force": { "default": false, "description": "Take the lease from a live but dead holder instead of returning a conflict. Releases the prior session's lease and claims the new one atomically. Always scoped to the task's assigned owner, same as an ordinary claim.", @@ -69600,6 +78844,8 @@ "schema": { "example": { "external_scope": "string", + "lease_id": "string", + "lease_session_id": "string", "object_id": "string", "object_type": "string" }, @@ -69609,6 +78855,16 @@ "example": "string", "type": "string" }, + "lease_id": { + "description": "Caller-held lease UUID, paired with lease_session_id.", + "example": "string", + "type": "string" + }, + "lease_session_id": { + "description": "Caller-held coding-session UUID, paired with lease_id.", + "example": "string", + "type": "string" + }, "object_id": { "description": "External object ID.", "example": "string", @@ -69645,9 +78901,15 @@ "401": { "description": "Unauthorized" }, + "403": { + "description": "Task is not assigned to the authenticated user" + }, "404": { "description": "Task not found" }, + "409": { + "description": "Task lease has expired; Task lease does not match the current holder" + }, "422": { "description": "Invalid parameters" }, @@ -69662,9 +78924,79 @@ ] } }, + "/api/v1/tasks/{task}/machine-rescope": { + "post": { + "description": "Applies the `rescope_local` recommendation the Factory recorded with a pause,\nonce the server's own clock shows the question has gone unanswered for the\nminimum age (24 hours). This is a different operation from submitting a human\nanswer: it takes the caller's existing Task edit authority, records a machine\nreceipt in `machine_rescope_receipts` and never a human one, and cannot grant\naccess, attach evidence, approve a sign-off or close the Task. Selections come\nfrom the stored recommendation, never from the request.\n", + "operationId": "post_api_v1_tasks__task_machine-rescope", + "parameters": [ + { + "description": "Task ID.", + "example": "string", + "in": "path", + "name": "task", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "example": { + "expected_version": 1 + }, + "properties": { + "expected_version": { + "description": "Version of the question observed.", + "example": 1, + "type": "integer" + } + }, + "required": [ + "expected_version" + ], + "type": "object" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "type": "object" + } + } + }, + "description": "Server-owned machine rescope receipt." + }, + "401": { + "description": "Unauthorized" + }, + "404": { + "description": "Task not found" + }, + "409": { + "description": "Task changed since it was read" + }, + "422": { + "description": "Invalid parameters" + } + }, + "summary": "Apply a recommended local rescope to an unanswered pause", + "x-auth": [ + "publishable_key", + "bearer" + ] + } + }, "/api/v1/tasks/{task}/ownership_conversions": { "post": { - "description": "Queues ownership changes for the connected task graph across parent, child, blocker, and blocking relationships. The selected tasks and their versions are frozen when queued. Each transfer checks the requesting user’s current authority; conflicts fail the job without undoing completed transfers.", + "description": "Queues ownership changes for the connected task graph across parent, child, blocker, and blocking relationships. The request checks access to the root and returns a job receipt. The worker discovers and validates the graph, then saves the selected tasks and versions before any transfer. Changes before preparation can affect the selection; retries reuse it. Validation failures are job outcomes. Each transfer checks the requesting user’s current authority; conflicts fail the job without undoing completed transfers.", "operationId": "post_api_v1_tasks__task_ownership_conversions", "parameters": [ { @@ -69840,6 +79172,9 @@ "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", "aggregate_version": 1, "blocked_by_count": 1, + "blockers": [ + "string" + ], "closed_at": "2024-01-01T00:00:00Z", "comments_count": 1, "created_at": "2024-01-01T00:00:00Z", @@ -69867,12 +79202,14 @@ "description": "An example description.", "due_date": "2024-01-01T00:00:00Z", "epic": "string", + "human_answer_receipts": {}, "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, "is_stalled": true, "links": { "key": "value" }, + "machine_rescope_receipts": {}, "metadata": { "key": "value" }, @@ -69909,6 +79246,7 @@ ], "target_binary": "string", "target_version": "string", + "task_epic": "string", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -69932,6 +79270,9 @@ "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", "aggregate_version": 1, "blocked_by_count": 1, + "blockers": [ + "string" + ], "closed_at": "2024-01-01T00:00:00Z", "comments_count": 1, "created_at": "2024-01-01T00:00:00Z", @@ -69959,12 +79300,14 @@ "description": "An example description.", "due_date": "2024-01-01T00:00:00Z", "epic": "string", + "human_answer_receipts": {}, "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, "is_stalled": true, "links": { "key": "value" }, + "machine_rescope_receipts": {}, "metadata": { "key": "value" }, @@ -70001,6 +79344,7 @@ ], "target_binary": "string", "target_version": "string", + "task_epic": "string", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -70013,6 +79357,9 @@ "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", "aggregate_version": 1, "blocked_by_count": 1, + "blockers": [ + "string" + ], "closed_at": "2024-01-01T00:00:00Z", "comments_count": 1, "created_at": "2024-01-01T00:00:00Z", @@ -70040,12 +79387,14 @@ "description": "An example description.", "due_date": "2024-01-01T00:00:00Z", "epic": "string", + "human_answer_receipts": {}, "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, "is_stalled": true, "links": { "key": "value" }, + "machine_rescope_receipts": {}, "metadata": { "key": "value" }, @@ -70082,6 +79431,7 @@ ], "target_binary": "string", "target_version": "string", + "task_epic": "string", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -70105,6 +79455,16 @@ "example": 1, "type": "integer" }, + "blockers": { + "description": "Visible blocker IDs when requested with include=blockers.", + "example": [ + "string" + ], + "items": { + "type": "string" + }, + "type": "array" + }, "closed_at": { "description": "When the task was marked as done or otherwise closed (ISO 8601). `null` if the task is still open.", "example": "2024-01-01T00:00:00Z", @@ -70284,6 +79644,11 @@ "nullable": true, "type": "string" }, + "human_answer_receipts": { + "description": "Server-owned authenticated human answer intent, keyed by question version. Not infrastructure permission.", + "example": {}, + "type": "object" + }, "id": { "description": "Task ID (`tsk_...`).", "example": "tsk_0aBcDeFgHiJkLmNoPqRsTu", @@ -70306,6 +79671,11 @@ }, "type": "object" }, + "machine_rescope_receipts": { + "description": "Server-owned records of machine-applied local rescopes, keyed by question version. Never evidence that a human answered.", + "example": {}, + "type": "object" + }, "metadata": { "description": "Arbitrary key-value map of application-specific data stored alongside the task. Returns an empty object when no metadata has been set.", "example": { @@ -70513,6 +79883,12 @@ "nullable": true, "type": "string" }, + "task_epic": { + "description": "First-class Epic membership; does not grant access to the task.", + "example": "string", + "nullable": true, + "type": "string" + }, "team": { "description": "ID of the team that owns this task (`tem_...`). `null` if the task is not scoped to a team.", "example": "tem_0aBcDeFgHiJkLmNoPqRsTu", @@ -70970,6 +80346,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -70980,11 +80376,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -71026,6 +80429,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -71036,11 +80459,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -71073,6 +80503,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -71083,11 +80533,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -71119,6 +80576,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -71129,11 +80606,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "nullable": true, @@ -71191,6 +80675,112 @@ }, "type": "array" }, + "add_denies": { + "description": "Patch mode: denies to add or merge, replacing any grant for the same principal.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, + "denies": { + "description": "Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, "grants": { "description": "Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", "example": [ @@ -71244,6 +80834,11 @@ }, "type": "array" }, + "preserve_denies": { + "description": "Retain current server denies atomically in replacement or patch mode; current denies win.", + "example": true, + "type": "boolean" + }, "remove": { "description": "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", "example": [ @@ -71276,6 +80871,39 @@ "type": "object" }, "type": "array" + }, + "remove_denies": { + "description": "Patch mode: principals whose denies should be removed.", + "example": [ + { + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "Identifies a principal to be removed from an access-control list.", + "example": { + "principal": "string", + "principal_type": "user" + }, + "properties": { + "principal": { + "description": "The identifier of the principal to remove. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`. Omit when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal to remove. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type" + ], + "type": "object" + }, + "type": "array" } }, "type": "object" @@ -71440,6 +81068,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -71450,11 +81098,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "description": "An example description.", @@ -71479,6 +81134,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -71489,11 +81164,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "properties": { @@ -71550,6 +81232,112 @@ }, "type": "array" }, + "add_denies": { + "description": "Patch mode: denies to add or merge, replacing any grant for the same principal.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, + "denies": { + "description": "Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, "grants": { "description": "Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", "example": [ @@ -71603,6 +81391,11 @@ }, "type": "array" }, + "preserve_denies": { + "description": "Retain current server denies atomically in replacement or patch mode; current denies win.", + "example": true, + "type": "boolean" + }, "remove": { "description": "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", "example": [ @@ -71635,6 +81428,39 @@ "type": "object" }, "type": "array" + }, + "remove_denies": { + "description": "Patch mode: principals whose denies should be removed.", + "example": [ + { + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "Identifies a principal to be removed from an access-control list.", + "example": { + "principal": "string", + "principal_type": "user" + }, + "properties": { + "principal": { + "description": "The identifier of the principal to remove. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`. Omit when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal to remove. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type" + ], + "type": "object" + }, + "type": "array" } }, "type": "object" @@ -71887,6 +81713,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -71897,11 +81743,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "description": "An example description.", @@ -71929,6 +81782,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -71939,11 +81812,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "properties": { @@ -72000,6 +81880,112 @@ }, "type": "array" }, + "add_denies": { + "description": "Patch mode: denies to add or merge, replacing any grant for the same principal.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, + "denies": { + "description": "Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, "grants": { "description": "Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", "example": [ @@ -72053,6 +82039,11 @@ }, "type": "array" }, + "preserve_denies": { + "description": "Retain current server denies atomically in replacement or patch mode; current denies win.", + "example": true, + "type": "boolean" + }, "remove": { "description": "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", "example": [ @@ -72085,6 +82076,39 @@ "type": "object" }, "type": "array" + }, + "remove_denies": { + "description": "Patch mode: principals whose denies should be removed.", + "example": [ + { + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "Identifies a principal to be removed from an access-control list.", + "example": { + "principal": "string", + "principal_type": "user" + }, + "properties": { + "principal": { + "description": "The identifier of the principal to remove. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`. Omit when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal to remove. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type" + ], + "type": "object" + }, + "type": "array" } }, "type": "object" @@ -72226,6 +82250,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -72236,11 +82280,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "agent": "agt_0aBcDeFgHiJkLmNoPqRsTu", @@ -72290,6 +82341,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -72300,11 +82371,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "agent": "agt_0aBcDeFgHiJkLmNoPqRsTu", @@ -72351,6 +82429,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -72361,11 +82459,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "agent": "agt_0aBcDeFgHiJkLmNoPqRsTu", @@ -72411,6 +82516,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -72421,11 +82546,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "nullable": true, @@ -72483,6 +82615,112 @@ }, "type": "array" }, + "add_denies": { + "description": "Patch mode: denies to add or merge, replacing any grant for the same principal.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, + "denies": { + "description": "Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, "grants": { "description": "Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", "example": [ @@ -72536,6 +82774,11 @@ }, "type": "array" }, + "preserve_denies": { + "description": "Retain current server denies atomically in replacement or patch mode; current denies win.", + "example": true, + "type": "boolean" + }, "remove": { "description": "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", "example": [ @@ -72568,6 +82811,39 @@ "type": "object" }, "type": "array" + }, + "remove_denies": { + "description": "Patch mode: principals whose denies should be removed.", + "example": [ + { + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "Identifies a principal to be removed from an access-control list.", + "example": { + "principal": "string", + "principal_type": "user" + }, + "properties": { + "principal": { + "description": "The identifier of the principal to remove. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`. Omit when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal to remove. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type" + ], + "type": "object" + }, + "type": "array" } }, "type": "object" @@ -72858,6 +83134,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -72868,11 +83164,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", @@ -72910,6 +83213,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -72920,11 +83243,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", @@ -72958,6 +83288,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -72968,11 +83318,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", @@ -73005,6 +83362,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -73015,11 +83392,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "properties": { @@ -73076,6 +83460,112 @@ }, "type": "array" }, + "add_denies": { + "description": "Patch mode: denies to add or merge, replacing any grant for the same principal.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, + "denies": { + "description": "Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, "grants": { "description": "Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", "example": [ @@ -73129,6 +83619,11 @@ }, "type": "array" }, + "preserve_denies": { + "description": "Retain current server denies atomically in replacement or patch mode; current denies win.", + "example": true, + "type": "boolean" + }, "remove": { "description": "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", "example": [ @@ -73161,6 +83656,39 @@ "type": "object" }, "type": "array" + }, + "remove_denies": { + "description": "Patch mode: principals whose denies should be removed.", + "example": [ + { + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "Identifies a principal to be removed from an access-control list.", + "example": { + "principal": "string", + "principal_type": "user" + }, + "properties": { + "principal": { + "description": "The identifier of the principal to remove. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`. Omit when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal to remove. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type" + ], + "type": "object" + }, + "type": "array" } }, "type": "object" @@ -73727,6 +84255,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -73737,11 +84285,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -73965,6 +84520,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -73975,11 +84550,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -74200,6 +84782,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -74210,11 +84812,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -74434,6 +85043,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -74444,11 +85073,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -74624,6 +85260,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -74634,11 +85290,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "nullable": true, @@ -74696,6 +85359,112 @@ }, "type": "array" }, + "add_denies": { + "description": "Patch mode: denies to add or merge, replacing any grant for the same principal.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, + "denies": { + "description": "Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, "grants": { "description": "Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", "example": [ @@ -74749,6 +85518,11 @@ }, "type": "array" }, + "preserve_denies": { + "description": "Retain current server denies atomically in replacement or patch mode; current denies win.", + "example": true, + "type": "boolean" + }, "remove": { "description": "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", "example": [ @@ -74781,6 +85555,39 @@ "type": "object" }, "type": "array" + }, + "remove_denies": { + "description": "Patch mode: principals whose denies should be removed.", + "example": [ + { + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "Identifies a principal to be removed from an access-control list.", + "example": { + "principal": "string", + "principal_type": "user" + }, + "properties": { + "principal": { + "description": "The identifier of the principal to remove. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`. Omit when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal to remove. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type" + ], + "type": "object" + }, + "type": "array" } }, "type": "object" @@ -76903,6 +87710,26 @@ "description": "Groups tasks by their exact epic label, ordered by label. Closed tasks include cancelled tasks, but cancelled prerequisites still block. Source filters select the tasks summarized; blockers outside that selection still affect readiness. Root ranking is capped per epic and root_blockers_partial is true when that graph is truncated. No epic entity is created.", "operationId": "get_api_v1_teams__team_task_epics", "parameters": [ + { + "description": "labels (default) or entities.", + "example": "string", + "in": "query", + "name": "representation", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "Exact entity name; only used for entities.", + "example": "Example Name", + "in": "query", + "name": "name", + "required": false, + "schema": { + "type": "string" + } + }, { "example": "string", "in": "path", @@ -76970,6 +87797,16 @@ "type": "integer" } }, + { + "description": "Keep only epics with at least one non-closed task owned by this user: `me` or a user public ID (`usr_...`).", + "example": "string", + "in": "query", + "name": "owner", + "required": false, + "schema": { + "type": "string" + } + }, { "description": "Include epics with no non-closed tasks; defaults to false.", "example": true, @@ -77006,260 +87843,459 @@ "content": { "application/json": { "schema": { - "example": { - "after_cursor": "string", - "before_cursor": "string", - "data": [ - { - "blocked_count": 1, - "counts": {}, - "epic": "string", - "next_ready": [ - { - "id": "string", - "name": "Example Name", - "priority": 1, - "status": "string" - } - ], - "root_blockers": [ + "anyOf": [ + { + "example": { + "after_cursor": "string", + "before_cursor": "string", + "data": [ { - "downstream_count": 1, - "id": "string", - "name": "Example Name", - "priority": 1, - "status": "string" - } - ], - "root_blockers_partial": true, - "top_open_priority": 1, - "updated_at": "2024-01-01T00:00:00Z" - } - ], - "has_more": true, - "no_epic_open_count": 1 - }, - "properties": { - "after_cursor": { - "example": "string", - "nullable": true, - "type": "string" - }, - "before_cursor": { - "example": "string", - "nullable": true, - "type": "string" - }, - "data": { - "example": [ - { - "blocked_count": 1, - "counts": {}, - "epic": "string", - "next_ready": [ - { - "id": "string", - "name": "Example Name", - "priority": 1, - "status": "string" - } - ], - "root_blockers": [ - { - "downstream_count": 1, - "id": "string", - "name": "Example Name", - "priority": 1, - "status": "string" - } - ], - "root_blockers_partial": true, - "top_open_priority": 1, - "updated_at": "2024-01-01T00:00:00Z" - } - ], - "items": { - "description": "Read-only progress and scheduling summary for an epic label.", - "example": { - "blocked_count": 1, - "counts": {}, - "epic": "string", - "next_ready": [ - { - "id": "string", + "blocked_count": 1, + "counts": {}, + "epic": "string", + "next_ready": [ + { + "id": "string", + "name": "Example Name", + "priority": 1, + "status": "string" + } + ], + "owner": { + "alias": "alice", + "id": "user-usr_01j3k5m7n9p2r4s6t8v0w1x2", "name": "Example Name", - "priority": 1, - "status": "string" - } - ], - "root_blockers": [ - { - "downstream_count": 1, + "profile_picture": { + "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", + "height": 600, + "media": "med_0aBcDeFgHiJkLmNoPqRsTu", + "mime_type": "application/json", + "refresh_url": "https://example.com", + "url": "https://example.com", + "width": 800 + } + }, + "primary_task": { "id": "string", "name": "Example Name", "priority": 1, "status": "string" - } - ], - "root_blockers_partial": true, - "top_open_priority": 1, - "updated_at": "2024-01-01T00:00:00Z" - }, - "properties": { - "blocked_count": { - "example": 1, - "type": "integer" - }, - "counts": { - "description": "Task counts keyed by status, including closed tasks.", - "example": {}, - "type": "object" - }, - "epic": { - "example": "string", - "type": "string" - }, - "next_ready": { - "example": [ + }, + "root_blockers": [ { + "downstream_count": 1, "id": "string", "name": "Example Name", "priority": 1, "status": "string" } ], - "items": { - "description": "An open task with no unfinished prerequisite or active lease.", - "example": { + "root_blockers_partial": true, + "top_open_priority": 1, + "updated_at": "2024-01-01T00:00:00Z" + } + ], + "has_more": true, + "no_epic_open_count": 1 + }, + "properties": { + "after_cursor": { + "example": "string", + "nullable": true, + "type": "string" + }, + "before_cursor": { + "example": "string", + "nullable": true, + "type": "string" + }, + "data": { + "example": [ + { + "blocked_count": 1, + "counts": {}, + "epic": "string", + "next_ready": [ + { + "id": "string", + "name": "Example Name", + "priority": 1, + "status": "string" + } + ], + "owner": { + "alias": "alice", + "id": "user-usr_01j3k5m7n9p2r4s6t8v0w1x2", + "name": "Example Name", + "profile_picture": { + "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", + "height": 600, + "media": "med_0aBcDeFgHiJkLmNoPqRsTu", + "mime_type": "application/json", + "refresh_url": "https://example.com", + "url": "https://example.com", + "width": 800 + } + }, + "primary_task": { "id": "string", "name": "Example Name", "priority": 1, "status": "string" }, - "properties": { - "id": { - "example": "string", - "type": "string" - }, - "name": { - "example": "Example Name", - "type": "string" - }, - "priority": { - "example": 1, - "type": "integer" - }, - "status": { - "example": "string", - "type": "string" + "root_blockers": [ + { + "downstream_count": 1, + "id": "string", + "name": "Example Name", + "priority": 1, + "status": "string" } - }, - "required": [ - "id", - "name", - "status", - "priority" ], - "type": "object" - }, - "type": "array" - }, - "root_blockers": { - "example": [ - { - "downstream_count": 1, - "id": "string", + "root_blockers_partial": true, + "top_open_priority": 1, + "updated_at": "2024-01-01T00:00:00Z" + } + ], + "items": { + "description": "Read-only progress and scheduling summary for an epic label.", + "example": { + "blocked_count": 1, + "counts": {}, + "epic": "string", + "next_ready": [ + { + "id": "string", + "name": "Example Name", + "priority": 1, + "status": "string" + } + ], + "owner": { + "alias": "alice", + "id": "user-usr_01j3k5m7n9p2r4s6t8v0w1x2", "name": "Example Name", - "priority": 1, - "status": "string" - } - ], - "items": { - "description": "An unblocked root and the number of open tasks downstream within its epic.", - "example": { - "downstream_count": 1, + "profile_picture": { + "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", + "height": 600, + "media": "med_0aBcDeFgHiJkLmNoPqRsTu", + "mime_type": "application/json", + "refresh_url": "https://example.com", + "url": "https://example.com", + "width": 800 + } + }, + "primary_task": { "id": "string", "name": "Example Name", "priority": 1, "status": "string" }, - "properties": { - "downstream_count": { - "example": 1, - "type": "integer" + "root_blockers": [ + { + "downstream_count": 1, + "id": "string", + "name": "Example Name", + "priority": 1, + "status": "string" + } + ], + "root_blockers_partial": true, + "top_open_priority": 1, + "updated_at": "2024-01-01T00:00:00Z" + }, + "properties": { + "blocked_count": { + "example": 1, + "type": "integer" + }, + "counts": { + "description": "Task counts keyed by status, including closed tasks.", + "example": {}, + "type": "object" + }, + "epic": { + "example": "string", + "type": "string" + }, + "next_ready": { + "example": [ + { + "id": "string", + "name": "Example Name", + "priority": 1, + "status": "string" + } + ], + "items": { + "description": "An open task with no unfinished prerequisite or active lease.", + "example": { + "id": "string", + "name": "Example Name", + "priority": 1, + "status": "string" + }, + "properties": { + "id": { + "example": "string", + "type": "string" + }, + "name": { + "example": "Example Name", + "type": "string" + }, + "priority": { + "example": 1, + "type": "integer" + }, + "status": { + "example": "string", + "type": "string" + } + }, + "required": [ + "id", + "name", + "status", + "priority" + ], + "type": "object" }, - "id": { - "example": "string", - "type": "string" + "type": "array" + }, + "owner": { + "description": "Owner of the epic's primary task, as `id`, `name`, `alias` and `profile_picture`. The primary task is the top-ranked root blocker (the open task that unblocks the most work), or when no task blocks another, the highest-priority open task (lowest priority number, then ID). `null` when that task is unassigned or the epic has no open task.", + "example": { + "alias": "alice", + "id": "user-usr_01j3k5m7n9p2r4s6t8v0w1x2", + "name": "Example Name", + "profile_picture": { + "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", + "height": 600, + "media": "med_0aBcDeFgHiJkLmNoPqRsTu", + "mime_type": "application/json", + "refresh_url": "https://example.com", + "url": "https://example.com", + "width": 800 + } }, - "name": { - "example": "Example Name", - "type": "string" + "nullable": true, + "properties": { + "alias": { + "description": "Short handle or alias for the actor, used as an alternate display identifier. `null` if not configured.", + "example": "alice", + "nullable": true, + "type": "string" + }, + "id": { + "description": "Composite actor identifier. Format is `\"user-\"` for human users or `\"agent-\"` for agents.", + "example": "user-usr_01j3k5m7n9p2r4s6t8v0w1x2", + "nullable": true, + "type": "string" + }, + "name": { + "description": "Display name of the actor shown in the UI. `null` if no name is set.", + "example": "Example Name", + "nullable": true, + "type": "string" + }, + "profile_picture": { + "description": "Profile picture for the actor. `null` if the actor has no profile picture.", + "example": { + "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", + "height": 600, + "media": "med_0aBcDeFgHiJkLmNoPqRsTu", + "mime_type": "application/json", + "refresh_url": "https://example.com", + "url": "https://example.com", + "width": 800 + }, + "nullable": true, + "properties": { + "file": { + "description": "ID of the underlying storage file (`fil_...`). `null` when the image is not backed by a platform storage file.", + "example": "fil_0aBcDeFgHiJkLmNoPqRsTu", + "nullable": true, + "type": "string" + }, + "height": { + "description": "Height of the image in pixels. `null` if not known.", + "example": 600, + "nullable": true, + "type": "integer" + }, + "media": { + "description": "ID of the associated media record (`med_...`). `null` when the image is not linked to a media entity.", + "example": "med_0aBcDeFgHiJkLmNoPqRsTu", + "nullable": true, + "type": "string" + }, + "mime_type": { + "description": "MIME type of the image, e.g. `\"image/png\"` or `\"image/jpeg\"`. `null` if not known.", + "example": "application/json", + "nullable": true, + "type": "string" + }, + "refresh_url": { + "description": "Endpoint URL you can call to obtain a fresh signed `url` when the current one has expired. `null` if the URL does not require refreshing.", + "example": "https://example.com", + "nullable": true, + "type": "string" + }, + "url": { + "description": "Signed or public URL for downloading the image. May be time-limited; use `refresh_url` to obtain a new URL when this one expires.", + "example": "https://example.com", + "nullable": true, + "type": "string" + }, + "width": { + "description": "Width of the image in pixels. `null` if not known.", + "example": 800, + "nullable": true, + "type": "integer" + } + }, + "type": "object" + } }, - "priority": { - "example": 1, - "type": "integer" + "type": "object" + }, + "primary_task": { + "description": "The primary task whose owner is reported in `owner`. `null` when the epic has no open task.", + "example": { + "id": "string", + "name": "Example Name", + "priority": 1, + "status": "string" }, - "status": { - "example": "string", - "type": "string" - } + "nullable": true, + "properties": { + "id": { + "example": "string", + "type": "string" + }, + "name": { + "example": "Example Name", + "type": "string" + }, + "priority": { + "example": 1, + "type": "integer" + }, + "status": { + "example": "string", + "type": "string" + } + }, + "required": [ + "id", + "name", + "status", + "priority" + ], + "type": "object" }, - "required": [ - "id", - "name", - "status", - "priority", - "downstream_count" - ], - "type": "object" + "root_blockers": { + "example": [ + { + "downstream_count": 1, + "id": "string", + "name": "Example Name", + "priority": 1, + "status": "string" + } + ], + "items": { + "description": "An unblocked root and the number of open tasks downstream within its epic.", + "example": { + "downstream_count": 1, + "id": "string", + "name": "Example Name", + "priority": 1, + "status": "string" + }, + "properties": { + "downstream_count": { + "example": 1, + "type": "integer" + }, + "id": { + "example": "string", + "type": "string" + }, + "name": { + "example": "Example Name", + "type": "string" + }, + "priority": { + "example": 1, + "type": "integer" + }, + "status": { + "example": "string", + "type": "string" + } + }, + "required": [ + "id", + "name", + "status", + "priority", + "downstream_count" + ], + "type": "object" + }, + "type": "array" + }, + "root_blockers_partial": { + "description": "True when root ranking used a truncated in-epic graph.", + "example": true, + "type": "boolean" + }, + "top_open_priority": { + "example": 1, + "nullable": true, + "type": "integer" + }, + "updated_at": { + "example": "2024-01-01T00:00:00Z", + "format": "date-time", + "type": "string" + } }, - "type": "array" - }, - "root_blockers_partial": { - "description": "True when root ranking used a truncated in-epic graph.", - "example": true, - "type": "boolean" - }, - "top_open_priority": { - "example": 1, - "nullable": true, - "type": "integer" + "required": [ + "epic", + "counts", + "blocked_count", + "updated_at", + "root_blockers", + "root_blockers_partial", + "next_ready" + ], + "type": "object" }, - "updated_at": { - "example": "2024-01-01T00:00:00Z", - "format": "date-time", - "type": "string" - } + "type": "array" }, - "required": [ - "epic", - "counts", - "blocked_count", - "updated_at", - "root_blockers", - "root_blockers_partial", - "next_ready" - ], - "type": "object" + "has_more": { + "example": true, + "type": "boolean" + }, + "no_epic_open_count": { + "example": 1, + "type": "integer" + } }, - "type": "array" - }, - "has_more": { - "example": true, - "type": "boolean" + "required": [ + "data", + "has_more", + "no_epic_open_count" + ], + "type": "object" }, - "no_epic_open_count": { - "example": 1, - "type": "integer" + { + "$ref": "#/components/schemas/TaskEpicEntityCollection" } - }, - "required": [ - "data", - "has_more", - "no_epic_open_count" - ], - "type": "object" + ] } } }, @@ -77280,6 +88316,89 @@ "publishable_key", "bearer" ] + }, + "post": { + "operationId": "post_api_v1_teams__team_task_epics", + "parameters": [ + { + "example": "string", + "in": "path", + "name": "team", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "example": { + "description": "An example description.", + "metadata": { + "key": "value" + }, + "name": "Example Name", + "state": "string", + "user": "string" + }, + "properties": { + "description": { + "example": "An example description.", + "type": "string" + }, + "metadata": { + "example": { + "key": "value" + }, + "type": "object" + }, + "name": { + "example": "Example Name", + "type": "string" + }, + "state": { + "example": "string", + "type": "string" + }, + "user": { + "example": "string", + "type": "string" + } + }, + "required": [ + "name" + ], + "type": "object" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TaskEpicEntity" + } + } + }, + "description": "Successful response" + }, + "404": { + "description": "Owner not found or Epics disabled" + }, + "422": { + "description": "Invalid Epic" + } + }, + "summary": "Create a task Epic", + "x-auth": [ + "publishable_key", + "bearer" + ] } }, "/api/v1/teams/{team}/tasks": { @@ -77347,6 +88466,36 @@ "type": "string" } }, + { + "description": "Return only tasks owned by this user: `me` or a user public ID (`usr_...`).", + "example": "string", + "in": "query", + "name": "owner", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "Return only tasks owned or created by this user: `me` or a user public ID (`usr_...`). The \"My work\" predicate.", + "example": "string", + "in": "query", + "name": "involving", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "When true, omit `description` from every task. Use for list views.", + "example": true, + "in": "query", + "name": "summary", + "required": false, + "schema": { + "type": "boolean" + } + }, { "description": "Filter tasks by priority, from 0 (highest) to 4 (lowest).", "example": 1, @@ -77532,6 +88681,9 @@ "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", "aggregate_version": 1, "blocked_by_count": 1, + "blockers": [ + "string" + ], "closed_at": "2024-01-01T00:00:00Z", "comments_count": 1, "created_at": "2024-01-01T00:00:00Z", @@ -77559,12 +88711,14 @@ "description": "An example description.", "due_date": "2024-01-01T00:00:00Z", "epic": "string", + "human_answer_receipts": {}, "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, "is_stalled": true, "links": { "key": "value" }, + "machine_rescope_receipts": {}, "metadata": { "key": "value" }, @@ -77601,6 +88755,7 @@ ], "target_binary": "string", "target_version": "string", + "task_epic": "string", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -77627,6 +88782,9 @@ "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", "aggregate_version": 1, "blocked_by_count": 1, + "blockers": [ + "string" + ], "closed_at": "2024-01-01T00:00:00Z", "comments_count": 1, "created_at": "2024-01-01T00:00:00Z", @@ -77654,12 +88812,14 @@ "description": "An example description.", "due_date": "2024-01-01T00:00:00Z", "epic": "string", + "human_answer_receipts": {}, "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, "is_stalled": true, "links": { "key": "value" }, + "machine_rescope_receipts": {}, "metadata": { "key": "value" }, @@ -77696,6 +88856,7 @@ ], "target_binary": "string", "target_version": "string", + "task_epic": "string", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -77708,6 +88869,9 @@ "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", "aggregate_version": 1, "blocked_by_count": 1, + "blockers": [ + "string" + ], "closed_at": "2024-01-01T00:00:00Z", "comments_count": 1, "created_at": "2024-01-01T00:00:00Z", @@ -77735,12 +88899,14 @@ "description": "An example description.", "due_date": "2024-01-01T00:00:00Z", "epic": "string", + "human_answer_receipts": {}, "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, "is_stalled": true, "links": { "key": "value" }, + "machine_rescope_receipts": {}, "metadata": { "key": "value" }, @@ -77777,6 +88943,7 @@ ], "target_binary": "string", "target_version": "string", + "task_epic": "string", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -77800,6 +88967,16 @@ "example": 1, "type": "integer" }, + "blockers": { + "description": "Visible blocker IDs when requested with include=blockers.", + "example": [ + "string" + ], + "items": { + "type": "string" + }, + "type": "array" + }, "closed_at": { "description": "When the task was marked as done or otherwise closed (ISO 8601). `null` if the task is still open.", "example": "2024-01-01T00:00:00Z", @@ -77979,6 +89156,11 @@ "nullable": true, "type": "string" }, + "human_answer_receipts": { + "description": "Server-owned authenticated human answer intent, keyed by question version. Not infrastructure permission.", + "example": {}, + "type": "object" + }, "id": { "description": "Task ID (`tsk_...`).", "example": "tsk_0aBcDeFgHiJkLmNoPqRsTu", @@ -78001,6 +89183,11 @@ }, "type": "object" }, + "machine_rescope_receipts": { + "description": "Server-owned records of machine-applied local rescopes, keyed by question version. Never evidence that a human answered.", + "example": {}, + "type": "object" + }, "metadata": { "description": "Arbitrary key-value map of application-specific data stored alongside the task. Returns an empty object when no metadata has been set.", "example": { @@ -78208,6 +89395,12 @@ "nullable": true, "type": "string" }, + "task_epic": { + "description": "First-class Epic membership; does not grant access to the task.", + "example": "string", + "nullable": true, + "type": "string" + }, "team": { "description": "ID of the team that owns this task (`tem_...`). `null` if the task is not scoped to a team.", "example": "tem_0aBcDeFgHiJkLmNoPqRsTu", @@ -78300,9 +89493,13 @@ "agent": "string", "org": "string", "task": { + "blockers": [ + "string" + ], "description": "An example description.", "due_date": "2024-01-01T00:00:00Z", "epic": "billing-cadence", + "epic_id": "string", "id": "string", "links": { "key": "value" @@ -78344,9 +89541,13 @@ "task": { "description": "Attributes for the task to create. `name` is required; all other fields are optional.", "example": { + "blockers": [ + "string" + ], "description": "An example description.", "due_date": "2024-01-01T00:00:00Z", "epic": "billing-cadence", + "epic_id": "string", "id": "string", "links": { "key": "value" @@ -78373,6 +89574,16 @@ "thread": "thr_01j3k5m7n9p2r4s6t8v0w1x2" }, "properties": { + "blockers": { + "description": "Existing task IDs (`tsk_...`) that block this task. Recorded atomically with creation; the task is not ready until these blockers are done.", + "example": [ + "string" + ], + "items": { + "type": "string" + }, + "type": "array" + }, "description": { "description": "Optional long-form description or notes for the task. Supports plain text.", "example": "An example description.", @@ -78389,6 +89600,11 @@ "example": "billing-cadence", "type": "string" }, + "epic_id": { + "description": "First-class Epic ID (`epc_...`).", + "example": "string", + "type": "string" + }, "id": { "description": "Optional caller-generated task public ID (`tsk_...`). Persist it before creating a task when creation must survive a lost response. An existing ID returns 409 without modifying the task; read the task by ID to reconcile. Omit for a server-generated ID.", "example": "string", @@ -78608,6 +89824,9 @@ "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", "aggregate_version": 1, "blocked_by_count": 1, + "blockers": [ + "string" + ], "closed_at": "2024-01-01T00:00:00Z", "comments_count": 1, "created_at": "2024-01-01T00:00:00Z", @@ -78635,12 +89854,14 @@ "description": "An example description.", "due_date": "2024-01-01T00:00:00Z", "epic": "string", + "human_answer_receipts": {}, "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, "is_stalled": true, "links": { "key": "value" }, + "machine_rescope_receipts": {}, "metadata": { "key": "value" }, @@ -78677,6 +89898,7 @@ ], "target_binary": "string", "target_version": "string", + "task_epic": "string", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -78704,6 +89926,9 @@ "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", "aggregate_version": 1, "blocked_by_count": 1, + "blockers": [ + "string" + ], "closed_at": "2024-01-01T00:00:00Z", "comments_count": 1, "created_at": "2024-01-01T00:00:00Z", @@ -78731,12 +89956,14 @@ "description": "An example description.", "due_date": "2024-01-01T00:00:00Z", "epic": "string", + "human_answer_receipts": {}, "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, "is_stalled": true, "links": { "key": "value" }, + "machine_rescope_receipts": {}, "metadata": { "key": "value" }, @@ -78773,6 +90000,7 @@ ], "target_binary": "string", "target_version": "string", + "task_epic": "string", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -78789,6 +90017,9 @@ "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", "aggregate_version": 1, "blocked_by_count": 1, + "blockers": [ + "string" + ], "closed_at": "2024-01-01T00:00:00Z", "comments_count": 1, "created_at": "2024-01-01T00:00:00Z", @@ -78816,12 +90047,14 @@ "description": "An example description.", "due_date": "2024-01-01T00:00:00Z", "epic": "string", + "human_answer_receipts": {}, "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, "is_stalled": true, "links": { "key": "value" }, + "machine_rescope_receipts": {}, "metadata": { "key": "value" }, @@ -78858,6 +90091,7 @@ ], "target_binary": "string", "target_version": "string", + "task_epic": "string", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -78873,6 +90107,9 @@ "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", "aggregate_version": 1, "blocked_by_count": 1, + "blockers": [ + "string" + ], "closed_at": "2024-01-01T00:00:00Z", "comments_count": 1, "created_at": "2024-01-01T00:00:00Z", @@ -78900,12 +90137,14 @@ "description": "An example description.", "due_date": "2024-01-01T00:00:00Z", "epic": "string", + "human_answer_receipts": {}, "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, "is_stalled": true, "links": { "key": "value" }, + "machine_rescope_receipts": {}, "metadata": { "key": "value" }, @@ -78942,6 +90181,7 @@ ], "target_binary": "string", "target_version": "string", + "task_epic": "string", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -78954,6 +90194,9 @@ "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", "aggregate_version": 1, "blocked_by_count": 1, + "blockers": [ + "string" + ], "closed_at": "2024-01-01T00:00:00Z", "comments_count": 1, "created_at": "2024-01-01T00:00:00Z", @@ -78981,12 +90224,14 @@ "description": "An example description.", "due_date": "2024-01-01T00:00:00Z", "epic": "string", + "human_answer_receipts": {}, "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, "is_stalled": true, "links": { "key": "value" }, + "machine_rescope_receipts": {}, "metadata": { "key": "value" }, @@ -79023,6 +90268,7 @@ ], "target_binary": "string", "target_version": "string", + "task_epic": "string", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -79046,6 +90292,16 @@ "example": 1, "type": "integer" }, + "blockers": { + "description": "Visible blocker IDs when requested with include=blockers.", + "example": [ + "string" + ], + "items": { + "type": "string" + }, + "type": "array" + }, "closed_at": { "description": "When the task was marked as done or otherwise closed (ISO 8601). `null` if the task is still open.", "example": "2024-01-01T00:00:00Z", @@ -79225,6 +90481,11 @@ "nullable": true, "type": "string" }, + "human_answer_receipts": { + "description": "Server-owned authenticated human answer intent, keyed by question version. Not infrastructure permission.", + "example": {}, + "type": "object" + }, "id": { "description": "Task ID (`tsk_...`).", "example": "tsk_0aBcDeFgHiJkLmNoPqRsTu", @@ -79247,6 +90508,11 @@ }, "type": "object" }, + "machine_rescope_receipts": { + "description": "Server-owned records of machine-applied local rescopes, keyed by question version. Never evidence that a human answered.", + "example": {}, + "type": "object" + }, "metadata": { "description": "Arbitrary key-value map of application-specific data stored alongside the task. Returns an empty object when no metadata has been set.", "example": { @@ -79454,6 +90720,12 @@ "nullable": true, "type": "string" }, + "task_epic": { + "description": "First-class Epic membership; does not grant access to the task.", + "example": "string", + "nullable": true, + "type": "string" + }, "team": { "description": "ID of the team that owns this task (`tem_...`). `null` if the task is not scoped to a team.", "example": "tem_0aBcDeFgHiJkLmNoPqRsTu", @@ -79528,6 +90800,853 @@ ] } }, + "/api/v1/teams/{team}/tasks/by-external-reference": { + "get": { + "description": "Returns all exact external-reference matches owned by the requested principal. Multiple matches remain explicit; callers must not choose an arbitrary task.", + "operationId": "get_api_v1_teams__team_tasks_by-external-reference", + "parameters": [ + { + "description": "User owner.", + "example": "string", + "in": "query", + "name": "user", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "Team owner.", + "example": "string", + "in": "path", + "name": "team", + "required": true, + "schema": { + "type": "string" + } + }, + { + "description": "Organization consistency check.", + "example": "string", + "in": "query", + "name": "org", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "External host.", + "example": "string", + "in": "query", + "name": "external_scope", + "required": true, + "schema": { + "type": "string" + } + }, + { + "description": "External object type.", + "example": "string", + "in": "query", + "name": "object_type", + "required": true, + "schema": { + "type": "string" + } + }, + { + "description": "External object identity.", + "example": "string", + "in": "query", + "name": "object_id", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "description": "Owner-isolated matching tasks.", + "example": { + "data": [ + { + "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", + "aggregate_version": 1, + "blocked_by_count": 1, + "blockers": [ + "string" + ], + "closed_at": "2024-01-01T00:00:00Z", + "comments_count": 1, + "created_at": "2024-01-01T00:00:00Z", + "created_by_actor": { + "alias": "alice", + "id": "user-usr_01j3k5m7n9p2r4s6t8v0w1x2", + "name": "Example Name", + "profile_picture": { + "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", + "height": 600, + "media": "med_0aBcDeFgHiJkLmNoPqRsTu", + "mime_type": "application/json", + "refresh_url": "https://example.com", + "url": "https://example.com", + "width": 800 + } + }, + "created_by_agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", + "created_by_user": "usr_0aBcDeFgHiJkLmNoPqRsTu", + "current_lease": { + "expires_at": "2024-01-01T00:00:00Z", + "harness": "string", + "session_name": "Example Name" + }, + "description": "An example description.", + "due_date": "2024-01-01T00:00:00Z", + "epic": "string", + "human_answer_receipts": {}, + "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", + "is_blocked": true, + "is_stalled": true, + "links": { + "key": "value" + }, + "machine_rescope_receipts": {}, + "metadata": { + "key": "value" + }, + "name": "Example Name", + "org": "org_0aBcDeFgHiJkLmNoPqRsTu", + "owner_actor": { + "alias": "alice", + "id": "user-usr_01j3k5m7n9p2r4s6t8v0w1x2", + "name": "Example Name", + "profile_picture": { + "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", + "height": 600, + "media": "med_0aBcDeFgHiJkLmNoPqRsTu", + "mime_type": "application/json", + "refresh_url": "https://example.com", + "url": "https://example.com", + "width": 800 + } + }, + "owner_agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", + "owner_user": "usr_0aBcDeFgHiJkLmNoPqRsTu", + "parent": "tsk_0aBcDeFgHiJkLmNoPqRsTu", + "priority": 2, + "project_id": "string", + "sandbox": "dsb_0aBcDeFgHiJkLmNoPqRsTu", + "source_id": "string", + "source_scope": "string", + "source_type": "string", + "stalled_since": "2024-01-01T00:00:00Z", + "status": "open", + "subtasks_count": 1, + "tags": [ + "string" + ], + "target_binary": "string", + "target_version": "string", + "task_epic": "string", + "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", + "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", + "updated_at": "2024-01-01T00:00:00Z", + "user": "usr_0aBcDeFgHiJkLmNoPqRsTu" + } + ] + }, + "properties": { + "data": { + "example": [ + { + "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", + "aggregate_version": 1, + "blocked_by_count": 1, + "blockers": [ + "string" + ], + "closed_at": "2024-01-01T00:00:00Z", + "comments_count": 1, + "created_at": "2024-01-01T00:00:00Z", + "created_by_actor": { + "alias": "alice", + "id": "user-usr_01j3k5m7n9p2r4s6t8v0w1x2", + "name": "Example Name", + "profile_picture": { + "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", + "height": 600, + "media": "med_0aBcDeFgHiJkLmNoPqRsTu", + "mime_type": "application/json", + "refresh_url": "https://example.com", + "url": "https://example.com", + "width": 800 + } + }, + "created_by_agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", + "created_by_user": "usr_0aBcDeFgHiJkLmNoPqRsTu", + "current_lease": { + "expires_at": "2024-01-01T00:00:00Z", + "harness": "string", + "session_name": "Example Name" + }, + "description": "An example description.", + "due_date": "2024-01-01T00:00:00Z", + "epic": "string", + "human_answer_receipts": {}, + "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", + "is_blocked": true, + "is_stalled": true, + "links": { + "key": "value" + }, + "machine_rescope_receipts": {}, + "metadata": { + "key": "value" + }, + "name": "Example Name", + "org": "org_0aBcDeFgHiJkLmNoPqRsTu", + "owner_actor": { + "alias": "alice", + "id": "user-usr_01j3k5m7n9p2r4s6t8v0w1x2", + "name": "Example Name", + "profile_picture": { + "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", + "height": 600, + "media": "med_0aBcDeFgHiJkLmNoPqRsTu", + "mime_type": "application/json", + "refresh_url": "https://example.com", + "url": "https://example.com", + "width": 800 + } + }, + "owner_agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", + "owner_user": "usr_0aBcDeFgHiJkLmNoPqRsTu", + "parent": "tsk_0aBcDeFgHiJkLmNoPqRsTu", + "priority": 2, + "project_id": "string", + "sandbox": "dsb_0aBcDeFgHiJkLmNoPqRsTu", + "source_id": "string", + "source_scope": "string", + "source_type": "string", + "stalled_since": "2024-01-01T00:00:00Z", + "status": "open", + "subtasks_count": 1, + "tags": [ + "string" + ], + "target_binary": "string", + "target_version": "string", + "task_epic": "string", + "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", + "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", + "updated_at": "2024-01-01T00:00:00Z", + "user": "usr_0aBcDeFgHiJkLmNoPqRsTu" + } + ], + "items": { + "description": "A task representing a unit of work, optionally assignable to a user or agent.", + "example": { + "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", + "aggregate_version": 1, + "blocked_by_count": 1, + "blockers": [ + "string" + ], + "closed_at": "2024-01-01T00:00:00Z", + "comments_count": 1, + "created_at": "2024-01-01T00:00:00Z", + "created_by_actor": { + "alias": "alice", + "id": "user-usr_01j3k5m7n9p2r4s6t8v0w1x2", + "name": "Example Name", + "profile_picture": { + "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", + "height": 600, + "media": "med_0aBcDeFgHiJkLmNoPqRsTu", + "mime_type": "application/json", + "refresh_url": "https://example.com", + "url": "https://example.com", + "width": 800 + } + }, + "created_by_agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", + "created_by_user": "usr_0aBcDeFgHiJkLmNoPqRsTu", + "current_lease": { + "expires_at": "2024-01-01T00:00:00Z", + "harness": "string", + "session_name": "Example Name" + }, + "description": "An example description.", + "due_date": "2024-01-01T00:00:00Z", + "epic": "string", + "human_answer_receipts": {}, + "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", + "is_blocked": true, + "is_stalled": true, + "links": { + "key": "value" + }, + "machine_rescope_receipts": {}, + "metadata": { + "key": "value" + }, + "name": "Example Name", + "org": "org_0aBcDeFgHiJkLmNoPqRsTu", + "owner_actor": { + "alias": "alice", + "id": "user-usr_01j3k5m7n9p2r4s6t8v0w1x2", + "name": "Example Name", + "profile_picture": { + "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", + "height": 600, + "media": "med_0aBcDeFgHiJkLmNoPqRsTu", + "mime_type": "application/json", + "refresh_url": "https://example.com", + "url": "https://example.com", + "width": 800 + } + }, + "owner_agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", + "owner_user": "usr_0aBcDeFgHiJkLmNoPqRsTu", + "parent": "tsk_0aBcDeFgHiJkLmNoPqRsTu", + "priority": 2, + "project_id": "string", + "sandbox": "dsb_0aBcDeFgHiJkLmNoPqRsTu", + "source_id": "string", + "source_scope": "string", + "source_type": "string", + "stalled_since": "2024-01-01T00:00:00Z", + "status": "open", + "subtasks_count": 1, + "tags": [ + "string" + ], + "target_binary": "string", + "target_version": "string", + "task_epic": "string", + "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", + "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", + "updated_at": "2024-01-01T00:00:00Z", + "user": "usr_0aBcDeFgHiJkLmNoPqRsTu" + }, + "properties": { + "agent": { + "description": "ID of the agent that owns this task (`agi_...`). `null` if the task is scoped to a team or user.", + "example": "agi_0aBcDeFgHiJkLmNoPqRsTu", + "nullable": true, + "type": "string" + }, + "aggregate_version": { + "description": "Event-stream version for optimistic update fencing. Pass this value as `expected_version` on an update to reject concurrent writes.", + "example": 1, + "nullable": true, + "type": "integer" + }, + "blocked_by_count": { + "description": "Number of readable tasks marked as blocking this task, whether or not they are done (see `GET /tasks/{task}/blockers`). Computed on list/show reads; create/update responses may lag one read behind.", + "example": 1, + "type": "integer" + }, + "blockers": { + "description": "Visible blocker IDs when requested with include=blockers.", + "example": [ + "string" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "closed_at": { + "description": "When the task was marked as done or otherwise closed (ISO 8601). `null` if the task is still open.", + "example": "2024-01-01T00:00:00Z", + "format": "date-time", + "nullable": true, + "type": "string" + }, + "comments_count": { + "description": "Total number of comments posted on this task.", + "example": 1, + "type": "integer" + }, + "created_at": { + "description": "When the task was created (ISO 8601).", + "example": "2024-01-01T00:00:00Z", + "format": "date-time", + "type": "string" + }, + "created_by_actor": { + "description": "Resolved creator details including `id`, `name`, `alias`, and `profile_picture`. `null` if no creator is set or the creator cannot be resolved (e.g. creating agent was deleted).", + "example": { + "alias": "alice", + "id": "user-usr_01j3k5m7n9p2r4s6t8v0w1x2", + "name": "Example Name", + "profile_picture": { + "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", + "height": 600, + "media": "med_0aBcDeFgHiJkLmNoPqRsTu", + "mime_type": "application/json", + "refresh_url": "https://example.com", + "url": "https://example.com", + "width": 800 + } + }, + "nullable": true, + "properties": { + "alias": { + "description": "Short handle or alias for the actor, used as an alternate display identifier. `null` if not configured.", + "example": "alice", + "nullable": true, + "type": "string" + }, + "id": { + "description": "Composite actor identifier. Format is `\"user-\"` for human users or `\"agent-\"` for agents.", + "example": "user-usr_01j3k5m7n9p2r4s6t8v0w1x2", + "nullable": true, + "type": "string" + }, + "name": { + "description": "Display name of the actor shown in the UI. `null` if no name is set.", + "example": "Example Name", + "nullable": true, + "type": "string" + }, + "profile_picture": { + "description": "Profile picture for the actor. `null` if the actor has no profile picture.", + "example": { + "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", + "height": 600, + "media": "med_0aBcDeFgHiJkLmNoPqRsTu", + "mime_type": "application/json", + "refresh_url": "https://example.com", + "url": "https://example.com", + "width": 800 + }, + "nullable": true, + "properties": { + "file": { + "description": "ID of the underlying storage file (`fil_...`). `null` when the image is not backed by a platform storage file.", + "example": "fil_0aBcDeFgHiJkLmNoPqRsTu", + "nullable": true, + "type": "string" + }, + "height": { + "description": "Height of the image in pixels. `null` if not known.", + "example": 600, + "nullable": true, + "type": "integer" + }, + "media": { + "description": "ID of the associated media record (`med_...`). `null` when the image is not linked to a media entity.", + "example": "med_0aBcDeFgHiJkLmNoPqRsTu", + "nullable": true, + "type": "string" + }, + "mime_type": { + "description": "MIME type of the image, e.g. `\"image/png\"` or `\"image/jpeg\"`. `null` if not known.", + "example": "application/json", + "nullable": true, + "type": "string" + }, + "refresh_url": { + "description": "Endpoint URL you can call to obtain a fresh signed `url` when the current one has expired. `null` if the URL does not require refreshing.", + "example": "https://example.com", + "nullable": true, + "type": "string" + }, + "url": { + "description": "Signed or public URL for downloading the image. May be time-limited; use `refresh_url` to obtain a new URL when this one expires.", + "example": "https://example.com", + "nullable": true, + "type": "string" + }, + "width": { + "description": "Width of the image in pixels. `null` if not known.", + "example": 800, + "nullable": true, + "type": "integer" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "created_by_agent": { + "description": "ID of the agent that created this task (`agi_...`). `null` if the task was created by a human user, or if the creating agent was later deleted.", + "example": "agi_0aBcDeFgHiJkLmNoPqRsTu", + "nullable": true, + "type": "string" + }, + "created_by_user": { + "description": "ID of the user who created this task (`usr_...`). `null` if the task was created by an agent, or if creator provenance was cleared after the creator was deleted.", + "example": "usr_0aBcDeFgHiJkLmNoPqRsTu", + "nullable": true, + "type": "string" + }, + "current_lease": { + "description": "Viewer-safe live coding-session lease summary. `null` when the task is unleased or the projected lease has expired. Fencing identifiers are never included.", + "example": { + "expires_at": "2024-01-01T00:00:00Z", + "harness": "string", + "session_name": "Example Name" + }, + "nullable": true, + "properties": { + "expires_at": { + "description": "Server-calculated lease expiry in ISO 8601 format.", + "example": "2024-01-01T00:00:00Z", + "format": "date-time", + "type": "string" + }, + "harness": { + "description": "Bounded harness identifier for the coding session.", + "example": "string", + "type": "string" + }, + "session_name": { + "description": "Display name supplied by the coding session that holds the lease.", + "example": "Example Name", + "type": "string" + } + }, + "required": [ + "session_name", + "harness", + "expires_at" + ], + "type": "object" + }, + "description": { + "description": "Long-form description or notes for the task. `null` if no description has been provided.", + "example": "An example description.", + "nullable": true, + "type": "string" + }, + "due_date": { + "description": "Date and time by which the task should be completed (ISO 8601). `null` if no due date is set.", + "example": "2024-01-01T00:00:00Z", + "format": "date-time", + "nullable": true, + "type": "string" + }, + "epic": { + "description": "Free-form grouping label. `null` when the task is not in an epic.", + "example": "string", + "nullable": true, + "type": "string" + }, + "human_answer_receipts": { + "description": "Server-owned authenticated human answer intent, keyed by question version. Not infrastructure permission.", + "example": {}, + "type": "object" + }, + "id": { + "description": "Task ID (`tsk_...`).", + "example": "tsk_0aBcDeFgHiJkLmNoPqRsTu", + "type": "string" + }, + "is_blocked": { + "description": "`true` while at least one blocking task is not yet done. Informational only - a blocked task can still change status - and derived at read time, so the task un-blocks automatically when its last open blocker completes. Computed on reads, including mutation responses.", + "example": true, + "type": "boolean" + }, + "is_stalled": { + "description": "True exactly when status is in_progress and the task has no lease or its lease expiry is in the past. Derived at read time from status and lease expiry, including on unannotated reads.", + "example": true, + "type": "boolean" + }, + "links": { + "description": "Key-value map of named URLs or references associated with the task. Returns an empty object when no links have been set.", + "example": { + "key": "value" + }, + "type": "object" + }, + "machine_rescope_receipts": { + "description": "Server-owned records of machine-applied local rescopes, keyed by question version. Never evidence that a human answered.", + "example": {}, + "type": "object" + }, + "metadata": { + "description": "Arbitrary key-value map of application-specific data stored alongside the task. Returns an empty object when no metadata has been set.", + "example": { + "key": "value" + }, + "type": "object" + }, + "name": { + "description": "Human-readable title of the task.", + "example": "Example Name", + "type": "string" + }, + "org": { + "description": "ID of the organization this task belongs to (`org_...`). `null` for tasks outside an org context.", + "example": "org_0aBcDeFgHiJkLmNoPqRsTu", + "nullable": true, + "type": "string" + }, + "owner_actor": { + "description": "Resolved owner details including `id`, `name`, `alias`, and `profile_picture`. `null` if the task is unassigned or the owner cannot be resolved (e.g. assigned agent was deleted).", + "example": { + "alias": "alice", + "id": "user-usr_01j3k5m7n9p2r4s6t8v0w1x2", + "name": "Example Name", + "profile_picture": { + "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", + "height": 600, + "media": "med_0aBcDeFgHiJkLmNoPqRsTu", + "mime_type": "application/json", + "refresh_url": "https://example.com", + "url": "https://example.com", + "width": 800 + } + }, + "nullable": true, + "properties": { + "alias": { + "description": "Short handle or alias for the actor, used as an alternate display identifier. `null` if not configured.", + "example": "alice", + "nullable": true, + "type": "string" + }, + "id": { + "description": "Composite actor identifier. Format is `\"user-\"` for human users or `\"agent-\"` for agents.", + "example": "user-usr_01j3k5m7n9p2r4s6t8v0w1x2", + "nullable": true, + "type": "string" + }, + "name": { + "description": "Display name of the actor shown in the UI. `null` if no name is set.", + "example": "Example Name", + "nullable": true, + "type": "string" + }, + "profile_picture": { + "description": "Profile picture for the actor. `null` if the actor has no profile picture.", + "example": { + "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", + "height": 600, + "media": "med_0aBcDeFgHiJkLmNoPqRsTu", + "mime_type": "application/json", + "refresh_url": "https://example.com", + "url": "https://example.com", + "width": 800 + }, + "nullable": true, + "properties": { + "file": { + "description": "ID of the underlying storage file (`fil_...`). `null` when the image is not backed by a platform storage file.", + "example": "fil_0aBcDeFgHiJkLmNoPqRsTu", + "nullable": true, + "type": "string" + }, + "height": { + "description": "Height of the image in pixels. `null` if not known.", + "example": 600, + "nullable": true, + "type": "integer" + }, + "media": { + "description": "ID of the associated media record (`med_...`). `null` when the image is not linked to a media entity.", + "example": "med_0aBcDeFgHiJkLmNoPqRsTu", + "nullable": true, + "type": "string" + }, + "mime_type": { + "description": "MIME type of the image, e.g. `\"image/png\"` or `\"image/jpeg\"`. `null` if not known.", + "example": "application/json", + "nullable": true, + "type": "string" + }, + "refresh_url": { + "description": "Endpoint URL you can call to obtain a fresh signed `url` when the current one has expired. `null` if the URL does not require refreshing.", + "example": "https://example.com", + "nullable": true, + "type": "string" + }, + "url": { + "description": "Signed or public URL for downloading the image. May be time-limited; use `refresh_url` to obtain a new URL when this one expires.", + "example": "https://example.com", + "nullable": true, + "type": "string" + }, + "width": { + "description": "Width of the image in pixels. `null` if not known.", + "example": 800, + "nullable": true, + "type": "integer" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "owner_agent": { + "description": "ID of the agent assigned as owner (`agi_...`). `null` if the owner is a human user, the task is unassigned, or the assigned agent was deleted.", + "example": "agi_0aBcDeFgHiJkLmNoPqRsTu", + "nullable": true, + "type": "string" + }, + "owner_user": { + "description": "ID of the user assigned as owner (`usr_...`). `null` if the owner is an agent, the task is unassigned, or the assigned agent was deleted.", + "example": "usr_0aBcDeFgHiJkLmNoPqRsTu", + "nullable": true, + "type": "string" + }, + "parent": { + "description": "ID of the parent task when this task is a subtask (`tsk_...`). `null` for top-level tasks or when the parent is not readable. Subtasks nest exactly one level.", + "example": "tsk_0aBcDeFgHiJkLmNoPqRsTu", + "nullable": true, + "type": "string" + }, + "priority": { + "description": "Priority level of the task from `0` (highest) to `4` (lowest). Defaults to `2` (medium) when not explicitly set.", + "example": 2, + "type": "integer" + }, + "project_id": { + "description": "Optional project ID (`prj_...`). Membership does not change task visibility.", + "example": "string", + "nullable": true, + "type": "string" + }, + "sandbox": { + "description": "ID of the developer sandbox this task is scoped to (`dsb_...`). `null` for tasks outside a sandbox environment.", + "example": "dsb_0aBcDeFgHiJkLmNoPqRsTu", + "nullable": true, + "type": "string" + }, + "source_id": { + "description": "Source object identity (for example `ArchAstro/firstlanding`). `null` when the task has no source.", + "example": "string", + "nullable": true, + "type": "string" + }, + "source_scope": { + "description": "Container of the work this task is about (for example `github.com`). `null` when the task has no source. Set together with `source_type` and `source_id`.", + "example": "string", + "nullable": true, + "type": "string" + }, + "source_type": { + "description": "Kind of source object (for example `repository`). `null` when the task has no source.", + "example": "string", + "nullable": true, + "type": "string" + }, + "stalled_since": { + "description": "Lease expiry for a stalled task, or its last update when no lease expiry exists. Null when not stalled.", + "example": "2024-01-01T00:00:00Z", + "format": "date-time", + "nullable": true, + "type": "string" + }, + "status": { + "description": "Current status of the task. One of `\"open\"`, `\"in_progress\"`, `\"in_review\"`, `\"paused\"`, `\"failed\"`, `\"superseding\"`, `\"done\"`, or `\"cancelled\"`.", + "example": "open", + "type": "string" + }, + "subtasks_count": { + "description": "Number of readable subtasks under this task. Computed on list/show reads; create/update responses may report 0 until the next read. Always 0 for subtasks.", + "example": 1, + "type": "integer" + }, + "tags": { + "description": "Labels for grouping and filtering, stored lowercase and de-duplicated. Empty array when untagged.", + "example": [ + "string" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "target_binary": { + "description": "Binary that must run this work (for example `my-cli`). A worker should take the task only when its own `target_binary` build is at least `target_version`. `null` when the task has no target. Set together with `target_version`.", + "example": "string", + "nullable": true, + "type": "string" + }, + "target_version": { + "description": "Minimum semantic version of `target_binary` that can run this work (for example `0.48.9`), in canonical `MAJOR.MINOR.PATCH[-prerelease][+build]` form. `null` when the task has no target.", + "example": "string", + "nullable": true, + "type": "string" + }, + "task_epic": { + "description": "First-class Epic membership; does not grant access to the task.", + "example": "string", + "nullable": true, + "type": "string" + }, + "team": { + "description": "ID of the team that owns this task (`tem_...`). `null` if the task is not scoped to a team.", + "example": "tem_0aBcDeFgHiJkLmNoPqRsTu", + "nullable": true, + "type": "string" + }, + "thread": { + "description": "ID of the thread this task is bound to (`thr_...`) - the conversation it was filed from, or the thread passed at creation. `null` for tasks not tied to a thread.", + "example": "thr_0aBcDeFgHiJkLmNoPqRsTu", + "nullable": true, + "type": "string" + }, + "updated_at": { + "description": "When the task was last modified (ISO 8601).", + "example": "2024-01-01T00:00:00Z", + "format": "date-time", + "type": "string" + }, + "user": { + "description": "ID of the user that owns this task (`usr_...`). `null` if the task is scoped to a team.", + "example": "usr_0aBcDeFgHiJkLmNoPqRsTu", + "nullable": true, + "type": "string" + } + }, + "required": [ + "id", + "name", + "status" + ], + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "data" + ], + "type": "object" + } + } + }, + "description": "Successful response" + }, + "401": { + "description": "Unauthorized" + }, + "404": { + "description": "Task owner not found" + }, + "422": { + "description": "Validation error" + } + }, + "summary": "Find an owner's tasks by external reference", + "x-auth": [ + "publishable_key", + "bearer" + ] + } + }, "/api/v1/teams/{team}/tasks/by-source": { "put": { "description": "Atomically creates one task per owner, tenant and source. Retries return the current task without updating it. Historical tasks created through ordinary create are not adopted.", @@ -79554,6 +91673,7 @@ "epic": "string", "name": "Example Name", "org": "string", + "owner_user": "string", "source_id": "string", "source_scope": "string", "source_type": "string", @@ -79586,6 +91706,11 @@ "example": "string", "type": "string" }, + "owner_user": { + "description": "Initial assigned user; immutable on retries.", + "example": "string", + "type": "string" + }, "source_id": { "description": "Source identity, for example owner/repo#123.", "example": "string", @@ -79899,6 +92024,9 @@ "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", "aggregate_version": 1, "blocked_by_count": 1, + "blockers": [ + "string" + ], "closed_at": "2024-01-01T00:00:00Z", "comments_count": 1, "created_at": "2024-01-01T00:00:00Z", @@ -79926,12 +92054,14 @@ "description": "An example description.", "due_date": "2024-01-01T00:00:00Z", "epic": "string", + "human_answer_receipts": {}, "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, "is_stalled": true, "links": { "key": "value" }, + "machine_rescope_receipts": {}, "metadata": { "key": "value" }, @@ -79968,6 +92098,7 @@ ], "target_binary": "string", "target_version": "string", + "task_epic": "string", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -80000,6 +92131,9 @@ "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", "aggregate_version": 1, "blocked_by_count": 1, + "blockers": [ + "string" + ], "closed_at": "2024-01-01T00:00:00Z", "comments_count": 1, "created_at": "2024-01-01T00:00:00Z", @@ -80027,12 +92161,14 @@ "description": "An example description.", "due_date": "2024-01-01T00:00:00Z", "epic": "string", + "human_answer_receipts": {}, "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, "is_stalled": true, "links": { "key": "value" }, + "machine_rescope_receipts": {}, "metadata": { "key": "value" }, @@ -80069,6 +92205,7 @@ ], "target_binary": "string", "target_version": "string", + "task_epic": "string", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -80085,6 +92222,9 @@ "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", "aggregate_version": 1, "blocked_by_count": 1, + "blockers": [ + "string" + ], "closed_at": "2024-01-01T00:00:00Z", "comments_count": 1, "created_at": "2024-01-01T00:00:00Z", @@ -80112,12 +92252,14 @@ "description": "An example description.", "due_date": "2024-01-01T00:00:00Z", "epic": "string", + "human_answer_receipts": {}, "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, "is_stalled": true, "links": { "key": "value" }, + "machine_rescope_receipts": {}, "metadata": { "key": "value" }, @@ -80154,6 +92296,7 @@ ], "target_binary": "string", "target_version": "string", + "task_epic": "string", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -80187,6 +92330,9 @@ "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", "aggregate_version": 1, "blocked_by_count": 1, + "blockers": [ + "string" + ], "closed_at": "2024-01-01T00:00:00Z", "comments_count": 1, "created_at": "2024-01-01T00:00:00Z", @@ -80214,12 +92360,14 @@ "description": "An example description.", "due_date": "2024-01-01T00:00:00Z", "epic": "string", + "human_answer_receipts": {}, "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, "is_stalled": true, "links": { "key": "value" }, + "machine_rescope_receipts": {}, "metadata": { "key": "value" }, @@ -80256,6 +92404,7 @@ ], "target_binary": "string", "target_version": "string", + "task_epic": "string", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -80279,6 +92428,16 @@ "example": 1, "type": "integer" }, + "blockers": { + "description": "Visible blocker IDs when requested with include=blockers.", + "example": [ + "string" + ], + "items": { + "type": "string" + }, + "type": "array" + }, "closed_at": { "description": "When the task was marked as done or otherwise closed (ISO 8601). `null` if the task is still open.", "example": "2024-01-01T00:00:00Z", @@ -80458,6 +92617,11 @@ "nullable": true, "type": "string" }, + "human_answer_receipts": { + "description": "Server-owned authenticated human answer intent, keyed by question version. Not infrastructure permission.", + "example": {}, + "type": "object" + }, "id": { "description": "Task ID (`tsk_...`).", "example": "tsk_0aBcDeFgHiJkLmNoPqRsTu", @@ -80480,6 +92644,11 @@ }, "type": "object" }, + "machine_rescope_receipts": { + "description": "Server-owned records of machine-applied local rescopes, keyed by question version. Never evidence that a human answered.", + "example": {}, + "type": "object" + }, "metadata": { "description": "Arbitrary key-value map of application-specific data stored alongside the task. Returns an empty object when no metadata has been set.", "example": { @@ -80687,6 +92856,12 @@ "nullable": true, "type": "string" }, + "task_epic": { + "description": "First-class Epic membership; does not grant access to the task.", + "example": "string", + "nullable": true, + "type": "string" + }, "team": { "description": "ID of the team that owns this task (`tem_...`). `null` if the task is not scoped to a team.", "example": "tem_0aBcDeFgHiJkLmNoPqRsTu", @@ -80951,6 +93126,9 @@ "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", "aggregate_version": 1, "blocked_by_count": 1, + "blockers": [ + "string" + ], "closed_at": "2024-01-01T00:00:00Z", "comments_count": 1, "created_at": "2024-01-01T00:00:00Z", @@ -80978,12 +93156,14 @@ "description": "An example description.", "due_date": "2024-01-01T00:00:00Z", "epic": "string", + "human_answer_receipts": {}, "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, "is_stalled": true, "links": { "key": "value" }, + "machine_rescope_receipts": {}, "metadata": { "key": "value" }, @@ -81020,6 +93200,7 @@ ], "target_binary": "string", "target_version": "string", + "task_epic": "string", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -81045,6 +93226,9 @@ "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", "aggregate_version": 1, "blocked_by_count": 1, + "blockers": [ + "string" + ], "closed_at": "2024-01-01T00:00:00Z", "comments_count": 1, "created_at": "2024-01-01T00:00:00Z", @@ -81072,12 +93256,14 @@ "description": "An example description.", "due_date": "2024-01-01T00:00:00Z", "epic": "string", + "human_answer_receipts": {}, "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, "is_stalled": true, "links": { "key": "value" }, + "machine_rescope_receipts": {}, "metadata": { "key": "value" }, @@ -81114,6 +93300,7 @@ ], "target_binary": "string", "target_version": "string", + "task_epic": "string", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -81126,6 +93313,9 @@ "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", "aggregate_version": 1, "blocked_by_count": 1, + "blockers": [ + "string" + ], "closed_at": "2024-01-01T00:00:00Z", "comments_count": 1, "created_at": "2024-01-01T00:00:00Z", @@ -81153,12 +93343,14 @@ "description": "An example description.", "due_date": "2024-01-01T00:00:00Z", "epic": "string", + "human_answer_receipts": {}, "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, "is_stalled": true, "links": { "key": "value" }, + "machine_rescope_receipts": {}, "metadata": { "key": "value" }, @@ -81195,6 +93387,7 @@ ], "target_binary": "string", "target_version": "string", + "task_epic": "string", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -81218,6 +93411,16 @@ "example": 1, "type": "integer" }, + "blockers": { + "description": "Visible blocker IDs when requested with include=blockers.", + "example": [ + "string" + ], + "items": { + "type": "string" + }, + "type": "array" + }, "closed_at": { "description": "When the task was marked as done or otherwise closed (ISO 8601). `null` if the task is still open.", "example": "2024-01-01T00:00:00Z", @@ -81397,6 +93600,11 @@ "nullable": true, "type": "string" }, + "human_answer_receipts": { + "description": "Server-owned authenticated human answer intent, keyed by question version. Not infrastructure permission.", + "example": {}, + "type": "object" + }, "id": { "description": "Task ID (`tsk_...`).", "example": "tsk_0aBcDeFgHiJkLmNoPqRsTu", @@ -81419,6 +93627,11 @@ }, "type": "object" }, + "machine_rescope_receipts": { + "description": "Server-owned records of machine-applied local rescopes, keyed by question version. Never evidence that a human answered.", + "example": {}, + "type": "object" + }, "metadata": { "description": "Arbitrary key-value map of application-specific data stored alongside the task. Returns an empty object when no metadata has been set.", "example": { @@ -81626,6 +93839,12 @@ "nullable": true, "type": "string" }, + "task_epic": { + "description": "First-class Epic membership; does not grant access to the task.", + "example": "string", + "nullable": true, + "type": "string" + }, "team": { "description": "ID of the team that owns this task (`tem_...`). `null` if the task is not scoped to a team.", "example": "tem_0aBcDeFgHiJkLmNoPqRsTu", @@ -81768,6 +93987,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -81778,11 +94017,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -81949,6 +94195,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -81959,11 +94225,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -82139,6 +94412,7 @@ "needs-review" ], "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", + "thread_template_key": "string", "title": "Example Title", "ttl": "2026-08-15T12:00:00", "unread_count": 5, @@ -82184,6 +94458,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -82194,11 +94488,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -82365,6 +94666,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -82375,11 +94696,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -82555,6 +94883,7 @@ "needs-review" ], "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", + "thread_template_key": "string", "title": "Example Title", "ttl": "2026-08-15T12:00:00", "unread_count": 5, @@ -82597,6 +94926,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -82607,11 +94956,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -82778,6 +95134,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -82788,11 +95164,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -82968,6 +95351,7 @@ "needs-review" ], "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", + "thread_template_key": "string", "title": "Example Title", "ttl": "2026-08-15T12:00:00", "unread_count": 5, @@ -83236,6 +95620,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -83246,11 +95650,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -83388,6 +95799,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -83398,11 +95829,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "nullable": true, @@ -83460,6 +95898,112 @@ }, "type": "array" }, + "add_denies": { + "description": "Patch mode: denies to add or merge, replacing any grant for the same principal.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, + "denies": { + "description": "Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, "grants": { "description": "Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", "example": [ @@ -83513,6 +96057,11 @@ }, "type": "array" }, + "preserve_denies": { + "description": "Retain current server denies atomically in replacement or patch mode; current denies win.", + "example": true, + "type": "boolean" + }, "remove": { "description": "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", "example": [ @@ -83545,6 +96094,39 @@ "type": "object" }, "type": "array" + }, + "remove_denies": { + "description": "Patch mode: principals whose denies should be removed.", + "example": [ + { + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "Identifies a principal to be removed from an access-control list.", + "example": { + "principal": "string", + "principal_type": "user" + }, + "properties": { + "principal": { + "description": "The identifier of the principal to remove. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`. Omit when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal to remove. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type" + ], + "type": "object" + }, + "type": "array" } }, "type": "object" @@ -84367,6 +96949,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -84377,11 +96979,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -84915,6 +97524,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -84925,11 +97554,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -85105,6 +97741,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -85115,11 +97771,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -85294,6 +97957,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -85304,11 +97987,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "nullable": true, @@ -85366,6 +98056,112 @@ }, "type": "array" }, + "add_denies": { + "description": "Patch mode: denies to add or merge, replacing any grant for the same principal.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, + "denies": { + "description": "Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, "grants": { "description": "Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", "example": [ @@ -85419,6 +98215,11 @@ }, "type": "array" }, + "preserve_denies": { + "description": "Retain current server denies atomically in replacement or patch mode; current denies win.", + "example": true, + "type": "boolean" + }, "remove": { "description": "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", "example": [ @@ -85451,6 +98252,39 @@ "type": "object" }, "type": "array" + }, + "remove_denies": { + "description": "Patch mode: principals whose denies should be removed.", + "example": [ + { + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "Identifies a principal to be removed from an access-control list.", + "example": { + "principal": "string", + "principal_type": "user" + }, + "properties": { + "principal": { + "description": "The identifier of the principal to remove. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`. Omit when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal to remove. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type" + ], + "type": "object" + }, + "type": "array" } }, "type": "object" @@ -86940,6 +99774,12 @@ "nullable": true, "type": "string" }, + "thread_template_key": { + "description": "Read-only key of the template used to create this thread. `null` for threads not created from a template.", + "example": "string", + "nullable": true, + "type": "string" + }, "title": { "description": "Human-readable name of the thread. `null` if no title has been set.", "example": "Example Title", @@ -87494,6 +100334,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -87504,11 +100364,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "content": "string", @@ -87532,6 +100399,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -87542,11 +100429,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "properties": { @@ -87603,6 +100497,112 @@ }, "type": "array" }, + "add_denies": { + "description": "Patch mode: denies to add or merge, replacing any grant for the same principal.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, + "denies": { + "description": "Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, "grants": { "description": "Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", "example": [ @@ -87656,6 +100656,11 @@ }, "type": "array" }, + "preserve_denies": { + "description": "Retain current server denies atomically in replacement or patch mode; current denies win.", + "example": true, + "type": "boolean" + }, "remove": { "description": "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", "example": [ @@ -87688,6 +100693,39 @@ "type": "object" }, "type": "array" + }, + "remove_denies": { + "description": "Patch mode: principals whose denies should be removed.", + "example": [ + { + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "Identifies a principal to be removed from an access-control list.", + "example": { + "principal": "string", + "principal_type": "user" + }, + "properties": { + "principal": { + "description": "The identifier of the principal to remove. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`. Omit when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal to remove. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type" + ], + "type": "object" + }, + "type": "array" } }, "type": "object" @@ -88361,6 +101399,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -88371,11 +101429,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "agent": "agt_0aBcDeFgHiJkLmNoPqRsTu", @@ -88425,6 +101490,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -88435,11 +101520,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "agent": "agt_0aBcDeFgHiJkLmNoPqRsTu", @@ -88486,6 +101578,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -88496,11 +101608,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "agent": "agt_0aBcDeFgHiJkLmNoPqRsTu", @@ -88546,6 +101665,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -88556,11 +101695,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "nullable": true, @@ -88618,6 +101764,112 @@ }, "type": "array" }, + "add_denies": { + "description": "Patch mode: denies to add or merge, replacing any grant for the same principal.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, + "denies": { + "description": "Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, "grants": { "description": "Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", "example": [ @@ -88671,6 +101923,11 @@ }, "type": "array" }, + "preserve_denies": { + "description": "Retain current server denies atomically in replacement or patch mode; current denies win.", + "example": true, + "type": "boolean" + }, "remove": { "description": "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", "example": [ @@ -88703,6 +101960,39 @@ "type": "object" }, "type": "array" + }, + "remove_denies": { + "description": "Patch mode: principals whose denies should be removed.", + "example": [ + { + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "Identifies a principal to be removed from an access-control list.", + "example": { + "principal": "string", + "principal_type": "user" + }, + "properties": { + "principal": { + "description": "The identifier of the principal to remove. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`. Omit when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal to remove. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type" + ], + "type": "object" + }, + "type": "array" } }, "type": "object" @@ -88971,6 +102261,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -88981,11 +102291,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "config": {}, @@ -88995,7 +102312,13 @@ }, "name": "Example Name", "provider": "string", - "region": "string" + "region": "string", + "repositories": [ + { + "ref": "string", + "repository": "string" + } + ] }, "properties": { "acl": { @@ -89011,6 +102334,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -89021,11 +102364,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "properties": { @@ -89082,6 +102432,112 @@ }, "type": "array" }, + "add_denies": { + "description": "Patch mode: denies to add or merge, replacing any grant for the same principal.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, + "denies": { + "description": "Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, "grants": { "description": "Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", "example": [ @@ -89135,6 +102591,11 @@ }, "type": "array" }, + "preserve_denies": { + "description": "Retain current server denies atomically in replacement or patch mode; current denies win.", + "example": true, + "type": "boolean" + }, "remove": { "description": "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", "example": [ @@ -89167,6 +102628,39 @@ "type": "object" }, "type": "array" + }, + "remove_denies": { + "description": "Patch mode: principals whose denies should be removed.", + "example": [ + { + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "Identifies a principal to be removed from an access-control list.", + "example": { + "principal": "string", + "principal_type": "user" + }, + "properties": { + "principal": { + "description": "The identifier of the principal to remove. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`. Omit when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal to remove. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type" + ], + "type": "object" + }, + "type": "array" } }, "type": "object" @@ -89194,7 +102688,7 @@ "type": "string" }, "provider": { - "description": "Compute backend: sprites (default), vercel or e2b.", + "description": "Compute backend: sprites (default), vercel, e2b, or devbox (a devbox lease owned by the thread's user; personal threads only, and the user needs devbox access).", "example": "string", "type": "string" }, @@ -89202,6 +102696,40 @@ "description": "Provider region; defaults to iad.", "example": "string", "type": "string" + }, + "repositories": { + "description": "Ordered GitHub checkouts (maximum 16): {repository: owner/name, ref: optional ref}. First is primary.", + "example": [ + { + "ref": "string", + "repository": "string" + } + ], + "items": { + "description": "A GitHub repository checkout recorded for later computer bootstrap.", + "example": { + "ref": "string", + "repository": "string" + }, + "properties": { + "ref": { + "description": "Optional checkout ref; null selects the repository's default branch.", + "example": "string", + "nullable": true, + "type": "string" + }, + "repository": { + "description": "GitHub owner/name; supported GitHub URLs are normalized on creation.", + "example": "string", + "type": "string" + } + }, + "required": [ + "repository" + ], + "type": "object" + }, + "type": "array" } }, "required": [ @@ -89943,6 +103471,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -89953,11 +103501,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -90103,6 +103658,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -90113,11 +103688,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -90276,6 +103858,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -90286,11 +103888,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -90428,6 +104037,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -90438,11 +104067,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -90568,6 +104204,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -90578,11 +104234,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -90727,6 +104390,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -90737,11 +104420,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "nullable": true, @@ -90799,6 +104489,112 @@ }, "type": "array" }, + "add_denies": { + "description": "Patch mode: denies to add or merge, replacing any grant for the same principal.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, + "denies": { + "description": "Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, "grants": { "description": "Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", "example": [ @@ -90852,6 +104648,11 @@ }, "type": "array" }, + "preserve_denies": { + "description": "Retain current server denies atomically in replacement or patch mode; current denies win.", + "example": true, + "type": "boolean" + }, "remove": { "description": "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", "example": [ @@ -90884,6 +104685,39 @@ "type": "object" }, "type": "array" + }, + "remove_denies": { + "description": "Patch mode: principals whose denies should be removed.", + "example": [ + { + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "Identifies a principal to be removed from an access-control list.", + "example": { + "principal": "string", + "principal_type": "user" + }, + "properties": { + "principal": { + "description": "The identifier of the principal to remove. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`. Omit when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal to remove. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type" + ], + "type": "object" + }, + "type": "array" } }, "type": "object" @@ -91706,6 +105540,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -91716,11 +105570,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -93240,6 +107101,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -93250,11 +107131,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "agent": "agt_0aBcDeFgHiJkLmNoPqRsTu", @@ -93304,6 +107192,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -93314,11 +107222,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "agent": "agt_0aBcDeFgHiJkLmNoPqRsTu", @@ -93365,6 +107280,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -93375,11 +107310,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "agent": "agt_0aBcDeFgHiJkLmNoPqRsTu", @@ -93425,6 +107367,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -93435,11 +107397,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "nullable": true, @@ -93497,6 +107466,112 @@ }, "type": "array" }, + "add_denies": { + "description": "Patch mode: denies to add or merge, replacing any grant for the same principal.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, + "denies": { + "description": "Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, "grants": { "description": "Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", "example": [ @@ -93550,6 +107625,11 @@ }, "type": "array" }, + "preserve_denies": { + "description": "Retain current server denies atomically in replacement or patch mode; current denies win.", + "example": true, + "type": "boolean" + }, "remove": { "description": "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", "example": [ @@ -93582,6 +107662,39 @@ "type": "object" }, "type": "array" + }, + "remove_denies": { + "description": "Patch mode: principals whose denies should be removed.", + "example": [ + { + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "Identifies a principal to be removed from an access-control list.", + "example": { + "principal": "string", + "principal_type": "user" + }, + "properties": { + "principal": { + "description": "The identifier of the principal to remove. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`. Omit when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal to remove. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type" + ], + "type": "object" + }, + "type": "array" } }, "type": "object" @@ -94586,6 +108699,26 @@ "description": "Groups tasks by their exact epic label, ordered by label. Closed tasks include cancelled tasks, but cancelled prerequisites still block. Source filters select the tasks summarized; blockers outside that selection still affect readiness. Root ranking is capped per epic and root_blockers_partial is true when that graph is truncated. No epic entity is created.", "operationId": "get_api_v1_users__user_task_epics", "parameters": [ + { + "description": "labels (default) or entities.", + "example": "string", + "in": "query", + "name": "representation", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "Exact entity name; only used for entities.", + "example": "Example Name", + "in": "query", + "name": "name", + "required": false, + "schema": { + "type": "string" + } + }, { "example": "string", "in": "query", @@ -94653,6 +108786,16 @@ "type": "integer" } }, + { + "description": "Keep only epics with at least one non-closed task owned by this user: `me` or a user public ID (`usr_...`).", + "example": "string", + "in": "query", + "name": "owner", + "required": false, + "schema": { + "type": "string" + } + }, { "description": "Include epics with no non-closed tasks; defaults to false.", "example": true, @@ -94689,260 +108832,459 @@ "content": { "application/json": { "schema": { - "example": { - "after_cursor": "string", - "before_cursor": "string", - "data": [ - { - "blocked_count": 1, - "counts": {}, - "epic": "string", - "next_ready": [ - { - "id": "string", - "name": "Example Name", - "priority": 1, - "status": "string" - } - ], - "root_blockers": [ + "anyOf": [ + { + "example": { + "after_cursor": "string", + "before_cursor": "string", + "data": [ { - "downstream_count": 1, - "id": "string", - "name": "Example Name", - "priority": 1, - "status": "string" - } - ], - "root_blockers_partial": true, - "top_open_priority": 1, - "updated_at": "2024-01-01T00:00:00Z" - } - ], - "has_more": true, - "no_epic_open_count": 1 - }, - "properties": { - "after_cursor": { - "example": "string", - "nullable": true, - "type": "string" - }, - "before_cursor": { - "example": "string", - "nullable": true, - "type": "string" - }, - "data": { - "example": [ - { - "blocked_count": 1, - "counts": {}, - "epic": "string", - "next_ready": [ - { - "id": "string", - "name": "Example Name", - "priority": 1, - "status": "string" - } - ], - "root_blockers": [ - { - "downstream_count": 1, - "id": "string", - "name": "Example Name", - "priority": 1, - "status": "string" - } - ], - "root_blockers_partial": true, - "top_open_priority": 1, - "updated_at": "2024-01-01T00:00:00Z" - } - ], - "items": { - "description": "Read-only progress and scheduling summary for an epic label.", - "example": { - "blocked_count": 1, - "counts": {}, - "epic": "string", - "next_ready": [ - { - "id": "string", + "blocked_count": 1, + "counts": {}, + "epic": "string", + "next_ready": [ + { + "id": "string", + "name": "Example Name", + "priority": 1, + "status": "string" + } + ], + "owner": { + "alias": "alice", + "id": "user-usr_01j3k5m7n9p2r4s6t8v0w1x2", "name": "Example Name", - "priority": 1, - "status": "string" - } - ], - "root_blockers": [ - { - "downstream_count": 1, + "profile_picture": { + "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", + "height": 600, + "media": "med_0aBcDeFgHiJkLmNoPqRsTu", + "mime_type": "application/json", + "refresh_url": "https://example.com", + "url": "https://example.com", + "width": 800 + } + }, + "primary_task": { "id": "string", "name": "Example Name", "priority": 1, "status": "string" - } - ], - "root_blockers_partial": true, - "top_open_priority": 1, - "updated_at": "2024-01-01T00:00:00Z" - }, - "properties": { - "blocked_count": { - "example": 1, - "type": "integer" - }, - "counts": { - "description": "Task counts keyed by status, including closed tasks.", - "example": {}, - "type": "object" - }, - "epic": { - "example": "string", - "type": "string" - }, - "next_ready": { - "example": [ + }, + "root_blockers": [ { + "downstream_count": 1, "id": "string", "name": "Example Name", "priority": 1, "status": "string" } ], - "items": { - "description": "An open task with no unfinished prerequisite or active lease.", - "example": { + "root_blockers_partial": true, + "top_open_priority": 1, + "updated_at": "2024-01-01T00:00:00Z" + } + ], + "has_more": true, + "no_epic_open_count": 1 + }, + "properties": { + "after_cursor": { + "example": "string", + "nullable": true, + "type": "string" + }, + "before_cursor": { + "example": "string", + "nullable": true, + "type": "string" + }, + "data": { + "example": [ + { + "blocked_count": 1, + "counts": {}, + "epic": "string", + "next_ready": [ + { + "id": "string", + "name": "Example Name", + "priority": 1, + "status": "string" + } + ], + "owner": { + "alias": "alice", + "id": "user-usr_01j3k5m7n9p2r4s6t8v0w1x2", + "name": "Example Name", + "profile_picture": { + "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", + "height": 600, + "media": "med_0aBcDeFgHiJkLmNoPqRsTu", + "mime_type": "application/json", + "refresh_url": "https://example.com", + "url": "https://example.com", + "width": 800 + } + }, + "primary_task": { "id": "string", "name": "Example Name", "priority": 1, "status": "string" }, - "properties": { - "id": { - "example": "string", - "type": "string" - }, - "name": { - "example": "Example Name", - "type": "string" - }, - "priority": { - "example": 1, - "type": "integer" - }, - "status": { - "example": "string", - "type": "string" + "root_blockers": [ + { + "downstream_count": 1, + "id": "string", + "name": "Example Name", + "priority": 1, + "status": "string" } - }, - "required": [ - "id", - "name", - "status", - "priority" ], - "type": "object" - }, - "type": "array" - }, - "root_blockers": { - "example": [ - { - "downstream_count": 1, - "id": "string", + "root_blockers_partial": true, + "top_open_priority": 1, + "updated_at": "2024-01-01T00:00:00Z" + } + ], + "items": { + "description": "Read-only progress and scheduling summary for an epic label.", + "example": { + "blocked_count": 1, + "counts": {}, + "epic": "string", + "next_ready": [ + { + "id": "string", + "name": "Example Name", + "priority": 1, + "status": "string" + } + ], + "owner": { + "alias": "alice", + "id": "user-usr_01j3k5m7n9p2r4s6t8v0w1x2", "name": "Example Name", - "priority": 1, - "status": "string" - } - ], - "items": { - "description": "An unblocked root and the number of open tasks downstream within its epic.", - "example": { - "downstream_count": 1, + "profile_picture": { + "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", + "height": 600, + "media": "med_0aBcDeFgHiJkLmNoPqRsTu", + "mime_type": "application/json", + "refresh_url": "https://example.com", + "url": "https://example.com", + "width": 800 + } + }, + "primary_task": { "id": "string", "name": "Example Name", "priority": 1, "status": "string" }, - "properties": { - "downstream_count": { - "example": 1, - "type": "integer" + "root_blockers": [ + { + "downstream_count": 1, + "id": "string", + "name": "Example Name", + "priority": 1, + "status": "string" + } + ], + "root_blockers_partial": true, + "top_open_priority": 1, + "updated_at": "2024-01-01T00:00:00Z" + }, + "properties": { + "blocked_count": { + "example": 1, + "type": "integer" + }, + "counts": { + "description": "Task counts keyed by status, including closed tasks.", + "example": {}, + "type": "object" + }, + "epic": { + "example": "string", + "type": "string" + }, + "next_ready": { + "example": [ + { + "id": "string", + "name": "Example Name", + "priority": 1, + "status": "string" + } + ], + "items": { + "description": "An open task with no unfinished prerequisite or active lease.", + "example": { + "id": "string", + "name": "Example Name", + "priority": 1, + "status": "string" + }, + "properties": { + "id": { + "example": "string", + "type": "string" + }, + "name": { + "example": "Example Name", + "type": "string" + }, + "priority": { + "example": 1, + "type": "integer" + }, + "status": { + "example": "string", + "type": "string" + } + }, + "required": [ + "id", + "name", + "status", + "priority" + ], + "type": "object" }, - "id": { - "example": "string", - "type": "string" + "type": "array" + }, + "owner": { + "description": "Owner of the epic's primary task, as `id`, `name`, `alias` and `profile_picture`. The primary task is the top-ranked root blocker (the open task that unblocks the most work), or when no task blocks another, the highest-priority open task (lowest priority number, then ID). `null` when that task is unassigned or the epic has no open task.", + "example": { + "alias": "alice", + "id": "user-usr_01j3k5m7n9p2r4s6t8v0w1x2", + "name": "Example Name", + "profile_picture": { + "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", + "height": 600, + "media": "med_0aBcDeFgHiJkLmNoPqRsTu", + "mime_type": "application/json", + "refresh_url": "https://example.com", + "url": "https://example.com", + "width": 800 + } }, - "name": { - "example": "Example Name", - "type": "string" + "nullable": true, + "properties": { + "alias": { + "description": "Short handle or alias for the actor, used as an alternate display identifier. `null` if not configured.", + "example": "alice", + "nullable": true, + "type": "string" + }, + "id": { + "description": "Composite actor identifier. Format is `\"user-\"` for human users or `\"agent-\"` for agents.", + "example": "user-usr_01j3k5m7n9p2r4s6t8v0w1x2", + "nullable": true, + "type": "string" + }, + "name": { + "description": "Display name of the actor shown in the UI. `null` if no name is set.", + "example": "Example Name", + "nullable": true, + "type": "string" + }, + "profile_picture": { + "description": "Profile picture for the actor. `null` if the actor has no profile picture.", + "example": { + "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", + "height": 600, + "media": "med_0aBcDeFgHiJkLmNoPqRsTu", + "mime_type": "application/json", + "refresh_url": "https://example.com", + "url": "https://example.com", + "width": 800 + }, + "nullable": true, + "properties": { + "file": { + "description": "ID of the underlying storage file (`fil_...`). `null` when the image is not backed by a platform storage file.", + "example": "fil_0aBcDeFgHiJkLmNoPqRsTu", + "nullable": true, + "type": "string" + }, + "height": { + "description": "Height of the image in pixels. `null` if not known.", + "example": 600, + "nullable": true, + "type": "integer" + }, + "media": { + "description": "ID of the associated media record (`med_...`). `null` when the image is not linked to a media entity.", + "example": "med_0aBcDeFgHiJkLmNoPqRsTu", + "nullable": true, + "type": "string" + }, + "mime_type": { + "description": "MIME type of the image, e.g. `\"image/png\"` or `\"image/jpeg\"`. `null` if not known.", + "example": "application/json", + "nullable": true, + "type": "string" + }, + "refresh_url": { + "description": "Endpoint URL you can call to obtain a fresh signed `url` when the current one has expired. `null` if the URL does not require refreshing.", + "example": "https://example.com", + "nullable": true, + "type": "string" + }, + "url": { + "description": "Signed or public URL for downloading the image. May be time-limited; use `refresh_url` to obtain a new URL when this one expires.", + "example": "https://example.com", + "nullable": true, + "type": "string" + }, + "width": { + "description": "Width of the image in pixels. `null` if not known.", + "example": 800, + "nullable": true, + "type": "integer" + } + }, + "type": "object" + } }, - "priority": { - "example": 1, - "type": "integer" + "type": "object" + }, + "primary_task": { + "description": "The primary task whose owner is reported in `owner`. `null` when the epic has no open task.", + "example": { + "id": "string", + "name": "Example Name", + "priority": 1, + "status": "string" }, - "status": { - "example": "string", - "type": "string" - } + "nullable": true, + "properties": { + "id": { + "example": "string", + "type": "string" + }, + "name": { + "example": "Example Name", + "type": "string" + }, + "priority": { + "example": 1, + "type": "integer" + }, + "status": { + "example": "string", + "type": "string" + } + }, + "required": [ + "id", + "name", + "status", + "priority" + ], + "type": "object" }, - "required": [ - "id", - "name", - "status", - "priority", - "downstream_count" - ], - "type": "object" + "root_blockers": { + "example": [ + { + "downstream_count": 1, + "id": "string", + "name": "Example Name", + "priority": 1, + "status": "string" + } + ], + "items": { + "description": "An unblocked root and the number of open tasks downstream within its epic.", + "example": { + "downstream_count": 1, + "id": "string", + "name": "Example Name", + "priority": 1, + "status": "string" + }, + "properties": { + "downstream_count": { + "example": 1, + "type": "integer" + }, + "id": { + "example": "string", + "type": "string" + }, + "name": { + "example": "Example Name", + "type": "string" + }, + "priority": { + "example": 1, + "type": "integer" + }, + "status": { + "example": "string", + "type": "string" + } + }, + "required": [ + "id", + "name", + "status", + "priority", + "downstream_count" + ], + "type": "object" + }, + "type": "array" + }, + "root_blockers_partial": { + "description": "True when root ranking used a truncated in-epic graph.", + "example": true, + "type": "boolean" + }, + "top_open_priority": { + "example": 1, + "nullable": true, + "type": "integer" + }, + "updated_at": { + "example": "2024-01-01T00:00:00Z", + "format": "date-time", + "type": "string" + } }, - "type": "array" - }, - "root_blockers_partial": { - "description": "True when root ranking used a truncated in-epic graph.", - "example": true, - "type": "boolean" - }, - "top_open_priority": { - "example": 1, - "nullable": true, - "type": "integer" + "required": [ + "epic", + "counts", + "blocked_count", + "updated_at", + "root_blockers", + "root_blockers_partial", + "next_ready" + ], + "type": "object" }, - "updated_at": { - "example": "2024-01-01T00:00:00Z", - "format": "date-time", - "type": "string" - } + "type": "array" }, - "required": [ - "epic", - "counts", - "blocked_count", - "updated_at", - "root_blockers", - "root_blockers_partial", - "next_ready" - ], - "type": "object" + "has_more": { + "example": true, + "type": "boolean" + }, + "no_epic_open_count": { + "example": 1, + "type": "integer" + } }, - "type": "array" - }, - "has_more": { - "example": true, - "type": "boolean" + "required": [ + "data", + "has_more", + "no_epic_open_count" + ], + "type": "object" }, - "no_epic_open_count": { - "example": 1, - "type": "integer" + { + "$ref": "#/components/schemas/TaskEpicEntityCollection" } - }, - "required": [ - "data", - "has_more", - "no_epic_open_count" - ], - "type": "object" + ] } } }, @@ -94963,6 +109305,89 @@ "publishable_key", "bearer" ] + }, + "post": { + "operationId": "post_api_v1_users__user_task_epics", + "parameters": [ + { + "example": "string", + "in": "path", + "name": "user", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "example": { + "description": "An example description.", + "metadata": { + "key": "value" + }, + "name": "Example Name", + "state": "string", + "team": "string" + }, + "properties": { + "description": { + "example": "An example description.", + "type": "string" + }, + "metadata": { + "example": { + "key": "value" + }, + "type": "object" + }, + "name": { + "example": "Example Name", + "type": "string" + }, + "state": { + "example": "string", + "type": "string" + }, + "team": { + "example": "string", + "type": "string" + } + }, + "required": [ + "name" + ], + "type": "object" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TaskEpicEntity" + } + } + }, + "description": "Successful response" + }, + "404": { + "description": "Owner not found or Epics disabled" + }, + "422": { + "description": "Invalid Epic" + } + }, + "summary": "Create a task Epic", + "x-auth": [ + "publishable_key", + "bearer" + ] } }, "/api/v1/users/{user}/tasks": { @@ -95030,6 +109455,36 @@ "type": "string" } }, + { + "description": "Return only tasks owned by this user: `me` or a user public ID (`usr_...`).", + "example": "string", + "in": "query", + "name": "owner", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "Return only tasks owned or created by this user: `me` or a user public ID (`usr_...`). The \"My work\" predicate.", + "example": "string", + "in": "query", + "name": "involving", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "When true, omit `description` from every task. Use for list views.", + "example": true, + "in": "query", + "name": "summary", + "required": false, + "schema": { + "type": "boolean" + } + }, { "description": "Filter tasks by priority, from 0 (highest) to 4 (lowest).", "example": 1, @@ -95215,6 +109670,9 @@ "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", "aggregate_version": 1, "blocked_by_count": 1, + "blockers": [ + "string" + ], "closed_at": "2024-01-01T00:00:00Z", "comments_count": 1, "created_at": "2024-01-01T00:00:00Z", @@ -95242,12 +109700,14 @@ "description": "An example description.", "due_date": "2024-01-01T00:00:00Z", "epic": "string", + "human_answer_receipts": {}, "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, "is_stalled": true, "links": { "key": "value" }, + "machine_rescope_receipts": {}, "metadata": { "key": "value" }, @@ -95284,6 +109744,7 @@ ], "target_binary": "string", "target_version": "string", + "task_epic": "string", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -95310,6 +109771,9 @@ "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", "aggregate_version": 1, "blocked_by_count": 1, + "blockers": [ + "string" + ], "closed_at": "2024-01-01T00:00:00Z", "comments_count": 1, "created_at": "2024-01-01T00:00:00Z", @@ -95337,12 +109801,14 @@ "description": "An example description.", "due_date": "2024-01-01T00:00:00Z", "epic": "string", + "human_answer_receipts": {}, "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, "is_stalled": true, "links": { "key": "value" }, + "machine_rescope_receipts": {}, "metadata": { "key": "value" }, @@ -95379,6 +109845,7 @@ ], "target_binary": "string", "target_version": "string", + "task_epic": "string", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -95391,6 +109858,9 @@ "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", "aggregate_version": 1, "blocked_by_count": 1, + "blockers": [ + "string" + ], "closed_at": "2024-01-01T00:00:00Z", "comments_count": 1, "created_at": "2024-01-01T00:00:00Z", @@ -95418,12 +109888,14 @@ "description": "An example description.", "due_date": "2024-01-01T00:00:00Z", "epic": "string", + "human_answer_receipts": {}, "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, "is_stalled": true, "links": { "key": "value" }, + "machine_rescope_receipts": {}, "metadata": { "key": "value" }, @@ -95460,6 +109932,7 @@ ], "target_binary": "string", "target_version": "string", + "task_epic": "string", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -95483,6 +109956,16 @@ "example": 1, "type": "integer" }, + "blockers": { + "description": "Visible blocker IDs when requested with include=blockers.", + "example": [ + "string" + ], + "items": { + "type": "string" + }, + "type": "array" + }, "closed_at": { "description": "When the task was marked as done or otherwise closed (ISO 8601). `null` if the task is still open.", "example": "2024-01-01T00:00:00Z", @@ -95662,6 +110145,11 @@ "nullable": true, "type": "string" }, + "human_answer_receipts": { + "description": "Server-owned authenticated human answer intent, keyed by question version. Not infrastructure permission.", + "example": {}, + "type": "object" + }, "id": { "description": "Task ID (`tsk_...`).", "example": "tsk_0aBcDeFgHiJkLmNoPqRsTu", @@ -95684,6 +110172,11 @@ }, "type": "object" }, + "machine_rescope_receipts": { + "description": "Server-owned records of machine-applied local rescopes, keyed by question version. Never evidence that a human answered.", + "example": {}, + "type": "object" + }, "metadata": { "description": "Arbitrary key-value map of application-specific data stored alongside the task. Returns an empty object when no metadata has been set.", "example": { @@ -95891,6 +110384,12 @@ "nullable": true, "type": "string" }, + "task_epic": { + "description": "First-class Epic membership; does not grant access to the task.", + "example": "string", + "nullable": true, + "type": "string" + }, "team": { "description": "ID of the team that owns this task (`tem_...`). `null` if the task is not scoped to a team.", "example": "tem_0aBcDeFgHiJkLmNoPqRsTu", @@ -95983,9 +110482,13 @@ "agent": "string", "org": "string", "task": { + "blockers": [ + "string" + ], "description": "An example description.", "due_date": "2024-01-01T00:00:00Z", "epic": "billing-cadence", + "epic_id": "string", "id": "string", "links": { "key": "value" @@ -96027,9 +110530,13 @@ "task": { "description": "Attributes for the task to create. `name` is required; all other fields are optional.", "example": { + "blockers": [ + "string" + ], "description": "An example description.", "due_date": "2024-01-01T00:00:00Z", "epic": "billing-cadence", + "epic_id": "string", "id": "string", "links": { "key": "value" @@ -96056,6 +110563,16 @@ "thread": "thr_01j3k5m7n9p2r4s6t8v0w1x2" }, "properties": { + "blockers": { + "description": "Existing task IDs (`tsk_...`) that block this task. Recorded atomically with creation; the task is not ready until these blockers are done.", + "example": [ + "string" + ], + "items": { + "type": "string" + }, + "type": "array" + }, "description": { "description": "Optional long-form description or notes for the task. Supports plain text.", "example": "An example description.", @@ -96072,6 +110589,11 @@ "example": "billing-cadence", "type": "string" }, + "epic_id": { + "description": "First-class Epic ID (`epc_...`).", + "example": "string", + "type": "string" + }, "id": { "description": "Optional caller-generated task public ID (`tsk_...`). Persist it before creating a task when creation must survive a lost response. An existing ID returns 409 without modifying the task; read the task by ID to reconcile. Omit for a server-generated ID.", "example": "string", @@ -96291,6 +110813,9 @@ "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", "aggregate_version": 1, "blocked_by_count": 1, + "blockers": [ + "string" + ], "closed_at": "2024-01-01T00:00:00Z", "comments_count": 1, "created_at": "2024-01-01T00:00:00Z", @@ -96318,12 +110843,14 @@ "description": "An example description.", "due_date": "2024-01-01T00:00:00Z", "epic": "string", + "human_answer_receipts": {}, "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, "is_stalled": true, "links": { "key": "value" }, + "machine_rescope_receipts": {}, "metadata": { "key": "value" }, @@ -96360,6 +110887,7 @@ ], "target_binary": "string", "target_version": "string", + "task_epic": "string", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -96387,6 +110915,9 @@ "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", "aggregate_version": 1, "blocked_by_count": 1, + "blockers": [ + "string" + ], "closed_at": "2024-01-01T00:00:00Z", "comments_count": 1, "created_at": "2024-01-01T00:00:00Z", @@ -96414,12 +110945,14 @@ "description": "An example description.", "due_date": "2024-01-01T00:00:00Z", "epic": "string", + "human_answer_receipts": {}, "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, "is_stalled": true, "links": { "key": "value" }, + "machine_rescope_receipts": {}, "metadata": { "key": "value" }, @@ -96456,6 +110989,7 @@ ], "target_binary": "string", "target_version": "string", + "task_epic": "string", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -96472,6 +111006,9 @@ "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", "aggregate_version": 1, "blocked_by_count": 1, + "blockers": [ + "string" + ], "closed_at": "2024-01-01T00:00:00Z", "comments_count": 1, "created_at": "2024-01-01T00:00:00Z", @@ -96499,12 +111036,14 @@ "description": "An example description.", "due_date": "2024-01-01T00:00:00Z", "epic": "string", + "human_answer_receipts": {}, "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, "is_stalled": true, "links": { "key": "value" }, + "machine_rescope_receipts": {}, "metadata": { "key": "value" }, @@ -96541,6 +111080,7 @@ ], "target_binary": "string", "target_version": "string", + "task_epic": "string", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -96556,6 +111096,9 @@ "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", "aggregate_version": 1, "blocked_by_count": 1, + "blockers": [ + "string" + ], "closed_at": "2024-01-01T00:00:00Z", "comments_count": 1, "created_at": "2024-01-01T00:00:00Z", @@ -96583,12 +111126,14 @@ "description": "An example description.", "due_date": "2024-01-01T00:00:00Z", "epic": "string", + "human_answer_receipts": {}, "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, "is_stalled": true, "links": { "key": "value" }, + "machine_rescope_receipts": {}, "metadata": { "key": "value" }, @@ -96625,6 +111170,7 @@ ], "target_binary": "string", "target_version": "string", + "task_epic": "string", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -96637,6 +111183,9 @@ "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", "aggregate_version": 1, "blocked_by_count": 1, + "blockers": [ + "string" + ], "closed_at": "2024-01-01T00:00:00Z", "comments_count": 1, "created_at": "2024-01-01T00:00:00Z", @@ -96664,12 +111213,14 @@ "description": "An example description.", "due_date": "2024-01-01T00:00:00Z", "epic": "string", + "human_answer_receipts": {}, "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, "is_stalled": true, "links": { "key": "value" }, + "machine_rescope_receipts": {}, "metadata": { "key": "value" }, @@ -96706,6 +111257,7 @@ ], "target_binary": "string", "target_version": "string", + "task_epic": "string", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -96729,6 +111281,16 @@ "example": 1, "type": "integer" }, + "blockers": { + "description": "Visible blocker IDs when requested with include=blockers.", + "example": [ + "string" + ], + "items": { + "type": "string" + }, + "type": "array" + }, "closed_at": { "description": "When the task was marked as done or otherwise closed (ISO 8601). `null` if the task is still open.", "example": "2024-01-01T00:00:00Z", @@ -96908,6 +111470,11 @@ "nullable": true, "type": "string" }, + "human_answer_receipts": { + "description": "Server-owned authenticated human answer intent, keyed by question version. Not infrastructure permission.", + "example": {}, + "type": "object" + }, "id": { "description": "Task ID (`tsk_...`).", "example": "tsk_0aBcDeFgHiJkLmNoPqRsTu", @@ -96930,6 +111497,11 @@ }, "type": "object" }, + "machine_rescope_receipts": { + "description": "Server-owned records of machine-applied local rescopes, keyed by question version. Never evidence that a human answered.", + "example": {}, + "type": "object" + }, "metadata": { "description": "Arbitrary key-value map of application-specific data stored alongside the task. Returns an empty object when no metadata has been set.", "example": { @@ -97137,6 +111709,12 @@ "nullable": true, "type": "string" }, + "task_epic": { + "description": "First-class Epic membership; does not grant access to the task.", + "example": "string", + "nullable": true, + "type": "string" + }, "team": { "description": "ID of the team that owns this task (`tem_...`). `null` if the task is not scoped to a team.", "example": "tem_0aBcDeFgHiJkLmNoPqRsTu", @@ -97211,6 +111789,853 @@ ] } }, + "/api/v1/users/{user}/tasks/by-external-reference": { + "get": { + "description": "Returns all exact external-reference matches owned by the requested principal. Multiple matches remain explicit; callers must not choose an arbitrary task.", + "operationId": "get_api_v1_users__user_tasks_by-external-reference", + "parameters": [ + { + "description": "User owner.", + "example": "string", + "in": "path", + "name": "user", + "required": true, + "schema": { + "type": "string" + } + }, + { + "description": "Team owner.", + "example": "string", + "in": "query", + "name": "team", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "Organization consistency check.", + "example": "string", + "in": "query", + "name": "org", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "External host.", + "example": "string", + "in": "query", + "name": "external_scope", + "required": true, + "schema": { + "type": "string" + } + }, + { + "description": "External object type.", + "example": "string", + "in": "query", + "name": "object_type", + "required": true, + "schema": { + "type": "string" + } + }, + { + "description": "External object identity.", + "example": "string", + "in": "query", + "name": "object_id", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "description": "Owner-isolated matching tasks.", + "example": { + "data": [ + { + "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", + "aggregate_version": 1, + "blocked_by_count": 1, + "blockers": [ + "string" + ], + "closed_at": "2024-01-01T00:00:00Z", + "comments_count": 1, + "created_at": "2024-01-01T00:00:00Z", + "created_by_actor": { + "alias": "alice", + "id": "user-usr_01j3k5m7n9p2r4s6t8v0w1x2", + "name": "Example Name", + "profile_picture": { + "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", + "height": 600, + "media": "med_0aBcDeFgHiJkLmNoPqRsTu", + "mime_type": "application/json", + "refresh_url": "https://example.com", + "url": "https://example.com", + "width": 800 + } + }, + "created_by_agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", + "created_by_user": "usr_0aBcDeFgHiJkLmNoPqRsTu", + "current_lease": { + "expires_at": "2024-01-01T00:00:00Z", + "harness": "string", + "session_name": "Example Name" + }, + "description": "An example description.", + "due_date": "2024-01-01T00:00:00Z", + "epic": "string", + "human_answer_receipts": {}, + "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", + "is_blocked": true, + "is_stalled": true, + "links": { + "key": "value" + }, + "machine_rescope_receipts": {}, + "metadata": { + "key": "value" + }, + "name": "Example Name", + "org": "org_0aBcDeFgHiJkLmNoPqRsTu", + "owner_actor": { + "alias": "alice", + "id": "user-usr_01j3k5m7n9p2r4s6t8v0w1x2", + "name": "Example Name", + "profile_picture": { + "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", + "height": 600, + "media": "med_0aBcDeFgHiJkLmNoPqRsTu", + "mime_type": "application/json", + "refresh_url": "https://example.com", + "url": "https://example.com", + "width": 800 + } + }, + "owner_agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", + "owner_user": "usr_0aBcDeFgHiJkLmNoPqRsTu", + "parent": "tsk_0aBcDeFgHiJkLmNoPqRsTu", + "priority": 2, + "project_id": "string", + "sandbox": "dsb_0aBcDeFgHiJkLmNoPqRsTu", + "source_id": "string", + "source_scope": "string", + "source_type": "string", + "stalled_since": "2024-01-01T00:00:00Z", + "status": "open", + "subtasks_count": 1, + "tags": [ + "string" + ], + "target_binary": "string", + "target_version": "string", + "task_epic": "string", + "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", + "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", + "updated_at": "2024-01-01T00:00:00Z", + "user": "usr_0aBcDeFgHiJkLmNoPqRsTu" + } + ] + }, + "properties": { + "data": { + "example": [ + { + "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", + "aggregate_version": 1, + "blocked_by_count": 1, + "blockers": [ + "string" + ], + "closed_at": "2024-01-01T00:00:00Z", + "comments_count": 1, + "created_at": "2024-01-01T00:00:00Z", + "created_by_actor": { + "alias": "alice", + "id": "user-usr_01j3k5m7n9p2r4s6t8v0w1x2", + "name": "Example Name", + "profile_picture": { + "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", + "height": 600, + "media": "med_0aBcDeFgHiJkLmNoPqRsTu", + "mime_type": "application/json", + "refresh_url": "https://example.com", + "url": "https://example.com", + "width": 800 + } + }, + "created_by_agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", + "created_by_user": "usr_0aBcDeFgHiJkLmNoPqRsTu", + "current_lease": { + "expires_at": "2024-01-01T00:00:00Z", + "harness": "string", + "session_name": "Example Name" + }, + "description": "An example description.", + "due_date": "2024-01-01T00:00:00Z", + "epic": "string", + "human_answer_receipts": {}, + "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", + "is_blocked": true, + "is_stalled": true, + "links": { + "key": "value" + }, + "machine_rescope_receipts": {}, + "metadata": { + "key": "value" + }, + "name": "Example Name", + "org": "org_0aBcDeFgHiJkLmNoPqRsTu", + "owner_actor": { + "alias": "alice", + "id": "user-usr_01j3k5m7n9p2r4s6t8v0w1x2", + "name": "Example Name", + "profile_picture": { + "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", + "height": 600, + "media": "med_0aBcDeFgHiJkLmNoPqRsTu", + "mime_type": "application/json", + "refresh_url": "https://example.com", + "url": "https://example.com", + "width": 800 + } + }, + "owner_agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", + "owner_user": "usr_0aBcDeFgHiJkLmNoPqRsTu", + "parent": "tsk_0aBcDeFgHiJkLmNoPqRsTu", + "priority": 2, + "project_id": "string", + "sandbox": "dsb_0aBcDeFgHiJkLmNoPqRsTu", + "source_id": "string", + "source_scope": "string", + "source_type": "string", + "stalled_since": "2024-01-01T00:00:00Z", + "status": "open", + "subtasks_count": 1, + "tags": [ + "string" + ], + "target_binary": "string", + "target_version": "string", + "task_epic": "string", + "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", + "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", + "updated_at": "2024-01-01T00:00:00Z", + "user": "usr_0aBcDeFgHiJkLmNoPqRsTu" + } + ], + "items": { + "description": "A task representing a unit of work, optionally assignable to a user or agent.", + "example": { + "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", + "aggregate_version": 1, + "blocked_by_count": 1, + "blockers": [ + "string" + ], + "closed_at": "2024-01-01T00:00:00Z", + "comments_count": 1, + "created_at": "2024-01-01T00:00:00Z", + "created_by_actor": { + "alias": "alice", + "id": "user-usr_01j3k5m7n9p2r4s6t8v0w1x2", + "name": "Example Name", + "profile_picture": { + "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", + "height": 600, + "media": "med_0aBcDeFgHiJkLmNoPqRsTu", + "mime_type": "application/json", + "refresh_url": "https://example.com", + "url": "https://example.com", + "width": 800 + } + }, + "created_by_agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", + "created_by_user": "usr_0aBcDeFgHiJkLmNoPqRsTu", + "current_lease": { + "expires_at": "2024-01-01T00:00:00Z", + "harness": "string", + "session_name": "Example Name" + }, + "description": "An example description.", + "due_date": "2024-01-01T00:00:00Z", + "epic": "string", + "human_answer_receipts": {}, + "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", + "is_blocked": true, + "is_stalled": true, + "links": { + "key": "value" + }, + "machine_rescope_receipts": {}, + "metadata": { + "key": "value" + }, + "name": "Example Name", + "org": "org_0aBcDeFgHiJkLmNoPqRsTu", + "owner_actor": { + "alias": "alice", + "id": "user-usr_01j3k5m7n9p2r4s6t8v0w1x2", + "name": "Example Name", + "profile_picture": { + "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", + "height": 600, + "media": "med_0aBcDeFgHiJkLmNoPqRsTu", + "mime_type": "application/json", + "refresh_url": "https://example.com", + "url": "https://example.com", + "width": 800 + } + }, + "owner_agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", + "owner_user": "usr_0aBcDeFgHiJkLmNoPqRsTu", + "parent": "tsk_0aBcDeFgHiJkLmNoPqRsTu", + "priority": 2, + "project_id": "string", + "sandbox": "dsb_0aBcDeFgHiJkLmNoPqRsTu", + "source_id": "string", + "source_scope": "string", + "source_type": "string", + "stalled_since": "2024-01-01T00:00:00Z", + "status": "open", + "subtasks_count": 1, + "tags": [ + "string" + ], + "target_binary": "string", + "target_version": "string", + "task_epic": "string", + "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", + "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", + "updated_at": "2024-01-01T00:00:00Z", + "user": "usr_0aBcDeFgHiJkLmNoPqRsTu" + }, + "properties": { + "agent": { + "description": "ID of the agent that owns this task (`agi_...`). `null` if the task is scoped to a team or user.", + "example": "agi_0aBcDeFgHiJkLmNoPqRsTu", + "nullable": true, + "type": "string" + }, + "aggregate_version": { + "description": "Event-stream version for optimistic update fencing. Pass this value as `expected_version` on an update to reject concurrent writes.", + "example": 1, + "nullable": true, + "type": "integer" + }, + "blocked_by_count": { + "description": "Number of readable tasks marked as blocking this task, whether or not they are done (see `GET /tasks/{task}/blockers`). Computed on list/show reads; create/update responses may lag one read behind.", + "example": 1, + "type": "integer" + }, + "blockers": { + "description": "Visible blocker IDs when requested with include=blockers.", + "example": [ + "string" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "closed_at": { + "description": "When the task was marked as done or otherwise closed (ISO 8601). `null` if the task is still open.", + "example": "2024-01-01T00:00:00Z", + "format": "date-time", + "nullable": true, + "type": "string" + }, + "comments_count": { + "description": "Total number of comments posted on this task.", + "example": 1, + "type": "integer" + }, + "created_at": { + "description": "When the task was created (ISO 8601).", + "example": "2024-01-01T00:00:00Z", + "format": "date-time", + "type": "string" + }, + "created_by_actor": { + "description": "Resolved creator details including `id`, `name`, `alias`, and `profile_picture`. `null` if no creator is set or the creator cannot be resolved (e.g. creating agent was deleted).", + "example": { + "alias": "alice", + "id": "user-usr_01j3k5m7n9p2r4s6t8v0w1x2", + "name": "Example Name", + "profile_picture": { + "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", + "height": 600, + "media": "med_0aBcDeFgHiJkLmNoPqRsTu", + "mime_type": "application/json", + "refresh_url": "https://example.com", + "url": "https://example.com", + "width": 800 + } + }, + "nullable": true, + "properties": { + "alias": { + "description": "Short handle or alias for the actor, used as an alternate display identifier. `null` if not configured.", + "example": "alice", + "nullable": true, + "type": "string" + }, + "id": { + "description": "Composite actor identifier. Format is `\"user-\"` for human users or `\"agent-\"` for agents.", + "example": "user-usr_01j3k5m7n9p2r4s6t8v0w1x2", + "nullable": true, + "type": "string" + }, + "name": { + "description": "Display name of the actor shown in the UI. `null` if no name is set.", + "example": "Example Name", + "nullable": true, + "type": "string" + }, + "profile_picture": { + "description": "Profile picture for the actor. `null` if the actor has no profile picture.", + "example": { + "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", + "height": 600, + "media": "med_0aBcDeFgHiJkLmNoPqRsTu", + "mime_type": "application/json", + "refresh_url": "https://example.com", + "url": "https://example.com", + "width": 800 + }, + "nullable": true, + "properties": { + "file": { + "description": "ID of the underlying storage file (`fil_...`). `null` when the image is not backed by a platform storage file.", + "example": "fil_0aBcDeFgHiJkLmNoPqRsTu", + "nullable": true, + "type": "string" + }, + "height": { + "description": "Height of the image in pixels. `null` if not known.", + "example": 600, + "nullable": true, + "type": "integer" + }, + "media": { + "description": "ID of the associated media record (`med_...`). `null` when the image is not linked to a media entity.", + "example": "med_0aBcDeFgHiJkLmNoPqRsTu", + "nullable": true, + "type": "string" + }, + "mime_type": { + "description": "MIME type of the image, e.g. `\"image/png\"` or `\"image/jpeg\"`. `null` if not known.", + "example": "application/json", + "nullable": true, + "type": "string" + }, + "refresh_url": { + "description": "Endpoint URL you can call to obtain a fresh signed `url` when the current one has expired. `null` if the URL does not require refreshing.", + "example": "https://example.com", + "nullable": true, + "type": "string" + }, + "url": { + "description": "Signed or public URL for downloading the image. May be time-limited; use `refresh_url` to obtain a new URL when this one expires.", + "example": "https://example.com", + "nullable": true, + "type": "string" + }, + "width": { + "description": "Width of the image in pixels. `null` if not known.", + "example": 800, + "nullable": true, + "type": "integer" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "created_by_agent": { + "description": "ID of the agent that created this task (`agi_...`). `null` if the task was created by a human user, or if the creating agent was later deleted.", + "example": "agi_0aBcDeFgHiJkLmNoPqRsTu", + "nullable": true, + "type": "string" + }, + "created_by_user": { + "description": "ID of the user who created this task (`usr_...`). `null` if the task was created by an agent, or if creator provenance was cleared after the creator was deleted.", + "example": "usr_0aBcDeFgHiJkLmNoPqRsTu", + "nullable": true, + "type": "string" + }, + "current_lease": { + "description": "Viewer-safe live coding-session lease summary. `null` when the task is unleased or the projected lease has expired. Fencing identifiers are never included.", + "example": { + "expires_at": "2024-01-01T00:00:00Z", + "harness": "string", + "session_name": "Example Name" + }, + "nullable": true, + "properties": { + "expires_at": { + "description": "Server-calculated lease expiry in ISO 8601 format.", + "example": "2024-01-01T00:00:00Z", + "format": "date-time", + "type": "string" + }, + "harness": { + "description": "Bounded harness identifier for the coding session.", + "example": "string", + "type": "string" + }, + "session_name": { + "description": "Display name supplied by the coding session that holds the lease.", + "example": "Example Name", + "type": "string" + } + }, + "required": [ + "session_name", + "harness", + "expires_at" + ], + "type": "object" + }, + "description": { + "description": "Long-form description or notes for the task. `null` if no description has been provided.", + "example": "An example description.", + "nullable": true, + "type": "string" + }, + "due_date": { + "description": "Date and time by which the task should be completed (ISO 8601). `null` if no due date is set.", + "example": "2024-01-01T00:00:00Z", + "format": "date-time", + "nullable": true, + "type": "string" + }, + "epic": { + "description": "Free-form grouping label. `null` when the task is not in an epic.", + "example": "string", + "nullable": true, + "type": "string" + }, + "human_answer_receipts": { + "description": "Server-owned authenticated human answer intent, keyed by question version. Not infrastructure permission.", + "example": {}, + "type": "object" + }, + "id": { + "description": "Task ID (`tsk_...`).", + "example": "tsk_0aBcDeFgHiJkLmNoPqRsTu", + "type": "string" + }, + "is_blocked": { + "description": "`true` while at least one blocking task is not yet done. Informational only - a blocked task can still change status - and derived at read time, so the task un-blocks automatically when its last open blocker completes. Computed on reads, including mutation responses.", + "example": true, + "type": "boolean" + }, + "is_stalled": { + "description": "True exactly when status is in_progress and the task has no lease or its lease expiry is in the past. Derived at read time from status and lease expiry, including on unannotated reads.", + "example": true, + "type": "boolean" + }, + "links": { + "description": "Key-value map of named URLs or references associated with the task. Returns an empty object when no links have been set.", + "example": { + "key": "value" + }, + "type": "object" + }, + "machine_rescope_receipts": { + "description": "Server-owned records of machine-applied local rescopes, keyed by question version. Never evidence that a human answered.", + "example": {}, + "type": "object" + }, + "metadata": { + "description": "Arbitrary key-value map of application-specific data stored alongside the task. Returns an empty object when no metadata has been set.", + "example": { + "key": "value" + }, + "type": "object" + }, + "name": { + "description": "Human-readable title of the task.", + "example": "Example Name", + "type": "string" + }, + "org": { + "description": "ID of the organization this task belongs to (`org_...`). `null` for tasks outside an org context.", + "example": "org_0aBcDeFgHiJkLmNoPqRsTu", + "nullable": true, + "type": "string" + }, + "owner_actor": { + "description": "Resolved owner details including `id`, `name`, `alias`, and `profile_picture`. `null` if the task is unassigned or the owner cannot be resolved (e.g. assigned agent was deleted).", + "example": { + "alias": "alice", + "id": "user-usr_01j3k5m7n9p2r4s6t8v0w1x2", + "name": "Example Name", + "profile_picture": { + "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", + "height": 600, + "media": "med_0aBcDeFgHiJkLmNoPqRsTu", + "mime_type": "application/json", + "refresh_url": "https://example.com", + "url": "https://example.com", + "width": 800 + } + }, + "nullable": true, + "properties": { + "alias": { + "description": "Short handle or alias for the actor, used as an alternate display identifier. `null` if not configured.", + "example": "alice", + "nullable": true, + "type": "string" + }, + "id": { + "description": "Composite actor identifier. Format is `\"user-\"` for human users or `\"agent-\"` for agents.", + "example": "user-usr_01j3k5m7n9p2r4s6t8v0w1x2", + "nullable": true, + "type": "string" + }, + "name": { + "description": "Display name of the actor shown in the UI. `null` if no name is set.", + "example": "Example Name", + "nullable": true, + "type": "string" + }, + "profile_picture": { + "description": "Profile picture for the actor. `null` if the actor has no profile picture.", + "example": { + "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", + "height": 600, + "media": "med_0aBcDeFgHiJkLmNoPqRsTu", + "mime_type": "application/json", + "refresh_url": "https://example.com", + "url": "https://example.com", + "width": 800 + }, + "nullable": true, + "properties": { + "file": { + "description": "ID of the underlying storage file (`fil_...`). `null` when the image is not backed by a platform storage file.", + "example": "fil_0aBcDeFgHiJkLmNoPqRsTu", + "nullable": true, + "type": "string" + }, + "height": { + "description": "Height of the image in pixels. `null` if not known.", + "example": 600, + "nullable": true, + "type": "integer" + }, + "media": { + "description": "ID of the associated media record (`med_...`). `null` when the image is not linked to a media entity.", + "example": "med_0aBcDeFgHiJkLmNoPqRsTu", + "nullable": true, + "type": "string" + }, + "mime_type": { + "description": "MIME type of the image, e.g. `\"image/png\"` or `\"image/jpeg\"`. `null` if not known.", + "example": "application/json", + "nullable": true, + "type": "string" + }, + "refresh_url": { + "description": "Endpoint URL you can call to obtain a fresh signed `url` when the current one has expired. `null` if the URL does not require refreshing.", + "example": "https://example.com", + "nullable": true, + "type": "string" + }, + "url": { + "description": "Signed or public URL for downloading the image. May be time-limited; use `refresh_url` to obtain a new URL when this one expires.", + "example": "https://example.com", + "nullable": true, + "type": "string" + }, + "width": { + "description": "Width of the image in pixels. `null` if not known.", + "example": 800, + "nullable": true, + "type": "integer" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "owner_agent": { + "description": "ID of the agent assigned as owner (`agi_...`). `null` if the owner is a human user, the task is unassigned, or the assigned agent was deleted.", + "example": "agi_0aBcDeFgHiJkLmNoPqRsTu", + "nullable": true, + "type": "string" + }, + "owner_user": { + "description": "ID of the user assigned as owner (`usr_...`). `null` if the owner is an agent, the task is unassigned, or the assigned agent was deleted.", + "example": "usr_0aBcDeFgHiJkLmNoPqRsTu", + "nullable": true, + "type": "string" + }, + "parent": { + "description": "ID of the parent task when this task is a subtask (`tsk_...`). `null` for top-level tasks or when the parent is not readable. Subtasks nest exactly one level.", + "example": "tsk_0aBcDeFgHiJkLmNoPqRsTu", + "nullable": true, + "type": "string" + }, + "priority": { + "description": "Priority level of the task from `0` (highest) to `4` (lowest). Defaults to `2` (medium) when not explicitly set.", + "example": 2, + "type": "integer" + }, + "project_id": { + "description": "Optional project ID (`prj_...`). Membership does not change task visibility.", + "example": "string", + "nullable": true, + "type": "string" + }, + "sandbox": { + "description": "ID of the developer sandbox this task is scoped to (`dsb_...`). `null` for tasks outside a sandbox environment.", + "example": "dsb_0aBcDeFgHiJkLmNoPqRsTu", + "nullable": true, + "type": "string" + }, + "source_id": { + "description": "Source object identity (for example `ArchAstro/firstlanding`). `null` when the task has no source.", + "example": "string", + "nullable": true, + "type": "string" + }, + "source_scope": { + "description": "Container of the work this task is about (for example `github.com`). `null` when the task has no source. Set together with `source_type` and `source_id`.", + "example": "string", + "nullable": true, + "type": "string" + }, + "source_type": { + "description": "Kind of source object (for example `repository`). `null` when the task has no source.", + "example": "string", + "nullable": true, + "type": "string" + }, + "stalled_since": { + "description": "Lease expiry for a stalled task, or its last update when no lease expiry exists. Null when not stalled.", + "example": "2024-01-01T00:00:00Z", + "format": "date-time", + "nullable": true, + "type": "string" + }, + "status": { + "description": "Current status of the task. One of `\"open\"`, `\"in_progress\"`, `\"in_review\"`, `\"paused\"`, `\"failed\"`, `\"superseding\"`, `\"done\"`, or `\"cancelled\"`.", + "example": "open", + "type": "string" + }, + "subtasks_count": { + "description": "Number of readable subtasks under this task. Computed on list/show reads; create/update responses may report 0 until the next read. Always 0 for subtasks.", + "example": 1, + "type": "integer" + }, + "tags": { + "description": "Labels for grouping and filtering, stored lowercase and de-duplicated. Empty array when untagged.", + "example": [ + "string" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "target_binary": { + "description": "Binary that must run this work (for example `my-cli`). A worker should take the task only when its own `target_binary` build is at least `target_version`. `null` when the task has no target. Set together with `target_version`.", + "example": "string", + "nullable": true, + "type": "string" + }, + "target_version": { + "description": "Minimum semantic version of `target_binary` that can run this work (for example `0.48.9`), in canonical `MAJOR.MINOR.PATCH[-prerelease][+build]` form. `null` when the task has no target.", + "example": "string", + "nullable": true, + "type": "string" + }, + "task_epic": { + "description": "First-class Epic membership; does not grant access to the task.", + "example": "string", + "nullable": true, + "type": "string" + }, + "team": { + "description": "ID of the team that owns this task (`tem_...`). `null` if the task is not scoped to a team.", + "example": "tem_0aBcDeFgHiJkLmNoPqRsTu", + "nullable": true, + "type": "string" + }, + "thread": { + "description": "ID of the thread this task is bound to (`thr_...`) - the conversation it was filed from, or the thread passed at creation. `null` for tasks not tied to a thread.", + "example": "thr_0aBcDeFgHiJkLmNoPqRsTu", + "nullable": true, + "type": "string" + }, + "updated_at": { + "description": "When the task was last modified (ISO 8601).", + "example": "2024-01-01T00:00:00Z", + "format": "date-time", + "type": "string" + }, + "user": { + "description": "ID of the user that owns this task (`usr_...`). `null` if the task is scoped to a team.", + "example": "usr_0aBcDeFgHiJkLmNoPqRsTu", + "nullable": true, + "type": "string" + } + }, + "required": [ + "id", + "name", + "status" + ], + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "data" + ], + "type": "object" + } + } + }, + "description": "Successful response" + }, + "401": { + "description": "Unauthorized" + }, + "404": { + "description": "Task owner not found" + }, + "422": { + "description": "Validation error" + } + }, + "summary": "Find an owner's tasks by external reference", + "x-auth": [ + "publishable_key", + "bearer" + ] + } + }, "/api/v1/users/{user}/tasks/by-source": { "put": { "description": "Atomically creates one task per owner, tenant and source. Retries return the current task without updating it. Historical tasks created through ordinary create are not adopted.", @@ -97237,6 +112662,7 @@ "epic": "string", "name": "Example Name", "org": "string", + "owner_user": "string", "source_id": "string", "source_scope": "string", "source_type": "string", @@ -97269,6 +112695,11 @@ "example": "string", "type": "string" }, + "owner_user": { + "description": "Initial assigned user; immutable on retries.", + "example": "string", + "type": "string" + }, "source_id": { "description": "Source identity, for example owner/repo#123.", "example": "string", @@ -97469,6 +112900,9 @@ "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", "aggregate_version": 1, "blocked_by_count": 1, + "blockers": [ + "string" + ], "closed_at": "2024-01-01T00:00:00Z", "comments_count": 1, "created_at": "2024-01-01T00:00:00Z", @@ -97496,12 +112930,14 @@ "description": "An example description.", "due_date": "2024-01-01T00:00:00Z", "epic": "string", + "human_answer_receipts": {}, "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, "is_stalled": true, "links": { "key": "value" }, + "machine_rescope_receipts": {}, "metadata": { "key": "value" }, @@ -97538,6 +112974,7 @@ ], "target_binary": "string", "target_version": "string", + "task_epic": "string", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -97570,6 +113007,9 @@ "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", "aggregate_version": 1, "blocked_by_count": 1, + "blockers": [ + "string" + ], "closed_at": "2024-01-01T00:00:00Z", "comments_count": 1, "created_at": "2024-01-01T00:00:00Z", @@ -97597,12 +113037,14 @@ "description": "An example description.", "due_date": "2024-01-01T00:00:00Z", "epic": "string", + "human_answer_receipts": {}, "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, "is_stalled": true, "links": { "key": "value" }, + "machine_rescope_receipts": {}, "metadata": { "key": "value" }, @@ -97639,6 +113081,7 @@ ], "target_binary": "string", "target_version": "string", + "task_epic": "string", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -97655,6 +113098,9 @@ "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", "aggregate_version": 1, "blocked_by_count": 1, + "blockers": [ + "string" + ], "closed_at": "2024-01-01T00:00:00Z", "comments_count": 1, "created_at": "2024-01-01T00:00:00Z", @@ -97682,12 +113128,14 @@ "description": "An example description.", "due_date": "2024-01-01T00:00:00Z", "epic": "string", + "human_answer_receipts": {}, "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, "is_stalled": true, "links": { "key": "value" }, + "machine_rescope_receipts": {}, "metadata": { "key": "value" }, @@ -97724,6 +113172,7 @@ ], "target_binary": "string", "target_version": "string", + "task_epic": "string", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -97757,6 +113206,9 @@ "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", "aggregate_version": 1, "blocked_by_count": 1, + "blockers": [ + "string" + ], "closed_at": "2024-01-01T00:00:00Z", "comments_count": 1, "created_at": "2024-01-01T00:00:00Z", @@ -97784,12 +113236,14 @@ "description": "An example description.", "due_date": "2024-01-01T00:00:00Z", "epic": "string", + "human_answer_receipts": {}, "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, "is_stalled": true, "links": { "key": "value" }, + "machine_rescope_receipts": {}, "metadata": { "key": "value" }, @@ -97826,6 +113280,7 @@ ], "target_binary": "string", "target_version": "string", + "task_epic": "string", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -97849,6 +113304,16 @@ "example": 1, "type": "integer" }, + "blockers": { + "description": "Visible blocker IDs when requested with include=blockers.", + "example": [ + "string" + ], + "items": { + "type": "string" + }, + "type": "array" + }, "closed_at": { "description": "When the task was marked as done or otherwise closed (ISO 8601). `null` if the task is still open.", "example": "2024-01-01T00:00:00Z", @@ -98028,6 +113493,11 @@ "nullable": true, "type": "string" }, + "human_answer_receipts": { + "description": "Server-owned authenticated human answer intent, keyed by question version. Not infrastructure permission.", + "example": {}, + "type": "object" + }, "id": { "description": "Task ID (`tsk_...`).", "example": "tsk_0aBcDeFgHiJkLmNoPqRsTu", @@ -98050,6 +113520,11 @@ }, "type": "object" }, + "machine_rescope_receipts": { + "description": "Server-owned records of machine-applied local rescopes, keyed by question version. Never evidence that a human answered.", + "example": {}, + "type": "object" + }, "metadata": { "description": "Arbitrary key-value map of application-specific data stored alongside the task. Returns an empty object when no metadata has been set.", "example": { @@ -98257,6 +113732,12 @@ "nullable": true, "type": "string" }, + "task_epic": { + "description": "First-class Epic membership; does not grant access to the task.", + "example": "string", + "nullable": true, + "type": "string" + }, "team": { "description": "ID of the team that owns this task (`tem_...`). `null` if the task is not scoped to a team.", "example": "tem_0aBcDeFgHiJkLmNoPqRsTu", @@ -98521,6 +114002,9 @@ "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", "aggregate_version": 1, "blocked_by_count": 1, + "blockers": [ + "string" + ], "closed_at": "2024-01-01T00:00:00Z", "comments_count": 1, "created_at": "2024-01-01T00:00:00Z", @@ -98548,12 +114032,14 @@ "description": "An example description.", "due_date": "2024-01-01T00:00:00Z", "epic": "string", + "human_answer_receipts": {}, "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, "is_stalled": true, "links": { "key": "value" }, + "machine_rescope_receipts": {}, "metadata": { "key": "value" }, @@ -98590,6 +114076,7 @@ ], "target_binary": "string", "target_version": "string", + "task_epic": "string", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -98615,6 +114102,9 @@ "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", "aggregate_version": 1, "blocked_by_count": 1, + "blockers": [ + "string" + ], "closed_at": "2024-01-01T00:00:00Z", "comments_count": 1, "created_at": "2024-01-01T00:00:00Z", @@ -98642,12 +114132,14 @@ "description": "An example description.", "due_date": "2024-01-01T00:00:00Z", "epic": "string", + "human_answer_receipts": {}, "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, "is_stalled": true, "links": { "key": "value" }, + "machine_rescope_receipts": {}, "metadata": { "key": "value" }, @@ -98684,6 +114176,7 @@ ], "target_binary": "string", "target_version": "string", + "task_epic": "string", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -98696,6 +114189,9 @@ "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", "aggregate_version": 1, "blocked_by_count": 1, + "blockers": [ + "string" + ], "closed_at": "2024-01-01T00:00:00Z", "comments_count": 1, "created_at": "2024-01-01T00:00:00Z", @@ -98723,12 +114219,14 @@ "description": "An example description.", "due_date": "2024-01-01T00:00:00Z", "epic": "string", + "human_answer_receipts": {}, "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, "is_stalled": true, "links": { "key": "value" }, + "machine_rescope_receipts": {}, "metadata": { "key": "value" }, @@ -98765,6 +114263,7 @@ ], "target_binary": "string", "target_version": "string", + "task_epic": "string", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -98788,6 +114287,16 @@ "example": 1, "type": "integer" }, + "blockers": { + "description": "Visible blocker IDs when requested with include=blockers.", + "example": [ + "string" + ], + "items": { + "type": "string" + }, + "type": "array" + }, "closed_at": { "description": "When the task was marked as done or otherwise closed (ISO 8601). `null` if the task is still open.", "example": "2024-01-01T00:00:00Z", @@ -98967,6 +114476,11 @@ "nullable": true, "type": "string" }, + "human_answer_receipts": { + "description": "Server-owned authenticated human answer intent, keyed by question version. Not infrastructure permission.", + "example": {}, + "type": "object" + }, "id": { "description": "Task ID (`tsk_...`).", "example": "tsk_0aBcDeFgHiJkLmNoPqRsTu", @@ -98989,6 +114503,11 @@ }, "type": "object" }, + "machine_rescope_receipts": { + "description": "Server-owned records of machine-applied local rescopes, keyed by question version. Never evidence that a human answered.", + "example": {}, + "type": "object" + }, "metadata": { "description": "Arbitrary key-value map of application-specific data stored alongside the task. Returns an empty object when no metadata has been set.", "example": { @@ -99196,6 +114715,12 @@ "nullable": true, "type": "string" }, + "task_epic": { + "description": "First-class Epic membership; does not grant access to the task.", + "example": "string", + "nullable": true, + "type": "string" + }, "team": { "description": "ID of the team that owns this task (`tem_...`). `null` if the task is not scoped to a team.", "example": "tem_0aBcDeFgHiJkLmNoPqRsTu", @@ -99385,6 +114910,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -99395,11 +114940,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -99566,6 +115118,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -99576,11 +115148,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -99756,6 +115335,7 @@ "needs-review" ], "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", + "thread_template_key": "string", "title": "Example Title", "ttl": "2026-08-15T12:00:00", "unread_count": 5, @@ -99801,6 +115381,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -99811,11 +115411,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -99982,6 +115589,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -99992,11 +115619,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -100172,6 +115806,7 @@ "needs-review" ], "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", + "thread_template_key": "string", "title": "Example Title", "ttl": "2026-08-15T12:00:00", "unread_count": 5, @@ -100214,6 +115849,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -100224,11 +115879,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -100395,6 +116057,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -100405,11 +116087,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -100585,6 +116274,7 @@ "needs-review" ], "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", + "thread_template_key": "string", "title": "Example Title", "ttl": "2026-08-15T12:00:00", "unread_count": 5, @@ -100853,6 +116543,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -100863,11 +116573,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -101005,6 +116722,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -101015,11 +116752,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "nullable": true, @@ -101077,6 +116821,112 @@ }, "type": "array" }, + "add_denies": { + "description": "Patch mode: denies to add or merge, replacing any grant for the same principal.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, + "denies": { + "description": "Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, "grants": { "description": "Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", "example": [ @@ -101130,6 +116980,11 @@ }, "type": "array" }, + "preserve_denies": { + "description": "Retain current server denies atomically in replacement or patch mode; current denies win.", + "example": true, + "type": "boolean" + }, "remove": { "description": "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", "example": [ @@ -101162,6 +117017,39 @@ "type": "object" }, "type": "array" + }, + "remove_denies": { + "description": "Patch mode: principals whose denies should be removed.", + "example": [ + { + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "Identifies a principal to be removed from an access-control list.", + "example": { + "principal": "string", + "principal_type": "user" + }, + "properties": { + "principal": { + "description": "The identifier of the principal to remove. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`. Omit when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal to remove. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type" + ], + "type": "object" + }, + "type": "array" } }, "type": "object" @@ -101984,6 +117872,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -101994,11 +117902,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -102532,6 +118447,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -102542,11 +118477,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -102722,6 +118664,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -102732,11 +118694,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -102911,6 +118880,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -102921,11 +118910,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "nullable": true, @@ -102983,6 +118979,112 @@ }, "type": "array" }, + "add_denies": { + "description": "Patch mode: denies to add or merge, replacing any grant for the same principal.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, + "denies": { + "description": "Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, "grants": { "description": "Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", "example": [ @@ -103036,6 +119138,11 @@ }, "type": "array" }, + "preserve_denies": { + "description": "Retain current server denies atomically in replacement or patch mode; current denies win.", + "example": true, + "type": "boolean" + }, "remove": { "description": "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", "example": [ @@ -103068,6 +119175,39 @@ "type": "object" }, "type": "array" + }, + "remove_denies": { + "description": "Patch mode: principals whose denies should be removed.", + "example": [ + { + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "Identifies a principal to be removed from an access-control list.", + "example": { + "principal": "string", + "principal_type": "user" + }, + "properties": { + "principal": { + "description": "The identifier of the principal to remove. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`. Omit when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal to remove. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type" + ], + "type": "object" + }, + "type": "array" } }, "type": "object" @@ -104557,6 +120697,12 @@ "nullable": true, "type": "string" }, + "thread_template_key": { + "description": "Read-only key of the template used to create this thread. `null` for threads not created from a template.", + "example": "string", + "nullable": true, + "type": "string" + }, "title": { "description": "Human-readable name of the thread. `null` if no title has been set.", "example": "Example Title", @@ -104905,6 +121051,86 @@ ] } }, + "/api/v1/users/{user}/threads/from_template": { + "post": { + "description": "Creates a private personal thread, installs the template's agent once per user,\nand atomically adds its members and a dedicated E2B computer. Requires\n`devbox_access`. The computer starts pending and provisions asynchronously.\n`key` is prefixed by the template namespace and is unique for the user. Replays return\n200 and never provision another computer or resend the first message; creation\nreturns 201. Initial-message delivery occurs after commit; a delivery failure\nis returned as `first_message_error` so the caller can resend it.\n`computer` is optional and applies on creation only: a replay with the same\n`key` returns the original thread and computer, ignoring any different\n`computer`, exactly like `title` and `first_message`. Invalid `computer`\ninput returns 422 `invalid_parameters` before anything is created; a provider\nthis deployment has no credentials for returns 422 `provider_unavailable`.\nUnknown templates return 422 `unknown_thread_template`; installation failures\nreturn 502 `agent_install_failed`. Computer config and credentials are never returned.\n", + "operationId": "post_api_v1_users__user_threads_from_template", + "parameters": [], + "requestBody": { + "content": { + "application/json": { + "schema": { + "example": { + "computer": {}, + "first_message": "string", + "key": "string", + "template": "string", + "title": "Example Title" + }, + "properties": { + "computer": { + "description": "Optional computer choice, applied on creation only: `provider` (`sprites`, `vercel`, `e2b` or `devbox`; defaults to the template's) and `repositories` (0 to 16 `{repository: owner/name, ref: optional}`; the first is the primary working directory).", + "example": {}, + "type": "object" + }, + "first_message": { + "description": "Optional first user message, posted only on creation.", + "example": "string", + "type": "string" + }, + "key": { + "description": "Required nonempty client idempotency key.", + "example": "string", + "type": "string" + }, + "template": { + "description": "Thread template lookup key.", + "example": "string", + "type": "string" + }, + "title": { + "description": "Title for the new thread.", + "example": "Example Title", + "type": "string" + } + }, + "required": [ + "template" + ], + "type": "object" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "type": "object" + } + } + }, + "description": "Thread fields plus agent and computers summaries, and optional first_message_error." + }, + "403": { + "description": "devbox_access_required" + }, + "422": { + "description": "unknown_thread_template, provider_unavailable or invalid parameters" + }, + "502": { + "description": "agent_install_failed" + } + }, + "summary": "Create a private thread from a template", + "x-auth": [ + "publishable_key", + "bearer" + ] + } + }, "/api/v1/users/{user}/tokens": { "get": { "description": "Returns all access tokens associated with the authenticated user, including\nactive and revoked tokens. Tokens are returned without their raw JWT values\n— the plaintext JWT is only available at creation time.\n\nThe caller must be the user identified by `user` and must present a\nfirst-party session (or a `full_access` access token).\n", @@ -106711,6 +122937,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -106721,11 +122967,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -106900,6 +123153,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -106910,11 +123183,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "nullable": true, @@ -106972,6 +123252,112 @@ }, "type": "array" }, + "add_denies": { + "description": "Patch mode: denies to add or merge, replacing any grant for the same principal.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, + "denies": { + "description": "Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, "grants": { "description": "Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", "example": [ @@ -107025,6 +123411,11 @@ }, "type": "array" }, + "preserve_denies": { + "description": "Retain current server denies atomically in replacement or patch mode; current denies win.", + "example": true, + "type": "boolean" + }, "remove": { "description": "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", "example": [ @@ -107057,6 +123448,39 @@ "type": "object" }, "type": "array" + }, + "remove_denies": { + "description": "Patch mode: principals whose denies should be removed.", + "example": [ + { + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "Identifies a principal to be removed from an access-control list.", + "example": { + "principal": "string", + "principal_type": "user" + }, + "properties": { + "principal": { + "description": "The identifier of the principal to remove. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`. Omit when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal to remove. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type" + ], + "type": "object" + }, + "type": "array" } }, "type": "object" @@ -109584,16 +126008,22 @@ "event": "access_revoked", "payload": { "example": { + "artifact": "string", "reason": "string" }, "properties": { + "artifact": { + "example": "string", + "type": "string" + }, "reason": { "example": "string", "type": "string" } }, "required": [ - "reason" + "reason", + "artifact" ], "type": "object" } @@ -110054,6 +126484,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -110064,11 +126514,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -110245,6 +126702,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -110255,11 +126732,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -110460,6 +126944,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -110470,11 +126974,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -110611,6 +127122,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -110621,11 +127152,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -110675,6 +127213,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -110685,11 +127243,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -110856,6 +127421,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -110866,11 +127451,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -111046,6 +127638,7 @@ "needs-review" ], "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", + "thread_template_key": "string", "title": "Example Title", "ttl": "2026-08-15T12:00:00", "unread_count": 5, @@ -111066,6 +127659,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -111076,11 +127689,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -111130,6 +127750,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -111140,11 +127780,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -111311,6 +127958,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -111321,11 +127988,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -111501,6 +128175,7 @@ "needs-review" ], "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", + "thread_template_key": "string", "title": "Example Title", "ttl": "2026-08-15T12:00:00", "unread_count": 5, @@ -111526,6 +128201,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -111536,11 +128231,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -111717,6 +128419,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -111727,11 +128449,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -111932,6 +128661,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -111942,11 +128691,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -112083,6 +128839,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -112093,11 +128869,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -112147,6 +128930,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -112157,11 +128960,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -112328,6 +129138,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -112338,11 +129168,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -112518,6 +129355,7 @@ "needs-review" ], "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", + "thread_template_key": "string", "title": "Example Title", "ttl": "2026-08-15T12:00:00", "unread_count": 5, @@ -112546,6 +129384,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -112556,11 +129414,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -112735,6 +129600,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -112745,11 +129630,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "nullable": true, @@ -112807,6 +129699,112 @@ }, "type": "array" }, + "add_denies": { + "description": "Patch mode: denies to add or merge, replacing any grant for the same principal.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, + "denies": { + "description": "Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, "grants": { "description": "Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", "example": [ @@ -112860,6 +129858,11 @@ }, "type": "array" }, + "preserve_denies": { + "description": "Retain current server denies atomically in replacement or patch mode; current denies win.", + "example": true, + "type": "boolean" + }, "remove": { "description": "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", "example": [ @@ -112892,6 +129895,39 @@ "type": "object" }, "type": "array" + }, + "remove_denies": { + "description": "Patch mode: principals whose denies should be removed.", + "example": [ + { + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "Identifies a principal to be removed from an access-control list.", + "example": { + "principal": "string", + "principal_type": "user" + }, + "properties": { + "principal": { + "description": "The identifier of the principal to remove. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`. Omit when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal to remove. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type" + ], + "type": "object" + }, + "type": "array" } }, "type": "object" @@ -114343,6 +131379,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -114353,11 +131409,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -114560,6 +131623,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -114570,11 +131653,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -114776,6 +131866,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -114786,11 +131896,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -114965,6 +132082,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -114975,11 +132112,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "nullable": true, @@ -115037,6 +132181,112 @@ }, "type": "array" }, + "add_denies": { + "description": "Patch mode: denies to add or merge, replacing any grant for the same principal.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, + "denies": { + "description": "Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, "grants": { "description": "Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", "example": [ @@ -115090,6 +132340,11 @@ }, "type": "array" }, + "preserve_denies": { + "description": "Retain current server denies atomically in replacement or patch mode; current denies win.", + "example": true, + "type": "boolean" + }, "remove": { "description": "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", "example": [ @@ -115122,6 +132377,39 @@ "type": "object" }, "type": "array" + }, + "remove_denies": { + "description": "Patch mode: principals whose denies should be removed.", + "example": [ + { + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "Identifies a principal to be removed from an access-control list.", + "example": { + "principal": "string", + "principal_type": "user" + }, + "properties": { + "principal": { + "description": "The identifier of the principal to remove. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`. Omit when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal to remove. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type" + ], + "type": "object" + }, + "type": "array" } }, "type": "object" @@ -116725,6 +134013,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -116735,11 +134043,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -116877,6 +134192,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -116887,11 +134222,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -117017,6 +134359,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -117027,11 +134389,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -117176,6 +134545,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -117186,11 +134575,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "nullable": true, @@ -117248,6 +134644,112 @@ }, "type": "array" }, + "add_denies": { + "description": "Patch mode: denies to add or merge, replacing any grant for the same principal.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, + "denies": { + "description": "Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, "grants": { "description": "Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", "example": [ @@ -117301,6 +134803,11 @@ }, "type": "array" }, + "preserve_denies": { + "description": "Retain current server denies atomically in replacement or patch mode; current denies win.", + "example": true, + "type": "boolean" + }, "remove": { "description": "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", "example": [ @@ -117333,6 +134840,39 @@ "type": "object" }, "type": "array" + }, + "remove_denies": { + "description": "Patch mode: principals whose denies should be removed.", + "example": [ + { + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "Identifies a principal to be removed from an access-control list.", + "example": { + "principal": "string", + "principal_type": "user" + }, + "properties": { + "principal": { + "description": "The identifier of the principal to remove. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`. Omit when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal to remove. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type" + ], + "type": "object" + }, + "type": "array" } }, "type": "object" @@ -118155,6 +135695,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -118165,11 +135725,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -118515,6 +136082,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -118525,11 +136112,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -118561,6 +136155,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -118571,11 +136185,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "nullable": true, @@ -118633,6 +136254,112 @@ }, "type": "array" }, + "add_denies": { + "description": "Patch mode: denies to add or merge, replacing any grant for the same principal.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, + "denies": { + "description": "Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, "grants": { "description": "Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", "example": [ @@ -118686,6 +136413,11 @@ }, "type": "array" }, + "preserve_denies": { + "description": "Retain current server denies atomically in replacement or patch mode; current denies win.", + "example": true, + "type": "boolean" + }, "remove": { "description": "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", "example": [ @@ -118718,6 +136450,39 @@ "type": "object" }, "type": "array" + }, + "remove_denies": { + "description": "Patch mode: principals whose denies should be removed.", + "example": [ + { + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "Identifies a principal to be removed from an access-control list.", + "example": { + "principal": "string", + "principal_type": "user" + }, + "properties": { + "principal": { + "description": "The identifier of the principal to remove. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`. Omit when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal to remove. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type" + ], + "type": "object" + }, + "type": "array" } }, "type": "object" @@ -118832,6 +136597,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -118842,11 +136627,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -119013,6 +136805,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -119023,11 +136835,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -119203,6 +137022,7 @@ "needs-review" ], "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", + "thread_template_key": "string", "title": "Example Title", "ttl": "2026-08-15T12:00:00", "unread_count": 5, @@ -119471,6 +137291,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -119481,11 +137321,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -119623,6 +137470,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -119633,11 +137500,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "nullable": true, @@ -119695,6 +137569,112 @@ }, "type": "array" }, + "add_denies": { + "description": "Patch mode: denies to add or merge, replacing any grant for the same principal.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, + "denies": { + "description": "Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, "grants": { "description": "Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", "example": [ @@ -119748,6 +137728,11 @@ }, "type": "array" }, + "preserve_denies": { + "description": "Retain current server denies atomically in replacement or patch mode; current denies win.", + "example": true, + "type": "boolean" + }, "remove": { "description": "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", "example": [ @@ -119780,6 +137765,39 @@ "type": "object" }, "type": "array" + }, + "remove_denies": { + "description": "Patch mode: principals whose denies should be removed.", + "example": [ + { + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "Identifies a principal to be removed from an access-control list.", + "example": { + "principal": "string", + "principal_type": "user" + }, + "properties": { + "principal": { + "description": "The identifier of the principal to remove. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`. Omit when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal to remove. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type" + ], + "type": "object" + }, + "type": "array" } }, "type": "object" @@ -120602,6 +138620,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -120612,11 +138650,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -121150,6 +139195,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -121160,11 +139225,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -121340,6 +139412,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -121350,11 +139442,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -121529,6 +139628,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -121539,11 +139658,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "nullable": true, @@ -121601,6 +139727,112 @@ }, "type": "array" }, + "add_denies": { + "description": "Patch mode: denies to add or merge, replacing any grant for the same principal.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, + "denies": { + "description": "Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, "grants": { "description": "Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", "example": [ @@ -121654,6 +139886,11 @@ }, "type": "array" }, + "preserve_denies": { + "description": "Retain current server denies atomically in replacement or patch mode; current denies win.", + "example": true, + "type": "boolean" + }, "remove": { "description": "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", "example": [ @@ -121686,6 +139923,39 @@ "type": "object" }, "type": "array" + }, + "remove_denies": { + "description": "Patch mode: principals whose denies should be removed.", + "example": [ + { + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "Identifies a principal to be removed from an access-control list.", + "example": { + "principal": "string", + "principal_type": "user" + }, + "properties": { + "principal": { + "description": "The identifier of the principal to remove. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`. Omit when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal to remove. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type" + ], + "type": "object" + }, + "type": "array" } }, "type": "object" @@ -123175,6 +141445,12 @@ "nullable": true, "type": "string" }, + "thread_template_key": { + "description": "Read-only key of the template used to create this thread. `null` for threads not created from a template.", + "example": "string", + "nullable": true, + "type": "string" + }, "title": { "description": "Human-readable name of the thread. `null` if no title has been set.", "example": "Example Title", @@ -123245,6 +141521,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -123255,11 +141551,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -123291,6 +141594,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -123301,11 +141624,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "nullable": true, @@ -123363,6 +141693,112 @@ }, "type": "array" }, + "add_denies": { + "description": "Patch mode: denies to add or merge, replacing any grant for the same principal.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, + "denies": { + "description": "Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, "grants": { "description": "Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", "example": [ @@ -123416,6 +141852,11 @@ }, "type": "array" }, + "preserve_denies": { + "description": "Retain current server denies atomically in replacement or patch mode; current denies win.", + "example": true, + "type": "boolean" + }, "remove": { "description": "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", "example": [ @@ -123448,6 +141889,39 @@ "type": "object" }, "type": "array" + }, + "remove_denies": { + "description": "Patch mode: principals whose denies should be removed.", + "example": [ + { + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "Identifies a principal to be removed from an access-control list.", + "example": { + "principal": "string", + "principal_type": "user" + }, + "properties": { + "principal": { + "description": "The identifier of the principal to remove. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`. Omit when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal to remove. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type" + ], + "type": "object" + }, + "type": "array" } }, "type": "object" @@ -123562,6 +142036,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -123572,11 +142066,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -123743,6 +142244,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -123753,11 +142274,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -123933,6 +142461,7 @@ "needs-review" ], "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", + "thread_template_key": "string", "title": "Example Title", "ttl": "2026-08-15T12:00:00", "unread_count": 5, @@ -124201,6 +142730,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -124211,11 +142760,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -124353,6 +142909,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -124363,11 +142939,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "nullable": true, @@ -124425,6 +143008,112 @@ }, "type": "array" }, + "add_denies": { + "description": "Patch mode: denies to add or merge, replacing any grant for the same principal.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, + "denies": { + "description": "Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, "grants": { "description": "Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", "example": [ @@ -124478,6 +143167,11 @@ }, "type": "array" }, + "preserve_denies": { + "description": "Retain current server denies atomically in replacement or patch mode; current denies win.", + "example": true, + "type": "boolean" + }, "remove": { "description": "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", "example": [ @@ -124510,6 +143204,39 @@ "type": "object" }, "type": "array" + }, + "remove_denies": { + "description": "Patch mode: principals whose denies should be removed.", + "example": [ + { + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "Identifies a principal to be removed from an access-control list.", + "example": { + "principal": "string", + "principal_type": "user" + }, + "properties": { + "principal": { + "description": "The identifier of the principal to remove. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`. Omit when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal to remove. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type" + ], + "type": "object" + }, + "type": "array" } }, "type": "object" @@ -125332,6 +144059,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -125342,11 +144089,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -125880,6 +144634,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -125890,11 +144664,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -126070,6 +144851,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -126080,11 +144881,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -126259,6 +145067,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -126269,11 +145097,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "nullable": true, @@ -126331,6 +145166,112 @@ }, "type": "array" }, + "add_denies": { + "description": "Patch mode: denies to add or merge, replacing any grant for the same principal.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, + "denies": { + "description": "Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, "grants": { "description": "Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", "example": [ @@ -126384,6 +145325,11 @@ }, "type": "array" }, + "preserve_denies": { + "description": "Retain current server denies atomically in replacement or patch mode; current denies win.", + "example": true, + "type": "boolean" + }, "remove": { "description": "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", "example": [ @@ -126416,6 +145362,39 @@ "type": "object" }, "type": "array" + }, + "remove_denies": { + "description": "Patch mode: principals whose denies should be removed.", + "example": [ + { + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "Identifies a principal to be removed from an access-control list.", + "example": { + "principal": "string", + "principal_type": "user" + }, + "properties": { + "principal": { + "description": "The identifier of the principal to remove. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`. Omit when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal to remove. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type" + ], + "type": "object" + }, + "type": "array" } }, "type": "object" @@ -127905,6 +146884,12 @@ "nullable": true, "type": "string" }, + "thread_template_key": { + "description": "Read-only key of the template used to create this thread. `null` for threads not created from a template.", + "example": "string", + "nullable": true, + "type": "string" + }, "title": { "description": "Human-readable name of the thread. `null` if no title has been set.", "example": "Example Title", @@ -127959,6 +146944,41 @@ "type": "object" } }, + { + "description": "Attach a room agent to a live Artifact; its session answers the Artifact's signals", + "event": "api:chat:attach_artifact", + "params": { + "example": { + "agent": "string", + "artifact": "string", + "instructions": "string" + }, + "properties": { + "agent": { + "example": "string", + "type": "string" + }, + "artifact": { + "example": "string", + "type": "string" + }, + "instructions": { + "example": "string", + "type": "string" + } + }, + "required": [ + "agent", + "artifact" + ], + "type": "object" + }, + "returns": { + "description": "Empty acknowledgement payload returned by channel message handlers that produce no data. The wire envelope is `{\"status\": \"ok\", \"response\": {}}`.", + "properties": {}, + "type": "object" + } + }, { "description": "Mark a thread as read up to a given message", "event": "api:chat:mark_thread_read", @@ -128018,6 +147038,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -128028,11 +147068,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -128173,6 +147220,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -128183,11 +147250,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -128325,6 +147399,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -128335,11 +147429,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -128465,6 +147566,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -128475,11 +147596,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -128624,6 +147752,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -128634,11 +147782,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "nullable": true, @@ -128696,6 +147851,112 @@ }, "type": "array" }, + "add_denies": { + "description": "Patch mode: denies to add or merge, replacing any grant for the same principal.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, + "denies": { + "description": "Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, "grants": { "description": "Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", "example": [ @@ -128749,6 +148010,11 @@ }, "type": "array" }, + "preserve_denies": { + "description": "Retain current server denies atomically in replacement or patch mode; current denies win.", + "example": true, + "type": "boolean" + }, "remove": { "description": "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", "example": [ @@ -128781,6 +148047,39 @@ "type": "object" }, "type": "array" + }, + "remove_denies": { + "description": "Patch mode: principals whose denies should be removed.", + "example": [ + { + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "Identifies a principal to be removed from an access-control list.", + "example": { + "principal": "string", + "principal_type": "user" + }, + "properties": { + "principal": { + "description": "The identifier of the principal to remove. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`. Omit when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal to remove. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type" + ], + "type": "object" + }, + "type": "array" } }, "type": "object" @@ -129603,6 +148902,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -129613,11 +148932,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -129998,6 +149324,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -130008,11 +149354,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -130189,6 +149542,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -130199,11 +149572,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -130404,6 +149784,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -130414,11 +149814,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -130555,6 +149962,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -130565,11 +149992,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -130619,6 +150053,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -130629,11 +150083,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -130800,6 +150261,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -130810,11 +150291,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -130990,6 +150478,7 @@ "needs-review" ], "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", + "thread_template_key": "string", "title": "Example Title", "ttl": "2026-08-15T12:00:00", "unread_count": 5, @@ -131016,6 +150505,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -131026,11 +150535,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -131207,6 +150723,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -131217,11 +150753,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -131422,6 +150965,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -131432,11 +150995,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -131573,6 +151143,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -131583,11 +151173,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -131637,6 +151234,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -131647,11 +151264,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -131818,6 +151442,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -131828,11 +151472,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -132008,6 +151659,7 @@ "needs-review" ], "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", + "thread_template_key": "string", "title": "Example Title", "ttl": "2026-08-15T12:00:00", "unread_count": 5, @@ -132036,6 +151688,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -132046,11 +151718,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -132225,6 +151904,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -132235,11 +151934,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "nullable": true, @@ -132297,6 +152003,112 @@ }, "type": "array" }, + "add_denies": { + "description": "Patch mode: denies to add or merge, replacing any grant for the same principal.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, + "denies": { + "description": "Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, "grants": { "description": "Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", "example": [ @@ -132350,6 +152162,11 @@ }, "type": "array" }, + "preserve_denies": { + "description": "Retain current server denies atomically in replacement or patch mode; current denies win.", + "example": true, + "type": "boolean" + }, "remove": { "description": "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", "example": [ @@ -132382,6 +152199,39 @@ "type": "object" }, "type": "array" + }, + "remove_denies": { + "description": "Patch mode: principals whose denies should be removed.", + "example": [ + { + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "Identifies a principal to be removed from an access-control list.", + "example": { + "principal": "string", + "principal_type": "user" + }, + "properties": { + "principal": { + "description": "The identifier of the principal to remove. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`. Omit when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal to remove. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type" + ], + "type": "object" + }, + "type": "array" } }, "type": "object" @@ -133833,6 +153683,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -133843,11 +153713,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -134050,6 +153927,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -134060,11 +153957,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -134266,6 +154170,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -134276,11 +154200,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -134455,6 +154386,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -134465,11 +154416,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "nullable": true, @@ -134527,6 +154485,112 @@ }, "type": "array" }, + "add_denies": { + "description": "Patch mode: denies to add or merge, replacing any grant for the same principal.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, + "denies": { + "description": "Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, "grants": { "description": "Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", "example": [ @@ -134580,6 +154644,11 @@ }, "type": "array" }, + "preserve_denies": { + "description": "Retain current server denies atomically in replacement or patch mode; current denies win.", + "example": true, + "type": "boolean" + }, "remove": { "description": "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", "example": [ @@ -134612,6 +154681,39 @@ "type": "object" }, "type": "array" + }, + "remove_denies": { + "description": "Patch mode: principals whose denies should be removed.", + "example": [ + { + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "Identifies a principal to be removed from an access-control list.", + "example": { + "principal": "string", + "principal_type": "user" + }, + "properties": { + "principal": { + "description": "The identifier of the principal to remove. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`. Omit when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal to remove. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type" + ], + "type": "object" + }, + "type": "array" } }, "type": "object" @@ -136215,6 +156317,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -136225,11 +156347,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -136367,6 +156496,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -136377,11 +156526,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -136507,6 +156663,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -136517,11 +156693,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -136666,6 +156849,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -136676,11 +156879,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "nullable": true, @@ -136738,6 +156948,112 @@ }, "type": "array" }, + "add_denies": { + "description": "Patch mode: denies to add or merge, replacing any grant for the same principal.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, + "denies": { + "description": "Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, "grants": { "description": "Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", "example": [ @@ -136791,6 +157107,11 @@ }, "type": "array" }, + "preserve_denies": { + "description": "Retain current server denies atomically in replacement or patch mode; current denies win.", + "example": true, + "type": "boolean" + }, "remove": { "description": "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", "example": [ @@ -136823,6 +157144,39 @@ "type": "object" }, "type": "array" + }, + "remove_denies": { + "description": "Patch mode: principals whose denies should be removed.", + "example": [ + { + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "Identifies a principal to be removed from an access-control list.", + "example": { + "principal": "string", + "principal_type": "user" + }, + "properties": { + "principal": { + "description": "The identifier of the principal to remove. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`. Omit when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal to remove. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type" + ], + "type": "object" + }, + "type": "array" } }, "type": "object" @@ -137645,6 +157999,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -137655,11 +158029,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -138005,6 +158386,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -138015,11 +158416,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -138051,6 +158459,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -138061,11 +158489,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "nullable": true, @@ -138123,6 +158558,112 @@ }, "type": "array" }, + "add_denies": { + "description": "Patch mode: denies to add or merge, replacing any grant for the same principal.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, + "denies": { + "description": "Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, "grants": { "description": "Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", "example": [ @@ -138176,6 +158717,11 @@ }, "type": "array" }, + "preserve_denies": { + "description": "Retain current server denies atomically in replacement or patch mode; current denies win.", + "example": true, + "type": "boolean" + }, "remove": { "description": "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", "example": [ @@ -138208,6 +158754,39 @@ "type": "object" }, "type": "array" + }, + "remove_denies": { + "description": "Patch mode: principals whose denies should be removed.", + "example": [ + { + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "Identifies a principal to be removed from an access-control list.", + "example": { + "principal": "string", + "principal_type": "user" + }, + "properties": { + "principal": { + "description": "The identifier of the principal to remove. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`. Omit when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal to remove. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type" + ], + "type": "object" + }, + "type": "array" } }, "type": "object" @@ -138322,6 +158901,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -138332,11 +158931,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -138503,6 +159109,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -138513,11 +159139,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -138693,6 +159326,7 @@ "needs-review" ], "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", + "thread_template_key": "string", "title": "Example Title", "ttl": "2026-08-15T12:00:00", "unread_count": 5, @@ -138961,6 +159595,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -138971,11 +159625,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -139113,6 +159774,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -139123,11 +159804,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "nullable": true, @@ -139185,6 +159873,112 @@ }, "type": "array" }, + "add_denies": { + "description": "Patch mode: denies to add or merge, replacing any grant for the same principal.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, + "denies": { + "description": "Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, "grants": { "description": "Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", "example": [ @@ -139238,6 +160032,11 @@ }, "type": "array" }, + "preserve_denies": { + "description": "Retain current server denies atomically in replacement or patch mode; current denies win.", + "example": true, + "type": "boolean" + }, "remove": { "description": "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", "example": [ @@ -139270,6 +160069,39 @@ "type": "object" }, "type": "array" + }, + "remove_denies": { + "description": "Patch mode: principals whose denies should be removed.", + "example": [ + { + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "Identifies a principal to be removed from an access-control list.", + "example": { + "principal": "string", + "principal_type": "user" + }, + "properties": { + "principal": { + "description": "The identifier of the principal to remove. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`. Omit when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal to remove. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type" + ], + "type": "object" + }, + "type": "array" } }, "type": "object" @@ -140092,6 +160924,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -140102,11 +160954,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -140640,6 +161499,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -140650,11 +161529,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -140830,6 +161716,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -140840,11 +161746,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "app": "dap_0aBcDeFgHiJkLmNoPqRsTu", @@ -141019,6 +161932,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -141029,11 +161962,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "nullable": true, @@ -141091,6 +162031,112 @@ }, "type": "array" }, + "add_denies": { + "description": "Patch mode: denies to add or merge, replacing any grant for the same principal.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, + "denies": { + "description": "Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, "grants": { "description": "Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", "example": [ @@ -141144,6 +162190,11 @@ }, "type": "array" }, + "preserve_denies": { + "description": "Retain current server denies atomically in replacement or patch mode; current denies win.", + "example": true, + "type": "boolean" + }, "remove": { "description": "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", "example": [ @@ -141176,6 +162227,39 @@ "type": "object" }, "type": "array" + }, + "remove_denies": { + "description": "Patch mode: principals whose denies should be removed.", + "example": [ + { + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "Identifies a principal to be removed from an access-control list.", + "example": { + "principal": "string", + "principal_type": "user" + }, + "properties": { + "principal": { + "description": "The identifier of the principal to remove. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`. Omit when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal to remove. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type" + ], + "type": "object" + }, + "type": "array" } }, "type": "object" @@ -142665,6 +163749,12 @@ "nullable": true, "type": "string" }, + "thread_template_key": { + "description": "Read-only key of the template used to create this thread. `null` for threads not created from a template.", + "example": "string", + "nullable": true, + "type": "string" + }, "title": { "description": "Human-readable name of the thread. `null` if no title has been set.", "example": "Example Title", @@ -142860,6 +163950,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -142870,11 +163980,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -143013,6 +164130,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -143023,11 +164160,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -143164,6 +164308,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -143174,11 +164338,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "nullable": true, @@ -143236,6 +164407,112 @@ }, "type": "array" }, + "add_denies": { + "description": "Patch mode: denies to add or merge, replacing any grant for the same principal.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, + "denies": { + "description": "Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, "grants": { "description": "Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", "example": [ @@ -143289,6 +164566,11 @@ }, "type": "array" }, + "preserve_denies": { + "description": "Retain current server denies atomically in replacement or patch mode; current denies win.", + "example": true, + "type": "boolean" + }, "remove": { "description": "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", "example": [ @@ -143321,6 +164603,39 @@ "type": "object" }, "type": "array" + }, + "remove_denies": { + "description": "Patch mode: principals whose denies should be removed.", + "example": [ + { + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "Identifies a principal to be removed from an access-control list.", + "example": { + "principal": "string", + "principal_type": "user" + }, + "properties": { + "principal": { + "description": "The identifier of the principal to remove. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`. Omit when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal to remove. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type" + ], + "type": "object" + }, + "type": "array" } }, "type": "object" @@ -144143,6 +165458,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -144153,11 +165488,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -144606,6 +165948,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -144616,11 +165978,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -144759,6 +166128,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -144769,11 +166158,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -144910,6 +166306,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -144920,11 +166336,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "nullable": true, @@ -144982,6 +166405,112 @@ }, "type": "array" }, + "add_denies": { + "description": "Patch mode: denies to add or merge, replacing any grant for the same principal.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, + "denies": { + "description": "Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, "grants": { "description": "Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", "example": [ @@ -145035,6 +166564,11 @@ }, "type": "array" }, + "preserve_denies": { + "description": "Retain current server denies atomically in replacement or patch mode; current denies win.", + "example": true, + "type": "boolean" + }, "remove": { "description": "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", "example": [ @@ -145067,6 +166601,39 @@ "type": "object" }, "type": "array" + }, + "remove_denies": { + "description": "Patch mode: principals whose denies should be removed.", + "example": [ + { + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "Identifies a principal to be removed from an access-control list.", + "example": { + "principal": "string", + "principal_type": "user" + }, + "properties": { + "principal": { + "description": "The identifier of the principal to remove. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`. Omit when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal to remove. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type" + ], + "type": "object" + }, + "type": "array" } }, "type": "object" @@ -145889,6 +167456,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -145899,11 +167486,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -146671,6 +168265,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -146681,11 +168295,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -146833,6 +168454,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -146843,11 +168484,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -146984,6 +168632,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -146994,11 +168662,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "nullable": true, @@ -147056,6 +168731,112 @@ }, "type": "array" }, + "add_denies": { + "description": "Patch mode: denies to add or merge, replacing any grant for the same principal.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, + "denies": { + "description": "Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, "grants": { "description": "Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", "example": [ @@ -147109,6 +168890,11 @@ }, "type": "array" }, + "preserve_denies": { + "description": "Retain current server denies atomically in replacement or patch mode; current denies win.", + "example": true, + "type": "boolean" + }, "remove": { "description": "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", "example": [ @@ -147141,6 +168927,39 @@ "type": "object" }, "type": "array" + }, + "remove_denies": { + "description": "Patch mode: principals whose denies should be removed.", + "example": [ + { + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "Identifies a principal to be removed from an access-control list.", + "example": { + "principal": "string", + "principal_type": "user" + }, + "properties": { + "principal": { + "description": "The identifier of the principal to remove. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`. Omit when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal to remove. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type" + ], + "type": "object" + }, + "type": "array" } }, "type": "object" @@ -147963,6 +169782,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -147973,11 +169812,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -148327,6 +170173,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -148337,11 +170203,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -148481,6 +170354,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -148491,11 +170384,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -148632,6 +170532,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -148642,11 +170562,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "nullable": true, @@ -148704,6 +170631,112 @@ }, "type": "array" }, + "add_denies": { + "description": "Patch mode: denies to add or merge, replacing any grant for the same principal.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, + "denies": { + "description": "Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support.", + "example": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "A single access-control grant that pairs a principal with the set of actions it is allowed to perform.", + "example": { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + }, + "properties": { + "actions": { + "description": "Array of action strings the principal is permitted to perform, e.g. `[\"read\", \"write\"]`. Must contain at least one entry.", + "example": [ + "read", + "write" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "principal": { + "description": "The identifier of the principal. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`; omit entirely when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal receiving the grant. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type", + "actions" + ], + "type": "object" + }, + "type": "array" + }, "grants": { "description": "Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", "example": [ @@ -148757,6 +170790,11 @@ }, "type": "array" }, + "preserve_denies": { + "description": "Retain current server denies atomically in replacement or patch mode; current denies win.", + "example": true, + "type": "boolean" + }, "remove": { "description": "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", "example": [ @@ -148789,6 +170827,39 @@ "type": "object" }, "type": "array" + }, + "remove_denies": { + "description": "Patch mode: principals whose denies should be removed.", + "example": [ + { + "principal": "string", + "principal_type": "user" + } + ], + "items": { + "description": "Identifies a principal to be removed from an access-control list.", + "example": { + "principal": "string", + "principal_type": "user" + }, + "properties": { + "principal": { + "description": "The identifier of the principal to remove. A string ID for `\"user\"`, `\"team\"`, `\"org\"`, and `\"agent\"` types; one of `\"admin\"`, `\"member\"`, or `\"viewer\"` for `\"org_role\"`. Omit when `principal_type` is `\"everyone\"`.", + "example": "string", + "type": "string" + }, + "principal_type": { + "description": "The kind of principal to remove. One of `\"user\"`, `\"team\"`, `\"org\"`, `\"org_role\"`, `\"agent\"`, or `\"everyone\"`.", + "example": "user", + "type": "string" + } + }, + "required": [ + "principal_type" + ], + "type": "object" + }, + "type": "array" } }, "type": "object" @@ -149611,6 +171682,26 @@ "principal_type": "user" } ], + "add_denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "denies": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], "grants": [ { "actions": [ @@ -149621,11 +171712,18 @@ "principal_type": "user" } ], + "preserve_denies": true, "remove": [ { "principal": "string", "principal_type": "user" } + ], + "remove_denies": [ + { + "principal": "string", + "principal_type": "user" + } ] }, "actors": [ @@ -150001,10 +172099,11 @@ } }, { - "description": "Broadcast when a participant (human or agent) starts or stops typing. Ephemeral; never persisted.", + "description": "Broadcast when a participant (human or agent) starts or stops typing. Ephemeral; never persisted. Agent events may carry `activity`, a snapshot of what the running turn has done (tool_calls, tool, thoughts).", "event": "typing", "payload": { "example": { + "activity": {}, "actor": { "alias": "alice", "id": "user-usr_01j3k5m7n9p2r4s6t8v0w1x2", @@ -150023,6 +172122,10 @@ "thread_id": "string" }, "properties": { + "activity": { + "example": {}, + "type": "object" + }, "actor": { "description": "The entity that authored a message, either a human user or an agent.", "example": { @@ -150792,6 +172895,9 @@ "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", "aggregate_version": 1, "blocked_by_count": 1, + "blockers": [ + "string" + ], "closed_at": "2024-01-01T00:00:00Z", "comments_count": 1, "created_at": "2024-01-01T00:00:00Z", @@ -150819,12 +172925,14 @@ "description": "An example description.", "due_date": "2024-01-01T00:00:00Z", "epic": "string", + "human_answer_receipts": {}, "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, "is_stalled": true, "links": { "key": "value" }, + "machine_rescope_receipts": {}, "metadata": { "key": "value" }, @@ -150861,6 +172969,7 @@ ], "target_binary": "string", "target_version": "string", + "task_epic": "string", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -150875,6 +172984,9 @@ "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", "aggregate_version": 1, "blocked_by_count": 1, + "blockers": [ + "string" + ], "closed_at": "2024-01-01T00:00:00Z", "comments_count": 1, "created_at": "2024-01-01T00:00:00Z", @@ -150902,12 +173014,14 @@ "description": "An example description.", "due_date": "2024-01-01T00:00:00Z", "epic": "string", + "human_answer_receipts": {}, "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, "is_stalled": true, "links": { "key": "value" }, + "machine_rescope_receipts": {}, "metadata": { "key": "value" }, @@ -150944,6 +173058,7 @@ ], "target_binary": "string", "target_version": "string", + "task_epic": "string", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -150956,6 +173071,9 @@ "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", "aggregate_version": 1, "blocked_by_count": 1, + "blockers": [ + "string" + ], "closed_at": "2024-01-01T00:00:00Z", "comments_count": 1, "created_at": "2024-01-01T00:00:00Z", @@ -150983,12 +173101,14 @@ "description": "An example description.", "due_date": "2024-01-01T00:00:00Z", "epic": "string", + "human_answer_receipts": {}, "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, "is_stalled": true, "links": { "key": "value" }, + "machine_rescope_receipts": {}, "metadata": { "key": "value" }, @@ -151025,6 +173145,7 @@ ], "target_binary": "string", "target_version": "string", + "task_epic": "string", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -151048,6 +173169,16 @@ "example": 1, "type": "integer" }, + "blockers": { + "description": "Visible blocker IDs when requested with include=blockers.", + "example": [ + "string" + ], + "items": { + "type": "string" + }, + "type": "array" + }, "closed_at": { "description": "When the task was marked as done or otherwise closed (ISO 8601). `null` if the task is still open.", "example": "2024-01-01T00:00:00Z", @@ -151227,6 +173358,11 @@ "nullable": true, "type": "string" }, + "human_answer_receipts": { + "description": "Server-owned authenticated human answer intent, keyed by question version. Not infrastructure permission.", + "example": {}, + "type": "object" + }, "id": { "description": "Task ID (`tsk_...`).", "example": "tsk_0aBcDeFgHiJkLmNoPqRsTu", @@ -151249,6 +173385,11 @@ }, "type": "object" }, + "machine_rescope_receipts": { + "description": "Server-owned records of machine-applied local rescopes, keyed by question version. Never evidence that a human answered.", + "example": {}, + "type": "object" + }, "metadata": { "description": "Arbitrary key-value map of application-specific data stored alongside the task. Returns an empty object when no metadata has been set.", "example": { @@ -151456,6 +173597,12 @@ "nullable": true, "type": "string" }, + "task_epic": { + "description": "First-class Epic membership; does not grant access to the task.", + "example": "string", + "nullable": true, + "type": "string" + }, "team": { "description": "ID of the team that owns this task (`tem_...`). `null` if the task is not scoped to a team.", "example": "tem_0aBcDeFgHiJkLmNoPqRsTu", diff --git a/src/archastro/platform/channels/api_artifact_channel.py b/src/archastro/platform/channels/api_artifact_channel.py index a6b3400..fc9302f 100644 --- a/src/archastro/platform/channels/api_artifact_channel.py +++ b/src/archastro/platform/channels/api_artifact_channel.py @@ -1,6 +1,6 @@ # Copyright (c) 2026 ArchAstro Inc. Licensed under the MIT License. # This file is auto-generated by @archastro/sdk-generator. Do not edit. -# Content hash: 681181d58578 +# Content hash: c562c7c7cd28 from collections.abc import Callable from typing import TYPE_CHECKING, Any, Literal, Required, TypedDict @@ -138,6 +138,7 @@ class SessionInvalidPayload(TypedDict): class AccessRevokedPayload(TypedDict): "Current read authority failed; this subscriber was detached before further egress." + artifact: str reason: str diff --git a/src/archastro/platform/channels/api_chat_channel.py b/src/archastro/platform/channels/api_chat_channel.py index 6ea6022..52f3d79 100644 --- a/src/archastro/platform/channels/api_chat_channel.py +++ b/src/archastro/platform/channels/api_chat_channel.py @@ -1,6 +1,6 @@ # Copyright (c) 2026 ArchAstro Inc. Licensed under the MIT License. # This file is auto-generated by @archastro/sdk-generator. Do not edit. -# Content hash: bc65fd615b6b +# Content hash: 517c62519b88 from collections.abc import Callable from datetime import datetime @@ -17,6 +17,14 @@ class ApiChatForkThreadInput(TypedDict, total=False): title: str +class ApiChatAttachArtifactInput(TypedDict, total=False): + "Attach a room agent to a live Artifact; its session answers the Artifact's signals" + + agent: Required[str] + artifact: Required[str] + instructions: str + + class ApiChatMarkThreadReadInput(TypedDict): "Mark a thread as read up to a given message" @@ -148,6 +156,24 @@ class MessageAddedPayloadMessageAclAddItem(TypedDict, total=False): 'The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' +class MessageAddedPayloadMessageAclAddDeniesItem(TypedDict, total=False): + actions: Required[list[str]] + 'Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.' + principal: str | None + 'The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.' + principal_type: Required[str] + 'The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' + + +class MessageAddedPayloadMessageAclDeniesItem(TypedDict, total=False): + actions: Required[list[str]] + 'Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.' + principal: str | None + 'The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.' + principal_type: Required[str] + 'The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' + + class MessageAddedPayloadMessageAclGrantsItem(TypedDict, total=False): actions: Required[list[str]] 'Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.' @@ -164,13 +190,28 @@ class MessageAddedPayloadMessageAclRemoveItem(TypedDict, total=False): 'The kind of principal to remove. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' +class MessageAddedPayloadMessageAclRemoveDeniesItem(TypedDict, total=False): + principal: str | None + 'The identifier of the principal to remove. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`. Omit when `principal_type` is `"everyone"`.' + principal_type: Required[str] + 'The kind of principal to remove. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' + + class MessageAddedPayloadMessageAcl(TypedDict, total=False): add: list[MessageAddedPayloadMessageAclAddItem] | None "Patch mode: grants to add or merge into the existing list. Cannot be combined with `grants`." + add_denies: list[MessageAddedPayloadMessageAclAddDeniesItem] | None + "Patch mode: denies to add or merge, replacing any grant for the same principal." + denies: list[MessageAddedPayloadMessageAclDeniesItem] | None + "Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support." grants: list[MessageAddedPayloadMessageAclGrantsItem] | None "Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`." + preserve_denies: bool | None + "Retain current server denies atomically in replacement or patch mode; current denies win." remove: list[MessageAddedPayloadMessageAclRemoveItem] | None "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`." + remove_denies: list[MessageAddedPayloadMessageAclRemoveDeniesItem] | None + "Patch mode: principals whose denies should be removed." class MessageAddedPayloadMessageActorsItemProfilePicture(TypedDict, total=False): @@ -411,6 +452,24 @@ class MessageUpdatedPayloadMessageAclAddItem(TypedDict, total=False): 'The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' +class MessageUpdatedPayloadMessageAclAddDeniesItem(TypedDict, total=False): + actions: Required[list[str]] + 'Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.' + principal: str | None + 'The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.' + principal_type: Required[str] + 'The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' + + +class MessageUpdatedPayloadMessageAclDeniesItem(TypedDict, total=False): + actions: Required[list[str]] + 'Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.' + principal: str | None + 'The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.' + principal_type: Required[str] + 'The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' + + class MessageUpdatedPayloadMessageAclGrantsItem(TypedDict, total=False): actions: Required[list[str]] 'Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.' @@ -427,13 +486,28 @@ class MessageUpdatedPayloadMessageAclRemoveItem(TypedDict, total=False): 'The kind of principal to remove. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' +class MessageUpdatedPayloadMessageAclRemoveDeniesItem(TypedDict, total=False): + principal: str | None + 'The identifier of the principal to remove. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`. Omit when `principal_type` is `"everyone"`.' + principal_type: Required[str] + 'The kind of principal to remove. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' + + class MessageUpdatedPayloadMessageAcl(TypedDict, total=False): add: list[MessageUpdatedPayloadMessageAclAddItem] | None "Patch mode: grants to add or merge into the existing list. Cannot be combined with `grants`." + add_denies: list[MessageUpdatedPayloadMessageAclAddDeniesItem] | None + "Patch mode: denies to add or merge, replacing any grant for the same principal." + denies: list[MessageUpdatedPayloadMessageAclDeniesItem] | None + "Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support." grants: list[MessageUpdatedPayloadMessageAclGrantsItem] | None "Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`." + preserve_denies: bool | None + "Retain current server denies atomically in replacement or patch mode; current denies win." remove: list[MessageUpdatedPayloadMessageAclRemoveItem] | None "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`." + remove_denies: list[MessageUpdatedPayloadMessageAclRemoveDeniesItem] | None + "Patch mode: principals whose denies should be removed." class MessageUpdatedPayloadMessageActorsItemProfilePicture(TypedDict, total=False): @@ -706,8 +780,9 @@ class TypingPayloadActor(TypedDict, total=False): class TypingPayload(TypedDict, total=False): - "Broadcast when a participant (human or agent) starts or stops typing. Ephemeral; never persisted." + "Broadcast when a participant (human or agent) starts or stops typing. Ephemeral; never persisted. Agent events may carry `activity`, a snapshot of what the running turn has done (tool_calls, tool, thoughts)." + activity: dict[str, Any] | None actor: TypingPayloadActor | None "The entity that authored a message, either a human user or an agent." is_typing: bool | None @@ -990,6 +1065,10 @@ async def leave(self): async def api_chat_fork_thread(self, payload: ApiChatForkThreadInput) -> dict[str, Any]: return await self._channel.push("api:chat:fork_thread", payload) + # Attach a room agent to a live Artifact; its session answers the Artifact's signals + async def api_chat_attach_artifact(self, payload: ApiChatAttachArtifactInput) -> dict[str, Any]: + return await self._channel.push("api:chat:attach_artifact", payload) + # Mark a thread as read up to a given message async def api_chat_mark_thread_read( self, payload: ApiChatMarkThreadReadInput @@ -1068,7 +1147,7 @@ def on_thread_event(self, callback: Callable[[ThreadEventPayload], None]) -> Cal def on_system_event(self, callback: Callable[[SystemEventPayload], None]) -> Callable[[], None]: return self._channel.on("system_event", callback) - # Broadcast when a participant (human or agent) starts or stops typing. Ephemeral; never persisted. + # Broadcast when a participant (human or agent) starts or stops typing. Ephemeral; never persisted. Agent events may carry `activity`, a snapshot of what the running turn has done (tool_calls, tool, thoughts). def on_typing(self, callback: Callable[[TypingPayload], None]) -> Callable[[], None]: return self._channel.on("typing", callback) diff --git a/src/archastro/platform/channels/api_tasks_channel.py b/src/archastro/platform/channels/api_tasks_channel.py index 39f46dd..95609e6 100644 --- a/src/archastro/platform/channels/api_tasks_channel.py +++ b/src/archastro/platform/channels/api_tasks_channel.py @@ -1,6 +1,6 @@ # Copyright (c) 2026 ArchAstro Inc. Licensed under the MIT License. # This file is auto-generated by @archastro/sdk-generator. Do not edit. -# Content hash: 923456011b8a +# Content hash: 78eb7ba46268 from collections.abc import Callable from datetime import datetime @@ -82,6 +82,8 @@ class TasksUpdatedPayloadTasksItem(TypedDict, total=False): "Event-stream version for optimistic update fencing. Pass this value as `expected_version` on an update to reject concurrent writes." blocked_by_count: int | None "Number of readable tasks marked as blocking this task, whether or not they are done (see `GET /tasks/{task}/blockers`). Computed on list/show reads; create/update responses may lag one read behind." + blockers: list[str] | None + "Visible blocker IDs when requested with include=blockers." closed_at: datetime | None "When the task was marked as done or otherwise closed (ISO 8601). `null` if the task is still open." comments_count: int | None @@ -102,6 +104,8 @@ class TasksUpdatedPayloadTasksItem(TypedDict, total=False): "Date and time by which the task should be completed (ISO 8601). `null` if no due date is set." epic: str | None "Free-form grouping label. `null` when the task is not in an epic." + human_answer_receipts: dict[str, Any] | None + "Server-owned authenticated human answer intent, keyed by question version. Not infrastructure permission." id: Required[str] "Task ID (`tsk_...`)." is_blocked: bool | None @@ -110,6 +114,8 @@ class TasksUpdatedPayloadTasksItem(TypedDict, total=False): "True exactly when status is in_progress and the task has no lease or its lease expiry is in the past. Derived at read time from status and lease expiry, including on unannotated reads." links: dict[str, Any] | None "Key-value map of named URLs or references associated with the task. Returns an empty object when no links have been set." + machine_rescope_receipts: dict[str, Any] | None + "Server-owned records of machine-applied local rescopes, keyed by question version. Never evidence that a human answered." metadata: dict[str, Any] | None "Arbitrary key-value map of application-specific data stored alongside the task. Returns an empty object when no metadata has been set." name: Required[str] @@ -148,6 +154,8 @@ class TasksUpdatedPayloadTasksItem(TypedDict, total=False): "Binary that must run this work (for example `my-cli`). A worker should take the task only when its own `target_binary` build is at least `target_version`. `null` when the task has no target. Set together with `target_version`." target_version: str | None "Minimum semantic version of `target_binary` that can run this work (for example `0.48.9`), in canonical `MAJOR.MINOR.PATCH[-prerelease][+build]` form. `null` when the task has no target." + task_epic: str | None + "First-class Epic membership; does not grant access to the task." team: str | None "ID of the team that owns this task (`tem_...`). `null` if the task is not scoped to a team." thread: str | None diff --git a/src/archastro/platform/client.py b/src/archastro/platform/client.py index 566bb03..9212ba1 100644 --- a/src/archastro/platform/client.py +++ b/src/archastro/platform/client.py @@ -1,6 +1,6 @@ # Copyright (c) 2026 ArchAstro Inc. Licensed under the MIT License. # This file is auto-generated by @archastro/sdk-generator. Do not edit. -# Content hash: b950691a4ecf +# Content hash: 4be57ec69404 from urllib.parse import urlparse, urlunparse @@ -53,6 +53,7 @@ def __init__( self.automation_runs = self.v1.automation_runs self.automations = self.v1.automations self.bug_reports = self.v1.bug_reports + self.computers = self.v1.computers self.config = self.v1.config self.custom_objects = self.v1.custom_objects self.event_subscription_deliveries = self.v1.event_subscription_deliveries @@ -83,6 +84,7 @@ def __init__( self.solutions = self.v1.solutions self.ssh_keys = self.v1.ssh_keys self.status = self.v1.status + self.task_epics = self.v1.task_epics self.task_ownership_conversions = self.v1.task_ownership_conversions self.tasks = self.v1.tasks self.team_memberships = self.v1.team_memberships @@ -294,6 +296,7 @@ def __init__( self.automation_runs = self.v1.automation_runs self.automations = self.v1.automations self.bug_reports = self.v1.bug_reports + self.computers = self.v1.computers self.config = self.v1.config self.custom_objects = self.v1.custom_objects self.event_subscription_deliveries = self.v1.event_subscription_deliveries @@ -324,6 +327,7 @@ def __init__( self.solutions = self.v1.solutions self.ssh_keys = self.v1.ssh_keys self.status = self.v1.status + self.task_epics = self.v1.task_epics self.task_ownership_conversions = self.v1.task_ownership_conversions self.tasks = self.v1.tasks self.team_memberships = self.v1.team_memberships diff --git a/src/archastro/platform/types/automations.py b/src/archastro/platform/types/automations.py index a513ac7..f4c2536 100644 --- a/src/archastro/platform/types/automations.py +++ b/src/archastro/platform/types/automations.py @@ -1,6 +1,6 @@ # Copyright (c) 2026 ArchAstro Inc. Licensed under the MIT License. # This file is auto-generated by @archastro/sdk-generator. Do not edit. -# Content hash: 2f5da28f3d4e +# Content hash: cb51260abd03 from datetime import datetime from typing import Any @@ -67,11 +67,11 @@ class AutomationRun(BaseModel): ) payload: dict[str, Any] | None = Field( default=None, - description="The input event payload that triggered this run. Structure varies by automation type. Defaults to an empty object if no payload was provided.", + description="The input event payload that triggered this run. Structure varies by automation type. Defaults to an empty object if no payload was provided. Omitted on retrieval when include_payload=false.", ) result: dict[str, Any] | None = Field( default=None, - description="The output produced after the automation finished executing. Contains workflow-defined keys alongside any returned output. `null` if the run has not yet completed.", + description="The output produced after the automation finished executing. Contains workflow-defined keys alongside any returned output. `null` if the run has not yet completed. Omitted on retrieval when include_payload=false.", ) status: str = Field( ..., diff --git a/src/archastro/platform/types/common.py b/src/archastro/platform/types/common.py index 197857a..99050e5 100644 --- a/src/archastro/platform/types/common.py +++ b/src/archastro/platform/types/common.py @@ -1,6 +1,6 @@ # Copyright (c) 2026 ArchAstro Inc. Licensed under the MIT License. # This file is auto-generated by @archastro/sdk-generator. Do not edit. -# Content hash: 8551e05dcaf9 +# Content hash: ba2df0282ff9 from datetime import datetime from typing import Annotated, Any, Literal @@ -8,6 +8,7 @@ from pydantic import BaseModel, ConfigDict, Field from .automations import AutomationParticipantSlot, AutomationPrefills +from .computers import ComputerRepository from .config import Config from .image import ImageSource from .users import User @@ -66,14 +67,29 @@ class Acl(BaseModel): default=None, description="Patch mode: grants to add or merge into the existing list. Cannot be combined with `grants`.", ) + add_denies: list[AclGrant] | None = Field( + default=None, + description="Patch mode: denies to add or merge, replacing any grant for the same principal.", + ) + denies: list[AclGrant] | None = Field( + default=None, + description="Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support.", + ) grants: list[AclGrant] | None = Field( default=None, description="Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", ) + preserve_denies: bool | None = Field( + default=None, + description="Retain current server denies atomically in replacement or patch mode; current denies win.", + ) remove: list[AclRemoveTarget] | None = Field( default=None, description="Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", ) + remove_denies: list[AclRemoveTarget] | None = Field( + default=None, description="Patch mode: principals whose denies should be removed." + ) class ActivityFeedEntry(BaseModel): @@ -279,12 +295,35 @@ class Origin(BaseModel): thread_id: str | None = None +class SelfUpdateChange(BaseModel): + """ + Public review fields for one proposed self-update change. + """ + + model_config = ConfigDict(populate_by_name=True) + + action: str | None = None + class_: str | None = Field(default=None, alias="class") + path: str | None = None + tier: str | None = None + + class Payload(BaseModel): """ - Question request payload. + Kind-safe request payload. """ - question: str + changes: list[SelfUpdateChange] | None = None + from_version: str | None = None + instructions_md: str | None = None + key: str | None = None + overwrite: bool | None = None + prompt: str | None = None + proposal_id: str | None = None + question: str | None = None + rationale: str | None = None + to_version: str | None = None + validate_script: str | None = None class Resolution(BaseModel): @@ -293,7 +332,11 @@ class Resolution(BaseModel): """ answer: str | None = None + key: str | None = None reason: str | None = None + set: bool | None = None + status: str | None = None + to_version: str | None = None class Summary(BaseModel): @@ -1143,6 +1186,10 @@ class CurrentUser(BaseModel): alias: str | None = Field(default=None, description="Short handle or alias of the user.") app: str | None = Field(default=None, description="ID of the token-scoped app (`dap_...`).") app_name: str | None = Field(default=None, description="Display name of the token-scoped app.") + avatar_url: str | None = Field( + default=None, + description="Stable public URL of the profile picture. Unlike `profile_picture.url` it does not expire, so clients can store it; it stops resolving when the picture is replaced. `null` when the user has no profile picture.", + ) effective_access: EffectiveAccess | None = Field( default=None, description="Present only when the request supplies one or more `entitlement[]` values.", @@ -2820,6 +2867,10 @@ class AgentComputer(BaseModel): app: str | None = Field( default=None, description="ID of the app this computer belongs to (`dap_...`)." ) + bootstrap: dict[str, Any] | None = Field( + default=None, + description="Bootstrap results, including each repository's status, commit and error.", + ) config: dict[str, Any] | None = Field( default=None, description="Provider-specific configuration key-value pairs for the computer. Structure depends on the underlying compute provider.", @@ -2852,19 +2903,23 @@ class AgentComputer(BaseModel): ) provider: str | None = Field( default=None, - description='Compute backend powering this computer: `"sprites"` (Fly Sprites), `"vercel"` (Vercel Sandbox) or `"e2b"` (E2B).', + description='Compute backend powering this computer: `"sprites"` (Fly Sprites), `"vercel"` (Vercel Sandbox), `"e2b"` (E2B) or `"devbox"` (an ArchAstro devbox owned by the computer\'s user).', ) region: str | None = Field( default=None, description='Cloud region where the computer is hosted, e.g. `"us-east-1"`. `null` if not yet assigned or when the provider has no region concept (e.g. `"vercel"`, `"e2b"`).', ) + repositories: list[ComputerRepository] | None = Field( + default=None, + description="Ordered GitHub checkouts with repository and nullable ref; the first checkout is primary.", + ) sprite_url: str | None = Field( default=None, description="URL of the live screenshot sprite used to render a real-time preview of the computer's screen. `null` when no sprite is available.", ) status: str | None = Field( default=None, - description='Current lifecycle state of the computer. Common values include `"provisioning"`, `"ready"`, `"error"`, and `"terminated"`.', + description='Current lifecycle state of the computer. Common values include `"provisioning"`, `"ready"`, `"paused"` (resumes on use), `"error"`, and `"destroyed"`.', ) thread_id: str | None = Field( default=None, @@ -3099,7 +3154,7 @@ class AgentRequest(BaseModel): ) kind: str | None = Field(default=None, description="Registered request kind.") origin: Origin | None = Field(default=None, description="Origin references.") - payload: Payload | None = Field(default=None, description="Question request payload.") + payload: Payload | None = Field(default=None, description="Kind-safe request payload.") resolution: Resolution | None = Field( default=None, description="Answer or rejection reason; null before resolution." ) @@ -3710,7 +3765,7 @@ class AgentUpgradeChange(BaseModel): ) resource_type: str = Field( ..., - description='Type of the resource being changed. One of `"agent"`, `"tool"`, `"routine"`, `"skill"`, `"computer"`, or `"knowledge"`.', + description='Type of the resource being changed. One of `"agent"`, `"tool"`, `"routine"`, `"skill"`, `"computer"`, `"endpoint"`, or `"knowledge"`.', ) source_template_config: UpgradeTemplateSummary | None = Field( default=None, diff --git a/src/archastro/platform/types/computers.py b/src/archastro/platform/types/computers.py index 74acb2b..6667fe1 100644 --- a/src/archastro/platform/types/computers.py +++ b/src/archastro/platform/types/computers.py @@ -1,11 +1,25 @@ # Copyright (c) 2026 ArchAstro Inc. Licensed under the MIT License. # This file is auto-generated by @archastro/sdk-generator. Do not edit. -# Content hash: 832fce2a8b08 +# Content hash: c5f7d02bc5d8 from pydantic import BaseModel, Field +class ComputerRepository(BaseModel): + """ + A GitHub repository checkout recorded for later computer bootstrap. + """ + + ref: str | None = Field( + default=None, + description="Optional checkout ref; null selects the repository's default branch.", + ) + repository: str = Field( + ..., description="GitHub owner/name; supported GitHub URLs are normalized on creation." + ) + + class ComputerExecResult(BaseModel): """ The result of executing a shell command on an agent's computer environment. Contains the captured output and the process exit code. diff --git a/src/archastro/platform/types/tasks.py b/src/archastro/platform/types/tasks.py index c859160..74e6805 100644 --- a/src/archastro/platform/types/tasks.py +++ b/src/archastro/platform/types/tasks.py @@ -1,6 +1,6 @@ # Copyright (c) 2026 ArchAstro Inc. Licensed under the MIT License. # This file is auto-generated by @archastro/sdk-generator. Do not edit. -# Content hash: 3a75d35595f1 +# Content hash: 4b59c2738ffd from datetime import datetime from typing import Any @@ -41,6 +41,9 @@ class Task(BaseModel): default=None, description="Number of readable tasks marked as blocking this task, whether or not they are done (see `GET /tasks/{task}/blockers`). Computed on list/show reads; create/update responses may lag one read behind.", ) + blockers: list[str] | None = Field( + default=None, description="Visible blocker IDs when requested with include=blockers." + ) closed_at: datetime | None = Field( default=None, description="When the task was marked as done or otherwise closed (ISO 8601). `null` if the task is still open.", @@ -79,6 +82,10 @@ class Task(BaseModel): default=None, description="Free-form grouping label. `null` when the task is not in an epic.", ) + human_answer_receipts: dict[str, Any] | None = Field( + default=None, + description="Server-owned authenticated human answer intent, keyed by question version. Not infrastructure permission.", + ) id: str = Field(..., description="Task ID (`tsk_...`).") is_blocked: bool | None = Field( default=None, @@ -92,6 +99,10 @@ class Task(BaseModel): default=None, description="Key-value map of named URLs or references associated with the task. Returns an empty object when no links have been set.", ) + machine_rescope_receipts: dict[str, Any] | None = Field( + default=None, + description="Server-owned records of machine-applied local rescopes, keyed by question version. Never evidence that a human answered.", + ) metadata: dict[str, Any] | None = Field( default=None, description="Arbitrary key-value map of application-specific data stored alongside the task. Returns an empty object when no metadata has been set.", @@ -165,6 +176,9 @@ class Task(BaseModel): default=None, description="Minimum semantic version of `target_binary` that can run this work (for example `0.48.9`), in canonical `MAJOR.MINOR.PATCH[-prerelease][+build]` form. `null` when the task has no target.", ) + task_epic: str | None = Field( + default=None, description="First-class Epic membership; does not grant access to the task." + ) team: str | None = Field( default=None, description="ID of the team that owns this task (`tem_...`). `null` if the task is not scoped to a team.", @@ -223,6 +237,15 @@ class TaskComment(BaseModel): ) +class TaskDeletion(BaseModel): + """ + A retained visible task deletion. + """ + + deleted_at: str + task: str + + class TaskEnsureResult(BaseModel): """ The current source task and whether this request created it. @@ -232,6 +255,43 @@ class TaskEnsureResult(BaseModel): task: Task = Field(..., description="The current task.") +class TaskEpicDrafts(BaseModel): + drafts_version: int + frozen: bool + tasks: list[dict[str, Any]] + + +class TaskEpicEntity(BaseModel): + """ + A first-class Epic, with counts restricted to tasks visible to the caller. + """ + + app_id: str + description: str | None = None + drafts_version: int + id: str + links: list[dict[str, Any]] + metadata: dict[str, Any] + name: str + owner: dict[str, Any] + publish_state: str + rollup: dict[str, Any] + sandbox_id: str | None = None + state: str + version: int + + +class TaskEpicEntityCollection(BaseModel): + """ + Entity representation of an owner's Epic collection; not a label-summary page. + """ + + after_cursor: str | None = None + before_cursor: str | None = None + data: list[TaskEpicEntity] + has_more: bool + + class TaskExternalLink(BaseModel): """ An indexed external object linked to a task. @@ -245,11 +305,14 @@ class TaskExternalLink(BaseModel): class TaskOwnershipJob(BaseModel): """ The background job accepted for a task ownership conversion. + Acceptance authorizes the root only. The worker validates and checkpoints the + connected graph before transferring ownership; validation can fail after 202. """ job_id: int = Field(..., description="Background job ID.") projection_pending: bool | None = Field( - default=None, description="Completed transfers are still reaching task read models." + default=None, + description="Completed transfers are still reaching task read models. False when preparation failed or the job was cancelled before selecting tasks.", ) status: str = Field(..., description="Current background job state.") diff --git a/src/archastro/platform/types/threads.py b/src/archastro/platform/types/threads.py index d35b14e..0afeaad 100644 --- a/src/archastro/platform/types/threads.py +++ b/src/archastro/platform/types/threads.py @@ -1,6 +1,6 @@ # Copyright (c) 2026 ArchAstro Inc. Licensed under the MIT License. # This file is auto-generated by @archastro/sdk-generator. Do not edit. -# Content hash: fed6220aebf2 +# Content hash: c45fd7a011de from datetime import datetime from typing import Any, Literal @@ -139,6 +139,10 @@ class Thread(BaseModel): default=None, description="ID of the team that owns this thread (`team_...`). `null` for user-owned or agent-owned threads.", ) + thread_template_key: str | None = Field( + default=None, + description="Read-only key of the template used to create this thread. `null` for threads not created from a template.", + ) title: str | None = Field( default=None, description="Human-readable name of the thread. `null` if no title has been set.", diff --git a/src/archastro/platform/v1/__init__.py b/src/archastro/platform/v1/__init__.py index 3f49cfd..50c20c0 100644 --- a/src/archastro/platform/v1/__init__.py +++ b/src/archastro/platform/v1/__init__.py @@ -1,6 +1,6 @@ # Copyright (c) 2026 ArchAstro Inc. Licensed under the MIT License. # This file is auto-generated by @archastro/sdk-generator. Do not edit. -# Content hash: 67fee539d52d +# Content hash: 0950d0e5016f from ..runtime.http_client import HttpClient, SyncHttpClient from .resources.activity_feed import ActivityFeedResource, AsyncActivityFeedResource @@ -23,6 +23,7 @@ from .resources.automation_runs import AsyncAutomationRunResource, AutomationRunResource from .resources.automations import AsyncAutomationResource, AutomationResource from .resources.bug_reports import AsyncBugReportResource, BugReportResource +from .resources.computers import AsyncComputerResource, ComputerResource from .resources.config import AsyncConfigResource, ConfigResource from .resources.custom_objects import AsyncCustomObjectResource, CustomObjectResource from .resources.event_subscription_deliveries import ( @@ -78,6 +79,7 @@ from .resources.solutions import AsyncSolutionResource, SolutionResource from .resources.ssh_keys import AsyncSshKeyResource, SshKeyResource from .resources.status import AsyncStatuResource, StatuResource +from .resources.task_epics import AsyncTaskEpicResource, TaskEpicResource from .resources.task_ownership_conversions import ( AsyncTaskOwnershipConversionResource, TaskOwnershipConversionResource, @@ -112,6 +114,7 @@ def __init__(self, http: SyncHttpClient): self.automation_runs = AutomationRunResource(http) self.automations = AutomationResource(http) self.bug_reports = BugReportResource(http) + self.computers = ComputerResource(http) self.config = ConfigResource(http) self.custom_objects = CustomObjectResource(http) self.event_subscription_deliveries = EventSubscriptionDeliveryResource(http) @@ -142,6 +145,7 @@ def __init__(self, http: SyncHttpClient): self.solutions = SolutionResource(http) self.ssh_keys = SshKeyResource(http) self.status = StatuResource(http) + self.task_epics = TaskEpicResource(http) self.task_ownership_conversions = TaskOwnershipConversionResource(http) self.tasks = TaskResource(http) self.team_memberships = TeamMembershipResource(http) @@ -174,6 +178,7 @@ def __init__(self, http: HttpClient): self.automation_runs = AsyncAutomationRunResource(http) self.automations = AsyncAutomationResource(http) self.bug_reports = AsyncBugReportResource(http) + self.computers = AsyncComputerResource(http) self.config = AsyncConfigResource(http) self.custom_objects = AsyncCustomObjectResource(http) self.event_subscription_deliveries = AsyncEventSubscriptionDeliveryResource(http) @@ -204,6 +209,7 @@ def __init__(self, http: HttpClient): self.solutions = AsyncSolutionResource(http) self.ssh_keys = AsyncSshKeyResource(http) self.status = AsyncStatuResource(http) + self.task_epics = AsyncTaskEpicResource(http) self.task_ownership_conversions = AsyncTaskOwnershipConversionResource(http) self.tasks = AsyncTaskResource(http) self.team_memberships = AsyncTeamMembershipResource(http) diff --git a/src/archastro/platform/v1/resources/__init__.py b/src/archastro/platform/v1/resources/__init__.py index 7f401b5..350c901 100644 --- a/src/archastro/platform/v1/resources/__init__.py +++ b/src/archastro/platform/v1/resources/__init__.py @@ -1,6 +1,6 @@ # Copyright (c) 2026 ArchAstro Inc. Licensed under the MIT License. # This file is auto-generated by @archastro/sdk-generator. Do not edit. -# Content hash: e6f3b46288bb +# Content hash: fdf109322c0c from .activity_feed import ( ActivityFeedResource, # noqa: F401 @@ -70,6 +70,10 @@ AsyncBugReportResource, # noqa: F401 BugReportResource, # noqa: F401 ) +from .computers import ( + AsyncComputerResource, # noqa: F401 + ComputerResource, # noqa: F401 +) from .config import ( AsyncConfigResource, # noqa: F401 ConfigResource, # noqa: F401 @@ -194,6 +198,10 @@ AsyncStatuResource, # noqa: F401 StatuResource, # noqa: F401 ) +from .task_epics import ( + AsyncTaskEpicResource, # noqa: F401 + TaskEpicResource, # noqa: F401 +) from .task_ownership_conversions import ( AsyncTaskOwnershipConversionResource, # noqa: F401 TaskOwnershipConversionResource, # noqa: F401 diff --git a/src/archastro/platform/v1/resources/agent_computers.py b/src/archastro/platform/v1/resources/agent_computers.py index 1f28211..9ccb72a 100644 --- a/src/archastro/platform/v1/resources/agent_computers.py +++ b/src/archastro/platform/v1/resources/agent_computers.py @@ -1,6 +1,6 @@ # Copyright (c) 2026 ArchAstro Inc. Licensed under the MIT License. # This file is auto-generated by @archastro/sdk-generator. Do not edit. -# Content hash: 58d0acadaa0a +# Content hash: e8a8dc109922 from __future__ import annotations @@ -20,6 +20,24 @@ class AgentComputerUpdateInputAclAddItem(TypedDict, total=False): 'The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' +class AgentComputerUpdateInputAclAddDeniesItem(TypedDict, total=False): + actions: Required[list[str]] + 'Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.' + principal: str | None + 'The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.' + principal_type: Required[str] + 'The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' + + +class AgentComputerUpdateInputAclDeniesItem(TypedDict, total=False): + actions: Required[list[str]] + 'Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.' + principal: str | None + 'The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.' + principal_type: Required[str] + 'The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' + + class AgentComputerUpdateInputAclGrantsItem(TypedDict, total=False): actions: Required[list[str]] 'Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.' @@ -36,13 +54,28 @@ class AgentComputerUpdateInputAclRemoveItem(TypedDict, total=False): 'The kind of principal to remove. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' +class AgentComputerUpdateInputAclRemoveDeniesItem(TypedDict, total=False): + principal: str | None + 'The identifier of the principal to remove. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`. Omit when `principal_type` is `"everyone"`.' + principal_type: Required[str] + 'The kind of principal to remove. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' + + class AgentComputerUpdateInputAcl(TypedDict, total=False): add: list[AgentComputerUpdateInputAclAddItem] | None "Patch mode: grants to add or merge into the existing list. Cannot be combined with `grants`." + add_denies: list[AgentComputerUpdateInputAclAddDeniesItem] | None + "Patch mode: denies to add or merge, replacing any grant for the same principal." + denies: list[AgentComputerUpdateInputAclDeniesItem] | None + "Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support." grants: list[AgentComputerUpdateInputAclGrantsItem] | None "Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`." + preserve_denies: bool | None + "Retain current server denies atomically in replacement or patch mode; current denies win." remove: list[AgentComputerUpdateInputAclRemoveItem] | None "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`." + remove_denies: list[AgentComputerUpdateInputAclRemoveDeniesItem] | None + "Patch mode: principals whose denies should be removed." class AgentComputerUpdateInput(TypedDict, total=False): diff --git a/src/archastro/platform/v1/resources/agent_requests.py b/src/archastro/platform/v1/resources/agent_requests.py index b82fea3..b223908 100644 --- a/src/archastro/platform/v1/resources/agent_requests.py +++ b/src/archastro/platform/v1/resources/agent_requests.py @@ -1,11 +1,13 @@ # Copyright (c) 2026 ArchAstro Inc. Licensed under the MIT License. # This file is auto-generated by @archastro/sdk-generator. Do not edit. -# Content hash: 9643ae844548 +# Content hash: 32c13240e319 from __future__ import annotations from typing import Any, TypedDict +from pydantic import BaseModel, Field + from ...runtime.http_client import HttpClient, SyncHttpClient from ...types.common import AgentRequest, AgentRequestListResponse @@ -24,6 +26,14 @@ class AgentRequestResolveInput(TypedDict): "Kind-specific input. Secrets must use secret_value." +class AgentRequestOauthStartResponse(BaseModel): + """ + Successful response + """ + + authorization_url: str | None = Field(default=None, description="Connector browser handoff URL") + + class AsyncAgentRequestResource: def __init__(self, http: HttpClient): self._http = http @@ -84,6 +94,22 @@ async def get(self, agent_request: str) -> AgentRequest: response_type=AgentRequest, ) + async def oauth_start(self, agent_request: str) -> AgentRequestOauthStartResponse: + """ + Start an agent OAuth connection + + Args: + agent_request: OAuth request ID + + Returns: + Successful response + """ + return await self._http.request( + f"/api/v1/agent_requests/{agent_request}/oauth_start", + method="POST", + response_type=AgentRequestOauthStartResponse, + ) + async def reject(self, agent_request: str, input: AgentRequestRejectInput) -> AgentRequest: """ Reject an agent request @@ -185,6 +211,22 @@ def get(self, agent_request: str) -> AgentRequest: response_type=AgentRequest, ) + def oauth_start(self, agent_request: str) -> AgentRequestOauthStartResponse: + """ + Start an agent OAuth connection + + Args: + agent_request: OAuth request ID + + Returns: + Successful response + """ + return self._http.request( + f"/api/v1/agent_requests/{agent_request}/oauth_start", + method="POST", + response_type=AgentRequestOauthStartResponse, + ) + def reject(self, agent_request: str, input: AgentRequestRejectInput) -> AgentRequest: """ Reject an agent request diff --git a/src/archastro/platform/v1/resources/agent_routines.py b/src/archastro/platform/v1/resources/agent_routines.py index ac893a3..a0aa6c8 100644 --- a/src/archastro/platform/v1/resources/agent_routines.py +++ b/src/archastro/platform/v1/resources/agent_routines.py @@ -1,6 +1,6 @@ # Copyright (c) 2026 ArchAstro Inc. Licensed under the MIT License. # This file is auto-generated by @archastro/sdk-generator. Do not edit. -# Content hash: 4f81edf1b7af +# Content hash: 23a32b27a505 from __future__ import annotations @@ -27,6 +27,24 @@ class AgentRoutineUpdateInputAclAddItem(TypedDict, total=False): 'The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' +class AgentRoutineUpdateInputAclAddDeniesItem(TypedDict, total=False): + actions: Required[list[str]] + 'Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.' + principal: str | None + 'The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.' + principal_type: Required[str] + 'The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' + + +class AgentRoutineUpdateInputAclDeniesItem(TypedDict, total=False): + actions: Required[list[str]] + 'Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.' + principal: str | None + 'The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.' + principal_type: Required[str] + 'The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' + + class AgentRoutineUpdateInputAclGrantsItem(TypedDict, total=False): actions: Required[list[str]] 'Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.' @@ -43,13 +61,28 @@ class AgentRoutineUpdateInputAclRemoveItem(TypedDict, total=False): 'The kind of principal to remove. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' +class AgentRoutineUpdateInputAclRemoveDeniesItem(TypedDict, total=False): + principal: str | None + 'The identifier of the principal to remove. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`. Omit when `principal_type` is `"everyone"`.' + principal_type: Required[str] + 'The kind of principal to remove. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' + + class AgentRoutineUpdateInputAcl(TypedDict, total=False): add: list[AgentRoutineUpdateInputAclAddItem] | None "Patch mode: grants to add or merge into the existing list. Cannot be combined with `grants`." + add_denies: list[AgentRoutineUpdateInputAclAddDeniesItem] | None + "Patch mode: denies to add or merge, replacing any grant for the same principal." + denies: list[AgentRoutineUpdateInputAclDeniesItem] | None + "Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support." grants: list[AgentRoutineUpdateInputAclGrantsItem] | None "Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`." + preserve_denies: bool | None + "Retain current server denies atomically in replacement or patch mode; current denies win." remove: list[AgentRoutineUpdateInputAclRemoveItem] | None "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`." + remove_denies: list[AgentRoutineUpdateInputAclRemoveDeniesItem] | None + "Patch mode: principals whose denies should be removed." class AgentRoutineUpdateInputMessagePolicy(TypedDict, total=False): diff --git a/src/archastro/platform/v1/resources/agents.py b/src/archastro/platform/v1/resources/agents.py index e171fec..3cba925 100644 --- a/src/archastro/platform/v1/resources/agents.py +++ b/src/archastro/platform/v1/resources/agents.py @@ -1,6 +1,6 @@ # Copyright (c) 2026 ArchAstro Inc. Licensed under the MIT License. # This file is auto-generated by @archastro/sdk-generator. Do not edit. -# Content hash: 84e4708f4187 +# Content hash: da81b6d79834 from __future__ import annotations @@ -46,6 +46,24 @@ class AgentAgentComputerCreateInputAclAddItem(TypedDict, total=False): 'The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' +class AgentAgentComputerCreateInputAclAddDeniesItem(TypedDict, total=False): + actions: Required[list[str]] + 'Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.' + principal: str | None + 'The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.' + principal_type: Required[str] + 'The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' + + +class AgentAgentComputerCreateInputAclDeniesItem(TypedDict, total=False): + actions: Required[list[str]] + 'Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.' + principal: str | None + 'The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.' + principal_type: Required[str] + 'The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' + + class AgentAgentComputerCreateInputAclGrantsItem(TypedDict, total=False): actions: Required[list[str]] 'Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.' @@ -62,13 +80,35 @@ class AgentAgentComputerCreateInputAclRemoveItem(TypedDict, total=False): 'The kind of principal to remove. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' +class AgentAgentComputerCreateInputAclRemoveDeniesItem(TypedDict, total=False): + principal: str | None + 'The identifier of the principal to remove. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`. Omit when `principal_type` is `"everyone"`.' + principal_type: Required[str] + 'The kind of principal to remove. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' + + class AgentAgentComputerCreateInputAcl(TypedDict, total=False): add: list[AgentAgentComputerCreateInputAclAddItem] | None "Patch mode: grants to add or merge into the existing list. Cannot be combined with `grants`." + add_denies: list[AgentAgentComputerCreateInputAclAddDeniesItem] | None + "Patch mode: denies to add or merge, replacing any grant for the same principal." + denies: list[AgentAgentComputerCreateInputAclDeniesItem] | None + "Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support." grants: list[AgentAgentComputerCreateInputAclGrantsItem] | None "Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`." + preserve_denies: bool | None + "Retain current server denies atomically in replacement or patch mode; current denies win." remove: list[AgentAgentComputerCreateInputAclRemoveItem] | None "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`." + remove_denies: list[AgentAgentComputerCreateInputAclRemoveDeniesItem] | None + "Patch mode: principals whose denies should be removed." + + +class AgentAgentComputerCreateInputRepositoriesItem(TypedDict, total=False): + ref: str | None + "Optional checkout ref; null selects the repository's default branch." + repository: Required[str] + "GitHub owner/name; supported GitHub URLs are normalized on creation." class AgentAgentComputerCreateInput(TypedDict, total=False): @@ -88,6 +128,8 @@ class AgentAgentComputerCreateInput(TypedDict, total=False): 'Compute backend for the computer: `"sprites"` (Fly Sprites, the default), `"vercel"` (Vercel Sandbox) or `"e2b"` (E2B). Folded into `config.provider`.' region: str | None 'Region in which to provision the computer, e.g. `"iad"`. Defaults to `"iad"` when omitted.' + repositories: list[AgentAgentComputerCreateInputRepositoriesItem] | None + "Ordered GitHub checkouts (maximum 16): {repository: owner/name, ref: optional ref}. First is primary." class AgentAgentEnvVarCreateInput(TypedDict, total=False): @@ -199,6 +241,24 @@ class AgentCreateInputAclAddItem(TypedDict, total=False): 'The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' +class AgentCreateInputAclAddDeniesItem(TypedDict, total=False): + actions: Required[list[str]] + 'Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.' + principal: str | None + 'The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.' + principal_type: Required[str] + 'The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' + + +class AgentCreateInputAclDeniesItem(TypedDict, total=False): + actions: Required[list[str]] + 'Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.' + principal: str | None + 'The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.' + principal_type: Required[str] + 'The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' + + class AgentCreateInputAclGrantsItem(TypedDict, total=False): actions: Required[list[str]] 'Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.' @@ -215,13 +275,28 @@ class AgentCreateInputAclRemoveItem(TypedDict, total=False): 'The kind of principal to remove. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' +class AgentCreateInputAclRemoveDeniesItem(TypedDict, total=False): + principal: str | None + 'The identifier of the principal to remove. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`. Omit when `principal_type` is `"everyone"`.' + principal_type: Required[str] + 'The kind of principal to remove. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' + + class AgentCreateInputAcl(TypedDict, total=False): add: list[AgentCreateInputAclAddItem] | None "Patch mode: grants to add or merge into the existing list. Cannot be combined with `grants`." + add_denies: list[AgentCreateInputAclAddDeniesItem] | None + "Patch mode: denies to add or merge, replacing any grant for the same principal." + denies: list[AgentCreateInputAclDeniesItem] | None + "Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support." grants: list[AgentCreateInputAclGrantsItem] | None "Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`." + preserve_denies: bool | None + "Retain current server denies atomically in replacement or patch mode; current denies win." remove: list[AgentCreateInputAclRemoveItem] | None "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`." + remove_denies: list[AgentCreateInputAclRemoveDeniesItem] | None + "Patch mode: principals whose denies should be removed." class AgentCreateInputProfilePicture(TypedDict): @@ -349,6 +424,24 @@ class AgentUpdateInputAclAddItem(TypedDict, total=False): 'The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' +class AgentUpdateInputAclAddDeniesItem(TypedDict, total=False): + actions: Required[list[str]] + 'Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.' + principal: str | None + 'The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.' + principal_type: Required[str] + 'The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' + + +class AgentUpdateInputAclDeniesItem(TypedDict, total=False): + actions: Required[list[str]] + 'Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.' + principal: str | None + 'The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.' + principal_type: Required[str] + 'The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' + + class AgentUpdateInputAclGrantsItem(TypedDict, total=False): actions: Required[list[str]] 'Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.' @@ -365,13 +458,28 @@ class AgentUpdateInputAclRemoveItem(TypedDict, total=False): 'The kind of principal to remove. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' +class AgentUpdateInputAclRemoveDeniesItem(TypedDict, total=False): + principal: str | None + 'The identifier of the principal to remove. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`. Omit when `principal_type` is `"everyone"`.' + principal_type: Required[str] + 'The kind of principal to remove. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' + + class AgentUpdateInputAcl(TypedDict, total=False): add: list[AgentUpdateInputAclAddItem] | None "Patch mode: grants to add or merge into the existing list. Cannot be combined with `grants`." + add_denies: list[AgentUpdateInputAclAddDeniesItem] | None + "Patch mode: denies to add or merge, replacing any grant for the same principal." + denies: list[AgentUpdateInputAclDeniesItem] | None + "Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support." grants: list[AgentUpdateInputAclGrantsItem] | None "Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`." + preserve_denies: bool | None + "Retain current server denies atomically in replacement or patch mode; current denies win." remove: list[AgentUpdateInputAclRemoveItem] | None "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`." + remove_denies: list[AgentUpdateInputAclRemoveDeniesItem] | None + "Patch mode: principals whose denies should be removed." class AgentUpdateInputProfilePicture(TypedDict): @@ -425,6 +533,24 @@ class AgentAgentRoutinesInputAclAddItem(TypedDict, total=False): 'The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' +class AgentAgentRoutinesInputAclAddDeniesItem(TypedDict, total=False): + actions: Required[list[str]] + 'Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.' + principal: str | None + 'The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.' + principal_type: Required[str] + 'The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' + + +class AgentAgentRoutinesInputAclDeniesItem(TypedDict, total=False): + actions: Required[list[str]] + 'Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.' + principal: str | None + 'The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.' + principal_type: Required[str] + 'The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' + + class AgentAgentRoutinesInputAclGrantsItem(TypedDict, total=False): actions: Required[list[str]] 'Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.' @@ -441,13 +567,28 @@ class AgentAgentRoutinesInputAclRemoveItem(TypedDict, total=False): 'The kind of principal to remove. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' +class AgentAgentRoutinesInputAclRemoveDeniesItem(TypedDict, total=False): + principal: str | None + 'The identifier of the principal to remove. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`. Omit when `principal_type` is `"everyone"`.' + principal_type: Required[str] + 'The kind of principal to remove. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' + + class AgentAgentRoutinesInputAcl(TypedDict, total=False): add: list[AgentAgentRoutinesInputAclAddItem] | None "Patch mode: grants to add or merge into the existing list. Cannot be combined with `grants`." + add_denies: list[AgentAgentRoutinesInputAclAddDeniesItem] | None + "Patch mode: denies to add or merge, replacing any grant for the same principal." + denies: list[AgentAgentRoutinesInputAclDeniesItem] | None + "Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support." grants: list[AgentAgentRoutinesInputAclGrantsItem] | None "Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`." + preserve_denies: bool | None + "Retain current server denies atomically in replacement or patch mode; current denies win." remove: list[AgentAgentRoutinesInputAclRemoveItem] | None "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`." + remove_denies: list[AgentAgentRoutinesInputAclRemoveDeniesItem] | None + "Patch mode: principals whose denies should be removed." class AgentAgentRoutinesInputMessagePolicy(TypedDict, total=False): @@ -801,6 +942,7 @@ async def create(self, agent: str, input: AgentAgentComputerCreateInput) -> Agen input.name: Human-readable display name for the computer. input.provider: Compute backend for the computer: `"sprites"` (Fly Sprites, the default), `"vercel"` (Vercel Sandbox) or `"e2b"` (E2B). Folded into `config.provider`. input.region: Region in which to provision the computer, e.g. `"iad"`. Defaults to `"iad"` when omitted. + input.repositories: Ordered GitHub checkouts (maximum 16): {repository: owner/name, ref: optional ref}. First is primary. Returns: The newly provisioned computer. @@ -1745,6 +1887,7 @@ def create(self, agent: str, input: AgentAgentComputerCreateInput) -> AgentCompu input.name: Human-readable display name for the computer. input.provider: Compute backend for the computer: `"sprites"` (Fly Sprites, the default), `"vercel"` (Vercel Sandbox) or `"e2b"` (E2B). Folded into `config.provider`. input.region: Region in which to provision the computer, e.g. `"iad"`. Defaults to `"iad"` when omitted. + input.repositories: Ordered GitHub checkouts (maximum 16): {repository: owner/name, ref: optional ref}. First is primary. Returns: The newly provisioned computer. diff --git a/src/archastro/platform/v1/resources/artifacts.py b/src/archastro/platform/v1/resources/artifacts.py index 98fdad6..ef83de9 100644 --- a/src/archastro/platform/v1/resources/artifacts.py +++ b/src/archastro/platform/v1/resources/artifacts.py @@ -1,6 +1,6 @@ # Copyright (c) 2026 ArchAstro Inc. Licensed under the MIT License. # This file is auto-generated by @archastro/sdk-generator. Do not edit. -# Content hash: 6a317c2bbbbe +# Content hash: 91a453756371 from __future__ import annotations @@ -19,6 +19,24 @@ class ArtifactCreateInputAclAddItem(TypedDict, total=False): 'The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' +class ArtifactCreateInputAclAddDeniesItem(TypedDict, total=False): + actions: Required[list[str]] + 'Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.' + principal: str | None + 'The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.' + principal_type: Required[str] + 'The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' + + +class ArtifactCreateInputAclDeniesItem(TypedDict, total=False): + actions: Required[list[str]] + 'Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.' + principal: str | None + 'The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.' + principal_type: Required[str] + 'The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' + + class ArtifactCreateInputAclGrantsItem(TypedDict, total=False): actions: Required[list[str]] 'Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.' @@ -35,13 +53,28 @@ class ArtifactCreateInputAclRemoveItem(TypedDict, total=False): 'The kind of principal to remove. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' +class ArtifactCreateInputAclRemoveDeniesItem(TypedDict, total=False): + principal: str | None + 'The identifier of the principal to remove. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`. Omit when `principal_type` is `"everyone"`.' + principal_type: Required[str] + 'The kind of principal to remove. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' + + class ArtifactCreateInputAcl(TypedDict, total=False): add: list[ArtifactCreateInputAclAddItem] | None "Patch mode: grants to add or merge into the existing list. Cannot be combined with `grants`." + add_denies: list[ArtifactCreateInputAclAddDeniesItem] | None + "Patch mode: denies to add or merge, replacing any grant for the same principal." + denies: list[ArtifactCreateInputAclDeniesItem] | None + "Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support." grants: list[ArtifactCreateInputAclGrantsItem] | None "Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`." + preserve_denies: bool | None + "Retain current server denies atomically in replacement or patch mode; current denies win." remove: list[ArtifactCreateInputAclRemoveItem] | None "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`." + remove_denies: list[ArtifactCreateInputAclRemoveDeniesItem] | None + "Patch mode: principals whose denies should be removed." class ArtifactCreateInputFile(TypedDict, total=False): @@ -95,6 +128,24 @@ class ArtifactReplaceInputAclAddItem(TypedDict, total=False): 'The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' +class ArtifactReplaceInputAclAddDeniesItem(TypedDict, total=False): + actions: Required[list[str]] + 'Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.' + principal: str | None + 'The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.' + principal_type: Required[str] + 'The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' + + +class ArtifactReplaceInputAclDeniesItem(TypedDict, total=False): + actions: Required[list[str]] + 'Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.' + principal: str | None + 'The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.' + principal_type: Required[str] + 'The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' + + class ArtifactReplaceInputAclGrantsItem(TypedDict, total=False): actions: Required[list[str]] 'Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.' @@ -111,13 +162,28 @@ class ArtifactReplaceInputAclRemoveItem(TypedDict, total=False): 'The kind of principal to remove. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' +class ArtifactReplaceInputAclRemoveDeniesItem(TypedDict, total=False): + principal: str | None + 'The identifier of the principal to remove. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`. Omit when `principal_type` is `"everyone"`.' + principal_type: Required[str] + 'The kind of principal to remove. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' + + class ArtifactReplaceInputAcl(TypedDict, total=False): add: list[ArtifactReplaceInputAclAddItem] | None "Patch mode: grants to add or merge into the existing list. Cannot be combined with `grants`." + add_denies: list[ArtifactReplaceInputAclAddDeniesItem] | None + "Patch mode: denies to add or merge, replacing any grant for the same principal." + denies: list[ArtifactReplaceInputAclDeniesItem] | None + "Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support." grants: list[ArtifactReplaceInputAclGrantsItem] | None "Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`." + preserve_denies: bool | None + "Retain current server denies atomically in replacement or patch mode; current denies win." remove: list[ArtifactReplaceInputAclRemoveItem] | None "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`." + remove_denies: list[ArtifactReplaceInputAclRemoveDeniesItem] | None + "Patch mode: principals whose denies should be removed." class ArtifactReplaceInputFile(TypedDict, total=False): diff --git a/src/archastro/platform/v1/resources/automation_runs.py b/src/archastro/platform/v1/resources/automation_runs.py index 7c2d455..d09cdd5 100644 --- a/src/archastro/platform/v1/resources/automation_runs.py +++ b/src/archastro/platform/v1/resources/automation_runs.py @@ -1,6 +1,6 @@ # Copyright (c) 2026 ArchAstro Inc. Licensed under the MIT License. # This file is auto-generated by @archastro/sdk-generator. Do not edit. -# Content hash: ee08edaaa3bf +# Content hash: 00cedd96f4b2 from __future__ import annotations @@ -24,7 +24,9 @@ class AsyncAutomationRunResource: def __init__(self, http: HttpClient): self._http = http - async def get(self, automation_run: str) -> AutomationRun: + async def get( + self, automation_run: str, *, include_payload: bool | None = None + ) -> AutomationRun: """ Retrieve an automation run Returns a single automation run by ID. @@ -37,12 +39,17 @@ async def get(self, automation_run: str) -> AutomationRun: Args: automation_run: Automation run ID (`arun_...`). + include_payload: Include payload and result. Set to false for a lightweight status response. Returns: - The requested automation run. + The requested automation run; payload and result are omitted when include_payload is false. """ + query: dict[str, object] = {} + if include_payload is not None: + query["include_payload"] = include_payload return await self._http.request( f"/api/v1/automation_runs/{automation_run}", + query=query, response_type=AutomationRun, ) @@ -102,7 +109,7 @@ class AutomationRunResource: def __init__(self, http: SyncHttpClient): self._http = http - def get(self, automation_run: str) -> AutomationRun: + def get(self, automation_run: str, *, include_payload: bool | None = None) -> AutomationRun: """ Retrieve an automation run Returns a single automation run by ID. @@ -115,12 +122,17 @@ def get(self, automation_run: str) -> AutomationRun: Args: automation_run: Automation run ID (`arun_...`). + include_payload: Include payload and result. Set to false for a lightweight status response. Returns: - The requested automation run. + The requested automation run; payload and result are omitted when include_payload is false. """ + query: dict[str, object] = {} + if include_payload is not None: + query["include_payload"] = include_payload return self._http.request( f"/api/v1/automation_runs/{automation_run}", + query=query, response_type=AutomationRun, ) diff --git a/src/archastro/platform/v1/resources/computers.py b/src/archastro/platform/v1/resources/computers.py new file mode 100644 index 0000000..74e6bbb --- /dev/null +++ b/src/archastro/platform/v1/resources/computers.py @@ -0,0 +1,385 @@ +# Copyright (c) 2026 ArchAstro Inc. Licensed under the MIT License. +# This file is auto-generated by @archastro/sdk-generator. Do not edit. +# Content hash: dae953ca4831 + +from __future__ import annotations + +from typing import Any, Required, TypedDict + +from ...runtime.http_client import HttpClient, SyncHttpClient +from ...types.common import AgentComputer, AgentComputerListResponse +from ...types.computers import ComputerExecResult + + +class ComputerCreateInputRepositoriesItem(TypedDict, total=False): + ref: str | None + "Optional checkout ref; null selects the repository's default branch." + repository: Required[str] + "GitHub owner/name; supported GitHub URLs are normalized on creation." + + +class ComputerCreateInput(TypedDict, total=False): + "Create a computer" + + key: str | None + "Stable key unique among your computers." + metadata: dict[str, Any] | None + "Arbitrary computer metadata." + name: Required[str] + "Human-readable computer name." + provider: str | None + "Compute backend: devbox (default), sprites, vercel, or e2b." + region: str | None + "Provider region." + repositories: list[ComputerCreateInputRepositoriesItem] | None + "Ordered GitHub checkouts (maximum 16): {repository: owner/name, ref: optional ref}. First is primary." + setup_bundle: str | None + "Base64 tar.gz repository setup bundle (maximum 512 KiB)." + + +class ComputerExecInput(TypedDict, total=False): + "Run a command on your computer" + + command: Required[str] + "Shell command to execute." + timeout_seconds: int | None + "Command timeout in seconds. Defaults to 60; at most 300." + working_directory: str | None + "Absolute working directory. Defaults to the computer's home directory." + + +class ComputerSetupInput(TypedDict, total=False): + "Run repository setup" + + force: bool | None + "Run again even when commit and bundle are unchanged." + setup_bundle: str | None + "Replacement base64 tar.gz setup bundle." + + +class AsyncComputerResource: + def __init__(self, http: HttpClient): + self._http = http + + async def list(self) -> AgentComputerListResponse: + """ + List your computers + Returns the authenticated user's live computers, oldest first, without pagination. Thread and agent computers are not included. Requires the `devbox_access` entitlement. + + Returns: + The user's live computers. + """ + return await self._http.request( + "/api/v1/computers", + response_type=AgentComputerListResponse, + ) + + async def create(self, input: ComputerCreateInput) -> AgentComputer: + """ + Create a computer + Provisions a computer owned by the authenticated user. Only that user can see or use it. Requires the `devbox_access` entitlement. + + Args: + input: Request body. + input.key: Stable key unique among your computers. + input.metadata: Arbitrary computer metadata. + input.name: Human-readable computer name. + input.provider: Compute backend: devbox (default), sprites, vercel, or e2b. + input.region: Provider region. + input.repositories: Ordered GitHub checkouts (maximum 16): {repository: owner/name, ref: optional ref}. First is primary. + input.setup_bundle: Base64 tar.gz repository setup bundle (maximum 512 KiB). + + Returns: + The newly created computer. Returns HTTP 201. + """ + return await self._http.request( + "/api/v1/computers", + method="POST", + body=input, + response_type=AgentComputer, + ) + + async def delete(self, computer: str) -> None: + """ + Delete your computer + Destroys one of the authenticated user's computers and releases its infrastructure. Irreversible. Requires the `devbox_access` entitlement. + + Args: + computer: Computer ID (`cmp_...`). + + Returns: + Empty response body. Returns HTTP 204 on success. + """ + await self._http.request(f"/api/v1/computers/{computer}", method="DELETE") + + async def get(self, computer: str) -> AgentComputer: + """ + Retrieve a computer + Returns a computer the caller can see: their own, a team or agent computer + visible to them, or a computer of a thread they can see. A computer the caller + cannot see is reported as not found. + For a `ready` or `paused` computer whose provider can pause, `status` is + checked against the provider first, so a computer that paused while idle is + returned as `paused`. + + Args: + computer: Computer ID (`cmp_...`). + + Returns: + The requested computer. + """ + return await self._http.request( + f"/api/v1/computers/{computer}", + response_type=AgentComputer, + ) + + async def exec(self, computer: str, input: ComputerExecInput) -> ComputerExecResult: + """ + Run a command on your computer + Runs a shell command on one of the authenticated user's computers and returns + its combined output and exit code. The computer must be `ready`; otherwise the + endpoint returns 409 `computer_not_ready`. A non-zero `exit_code` is not an + HTTP error. Requires the `devbox_access` entitlement. + + Args: + computer: Computer ID (`cmp_...`). + input: Request body. + input.command: Shell command to execute. + input.timeout_seconds: Command timeout in seconds. Defaults to 60; at most 300. + input.working_directory: Absolute working directory. Defaults to the computer's home directory. + + Returns: + The output and exit code produced by the command. + """ + return await self._http.request( + f"/api/v1/computers/{computer}/exec", + method="POST", + body=input, + response_type=ComputerExecResult, + ) + + async def pause(self, computer: str) -> AgentComputer: + """ + Pause a computer + Powers a computer down while keeping its disk, and returns it with status + `paused`. The next command run on it resumes it. Works for any computer the + caller can manage: their own, a team computer they administer, an agent's + computer they manage, or a computer of a thread they manage. Pausing a paused + computer succeeds. + Returns 403 when the caller can see the computer but not manage it, 409 when + it is neither `ready` nor `paused`, and 422 `unsupported` when its provider + cannot pause. + + Args: + computer: Computer ID (`cmp_...`). + + Returns: + The computer in its `"paused"` state. + """ + return await self._http.request( + f"/api/v1/computers/{computer}/pause", + method="POST", + response_type=AgentComputer, + ) + + async def resume(self, computer: str) -> AgentComputer: + """ + Resume a computer + Starts a paused computer from its kept disk and returns it with status + `ready`. Authorized like pause: any computer the caller can manage. Resuming a + running computer succeeds. + Returns 403 when the caller can see the computer but not manage it, 409 when + it is neither `ready` nor `paused`, and 422 `unsupported` when its provider + cannot pause or resume. + + Args: + computer: Computer ID (`cmp_...`). + + Returns: + The computer in its `"ready"` state. + """ + return await self._http.request( + f"/api/v1/computers/{computer}/resume", + method="POST", + response_type=AgentComputer, + ) + + async def setup(self, computer: str, input: ComputerSetupInput) -> AgentComputer: + """ + Run repository setup + + Args: + input: Request body. + input.force: Run again even when commit and bundle are unchanged. + input.setup_bundle: Replacement base64 tar.gz setup bundle. + + Returns: + Successful response + """ + return await self._http.request( + f"/api/v1/computers/{computer}/setup", + method="POST", + body=input, + response_type=AgentComputer, + ) + + +class ComputerResource: + def __init__(self, http: SyncHttpClient): + self._http = http + + def list(self) -> AgentComputerListResponse: + """ + List your computers + Returns the authenticated user's live computers, oldest first, without pagination. Thread and agent computers are not included. Requires the `devbox_access` entitlement. + + Returns: + The user's live computers. + """ + return self._http.request("/api/v1/computers", response_type=AgentComputerListResponse) + + def create(self, input: ComputerCreateInput) -> AgentComputer: + """ + Create a computer + Provisions a computer owned by the authenticated user. Only that user can see or use it. Requires the `devbox_access` entitlement. + + Args: + input: Request body. + input.key: Stable key unique among your computers. + input.metadata: Arbitrary computer metadata. + input.name: Human-readable computer name. + input.provider: Compute backend: devbox (default), sprites, vercel, or e2b. + input.region: Provider region. + input.repositories: Ordered GitHub checkouts (maximum 16): {repository: owner/name, ref: optional ref}. First is primary. + input.setup_bundle: Base64 tar.gz repository setup bundle (maximum 512 KiB). + + Returns: + The newly created computer. Returns HTTP 201. + """ + return self._http.request( + "/api/v1/computers", + method="POST", + body=input, + response_type=AgentComputer, + ) + + def delete(self, computer: str) -> None: + """ + Delete your computer + Destroys one of the authenticated user's computers and releases its infrastructure. Irreversible. Requires the `devbox_access` entitlement. + + Args: + computer: Computer ID (`cmp_...`). + + Returns: + Empty response body. Returns HTTP 204 on success. + """ + self._http.request(f"/api/v1/computers/{computer}", method="DELETE") + + def get(self, computer: str) -> AgentComputer: + """ + Retrieve a computer + Returns a computer the caller can see: their own, a team or agent computer + visible to them, or a computer of a thread they can see. A computer the caller + cannot see is reported as not found. + For a `ready` or `paused` computer whose provider can pause, `status` is + checked against the provider first, so a computer that paused while idle is + returned as `paused`. + + Args: + computer: Computer ID (`cmp_...`). + + Returns: + The requested computer. + """ + return self._http.request(f"/api/v1/computers/{computer}", response_type=AgentComputer) + + def exec(self, computer: str, input: ComputerExecInput) -> ComputerExecResult: + """ + Run a command on your computer + Runs a shell command on one of the authenticated user's computers and returns + its combined output and exit code. The computer must be `ready`; otherwise the + endpoint returns 409 `computer_not_ready`. A non-zero `exit_code` is not an + HTTP error. Requires the `devbox_access` entitlement. + + Args: + computer: Computer ID (`cmp_...`). + input: Request body. + input.command: Shell command to execute. + input.timeout_seconds: Command timeout in seconds. Defaults to 60; at most 300. + input.working_directory: Absolute working directory. Defaults to the computer's home directory. + + Returns: + The output and exit code produced by the command. + """ + return self._http.request( + f"/api/v1/computers/{computer}/exec", + method="POST", + body=input, + response_type=ComputerExecResult, + ) + + def pause(self, computer: str) -> AgentComputer: + """ + Pause a computer + Powers a computer down while keeping its disk, and returns it with status + `paused`. The next command run on it resumes it. Works for any computer the + caller can manage: their own, a team computer they administer, an agent's + computer they manage, or a computer of a thread they manage. Pausing a paused + computer succeeds. + Returns 403 when the caller can see the computer but not manage it, 409 when + it is neither `ready` nor `paused`, and 422 `unsupported` when its provider + cannot pause. + + Args: + computer: Computer ID (`cmp_...`). + + Returns: + The computer in its `"paused"` state. + """ + return self._http.request( + f"/api/v1/computers/{computer}/pause", + method="POST", + response_type=AgentComputer, + ) + + def resume(self, computer: str) -> AgentComputer: + """ + Resume a computer + Starts a paused computer from its kept disk and returns it with status + `ready`. Authorized like pause: any computer the caller can manage. Resuming a + running computer succeeds. + Returns 403 when the caller can see the computer but not manage it, 409 when + it is neither `ready` nor `paused`, and 422 `unsupported` when its provider + cannot pause or resume. + + Args: + computer: Computer ID (`cmp_...`). + + Returns: + The computer in its `"ready"` state. + """ + return self._http.request( + f"/api/v1/computers/{computer}/resume", + method="POST", + response_type=AgentComputer, + ) + + def setup(self, computer: str, input: ComputerSetupInput) -> AgentComputer: + """ + Run repository setup + + Args: + input: Request body. + input.force: Run again even when commit and bundle are unchanged. + input.setup_bundle: Replacement base64 tar.gz setup bundle. + + Returns: + Successful response + """ + return self._http.request( + f"/api/v1/computers/{computer}/setup", + method="POST", + body=input, + response_type=AgentComputer, + ) diff --git a/src/archastro/platform/v1/resources/custom_objects.py b/src/archastro/platform/v1/resources/custom_objects.py index ef65731..ab1ef86 100644 --- a/src/archastro/platform/v1/resources/custom_objects.py +++ b/src/archastro/platform/v1/resources/custom_objects.py @@ -1,6 +1,6 @@ # Copyright (c) 2026 ArchAstro Inc. Licensed under the MIT License. # This file is auto-generated by @archastro/sdk-generator. Do not edit. -# Content hash: ff8413024cce +# Content hash: fe52fd93ea41 from __future__ import annotations @@ -23,6 +23,24 @@ class CustomObjectCreateInputAclAddItem(TypedDict, total=False): 'The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' +class CustomObjectCreateInputAclAddDeniesItem(TypedDict, total=False): + actions: Required[list[str]] + 'Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.' + principal: str | None + 'The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.' + principal_type: Required[str] + 'The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' + + +class CustomObjectCreateInputAclDeniesItem(TypedDict, total=False): + actions: Required[list[str]] + 'Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.' + principal: str | None + 'The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.' + principal_type: Required[str] + 'The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' + + class CustomObjectCreateInputAclGrantsItem(TypedDict, total=False): actions: Required[list[str]] 'Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.' @@ -39,13 +57,28 @@ class CustomObjectCreateInputAclRemoveItem(TypedDict, total=False): 'The kind of principal to remove. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' +class CustomObjectCreateInputAclRemoveDeniesItem(TypedDict, total=False): + principal: str | None + 'The identifier of the principal to remove. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`. Omit when `principal_type` is `"everyone"`.' + principal_type: Required[str] + 'The kind of principal to remove. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' + + class CustomObjectCreateInputAcl(TypedDict, total=False): add: list[CustomObjectCreateInputAclAddItem] | None "Patch mode: grants to add or merge into the existing list. Cannot be combined with `grants`." + add_denies: list[CustomObjectCreateInputAclAddDeniesItem] | None + "Patch mode: denies to add or merge, replacing any grant for the same principal." + denies: list[CustomObjectCreateInputAclDeniesItem] | None + "Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support." grants: list[CustomObjectCreateInputAclGrantsItem] | None "Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`." + preserve_denies: bool | None + "Retain current server denies atomically in replacement or patch mode; current denies win." remove: list[CustomObjectCreateInputAclRemoveItem] | None "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`." + remove_denies: list[CustomObjectCreateInputAclRemoveDeniesItem] | None + "Patch mode: principals whose denies should be removed." class CustomObjectCreateInput(TypedDict, total=False): @@ -111,6 +144,24 @@ class CustomObjectReplaceInputAclAddItem(TypedDict, total=False): 'The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' +class CustomObjectReplaceInputAclAddDeniesItem(TypedDict, total=False): + actions: Required[list[str]] + 'Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.' + principal: str | None + 'The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.' + principal_type: Required[str] + 'The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' + + +class CustomObjectReplaceInputAclDeniesItem(TypedDict, total=False): + actions: Required[list[str]] + 'Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.' + principal: str | None + 'The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.' + principal_type: Required[str] + 'The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' + + class CustomObjectReplaceInputAclGrantsItem(TypedDict, total=False): actions: Required[list[str]] 'Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.' @@ -127,13 +178,28 @@ class CustomObjectReplaceInputAclRemoveItem(TypedDict, total=False): 'The kind of principal to remove. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' +class CustomObjectReplaceInputAclRemoveDeniesItem(TypedDict, total=False): + principal: str | None + 'The identifier of the principal to remove. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`. Omit when `principal_type` is `"everyone"`.' + principal_type: Required[str] + 'The kind of principal to remove. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' + + class CustomObjectReplaceInputAcl(TypedDict, total=False): add: list[CustomObjectReplaceInputAclAddItem] | None "Patch mode: grants to add or merge into the existing list. Cannot be combined with `grants`." + add_denies: list[CustomObjectReplaceInputAclAddDeniesItem] | None + "Patch mode: denies to add or merge, replacing any grant for the same principal." + denies: list[CustomObjectReplaceInputAclDeniesItem] | None + "Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support." grants: list[CustomObjectReplaceInputAclGrantsItem] | None "Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`." + preserve_denies: bool | None + "Retain current server denies atomically in replacement or patch mode; current denies win." remove: list[CustomObjectReplaceInputAclRemoveItem] | None "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`." + remove_denies: list[CustomObjectReplaceInputAclRemoveDeniesItem] | None + "Patch mode: principals whose denies should be removed." class CustomObjectReplaceInput(TypedDict, total=False): @@ -170,6 +236,36 @@ class CustomObjectPatchResponseDataAclAddItem(BaseModel): ) +class CustomObjectPatchResponseDataAclAddDeniesItem(BaseModel): + actions: list[str] = Field( + ..., + description='Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.', + ) + principal: str | None = Field( + default=None, + description='The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.', + ) + principal_type: str = Field( + ..., + description='The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.', + ) + + +class CustomObjectPatchResponseDataAclDeniesItem(BaseModel): + actions: list[str] = Field( + ..., + description='Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.', + ) + principal: str | None = Field( + default=None, + description='The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.', + ) + principal_type: str = Field( + ..., + description='The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.', + ) + + class CustomObjectPatchResponseDataAclGrantsItem(BaseModel): actions: list[str] = Field( ..., @@ -196,19 +292,45 @@ class CustomObjectPatchResponseDataAclRemoveItem(BaseModel): ) +class CustomObjectPatchResponseDataAclRemoveDeniesItem(BaseModel): + principal: str | None = Field( + default=None, + description='The identifier of the principal to remove. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`. Omit when `principal_type` is `"everyone"`.', + ) + principal_type: str = Field( + ..., + description='The kind of principal to remove. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.', + ) + + class CustomObjectPatchResponseDataAcl(BaseModel): add: list[CustomObjectPatchResponseDataAclAddItem] | None = Field( default=None, description="Patch mode: grants to add or merge into the existing list. Cannot be combined with `grants`.", ) + add_denies: list[CustomObjectPatchResponseDataAclAddDeniesItem] | None = Field( + default=None, + description="Patch mode: denies to add or merge, replacing any grant for the same principal.", + ) + denies: list[CustomObjectPatchResponseDataAclDeniesItem] | None = Field( + default=None, + description="Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support.", + ) grants: list[CustomObjectPatchResponseDataAclGrantsItem] | None = Field( default=None, description="Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", ) + preserve_denies: bool | None = Field( + default=None, + description="Retain current server denies atomically in replacement or patch mode; current denies win.", + ) remove: list[CustomObjectPatchResponseDataAclRemoveItem] | None = Field( default=None, description="Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", ) + remove_denies: list[CustomObjectPatchResponseDataAclRemoveDeniesItem] | None = Field( + default=None, description="Patch mode: principals whose denies should be removed." + ) class CustomObjectPatchResponseData(BaseModel): @@ -301,6 +423,36 @@ class CustomObjectReplaceResponseDataAclAddItem(BaseModel): ) +class CustomObjectReplaceResponseDataAclAddDeniesItem(BaseModel): + actions: list[str] = Field( + ..., + description='Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.', + ) + principal: str | None = Field( + default=None, + description='The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.', + ) + principal_type: str = Field( + ..., + description='The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.', + ) + + +class CustomObjectReplaceResponseDataAclDeniesItem(BaseModel): + actions: list[str] = Field( + ..., + description='Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.', + ) + principal: str | None = Field( + default=None, + description='The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.', + ) + principal_type: str = Field( + ..., + description='The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.', + ) + + class CustomObjectReplaceResponseDataAclGrantsItem(BaseModel): actions: list[str] = Field( ..., @@ -327,19 +479,45 @@ class CustomObjectReplaceResponseDataAclRemoveItem(BaseModel): ) +class CustomObjectReplaceResponseDataAclRemoveDeniesItem(BaseModel): + principal: str | None = Field( + default=None, + description='The identifier of the principal to remove. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`. Omit when `principal_type` is `"everyone"`.', + ) + principal_type: str = Field( + ..., + description='The kind of principal to remove. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.', + ) + + class CustomObjectReplaceResponseDataAcl(BaseModel): add: list[CustomObjectReplaceResponseDataAclAddItem] | None = Field( default=None, description="Patch mode: grants to add or merge into the existing list. Cannot be combined with `grants`.", ) + add_denies: list[CustomObjectReplaceResponseDataAclAddDeniesItem] | None = Field( + default=None, + description="Patch mode: denies to add or merge, replacing any grant for the same principal.", + ) + denies: list[CustomObjectReplaceResponseDataAclDeniesItem] | None = Field( + default=None, + description="Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support.", + ) grants: list[CustomObjectReplaceResponseDataAclGrantsItem] | None = Field( default=None, description="Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", ) + preserve_denies: bool | None = Field( + default=None, + description="Retain current server denies atomically in replacement or patch mode; current denies win.", + ) remove: list[CustomObjectReplaceResponseDataAclRemoveItem] | None = Field( default=None, description="Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", ) + remove_denies: list[CustomObjectReplaceResponseDataAclRemoveDeniesItem] | None = Field( + default=None, description="Patch mode: principals whose denies should be removed." + ) class CustomObjectReplaceResponseData(BaseModel): diff --git a/src/archastro/platform/v1/resources/files.py b/src/archastro/platform/v1/resources/files.py index d3031f1..0c53e5b 100644 --- a/src/archastro/platform/v1/resources/files.py +++ b/src/archastro/platform/v1/resources/files.py @@ -1,6 +1,6 @@ # Copyright (c) 2026 ArchAstro Inc. Licensed under the MIT License. # This file is auto-generated by @archastro/sdk-generator. Do not edit. -# Content hash: eefe9c7e925d +# Content hash: 56cdb79f69d4 from __future__ import annotations @@ -19,6 +19,24 @@ class FileCreateInputAclAddItem(TypedDict, total=False): 'The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' +class FileCreateInputAclAddDeniesItem(TypedDict, total=False): + actions: Required[list[str]] + 'Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.' + principal: str | None + 'The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.' + principal_type: Required[str] + 'The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' + + +class FileCreateInputAclDeniesItem(TypedDict, total=False): + actions: Required[list[str]] + 'Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.' + principal: str | None + 'The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.' + principal_type: Required[str] + 'The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' + + class FileCreateInputAclGrantsItem(TypedDict, total=False): actions: Required[list[str]] 'Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.' @@ -35,13 +53,28 @@ class FileCreateInputAclRemoveItem(TypedDict, total=False): 'The kind of principal to remove. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' +class FileCreateInputAclRemoveDeniesItem(TypedDict, total=False): + principal: str | None + 'The identifier of the principal to remove. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`. Omit when `principal_type` is `"everyone"`.' + principal_type: Required[str] + 'The kind of principal to remove. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' + + class FileCreateInputAcl(TypedDict, total=False): add: list[FileCreateInputAclAddItem] | None "Patch mode: grants to add or merge into the existing list. Cannot be combined with `grants`." + add_denies: list[FileCreateInputAclAddDeniesItem] | None + "Patch mode: denies to add or merge, replacing any grant for the same principal." + denies: list[FileCreateInputAclDeniesItem] | None + "Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support." grants: list[FileCreateInputAclGrantsItem] | None "Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`." + preserve_denies: bool | None + "Retain current server denies atomically in replacement or patch mode; current denies win." remove: list[FileCreateInputAclRemoveItem] | None "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`." + remove_denies: list[FileCreateInputAclRemoveDeniesItem] | None + "Patch mode: principals whose denies should be removed." class FileCreateInput(TypedDict, total=False): @@ -51,6 +84,8 @@ class FileCreateInput(TypedDict, total=False): "Access control list for the file. Supports explicit `read` and `write` grants to users, teams, organizations, organization roles, agents, or everyone." agent: str | None "Agent ID (`agi_...`) to associate with this file. When provided, the file's organization is derived from the agent." + artifact: str | None + "Artifact whose current readers may download this attachment. Requires write access; cannot be publicly shared." content_type: Required[str] 'MIME type of the file, e.g. `"image/png"` or `"application/pdf"`.' data: Required[str] @@ -59,6 +94,8 @@ class FileCreateInput(TypedDict, total=False): 'Original filename including extension, e.g. `"avatar.png"`.' org: str | None "Organization ID (`org_...`) to associate with this file. Optional; defaults to the viewer's organization when omitted." + plan_image: bool | None + "Opt in to plan-image validation: PNG, JPEG, GIF or WebP up to 10,000,000 decoded bytes. Pass as a query parameter to enable the larger request budget." share: bool | None "When `true`, marks the file publicly shareable and returns a stable, non-expiring `share_url` fetchable without authentication. Only image content types can be shared." team: str | None @@ -95,6 +132,11 @@ async def create(self, input: FileCreateInput) -> StorageFile: budget at most `3 * floor((8,000,000 - E) / 4)` binary bytes: less than 6,000,000 bytes (about 5.72 MiB). Do not rely on parser chunk overshoot. Oversized JSON requests are rejected with HTTP 413 before upload processing. + Plan editors may opt in with `?plan_image=true`. This route/mode permits a + 13,398,872-byte JSON envelope (base64 for 10,000,000 decoded bytes plus 64 KiB + metadata). Plan images must declare PNG, JPEG, GIF or WebP MIME types and + contain at most 10,000,000 decoded bytes. Other uploads retain the default + parser budget and arbitrary content types. App scope is derived from the authenticated viewer's bearer token or publishable key. You may optionally associate the file with an organization, team, user, or agent by passing the corresponding ID. If no owner is specified and the viewer is a user, the @@ -115,10 +157,12 @@ async def create(self, input: FileCreateInput) -> StorageFile: input: Request body. input.acl: Access control list for the file. Supports explicit `read` and `write` grants to users, teams, organizations, organization roles, agents, or everyone. input.agent: Agent ID (`agi_...`) to associate with this file. When provided, the file's organization is derived from the agent. + input.artifact: Artifact whose current readers may download this attachment. Requires write access; cannot be publicly shared. input.content_type: MIME type of the file, e.g. `"image/png"` or `"application/pdf"`. input.data: Base64-encoded binary content of the file to upload. input.filename: Original filename including extension, e.g. `"avatar.png"`. input.org: Organization ID (`org_...`) to associate with this file. Optional; defaults to the viewer's organization when omitted. + input.plan_image: Opt in to plan-image validation: PNG, JPEG, GIF or WebP up to 10,000,000 decoded bytes. Pass as a query parameter to enable the larger request budget. input.share: When `true`, marks the file publicly shareable and returns a stable, non-expiring `share_url` fetchable without authentication. Only image content types can be shared. input.team: Team ID (`tem_...`) that owns this file. Takes precedence over `user` when both are provided. input.user: User ID (`usr_...`) that owns this file. Defaults to the authenticated user when neither `user` nor `team` is specified. @@ -292,6 +336,11 @@ def create(self, input: FileCreateInput) -> StorageFile: budget at most `3 * floor((8,000,000 - E) / 4)` binary bytes: less than 6,000,000 bytes (about 5.72 MiB). Do not rely on parser chunk overshoot. Oversized JSON requests are rejected with HTTP 413 before upload processing. + Plan editors may opt in with `?plan_image=true`. This route/mode permits a + 13,398,872-byte JSON envelope (base64 for 10,000,000 decoded bytes plus 64 KiB + metadata). Plan images must declare PNG, JPEG, GIF or WebP MIME types and + contain at most 10,000,000 decoded bytes. Other uploads retain the default + parser budget and arbitrary content types. App scope is derived from the authenticated viewer's bearer token or publishable key. You may optionally associate the file with an organization, team, user, or agent by passing the corresponding ID. If no owner is specified and the viewer is a user, the @@ -312,10 +361,12 @@ def create(self, input: FileCreateInput) -> StorageFile: input: Request body. input.acl: Access control list for the file. Supports explicit `read` and `write` grants to users, teams, organizations, organization roles, agents, or everyone. input.agent: Agent ID (`agi_...`) to associate with this file. When provided, the file's organization is derived from the agent. + input.artifact: Artifact whose current readers may download this attachment. Requires write access; cannot be publicly shared. input.content_type: MIME type of the file, e.g. `"image/png"` or `"application/pdf"`. input.data: Base64-encoded binary content of the file to upload. input.filename: Original filename including extension, e.g. `"avatar.png"`. input.org: Organization ID (`org_...`) to associate with this file. Optional; defaults to the viewer's organization when omitted. + input.plan_image: Opt in to plan-image validation: PNG, JPEG, GIF or WebP up to 10,000,000 decoded bytes. Pass as a query parameter to enable the larger request budget. input.share: When `true`, marks the file publicly shareable and returns a stable, non-expiring `share_url` fetchable without authentication. Only image content types can be shared. input.team: Team ID (`tem_...`) that owns this file. Takes precedence over `user` when both are provided. input.user: User ID (`usr_...`) that owns this file. Defaults to the authenticated user when neither `user` nor `team` is specified. diff --git a/src/archastro/platform/v1/resources/orgs.py b/src/archastro/platform/v1/resources/orgs.py index b446584..3fa77bd 100644 --- a/src/archastro/platform/v1/resources/orgs.py +++ b/src/archastro/platform/v1/resources/orgs.py @@ -1,27 +1,52 @@ # Copyright (c) 2026 ArchAstro Inc. Licensed under the MIT License. # This file is auto-generated by @archastro/sdk-generator. Do not edit. -# Content hash: e193124aa024 +# Content hash: 7b08f0532f81 from __future__ import annotations import builtins +from collections.abc import AsyncIterator, Iterator from datetime import datetime -from typing import Any, Literal, Required, TypedDict +from typing import ( + Any, + Literal, + Required, + TypedDict, +) from pydantic import BaseModel, Field from ...runtime.http_client import HttpClient, SyncHttpClient -from ...types.tasks import Task, TaskEnsureResult +from ...types.tasks import ( + Task, + TaskDeletion, + TaskEnsureResult, + TaskEpicEntity, + TaskEpicEntityCollection, +) from ...types.threads import Thread +class OrgTaskEpicCreateInput(TypedDict, total=False): + "Create an organization task Epic" + + description: str | None + metadata: dict[str, Any] | None + name: Required[str] + state: str | None + + class OrgTaskCreateInputTask(TypedDict, total=False): + blockers: list[str] | None + "Existing task IDs (`tsk_...`) that block this task. Recorded atomically with creation; the task is not ready until these blockers are done." description: str | None "Optional long-form description or notes for the task. Supports plain text." due_date: datetime | None "Date and time by which the task should be completed (ISO 8601). Omit to create the task without a due date." epic: str | None "Optional free-form grouping label." + epic_id: str | None + "First-class Epic ID (`epc_...`)." id: str | None "Optional caller-generated task public ID (`tsk_...`). Persist it before creating a task when creation must survive a lost response. An existing ID returns 409 without modifying the task; read the task by ID to reconcile. Omit for a server-generated ID." links: dict[str, Any] | None @@ -80,6 +105,8 @@ class OrgTaskBySourceInput(TypedDict, total=False): "Initial epic grouping." name: Required[str] "Initial task name." + owner_user: str | None + "Initial assigned user; immutable on retries." source_id: Required[str] "Source identity, for example owner/repo#123." source_scope: Required[str] @@ -274,6 +301,9 @@ class OrgTaskListResponseDataItem(BaseModel): default=None, description="Number of readable tasks marked as blocking this task, whether or not they are done (see `GET /tasks/{task}/blockers`). Computed on list/show reads; create/update responses may lag one read behind.", ) + blockers: list[str] | None = Field( + default=None, description="Visible blocker IDs when requested with include=blockers." + ) closed_at: datetime | None = Field( default=None, description="When the task was marked as done or otherwise closed (ISO 8601). `null` if the task is still open.", @@ -312,6 +342,10 @@ class OrgTaskListResponseDataItem(BaseModel): default=None, description="Free-form grouping label. `null` when the task is not in an epic.", ) + human_answer_receipts: dict[str, Any] | None = Field( + default=None, + description="Server-owned authenticated human answer intent, keyed by question version. Not infrastructure permission.", + ) id: str = Field(..., description="Task ID (`tsk_...`).") is_blocked: bool | None = Field( default=None, @@ -325,6 +359,10 @@ class OrgTaskListResponseDataItem(BaseModel): default=None, description="Key-value map of named URLs or references associated with the task. Returns an empty object when no links have been set.", ) + machine_rescope_receipts: dict[str, Any] | None = Field( + default=None, + description="Server-owned records of machine-applied local rescopes, keyed by question version. Never evidence that a human answered.", + ) metadata: dict[str, Any] | None = Field( default=None, description="Arbitrary key-value map of application-specific data stored alongside the task. Returns an empty object when no metadata has been set.", @@ -398,6 +436,9 @@ class OrgTaskListResponseDataItem(BaseModel): default=None, description="Minimum semantic version of `target_binary` that can run this work (for example `0.48.9`), in canonical `MAJOR.MINOR.PATCH[-prerelease][+build]` form. `null` when the task has no target.", ) + task_epic: str | None = Field( + default=None, description="First-class Epic membership; does not grant access to the task." + ) team: str | None = Field( default=None, description="ID of the team that owns this task (`tem_...`). `null` if the task is not scoped to a team.", @@ -551,6 +592,9 @@ class OrgTaskBlockerCyclesResponseDataItemTasksItem(BaseModel): default=None, description="Number of readable tasks marked as blocking this task, whether or not they are done (see `GET /tasks/{task}/blockers`). Computed on list/show reads; create/update responses may lag one read behind.", ) + blockers: list[str] | None = Field( + default=None, description="Visible blocker IDs when requested with include=blockers." + ) closed_at: datetime | None = Field( default=None, description="When the task was marked as done or otherwise closed (ISO 8601). `null` if the task is still open.", @@ -589,6 +633,10 @@ class OrgTaskBlockerCyclesResponseDataItemTasksItem(BaseModel): default=None, description="Free-form grouping label. `null` when the task is not in an epic.", ) + human_answer_receipts: dict[str, Any] | None = Field( + default=None, + description="Server-owned authenticated human answer intent, keyed by question version. Not infrastructure permission.", + ) id: str = Field(..., description="Task ID (`tsk_...`).") is_blocked: bool | None = Field( default=None, @@ -602,6 +650,10 @@ class OrgTaskBlockerCyclesResponseDataItemTasksItem(BaseModel): default=None, description="Key-value map of named URLs or references associated with the task. Returns an empty object when no links have been set.", ) + machine_rescope_receipts: dict[str, Any] | None = Field( + default=None, + description="Server-owned records of machine-applied local rescopes, keyed by question version. Never evidence that a human answered.", + ) metadata: dict[str, Any] | None = Field( default=None, description="Arbitrary key-value map of application-specific data stored alongside the task. Returns an empty object when no metadata has been set.", @@ -675,6 +727,9 @@ class OrgTaskBlockerCyclesResponseDataItemTasksItem(BaseModel): default=None, description="Minimum semantic version of `target_binary` that can run this work (for example `0.48.9`), in canonical `MAJOR.MINOR.PATCH[-prerelease][+build]` form. `null` when the task has no target.", ) + task_epic: str | None = Field( + default=None, description="First-class Epic membership; does not grant access to the task." + ) team: str | None = Field( default=None, description="ID of the team that owns this task (`tem_...`). `null` if the task is not scoped to a team.", @@ -709,6 +764,292 @@ class OrgTaskBlockerCyclesResponse(BaseModel): has_more: bool +class OrgTaskByExternalReferenceResponseDataItemCreatedByActorProfilePicture(BaseModel): + file: str | None = Field( + default=None, + description="ID of the underlying storage file (`fil_...`). `null` when the image is not backed by a platform storage file.", + ) + height: int | None = Field( + default=None, description="Height of the image in pixels. `null` if not known." + ) + media: str | None = Field( + default=None, + description="ID of the associated media record (`med_...`). `null` when the image is not linked to a media entity.", + ) + mime_type: str | None = Field( + default=None, + description='MIME type of the image, e.g. `"image/png"` or `"image/jpeg"`. `null` if not known.', + ) + refresh_url: str | None = Field( + default=None, + description="Endpoint URL you can call to obtain a fresh signed `url` when the current one has expired. `null` if the URL does not require refreshing.", + ) + url: str | None = Field( + default=None, + description="Signed or public URL for downloading the image. May be time-limited; use `refresh_url` to obtain a new URL when this one expires.", + ) + width: int | None = Field( + default=None, description="Width of the image in pixels. `null` if not known." + ) + + +class OrgTaskByExternalReferenceResponseDataItemCreatedByActor(BaseModel): + alias: str | None = Field( + default=None, + description="Short handle or alias for the actor, used as an alternate display identifier. `null` if not configured.", + ) + id: str | None = Field( + default=None, + description='Composite actor identifier. Format is `"user-"` for human users or `"agent-"` for agents.', + ) + name: str | None = Field( + default=None, + description="Display name of the actor shown in the UI. `null` if no name is set.", + ) + profile_picture: ( + OrgTaskByExternalReferenceResponseDataItemCreatedByActorProfilePicture | None + ) = Field( + default=None, + description="Profile picture for the actor. `null` if the actor has no profile picture.", + ) + + +class OrgTaskByExternalReferenceResponseDataItemCurrentLease(BaseModel): + expires_at: datetime = Field( + ..., description="Server-calculated lease expiry in ISO 8601 format." + ) + harness: str = Field(..., description="Bounded harness identifier for the coding session.") + session_name: str = Field( + ..., description="Display name supplied by the coding session that holds the lease." + ) + + +class OrgTaskByExternalReferenceResponseDataItemOwnerActorProfilePicture(BaseModel): + file: str | None = Field( + default=None, + description="ID of the underlying storage file (`fil_...`). `null` when the image is not backed by a platform storage file.", + ) + height: int | None = Field( + default=None, description="Height of the image in pixels. `null` if not known." + ) + media: str | None = Field( + default=None, + description="ID of the associated media record (`med_...`). `null` when the image is not linked to a media entity.", + ) + mime_type: str | None = Field( + default=None, + description='MIME type of the image, e.g. `"image/png"` or `"image/jpeg"`. `null` if not known.', + ) + refresh_url: str | None = Field( + default=None, + description="Endpoint URL you can call to obtain a fresh signed `url` when the current one has expired. `null` if the URL does not require refreshing.", + ) + url: str | None = Field( + default=None, + description="Signed or public URL for downloading the image. May be time-limited; use `refresh_url` to obtain a new URL when this one expires.", + ) + width: int | None = Field( + default=None, description="Width of the image in pixels. `null` if not known." + ) + + +class OrgTaskByExternalReferenceResponseDataItemOwnerActor(BaseModel): + alias: str | None = Field( + default=None, + description="Short handle or alias for the actor, used as an alternate display identifier. `null` if not configured.", + ) + id: str | None = Field( + default=None, + description='Composite actor identifier. Format is `"user-"` for human users or `"agent-"` for agents.', + ) + name: str | None = Field( + default=None, + description="Display name of the actor shown in the UI. `null` if no name is set.", + ) + profile_picture: OrgTaskByExternalReferenceResponseDataItemOwnerActorProfilePicture | None = ( + Field( + default=None, + description="Profile picture for the actor. `null` if the actor has no profile picture.", + ) + ) + + +class OrgTaskByExternalReferenceResponseDataItem(BaseModel): + agent: str | None = Field( + default=None, + description="ID of the agent that owns this task (`agi_...`). `null` if the task is scoped to a team or user.", + ) + aggregate_version: int | None = Field( + default=None, + description="Event-stream version for optimistic update fencing. Pass this value as `expected_version` on an update to reject concurrent writes.", + ) + blocked_by_count: int | None = Field( + default=None, + description="Number of readable tasks marked as blocking this task, whether or not they are done (see `GET /tasks/{task}/blockers`). Computed on list/show reads; create/update responses may lag one read behind.", + ) + blockers: list[str] | None = Field( + default=None, description="Visible blocker IDs when requested with include=blockers." + ) + closed_at: datetime | None = Field( + default=None, + description="When the task was marked as done or otherwise closed (ISO 8601). `null` if the task is still open.", + ) + comments_count: int | None = Field( + default=None, description="Total number of comments posted on this task." + ) + created_at: datetime | None = Field( + default=None, description="When the task was created (ISO 8601)." + ) + created_by_actor: OrgTaskByExternalReferenceResponseDataItemCreatedByActor | None = Field( + default=None, + description="Resolved creator details including `id`, `name`, `alias`, and `profile_picture`. `null` if no creator is set or the creator cannot be resolved (e.g. creating agent was deleted).", + ) + created_by_agent: str | None = Field( + default=None, + description="ID of the agent that created this task (`agi_...`). `null` if the task was created by a human user, or if the creating agent was later deleted.", + ) + created_by_user: str | None = Field( + default=None, + description="ID of the user who created this task (`usr_...`). `null` if the task was created by an agent, or if creator provenance was cleared after the creator was deleted.", + ) + current_lease: OrgTaskByExternalReferenceResponseDataItemCurrentLease | None = Field( + default=None, + description="Viewer-safe live coding-session lease summary. `null` when the task is unleased or the projected lease has expired. Fencing identifiers are never included.", + ) + description: str | None = Field( + default=None, + description="Long-form description or notes for the task. `null` if no description has been provided.", + ) + due_date: datetime | None = Field( + default=None, + description="Date and time by which the task should be completed (ISO 8601). `null` if no due date is set.", + ) + epic: str | None = Field( + default=None, + description="Free-form grouping label. `null` when the task is not in an epic.", + ) + human_answer_receipts: dict[str, Any] | None = Field( + default=None, + description="Server-owned authenticated human answer intent, keyed by question version. Not infrastructure permission.", + ) + id: str = Field(..., description="Task ID (`tsk_...`).") + is_blocked: bool | None = Field( + default=None, + description="`true` while at least one blocking task is not yet done. Informational only - a blocked task can still change status - and derived at read time, so the task un-blocks automatically when its last open blocker completes. Computed on reads, including mutation responses.", + ) + is_stalled: bool | None = Field( + default=None, + description="True exactly when status is in_progress and the task has no lease or its lease expiry is in the past. Derived at read time from status and lease expiry, including on unannotated reads.", + ) + links: dict[str, Any] | None = Field( + default=None, + description="Key-value map of named URLs or references associated with the task. Returns an empty object when no links have been set.", + ) + machine_rescope_receipts: dict[str, Any] | None = Field( + default=None, + description="Server-owned records of machine-applied local rescopes, keyed by question version. Never evidence that a human answered.", + ) + metadata: dict[str, Any] | None = Field( + default=None, + description="Arbitrary key-value map of application-specific data stored alongside the task. Returns an empty object when no metadata has been set.", + ) + name: str = Field(..., description="Human-readable title of the task.") + org: str | None = Field( + default=None, + description="ID of the organization this task belongs to (`org_...`). `null` for tasks outside an org context.", + ) + owner_actor: OrgTaskByExternalReferenceResponseDataItemOwnerActor | None = Field( + default=None, + description="Resolved owner details including `id`, `name`, `alias`, and `profile_picture`. `null` if the task is unassigned or the owner cannot be resolved (e.g. assigned agent was deleted).", + ) + owner_agent: str | None = Field( + default=None, + description="ID of the agent assigned as owner (`agi_...`). `null` if the owner is a human user, the task is unassigned, or the assigned agent was deleted.", + ) + owner_user: str | None = Field( + default=None, + description="ID of the user assigned as owner (`usr_...`). `null` if the owner is an agent, the task is unassigned, or the assigned agent was deleted.", + ) + parent: str | None = Field( + default=None, + description="ID of the parent task when this task is a subtask (`tsk_...`). `null` for top-level tasks or when the parent is not readable. Subtasks nest exactly one level.", + ) + priority: int | None = Field( + default=None, + description="Priority level of the task from `0` (highest) to `4` (lowest). Defaults to `2` (medium) when not explicitly set.", + ) + project_id: str | None = Field( + default=None, + description="Optional project ID (`prj_...`). Membership does not change task visibility.", + ) + sandbox: str | None = Field( + default=None, + description="ID of the developer sandbox this task is scoped to (`dsb_...`). `null` for tasks outside a sandbox environment.", + ) + source_id: str | None = Field( + default=None, + description="Source object identity (for example `ArchAstro/firstlanding`). `null` when the task has no source.", + ) + source_scope: str | None = Field( + default=None, + description="Container of the work this task is about (for example `github.com`). `null` when the task has no source. Set together with `source_type` and `source_id`.", + ) + source_type: str | None = Field( + default=None, + description="Kind of source object (for example `repository`). `null` when the task has no source.", + ) + stalled_since: datetime | None = Field( + default=None, + description="Lease expiry for a stalled task, or its last update when no lease expiry exists. Null when not stalled.", + ) + status: str = Field( + ..., + description='Current status of the task. One of `"open"`, `"in_progress"`, `"in_review"`, `"paused"`, `"failed"`, `"superseding"`, `"done"`, or `"cancelled"`.', + ) + subtasks_count: int | None = Field( + default=None, + description="Number of readable subtasks under this task. Computed on list/show reads; create/update responses may report 0 until the next read. Always 0 for subtasks.", + ) + tags: list[str] | None = Field( + default=None, + description="Labels for grouping and filtering, stored lowercase and de-duplicated. Empty array when untagged.", + ) + target_binary: str | None = Field( + default=None, + description="Binary that must run this work (for example `my-cli`). A worker should take the task only when its own `target_binary` build is at least `target_version`. `null` when the task has no target. Set together with `target_version`.", + ) + target_version: str | None = Field( + default=None, + description="Minimum semantic version of `target_binary` that can run this work (for example `0.48.9`), in canonical `MAJOR.MINOR.PATCH[-prerelease][+build]` form. `null` when the task has no target.", + ) + task_epic: str | None = Field( + default=None, description="First-class Epic membership; does not grant access to the task." + ) + team: str | None = Field( + default=None, + description="ID of the team that owns this task (`tem_...`). `null` if the task is not scoped to a team.", + ) + thread: str | None = Field( + default=None, + description="ID of the thread this task is bound to (`thr_...`) - the conversation it was filed from, or the thread passed at creation. `null` for tasks not tied to a thread.", + ) + updated_at: datetime | None = Field( + default=None, description="When the task was last modified (ISO 8601)." + ) + user: str | None = Field( + default=None, + description="ID of the user that owns this task (`usr_...`). `null` if the task is scoped to a team.", + ) + + +class OrgTaskByExternalReferenceResponse(BaseModel): + """ + Successful response + """ + + data: list[OrgTaskByExternalReferenceResponseDataItem] + + class OrgTaskMetricsResponse(BaseModel): """ Successful response @@ -845,6 +1186,9 @@ class OrgTaskReadyResponseDataItemTask(BaseModel): default=None, description="Number of readable tasks marked as blocking this task, whether or not they are done (see `GET /tasks/{task}/blockers`). Computed on list/show reads; create/update responses may lag one read behind.", ) + blockers: list[str] | None = Field( + default=None, description="Visible blocker IDs when requested with include=blockers." + ) closed_at: datetime | None = Field( default=None, description="When the task was marked as done or otherwise closed (ISO 8601). `null` if the task is still open.", @@ -883,6 +1227,10 @@ class OrgTaskReadyResponseDataItemTask(BaseModel): default=None, description="Free-form grouping label. `null` when the task is not in an epic.", ) + human_answer_receipts: dict[str, Any] | None = Field( + default=None, + description="Server-owned authenticated human answer intent, keyed by question version. Not infrastructure permission.", + ) id: str = Field(..., description="Task ID (`tsk_...`).") is_blocked: bool | None = Field( default=None, @@ -896,6 +1244,10 @@ class OrgTaskReadyResponseDataItemTask(BaseModel): default=None, description="Key-value map of named URLs or references associated with the task. Returns an empty object when no links have been set.", ) + machine_rescope_receipts: dict[str, Any] | None = Field( + default=None, + description="Server-owned records of machine-applied local rescopes, keyed by question version. Never evidence that a human answered.", + ) metadata: dict[str, Any] | None = Field( default=None, description="Arbitrary key-value map of application-specific data stored alongside the task. Returns an empty object when no metadata has been set.", @@ -969,6 +1321,9 @@ class OrgTaskReadyResponseDataItemTask(BaseModel): default=None, description="Minimum semantic version of `target_binary` that can run this work (for example `0.48.9`), in canonical `MAJOR.MINOR.PATCH[-prerelease][+build]` form. `null` when the task has no target.", ) + task_epic: str | None = Field( + default=None, description="First-class Epic membership; does not grant access to the task." + ) team: str | None = Field( default=None, description="ID of the team that owns this task (`tem_...`). `null` if the task is not scoped to a team.", @@ -1133,6 +1488,9 @@ class OrgTaskSearchResponseDataItem(BaseModel): default=None, description="Number of readable tasks marked as blocking this task, whether or not they are done (see `GET /tasks/{task}/blockers`). Computed on list/show reads; create/update responses may lag one read behind.", ) + blockers: list[str] | None = Field( + default=None, description="Visible blocker IDs when requested with include=blockers." + ) closed_at: datetime | None = Field( default=None, description="When the task was marked as done or otherwise closed (ISO 8601). `null` if the task is still open.", @@ -1171,6 +1529,10 @@ class OrgTaskSearchResponseDataItem(BaseModel): default=None, description="Free-form grouping label. `null` when the task is not in an epic.", ) + human_answer_receipts: dict[str, Any] | None = Field( + default=None, + description="Server-owned authenticated human answer intent, keyed by question version. Not infrastructure permission.", + ) id: str = Field(..., description="Task ID (`tsk_...`).") is_blocked: bool | None = Field( default=None, @@ -1184,6 +1546,10 @@ class OrgTaskSearchResponseDataItem(BaseModel): default=None, description="Key-value map of named URLs or references associated with the task. Returns an empty object when no links have been set.", ) + machine_rescope_receipts: dict[str, Any] | None = Field( + default=None, + description="Server-owned records of machine-applied local rescopes, keyed by question version. Never evidence that a human answered.", + ) metadata: dict[str, Any] | None = Field( default=None, description="Arbitrary key-value map of application-specific data stored alongside the task. Returns an empty object when no metadata has been set.", @@ -1257,6 +1623,9 @@ class OrgTaskSearchResponseDataItem(BaseModel): default=None, description="Minimum semantic version of `target_binary` that can run this work (for example `0.48.9`), in canonical `MAJOR.MINOR.PATCH[-prerelease][+build]` form. `null` when the task has no target.", ) + task_epic: str | None = Field( + default=None, description="First-class Epic membership; does not grant access to the task." + ) team: str | None = Field( default=None, description="ID of the team that owns this task (`tem_...`). `null` if the task is not scoped to a team.", @@ -1303,6 +1672,36 @@ class OrgThreadListResponseDataItemParentMessageAclAddItem(BaseModel): ) +class OrgThreadListResponseDataItemParentMessageAclAddDeniesItem(BaseModel): + actions: list[str] = Field( + ..., + description='Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.', + ) + principal: str | None = Field( + default=None, + description='The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.', + ) + principal_type: str = Field( + ..., + description='The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.', + ) + + +class OrgThreadListResponseDataItemParentMessageAclDeniesItem(BaseModel): + actions: list[str] = Field( + ..., + description='Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.', + ) + principal: str | None = Field( + default=None, + description='The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.', + ) + principal_type: str = Field( + ..., + description='The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.', + ) + + class OrgThreadListResponseDataItemParentMessageAclGrantsItem(BaseModel): actions: list[str] = Field( ..., @@ -1329,19 +1728,45 @@ class OrgThreadListResponseDataItemParentMessageAclRemoveItem(BaseModel): ) +class OrgThreadListResponseDataItemParentMessageAclRemoveDeniesItem(BaseModel): + principal: str | None = Field( + default=None, + description='The identifier of the principal to remove. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`. Omit when `principal_type` is `"everyone"`.', + ) + principal_type: str = Field( + ..., + description='The kind of principal to remove. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.', + ) + + class OrgThreadListResponseDataItemParentMessageAcl(BaseModel): add: list[OrgThreadListResponseDataItemParentMessageAclAddItem] | None = Field( default=None, description="Patch mode: grants to add or merge into the existing list. Cannot be combined with `grants`.", ) + add_denies: list[OrgThreadListResponseDataItemParentMessageAclAddDeniesItem] | None = Field( + default=None, + description="Patch mode: denies to add or merge, replacing any grant for the same principal.", + ) + denies: list[OrgThreadListResponseDataItemParentMessageAclDeniesItem] | None = Field( + default=None, + description="Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support.", + ) grants: list[OrgThreadListResponseDataItemParentMessageAclGrantsItem] | None = Field( default=None, description="Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", ) + preserve_denies: bool | None = Field( + default=None, + description="Retain current server denies atomically in replacement or patch mode; current denies win.", + ) remove: list[OrgThreadListResponseDataItemParentMessageAclRemoveItem] | None = Field( default=None, description="Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", ) + remove_denies: list[OrgThreadListResponseDataItemParentMessageAclRemoveDeniesItem] | None = ( + Field(default=None, description="Patch mode: principals whose denies should be removed.") + ) class OrgThreadListResponseDataItemParentMessageActorsItemProfilePicture(BaseModel): @@ -1819,6 +2244,36 @@ class OrgThreadListResponseDataItemParticipatingAgentsItemAclAddItem(BaseModel): ) +class OrgThreadListResponseDataItemParticipatingAgentsItemAclAddDeniesItem(BaseModel): + actions: list[str] = Field( + ..., + description='Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.', + ) + principal: str | None = Field( + default=None, + description='The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.', + ) + principal_type: str = Field( + ..., + description='The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.', + ) + + +class OrgThreadListResponseDataItemParticipatingAgentsItemAclDeniesItem(BaseModel): + actions: list[str] = Field( + ..., + description='Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.', + ) + principal: str | None = Field( + default=None, + description='The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.', + ) + principal_type: str = Field( + ..., + description='The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.', + ) + + class OrgThreadListResponseDataItemParticipatingAgentsItemAclGrantsItem(BaseModel): actions: list[str] = Field( ..., @@ -1845,19 +2300,47 @@ class OrgThreadListResponseDataItemParticipatingAgentsItemAclRemoveItem(BaseMode ) +class OrgThreadListResponseDataItemParticipatingAgentsItemAclRemoveDeniesItem(BaseModel): + principal: str | None = Field( + default=None, + description='The identifier of the principal to remove. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`. Omit when `principal_type` is `"everyone"`.', + ) + principal_type: str = Field( + ..., + description='The kind of principal to remove. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.', + ) + + class OrgThreadListResponseDataItemParticipatingAgentsItemAcl(BaseModel): add: list[OrgThreadListResponseDataItemParticipatingAgentsItemAclAddItem] | None = Field( default=None, - description="Patch mode: grants to add or merge into the existing list. Cannot be combined with `grants`.", + description="Patch mode: grants to add or merge into the existing list. Cannot be combined with `grants`.", + ) + add_denies: ( + list[OrgThreadListResponseDataItemParticipatingAgentsItemAclAddDeniesItem] | None + ) = Field( + default=None, + description="Patch mode: denies to add or merge, replacing any grant for the same principal.", + ) + denies: list[OrgThreadListResponseDataItemParticipatingAgentsItemAclDeniesItem] | None = Field( + default=None, + description="Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support.", ) grants: list[OrgThreadListResponseDataItemParticipatingAgentsItemAclGrantsItem] | None = Field( default=None, description="Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", ) + preserve_denies: bool | None = Field( + default=None, + description="Retain current server denies atomically in replacement or patch mode; current denies win.", + ) remove: list[OrgThreadListResponseDataItemParticipatingAgentsItemAclRemoveItem] | None = Field( default=None, description="Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", ) + remove_denies: ( + list[OrgThreadListResponseDataItemParticipatingAgentsItemAclRemoveDeniesItem] | None + ) = Field(default=None, description="Patch mode: principals whose denies should be removed.") class OrgThreadListResponseDataItemParticipatingAgentsItemSourceSolutionCurrentSolutionOrgLogo( @@ -2639,6 +3122,10 @@ class OrgThreadListResponseDataItem(BaseModel): default=None, description="ID of the team that owns this thread (`team_...`). `null` for user-owned or agent-owned threads.", ) + thread_template_key: str | None = Field( + default=None, + description="Read-only key of the template used to create this thread. `null` for threads not created from a template.", + ) title: str | None = Field( default=None, description="Human-readable name of the thread. `null` if no title has been set.", @@ -2728,6 +3215,36 @@ class OrgArtifactsResponseDataItemAclAddItem(BaseModel): ) +class OrgArtifactsResponseDataItemAclAddDeniesItem(BaseModel): + actions: list[str] = Field( + ..., + description='Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.', + ) + principal: str | None = Field( + default=None, + description='The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.', + ) + principal_type: str = Field( + ..., + description='The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.', + ) + + +class OrgArtifactsResponseDataItemAclDeniesItem(BaseModel): + actions: list[str] = Field( + ..., + description='Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.', + ) + principal: str | None = Field( + default=None, + description='The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.', + ) + principal_type: str = Field( + ..., + description='The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.', + ) + + class OrgArtifactsResponseDataItemAclGrantsItem(BaseModel): actions: list[str] = Field( ..., @@ -2754,19 +3271,45 @@ class OrgArtifactsResponseDataItemAclRemoveItem(BaseModel): ) +class OrgArtifactsResponseDataItemAclRemoveDeniesItem(BaseModel): + principal: str | None = Field( + default=None, + description='The identifier of the principal to remove. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`. Omit when `principal_type` is `"everyone"`.', + ) + principal_type: str = Field( + ..., + description='The kind of principal to remove. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.', + ) + + class OrgArtifactsResponseDataItemAcl(BaseModel): add: list[OrgArtifactsResponseDataItemAclAddItem] | None = Field( default=None, description="Patch mode: grants to add or merge into the existing list. Cannot be combined with `grants`.", ) + add_denies: list[OrgArtifactsResponseDataItemAclAddDeniesItem] | None = Field( + default=None, + description="Patch mode: denies to add or merge, replacing any grant for the same principal.", + ) + denies: list[OrgArtifactsResponseDataItemAclDeniesItem] | None = Field( + default=None, + description="Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support.", + ) grants: list[OrgArtifactsResponseDataItemAclGrantsItem] | None = Field( default=None, description="Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", ) + preserve_denies: bool | None = Field( + default=None, + description="Retain current server denies atomically in replacement or patch mode; current denies win.", + ) remove: list[OrgArtifactsResponseDataItemAclRemoveItem] | None = Field( default=None, description="Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", ) + remove_denies: list[OrgArtifactsResponseDataItemAclRemoveDeniesItem] | None = Field( + default=None, description="Patch mode: principals whose denies should be removed." + ) class OrgArtifactsResponseDataItemImageSource(BaseModel): @@ -2917,46 +3460,125 @@ class OrgLinkedAccountsResponse(BaseModel): has_more: bool -class OrgTaskEpicsResponseDataItemNextReadyItem(BaseModel): - id: str - name: str - priority: int - status: str - - -class OrgTaskEpicsResponseDataItemRootBlockersItem(BaseModel): - downstream_count: int - id: str - name: str - priority: int - status: str - - -class OrgTaskEpicsResponseDataItem(BaseModel): - blocked_count: int - counts: dict[str, Any] = Field( - ..., description="Task counts keyed by status, including closed tasks." - ) - epic: str - next_ready: list[OrgTaskEpicsResponseDataItemNextReadyItem] - root_blockers: list[OrgTaskEpicsResponseDataItemRootBlockersItem] - root_blockers_partial: bool = Field( - ..., description="True when root ranking used a truncated in-epic graph." - ) - top_open_priority: int | None = None - updated_at: datetime +class OrgTaskDeletionsResponseDataItem(BaseModel): + deleted_at: str + task: str -class OrgTaskEpicsResponse(BaseModel): +class OrgTaskDeletionsResponse(BaseModel): """ Successful response """ after_cursor: str | None = None before_cursor: str | None = None - data: list[OrgTaskEpicsResponseDataItem] + data: list[OrgTaskDeletionsResponseDataItem] has_more: bool - no_epic_open_count: int + + +class OrgTaskStreamEventReady(TypedDict): + event: Literal["ready"] + data: dict[str, Any] + + +class OrgTaskStreamEventTaskChanged(TypedDict): + event: Literal["task_changed"] + data: dict[str, Any] + + +class OrgTaskStreamEventTaskDeleted(TypedDict): + event: Literal["task_deleted"] + data: TaskDeletion + + +OrgTaskStreamEvent = ( + OrgTaskStreamEventReady | OrgTaskStreamEventTaskChanged | OrgTaskStreamEventTaskDeleted +) + + +class AsyncOrgTaskEpicResource: + def __init__(self, http: HttpClient): + self._http = http + + async def list( + self, + org: str, + *, + representation: str | None = None, + name: str | None = None, + source_scope: str | None = None, + source_type: str | None = None, + source_id: str | None = None, + top_priority: int | None = None, + owner: str | None = None, + include_closed: bool | None = None, + limit: int | None = None, + after_cursor: str | None = None, + ) -> dict[str, Any] | TaskEpicEntityCollection: + """ + List an organization's epic summaries + Groups org-owned tasks by their exact epic label, ordered by label. Closed tasks include cancelled tasks, but cancelled prerequisites still block. Source filters select the tasks summarized; blockers outside that selection still affect readiness. Root ranking is capped per epic and root_blockers_partial is true when that graph is truncated. No epic entity is created. + + Args: + org: Organization ID (`org_...`) owning the tasks. + representation: labels (default) or entities. + name: Exact entity name; only used for entities. + source_scope: Exact source scope; supply all three source fields. + source_type: Exact source type. + source_id: Exact source ID. + top_priority: Exact highest open priority, from 0 to 4. + owner: Keep only epics with at least one non-closed task owned by this user: `me` or a user public ID (`usr_...`). + include_closed: Include epics with no non-closed tasks; defaults to false. + limit: Maximum epics; defaults to 50, capped at 100. + after_cursor: Opaque forward cursor from the preceding page. + + Returns: + Successful response + """ + query: dict[str, object] = {} + if representation is not None: + query["representation"] = representation + if name is not None: + query["name"] = name + if source_scope is not None: + query["source_scope"] = source_scope + if source_type is not None: + query["source_type"] = source_type + if source_id is not None: + query["source_id"] = source_id + if top_priority is not None: + query["top_priority"] = top_priority + if owner is not None: + query["owner"] = owner + if include_closed is not None: + query["include_closed"] = include_closed + if limit is not None: + query["limit"] = limit + if after_cursor is not None: + query["after_cursor"] = after_cursor + return await self._http.request( + f"/api/v1/orgs/{org}/task_epics", + query=query, + response_type=TaskEpicEntityCollection | dict[str, Any], + ) + + async def create(self, org: str, input: OrgTaskEpicCreateInput) -> TaskEpicEntity: + """ + Create an organization task Epic + + Args: + org: Organization ID (`org_...`) owning the tasks. + input: Request body. + + Returns: + Successful response + """ + return await self._http.request( + f"/api/v1/orgs/{org}/task_epics", + method="POST", + body=input, + response_type=TaskEpicEntity, + ) class AsyncOrgTaskResource: @@ -2970,6 +3592,9 @@ async def list( status: str | None = None, owner_user: str | None = None, owner_agent: str | None = None, + owner: str | None = None, + involving: str | None = None, + summary: bool | None = None, priority: int | None = None, tag: str | None = None, parent: str | None = None, @@ -2978,6 +3603,7 @@ async def list( source_id: str | None = None, epic: str | None = None, search: str | None = None, + include: str | None = None, sort: str | None = None, order: str | None = None, due_before: str | None = None, @@ -3002,6 +3628,9 @@ async def list( status: Filter tasks by status. One of `"open"`, `"in_progress"`, `"in_review"`, or `"done"`. Omit to return tasks in all statuses. owner_user: Filter tasks assigned to a specific user. Provide the user's public ID (`usr_...`). owner_agent: Filter tasks assigned to a specific agent. Provide the agent's public ID (`agi_...`). + owner: Return only tasks owned by this user: `me` or a user public ID (`usr_...`). + involving: Return only tasks owned or created by this user: `me` or a user public ID (`usr_...`). The "My work" predicate. + summary: When true, omit `description` from every task. Use for list views. priority: Filter tasks by priority, from 0 (highest) to 4 (lowest). tag: Return only tasks carrying this tag (matched against the canonical lowercase form). parent: Return only subtasks of the given task (`tsk_...`), or pass `none` to return only top-level tasks. @@ -3010,8 +3639,9 @@ async def list( source_id: Return only tasks whose source matches this object identity. Must be supplied with the other source filters. epic: Return only tasks with this exact epic label. search: Restrict results to tasks whose name or description contains this string. - sort: Sort key. One of `"created"` (default most recently created first), `"due_date"` (soonest due first; tasks without a due date always sort last), or `"priority"` (most urgent first). Ties break by most recently created. - order: Sort direction, `"asc"` or `"desc"`. Defaults to `"desc"` for `created` and `"asc"` for `due_date` and `priority`. + include: Set to `blockers` to include visible blocker task IDs. + sort: Sort key. One of `"created"` (default most recently created first), `"due_date"` (soonest due first; tasks without a due date always sort last), `"priority"` (most urgent first), or `"updated"` (latest-state sync, ties by ID). Updated rows can coalesce or reappear: upsert by ID and aggregate version. Delayed/backdated or equal-time updates behind a cursor require periodic reconciliation. This is not a lossless mutation log. + order: Sort direction, `"asc"` or `"desc"`. Defaults to `"desc"` for `created` and `"asc"` for `updated`, `due_date` and `priority`. due_before: Return only tasks with a due date strictly before this ISO 8601 datetime (`2026-08-01T00:00:00Z`) or date (`2026-08-01`, meaning midnight UTC). Tasks without a due date are excluded. due_after: Return only tasks with a due date strictly after this ISO 8601 datetime or date. Tasks without a due date are excluded. overdue: When `true`, return only overdue tasks: a due date before the current UTC day and a status other than `"done"`. A task due today is not overdue. @@ -3030,6 +3660,12 @@ async def list( query["owner_user"] = owner_user if owner_agent is not None: query["owner_agent"] = owner_agent + if owner is not None: + query["owner"] = owner + if involving is not None: + query["involving"] = involving + if summary is not None: + query["summary"] = summary if priority is not None: query["priority"] = priority if tag is not None: @@ -3046,6 +3682,8 @@ async def list( query["epic"] = epic if search is not None: query["search"] = search + if include is not None: + query["include"] = include if sort is not None: query["sort"] = sort if order is not None: @@ -3127,6 +3765,45 @@ async def blocker_cycles( response_type=OrgTaskBlockerCyclesResponse, ) + async def by_external_reference( + self, + org: str, + external_scope: str, + object_type: str, + object_id: str, + *, + user: str | None = None, + team: str | None = None, + ) -> OrgTaskByExternalReferenceResponse: + """ + Find an owner's tasks by external reference + Returns all exact external-reference matches owned by the requested principal. Multiple matches remain explicit; callers must not choose an arbitrary task. + + Args: + org: Organization ID (`org_...`) whose org-owned tasks should be returned. + user: User owner. + team: Team owner. + external_scope: External host. + object_type: External object type. + object_id: External object identity. + + Returns: + Successful response + """ + query: dict[str, object] = {} + if user is not None: + query["user"] = user + if team is not None: + query["team"] = team + query["external_scope"] = external_scope + query["object_type"] = object_type + query["object_id"] = object_id + return await self._http.request( + f"/api/v1/orgs/{org}/tasks/by-external-reference", + query=query, + response_type=OrgTaskByExternalReferenceResponse, + ) + async def by_source(self, org: str, input: OrgTaskBySourceInput) -> TaskEnsureResult: """ Find or create a task by source @@ -3139,6 +3816,7 @@ async def by_source(self, org: str, input: OrgTaskBySourceInput) -> TaskEnsureRe input.description: Initial task description. input.epic: Initial epic grouping. input.name: Initial task name. + input.owner_user: Initial assigned user; immutable on retries. input.source_id: Source identity, for example owner/repo#123. input.source_scope: Source scope, for example github. input.source_type: Source type, for example pull_request. @@ -3192,6 +3870,7 @@ async def ready( *, explain: bool | None = None, assigned_to_me: bool | None = None, + owner: builtins.list[str] | None = None, source_scope: str | None = None, source_type: str | None = None, source_id: str | None = None, @@ -3212,7 +3891,8 @@ async def ready( Args: org: Organization ID (`org_...`) whose org-owned tasks should be returned. explain: Include blocked and actively leased open tasks with exclusion reasons. - assigned_to_me: Only include tasks assigned to the authenticated user. + assigned_to_me: Only include tasks assigned to the authenticated user. Equivalent to `owner[]=me`; sending it together with `owner` returns 422. + owner: Owner kinds to include; the result is the union of the listed kinds. Accepted values: `me` (assigned to the authenticated user) and `unassigned` (no user or agent owner). Agent-assigned tasks match neither value. Omit to include every owner. source_scope: Only include tasks whose source matches this container. Must be supplied with `source_type` and `source_id`. source_type: Only include tasks whose source matches this object kind. source_id: Only include tasks whose source matches this object identity. @@ -3228,6 +3908,8 @@ async def ready( query["explain"] = explain if assigned_to_me is not None: query["assigned_to_me"] = assigned_to_me + if owner is not None: + query["owner"] = owner if source_scope is not None: query["source_scope"] = source_scope if source_type is not None: @@ -3329,6 +4011,34 @@ async def search( response_type=OrgTaskSearchResponse, ) + async def stream(self, org: str) -> AsyncIterator[OrgTaskStreamEvent]: + """ + Stream organization task changes + Organization task hints, not a lossless mutation log. Subscribe before reading + ready cursors. Resume tasks with sort=updated&order=asc and deletions with their + own cursor, retaining each page's after_cursor. Rows may coalesce or reappear; + upsert by ID/version and periodically reconcile late/backdated/equal-time rows + behind a cursor. Gaps beyond seven-day tombstone retention require full resync. + Projector commit/ack failures can lose hints, so clients must reconcile too. + Cross-batch deduplication retains at most 1024 task IDs in FIFO order; hints + for evicted IDs can reappear, so clients must discard older/equal versions. + Pending batches admit at most 512 distinct IDs, bounding visibility queries + and emitted event lists. Overflow closes the stream; reconnect and reconcile. + The independently released Rust Factory panel and assignment sweeps consume + this contract in https://archdev.ai/tasks/tsk_6ttk2gUwttt6wwkiprwui7. + That consumer must not roll out until this provider endpoint and the cursor / + deletion contracts are deployed and verified on Platform. Its old-server 404 + polling fallback is compatibility protection, not a substitute for this gate. + + Args: + org: Organization ID (`org_...`) whose org-owned tasks should be returned. + + Returns: + Server-Sent Events stream + """ + async for event in self._http.stream_sse(f"/api/v1/orgs/{org}/tasks/stream"): + yield event + class AsyncOrgThreadResource: def __init__(self, http: HttpClient): @@ -3388,6 +4098,7 @@ async def create(self, org: str, input: OrgThreadCreateInput) -> Thread: class AsyncOrgResource: def __init__(self, http: HttpClient): self._http = http + self.task_epics = AsyncOrgTaskEpicResource(http) self.tasks = AsyncOrgTaskResource(http) self.threads = AsyncOrgThreadResource(http) @@ -3502,28 +4213,68 @@ async def linked_accounts( response_type=OrgLinkedAccountsResponse, ) - async def task_epics( + async def task_deletions( + self, org: str, *, limit: int | None = None, after_cursor: str | None = None + ) -> OrgTaskDeletionsResponse: + """ + List visible task deletions + Returns visible task tombstones in ascending (deleted_at, task) order. + Tombstones are retained for seven days. Clients must fully resynchronize after + retention gaps, and periodically reconcile delayed projections. This is not an + immutable mutation log. Upsert live tasks by ID and aggregate version. + + Args: + org: Organization ID (`org_...`). + limit: Page size, capped at 100. + after_cursor: Opaque cursor from the previous page. + + Returns: + Successful response + """ + query: dict[str, object] = {} + if limit is not None: + query["limit"] = limit + if after_cursor is not None: + query["after_cursor"] = after_cursor + return await self._http.request( + f"/api/v1/orgs/{org}/task_deletions", + query=query, + response_type=OrgTaskDeletionsResponse, + ) + + +class OrgTaskEpicResource: + def __init__(self, http: SyncHttpClient): + self._http = http + + def list( self, org: str, *, + representation: str | None = None, + name: str | None = None, source_scope: str | None = None, source_type: str | None = None, source_id: str | None = None, top_priority: int | None = None, + owner: str | None = None, include_closed: bool | None = None, limit: int | None = None, after_cursor: str | None = None, - ) -> OrgTaskEpicsResponse: + ) -> dict[str, Any] | TaskEpicEntityCollection: """ List an organization's epic summaries Groups org-owned tasks by their exact epic label, ordered by label. Closed tasks include cancelled tasks, but cancelled prerequisites still block. Source filters select the tasks summarized; blockers outside that selection still affect readiness. Root ranking is capped per epic and root_blockers_partial is true when that graph is truncated. No epic entity is created. Args: org: Organization ID (`org_...`) owning the tasks. + representation: labels (default) or entities. + name: Exact entity name; only used for entities. source_scope: Exact source scope; supply all three source fields. source_type: Exact source type. source_id: Exact source ID. top_priority: Exact highest open priority, from 0 to 4. + owner: Keep only epics with at least one non-closed task owned by this user: `me` or a user public ID (`usr_...`). include_closed: Include epics with no non-closed tasks; defaults to false. limit: Maximum epics; defaults to 50, capped at 100. after_cursor: Opaque forward cursor from the preceding page. @@ -3532,6 +4283,10 @@ async def task_epics( Successful response """ query: dict[str, object] = {} + if representation is not None: + query["representation"] = representation + if name is not None: + query["name"] = name if source_scope is not None: query["source_scope"] = source_scope if source_type is not None: @@ -3540,16 +4295,36 @@ async def task_epics( query["source_id"] = source_id if top_priority is not None: query["top_priority"] = top_priority + if owner is not None: + query["owner"] = owner if include_closed is not None: query["include_closed"] = include_closed if limit is not None: query["limit"] = limit if after_cursor is not None: query["after_cursor"] = after_cursor - return await self._http.request( + return self._http.request( f"/api/v1/orgs/{org}/task_epics", query=query, - response_type=OrgTaskEpicsResponse, + response_type=TaskEpicEntityCollection | dict[str, Any], + ) + + def create(self, org: str, input: OrgTaskEpicCreateInput) -> TaskEpicEntity: + """ + Create an organization task Epic + + Args: + org: Organization ID (`org_...`) owning the tasks. + input: Request body. + + Returns: + Successful response + """ + return self._http.request( + f"/api/v1/orgs/{org}/task_epics", + method="POST", + body=input, + response_type=TaskEpicEntity, ) @@ -3564,6 +4339,9 @@ def list( status: str | None = None, owner_user: str | None = None, owner_agent: str | None = None, + owner: str | None = None, + involving: str | None = None, + summary: bool | None = None, priority: int | None = None, tag: str | None = None, parent: str | None = None, @@ -3572,6 +4350,7 @@ def list( source_id: str | None = None, epic: str | None = None, search: str | None = None, + include: str | None = None, sort: str | None = None, order: str | None = None, due_before: str | None = None, @@ -3596,6 +4375,9 @@ def list( status: Filter tasks by status. One of `"open"`, `"in_progress"`, `"in_review"`, or `"done"`. Omit to return tasks in all statuses. owner_user: Filter tasks assigned to a specific user. Provide the user's public ID (`usr_...`). owner_agent: Filter tasks assigned to a specific agent. Provide the agent's public ID (`agi_...`). + owner: Return only tasks owned by this user: `me` or a user public ID (`usr_...`). + involving: Return only tasks owned or created by this user: `me` or a user public ID (`usr_...`). The "My work" predicate. + summary: When true, omit `description` from every task. Use for list views. priority: Filter tasks by priority, from 0 (highest) to 4 (lowest). tag: Return only tasks carrying this tag (matched against the canonical lowercase form). parent: Return only subtasks of the given task (`tsk_...`), or pass `none` to return only top-level tasks. @@ -3604,8 +4386,9 @@ def list( source_id: Return only tasks whose source matches this object identity. Must be supplied with the other source filters. epic: Return only tasks with this exact epic label. search: Restrict results to tasks whose name or description contains this string. - sort: Sort key. One of `"created"` (default most recently created first), `"due_date"` (soonest due first; tasks without a due date always sort last), or `"priority"` (most urgent first). Ties break by most recently created. - order: Sort direction, `"asc"` or `"desc"`. Defaults to `"desc"` for `created` and `"asc"` for `due_date` and `priority`. + include: Set to `blockers` to include visible blocker task IDs. + sort: Sort key. One of `"created"` (default most recently created first), `"due_date"` (soonest due first; tasks without a due date always sort last), `"priority"` (most urgent first), or `"updated"` (latest-state sync, ties by ID). Updated rows can coalesce or reappear: upsert by ID and aggregate version. Delayed/backdated or equal-time updates behind a cursor require periodic reconciliation. This is not a lossless mutation log. + order: Sort direction, `"asc"` or `"desc"`. Defaults to `"desc"` for `created` and `"asc"` for `updated`, `due_date` and `priority`. due_before: Return only tasks with a due date strictly before this ISO 8601 datetime (`2026-08-01T00:00:00Z`) or date (`2026-08-01`, meaning midnight UTC). Tasks without a due date are excluded. due_after: Return only tasks with a due date strictly after this ISO 8601 datetime or date. Tasks without a due date are excluded. overdue: When `true`, return only overdue tasks: a due date before the current UTC day and a status other than `"done"`. A task due today is not overdue. @@ -3624,6 +4407,12 @@ def list( query["owner_user"] = owner_user if owner_agent is not None: query["owner_agent"] = owner_agent + if owner is not None: + query["owner"] = owner + if involving is not None: + query["involving"] = involving + if summary is not None: + query["summary"] = summary if priority is not None: query["priority"] = priority if tag is not None: @@ -3640,6 +4429,8 @@ def list( query["epic"] = epic if search is not None: query["search"] = search + if include is not None: + query["include"] = include if sort is not None: query["sort"] = sort if order is not None: @@ -3721,6 +4512,45 @@ def blocker_cycles( response_type=OrgTaskBlockerCyclesResponse, ) + def by_external_reference( + self, + org: str, + external_scope: str, + object_type: str, + object_id: str, + *, + user: str | None = None, + team: str | None = None, + ) -> OrgTaskByExternalReferenceResponse: + """ + Find an owner's tasks by external reference + Returns all exact external-reference matches owned by the requested principal. Multiple matches remain explicit; callers must not choose an arbitrary task. + + Args: + org: Organization ID (`org_...`) whose org-owned tasks should be returned. + user: User owner. + team: Team owner. + external_scope: External host. + object_type: External object type. + object_id: External object identity. + + Returns: + Successful response + """ + query: dict[str, object] = {} + if user is not None: + query["user"] = user + if team is not None: + query["team"] = team + query["external_scope"] = external_scope + query["object_type"] = object_type + query["object_id"] = object_id + return self._http.request( + f"/api/v1/orgs/{org}/tasks/by-external-reference", + query=query, + response_type=OrgTaskByExternalReferenceResponse, + ) + def by_source(self, org: str, input: OrgTaskBySourceInput) -> TaskEnsureResult: """ Find or create a task by source @@ -3733,6 +4563,7 @@ def by_source(self, org: str, input: OrgTaskBySourceInput) -> TaskEnsureResult: input.description: Initial task description. input.epic: Initial epic grouping. input.name: Initial task name. + input.owner_user: Initial assigned user; immutable on retries. input.source_id: Source identity, for example owner/repo#123. input.source_scope: Source scope, for example github. input.source_type: Source type, for example pull_request. @@ -3786,6 +4617,7 @@ def ready( *, explain: bool | None = None, assigned_to_me: bool | None = None, + owner: builtins.list[str] | None = None, source_scope: str | None = None, source_type: str | None = None, source_id: str | None = None, @@ -3806,7 +4638,8 @@ def ready( Args: org: Organization ID (`org_...`) whose org-owned tasks should be returned. explain: Include blocked and actively leased open tasks with exclusion reasons. - assigned_to_me: Only include tasks assigned to the authenticated user. + assigned_to_me: Only include tasks assigned to the authenticated user. Equivalent to `owner[]=me`; sending it together with `owner` returns 422. + owner: Owner kinds to include; the result is the union of the listed kinds. Accepted values: `me` (assigned to the authenticated user) and `unassigned` (no user or agent owner). Agent-assigned tasks match neither value. Omit to include every owner. source_scope: Only include tasks whose source matches this container. Must be supplied with `source_type` and `source_id`. source_type: Only include tasks whose source matches this object kind. source_id: Only include tasks whose source matches this object identity. @@ -3822,6 +4655,8 @@ def ready( query["explain"] = explain if assigned_to_me is not None: query["assigned_to_me"] = assigned_to_me + if owner is not None: + query["owner"] = owner if source_scope is not None: query["source_scope"] = source_scope if source_type is not None: @@ -3923,6 +4758,33 @@ def search( response_type=OrgTaskSearchResponse, ) + def stream(self, org: str) -> Iterator[OrgTaskStreamEvent]: + """ + Stream organization task changes + Organization task hints, not a lossless mutation log. Subscribe before reading + ready cursors. Resume tasks with sort=updated&order=asc and deletions with their + own cursor, retaining each page's after_cursor. Rows may coalesce or reappear; + upsert by ID/version and periodically reconcile late/backdated/equal-time rows + behind a cursor. Gaps beyond seven-day tombstone retention require full resync. + Projector commit/ack failures can lose hints, so clients must reconcile too. + Cross-batch deduplication retains at most 1024 task IDs in FIFO order; hints + for evicted IDs can reappear, so clients must discard older/equal versions. + Pending batches admit at most 512 distinct IDs, bounding visibility queries + and emitted event lists. Overflow closes the stream; reconnect and reconcile. + The independently released Rust Factory panel and assignment sweeps consume + this contract in https://archdev.ai/tasks/tsk_6ttk2gUwttt6wwkiprwui7. + That consumer must not roll out until this provider endpoint and the cursor / + deletion contracts are deployed and verified on Platform. Its old-server 404 + polling fallback is compatibility protection, not a substitute for this gate. + + Args: + org: Organization ID (`org_...`) whose org-owned tasks should be returned. + + Returns: + Server-Sent Events stream + """ + yield from self._http.stream_sse_sync(f"/api/v1/orgs/{org}/tasks/stream") + class OrgThreadResource: def __init__(self, http: SyncHttpClient): @@ -3982,6 +4844,7 @@ def create(self, org: str, input: OrgThreadCreateInput) -> Thread: class OrgResource: def __init__(self, http: SyncHttpClient): self._http = http + self.task_epics = OrgTaskEpicResource(http) self.tasks = OrgTaskResource(http) self.threads = OrgThreadResource(http) @@ -4096,52 +4959,31 @@ def linked_accounts( response_type=OrgLinkedAccountsResponse, ) - def task_epics( - self, - org: str, - *, - source_scope: str | None = None, - source_type: str | None = None, - source_id: str | None = None, - top_priority: int | None = None, - include_closed: bool | None = None, - limit: int | None = None, - after_cursor: str | None = None, - ) -> OrgTaskEpicsResponse: + def task_deletions( + self, org: str, *, limit: int | None = None, after_cursor: str | None = None + ) -> OrgTaskDeletionsResponse: """ - List an organization's epic summaries - Groups org-owned tasks by their exact epic label, ordered by label. Closed tasks include cancelled tasks, but cancelled prerequisites still block. Source filters select the tasks summarized; blockers outside that selection still affect readiness. Root ranking is capped per epic and root_blockers_partial is true when that graph is truncated. No epic entity is created. + List visible task deletions + Returns visible task tombstones in ascending (deleted_at, task) order. + Tombstones are retained for seven days. Clients must fully resynchronize after + retention gaps, and periodically reconcile delayed projections. This is not an + immutable mutation log. Upsert live tasks by ID and aggregate version. Args: - org: Organization ID (`org_...`) owning the tasks. - source_scope: Exact source scope; supply all three source fields. - source_type: Exact source type. - source_id: Exact source ID. - top_priority: Exact highest open priority, from 0 to 4. - include_closed: Include epics with no non-closed tasks; defaults to false. - limit: Maximum epics; defaults to 50, capped at 100. - after_cursor: Opaque forward cursor from the preceding page. + org: Organization ID (`org_...`). + limit: Page size, capped at 100. + after_cursor: Opaque cursor from the previous page. Returns: Successful response """ query: dict[str, object] = {} - if source_scope is not None: - query["source_scope"] = source_scope - if source_type is not None: - query["source_type"] = source_type - if source_id is not None: - query["source_id"] = source_id - if top_priority is not None: - query["top_priority"] = top_priority - if include_closed is not None: - query["include_closed"] = include_closed if limit is not None: query["limit"] = limit if after_cursor is not None: query["after_cursor"] = after_cursor return self._http.request( - f"/api/v1/orgs/{org}/task_epics", + f"/api/v1/orgs/{org}/task_deletions", query=query, - response_type=OrgTaskEpicsResponse, + response_type=OrgTaskDeletionsResponse, ) diff --git a/src/archastro/platform/v1/resources/solutions.py b/src/archastro/platform/v1/resources/solutions.py index 85de5ff..d394164 100644 --- a/src/archastro/platform/v1/resources/solutions.py +++ b/src/archastro/platform/v1/resources/solutions.py @@ -1,6 +1,6 @@ # Copyright (c) 2026 ArchAstro Inc. Licensed under the MIT License. # This file is auto-generated by @archastro/sdk-generator. Do not edit. -# Content hash: 593cc7ef4728 +# Content hash: 87600abe2436 from __future__ import annotations @@ -154,6 +154,24 @@ class SolutionInstallInputAclAddItem(TypedDict, total=False): 'The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' +class SolutionInstallInputAclAddDeniesItem(TypedDict, total=False): + actions: Required[list[str]] + 'Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.' + principal: str | None + 'The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.' + principal_type: Required[str] + 'The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' + + +class SolutionInstallInputAclDeniesItem(TypedDict, total=False): + actions: Required[list[str]] + 'Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.' + principal: str | None + 'The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.' + principal_type: Required[str] + 'The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' + + class SolutionInstallInputAclGrantsItem(TypedDict, total=False): actions: Required[list[str]] 'Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.' @@ -170,13 +188,28 @@ class SolutionInstallInputAclRemoveItem(TypedDict, total=False): 'The kind of principal to remove. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' +class SolutionInstallInputAclRemoveDeniesItem(TypedDict, total=False): + principal: str | None + 'The identifier of the principal to remove. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`. Omit when `principal_type` is `"everyone"`.' + principal_type: Required[str] + 'The kind of principal to remove. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' + + class SolutionInstallInputAcl(TypedDict, total=False): add: list[SolutionInstallInputAclAddItem] | None "Patch mode: grants to add or merge into the existing list. Cannot be combined with `grants`." + add_denies: list[SolutionInstallInputAclAddDeniesItem] | None + "Patch mode: denies to add or merge, replacing any grant for the same principal." + denies: list[SolutionInstallInputAclDeniesItem] | None + "Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support." grants: list[SolutionInstallInputAclGrantsItem] | None "Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`." + preserve_denies: bool | None + "Retain current server denies atomically in replacement or patch mode; current denies win." remove: list[SolutionInstallInputAclRemoveItem] | None "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`." + remove_denies: list[SolutionInstallInputAclRemoveDeniesItem] | None + "Patch mode: principals whose denies should be removed." class SolutionInstallInputDetailsPrefills(TypedDict, total=False): diff --git a/src/archastro/platform/v1/resources/task_epics.py b/src/archastro/platform/v1/resources/task_epics.py new file mode 100644 index 0000000..c8b3f62 --- /dev/null +++ b/src/archastro/platform/v1/resources/task_epics.py @@ -0,0 +1,272 @@ +# Copyright (c) 2026 ArchAstro Inc. Licensed under the MIT License. +# This file is auto-generated by @archastro/sdk-generator. Do not edit. +# Content hash: 3ab3b240825b + +from __future__ import annotations + +from typing import Any, Literal, Required, TypedDict + +from ...runtime.http_client import HttpClient, SyncHttpClient +from ...types.tasks import TaskEpicDrafts, TaskEpicEntity + + +class DraftReplaceInputUpsertsItem(TypedDict, total=False): + blocker_keys: list[str] | None + blocker_tasks: list[str] | None + description: str | None + file_ids: list[str] | None + initial_status: Literal["open", "paused"] | None + key: str | None + metadata: dict[str, Any] | None + name: Required[str] + priority: int | None + tags: list[str] | None + + +class DraftReplaceInput(TypedDict, total=False): + "ApplyDrafts task Epic drafts" + + expected_drafts_version: Required[int] + removes: list[str] | None + upserts: list[DraftReplaceInputUpsertsItem] | None + + +class DraftReplaceByKeyInputDraft(TypedDict, total=False): + blocker_keys: list[str] | None + blocker_tasks: list[str] | None + description: str | None + file_ids: list[str] | None + initial_status: Literal["open", "paused"] | None + key: str | None + metadata: dict[str, Any] | None + name: Required[str] + priority: int | None + tags: list[str] | None + + +class DraftReplaceByKeyInput(TypedDict): + "PutDraft task Epic drafts" + + draft: DraftReplaceByKeyInputDraft + "Shared input boundary for batch and single Epic draft writes." + expected_drafts_version: int + + +class TaskEpicUpdateInput(TypedDict, total=False): + "Edit a task Epic" + + description: str | None + metadata: dict[str, Any] | None + name: str | None + state: str | None + + +class AsyncDraftResource: + def __init__(self, http: HttpClient): + self._http = http + + async def list(self, epic: str) -> TaskEpicDrafts: + """ + Drafts task Epic drafts + + Returns: + Successful response + """ + return await self._http.request( + f"/api/v1/task_epics/{epic}/drafts", + response_type=TaskEpicDrafts, + ) + + async def replace(self, epic: str, input: DraftReplaceInput) -> TaskEpicDrafts: + """ + ApplyDrafts task Epic drafts + + Args: + input: Request body. + + Returns: + Successful response + """ + return await self._http.request( + f"/api/v1/task_epics/{epic}/drafts", + method="PUT", + body=input, + response_type=TaskEpicDrafts, + ) + + async def delete(self, epic: str, key: str) -> TaskEpicDrafts: + """ + DeleteDraft task Epic drafts + + Returns: + Successful response + """ + return await self._http.request( + f"/api/v1/task_epics/{epic}/drafts/{key}", + method="DELETE", + response_type=TaskEpicDrafts, + ) + + async def replace_by_key( + self, epic: str, key: str, input: DraftReplaceByKeyInput + ) -> TaskEpicDrafts: + """ + PutDraft task Epic drafts + + Args: + input: Request body. + input.draft: Shared input boundary for batch and single Epic draft writes. + + Returns: + Successful response + """ + return await self._http.request( + f"/api/v1/task_epics/{epic}/drafts/{key}", + method="PUT", + body=input, + response_type=TaskEpicDrafts, + ) + + +class AsyncTaskEpicResource: + def __init__(self, http: HttpClient): + self._http = http + self.drafts = AsyncDraftResource(http) + + async def get(self, epic: str) -> TaskEpicEntity: + """ + Retrieve a task Epic + + Returns: + Successful response + """ + return await self._http.request(f"/api/v1/task_epics/{epic}", response_type=TaskEpicEntity) + + async def update(self, epic: str, input: TaskEpicUpdateInput) -> TaskEpicEntity: + """ + Edit a task Epic + + Args: + input: Request body. + + Returns: + Successful response + """ + return await self._http.request( + f"/api/v1/task_epics/{epic}", + method="PATCH", + body=input, + response_type=TaskEpicEntity, + ) + + async def cancel(self, epic: str) -> None: + """ + Cancel a task Epic + + Returns: + No content + """ + await self._http.request(f"/api/v1/task_epics/{epic}/cancel", method="POST") + + +class DraftResource: + def __init__(self, http: SyncHttpClient): + self._http = http + + def list(self, epic: str) -> TaskEpicDrafts: + """ + Drafts task Epic drafts + + Returns: + Successful response + """ + return self._http.request(f"/api/v1/task_epics/{epic}/drafts", response_type=TaskEpicDrafts) + + def replace(self, epic: str, input: DraftReplaceInput) -> TaskEpicDrafts: + """ + ApplyDrafts task Epic drafts + + Args: + input: Request body. + + Returns: + Successful response + """ + return self._http.request( + f"/api/v1/task_epics/{epic}/drafts", + method="PUT", + body=input, + response_type=TaskEpicDrafts, + ) + + def delete(self, epic: str, key: str) -> TaskEpicDrafts: + """ + DeleteDraft task Epic drafts + + Returns: + Successful response + """ + return self._http.request( + f"/api/v1/task_epics/{epic}/drafts/{key}", + method="DELETE", + response_type=TaskEpicDrafts, + ) + + def replace_by_key(self, epic: str, key: str, input: DraftReplaceByKeyInput) -> TaskEpicDrafts: + """ + PutDraft task Epic drafts + + Args: + input: Request body. + input.draft: Shared input boundary for batch and single Epic draft writes. + + Returns: + Successful response + """ + return self._http.request( + f"/api/v1/task_epics/{epic}/drafts/{key}", + method="PUT", + body=input, + response_type=TaskEpicDrafts, + ) + + +class TaskEpicResource: + def __init__(self, http: SyncHttpClient): + self._http = http + self.drafts = DraftResource(http) + + def get(self, epic: str) -> TaskEpicEntity: + """ + Retrieve a task Epic + + Returns: + Successful response + """ + return self._http.request(f"/api/v1/task_epics/{epic}", response_type=TaskEpicEntity) + + def update(self, epic: str, input: TaskEpicUpdateInput) -> TaskEpicEntity: + """ + Edit a task Epic + + Args: + input: Request body. + + Returns: + Successful response + """ + return self._http.request( + f"/api/v1/task_epics/{epic}", + method="PATCH", + body=input, + response_type=TaskEpicEntity, + ) + + def cancel(self, epic: str) -> None: + """ + Cancel a task Epic + + Returns: + No content + """ + self._http.request(f"/api/v1/task_epics/{epic}/cancel", method="POST") diff --git a/src/archastro/platform/v1/resources/tasks.py b/src/archastro/platform/v1/resources/tasks.py index 44ae627..bbd5f02 100644 --- a/src/archastro/platform/v1/resources/tasks.py +++ b/src/archastro/platform/v1/resources/tasks.py @@ -1,6 +1,6 @@ # Copyright (c) 2026 ArchAstro Inc. Licensed under the MIT License. # This file is auto-generated by @archastro/sdk-generator. Do not edit. -# Content hash: 929c29305abf +# Content hash: a39c843025e1 from __future__ import annotations @@ -59,6 +59,8 @@ class CommentReplaceInput(TypedDict): class LeaseCreateInput(TypedDict, total=False): "Claim a task for a coding session" + assign_if_ownerless: bool | None + "Assign an ownerless task to the authenticated system user while claiming its lease." force: bool | None "Take the lease from a live but dead holder instead of returning a conflict. Releases the prior session's lease and claims the new one atomically. Always scoped to the task's assigned owner, same as an ordinary claim." harness: Required[str] @@ -86,14 +88,18 @@ class LeaseRenewInput(TypedDict, total=False): "Current coding-session UUID." -class LinkCreateInput(TypedDict): +class LinkCreateInput(TypedDict, total=False): "Add an external link to a task" - external_scope: str + external_scope: Required[str] "External container ID." - object_id: str + lease_id: str | None + "Caller-held lease UUID, paired with lease_session_id." + lease_session_id: str | None + "Caller-held coding-session UUID, paired with lease_id." + object_id: Required[str] "External object ID." - object_type: str + object_type: Required[str] "External object type." @@ -108,6 +114,8 @@ class TaskReplaceInput(TypedDict, total=False): "Updated due date in ISO 8601 format, or null to clear it." epic: str | None "Replacement grouping label. Pass null to clear it." + epic_id: str | None + "First-class Epic ID; null clears membership." expected_version: int | None "Aggregate version returned by the latest task read. The update fails with `task_version_conflict` if the task changed first." lease_id: str | None @@ -154,6 +162,32 @@ class TaskReplaceInput(TypedDict, total=False): "Explicit user (`usr_...`) for a developer or server-to-server call. With `team`, this identifies the acting team member." +class TaskHumanAnswerInput(TypedDict, total=False): + "Submit a structured human answer" + + drop_acceptance: str | None + "Exact unique acceptance item to defer for rescope_local." + drop_verification: list[str] | None + "Exact associated verification items to defer. Entries identical to the acceptance item move automatically." + evidence: str | None + "Evidence link or attachment reference." + expected_version: Required[int] + "Version of the question answered." + outcome: str | None + "evidence, access_granted, or rescope_local." + standing: bool | None + "Apply this explicit instruction to matching future pauses." + text: str | None + "Optional answer or required access note." + + +class TaskMachineRescopeInput(TypedDict): + "Apply a recommended local rescope to an unanswered pause" + + expected_version: int + "Version of the question observed." + + class TaskOwnershipConversionsInput(TypedDict, total=False): "Convert ownership of a connected task graph" @@ -301,6 +335,9 @@ class BlockerListResponseDataItem(BaseModel): default=None, description="Number of readable tasks marked as blocking this task, whether or not they are done (see `GET /tasks/{task}/blockers`). Computed on list/show reads; create/update responses may lag one read behind.", ) + blockers: list[str] | None = Field( + default=None, description="Visible blocker IDs when requested with include=blockers." + ) closed_at: datetime | None = Field( default=None, description="When the task was marked as done or otherwise closed (ISO 8601). `null` if the task is still open.", @@ -339,6 +376,10 @@ class BlockerListResponseDataItem(BaseModel): default=None, description="Free-form grouping label. `null` when the task is not in an epic.", ) + human_answer_receipts: dict[str, Any] | None = Field( + default=None, + description="Server-owned authenticated human answer intent, keyed by question version. Not infrastructure permission.", + ) id: str = Field(..., description="Task ID (`tsk_...`).") is_blocked: bool | None = Field( default=None, @@ -352,6 +393,10 @@ class BlockerListResponseDataItem(BaseModel): default=None, description="Key-value map of named URLs or references associated with the task. Returns an empty object when no links have been set.", ) + machine_rescope_receipts: dict[str, Any] | None = Field( + default=None, + description="Server-owned records of machine-applied local rescopes, keyed by question version. Never evidence that a human answered.", + ) metadata: dict[str, Any] | None = Field( default=None, description="Arbitrary key-value map of application-specific data stored alongside the task. Returns an empty object when no metadata has been set.", @@ -425,6 +470,9 @@ class BlockerListResponseDataItem(BaseModel): default=None, description="Minimum semantic version of `target_binary` that can run this work (for example `0.48.9`), in canonical `MAJOR.MINOR.PATCH[-prerelease][+build]` form. `null` when the task has no target.", ) + task_epic: str | None = Field( + default=None, description="First-class Epic membership; does not grant access to the task." + ) team: str | None = Field( default=None, description="ID of the team that owns this task (`tem_...`). `null` if the task is not scoped to a team.", @@ -710,6 +758,9 @@ class TaskBlockingResponseDataItem(BaseModel): default=None, description="Number of readable tasks marked as blocking this task, whether or not they are done (see `GET /tasks/{task}/blockers`). Computed on list/show reads; create/update responses may lag one read behind.", ) + blockers: list[str] | None = Field( + default=None, description="Visible blocker IDs when requested with include=blockers." + ) closed_at: datetime | None = Field( default=None, description="When the task was marked as done or otherwise closed (ISO 8601). `null` if the task is still open.", @@ -748,6 +799,10 @@ class TaskBlockingResponseDataItem(BaseModel): default=None, description="Free-form grouping label. `null` when the task is not in an epic.", ) + human_answer_receipts: dict[str, Any] | None = Field( + default=None, + description="Server-owned authenticated human answer intent, keyed by question version. Not infrastructure permission.", + ) id: str = Field(..., description="Task ID (`tsk_...`).") is_blocked: bool | None = Field( default=None, @@ -761,6 +816,10 @@ class TaskBlockingResponseDataItem(BaseModel): default=None, description="Key-value map of named URLs or references associated with the task. Returns an empty object when no links have been set.", ) + machine_rescope_receipts: dict[str, Any] | None = Field( + default=None, + description="Server-owned records of machine-applied local rescopes, keyed by question version. Never evidence that a human answered.", + ) metadata: dict[str, Any] | None = Field( default=None, description="Arbitrary key-value map of application-specific data stored alongside the task. Returns an empty object when no metadata has been set.", @@ -834,6 +893,9 @@ class TaskBlockingResponseDataItem(BaseModel): default=None, description="Minimum semantic version of `target_binary` that can run this work (for example `0.48.9`), in canonical `MAJOR.MINOR.PATCH[-prerelease][+build]` form. `null` when the task has no target.", ) + task_epic: str | None = Field( + default=None, description="First-class Epic membership; does not grant access to the task." + ) team: str | None = Field( default=None, description="ID of the team that owns this task (`tem_...`). `null` if the task is not scoped to a team.", @@ -981,6 +1043,9 @@ class TaskSubtasksResponseDataItem(BaseModel): default=None, description="Number of readable tasks marked as blocking this task, whether or not they are done (see `GET /tasks/{task}/blockers`). Computed on list/show reads; create/update responses may lag one read behind.", ) + blockers: list[str] | None = Field( + default=None, description="Visible blocker IDs when requested with include=blockers." + ) closed_at: datetime | None = Field( default=None, description="When the task was marked as done or otherwise closed (ISO 8601). `null` if the task is still open.", @@ -1019,6 +1084,10 @@ class TaskSubtasksResponseDataItem(BaseModel): default=None, description="Free-form grouping label. `null` when the task is not in an epic.", ) + human_answer_receipts: dict[str, Any] | None = Field( + default=None, + description="Server-owned authenticated human answer intent, keyed by question version. Not infrastructure permission.", + ) id: str = Field(..., description="Task ID (`tsk_...`).") is_blocked: bool | None = Field( default=None, @@ -1032,6 +1101,10 @@ class TaskSubtasksResponseDataItem(BaseModel): default=None, description="Key-value map of named URLs or references associated with the task. Returns an empty object when no links have been set.", ) + machine_rescope_receipts: dict[str, Any] | None = Field( + default=None, + description="Server-owned records of machine-applied local rescopes, keyed by question version. Never evidence that a human answered.", + ) metadata: dict[str, Any] | None = Field( default=None, description="Arbitrary key-value map of application-specific data stored alongside the task. Returns an empty object when no metadata has been set.", @@ -1105,6 +1178,9 @@ class TaskSubtasksResponseDataItem(BaseModel): default=None, description="Minimum semantic version of `target_binary` that can run this work (for example `0.48.9`), in canonical `MAJOR.MINOR.PATCH[-prerelease][+build]` form. `null` when the task has no target.", ) + task_epic: str | None = Field( + default=None, description="First-class Epic membership; does not grant access to the task." + ) team: str | None = Field( default=None, description="ID of the team that owns this task (`tem_...`). `null` if the task is not scoped to a team.", @@ -1399,6 +1475,7 @@ async def create(self, task: str, input: LeaseCreateInput) -> TaskSessionLease: Args: task: Task ID (`tsk_...`). input: Request body. + input.assign_if_ownerless: Assign an ownerless task to the authenticated system user while claiming its lease. input.force: Take the lease from a live but dead holder instead of returning a conflict. Releases the prior session's lease and claims the new one atomically. Always scoped to the task's assigned owner, same as an ordinary claim. input.harness: Bounded harness identifier. input.lease_duration_seconds: Requested lease lifetime in seconds; the task aggregate enforces its bounds. @@ -1534,6 +1611,8 @@ async def create(self, task: str, input: LinkCreateInput) -> TaskExternalLink: task: Task ID (`tsk_...`). input: Request body. input.external_scope: External container ID. + input.lease_id: Caller-held lease UUID, paired with lease_session_id. + input.lease_session_id: Caller-held coding-session UUID, paired with lease_id. input.object_id: External object ID. input.object_type: External object type. @@ -1640,6 +1719,7 @@ async def replace(self, task: str, input: TaskReplaceInput) -> Task: input.description: Updated long-form description. input.due_date: Updated due date in ISO 8601 format, or null to clear it. input.epic: Replacement grouping label. Pass null to clear it. + input.epic_id: First-class Epic ID; null clears membership. input.expected_version: Aggregate version returned by the latest task read. The update fails with `task_version_conflict` if the task changed first. input.lease_id: Current caller-held lease UUID. Must be paired with `lease_session_id`. input.lease_session_id: Current coding-session UUID. Must be paired with `lease_id`. @@ -1769,12 +1849,62 @@ async def blocking( response_type=TaskBlockingResponse, ) + async def human_answer(self, task: str, input: TaskHumanAnswerInput) -> dict[str, Any]: + """ + Submit a structured human answer + Records authenticated human owner intent. The receipt does not grant infrastructure authority. + + Args: + task: Task ID. + input: Request body. + input.drop_acceptance: Exact unique acceptance item to defer for rescope_local. + input.drop_verification: Exact associated verification items to defer. Entries identical to the acceptance item move automatically. + input.evidence: Evidence link or attachment reference. + input.expected_version: Version of the question answered. + input.outcome: evidence, access_granted, or rescope_local. + input.standing: Apply this explicit instruction to matching future pauses. + input.text: Optional answer or required access note. + + Returns: + Server-owned answer receipt. + """ + return await self._http.request( + f"/api/v1/tasks/{task}/human-answer", + method="POST", + body=input, + ) + + async def machine_rescope(self, task: str, input: TaskMachineRescopeInput) -> dict[str, Any]: + """ + Apply a recommended local rescope to an unanswered pause + Applies the `rescope_local` recommendation the Factory recorded with a pause, + once the server's own clock shows the question has gone unanswered for the + minimum age (24 hours). This is a different operation from submitting a human + answer: it takes the caller's existing Task edit authority, records a machine + receipt in `machine_rescope_receipts` and never a human one, and cannot grant + access, attach evidence, approve a sign-off or close the Task. Selections come + from the stored recommendation, never from the request. + + Args: + task: Task ID. + input: Request body. + input.expected_version: Version of the question observed. + + Returns: + Server-owned machine rescope receipt. + """ + return await self._http.request( + f"/api/v1/tasks/{task}/machine-rescope", + method="POST", + body=input, + ) + async def ownership_conversions( self, task: str, input: TaskOwnershipConversionsInput ) -> TaskOwnershipJob: """ Convert ownership of a connected task graph - Queues ownership changes for the connected task graph across parent, child, blocker, and blocking relationships. The selected tasks and their versions are frozen when queued. Each transfer checks the requesting user s current authority; conflicts fail the job without undoing completed transfers. + Queues ownership changes for the connected task graph across parent, child, blocker, and blocking relationships. The request checks access to the root and returns a job receipt. The worker discovers and validates the graph, then saves the selected tasks and versions before any transfer. Changes before preparation can affect the selection; retries reuse it. Validation failures are job outcomes. Each transfer checks the requesting user s current authority; conflicts fail the job without undoing completed transfers. Args: task: Root task (`tsk_...`). @@ -2134,6 +2264,7 @@ def create(self, task: str, input: LeaseCreateInput) -> TaskSessionLease: Args: task: Task ID (`tsk_...`). input: Request body. + input.assign_if_ownerless: Assign an ownerless task to the authenticated system user while claiming its lease. input.force: Take the lease from a live but dead holder instead of returning a conflict. Releases the prior session's lease and claims the new one atomically. Always scoped to the task's assigned owner, same as an ordinary claim. input.harness: Bounded harness identifier. input.lease_duration_seconds: Requested lease lifetime in seconds; the task aggregate enforces its bounds. @@ -2269,6 +2400,8 @@ def create(self, task: str, input: LinkCreateInput) -> TaskExternalLink: task: Task ID (`tsk_...`). input: Request body. input.external_scope: External container ID. + input.lease_id: Caller-held lease UUID, paired with lease_session_id. + input.lease_session_id: Caller-held coding-session UUID, paired with lease_id. input.object_id: External object ID. input.object_type: External object type. @@ -2375,6 +2508,7 @@ def replace(self, task: str, input: TaskReplaceInput) -> Task: input.description: Updated long-form description. input.due_date: Updated due date in ISO 8601 format, or null to clear it. input.epic: Replacement grouping label. Pass null to clear it. + input.epic_id: First-class Epic ID; null clears membership. input.expected_version: Aggregate version returned by the latest task read. The update fails with `task_version_conflict` if the task changed first. input.lease_id: Current caller-held lease UUID. Must be paired with `lease_session_id`. input.lease_session_id: Current coding-session UUID. Must be paired with `lease_id`. @@ -2504,12 +2638,58 @@ def blocking( response_type=TaskBlockingResponse, ) + def human_answer(self, task: str, input: TaskHumanAnswerInput) -> dict[str, Any]: + """ + Submit a structured human answer + Records authenticated human owner intent. The receipt does not grant infrastructure authority. + + Args: + task: Task ID. + input: Request body. + input.drop_acceptance: Exact unique acceptance item to defer for rescope_local. + input.drop_verification: Exact associated verification items to defer. Entries identical to the acceptance item move automatically. + input.evidence: Evidence link or attachment reference. + input.expected_version: Version of the question answered. + input.outcome: evidence, access_granted, or rescope_local. + input.standing: Apply this explicit instruction to matching future pauses. + input.text: Optional answer or required access note. + + Returns: + Server-owned answer receipt. + """ + return self._http.request(f"/api/v1/tasks/{task}/human-answer", method="POST", body=input) + + def machine_rescope(self, task: str, input: TaskMachineRescopeInput) -> dict[str, Any]: + """ + Apply a recommended local rescope to an unanswered pause + Applies the `rescope_local` recommendation the Factory recorded with a pause, + once the server's own clock shows the question has gone unanswered for the + minimum age (24 hours). This is a different operation from submitting a human + answer: it takes the caller's existing Task edit authority, records a machine + receipt in `machine_rescope_receipts` and never a human one, and cannot grant + access, attach evidence, approve a sign-off or close the Task. Selections come + from the stored recommendation, never from the request. + + Args: + task: Task ID. + input: Request body. + input.expected_version: Version of the question observed. + + Returns: + Server-owned machine rescope receipt. + """ + return self._http.request( + f"/api/v1/tasks/{task}/machine-rescope", + method="POST", + body=input, + ) + def ownership_conversions( self, task: str, input: TaskOwnershipConversionsInput ) -> TaskOwnershipJob: """ Convert ownership of a connected task graph - Queues ownership changes for the connected task graph across parent, child, blocker, and blocking relationships. The selected tasks and their versions are frozen when queued. Each transfer checks the requesting user s current authority; conflicts fail the job without undoing completed transfers. + Queues ownership changes for the connected task graph across parent, child, blocker, and blocking relationships. The request checks access to the root and returns a job receipt. The worker discovers and validates the graph, then saves the selected tasks and versions before any transfer. Changes before preparation can affect the selection; retries reuse it. Validation failures are job outcomes. Each transfer checks the requesting user s current authority; conflicts fail the job without undoing completed transfers. Args: task: Root task (`tsk_...`). diff --git a/src/archastro/platform/v1/resources/teams.py b/src/archastro/platform/v1/resources/teams.py index 322734f..ee94804 100644 --- a/src/archastro/platform/v1/resources/teams.py +++ b/src/archastro/platform/v1/resources/teams.py @@ -1,6 +1,6 @@ # Copyright (c) 2026 ArchAstro Inc. Licensed under the MIT License. # This file is auto-generated by @archastro/sdk-generator. Do not edit. -# Content hash: 7f84db90b859 +# Content hash: 3cd245e7f390 from __future__ import annotations @@ -12,7 +12,7 @@ from ...runtime.http_client import HttpClient, SyncHttpClient from ...types.common import CustomObject -from ...types.tasks import Task, TaskEnsureResult +from ...types.tasks import Task, TaskEnsureResult, TaskEpicEntity, TaskEpicEntityCollection from ...types.teams import Team, TeamDeleteImpactResponse, TeamInvite, TeamMembership from ...types.threads import Thread @@ -44,13 +44,27 @@ class MemberUpdateInput(TypedDict): 'New role to assign. One of `"owner"`, `"admin"`, or `"member"`.' +class TeamTaskEpicCreateInput(TypedDict, total=False): + "Create a task Epic" + + description: str | None + metadata: dict[str, Any] | None + name: Required[str] + state: str | None + user: str | None + + class TeamTaskCreateInputTask(TypedDict, total=False): + blockers: list[str] | None + "Existing task IDs (`tsk_...`) that block this task. Recorded atomically with creation; the task is not ready until these blockers are done." description: str | None "Optional long-form description or notes for the task. Supports plain text." due_date: datetime | None "Date and time by which the task should be completed (ISO 8601). Omit to create the task without a due date." epic: str | None "Optional free-form grouping label." + epic_id: str | None + "First-class Epic ID (`epc_...`)." id: str | None "Optional caller-generated task public ID (`tsk_...`). Persist it before creating a task when creation must survive a lost response. An existing ID returns 409 without modifying the task; read the task by ID to reconcile. Omit for a server-generated ID." links: dict[str, Any] | None @@ -113,6 +127,8 @@ class TeamTaskBySourceInput(TypedDict, total=False): "Initial task name." org: str | None "Explicit organization for privileged callers." + owner_user: str | None + "Initial assigned user; immutable on retries." source_id: Required[str] "Source identity, for example owner/repo#123." source_scope: Required[str] @@ -195,6 +211,24 @@ class TeamCreateInputAclAddItem(TypedDict, total=False): 'The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' +class TeamCreateInputAclAddDeniesItem(TypedDict, total=False): + actions: Required[list[str]] + 'Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.' + principal: str | None + 'The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.' + principal_type: Required[str] + 'The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' + + +class TeamCreateInputAclDeniesItem(TypedDict, total=False): + actions: Required[list[str]] + 'Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.' + principal: str | None + 'The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.' + principal_type: Required[str] + 'The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' + + class TeamCreateInputAclGrantsItem(TypedDict, total=False): actions: Required[list[str]] 'Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.' @@ -211,13 +245,28 @@ class TeamCreateInputAclRemoveItem(TypedDict, total=False): 'The kind of principal to remove. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' +class TeamCreateInputAclRemoveDeniesItem(TypedDict, total=False): + principal: str | None + 'The identifier of the principal to remove. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`. Omit when `principal_type` is `"everyone"`.' + principal_type: Required[str] + 'The kind of principal to remove. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' + + class TeamCreateInputAcl(TypedDict, total=False): add: list[TeamCreateInputAclAddItem] | None "Patch mode: grants to add or merge into the existing list. Cannot be combined with `grants`." + add_denies: list[TeamCreateInputAclAddDeniesItem] | None + "Patch mode: denies to add or merge, replacing any grant for the same principal." + denies: list[TeamCreateInputAclDeniesItem] | None + "Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support." grants: list[TeamCreateInputAclGrantsItem] | None "Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`." + preserve_denies: bool | None + "Retain current server denies atomically in replacement or patch mode; current denies win." remove: list[TeamCreateInputAclRemoveItem] | None "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`." + remove_denies: list[TeamCreateInputAclRemoveDeniesItem] | None + "Patch mode: principals whose denies should be removed." class TeamCreateInput(TypedDict, total=False): @@ -259,6 +308,24 @@ class TeamUpdateInputAclAddItem(TypedDict, total=False): 'The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' +class TeamUpdateInputAclAddDeniesItem(TypedDict, total=False): + actions: Required[list[str]] + 'Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.' + principal: str | None + 'The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.' + principal_type: Required[str] + 'The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' + + +class TeamUpdateInputAclDeniesItem(TypedDict, total=False): + actions: Required[list[str]] + 'Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.' + principal: str | None + 'The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.' + principal_type: Required[str] + 'The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' + + class TeamUpdateInputAclGrantsItem(TypedDict, total=False): actions: Required[list[str]] 'Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.' @@ -275,13 +342,28 @@ class TeamUpdateInputAclRemoveItem(TypedDict, total=False): 'The kind of principal to remove. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' +class TeamUpdateInputAclRemoveDeniesItem(TypedDict, total=False): + principal: str | None + 'The identifier of the principal to remove. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`. Omit when `principal_type` is `"everyone"`.' + principal_type: Required[str] + 'The kind of principal to remove. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' + + class TeamUpdateInputAcl(TypedDict, total=False): add: list[TeamUpdateInputAclAddItem] | None "Patch mode: grants to add or merge into the existing list. Cannot be combined with `grants`." + add_denies: list[TeamUpdateInputAclAddDeniesItem] | None + "Patch mode: denies to add or merge, replacing any grant for the same principal." + denies: list[TeamUpdateInputAclDeniesItem] | None + "Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support." grants: list[TeamUpdateInputAclGrantsItem] | None "Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`." + preserve_denies: bool | None + "Retain current server denies atomically in replacement or patch mode; current denies win." remove: list[TeamUpdateInputAclRemoveItem] | None "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`." + remove_denies: list[TeamUpdateInputAclRemoveDeniesItem] | None + "Patch mode: principals whose denies should be removed." class TeamUpdateInputProfilePicture(TypedDict, total=False): @@ -334,6 +416,36 @@ class TeamCustomObjectListResponseDataItemAclAddItem(BaseModel): ) +class TeamCustomObjectListResponseDataItemAclAddDeniesItem(BaseModel): + actions: list[str] = Field( + ..., + description='Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.', + ) + principal: str | None = Field( + default=None, + description='The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.', + ) + principal_type: str = Field( + ..., + description='The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.', + ) + + +class TeamCustomObjectListResponseDataItemAclDeniesItem(BaseModel): + actions: list[str] = Field( + ..., + description='Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.', + ) + principal: str | None = Field( + default=None, + description='The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.', + ) + principal_type: str = Field( + ..., + description='The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.', + ) + + class TeamCustomObjectListResponseDataItemAclGrantsItem(BaseModel): actions: list[str] = Field( ..., @@ -360,19 +472,45 @@ class TeamCustomObjectListResponseDataItemAclRemoveItem(BaseModel): ) +class TeamCustomObjectListResponseDataItemAclRemoveDeniesItem(BaseModel): + principal: str | None = Field( + default=None, + description='The identifier of the principal to remove. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`. Omit when `principal_type` is `"everyone"`.', + ) + principal_type: str = Field( + ..., + description='The kind of principal to remove. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.', + ) + + class TeamCustomObjectListResponseDataItemAcl(BaseModel): add: list[TeamCustomObjectListResponseDataItemAclAddItem] | None = Field( default=None, description="Patch mode: grants to add or merge into the existing list. Cannot be combined with `grants`.", ) + add_denies: list[TeamCustomObjectListResponseDataItemAclAddDeniesItem] | None = Field( + default=None, + description="Patch mode: denies to add or merge, replacing any grant for the same principal.", + ) + denies: list[TeamCustomObjectListResponseDataItemAclDeniesItem] | None = Field( + default=None, + description="Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support.", + ) grants: list[TeamCustomObjectListResponseDataItemAclGrantsItem] | None = Field( default=None, description="Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", ) + preserve_denies: bool | None = Field( + default=None, + description="Retain current server denies atomically in replacement or patch mode; current denies win.", + ) remove: list[TeamCustomObjectListResponseDataItemAclRemoveItem] | None = Field( default=None, description="Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", ) + remove_denies: list[TeamCustomObjectListResponseDataItemAclRemoveDeniesItem] | None = Field( + default=None, description="Patch mode: principals whose denies should be removed." + ) class TeamCustomObjectListResponseDataItem(BaseModel): @@ -456,6 +594,36 @@ class MemberListResponseDataItemAgentAclAddItem(BaseModel): ) +class MemberListResponseDataItemAgentAclAddDeniesItem(BaseModel): + actions: list[str] = Field( + ..., + description='Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.', + ) + principal: str | None = Field( + default=None, + description='The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.', + ) + principal_type: str = Field( + ..., + description='The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.', + ) + + +class MemberListResponseDataItemAgentAclDeniesItem(BaseModel): + actions: list[str] = Field( + ..., + description='Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.', + ) + principal: str | None = Field( + default=None, + description='The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.', + ) + principal_type: str = Field( + ..., + description='The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.', + ) + + class MemberListResponseDataItemAgentAclGrantsItem(BaseModel): actions: list[str] = Field( ..., @@ -482,19 +650,45 @@ class MemberListResponseDataItemAgentAclRemoveItem(BaseModel): ) +class MemberListResponseDataItemAgentAclRemoveDeniesItem(BaseModel): + principal: str | None = Field( + default=None, + description='The identifier of the principal to remove. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`. Omit when `principal_type` is `"everyone"`.', + ) + principal_type: str = Field( + ..., + description='The kind of principal to remove. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.', + ) + + class MemberListResponseDataItemAgentAcl(BaseModel): add: list[MemberListResponseDataItemAgentAclAddItem] | None = Field( default=None, description="Patch mode: grants to add or merge into the existing list. Cannot be combined with `grants`.", ) + add_denies: list[MemberListResponseDataItemAgentAclAddDeniesItem] | None = Field( + default=None, + description="Patch mode: denies to add or merge, replacing any grant for the same principal.", + ) + denies: list[MemberListResponseDataItemAgentAclDeniesItem] | None = Field( + default=None, + description="Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support.", + ) grants: list[MemberListResponseDataItemAgentAclGrantsItem] | None = Field( default=None, description="Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", ) + preserve_denies: bool | None = Field( + default=None, + description="Retain current server denies atomically in replacement or patch mode; current denies win.", + ) remove: list[MemberListResponseDataItemAgentAclRemoveItem] | None = Field( default=None, description="Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", ) + remove_denies: list[MemberListResponseDataItemAgentAclRemoveDeniesItem] | None = Field( + default=None, description="Patch mode: principals whose denies should be removed." + ) class MemberListResponseDataItemAgentSourceSolutionCurrentSolutionOrgLogo(BaseModel): @@ -1408,6 +1602,9 @@ class TeamTaskListResponseDataItem(BaseModel): default=None, description="Number of readable tasks marked as blocking this task, whether or not they are done (see `GET /tasks/{task}/blockers`). Computed on list/show reads; create/update responses may lag one read behind.", ) + blockers: list[str] | None = Field( + default=None, description="Visible blocker IDs when requested with include=blockers." + ) closed_at: datetime | None = Field( default=None, description="When the task was marked as done or otherwise closed (ISO 8601). `null` if the task is still open.", @@ -1446,6 +1643,10 @@ class TeamTaskListResponseDataItem(BaseModel): default=None, description="Free-form grouping label. `null` when the task is not in an epic.", ) + human_answer_receipts: dict[str, Any] | None = Field( + default=None, + description="Server-owned authenticated human answer intent, keyed by question version. Not infrastructure permission.", + ) id: str = Field(..., description="Task ID (`tsk_...`).") is_blocked: bool | None = Field( default=None, @@ -1459,6 +1660,10 @@ class TeamTaskListResponseDataItem(BaseModel): default=None, description="Key-value map of named URLs or references associated with the task. Returns an empty object when no links have been set.", ) + machine_rescope_receipts: dict[str, Any] | None = Field( + default=None, + description="Server-owned records of machine-applied local rescopes, keyed by question version. Never evidence that a human answered.", + ) metadata: dict[str, Any] | None = Field( default=None, description="Arbitrary key-value map of application-specific data stored alongside the task. Returns an empty object when no metadata has been set.", @@ -1532,6 +1737,9 @@ class TeamTaskListResponseDataItem(BaseModel): default=None, description="Minimum semantic version of `target_binary` that can run this work (for example `0.48.9`), in canonical `MAJOR.MINOR.PATCH[-prerelease][+build]` form. `null` when the task has no target.", ) + task_epic: str | None = Field( + default=None, description="First-class Epic membership; does not grant access to the task." + ) team: str | None = Field( default=None, description="ID of the team that owns this task (`tem_...`). `null` if the task is not scoped to a team.", @@ -1685,6 +1893,9 @@ class TeamTaskBlockerCyclesResponseDataItemTasksItem(BaseModel): default=None, description="Number of readable tasks marked as blocking this task, whether or not they are done (see `GET /tasks/{task}/blockers`). Computed on list/show reads; create/update responses may lag one read behind.", ) + blockers: list[str] | None = Field( + default=None, description="Visible blocker IDs when requested with include=blockers." + ) closed_at: datetime | None = Field( default=None, description="When the task was marked as done or otherwise closed (ISO 8601). `null` if the task is still open.", @@ -1723,6 +1934,10 @@ class TeamTaskBlockerCyclesResponseDataItemTasksItem(BaseModel): default=None, description="Free-form grouping label. `null` when the task is not in an epic.", ) + human_answer_receipts: dict[str, Any] | None = Field( + default=None, + description="Server-owned authenticated human answer intent, keyed by question version. Not infrastructure permission.", + ) id: str = Field(..., description="Task ID (`tsk_...`).") is_blocked: bool | None = Field( default=None, @@ -1736,6 +1951,10 @@ class TeamTaskBlockerCyclesResponseDataItemTasksItem(BaseModel): default=None, description="Key-value map of named URLs or references associated with the task. Returns an empty object when no links have been set.", ) + machine_rescope_receipts: dict[str, Any] | None = Field( + default=None, + description="Server-owned records of machine-applied local rescopes, keyed by question version. Never evidence that a human answered.", + ) metadata: dict[str, Any] | None = Field( default=None, description="Arbitrary key-value map of application-specific data stored alongside the task. Returns an empty object when no metadata has been set.", @@ -1809,6 +2028,9 @@ class TeamTaskBlockerCyclesResponseDataItemTasksItem(BaseModel): default=None, description="Minimum semantic version of `target_binary` that can run this work (for example `0.48.9`), in canonical `MAJOR.MINOR.PATCH[-prerelease][+build]` form. `null` when the task has no target.", ) + task_epic: str | None = Field( + default=None, description="First-class Epic membership; does not grant access to the task." + ) team: str | None = Field( default=None, description="ID of the team that owns this task (`tem_...`). `null` if the task is not scoped to a team.", @@ -1843,24 +2065,7 @@ class TeamTaskBlockerCyclesResponse(BaseModel): has_more: bool -class TeamTaskMetricsResponse(BaseModel): - """ - Successful response - """ - - completed: int - created: int - days: int - end_at: datetime - open: int - series: list[dict[str, Any]] = Field( - ..., - description="Zero-filled UTC-day buckets with `date`, end-of-day `open`, `created`, and `completed`.", - ) - start_at: datetime - - -class TeamTaskReadyResponseDataItemTaskCreatedByActorProfilePicture(BaseModel): +class TeamTaskByExternalReferenceResponseDataItemCreatedByActorProfilePicture(BaseModel): file: str | None = Field( default=None, description="ID of the underlying storage file (`fil_...`). `null` when the image is not backed by a platform storage file.", @@ -1889,7 +2094,7 @@ class TeamTaskReadyResponseDataItemTaskCreatedByActorProfilePicture(BaseModel): ) -class TeamTaskReadyResponseDataItemTaskCreatedByActor(BaseModel): +class TeamTaskByExternalReferenceResponseDataItemCreatedByActor(BaseModel): alias: str | None = Field( default=None, description="Short handle or alias for the actor, used as an alternate display identifier. `null` if not configured.", @@ -1902,13 +2107,15 @@ class TeamTaskReadyResponseDataItemTaskCreatedByActor(BaseModel): default=None, description="Display name of the actor shown in the UI. `null` if no name is set.", ) - profile_picture: TeamTaskReadyResponseDataItemTaskCreatedByActorProfilePicture | None = Field( + profile_picture: ( + TeamTaskByExternalReferenceResponseDataItemCreatedByActorProfilePicture | None + ) = Field( default=None, description="Profile picture for the actor. `null` if the actor has no profile picture.", ) -class TeamTaskReadyResponseDataItemTaskCurrentLease(BaseModel): +class TeamTaskByExternalReferenceResponseDataItemCurrentLease(BaseModel): expires_at: datetime = Field( ..., description="Server-calculated lease expiry in ISO 8601 format." ) @@ -1918,7 +2125,7 @@ class TeamTaskReadyResponseDataItemTaskCurrentLease(BaseModel): ) -class TeamTaskReadyResponseDataItemTaskOwnerActorProfilePicture(BaseModel): +class TeamTaskByExternalReferenceResponseDataItemOwnerActorProfilePicture(BaseModel): file: str | None = Field( default=None, description="ID of the underlying storage file (`fil_...`). `null` when the image is not backed by a platform storage file.", @@ -1947,7 +2154,7 @@ class TeamTaskReadyResponseDataItemTaskOwnerActorProfilePicture(BaseModel): ) -class TeamTaskReadyResponseDataItemTaskOwnerActor(BaseModel): +class TeamTaskByExternalReferenceResponseDataItemOwnerActor(BaseModel): alias: str | None = Field( default=None, description="Short handle or alias for the actor, used as an alternate display identifier. `null` if not configured.", @@ -1960,13 +2167,15 @@ class TeamTaskReadyResponseDataItemTaskOwnerActor(BaseModel): default=None, description="Display name of the actor shown in the UI. `null` if no name is set.", ) - profile_picture: TeamTaskReadyResponseDataItemTaskOwnerActorProfilePicture | None = Field( - default=None, - description="Profile picture for the actor. `null` if the actor has no profile picture.", + profile_picture: TeamTaskByExternalReferenceResponseDataItemOwnerActorProfilePicture | None = ( + Field( + default=None, + description="Profile picture for the actor. `null` if the actor has no profile picture.", + ) ) -class TeamTaskReadyResponseDataItemTask(BaseModel): +class TeamTaskByExternalReferenceResponseDataItem(BaseModel): agent: str | None = Field( default=None, description="ID of the agent that owns this task (`agi_...`). `null` if the task is scoped to a team or user.", @@ -1979,6 +2188,9 @@ class TeamTaskReadyResponseDataItemTask(BaseModel): default=None, description="Number of readable tasks marked as blocking this task, whether or not they are done (see `GET /tasks/{task}/blockers`). Computed on list/show reads; create/update responses may lag one read behind.", ) + blockers: list[str] | None = Field( + default=None, description="Visible blocker IDs when requested with include=blockers." + ) closed_at: datetime | None = Field( default=None, description="When the task was marked as done or otherwise closed (ISO 8601). `null` if the task is still open.", @@ -1989,7 +2201,7 @@ class TeamTaskReadyResponseDataItemTask(BaseModel): created_at: datetime | None = Field( default=None, description="When the task was created (ISO 8601)." ) - created_by_actor: TeamTaskReadyResponseDataItemTaskCreatedByActor | None = Field( + created_by_actor: TeamTaskByExternalReferenceResponseDataItemCreatedByActor | None = Field( default=None, description="Resolved creator details including `id`, `name`, `alias`, and `profile_picture`. `null` if no creator is set or the creator cannot be resolved (e.g. creating agent was deleted).", ) @@ -2001,7 +2213,7 @@ class TeamTaskReadyResponseDataItemTask(BaseModel): default=None, description="ID of the user who created this task (`usr_...`). `null` if the task was created by an agent, or if creator provenance was cleared after the creator was deleted.", ) - current_lease: TeamTaskReadyResponseDataItemTaskCurrentLease | None = Field( + current_lease: TeamTaskByExternalReferenceResponseDataItemCurrentLease | None = Field( default=None, description="Viewer-safe live coding-session lease summary. `null` when the task is unleased or the projected lease has expired. Fencing identifiers are never included.", ) @@ -2017,6 +2229,10 @@ class TeamTaskReadyResponseDataItemTask(BaseModel): default=None, description="Free-form grouping label. `null` when the task is not in an epic.", ) + human_answer_receipts: dict[str, Any] | None = Field( + default=None, + description="Server-owned authenticated human answer intent, keyed by question version. Not infrastructure permission.", + ) id: str = Field(..., description="Task ID (`tsk_...`).") is_blocked: bool | None = Field( default=None, @@ -2030,6 +2246,10 @@ class TeamTaskReadyResponseDataItemTask(BaseModel): default=None, description="Key-value map of named URLs or references associated with the task. Returns an empty object when no links have been set.", ) + machine_rescope_receipts: dict[str, Any] | None = Field( + default=None, + description="Server-owned records of machine-applied local rescopes, keyed by question version. Never evidence that a human answered.", + ) metadata: dict[str, Any] | None = Field( default=None, description="Arbitrary key-value map of application-specific data stored alongside the task. Returns an empty object when no metadata has been set.", @@ -2039,7 +2259,7 @@ class TeamTaskReadyResponseDataItemTask(BaseModel): default=None, description="ID of the organization this task belongs to (`org_...`). `null` for tasks outside an org context.", ) - owner_actor: TeamTaskReadyResponseDataItemTaskOwnerActor | None = Field( + owner_actor: TeamTaskByExternalReferenceResponseDataItemOwnerActor | None = Field( default=None, description="Resolved owner details including `id`, `name`, `alias`, and `profile_picture`. `null` if the task is unassigned or the owner cannot be resolved (e.g. assigned agent was deleted).", ) @@ -2103,6 +2323,9 @@ class TeamTaskReadyResponseDataItemTask(BaseModel): default=None, description="Minimum semantic version of `target_binary` that can run this work (for example `0.48.9`), in canonical `MAJOR.MINOR.PATCH[-prerelease][+build]` form. `null` when the task has no target.", ) + task_epic: str | None = Field( + default=None, description="First-class Epic membership; does not grant access to the task." + ) team: str | None = Field( default=None, description="ID of the team that owns this task (`tem_...`). `null` if the task is not scoped to a team.", @@ -2120,35 +2343,32 @@ class TeamTaskReadyResponseDataItemTask(BaseModel): ) -class TeamTaskReadyResponseDataItem(BaseModel): - readiness: Literal["ready", "blocked", "leased"] = Field( - ..., description="One of `ready`, `blocked`, or `leased`." - ) - reason: Literal["open_blockers", "active_lease"] | None = Field( - default=None, - description="Stable exclusion reason: `open_blockers` or `active_lease`; omitted when ready.", - ) - task: TeamTaskReadyResponseDataItemTask = Field( - ..., description="The task evaluated for readiness." - ) +class TeamTaskByExternalReferenceResponse(BaseModel): + """ + Successful response + """ + data: list[TeamTaskByExternalReferenceResponseDataItem] -class TeamTaskReadyResponse(BaseModel): + +class TeamTaskMetricsResponse(BaseModel): """ Successful response """ - after_cursor: str | None = None - authoritative: bool = Field( + completed: int + created: int + days: int + end_at: datetime + open: int + series: list[dict[str, Any]] = Field( ..., - description="Always false because projections can lag writes and a later claim can race this read.", + description="Zero-filled UTC-day buckets with `date`, end-of-day `open`, `created`, and `completed`.", ) - before_cursor: str | None = None - data: list[TeamTaskReadyResponseDataItem] - has_more: bool + start_at: datetime -class TeamTaskSearchResponseDataItemCreatedByActorProfilePicture(BaseModel): +class TeamTaskReadyResponseDataItemTaskCreatedByActorProfilePicture(BaseModel): file: str | None = Field( default=None, description="ID of the underlying storage file (`fil_...`). `null` when the image is not backed by a platform storage file.", @@ -2177,7 +2397,7 @@ class TeamTaskSearchResponseDataItemCreatedByActorProfilePicture(BaseModel): ) -class TeamTaskSearchResponseDataItemCreatedByActor(BaseModel): +class TeamTaskReadyResponseDataItemTaskCreatedByActor(BaseModel): alias: str | None = Field( default=None, description="Short handle or alias for the actor, used as an alternate display identifier. `null` if not configured.", @@ -2190,13 +2410,13 @@ class TeamTaskSearchResponseDataItemCreatedByActor(BaseModel): default=None, description="Display name of the actor shown in the UI. `null` if no name is set.", ) - profile_picture: TeamTaskSearchResponseDataItemCreatedByActorProfilePicture | None = Field( + profile_picture: TeamTaskReadyResponseDataItemTaskCreatedByActorProfilePicture | None = Field( default=None, description="Profile picture for the actor. `null` if the actor has no profile picture.", ) -class TeamTaskSearchResponseDataItemCurrentLease(BaseModel): +class TeamTaskReadyResponseDataItemTaskCurrentLease(BaseModel): expires_at: datetime = Field( ..., description="Server-calculated lease expiry in ISO 8601 format." ) @@ -2206,7 +2426,7 @@ class TeamTaskSearchResponseDataItemCurrentLease(BaseModel): ) -class TeamTaskSearchResponseDataItemOwnerActorProfilePicture(BaseModel): +class TeamTaskReadyResponseDataItemTaskOwnerActorProfilePicture(BaseModel): file: str | None = Field( default=None, description="ID of the underlying storage file (`fil_...`). `null` when the image is not backed by a platform storage file.", @@ -2235,7 +2455,7 @@ class TeamTaskSearchResponseDataItemOwnerActorProfilePicture(BaseModel): ) -class TeamTaskSearchResponseDataItemOwnerActor(BaseModel): +class TeamTaskReadyResponseDataItemTaskOwnerActor(BaseModel): alias: str | None = Field( default=None, description="Short handle or alias for the actor, used as an alternate display identifier. `null` if not configured.", @@ -2248,13 +2468,13 @@ class TeamTaskSearchResponseDataItemOwnerActor(BaseModel): default=None, description="Display name of the actor shown in the UI. `null` if no name is set.", ) - profile_picture: TeamTaskSearchResponseDataItemOwnerActorProfilePicture | None = Field( + profile_picture: TeamTaskReadyResponseDataItemTaskOwnerActorProfilePicture | None = Field( default=None, description="Profile picture for the actor. `null` if the actor has no profile picture.", ) -class TeamTaskSearchResponseDataItem(BaseModel): +class TeamTaskReadyResponseDataItemTask(BaseModel): agent: str | None = Field( default=None, description="ID of the agent that owns this task (`agi_...`). `null` if the task is scoped to a team or user.", @@ -2267,6 +2487,9 @@ class TeamTaskSearchResponseDataItem(BaseModel): default=None, description="Number of readable tasks marked as blocking this task, whether or not they are done (see `GET /tasks/{task}/blockers`). Computed on list/show reads; create/update responses may lag one read behind.", ) + blockers: list[str] | None = Field( + default=None, description="Visible blocker IDs when requested with include=blockers." + ) closed_at: datetime | None = Field( default=None, description="When the task was marked as done or otherwise closed (ISO 8601). `null` if the task is still open.", @@ -2277,7 +2500,7 @@ class TeamTaskSearchResponseDataItem(BaseModel): created_at: datetime | None = Field( default=None, description="When the task was created (ISO 8601)." ) - created_by_actor: TeamTaskSearchResponseDataItemCreatedByActor | None = Field( + created_by_actor: TeamTaskReadyResponseDataItemTaskCreatedByActor | None = Field( default=None, description="Resolved creator details including `id`, `name`, `alias`, and `profile_picture`. `null` if no creator is set or the creator cannot be resolved (e.g. creating agent was deleted).", ) @@ -2289,7 +2512,7 @@ class TeamTaskSearchResponseDataItem(BaseModel): default=None, description="ID of the user who created this task (`usr_...`). `null` if the task was created by an agent, or if creator provenance was cleared after the creator was deleted.", ) - current_lease: TeamTaskSearchResponseDataItemCurrentLease | None = Field( + current_lease: TeamTaskReadyResponseDataItemTaskCurrentLease | None = Field( default=None, description="Viewer-safe live coding-session lease summary. `null` when the task is unleased or the projected lease has expired. Fencing identifiers are never included.", ) @@ -2305,6 +2528,10 @@ class TeamTaskSearchResponseDataItem(BaseModel): default=None, description="Free-form grouping label. `null` when the task is not in an epic.", ) + human_answer_receipts: dict[str, Any] | None = Field( + default=None, + description="Server-owned authenticated human answer intent, keyed by question version. Not infrastructure permission.", + ) id: str = Field(..., description="Task ID (`tsk_...`).") is_blocked: bool | None = Field( default=None, @@ -2318,6 +2545,10 @@ class TeamTaskSearchResponseDataItem(BaseModel): default=None, description="Key-value map of named URLs or references associated with the task. Returns an empty object when no links have been set.", ) + machine_rescope_receipts: dict[str, Any] | None = Field( + default=None, + description="Server-owned records of machine-applied local rescopes, keyed by question version. Never evidence that a human answered.", + ) metadata: dict[str, Any] | None = Field( default=None, description="Arbitrary key-value map of application-specific data stored alongside the task. Returns an empty object when no metadata has been set.", @@ -2327,7 +2558,7 @@ class TeamTaskSearchResponseDataItem(BaseModel): default=None, description="ID of the organization this task belongs to (`org_...`). `null` for tasks outside an org context.", ) - owner_actor: TeamTaskSearchResponseDataItemOwnerActor | None = Field( + owner_actor: TeamTaskReadyResponseDataItemTaskOwnerActor | None = Field( default=None, description="Resolved owner details including `id`, `name`, `alias`, and `profile_picture`. `null` if the task is unassigned or the owner cannot be resolved (e.g. assigned agent was deleted).", ) @@ -2391,6 +2622,9 @@ class TeamTaskSearchResponseDataItem(BaseModel): default=None, description="Minimum semantic version of `target_binary` that can run this work (for example `0.48.9`), in canonical `MAJOR.MINOR.PATCH[-prerelease][+build]` form. `null` when the task has no target.", ) + task_epic: str | None = Field( + default=None, description="First-class Epic membership; does not grant access to the task." + ) team: str | None = Field( default=None, description="ID of the team that owns this task (`tem_...`). `null` if the task is not scoped to a team.", @@ -2408,7 +2642,309 @@ class TeamTaskSearchResponseDataItem(BaseModel): ) -class TeamTaskSearchResponse(BaseModel): +class TeamTaskReadyResponseDataItem(BaseModel): + readiness: Literal["ready", "blocked", "leased"] = Field( + ..., description="One of `ready`, `blocked`, or `leased`." + ) + reason: Literal["open_blockers", "active_lease"] | None = Field( + default=None, + description="Stable exclusion reason: `open_blockers` or `active_lease`; omitted when ready.", + ) + task: TeamTaskReadyResponseDataItemTask = Field( + ..., description="The task evaluated for readiness." + ) + + +class TeamTaskReadyResponse(BaseModel): + """ + Successful response + """ + + after_cursor: str | None = None + authoritative: bool = Field( + ..., + description="Always false because projections can lag writes and a later claim can race this read.", + ) + before_cursor: str | None = None + data: list[TeamTaskReadyResponseDataItem] + has_more: bool + + +class TeamTaskSearchResponseDataItemCreatedByActorProfilePicture(BaseModel): + file: str | None = Field( + default=None, + description="ID of the underlying storage file (`fil_...`). `null` when the image is not backed by a platform storage file.", + ) + height: int | None = Field( + default=None, description="Height of the image in pixels. `null` if not known." + ) + media: str | None = Field( + default=None, + description="ID of the associated media record (`med_...`). `null` when the image is not linked to a media entity.", + ) + mime_type: str | None = Field( + default=None, + description='MIME type of the image, e.g. `"image/png"` or `"image/jpeg"`. `null` if not known.', + ) + refresh_url: str | None = Field( + default=None, + description="Endpoint URL you can call to obtain a fresh signed `url` when the current one has expired. `null` if the URL does not require refreshing.", + ) + url: str | None = Field( + default=None, + description="Signed or public URL for downloading the image. May be time-limited; use `refresh_url` to obtain a new URL when this one expires.", + ) + width: int | None = Field( + default=None, description="Width of the image in pixels. `null` if not known." + ) + + +class TeamTaskSearchResponseDataItemCreatedByActor(BaseModel): + alias: str | None = Field( + default=None, + description="Short handle or alias for the actor, used as an alternate display identifier. `null` if not configured.", + ) + id: str | None = Field( + default=None, + description='Composite actor identifier. Format is `"user-"` for human users or `"agent-"` for agents.', + ) + name: str | None = Field( + default=None, + description="Display name of the actor shown in the UI. `null` if no name is set.", + ) + profile_picture: TeamTaskSearchResponseDataItemCreatedByActorProfilePicture | None = Field( + default=None, + description="Profile picture for the actor. `null` if the actor has no profile picture.", + ) + + +class TeamTaskSearchResponseDataItemCurrentLease(BaseModel): + expires_at: datetime = Field( + ..., description="Server-calculated lease expiry in ISO 8601 format." + ) + harness: str = Field(..., description="Bounded harness identifier for the coding session.") + session_name: str = Field( + ..., description="Display name supplied by the coding session that holds the lease." + ) + + +class TeamTaskSearchResponseDataItemOwnerActorProfilePicture(BaseModel): + file: str | None = Field( + default=None, + description="ID of the underlying storage file (`fil_...`). `null` when the image is not backed by a platform storage file.", + ) + height: int | None = Field( + default=None, description="Height of the image in pixels. `null` if not known." + ) + media: str | None = Field( + default=None, + description="ID of the associated media record (`med_...`). `null` when the image is not linked to a media entity.", + ) + mime_type: str | None = Field( + default=None, + description='MIME type of the image, e.g. `"image/png"` or `"image/jpeg"`. `null` if not known.', + ) + refresh_url: str | None = Field( + default=None, + description="Endpoint URL you can call to obtain a fresh signed `url` when the current one has expired. `null` if the URL does not require refreshing.", + ) + url: str | None = Field( + default=None, + description="Signed or public URL for downloading the image. May be time-limited; use `refresh_url` to obtain a new URL when this one expires.", + ) + width: int | None = Field( + default=None, description="Width of the image in pixels. `null` if not known." + ) + + +class TeamTaskSearchResponseDataItemOwnerActor(BaseModel): + alias: str | None = Field( + default=None, + description="Short handle or alias for the actor, used as an alternate display identifier. `null` if not configured.", + ) + id: str | None = Field( + default=None, + description='Composite actor identifier. Format is `"user-"` for human users or `"agent-"` for agents.', + ) + name: str | None = Field( + default=None, + description="Display name of the actor shown in the UI. `null` if no name is set.", + ) + profile_picture: TeamTaskSearchResponseDataItemOwnerActorProfilePicture | None = Field( + default=None, + description="Profile picture for the actor. `null` if the actor has no profile picture.", + ) + + +class TeamTaskSearchResponseDataItem(BaseModel): + agent: str | None = Field( + default=None, + description="ID of the agent that owns this task (`agi_...`). `null` if the task is scoped to a team or user.", + ) + aggregate_version: int | None = Field( + default=None, + description="Event-stream version for optimistic update fencing. Pass this value as `expected_version` on an update to reject concurrent writes.", + ) + blocked_by_count: int | None = Field( + default=None, + description="Number of readable tasks marked as blocking this task, whether or not they are done (see `GET /tasks/{task}/blockers`). Computed on list/show reads; create/update responses may lag one read behind.", + ) + blockers: list[str] | None = Field( + default=None, description="Visible blocker IDs when requested with include=blockers." + ) + closed_at: datetime | None = Field( + default=None, + description="When the task was marked as done or otherwise closed (ISO 8601). `null` if the task is still open.", + ) + comments_count: int | None = Field( + default=None, description="Total number of comments posted on this task." + ) + created_at: datetime | None = Field( + default=None, description="When the task was created (ISO 8601)." + ) + created_by_actor: TeamTaskSearchResponseDataItemCreatedByActor | None = Field( + default=None, + description="Resolved creator details including `id`, `name`, `alias`, and `profile_picture`. `null` if no creator is set or the creator cannot be resolved (e.g. creating agent was deleted).", + ) + created_by_agent: str | None = Field( + default=None, + description="ID of the agent that created this task (`agi_...`). `null` if the task was created by a human user, or if the creating agent was later deleted.", + ) + created_by_user: str | None = Field( + default=None, + description="ID of the user who created this task (`usr_...`). `null` if the task was created by an agent, or if creator provenance was cleared after the creator was deleted.", + ) + current_lease: TeamTaskSearchResponseDataItemCurrentLease | None = Field( + default=None, + description="Viewer-safe live coding-session lease summary. `null` when the task is unleased or the projected lease has expired. Fencing identifiers are never included.", + ) + description: str | None = Field( + default=None, + description="Long-form description or notes for the task. `null` if no description has been provided.", + ) + due_date: datetime | None = Field( + default=None, + description="Date and time by which the task should be completed (ISO 8601). `null` if no due date is set.", + ) + epic: str | None = Field( + default=None, + description="Free-form grouping label. `null` when the task is not in an epic.", + ) + human_answer_receipts: dict[str, Any] | None = Field( + default=None, + description="Server-owned authenticated human answer intent, keyed by question version. Not infrastructure permission.", + ) + id: str = Field(..., description="Task ID (`tsk_...`).") + is_blocked: bool | None = Field( + default=None, + description="`true` while at least one blocking task is not yet done. Informational only - a blocked task can still change status - and derived at read time, so the task un-blocks automatically when its last open blocker completes. Computed on reads, including mutation responses.", + ) + is_stalled: bool | None = Field( + default=None, + description="True exactly when status is in_progress and the task has no lease or its lease expiry is in the past. Derived at read time from status and lease expiry, including on unannotated reads.", + ) + links: dict[str, Any] | None = Field( + default=None, + description="Key-value map of named URLs or references associated with the task. Returns an empty object when no links have been set.", + ) + machine_rescope_receipts: dict[str, Any] | None = Field( + default=None, + description="Server-owned records of machine-applied local rescopes, keyed by question version. Never evidence that a human answered.", + ) + metadata: dict[str, Any] | None = Field( + default=None, + description="Arbitrary key-value map of application-specific data stored alongside the task. Returns an empty object when no metadata has been set.", + ) + name: str = Field(..., description="Human-readable title of the task.") + org: str | None = Field( + default=None, + description="ID of the organization this task belongs to (`org_...`). `null` for tasks outside an org context.", + ) + owner_actor: TeamTaskSearchResponseDataItemOwnerActor | None = Field( + default=None, + description="Resolved owner details including `id`, `name`, `alias`, and `profile_picture`. `null` if the task is unassigned or the owner cannot be resolved (e.g. assigned agent was deleted).", + ) + owner_agent: str | None = Field( + default=None, + description="ID of the agent assigned as owner (`agi_...`). `null` if the owner is a human user, the task is unassigned, or the assigned agent was deleted.", + ) + owner_user: str | None = Field( + default=None, + description="ID of the user assigned as owner (`usr_...`). `null` if the owner is an agent, the task is unassigned, or the assigned agent was deleted.", + ) + parent: str | None = Field( + default=None, + description="ID of the parent task when this task is a subtask (`tsk_...`). `null` for top-level tasks or when the parent is not readable. Subtasks nest exactly one level.", + ) + priority: int | None = Field( + default=None, + description="Priority level of the task from `0` (highest) to `4` (lowest). Defaults to `2` (medium) when not explicitly set.", + ) + project_id: str | None = Field( + default=None, + description="Optional project ID (`prj_...`). Membership does not change task visibility.", + ) + sandbox: str | None = Field( + default=None, + description="ID of the developer sandbox this task is scoped to (`dsb_...`). `null` for tasks outside a sandbox environment.", + ) + source_id: str | None = Field( + default=None, + description="Source object identity (for example `ArchAstro/firstlanding`). `null` when the task has no source.", + ) + source_scope: str | None = Field( + default=None, + description="Container of the work this task is about (for example `github.com`). `null` when the task has no source. Set together with `source_type` and `source_id`.", + ) + source_type: str | None = Field( + default=None, + description="Kind of source object (for example `repository`). `null` when the task has no source.", + ) + stalled_since: datetime | None = Field( + default=None, + description="Lease expiry for a stalled task, or its last update when no lease expiry exists. Null when not stalled.", + ) + status: str = Field( + ..., + description='Current status of the task. One of `"open"`, `"in_progress"`, `"in_review"`, `"paused"`, `"failed"`, `"superseding"`, `"done"`, or `"cancelled"`.', + ) + subtasks_count: int | None = Field( + default=None, + description="Number of readable subtasks under this task. Computed on list/show reads; create/update responses may report 0 until the next read. Always 0 for subtasks.", + ) + tags: list[str] | None = Field( + default=None, + description="Labels for grouping and filtering, stored lowercase and de-duplicated. Empty array when untagged.", + ) + target_binary: str | None = Field( + default=None, + description="Binary that must run this work (for example `my-cli`). A worker should take the task only when its own `target_binary` build is at least `target_version`. `null` when the task has no target. Set together with `target_version`.", + ) + target_version: str | None = Field( + default=None, + description="Minimum semantic version of `target_binary` that can run this work (for example `0.48.9`), in canonical `MAJOR.MINOR.PATCH[-prerelease][+build]` form. `null` when the task has no target.", + ) + task_epic: str | None = Field( + default=None, description="First-class Epic membership; does not grant access to the task." + ) + team: str | None = Field( + default=None, + description="ID of the team that owns this task (`tem_...`). `null` if the task is not scoped to a team.", + ) + thread: str | None = Field( + default=None, + description="ID of the thread this task is bound to (`thr_...`) - the conversation it was filed from, or the thread passed at creation. `null` for tasks not tied to a thread.", + ) + updated_at: datetime | None = Field( + default=None, description="When the task was last modified (ISO 8601)." + ) + user: str | None = Field( + default=None, + description="ID of the user that owns this task (`usr_...`). `null` if the task is scoped to a team.", + ) + + +class TeamTaskSearchResponse(BaseModel): """ Successful response """ @@ -2418,11 +2954,41 @@ class TeamTaskSearchResponse(BaseModel): data: list[TeamTaskSearchResponseDataItem] = Field( ..., description="Array of task objects matching the query and filters." ) - has_more: bool - query: str + has_more: bool + query: str + + +class TeamThreadListResponseDataItemParentMessageAclAddItem(BaseModel): + actions: list[str] = Field( + ..., + description='Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.', + ) + principal: str | None = Field( + default=None, + description='The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.', + ) + principal_type: str = Field( + ..., + description='The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.', + ) + + +class TeamThreadListResponseDataItemParentMessageAclAddDeniesItem(BaseModel): + actions: list[str] = Field( + ..., + description='Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.', + ) + principal: str | None = Field( + default=None, + description='The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.', + ) + principal_type: str = Field( + ..., + description='The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.', + ) -class TeamThreadListResponseDataItemParentMessageAclAddItem(BaseModel): +class TeamThreadListResponseDataItemParentMessageAclDeniesItem(BaseModel): actions: list[str] = Field( ..., description='Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.', @@ -2463,19 +3029,45 @@ class TeamThreadListResponseDataItemParentMessageAclRemoveItem(BaseModel): ) +class TeamThreadListResponseDataItemParentMessageAclRemoveDeniesItem(BaseModel): + principal: str | None = Field( + default=None, + description='The identifier of the principal to remove. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`. Omit when `principal_type` is `"everyone"`.', + ) + principal_type: str = Field( + ..., + description='The kind of principal to remove. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.', + ) + + class TeamThreadListResponseDataItemParentMessageAcl(BaseModel): add: list[TeamThreadListResponseDataItemParentMessageAclAddItem] | None = Field( default=None, description="Patch mode: grants to add or merge into the existing list. Cannot be combined with `grants`.", ) + add_denies: list[TeamThreadListResponseDataItemParentMessageAclAddDeniesItem] | None = Field( + default=None, + description="Patch mode: denies to add or merge, replacing any grant for the same principal.", + ) + denies: list[TeamThreadListResponseDataItemParentMessageAclDeniesItem] | None = Field( + default=None, + description="Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support.", + ) grants: list[TeamThreadListResponseDataItemParentMessageAclGrantsItem] | None = Field( default=None, description="Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", ) + preserve_denies: bool | None = Field( + default=None, + description="Retain current server denies atomically in replacement or patch mode; current denies win.", + ) remove: list[TeamThreadListResponseDataItemParentMessageAclRemoveItem] | None = Field( default=None, description="Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", ) + remove_denies: list[TeamThreadListResponseDataItemParentMessageAclRemoveDeniesItem] | None = ( + Field(default=None, description="Patch mode: principals whose denies should be removed.") + ) class TeamThreadListResponseDataItemParentMessageActorsItemProfilePicture(BaseModel): @@ -2953,6 +3545,36 @@ class TeamThreadListResponseDataItemParticipatingAgentsItemAclAddItem(BaseModel) ) +class TeamThreadListResponseDataItemParticipatingAgentsItemAclAddDeniesItem(BaseModel): + actions: list[str] = Field( + ..., + description='Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.', + ) + principal: str | None = Field( + default=None, + description='The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.', + ) + principal_type: str = Field( + ..., + description='The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.', + ) + + +class TeamThreadListResponseDataItemParticipatingAgentsItemAclDeniesItem(BaseModel): + actions: list[str] = Field( + ..., + description='Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.', + ) + principal: str | None = Field( + default=None, + description='The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.', + ) + principal_type: str = Field( + ..., + description='The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.', + ) + + class TeamThreadListResponseDataItemParticipatingAgentsItemAclGrantsItem(BaseModel): actions: list[str] = Field( ..., @@ -2979,19 +3601,47 @@ class TeamThreadListResponseDataItemParticipatingAgentsItemAclRemoveItem(BaseMod ) +class TeamThreadListResponseDataItemParticipatingAgentsItemAclRemoveDeniesItem(BaseModel): + principal: str | None = Field( + default=None, + description='The identifier of the principal to remove. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`. Omit when `principal_type` is `"everyone"`.', + ) + principal_type: str = Field( + ..., + description='The kind of principal to remove. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.', + ) + + class TeamThreadListResponseDataItemParticipatingAgentsItemAcl(BaseModel): add: list[TeamThreadListResponseDataItemParticipatingAgentsItemAclAddItem] | None = Field( default=None, description="Patch mode: grants to add or merge into the existing list. Cannot be combined with `grants`.", ) + add_denies: ( + list[TeamThreadListResponseDataItemParticipatingAgentsItemAclAddDeniesItem] | None + ) = Field( + default=None, + description="Patch mode: denies to add or merge, replacing any grant for the same principal.", + ) + denies: list[TeamThreadListResponseDataItemParticipatingAgentsItemAclDeniesItem] | None = Field( + default=None, + description="Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support.", + ) grants: list[TeamThreadListResponseDataItemParticipatingAgentsItemAclGrantsItem] | None = Field( default=None, description="Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", ) + preserve_denies: bool | None = Field( + default=None, + description="Retain current server denies atomically in replacement or patch mode; current denies win.", + ) remove: list[TeamThreadListResponseDataItemParticipatingAgentsItemAclRemoveItem] | None = Field( default=None, description="Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", ) + remove_denies: ( + list[TeamThreadListResponseDataItemParticipatingAgentsItemAclRemoveDeniesItem] | None + ) = Field(default=None, description="Patch mode: principals whose denies should be removed.") class TeamThreadListResponseDataItemParticipatingAgentsItemSourceSolutionCurrentSolutionOrgLogo( @@ -3775,6 +4425,10 @@ class TeamThreadListResponseDataItem(BaseModel): default=None, description="ID of the team that owns this thread (`team_...`). `null` for user-owned or agent-owned threads.", ) + thread_template_key: str | None = Field( + default=None, + description="Read-only key of the template used to create this thread. `null` for threads not created from a template.", + ) title: str | None = Field( default=None, description="Human-readable name of the thread. `null` if no title has been set.", @@ -3836,6 +4490,36 @@ class TeamListResponseDataItemAclAddItem(BaseModel): ) +class TeamListResponseDataItemAclAddDeniesItem(BaseModel): + actions: list[str] = Field( + ..., + description='Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.', + ) + principal: str | None = Field( + default=None, + description='The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.', + ) + principal_type: str = Field( + ..., + description='The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.', + ) + + +class TeamListResponseDataItemAclDeniesItem(BaseModel): + actions: list[str] = Field( + ..., + description='Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.', + ) + principal: str | None = Field( + default=None, + description='The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.', + ) + principal_type: str = Field( + ..., + description='The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.', + ) + + class TeamListResponseDataItemAclGrantsItem(BaseModel): actions: list[str] = Field( ..., @@ -3862,19 +4546,45 @@ class TeamListResponseDataItemAclRemoveItem(BaseModel): ) +class TeamListResponseDataItemAclRemoveDeniesItem(BaseModel): + principal: str | None = Field( + default=None, + description='The identifier of the principal to remove. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`. Omit when `principal_type` is `"everyone"`.', + ) + principal_type: str = Field( + ..., + description='The kind of principal to remove. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.', + ) + + class TeamListResponseDataItemAcl(BaseModel): add: list[TeamListResponseDataItemAclAddItem] | None = Field( default=None, description="Patch mode: grants to add or merge into the existing list. Cannot be combined with `grants`.", ) + add_denies: list[TeamListResponseDataItemAclAddDeniesItem] | None = Field( + default=None, + description="Patch mode: denies to add or merge, replacing any grant for the same principal.", + ) + denies: list[TeamListResponseDataItemAclDeniesItem] | None = Field( + default=None, + description="Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support.", + ) grants: list[TeamListResponseDataItemAclGrantsItem] | None = Field( default=None, description="Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", ) + preserve_denies: bool | None = Field( + default=None, + description="Retain current server denies atomically in replacement or patch mode; current denies win.", + ) remove: list[TeamListResponseDataItemAclRemoveItem] | None = Field( default=None, description="Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", ) + remove_denies: list[TeamListResponseDataItemAclRemoveDeniesItem] | None = Field( + default=None, description="Patch mode: principals whose denies should be removed." + ) class TeamListResponseDataItem(BaseModel): @@ -3959,6 +4669,36 @@ class TeamArtifactsResponseDataItemAclAddItem(BaseModel): ) +class TeamArtifactsResponseDataItemAclAddDeniesItem(BaseModel): + actions: list[str] = Field( + ..., + description='Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.', + ) + principal: str | None = Field( + default=None, + description='The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.', + ) + principal_type: str = Field( + ..., + description='The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.', + ) + + +class TeamArtifactsResponseDataItemAclDeniesItem(BaseModel): + actions: list[str] = Field( + ..., + description='Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.', + ) + principal: str | None = Field( + default=None, + description='The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.', + ) + principal_type: str = Field( + ..., + description='The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.', + ) + + class TeamArtifactsResponseDataItemAclGrantsItem(BaseModel): actions: list[str] = Field( ..., @@ -3985,19 +4725,45 @@ class TeamArtifactsResponseDataItemAclRemoveItem(BaseModel): ) +class TeamArtifactsResponseDataItemAclRemoveDeniesItem(BaseModel): + principal: str | None = Field( + default=None, + description='The identifier of the principal to remove. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`. Omit when `principal_type` is `"everyone"`.', + ) + principal_type: str = Field( + ..., + description='The kind of principal to remove. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.', + ) + + class TeamArtifactsResponseDataItemAcl(BaseModel): add: list[TeamArtifactsResponseDataItemAclAddItem] | None = Field( default=None, description="Patch mode: grants to add or merge into the existing list. Cannot be combined with `grants`.", ) + add_denies: list[TeamArtifactsResponseDataItemAclAddDeniesItem] | None = Field( + default=None, + description="Patch mode: denies to add or merge, replacing any grant for the same principal.", + ) + denies: list[TeamArtifactsResponseDataItemAclDeniesItem] | None = Field( + default=None, + description="Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support.", + ) grants: list[TeamArtifactsResponseDataItemAclGrantsItem] | None = Field( default=None, description="Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", ) + preserve_denies: bool | None = Field( + default=None, + description="Retain current server denies atomically in replacement or patch mode; current denies win.", + ) remove: list[TeamArtifactsResponseDataItemAclRemoveItem] | None = Field( default=None, description="Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", ) + remove_denies: list[TeamArtifactsResponseDataItemAclRemoveDeniesItem] | None = Field( + default=None, description="Patch mode: principals whose denies should be removed." + ) class TeamArtifactsResponseDataItemImageSource(BaseModel): @@ -4197,48 +4963,6 @@ class TeamTaskAssigneesResponse(BaseModel): ) -class TeamTaskEpicsResponseDataItemNextReadyItem(BaseModel): - id: str - name: str - priority: int - status: str - - -class TeamTaskEpicsResponseDataItemRootBlockersItem(BaseModel): - downstream_count: int - id: str - name: str - priority: int - status: str - - -class TeamTaskEpicsResponseDataItem(BaseModel): - blocked_count: int - counts: dict[str, Any] = Field( - ..., description="Task counts keyed by status, including closed tasks." - ) - epic: str - next_ready: list[TeamTaskEpicsResponseDataItemNextReadyItem] - root_blockers: list[TeamTaskEpicsResponseDataItemRootBlockersItem] - root_blockers_partial: bool = Field( - ..., description="True when root ranking used a truncated in-epic graph." - ) - top_open_priority: int | None = None - updated_at: datetime - - -class TeamTaskEpicsResponse(BaseModel): - """ - Successful response - """ - - after_cursor: str | None = None - before_cursor: str | None = None - data: list[TeamTaskEpicsResponseDataItem] - has_more: bool - no_epic_open_count: int - - class AsyncTeamCustomObjectResource: def __init__(self, http: HttpClient): self._http = http @@ -4447,39 +5171,128 @@ async def create(self, team: str, input: MemberCreateInput) -> TeamMembership: The newly created team membership. """ return await self._http.request( - f"/api/v1/teams/{team}/members", - method="POST", - body=input, - response_type=TeamMembership, + f"/api/v1/teams/{team}/members", + method="POST", + body=input, + response_type=TeamMembership, + ) + + async def update(self, team: str, user: str, input: MemberUpdateInput) -> TeamMembership: + """ + Update a team member's role + Changes the role of an existing user member on the specified team. Returns the + updated membership on success. + Only user memberships are supported by this endpoint. Attempting to update an + agent membership returns 404. To change an agent's role, remove the existing + membership and re-add the agent with the desired role. + The caller must have permission to modify the team. You cannot change a member's + role across organization boundaries. Demoting the last owner of a team returns + 409. An invalid `role` value returns 422. When `app` is provided, the request + is scoped to that app and requires a valid app-scoped token. + + Args: + team: Team ID (`team_...`). The team to remove the member from. + user: User ID (`usr_...`) of the existing member whose role should be changed. + input: Request body. + input.role: New role to assign. One of `"owner"`, `"admin"`, or `"member"`. + + Returns: + The updated team membership reflecting the new role. + """ + return await self._http.request( + f"/api/v1/teams/{team}/members/{user}", + method="PATCH", + body=input, + response_type=TeamMembership, + ) + + +class AsyncTeamTaskEpicResource: + def __init__(self, http: HttpClient): + self._http = http + + async def list( + self, + team: str, + *, + representation: str | None = None, + name: str | None = None, + user: str | None = None, + org: str | None = None, + source_scope: str | None = None, + source_type: str | None = None, + source_id: str | None = None, + top_priority: int | None = None, + owner: str | None = None, + include_closed: bool | None = None, + limit: int | None = None, + after_cursor: str | None = None, + ) -> dict[str, Any] | TaskEpicEntityCollection: + """ + List an owner's epic summaries + Groups tasks by their exact epic label, ordered by label. Closed tasks include cancelled tasks, but cancelled prerequisites still block. Source filters select the tasks summarized; blockers outside that selection still affect readiness. Root ranking is capped per epic and root_blockers_partial is true when that graph is truncated. No epic entity is created. + + Args: + representation: labels (default) or entities. + name: Exact entity name; only used for entities. + source_scope: Exact source scope; supply all three source fields. + source_type: Exact source type. + source_id: Exact source ID. + top_priority: Exact highest open priority, from 0 to 4. + owner: Keep only epics with at least one non-closed task owned by this user: `me` or a user public ID (`usr_...`). + include_closed: Include epics with no non-closed tasks; defaults to false. + limit: Maximum epics; defaults to 50, capped at 100. + after_cursor: Opaque forward cursor from the preceding page. + + Returns: + Successful response + """ + query: dict[str, object] = {} + if representation is not None: + query["representation"] = representation + if name is not None: + query["name"] = name + if user is not None: + query["user"] = user + if org is not None: + query["org"] = org + if source_scope is not None: + query["source_scope"] = source_scope + if source_type is not None: + query["source_type"] = source_type + if source_id is not None: + query["source_id"] = source_id + if top_priority is not None: + query["top_priority"] = top_priority + if owner is not None: + query["owner"] = owner + if include_closed is not None: + query["include_closed"] = include_closed + if limit is not None: + query["limit"] = limit + if after_cursor is not None: + query["after_cursor"] = after_cursor + return await self._http.request( + f"/api/v1/teams/{team}/task_epics", + query=query, + response_type=TaskEpicEntityCollection | dict[str, Any], ) - async def update(self, team: str, user: str, input: MemberUpdateInput) -> TeamMembership: + async def create(self, team: str, input: TeamTaskEpicCreateInput) -> TaskEpicEntity: """ - Update a team member's role - Changes the role of an existing user member on the specified team. Returns the - updated membership on success. - Only user memberships are supported by this endpoint. Attempting to update an - agent membership returns 404. To change an agent's role, remove the existing - membership and re-add the agent with the desired role. - The caller must have permission to modify the team. You cannot change a member's - role across organization boundaries. Demoting the last owner of a team returns - 409. An invalid `role` value returns 422. When `app` is provided, the request - is scoped to that app and requires a valid app-scoped token. + Create a task Epic Args: - team: Team ID (`team_...`). The team to remove the member from. - user: User ID (`usr_...`) of the existing member whose role should be changed. input: Request body. - input.role: New role to assign. One of `"owner"`, `"admin"`, or `"member"`. Returns: - The updated team membership reflecting the new role. + Successful response """ return await self._http.request( - f"/api/v1/teams/{team}/members/{user}", - method="PATCH", + f"/api/v1/teams/{team}/task_epics", + method="POST", body=input, - response_type=TeamMembership, + response_type=TaskEpicEntity, ) @@ -4496,6 +5309,9 @@ async def list( status: str | None = None, owner_user: str | None = None, owner_agent: str | None = None, + owner: str | None = None, + involving: str | None = None, + summary: bool | None = None, priority: int | None = None, tag: str | None = None, parent: str | None = None, @@ -4532,6 +5348,9 @@ async def list( status: Filter tasks by status. One of `"open"`, `"in_progress"`, `"in_review"`, or `"done"`. Omit to return tasks in all statuses. owner_user: Filter tasks assigned to a specific user. Provide the user's public ID (`usr_...`). owner_agent: Filter tasks assigned to a specific agent. Provide the agent's public ID (`agi_...`). + owner: Return only tasks owned by this user: `me` or a user public ID (`usr_...`). + involving: Return only tasks owned or created by this user: `me` or a user public ID (`usr_...`). The "My work" predicate. + summary: When true, omit `description` from every task. Use for list views. priority: Filter tasks by priority, from 0 (highest) to 4 (lowest). tag: Return only tasks carrying this tag (matched against the canonical lowercase form). parent: Return only subtasks of the given task (`tsk_...`), or pass `none` to return only top-level tasks. @@ -4564,6 +5383,12 @@ async def list( query["owner_user"] = owner_user if owner_agent is not None: query["owner_agent"] = owner_agent + if owner is not None: + query["owner"] = owner + if involving is not None: + query["involving"] = involving + if summary is not None: + query["summary"] = summary if priority is not None: query["priority"] = priority if tag is not None: @@ -4675,6 +5500,45 @@ async def blocker_cycles( response_type=TeamTaskBlockerCyclesResponse, ) + async def by_external_reference( + self, + team: str, + external_scope: str, + object_type: str, + object_id: str, + *, + user: str | None = None, + org: str | None = None, + ) -> TeamTaskByExternalReferenceResponse: + """ + Find an owner's tasks by external reference + Returns all exact external-reference matches owned by the requested principal. Multiple matches remain explicit; callers must not choose an arbitrary task. + + Args: + team: Team ID (`tem_...`). Only tasks belonging to this team are returned. + user: User owner. + org: Organization consistency check. + external_scope: External host. + object_type: External object type. + object_id: External object identity. + + Returns: + Successful response + """ + query: dict[str, object] = {} + if user is not None: + query["user"] = user + if org is not None: + query["org"] = org + query["external_scope"] = external_scope + query["object_type"] = object_type + query["object_id"] = object_id + return await self._http.request( + f"/api/v1/teams/{team}/tasks/by-external-reference", + query=query, + response_type=TeamTaskByExternalReferenceResponse, + ) + async def by_source(self, team: str, input: TeamTaskBySourceInput) -> TaskEnsureResult: """ Find or create a task by source @@ -4688,6 +5552,7 @@ async def by_source(self, team: str, input: TeamTaskBySourceInput) -> TaskEnsure input.epic: Initial epic grouping. input.name: Initial task name. input.org: Explicit organization for privileged callers. + input.owner_user: Initial assigned user; immutable on retries. input.source_id: Source identity, for example owner/repo#123. input.source_scope: Source scope, for example github. input.source_type: Source type, for example pull_request. @@ -4997,6 +5862,7 @@ def __init__(self, http: HttpClient): self.custom_objects = AsyncTeamCustomObjectResource(http) self.invite = AsyncTeamInviteResource(http) self.members = AsyncMemberResource(http) + self.task_epics = AsyncTeamTaskEpicResource(http) self.tasks = AsyncTeamTaskResource(http) self.threads = AsyncTeamThreadResource(http) @@ -5319,61 +6185,6 @@ async def task_assignees( response_type=TeamTaskAssigneesResponse, ) - async def task_epics( - self, - team: str, - *, - user: str | None = None, - org: str | None = None, - source_scope: str | None = None, - source_type: str | None = None, - source_id: str | None = None, - top_priority: int | None = None, - include_closed: bool | None = None, - limit: int | None = None, - after_cursor: str | None = None, - ) -> TeamTaskEpicsResponse: - """ - List an owner's epic summaries - Groups tasks by their exact epic label, ordered by label. Closed tasks include cancelled tasks, but cancelled prerequisites still block. Source filters select the tasks summarized; blockers outside that selection still affect readiness. Root ranking is capped per epic and root_blockers_partial is true when that graph is truncated. No epic entity is created. - - Args: - source_scope: Exact source scope; supply all three source fields. - source_type: Exact source type. - source_id: Exact source ID. - top_priority: Exact highest open priority, from 0 to 4. - include_closed: Include epics with no non-closed tasks; defaults to false. - limit: Maximum epics; defaults to 50, capped at 100. - after_cursor: Opaque forward cursor from the preceding page. - - Returns: - Successful response - """ - query: dict[str, object] = {} - if user is not None: - query["user"] = user - if org is not None: - query["org"] = org - if source_scope is not None: - query["source_scope"] = source_scope - if source_type is not None: - query["source_type"] = source_type - if source_id is not None: - query["source_id"] = source_id - if top_priority is not None: - query["top_priority"] = top_priority - if include_closed is not None: - query["include_closed"] = include_closed - if limit is not None: - query["limit"] = limit - if after_cursor is not None: - query["after_cursor"] = after_cursor - return await self._http.request( - f"/api/v1/teams/{team}/task_epics", - query=query, - response_type=TeamTaskEpicsResponse, - ) - class TeamCustomObjectResource: def __init__(self, http: SyncHttpClient): @@ -5616,6 +6427,95 @@ def update(self, team: str, user: str, input: MemberUpdateInput) -> TeamMembersh ) +class TeamTaskEpicResource: + def __init__(self, http: SyncHttpClient): + self._http = http + + def list( + self, + team: str, + *, + representation: str | None = None, + name: str | None = None, + user: str | None = None, + org: str | None = None, + source_scope: str | None = None, + source_type: str | None = None, + source_id: str | None = None, + top_priority: int | None = None, + owner: str | None = None, + include_closed: bool | None = None, + limit: int | None = None, + after_cursor: str | None = None, + ) -> dict[str, Any] | TaskEpicEntityCollection: + """ + List an owner's epic summaries + Groups tasks by their exact epic label, ordered by label. Closed tasks include cancelled tasks, but cancelled prerequisites still block. Source filters select the tasks summarized; blockers outside that selection still affect readiness. Root ranking is capped per epic and root_blockers_partial is true when that graph is truncated. No epic entity is created. + + Args: + representation: labels (default) or entities. + name: Exact entity name; only used for entities. + source_scope: Exact source scope; supply all three source fields. + source_type: Exact source type. + source_id: Exact source ID. + top_priority: Exact highest open priority, from 0 to 4. + owner: Keep only epics with at least one non-closed task owned by this user: `me` or a user public ID (`usr_...`). + include_closed: Include epics with no non-closed tasks; defaults to false. + limit: Maximum epics; defaults to 50, capped at 100. + after_cursor: Opaque forward cursor from the preceding page. + + Returns: + Successful response + """ + query: dict[str, object] = {} + if representation is not None: + query["representation"] = representation + if name is not None: + query["name"] = name + if user is not None: + query["user"] = user + if org is not None: + query["org"] = org + if source_scope is not None: + query["source_scope"] = source_scope + if source_type is not None: + query["source_type"] = source_type + if source_id is not None: + query["source_id"] = source_id + if top_priority is not None: + query["top_priority"] = top_priority + if owner is not None: + query["owner"] = owner + if include_closed is not None: + query["include_closed"] = include_closed + if limit is not None: + query["limit"] = limit + if after_cursor is not None: + query["after_cursor"] = after_cursor + return self._http.request( + f"/api/v1/teams/{team}/task_epics", + query=query, + response_type=TaskEpicEntityCollection | dict[str, Any], + ) + + def create(self, team: str, input: TeamTaskEpicCreateInput) -> TaskEpicEntity: + """ + Create a task Epic + + Args: + input: Request body. + + Returns: + Successful response + """ + return self._http.request( + f"/api/v1/teams/{team}/task_epics", + method="POST", + body=input, + response_type=TaskEpicEntity, + ) + + class TeamTaskResource: def __init__(self, http: SyncHttpClient): self._http = http @@ -5629,6 +6529,9 @@ def list( status: str | None = None, owner_user: str | None = None, owner_agent: str | None = None, + owner: str | None = None, + involving: str | None = None, + summary: bool | None = None, priority: int | None = None, tag: str | None = None, parent: str | None = None, @@ -5665,6 +6568,9 @@ def list( status: Filter tasks by status. One of `"open"`, `"in_progress"`, `"in_review"`, or `"done"`. Omit to return tasks in all statuses. owner_user: Filter tasks assigned to a specific user. Provide the user's public ID (`usr_...`). owner_agent: Filter tasks assigned to a specific agent. Provide the agent's public ID (`agi_...`). + owner: Return only tasks owned by this user: `me` or a user public ID (`usr_...`). + involving: Return only tasks owned or created by this user: `me` or a user public ID (`usr_...`). The "My work" predicate. + summary: When true, omit `description` from every task. Use for list views. priority: Filter tasks by priority, from 0 (highest) to 4 (lowest). tag: Return only tasks carrying this tag (matched against the canonical lowercase form). parent: Return only subtasks of the given task (`tsk_...`), or pass `none` to return only top-level tasks. @@ -5697,6 +6603,12 @@ def list( query["owner_user"] = owner_user if owner_agent is not None: query["owner_agent"] = owner_agent + if owner is not None: + query["owner"] = owner + if involving is not None: + query["involving"] = involving + if summary is not None: + query["summary"] = summary if priority is not None: query["priority"] = priority if tag is not None: @@ -5808,6 +6720,45 @@ def blocker_cycles( response_type=TeamTaskBlockerCyclesResponse, ) + def by_external_reference( + self, + team: str, + external_scope: str, + object_type: str, + object_id: str, + *, + user: str | None = None, + org: str | None = None, + ) -> TeamTaskByExternalReferenceResponse: + """ + Find an owner's tasks by external reference + Returns all exact external-reference matches owned by the requested principal. Multiple matches remain explicit; callers must not choose an arbitrary task. + + Args: + team: Team ID (`tem_...`). Only tasks belonging to this team are returned. + user: User owner. + org: Organization consistency check. + external_scope: External host. + object_type: External object type. + object_id: External object identity. + + Returns: + Successful response + """ + query: dict[str, object] = {} + if user is not None: + query["user"] = user + if org is not None: + query["org"] = org + query["external_scope"] = external_scope + query["object_type"] = object_type + query["object_id"] = object_id + return self._http.request( + f"/api/v1/teams/{team}/tasks/by-external-reference", + query=query, + response_type=TeamTaskByExternalReferenceResponse, + ) + def by_source(self, team: str, input: TeamTaskBySourceInput) -> TaskEnsureResult: """ Find or create a task by source @@ -5821,6 +6772,7 @@ def by_source(self, team: str, input: TeamTaskBySourceInput) -> TaskEnsureResult input.epic: Initial epic grouping. input.name: Initial task name. input.org: Explicit organization for privileged callers. + input.owner_user: Initial assigned user; immutable on retries. input.source_id: Source identity, for example owner/repo#123. input.source_scope: Source scope, for example github. input.source_type: Source type, for example pull_request. @@ -6128,6 +7080,7 @@ def __init__(self, http: SyncHttpClient): self.custom_objects = TeamCustomObjectResource(http) self.invite = TeamInviteResource(http) self.members = MemberResource(http) + self.task_epics = TeamTaskEpicResource(http) self.tasks = TeamTaskResource(http) self.threads = TeamThreadResource(http) @@ -6438,58 +7391,3 @@ def task_assignees(self, team: str, *, org: str | None = None) -> TeamTaskAssign query=query, response_type=TeamTaskAssigneesResponse, ) - - def task_epics( - self, - team: str, - *, - user: str | None = None, - org: str | None = None, - source_scope: str | None = None, - source_type: str | None = None, - source_id: str | None = None, - top_priority: int | None = None, - include_closed: bool | None = None, - limit: int | None = None, - after_cursor: str | None = None, - ) -> TeamTaskEpicsResponse: - """ - List an owner's epic summaries - Groups tasks by their exact epic label, ordered by label. Closed tasks include cancelled tasks, but cancelled prerequisites still block. Source filters select the tasks summarized; blockers outside that selection still affect readiness. Root ranking is capped per epic and root_blockers_partial is true when that graph is truncated. No epic entity is created. - - Args: - source_scope: Exact source scope; supply all three source fields. - source_type: Exact source type. - source_id: Exact source ID. - top_priority: Exact highest open priority, from 0 to 4. - include_closed: Include epics with no non-closed tasks; defaults to false. - limit: Maximum epics; defaults to 50, capped at 100. - after_cursor: Opaque forward cursor from the preceding page. - - Returns: - Successful response - """ - query: dict[str, object] = {} - if user is not None: - query["user"] = user - if org is not None: - query["org"] = org - if source_scope is not None: - query["source_scope"] = source_scope - if source_type is not None: - query["source_type"] = source_type - if source_id is not None: - query["source_id"] = source_id - if top_priority is not None: - query["top_priority"] = top_priority - if include_closed is not None: - query["include_closed"] = include_closed - if limit is not None: - query["limit"] = limit - if after_cursor is not None: - query["after_cursor"] = after_cursor - return self._http.request( - f"/api/v1/teams/{team}/task_epics", - query=query, - response_type=TeamTaskEpicsResponse, - ) diff --git a/src/archastro/platform/v1/resources/thread_messages.py b/src/archastro/platform/v1/resources/thread_messages.py index 5788469..fcd1ecd 100644 --- a/src/archastro/platform/v1/resources/thread_messages.py +++ b/src/archastro/platform/v1/resources/thread_messages.py @@ -1,6 +1,6 @@ # Copyright (c) 2026 ArchAstro Inc. Licensed under the MIT License. # This file is auto-generated by @archastro/sdk-generator. Do not edit. -# Content hash: b91c191bc4f5 +# Content hash: 06ed86551811 from __future__ import annotations @@ -30,6 +30,24 @@ class ThreadMessageReplaceInputAclAddItem(TypedDict, total=False): 'The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' +class ThreadMessageReplaceInputAclAddDeniesItem(TypedDict, total=False): + actions: Required[list[str]] + 'Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.' + principal: str | None + 'The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.' + principal_type: Required[str] + 'The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' + + +class ThreadMessageReplaceInputAclDeniesItem(TypedDict, total=False): + actions: Required[list[str]] + 'Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.' + principal: str | None + 'The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.' + principal_type: Required[str] + 'The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' + + class ThreadMessageReplaceInputAclGrantsItem(TypedDict, total=False): actions: Required[list[str]] 'Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.' @@ -46,13 +64,28 @@ class ThreadMessageReplaceInputAclRemoveItem(TypedDict, total=False): 'The kind of principal to remove. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' +class ThreadMessageReplaceInputAclRemoveDeniesItem(TypedDict, total=False): + principal: str | None + 'The identifier of the principal to remove. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`. Omit when `principal_type` is `"everyone"`.' + principal_type: Required[str] + 'The kind of principal to remove. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' + + class ThreadMessageReplaceInputAcl(TypedDict, total=False): add: list[ThreadMessageReplaceInputAclAddItem] | None "Patch mode: grants to add or merge into the existing list. Cannot be combined with `grants`." + add_denies: list[ThreadMessageReplaceInputAclAddDeniesItem] | None + "Patch mode: denies to add or merge, replacing any grant for the same principal." + denies: list[ThreadMessageReplaceInputAclDeniesItem] | None + "Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support." grants: list[ThreadMessageReplaceInputAclGrantsItem] | None "Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`." + preserve_denies: bool | None + "Retain current server denies atomically in replacement or patch mode; current denies win." remove: list[ThreadMessageReplaceInputAclRemoveItem] | None "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`." + remove_denies: list[ThreadMessageReplaceInputAclRemoveDeniesItem] | None + "Patch mode: principals whose denies should be removed." class ThreadMessageReplaceInput(TypedDict, total=False): diff --git a/src/archastro/platform/v1/resources/threads.py b/src/archastro/platform/v1/resources/threads.py index d8257f6..07b14f0 100644 --- a/src/archastro/platform/v1/resources/threads.py +++ b/src/archastro/platform/v1/resources/threads.py @@ -1,6 +1,6 @@ # Copyright (c) 2026 ArchAstro Inc. Licensed under the MIT License. # This file is auto-generated by @archastro/sdk-generator. Do not edit. -# Content hash: fe8db978c7bd +# Content hash: 8216a1b56d8a from __future__ import annotations @@ -15,7 +15,7 @@ from ...types.threads import Thread, ThreadReadStatus, ThreadSettings -class ComputerCreateInputAclAddItem(TypedDict, total=False): +class ThreadComputerCreateInputAclAddItem(TypedDict, total=False): actions: Required[list[str]] 'Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.' principal: str | None @@ -24,7 +24,7 @@ class ComputerCreateInputAclAddItem(TypedDict, total=False): 'The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' -class ComputerCreateInputAclGrantsItem(TypedDict, total=False): +class ThreadComputerCreateInputAclAddDeniesItem(TypedDict, total=False): actions: Required[list[str]] 'Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.' principal: str | None @@ -33,26 +33,66 @@ class ComputerCreateInputAclGrantsItem(TypedDict, total=False): 'The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' -class ComputerCreateInputAclRemoveItem(TypedDict, total=False): +class ThreadComputerCreateInputAclDeniesItem(TypedDict, total=False): + actions: Required[list[str]] + 'Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.' + principal: str | None + 'The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.' + principal_type: Required[str] + 'The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' + + +class ThreadComputerCreateInputAclGrantsItem(TypedDict, total=False): + actions: Required[list[str]] + 'Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.' + principal: str | None + 'The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.' + principal_type: Required[str] + 'The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' + + +class ThreadComputerCreateInputAclRemoveItem(TypedDict, total=False): + principal: str | None + 'The identifier of the principal to remove. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`. Omit when `principal_type` is `"everyone"`.' + principal_type: Required[str] + 'The kind of principal to remove. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' + + +class ThreadComputerCreateInputAclRemoveDeniesItem(TypedDict, total=False): principal: str | None 'The identifier of the principal to remove. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`. Omit when `principal_type` is `"everyone"`.' principal_type: Required[str] 'The kind of principal to remove. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' -class ComputerCreateInputAcl(TypedDict, total=False): - add: list[ComputerCreateInputAclAddItem] | None +class ThreadComputerCreateInputAcl(TypedDict, total=False): + add: list[ThreadComputerCreateInputAclAddItem] | None "Patch mode: grants to add or merge into the existing list. Cannot be combined with `grants`." - grants: list[ComputerCreateInputAclGrantsItem] | None + add_denies: list[ThreadComputerCreateInputAclAddDeniesItem] | None + "Patch mode: denies to add or merge, replacing any grant for the same principal." + denies: list[ThreadComputerCreateInputAclDeniesItem] | None + "Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support." + grants: list[ThreadComputerCreateInputAclGrantsItem] | None "Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`." - remove: list[ComputerCreateInputAclRemoveItem] | None + preserve_denies: bool | None + "Retain current server denies atomically in replacement or patch mode; current denies win." + remove: list[ThreadComputerCreateInputAclRemoveItem] | None "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`." + remove_denies: list[ThreadComputerCreateInputAclRemoveDeniesItem] | None + "Patch mode: principals whose denies should be removed." -class ComputerCreateInput(TypedDict, total=False): +class ThreadComputerCreateInputRepositoriesItem(TypedDict, total=False): + ref: str | None + "Optional checkout ref; null selects the repository's default branch." + repository: Required[str] + "GitHub owner/name; supported GitHub URLs are normalized on creation." + + +class ThreadComputerCreateInput(TypedDict, total=False): "Provision a computer for a thread" - acl: ComputerCreateInputAcl | None + acl: ThreadComputerCreateInputAcl | None "Initial access control list." config: dict[str, Any] | None "Provider configuration; top-level provider takes precedence." @@ -63,9 +103,11 @@ class ComputerCreateInput(TypedDict, total=False): name: Required[str] "Human-readable computer name." provider: str | None - "Compute backend: sprites (default), vercel or e2b." + "Compute backend: sprites (default), vercel, e2b, or devbox (a devbox lease owned by the thread's user; personal threads only, and the user needs devbox access)." region: str | None "Provider region; defaults to iad." + repositories: list[ThreadComputerCreateInputRepositoriesItem] | None + "Ordered GitHub checkouts (maximum 16): {repository: owner/name, ref: optional ref}. First is primary." class ThreadMemberCreateInput(TypedDict, total=False): @@ -264,6 +306,36 @@ class ThreadArtifactsResponseDataItemAclAddItem(BaseModel): ) +class ThreadArtifactsResponseDataItemAclAddDeniesItem(BaseModel): + actions: list[str] = Field( + ..., + description='Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.', + ) + principal: str | None = Field( + default=None, + description='The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.', + ) + principal_type: str = Field( + ..., + description='The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.', + ) + + +class ThreadArtifactsResponseDataItemAclDeniesItem(BaseModel): + actions: list[str] = Field( + ..., + description='Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.', + ) + principal: str | None = Field( + default=None, + description='The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.', + ) + principal_type: str = Field( + ..., + description='The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.', + ) + + class ThreadArtifactsResponseDataItemAclGrantsItem(BaseModel): actions: list[str] = Field( ..., @@ -290,19 +362,45 @@ class ThreadArtifactsResponseDataItemAclRemoveItem(BaseModel): ) +class ThreadArtifactsResponseDataItemAclRemoveDeniesItem(BaseModel): + principal: str | None = Field( + default=None, + description='The identifier of the principal to remove. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`. Omit when `principal_type` is `"everyone"`.', + ) + principal_type: str = Field( + ..., + description='The kind of principal to remove. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.', + ) + + class ThreadArtifactsResponseDataItemAcl(BaseModel): add: list[ThreadArtifactsResponseDataItemAclAddItem] | None = Field( default=None, description="Patch mode: grants to add or merge into the existing list. Cannot be combined with `grants`.", ) + add_denies: list[ThreadArtifactsResponseDataItemAclAddDeniesItem] | None = Field( + default=None, + description="Patch mode: denies to add or merge, replacing any grant for the same principal.", + ) + denies: list[ThreadArtifactsResponseDataItemAclDeniesItem] | None = Field( + default=None, + description="Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support.", + ) grants: list[ThreadArtifactsResponseDataItemAclGrantsItem] | None = Field( default=None, description="Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", ) + preserve_denies: bool | None = Field( + default=None, + description="Retain current server denies atomically in replacement or patch mode; current denies win.", + ) remove: list[ThreadArtifactsResponseDataItemAclRemoveItem] | None = Field( default=None, description="Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", ) + remove_denies: list[ThreadArtifactsResponseDataItemAclRemoveDeniesItem] | None = Field( + default=None, description="Patch mode: principals whose denies should be removed." + ) class ThreadArtifactsResponseDataItemImageSource(BaseModel): @@ -440,6 +538,36 @@ class ThreadMessagesResponseDataMessagesItemAclAddItem(BaseModel): ) +class ThreadMessagesResponseDataMessagesItemAclAddDeniesItem(BaseModel): + actions: list[str] = Field( + ..., + description='Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.', + ) + principal: str | None = Field( + default=None, + description='The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.', + ) + principal_type: str = Field( + ..., + description='The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.', + ) + + +class ThreadMessagesResponseDataMessagesItemAclDeniesItem(BaseModel): + actions: list[str] = Field( + ..., + description='Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.', + ) + principal: str | None = Field( + default=None, + description='The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.', + ) + principal_type: str = Field( + ..., + description='The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.', + ) + + class ThreadMessagesResponseDataMessagesItemAclGrantsItem(BaseModel): actions: list[str] = Field( ..., @@ -466,19 +594,45 @@ class ThreadMessagesResponseDataMessagesItemAclRemoveItem(BaseModel): ) +class ThreadMessagesResponseDataMessagesItemAclRemoveDeniesItem(BaseModel): + principal: str | None = Field( + default=None, + description='The identifier of the principal to remove. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`. Omit when `principal_type` is `"everyone"`.', + ) + principal_type: str = Field( + ..., + description='The kind of principal to remove. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.', + ) + + class ThreadMessagesResponseDataMessagesItemAcl(BaseModel): add: list[ThreadMessagesResponseDataMessagesItemAclAddItem] | None = Field( default=None, description="Patch mode: grants to add or merge into the existing list. Cannot be combined with `grants`.", ) + add_denies: list[ThreadMessagesResponseDataMessagesItemAclAddDeniesItem] | None = Field( + default=None, + description="Patch mode: denies to add or merge, replacing any grant for the same principal.", + ) + denies: list[ThreadMessagesResponseDataMessagesItemAclDeniesItem] | None = Field( + default=None, + description="Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support.", + ) grants: list[ThreadMessagesResponseDataMessagesItemAclGrantsItem] | None = Field( default=None, description="Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", ) + preserve_denies: bool | None = Field( + default=None, + description="Retain current server denies atomically in replacement or patch mode; current denies win.", + ) remove: list[ThreadMessagesResponseDataMessagesItemAclRemoveItem] | None = Field( default=None, description="Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", ) + remove_denies: list[ThreadMessagesResponseDataMessagesItemAclRemoveDeniesItem] | None = Field( + default=None, description="Patch mode: principals whose denies should be removed." + ) class ThreadMessagesResponseDataMessagesItemActorsItemProfilePicture(BaseModel): @@ -992,7 +1146,7 @@ class ThreadTrajectoriesResponse(BaseModel): ) -class AsyncComputerResource: +class AsyncThreadComputerResource: def __init__(self, http: HttpClient): self._http = http @@ -1012,7 +1166,7 @@ async def list(self, thread: str) -> AgentComputerListResponse: response_type=AgentComputerListResponse, ) - async def create(self, thread: str, input: ComputerCreateInput) -> AgentComputer: + async def create(self, thread: str, input: ThreadComputerCreateInput) -> AgentComputer: """ Provision a computer for a thread Creates a computer owned by the thread's owner. Requires permission to manage the thread; every thread viewer may use the computer. @@ -1025,8 +1179,9 @@ async def create(self, thread: str, input: ComputerCreateInput) -> AgentComputer input.key: Stable key unique within this thread. input.metadata: Arbitrary computer metadata. input.name: Human-readable computer name. - input.provider: Compute backend: sprites (default), vercel or e2b. + input.provider: Compute backend: sprites (default), vercel, e2b, or devbox (a devbox lease owned by the thread's user; personal threads only, and the user needs devbox access). input.region: Provider region; defaults to iad. + input.repositories: Ordered GitHub checkouts (maximum 16): {repository: owner/name, ref: optional ref}. First is primary. Returns: The newly created computer. Returns HTTP 201. @@ -1240,7 +1395,7 @@ async def replace(self, thread: str, input: TagReplaceInput) -> Thread: class AsyncThreadResource: def __init__(self, http: HttpClient): self._http = http - self.computers = AsyncComputerResource(http) + self.computers = AsyncThreadComputerResource(http) self.members = AsyncThreadMemberResource(http) self.settings = AsyncSettingResource(http) self.tags = AsyncTagResource(http) @@ -1639,7 +1794,7 @@ async def trajectories( ) -class ComputerResource: +class ThreadComputerResource: def __init__(self, http: SyncHttpClient): self._http = http @@ -1659,7 +1814,7 @@ def list(self, thread: str) -> AgentComputerListResponse: response_type=AgentComputerListResponse, ) - def create(self, thread: str, input: ComputerCreateInput) -> AgentComputer: + def create(self, thread: str, input: ThreadComputerCreateInput) -> AgentComputer: """ Provision a computer for a thread Creates a computer owned by the thread's owner. Requires permission to manage the thread; every thread viewer may use the computer. @@ -1672,8 +1827,9 @@ def create(self, thread: str, input: ComputerCreateInput) -> AgentComputer: input.key: Stable key unique within this thread. input.metadata: Arbitrary computer metadata. input.name: Human-readable computer name. - input.provider: Compute backend: sprites (default), vercel or e2b. + input.provider: Compute backend: sprites (default), vercel, e2b, or devbox (a devbox lease owned by the thread's user; personal threads only, and the user needs devbox access). input.region: Provider region; defaults to iad. + input.repositories: Ordered GitHub checkouts (maximum 16): {repository: owner/name, ref: optional ref}. First is primary. Returns: The newly created computer. Returns HTTP 201. @@ -1887,7 +2043,7 @@ def replace(self, thread: str, input: TagReplaceInput) -> Thread: class ThreadResource: def __init__(self, http: SyncHttpClient): self._http = http - self.computers = ComputerResource(http) + self.computers = ThreadComputerResource(http) self.members = ThreadMemberResource(http) self.settings = SettingResource(http) self.tags = TagResource(http) diff --git a/src/archastro/platform/v1/resources/users.py b/src/archastro/platform/v1/resources/users.py index d08fa9a..c2b7668 100644 --- a/src/archastro/platform/v1/resources/users.py +++ b/src/archastro/platform/v1/resources/users.py @@ -1,6 +1,6 @@ # Copyright (c) 2026 ArchAstro Inc. Licensed under the MIT License. # This file is auto-generated by @archastro/sdk-generator. Do not edit. -# Content hash: 557ee782b674 +# Content hash: ec5860d7cfe0 from __future__ import annotations @@ -13,7 +13,7 @@ from ...runtime.http_client import HttpClient, SyncHttpClient from ...types.common import CurrentUser from ...types.system import SystemAccessToken -from ...types.tasks import Task, TaskEnsureResult +from ...types.tasks import Task, TaskEnsureResult, TaskEpicEntity, TaskEpicEntityCollection from ...types.threads import Thread from ...types.users import User, UserInvite, UserSSHKey @@ -27,13 +27,27 @@ class UserSshKeyCreateInput(TypedDict): "One `ssh-ed25519 ` public key without options or a comment." +class UserTaskEpicCreateInput(TypedDict, total=False): + "Create a task Epic" + + description: str | None + metadata: dict[str, Any] | None + name: Required[str] + state: str | None + team: str | None + + class UserTaskCreateInputTask(TypedDict, total=False): + blockers: list[str] | None + "Existing task IDs (`tsk_...`) that block this task. Recorded atomically with creation; the task is not ready until these blockers are done." description: str | None "Optional long-form description or notes for the task. Supports plain text." due_date: datetime | None "Date and time by which the task should be completed (ISO 8601). Omit to create the task without a due date." epic: str | None "Optional free-form grouping label." + epic_id: str | None + "First-class Epic ID (`epc_...`)." id: str | None "Optional caller-generated task public ID (`tsk_...`). Persist it before creating a task when creation must survive a lost response. An existing ID returns 409 without modifying the task; read the task by ID to reconcile. Omit for a server-generated ID." links: dict[str, Any] | None @@ -96,6 +110,8 @@ class UserTaskBySourceInput(TypedDict, total=False): "Initial task name." org: str | None "Explicit organization for privileged callers." + owner_user: str | None + "Initial assigned user; immutable on retries." source_id: Required[str] "Source identity, for example owner/repo#123." source_scope: Required[str] @@ -169,6 +185,21 @@ class UserThreadCreateInput(TypedDict, total=False): "Attributes for the new thread. See ThreadCreateParams for the full set of accepted fields." +class UserThreadFromTemplateInput(TypedDict, total=False): + "Create a private thread from a template" + + computer: dict[str, Any] | None + "Optional computer choice, applied on creation only: `provider` (`sprites`, `vercel`, `e2b` or `devbox`; defaults to the template's) and `repositories` (0 to 16 `{repository: owner/name, ref: optional}`; the first is the primary working directory)." + first_message: str | None + "Optional first user message, posted only on creation." + key: str | None + "Required nonempty client idempotency key." + template: Required[str] + "Thread template lookup key." + title: str | None + "Title for the new thread." + + class TokenCreateInput(TypedDict, total=False): "Create a personal access token" @@ -383,6 +414,9 @@ class UserTaskListResponseDataItem(BaseModel): default=None, description="Number of readable tasks marked as blocking this task, whether or not they are done (see `GET /tasks/{task}/blockers`). Computed on list/show reads; create/update responses may lag one read behind.", ) + blockers: list[str] | None = Field( + default=None, description="Visible blocker IDs when requested with include=blockers." + ) closed_at: datetime | None = Field( default=None, description="When the task was marked as done or otherwise closed (ISO 8601). `null` if the task is still open.", @@ -421,6 +455,10 @@ class UserTaskListResponseDataItem(BaseModel): default=None, description="Free-form grouping label. `null` when the task is not in an epic.", ) + human_answer_receipts: dict[str, Any] | None = Field( + default=None, + description="Server-owned authenticated human answer intent, keyed by question version. Not infrastructure permission.", + ) id: str = Field(..., description="Task ID (`tsk_...`).") is_blocked: bool | None = Field( default=None, @@ -434,6 +472,10 @@ class UserTaskListResponseDataItem(BaseModel): default=None, description="Key-value map of named URLs or references associated with the task. Returns an empty object when no links have been set.", ) + machine_rescope_receipts: dict[str, Any] | None = Field( + default=None, + description="Server-owned records of machine-applied local rescopes, keyed by question version. Never evidence that a human answered.", + ) metadata: dict[str, Any] | None = Field( default=None, description="Arbitrary key-value map of application-specific data stored alongside the task. Returns an empty object when no metadata has been set.", @@ -507,6 +549,9 @@ class UserTaskListResponseDataItem(BaseModel): default=None, description="Minimum semantic version of `target_binary` that can run this work (for example `0.48.9`), in canonical `MAJOR.MINOR.PATCH[-prerelease][+build]` form. `null` when the task has no target.", ) + task_epic: str | None = Field( + default=None, description="First-class Epic membership; does not grant access to the task." + ) team: str | None = Field( default=None, description="ID of the team that owns this task (`tem_...`). `null` if the task is not scoped to a team.", @@ -660,6 +705,9 @@ class UserTaskBlockerCyclesResponseDataItemTasksItem(BaseModel): default=None, description="Number of readable tasks marked as blocking this task, whether or not they are done (see `GET /tasks/{task}/blockers`). Computed on list/show reads; create/update responses may lag one read behind.", ) + blockers: list[str] | None = Field( + default=None, description="Visible blocker IDs when requested with include=blockers." + ) closed_at: datetime | None = Field( default=None, description="When the task was marked as done or otherwise closed (ISO 8601). `null` if the task is still open.", @@ -696,7 +744,306 @@ class UserTaskBlockerCyclesResponseDataItemTasksItem(BaseModel): ) epic: str | None = Field( default=None, - description="Free-form grouping label. `null` when the task is not in an epic.", + description="Free-form grouping label. `null` when the task is not in an epic.", + ) + human_answer_receipts: dict[str, Any] | None = Field( + default=None, + description="Server-owned authenticated human answer intent, keyed by question version. Not infrastructure permission.", + ) + id: str = Field(..., description="Task ID (`tsk_...`).") + is_blocked: bool | None = Field( + default=None, + description="`true` while at least one blocking task is not yet done. Informational only - a blocked task can still change status - and derived at read time, so the task un-blocks automatically when its last open blocker completes. Computed on reads, including mutation responses.", + ) + is_stalled: bool | None = Field( + default=None, + description="True exactly when status is in_progress and the task has no lease or its lease expiry is in the past. Derived at read time from status and lease expiry, including on unannotated reads.", + ) + links: dict[str, Any] | None = Field( + default=None, + description="Key-value map of named URLs or references associated with the task. Returns an empty object when no links have been set.", + ) + machine_rescope_receipts: dict[str, Any] | None = Field( + default=None, + description="Server-owned records of machine-applied local rescopes, keyed by question version. Never evidence that a human answered.", + ) + metadata: dict[str, Any] | None = Field( + default=None, + description="Arbitrary key-value map of application-specific data stored alongside the task. Returns an empty object when no metadata has been set.", + ) + name: str = Field(..., description="Human-readable title of the task.") + org: str | None = Field( + default=None, + description="ID of the organization this task belongs to (`org_...`). `null` for tasks outside an org context.", + ) + owner_actor: UserTaskBlockerCyclesResponseDataItemTasksItemOwnerActor | None = Field( + default=None, + description="Resolved owner details including `id`, `name`, `alias`, and `profile_picture`. `null` if the task is unassigned or the owner cannot be resolved (e.g. assigned agent was deleted).", + ) + owner_agent: str | None = Field( + default=None, + description="ID of the agent assigned as owner (`agi_...`). `null` if the owner is a human user, the task is unassigned, or the assigned agent was deleted.", + ) + owner_user: str | None = Field( + default=None, + description="ID of the user assigned as owner (`usr_...`). `null` if the owner is an agent, the task is unassigned, or the assigned agent was deleted.", + ) + parent: str | None = Field( + default=None, + description="ID of the parent task when this task is a subtask (`tsk_...`). `null` for top-level tasks or when the parent is not readable. Subtasks nest exactly one level.", + ) + priority: int | None = Field( + default=None, + description="Priority level of the task from `0` (highest) to `4` (lowest). Defaults to `2` (medium) when not explicitly set.", + ) + project_id: str | None = Field( + default=None, + description="Optional project ID (`prj_...`). Membership does not change task visibility.", + ) + sandbox: str | None = Field( + default=None, + description="ID of the developer sandbox this task is scoped to (`dsb_...`). `null` for tasks outside a sandbox environment.", + ) + source_id: str | None = Field( + default=None, + description="Source object identity (for example `ArchAstro/firstlanding`). `null` when the task has no source.", + ) + source_scope: str | None = Field( + default=None, + description="Container of the work this task is about (for example `github.com`). `null` when the task has no source. Set together with `source_type` and `source_id`.", + ) + source_type: str | None = Field( + default=None, + description="Kind of source object (for example `repository`). `null` when the task has no source.", + ) + stalled_since: datetime | None = Field( + default=None, + description="Lease expiry for a stalled task, or its last update when no lease expiry exists. Null when not stalled.", + ) + status: str = Field( + ..., + description='Current status of the task. One of `"open"`, `"in_progress"`, `"in_review"`, `"paused"`, `"failed"`, `"superseding"`, `"done"`, or `"cancelled"`.', + ) + subtasks_count: int | None = Field( + default=None, + description="Number of readable subtasks under this task. Computed on list/show reads; create/update responses may report 0 until the next read. Always 0 for subtasks.", + ) + tags: list[str] | None = Field( + default=None, + description="Labels for grouping and filtering, stored lowercase and de-duplicated. Empty array when untagged.", + ) + target_binary: str | None = Field( + default=None, + description="Binary that must run this work (for example `my-cli`). A worker should take the task only when its own `target_binary` build is at least `target_version`. `null` when the task has no target. Set together with `target_version`.", + ) + target_version: str | None = Field( + default=None, + description="Minimum semantic version of `target_binary` that can run this work (for example `0.48.9`), in canonical `MAJOR.MINOR.PATCH[-prerelease][+build]` form. `null` when the task has no target.", + ) + task_epic: str | None = Field( + default=None, description="First-class Epic membership; does not grant access to the task." + ) + team: str | None = Field( + default=None, + description="ID of the team that owns this task (`tem_...`). `null` if the task is not scoped to a team.", + ) + thread: str | None = Field( + default=None, + description="ID of the thread this task is bound to (`thr_...`) - the conversation it was filed from, or the thread passed at creation. `null` for tasks not tied to a thread.", + ) + updated_at: datetime | None = Field( + default=None, description="When the task was last modified (ISO 8601)." + ) + user: str | None = Field( + default=None, + description="ID of the user that owns this task (`usr_...`). `null` if the task is scoped to a team.", + ) + + +class UserTaskBlockerCyclesResponseDataItem(BaseModel): + tasks: list[UserTaskBlockerCyclesResponseDataItemTasksItem] = Field( + ..., description="Every unfinished task in this cyclic blocker component." + ) + + +class UserTaskBlockerCyclesResponse(BaseModel): + """ + Successful response + """ + + after_cursor: str | None = None + before_cursor: str | None = None + data: list[UserTaskBlockerCyclesResponseDataItem] + has_more: bool + + +class UserTaskByExternalReferenceResponseDataItemCreatedByActorProfilePicture(BaseModel): + file: str | None = Field( + default=None, + description="ID of the underlying storage file (`fil_...`). `null` when the image is not backed by a platform storage file.", + ) + height: int | None = Field( + default=None, description="Height of the image in pixels. `null` if not known." + ) + media: str | None = Field( + default=None, + description="ID of the associated media record (`med_...`). `null` when the image is not linked to a media entity.", + ) + mime_type: str | None = Field( + default=None, + description='MIME type of the image, e.g. `"image/png"` or `"image/jpeg"`. `null` if not known.', + ) + refresh_url: str | None = Field( + default=None, + description="Endpoint URL you can call to obtain a fresh signed `url` when the current one has expired. `null` if the URL does not require refreshing.", + ) + url: str | None = Field( + default=None, + description="Signed or public URL for downloading the image. May be time-limited; use `refresh_url` to obtain a new URL when this one expires.", + ) + width: int | None = Field( + default=None, description="Width of the image in pixels. `null` if not known." + ) + + +class UserTaskByExternalReferenceResponseDataItemCreatedByActor(BaseModel): + alias: str | None = Field( + default=None, + description="Short handle or alias for the actor, used as an alternate display identifier. `null` if not configured.", + ) + id: str | None = Field( + default=None, + description='Composite actor identifier. Format is `"user-"` for human users or `"agent-"` for agents.', + ) + name: str | None = Field( + default=None, + description="Display name of the actor shown in the UI. `null` if no name is set.", + ) + profile_picture: ( + UserTaskByExternalReferenceResponseDataItemCreatedByActorProfilePicture | None + ) = Field( + default=None, + description="Profile picture for the actor. `null` if the actor has no profile picture.", + ) + + +class UserTaskByExternalReferenceResponseDataItemCurrentLease(BaseModel): + expires_at: datetime = Field( + ..., description="Server-calculated lease expiry in ISO 8601 format." + ) + harness: str = Field(..., description="Bounded harness identifier for the coding session.") + session_name: str = Field( + ..., description="Display name supplied by the coding session that holds the lease." + ) + + +class UserTaskByExternalReferenceResponseDataItemOwnerActorProfilePicture(BaseModel): + file: str | None = Field( + default=None, + description="ID of the underlying storage file (`fil_...`). `null` when the image is not backed by a platform storage file.", + ) + height: int | None = Field( + default=None, description="Height of the image in pixels. `null` if not known." + ) + media: str | None = Field( + default=None, + description="ID of the associated media record (`med_...`). `null` when the image is not linked to a media entity.", + ) + mime_type: str | None = Field( + default=None, + description='MIME type of the image, e.g. `"image/png"` or `"image/jpeg"`. `null` if not known.', + ) + refresh_url: str | None = Field( + default=None, + description="Endpoint URL you can call to obtain a fresh signed `url` when the current one has expired. `null` if the URL does not require refreshing.", + ) + url: str | None = Field( + default=None, + description="Signed or public URL for downloading the image. May be time-limited; use `refresh_url` to obtain a new URL when this one expires.", + ) + width: int | None = Field( + default=None, description="Width of the image in pixels. `null` if not known." + ) + + +class UserTaskByExternalReferenceResponseDataItemOwnerActor(BaseModel): + alias: str | None = Field( + default=None, + description="Short handle or alias for the actor, used as an alternate display identifier. `null` if not configured.", + ) + id: str | None = Field( + default=None, + description='Composite actor identifier. Format is `"user-"` for human users or `"agent-"` for agents.', + ) + name: str | None = Field( + default=None, + description="Display name of the actor shown in the UI. `null` if no name is set.", + ) + profile_picture: UserTaskByExternalReferenceResponseDataItemOwnerActorProfilePicture | None = ( + Field( + default=None, + description="Profile picture for the actor. `null` if the actor has no profile picture.", + ) + ) + + +class UserTaskByExternalReferenceResponseDataItem(BaseModel): + agent: str | None = Field( + default=None, + description="ID of the agent that owns this task (`agi_...`). `null` if the task is scoped to a team or user.", + ) + aggregate_version: int | None = Field( + default=None, + description="Event-stream version for optimistic update fencing. Pass this value as `expected_version` on an update to reject concurrent writes.", + ) + blocked_by_count: int | None = Field( + default=None, + description="Number of readable tasks marked as blocking this task, whether or not they are done (see `GET /tasks/{task}/blockers`). Computed on list/show reads; create/update responses may lag one read behind.", + ) + blockers: list[str] | None = Field( + default=None, description="Visible blocker IDs when requested with include=blockers." + ) + closed_at: datetime | None = Field( + default=None, + description="When the task was marked as done or otherwise closed (ISO 8601). `null` if the task is still open.", + ) + comments_count: int | None = Field( + default=None, description="Total number of comments posted on this task." + ) + created_at: datetime | None = Field( + default=None, description="When the task was created (ISO 8601)." + ) + created_by_actor: UserTaskByExternalReferenceResponseDataItemCreatedByActor | None = Field( + default=None, + description="Resolved creator details including `id`, `name`, `alias`, and `profile_picture`. `null` if no creator is set or the creator cannot be resolved (e.g. creating agent was deleted).", + ) + created_by_agent: str | None = Field( + default=None, + description="ID of the agent that created this task (`agi_...`). `null` if the task was created by a human user, or if the creating agent was later deleted.", + ) + created_by_user: str | None = Field( + default=None, + description="ID of the user who created this task (`usr_...`). `null` if the task was created by an agent, or if creator provenance was cleared after the creator was deleted.", + ) + current_lease: UserTaskByExternalReferenceResponseDataItemCurrentLease | None = Field( + default=None, + description="Viewer-safe live coding-session lease summary. `null` when the task is unleased or the projected lease has expired. Fencing identifiers are never included.", + ) + description: str | None = Field( + default=None, + description="Long-form description or notes for the task. `null` if no description has been provided.", + ) + due_date: datetime | None = Field( + default=None, + description="Date and time by which the task should be completed (ISO 8601). `null` if no due date is set.", + ) + epic: str | None = Field( + default=None, + description="Free-form grouping label. `null` when the task is not in an epic.", + ) + human_answer_receipts: dict[str, Any] | None = Field( + default=None, + description="Server-owned authenticated human answer intent, keyed by question version. Not infrastructure permission.", ) id: str = Field(..., description="Task ID (`tsk_...`).") is_blocked: bool | None = Field( @@ -711,6 +1058,10 @@ class UserTaskBlockerCyclesResponseDataItemTasksItem(BaseModel): default=None, description="Key-value map of named URLs or references associated with the task. Returns an empty object when no links have been set.", ) + machine_rescope_receipts: dict[str, Any] | None = Field( + default=None, + description="Server-owned records of machine-applied local rescopes, keyed by question version. Never evidence that a human answered.", + ) metadata: dict[str, Any] | None = Field( default=None, description="Arbitrary key-value map of application-specific data stored alongside the task. Returns an empty object when no metadata has been set.", @@ -720,7 +1071,7 @@ class UserTaskBlockerCyclesResponseDataItemTasksItem(BaseModel): default=None, description="ID of the organization this task belongs to (`org_...`). `null` for tasks outside an org context.", ) - owner_actor: UserTaskBlockerCyclesResponseDataItemTasksItemOwnerActor | None = Field( + owner_actor: UserTaskByExternalReferenceResponseDataItemOwnerActor | None = Field( default=None, description="Resolved owner details including `id`, `name`, `alias`, and `profile_picture`. `null` if the task is unassigned or the owner cannot be resolved (e.g. assigned agent was deleted).", ) @@ -784,6 +1135,9 @@ class UserTaskBlockerCyclesResponseDataItemTasksItem(BaseModel): default=None, description="Minimum semantic version of `target_binary` that can run this work (for example `0.48.9`), in canonical `MAJOR.MINOR.PATCH[-prerelease][+build]` form. `null` when the task has no target.", ) + task_epic: str | None = Field( + default=None, description="First-class Epic membership; does not grant access to the task." + ) team: str | None = Field( default=None, description="ID of the team that owns this task (`tem_...`). `null` if the task is not scoped to a team.", @@ -801,21 +1155,12 @@ class UserTaskBlockerCyclesResponseDataItemTasksItem(BaseModel): ) -class UserTaskBlockerCyclesResponseDataItem(BaseModel): - tasks: list[UserTaskBlockerCyclesResponseDataItemTasksItem] = Field( - ..., description="Every unfinished task in this cyclic blocker component." - ) - - -class UserTaskBlockerCyclesResponse(BaseModel): +class UserTaskByExternalReferenceResponse(BaseModel): """ Successful response """ - after_cursor: str | None = None - before_cursor: str | None = None - data: list[UserTaskBlockerCyclesResponseDataItem] - has_more: bool + data: list[UserTaskByExternalReferenceResponseDataItem] class UserTaskReadyResponseDataItemTaskCreatedByActorProfilePicture(BaseModel): @@ -937,6 +1282,9 @@ class UserTaskReadyResponseDataItemTask(BaseModel): default=None, description="Number of readable tasks marked as blocking this task, whether or not they are done (see `GET /tasks/{task}/blockers`). Computed on list/show reads; create/update responses may lag one read behind.", ) + blockers: list[str] | None = Field( + default=None, description="Visible blocker IDs when requested with include=blockers." + ) closed_at: datetime | None = Field( default=None, description="When the task was marked as done or otherwise closed (ISO 8601). `null` if the task is still open.", @@ -975,6 +1323,10 @@ class UserTaskReadyResponseDataItemTask(BaseModel): default=None, description="Free-form grouping label. `null` when the task is not in an epic.", ) + human_answer_receipts: dict[str, Any] | None = Field( + default=None, + description="Server-owned authenticated human answer intent, keyed by question version. Not infrastructure permission.", + ) id: str = Field(..., description="Task ID (`tsk_...`).") is_blocked: bool | None = Field( default=None, @@ -988,6 +1340,10 @@ class UserTaskReadyResponseDataItemTask(BaseModel): default=None, description="Key-value map of named URLs or references associated with the task. Returns an empty object when no links have been set.", ) + machine_rescope_receipts: dict[str, Any] | None = Field( + default=None, + description="Server-owned records of machine-applied local rescopes, keyed by question version. Never evidence that a human answered.", + ) metadata: dict[str, Any] | None = Field( default=None, description="Arbitrary key-value map of application-specific data stored alongside the task. Returns an empty object when no metadata has been set.", @@ -1061,6 +1417,9 @@ class UserTaskReadyResponseDataItemTask(BaseModel): default=None, description="Minimum semantic version of `target_binary` that can run this work (for example `0.48.9`), in canonical `MAJOR.MINOR.PATCH[-prerelease][+build]` form. `null` when the task has no target.", ) + task_epic: str | None = Field( + default=None, description="First-class Epic membership; does not grant access to the task." + ) team: str | None = Field( default=None, description="ID of the team that owns this task (`tem_...`). `null` if the task is not scoped to a team.", @@ -1225,6 +1584,9 @@ class UserTaskSearchResponseDataItem(BaseModel): default=None, description="Number of readable tasks marked as blocking this task, whether or not they are done (see `GET /tasks/{task}/blockers`). Computed on list/show reads; create/update responses may lag one read behind.", ) + blockers: list[str] | None = Field( + default=None, description="Visible blocker IDs when requested with include=blockers." + ) closed_at: datetime | None = Field( default=None, description="When the task was marked as done or otherwise closed (ISO 8601). `null` if the task is still open.", @@ -1263,6 +1625,10 @@ class UserTaskSearchResponseDataItem(BaseModel): default=None, description="Free-form grouping label. `null` when the task is not in an epic.", ) + human_answer_receipts: dict[str, Any] | None = Field( + default=None, + description="Server-owned authenticated human answer intent, keyed by question version. Not infrastructure permission.", + ) id: str = Field(..., description="Task ID (`tsk_...`).") is_blocked: bool | None = Field( default=None, @@ -1276,6 +1642,10 @@ class UserTaskSearchResponseDataItem(BaseModel): default=None, description="Key-value map of named URLs or references associated with the task. Returns an empty object when no links have been set.", ) + machine_rescope_receipts: dict[str, Any] | None = Field( + default=None, + description="Server-owned records of machine-applied local rescopes, keyed by question version. Never evidence that a human answered.", + ) metadata: dict[str, Any] | None = Field( default=None, description="Arbitrary key-value map of application-specific data stored alongside the task. Returns an empty object when no metadata has been set.", @@ -1349,6 +1719,9 @@ class UserTaskSearchResponseDataItem(BaseModel): default=None, description="Minimum semantic version of `target_binary` that can run this work (for example `0.48.9`), in canonical `MAJOR.MINOR.PATCH[-prerelease][+build]` form. `null` when the task has no target.", ) + task_epic: str | None = Field( + default=None, description="First-class Epic membership; does not grant access to the task." + ) team: str | None = Field( default=None, description="ID of the team that owns this task (`tem_...`). `null` if the task is not scoped to a team.", @@ -1395,6 +1768,36 @@ class UserThreadListResponseDataItemParentMessageAclAddItem(BaseModel): ) +class UserThreadListResponseDataItemParentMessageAclAddDeniesItem(BaseModel): + actions: list[str] = Field( + ..., + description='Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.', + ) + principal: str | None = Field( + default=None, + description='The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.', + ) + principal_type: str = Field( + ..., + description='The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.', + ) + + +class UserThreadListResponseDataItemParentMessageAclDeniesItem(BaseModel): + actions: list[str] = Field( + ..., + description='Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.', + ) + principal: str | None = Field( + default=None, + description='The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.', + ) + principal_type: str = Field( + ..., + description='The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.', + ) + + class UserThreadListResponseDataItemParentMessageAclGrantsItem(BaseModel): actions: list[str] = Field( ..., @@ -1421,19 +1824,45 @@ class UserThreadListResponseDataItemParentMessageAclRemoveItem(BaseModel): ) +class UserThreadListResponseDataItemParentMessageAclRemoveDeniesItem(BaseModel): + principal: str | None = Field( + default=None, + description='The identifier of the principal to remove. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`. Omit when `principal_type` is `"everyone"`.', + ) + principal_type: str = Field( + ..., + description='The kind of principal to remove. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.', + ) + + class UserThreadListResponseDataItemParentMessageAcl(BaseModel): add: list[UserThreadListResponseDataItemParentMessageAclAddItem] | None = Field( default=None, description="Patch mode: grants to add or merge into the existing list. Cannot be combined with `grants`.", ) + add_denies: list[UserThreadListResponseDataItemParentMessageAclAddDeniesItem] | None = Field( + default=None, + description="Patch mode: denies to add or merge, replacing any grant for the same principal.", + ) + denies: list[UserThreadListResponseDataItemParentMessageAclDeniesItem] | None = Field( + default=None, + description="Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support.", + ) grants: list[UserThreadListResponseDataItemParentMessageAclGrantsItem] | None = Field( default=None, description="Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", ) + preserve_denies: bool | None = Field( + default=None, + description="Retain current server denies atomically in replacement or patch mode; current denies win.", + ) remove: list[UserThreadListResponseDataItemParentMessageAclRemoveItem] | None = Field( default=None, description="Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", ) + remove_denies: list[UserThreadListResponseDataItemParentMessageAclRemoveDeniesItem] | None = ( + Field(default=None, description="Patch mode: principals whose denies should be removed.") + ) class UserThreadListResponseDataItemParentMessageActorsItemProfilePicture(BaseModel): @@ -1911,6 +2340,36 @@ class UserThreadListResponseDataItemParticipatingAgentsItemAclAddItem(BaseModel) ) +class UserThreadListResponseDataItemParticipatingAgentsItemAclAddDeniesItem(BaseModel): + actions: list[str] = Field( + ..., + description='Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.', + ) + principal: str | None = Field( + default=None, + description='The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.', + ) + principal_type: str = Field( + ..., + description='The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.', + ) + + +class UserThreadListResponseDataItemParticipatingAgentsItemAclDeniesItem(BaseModel): + actions: list[str] = Field( + ..., + description='Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.', + ) + principal: str | None = Field( + default=None, + description='The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.', + ) + principal_type: str = Field( + ..., + description='The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.', + ) + + class UserThreadListResponseDataItemParticipatingAgentsItemAclGrantsItem(BaseModel): actions: list[str] = Field( ..., @@ -1937,19 +2396,47 @@ class UserThreadListResponseDataItemParticipatingAgentsItemAclRemoveItem(BaseMod ) +class UserThreadListResponseDataItemParticipatingAgentsItemAclRemoveDeniesItem(BaseModel): + principal: str | None = Field( + default=None, + description='The identifier of the principal to remove. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`. Omit when `principal_type` is `"everyone"`.', + ) + principal_type: str = Field( + ..., + description='The kind of principal to remove. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.', + ) + + class UserThreadListResponseDataItemParticipatingAgentsItemAcl(BaseModel): add: list[UserThreadListResponseDataItemParticipatingAgentsItemAclAddItem] | None = Field( default=None, description="Patch mode: grants to add or merge into the existing list. Cannot be combined with `grants`.", ) + add_denies: ( + list[UserThreadListResponseDataItemParticipatingAgentsItemAclAddDeniesItem] | None + ) = Field( + default=None, + description="Patch mode: denies to add or merge, replacing any grant for the same principal.", + ) + denies: list[UserThreadListResponseDataItemParticipatingAgentsItemAclDeniesItem] | None = Field( + default=None, + description="Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support.", + ) grants: list[UserThreadListResponseDataItemParticipatingAgentsItemAclGrantsItem] | None = Field( default=None, description="Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", ) + preserve_denies: bool | None = Field( + default=None, + description="Retain current server denies atomically in replacement or patch mode; current denies win.", + ) remove: list[UserThreadListResponseDataItemParticipatingAgentsItemAclRemoveItem] | None = Field( default=None, description="Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", ) + remove_denies: ( + list[UserThreadListResponseDataItemParticipatingAgentsItemAclRemoveDeniesItem] | None + ) = Field(default=None, description="Patch mode: principals whose denies should be removed.") class UserThreadListResponseDataItemParticipatingAgentsItemSourceSolutionCurrentSolutionOrgLogo( @@ -2733,6 +3220,10 @@ class UserThreadListResponseDataItem(BaseModel): default=None, description="ID of the team that owns this thread (`team_...`). `null` for user-owned or agent-owned threads.", ) + thread_template_key: str | None = Field( + default=None, + description="Read-only key of the template used to create this thread. `null` for threads not created from a template.", + ) title: str | None = Field( default=None, description="Human-readable name of the thread. `null` if no title has been set.", @@ -2845,6 +3336,36 @@ class UserArtifactsResponseDataItemAclAddItem(BaseModel): ) +class UserArtifactsResponseDataItemAclAddDeniesItem(BaseModel): + actions: list[str] = Field( + ..., + description='Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.', + ) + principal: str | None = Field( + default=None, + description='The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.', + ) + principal_type: str = Field( + ..., + description='The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.', + ) + + +class UserArtifactsResponseDataItemAclDeniesItem(BaseModel): + actions: list[str] = Field( + ..., + description='Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.', + ) + principal: str | None = Field( + default=None, + description='The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.', + ) + principal_type: str = Field( + ..., + description='The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.', + ) + + class UserArtifactsResponseDataItemAclGrantsItem(BaseModel): actions: list[str] = Field( ..., @@ -2871,19 +3392,45 @@ class UserArtifactsResponseDataItemAclRemoveItem(BaseModel): ) +class UserArtifactsResponseDataItemAclRemoveDeniesItem(BaseModel): + principal: str | None = Field( + default=None, + description='The identifier of the principal to remove. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`. Omit when `principal_type` is `"everyone"`.', + ) + principal_type: str = Field( + ..., + description='The kind of principal to remove. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.', + ) + + class UserArtifactsResponseDataItemAcl(BaseModel): add: list[UserArtifactsResponseDataItemAclAddItem] | None = Field( default=None, description="Patch mode: grants to add or merge into the existing list. Cannot be combined with `grants`.", ) + add_denies: list[UserArtifactsResponseDataItemAclAddDeniesItem] | None = Field( + default=None, + description="Patch mode: denies to add or merge, replacing any grant for the same principal.", + ) + denies: list[UserArtifactsResponseDataItemAclDeniesItem] | None = Field( + default=None, + description="Replace mode: the complete deny list. Supplying grants or denies replaces both lists. Requires schema deny support.", + ) grants: list[UserArtifactsResponseDataItemAclGrantsItem] | None = Field( default=None, description="Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", ) + preserve_denies: bool | None = Field( + default=None, + description="Retain current server denies atomically in replacement or patch mode; current denies win.", + ) remove: list[UserArtifactsResponseDataItemAclRemoveItem] | None = Field( default=None, description="Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", ) + remove_denies: list[UserArtifactsResponseDataItemAclRemoveDeniesItem] | None = Field( + default=None, description="Patch mode: principals whose denies should be removed." + ) class UserArtifactsResponseDataItemImageSource(BaseModel): @@ -3076,48 +3623,6 @@ class UserOrgsResponse(BaseModel): ) -class UserTaskEpicsResponseDataItemNextReadyItem(BaseModel): - id: str - name: str - priority: int - status: str - - -class UserTaskEpicsResponseDataItemRootBlockersItem(BaseModel): - downstream_count: int - id: str - name: str - priority: int - status: str - - -class UserTaskEpicsResponseDataItem(BaseModel): - blocked_count: int - counts: dict[str, Any] = Field( - ..., description="Task counts keyed by status, including closed tasks." - ) - epic: str - next_ready: list[UserTaskEpicsResponseDataItemNextReadyItem] - root_blockers: list[UserTaskEpicsResponseDataItemRootBlockersItem] - root_blockers_partial: bool = Field( - ..., description="True when root ranking used a truncated in-epic graph." - ) - top_open_priority: int | None = None - updated_at: datetime - - -class UserTaskEpicsResponse(BaseModel): - """ - Successful response - """ - - after_cursor: str | None = None - before_cursor: str | None = None - data: list[UserTaskEpicsResponseDataItem] - has_more: bool - no_epic_open_count: int - - class AsyncIntegrationResource: def __init__(self, http: HttpClient): self._http = http @@ -3186,19 +3691,108 @@ async def create(self, user: str, input: UserSshKeyCreateInput) -> UserSSHKey: session or a `full_access` personal access token. Args: - user: User ID (`usr_...`) or `me`. + user: User ID (`usr_...`) or `me`. + input: Request body. + input.label: A label such as `Work laptop`. + input.public_key: One `ssh-ed25519 ` public key without options or a comment. + + Returns: + Metadata for the registered key; no key material. + """ + return await self._http.request( + f"/api/v1/users/{user}/ssh_keys", + method="POST", + body=input, + response_type=UserSSHKey, + ) + + +class AsyncUserTaskEpicResource: + def __init__(self, http: HttpClient): + self._http = http + + async def list( + self, + user: str, + *, + representation: str | None = None, + name: str | None = None, + team: str | None = None, + org: str | None = None, + source_scope: str | None = None, + source_type: str | None = None, + source_id: str | None = None, + top_priority: int | None = None, + owner: str | None = None, + include_closed: bool | None = None, + limit: int | None = None, + after_cursor: str | None = None, + ) -> dict[str, Any] | TaskEpicEntityCollection: + """ + List an owner's epic summaries + Groups tasks by their exact epic label, ordered by label. Closed tasks include cancelled tasks, but cancelled prerequisites still block. Source filters select the tasks summarized; blockers outside that selection still affect readiness. Root ranking is capped per epic and root_blockers_partial is true when that graph is truncated. No epic entity is created. + + Args: + representation: labels (default) or entities. + name: Exact entity name; only used for entities. + source_scope: Exact source scope; supply all three source fields. + source_type: Exact source type. + source_id: Exact source ID. + top_priority: Exact highest open priority, from 0 to 4. + owner: Keep only epics with at least one non-closed task owned by this user: `me` or a user public ID (`usr_...`). + include_closed: Include epics with no non-closed tasks; defaults to false. + limit: Maximum epics; defaults to 50, capped at 100. + after_cursor: Opaque forward cursor from the preceding page. + + Returns: + Successful response + """ + query: dict[str, object] = {} + if representation is not None: + query["representation"] = representation + if name is not None: + query["name"] = name + if team is not None: + query["team"] = team + if org is not None: + query["org"] = org + if source_scope is not None: + query["source_scope"] = source_scope + if source_type is not None: + query["source_type"] = source_type + if source_id is not None: + query["source_id"] = source_id + if top_priority is not None: + query["top_priority"] = top_priority + if owner is not None: + query["owner"] = owner + if include_closed is not None: + query["include_closed"] = include_closed + if limit is not None: + query["limit"] = limit + if after_cursor is not None: + query["after_cursor"] = after_cursor + return await self._http.request( + f"/api/v1/users/{user}/task_epics", + query=query, + response_type=TaskEpicEntityCollection | dict[str, Any], + ) + + async def create(self, user: str, input: UserTaskEpicCreateInput) -> TaskEpicEntity: + """ + Create a task Epic + + Args: input: Request body. - input.label: A label such as `Work laptop`. - input.public_key: One `ssh-ed25519 ` public key without options or a comment. Returns: - Metadata for the registered key; no key material. + Successful response """ return await self._http.request( - f"/api/v1/users/{user}/ssh_keys", + f"/api/v1/users/{user}/task_epics", method="POST", body=input, - response_type=UserSSHKey, + response_type=TaskEpicEntity, ) @@ -3215,6 +3809,9 @@ async def list( status: str | None = None, owner_user: str | None = None, owner_agent: str | None = None, + owner: str | None = None, + involving: str | None = None, + summary: bool | None = None, priority: int | None = None, tag: str | None = None, parent: str | None = None, @@ -3251,6 +3848,9 @@ async def list( status: Filter tasks by status. One of `"open"`, `"in_progress"`, `"in_review"`, or `"done"`. Omit to return tasks in all statuses. owner_user: Filter tasks assigned to a specific user. Provide the user's public ID (`usr_...`). owner_agent: Filter tasks assigned to a specific agent. Provide the agent's public ID (`agi_...`). + owner: Return only tasks owned by this user: `me` or a user public ID (`usr_...`). + involving: Return only tasks owned or created by this user: `me` or a user public ID (`usr_...`). The "My work" predicate. + summary: When true, omit `description` from every task. Use for list views. priority: Filter tasks by priority, from 0 (highest) to 4 (lowest). tag: Return only tasks carrying this tag (matched against the canonical lowercase form). parent: Return only subtasks of the given task (`tsk_...`), or pass `none` to return only top-level tasks. @@ -3283,6 +3883,12 @@ async def list( query["owner_user"] = owner_user if owner_agent is not None: query["owner_agent"] = owner_agent + if owner is not None: + query["owner"] = owner + if involving is not None: + query["involving"] = involving + if summary is not None: + query["summary"] = summary if priority is not None: query["priority"] = priority if tag is not None: @@ -3394,6 +4000,45 @@ async def blocker_cycles( response_type=UserTaskBlockerCyclesResponse, ) + async def by_external_reference( + self, + user: str, + external_scope: str, + object_type: str, + object_id: str, + *, + team: str | None = None, + org: str | None = None, + ) -> UserTaskByExternalReferenceResponse: + """ + Find an owner's tasks by external reference + Returns all exact external-reference matches owned by the requested principal. Multiple matches remain explicit; callers must not choose an arbitrary task. + + Args: + user: User ID (`usr_...`) for user-scoped tasks. + team: Team owner. + org: Organization consistency check. + external_scope: External host. + object_type: External object type. + object_id: External object identity. + + Returns: + Successful response + """ + query: dict[str, object] = {} + if team is not None: + query["team"] = team + if org is not None: + query["org"] = org + query["external_scope"] = external_scope + query["object_type"] = object_type + query["object_id"] = object_id + return await self._http.request( + f"/api/v1/users/{user}/tasks/by-external-reference", + query=query, + response_type=UserTaskByExternalReferenceResponse, + ) + async def by_source(self, user: str, input: UserTaskBySourceInput) -> TaskEnsureResult: """ Find or create a task by source @@ -3407,6 +4052,7 @@ async def by_source(self, user: str, input: UserTaskBySourceInput) -> TaskEnsure input.epic: Initial epic grouping. input.name: Initial task name. input.org: Explicit organization for privileged callers. + input.owner_user: Initial assigned user; immutable on retries. input.source_id: Source identity, for example owner/repo#123. input.source_scope: Source scope, for example github. input.source_type: Source type, for example pull_request. @@ -3652,6 +4298,42 @@ async def create(self, user: str, input: UserThreadCreateInput) -> Thread: response_type=Thread, ) + async def from_template(self, user: str, input: UserThreadFromTemplateInput) -> dict[str, Any]: + """ + Create a private thread from a template + Creates a private personal thread, installs the template's agent once per user, + and atomically adds its members and a dedicated E2B computer. Requires + `devbox_access`. The computer starts pending and provisions asynchronously. + `key` is prefixed by the template namespace and is unique for the user. Replays return + 200 and never provision another computer or resend the first message; creation + returns 201. Initial-message delivery occurs after commit; a delivery failure + is returned as `first_message_error` so the caller can resend it. + `computer` is optional and applies on creation only: a replay with the same + `key` returns the original thread and computer, ignoring any different + `computer`, exactly like `title` and `first_message`. Invalid `computer` + input returns 422 `invalid_parameters` before anything is created; a provider + this deployment has no credentials for returns 422 `provider_unavailable`. + Unknown templates return 422 `unknown_thread_template`; installation failures + return 502 `agent_install_failed`. Computer config and credentials are never returned. + + Args: + user: User ID (`usr_...`) whose threads should be listed. + input: Request body. + input.computer: Optional computer choice, applied on creation only: `provider` (`sprites`, `vercel`, `e2b` or `devbox`; defaults to the template's) and `repositories` (0 to 16 `{repository: owner/name, ref: optional}`; the first is the primary working directory). + input.first_message: Optional first user message, posted only on creation. + input.key: Required nonempty client idempotency key. + input.template: Thread template lookup key. + input.title: Title for the new thread. + + Returns: + Thread fields plus agent and computers summaries, and optional first_message_error. + """ + return await self._http.request( + f"/api/v1/users/{user}/threads/from_template", + method="POST", + body=input, + ) + class AsyncTokenResource: def __init__(self, http: HttpClient): @@ -3740,6 +4422,7 @@ def __init__(self, http: HttpClient): self._http = http self.integrations = AsyncIntegrationResource(http) self.ssh_keys = AsyncUserSshKeyResource(http) + self.task_epics = AsyncUserTaskEpicResource(http) self.tasks = AsyncUserTaskResource(http) self.threads = AsyncUserThreadResource(http) self.tokens = AsyncTokenResource(http) @@ -3898,61 +4581,6 @@ async def profile(self, user: str, input: UserProfileInput) -> User: response_type=User, ) - async def task_epics( - self, - user: str, - *, - team: str | None = None, - org: str | None = None, - source_scope: str | None = None, - source_type: str | None = None, - source_id: str | None = None, - top_priority: int | None = None, - include_closed: bool | None = None, - limit: int | None = None, - after_cursor: str | None = None, - ) -> UserTaskEpicsResponse: - """ - List an owner's epic summaries - Groups tasks by their exact epic label, ordered by label. Closed tasks include cancelled tasks, but cancelled prerequisites still block. Source filters select the tasks summarized; blockers outside that selection still affect readiness. Root ranking is capped per epic and root_blockers_partial is true when that graph is truncated. No epic entity is created. - - Args: - source_scope: Exact source scope; supply all three source fields. - source_type: Exact source type. - source_id: Exact source ID. - top_priority: Exact highest open priority, from 0 to 4. - include_closed: Include epics with no non-closed tasks; defaults to false. - limit: Maximum epics; defaults to 50, capped at 100. - after_cursor: Opaque forward cursor from the preceding page. - - Returns: - Successful response - """ - query: dict[str, object] = {} - if team is not None: - query["team"] = team - if org is not None: - query["org"] = org - if source_scope is not None: - query["source_scope"] = source_scope - if source_type is not None: - query["source_type"] = source_type - if source_id is not None: - query["source_id"] = source_id - if top_priority is not None: - query["top_priority"] = top_priority - if include_closed is not None: - query["include_closed"] = include_closed - if limit is not None: - query["limit"] = limit - if after_cursor is not None: - query["after_cursor"] = after_cursor - return await self._http.request( - f"/api/v1/users/{user}/task_epics", - query=query, - response_type=UserTaskEpicsResponse, - ) - class IntegrationResource: def __init__(self, http: SyncHttpClient): @@ -4038,6 +4666,95 @@ def create(self, user: str, input: UserSshKeyCreateInput) -> UserSSHKey: ) +class UserTaskEpicResource: + def __init__(self, http: SyncHttpClient): + self._http = http + + def list( + self, + user: str, + *, + representation: str | None = None, + name: str | None = None, + team: str | None = None, + org: str | None = None, + source_scope: str | None = None, + source_type: str | None = None, + source_id: str | None = None, + top_priority: int | None = None, + owner: str | None = None, + include_closed: bool | None = None, + limit: int | None = None, + after_cursor: str | None = None, + ) -> dict[str, Any] | TaskEpicEntityCollection: + """ + List an owner's epic summaries + Groups tasks by their exact epic label, ordered by label. Closed tasks include cancelled tasks, but cancelled prerequisites still block. Source filters select the tasks summarized; blockers outside that selection still affect readiness. Root ranking is capped per epic and root_blockers_partial is true when that graph is truncated. No epic entity is created. + + Args: + representation: labels (default) or entities. + name: Exact entity name; only used for entities. + source_scope: Exact source scope; supply all three source fields. + source_type: Exact source type. + source_id: Exact source ID. + top_priority: Exact highest open priority, from 0 to 4. + owner: Keep only epics with at least one non-closed task owned by this user: `me` or a user public ID (`usr_...`). + include_closed: Include epics with no non-closed tasks; defaults to false. + limit: Maximum epics; defaults to 50, capped at 100. + after_cursor: Opaque forward cursor from the preceding page. + + Returns: + Successful response + """ + query: dict[str, object] = {} + if representation is not None: + query["representation"] = representation + if name is not None: + query["name"] = name + if team is not None: + query["team"] = team + if org is not None: + query["org"] = org + if source_scope is not None: + query["source_scope"] = source_scope + if source_type is not None: + query["source_type"] = source_type + if source_id is not None: + query["source_id"] = source_id + if top_priority is not None: + query["top_priority"] = top_priority + if owner is not None: + query["owner"] = owner + if include_closed is not None: + query["include_closed"] = include_closed + if limit is not None: + query["limit"] = limit + if after_cursor is not None: + query["after_cursor"] = after_cursor + return self._http.request( + f"/api/v1/users/{user}/task_epics", + query=query, + response_type=TaskEpicEntityCollection | dict[str, Any], + ) + + def create(self, user: str, input: UserTaskEpicCreateInput) -> TaskEpicEntity: + """ + Create a task Epic + + Args: + input: Request body. + + Returns: + Successful response + """ + return self._http.request( + f"/api/v1/users/{user}/task_epics", + method="POST", + body=input, + response_type=TaskEpicEntity, + ) + + class UserTaskResource: def __init__(self, http: SyncHttpClient): self._http = http @@ -4051,6 +4768,9 @@ def list( status: str | None = None, owner_user: str | None = None, owner_agent: str | None = None, + owner: str | None = None, + involving: str | None = None, + summary: bool | None = None, priority: int | None = None, tag: str | None = None, parent: str | None = None, @@ -4087,6 +4807,9 @@ def list( status: Filter tasks by status. One of `"open"`, `"in_progress"`, `"in_review"`, or `"done"`. Omit to return tasks in all statuses. owner_user: Filter tasks assigned to a specific user. Provide the user's public ID (`usr_...`). owner_agent: Filter tasks assigned to a specific agent. Provide the agent's public ID (`agi_...`). + owner: Return only tasks owned by this user: `me` or a user public ID (`usr_...`). + involving: Return only tasks owned or created by this user: `me` or a user public ID (`usr_...`). The "My work" predicate. + summary: When true, omit `description` from every task. Use for list views. priority: Filter tasks by priority, from 0 (highest) to 4 (lowest). tag: Return only tasks carrying this tag (matched against the canonical lowercase form). parent: Return only subtasks of the given task (`tsk_...`), or pass `none` to return only top-level tasks. @@ -4119,6 +4842,12 @@ def list( query["owner_user"] = owner_user if owner_agent is not None: query["owner_agent"] = owner_agent + if owner is not None: + query["owner"] = owner + if involving is not None: + query["involving"] = involving + if summary is not None: + query["summary"] = summary if priority is not None: query["priority"] = priority if tag is not None: @@ -4230,6 +4959,45 @@ def blocker_cycles( response_type=UserTaskBlockerCyclesResponse, ) + def by_external_reference( + self, + user: str, + external_scope: str, + object_type: str, + object_id: str, + *, + team: str | None = None, + org: str | None = None, + ) -> UserTaskByExternalReferenceResponse: + """ + Find an owner's tasks by external reference + Returns all exact external-reference matches owned by the requested principal. Multiple matches remain explicit; callers must not choose an arbitrary task. + + Args: + user: User ID (`usr_...`) for user-scoped tasks. + team: Team owner. + org: Organization consistency check. + external_scope: External host. + object_type: External object type. + object_id: External object identity. + + Returns: + Successful response + """ + query: dict[str, object] = {} + if team is not None: + query["team"] = team + if org is not None: + query["org"] = org + query["external_scope"] = external_scope + query["object_type"] = object_type + query["object_id"] = object_id + return self._http.request( + f"/api/v1/users/{user}/tasks/by-external-reference", + query=query, + response_type=UserTaskByExternalReferenceResponse, + ) + def by_source(self, user: str, input: UserTaskBySourceInput) -> TaskEnsureResult: """ Find or create a task by source @@ -4243,6 +5011,7 @@ def by_source(self, user: str, input: UserTaskBySourceInput) -> TaskEnsureResult input.epic: Initial epic grouping. input.name: Initial task name. input.org: Explicit organization for privileged callers. + input.owner_user: Initial assigned user; immutable on retries. input.source_id: Source identity, for example owner/repo#123. input.source_scope: Source scope, for example github. input.source_type: Source type, for example pull_request. @@ -4488,6 +5257,42 @@ def create(self, user: str, input: UserThreadCreateInput) -> Thread: response_type=Thread, ) + def from_template(self, user: str, input: UserThreadFromTemplateInput) -> dict[str, Any]: + """ + Create a private thread from a template + Creates a private personal thread, installs the template's agent once per user, + and atomically adds its members and a dedicated E2B computer. Requires + `devbox_access`. The computer starts pending and provisions asynchronously. + `key` is prefixed by the template namespace and is unique for the user. Replays return + 200 and never provision another computer or resend the first message; creation + returns 201. Initial-message delivery occurs after commit; a delivery failure + is returned as `first_message_error` so the caller can resend it. + `computer` is optional and applies on creation only: a replay with the same + `key` returns the original thread and computer, ignoring any different + `computer`, exactly like `title` and `first_message`. Invalid `computer` + input returns 422 `invalid_parameters` before anything is created; a provider + this deployment has no credentials for returns 422 `provider_unavailable`. + Unknown templates return 422 `unknown_thread_template`; installation failures + return 502 `agent_install_failed`. Computer config and credentials are never returned. + + Args: + user: User ID (`usr_...`) whose threads should be listed. + input: Request body. + input.computer: Optional computer choice, applied on creation only: `provider` (`sprites`, `vercel`, `e2b` or `devbox`; defaults to the template's) and `repositories` (0 to 16 `{repository: owner/name, ref: optional}`; the first is the primary working directory). + input.first_message: Optional first user message, posted only on creation. + input.key: Required nonempty client idempotency key. + input.template: Thread template lookup key. + input.title: Title for the new thread. + + Returns: + Thread fields plus agent and computers summaries, and optional first_message_error. + """ + return self._http.request( + f"/api/v1/users/{user}/threads/from_template", + method="POST", + body=input, + ) + class TokenResource: def __init__(self, http: SyncHttpClient): @@ -4573,6 +5378,7 @@ def __init__(self, http: SyncHttpClient): self._http = http self.integrations = IntegrationResource(http) self.ssh_keys = UserSshKeyResource(http) + self.task_epics = UserTaskEpicResource(http) self.tasks = UserTaskResource(http) self.threads = UserThreadResource(http) self.tokens = TokenResource(http) @@ -4727,58 +5533,3 @@ def profile(self, user: str, input: UserProfileInput) -> User: body=input, response_type=User, ) - - def task_epics( - self, - user: str, - *, - team: str | None = None, - org: str | None = None, - source_scope: str | None = None, - source_type: str | None = None, - source_id: str | None = None, - top_priority: int | None = None, - include_closed: bool | None = None, - limit: int | None = None, - after_cursor: str | None = None, - ) -> UserTaskEpicsResponse: - """ - List an owner's epic summaries - Groups tasks by their exact epic label, ordered by label. Closed tasks include cancelled tasks, but cancelled prerequisites still block. Source filters select the tasks summarized; blockers outside that selection still affect readiness. Root ranking is capped per epic and root_blockers_partial is true when that graph is truncated. No epic entity is created. - - Args: - source_scope: Exact source scope; supply all three source fields. - source_type: Exact source type. - source_id: Exact source ID. - top_priority: Exact highest open priority, from 0 to 4. - include_closed: Include epics with no non-closed tasks; defaults to false. - limit: Maximum epics; defaults to 50, capped at 100. - after_cursor: Opaque forward cursor from the preceding page. - - Returns: - Successful response - """ - query: dict[str, object] = {} - if team is not None: - query["team"] = team - if org is not None: - query["org"] = org - if source_scope is not None: - query["source_scope"] = source_scope - if source_type is not None: - query["source_type"] = source_type - if source_id is not None: - query["source_id"] = source_id - if top_priority is not None: - query["top_priority"] = top_priority - if include_closed is not None: - query["include_closed"] = include_closed - if limit is not None: - query["limit"] = limit - if after_cursor is not None: - query["after_cursor"] = after_cursor - return self._http.request( - f"/api/v1/users/{user}/task_epics", - query=query, - response_type=UserTaskEpicsResponse, - ) diff --git a/tests/contract/channels/test_api_chat_channel.py b/tests/contract/channels/test_api_chat_channel.py index cbfde6b..9e9c663 100644 --- a/tests/contract/channels/test_api_chat_channel.py +++ b/tests/contract/channels/test_api_chat_channel.py @@ -1,6 +1,6 @@ # Copyright (c) 2026 ArchAstro Inc. Licensed under the MIT License. # This file is auto-generated by @archastro/sdk-generator. Do not edit. -# Content hash: 2277b5e98500 +# Content hash: 1df4f0952b5f """ Contract tests for ApiChatChannel — generated from the channel spec. @@ -360,6 +360,64 @@ async def test_api_chat_channel_api_chat_fork_thread_returns_error_envelope_when assert reply["status"] == "error" +async def test_api_chat_channel_api_chat_attach_artifact_sends_valid_push_and_receives_contract_valid_reply( + rig, +): + client, socket = rig + await client.register_scenario( + { + "topic": "api:chat:team:test-id:thread:test-id", + "onJoin": [{"type": "autoReply"}], + "onMessage": { + "api:chat:attach_artifact": [{"type": "autoReply"}], + }, + } + ) + channel = await ApiChatChannel.join_team_thread( + socket, + "test-id", + "test-id", + after_cursor="test-value", + before_cursor="test-value", + include_metadata=True, + limit=1, + ) + reply = await channel.api_chat_attach_artifact( + {"agent": "test-value", "artifact": "test-value", "instructions": "test-value"} + ) + assert reply["status"] == "ok" + + observed = await client.observations( + "api:chat:team:test-id:thread:test-id", "api:chat:attach_artifact" + ) + assert len(observed) == 1 + assert observed[0]["params"]["agent"] == "test-value" + assert observed[0]["params"]["artifact"] == "test-value" + + +async def test_api_chat_channel_api_chat_attach_artifact_returns_error_envelope_when_required_missing( + rig, +): + client, socket = rig + await client.register_scenario( + { + "topic": "api:chat:team:test-id:thread:test-id", + "onJoin": [{"type": "autoReply"}], + } + ) + channel = await ApiChatChannel.join_team_thread( + socket, + "test-id", + "test-id", + after_cursor="test-value", + before_cursor="test-value", + include_metadata=True, + limit=1, + ) + reply = await channel.api_chat_attach_artifact({}) + assert reply["status"] == "error" + + async def test_api_chat_channel_api_chat_mark_thread_read_sends_valid_push_and_receives_contract_valid_reply( rig, ): diff --git a/tests/contract/streams/test_orgs.py b/tests/contract/streams/test_orgs.py new file mode 100644 index 0000000..d4e316c --- /dev/null +++ b/tests/contract/streams/test_orgs.py @@ -0,0 +1,70 @@ +# Copyright (c) 2026 ArchAstro Inc. Licensed under the MIT License. +# This file is auto-generated by @archastro/sdk-generator. Do not edit. +# Content hash: 667012f2bfc2 + +import pytest + +from archastro.phx_channel import HarnessServiceClient +from archastro.platform import AsyncPlatformClient +from archastro.platform.runtime.http_client import ApiError + +# Mark every coroutine in this file as async so the tests run whether or +# not the consuming project sets asyncio_mode=auto. +pytestmark = pytest.mark.asyncio + + +async def test_orgs_tasks_stream_yields_sse_events(harness_service): + harness = HarnessServiceClient( + ws_url=harness_service["wsUrl"], control_url=harness_service["controlUrl"] + ) + await harness.reset() + await harness.register_stream_scenario( + { + "route": "GET /api/v1/orgs/{org}/tasks/stream", + "actions": [ + {"type": "autoEmit", "event": "ready"}, + {"type": "autoEmit", "event": "task_changed"}, + {"type": "autoEmit", "event": "task_deleted"}, + ], + } + ) + client = AsyncPlatformClient( + base_url=harness_service["controlUrl"], + default_headers={"x-archastro-api-key": "pk_test-key"}, + access_token="test-token", + ) + try: + events = [] + async for ev in client.v1.orgs.tasks.stream("test-value"): + events.append(ev) + assert [e["event"] for e in events] == ["ready", "task_changed", "task_deleted"] + finally: + await client.close() + await harness.close() + + +async def test_orgs_tasks_stream_rejects_non_2xx(harness_service): + harness = HarnessServiceClient( + ws_url=harness_service["wsUrl"], control_url=harness_service["controlUrl"] + ) + await harness.reset() + await harness.register_stream_scenario( + { + "route": "GET /api/v1/orgs/{org}/tasks/stream", + "actions": [ + {"type": "status", "code": 402, "body": {"error": {"code": "plan_not_entitled"}}} + ], + } + ) + client = AsyncPlatformClient( + base_url=harness_service["controlUrl"], + default_headers={"x-archastro-api-key": "pk_test-key"}, + access_token="test-token", + ) + try: + with pytest.raises(ApiError): + async for _ in client.v1.orgs.tasks.stream("test-value"): + pass + finally: + await client.close() + await harness.close() diff --git a/tests/contract/v1/test_agent_env_vars.py b/tests/contract/v1/test_agent_env_vars.py index dec146b..5afdc23 100644 --- a/tests/contract/v1/test_agent_env_vars.py +++ b/tests/contract/v1/test_agent_env_vars.py @@ -1,6 +1,6 @@ # Copyright (c) 2026 ArchAstro Inc. Licensed under the MIT License. # This file is auto-generated by @archastro/sdk-generator. Do not edit. -# Content hash: 1bac408e96b2 +# Content hash: 82428e4077a3 import pytest from pydantic import BaseModel @@ -82,6 +82,16 @@ def test_agent_env_vars_delete_error_404(): ec.close() +def test_agent_env_vars_delete_error_409(): + ec = _error_client(409) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.agent_env_vars.delete("test-value") + assert exc_info.value.status == 409 + finally: + ec.close() + + @pytest.mark.asyncio async def test_async_agent_env_vars_delete_success(): client = _async_client() @@ -125,6 +135,17 @@ async def test_async_agent_env_vars_delete_error_404(): await ec.close() +@pytest.mark.asyncio +async def test_async_agent_env_vars_delete_error_409(): + ec = _async_error_client(409) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.agent_env_vars.delete("test-value") + assert exc_info.value.status == 409 + finally: + await ec.close() + + def test_agent_env_vars_get_success(): client = _client() try: @@ -249,6 +270,16 @@ def test_agent_env_vars_update_error_404(): ec.close() +def test_agent_env_vars_update_error_409(): + ec = _error_client(409) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.agent_env_vars.update("test-value", {}) + assert exc_info.value.status == 409 + finally: + ec.close() + + def test_agent_env_vars_update_error_422(): ec = _error_client(422) try: @@ -303,6 +334,17 @@ async def test_async_agent_env_vars_update_error_404(): await ec.close() +@pytest.mark.asyncio +async def test_async_agent_env_vars_update_error_409(): + ec = _async_error_client(409) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.agent_env_vars.update("test-value", {}) + assert exc_info.value.status == 409 + finally: + await ec.close() + + @pytest.mark.asyncio async def test_async_agent_env_vars_update_error_422(): ec = _async_error_client(422) diff --git a/tests/contract/v1/test_agent_requests.py b/tests/contract/v1/test_agent_requests.py index 07832cb..d7795f0 100644 --- a/tests/contract/v1/test_agent_requests.py +++ b/tests/contract/v1/test_agent_requests.py @@ -1,6 +1,6 @@ # Copyright (c) 2026 ArchAstro Inc. Licensed under the MIT License. # This file is auto-generated by @archastro/sdk-generator. Do not edit. -# Content hash: b5b626f10faf +# Content hash: 994c929bbf0f import pytest from pydantic import BaseModel @@ -232,6 +232,27 @@ async def test_async_agent_requests_get_error_422(): await ec.close() +def test_agent_requests_oauth_start_success(): + client = _client() + try: + result = client.v1.agent_requests.oauth_start("test-value") + assert isinstance(result, BaseModel) + assert type(result).__name__ == "AgentRequestOauthStartResponse" + finally: + client.close() + + +@pytest.mark.asyncio +async def test_async_agent_requests_oauth_start_success(): + client = _async_client() + try: + result = await client.v1.agent_requests.oauth_start("test-value") + assert isinstance(result, BaseModel) + assert type(result).__name__ == "AgentRequestOauthStartResponse" + finally: + await client.close() + + def test_agent_requests_reject_success(): client = _client() try: diff --git a/tests/contract/v1/test_computers.py b/tests/contract/v1/test_computers.py new file mode 100644 index 0000000..564ccb2 --- /dev/null +++ b/tests/contract/v1/test_computers.py @@ -0,0 +1,776 @@ +# Copyright (c) 2026 ArchAstro Inc. Licensed under the MIT License. +# This file is auto-generated by @archastro/sdk-generator. Do not edit. +# Content hash: 67919dddafcd + +import pytest +from pydantic import BaseModel + +from archastro.platform import AsyncPlatformClient, PlatformClient +from archastro.platform.runtime.http_client import ApiError + +PRISM_URL = "http://127.0.0.1:4040" + + +def _client() -> PlatformClient: + return PlatformClient( + base_url=PRISM_URL, + default_headers={"x-archastro-api-key": "pk_test-key"}, + access_token="test-token", + ) + + +def _error_client(code: int) -> PlatformClient: + return PlatformClient( + base_url=PRISM_URL, + default_headers={"x-archastro-api-key": "pk_test-key", "Prefer": f"code={code}"}, + access_token="test-token", + ) + + +def _async_client() -> AsyncPlatformClient: + return AsyncPlatformClient( + base_url=PRISM_URL, + default_headers={"x-archastro-api-key": "pk_test-key"}, + access_token="test-token", + ) + + +def _async_error_client(code: int) -> AsyncPlatformClient: + return AsyncPlatformClient( + base_url=PRISM_URL, + default_headers={"x-archastro-api-key": "pk_test-key", "Prefer": f"code={code}"}, + access_token="test-token", + ) + + +def test_computers_list_success(): + client = _client() + try: + result = client.v1.computers.list() + assert isinstance(result, BaseModel) + assert type(result).__name__ == "AgentComputerListResponse" + finally: + client.close() + + +def test_computers_list_error_401(): + ec = _error_client(401) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.computers.list() + assert exc_info.value.status == 401 + finally: + ec.close() + + +def test_computers_list_error_403(): + ec = _error_client(403) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.computers.list() + assert exc_info.value.status == 403 + finally: + ec.close() + + +@pytest.mark.asyncio +async def test_async_computers_list_success(): + client = _async_client() + try: + result = await client.v1.computers.list() + assert isinstance(result, BaseModel) + assert type(result).__name__ == "AgentComputerListResponse" + finally: + await client.close() + + +@pytest.mark.asyncio +async def test_async_computers_list_error_401(): + ec = _async_error_client(401) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.computers.list() + assert exc_info.value.status == 401 + finally: + await ec.close() + + +@pytest.mark.asyncio +async def test_async_computers_list_error_403(): + ec = _async_error_client(403) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.computers.list() + assert exc_info.value.status == 403 + finally: + await ec.close() + + +def test_computers_create_success(): + client = _client() + try: + result = client.v1.computers.create({"name": "test-name"}) + assert isinstance(result, BaseModel) + assert type(result).__name__ == "AgentComputer" + finally: + client.close() + + +def test_computers_create_error_401(): + ec = _error_client(401) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.computers.create({"name": "test-name"}) + assert exc_info.value.status == 401 + finally: + ec.close() + + +def test_computers_create_error_403(): + ec = _error_client(403) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.computers.create({"name": "test-name"}) + assert exc_info.value.status == 403 + finally: + ec.close() + + +def test_computers_create_error_422(): + ec = _error_client(422) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.computers.create({"name": "test-name"}) + assert exc_info.value.status == 422 + finally: + ec.close() + + +@pytest.mark.asyncio +async def test_async_computers_create_success(): + client = _async_client() + try: + result = await client.v1.computers.create({"name": "test-name"}) + assert isinstance(result, BaseModel) + assert type(result).__name__ == "AgentComputer" + finally: + await client.close() + + +@pytest.mark.asyncio +async def test_async_computers_create_error_401(): + ec = _async_error_client(401) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.computers.create({"name": "test-name"}) + assert exc_info.value.status == 401 + finally: + await ec.close() + + +@pytest.mark.asyncio +async def test_async_computers_create_error_403(): + ec = _async_error_client(403) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.computers.create({"name": "test-name"}) + assert exc_info.value.status == 403 + finally: + await ec.close() + + +@pytest.mark.asyncio +async def test_async_computers_create_error_422(): + ec = _async_error_client(422) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.computers.create({"name": "test-name"}) + assert exc_info.value.status == 422 + finally: + await ec.close() + + +def test_computers_delete_success(): + client = _client() + try: + result = client.v1.computers.delete("test-value") + assert result is None + finally: + client.close() + + +def test_computers_delete_error_401(): + ec = _error_client(401) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.computers.delete("test-value") + assert exc_info.value.status == 401 + finally: + ec.close() + + +def test_computers_delete_error_403(): + ec = _error_client(403) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.computers.delete("test-value") + assert exc_info.value.status == 403 + finally: + ec.close() + + +def test_computers_delete_error_404(): + ec = _error_client(404) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.computers.delete("test-value") + assert exc_info.value.status == 404 + finally: + ec.close() + + +@pytest.mark.asyncio +async def test_async_computers_delete_success(): + client = _async_client() + try: + result = await client.v1.computers.delete("test-value") + assert result is None + finally: + await client.close() + + +@pytest.mark.asyncio +async def test_async_computers_delete_error_401(): + ec = _async_error_client(401) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.computers.delete("test-value") + assert exc_info.value.status == 401 + finally: + await ec.close() + + +@pytest.mark.asyncio +async def test_async_computers_delete_error_403(): + ec = _async_error_client(403) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.computers.delete("test-value") + assert exc_info.value.status == 403 + finally: + await ec.close() + + +@pytest.mark.asyncio +async def test_async_computers_delete_error_404(): + ec = _async_error_client(404) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.computers.delete("test-value") + assert exc_info.value.status == 404 + finally: + await ec.close() + + +def test_computers_get_success(): + client = _client() + try: + result = client.v1.computers.get("test-value") + assert isinstance(result, BaseModel) + assert type(result).__name__ == "AgentComputer" + finally: + client.close() + + +def test_computers_get_error_401(): + ec = _error_client(401) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.computers.get("test-value") + assert exc_info.value.status == 401 + finally: + ec.close() + + +def test_computers_get_error_404(): + ec = _error_client(404) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.computers.get("test-value") + assert exc_info.value.status == 404 + finally: + ec.close() + + +@pytest.mark.asyncio +async def test_async_computers_get_success(): + client = _async_client() + try: + result = await client.v1.computers.get("test-value") + assert isinstance(result, BaseModel) + assert type(result).__name__ == "AgentComputer" + finally: + await client.close() + + +@pytest.mark.asyncio +async def test_async_computers_get_error_401(): + ec = _async_error_client(401) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.computers.get("test-value") + assert exc_info.value.status == 401 + finally: + await ec.close() + + +@pytest.mark.asyncio +async def test_async_computers_get_error_404(): + ec = _async_error_client(404) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.computers.get("test-value") + assert exc_info.value.status == 404 + finally: + await ec.close() + + +def test_computers_exec_success(): + client = _client() + try: + result = client.v1.computers.exec("test-value", {"command": "test-value"}) + assert isinstance(result, BaseModel) + assert type(result).__name__ == "ComputerExecResult" + finally: + client.close() + + +def test_computers_exec_error_401(): + ec = _error_client(401) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.computers.exec("test-value", {"command": "test-value"}) + assert exc_info.value.status == 401 + finally: + ec.close() + + +def test_computers_exec_error_403(): + ec = _error_client(403) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.computers.exec("test-value", {"command": "test-value"}) + assert exc_info.value.status == 403 + finally: + ec.close() + + +def test_computers_exec_error_404(): + ec = _error_client(404) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.computers.exec("test-value", {"command": "test-value"}) + assert exc_info.value.status == 404 + finally: + ec.close() + + +def test_computers_exec_error_409(): + ec = _error_client(409) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.computers.exec("test-value", {"command": "test-value"}) + assert exc_info.value.status == 409 + finally: + ec.close() + + +def test_computers_exec_error_422(): + ec = _error_client(422) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.computers.exec("test-value", {"command": "test-value"}) + assert exc_info.value.status == 422 + finally: + ec.close() + + +@pytest.mark.asyncio +async def test_async_computers_exec_success(): + client = _async_client() + try: + result = await client.v1.computers.exec("test-value", {"command": "test-value"}) + assert isinstance(result, BaseModel) + assert type(result).__name__ == "ComputerExecResult" + finally: + await client.close() + + +@pytest.mark.asyncio +async def test_async_computers_exec_error_401(): + ec = _async_error_client(401) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.computers.exec("test-value", {"command": "test-value"}) + assert exc_info.value.status == 401 + finally: + await ec.close() + + +@pytest.mark.asyncio +async def test_async_computers_exec_error_403(): + ec = _async_error_client(403) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.computers.exec("test-value", {"command": "test-value"}) + assert exc_info.value.status == 403 + finally: + await ec.close() + + +@pytest.mark.asyncio +async def test_async_computers_exec_error_404(): + ec = _async_error_client(404) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.computers.exec("test-value", {"command": "test-value"}) + assert exc_info.value.status == 404 + finally: + await ec.close() + + +@pytest.mark.asyncio +async def test_async_computers_exec_error_409(): + ec = _async_error_client(409) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.computers.exec("test-value", {"command": "test-value"}) + assert exc_info.value.status == 409 + finally: + await ec.close() + + +@pytest.mark.asyncio +async def test_async_computers_exec_error_422(): + ec = _async_error_client(422) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.computers.exec("test-value", {"command": "test-value"}) + assert exc_info.value.status == 422 + finally: + await ec.close() + + +def test_computers_pause_success(): + client = _client() + try: + result = client.v1.computers.pause("test-value") + assert isinstance(result, BaseModel) + assert type(result).__name__ == "AgentComputer" + finally: + client.close() + + +def test_computers_pause_error_401(): + ec = _error_client(401) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.computers.pause("test-value") + assert exc_info.value.status == 401 + finally: + ec.close() + + +def test_computers_pause_error_403(): + ec = _error_client(403) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.computers.pause("test-value") + assert exc_info.value.status == 403 + finally: + ec.close() + + +def test_computers_pause_error_404(): + ec = _error_client(404) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.computers.pause("test-value") + assert exc_info.value.status == 404 + finally: + ec.close() + + +def test_computers_pause_error_409(): + ec = _error_client(409) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.computers.pause("test-value") + assert exc_info.value.status == 409 + finally: + ec.close() + + +def test_computers_pause_error_422(): + ec = _error_client(422) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.computers.pause("test-value") + assert exc_info.value.status == 422 + finally: + ec.close() + + +@pytest.mark.asyncio +async def test_async_computers_pause_success(): + client = _async_client() + try: + result = await client.v1.computers.pause("test-value") + assert isinstance(result, BaseModel) + assert type(result).__name__ == "AgentComputer" + finally: + await client.close() + + +@pytest.mark.asyncio +async def test_async_computers_pause_error_401(): + ec = _async_error_client(401) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.computers.pause("test-value") + assert exc_info.value.status == 401 + finally: + await ec.close() + + +@pytest.mark.asyncio +async def test_async_computers_pause_error_403(): + ec = _async_error_client(403) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.computers.pause("test-value") + assert exc_info.value.status == 403 + finally: + await ec.close() + + +@pytest.mark.asyncio +async def test_async_computers_pause_error_404(): + ec = _async_error_client(404) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.computers.pause("test-value") + assert exc_info.value.status == 404 + finally: + await ec.close() + + +@pytest.mark.asyncio +async def test_async_computers_pause_error_409(): + ec = _async_error_client(409) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.computers.pause("test-value") + assert exc_info.value.status == 409 + finally: + await ec.close() + + +@pytest.mark.asyncio +async def test_async_computers_pause_error_422(): + ec = _async_error_client(422) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.computers.pause("test-value") + assert exc_info.value.status == 422 + finally: + await ec.close() + + +def test_computers_resume_success(): + client = _client() + try: + result = client.v1.computers.resume("test-value") + assert isinstance(result, BaseModel) + assert type(result).__name__ == "AgentComputer" + finally: + client.close() + + +def test_computers_resume_error_401(): + ec = _error_client(401) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.computers.resume("test-value") + assert exc_info.value.status == 401 + finally: + ec.close() + + +def test_computers_resume_error_403(): + ec = _error_client(403) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.computers.resume("test-value") + assert exc_info.value.status == 403 + finally: + ec.close() + + +def test_computers_resume_error_404(): + ec = _error_client(404) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.computers.resume("test-value") + assert exc_info.value.status == 404 + finally: + ec.close() + + +def test_computers_resume_error_409(): + ec = _error_client(409) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.computers.resume("test-value") + assert exc_info.value.status == 409 + finally: + ec.close() + + +def test_computers_resume_error_422(): + ec = _error_client(422) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.computers.resume("test-value") + assert exc_info.value.status == 422 + finally: + ec.close() + + +@pytest.mark.asyncio +async def test_async_computers_resume_success(): + client = _async_client() + try: + result = await client.v1.computers.resume("test-value") + assert isinstance(result, BaseModel) + assert type(result).__name__ == "AgentComputer" + finally: + await client.close() + + +@pytest.mark.asyncio +async def test_async_computers_resume_error_401(): + ec = _async_error_client(401) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.computers.resume("test-value") + assert exc_info.value.status == 401 + finally: + await ec.close() + + +@pytest.mark.asyncio +async def test_async_computers_resume_error_403(): + ec = _async_error_client(403) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.computers.resume("test-value") + assert exc_info.value.status == 403 + finally: + await ec.close() + + +@pytest.mark.asyncio +async def test_async_computers_resume_error_404(): + ec = _async_error_client(404) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.computers.resume("test-value") + assert exc_info.value.status == 404 + finally: + await ec.close() + + +@pytest.mark.asyncio +async def test_async_computers_resume_error_409(): + ec = _async_error_client(409) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.computers.resume("test-value") + assert exc_info.value.status == 409 + finally: + await ec.close() + + +@pytest.mark.asyncio +async def test_async_computers_resume_error_422(): + ec = _async_error_client(422) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.computers.resume("test-value") + assert exc_info.value.status == 422 + finally: + await ec.close() + + +def test_computers_setup_success(): + client = _client() + try: + result = client.v1.computers.setup("test-value", {}) + assert isinstance(result, BaseModel) + assert type(result).__name__ == "AgentComputer" + finally: + client.close() + + +def test_computers_setup_error_409(): + ec = _error_client(409) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.computers.setup("test-value", {}) + assert exc_info.value.status == 409 + finally: + ec.close() + + +def test_computers_setup_error_422(): + ec = _error_client(422) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.computers.setup("test-value", {}) + assert exc_info.value.status == 422 + finally: + ec.close() + + +@pytest.mark.asyncio +async def test_async_computers_setup_success(): + client = _async_client() + try: + result = await client.v1.computers.setup("test-value", {}) + assert isinstance(result, BaseModel) + assert type(result).__name__ == "AgentComputer" + finally: + await client.close() + + +@pytest.mark.asyncio +async def test_async_computers_setup_error_409(): + ec = _async_error_client(409) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.computers.setup("test-value", {}) + assert exc_info.value.status == 409 + finally: + await ec.close() + + +@pytest.mark.asyncio +async def test_async_computers_setup_error_422(): + ec = _async_error_client(422) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.computers.setup("test-value", {}) + assert exc_info.value.status == 422 + finally: + await ec.close() diff --git a/tests/contract/v1/test_orgs.py b/tests/contract/v1/test_orgs.py index bed5ad6..a085f1f 100644 --- a/tests/contract/v1/test_orgs.py +++ b/tests/contract/v1/test_orgs.py @@ -1,6 +1,6 @@ # Copyright (c) 2026 ArchAstro Inc. Licensed under the MIT License. # This file is auto-generated by @archastro/sdk-generator. Do not edit. -# Content hash: 1ca1483446d1 +# Content hash: 7e85e43f3b61 import pytest from pydantic import BaseModel @@ -301,87 +301,232 @@ async def test_async_orgs_linked_accounts_error_404(): await ec.close() -def test_orgs_task_epics_success(): +def test_orgs_task_deletions_success(): client = _client() try: - result = client.v1.orgs.task_epics("test-value") + result = client.v1.orgs.task_deletions("test-value") assert isinstance(result, BaseModel) - assert type(result).__name__ == "OrgTaskEpicsResponse" + assert type(result).__name__ == "OrgTaskDeletionsResponse" assert isinstance(result.data, list) finally: client.close() -def test_orgs_task_epics_error_401(): +def test_orgs_task_deletions_error_401(): ec = _error_client(401) try: with pytest.raises(ApiError) as exc_info: - ec.v1.orgs.task_epics("test-value") + ec.v1.orgs.task_deletions("test-value") assert exc_info.value.status == 401 finally: ec.close() -def test_orgs_task_epics_error_404(): +def test_orgs_task_deletions_error_404(): ec = _error_client(404) try: with pytest.raises(ApiError) as exc_info: - ec.v1.orgs.task_epics("test-value") + ec.v1.orgs.task_deletions("test-value") assert exc_info.value.status == 404 finally: ec.close() -def test_orgs_task_epics_error_422(): +def test_orgs_task_deletions_error_422(): ec = _error_client(422) try: with pytest.raises(ApiError) as exc_info: - ec.v1.orgs.task_epics("test-value") + ec.v1.orgs.task_deletions("test-value") assert exc_info.value.status == 422 finally: ec.close() @pytest.mark.asyncio -async def test_async_orgs_task_epics_success(): +async def test_async_orgs_task_deletions_success(): client = _async_client() try: - result = await client.v1.orgs.task_epics("test-value") + result = await client.v1.orgs.task_deletions("test-value") assert isinstance(result, BaseModel) - assert type(result).__name__ == "OrgTaskEpicsResponse" + assert type(result).__name__ == "OrgTaskDeletionsResponse" assert isinstance(result.data, list) finally: await client.close() @pytest.mark.asyncio -async def test_async_orgs_task_epics_error_401(): +async def test_async_orgs_task_deletions_error_401(): ec = _async_error_client(401) try: with pytest.raises(ApiError) as exc_info: - await ec.v1.orgs.task_epics("test-value") + await ec.v1.orgs.task_deletions("test-value") assert exc_info.value.status == 401 finally: await ec.close() @pytest.mark.asyncio -async def test_async_orgs_task_epics_error_404(): +async def test_async_orgs_task_deletions_error_404(): ec = _async_error_client(404) try: with pytest.raises(ApiError) as exc_info: - await ec.v1.orgs.task_epics("test-value") + await ec.v1.orgs.task_deletions("test-value") assert exc_info.value.status == 404 finally: await ec.close() @pytest.mark.asyncio -async def test_async_orgs_task_epics_error_422(): +async def test_async_orgs_task_deletions_error_422(): ec = _async_error_client(422) try: with pytest.raises(ApiError) as exc_info: - await ec.v1.orgs.task_epics("test-value") + await ec.v1.orgs.task_deletions("test-value") + assert exc_info.value.status == 422 + finally: + await ec.close() + + +def test_orgs_task_epics_list_success(): + client = _client() + try: + result = client.v1.orgs.task_epics.list("test-value") + assert isinstance(result, (BaseModel, dict)) + finally: + client.close() + + +def test_orgs_task_epics_list_error_401(): + ec = _error_client(401) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.orgs.task_epics.list("test-value") + assert exc_info.value.status == 401 + finally: + ec.close() + + +def test_orgs_task_epics_list_error_404(): + ec = _error_client(404) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.orgs.task_epics.list("test-value") + assert exc_info.value.status == 404 + finally: + ec.close() + + +def test_orgs_task_epics_list_error_422(): + ec = _error_client(422) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.orgs.task_epics.list("test-value") + assert exc_info.value.status == 422 + finally: + ec.close() + + +@pytest.mark.asyncio +async def test_async_orgs_task_epics_list_success(): + client = _async_client() + try: + result = await client.v1.orgs.task_epics.list("test-value") + assert isinstance(result, (BaseModel, dict)) + finally: + await client.close() + + +@pytest.mark.asyncio +async def test_async_orgs_task_epics_list_error_401(): + ec = _async_error_client(401) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.orgs.task_epics.list("test-value") + assert exc_info.value.status == 401 + finally: + await ec.close() + + +@pytest.mark.asyncio +async def test_async_orgs_task_epics_list_error_404(): + ec = _async_error_client(404) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.orgs.task_epics.list("test-value") + assert exc_info.value.status == 404 + finally: + await ec.close() + + +@pytest.mark.asyncio +async def test_async_orgs_task_epics_list_error_422(): + ec = _async_error_client(422) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.orgs.task_epics.list("test-value") + assert exc_info.value.status == 422 + finally: + await ec.close() + + +def test_orgs_task_epics_create_success(): + client = _client() + try: + result = client.v1.orgs.task_epics.create("test-value", {"name": "test-name"}) + assert isinstance(result, BaseModel) + assert type(result).__name__ == "TaskEpicEntity" + finally: + client.close() + + +def test_orgs_task_epics_create_error_404(): + ec = _error_client(404) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.orgs.task_epics.create("test-value", {"name": "test-name"}) + assert exc_info.value.status == 404 + finally: + ec.close() + + +def test_orgs_task_epics_create_error_422(): + ec = _error_client(422) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.orgs.task_epics.create("test-value", {"name": "test-name"}) + assert exc_info.value.status == 422 + finally: + ec.close() + + +@pytest.mark.asyncio +async def test_async_orgs_task_epics_create_success(): + client = _async_client() + try: + result = await client.v1.orgs.task_epics.create("test-value", {"name": "test-name"}) + assert isinstance(result, BaseModel) + assert type(result).__name__ == "TaskEpicEntity" + finally: + await client.close() + + +@pytest.mark.asyncio +async def test_async_orgs_task_epics_create_error_404(): + ec = _async_error_client(404) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.orgs.task_epics.create("test-value", {"name": "test-name"}) + assert exc_info.value.status == 404 + finally: + await ec.close() + + +@pytest.mark.asyncio +async def test_async_orgs_task_epics_create_error_422(): + ec = _async_error_client(422) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.orgs.task_epics.create("test-value", {"name": "test-name"}) assert exc_info.value.status == 422 finally: await ec.close() @@ -664,6 +809,126 @@ async def test_async_orgs_tasks_blocker_cycles_error_422(): await ec.close() +def test_orgs_tasks_by_external_reference_success(): + client = _client() + try: + result = client.v1.orgs.tasks.by_external_reference( + "test-value", external_scope="test-value", object_type="test-value", object_id="test-id" + ) + assert isinstance(result, BaseModel) + assert type(result).__name__ == "OrgTaskByExternalReferenceResponse" + assert isinstance(result.data, list) + finally: + client.close() + + +def test_orgs_tasks_by_external_reference_error_401(): + ec = _error_client(401) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.orgs.tasks.by_external_reference( + "test-value", + external_scope="test-value", + object_type="test-value", + object_id="test-id", + ) + assert exc_info.value.status == 401 + finally: + ec.close() + + +def test_orgs_tasks_by_external_reference_error_404(): + ec = _error_client(404) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.orgs.tasks.by_external_reference( + "test-value", + external_scope="test-value", + object_type="test-value", + object_id="test-id", + ) + assert exc_info.value.status == 404 + finally: + ec.close() + + +def test_orgs_tasks_by_external_reference_error_422(): + ec = _error_client(422) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.orgs.tasks.by_external_reference( + "test-value", + external_scope="test-value", + object_type="test-value", + object_id="test-id", + ) + assert exc_info.value.status == 422 + finally: + ec.close() + + +@pytest.mark.asyncio +async def test_async_orgs_tasks_by_external_reference_success(): + client = _async_client() + try: + result = await client.v1.orgs.tasks.by_external_reference( + "test-value", external_scope="test-value", object_type="test-value", object_id="test-id" + ) + assert isinstance(result, BaseModel) + assert type(result).__name__ == "OrgTaskByExternalReferenceResponse" + assert isinstance(result.data, list) + finally: + await client.close() + + +@pytest.mark.asyncio +async def test_async_orgs_tasks_by_external_reference_error_401(): + ec = _async_error_client(401) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.orgs.tasks.by_external_reference( + "test-value", + external_scope="test-value", + object_type="test-value", + object_id="test-id", + ) + assert exc_info.value.status == 401 + finally: + await ec.close() + + +@pytest.mark.asyncio +async def test_async_orgs_tasks_by_external_reference_error_404(): + ec = _async_error_client(404) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.orgs.tasks.by_external_reference( + "test-value", + external_scope="test-value", + object_type="test-value", + object_id="test-id", + ) + assert exc_info.value.status == 404 + finally: + await ec.close() + + +@pytest.mark.asyncio +async def test_async_orgs_tasks_by_external_reference_error_422(): + ec = _async_error_client(422) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.orgs.tasks.by_external_reference( + "test-value", + external_scope="test-value", + object_type="test-value", + object_id="test-id", + ) + assert exc_info.value.status == 422 + finally: + await ec.close() + + def test_orgs_tasks_by_source_success(): client = _client() try: @@ -917,6 +1182,16 @@ def test_orgs_tasks_ready_error_401(): ec.close() +def test_orgs_tasks_ready_error_403(): + ec = _error_client(403) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.orgs.tasks.ready("test-value") + assert exc_info.value.status == 403 + finally: + ec.close() + + def test_orgs_tasks_ready_error_404(): ec = _error_client(404) try: @@ -960,6 +1235,17 @@ async def test_async_orgs_tasks_ready_error_401(): await ec.close() +@pytest.mark.asyncio +async def test_async_orgs_tasks_ready_error_403(): + ec = _async_error_client(403) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.orgs.tasks.ready("test-value") + assert exc_info.value.status == 403 + finally: + await ec.close() + + @pytest.mark.asyncio async def test_async_orgs_tasks_ready_error_404(): ec = _async_error_client(404) diff --git a/tests/contract/v1/test_task_epics.py b/tests/contract/v1/test_task_epics.py new file mode 100644 index 0000000..5c90d6c --- /dev/null +++ b/tests/contract/v1/test_task_epics.py @@ -0,0 +1,554 @@ +# Copyright (c) 2026 ArchAstro Inc. Licensed under the MIT License. +# This file is auto-generated by @archastro/sdk-generator. Do not edit. +# Content hash: 6ff9ffd3cda7 + +import pytest +from pydantic import BaseModel + +from archastro.platform import AsyncPlatformClient, PlatformClient +from archastro.platform.runtime.http_client import ApiError + +PRISM_URL = "http://127.0.0.1:4040" + + +def _client() -> PlatformClient: + return PlatformClient( + base_url=PRISM_URL, + default_headers={"x-archastro-api-key": "pk_test-key"}, + access_token="test-token", + ) + + +def _error_client(code: int) -> PlatformClient: + return PlatformClient( + base_url=PRISM_URL, + default_headers={"x-archastro-api-key": "pk_test-key", "Prefer": f"code={code}"}, + access_token="test-token", + ) + + +def _async_client() -> AsyncPlatformClient: + return AsyncPlatformClient( + base_url=PRISM_URL, + default_headers={"x-archastro-api-key": "pk_test-key"}, + access_token="test-token", + ) + + +def _async_error_client(code: int) -> AsyncPlatformClient: + return AsyncPlatformClient( + base_url=PRISM_URL, + default_headers={"x-archastro-api-key": "pk_test-key", "Prefer": f"code={code}"}, + access_token="test-token", + ) + + +def test_task_epics_get_success(): + client = _client() + try: + result = client.v1.task_epics.get("test-value") + assert isinstance(result, BaseModel) + assert type(result).__name__ == "TaskEpicEntity" + finally: + client.close() + + +def test_task_epics_get_error_404(): + ec = _error_client(404) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.task_epics.get("test-value") + assert exc_info.value.status == 404 + finally: + ec.close() + + +@pytest.mark.asyncio +async def test_async_task_epics_get_success(): + client = _async_client() + try: + result = await client.v1.task_epics.get("test-value") + assert isinstance(result, BaseModel) + assert type(result).__name__ == "TaskEpicEntity" + finally: + await client.close() + + +@pytest.mark.asyncio +async def test_async_task_epics_get_error_404(): + ec = _async_error_client(404) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.task_epics.get("test-value") + assert exc_info.value.status == 404 + finally: + await ec.close() + + +def test_task_epics_update_success(): + client = _client() + try: + result = client.v1.task_epics.update("test-value", {}) + assert isinstance(result, BaseModel) + assert type(result).__name__ == "TaskEpicEntity" + finally: + client.close() + + +def test_task_epics_update_error_404(): + ec = _error_client(404) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.task_epics.update("test-value", {}) + assert exc_info.value.status == 404 + finally: + ec.close() + + +def test_task_epics_update_error_422(): + ec = _error_client(422) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.task_epics.update("test-value", {}) + assert exc_info.value.status == 422 + finally: + ec.close() + + +@pytest.mark.asyncio +async def test_async_task_epics_update_success(): + client = _async_client() + try: + result = await client.v1.task_epics.update("test-value", {}) + assert isinstance(result, BaseModel) + assert type(result).__name__ == "TaskEpicEntity" + finally: + await client.close() + + +@pytest.mark.asyncio +async def test_async_task_epics_update_error_404(): + ec = _async_error_client(404) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.task_epics.update("test-value", {}) + assert exc_info.value.status == 404 + finally: + await ec.close() + + +@pytest.mark.asyncio +async def test_async_task_epics_update_error_422(): + ec = _async_error_client(422) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.task_epics.update("test-value", {}) + assert exc_info.value.status == 422 + finally: + await ec.close() + + +def test_task_epics_cancel_success(): + client = _client() + try: + result = client.v1.task_epics.cancel("test-value") + assert result is None + finally: + client.close() + + +def test_task_epics_cancel_error_404(): + ec = _error_client(404) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.task_epics.cancel("test-value") + assert exc_info.value.status == 404 + finally: + ec.close() + + +@pytest.mark.asyncio +async def test_async_task_epics_cancel_success(): + client = _async_client() + try: + result = await client.v1.task_epics.cancel("test-value") + assert result is None + finally: + await client.close() + + +@pytest.mark.asyncio +async def test_async_task_epics_cancel_error_404(): + ec = _async_error_client(404) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.task_epics.cancel("test-value") + assert exc_info.value.status == 404 + finally: + await ec.close() + + +def test_task_epics_drafts_list_success(): + client = _client() + try: + result = client.v1.task_epics.drafts.list("test-value") + assert isinstance(result, BaseModel) + assert type(result).__name__ == "TaskEpicDrafts" + finally: + client.close() + + +def test_task_epics_drafts_list_error_404(): + ec = _error_client(404) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.task_epics.drafts.list("test-value") + assert exc_info.value.status == 404 + finally: + ec.close() + + +def test_task_epics_drafts_list_error_409(): + ec = _error_client(409) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.task_epics.drafts.list("test-value") + assert exc_info.value.status == 409 + finally: + ec.close() + + +def test_task_epics_drafts_list_error_422(): + ec = _error_client(422) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.task_epics.drafts.list("test-value") + assert exc_info.value.status == 422 + finally: + ec.close() + + +@pytest.mark.asyncio +async def test_async_task_epics_drafts_list_success(): + client = _async_client() + try: + result = await client.v1.task_epics.drafts.list("test-value") + assert isinstance(result, BaseModel) + assert type(result).__name__ == "TaskEpicDrafts" + finally: + await client.close() + + +@pytest.mark.asyncio +async def test_async_task_epics_drafts_list_error_404(): + ec = _async_error_client(404) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.task_epics.drafts.list("test-value") + assert exc_info.value.status == 404 + finally: + await ec.close() + + +@pytest.mark.asyncio +async def test_async_task_epics_drafts_list_error_409(): + ec = _async_error_client(409) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.task_epics.drafts.list("test-value") + assert exc_info.value.status == 409 + finally: + await ec.close() + + +@pytest.mark.asyncio +async def test_async_task_epics_drafts_list_error_422(): + ec = _async_error_client(422) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.task_epics.drafts.list("test-value") + assert exc_info.value.status == 422 + finally: + await ec.close() + + +def test_task_epics_drafts_replace_success(): + client = _client() + try: + result = client.v1.task_epics.drafts.replace("test-value", {"expected_drafts_version": 1}) + assert isinstance(result, BaseModel) + assert type(result).__name__ == "TaskEpicDrafts" + finally: + client.close() + + +def test_task_epics_drafts_replace_error_404(): + ec = _error_client(404) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.task_epics.drafts.replace("test-value", {"expected_drafts_version": 1}) + assert exc_info.value.status == 404 + finally: + ec.close() + + +def test_task_epics_drafts_replace_error_409(): + ec = _error_client(409) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.task_epics.drafts.replace("test-value", {"expected_drafts_version": 1}) + assert exc_info.value.status == 409 + finally: + ec.close() + + +def test_task_epics_drafts_replace_error_422(): + ec = _error_client(422) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.task_epics.drafts.replace("test-value", {"expected_drafts_version": 1}) + assert exc_info.value.status == 422 + finally: + ec.close() + + +@pytest.mark.asyncio +async def test_async_task_epics_drafts_replace_success(): + client = _async_client() + try: + result = await client.v1.task_epics.drafts.replace( + "test-value", {"expected_drafts_version": 1} + ) + assert isinstance(result, BaseModel) + assert type(result).__name__ == "TaskEpicDrafts" + finally: + await client.close() + + +@pytest.mark.asyncio +async def test_async_task_epics_drafts_replace_error_404(): + ec = _async_error_client(404) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.task_epics.drafts.replace("test-value", {"expected_drafts_version": 1}) + assert exc_info.value.status == 404 + finally: + await ec.close() + + +@pytest.mark.asyncio +async def test_async_task_epics_drafts_replace_error_409(): + ec = _async_error_client(409) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.task_epics.drafts.replace("test-value", {"expected_drafts_version": 1}) + assert exc_info.value.status == 409 + finally: + await ec.close() + + +@pytest.mark.asyncio +async def test_async_task_epics_drafts_replace_error_422(): + ec = _async_error_client(422) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.task_epics.drafts.replace("test-value", {"expected_drafts_version": 1}) + assert exc_info.value.status == 422 + finally: + await ec.close() + + +def test_task_epics_drafts_delete_success(): + client = _client() + try: + result = client.v1.task_epics.drafts.delete("test-value", "test-key") + assert isinstance(result, BaseModel) + assert type(result).__name__ == "TaskEpicDrafts" + finally: + client.close() + + +def test_task_epics_drafts_delete_error_404(): + ec = _error_client(404) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.task_epics.drafts.delete("test-value", "test-key") + assert exc_info.value.status == 404 + finally: + ec.close() + + +def test_task_epics_drafts_delete_error_409(): + ec = _error_client(409) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.task_epics.drafts.delete("test-value", "test-key") + assert exc_info.value.status == 409 + finally: + ec.close() + + +def test_task_epics_drafts_delete_error_422(): + ec = _error_client(422) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.task_epics.drafts.delete("test-value", "test-key") + assert exc_info.value.status == 422 + finally: + ec.close() + + +@pytest.mark.asyncio +async def test_async_task_epics_drafts_delete_success(): + client = _async_client() + try: + result = await client.v1.task_epics.drafts.delete("test-value", "test-key") + assert isinstance(result, BaseModel) + assert type(result).__name__ == "TaskEpicDrafts" + finally: + await client.close() + + +@pytest.mark.asyncio +async def test_async_task_epics_drafts_delete_error_404(): + ec = _async_error_client(404) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.task_epics.drafts.delete("test-value", "test-key") + assert exc_info.value.status == 404 + finally: + await ec.close() + + +@pytest.mark.asyncio +async def test_async_task_epics_drafts_delete_error_409(): + ec = _async_error_client(409) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.task_epics.drafts.delete("test-value", "test-key") + assert exc_info.value.status == 409 + finally: + await ec.close() + + +@pytest.mark.asyncio +async def test_async_task_epics_drafts_delete_error_422(): + ec = _async_error_client(422) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.task_epics.drafts.delete("test-value", "test-key") + assert exc_info.value.status == 422 + finally: + await ec.close() + + +def test_task_epics_drafts_replace_by_key_success(): + client = _client() + try: + result = client.v1.task_epics.drafts.replace_by_key( + "test-value", "test-key", {"draft": {"name": "test-name"}, "expected_drafts_version": 1} + ) + assert isinstance(result, BaseModel) + assert type(result).__name__ == "TaskEpicDrafts" + finally: + client.close() + + +def test_task_epics_drafts_replace_by_key_error_404(): + ec = _error_client(404) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.task_epics.drafts.replace_by_key( + "test-value", + "test-key", + {"draft": {"name": "test-name"}, "expected_drafts_version": 1}, + ) + assert exc_info.value.status == 404 + finally: + ec.close() + + +def test_task_epics_drafts_replace_by_key_error_409(): + ec = _error_client(409) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.task_epics.drafts.replace_by_key( + "test-value", + "test-key", + {"draft": {"name": "test-name"}, "expected_drafts_version": 1}, + ) + assert exc_info.value.status == 409 + finally: + ec.close() + + +def test_task_epics_drafts_replace_by_key_error_422(): + ec = _error_client(422) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.task_epics.drafts.replace_by_key( + "test-value", + "test-key", + {"draft": {"name": "test-name"}, "expected_drafts_version": 1}, + ) + assert exc_info.value.status == 422 + finally: + ec.close() + + +@pytest.mark.asyncio +async def test_async_task_epics_drafts_replace_by_key_success(): + client = _async_client() + try: + result = await client.v1.task_epics.drafts.replace_by_key( + "test-value", "test-key", {"draft": {"name": "test-name"}, "expected_drafts_version": 1} + ) + assert isinstance(result, BaseModel) + assert type(result).__name__ == "TaskEpicDrafts" + finally: + await client.close() + + +@pytest.mark.asyncio +async def test_async_task_epics_drafts_replace_by_key_error_404(): + ec = _async_error_client(404) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.task_epics.drafts.replace_by_key( + "test-value", + "test-key", + {"draft": {"name": "test-name"}, "expected_drafts_version": 1}, + ) + assert exc_info.value.status == 404 + finally: + await ec.close() + + +@pytest.mark.asyncio +async def test_async_task_epics_drafts_replace_by_key_error_409(): + ec = _async_error_client(409) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.task_epics.drafts.replace_by_key( + "test-value", + "test-key", + {"draft": {"name": "test-name"}, "expected_drafts_version": 1}, + ) + assert exc_info.value.status == 409 + finally: + await ec.close() + + +@pytest.mark.asyncio +async def test_async_task_epics_drafts_replace_by_key_error_422(): + ec = _async_error_client(422) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.task_epics.drafts.replace_by_key( + "test-value", + "test-key", + {"draft": {"name": "test-name"}, "expected_drafts_version": 1}, + ) + assert exc_info.value.status == 422 + finally: + await ec.close() diff --git a/tests/contract/v1/test_tasks.py b/tests/contract/v1/test_tasks.py index ce84eaa..0988613 100644 --- a/tests/contract/v1/test_tasks.py +++ b/tests/contract/v1/test_tasks.py @@ -1,6 +1,6 @@ # Copyright (c) 2026 ArchAstro Inc. Licensed under the MIT License. # This file is auto-generated by @archastro/sdk-generator. Do not edit. -# Content hash: e27df6d7e919 +# Content hash: 98e2621855fa import pytest from pydantic import BaseModel @@ -528,6 +528,212 @@ async def test_async_tasks_blocking_error_422(): await ec.close() +def test_tasks_human_answer_success(): + client = _client() + try: + result = client.v1.tasks.human_answer("test-value", {"expected_version": 1}) + assert result is not None + finally: + client.close() + + +def test_tasks_human_answer_error_401(): + ec = _error_client(401) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.tasks.human_answer("test-value", {"expected_version": 1}) + assert exc_info.value.status == 401 + finally: + ec.close() + + +def test_tasks_human_answer_error_404(): + ec = _error_client(404) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.tasks.human_answer("test-value", {"expected_version": 1}) + assert exc_info.value.status == 404 + finally: + ec.close() + + +def test_tasks_human_answer_error_409(): + ec = _error_client(409) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.tasks.human_answer("test-value", {"expected_version": 1}) + assert exc_info.value.status == 409 + finally: + ec.close() + + +def test_tasks_human_answer_error_422(): + ec = _error_client(422) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.tasks.human_answer("test-value", {"expected_version": 1}) + assert exc_info.value.status == 422 + finally: + ec.close() + + +@pytest.mark.asyncio +async def test_async_tasks_human_answer_success(): + client = _async_client() + try: + result = await client.v1.tasks.human_answer("test-value", {"expected_version": 1}) + assert result is not None + finally: + await client.close() + + +@pytest.mark.asyncio +async def test_async_tasks_human_answer_error_401(): + ec = _async_error_client(401) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.tasks.human_answer("test-value", {"expected_version": 1}) + assert exc_info.value.status == 401 + finally: + await ec.close() + + +@pytest.mark.asyncio +async def test_async_tasks_human_answer_error_404(): + ec = _async_error_client(404) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.tasks.human_answer("test-value", {"expected_version": 1}) + assert exc_info.value.status == 404 + finally: + await ec.close() + + +@pytest.mark.asyncio +async def test_async_tasks_human_answer_error_409(): + ec = _async_error_client(409) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.tasks.human_answer("test-value", {"expected_version": 1}) + assert exc_info.value.status == 409 + finally: + await ec.close() + + +@pytest.mark.asyncio +async def test_async_tasks_human_answer_error_422(): + ec = _async_error_client(422) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.tasks.human_answer("test-value", {"expected_version": 1}) + assert exc_info.value.status == 422 + finally: + await ec.close() + + +def test_tasks_machine_rescope_success(): + client = _client() + try: + result = client.v1.tasks.machine_rescope("test-value", {"expected_version": 1}) + assert result is not None + finally: + client.close() + + +def test_tasks_machine_rescope_error_401(): + ec = _error_client(401) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.tasks.machine_rescope("test-value", {"expected_version": 1}) + assert exc_info.value.status == 401 + finally: + ec.close() + + +def test_tasks_machine_rescope_error_404(): + ec = _error_client(404) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.tasks.machine_rescope("test-value", {"expected_version": 1}) + assert exc_info.value.status == 404 + finally: + ec.close() + + +def test_tasks_machine_rescope_error_409(): + ec = _error_client(409) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.tasks.machine_rescope("test-value", {"expected_version": 1}) + assert exc_info.value.status == 409 + finally: + ec.close() + + +def test_tasks_machine_rescope_error_422(): + ec = _error_client(422) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.tasks.machine_rescope("test-value", {"expected_version": 1}) + assert exc_info.value.status == 422 + finally: + ec.close() + + +@pytest.mark.asyncio +async def test_async_tasks_machine_rescope_success(): + client = _async_client() + try: + result = await client.v1.tasks.machine_rescope("test-value", {"expected_version": 1}) + assert result is not None + finally: + await client.close() + + +@pytest.mark.asyncio +async def test_async_tasks_machine_rescope_error_401(): + ec = _async_error_client(401) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.tasks.machine_rescope("test-value", {"expected_version": 1}) + assert exc_info.value.status == 401 + finally: + await ec.close() + + +@pytest.mark.asyncio +async def test_async_tasks_machine_rescope_error_404(): + ec = _async_error_client(404) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.tasks.machine_rescope("test-value", {"expected_version": 1}) + assert exc_info.value.status == 404 + finally: + await ec.close() + + +@pytest.mark.asyncio +async def test_async_tasks_machine_rescope_error_409(): + ec = _async_error_client(409) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.tasks.machine_rescope("test-value", {"expected_version": 1}) + assert exc_info.value.status == 409 + finally: + await ec.close() + + +@pytest.mark.asyncio +async def test_async_tasks_machine_rescope_error_422(): + ec = _async_error_client(422) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.tasks.machine_rescope("test-value", {"expected_version": 1}) + assert exc_info.value.status == 422 + finally: + await ec.close() + + def test_tasks_ownership_conversions_success(): client = _client() try: @@ -2291,6 +2497,23 @@ def test_tasks_links_create_error_401(): ec.close() +def test_tasks_links_create_error_403(): + ec = _error_client(403) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.tasks.links.create( + "test-value", + { + "external_scope": "test-value", + "object_id": "test-id", + "object_type": "test-value", + }, + ) + assert exc_info.value.status == 403 + finally: + ec.close() + + def test_tasks_links_create_error_404(): ec = _error_client(404) try: @@ -2308,6 +2531,23 @@ def test_tasks_links_create_error_404(): ec.close() +def test_tasks_links_create_error_409(): + ec = _error_client(409) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.tasks.links.create( + "test-value", + { + "external_scope": "test-value", + "object_id": "test-id", + "object_type": "test-value", + }, + ) + assert exc_info.value.status == 409 + finally: + ec.close() + + def test_tasks_links_create_error_422(): ec = _error_client(422) try: @@ -2374,6 +2614,24 @@ async def test_async_tasks_links_create_error_401(): await ec.close() +@pytest.mark.asyncio +async def test_async_tasks_links_create_error_403(): + ec = _async_error_client(403) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.tasks.links.create( + "test-value", + { + "external_scope": "test-value", + "object_id": "test-id", + "object_type": "test-value", + }, + ) + assert exc_info.value.status == 403 + finally: + await ec.close() + + @pytest.mark.asyncio async def test_async_tasks_links_create_error_404(): ec = _async_error_client(404) @@ -2392,6 +2650,24 @@ async def test_async_tasks_links_create_error_404(): await ec.close() +@pytest.mark.asyncio +async def test_async_tasks_links_create_error_409(): + ec = _async_error_client(409) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.tasks.links.create( + "test-value", + { + "external_scope": "test-value", + "object_id": "test-id", + "object_type": "test-value", + }, + ) + assert exc_info.value.status == 409 + finally: + await ec.close() + + @pytest.mark.asyncio async def test_async_tasks_links_create_error_422(): ec = _async_error_client(422) diff --git a/tests/contract/v1/test_teams.py b/tests/contract/v1/test_teams.py index 2c71a82..602bcd9 100644 --- a/tests/contract/v1/test_teams.py +++ b/tests/contract/v1/test_teams.py @@ -1,6 +1,6 @@ # Copyright (c) 2026 ArchAstro Inc. Licensed under the MIT License. # This file is auto-generated by @archastro/sdk-generator. Do not edit. -# Content hash: 221a750640f9 +# Content hash: 5f89e2d402c9 import pytest from pydantic import BaseModel @@ -1114,92 +1114,6 @@ async def test_async_teams_task_assignees_error_422(): await ec.close() -def test_teams_task_epics_success(): - client = _client() - try: - result = client.v1.teams.task_epics("test-value") - assert isinstance(result, BaseModel) - assert type(result).__name__ == "TeamTaskEpicsResponse" - assert isinstance(result.data, list) - finally: - client.close() - - -def test_teams_task_epics_error_401(): - ec = _error_client(401) - try: - with pytest.raises(ApiError) as exc_info: - ec.v1.teams.task_epics("test-value") - assert exc_info.value.status == 401 - finally: - ec.close() - - -def test_teams_task_epics_error_404(): - ec = _error_client(404) - try: - with pytest.raises(ApiError) as exc_info: - ec.v1.teams.task_epics("test-value") - assert exc_info.value.status == 404 - finally: - ec.close() - - -def test_teams_task_epics_error_422(): - ec = _error_client(422) - try: - with pytest.raises(ApiError) as exc_info: - ec.v1.teams.task_epics("test-value") - assert exc_info.value.status == 422 - finally: - ec.close() - - -@pytest.mark.asyncio -async def test_async_teams_task_epics_success(): - client = _async_client() - try: - result = await client.v1.teams.task_epics("test-value") - assert isinstance(result, BaseModel) - assert type(result).__name__ == "TeamTaskEpicsResponse" - assert isinstance(result.data, list) - finally: - await client.close() - - -@pytest.mark.asyncio -async def test_async_teams_task_epics_error_401(): - ec = _async_error_client(401) - try: - with pytest.raises(ApiError) as exc_info: - await ec.v1.teams.task_epics("test-value") - assert exc_info.value.status == 401 - finally: - await ec.close() - - -@pytest.mark.asyncio -async def test_async_teams_task_epics_error_404(): - ec = _async_error_client(404) - try: - with pytest.raises(ApiError) as exc_info: - await ec.v1.teams.task_epics("test-value") - assert exc_info.value.status == 404 - finally: - await ec.close() - - -@pytest.mark.asyncio -async def test_async_teams_task_epics_error_422(): - ec = _async_error_client(422) - try: - with pytest.raises(ApiError) as exc_info: - await ec.v1.teams.task_epics("test-value") - assert exc_info.value.status == 422 - finally: - await ec.close() - - def test_teams_custom_objects_list_success(): client = _client() try: @@ -1916,6 +1830,151 @@ async def test_async_teams_members_update_error_422(): await ec.close() +def test_teams_task_epics_list_success(): + client = _client() + try: + result = client.v1.teams.task_epics.list("test-value") + assert isinstance(result, (BaseModel, dict)) + finally: + client.close() + + +def test_teams_task_epics_list_error_401(): + ec = _error_client(401) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.teams.task_epics.list("test-value") + assert exc_info.value.status == 401 + finally: + ec.close() + + +def test_teams_task_epics_list_error_404(): + ec = _error_client(404) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.teams.task_epics.list("test-value") + assert exc_info.value.status == 404 + finally: + ec.close() + + +def test_teams_task_epics_list_error_422(): + ec = _error_client(422) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.teams.task_epics.list("test-value") + assert exc_info.value.status == 422 + finally: + ec.close() + + +@pytest.mark.asyncio +async def test_async_teams_task_epics_list_success(): + client = _async_client() + try: + result = await client.v1.teams.task_epics.list("test-value") + assert isinstance(result, (BaseModel, dict)) + finally: + await client.close() + + +@pytest.mark.asyncio +async def test_async_teams_task_epics_list_error_401(): + ec = _async_error_client(401) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.teams.task_epics.list("test-value") + assert exc_info.value.status == 401 + finally: + await ec.close() + + +@pytest.mark.asyncio +async def test_async_teams_task_epics_list_error_404(): + ec = _async_error_client(404) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.teams.task_epics.list("test-value") + assert exc_info.value.status == 404 + finally: + await ec.close() + + +@pytest.mark.asyncio +async def test_async_teams_task_epics_list_error_422(): + ec = _async_error_client(422) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.teams.task_epics.list("test-value") + assert exc_info.value.status == 422 + finally: + await ec.close() + + +def test_teams_task_epics_create_success(): + client = _client() + try: + result = client.v1.teams.task_epics.create("test-value", {"name": "test-name"}) + assert isinstance(result, BaseModel) + assert type(result).__name__ == "TaskEpicEntity" + finally: + client.close() + + +def test_teams_task_epics_create_error_404(): + ec = _error_client(404) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.teams.task_epics.create("test-value", {"name": "test-name"}) + assert exc_info.value.status == 404 + finally: + ec.close() + + +def test_teams_task_epics_create_error_422(): + ec = _error_client(422) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.teams.task_epics.create("test-value", {"name": "test-name"}) + assert exc_info.value.status == 422 + finally: + ec.close() + + +@pytest.mark.asyncio +async def test_async_teams_task_epics_create_success(): + client = _async_client() + try: + result = await client.v1.teams.task_epics.create("test-value", {"name": "test-name"}) + assert isinstance(result, BaseModel) + assert type(result).__name__ == "TaskEpicEntity" + finally: + await client.close() + + +@pytest.mark.asyncio +async def test_async_teams_task_epics_create_error_404(): + ec = _async_error_client(404) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.teams.task_epics.create("test-value", {"name": "test-name"}) + assert exc_info.value.status == 404 + finally: + await ec.close() + + +@pytest.mark.asyncio +async def test_async_teams_task_epics_create_error_422(): + ec = _async_error_client(422) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.teams.task_epics.create("test-value", {"name": "test-name"}) + assert exc_info.value.status == 422 + finally: + await ec.close() + + def test_teams_tasks_list_success(): client = _client() try: @@ -2193,6 +2252,126 @@ async def test_async_teams_tasks_blocker_cycles_error_422(): await ec.close() +def test_teams_tasks_by_external_reference_success(): + client = _client() + try: + result = client.v1.teams.tasks.by_external_reference( + "test-value", external_scope="test-value", object_type="test-value", object_id="test-id" + ) + assert isinstance(result, BaseModel) + assert type(result).__name__ == "TeamTaskByExternalReferenceResponse" + assert isinstance(result.data, list) + finally: + client.close() + + +def test_teams_tasks_by_external_reference_error_401(): + ec = _error_client(401) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.teams.tasks.by_external_reference( + "test-value", + external_scope="test-value", + object_type="test-value", + object_id="test-id", + ) + assert exc_info.value.status == 401 + finally: + ec.close() + + +def test_teams_tasks_by_external_reference_error_404(): + ec = _error_client(404) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.teams.tasks.by_external_reference( + "test-value", + external_scope="test-value", + object_type="test-value", + object_id="test-id", + ) + assert exc_info.value.status == 404 + finally: + ec.close() + + +def test_teams_tasks_by_external_reference_error_422(): + ec = _error_client(422) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.teams.tasks.by_external_reference( + "test-value", + external_scope="test-value", + object_type="test-value", + object_id="test-id", + ) + assert exc_info.value.status == 422 + finally: + ec.close() + + +@pytest.mark.asyncio +async def test_async_teams_tasks_by_external_reference_success(): + client = _async_client() + try: + result = await client.v1.teams.tasks.by_external_reference( + "test-value", external_scope="test-value", object_type="test-value", object_id="test-id" + ) + assert isinstance(result, BaseModel) + assert type(result).__name__ == "TeamTaskByExternalReferenceResponse" + assert isinstance(result.data, list) + finally: + await client.close() + + +@pytest.mark.asyncio +async def test_async_teams_tasks_by_external_reference_error_401(): + ec = _async_error_client(401) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.teams.tasks.by_external_reference( + "test-value", + external_scope="test-value", + object_type="test-value", + object_id="test-id", + ) + assert exc_info.value.status == 401 + finally: + await ec.close() + + +@pytest.mark.asyncio +async def test_async_teams_tasks_by_external_reference_error_404(): + ec = _async_error_client(404) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.teams.tasks.by_external_reference( + "test-value", + external_scope="test-value", + object_type="test-value", + object_id="test-id", + ) + assert exc_info.value.status == 404 + finally: + await ec.close() + + +@pytest.mark.asyncio +async def test_async_teams_tasks_by_external_reference_error_422(): + ec = _async_error_client(422) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.teams.tasks.by_external_reference( + "test-value", + external_scope="test-value", + object_type="test-value", + object_id="test-id", + ) + assert exc_info.value.status == 422 + finally: + await ec.close() + + def test_teams_tasks_by_source_success(): client = _client() try: diff --git a/tests/contract/v1/test_users.py b/tests/contract/v1/test_users.py index 87441c8..d472ffb 100644 --- a/tests/contract/v1/test_users.py +++ b/tests/contract/v1/test_users.py @@ -1,6 +1,6 @@ # Copyright (c) 2026 ArchAstro Inc. Licensed under the MIT License. # This file is auto-generated by @archastro/sdk-generator. Do not edit. -# Content hash: af103bbf2002 +# Content hash: a2b68f1ca8fd import pytest from pydantic import BaseModel @@ -509,92 +509,6 @@ async def test_async_users_profile_error_422(): await ec.close() -def test_users_task_epics_success(): - client = _client() - try: - result = client.v1.users.task_epics("test-value") - assert isinstance(result, BaseModel) - assert type(result).__name__ == "UserTaskEpicsResponse" - assert isinstance(result.data, list) - finally: - client.close() - - -def test_users_task_epics_error_401(): - ec = _error_client(401) - try: - with pytest.raises(ApiError) as exc_info: - ec.v1.users.task_epics("test-value") - assert exc_info.value.status == 401 - finally: - ec.close() - - -def test_users_task_epics_error_404(): - ec = _error_client(404) - try: - with pytest.raises(ApiError) as exc_info: - ec.v1.users.task_epics("test-value") - assert exc_info.value.status == 404 - finally: - ec.close() - - -def test_users_task_epics_error_422(): - ec = _error_client(422) - try: - with pytest.raises(ApiError) as exc_info: - ec.v1.users.task_epics("test-value") - assert exc_info.value.status == 422 - finally: - ec.close() - - -@pytest.mark.asyncio -async def test_async_users_task_epics_success(): - client = _async_client() - try: - result = await client.v1.users.task_epics("test-value") - assert isinstance(result, BaseModel) - assert type(result).__name__ == "UserTaskEpicsResponse" - assert isinstance(result.data, list) - finally: - await client.close() - - -@pytest.mark.asyncio -async def test_async_users_task_epics_error_401(): - ec = _async_error_client(401) - try: - with pytest.raises(ApiError) as exc_info: - await ec.v1.users.task_epics("test-value") - assert exc_info.value.status == 401 - finally: - await ec.close() - - -@pytest.mark.asyncio -async def test_async_users_task_epics_error_404(): - ec = _async_error_client(404) - try: - with pytest.raises(ApiError) as exc_info: - await ec.v1.users.task_epics("test-value") - assert exc_info.value.status == 404 - finally: - await ec.close() - - -@pytest.mark.asyncio -async def test_async_users_task_epics_error_422(): - ec = _async_error_client(422) - try: - with pytest.raises(ApiError) as exc_info: - await ec.v1.users.task_epics("test-value") - assert exc_info.value.status == 422 - finally: - await ec.close() - - def test_users_integrations_access_token_success(): client = _client() try: @@ -928,6 +842,151 @@ async def test_async_users_ssh_keys_create_error_422(): await ec.close() +def test_users_task_epics_list_success(): + client = _client() + try: + result = client.v1.users.task_epics.list("test-value") + assert isinstance(result, (BaseModel, dict)) + finally: + client.close() + + +def test_users_task_epics_list_error_401(): + ec = _error_client(401) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.users.task_epics.list("test-value") + assert exc_info.value.status == 401 + finally: + ec.close() + + +def test_users_task_epics_list_error_404(): + ec = _error_client(404) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.users.task_epics.list("test-value") + assert exc_info.value.status == 404 + finally: + ec.close() + + +def test_users_task_epics_list_error_422(): + ec = _error_client(422) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.users.task_epics.list("test-value") + assert exc_info.value.status == 422 + finally: + ec.close() + + +@pytest.mark.asyncio +async def test_async_users_task_epics_list_success(): + client = _async_client() + try: + result = await client.v1.users.task_epics.list("test-value") + assert isinstance(result, (BaseModel, dict)) + finally: + await client.close() + + +@pytest.mark.asyncio +async def test_async_users_task_epics_list_error_401(): + ec = _async_error_client(401) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.users.task_epics.list("test-value") + assert exc_info.value.status == 401 + finally: + await ec.close() + + +@pytest.mark.asyncio +async def test_async_users_task_epics_list_error_404(): + ec = _async_error_client(404) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.users.task_epics.list("test-value") + assert exc_info.value.status == 404 + finally: + await ec.close() + + +@pytest.mark.asyncio +async def test_async_users_task_epics_list_error_422(): + ec = _async_error_client(422) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.users.task_epics.list("test-value") + assert exc_info.value.status == 422 + finally: + await ec.close() + + +def test_users_task_epics_create_success(): + client = _client() + try: + result = client.v1.users.task_epics.create("test-value", {"name": "test-name"}) + assert isinstance(result, BaseModel) + assert type(result).__name__ == "TaskEpicEntity" + finally: + client.close() + + +def test_users_task_epics_create_error_404(): + ec = _error_client(404) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.users.task_epics.create("test-value", {"name": "test-name"}) + assert exc_info.value.status == 404 + finally: + ec.close() + + +def test_users_task_epics_create_error_422(): + ec = _error_client(422) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.users.task_epics.create("test-value", {"name": "test-name"}) + assert exc_info.value.status == 422 + finally: + ec.close() + + +@pytest.mark.asyncio +async def test_async_users_task_epics_create_success(): + client = _async_client() + try: + result = await client.v1.users.task_epics.create("test-value", {"name": "test-name"}) + assert isinstance(result, BaseModel) + assert type(result).__name__ == "TaskEpicEntity" + finally: + await client.close() + + +@pytest.mark.asyncio +async def test_async_users_task_epics_create_error_404(): + ec = _async_error_client(404) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.users.task_epics.create("test-value", {"name": "test-name"}) + assert exc_info.value.status == 404 + finally: + await ec.close() + + +@pytest.mark.asyncio +async def test_async_users_task_epics_create_error_422(): + ec = _async_error_client(422) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.users.task_epics.create("test-value", {"name": "test-name"}) + assert exc_info.value.status == 422 + finally: + await ec.close() + + def test_users_tasks_list_success(): client = _client() try: @@ -1205,6 +1264,126 @@ async def test_async_users_tasks_blocker_cycles_error_422(): await ec.close() +def test_users_tasks_by_external_reference_success(): + client = _client() + try: + result = client.v1.users.tasks.by_external_reference( + "test-value", external_scope="test-value", object_type="test-value", object_id="test-id" + ) + assert isinstance(result, BaseModel) + assert type(result).__name__ == "UserTaskByExternalReferenceResponse" + assert isinstance(result.data, list) + finally: + client.close() + + +def test_users_tasks_by_external_reference_error_401(): + ec = _error_client(401) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.users.tasks.by_external_reference( + "test-value", + external_scope="test-value", + object_type="test-value", + object_id="test-id", + ) + assert exc_info.value.status == 401 + finally: + ec.close() + + +def test_users_tasks_by_external_reference_error_404(): + ec = _error_client(404) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.users.tasks.by_external_reference( + "test-value", + external_scope="test-value", + object_type="test-value", + object_id="test-id", + ) + assert exc_info.value.status == 404 + finally: + ec.close() + + +def test_users_tasks_by_external_reference_error_422(): + ec = _error_client(422) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.users.tasks.by_external_reference( + "test-value", + external_scope="test-value", + object_type="test-value", + object_id="test-id", + ) + assert exc_info.value.status == 422 + finally: + ec.close() + + +@pytest.mark.asyncio +async def test_async_users_tasks_by_external_reference_success(): + client = _async_client() + try: + result = await client.v1.users.tasks.by_external_reference( + "test-value", external_scope="test-value", object_type="test-value", object_id="test-id" + ) + assert isinstance(result, BaseModel) + assert type(result).__name__ == "UserTaskByExternalReferenceResponse" + assert isinstance(result.data, list) + finally: + await client.close() + + +@pytest.mark.asyncio +async def test_async_users_tasks_by_external_reference_error_401(): + ec = _async_error_client(401) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.users.tasks.by_external_reference( + "test-value", + external_scope="test-value", + object_type="test-value", + object_id="test-id", + ) + assert exc_info.value.status == 401 + finally: + await ec.close() + + +@pytest.mark.asyncio +async def test_async_users_tasks_by_external_reference_error_404(): + ec = _async_error_client(404) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.users.tasks.by_external_reference( + "test-value", + external_scope="test-value", + object_type="test-value", + object_id="test-id", + ) + assert exc_info.value.status == 404 + finally: + await ec.close() + + +@pytest.mark.asyncio +async def test_async_users_tasks_by_external_reference_error_422(): + ec = _async_error_client(422) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.users.tasks.by_external_reference( + "test-value", + external_scope="test-value", + object_type="test-value", + object_id="test-id", + ) + assert exc_info.value.status == 422 + finally: + await ec.close() + + def test_users_tasks_by_source_success(): client = _client() try: @@ -1674,6 +1853,90 @@ async def test_async_users_threads_create_error_422(): await ec.close() +def test_users_threads_from_template_success(): + client = _client() + try: + result = client.v1.users.threads.from_template("test-value", {"template": "test-value"}) + assert result is not None + finally: + client.close() + + +def test_users_threads_from_template_error_403(): + ec = _error_client(403) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.users.threads.from_template("test-value", {"template": "test-value"}) + assert exc_info.value.status == 403 + finally: + ec.close() + + +def test_users_threads_from_template_error_422(): + ec = _error_client(422) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.users.threads.from_template("test-value", {"template": "test-value"}) + assert exc_info.value.status == 422 + finally: + ec.close() + + +def test_users_threads_from_template_error_502(): + ec = _error_client(502) + try: + with pytest.raises(ApiError) as exc_info: + ec.v1.users.threads.from_template("test-value", {"template": "test-value"}) + assert exc_info.value.status == 502 + finally: + ec.close() + + +@pytest.mark.asyncio +async def test_async_users_threads_from_template_success(): + client = _async_client() + try: + result = await client.v1.users.threads.from_template( + "test-value", {"template": "test-value"} + ) + assert result is not None + finally: + await client.close() + + +@pytest.mark.asyncio +async def test_async_users_threads_from_template_error_403(): + ec = _async_error_client(403) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.users.threads.from_template("test-value", {"template": "test-value"}) + assert exc_info.value.status == 403 + finally: + await ec.close() + + +@pytest.mark.asyncio +async def test_async_users_threads_from_template_error_422(): + ec = _async_error_client(422) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.users.threads.from_template("test-value", {"template": "test-value"}) + assert exc_info.value.status == 422 + finally: + await ec.close() + + +@pytest.mark.asyncio +async def test_async_users_threads_from_template_error_502(): + ec = _async_error_client(502) + try: + with pytest.raises(ApiError) as exc_info: + await ec.v1.users.threads.from_template("test-value", {"template": "test-value"}) + assert exc_info.value.status == 502 + finally: + await ec.close() + + def test_users_tokens_list_success(): client = _client() try: