diff --git a/packages/sdk/__tests__/contract/channels/api_artifact_channel.contract.test.ts b/packages/sdk/__tests__/contract/channels/api_artifact_channel.contract.test.ts new file mode 100644 index 0000000..c5684f9 --- /dev/null +++ b/packages/sdk/__tests__/contract/channels/api_artifact_channel.contract.test.ts @@ -0,0 +1,464 @@ +// Copyright (c) 2026 ArchAstro Inc. Licensed under the MIT License. +// This file is auto-generated by @archastro/sdk-generator. Do not edit. +// Content hash: 87dfa4111450 + +// Contract tests for the generated channel class. Drives the channel +// through a real WebSocket against the harness-service subprocess — +// the same service Python tests connect to. Scenario closures are +// serialized over an HTTP control API, not passed in-process. + +import { describe, it, expect, beforeEach, afterEach } from "vitest"; +import { + ChannelJoinError, + ChannelReplyError, + HarnessServiceClient, + type HarnessSocket, +} from "@archastro/channel-harness"; +import { ApiArtifactChannel } from "../../../src/channels/api_artifact_channel.js"; + +interface Rig { + client: HarnessServiceClient; + socket: HarnessSocket; +} + +// Check the env vars inside bootHarness() rather than at module scope: +// a module-level throw would surface as a vitest collection error for the +// whole file, while a thrown inside bootHarness() becomes a normal test +// failure that doesn't tear down the rest of the suite. +async function bootHarness(): Promise { + const wsUrl = process.env.ARCHASTRO_HARNESS_WS_URL; + const controlUrl = process.env.ARCHASTRO_HARNESS_CONTROL_URL; + if (!wsUrl || !controlUrl) { + throw new Error( + "Channel contract tests require ARCHASTRO_HARNESS_WS_URL and " + + "ARCHASTRO_HARNESS_CONTROL_URL — set by global-setup.ts." + ); + } + const client = new HarnessServiceClient({ wsUrl, controlUrl }); + await client.reset(); + const socket = await client.openSocket(); + return { client, socket }; +} + +function nextPush( + subscribe: (cb: (payload: unknown) => void) => () => void, + timeoutMs = 500 +): Promise { + return new Promise((resolve, reject) => { + let settled = false; + let unsubscribe: (() => void) | null = null; + const timer = setTimeout(() => { + if (settled) return; + settled = true; + unsubscribe?.(); + reject(new Error("push not received in time")); + }, timeoutMs); + unsubscribe = subscribe((payload) => { + if (settled) return; + settled = true; + clearTimeout(timer); + unsubscribe?.(); + resolve(payload); + }); + if (settled) unsubscribe(); + }); +} + +describe("ApiArtifactChannel.joinArtifact (api:artifact:{artifact_id})", () => { + let rig: Rig; + beforeEach(async () => { + rig = await bootHarness(); + }); + afterEach(() => { + rig.client.closeAllSockets(); + }); + + it("joins and receives a contract-valid reply", async () => { + const channel = await ApiArtifactChannel.joinArtifact(rig.socket, "test-id", { as_agent: "test-value" }); + expect(channel).toBeInstanceOf(ApiArtifactChannel); + expect(channel.joinResponse).toBeDefined(); + }); + + it("surfaces an application-level error reply as ChannelJoinError", async () => { + await rig.client.registerScenario({ + topic: "api:artifact:test-id", + onJoin: [{ type: "replyError", payload: { reason: "test_error" } }], + }); + + const err = await ApiArtifactChannel.joinArtifact(rig.socket, "test-id", { as_agent: "test-value" }).catch((e: unknown) => e); + expect(err).toBeInstanceOf(ChannelJoinError); + expect((err as ChannelJoinError).response).toEqual({ reason: "test_error" }); + }); +}); + +describe("ApiArtifactChannel.operation (operation)", () => { + let rig: Rig; + beforeEach(async () => { + rig = await bootHarness(); + }); + afterEach(() => { + rig.client.closeAllSockets(); + }); + + it("sends a valid push and receives a contract-valid reply", async () => { + await rig.client.registerScenario({ + topic: "api:artifact:test-id", + onJoin: [{ type: "autoReply" }], + onMessage: { + "operation": [{ type: "autoReply" }], + }, + }); + + const channel = await ApiArtifactChannel.joinArtifact(rig.socket, "test-id", { as_agent: "test-value" }); + const reply = await channel.operation({ cursor: { position: 1 }, op: [{}], op_id: "test-id", revision: 1 }); + expect(reply).toBeDefined(); + + const observed = await rig.client.observations("api:artifact:test-id", "operation"); + expect(observed).toHaveLength(1); + expect(observed[0]!.params).toEqual(expect.objectContaining({ op: [{}], revision: 1 })); + }); + + it("rejects with ChannelReplyError when required params are missing", async () => { + await rig.client.registerScenario({ + topic: "api:artifact:test-id", + onJoin: [{ type: "autoReply" }], + }); + const channel = await ApiArtifactChannel.joinArtifact(rig.socket, "test-id", { as_agent: "test-value" }); + + await expect(channel.operation({})).rejects.toBeInstanceOf(ChannelReplyError); + }); +}); + +describe("ApiArtifactChannel.cursor (cursor)", () => { + let rig: Rig; + beforeEach(async () => { + rig = await bootHarness(); + }); + afterEach(() => { + rig.client.closeAllSockets(); + }); + + it("sends a valid push and receives a contract-valid reply", async () => { + await rig.client.registerScenario({ + topic: "api:artifact:test-id", + onJoin: [{ type: "autoReply" }], + onMessage: { + "cursor": [{ type: "autoReply" }], + }, + }); + + const channel = await ApiArtifactChannel.joinArtifact(rig.socket, "test-id", { as_agent: "test-value" }); + const reply = await channel.cursor({ cursor: { position: 1 }, revision: 1 }); + expect(reply).toBeDefined(); + + const observed = await rig.client.observations("api:artifact:test-id", "cursor"); + expect(observed).toHaveLength(1); + expect(observed[0]!.params).toBeDefined(); + }); +}); + +describe("ApiArtifactChannel.signal (signal)", () => { + let rig: Rig; + beforeEach(async () => { + rig = await bootHarness(); + }); + afterEach(() => { + rig.client.closeAllSockets(); + }); + + it("sends a valid push and receives a contract-valid reply", async () => { + await rig.client.registerScenario({ + topic: "api:artifact:test-id", + onJoin: [{ type: "autoReply" }], + onMessage: { + "signal": [{ type: "autoReply" }], + }, + }); + + const channel = await ApiArtifactChannel.joinArtifact(rig.socket, "test-id", { as_agent: "test-value" }); + const reply = await channel.signal({ kind: "test", payload: {}, to: "test-value" }); + expect(reply).toBeDefined(); + + const observed = await rig.client.observations("api:artifact:test-id", "signal"); + expect(observed).toHaveLength(1); + expect(observed[0]!.params).toEqual(expect.objectContaining({ kind: "test", payload: {}, to: "test-value" })); + }); + + it("rejects with ChannelReplyError when required params are missing", async () => { + await rig.client.registerScenario({ + topic: "api:artifact:test-id", + onJoin: [{ type: "autoReply" }], + }); + const channel = await ApiArtifactChannel.joinArtifact(rig.socket, "test-id", { as_agent: "test-value" }); + + await expect(channel.signal({})).rejects.toBeInstanceOf(ChannelReplyError); + }); +}); + +describe("ApiArtifactChannel.checkpoint (checkpoint)", () => { + let rig: Rig; + beforeEach(async () => { + rig = await bootHarness(); + }); + afterEach(() => { + rig.client.closeAllSockets(); + }); + + it("sends a valid push and receives a contract-valid reply", async () => { + await rig.client.registerScenario({ + topic: "api:artifact:test-id", + onJoin: [{ type: "autoReply" }], + onMessage: { + "checkpoint": [{ type: "autoReply" }], + }, + }); + + const channel = await ApiArtifactChannel.joinArtifact(rig.socket, "test-id", { as_agent: "test-value" }); + const reply = await channel.checkpoint({}); + expect(reply).toBeDefined(); + + const observed = await rig.client.observations("api:artifact:test-id", "checkpoint"); + expect(observed).toHaveLength(1); + expect(observed[0]!.params).toBeDefined(); + }); +}); + +describe("ApiArtifactChannel.leaveMessage (leave)", () => { + let rig: Rig; + beforeEach(async () => { + rig = await bootHarness(); + }); + afterEach(() => { + rig.client.closeAllSockets(); + }); + + it("sends a valid push and receives a contract-valid reply", async () => { + await rig.client.registerScenario({ + topic: "api:artifact:test-id", + onJoin: [{ type: "autoReply" }], + onMessage: { + "leave": [{ type: "autoReply" }], + }, + }); + + const channel = await ApiArtifactChannel.joinArtifact(rig.socket, "test-id", { as_agent: "test-value" }); + const reply = await channel.leaveMessage({}); + expect(reply).toBeDefined(); + + const observed = await rig.client.observations("api:artifact:test-id", "leave"); + expect(observed).toHaveLength(1); + expect(observed[0]!.params).toBeDefined(); + }); +}); + +describe("ApiArtifactChannel.onOpRejected (op_rejected)", () => { + let rig: Rig; + beforeEach(async () => { + rig = await bootHarness(); + }); + afterEach(() => { + rig.client.closeAllSockets(); + }); + + it("delivers contract-valid payloads to onOpRejected", async () => { + await rig.client.registerScenario({ + topic: "api:artifact:test-id", + onJoin: [ + { type: "autoReply" }, + { type: "autoPush", event: "op_rejected" }, + ], + }); + + const channel = await ApiArtifactChannel.joinArtifact(rig.socket, "test-id", { as_agent: "test-value" }); + const payload = await nextPush((cb) => channel.onOpRejected(cb)); + expect(payload).toBeDefined(); + }); +}); + +describe("ApiArtifactChannel.onOperation (operation)", () => { + let rig: Rig; + beforeEach(async () => { + rig = await bootHarness(); + }); + afterEach(() => { + rig.client.closeAllSockets(); + }); + + it("delivers contract-valid payloads to onOperation", async () => { + await rig.client.registerScenario({ + topic: "api:artifact:test-id", + onJoin: [ + { type: "autoReply" }, + { type: "autoPush", event: "operation" }, + ], + }); + + const channel = await ApiArtifactChannel.joinArtifact(rig.socket, "test-id", { as_agent: "test-value" }); + const payload = await nextPush((cb) => channel.onOperation(cb)); + expect(payload).toBeDefined(); + }); +}); + +describe("ApiArtifactChannel.onSignal (signal)", () => { + let rig: Rig; + beforeEach(async () => { + rig = await bootHarness(); + }); + afterEach(() => { + rig.client.closeAllSockets(); + }); + + it("delivers contract-valid payloads to onSignal", async () => { + await rig.client.registerScenario({ + topic: "api:artifact:test-id", + onJoin: [ + { type: "autoReply" }, + { type: "autoPush", event: "signal" }, + ], + }); + + const channel = await ApiArtifactChannel.joinArtifact(rig.socket, "test-id", { as_agent: "test-value" }); + const payload = await nextPush((cb) => channel.onSignal(cb)); + expect(payload).toBeDefined(); + }); +}); + +describe("ApiArtifactChannel.onPresence (presence)", () => { + let rig: Rig; + beforeEach(async () => { + rig = await bootHarness(); + }); + afterEach(() => { + rig.client.closeAllSockets(); + }); + + it("delivers contract-valid payloads to onPresence", async () => { + await rig.client.registerScenario({ + topic: "api:artifact:test-id", + onJoin: [ + { type: "autoReply" }, + { type: "autoPush", event: "presence" }, + ], + }); + + const channel = await ApiArtifactChannel.joinArtifact(rig.socket, "test-id", { as_agent: "test-value" }); + const payload = await nextPush((cb) => channel.onPresence(cb)); + expect(payload).toBeDefined(); + }); +}); + +describe("ApiArtifactChannel.onCheckpoint (checkpoint)", () => { + let rig: Rig; + beforeEach(async () => { + rig = await bootHarness(); + }); + afterEach(() => { + rig.client.closeAllSockets(); + }); + + it("delivers contract-valid payloads to onCheckpoint", async () => { + await rig.client.registerScenario({ + topic: "api:artifact:test-id", + onJoin: [ + { type: "autoReply" }, + { type: "autoPush", event: "checkpoint" }, + ], + }); + + const channel = await ApiArtifactChannel.joinArtifact(rig.socket, "test-id", { as_agent: "test-value" }); + const payload = await nextPush((cb) => channel.onCheckpoint(cb)); + expect(payload).toBeDefined(); + }); +}); + +describe("ApiArtifactChannel.onCheckpointFailed (checkpoint_failed)", () => { + let rig: Rig; + beforeEach(async () => { + rig = await bootHarness(); + }); + afterEach(() => { + rig.client.closeAllSockets(); + }); + + it("delivers contract-valid payloads to onCheckpointFailed", async () => { + await rig.client.registerScenario({ + topic: "api:artifact:test-id", + onJoin: [ + { type: "autoReply" }, + { type: "autoPush", event: "checkpoint_failed" }, + ], + }); + + const channel = await ApiArtifactChannel.joinArtifact(rig.socket, "test-id", { as_agent: "test-value" }); + const payload = await nextPush((cb) => channel.onCheckpointFailed(cb)); + expect(payload).toBeDefined(); + }); +}); + +describe("ApiArtifactChannel.onSessionInvalid (session_invalid)", () => { + let rig: Rig; + beforeEach(async () => { + rig = await bootHarness(); + }); + afterEach(() => { + rig.client.closeAllSockets(); + }); + + it("delivers contract-valid payloads to onSessionInvalid", async () => { + await rig.client.registerScenario({ + topic: "api:artifact:test-id", + onJoin: [ + { type: "autoReply" }, + { type: "autoPush", event: "session_invalid" }, + ], + }); + + const channel = await ApiArtifactChannel.joinArtifact(rig.socket, "test-id", { as_agent: "test-value" }); + const payload = await nextPush((cb) => channel.onSessionInvalid(cb)); + expect(payload).toBeDefined(); + }); +}); + +describe("ApiArtifactChannel.onAccessRevoked (access_revoked)", () => { + let rig: Rig; + beforeEach(async () => { + rig = await bootHarness(); + }); + afterEach(() => { + rig.client.closeAllSockets(); + }); + + it("delivers contract-valid payloads to onAccessRevoked", async () => { + await rig.client.registerScenario({ + topic: "api:artifact:test-id", + onJoin: [ + { type: "autoReply" }, + { type: "autoPush", event: "access_revoked" }, + ], + }); + + const channel = await ApiArtifactChannel.joinArtifact(rig.socket, "test-id", { as_agent: "test-value" }); + const payload = await nextPush((cb) => channel.onAccessRevoked(cb)); + expect(payload).toBeDefined(); + }); +}); + +describe("ApiArtifactChannel.leave", () => { + let rig: Rig; + beforeEach(async () => { + rig = await bootHarness(); + }); + afterEach(() => { + rig.client.closeAllSockets(); + }); + + it("leaves cleanly through the generated leave()", async () => { + await rig.client.registerScenario({ + topic: "api:artifact:test-id", + onJoin: [{ type: "autoReply" }], + }); + const channel = await ApiArtifactChannel.joinArtifact(rig.socket, "test-id", { as_agent: "test-value" }); + await channel.leave(); + }); +}); + diff --git a/packages/sdk/__tests__/contract/channels/api_chat_channel.contract.test.ts b/packages/sdk/__tests__/contract/channels/api_chat_channel.contract.test.ts index 7fbd506..522ca42 100644 --- a/packages/sdk/__tests__/contract/channels/api_chat_channel.contract.test.ts +++ b/packages/sdk/__tests__/contract/channels/api_chat_channel.contract.test.ts @@ -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: b10684f9f76a +// Content hash: 6195fa42cc50 // Contract tests for the generated channel class. Drives the channel // through a real WebSocket against the harness-service subprocess — @@ -404,7 +404,7 @@ describe("ApiChatChannel.apiChatPostMessage (api:chat:post_message)", () => { }); const channel = await ApiChatChannel.joinTeamThread(rig.socket, "test-id", "test-id", { after_cursor: "test-value", before_cursor: "test-value", include_metadata: true, limit: 1 }); - const reply = await channel.apiChatPostMessage({ content: "test content", context: [{ type: "test" }], idempotency_key: "test-key", reply_to: "test-value", uploads: [{}] }); + const reply = await channel.apiChatPostMessage({ content: "test content", context: [{ type: "test" }], idempotency_key: "test-key", mentions: ["test-value"], metadata: {}, reply_to: "test-value", uploads: [{}] }); expect(reply).toBeDefined(); const observed = await rig.client.observations("api:chat:team:test-id:thread:test-id", "api:chat:post_message"); @@ -442,7 +442,7 @@ describe("ApiChatChannel.apiChatPostSimpleMessage (api:chat:post_simple_message) }); const channel = await ApiChatChannel.joinTeamThread(rig.socket, "test-id", "test-id", { after_cursor: "test-value", before_cursor: "test-value", include_metadata: true, limit: 1 }); - const reply = await channel.apiChatPostSimpleMessage({ content: "test content", context: [{ type: "test" }], idempotency_key: "test-key", reply_to: "test-value" }); + const reply = await channel.apiChatPostSimpleMessage({ content: "test content", context: [{ type: "test" }], idempotency_key: "test-key", mentions: ["test-value"], metadata: {}, reply_to: "test-value" }); expect(reply).toBeDefined(); const observed = await rig.client.observations("api:chat:team:test-id:thread:test-id", "api:chat:post_simple_message"); diff --git a/packages/sdk/__tests__/contract/streams/agent_sessions.contract.test.ts b/packages/sdk/__tests__/contract/streams/agent_sessions.contract.test.ts index ee3fd4d..7291b83 100644 --- a/packages/sdk/__tests__/contract/streams/agent_sessions.contract.test.ts +++ b/packages/sdk/__tests__/contract/streams/agent_sessions.contract.test.ts @@ -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: 79936f5130bb +// Content hash: 0acc4debbbfa import { describe, it, expect, beforeEach, afterEach } from "vitest"; @@ -35,12 +35,12 @@ afterEach(() => { describe("contract: agent_sessions (SSE)", () => { describe("v1.agent_sessions.stream (GET /api/v1/agent_sessions/{agent_session}/stream)", () => { it("yields the declared SSE events in order", async () => { - await harness.registerStreamScenario({ route: "GET /api/v1/agent_sessions/{agent_session}/stream", actions: [{ type: "autoEmit", event: "session_update" }] }); + await harness.registerStreamScenario({ route: "GET /api/v1/agent_sessions/{agent_session}/stream", actions: [{ type: "autoEmit", event: "session_event" }, { type: "autoEmit", event: "session_update" }] }); const events: Array<{ event: string; data: unknown }> = []; for await (const ev of client.v1.agent_sessions.stream("test-value")) { events.push(ev); } - expect(events.map((e) => e.event)).toEqual(["session_update"]); + expect(events.map((e) => e.event)).toEqual(["session_event","session_update"]); }); it("rejects with ApiError on a non-2xx status", async () => { diff --git a/packages/sdk/__tests__/contract/v1/agent_computers.contract.test.ts b/packages/sdk/__tests__/contract/v1/agent_computers.contract.test.ts index a9946b6..2d3446d 100644 --- a/packages/sdk/__tests__/contract/v1/agent_computers.contract.test.ts +++ b/packages/sdk/__tests__/contract/v1/agent_computers.contract.test.ts @@ -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: ff9e0a1e2748 +// Content hash: da7f574165da import { describe, it, expect } from "vitest"; @@ -101,6 +101,55 @@ describe("contract: agent_computers", () => { } }); + it("PATCH /api/v1/agent_computers/{computer} returns successfully", async () => { + const result = await client.v1.agent_computers.update("test-value", {}); + expect(result).toBeUndefined(); + }); + + it("PATCH /api/v1/agent_computers/{computer} returns 401", async () => { + const ec = errorClient(401); + try { + await ec.v1.agent_computers.update("test-value", {}); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(401); + } + }); + + it("PATCH /api/v1/agent_computers/{computer} returns 403", async () => { + const ec = errorClient(403); + try { + await ec.v1.agent_computers.update("test-value", {}); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(403); + } + }); + + it("PATCH /api/v1/agent_computers/{computer} returns 404", async () => { + const ec = errorClient(404); + try { + await ec.v1.agent_computers.update("test-value", {}); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(404); + } + }); + + it("PATCH /api/v1/agent_computers/{computer} returns 422", async () => { + const ec = errorClient(422); + try { + await ec.v1.agent_computers.update("test-value", {}); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(422); + } + }); + it("POST /api/v1/agent_computers/{computer}/exec returns successfully", async () => { const result = await client.v1.agent_computers.exec("test-value", { command: "test-value" }); expect(result).toBeDefined(); diff --git a/packages/sdk/__tests__/contract/v1/agent_requests.contract.test.ts b/packages/sdk/__tests__/contract/v1/agent_requests.contract.test.ts new file mode 100644 index 0000000..e8ec23f --- /dev/null +++ b/packages/sdk/__tests__/contract/v1/agent_requests.contract.test.ts @@ -0,0 +1,237 @@ +// Copyright (c) 2026 ArchAstro Inc. Licensed under the MIT License. +// This file is auto-generated by @archastro/sdk-generator. Do not edit. +// Content hash: cc309736c038 + + +import { describe, it, expect } from "vitest"; +import { PlatformClient } from "../../../src/index.js"; +import { ApiError } from "../../../src/runtime/http-client.js"; + +const PRISM_URL = process.env.PRISM_URL ?? "http://127.0.0.1:4040"; + +const client = new PlatformClient({ + baseUrl: PRISM_URL, + defaultHeaders: { "x-archastro-api-key": "pk_test-key" }, + accessToken: "test-token", +}); + +function errorClient(code: number): PlatformClient { + return new PlatformClient({ + baseUrl: PRISM_URL, + defaultHeaders: { "x-archastro-api-key": "pk_test-key", "Prefer": `code=${code}` }, + accessToken: "test-token", + }); +} + +describe("contract: agent_requests", () => { + describe("agent_requests", () => { + it("GET /api/v1/agent_requests returns successfully", async () => { + const result = await client.v1.agent_requests.list(); + expect(result).toBeDefined(); + }); + + it("GET /api/v1/agent_requests returns 401", async () => { + const ec = errorClient(401); + try { + await ec.v1.agent_requests.list(); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(401); + } + }); + + it("GET /api/v1/agent_requests returns 422", async () => { + const ec = errorClient(422); + try { + await ec.v1.agent_requests.list(); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(422); + } + }); + + it("GET /api/v1/agent_requests/{agent_request} returns successfully", async () => { + const result = await client.v1.agent_requests.get("test-value"); + expect(result).toBeDefined(); + }); + + it("GET /api/v1/agent_requests/{agent_request} returns 401", async () => { + const ec = errorClient(401); + try { + await ec.v1.agent_requests.get("test-value"); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(401); + } + }); + + it("GET /api/v1/agent_requests/{agent_request} returns 403", async () => { + const ec = errorClient(403); + try { + await ec.v1.agent_requests.get("test-value"); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(403); + } + }); + + it("GET /api/v1/agent_requests/{agent_request} returns 404", async () => { + const ec = errorClient(404); + try { + await ec.v1.agent_requests.get("test-value"); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(404); + } + }); + + it("GET /api/v1/agent_requests/{agent_request} returns 409", async () => { + const ec = errorClient(409); + try { + await ec.v1.agent_requests.get("test-value"); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(409); + } + }); + + it("GET /api/v1/agent_requests/{agent_request} returns 422", async () => { + const ec = errorClient(422); + try { + await ec.v1.agent_requests.get("test-value"); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(422); + } + }); + + it("POST /api/v1/agent_requests/{agent_request}/reject returns successfully", async () => { + const result = await client.v1.agent_requests.reject("test-value", { reason: "test-value" }); + expect(result).toBeDefined(); + }); + + it("POST /api/v1/agent_requests/{agent_request}/reject returns 401", async () => { + const ec = errorClient(401); + try { + await ec.v1.agent_requests.reject("test-value", { reason: "test-value" }); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(401); + } + }); + + it("POST /api/v1/agent_requests/{agent_request}/reject returns 403", async () => { + const ec = errorClient(403); + try { + await ec.v1.agent_requests.reject("test-value", { reason: "test-value" }); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(403); + } + }); + + it("POST /api/v1/agent_requests/{agent_request}/reject returns 404", async () => { + const ec = errorClient(404); + try { + await ec.v1.agent_requests.reject("test-value", { reason: "test-value" }); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(404); + } + }); + + it("POST /api/v1/agent_requests/{agent_request}/reject returns 409", async () => { + const ec = errorClient(409); + try { + await ec.v1.agent_requests.reject("test-value", { reason: "test-value" }); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(409); + } + }); + + it("POST /api/v1/agent_requests/{agent_request}/reject returns 422", async () => { + const ec = errorClient(422); + try { + await ec.v1.agent_requests.reject("test-value", { reason: "test-value" }); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(422); + } + }); + + it("POST /api/v1/agent_requests/{agent_request}/resolve returns successfully", async () => { + const result = await client.v1.agent_requests.resolve("test-value", { input: {} }); + expect(result).toBeDefined(); + }); + + it("POST /api/v1/agent_requests/{agent_request}/resolve returns 401", async () => { + const ec = errorClient(401); + try { + await ec.v1.agent_requests.resolve("test-value", { input: {} }); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(401); + } + }); + + it("POST /api/v1/agent_requests/{agent_request}/resolve returns 403", async () => { + const ec = errorClient(403); + try { + await ec.v1.agent_requests.resolve("test-value", { input: {} }); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(403); + } + }); + + it("POST /api/v1/agent_requests/{agent_request}/resolve returns 404", async () => { + const ec = errorClient(404); + try { + await ec.v1.agent_requests.resolve("test-value", { input: {} }); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(404); + } + }); + + it("POST /api/v1/agent_requests/{agent_request}/resolve returns 409", async () => { + const ec = errorClient(409); + try { + await ec.v1.agent_requests.resolve("test-value", { input: {} }); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(409); + } + }); + + it("POST /api/v1/agent_requests/{agent_request}/resolve returns 422", async () => { + const ec = errorClient(422); + try { + await ec.v1.agent_requests.resolve("test-value", { input: {} }); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(422); + } + }); + + }); + +}); diff --git a/packages/sdk/__tests__/contract/v1/agent_sessions.contract.test.ts b/packages/sdk/__tests__/contract/v1/agent_sessions.contract.test.ts index 9d058f3..2b75901 100644 --- a/packages/sdk/__tests__/contract/v1/agent_sessions.contract.test.ts +++ b/packages/sdk/__tests__/contract/v1/agent_sessions.contract.test.ts @@ -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: b370fe123883 +// Content hash: 89bef7a0f2f9 import { describe, it, expect } from "vitest"; @@ -275,6 +275,44 @@ describe("contract: agent_sessions", () => { } }); + it("GET /api/v1/agent_sessions/{agent_session}/events returns successfully", async () => { + const result = await client.v1.agent_sessions.events("test-value"); + expect(result).toBeDefined(); + }); + + it("GET /api/v1/agent_sessions/{agent_session}/events returns 401", async () => { + const ec = errorClient(401); + try { + await ec.v1.agent_sessions.events("test-value"); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(401); + } + }); + + it("GET /api/v1/agent_sessions/{agent_session}/events returns 403", async () => { + const ec = errorClient(403); + try { + await ec.v1.agent_sessions.events("test-value"); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(403); + } + }); + + it("GET /api/v1/agent_sessions/{agent_session}/events returns 404", async () => { + const ec = errorClient(404); + try { + await ec.v1.agent_sessions.events("test-value"); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(404); + } + }); + it("POST /api/v1/agent_sessions/{agent_session}/message returns successfully", async () => { const result = await client.v1.agent_sessions.message("test-value", { content: "test content" }); expect(result).toBeDefined(); diff --git a/packages/sdk/__tests__/contract/v1/agents.contract.test.ts b/packages/sdk/__tests__/contract/v1/agents.contract.test.ts index 825499b..15ee673 100644 --- a/packages/sdk/__tests__/contract/v1/agents.contract.test.ts +++ b/packages/sdk/__tests__/contract/v1/agents.contract.test.ts @@ -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: 47cd9ba7e06f +// Content hash: 0944bc53a3eb import { describe, it, expect } from "vitest"; @@ -451,6 +451,66 @@ describe("contract: agents", () => { } }); + it("GET /api/v1/agents/{agent}/self_solution returns successfully", async () => { + const result = await client.v1.agents.selfSolution("test-value"); + expect(result).toBeDefined(); + }); + + it("GET /api/v1/agents/{agent}/self_solution returns 401", async () => { + const ec = errorClient(401); + try { + await ec.v1.agents.selfSolution("test-value"); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(401); + } + }); + + it("GET /api/v1/agents/{agent}/self_solution returns 404", async () => { + const ec = errorClient(404); + try { + await ec.v1.agents.selfSolution("test-value"); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(404); + } + }); + + it("GET /api/v1/agents/{agent}/self_solution returns 409", async () => { + const ec = errorClient(409); + try { + await ec.v1.agents.selfSolution("test-value"); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(409); + } + }); + + it("GET /api/v1/agents/{agent}/self_solution returns 422", async () => { + const ec = errorClient(422); + try { + await ec.v1.agents.selfSolution("test-value"); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(422); + } + }); + + it("GET /api/v1/agents/{agent}/self_solution returns 500", async () => { + const ec = errorClient(500); + try { + await ec.v1.agents.selfSolution("test-value"); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(500); + } + }); + it("POST /api/v1/agents/{agent}/threads returns successfully", async () => { const result = await client.v1.agents.threads("test-value", { thread: {} }); expect(result).toBeDefined(); diff --git a/packages/sdk/__tests__/contract/v1/ai.contract.test.ts b/packages/sdk/__tests__/contract/v1/ai.contract.test.ts index 0676778..5bce4cb 100644 --- a/packages/sdk/__tests__/contract/v1/ai.contract.test.ts +++ b/packages/sdk/__tests__/contract/v1/ai.contract.test.ts @@ -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: 647ae8bf1383 +// Content hash: 08dbae4f8116 import { describe, it, expect } from "vitest"; @@ -63,6 +63,35 @@ describe("contract: ai", () => { } }); + it("GET /api/v1/ai/usage returns successfully", async () => { + const result = await client.v1.ai.usage(); + expect(result).toBeDefined(); + expect(result).toHaveProperty("data"); + expect(Array.isArray((result as any).data)).toBe(true); + }); + + it("GET /api/v1/ai/usage returns 401", async () => { + const ec = errorClient(401); + try { + await ec.v1.ai.usage(); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(401); + } + }); + + it("GET /api/v1/ai/usage returns 422", async () => { + const ec = errorClient(422); + try { + await ec.v1.ai.usage(); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(422); + } + }); + }); describe("ai > chat", () => { diff --git a/packages/sdk/__tests__/contract/v1/custom_objects.contract.test.ts b/packages/sdk/__tests__/contract/v1/custom_objects.contract.test.ts index af6c1e1..d6f895a 100644 --- a/packages/sdk/__tests__/contract/v1/custom_objects.contract.test.ts +++ b/packages/sdk/__tests__/contract/v1/custom_objects.contract.test.ts @@ -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: 37b54ea95f3a +// Content hash: 9cb301fe414e import { describe, it, expect } from "vitest"; @@ -123,6 +123,66 @@ describe("contract: custom_objects", () => { } }); + it("POST /api/v1/custom_objects/patch returns successfully", async () => { + const result = await client.v1.custom_objects.patch({ ops: [{}] }); + expect(result).toBeDefined(); + }); + + it("POST /api/v1/custom_objects/patch returns 401", async () => { + const ec = errorClient(401); + try { + await ec.v1.custom_objects.patch({ ops: [{}] }); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(401); + } + }); + + it("POST /api/v1/custom_objects/patch returns 403", async () => { + const ec = errorClient(403); + try { + await ec.v1.custom_objects.patch({ ops: [{}] }); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(403); + } + }); + + it("POST /api/v1/custom_objects/patch returns 404", async () => { + const ec = errorClient(404); + try { + await ec.v1.custom_objects.patch({ ops: [{}] }); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(404); + } + }); + + it("POST /api/v1/custom_objects/patch returns 409", async () => { + const ec = errorClient(409); + try { + await ec.v1.custom_objects.patch({ ops: [{}] }); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(409); + } + }); + + it("POST /api/v1/custom_objects/patch returns 422", async () => { + const ec = errorClient(422); + try { + await ec.v1.custom_objects.patch({ ops: [{}] }); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(422); + } + }); + it("DELETE /api/v1/custom_objects/{object} returns successfully", async () => { const result = await client.v1.custom_objects.delete("test-value"); expect(result).toBeDefined(); diff --git a/packages/sdk/__tests__/contract/v1/files.contract.test.ts b/packages/sdk/__tests__/contract/v1/files.contract.test.ts index 2ec9e93..6f15bab 100644 --- a/packages/sdk/__tests__/contract/v1/files.contract.test.ts +++ b/packages/sdk/__tests__/contract/v1/files.contract.test.ts @@ -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: 370735636b8a +// Content hash: e971f1657199 import { describe, it, expect } from "vitest"; @@ -129,6 +129,67 @@ describe("contract: files", () => { } }); + it("GET /api/v1/files/{file}/download returns successfully", async () => { + const result = await client.v1.files.download("test-value"); + expect(result.content).toBeDefined(); + expect(result.mimeType).toBeTruthy(); + }); + + it("GET /api/v1/files/{file}/download returns 401", async () => { + const ec = errorClient(401); + try { + await ec.v1.files.download("test-value"); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(401); + } + }); + + it("GET /api/v1/files/{file}/download returns 403", async () => { + const ec = errorClient(403); + try { + await ec.v1.files.download("test-value"); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(403); + } + }); + + it("GET /api/v1/files/{file}/download returns 404", async () => { + const ec = errorClient(404); + try { + await ec.v1.files.download("test-value"); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(404); + } + }); + + it("GET /api/v1/files/{file}/download returns 413", async () => { + const ec = errorClient(413); + try { + await ec.v1.files.download("test-value"); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(413); + } + }); + + it("GET /api/v1/files/{file}/download returns 502", async () => { + const ec = errorClient(502); + try { + await ec.v1.files.download("test-value"); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(502); + } + }); + it("GET /api/v1/files/{file}/org_logo returns successfully", async () => { const result = await client.v1.files.orgLogo("test-value", { token: "test-token" }); expect(result.content).toBeDefined(); diff --git a/packages/sdk/__tests__/contract/v1/kv.contract.test.ts b/packages/sdk/__tests__/contract/v1/kv.contract.test.ts index ef662a1..444ef5d 100644 --- a/packages/sdk/__tests__/contract/v1/kv.contract.test.ts +++ b/packages/sdk/__tests__/contract/v1/kv.contract.test.ts @@ -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: e4be8a93a853 +// Content hash: a92272fa7611 import { describe, it, expect } from "vitest"; @@ -63,6 +63,17 @@ describe("contract: kv", () => { } }); + it("GET /api/v1/kv returns 422", async () => { + const ec = errorClient(422); + try { + await ec.v1.kv.list(); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(422); + } + }); + it("POST /api/v1/kv returns successfully", async () => { const result = await client.v1.kv.create({ key: "test-key", value: "test-value" }); expect(result).toBeDefined(); @@ -112,6 +123,17 @@ describe("contract: kv", () => { } }); + it("POST /api/v1/kv returns 409", async () => { + const ec = errorClient(409); + try { + await ec.v1.kv.create({ key: "test-key", value: "test-value" }); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(409); + } + }); + it("POST /api/v1/kv returns 422", async () => { const ec = errorClient(422); try { @@ -125,7 +147,7 @@ describe("contract: kv", () => { it("DELETE /api/v1/kv/{key} returns successfully", async () => { const result = await client.v1.kv.delete("test-key"); - expect(result).toBeUndefined(); + expect(result).toBeDefined(); }); it("DELETE /api/v1/kv/{key} returns 400", async () => { diff --git a/packages/sdk/__tests__/contract/v1/orgs.contract.test.ts b/packages/sdk/__tests__/contract/v1/orgs.contract.test.ts index 1563b82..e2cd35e 100644 --- a/packages/sdk/__tests__/contract/v1/orgs.contract.test.ts +++ b/packages/sdk/__tests__/contract/v1/orgs.contract.test.ts @@ -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: 19ebcf0ff5db +// Content hash: 22dcb76d6014 import { describe, it, expect } from "vitest"; @@ -145,6 +145,334 @@ describe("contract: orgs", () => { } }); + it("GET /api/v1/orgs/{org}/task_epics returns successfully", async () => { + const result = await client.v1.orgs.taskEpics("test-value"); + expect(result).toBeDefined(); + expect(result).toHaveProperty("data"); + expect(Array.isArray((result as any).data)).toBe(true); + }); + + it("GET /api/v1/orgs/{org}/task_epics returns 401", async () => { + const ec = errorClient(401); + try { + await ec.v1.orgs.taskEpics("test-value"); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(401); + } + }); + + it("GET /api/v1/orgs/{org}/task_epics returns 404", async () => { + const ec = errorClient(404); + try { + await ec.v1.orgs.taskEpics("test-value"); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(404); + } + }); + + it("GET /api/v1/orgs/{org}/task_epics returns 422", async () => { + const ec = errorClient(422); + try { + await ec.v1.orgs.taskEpics("test-value"); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(422); + } + }); + + }); + + describe("orgs > tasks", () => { + it("GET /api/v1/orgs/{org}/tasks returns successfully", async () => { + const result = await client.v1.orgs.tasks.list("test-value"); + expect(result).toBeDefined(); + expect(result).toHaveProperty("data"); + expect(Array.isArray((result as any).data)).toBe(true); + }); + + it("GET /api/v1/orgs/{org}/tasks returns 401", async () => { + const ec = errorClient(401); + try { + await ec.v1.orgs.tasks.list("test-value"); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(401); + } + }); + + it("GET /api/v1/orgs/{org}/tasks returns 404", async () => { + const ec = errorClient(404); + try { + await ec.v1.orgs.tasks.list("test-value"); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(404); + } + }); + + it("GET /api/v1/orgs/{org}/tasks returns 422", async () => { + const ec = errorClient(422); + try { + await ec.v1.orgs.tasks.list("test-value"); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(422); + } + }); + + it("POST /api/v1/orgs/{org}/tasks returns successfully", async () => { + const result = await client.v1.orgs.tasks.create("test-value", { task: { name: "test-name" } }); + expect(result).toBeDefined(); + }); + + it("POST /api/v1/orgs/{org}/tasks returns 401", async () => { + const ec = errorClient(401); + try { + await ec.v1.orgs.tasks.create("test-value", { task: { name: "test-name" } }); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(401); + } + }); + + it("POST /api/v1/orgs/{org}/tasks returns 404", async () => { + const ec = errorClient(404); + try { + await ec.v1.orgs.tasks.create("test-value", { task: { name: "test-name" } }); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(404); + } + }); + + it("POST /api/v1/orgs/{org}/tasks returns 409", async () => { + const ec = errorClient(409); + try { + await ec.v1.orgs.tasks.create("test-value", { task: { name: "test-name" } }); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(409); + } + }); + + it("POST /api/v1/orgs/{org}/tasks returns 422", async () => { + const ec = errorClient(422); + try { + await ec.v1.orgs.tasks.create("test-value", { task: { name: "test-name" } }); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(422); + } + }); + + it("GET /api/v1/orgs/{org}/tasks/blocker_cycles returns successfully", async () => { + const result = await client.v1.orgs.tasks.blockerCycles("test-value"); + expect(result).toBeDefined(); + expect(result).toHaveProperty("data"); + expect(Array.isArray((result as any).data)).toBe(true); + }); + + it("GET /api/v1/orgs/{org}/tasks/blocker_cycles returns 401", async () => { + const ec = errorClient(401); + try { + await ec.v1.orgs.tasks.blockerCycles("test-value"); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(401); + } + }); + + it("GET /api/v1/orgs/{org}/tasks/blocker_cycles returns 404", async () => { + const ec = errorClient(404); + try { + await ec.v1.orgs.tasks.blockerCycles("test-value"); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(404); + } + }); + + it("GET /api/v1/orgs/{org}/tasks/blocker_cycles returns 422", async () => { + const ec = errorClient(422); + try { + await ec.v1.orgs.tasks.blockerCycles("test-value"); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(422); + } + }); + + it("PUT /api/v1/orgs/{org}/tasks/by-source returns successfully", async () => { + const result = await client.v1.orgs.tasks.bySource("test-value", { name: "test-name", source_id: "test-id", source_scope: "test-value", source_type: "test-value" }); + expect(result).toBeDefined(); + }); + + it("PUT /api/v1/orgs/{org}/tasks/by-source returns 401", async () => { + const ec = errorClient(401); + try { + await ec.v1.orgs.tasks.bySource("test-value", { name: "test-name", source_id: "test-id", source_scope: "test-value", source_type: "test-value" }); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(401); + } + }); + + it("PUT /api/v1/orgs/{org}/tasks/by-source returns 404", async () => { + const ec = errorClient(404); + try { + await ec.v1.orgs.tasks.bySource("test-value", { name: "test-name", source_id: "test-id", source_scope: "test-value", source_type: "test-value" }); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(404); + } + }); + + it("PUT /api/v1/orgs/{org}/tasks/by-source returns 422", async () => { + const ec = errorClient(422); + try { + await ec.v1.orgs.tasks.bySource("test-value", { name: "test-name", source_id: "test-id", source_scope: "test-value", source_type: "test-value" }); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(422); + } + }); + + it("GET /api/v1/orgs/{org}/tasks/metrics returns successfully", async () => { + const result = await client.v1.orgs.tasks.metrics("test-value"); + expect(result).toBeDefined(); + }); + + it("GET /api/v1/orgs/{org}/tasks/metrics returns 401", async () => { + const ec = errorClient(401); + try { + await ec.v1.orgs.tasks.metrics("test-value"); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(401); + } + }); + + it("GET /api/v1/orgs/{org}/tasks/metrics returns 404", async () => { + const ec = errorClient(404); + try { + await ec.v1.orgs.tasks.metrics("test-value"); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(404); + } + }); + + it("GET /api/v1/orgs/{org}/tasks/metrics returns 422", async () => { + const ec = errorClient(422); + try { + await ec.v1.orgs.tasks.metrics("test-value"); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(422); + } + }); + + it("GET /api/v1/orgs/{org}/tasks/ready returns successfully", async () => { + const result = await client.v1.orgs.tasks.ready("test-value"); + expect(result).toBeDefined(); + expect(result).toHaveProperty("data"); + expect(Array.isArray((result as any).data)).toBe(true); + }); + + it("GET /api/v1/orgs/{org}/tasks/ready returns 401", async () => { + const ec = errorClient(401); + try { + await ec.v1.orgs.tasks.ready("test-value"); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(401); + } + }); + + it("GET /api/v1/orgs/{org}/tasks/ready returns 404", async () => { + const ec = errorClient(404); + try { + await ec.v1.orgs.tasks.ready("test-value"); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(404); + } + }); + + it("GET /api/v1/orgs/{org}/tasks/ready returns 422", async () => { + const ec = errorClient(422); + try { + await ec.v1.orgs.tasks.ready("test-value"); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(422); + } + }); + + it("GET /api/v1/orgs/{org}/tasks/search returns successfully", async () => { + const result = await client.v1.orgs.tasks.search("test-value"); + expect(result).toBeDefined(); + expect(result).toHaveProperty("data"); + expect(Array.isArray((result as any).data)).toBe(true); + }); + + it("GET /api/v1/orgs/{org}/tasks/search returns 401", async () => { + const ec = errorClient(401); + try { + await ec.v1.orgs.tasks.search("test-value"); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(401); + } + }); + + it("GET /api/v1/orgs/{org}/tasks/search returns 404", async () => { + const ec = errorClient(404); + try { + await ec.v1.orgs.tasks.search("test-value"); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(404); + } + }); + + it("GET /api/v1/orgs/{org}/tasks/search returns 422", async () => { + const ec = errorClient(422); + try { + await ec.v1.orgs.tasks.search("test-value"); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(422); + } + }); + }); describe("orgs > threads", () => { diff --git a/packages/sdk/__tests__/contract/v1/private_service_enrollments.contract.test.ts b/packages/sdk/__tests__/contract/v1/private_service_enrollments.contract.test.ts index 9ec65a1..0c0f229 100644 --- a/packages/sdk/__tests__/contract/v1/private_service_enrollments.contract.test.ts +++ b/packages/sdk/__tests__/contract/v1/private_service_enrollments.contract.test.ts @@ -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: 8f1408e6f82d +// Content hash: 6cc1831c7b69 import { describe, it, expect } from "vitest"; @@ -134,6 +134,55 @@ describe("contract: private_service_enrollments", () => { } }); + it("DELETE /api/v1/private_service_enrollments/{private_service_enrollment_id} returns successfully", async () => { + const result = await client.v1.private_service_enrollments.delete("test-id"); + expect(result).toBeUndefined(); + }); + + it("DELETE /api/v1/private_service_enrollments/{private_service_enrollment_id} returns 400", async () => { + const ec = errorClient(400); + try { + await ec.v1.private_service_enrollments.delete("test-id"); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(400); + } + }); + + it("DELETE /api/v1/private_service_enrollments/{private_service_enrollment_id} returns 403", async () => { + const ec = errorClient(403); + try { + await ec.v1.private_service_enrollments.delete("test-id"); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(403); + } + }); + + it("DELETE /api/v1/private_service_enrollments/{private_service_enrollment_id} returns 404", async () => { + const ec = errorClient(404); + try { + await ec.v1.private_service_enrollments.delete("test-id"); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(404); + } + }); + + it("DELETE /api/v1/private_service_enrollments/{private_service_enrollment_id} returns 503", async () => { + const ec = errorClient(503); + try { + await ec.v1.private_service_enrollments.delete("test-id"); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(503); + } + }); + it("GET /api/v1/private_service_enrollments/{private_service_enrollment_id} returns successfully", async () => { const result = await client.v1.private_service_enrollments.get("test-id"); expect(result).toBeDefined(); diff --git a/packages/sdk/__tests__/contract/v1/relays.contract.test.ts b/packages/sdk/__tests__/contract/v1/relays.contract.test.ts new file mode 100644 index 0000000..7b85830 --- /dev/null +++ b/packages/sdk/__tests__/contract/v1/relays.contract.test.ts @@ -0,0 +1,182 @@ +// Copyright (c) 2026 ArchAstro Inc. Licensed under the MIT License. +// This file is auto-generated by @archastro/sdk-generator. Do not edit. +// Content hash: 8cea54cbbe1d + + +import { describe, it, expect } from "vitest"; +import { PlatformClient } from "../../../src/index.js"; +import { ApiError } from "../../../src/runtime/http-client.js"; + +const PRISM_URL = process.env.PRISM_URL ?? "http://127.0.0.1:4040"; + +const client = new PlatformClient({ + baseUrl: PRISM_URL, + defaultHeaders: { "x-archastro-api-key": "pk_test-key" }, + accessToken: "test-token", +}); + +function errorClient(code: number): PlatformClient { + return new PlatformClient({ + baseUrl: PRISM_URL, + defaultHeaders: { "x-archastro-api-key": "pk_test-key", "Prefer": `code=${code}` }, + accessToken: "test-token", + }); +} + +describe("contract: relays", () => { + describe("relays", () => { + it("POST /api/v1/relays returns successfully", async () => { + const result = await client.v1.relays.create({ purpose: "test-value", ttl_seconds: 1 }); + expect(result).toBeDefined(); + }); + + it("POST /api/v1/relays returns 403", async () => { + const ec = errorClient(403); + try { + await ec.v1.relays.create({ purpose: "test-value", ttl_seconds: 1 }); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(403); + } + }); + + it("POST /api/v1/relays returns 404", async () => { + const ec = errorClient(404); + try { + await ec.v1.relays.create({ purpose: "test-value", ttl_seconds: 1 }); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(404); + } + }); + + it("POST /api/v1/relays returns 422", async () => { + const ec = errorClient(422); + try { + await ec.v1.relays.create({ purpose: "test-value", ttl_seconds: 1 }); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(422); + } + }); + + it("DELETE /api/v1/relays/{relay} returns successfully", async () => { + const result = await client.v1.relays.delete("test-value"); + expect(result).toBeDefined(); + }); + + it("DELETE /api/v1/relays/{relay} returns 403", async () => { + const ec = errorClient(403); + try { + await ec.v1.relays.delete("test-value"); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(403); + } + }); + + it("DELETE /api/v1/relays/{relay} returns 404", async () => { + const ec = errorClient(404); + try { + await ec.v1.relays.delete("test-value"); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(404); + } + }); + + it("DELETE /api/v1/relays/{relay} returns 422", async () => { + const ec = errorClient(422); + try { + await ec.v1.relays.delete("test-value"); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(422); + } + }); + + it("GET /api/v1/relays/{relay} returns successfully", async () => { + const result = await client.v1.relays.get("test-value"); + expect(result).toBeDefined(); + }); + + it("GET /api/v1/relays/{relay} returns 403", async () => { + const ec = errorClient(403); + try { + await ec.v1.relays.get("test-value"); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(403); + } + }); + + it("GET /api/v1/relays/{relay} returns 404", async () => { + const ec = errorClient(404); + try { + await ec.v1.relays.get("test-value"); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(404); + } + }); + + it("GET /api/v1/relays/{relay} returns 422", async () => { + const ec = errorClient(422); + try { + await ec.v1.relays.get("test-value"); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(422); + } + }); + + it("POST /api/v1/relays/{relay}/extend returns successfully", async () => { + const result = await client.v1.relays.extend("test-value", { ttl_seconds: 1 }); + expect(result).toBeDefined(); + }); + + it("POST /api/v1/relays/{relay}/extend returns 403", async () => { + const ec = errorClient(403); + try { + await ec.v1.relays.extend("test-value", { ttl_seconds: 1 }); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(403); + } + }); + + it("POST /api/v1/relays/{relay}/extend returns 404", async () => { + const ec = errorClient(404); + try { + await ec.v1.relays.extend("test-value", { ttl_seconds: 1 }); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(404); + } + }); + + it("POST /api/v1/relays/{relay}/extend returns 422", async () => { + const ec = errorClient(422); + try { + await ec.v1.relays.extend("test-value", { ttl_seconds: 1 }); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(422); + } + }); + + }); + +}); diff --git a/packages/sdk/__tests__/contract/v1/task_ownership_conversions.contract.test.ts b/packages/sdk/__tests__/contract/v1/task_ownership_conversions.contract.test.ts new file mode 100644 index 0000000..78704b7 --- /dev/null +++ b/packages/sdk/__tests__/contract/v1/task_ownership_conversions.contract.test.ts @@ -0,0 +1,79 @@ +// Copyright (c) 2026 ArchAstro Inc. Licensed under the MIT License. +// This file is auto-generated by @archastro/sdk-generator. Do not edit. +// Content hash: dc3d920163be + + +import { describe, it, expect } from "vitest"; +import { PlatformClient } from "../../../src/index.js"; +import { ApiError } from "../../../src/runtime/http-client.js"; + +const PRISM_URL = process.env.PRISM_URL ?? "http://127.0.0.1:4040"; + +const client = new PlatformClient({ + baseUrl: PRISM_URL, + defaultHeaders: { "x-archastro-api-key": "pk_test-key" }, + accessToken: "test-token", +}); + +function errorClient(code: number): PlatformClient { + return new PlatformClient({ + baseUrl: PRISM_URL, + defaultHeaders: { "x-archastro-api-key": "pk_test-key", "Prefer": `code=${code}` }, + accessToken: "test-token", + }); +} + +describe("contract: task_ownership_conversions", () => { + describe("task_ownership_conversions", () => { + it("GET /api/v1/task_ownership_conversions/{job_id} returns successfully", async () => { + const result = await client.v1.task_ownership_conversions.get(1); + expect(result).toBeDefined(); + }); + + it("GET /api/v1/task_ownership_conversions/{job_id} returns 401", async () => { + const ec = errorClient(401); + try { + await ec.v1.task_ownership_conversions.get(1); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(401); + } + }); + + it("GET /api/v1/task_ownership_conversions/{job_id} returns 403", async () => { + const ec = errorClient(403); + try { + await ec.v1.task_ownership_conversions.get(1); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(403); + } + }); + + it("GET /api/v1/task_ownership_conversions/{job_id} returns 404", async () => { + const ec = errorClient(404); + try { + await ec.v1.task_ownership_conversions.get(1); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(404); + } + }); + + it("GET /api/v1/task_ownership_conversions/{job_id} returns 422", async () => { + const ec = errorClient(422); + try { + await ec.v1.task_ownership_conversions.get(1); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(422); + } + }); + + }); + +}); diff --git a/packages/sdk/__tests__/contract/v1/tasks.contract.test.ts b/packages/sdk/__tests__/contract/v1/tasks.contract.test.ts index 3db1d88..e1d168a 100644 --- a/packages/sdk/__tests__/contract/v1/tasks.contract.test.ts +++ b/packages/sdk/__tests__/contract/v1/tasks.contract.test.ts @@ -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: cabe98ee4648 +// Content hash: 0e46aa47840e import { describe, it, expect } from "vitest"; @@ -252,6 +252,66 @@ describe("contract: tasks", () => { } }); + it("POST /api/v1/tasks/{task}/ownership_conversions returns successfully", async () => { + const result = await client.v1.tasks.ownershipConversions("test-value", {}); + expect(result).toBeDefined(); + }); + + it("POST /api/v1/tasks/{task}/ownership_conversions returns 401", async () => { + const ec = errorClient(401); + try { + await ec.v1.tasks.ownershipConversions("test-value", {}); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(401); + } + }); + + it("POST /api/v1/tasks/{task}/ownership_conversions returns 403", async () => { + const ec = errorClient(403); + try { + await ec.v1.tasks.ownershipConversions("test-value", {}); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(403); + } + }); + + it("POST /api/v1/tasks/{task}/ownership_conversions returns 404", async () => { + const ec = errorClient(404); + try { + await ec.v1.tasks.ownershipConversions("test-value", {}); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(404); + } + }); + + it("POST /api/v1/tasks/{task}/ownership_conversions returns 409", async () => { + const ec = errorClient(409); + try { + await ec.v1.tasks.ownershipConversions("test-value", {}); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(409); + } + }); + + it("POST /api/v1/tasks/{task}/ownership_conversions returns 422", async () => { + const ec = errorClient(422); + try { + await ec.v1.tasks.ownershipConversions("test-value", {}); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(422); + } + }); + it("GET /api/v1/tasks/{task}/subtasks returns successfully", async () => { const result = await client.v1.tasks.subtasks("test-value"); expect(result).toBeDefined(); @@ -292,6 +352,66 @@ describe("contract: tasks", () => { } }); + it("POST /api/v1/tasks/{task}/transfer_ownership returns successfully", async () => { + const result = await client.v1.tasks.transferOwnership("test-value", { expected_version: 1 }); + expect(result).toBeDefined(); + }); + + it("POST /api/v1/tasks/{task}/transfer_ownership returns 401", async () => { + const ec = errorClient(401); + try { + await ec.v1.tasks.transferOwnership("test-value", { expected_version: 1 }); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(401); + } + }); + + it("POST /api/v1/tasks/{task}/transfer_ownership returns 403", async () => { + const ec = errorClient(403); + try { + await ec.v1.tasks.transferOwnership("test-value", { expected_version: 1 }); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(403); + } + }); + + it("POST /api/v1/tasks/{task}/transfer_ownership returns 404", async () => { + const ec = errorClient(404); + try { + await ec.v1.tasks.transferOwnership("test-value", { expected_version: 1 }); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(404); + } + }); + + it("POST /api/v1/tasks/{task}/transfer_ownership returns 409", async () => { + const ec = errorClient(409); + try { + await ec.v1.tasks.transferOwnership("test-value", { expected_version: 1 }); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(409); + } + }); + + it("POST /api/v1/tasks/{task}/transfer_ownership returns 422", async () => { + const ec = errorClient(422); + try { + await ec.v1.tasks.transferOwnership("test-value", { expected_version: 1 }); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(422); + } + }); + }); describe("tasks > blockers", () => { diff --git a/packages/sdk/__tests__/contract/v1/teams.contract.test.ts b/packages/sdk/__tests__/contract/v1/teams.contract.test.ts index 1315336..4791475 100644 --- a/packages/sdk/__tests__/contract/v1/teams.contract.test.ts +++ b/packages/sdk/__tests__/contract/v1/teams.contract.test.ts @@ -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: eb2523dd8b20 +// Content hash: 9eb3f4fd0c2a import { describe, it, expect } from "vitest"; @@ -520,6 +520,46 @@ describe("contract: teams", () => { } }); + it("GET /api/v1/teams/{team}/task_epics returns successfully", async () => { + const result = await client.v1.teams.taskEpics("test-value"); + expect(result).toBeDefined(); + expect(result).toHaveProperty("data"); + expect(Array.isArray((result as any).data)).toBe(true); + }); + + it("GET /api/v1/teams/{team}/task_epics returns 401", async () => { + const ec = errorClient(401); + try { + await ec.v1.teams.taskEpics("test-value"); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(401); + } + }); + + it("GET /api/v1/teams/{team}/task_epics returns 404", async () => { + const ec = errorClient(404); + try { + await ec.v1.teams.taskEpics("test-value"); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(404); + } + }); + + it("GET /api/v1/teams/{team}/task_epics returns 422", async () => { + const ec = errorClient(422); + try { + await ec.v1.teams.taskEpics("test-value"); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(422); + } + }); + }); describe("teams > custom_objects", () => { @@ -991,6 +1031,44 @@ describe("contract: teams", () => { } }); + it("PUT /api/v1/teams/{team}/tasks/by-source returns successfully", async () => { + const result = await client.v1.teams.tasks.bySource("test-value", { name: "test-name", source_id: "test-id", source_scope: "test-value", source_type: "test-value" }); + expect(result).toBeDefined(); + }); + + it("PUT /api/v1/teams/{team}/tasks/by-source returns 401", async () => { + const ec = errorClient(401); + try { + await ec.v1.teams.tasks.bySource("test-value", { name: "test-name", source_id: "test-id", source_scope: "test-value", source_type: "test-value" }); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(401); + } + }); + + it("PUT /api/v1/teams/{team}/tasks/by-source returns 404", async () => { + const ec = errorClient(404); + try { + await ec.v1.teams.tasks.bySource("test-value", { name: "test-name", source_id: "test-id", source_scope: "test-value", source_type: "test-value" }); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(404); + } + }); + + it("PUT /api/v1/teams/{team}/tasks/by-source returns 422", async () => { + const ec = errorClient(422); + try { + await ec.v1.teams.tasks.bySource("test-value", { name: "test-name", source_id: "test-id", source_scope: "test-value", source_type: "test-value" }); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(422); + } + }); + it("GET /api/v1/teams/{team}/tasks/metrics returns successfully", async () => { const result = await client.v1.teams.tasks.metrics("test-value"); expect(result).toBeDefined(); diff --git a/packages/sdk/__tests__/contract/v1/threads.contract.test.ts b/packages/sdk/__tests__/contract/v1/threads.contract.test.ts index 7b23c07..bea3582 100644 --- a/packages/sdk/__tests__/contract/v1/threads.contract.test.ts +++ b/packages/sdk/__tests__/contract/v1/threads.contract.test.ts @@ -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: 28fab5fda600 +// Content hash: 66148d0e096d import { describe, it, expect } from "vitest"; @@ -552,6 +552,85 @@ describe("contract: threads", () => { }); + describe("threads > computers", () => { + it("GET /api/v1/threads/{thread}/computers returns successfully", async () => { + const result = await client.v1.threads.computers.list("test-value"); + expect(result).toBeDefined(); + }); + + it("GET /api/v1/threads/{thread}/computers returns 401", async () => { + const ec = errorClient(401); + try { + await ec.v1.threads.computers.list("test-value"); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(401); + } + }); + + it("GET /api/v1/threads/{thread}/computers returns 404", async () => { + const ec = errorClient(404); + try { + await ec.v1.threads.computers.list("test-value"); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(404); + } + }); + + it("POST /api/v1/threads/{thread}/computers returns successfully", async () => { + const result = await client.v1.threads.computers.create("test-value", { name: "test-name" }); + expect(result).toBeDefined(); + }); + + it("POST /api/v1/threads/{thread}/computers returns 401", async () => { + const ec = errorClient(401); + try { + await ec.v1.threads.computers.create("test-value", { name: "test-name" }); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(401); + } + }); + + it("POST /api/v1/threads/{thread}/computers returns 403", async () => { + const ec = errorClient(403); + try { + await ec.v1.threads.computers.create("test-value", { name: "test-name" }); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(403); + } + }); + + it("POST /api/v1/threads/{thread}/computers returns 404", async () => { + const ec = errorClient(404); + try { + await ec.v1.threads.computers.create("test-value", { name: "test-name" }); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(404); + } + }); + + it("POST /api/v1/threads/{thread}/computers returns 422", async () => { + const ec = errorClient(422); + try { + await ec.v1.threads.computers.create("test-value", { name: "test-name" }); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(422); + } + }); + + }); + describe("threads > members", () => { it("DELETE /api/v1/threads/{thread}/members returns successfully", async () => { const result = await client.v1.threads.members.remove("test-value"); diff --git a/packages/sdk/__tests__/contract/v1/users.contract.test.ts b/packages/sdk/__tests__/contract/v1/users.contract.test.ts index 4b741ee..4105f2b 100644 --- a/packages/sdk/__tests__/contract/v1/users.contract.test.ts +++ b/packages/sdk/__tests__/contract/v1/users.contract.test.ts @@ -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: dc1c7d144356 +// Content hash: 560f4b671b01 import { describe, it, expect } from "vitest"; @@ -235,6 +235,46 @@ describe("contract: users", () => { } }); + it("GET /api/v1/users/{user}/task_epics returns successfully", async () => { + const result = await client.v1.users.taskEpics("test-value"); + expect(result).toBeDefined(); + expect(result).toHaveProperty("data"); + expect(Array.isArray((result as any).data)).toBe(true); + }); + + it("GET /api/v1/users/{user}/task_epics returns 401", async () => { + const ec = errorClient(401); + try { + await ec.v1.users.taskEpics("test-value"); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(401); + } + }); + + it("GET /api/v1/users/{user}/task_epics returns 404", async () => { + const ec = errorClient(404); + try { + await ec.v1.users.taskEpics("test-value"); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(404); + } + }); + + it("GET /api/v1/users/{user}/task_epics returns 422", async () => { + const ec = errorClient(422); + try { + await ec.v1.users.taskEpics("test-value"); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(422); + } + }); + }); describe("users > integrations", () => { @@ -522,6 +562,44 @@ describe("contract: users", () => { } }); + it("PUT /api/v1/users/{user}/tasks/by-source returns successfully", async () => { + const result = await client.v1.users.tasks.bySource("test-value", { name: "test-name", source_id: "test-id", source_scope: "test-value", source_type: "test-value" }); + expect(result).toBeDefined(); + }); + + it("PUT /api/v1/users/{user}/tasks/by-source returns 401", async () => { + const ec = errorClient(401); + try { + await ec.v1.users.tasks.bySource("test-value", { name: "test-name", source_id: "test-id", source_scope: "test-value", source_type: "test-value" }); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(401); + } + }); + + it("PUT /api/v1/users/{user}/tasks/by-source returns 404", async () => { + const ec = errorClient(404); + try { + await ec.v1.users.tasks.bySource("test-value", { name: "test-name", source_id: "test-id", source_scope: "test-value", source_type: "test-value" }); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(404); + } + }); + + it("PUT /api/v1/users/{user}/tasks/by-source returns 422", async () => { + const ec = errorClient(422); + try { + await ec.v1.users.tasks.bySource("test-value", { name: "test-name", source_id: "test-id", source_scope: "test-value", source_type: "test-value" }); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(422); + } + }); + it("GET /api/v1/users/{user}/tasks/ready returns successfully", async () => { const result = await client.v1.users.tasks.ready("test-value"); expect(result).toBeDefined(); diff --git a/packages/sdk/__tests__/contract/v1/workflows.contract.test.ts b/packages/sdk/__tests__/contract/v1/workflows.contract.test.ts index 3a261d9..0b66968 100644 --- a/packages/sdk/__tests__/contract/v1/workflows.contract.test.ts +++ b/packages/sdk/__tests__/contract/v1/workflows.contract.test.ts @@ -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: eec8c1f7e09b +// Content hash: 564dad9482ff import { describe, it, expect } from "vitest"; @@ -74,6 +74,28 @@ describe("contract: workflows", () => { } }); + it("POST /api/v1/workflows/run returns 403", async () => { + const ec = errorClient(403); + try { + await ec.v1.workflows.run({}); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(403); + } + }); + + it("POST /api/v1/workflows/run returns 404", async () => { + const ec = errorClient(404); + try { + await ec.v1.workflows.run({}); + expect.fail("Expected ApiError to be thrown"); + } catch (e) { + expect(e).toBeInstanceOf(ApiError); + expect((e as ApiError).status).toBe(404); + } + }); + it("POST /api/v1/workflows/run returns 422", async () => { const ec = errorClient(422); try { diff --git a/packages/sdk/specs/platform-openapi.json b/packages/sdk/specs/platform-openapi.json index 454777a..1b72868 100644 --- a/packages/sdk/specs/platform-openapi.json +++ b/packages/sdk/specs/platform-openapi.json @@ -4,12 +4,25 @@ "AIChatStreamDone": { "description": "Terminal event marking the end of a streaming chat completion (SSE `done` event).", "example": { + "completions": [ + { + "response_model": "string", + "timing": {} + } + ], "finish_reason": "stop", "run_count": 1, "total_usage": {}, "usage": {} }, "properties": { + "completions": { + "description": "Ordered accepted completions; empty records retain unknown identities.", + "items": { + "$ref": "#/components/schemas/AICompletionProvenance" + }, + "type": "array" + }, "finish_reason": { "description": "The overall finish reason for the completion.", "example": "stop", @@ -36,13 +49,27 @@ "AIChatStreamError": { "description": "Terminal error event for a streaming chat completion (SSE `error` event).", "example": { - "message": "string" + "message": "string", + "retryable": true, + "status": 1 }, "properties": { "message": { "description": "Human-readable description of the error that terminated the stream.", "example": "string", "type": "string" + }, + "retryable": { + "description": "Whether the provider failure can be retried.", + "example": true, + "nullable": true, + "type": "boolean" + }, + "status": { + "description": "Upstream HTTP status, when reported.", + "example": 1, + "nullable": true, + "type": "integer" } }, "required": [ @@ -77,6 +104,7 @@ } ] }, + "response_model": "string", "usage": {} }, "properties": { @@ -89,6 +117,11 @@ "$ref": "#/components/schemas/AIMessage", "description": "The complete assistant message for this run, assembled from the preceding deltas." }, + "response_model": { + "description": "Provider-reported model identity for this accepted completion.", + "example": "string", + "type": "string" + }, "usage": { "description": "Token consumption for this run, keyed by model ID. `null` when usage data is unavailable.", "example": {}, @@ -192,9 +225,35 @@ }, "type": "object" }, + "AICompletionProvenance": { + "description": "One accepted provider completion. An empty record preserves an unknown identity.", + "example": { + "response_model": "string", + "timing": {} + }, + "properties": { + "response_model": { + "description": "Model identity reported by the provider response, not the requested model or usage key.", + "example": "string", + "type": "string" + }, + "timing": { + "description": "Optional monotonic timing for this accepted completion and its retries. request_ms includes all attempts, backoff and local processing; provider_attempts_ms is the sum of provider request wall times, including transport and parsing; retry_backoff_ms is measured retry sleep. attempt_count includes the accepted call and retry_count counts earlier attempts. These overlapping measurements are not provider-internal inference time. Missing timing is unknown, not zero.", + "example": {}, + "type": "object" + } + }, + "type": "object" + }, "AICompletionResult": { "description": "The result of an AI chat completion request. Returned by chat completion endpoints after the model finishes generating.", "example": { + "completions": [ + { + "response_model": "string", + "timing": {} + } + ], "finish_reason": "stop", "message": { "content": "How can I help you today?", @@ -244,9 +303,17 @@ ] } ], + "response_model": "string", "token_usage": {} }, "properties": { + "completions": { + "description": "Ordered accepted provider completions, including empty records for unknown identities.", + "items": { + "$ref": "#/components/schemas/AICompletionProvenance" + }, + "type": "array" + }, "finish_reason": { "description": "The reason the model stopped generating. Common values include `\"stop\"` (natural end), `\"length\"` (token limit reached), and `\"tool_calls\"` (the model invoked a tool).", "example": "stop", @@ -263,8 +330,13 @@ }, "type": "array" }, + "response_model": { + "description": "Final accepted completion provider-reported identity; absent when unknown.", + "example": "string", + "type": "string" + }, "token_usage": { - "description": "Token consumption breakdown keyed by model ID. Each value is a map with `\"input_tokens\"` and `\"output_tokens\"` counts. `null` when usage data is unavailable.", + "description": "Token consumption keyed by model ID. Each value has `input` (all prompt tokens, including cache reads and writes) and `output` counts. When reported, `fresh_input`, `cache_read`, and `cache_creation` are disjoint input buckets; missing cache counts remain unknown. `null` when usage data is unavailable.", "example": {}, "type": "object" } @@ -277,11 +349,12 @@ "type": "object" }, "AIEvaluationAnswer": { - "description": "One typed evaluation answer. `type` selects boolean, choice, or score.\n`id` matches the question id.\n", + "description": "One typed evaluation answer. `type` selects boolean, choice, score, or refusal.\n`id` matches the question id.\n", "discriminator": { "mapping": { "boolean": "#/components/schemas/AIEvaluationAnswerBoolean", "choice": "#/components/schemas/AIEvaluationAnswerChoice", + "refusal": "#/components/schemas/Refusal", "score": "#/components/schemas/AIEvaluationAnswerScore" }, "propertyName": "type" @@ -295,6 +368,9 @@ }, { "$ref": "#/components/schemas/AIEvaluationAnswerScore" + }, + { + "$ref": "#/components/schemas/Refusal" } ] }, @@ -435,7 +511,7 @@ }, "properties": { "answers": { - "description": "Typed answers. Each value is a boolean, choice, or score object with the question `id`.", + "description": "Typed boolean, choice, score, or refusal answers with the question `id`.", "items": { "$ref": "#/components/schemas/AIEvaluationAnswer" }, @@ -3543,6 +3619,7 @@ "created_at": "2024-01-01T00:00:00Z", "error_message": "string", "id": "cmp_0aBcDeFgHiJkLmNoPqRsTu", + "key": "string", "last_active_at": "2024-01-01T00:00:00Z", "lookup_key": "main-computer", "metadata": { @@ -3553,12 +3630,14 @@ "region": "us-east-1", "sprite_url": "https://example.com", "status": "ready", + "thread_id": "string", "updated_at": "2024-01-01T00:00:00Z" }, "properties": { "agent": { "description": "ID of the agent that owns this computer (`agi_...`). `null` if the computer is not yet assigned to an agent.", "example": "agi_0aBcDeFgHiJkLmNoPqRsTu", + "nullable": true, "type": "string" }, "app": { @@ -3582,6 +3661,7 @@ "error_message": { "description": "Human-readable error description when `status` is `\"error\"`. `null` otherwise.", "example": "string", + "nullable": true, "type": "string" }, "id": { @@ -3589,15 +3669,23 @@ "example": "cmp_0aBcDeFgHiJkLmNoPqRsTu", "type": "string" }, + "key": { + "description": "Stable key unique within the thread, or null if unset.", + "example": "string", + "nullable": true, + "type": "string" + }, "last_active_at": { "description": "When the computer last reported activity or received a command. `null` if the computer has never been active.", "example": "2024-01-01T00:00:00Z", "format": "date-time", + "nullable": true, "type": "string" }, "lookup_key": { "description": "Unique, stable identifier you assign to this computer within its app. `null` if not set.", "example": "main-computer", + "nullable": true, "type": "string" }, "metadata": { @@ -3613,23 +3701,32 @@ "type": "string" }, "provider": { - "description": "Compute backend powering this computer: `\"sprites\"` (Fly Sprites) or `\"vercel\"` (Vercel Sandbox).", + "description": "Compute backend powering this computer: `\"sprites\"` (Fly Sprites), `\"vercel\"` (Vercel Sandbox) or `\"e2b\"` (E2B).", "example": "sprites", "type": "string" }, "region": { - "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\"`).", + "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\"`).", "example": "us-east-1", + "nullable": true, "type": "string" }, "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", + "nullable": true, "type": "string" }, "status": { "description": "Current lifecycle state of the computer. Common values include `\"provisioning\"`, `\"ready\"`, `\"error\"`, and `\"terminated\"`.", "example": "ready", + "nullable": true, + "type": "string" + }, + "thread_id": { + "description": "Thread this computer belongs to, or null for a non-thread computer.", + "example": "string", + "nullable": true, "type": "string" }, "updated_at": { @@ -3657,6 +3754,7 @@ "created_at": "2024-01-01T00:00:00Z", "error_message": "string", "id": "cmp_0aBcDeFgHiJkLmNoPqRsTu", + "key": "string", "last_active_at": "2024-01-01T00:00:00Z", "lookup_key": "main-computer", "metadata": { @@ -3667,6 +3765,7 @@ "region": "us-east-1", "sprite_url": "https://example.com", "status": "ready", + "thread_id": "string", "updated_at": "2024-01-01T00:00:00Z" } ] @@ -4705,6 +4804,201 @@ ], "type": "object" }, + "AgentRequest": { + "description": "A request for human approval or input. Secret input is never returned.", + "example": { + "agent": { + "id": "string", + "name": "Example Name" + }, + "approvers": { + "mode": "string" + }, + "expires_at": "2024-01-01T00:00:00Z", + "id": "arq_0aBcDeFgHiJkLmNoPqRsTu", + "is_approver": true, + "kind": "string", + "origin": { + "routine_id": "string", + "session_id": "string", + "thread_id": "string" + }, + "payload": { + "question": "string" + }, + "resolution": { + "answer": "string", + "reason": "string" + }, + "resolved_at": "2024-01-01T00:00:00Z", + "resolved_by": "usr_0aBcDeFgHiJkLmNoPqRsTu", + "status": "string", + "summary": { + "lines": [ + "string" + ], + "title": "Example Title" + } + }, + "properties": { + "agent": { + "$ref": "#/components/schemas/AgentRequestAgent", + "description": "Originating agent." + }, + "approvers": { + "$ref": "#/components/schemas/Approvers", + "description": "Approval policy, excluding user IDs." + }, + "expires_at": { + "description": "Expiration time.", + "example": "2024-01-01T00:00:00Z", + "format": "date-time", + "type": "string" + }, + "id": { + "description": "Request ID (`arq_...`).", + "example": "arq_0aBcDeFgHiJkLmNoPqRsTu", + "type": "string" + }, + "is_approver": { + "description": "Whether the authenticated caller is an approver, regardless of request status.", + "example": true, + "type": "boolean" + }, + "kind": { + "description": "Registered request kind.", + "example": "string", + "type": "string" + }, + "origin": { + "$ref": "#/components/schemas/Origin", + "description": "Origin references." + }, + "payload": { + "$ref": "#/components/schemas/Payload", + "description": "Question request payload." + }, + "resolution": { + "allOf": [ + { + "$ref": "#/components/schemas/Resolution" + } + ], + "description": "Answer or rejection reason; null before resolution.", + "example": { + "answer": "string", + "reason": "string" + }, + "nullable": true + }, + "resolved_at": { + "description": "Resolution time.", + "example": "2024-01-01T00:00:00Z", + "format": "date-time", + "type": "string" + }, + "resolved_by": { + "description": "Resolving user ID.", + "example": "usr_0aBcDeFgHiJkLmNoPqRsTu", + "type": "string" + }, + "status": { + "description": "Request status.", + "example": "string", + "type": "string" + }, + "summary": { + "$ref": "#/components/schemas/Summary", + "description": "Kind-provided summary." + } + }, + "required": [ + "id" + ], + "type": "object" + }, + "AgentRequestAgent": { + "description": "Originating agent.", + "example": { + "id": "string", + "name": "Example Name" + }, + "properties": { + "id": { + "example": "string", + "type": "string" + }, + "name": { + "example": "Example Name", + "nullable": true, + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + "AgentRequestListResponse": { + "description": "A page of visible agent requests.", + "example": { + "data": [ + { + "agent": { + "id": "string", + "name": "Example Name" + }, + "approvers": { + "mode": "string" + }, + "expires_at": "2024-01-01T00:00:00Z", + "id": "arq_0aBcDeFgHiJkLmNoPqRsTu", + "is_approver": true, + "kind": "string", + "origin": { + "routine_id": "string", + "session_id": "string", + "thread_id": "string" + }, + "payload": { + "question": "string" + }, + "resolution": { + "answer": "string", + "reason": "string" + }, + "resolved_at": "2024-01-01T00:00:00Z", + "resolved_by": "usr_0aBcDeFgHiJkLmNoPqRsTu", + "status": "string", + "summary": { + "lines": [ + "string" + ], + "title": "Example Title" + } + } + ], + "next_cursor": "string" + }, + "properties": { + "data": { + "description": "Visible requests.", + "items": { + "$ref": "#/components/schemas/AgentRequest" + }, + "type": "array" + }, + "next_cursor": { + "description": "Pass as cursor for the next page; null at the end.", + "example": "string", + "type": "string" + } + }, + "required": [ + "data" + ], + "type": "object" + }, "AgentRoutine": { "description": "An agent routine defines a reusable handler — script, preset, or chain — that runs in response to events or on a schedule.", "example": { @@ -5568,6 +5862,47 @@ ], "type": "object" }, + "AgentSessionEvent": { + "description": "One event from the coding harness running an agent session on a computer.", + "example": { + "event": "tool_use", + "harness": "claude", + "id": "cse_...", + "occurred_at": "2024-01-01T00:00:00Z", + "payload": {} + }, + "properties": { + "event": { + "description": "Event name: `session_started`, `message`, `tool_use`, `needs_input`, `activity`, `error`, `turn_complete`, `finished`, `adopted`, or `harness_raw`.", + "example": "tool_use", + "type": "string" + }, + "harness": { + "description": "Harness that emitted it.", + "example": "claude", + "nullable": true, + "type": "string" + }, + "id": { + "description": "Event ID; pass as `after` to page.", + "example": "cse_...", + "type": "string" + }, + "occurred_at": { + "description": "When the event happened in the sandbox.", + "example": "2024-01-01T00:00:00Z", + "format": "date-time", + "type": "string" + }, + "payload": { + "description": "Harness-specific event data.", + "example": {}, + "nullable": true, + "type": "object" + } + }, + "type": "object" + }, "AgentSessionListResponse": { "description": "Paginated list response containing an array of agent session objects.", "example": { @@ -6693,9 +7028,53 @@ ], "type": "object" }, + "Approvers": { + "description": "Approval policy, excluding user IDs.", + "example": { + "mode": "string" + }, + "properties": { + "mode": { + "example": "string", + "type": "string" + } + }, + "required": [ + "mode" + ], + "type": "object" + }, "Artifact": { "description": "A versioned artifact produced or managed by an agent, such as a generated file, report, or code output.", "example": { + "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" + } + ] + }, "agent": "agt_0aBcDeFgHiJkLmNoPqRsTu", "content_type": "application/json", "created_at": "2024-01-01T00:00:00Z", @@ -6726,6 +7105,43 @@ "version": 1 }, "properties": { + "acl": { + "allOf": [ + { + "$ref": "#/components/schemas/Acl" + } + ], + "description": "Access control list for the artifact. Contains a `grants` array where each entry specifies `principal_type`, `principal`, and `actions` (`read`, `write`). `null` when the artifact has no grants or the viewer is not its owner.", + "example": { + "add": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "grants": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "remove": [ + { + "principal": "string", + "principal_type": "user" + } + ] + }, + "nullable": true + }, "agent": { "description": "ID of the agent that produced this artifact (`agt_...`). `null` if not agent-produced.", "example": "agt_0aBcDeFgHiJkLmNoPqRsTu", @@ -6834,6 +7250,254 @@ ], "type": "object" }, + "ArtifactEditingAck": { + "description": "Acknowledges an Artifact editing presence or leave request.", + "example": { + "ok": true + }, + "properties": { + "ok": { + "example": true, + "type": "boolean" + } + }, + "required": [ + "ok" + ], + "type": "object" + }, + "ArtifactEditingActor": { + "description": "A server-issued collaborator identity and its ephemeral presence.", + "example": { + "actor_id": "string", + "cursor": { + "position": 1, + "selection_end": 1 + }, + "meta": {} + }, + "properties": { + "actor_id": { + "description": "Opaque identity unique to this channel join.", + "example": "string", + "type": "string" + }, + "cursor": { + "allOf": [ + { + "$ref": "#/components/schemas/ArtifactEditingCursor" + } + ], + "description": "Current code-point cursor, or null.", + "example": { + "position": 1, + "selection_end": 1 + }, + "nullable": true + }, + "meta": { + "description": "Server-derived collaborator display metadata.", + "example": {}, + "type": "object" + } + }, + "required": [ + "actor_id", + "meta" + ], + "type": "object" + }, + "ArtifactEditingCheckpointResponse": { + "description": "Confirms the exact live revision that reached durable ArtifactVersion storage.", + "example": { + "artifact_version": "string", + "artifact_version_number": 1, + "checkpointed_revision": 1, + "dirty": true, + "incarnation": "string" + }, + "properties": { + "artifact_version": { + "description": "New durable ArtifactVersion ID.", + "example": "string", + "type": "string" + }, + "artifact_version_number": { + "example": 1, + "type": "integer" + }, + "checkpointed_revision": { + "example": 1, + "type": "integer" + }, + "dirty": { + "description": "True when later live operations remain unsaved.", + "example": true, + "type": "boolean" + }, + "incarnation": { + "example": "string", + "type": "string" + } + }, + "required": [ + "incarnation", + "checkpointed_revision", + "artifact_version", + "artifact_version_number", + "dirty" + ], + "type": "object" + }, + "ArtifactEditingCursor": { + "description": "A Unicode code-point cursor and optional selection endpoint.", + "example": { + "position": 1, + "selection_end": 1 + }, + "properties": { + "position": { + "description": "Zero-based Unicode code-point position.", + "example": 1, + "type": "integer" + }, + "selection_end": { + "description": "Zero-based Unicode code-point selection endpoint.", + "example": 1, + "type": "integer" + } + }, + "required": [ + "position" + ], + "type": "object" + }, + "ArtifactEditingJoinResponse": { + "description": "Authoritative live Artifact snapshot returned by an editing-channel join.", + "example": { + "actor_id": "string", + "actors": [ + { + "actor_id": "string", + "cursor": { + "position": 1, + "selection_end": 1 + }, + "meta": {} + } + ], + "artifact": "string", + "artifact_version": "string", + "artifact_version_number": 1, + "can_write": true, + "checkpoint_error": "string", + "checkpointed_revision": 1, + "connection_id": "string", + "content": "string", + "dirty": true, + "incarnation": "string", + "revision": 1 + }, + "properties": { + "actor_id": { + "description": "Server-issued identity for this channel join.", + "example": "string", + "type": "string" + }, + "actors": { + "items": { + "$ref": "#/components/schemas/ArtifactEditingActor" + }, + "type": "array" + }, + "artifact": { + "description": "Public Artifact ID (`art_...`).", + "example": "string", + "type": "string" + }, + "artifact_version": { + "description": "Durable version ID (`artv_...`).", + "example": "string", + "type": "string" + }, + "artifact_version_number": { + "example": 1, + "type": "integer" + }, + "can_write": { + "example": true, + "type": "boolean" + }, + "checkpoint_error": { + "description": "Last durable-save failure reason, or null.", + "example": "string", + "nullable": true, + "type": "string" + }, + "checkpointed_revision": { + "description": "Latest revision known durable.", + "example": 1, + "type": "integer" + }, + "connection_id": { + "description": "Server-issued connection identity.", + "example": "string", + "type": "string" + }, + "content": { + "description": "UTF-8 document content.", + "example": "string", + "type": "string" + }, + "dirty": { + "description": "True while a live tail remains crash-loss exposed.", + "example": true, + "type": "boolean" + }, + "incarnation": { + "description": "Opaque live-session fence token.", + "example": "string", + "type": "string" + }, + "revision": { + "description": "Live OT revision in Unicode code points.", + "example": 1, + "type": "integer" + } + }, + "required": [ + "artifact", + "artifact_version", + "artifact_version_number", + "actor_id", + "connection_id", + "incarnation", + "content", + "revision", + "checkpointed_revision", + "dirty", + "can_write", + "actors" + ], + "type": "object" + }, + "ArtifactEditingOperationAck": { + "description": "Acknowledges an operation only after the authoritative OT server applied it.", + "example": { + "revision": 1 + }, + "properties": { + "revision": { + "description": "Authoritative live revision after application.", + "example": 1, + "type": "integer" + } + }, + "required": [ + "revision" + ], + "type": "object" + }, "Attachment": { "description": "A rich attachment associated with a message, such as a file, scraped link, artifact, task, media item, or inline action.", "example": { @@ -6863,8 +7527,10 @@ "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, @@ -6878,8 +7544,10 @@ "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 } @@ -7196,8 +7864,9 @@ "type": "string" }, "event_id": { - "description": "ID of the platform event that triggered this run. `null` for directly invoked automations.", + "description": "Event or invocation identifier for this run. Direct invocations use the supplied idempotency key or a generated UUID. `null` when no event identifier was recorded.", "example": "string", + "nullable": true, "type": "string" }, "id": { @@ -7208,6 +7877,7 @@ "participants": { "description": "Invoke-time map of symbolic participant references to agent IDs. `null` when no participants were supplied.", "example": {}, + "nullable": true, "type": "object" }, "payload": { @@ -7218,6 +7888,7 @@ "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.", "example": {}, + "nullable": true, "type": "object" }, "status": { @@ -7228,6 +7899,7 @@ "team": { "description": "ID of the team that owns this run (`tea_...`). `null` if the run is owned by a user rather than a team.", "example": "tem_0aBcDeFgHiJkLmNoPqRsTu", + "nullable": true, "type": "string" }, "updated_at": { @@ -7239,6 +7911,7 @@ "user": { "description": "ID of the user that owns this run (`usr_...`). `null` if the run is owned by a team rather than a user.", "example": "usr_0aBcDeFgHiJkLmNoPqRsTu", + "nullable": true, "type": "string" } }, @@ -7967,8 +8640,10 @@ "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, @@ -7982,8 +8657,10 @@ "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 } @@ -7999,7 +8676,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "2024-01-01T00:00:00Z", @@ -8178,8 +8855,10 @@ "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, @@ -8193,8 +8872,10 @@ "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 } @@ -8210,7 +8891,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "2024-01-01T00:00:00Z", @@ -8629,8 +9310,10 @@ "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, @@ -8644,8 +9327,10 @@ "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 } @@ -8661,7 +9346,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "2024-01-01T00:00:00Z", @@ -9446,8 +10131,10 @@ "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, @@ -9461,8 +10148,10 @@ "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 } @@ -9478,7 +10167,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "2024-01-01T00:00:00Z", @@ -9657,8 +10346,10 @@ "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, @@ -9672,8 +10363,10 @@ "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 } @@ -9689,7 +10382,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "2024-01-01T00:00:00Z", @@ -10514,8 +11207,10 @@ "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, @@ -10529,8 +11224,10 @@ "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 } @@ -10546,7 +11243,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "2024-01-01T00:00:00Z", @@ -10678,8 +11375,10 @@ "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, @@ -10693,8 +11392,10 @@ "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 } @@ -10710,7 +11411,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "2024-01-01T00:00:00Z", @@ -11245,8 +11946,10 @@ "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, @@ -11260,8 +11963,10 @@ "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 } @@ -11277,7 +11982,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "2024-01-01T00:00:00Z", @@ -11456,8 +12161,10 @@ "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, @@ -11471,8 +12178,10 @@ "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 } @@ -11488,7 +12197,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "2024-01-01T00:00:00Z", @@ -12556,9 +13265,13 @@ { "granted": true, "key": "string", + "limit": 1, "provided_by": [ "personal" ], + "quantity": 1, + "remaining": 1, + "used": 1, "value": true, "value_type": "boolean" } @@ -12572,6 +13285,7 @@ }, "name": "Example Name", "notification_settings": {}, + "oauth_client_name": "Example Name", "org": "org_0aBcDeFgHiJkLmNoPqRsTu", "org_kind": "company", "org_name": "Example Name", @@ -12647,6 +13361,11 @@ "example": {}, "type": "object" }, + "oauth_client_name": { + "description": "Registered display name of the verified OAuth client, when available. Not a verified vendor identity.", + "example": "Example Name", + "type": "string" + }, "org": { "description": "ID of the current organization (`org_...`).", "example": "org_0aBcDeFgHiJkLmNoPqRsTu", @@ -12756,7 +13475,9 @@ } ] }, + "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", "created_at": "2024-01-01T00:00:00Z", + "expires_at": "2024-01-01T00:00:00Z", "fields": { "key": "value" }, @@ -12775,12 +13496,24 @@ "$ref": "#/components/schemas/Acl", "description": "Access control list governing read and write access to this custom object. Only returned to resource owners and privileged or organization-admin viewers; `null` for everyone else." }, + "agent": { + "description": "ID of the agent that owns this object (`agt_...`). `null` for other ownership types.", + "example": "agi_0aBcDeFgHiJkLmNoPqRsTu", + "type": "string" + }, "created_at": { "description": "When the custom object was created (ISO 8601).", "example": "2024-01-01T00:00:00Z", "format": "date-time", "type": "string" }, + "expires_at": { + "description": "Absolute expiry time (RFC 3339). Null when no expiry is set.", + "example": "2024-01-01T00:00:00Z", + "format": "date-time", + "nullable": true, + "type": "string" + }, "fields": { "description": "Map of field names to their current values as defined by the object's schema type.", "example": { @@ -12927,7 +13660,9 @@ } ] }, + "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", "created_at": "2024-01-01T00:00:00Z", + "expires_at": "2024-01-01T00:00:00Z", "fields": { "key": "value" }, @@ -12978,13 +13713,15 @@ "type": "integer" }, "total_entries": { - "description": "Total number of custom objects matching the query across all pages.", + "description": "Total number of custom objects matching the query across all pages; null when include_count is false.", "example": 1, + "nullable": true, "type": "integer" }, "total_pages": { - "description": "Total number of pages available for the current query.", + "description": "Total number of pages available for the current query; null when include_count is false.", "example": 1, + "nullable": true, "type": "integer" } }, @@ -13345,9 +14082,13 @@ { "granted": true, "key": "string", + "limit": 1, "provided_by": [ "personal" ], + "quantity": 1, + "remaining": 1, + "used": 1, "value": true, "value_type": "boolean" } @@ -13454,9 +14195,13 @@ "example": { "granted": true, "key": "string", + "limit": 1, "provided_by": [ "personal" ], + "quantity": 1, + "remaining": 1, + "used": 1, "value": true, "value_type": "boolean" }, @@ -13471,6 +14216,12 @@ "example": "string", "type": "string" }, + "limit": { + "description": "Unexpired metered allowance, including exhausted grants; null for boolean entitlements.", + "example": 1, + "nullable": true, + "type": "integer" + }, "provided_by": { "description": "Privacy-safe principal kinds that contribute to the effective value.", "example": [ @@ -13485,6 +14236,24 @@ }, "type": "array" }, + "quantity": { + "description": "Effective purchased quantity from the recurring terms linked to this key (for example seats), summed across granting principals. `null` when the key is not granted or no granting plan links a term to it.", + "example": 1, + "nullable": true, + "type": "integer" + }, + "remaining": { + "description": "Remaining metered allowance credits; null for boolean entitlements.", + "example": 1, + "nullable": true, + "type": "integer" + }, + "used": { + "description": "Signed metered consumption in the allowance window; may be negative after reversals. Null for boolean entitlements.", + "example": 1, + "nullable": true, + "type": "integer" + }, "value": { "description": "Merged entitlement value, or `null` when the key is not granted.", "example": true, @@ -13494,7 +14263,8 @@ "value_type": { "description": "Catalog type used to interpret `value`.", "enum": [ - "boolean" + "boolean", + "metered" ], "example": "boolean", "type": "string" @@ -13519,6 +14289,7 @@ "event_names": [ "Example Name" ], + "filter": {}, "id": "string", "last_overflow_at": "2024-01-01T00:00:00Z", "leased_count": 1, @@ -13532,7 +14303,8 @@ "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", "user": "usr_0aBcDeFgHiJkLmNoPqRsTu", - "visibility_timeout_seconds": 1 + "visibility_timeout_seconds": 1, + "watch_key": "string" }, "properties": { "agent": { @@ -13565,6 +14337,10 @@ }, "type": "array" }, + "filter": { + "example": {}, + "type": "object" + }, "id": { "example": "string", "type": "string" @@ -13626,6 +14402,10 @@ "visibility_timeout_seconds": { "example": 1, "type": "integer" + }, + "watch_key": { + "example": "string", + "type": "string" } }, "required": [ @@ -13808,6 +14588,7 @@ "event_names": [ "Example Name" ], + "filter": {}, "id": "string", "last_overflow_at": "2024-01-01T00:00:00Z", "leased_count": 1, @@ -13821,7 +14602,8 @@ "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", "user": "usr_0aBcDeFgHiJkLmNoPqRsTu", - "visibility_timeout_seconds": 1 + "visibility_timeout_seconds": 1, + "watch_key": "string" } ], "page": 1, @@ -14937,26 +15719,51 @@ "type": "object" }, "KeyValueStorageEntry": { - "description": "A single key-value storage entry belonging to a user. Represents one key/value pair written to a user's isolated storage namespace within an app.", + "description": "An owner-scoped key/value pair within an app, optionally expiring.", "example": { + "agent": "string", "created_at": "2024-01-01T00:00:00Z", + "expires_at": "2024-01-01T00:00:00Z", "key": "theme", + "org": "string", + "team": "string", "updated_at": "2024-01-01T00:00:00Z", "user": "usr_0aBcDeFgHiJkLmNoPqRsTu", "value": "dark" }, "properties": { + "agent": { + "description": "Agent owner, if any.", + "example": "string", + "type": "string" + }, "created_at": { "description": "When this storage entry was first created (ISO 8601). `null` if not yet persisted.", "example": "2024-01-01T00:00:00Z", "format": "date-time", "type": "string" }, + "expires_at": { + "description": "Expiry deadline, or null for entries without expiry.", + "example": "2024-01-01T00:00:00Z", + "format": "date-time", + "type": "string" + }, "key": { "description": "The string key used to store and look up this entry.", "example": "theme", "type": "string" }, + "org": { + "description": "Organization scope.", + "example": "string", + "type": "string" + }, + "team": { + "description": "Team owner, if any.", + "example": "string", + "type": "string" + }, "updated_at": { "description": "When this storage entry was last updated (ISO 8601). `null` if not yet persisted.", "example": "2024-01-01T00:00:00Z", @@ -14964,7 +15771,7 @@ "type": "string" }, "user": { - "description": "ID of the user who owns this storage entry (`usr_...`).", + "description": "ID of the user owner, or null for non-user ownership.", "example": "usr_0aBcDeFgHiJkLmNoPqRsTu", "type": "string" }, @@ -14975,7 +15782,6 @@ } }, "required": [ - "user", "key", "value" ], @@ -14986,8 +15792,12 @@ "example": { "data": [ { + "agent": "string", "created_at": "2024-01-01T00:00:00Z", + "expires_at": "2024-01-01T00:00:00Z", "key": "theme", + "org": "string", + "team": "string", "updated_at": "2024-01-01T00:00:00Z", "user": "usr_0aBcDeFgHiJkLmNoPqRsTu", "user_email": "user@example.com", @@ -15049,8 +15859,12 @@ "KeyValueStorageEntryWithUser": { "description": "A key-value storage entry enriched with owner information. Developer and server-to-server callers receive `user_email` and `user_name` populated; end-user (user-JWT) callers receive those fields as `null`.", "example": { + "agent": "string", "created_at": "2024-01-01T00:00:00Z", + "expires_at": "2024-01-01T00:00:00Z", "key": "theme", + "org": "string", + "team": "string", "updated_at": "2024-01-01T00:00:00Z", "user": "usr_0aBcDeFgHiJkLmNoPqRsTu", "user_email": "user@example.com", @@ -15058,17 +15872,38 @@ "value": "dark" }, "properties": { + "agent": { + "description": "Agent owner, if any.", + "example": "string", + "type": "string" + }, "created_at": { "description": "When this storage entry was first created (ISO 8601).", "example": "2024-01-01T00:00:00Z", "format": "date-time", "type": "string" }, + "expires_at": { + "description": "Expiry deadline, or null for entries without expiry.", + "example": "2024-01-01T00:00:00Z", + "format": "date-time", + "type": "string" + }, "key": { "description": "The string key used to store and look up this entry.", "example": "theme", "type": "string" }, + "org": { + "description": "Organization scope.", + "example": "string", + "type": "string" + }, + "team": { + "description": "Team owner, if any.", + "example": "string", + "type": "string" + }, "updated_at": { "description": "When this storage entry was last updated (ISO 8601).", "example": "2024-01-01T00:00:00Z", @@ -15076,7 +15911,7 @@ "type": "string" }, "user": { - "description": "ID of the user who owns this storage entry (`usr_...`).", + "description": "ID of the user owner, or null for non-user ownership.", "example": "usr_0aBcDeFgHiJkLmNoPqRsTu", "type": "string" }, @@ -15097,7 +15932,6 @@ } }, "required": [ - "user", "key", "value", "created_at", @@ -15289,8 +16123,10 @@ "MediaVariant": { "description": "A processed variant of a media item, such as the original upload or a resized thumbnail, including a signed download URL resolved at request time.", "example": { + "byte_size": 1, "content_type": "application/json", "created_at": "2024-01-01T00:00:00Z", + "duration_ms": 1, "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", "filename": "string", "height": 600, @@ -15304,12 +16140,20 @@ "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 }, "properties": { + "byte_size": { + "description": "Size of the stored bytes.", + "example": 1, + "nullable": true, + "type": "integer" + }, "content_type": { "description": "MIME type of this variant's file (e.g., `\"image/jpeg\"`, `\"video/mp4\"`). `null` if the file is not loaded.", "example": "application/json", @@ -15322,6 +16166,12 @@ "format": "date-time", "type": "string" }, + "duration_ms": { + "description": "Client-declared video duration in milliseconds; not server-probed.", + "example": 1, + "nullable": true, + "type": "integer" + }, "file": { "description": "ID of the underlying storage file that backs this variant (`fil_...`).", "example": "fil_0aBcDeFgHiJkLmNoPqRsTu", @@ -15362,6 +16212,12 @@ }, "nullable": true }, + "sha256": { + "description": "Lowercase SHA-256 of the stored bytes.", + "example": "string", + "nullable": true, + "type": "string" + }, "updated_at": { "description": "When this variant was last updated (ISO 8601).", "example": "2024-01-01T00:00:00Z", @@ -15374,6 +16230,13 @@ "nullable": true, "type": "string" }, + "url_expires_at": { + "description": "Expiry of this variant's playable URL.", + "example": "2024-01-01T00:00:00Z", + "format": "date-time", + "nullable": true, + "type": "string" + }, "variant_key": { "description": "Identifier for this variant's processing tier. Common values include `\"original\"` (the unmodified upload) and `\"thumbnail\"` (a resized preview).", "example": "original", @@ -15468,8 +16331,10 @@ "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, @@ -15483,8 +16348,10 @@ "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 } @@ -15500,7 +16367,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "string", @@ -15604,8 +16471,10 @@ "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, @@ -15619,8 +16488,10 @@ "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 } @@ -15636,7 +16507,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "2024-01-01T00:00:00Z", @@ -15931,8 +16802,10 @@ "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, @@ -15946,8 +16819,10 @@ "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 } @@ -15963,7 +16838,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "2024-01-01T00:00:00Z", @@ -16209,7 +17084,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" }, "properties": { "attributes": { @@ -16231,7 +17106,7 @@ }, "type": { "description": "Stable context kind. Must start with a lowercase letter and contain only lowercase letters, numbers, dots, dashes, or underscores.", - "example": "archdev.pull_request", + "example": "myapp.pull_request", "type": "string" } }, @@ -16696,6 +17571,32 @@ ], "type": "object" }, + "Origin": { + "description": "Origin references.", + "example": { + "routine_id": "string", + "session_id": "string", + "thread_id": "string" + }, + "properties": { + "routine_id": { + "example": "string", + "nullable": true, + "type": "string" + }, + "session_id": { + "example": "string", + "nullable": true, + "type": "string" + }, + "thread_id": { + "example": "string", + "nullable": true, + "type": "string" + } + }, + "type": "object" + }, "PaginatedReplies": { "description": "A paginated list of reply messages for a thread. The reply array is returned directly, not nested inside a `data` wrapper.", "example": { @@ -16778,8 +17679,10 @@ "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, @@ -16793,8 +17696,10 @@ "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 } @@ -16810,7 +17715,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "2024-01-01T00:00:00Z", @@ -16885,6 +17790,22 @@ ], "type": "object" }, + "Payload": { + "description": "Question request payload.", + "example": { + "question": "string" + }, + "properties": { + "question": { + "example": "string", + "type": "string" + } + }, + "required": [ + "question" + ], + "type": "object" + }, "PresetConfig": { "description": "Configuration for a preset routine handler. Controls the agent's behavior, session persistence, and model selection for a given routine or chain step.", "example": { @@ -17278,6 +18199,75 @@ ], "type": "object" }, + "Refusal": { + "description": "The model declined to judge this question.", + "example": { + "id": "string", + "type": "refusal" + }, + "properties": { + "id": { + "example": "string", + "type": "string" + }, + "type": { + "default": "refusal", + "enum": [ + "refusal" + ], + "example": "refusal", + "type": "string" + } + }, + "required": [ + "id", + "type" + ], + "type": "object" + }, + "Relay": { + "description": "Public relay authorization record.", + "example": { + "expires_at": "2024-01-01T00:00:00Z", + "id": "string" + }, + "properties": { + "expires_at": { + "description": "Relay expiry.", + "example": "2024-01-01T00:00:00Z", + "format": "date-time", + "type": "string" + }, + "id": { + "description": "Relay ID.", + "example": "string", + "type": "string" + } + }, + "required": [ + "id", + "expires_at" + ], + "type": "object" + }, + "Resolution": { + "description": "Answer or rejection reason; null before resolution.", + "example": { + "answer": "string", + "reason": "string" + }, + "properties": { + "answer": { + "example": "string", + "type": "string" + }, + "reason": { + "example": "string", + "type": "string" + } + }, + "type": "object" + }, "RoutinePreset": { "description": "A named preset that defines the execution model and constraints for a routine. Presets are shared definitions; individual routines reference a preset by name.", "example": { @@ -20829,6 +21819,35 @@ ], "type": "object" }, + "Summary": { + "description": "Kind-provided summary.", + "example": { + "lines": [ + "string" + ], + "title": "Example Title" + }, + "properties": { + "lines": { + "example": [ + "string" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "title": { + "example": "Example Title", + "type": "string" + } + }, + "required": [ + "title", + "lines" + ], + "type": "object" + }, "SystemAccessToken": { "description": "A long-lived API credential associated with a system account, used to authenticate server-to-server requests.", "example": { @@ -20967,6 +21986,7 @@ "epic": "string", "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, + "is_stalled": true, "links": { "key": "value" }, @@ -20993,15 +22013,19 @@ "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", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -21021,7 +22045,7 @@ "type": "integer" }, "blocked_by_count": { - "description": "Number of 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.", + "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" }, @@ -21117,7 +22141,12 @@ "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 list/show reads; create/update responses report `false` until the next read.", + "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" }, @@ -21182,7 +22211,7 @@ "type": "string" }, "parent": { - "description": "ID of the parent task when this task is a subtask (`tsk_...`). `null` for top-level tasks. Subtasks nest exactly one level.", + "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" @@ -21192,6 +22221,12 @@ "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", @@ -21216,13 +22251,20 @@ "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 subtasks under this task. Computed on list/show reads; create/update responses may report 0 until the next read. Always 0 for subtasks.", + "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" }, @@ -21236,6 +22278,18 @@ }, "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" + }, "team": { "description": "ID of the team that owns this task (`tem_...`). `null` if the task is not scoped to a team.", "example": "tem_0aBcDeFgHiJkLmNoPqRsTu", @@ -21243,7 +22297,7 @@ "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.", + "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" @@ -21360,6 +22414,106 @@ ], "type": "object" }, + "TaskEnsureResult": { + "description": "The current source task and whether this request created it.", + "example": { + "created": true, + "task": { + "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", + "aggregate_version": 1, + "blocked_by_count": 1, + "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", + "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", + "is_blocked": true, + "is_stalled": true, + "links": { + "key": "value" + }, + "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", + "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", + "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", + "updated_at": "2024-01-01T00:00:00Z", + "user": "usr_0aBcDeFgHiJkLmNoPqRsTu" + } + }, + "properties": { + "created": { + "description": "Whether this request created the task.", + "example": true, + "type": "boolean" + }, + "task": { + "$ref": "#/components/schemas/Task", + "description": "The current task." + } + }, + "required": [ + "created", + "task" + ], + "type": "object" + }, "TaskExternalLink": { "description": "An indexed external object linked to a task.", "example": { @@ -21391,15 +22545,48 @@ ], "type": "object" }, + "TaskOwnershipJob": { + "description": "The background job accepted for a task ownership conversion.", + "example": { + "job_id": 1, + "projection_pending": true, + "status": "string" + }, + "properties": { + "job_id": { + "description": "Background job ID.", + "example": 1, + "type": "integer" + }, + "projection_pending": { + "description": "Completed transfers are still reaching task read models.", + "example": true, + "type": "boolean" + }, + "status": { + "description": "Current background job state.", + "example": "string", + "type": "string" + } + }, + "required": [ + "job_id", + "status" + ], + "type": "object" + }, "TaskSessionLease": { "description": "A task-session lease returned only to its matching holder.", "example": { "expires_at": "2024-01-01T00:00:00Z", "harness": "string", "lease_id": "string", + "lease_remaining_ms": 1, "renewed_at": "2024-01-01T00:00:00Z", "session_id": "string", - "session_name": "Example Name" + "session_name": "Example Name", + "task_aggregate_version": 1, + "task_status": "string" }, "properties": { "expires_at": { @@ -21418,6 +22605,11 @@ "example": "string", "type": "string" }, + "lease_remaining_ms": { + "description": "Milliseconds of lease left when the response was built, clamped at zero. A renewal made while more than half the lease remains appends no event and leaves the expiry unchanged, so clients derive their deadline from this value.", + "example": 1, + "type": "integer" + }, "renewed_at": { "description": "Server timestamp for the most recent claim, reclaim, or renewal.", "example": "2024-01-01T00:00:00Z", @@ -21433,6 +22625,16 @@ "description": "Display name supplied by the matching coding session.", "example": "Example Name", "type": "string" + }, + "task_aggregate_version": { + "description": "Task aggregate version including the claim, reclaim, or renewal event.", + "example": 1, + "type": "integer" + }, + "task_status": { + "description": "Native task status after the lease event.", + "example": "string", + "type": "string" } }, "required": [ @@ -21441,7 +22643,10 @@ "session_name", "harness", "expires_at", - "renewed_at" + "lease_remaining_ms", + "renewed_at", + "task_status", + "task_aggregate_version" ], "type": "object" }, @@ -22602,8 +23807,10 @@ "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, @@ -22617,8 +23824,10 @@ "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 } @@ -22634,7 +23843,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "2024-01-01T00:00:00Z", @@ -23242,8 +24451,10 @@ "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, @@ -23257,8 +24468,10 @@ "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 } @@ -23274,7 +24487,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "2024-01-01T00:00:00Z", @@ -23509,8 +24722,10 @@ "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, @@ -23524,8 +24739,10 @@ "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 } @@ -27077,6 +28294,259 @@ "publishable_key", "bearer" ] + }, + "patch": { + "description": "Updates the computer's direct access grants. Requires permission to modify\nthe computer. Read grants allow retrieval and command execution; write grants\nalso allow management and deletion. Use acl.grants to replace grants, or\nacl.add/acl.remove to patch them. An empty acl.grants array revokes all direct\ngrants; omitting acl preserves them. Sharing does not add the computer to\nagent or thread lists.\n", + "operationId": "patch_api_v1_agent_computers__computer", + "parameters": [ + { + "description": "Computer ID (`cmp_...`).", + "example": "string", + "in": "path", + "name": "computer", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "example": { + "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" + } + ] + } + }, + "properties": { + "acl": { + "description": "Access control list replacement or add/remove operations.", + "example": { + "add": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "grants": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "remove": [ + { + "principal": "string", + "principal_type": "user" + } + ] + }, + "properties": { + "add": { + "description": "Patch mode: grants to add or merge into the existing list. Cannot be combined with `grants`.", + "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": [ + { + "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" + }, + "remove": { + "description": "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", + "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" + } + }, + "type": "object" + } + } + }, + "required": true + }, + "responses": { + "204": { + "description": "Empty response body. Returns HTTP 204 on success." + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Computer management permission required" + }, + "404": { + "description": "Computer not found" + }, + "422": { + "description": "Invalid grants" + } + }, + "summary": "Update a computer", + "x-auth": [ + "publishable_key", + "bearer" + ] } }, "/api/v1/agent_computers/{computer}/exec": { @@ -27845,6 +29315,283 @@ ] } }, + "/api/v1/agent_requests": { + "get": { + "description": "Lists requests visible under the context policy, newest first. Filters are combined. Pagination is not a snapshot; later pages continue after the last returned request.", + "operationId": "get_api_v1_agent_requests", + "parameters": [ + { + "description": "Filter by agent ID.", + "example": "string", + "in": "query", + "name": "agent", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "open, resolved, rejected, expired or cancelled.", + "example": "string", + "in": "query", + "name": "status", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "Filter by registered kind.", + "example": "string", + "in": "query", + "name": "kind", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "Page size, 1–100; default 25.", + "example": 1, + "in": "query", + "name": "limit", + "required": false, + "schema": { + "type": "integer" + } + }, + { + "description": "Opaque next_cursor from a prior page.", + "example": "string", + "in": "query", + "name": "cursor", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AgentRequestListResponse" + } + } + }, + "description": "A page of visible requests." + }, + "401": { + "description": "Unauthorized" + }, + "422": { + "description": "Invalid filter or cursor" + } + }, + "summary": "List agent requests", + "x-auth": [ + "publishable_key", + "bearer" + ] + } + }, + "/api/v1/agent_requests/{agent_request}": { + "get": { + "description": "Uses the request context visibility and approver policy. Agents cannot resolve or reject requests.", + "operationId": "get_api_v1_agent_requests__agent_request", + "parameters": [ + { + "description": "Request ID (`arq_...`).", + "example": "string", + "in": "path", + "name": "agent_request", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AgentRequest" + } + } + }, + "description": "The request, without secret input." + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Not an approver" + }, + "404": { + "description": "Request not found" + }, + "409": { + "description": "not_open or stale" + }, + "422": { + "description": "Input validation failed" + } + }, + "summary": "Show an agent request", + "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.", + "operationId": "post_api_v1_agent_requests__agent_request_reject", + "parameters": [ + { + "description": "Request ID (`arq_...`).", + "example": "string", + "in": "path", + "name": "agent_request", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "example": { + "reason": "string" + }, + "properties": { + "reason": { + "description": "Reason for rejecting the request.", + "example": "string", + "type": "string" + } + }, + "required": [ + "reason" + ], + "type": "object" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AgentRequest" + } + } + }, + "description": "The request, without secret input." + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Not an approver" + }, + "404": { + "description": "Request not found" + }, + "409": { + "description": "not_open or stale" + }, + "422": { + "description": "Input validation failed" + } + }, + "summary": "Reject an agent request", + "x-auth": [ + "publishable_key", + "bearer" + ] + } + }, + "/api/v1/agent_requests/{agent_request}/resolve": { + "post": { + "description": "Uses the request context visibility and approver policy. Agents cannot resolve or reject requests.", + "operationId": "post_api_v1_agent_requests__agent_request_resolve", + "parameters": [ + { + "description": "Request ID (`arq_...`).", + "example": "string", + "in": "path", + "name": "agent_request", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "example": { + "input": {} + }, + "properties": { + "input": { + "description": "Kind-specific input. Secrets must use secret_value.", + "example": {}, + "type": "object" + } + }, + "required": [ + "input" + ], + "type": "object" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AgentRequest" + } + } + }, + "description": "The request, without secret input." + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Not an approver" + }, + "404": { + "description": "Request not found" + }, + "409": { + "description": "not_open or stale" + }, + "422": { + "description": "Input validation failed" + } + }, + "summary": "Resolve an agent request", + "x-auth": [ + "publishable_key", + "bearer" + ] + } + }, "/api/v1/agent_routine_runs": { "get": { "description": "Returns a paginated list of agent routine runs across all routines visible to\nthe authenticated app scope. Results are ordered by creation time descending\n(most recent first).\n\nUse the `agent` parameter to filter runs to one or more specific agents. Use\n`status` to narrow results to runs in a particular state. Pagination is\nbidirectional: supply `after_cursor` to page forward through newer runs or\n`before_cursor` to page backward through older runs.\n\nThis endpoint requires an app scope. Requests without a valid app credential\nreturn 403.\n", @@ -29638,6 +31385,73 @@ ] } }, + "/api/v1/agent_sessions/{agent_session}/events": { + "get": { + "description": "Returns what the coding harness (Claude Code, Codex) running an agent\nsession on a computer has done so far: messages, tool use, turn\ncompletions, in order. Events arrive while the harness runs; page with\n`after`. The session stream endpoint pushes the same events live.\n", + "operationId": "get_api_v1_agent_sessions__agent_session_events", + "parameters": [ + { + "description": "Agent session ID (`ase_...`).", + "example": "string", + "in": "path", + "name": "agent_session", + "required": true, + "schema": { + "type": "string" + } + }, + { + "description": "Return events after this event ID (`cse_...`).", + "example": "string", + "in": "query", + "name": "after", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "Maximum events to return (default 200, max 1000).", + "example": 1, + "in": "query", + "name": "limit", + "required": false, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/AgentSessionEvent" + }, + "type": "array" + } + } + }, + "description": "Events in the order they happened." + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Forbidden - app scope required" + }, + "404": { + "description": "Session not found" + } + }, + "summary": "List an agent session's harness events", + "x-auth": [ + "publishable_key", + "bearer" + ] + } + }, "/api/v1/agent_sessions/{agent_session}/message": { "post": { "description": "Appends a message to the inbox of the specified agent session. The agent\nreads inbox messages at the start of each turn; sending a message to a\n`\"waiting\"` session signals it to resume execution.\n\nUse `role` to identify the sender type. The default role is `\"user\"`.\nArbitrary key-value metadata may be attached to the message for tracking\nor display purposes.\n\nRequires an app-scoped API key. The session must belong to an agent owned\nby the authenticated app.\n", @@ -29726,7 +31540,7 @@ }, "/api/v1/agent_sessions/{agent_session}/stream": { "get": { - "description": "Opens a Server-Sent Events connection that emits a `session_update` event\nwhenever the agent session's status changes, replaying the current status on\nconnect and closing on a terminal status (`completed`, `failed`, `cancelled`).\n", + "description": "Opens a Server-Sent Events connection that emits a `session_update` event\nwhenever the agent session's status changes, replaying the current status on\nconnect and closing on a terminal status (`completed`, `failed`, `cancelled`).\nSessions that run a coding harness on a computer also emit a `session_event`\nfor each harness event (messages, tool use, turn completion) as it happens;\nlist earlier ones with the session events endpoint.\n", "operationId": "get_api_v1_agent_sessions__agent_session_stream", "parameters": [ { @@ -29745,7 +31559,14 @@ "content": { "text/event-stream": { "schema": { - "$ref": "#/components/schemas/AgentSession" + "oneOf": [ + { + "$ref": "#/components/schemas/AgentSession" + }, + { + "$ref": "#/components/schemas/AgentSessionEvent" + } + ] } } }, @@ -29762,6 +31583,9 @@ ], "x-sdk-streaming": { "events": { + "session_event": { + "$ref": "#/components/schemas/AgentSessionEvent" + }, "session_update": { "$ref": "#/components/schemas/AgentSession" } @@ -31920,6 +33744,34 @@ "application/json": { "schema": { "example": { + "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" + } + ] + }, "config": {}, "lookup_key": "string", "metadata": { @@ -31930,6 +33782,179 @@ "region": "string" }, "properties": { + "acl": { + "description": "Initial access control list.", + "example": { + "add": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "grants": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "remove": [ + { + "principal": "string", + "principal_type": "user" + } + ] + }, + "properties": { + "add": { + "description": "Patch mode: grants to add or merge into the existing list. Cannot be combined with `grants`.", + "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": [ + { + "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" + }, + "remove": { + "description": "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", + "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" + }, "config": { "description": "Provider-specific configuration for the computer. Supported keys vary by provider. A top-level `provider` takes precedence over `config.provider`.", "example": {}, @@ -31953,7 +33978,7 @@ "type": "string" }, "provider": { - "description": "Compute backend for the computer: `\"sprites\"` (Fly Sprites, the default) or `\"vercel\"` (Vercel Sandbox). Folded into `config.provider`.", + "description": "Compute backend for the computer: `\"sprites\"` (Fly Sprites, the default), `\"vercel\"` (Vercel Sandbox) or `\"e2b\"` (E2B). Folded into `config.provider`.", "example": "string", "type": "string" }, @@ -33968,6 +35993,8 @@ "key": "value" }, "raw_content": {}, + "structured_data": "string", + "structured_data_summary": "string", "type": "gmail" }, "properties": { @@ -34013,6 +36040,18 @@ "example": {}, "type": "object" }, + "structured_data": { + "description": "Public ID (`sda_...`) of the structured-data record attached to the source message. Present only for such items on source search.", + "example": "string", + "nullable": true, + "type": "string" + }, + "structured_data_summary": { + "description": "Search summary of that record, computed when the request is served. When present, `content` is the indexed text and may be stale.", + "example": "string", + "nullable": true, + "type": "string" + }, "type": { "description": "Type identifier of the parent knowledge source (e.g. `\"gmail\"`, `\"github_activity\"`). Returns `\"unknown\"` when the source association is not loaded.", "example": "gmail", @@ -34124,6 +36163,81 @@ ] } }, + "/api/v1/agents/{agent}/self_solution": { + "get": { + "description": "Lazily snapshots an authorized agent into its single private, versioned Solution.", + "operationId": "get_api_v1_agents__agent_self_solution", + "parameters": [ + { + "description": "Agent ID or lookup key.", + "example": "string", + "in": "path", + "name": "agent", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "description": "Solution ID, solution version and stable lookup key.", + "example": { + "lookup_key": "string", + "solution_id": "string", + "solution_version": "string" + }, + "properties": { + "lookup_key": { + "example": "string", + "type": "string" + }, + "solution_id": { + "example": "string", + "type": "string" + }, + "solution_version": { + "example": "string", + "type": "string" + } + }, + "required": [ + "solution_id", + "solution_version", + "lookup_key" + ], + "type": "object" + } + } + }, + "description": "Successful response" + }, + "401": { + "description": "Unauthorized" + }, + "404": { + "description": "Agent not found" + }, + "409": { + "description": "Self-solution conflict" + }, + "422": { + "description": "Unexportable dependency" + }, + "500": { + "description": "Self-solution bootstrap failed" + } + }, + "summary": "Ensure an agent's private self-solution", + "x-auth": [ + "publishable_key", + "bearer" + ] + } + }, "/api/v1/agents/{agent}/threads": { "post": { "description": "Creates a new thread owned by the specified agent. The thread is scoped to the\nagent's identity and is immediately available for messaging.\n\nThe authenticated caller must have access to the agent's parent app. If your\nAPI key is scoped to a specific app, pass that app's ID via the `app` parameter.\nAttempting to create a thread for an agent you cannot access returns 404.\n\nBy default the platform may send an automatic welcome message into the new\nthread. Pass `skip_welcome_message: true` to suppress this behavior.\n", @@ -35874,7 +37988,7 @@ }, "/api/v1/ai/evaluation/evaluations": { "post": { - "description": "Sends a shared `state` and a list of typed questions to an evaluation\nmodel and returns typed answers. This is not chat completion and not\nJSON-schema structured output: there is no generated text.\n\nEach question is a `boolean`, `choice`, or `score` object with its own\n`id`. Answers come back as the same three typed objects, each carrying\nthat `id`.\n\nThe authenticated app must have the `llm_calls` entitlement enabled on its\nplan. Requests that exceed the plan quota are rejected with `402`. Token\nusage is recorded against the authenticated app and organization.\n", + "description": "Sends a shared `state` and a list of typed questions to an evaluation\nmodel and returns typed answers. This is not chat completion and not\nJSON-schema structured output: there is no generated text.\n\nEach question is a `boolean`, `choice`, or `score` object with its own\n`id`. Answers carry that `id`, including a `refusal` answer containing\nonly `id` and `type` when the model declines to judge a question.\n\nImage input, labelled score levels, and refusal answers are model-dependent.\nImages are separate from `state` and use the chat completion image-part format.\nModels without image support reject image input with `400 unsupported_capability`.\n\nThe authenticated app must have the `llm_calls` entitlement enabled on its\nplan. Requests that exceed the plan quota are rejected with `402`. Token\nusage is recorded against the authenticated app and organization.\n", "operationId": "post_api_v1_ai_evaluation_evaluations", "parameters": [], "requestBody": { @@ -35882,11 +37996,68 @@ "application/json": { "schema": { "example": { + "images": [ + { + "image_data": "string", + "image_type": "string", + "image_url": "https://example.com", + "type": "image" + } + ], "model": "string", "questions": [], "session_id": "string" }, "properties": { + "images": { + "description": "Optional image content parts. Omitted or empty means no images. Requires model image support.", + "example": [ + { + "image_data": "string", + "image_type": "string", + "image_url": "https://example.com", + "type": "image" + } + ], + "items": { + "description": "An image content part in the chat completion input format.", + "example": { + "image_data": "string", + "image_type": "string", + "image_url": "https://example.com", + "type": "image" + }, + "properties": { + "image_data": { + "description": "Base64 image bytes; requires image_type.", + "example": "string", + "type": "string" + }, + "image_type": { + "description": "Image MIME type, such as image/png.", + "example": "string", + "type": "string" + }, + "image_url": { + "description": "Image URL; mutually exclusive with image_data.", + "example": "https://example.com", + "type": "string" + }, + "type": { + "enum": [ + "image" + ], + "example": "image", + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object" + }, + "type": "array" + }, "model": { "description": "Evaluation model identifier. Omit to use the platform default.", "example": "string", @@ -36003,22 +38174,16 @@ { "description": "Place the state along ordered `criteria` levels.", "example": { - "criteria": [ - "string" - ], + "criteria": [], "id": "frustration", "instructions": "string", "type": "score" }, "properties": { "criteria": { - "description": "At least two ordered level descriptions.", - "example": [ - "string" - ], - "items": { - "type": "string" - }, + "description": "At least two ordered levels, each a string or an object with string label and description.", + "example": [], + "items": {}, "type": "array" }, "id": { @@ -36080,7 +38245,7 @@ } } }, - "description": "Typed answers as a list of boolean, choice, or score objects, plus model and usage." + "description": "Typed boolean, choice, score, or refusal answers, plus model and usage." }, "400": { "description": "Bad request" @@ -36816,6 +38981,256 @@ ] } }, + "/api/v1/ai/usage": { + "get": { + "description": "Returns the authenticated user's own LLM usage aggregated over a bounded\ntime window. Each row carries request and token sums plus the customer-billed\ncost for the group. Cost is derived from the customer's active billing plan;\nprovider-reported cost is never returned.\n\nPass `group_by` one or more times to choose the grouping dimensions\n(`task`, `model`, `agent_kind`, `agent_id`, `hour`). The window (`since` to\n`until`) may span at most 31 days. Results are capped at `limit` groups.\n", + "operationId": "get_api_v1_ai_usage", + "parameters": [ + { + "description": "Window start as an ISO 8601 timestamp (inclusive). Defaults to 7 days before `until`.", + "example": "string", + "in": "query", + "name": "since", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "Window end as an ISO 8601 timestamp (inclusive). Defaults to now.", + "example": "string", + "in": "query", + "name": "until", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "Grouping dimensions. Repeat for multiple dimensions (e.g. `group_by[]=task&group_by[]=model`). Defaults to `model`.", + "example": [ + "task" + ], + "in": "query", + "name": "group_by", + "required": false, + "schema": { + "items": { + "enum": [ + "task", + "model", + "agent_kind", + "agent_id", + "hour" + ], + "type": "string" + }, + "type": "array" + } + }, + { + "description": "Restrict results to these caller task IDs. Omit to include every task.", + "example": [ + "string" + ], + "in": "query", + "name": "task", + "required": false, + "schema": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + { + "description": "Maximum number of groups to return. Defaults to 50; maximum is 200.", + "example": 1, + "in": "query", + "name": "limit", + "required": false, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "description": "Aggregated LLM usage for the authenticated user.", + "example": { + "data": [ + { + "agent_id": "string", + "agent_kind": "string", + "billed_usd": 1.0, + "cache_read_tokens": 1, + "cache_write_tokens": 1, + "completion_tokens": 1, + "hour": "string", + "model": "string", + "priced": true, + "prompt_tokens": 1, + "requests": 1, + "task": "string" + } + ], + "since": "string", + "until": "string" + }, + "properties": { + "data": { + "description": "One row per group with request/token sums, the group key fields, `billed_usd`, and `priced`.", + "example": [ + { + "agent_id": "string", + "agent_kind": "string", + "billed_usd": 1.0, + "cache_read_tokens": 1, + "cache_write_tokens": 1, + "completion_tokens": 1, + "hour": "string", + "model": "string", + "priced": true, + "prompt_tokens": 1, + "requests": 1, + "task": "string" + } + ], + "items": { + "description": "One aggregated LLM usage group: request/token sums plus billed cost and the group key fields.", + "example": { + "agent_id": "string", + "agent_kind": "string", + "billed_usd": 1.0, + "cache_read_tokens": 1, + "cache_write_tokens": 1, + "completion_tokens": 1, + "hour": "string", + "model": "string", + "priced": true, + "prompt_tokens": 1, + "requests": 1, + "task": "string" + }, + "properties": { + "agent_id": { + "description": "Agent ID for this group. Present only when grouped by `agent_id`.", + "example": "string", + "nullable": true, + "type": "string" + }, + "agent_kind": { + "description": "Agent kind for this group. Present only when grouped by `agent_kind`.", + "example": "string", + "nullable": true, + "type": "string" + }, + "billed_usd": { + "description": "Customer-billed cost for this group in USD. `null` when `priced` is `false`.", + "example": 1.0, + "nullable": true, + "type": "number" + }, + "cache_read_tokens": { + "description": "Summed cache-read tokens in this group.", + "example": 1, + "type": "integer" + }, + "cache_write_tokens": { + "description": "Summed cache-write tokens in this group.", + "example": 1, + "type": "integer" + }, + "completion_tokens": { + "description": "Summed completion (output) tokens in this group.", + "example": 1, + "type": "integer" + }, + "hour": { + "description": "Hour bucket (ISO 8601) for this group. Present only when grouped by `hour`.", + "example": "string", + "nullable": true, + "type": "string" + }, + "model": { + "description": "Model identifier for this group. Present only when grouped by `model`.", + "example": "string", + "nullable": true, + "type": "string" + }, + "priced": { + "description": "`true` when `billed_usd` was priced from the customer's active billing plan; `false` when the group could not be priced.", + "example": true, + "type": "boolean" + }, + "prompt_tokens": { + "description": "Summed prompt (input) tokens in this group.", + "example": 1, + "type": "integer" + }, + "requests": { + "description": "Number of LLM calls in this group.", + "example": 1, + "type": "integer" + }, + "task": { + "description": "Caller task ID for this group. Present only when grouped by `task`.", + "example": "string", + "nullable": true, + "type": "string" + } + }, + "required": [ + "requests", + "prompt_tokens", + "completion_tokens", + "cache_read_tokens", + "cache_write_tokens", + "priced" + ], + "type": "object" + }, + "type": "array" + }, + "since": { + "description": "Effective window start (ISO 8601).", + "example": "string", + "type": "string" + }, + "until": { + "description": "Effective window end (ISO 8601).", + "example": "string", + "type": "string" + } + }, + "required": [ + "data", + "since", + "until" + ], + "type": "object" + } + } + }, + "description": "Successful response" + }, + "401": { + "description": "Unauthorized" + }, + "422": { + "description": "Invalid parameters" + } + }, + "summary": "Read the authenticated user's LLM usage", + "x-auth": [ + "publishable_key", + "bearer" + ] + } + }, "/api/v1/artifacts": { "post": { "description": "Creates a new artifact and stores its file content. A file payload is required;\nsupply it via the `file.data` (Base64-encoded by default), `file.filename`, and\n`file.mime_type` fields. The artifact is scoped to the owner resolved from the\nrequest body — either a team, a user, or an explicit system owner. When no\nowner is supplied and the viewer is an authenticated user, the artifact\ndefaults to that user.\n\nFor company-readable snapshots, pass `system: true` and `org`. Organization\nmembers can read these artifacts; organization admins and system viewers can\ncreate them. Scripts may supply text directly using `file.encoding: \"utf8\"`.\n\nOptionally associate the artifact with an existing thread or agent by passing\n`thread` or `agent`. Legacy requests that wrap fields in an `artifact` object\nare still accepted.\n", @@ -36826,6 +39241,34 @@ "application/json": { "schema": { "example": { + "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" + } + ] + }, "agent": "string", "artifact": {}, "description": "An example description.", @@ -36839,13 +39282,185 @@ "idempotency_key": "string", "name": "Example Name", "org": "string", - "permissions": {}, "system": true, "team": "string", "thread": "string", "user": "string" }, "properties": { + "acl": { + "description": "Initial access control list. Grants add read or write access beyond the owner.", + "example": { + "add": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "grants": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "remove": [ + { + "principal": "string", + "principal_type": "user" + } + ] + }, + "properties": { + "add": { + "description": "Patch mode: grants to add or merge into the existing list. Cannot be combined with `grants`.", + "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": [ + { + "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" + }, + "remove": { + "description": "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", + "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" + }, "agent": { "description": "Agent ID (`agt_...`) to associate with the artifact.", "example": "string", @@ -36921,11 +39536,6 @@ "example": "string", "type": "string" }, - "permissions": { - "description": "Optional artifact permissions map.", - "example": {}, - "type": "object" - }, "system": { "description": "When true, create a system-owned artifact. Mutually exclusive with `team` and `user`.", "example": true, @@ -37079,6 +39689,34 @@ "application/json": { "schema": { "example": { + "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" + } + ] + }, "description": "An example description.", "file": { "data": "string", @@ -37094,6 +39732,179 @@ "name": "Example Name" }, "properties": { + "acl": { + "description": "Access control list replacement (`grants`) or add/remove operations. Omit to leave grants unchanged. ACL-only updates do not increment the content version.", + "example": { + "add": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "grants": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "remove": [ + { + "principal": "string", + "principal_type": "user" + } + ] + }, + "properties": { + "add": { + "description": "Patch mode: grants to add or merge into the existing list. Cannot be combined with `grants`.", + "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": [ + { + "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" + }, + "remove": { + "description": "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", + "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" + }, "description": { "description": "New description for the artifact. Omit to leave the existing description unchanged.", "example": "An example description.", @@ -40820,6 +43631,36 @@ "type": "string" } }, + { + "description": "JSON containment predicates on fields, applied before pagination and counting.", + "example": {}, + "in": "query", + "name": "field_filters", + "required": false, + "schema": { + "type": "object" + } + }, + { + "description": "Only system-owned objects (no user, team, agent or thread owner). Visibility is unchanged.", + "example": true, + "in": "query", + "name": "system_only", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "description": "Top-level JSON field for descending text order, with ID tie-breaker. Full-text relevance takes precedence.", + "example": "string", + "in": "query", + "name": "order_by_field", + "required": false, + "schema": { + "type": "string" + } + }, { "description": "Exact `row_key` value to match. When supplied, only objects with this partition key are returned.", "example": "string", @@ -40845,6 +43686,21 @@ "type": "array" } }, + { + "description": "JSON-encoded array of up to 100 objects with required string row_key and optional string-array sort_key. Missing or empty sort_key selects the whole partition. Mutually exclusive with row_key and sort_key. Pagination applies globally across all matched partitions.", + "example": [ + {} + ], + "in": "query", + "name": "keys", + "required": false, + "schema": { + "items": { + "type": "object" + }, + "type": "array" + } + }, { "description": "One or more team IDs (`team_...`) to filter by owning team. Returns objects owned by any of the supplied teams.", "example": [ @@ -40935,6 +43791,17 @@ "type": "integer" } }, + { + "description": "Include only objects updated at or after this ISO 8601 timestamp. Applies before pagination and counting.", + "example": "2024-01-01T00:00:00Z", + "in": "query", + "name": "updated_since", + "required": false, + "schema": { + "format": "date-time", + "type": "string" + } + }, { "description": "Number of objects per page. Defaults to `25`; maximum is `100`.", "example": 1, @@ -40944,6 +43811,16 @@ "schema": { "type": "integer" } + }, + { + "description": "Include total_entries and total_pages (default true). When false, totals are null, has_next uses one extra row, and pages beyond the end return an empty list without clamping. The page offset must fit PostgreSQL's signed 64-bit integer range.", + "example": true, + "in": "query", + "name": "include_count", + "required": false, + "schema": { + "type": "boolean" + } } ], "responses": { @@ -40970,7 +43847,11 @@ "summary": "List custom objects", "x-auth": [ "publishable_key", - "bearer" + "bearer", + "device_flow" + ], + "x-required-scopes": [ + "objects:read" ] }, "post": { @@ -41012,6 +43893,7 @@ }, "agent": "string", "config": "string", + "expires_at": "2024-01-01T00:00:00Z", "fields": {}, "org": "string", "schema_key": "string", @@ -41205,6 +44087,13 @@ "example": "string", "type": "string" }, + "expires_at": { + "description": "Absolute expiry time in RFC 3339 format. Pass null to clear; omit to leave unchanged on update.", + "example": "2024-01-01T00:00:00Z", + "format": "date-time", + "nullable": true, + "type": "string" + }, "fields": { "description": "Key-value map of field values for the new object. Must conform to the schema's field definitions. Omit to create an object with all fields at their default or null values.", "example": {}, @@ -41280,6 +44169,497 @@ } }, "summary": "Create a custom object", + "x-auth": [ + "publishable_key", + "bearer", + "device_flow" + ], + "x-required-scopes": [ + "objects:write" + ] + } + }, + "/api/v1/custom_objects/patch": { + "post": { + "description": "Applies numeric patch ops (`increment`, `max`, `min`, `set_if_newer` with\ndotted `path`s) atomically to a custom object and returns the updated\nobject along with per-op results. The authenticated viewer must have\npermission to modify the object.\n\nAddress the row in one of two ways: by `object` ID (`cobj_...`), or by\n`schema` + `row_key` (with optional `sort_key` for schemas that declare\none). The keyed form resolves the row for the same owner the create\ncontract would use and, when no row exists yet, creates it from\n`create_with` merged over the key fields before applying the ops — so an\naggregator's first call creates the counter and later calls increment it.\nA racing create resolves to the same row instead of a duplicate.\n\nPass `idempotency_key` to make retries safe: a retry with the same key and\nops replays the stored result without re-applying the write (survives\nserver restarts); reusing a key with different ops returns 409.\n", + "operationId": "post_api_v1_custom_objects_patch", + "parameters": [], + "requestBody": { + "content": { + "application/json": { + "schema": { + "example": { + "agent": "string", + "create_with": {}, + "idempotency_key": "string", + "object": "string", + "ops": [ + {} + ], + "row_key": "string", + "schema": "string", + "sort_key": [ + "string" + ], + "team": "string", + "user": "string" + }, + "properties": { + "agent": { + "description": "Agent user ID owning the keyed row. At most one owner selector may be present.", + "example": "string", + "type": "string" + }, + "create_with": { + "description": "Field values used to create the row when the keyed form finds no existing row. Merged over the key fields before validation; ignored by the `object` form.", + "example": {}, + "type": "object" + }, + "idempotency_key": { + "description": "Client-supplied deduplication key for this patch. A retry with the same key and the same ops replays the stored result without re-applying the write (survives server restarts); reusing a key with different ops returns 409.", + "example": "string", + "type": "string" + }, + "object": { + "description": "Custom object ID (`cobj_...`) to patch. Exactly one of `object` or `schema` + `row_key` is required.", + "example": "string", + "type": "string" + }, + "ops": { + "description": "Numeric patch ops to apply in order (e.g. `[%{\"op\" => \"increment\", \"path\" => \"count\", \"by\" => 1}]`). Supported ops: `increment` (`by`), `max`/`min` (`value`), `set_if_newer` (`value`, `fence_path`, `fence`).", + "example": [ + {} + ], + "items": { + "type": "object" + }, + "type": "array" + }, + "row_key": { + "description": "Row key naming the row within `schema` (e.g. a counter name). Requires `schema`.", + "example": "string", + "type": "string" + }, + "schema": { + "description": "Schema type identifier (`lookup_key`) for the keyed form. Requires `row_key`.", + "example": "string", + "type": "string" + }, + "sort_key": { + "description": "Sort-key segments partitioning rows within the `row_key` bucket. Only meaningful for schemas that declare a `sort_key`.", + "example": [ + "string" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "team": { + "description": "Team ID (`tem_...`) owning the keyed row. Defaults to the viewer's owner like the create contract.", + "example": "string", + "type": "string" + }, + "user": { + "description": "User ID (`usr_...`) owning the keyed row. At most one owner selector may be present.", + "example": "string", + "type": "string" + } + }, + "required": [ + "ops" + ], + "type": "object" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "description": "The patched custom object, its version, and per-op results.", + "example": { + "data": { + "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" + } + ] + }, + "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", + "created_at": "2024-01-01T00:00:00Z", + "expires_at": "2024-01-01T00:00:00Z", + "fields": { + "key": "value" + }, + "id": "cobj_0aBcDeFgHiJkLmNoPqRsTu", + "org": "org_0aBcDeFgHiJkLmNoPqRsTu", + "row_key": "string", + "sandbox": "dsb_0aBcDeFgHiJkLmNoPqRsTu", + "schema_type": "contact", + "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", + "updated_at": "2024-01-01T00:00:00Z", + "user": "usr_0aBcDeFgHiJkLmNoPqRsTu", + "version": 1 + }, + "meta": {} + }, + "properties": { + "data": { + "description": "The custom object after the patch has been applied.", + "example": { + "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" + } + ] + }, + "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", + "created_at": "2024-01-01T00:00:00Z", + "expires_at": "2024-01-01T00:00:00Z", + "fields": { + "key": "value" + }, + "id": "cobj_0aBcDeFgHiJkLmNoPqRsTu", + "org": "org_0aBcDeFgHiJkLmNoPqRsTu", + "row_key": "string", + "sandbox": "dsb_0aBcDeFgHiJkLmNoPqRsTu", + "schema_type": "contact", + "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", + "updated_at": "2024-01-01T00:00:00Z", + "user": "usr_0aBcDeFgHiJkLmNoPqRsTu", + "version": 1 + }, + "properties": { + "acl": { + "description": "Access control list governing read and write access to this custom object. Only returned to resource owners and privileged or organization-admin viewers; `null` for everyone else.", + "example": { + "add": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "grants": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "remove": [ + { + "principal": "string", + "principal_type": "user" + } + ] + }, + "properties": { + "add": { + "description": "Patch mode: grants to add or merge into the existing list. Cannot be combined with `grants`.", + "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": [ + { + "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" + }, + "remove": { + "description": "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", + "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" + }, + "agent": { + "description": "ID of the agent that owns this object (`agt_...`). `null` for other ownership types.", + "example": "agi_0aBcDeFgHiJkLmNoPqRsTu", + "type": "string" + }, + "created_at": { + "description": "When the custom object was created (ISO 8601).", + "example": "2024-01-01T00:00:00Z", + "format": "date-time", + "type": "string" + }, + "expires_at": { + "description": "Absolute expiry time (RFC 3339). Null when no expiry is set.", + "example": "2024-01-01T00:00:00Z", + "format": "date-time", + "nullable": true, + "type": "string" + }, + "fields": { + "description": "Map of field names to their current values as defined by the object's schema type.", + "example": { + "key": "value" + }, + "type": "object" + }, + "id": { + "description": "Unique identifier for the custom object (`cobj_...`).", + "example": "cobj_0aBcDeFgHiJkLmNoPqRsTu", + "type": "string" + }, + "org": { + "description": "ID of the organization this object belongs to (`org_...`).", + "example": "org_0aBcDeFgHiJkLmNoPqRsTu", + "type": "string" + }, + "row_key": { + "description": "An optional stable key used to identify this object by a caller-controlled string rather than its generated ID. `null` if not set.", + "example": "string", + "type": "string" + }, + "sandbox": { + "description": "ID of the sandbox environment this object is scoped to (`dsb_...`). `null` for production objects.", + "example": "dsb_0aBcDeFgHiJkLmNoPqRsTu", + "type": "string" + }, + "schema_type": { + "description": "The lookup key of the schema type that defines this object's field structure. `null` if the schema type has not been set.", + "example": "contact", + "type": "string" + }, + "team": { + "description": "ID of the team that owns this object (`tem_...`). `null` if the object is not team-scoped.", + "example": "tem_0aBcDeFgHiJkLmNoPqRsTu", + "type": "string" + }, + "updated_at": { + "description": "When the custom object was last modified (ISO 8601). `null` if the object has never been updated after creation.", + "example": "2024-01-01T00:00:00Z", + "format": "date-time", + "type": "string" + }, + "user": { + "description": "ID of the user that owns this object (`usr_...`). `null` if the object is not user-scoped.", + "example": "usr_0aBcDeFgHiJkLmNoPqRsTu", + "type": "string" + }, + "version": { + "description": "Optimistic concurrency version of the object. Increments with each successful update; pass this value in write operations to detect conflicting changes.", + "example": 1, + "type": "integer" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + "meta": { + "description": "Version metadata and per-op patch results.", + "example": {}, + "type": "object" + } + }, + "required": [ + "data" + ], + "type": "object" + } + } + }, + "description": "Successful response" + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Forbidden" + }, + "404": { + "description": "Not found" + }, + "409": { + "description": "Conflict - row already exists at this key or idempotency key reused" + }, + "422": { + "description": "Validation failed" + } + }, + "summary": "Apply numeric patch ops to a custom object", "x-auth": [ "publishable_key", "bearer" @@ -41393,7 +44773,11 @@ "summary": "Retrieve a custom object", "x-auth": [ "publishable_key", - "bearer" + "bearer", + "device_flow" + ], + "x-required-scopes": [ + "objects:read" ] }, "put": { @@ -41445,8 +44829,10 @@ ] }, "expected_version": 1, + "expires_at": "2024-01-01T00:00:00Z", "field_ops": {}, "fields": {}, + "idempotency_key": "string", "type": "string" }, "properties": { @@ -41628,6 +45014,13 @@ "example": 1, "type": "integer" }, + "expires_at": { + "description": "Absolute expiry time in RFC 3339 format. Pass null to clear; omit to leave unchanged on update.", + "example": "2024-01-01T00:00:00Z", + "format": "date-time", + "nullable": true, + "type": "string" + }, "field_ops": { "description": "Granular array operations to apply per field (e.g. append, prepend, remove). A field must not appear in both `fields` and `field_ops`.", "example": {}, @@ -41638,6 +45031,11 @@ "example": {}, "type": "object" }, + "idempotency_key": { + "description": "Client-supplied deduplication key for this write. A retry with the same key and the same body replays the stored result without re-applying the write (survives server restarts); reusing a key with a different body returns 409.", + "example": "string", + "type": "string" + }, "type": { "description": "Schema type identifier (`lookup_key`) of the object. Optional; used for routing context only.", "example": "string", @@ -41686,7 +45084,9 @@ } ] }, + "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", "created_at": "2024-01-01T00:00:00Z", + "expires_at": "2024-01-01T00:00:00Z", "fields": { "key": "value" }, @@ -41734,7 +45134,9 @@ } ] }, + "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", "created_at": "2024-01-01T00:00:00Z", + "expires_at": "2024-01-01T00:00:00Z", "fields": { "key": "value" }, @@ -41922,12 +45324,24 @@ }, "type": "object" }, + "agent": { + "description": "ID of the agent that owns this object (`agt_...`). `null` for other ownership types.", + "example": "agi_0aBcDeFgHiJkLmNoPqRsTu", + "type": "string" + }, "created_at": { "description": "When the custom object was created (ISO 8601).", "example": "2024-01-01T00:00:00Z", "format": "date-time", "type": "string" }, + "expires_at": { + "description": "Absolute expiry time (RFC 3339). Null when no expiry is set.", + "example": "2024-01-01T00:00:00Z", + "format": "date-time", + "nullable": true, + "type": "string" + }, "fields": { "description": "Map of field names to their current values as defined by the object's schema type.", "example": { @@ -42021,7 +45435,11 @@ "summary": "Update a custom object", "x-auth": [ "publishable_key", - "bearer" + "bearer", + "device_flow" + ], + "x-required-scopes": [ + "objects:write" ] } }, @@ -42147,11 +45565,18 @@ "event_names": [ "Example Name" ], + "filter": {}, "max_pending_events": 1, "name": "Example Name", + "previous_filter": {}, + "previous_filters": [ + {} + ], + "previous_watch_key": "string", "retention_seconds": 1, "status": "active", - "visibility_timeout_seconds": 1 + "visibility_timeout_seconds": 1, + "watch_key": "string" }, "properties": { "event_names": { @@ -42164,6 +45589,11 @@ }, "type": "array" }, + "filter": { + "description": "Optional match over subject_key, actor_key, and allowlisted dims. Only valid when every event name is a custom (script-emitted) event type. Missing filter matches all events.", + "example": {}, + "type": "object" + }, "max_pending_events": { "description": "Queue cap. Defaults to 100; maximum 1000.", "example": 1, @@ -42174,6 +45604,26 @@ "example": "Example Name", "type": "string" }, + "previous_filter": { + "description": "Expected legacy filter for atomic watch-key adoption.", + "example": {}, + "type": "object" + }, + "previous_filters": { + "description": "Additional exact historical filters accepted for atomic watch-key adoption.", + "example": [ + {} + ], + "items": { + "type": "object" + }, + "type": "array" + }, + "previous_watch_key": { + "description": "Optionally adopt an existing key in the exact same owner and residence when the destination is absent and its filter exactly matches previous_filter, one of previous_filters, or filter. Preserves queue identity and deliveries; mismatches reject the request without changing either queue.", + "example": "string", + "type": "string" + }, "retention_seconds": { "description": "Delivery retention in seconds. Defaults to 86400 (24 hours); between 7200 and 2592000. Applies to future deliveries only.", "example": 1, @@ -42192,6 +45642,11 @@ "description": "Default claim lease in seconds. Defaults to 300.", "example": 1, "type": "integer" + }, + "watch_key": { + "description": "Optional durable identity within the caller owner and residence. Repeated creates replace routes and filter on that queue; omission creates a new queue regardless of name.", + "example": "string", + "type": "string" } }, "required": [ @@ -42219,7 +45674,7 @@ "description": "Unauthorized" }, "422": { - "description": "Invalid parameters; Validation failed" + "description": "Invalid parameters; Filter clauses must be bounded string lists over allowlisted dims; Filter is only valid when every event name is a custom (script-emitted) event type; Validation failed" } }, "summary": "Create a domain-event subscription", @@ -42324,6 +45779,7 @@ "event_names": [ "Example Name" ], + "filter": {}, "max_pending_events": 1, "name": "Example Name", "retention_seconds": 1, @@ -42340,6 +45796,11 @@ }, "type": "array" }, + "filter": { + "description": "Optional match over subject_key, actor_key, and allowlisted dims. Only valid when every event name is a custom (script-emitted) event type. Missing filter matches all events.", + "example": {}, + "type": "object" + }, "max_pending_events": { "example": 1, "type": "integer" @@ -42390,7 +45851,7 @@ "description": "Event subscription not found" }, "422": { - "description": "Invalid parameters; Validation failed" + "description": "Invalid parameters; Filter clauses must be bounded string lists over allowlisted dims; Filter is only valid when every event name is a custom (script-emitted) event type; Validation failed" } }, "summary": "Update a domain-event subscription", @@ -43553,7 +47014,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\nArchDev Platform proxy has 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\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": { @@ -43937,11 +47398,11 @@ }, "/api/v1/files/{file}/avatar": { "get": { - "description": "Returns the raw image bytes for an agent's profile picture identified by `file`.\nThis endpoint is designed for integration partners (such as Slack) that fetch\navatar URLs via plain GET requests without bearer token support. Authorization\nis performed via a short, stable capability `token` rather than an HTTP header.\n\nThe `token` is an HMAC-based capability tied to the file ID. It does not expire,\nbut it is invalidated when the agent's profile picture is replaced or the agent is\ndeleted — shared caches may continue serving the old image until the\n`Cache-Control` max-age of one hour elapses. The endpoint never redirects to\na signed storage URL; bytes are served inline so behavior is consistent across\nstorage backends.\n\nAll failure modes — invalid file ID, invalid token, file not currently referenced\nas an agent avatar — return a uniform `404` to avoid acting as an existence oracle.\n", + "description": "Returns the raw image bytes for an agent's or user's profile picture identified\nby `file`. Chat messages and integration partners (such as Slack) fetch avatars\nthrough it with plain GET requests, without bearer tokens. Authorization is\nperformed via a short, stable capability `token` rather than an HTTP header.\n\nThe `token` is an HMAC-based capability tied to the file ID. It does not expire,\nbut it is invalidated when the profile picture is replaced or its agent or user\nis deleted — shared caches may continue serving the old image until the\n`Cache-Control` max-age of one hour elapses. The endpoint never redirects to\na signed storage URL; bytes are served inline so behavior is consistent across\nstorage backends.\n\nAll failure modes — invalid file ID, invalid token, file not currently referenced\nas an agent avatar — return a uniform `404` to avoid acting as an existence oracle.\n", "operationId": "get_api_v1_files__file_avatar", "parameters": [ { - "description": "File ID of the agent's profile picture (`fil_...`). Must be currently set as an agent's profile picture within the same app.", + "description": "File ID of the profile picture (`fil_...`). Must be currently set as an agent's or user's profile picture within the same app.", "example": "string", "in": "path", "name": "file", @@ -43971,13 +47432,64 @@ } } }, - "description": "Raw image bytes of the agent avatar, served with the file's original content type." + "description": "Raw image bytes of the avatar, served with the file's original content type." }, "404": { "description": "Not found" } }, - "summary": "Fetch an agent avatar image" + "summary": "Fetch an agent or user avatar image" + } + }, + "/api/v1/files/{file}/download": { + "get": { + "description": "Returns the raw binary content of a file the authenticated viewer may see.\nThe response `Content-Type` header reflects the file's stored MIME type and\n`Content-Disposition` names the file as an attachment, so a browser can hand\nthe body to the download manager directly.\n\nUnlike `Show` (which mints a storage URL the browser must resolve itself),\nthis endpoint serves bytes inline through the authenticated API mount, so it\nbehaves identically across storage backends: local files are not exposed as\nunauthenticated static paths, and signed GCS URLs never cross the browser\nboundary. A file that exists but is not visible to the current viewer\nreturns `404` rather than `403` to avoid revealing the file's existence.\n\nByte downloads are limited to 32 MiB (33,554,432 bytes). The storage provider\nenforces this limit on actual content, independently of stored size metadata.\nLarger content returns HTTP `413` with error code `content_too_large`.\n", + "operationId": "get_api_v1_files__file_download", + "parameters": [ + { + "description": "File ID (`fil_...`) of the file to download.", + "example": "string", + "in": "path", + "name": "file", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "*/*": { + "schema": { + "format": "binary", + "type": "string" + } + } + }, + "description": "Raw binary content of the file, served with the file's stored MIME type." + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Forbidden - app scope required" + }, + "404": { + "description": "File not found" + }, + "413": { + "description": "File content exceeds the 32 MiB download limit" + }, + "502": { + "description": "File content temporarily unavailable" + } + }, + "summary": "Download a file's bytes", + "x-auth": [ + "publishable_key", + "bearer" + ] } }, "/api/v1/files/{file}/org_logo": { @@ -45145,7 +48657,11 @@ "summary": "List knowledge sources", "x-auth": [ "publishable_key", - "bearer" + "bearer", + "device_flow" + ], + "x-required-scopes": [ + "knowledge:read" ] }, "post": { @@ -45677,13 +49193,17 @@ "key": "value" }, "raw_content": {}, + "structured_data": "string", + "structured_data_summary": "string", "type": "gmail" } - ] + ], + "degraded": true, + "effective_mode": "hybrid" }, "properties": { "data": { - "description": "Array of matching knowledge items ordered by relevance score descending.", + "description": "Array of matching knowledge items ordered by relevance score descending. An item indexed from a message that has structured data attached also carries `structured_data` and `structured_data_summary`, the record's search summary computed at read time. `content` is still the indexed text and may be stale.", "example": [ { "content": "ArchAstro connects your agents to external knowledge sources for real-time context retrieval.", @@ -45695,6 +49215,8 @@ "key": "value" }, "raw_content": {}, + "structured_data": "string", + "structured_data_summary": "string", "type": "gmail" } ], @@ -45710,6 +49232,8 @@ "key": "value" }, "raw_content": {}, + "structured_data": "string", + "structured_data_summary": "string", "type": "gmail" }, "properties": { @@ -45755,6 +49279,18 @@ "example": {}, "type": "object" }, + "structured_data": { + "description": "Public ID (`sda_...`) of the structured-data record attached to the source message. Present only for such items on source search.", + "example": "string", + "nullable": true, + "type": "string" + }, + "structured_data_summary": { + "description": "Search summary of that record, computed when the request is served. When present, `content` is the indexed text and may be stale.", + "example": "string", + "nullable": true, + "type": "string" + }, "type": { "description": "Type identifier of the parent knowledge source (e.g. `\"gmail\"`, `\"github_activity\"`). Returns `\"unknown\"` when the source association is not loaded.", "example": "gmail", @@ -45768,6 +49304,21 @@ "type": "object" }, "type": "array" + }, + "degraded": { + "description": "True when a `hybrid` search ran fulltext only because the vector leg was unavailable. Absent when the query was empty.", + "example": true, + "type": "boolean" + }, + "effective_mode": { + "description": "Retrieval mode that actually ran. Differs from the requested `mode` when a `hybrid` search fell back to `fulltext`. Absent when the query was empty.", + "enum": [ + "hybrid", + "vector", + "fulltext" + ], + "example": "hybrid", + "type": "string" } }, "required": [ @@ -45795,15 +49346,59 @@ "summary": "Search within a knowledge source", "x-auth": [ "publishable_key", - "bearer" + "bearer", + "device_flow" + ], + "x-required-scopes": [ + "knowledge:read" ] } }, "/api/v1/kv": { "get": { - "description": "Returns key-value storage entries in one of two modes depending on the caller's\nauth scope.\n\n**User-JWT callers** receive a flat list of all their own entries with no\npagination fields. The `page`, `page_size`, `user`, `user_search`, and `key`\nparams are ignored.\n\n**Developer and server-to-server callers** receive a page-based paginated\nresponse across all users within the caller's app. Use `user` to scope results\nto a single user, `user_search` to do a substring match on email or full name,\nand `key` to filter entries whose key starts with the given prefix. Results are\nordered by creation time descending.\n", + "description": "Returns key-value storage entries in one of two modes depending on the caller's\nauth scope.\n\n**User-JWT callers** receive a flat list of all their own entries with no\npagination fields. The `page`, `page_size`, `user`, `user_search`, and `key`\nparams are ignored.\n\n**Developer and server-to-server callers** receive a page-based paginated\nresponse across all users within the caller's app. Use `user` to scope results\nto a single user, `user_search` to do a substring match on email or full name,\nand `key` to filter entries whose key starts with the given prefix. Results are\nordered by update time descending. Supplying org, team, agent, or system selects\na single owner's flat list instead. Expired entries are excluded in every mode.\n", "operationId": "get_api_v1_kv", "parameters": [ + { + "description": "Organization scope for the owner.", + "example": "string", + "in": "query", + "name": "org", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "Team owner ID.", + "example": "string", + "in": "query", + "name": "team", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "Agent owner ID.", + "example": "string", + "in": "query", + "name": "agent", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "Select system ownership within the app or organization.", + "example": true, + "in": "query", + "name": "system", + "required": false, + "schema": { + "type": "boolean" + } + }, { "description": "Page number to retrieve. Applies to developer and server-to-server callers only. Defaults to 1.", "example": 1, @@ -45873,7 +49468,10 @@ "description": "Unauthorized" }, "403": { - "description": "App-scoped token required. Use a token scoped to the target app." + "description": "Forbidden; App-scoped token required. Use a token scoped to the target app." + }, + "422": { + "description": "Invalid parameters" } }, "summary": "List key-value storage entries", @@ -45883,7 +49481,7 @@ ] }, "post": { - "description": "Creates a new key-value storage entry for the target user under the given key.\nThe key must not already exist for this user; use the upsert endpoint to create\nor overwrite in a single call.\n\nEnd-user (user-JWT) callers always write to their own storage. Developer and\nserver-to-server callers must supply a `user` param identifying the target user\nwithin their app's scope. Attempting to write for a user in a different app\nreturns 404.\n", + "description": "Creates a key once per owner. An existing key returns HTTP 409 conflict, including expired rows awaiting sweep.\n\nUser-JWT callers use their own storage. Elevated callers select an owner with\nsystem: true, team, user, or agent (in that priority order). An org alone selects\nsystem ownership within that organization; all owners must be in the app scope.\nCreate and upsert accept a positive ttl_seconds; absent means no expiry.\n\nScript binding (`kv.create`): the entry is owned by the triggering\nautomation's owner; scripts pass no owner params. A duplicate key\nreturns a script Err with code \"conflict\" instead of raising.\n", "operationId": "post_api_v1_kv", "parameters": [], "requestBody": { @@ -45891,18 +49489,48 @@ "application/json": { "schema": { "example": { + "agent": "string", "key": "string", + "org": "string", + "system": true, + "team": "string", + "ttl_seconds": 1, "user": "string", "value": "string" }, "properties": { + "agent": { + "description": "Agent owner ID.", + "example": "string", + "type": "string" + }, "key": { "description": "Storage key for the entry. Must be a non-empty string unique to this user.", "example": "string", "type": "string" }, + "org": { + "description": "Organization scope for the owner.", + "example": "string", + "type": "string" + }, + "system": { + "description": "Select system ownership within the app or organization.", + "example": true, + "type": "boolean" + }, + "team": { + "description": "Team owner ID.", + "example": "string", + "type": "string" + }, + "ttl_seconds": { + "description": "Positive lifetime in seconds; omitted means no expiry.", + "example": 1, + "type": "integer" + }, "user": { - "description": "Target user ID. Required when calling as a developer or with a server-to-server key; ignored for end-user callers.", + "description": "User owner ID. Elevated callers may instead select team, agent, org, or system ownership.", "example": "string", "type": "string" }, @@ -45945,6 +49573,9 @@ "404": { "description": "User not found" }, + "409": { + "description": "Conflict" + }, "422": { "description": "Invalid parameters" } @@ -45958,7 +49589,7 @@ }, "/api/v1/kv/{key}": { "delete": { - "description": "Permanently deletes the key-value storage entry identified by `key` for the\ntarget user. Returns 204 No Content on success and 404 if the entry does not\nexist.\n\nEnd-user (user-JWT) callers can only delete entries they own. Developer and\nserver-to-server callers must supply a `user` param identifying the target user\nwithin their app's scope.\n", + "description": "Deletes an unexpired entry by owner and key. Returns 204, or 404 when absent.\n\nUser-JWT callers use their own storage. Elevated callers select an owner with\nsystem: true, team, user, or agent (in that priority order). An org alone selects\nsystem ownership within that organization; all owners must be in the app scope.\nCreate and upsert accept a positive ttl_seconds; absent means no expiry.\n\nScript binding (`kv.delete`): removes the entry owned by the triggering\nautomation's owner; scripts pass no owner params.\n", "operationId": "delete_api_v1_kv__key", "parameters": [ { @@ -45973,8 +49604,36 @@ } ], "responses": { - "204": { - "description": "Empty response body. HTTP 204 No Content on success." + "200": { + "content": { + "application/json": { + "schema": { + "description": "Confirmation that the entry was deleted.", + "example": { + "deleted": true, + "key": "string" + }, + "properties": { + "deleted": { + "description": "Always `true` when the deletion succeeds.", + "example": true, + "type": "boolean" + }, + "key": { + "description": "Storage key of the deleted entry.", + "example": "string", + "type": "string" + } + }, + "required": [ + "deleted", + "key" + ], + "type": "object" + } + } + }, + "description": "Successful response" }, "400": { "description": "Bad request" @@ -45996,9 +49655,49 @@ ] }, "get": { - "description": "Returns the key-value storage entry identified by `key` for the target user.\nReturns 404 if no entry exists for that key.\n\nEnd-user (user-JWT) callers retrieve entries from their own storage. Developer\nand server-to-server callers must supply a `user` param identifying the target\nuser within their app's scope.\n", + "description": "Returns an unexpired entry by owner and key, or 404.\n\nUser-JWT callers use their own storage. Elevated callers select an owner with\nsystem: true, team, user, or agent (in that priority order). An org alone selects\nsystem ownership within that organization; all owners must be in the app scope.\nCreate and upsert accept a positive ttl_seconds; absent means no expiry.\n\nScript binding (`kv.get`): reads the entry owned by the triggering\nautomation's owner; scripts pass no owner params.\n", "operationId": "get_api_v1_kv__key", "parameters": [ + { + "description": "Organization scope for the owner.", + "example": "string", + "in": "query", + "name": "org", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "Team owner ID.", + "example": "string", + "in": "query", + "name": "team", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "Agent owner ID.", + "example": "string", + "in": "query", + "name": "agent", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "Select system ownership within the app or organization.", + "example": true, + "in": "query", + "name": "system", + "required": false, + "schema": { + "type": "boolean" + } + }, { "description": "Storage key of the entry to retrieve. Must be a non-empty string.", "example": "string", @@ -46010,7 +49709,7 @@ } }, { - "description": "Target user ID. Required when calling as a developer or with a server-to-server key; ignored for end-user callers.", + "description": "User owner ID. Elevated callers may instead select team, agent, org, or system ownership.", "example": "string", "in": "query", "name": "user", @@ -46048,10 +49747,11 @@ "x-auth": [ "publishable_key", "bearer" - ] + ], + "x-sdk-name": "get" }, "put": { - "description": "Creates a new key-value storage entry for the given `key`, or overwrites the\nvalue if an entry already exists. This is the idempotent alternative to the\ncreate endpoint: safe to call regardless of whether the key already exists.\n\nEnd-user (user-JWT) callers always write to their own storage. Developer and\nserver-to-server callers must supply a `user` param identifying the target user\nwithin their app's scope. Attempting to write for a user in a different app\nreturns 404.\n", + "description": "Creates or replaces a value and its expiry. Omitted ttl_seconds clears any previous expiry.\n\nUser-JWT callers use their own storage. Elevated callers select an owner with\nsystem: true, team, user, or agent (in that priority order). An org alone selects\nsystem ownership within that organization; all owners must be in the app scope.\nCreate and upsert accept a positive ttl_seconds; absent means no expiry.\n\nScript binding (`kv.upsert`): overwrites the entry owned by the triggering\nautomation's owner; scripts pass no owner params.\n", "operationId": "put_api_v1_kv__key", "parameters": [ { @@ -46070,12 +49770,42 @@ "application/json": { "schema": { "example": { + "agent": "string", + "org": "string", + "system": true, + "team": "string", + "ttl_seconds": 1, "user": "string", "value": "string" }, "properties": { + "agent": { + "description": "Agent owner ID.", + "example": "string", + "type": "string" + }, + "org": { + "description": "Organization scope for the owner.", + "example": "string", + "type": "string" + }, + "system": { + "description": "Select system ownership within the app or organization.", + "example": true, + "type": "boolean" + }, + "team": { + "description": "Team owner ID.", + "example": "string", + "type": "string" + }, + "ttl_seconds": { + "description": "Positive lifetime in seconds; omitted means no expiry.", + "example": 1, + "type": "integer" + }, "user": { - "description": "Target user ID. Required when calling as a developer or with a server-to-server key; ignored for end-user callers.", + "description": "User owner ID. Elevated callers may instead select team, agent, org, or system ownership.", "example": "string", "type": "string" }, @@ -46430,7 +50160,11 @@ "summary": "List a user's notifications", "x-auth": [ "publishable_key", - "bearer" + "bearer", + "device_flow" + ], + "x-required-scopes": [ + "notifications:read" ] } }, @@ -46459,7 +50193,7 @@ }, "/api/v1/notifications/send": { "post": { - "description": "Delivers a custom-typed notification to one of the calling app's users.\nApps define notification types by declaring `NotificationType` config objects\nin their bundle (one per `lookup_key`). Supply the type as\n`\"custom:\"` and provide a `data` map that is merged with\nplatform-provided context to render the notification's display fields.\n\nOnly app-scoped tokens may call this endpoint — user tokens are rejected with\n403. The app scope is stamped onto the notification automatically; an app\ncannot target recipients outside its tenant. Built-in platform types such as\n`\"app_info\"` and `\"billing_alert\"` are not accepted here.\n\nPass `idempotency_key` to deduplicate sends. If you call this endpoint twice\nwith the same `idempotency_key` for the same recipient, the second call\nreturns the original notification without creating a duplicate. The key is\nscoped to the calling app, so the same raw key used by different apps cannot\ncollide.\n", + "description": "Delivers a custom-typed notification to one of the calling app's users.\nApps define notification types by declaring `NotificationType` config objects\nin their bundle (one per `lookup_key`). Supply the type as\n`\"custom:\"` and provide a `data` map that is merged with\nplatform-provided context to render the notification's display fields.\n\nOnly app-scoped tokens may call this endpoint — user tokens are rejected with\n403. The app scope is stamped onto the notification automatically; an app\ncannot target recipients outside its tenant. Built-in platform types such as\n`\"app_info\"` and `\"billing_alert\"` are not accepted here.\n\nThe `notifications.send` script binding also accepts the viewer a script runs\nas: a user, an agent, or a team's system viewer. Such a sender may notify only\na user it can see in its own organization and sandbox. When the sender is a\nuser, the recipient must also be able to see the sender. An agent cannot see\nuser records, so an agent sender must name a source message: it may then\nnotify a user in its own organization and sandbox who can read that message.\n\nPass `thread` and `message` together to name the message the notification is\nabout. The send is then refused unless that message is in that thread and both\nthe sender and the recipient can read it, so a notification cannot quote a\nmessage its recipient cannot open.\n\nPass `idempotency_key` to deduplicate sends. If you call this endpoint twice\nwith the same `idempotency_key` for the same recipient, the second call\nreturns the original notification without creating a duplicate. The key is\nscoped to the calling app, so the same raw key used by different apps cannot\ncollide.\n", "operationId": "post_api_v1_notifications_send", "parameters": [], "requestBody": { @@ -46469,6 +50203,8 @@ "example": { "data": {}, "idempotency_key": "string", + "message": "string", + "thread": "string", "type": "string", "user": "string" }, @@ -46483,6 +50219,16 @@ "example": "string", "type": "string" }, + "message": { + "description": "Source message (`msg_...`) that the sender and the recipient must both be able to read.", + "example": "string", + "type": "string" + }, + "thread": { + "description": "Thread (`thr_...`) of the source message. Requires `message`.", + "example": "string", + "type": "string" + }, "type": { "description": "Custom notification type identifier in the form `\"custom:\"`, where `` matches a `NotificationType` config declared in the calling app's bundle.", "example": "string", @@ -46578,7 +50324,11 @@ "summary": "Get the unread notification count", "x-auth": [ "publishable_key", - "bearer" + "bearer", + "device_flow" + ], + "x-required-scopes": [ + "notifications:read" ] } }, @@ -46652,7 +50402,11 @@ "summary": "Mark a notification as read", "x-auth": [ "publishable_key", - "bearer" + "bearer", + "device_flow" + ], + "x-required-scopes": [ + "notifications:write" ] } }, @@ -46925,6 +50679,34 @@ "before_cursor": "string", "data": [ { + "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" + } + ] + }, "agent": "agt_0aBcDeFgHiJkLmNoPqRsTu", "content_type": "application/json", "created_at": "2024-01-01T00:00:00Z", @@ -46972,6 +50754,34 @@ "data": { "example": [ { + "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" + } + ] + }, "agent": "agt_0aBcDeFgHiJkLmNoPqRsTu", "content_type": "application/json", "created_at": "2024-01-01T00:00:00Z", @@ -47005,6 +50815,34 @@ "items": { "description": "A versioned artifact produced or managed by an agent, such as a generated file, report, or code output.", "example": { + "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" + } + ] + }, "agent": "agt_0aBcDeFgHiJkLmNoPqRsTu", "content_type": "application/json", "created_at": "2024-01-01T00:00:00Z", @@ -47035,6 +50873,180 @@ "version": 1 }, "properties": { + "acl": { + "description": "Access control list for the artifact. Contains a `grants` array where each entry specifies `principal_type`, `principal`, and `actions` (`read`, `write`). `null` when the artifact has no grants or the viewer is not its owner.", + "example": { + "add": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "grants": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "remove": [ + { + "principal": "string", + "principal_type": "user" + } + ] + }, + "nullable": true, + "properties": { + "add": { + "description": "Patch mode: grants to add or merge into the existing list. Cannot be combined with `grants`.", + "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": [ + { + "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" + }, + "remove": { + "description": "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", + "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" + }, "agent": { "description": "ID of the agent that produced this artifact (`agt_...`). `null` if not agent-produced.", "example": "agt_0aBcDeFgHiJkLmNoPqRsTu", @@ -47388,6 +51400,4702 @@ ] } }, + "/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": "Organization ID (`org_...`) owning the tasks.", + "example": "string", + "in": "path", + "name": "org", + "required": true, + "schema": { + "type": "string" + } + }, + { + "description": "Exact source scope; supply all three source fields.", + "example": "string", + "in": "query", + "name": "source_scope", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "Exact source type.", + "example": "string", + "in": "query", + "name": "source_type", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "Exact source ID.", + "example": "string", + "in": "query", + "name": "source_id", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "Exact highest open priority, from 0 to 4.", + "example": 1, + "in": "query", + "name": "top_priority", + "required": false, + "schema": { + "type": "integer" + } + }, + { + "description": "Include epics with no non-closed tasks; defaults to false.", + "example": true, + "in": "query", + "name": "include_closed", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "description": "Maximum epics; defaults to 50, capped at 100.", + "example": 1, + "in": "query", + "name": "limit", + "required": false, + "schema": { + "type": "integer" + } + }, + { + "description": "Opaque forward cursor from the preceding 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": [ + { + "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" + } + ], + "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", + "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" + }, + "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" + }, + "type": "array" + }, + "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" + } + }, + "required": [ + "epic", + "counts", + "blocked_count", + "updated_at", + "root_blockers", + "root_blockers_partial", + "next_ready" + ], + "type": "object" + }, + "type": "array" + }, + "has_more": { + "example": true, + "type": "boolean" + }, + "no_epic_open_count": { + "example": 1, + "type": "integer" + } + }, + "required": [ + "data", + "has_more", + "no_epic_open_count" + ], + "type": "object" + } + } + }, + "description": "Successful response" + }, + "401": { + "description": "Unauthorized" + }, + "404": { + "description": "Organization not found" + }, + "422": { + "description": "Invalid filters or owner context" + } + }, + "summary": "List an organization's epic summaries", + "x-auth": [ + "publishable_key", + "bearer" + ] + } + }, + "/api/v1/orgs/{org}/tasks": { + "get": { + "description": "Returns org-owned tasks for the specified organization: rows with the org\ntenant and no narrower user/team/agent scope. Explicitly personal, team, or\nagent tasks are excluded here; list those via the user/team collections or\nfetch them directly when authorized.\n\nEvery organization member may list. App-scoped developer and\nserver-to-server callers supply the org in the route.\n", + "operationId": "get_api_v1_orgs__org_tasks", + "parameters": [ + { + "description": "Organization ID (`org_...`) whose org-owned tasks should be returned.", + "example": "string", + "in": "path", + "name": "org", + "required": true, + "schema": { + "type": "string" + } + }, + { + "description": "Filter tasks by status. One of `\"open\"`, `\"in_progress\"`, `\"in_review\"`, or `\"done\"`. Omit to return tasks in all statuses.", + "example": "string", + "in": "query", + "name": "status", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "Filter tasks assigned to a specific user. Provide the user's public ID (`usr_...`).", + "example": "string", + "in": "query", + "name": "owner_user", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "Filter tasks assigned to a specific agent. Provide the agent's public ID (`agi_...`).", + "example": "string", + "in": "query", + "name": "owner_agent", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "Filter tasks by priority, from 0 (highest) to 4 (lowest).", + "example": 1, + "in": "query", + "name": "priority", + "required": false, + "schema": { + "type": "integer" + } + }, + { + "description": "Return only tasks carrying this tag (matched against the canonical lowercase form).", + "example": "string", + "in": "query", + "name": "tag", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "Return only subtasks of the given task (`tsk_...`), or pass `none` to return only top-level tasks.", + "example": "string", + "in": "query", + "name": "parent", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "Return only 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": "Return only tasks whose source matches this object kind. Must be supplied with the other source filters.", + "example": "string", + "in": "query", + "name": "source_type", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "Return only tasks whose source matches this object identity. Must be supplied with the other source filters.", + "example": "string", + "in": "query", + "name": "source_id", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "Return only tasks with this exact epic label.", + "example": "string", + "in": "query", + "name": "epic", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "Restrict results to tasks whose name or description contains this string.", + "example": "string", + "in": "query", + "name": "search", + "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), or `\"priority\"` (most urgent first). Ties break by most recently created.", + "example": "string", + "in": "query", + "name": "sort", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "Sort direction, `\"asc\"` or `\"desc\"`. Defaults to `\"desc\"` for `created` and `\"asc\"` for `due_date` and `priority`.", + "example": "string", + "in": "query", + "name": "order", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "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.", + "example": "string", + "in": "query", + "name": "due_before", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "Return only tasks with a due date strictly after this ISO 8601 datetime or date. Tasks without a due date are excluded.", + "example": "string", + "in": "query", + "name": "due_after", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "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.", + "example": true, + "in": "query", + "name": "overdue", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "description": "When true, return only open tasks with no unfinished blockers and no active session lease. This is a projection snapshot; claim a lease before starting work.", + "example": true, + "in": "query", + "name": "ready", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "description": "When true, return paused, failed, or in-progress tasks with no lease or a past lease expiry.", + "example": true, + "in": "query", + "name": "attention", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "description": "Maximum number of tasks 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": "Filtered list of tasks for the organization.", + "example": { + "after_cursor": "string", + "before_cursor": "string", + "data": [ + { + "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", + "aggregate_version": 1, + "blocked_by_count": 1, + "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", + "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", + "is_blocked": true, + "is_stalled": true, + "links": { + "key": "value" + }, + "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", + "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", + "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", + "updated_at": "2024-01-01T00:00:00Z", + "user": "usr_0aBcDeFgHiJkLmNoPqRsTu" + } + ], + "has_more": true + }, + "properties": { + "after_cursor": { + "example": "string", + "nullable": true, + "type": "string" + }, + "before_cursor": { + "example": "string", + "nullable": true, + "type": "string" + }, + "data": { + "description": "Array of task objects matching the requested filters.", + "example": [ + { + "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", + "aggregate_version": 1, + "blocked_by_count": 1, + "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", + "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", + "is_blocked": true, + "is_stalled": true, + "links": { + "key": "value" + }, + "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", + "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, + "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", + "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", + "is_blocked": true, + "is_stalled": true, + "links": { + "key": "value" + }, + "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", + "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" + }, + "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" + }, + "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" + }, + "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" + }, + "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" + }, + "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 filters" + } + }, + "summary": "List an organization's tasks", + "x-auth": [ + "publishable_key", + "bearer", + "device_flow" + ], + "x-required-scopes": [ + "tasks:read" + ] + }, + "post": { + "description": "Creates a new org-owned task (org tenant, no narrower user/team/agent\nscope) and returns the full task object. User-authenticated calls are\nattributed to the authenticated user or agent. App-scoped developer and\nserver-to-server callers must provide an explicit `user` or `agent` actor\nfor the organization. Every referenced principal is validated against the\napp and organization before creation.\n", + "operationId": "post_api_v1_orgs__org_tasks", + "parameters": [ + { + "description": "Organization ID (`org_...`). The task will be owned by this organization.", + "example": "string", + "in": "path", + "name": "org", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "example": { + "agent": "string", + "task": { + "description": "An example description.", + "due_date": "2024-01-01T00:00:00Z", + "epic": "billing-cadence", + "id": "string", + "links": { + "key": "value" + }, + "metadata": { + "key": "value" + }, + "name": "Example Name", + "owner_agent": "string", + "owner_user": "string", + "parent": "tsk_01j3k5m7n9p2r4s6t8v0w1x2", + "priority": 2, + "project_id": "string", + "source_id": "ArchAstro/firstlanding", + "source_scope": "github.com", + "source_type": "repository", + "status": "open", + "tags": [ + "backend", + "q3-launch" + ], + "target_binary": "my-cli", + "target_version": "0.48.9", + "thread": "thr_01j3k5m7n9p2r4s6t8v0w1x2" + }, + "user": "string" + }, + "properties": { + "agent": { + "description": "Explicit acting agent (`agi_...`) for a developer or server-to-server call. Mutually exclusive with an acting `user`; the agent must belong to the organization.", + "example": "string", + "type": "string" + }, + "task": { + "description": "Attributes for the task to create. `name` is required; all other fields are optional.", + "example": { + "description": "An example description.", + "due_date": "2024-01-01T00:00:00Z", + "epic": "billing-cadence", + "id": "string", + "links": { + "key": "value" + }, + "metadata": { + "key": "value" + }, + "name": "Example Name", + "owner_agent": "string", + "owner_user": "string", + "parent": "tsk_01j3k5m7n9p2r4s6t8v0w1x2", + "priority": 2, + "project_id": "string", + "source_id": "ArchAstro/firstlanding", + "source_scope": "github.com", + "source_type": "repository", + "status": "open", + "tags": [ + "backend", + "q3-launch" + ], + "target_binary": "my-cli", + "target_version": "0.48.9", + "thread": "thr_01j3k5m7n9p2r4s6t8v0w1x2" + }, + "properties": { + "description": { + "description": "Optional long-form description or notes for the task. Supports plain text.", + "example": "An example description.", + "type": "string" + }, + "due_date": { + "description": "Date and time by which the task should be completed (ISO 8601). Omit to create the task without a due date.", + "example": "2024-01-01T00:00:00Z", + "format": "date-time", + "type": "string" + }, + "epic": { + "description": "Optional free-form grouping label.", + "example": "billing-cadence", + "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", + "type": "string" + }, + "links": { + "description": "Arbitrary key-value map of named URLs or references associated with the task (e.g. external ticket links).", + "example": { + "key": "value" + }, + "type": "object" + }, + "metadata": { + "description": "Arbitrary key-value map for storing application-specific data alongside the task. Omit to create the task with no metadata.", + "example": { + "key": "value" + }, + "type": "object" + }, + "name": { + "description": "Human-readable title for the task.", + "example": "Example Name", + "type": "string" + }, + "owner_agent": { + "description": "ID of the agent to assign as owner (`agi_...`). Mutually exclusive with `owner_user`; omit to leave the task unassigned.", + "example": "string", + "type": "string" + }, + "owner_user": { + "description": "ID of the user to assign as owner (`usr_...`). Mutually exclusive with `owner_agent`; omit to leave the task unassigned.", + "example": "string", + "type": "string" + }, + "parent": { + "description": "Create this task as a subtask of an existing top-level task (`tsk_...`). Subtasks nest exactly one level.", + "example": "tsk_01j3k5m7n9p2r4s6t8v0w1x2", + "type": "string" + }, + "priority": { + "description": "Priority level from `0` (highest) to `4` (lowest). Defaults to `2` (medium) when omitted.", + "example": 2, + "type": "integer" + }, + "project_id": { + "description": "Optional project ID (`prj_...`). Pass null to clear it.", + "example": "string", + "type": "string" + }, + "source_id": { + "description": "Source object identity (for example `ArchAstro/firstlanding`).", + "example": "ArchAstro/firstlanding", + "type": "string" + }, + "source_scope": { + "description": "Container of the work this task is about (for example `github.com`). Must be supplied with `source_type` and `source_id`.", + "example": "github.com", + "type": "string" + }, + "source_type": { + "description": "Kind of source object (for example `repository`).", + "example": "repository", + "type": "string" + }, + "status": { + "description": "Initial status for the task. One of `\"open\"`, `\"in_progress\"`, `\"in_review\"`, `\"paused\"`, `\"failed\"`, `\"superseding\"`, `\"done\"`, or `\"cancelled\"`. Defaults to `\"open\"` when omitted.", + "example": "open", + "type": "string" + }, + "tags": { + "description": "Labels for grouping and filtering (max 20, each up to 40 characters). Stored canonically: lowercase, trimmed, de-duplicated.", + "example": [ + "backend", + "q3-launch" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "target_binary": { + "description": "Binary that must run this work, as a lowercase identifier of 1-64 characters (letters, digits, `.`, `_`, `-`; for example `my-cli`). Must be supplied with `target_version`.", + "example": "my-cli", + "type": "string" + }, + "target_version": { + "description": "Minimum semantic version of `target_binary` that can run this work (`MAJOR.MINOR.PATCH` with optional prerelease and build, no leading `v`). Must be supplied with `target_binary`.", + "example": "0.48.9", + "type": "string" + }, + "thread": { + "description": "Bind the task to a thread (`thr_...`) owned by the same team or user as the task. A bound task appears in that thread's task scope, exactly like a task filed from inside the conversation. Omit for a task not tied to a conversation.", + "example": "thr_01j3k5m7n9p2r4s6t8v0w1x2", + "type": "string" + } + }, + "required": [ + "name" + ], + "type": "object" + }, + "user": { + "description": "Explicit acting user (`usr_...`) for a developer or server-to-server call. Mutually exclusive with an acting `agent`.", + "example": "string", + "type": "string" + } + }, + "required": [ + "task" + ], + "type": "object" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Task" + } + } + }, + "description": "The newly created task." + }, + "401": { + "description": "Unauthorized" + }, + "404": { + "description": "Organization not found" + }, + "409": { + "description": "Conflict" + }, + "422": { + "description": "Validation error" + } + }, + "summary": "Create a task for an organization", + "x-auth": [ + "publishable_key", + "bearer" + ] + } + }, + "/api/v1/orgs/{org}/tasks/blocker_cycles": { + "get": { + "description": "Runs an on-demand diagnostic over unfinished org-owned tasks for the\nspecified organization and returns a forward cursor-paginated page of\ncomplete cyclic blocker components. Detection is bounded to owners with at\nmost 100 unfinished tasks. This endpoint is read-only: cycles do not prevent\ntask updates, lease acquisition, or completion.\n", + "operationId": "get_api_v1_orgs__org_tasks_blocker_cycles", + "parameters": [ + { + "description": "Organization ID (`org_...`) whose org-owned tasks are diagnosed.", + "example": "string", + "in": "path", + "name": "org", + "required": true, + "schema": { + "type": "string" + } + }, + { + "description": "Maximum cycle components to return. Defaults to 50; maximum is 100.", + "example": 1, + "in": "query", + "name": "limit", + "required": false, + "schema": { + "type": "integer" + } + }, + { + "description": "Opaque cursor returned by the preceding page.", + "example": "string", + "in": "query", + "name": "after_cursor", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "description": "On-demand task blocker cycle diagnostics.", + "example": { + "after_cursor": "string", + "before_cursor": "string", + "data": [ + { + "tasks": [ + { + "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", + "aggregate_version": 1, + "blocked_by_count": 1, + "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", + "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", + "is_blocked": true, + "is_stalled": true, + "links": { + "key": "value" + }, + "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", + "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", + "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", + "updated_at": "2024-01-01T00:00:00Z", + "user": "usr_0aBcDeFgHiJkLmNoPqRsTu" + } + ] + } + ], + "has_more": true + }, + "properties": { + "after_cursor": { + "example": "string", + "type": "string" + }, + "before_cursor": { + "example": "string", + "type": "string" + }, + "data": { + "example": [ + { + "tasks": [ + { + "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", + "aggregate_version": 1, + "blocked_by_count": 1, + "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", + "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", + "is_blocked": true, + "is_stalled": true, + "links": { + "key": "value" + }, + "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", + "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", + "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", + "updated_at": "2024-01-01T00:00:00Z", + "user": "usr_0aBcDeFgHiJkLmNoPqRsTu" + } + ] + } + ], + "items": { + "description": "A strongly connected component of unfinished task blocker edges.", + "example": { + "tasks": [ + { + "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", + "aggregate_version": 1, + "blocked_by_count": 1, + "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", + "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", + "is_blocked": true, + "is_stalled": true, + "links": { + "key": "value" + }, + "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", + "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", + "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", + "updated_at": "2024-01-01T00:00:00Z", + "user": "usr_0aBcDeFgHiJkLmNoPqRsTu" + } + ] + }, + "properties": { + "tasks": { + "description": "Every unfinished task in this cyclic blocker component.", + "example": [ + { + "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", + "aggregate_version": 1, + "blocked_by_count": 1, + "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", + "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", + "is_blocked": true, + "is_stalled": true, + "links": { + "key": "value" + }, + "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", + "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, + "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", + "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", + "is_blocked": true, + "is_stalled": true, + "links": { + "key": "value" + }, + "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", + "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" + }, + "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" + }, + "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" + }, + "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" + }, + "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": [ + "tasks" + ], + "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 owner context or diagnostic limit" + } + }, + "summary": "List task blocker cycles for an organization", + "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", + "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": { + "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.", + "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`.", + "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, + "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", + "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", + "is_blocked": true, + "is_stalled": true, + "links": { + "key": "value" + }, + "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", + "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", + "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", + "updated_at": "2024-01-01T00:00:00Z", + "user": "usr_0aBcDeFgHiJkLmNoPqRsTu" + } + } + ], + "has_more": true + }, + "properties": { + "after_cursor": { + "example": "string", + "type": "string" + }, + "authoritative": { + "description": "Always false because projections can lag writes and a later claim can race this read.", + "example": true, + "type": "boolean" + }, + "before_cursor": { + "example": "string", + "type": "string" + }, + "data": { + "example": [ + { + "readiness": "ready", + "reason": "open_blockers", + "task": { + "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", + "aggregate_version": 1, + "blocked_by_count": 1, + "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", + "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", + "is_blocked": true, + "is_stalled": true, + "links": { + "key": "value" + }, + "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", + "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", + "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", + "updated_at": "2024-01-01T00:00:00Z", + "user": "usr_0aBcDeFgHiJkLmNoPqRsTu" + } + } + ], + "items": { + "description": "A task plus the server-calculated reason it is or is not ready.", + "example": { + "readiness": "ready", + "reason": "open_blockers", + "task": { + "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", + "aggregate_version": 1, + "blocked_by_count": 1, + "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", + "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", + "is_blocked": true, + "is_stalled": true, + "links": { + "key": "value" + }, + "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", + "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", + "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", + "updated_at": "2024-01-01T00:00:00Z", + "user": "usr_0aBcDeFgHiJkLmNoPqRsTu" + } + }, + "properties": { + "readiness": { + "description": "One of `ready`, `blocked`, or `leased`.", + "enum": [ + "ready", + "blocked", + "leased" + ], + "example": "ready", + "type": "string" + }, + "reason": { + "description": "Stable exclusion reason: `open_blockers` or `active_lease`; omitted when ready.", + "enum": [ + "open_blockers", + "active_lease" + ], + "example": "open_blockers", + "nullable": true, + "type": "string" + }, + "task": { + "description": "The task evaluated for readiness.", + "example": { + "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", + "aggregate_version": 1, + "blocked_by_count": 1, + "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", + "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", + "is_blocked": true, + "is_stalled": true, + "links": { + "key": "value" + }, + "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", + "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" + }, + "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" + }, + "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" + }, + "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" + }, + "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" + } + }, + "required": [ + "task", + "readiness" + ], + "type": "object" + }, + "type": "array" + }, + "has_more": { + "example": true, + "type": "boolean" + } + }, + "required": [ + "data", + "authoritative", + "has_more" + ], + "type": "object" + } + } + }, + "description": "Successful response" + }, + "401": { + "description": "Unauthorized" + }, + "404": { + "description": "Organization not found" + }, + "422": { + "description": "Invalid owner context or pagination cursor" + } + }, + "summary": "List an organization's ready tasks", + "x-auth": [ + "publishable_key", + "bearer" + ] + } + }, + "/api/v1/orgs/{org}/tasks/search": { + "get": { + "description": "Performs a full-text search over org-owned tasks for the specified\norganization and returns matching results. Combine `q` with the optional\nfilters to narrow the result set further. When no query is provided, the\nendpoint behaves like a filtered list.\n\nThe `query` field in the response echoes the effective search query.\nExplicitly personal, team, or agent tasks are excluded here.\n", + "operationId": "get_api_v1_orgs__org_tasks_search", + "parameters": [ + { + "description": "Organization ID (`org_...`) whose org-owned tasks are searched.", + "example": "string", + "in": "path", + "name": "org", + "required": true, + "schema": { + "type": "string" + } + }, + { + "description": "Full-text search query matched against task names and descriptions. Takes precedence over `query` when both are provided.", + "example": "string", + "in": "query", + "name": "q", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "Alias for `q`. Use `q` when possible; this parameter exists for compatibility.", + "example": "string", + "in": "query", + "name": "query", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "Filter results by status. One of `\"open\"`, `\"in_progress\"`, `\"in_review\"`, or `\"done\"`. Omit to include all statuses.", + "example": "string", + "in": "query", + "name": "status", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "Filter tasks assigned to a specific user. Provide the user's public ID (`usr_...`).", + "example": "string", + "in": "query", + "name": "owner_user", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "Filter tasks assigned to a specific agent. Provide the agent's public ID (`agi_...`).", + "example": "string", + "in": "query", + "name": "owner_agent", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "Filter tasks by priority, from 0 (highest) to 4 (lowest).", + "example": 1, + "in": "query", + "name": "priority", + "required": false, + "schema": { + "type": "integer" + } + }, + { + "description": "Return only tasks carrying this tag (matched against the canonical lowercase form).", + "example": "string", + "in": "query", + "name": "tag", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "Return only subtasks of the given task (`tsk_...`), or pass `none` to return only top-level tasks.", + "example": "string", + "in": "query", + "name": "parent", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "Return only 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": "Return only tasks whose source matches this object kind. Must be supplied with the other source filters.", + "example": "string", + "in": "query", + "name": "source_type", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "Return only tasks whose source matches this object identity. Must be supplied with the other source filters.", + "example": "string", + "in": "query", + "name": "source_id", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "Return only tasks with this exact epic label.", + "example": "string", + "in": "query", + "name": "epic", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "Maximum number of tasks 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": "Search results for the organization's tasks.", + "example": { + "after_cursor": "string", + "before_cursor": "string", + "data": [ + { + "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", + "aggregate_version": 1, + "blocked_by_count": 1, + "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", + "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", + "is_blocked": true, + "is_stalled": true, + "links": { + "key": "value" + }, + "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", + "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", + "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", + "updated_at": "2024-01-01T00:00:00Z", + "user": "usr_0aBcDeFgHiJkLmNoPqRsTu" + } + ], + "has_more": true, + "query": "string" + }, + "properties": { + "after_cursor": { + "example": "string", + "type": "string" + }, + "before_cursor": { + "example": "string", + "type": "string" + }, + "data": { + "description": "Array of task objects matching the query and filters.", + "example": [ + { + "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", + "aggregate_version": 1, + "blocked_by_count": 1, + "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", + "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", + "is_blocked": true, + "is_stalled": true, + "links": { + "key": "value" + }, + "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", + "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, + "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", + "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", + "is_blocked": true, + "is_stalled": true, + "links": { + "key": "value" + }, + "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", + "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" + }, + "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" + }, + "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" + }, + "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" + }, + "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" + }, + "has_more": { + "example": true, + "type": "boolean" + }, + "query": { + "example": "string", + "type": "string" + } + }, + "required": [ + "data", + "has_more", + "query" + ], + "type": "object" + } + } + }, + "description": "Successful response" + }, + "401": { + "description": "Unauthorized" + }, + "404": { + "description": "Organization not found" + }, + "422": { + "description": "Invalid filters" + } + }, + "summary": "Search an organization's tasks", + "x-auth": [ + "publishable_key", + "bearer" + ] + } + }, "/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", @@ -47404,7 +56112,7 @@ } }, { - "description": "Optional exact thread key, for example `archdev-room`.", + "description": "Optional exact thread key, for example `support-room`.", "example": "string", "in": "query", "name": "key", @@ -47517,8 +56225,10 @@ "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, @@ -47532,8 +56242,10 @@ "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 } @@ -47549,7 +56261,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "2024-01-01T00:00:00Z", @@ -47929,8 +56641,10 @@ "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, @@ -47944,8 +56658,10 @@ "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 } @@ -47961,7 +56677,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "2024-01-01T00:00:00Z", @@ -48338,8 +57054,10 @@ "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, @@ -48353,8 +57071,10 @@ "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 } @@ -48370,7 +57090,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "2024-01-01T00:00:00Z", @@ -48973,8 +57693,10 @@ "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, @@ -48988,8 +57710,10 @@ "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 } @@ -49005,7 +57729,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "2024-01-01T00:00:00Z", @@ -49381,8 +58105,10 @@ "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, @@ -49396,8 +58122,10 @@ "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 } @@ -49435,8 +58163,10 @@ "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, @@ -49450,8 +58180,10 @@ "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 } @@ -49608,8 +58340,10 @@ "description": "Array of available encoding variants for the media item (e.g. different resolutions). Present on `media` type only; omitted otherwise.", "example": [ { + "byte_size": 1, "content_type": "application/json", "created_at": "2024-01-01T00:00:00Z", + "duration_ms": 1, "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", "filename": "string", "height": 600, @@ -49623,8 +58357,10 @@ "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 } @@ -49632,8 +58368,10 @@ "items": { "description": "A processed variant of a media item, such as the original upload or a resized thumbnail, including a signed download URL resolved at request time.", "example": { + "byte_size": 1, "content_type": "application/json", "created_at": "2024-01-01T00:00:00Z", + "duration_ms": 1, "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", "filename": "string", "height": 600, @@ -49647,12 +58385,20 @@ "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 }, "properties": { + "byte_size": { + "description": "Size of the stored bytes.", + "example": 1, + "nullable": true, + "type": "integer" + }, "content_type": { "description": "MIME type of this variant's file (e.g., `\"image/jpeg\"`, `\"video/mp4\"`). `null` if the file is not loaded.", "example": "application/json", @@ -49665,6 +58411,12 @@ "format": "date-time", "type": "string" }, + "duration_ms": { + "description": "Client-declared video duration in milliseconds; not server-probed.", + "example": 1, + "nullable": true, + "type": "integer" + }, "file": { "description": "ID of the underlying storage file that backs this variant (`fil_...`).", "example": "fil_0aBcDeFgHiJkLmNoPqRsTu", @@ -49745,6 +58497,12 @@ }, "type": "object" }, + "sha256": { + "description": "Lowercase SHA-256 of the stored bytes.", + "example": "string", + "nullable": true, + "type": "string" + }, "updated_at": { "description": "When this variant was last updated (ISO 8601).", "example": "2024-01-01T00:00:00Z", @@ -49757,6 +58515,13 @@ "nullable": true, "type": "string" }, + "url_expires_at": { + "description": "Expiry of this variant's playable URL.", + "example": "2024-01-01T00:00:00Z", + "format": "date-time", + "nullable": true, + "type": "string" + }, "variant_key": { "description": "Identifier for this variant's processing tier. Common values include `\"original\"` (the unmodified upload) and `\"thumbnail\"` (a resized preview).", "example": "original", @@ -49816,7 +58581,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "items": { @@ -49825,7 +58590,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" }, "properties": { "attributes": { @@ -49847,7 +58612,7 @@ }, "type": { "description": "Stable context kind. Must start with a lowercase letter and contain only lowercase letters, numbers, dots, dashes, or underscores.", - "example": "archdev.pull_request", + "example": "myapp.pull_request", "type": "string" } }, @@ -50059,8 +58824,10 @@ "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, @@ -50074,8 +58841,10 @@ "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 } @@ -50091,7 +58860,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "2024-01-01T00:00:00Z", @@ -52634,7 +61403,11 @@ "summary": "List organization-visibility threads", "x-auth": [ "publishable_key", - "bearer" + "bearer", + "device_flow" + ], + "x-required-scopes": [ + "threads:read" ] }, "post": { @@ -53005,7 +61778,233 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PrivateServiceEnrollmentPage" + "$ref": "#/components/schemas/PrivateServiceEnrollmentPage" + } + } + }, + "description": "Successful response" + }, + "400": { + "description": "Bad request" + }, + "403": { + "description": "Forbidden" + }, + "404": { + "description": "Not found" + }, + "503": { + "description": "Private service control is unavailable" + } + }, + "summary": "List private service enrollments", + "x-auth": [ + "publishable_key", + "bearer" + ] + }, + "post": { + "description": "Creates or safely replaces an unreserved one-time connector enrollment token.", + "operationId": "post_api_v1_private_service_enrollments", + "parameters": [], + "requestBody": { + "content": { + "application/json": { + "schema": { + "example": { + "org": "string", + "private_service": "string" + }, + "properties": { + "org": { + "description": "Organization ID or slug. Required for developer and server callers.", + "example": "string", + "type": "string" + }, + "private_service": { + "description": "Private service ID (`pvs_...`).", + "example": "string", + "type": "string" + } + }, + "required": [ + "private_service" + ], + "type": "object" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreatedPrivateServiceEnrollment" + } + } + }, + "description": "Successful response" + }, + "400": { + "description": "Bad request" + }, + "403": { + "description": "Forbidden" + }, + "404": { + "description": "Not found" + }, + "409": { + "description": "Conflict" + }, + "503": { + "description": "Private service control is unavailable" + } + }, + "summary": "Create a private service enrollment", + "x-auth": [ + "publishable_key", + "bearer" + ] + } + }, + "/api/v1/private_service_enrollments/{private_service_enrollment_id}": { + "delete": { + "description": "Removes online connector authorization and prevents credential renewal.", + "operationId": "delete_api_v1_private_service_enrollments__private_service_enrollment_id", + "parameters": [ + { + "description": "Canonical certificate-bound service identity.", + "example": "string", + "in": "path", + "name": "private_service_enrollment_id", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "204": { + "description": "Authorization was durably revoked." + }, + "400": { + "description": "Bad request" + }, + "403": { + "description": "Forbidden" + }, + "404": { + "description": "Not found" + }, + "503": { + "description": "Private service control is unavailable" + } + }, + "summary": "Revoke a private service enrollment", + "x-auth": [ + "publishable_key", + "bearer" + ] + }, + "get": { + "operationId": "get_api_v1_private_service_enrollments__private_service_enrollment_id", + "parameters": [ + { + "description": "Organization ID or slug. Required for developer and server callers.", + "example": "string", + "in": "query", + "name": "org", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "Canonical certificate-bound service identity.", + "example": "string", + "in": "path", + "name": "private_service_enrollment_id", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PrivateServiceEnrollment" + } + } + }, + "description": "Successful response" + }, + "400": { + "description": "Bad request" + }, + "403": { + "description": "Forbidden" + }, + "404": { + "description": "Not found" + }, + "503": { + "description": "Private service control is unavailable" + } + }, + "summary": "Retrieve a private service enrollment", + "x-auth": [ + "publishable_key", + "bearer" + ] + } + }, + "/api/v1/private_services": { + "get": { + "operationId": "get_api_v1_private_services", + "parameters": [ + { + "description": "Organization ID or slug. Required for developer and server callers.", + "example": "string", + "in": "query", + "name": "org", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "Page number. Defaults to 1.", + "example": 1, + "in": "query", + "name": "page", + "required": false, + "schema": { + "type": "integer" + } + }, + { + "description": "Results per page. Defaults to 25; maximum is 100.", + "example": 1, + "in": "query", + "name": "page_size", + "required": false, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PrivateServicePage" } } }, @@ -53024,38 +62023,89 @@ "description": "Private service control is unavailable" } }, - "summary": "List private service enrollments", + "summary": "List private services", "x-auth": [ "publishable_key", "bearer" ] }, "post": { - "description": "Creates or safely replaces an unreserved one-time connector enrollment token.", - "operationId": "post_api_v1_private_service_enrollments", + "description": "Creates one immutable private service in the selected organization.", + "operationId": "post_api_v1_private_services", "parameters": [], "requestBody": { "content": { "application/json": { "schema": { "example": { - "org": "string", - "private_service": "string" + "functions": [ + { + "description": "An example description.", + "input_schema": {}, + "name": "Example Name", + "output_schema": {} + } + ], + "org": "string" }, "properties": { + "functions": { + "description": "Complete callable contracts. Input schemas are required; output schemas are optional.", + "example": [ + { + "description": "An example description.", + "input_schema": {}, + "name": "Example Name", + "output_schema": {} + } + ], + "items": { + "description": "A documented callable operation exposed by a private service.", + "example": { + "description": "An example description.", + "input_schema": {}, + "name": "Example Name", + "output_schema": {} + }, + "properties": { + "description": { + "description": "Human-readable guidance describing when and why to call the operation.", + "example": "An example description.", + "type": "string" + }, + "input_schema": { + "description": "JSON Schema Draft 7 object describing the operation's argument object.", + "example": {}, + "type": "object" + }, + "name": { + "description": "Stable operation name used when invoking the private service.", + "example": "Example Name", + "type": "string" + }, + "output_schema": { + "description": "Optional JSON Schema Draft 7 object describing the successful result.", + "example": {}, + "type": "object" + } + }, + "required": [ + "name", + "description", + "input_schema" + ], + "type": "object" + }, + "type": "array" + }, "org": { "description": "Organization ID or slug. Required for developer and server callers.", "example": "string", "type": "string" - }, - "private_service": { - "description": "Private service ID (`pvs_...`).", - "example": "string", - "type": "string" } }, "required": [ - "private_service" + "functions" ], "type": "object" } @@ -53068,11 +62118,11 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreatedPrivateServiceEnrollment" + "$ref": "#/components/schemas/PrivateService" } } }, - "description": "Successful response" + "description": "The newly created private service." }, "400": { "description": "Bad request" @@ -53090,16 +62140,16 @@ "description": "Private service control is unavailable" } }, - "summary": "Create a private service enrollment", + "summary": "Create a private service", "x-auth": [ "publishable_key", "bearer" ] } }, - "/api/v1/private_service_enrollments/{private_service_enrollment_id}": { + "/api/v1/private_services/{private_service_id}": { "get": { - "operationId": "get_api_v1_private_service_enrollments__private_service_enrollment_id", + "operationId": "get_api_v1_private_services__private_service_id", "parameters": [ { "description": "Organization ID or slug. Required for developer and server callers.", @@ -53112,10 +62162,9 @@ } }, { - "description": "Canonical certificate-bound service identity.", "example": "string", "in": "path", - "name": "private_service_enrollment_id", + "name": "private_service_id", "required": true, "schema": { "type": "string" @@ -53127,7 +62176,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PrivateServiceEnrollment" + "$ref": "#/components/schemas/PrivateService" } } }, @@ -53146,45 +62195,86 @@ "description": "Private service control is unavailable" } }, - "summary": "Retrieve a private service enrollment", + "summary": "Retrieve a private service", "x-auth": [ "publishable_key", "bearer" ] } }, - "/api/v1/private_services": { - "get": { - "operationId": "get_api_v1_private_services", - "parameters": [ - { - "description": "Organization ID or slug. Required for developer and server callers.", - "example": "string", - "in": "query", - "name": "org", - "required": false, - "schema": { - "type": "string" + "/api/v1/relays": { + "post": { + "description": "Only the owning user in the same app may access this relay.", + "operationId": "post_api_v1_relays", + "parameters": [], + "requestBody": { + "content": { + "application/json": { + "schema": { + "example": { + "purpose": "string", + "ttl_seconds": 1 + }, + "properties": { + "purpose": { + "example": "string", + "type": "string" + }, + "ttl_seconds": { + "example": 1, + "type": "integer" + } + }, + "required": [ + "purpose", + "ttl_seconds" + ], + "type": "object" + } } }, - { - "description": "Page number. Defaults to 1.", - "example": 1, - "in": "query", - "name": "page", - "required": false, - "schema": { - "type": "integer" - } + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Relay" + } + } + }, + "description": "Successful response" + }, + "403": { + "description": "Forbidden" }, + "404": { + "description": "Not found" + }, + "422": { + "description": "Invalid parameters" + } + }, + "summary": "Create an owner-only relay", + "x-auth": [ + "publishable_key", + "bearer" + ] + } + }, + "/api/v1/relays/{relay}": { + "delete": { + "description": "Only the owning user in the same app may access this relay.", + "operationId": "delete_api_v1_relays__relay", + "parameters": [ { - "description": "Results per page. Defaults to 25; maximum is 100.", - "example": 1, - "in": "query", - "name": "page_size", - "required": false, + "example": "string", + "in": "path", + "name": "relay", + "required": true, "schema": { - "type": "integer" + "type": "string" } } ], @@ -53193,128 +62283,52 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PrivateServicePage" + "$ref": "#/components/schemas/Relay" } } }, "description": "Successful response" }, - "400": { - "description": "Bad request" - }, "403": { "description": "Forbidden" }, "404": { "description": "Not found" }, - "503": { - "description": "Private service control is unavailable" + "422": { + "description": "Invalid parameters" } }, - "summary": "List private services", + "summary": "Delete an owner-only relay", "x-auth": [ "publishable_key", "bearer" ] }, - "post": { - "description": "Creates one immutable private service in the selected organization.", - "operationId": "post_api_v1_private_services", - "parameters": [], - "requestBody": { - "content": { - "application/json": { - "schema": { - "example": { - "functions": [ - { - "description": "An example description.", - "input_schema": {}, - "name": "Example Name", - "output_schema": {} - } - ], - "org": "string" - }, - "properties": { - "functions": { - "description": "Complete callable contracts. Input schemas are required; output schemas are optional.", - "example": [ - { - "description": "An example description.", - "input_schema": {}, - "name": "Example Name", - "output_schema": {} - } - ], - "items": { - "description": "A documented callable operation exposed by a private service.", - "example": { - "description": "An example description.", - "input_schema": {}, - "name": "Example Name", - "output_schema": {} - }, - "properties": { - "description": { - "description": "Human-readable guidance describing when and why to call the operation.", - "example": "An example description.", - "type": "string" - }, - "input_schema": { - "description": "JSON Schema Draft 7 object describing the operation's argument object.", - "example": {}, - "type": "object" - }, - "name": { - "description": "Stable operation name used when invoking the private service.", - "example": "Example Name", - "type": "string" - }, - "output_schema": { - "description": "Optional JSON Schema Draft 7 object describing the successful result.", - "example": {}, - "type": "object" - } - }, - "required": [ - "name", - "description", - "input_schema" - ], - "type": "object" - }, - "type": "array" - }, - "org": { - "description": "Organization ID or slug. Required for developer and server callers.", - "example": "string", - "type": "string" - } - }, - "required": [ - "functions" - ], - "type": "object" - } + "get": { + "description": "Only the owning user in the same app may access this relay.", + "operationId": "get_api_v1_relays__relay", + "parameters": [ + { + "example": "string", + "in": "path", + "name": "relay", + "required": true, + "schema": { + "type": "string" } - }, - "required": true - }, + } + ], "responses": { "200": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PrivateService" + "$ref": "#/components/schemas/Relay" } } }, - "description": "The newly created private service." - }, - "400": { - "description": "Bad request" + "description": "Successful response" }, "403": { "description": "Forbidden" @@ -53322,69 +62336,76 @@ "404": { "description": "Not found" }, - "409": { - "description": "Conflict" - }, - "503": { - "description": "Private service control is unavailable" + "422": { + "description": "Invalid parameters" } }, - "summary": "Create a private service", + "summary": "Show an owner-only relay", "x-auth": [ "publishable_key", "bearer" ] } }, - "/api/v1/private_services/{private_service_id}": { - "get": { - "operationId": "get_api_v1_private_services__private_service_id", + "/api/v1/relays/{relay}/extend": { + "post": { + "description": "Only the owning user in the same app may access this relay.", + "operationId": "post_api_v1_relays__relay_extend", "parameters": [ - { - "description": "Organization ID or slug. Required for developer and server callers.", - "example": "string", - "in": "query", - "name": "org", - "required": false, - "schema": { - "type": "string" - } - }, { "example": "string", "in": "path", - "name": "private_service_id", + "name": "relay", "required": true, "schema": { "type": "string" } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "example": { + "ttl_seconds": 1 + }, + "properties": { + "ttl_seconds": { + "example": 1, + "type": "integer" + } + }, + "required": [ + "ttl_seconds" + ], + "type": "object" + } + } + }, + "required": true + }, "responses": { "200": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PrivateService" + "$ref": "#/components/schemas/Relay" } } }, "description": "Successful response" }, - "400": { - "description": "Bad request" - }, "403": { "description": "Forbidden" }, "404": { "description": "Not found" }, - "503": { - "description": "Private service control is unavailable" + "422": { + "description": "Invalid parameters" } }, - "summary": "Retrieve a private service", + "summary": "Extend an owner-only relay", "x-auth": [ "publishable_key", "bearer" @@ -53679,7 +62700,7 @@ }, "/api/v1/scripts/run": { "post": { - "description": "Executes the provided script source and returns the result value together\nwith any `print` output captured during the run. Use this endpoint to\nevaluate scripts interactively during development, or to drive automation\nfrom external tooling.\n\nThe script runs with the authenticated viewer's identity by default. Pass\n`run_as_user` to impersonate a specific user, or `run_as_agent` to run as\na specific agent, subject to the caller's delegation permissions. These two params are mutually exclusive — supplying both\nreturns a 422 error.\n\nRuntime environment variables resolved for the execution identity's app and organization are automatically injected\ninto the script's `variables.env` scope. When the script raises a runtime\nerror, the response still returns HTTP 200 with `error`, `findings`, and any\npartial output; the error is also recorded in the app's activity feed.\n", + "description": "Executes script source and returns the result value together with any\n`print` output captured during the run. Pass `script` for interactive\nevaluation, or `config` to run a stored Script config by ID. Server-side\nproducers (for example a webhook service emitting through `events.emit`)\nmust use `config`; raw source from those callers is not an authorized\napplication script.\n\nThe script runs with the authenticated viewer's identity by default. Org\ntargeting for secret-key callers comes from the `X-ArchAstro-Org-Id`\nheader, not from the body. Pass `run_as_user` to impersonate a specific\nuser, or `run_as_agent` to run as a specific agent, subject to the\ncaller's delegation permissions. These two params are mutually exclusive\n— supplying both returns a 422 error. `script` and `config` are also\nmutually exclusive.\n\nRuntime environment variables resolved for the execution identity's app and organization are automatically injected\ninto the script's `variables.env` scope. When the script raises a runtime\nerror, the response still returns HTTP 200 with `error`, `findings`, and any\npartial output; the error is also recorded in the app's activity feed.\n", "operationId": "post_api_v1_scripts_run", "parameters": [], "requestBody": { @@ -53687,13 +62708,26 @@ "application/json": { "schema": { "example": { + "config": "string", + "config_key": "string", "resolution_context_config": "string", "run_as_agent": "string", "run_as_user": "string", "scope": {}, - "script": "string" + "script": "string", + "thread": "string" }, "properties": { + "config": { + "description": "Stored Script config ID (`cfg_...`) whose current version is executed. Mutually exclusive with `script`. Required for server-side producers that must not supply raw source.", + "example": "string", + "type": "string" + }, + "config_key": { + "description": "`lookup_key` of an app-level Script config whose current version is executed. Resolved among the app's configs that belong to no organization, never an organization's config with the same key. Mutually exclusive with `script` and `config`.", + "example": "string", + "type": "string" + }, "resolution_context_config": { "description": "Optional Script config ID establishing the authorized installation context for imports.", "example": "string", @@ -53717,7 +62751,12 @@ }, "script": { "default": "", - "description": "The script source to execute. Defaults to an empty string.", + "description": "The script source to execute. Defaults to an empty string. Mutually exclusive with `config`.", + "example": "string", + "type": "string" + }, + "thread": { + "description": "Optional thread ID for agent execution. Requires run_as_agent, caller access to the thread, matching agent app and organization, and agent membership in the thread.", "example": "string", "type": "string" } @@ -53746,16 +62785,20 @@ "description": "Execution identity is not authorized" }, "404": { - "description": "Execution identity was not found" + "description": "Script config not found" }, "422": { - "description": "run_as_user and run_as_agent are mutually exclusive" + "description": "config_key is mutually exclusive with script and config" } }, "summary": "Execute a workflow script", "x-auth": [ "publishable_key", - "bearer" + "bearer", + "device_flow" + ], + "x-required-scopes": [ + "scripts:run_config" ] } }, @@ -54197,7 +63240,7 @@ "description": "Unauthorized" }, "403": { - "description": "Forbidden; The Slack integration referenced by this binding is not visible to the caller; This private channel is member-managed; managing its agent requires being a member of the channel" + "description": "Forbidden; The Slack integration referenced by this binding is not visible to the caller; This private channel is member-managed; managing its agent requires verified membership in the channel. Link your Slack account from the app's Slack App Home tab so your membership can be matched, or run `/archagent connect` from inside the channel" }, "404": { "description": "Not found; Agent not found" @@ -57077,6 +66120,57 @@ ] } }, + "/api/v1/task_ownership_conversions/{job_id}": { + "get": { + "description": "Returns only the requesting user's job status, even after task visibility changes.", + "operationId": "get_api_v1_task_ownership_conversions__job_id", + "parameters": [ + { + "description": "The accepted background job ID.", + "example": 1, + "in": "path", + "name": "job_id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TaskOwnershipJob" + } + } + }, + "description": "Current background job state." + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Forbidden" + }, + "404": { + "description": "Not found" + }, + "422": { + "description": "Invalid parameters" + } + }, + "summary": "Read the status of a task ownership conversion", + "x-auth": [ + "publishable_key", + "bearer", + "device_flow" + ], + "x-required-scopes": [ + "tasks:read" + ] + } + }, "/api/v1/tasks/{task}": { "delete": { "description": "Deletes a task from task lists and detail views. The task event stream is\nretained for auditability, while comments are removed and direct subtasks\nare promoted to top-level tasks.\n\nThe delete event is accepted before the read model is updated. Clients\nshould remove the task from local collections immediately; subsequent reads\nconverge once the projection processes the event.\n\nAuthenticated users may delete tasks they can access using their session\nidentity. App-scoped developer and server-to-server callers must explicitly\nsupply the task's `org` and owner. `team` or `user` identifies that owner;\nwhen neither is present, `agent` identifies an agent-owned task. With a team\nor user owner, `agent` identifies the acting principal. Each reference is\nvalidated before deletion.\n", @@ -57195,7 +66289,11 @@ "summary": "Retrieve a task", "x-auth": [ "publishable_key", - "bearer" + "bearer", + "device_flow" + ], + "x-required-scopes": [ + "tasks:read" ] }, "put": { @@ -57235,6 +66333,8 @@ "owner_user": "string", "parent": "string", "priority": 1, + "project_id": "string", + "require_status_lease": true, "source_id": "string", "source_scope": "string", "source_type": "string", @@ -57242,6 +66342,8 @@ "tags": [ "string" ], + "target_binary": "string", + "target_version": "string", "team": "string", "user": "string" }, @@ -57324,6 +66426,16 @@ "example": 1, "type": "integer" }, + "project_id": { + "description": "Project ID (`prj_...`). Omit to preserve; pass null to clear.", + "example": "string", + "type": "string" + }, + "require_status_lease": { + "description": "Session clients must set true for status changes. A live lease then requires the holder's lease_id and lease_session_id; human and host overrides remain available.", + "example": true, + "type": "boolean" + }, "source_id": { "description": "Replacement source object identity. Must be supplied with the other source fields.", "example": "string", @@ -57354,6 +66466,16 @@ }, "type": "array" }, + "target_binary": { + "description": "Replacement target binary (for example `my-cli`): a lowercase identifier of 1-64 characters. Pass together with `target_version`, or pass both as null to clear the target.", + "example": "string", + "type": "string" + }, + "target_version": { + "description": "Replacement minimum semantic version of `target_binary` (for example `0.48.9`). Must be supplied with `target_binary`.", + "example": "string", + "type": "string" + }, "team": { "description": "Explicit owning team (`tem_...`) for a developer or server-to-server call.", "example": "string", @@ -57392,7 +66514,7 @@ "description": "Task not found" }, "409": { - "description": "Task lease has expired; Task lease does not match the current holder; Task changed since it was read" + "description": "Task is leased by another coding session; Task lease has expired; Task lease does not match the current holder; Task changed since it was read" }, "422": { "description": "Invalid parameters" @@ -57696,6 +66818,7 @@ "epic": "string", "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, + "is_stalled": true, "links": { "key": "value" }, @@ -57722,15 +66845,19 @@ "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", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -57783,6 +66910,7 @@ "epic": "string", "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, + "is_stalled": true, "links": { "key": "value" }, @@ -57809,15 +66937,19 @@ "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", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -57859,6 +66991,7 @@ "epic": "string", "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, + "is_stalled": true, "links": { "key": "value" }, @@ -57885,15 +67018,19 @@ "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", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -57913,7 +67050,7 @@ "type": "integer" }, "blocked_by_count": { - "description": "Number of 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.", + "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" }, @@ -58102,7 +67239,12 @@ "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 list/show reads; create/update responses report `false` until the next read.", + "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" }, @@ -58241,7 +67383,7 @@ "type": "string" }, "parent": { - "description": "ID of the parent task when this task is a subtask (`tsk_...`). `null` for top-level tasks. Subtasks nest exactly one level.", + "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" @@ -58251,6 +67393,12 @@ "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", @@ -58275,13 +67423,20 @@ "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 subtasks under this task. Computed on list/show reads; create/update responses may report 0 until the next read. Always 0 for subtasks.", + "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" }, @@ -58295,6 +67450,18 @@ }, "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" + }, "team": { "description": "ID of the team that owns this task (`tem_...`). `null` if the task is not scoped to a team.", "example": "tem_0aBcDeFgHiJkLmNoPqRsTu", @@ -58302,7 +67469,7 @@ "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.", + "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" @@ -58616,6 +67783,7 @@ "epic": "string", "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, + "is_stalled": true, "links": { "key": "value" }, @@ -58642,15 +67810,19 @@ "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", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -58703,6 +67875,7 @@ "epic": "string", "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, + "is_stalled": true, "links": { "key": "value" }, @@ -58729,15 +67902,19 @@ "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", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -58779,6 +67956,7 @@ "epic": "string", "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, + "is_stalled": true, "links": { "key": "value" }, @@ -58805,15 +67983,19 @@ "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", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -58833,7 +68015,7 @@ "type": "integer" }, "blocked_by_count": { - "description": "Number of 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.", + "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" }, @@ -59022,7 +68204,12 @@ "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 list/show reads; create/update responses report `false` until the next read.", + "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" }, @@ -59161,7 +68348,7 @@ "type": "string" }, "parent": { - "description": "ID of the parent task when this task is a subtask (`tsk_...`). `null` for top-level tasks. Subtasks nest exactly one level.", + "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" @@ -59171,6 +68358,12 @@ "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", @@ -59195,13 +68388,20 @@ "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 subtasks under this task. Computed on list/show reads; create/update responses may report 0 until the next read. Always 0 for subtasks.", + "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" }, @@ -59215,6 +68415,18 @@ }, "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" + }, "team": { "description": "ID of the team that owns this task (`tem_...`). `null` if the task is not scoped to a team.", "example": "tem_0aBcDeFgHiJkLmNoPqRsTu", @@ -59222,7 +68434,7 @@ "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.", + "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" @@ -59673,7 +68885,8 @@ "example": { "comment": { "body": "Looks good to me, ready for review." - } + }, + "expected_version": 1 }, "properties": { "comment": { @@ -59692,6 +68905,11 @@ "body" ], "type": "object" + }, + "expected_version": { + "description": "Reject the comment if the task changed since this version.", + "example": 1, + "type": "integer" } }, "required": [ @@ -60444,6 +69662,94 @@ ] } }, + "/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.", + "operationId": "post_api_v1_tasks__task_ownership_conversions", + "parameters": [ + { + "description": "Root task (`tsk_...`).", + "example": "string", + "in": "path", + "name": "task", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "example": { + "dest_agent": "string", + "dest_org": "string", + "dest_team": "string", + "dest_user": "string" + }, + "properties": { + "dest_agent": { + "description": "Destination agent (`agi_...`).", + "example": "string", + "type": "string" + }, + "dest_org": { + "description": "Destination organization (`org_...`).", + "example": "string", + "type": "string" + }, + "dest_team": { + "description": "Destination team (`tem_...`).", + "example": "string", + "type": "string" + }, + "dest_user": { + "description": "Destination user (`usr_...`). Supply exactly one destination.", + "example": "string", + "type": "string" + } + }, + "type": "object" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TaskOwnershipJob" + } + } + }, + "description": "The queued background job." + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Forbidden" + }, + "404": { + "description": "Not found" + }, + "409": { + "description": "Conflict" + }, + "422": { + "description": "Invalid parameters" + } + }, + "summary": "Convert ownership of a connected task graph", + "x-auth": [ + "publishable_key", + "bearer" + ] + } + }, "/api/v1/tasks/{task}/subtasks": { "get": { "description": "Returns a bounded page of the specified task's subtasks (tasks whose\n`parent` is this task), newest first. Subtasks nest exactly one level, so\nentries never have subtasks of their own. Privileged callers explicitly\nprovide the owning `team`, `user`, or `agent` and `org`.\n", @@ -60563,6 +69869,7 @@ "epic": "string", "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, + "is_stalled": true, "links": { "key": "value" }, @@ -60589,15 +69896,19 @@ "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", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -60650,6 +69961,7 @@ "epic": "string", "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, + "is_stalled": true, "links": { "key": "value" }, @@ -60676,15 +69988,19 @@ "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", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -60726,6 +70042,7 @@ "epic": "string", "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, + "is_stalled": true, "links": { "key": "value" }, @@ -60752,15 +70069,19 @@ "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", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -60780,7 +70101,7 @@ "type": "integer" }, "blocked_by_count": { - "description": "Number of 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.", + "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" }, @@ -60969,7 +70290,12 @@ "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 list/show reads; create/update responses report `false` until the next read.", + "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" }, @@ -61108,7 +70434,7 @@ "type": "string" }, "parent": { - "description": "ID of the parent task when this task is a subtask (`tsk_...`). `null` for top-level tasks. Subtasks nest exactly one level.", + "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" @@ -61118,6 +70444,12 @@ "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", @@ -61142,13 +70474,20 @@ "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 subtasks under this task. Computed on list/show reads; create/update responses may report 0 until the next read. Always 0 for subtasks.", + "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" }, @@ -61162,6 +70501,18 @@ }, "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" + }, "team": { "description": "ID of the team that owns this task (`tem_...`). `null` if the task is not scoped to a team.", "example": "tem_0aBcDeFgHiJkLmNoPqRsTu", @@ -61169,7 +70520,7 @@ "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.", + "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" @@ -61228,6 +70579,103 @@ ] } }, + "/api/v1/tasks/{task}/transfer_ownership": { + "post": { + "description": "Changes one task’s privacy owner at the supplied aggregate version. Assignment, creator, source identity, comments, and relationship IDs remain unchanged. Source and destination must have the same app and sandbox; the authenticated user must have authority over both scopes.", + "operationId": "post_api_v1_tasks__task_transfer_ownership", + "parameters": [ + { + "description": "Task (`tsk_...`).", + "example": "string", + "in": "path", + "name": "task", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "example": { + "dest_agent": "string", + "dest_org": "string", + "dest_team": "string", + "dest_user": "string", + "expected_version": 1 + }, + "properties": { + "dest_agent": { + "description": "Destination agent (`agi_...`).", + "example": "string", + "type": "string" + }, + "dest_org": { + "description": "Destination organization (`org_...`).", + "example": "string", + "type": "string" + }, + "dest_team": { + "description": "Destination team (`tem_...`).", + "example": "string", + "type": "string" + }, + "dest_user": { + "description": "Destination user (`usr_...`). Supply exactly one destination.", + "example": "string", + "type": "string" + }, + "expected_version": { + "description": "The task version reviewed by the caller.", + "example": 1, + "type": "integer" + } + }, + "required": [ + "expected_version" + ], + "type": "object" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Task" + } + } + }, + "description": "The task with its new owner." + }, + "401": { + "description": "Unauthorized" + }, + "403": { + "description": "Forbidden" + }, + "404": { + "description": "Not found" + }, + "409": { + "description": "Conflict; Task changed since it was read" + }, + "422": { + "description": "Invalid parameters" + } + }, + "summary": "Transfer one task to a different owner", + "x-auth": [ + "publishable_key", + "bearer" + ] + } + }, "/api/v1/team_memberships": { "get": { "description": "Returns a paginated list of team memberships across all teams accessible to\nthe authenticated caller. Use the `team`, `user`, and `agent` filters to\nnarrow results to a specific team or principal.\n\nThis endpoint requires S2S (service-to-service) authentication. Callers\nauthenticated with a user token receive a 401. Each membership includes the\nresolved `type` (`\"user\"`, `\"agent\"`, or `\"unknown\"`), display name, and\nprofile picture derived from the associated user or agent at request time.\n\nResults are returned in offset-based pages. Pass `page` and `page_size` to\nnavigate; the response includes `has_next` and `has_prev` to determine\nwhether adjacent pages exist.\n", @@ -62767,6 +72215,34 @@ "example": { "data": [ { + "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" + } + ] + }, "agent": "agt_0aBcDeFgHiJkLmNoPqRsTu", "content_type": "application/json", "created_at": "2024-01-01T00:00:00Z", @@ -62803,6 +72279,34 @@ "description": "Array of artifact objects belonging to the team.", "example": [ { + "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" + } + ] + }, "agent": "agt_0aBcDeFgHiJkLmNoPqRsTu", "content_type": "application/json", "created_at": "2024-01-01T00:00:00Z", @@ -62836,6 +72340,34 @@ "items": { "description": "A versioned artifact produced or managed by an agent, such as a generated file, report, or code output.", "example": { + "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" + } + ] + }, "agent": "agt_0aBcDeFgHiJkLmNoPqRsTu", "content_type": "application/json", "created_at": "2024-01-01T00:00:00Z", @@ -62866,6 +72398,180 @@ "version": 1 }, "properties": { + "acl": { + "description": "Access control list for the artifact. Contains a `grants` array where each entry specifies `principal_type`, `principal`, and `actions` (`read`, `write`). `null` when the artifact has no grants or the viewer is not its owner.", + "example": { + "add": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "grants": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "remove": [ + { + "principal": "string", + "principal_type": "user" + } + ] + }, + "nullable": true, + "properties": { + "add": { + "description": "Patch mode: grants to add or merge into the existing list. Cannot be combined with `grants`.", + "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": [ + { + "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" + }, + "remove": { + "description": "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", + "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" + }, "agent": { "description": "ID of the agent that produced this artifact (`agt_...`). `null` if not agent-produced.", "example": "agt_0aBcDeFgHiJkLmNoPqRsTu", @@ -63169,7 +72875,9 @@ } ] }, + "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", "created_at": "2024-01-01T00:00:00Z", + "expires_at": "2024-01-01T00:00:00Z", "fields": { "key": "value" }, @@ -63219,7 +72927,9 @@ } ] }, + "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", "created_at": "2024-01-01T00:00:00Z", + "expires_at": "2024-01-01T00:00:00Z", "fields": { "key": "value" }, @@ -63265,7 +72975,9 @@ } ] }, + "agent": "agi_0aBcDeFgHiJkLmNoPqRsTu", "created_at": "2024-01-01T00:00:00Z", + "expires_at": "2024-01-01T00:00:00Z", "fields": { "key": "value" }, @@ -63453,12 +73165,24 @@ }, "type": "object" }, + "agent": { + "description": "ID of the agent that owns this object (`agt_...`). `null` for other ownership types.", + "example": "agi_0aBcDeFgHiJkLmNoPqRsTu", + "type": "string" + }, "created_at": { "description": "When the custom object was created (ISO 8601).", "example": "2024-01-01T00:00:00Z", "format": "date-time", "type": "string" }, + "expires_at": { + "description": "Absolute expiry time (RFC 3339). Null when no expiry is set.", + "example": "2024-01-01T00:00:00Z", + "format": "date-time", + "nullable": true, + "type": "string" + }, "fields": { "description": "Map of field names to their current values as defined by the object's schema type.", "example": { @@ -67174,6 +76898,390 @@ ] } }, + "/api/v1/teams/{team}/task_epics": { + "get": { + "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": [ + { + "example": "string", + "in": "path", + "name": "team", + "required": true, + "schema": { + "type": "string" + } + }, + { + "example": "string", + "in": "query", + "name": "user", + "required": false, + "schema": { + "type": "string" + } + }, + { + "example": "string", + "in": "query", + "name": "org", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "Exact source scope; supply all three source fields.", + "example": "string", + "in": "query", + "name": "source_scope", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "Exact source type.", + "example": "string", + "in": "query", + "name": "source_type", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "Exact source ID.", + "example": "string", + "in": "query", + "name": "source_id", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "Exact highest open priority, from 0 to 4.", + "example": 1, + "in": "query", + "name": "top_priority", + "required": false, + "schema": { + "type": "integer" + } + }, + { + "description": "Include epics with no non-closed tasks; defaults to false.", + "example": true, + "in": "query", + "name": "include_closed", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "description": "Maximum epics; defaults to 50, capped at 100.", + "example": 1, + "in": "query", + "name": "limit", + "required": false, + "schema": { + "type": "integer" + } + }, + { + "description": "Opaque forward cursor from the preceding 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": [ + { + "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" + } + ], + "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", + "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" + }, + "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" + }, + "type": "array" + }, + "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" + } + }, + "required": [ + "epic", + "counts", + "blocked_count", + "updated_at", + "root_blockers", + "root_blockers_partial", + "next_ready" + ], + "type": "object" + }, + "type": "array" + }, + "has_more": { + "example": true, + "type": "boolean" + }, + "no_epic_open_count": { + "example": 1, + "type": "integer" + } + }, + "required": [ + "data", + "has_more", + "no_epic_open_count" + ], + "type": "object" + } + } + }, + "description": "Successful response" + }, + "401": { + "description": "Unauthorized" + }, + "404": { + "description": "Task owner not found" + }, + "422": { + "description": "Invalid filters or owner context" + } + }, + "summary": "List an owner's epic summaries", + "x-auth": [ + "publishable_key", + "bearer" + ] + } + }, "/api/v1/teams/{team}/tasks": { "get": { "description": "Returns tasks owned by the specified user or team. You can narrow results using the\noptional filters below. By default results are returned in reverse chronological\norder (most recently created first); use `sort` and `order` to sort by due date or\npriority instead.\n\nUser-authenticated callers may list their personal tasks or tasks for teams they\nhave joined. Privileged callers provide the owner in the route; the owner's\norganization is implied by that principal. An explicit `org` is optional and,\nwhen set, must match the owner's organization.\n", @@ -67379,6 +77487,16 @@ "type": "boolean" } }, + { + "description": "When true, return paused, failed, or in-progress tasks with no lease or a past lease expiry.", + "example": true, + "in": "query", + "name": "attention", + "required": false, + "schema": { + "type": "boolean" + } + }, { "description": "Maximum number of tasks to return. Capped at 100.", "example": 1, @@ -67443,6 +77561,7 @@ "epic": "string", "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, + "is_stalled": true, "links": { "key": "value" }, @@ -67469,15 +77588,19 @@ "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", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -67533,6 +77656,7 @@ "epic": "string", "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, + "is_stalled": true, "links": { "key": "value" }, @@ -67559,15 +77683,19 @@ "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", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -67609,6 +77737,7 @@ "epic": "string", "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, + "is_stalled": true, "links": { "key": "value" }, @@ -67635,15 +77764,19 @@ "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", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -67663,7 +77796,7 @@ "type": "integer" }, "blocked_by_count": { - "description": "Number of 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.", + "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" }, @@ -67852,7 +77985,12 @@ "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 list/show reads; create/update responses report `false` until the next read.", + "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" }, @@ -67991,7 +78129,7 @@ "type": "string" }, "parent": { - "description": "ID of the parent task when this task is a subtask (`tsk_...`). `null` for top-level tasks. Subtasks nest exactly one level.", + "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" @@ -68001,6 +78139,12 @@ "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", @@ -68025,13 +78169,20 @@ "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 subtasks under this task. Computed on list/show reads; create/update responses may report 0 until the next read. Always 0 for subtasks.", + "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" }, @@ -68045,6 +78196,18 @@ }, "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" + }, "team": { "description": "ID of the team that owns this task (`tem_...`). `null` if the task is not scoped to a team.", "example": "tem_0aBcDeFgHiJkLmNoPqRsTu", @@ -68052,7 +78215,7 @@ "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.", + "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" @@ -68107,7 +78270,11 @@ "summary": "List an owner's tasks", "x-auth": [ "publishable_key", - "bearer" + "bearer", + "device_flow" + ], + "x-required-scopes": [ + "tasks:read" ] }, "post": { @@ -68148,6 +78315,7 @@ "owner_user": "string", "parent": "tsk_01j3k5m7n9p2r4s6t8v0w1x2", "priority": 2, + "project_id": "string", "source_id": "ArchAstro/firstlanding", "source_scope": "github.com", "source_type": "repository", @@ -68156,6 +78324,8 @@ "backend", "q3-launch" ], + "target_binary": "my-cli", + "target_version": "0.48.9", "thread": "thr_01j3k5m7n9p2r4s6t8v0w1x2" }, "user": "string" @@ -68189,6 +78359,7 @@ "owner_user": "string", "parent": "tsk_01j3k5m7n9p2r4s6t8v0w1x2", "priority": 2, + "project_id": "string", "source_id": "ArchAstro/firstlanding", "source_scope": "github.com", "source_type": "repository", @@ -68197,6 +78368,8 @@ "backend", "q3-launch" ], + "target_binary": "my-cli", + "target_version": "0.48.9", "thread": "thr_01j3k5m7n9p2r4s6t8v0w1x2" }, "properties": { @@ -68260,6 +78433,11 @@ "example": 2, "type": "integer" }, + "project_id": { + "description": "Optional project ID (`prj_...`). Pass null to clear it.", + "example": "string", + "type": "string" + }, "source_id": { "description": "Source object identity (for example `ArchAstro/firstlanding`).", "example": "ArchAstro/firstlanding", @@ -68291,6 +78469,16 @@ }, "type": "array" }, + "target_binary": { + "description": "Binary that must run this work, as a lowercase identifier of 1-64 characters (letters, digits, `.`, `_`, `-`; for example `my-cli`). Must be supplied with `target_version`.", + "example": "my-cli", + "type": "string" + }, + "target_version": { + "description": "Minimum semantic version of `target_binary` that can run this work (`MAJOR.MINOR.PATCH` with optional prerelease and build, no leading `v`). Must be supplied with `target_binary`.", + "example": "0.48.9", + "type": "string" + }, "thread": { "description": "Bind the task to a thread (`thr_...`) owned by the same team or user as the task. A bound task appears in that thread's task scope, exactly like a task filed from inside the conversation. Omit for a task not tied to a conversation.", "example": "thr_01j3k5m7n9p2r4s6t8v0w1x2", @@ -68449,6 +78637,7 @@ "epic": "string", "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, + "is_stalled": true, "links": { "key": "value" }, @@ -68475,15 +78664,19 @@ "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", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -68540,6 +78733,7 @@ "epic": "string", "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, + "is_stalled": true, "links": { "key": "value" }, @@ -68566,15 +78760,19 @@ "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", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -68620,6 +78818,7 @@ "epic": "string", "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, + "is_stalled": true, "links": { "key": "value" }, @@ -68646,15 +78845,19 @@ "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", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -68699,6 +78902,7 @@ "epic": "string", "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, + "is_stalled": true, "links": { "key": "value" }, @@ -68725,15 +78929,19 @@ "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", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -68775,6 +78983,7 @@ "epic": "string", "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, + "is_stalled": true, "links": { "key": "value" }, @@ -68801,15 +79010,19 @@ "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", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -68829,7 +79042,7 @@ "type": "integer" }, "blocked_by_count": { - "description": "Number of 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.", + "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" }, @@ -69018,7 +79231,12 @@ "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 list/show reads; create/update responses report `false` until the next read.", + "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" }, @@ -69157,7 +79375,7 @@ "type": "string" }, "parent": { - "description": "ID of the parent task when this task is a subtask (`tsk_...`). `null` for top-level tasks. Subtasks nest exactly one level.", + "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" @@ -69167,6 +79385,12 @@ "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", @@ -69191,13 +79415,20 @@ "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 subtasks under this task. Computed on list/show reads; create/update responses may report 0 until the next read. Always 0 for subtasks.", + "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" }, @@ -69211,6 +79442,18 @@ }, "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" + }, "team": { "description": "ID of the team that owns this task (`tem_...`). `null` if the task is not scoped to a team.", "example": "tem_0aBcDeFgHiJkLmNoPqRsTu", @@ -69218,7 +79461,7 @@ "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.", + "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" @@ -69285,6 +79528,130 @@ ] } }, + "/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.", + "operationId": "put_api_v1_teams__team_tasks_by-source", + "parameters": [ + { + "description": "Team owner.", + "example": "string", + "in": "path", + "name": "team", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "example": { + "agent": "string", + "description": "An example description.", + "epic": "string", + "name": "Example Name", + "org": "string", + "source_id": "string", + "source_scope": "string", + "source_type": "string", + "status": "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" + }, + "org": { + "description": "Explicit organization for privileged callers.", + "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" + }, + "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/teams/{team}/tasks/metrics": { "get": { "description": "Returns task activity metrics scoped to one team (the Network in ArchAgents).\n`open` counts currently open or in-progress team tasks, `created` counts\ntasks inserted in the UTC-day window, and `completed` counts tasks whose\n`closed_at` falls in that window while still in a closed status. Hard-deleted\ntasks are absent from the projection and therefore omitted. The daily series\nis zero-filled across the requested window and includes reconstructed\nend-of-day `open` stock (from remaining projection rows' inserted_at/closed_at).\n\nAny authenticated team member may read this count-only Network summary.\nRequests from callers without team access return 404 so team existence is\nnot disclosed.\n", @@ -69400,7 +79767,7 @@ }, "/api/v1/teams/{team}/tasks/ready": { "get": { - "description": "Returns open tasks with no unfinished blockers and no active session lease.\nReadiness is calculated by the server from the current task projection. It is\na snapshot, not a reservation; claim a task lease before starting work.\n\nPass `explain=true` to include every open task with a stable readiness reason.\n", + "description": "Returns open tasks with no unfinished blockers and no active session lease.\nReadiness is calculated by the server from the current task projection. It is\na snapshot, not a reservation; claim a task lease before starting 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_teams__team_tasks_ready", "parameters": [ { @@ -69561,6 +79928,7 @@ "epic": "string", "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, + "is_stalled": true, "links": { "key": "value" }, @@ -69587,15 +79955,19 @@ "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", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -69657,6 +80029,7 @@ "epic": "string", "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, + "is_stalled": true, "links": { "key": "value" }, @@ -69683,15 +80056,19 @@ "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", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -69737,6 +80114,7 @@ "epic": "string", "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, + "is_stalled": true, "links": { "key": "value" }, @@ -69763,15 +80141,19 @@ "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", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -69834,6 +80216,7 @@ "epic": "string", "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, + "is_stalled": true, "links": { "key": "value" }, @@ -69860,15 +80243,19 @@ "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", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -69888,7 +80275,7 @@ "type": "integer" }, "blocked_by_count": { - "description": "Number of 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.", + "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" }, @@ -70077,7 +80464,12 @@ "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 list/show reads; create/update responses report `false` until the next read.", + "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" }, @@ -70216,7 +80608,7 @@ "type": "string" }, "parent": { - "description": "ID of the parent task when this task is a subtask (`tsk_...`). `null` for top-level tasks. Subtasks nest exactly one level.", + "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" @@ -70226,6 +80618,12 @@ "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", @@ -70250,13 +80648,20 @@ "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 subtasks under this task. Computed on list/show reads; create/update responses may report 0 until the next read. Always 0 for subtasks.", + "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" }, @@ -70270,6 +80675,18 @@ }, "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" + }, "team": { "description": "ID of the team that owns this task (`tem_...`). `null` if the task is not scoped to a team.", "example": "tem_0aBcDeFgHiJkLmNoPqRsTu", @@ -70277,7 +80694,7 @@ "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.", + "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" @@ -70563,6 +80980,7 @@ "epic": "string", "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, + "is_stalled": true, "links": { "key": "value" }, @@ -70589,15 +81007,19 @@ "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", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -70652,6 +81074,7 @@ "epic": "string", "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, + "is_stalled": true, "links": { "key": "value" }, @@ -70678,15 +81101,19 @@ "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", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -70728,6 +81155,7 @@ "epic": "string", "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, + "is_stalled": true, "links": { "key": "value" }, @@ -70754,15 +81182,19 @@ "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", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -70782,7 +81214,7 @@ "type": "integer" }, "blocked_by_count": { - "description": "Number of 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.", + "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" }, @@ -70971,7 +81403,12 @@ "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 list/show reads; create/update responses report `false` until the next read.", + "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" }, @@ -71110,7 +81547,7 @@ "type": "string" }, "parent": { - "description": "ID of the parent task when this task is a subtask (`tsk_...`). `null` for top-level tasks. Subtasks nest exactly one level.", + "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" @@ -71120,6 +81557,12 @@ "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", @@ -71144,13 +81587,20 @@ "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 subtasks under this task. Computed on list/show reads; create/update responses may report 0 until the next read. Always 0 for subtasks.", + "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" }, @@ -71164,6 +81614,18 @@ }, "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" + }, "team": { "description": "ID of the team that owns this task (`tem_...`). `null` if the task is not scoped to a team.", "example": "tem_0aBcDeFgHiJkLmNoPqRsTu", @@ -71171,7 +81633,7 @@ "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.", + "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" @@ -71369,8 +81831,10 @@ "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, @@ -71384,8 +81848,10 @@ "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 } @@ -71401,7 +81867,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "2024-01-01T00:00:00Z", @@ -71781,8 +82247,10 @@ "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, @@ -71796,8 +82264,10 @@ "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 } @@ -71813,7 +82283,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "2024-01-01T00:00:00Z", @@ -72190,8 +82660,10 @@ "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, @@ -72205,8 +82677,10 @@ "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 } @@ -72222,7 +82696,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "2024-01-01T00:00:00Z", @@ -72825,8 +83299,10 @@ "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, @@ -72840,8 +83316,10 @@ "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 } @@ -72857,7 +83335,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "2024-01-01T00:00:00Z", @@ -73233,8 +83711,10 @@ "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, @@ -73248,8 +83728,10 @@ "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 } @@ -73287,8 +83769,10 @@ "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, @@ -73302,8 +83786,10 @@ "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 } @@ -73460,8 +83946,10 @@ "description": "Array of available encoding variants for the media item (e.g. different resolutions). Present on `media` type only; omitted otherwise.", "example": [ { + "byte_size": 1, "content_type": "application/json", "created_at": "2024-01-01T00:00:00Z", + "duration_ms": 1, "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", "filename": "string", "height": 600, @@ -73475,8 +83963,10 @@ "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 } @@ -73484,8 +83974,10 @@ "items": { "description": "A processed variant of a media item, such as the original upload or a resized thumbnail, including a signed download URL resolved at request time.", "example": { + "byte_size": 1, "content_type": "application/json", "created_at": "2024-01-01T00:00:00Z", + "duration_ms": 1, "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", "filename": "string", "height": 600, @@ -73499,12 +83991,20 @@ "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 }, "properties": { + "byte_size": { + "description": "Size of the stored bytes.", + "example": 1, + "nullable": true, + "type": "integer" + }, "content_type": { "description": "MIME type of this variant's file (e.g., `\"image/jpeg\"`, `\"video/mp4\"`). `null` if the file is not loaded.", "example": "application/json", @@ -73517,6 +84017,12 @@ "format": "date-time", "type": "string" }, + "duration_ms": { + "description": "Client-declared video duration in milliseconds; not server-probed.", + "example": 1, + "nullable": true, + "type": "integer" + }, "file": { "description": "ID of the underlying storage file that backs this variant (`fil_...`).", "example": "fil_0aBcDeFgHiJkLmNoPqRsTu", @@ -73597,6 +84103,12 @@ }, "type": "object" }, + "sha256": { + "description": "Lowercase SHA-256 of the stored bytes.", + "example": "string", + "nullable": true, + "type": "string" + }, "updated_at": { "description": "When this variant was last updated (ISO 8601).", "example": "2024-01-01T00:00:00Z", @@ -73609,6 +84121,13 @@ "nullable": true, "type": "string" }, + "url_expires_at": { + "description": "Expiry of this variant's playable URL.", + "example": "2024-01-01T00:00:00Z", + "format": "date-time", + "nullable": true, + "type": "string" + }, "variant_key": { "description": "Identifier for this variant's processing tier. Common values include `\"original\"` (the unmodified upload) and `\"thumbnail\"` (a resized preview).", "example": "original", @@ -73668,7 +84187,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "items": { @@ -73677,7 +84196,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" }, "properties": { "attributes": { @@ -73699,7 +84218,7 @@ }, "type": { "description": "Stable context kind. Must start with a lowercase letter and contain only lowercase letters, numbers, dots, dashes, or underscores.", - "example": "archdev.pull_request", + "example": "myapp.pull_request", "type": "string" } }, @@ -73911,8 +84430,10 @@ "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, @@ -73926,8 +84447,10 @@ "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 } @@ -73943,7 +84466,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "2024-01-01T00:00:00Z", @@ -76933,7 +87456,11 @@ "summary": "Retrieve a message", "x-auth": [ "publishable_key", - "bearer" + "bearer", + "device_flow" + ], + "x-required-scopes": [ + "threads:read" ] }, "put": { @@ -77823,6 +88350,34 @@ "example": { "data": [ { + "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" + } + ] + }, "agent": "agt_0aBcDeFgHiJkLmNoPqRsTu", "content_type": "application/json", "created_at": "2024-01-01T00:00:00Z", @@ -77859,6 +88414,34 @@ "description": "Array of artifact objects produced during the thread's conversation.", "example": [ { + "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" + } + ] + }, "agent": "agt_0aBcDeFgHiJkLmNoPqRsTu", "content_type": "application/json", "created_at": "2024-01-01T00:00:00Z", @@ -77892,6 +88475,34 @@ "items": { "description": "A versioned artifact produced or managed by an agent, such as a generated file, report, or code output.", "example": { + "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" + } + ] + }, "agent": "agt_0aBcDeFgHiJkLmNoPqRsTu", "content_type": "application/json", "created_at": "2024-01-01T00:00:00Z", @@ -77922,6 +88533,180 @@ "version": 1 }, "properties": { + "acl": { + "description": "Access control list for the artifact. Contains a `grants` array where each entry specifies `principal_type`, `principal`, and `actions` (`read`, `write`). `null` when the artifact has no grants or the viewer is not its owner.", + "example": { + "add": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "grants": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "remove": [ + { + "principal": "string", + "principal_type": "user" + } + ] + }, + "nullable": true, + "properties": { + "add": { + "description": "Patch mode: grants to add or merge into the existing list. Cannot be combined with `grants`.", + "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": [ + { + "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" + }, + "remove": { + "description": "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", + "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" + }, "agent": { "description": "ID of the agent that produced this artifact (`agt_...`). `null` if not agent-produced.", "example": "agt_0aBcDeFgHiJkLmNoPqRsTu", @@ -78115,6 +88900,350 @@ ] } }, + "/api/v1/threads/{thread}/computers": { + "get": { + "description": "Returns all live computers in the visible thread, oldest first, without pagination.", + "operationId": "get_api_v1_threads__thread_computers", + "parameters": [ + { + "description": "Thread ID (`thr_...`).", + "example": "string", + "in": "path", + "name": "thread", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AgentComputerListResponse" + } + } + }, + "description": "The thread's live computers." + }, + "401": { + "description": "Unauthorized" + }, + "404": { + "description": "Thread not found" + } + }, + "summary": "List a thread's computers", + "x-auth": [ + "publishable_key", + "bearer" + ] + }, + "post": { + "description": "Creates a computer owned by the thread's owner. Requires permission to manage the thread; every thread viewer may use the computer.", + "operationId": "post_api_v1_threads__thread_computers", + "parameters": [ + { + "description": "Thread ID (`thr_...`).", + "example": "string", + "in": "path", + "name": "thread", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "example": { + "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" + } + ] + }, + "config": {}, + "key": "string", + "metadata": { + "key": "value" + }, + "name": "Example Name", + "provider": "string", + "region": "string" + }, + "properties": { + "acl": { + "description": "Initial access control list.", + "example": { + "add": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "grants": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "remove": [ + { + "principal": "string", + "principal_type": "user" + } + ] + }, + "properties": { + "add": { + "description": "Patch mode: grants to add or merge into the existing list. Cannot be combined with `grants`.", + "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": [ + { + "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" + }, + "remove": { + "description": "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", + "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" + }, + "config": { + "description": "Provider configuration; top-level provider takes precedence.", + "example": {}, + "type": "object" + }, + "key": { + "description": "Stable key unique within this thread.", + "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: sprites (default), vercel or e2b.", + "example": "string", + "type": "string" + }, + "region": { + "description": "Provider region; defaults to iad.", + "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": "Forbidden" + }, + "404": { + "description": "Thread not found" + }, + "422": { + "description": "Unsupported thread or invalid computer" + } + }, + "summary": "Provision a computer for a thread", + "x-auth": [ + "publishable_key", + "bearer" + ] + } + }, "/api/v1/threads/{thread}/mark_read": { "post": { "description": "Records that a user has read up to a specific message in the thread. Unread\nindicators and badge counts are cleared up to the specified message.\n\nYou must supply exactly one of `last_read_message` or `use_latest_message`.\nOmitting both returns 400. If `use_latest_message` is `true` and the thread\nhas no messages, the request succeeds silently with no state change.\n\nFor server-to-server (S2S) requests where no user identity is present in the\ntoken, the `user` param is required to identify whose read state to update.\n", @@ -78559,7 +89688,7 @@ }, "/api/v1/threads/{thread}/messages": { "get": { - "description": "Returns a cursor-paginated list of messages belonging to the specified thread,\nordered from oldest to newest. Supply `before_cursor`, `after_cursor`, or both\nto page through or bound the result set; omit both to receive the most recent page.\nSupply `anchor` and `direction` to fetch a window before, after, or around a\nspecific message. Use `anchor=last_matching&anchor_agent_mode=embedded` to\nresolve the anchor from the latest embedded-agent message, and add\n`anchor_agent` to scope that resolution to a single sender agent.\nSupply `metadata` as a JSON-encoded structured expression to filter message\nmetadata before cursor pagination or anchored window limits are applied.\n\nThe authenticated user must have access to the thread's owner (workspace or user).\nA 403 is returned if the thread exists but is not accessible to the caller; a 404\nis returned if the thread does not exist or is not visible to the authenticated user.\n\nThreads with `kind: feed` return only top-level posts, each with its newest\nreplies inline under `replies` and reply cursors for paging the rest.\n\nPass `include_reply_counts: true` to annotate each message with the number of\nthreaded replies it has received. This adds a small amount of latency and should\nbe omitted when reply counts are not needed.\n", + "description": "Returns a cursor-paginated list of messages belonging to the specified thread,\nordered from oldest to newest. Supply `before_cursor`, `after_cursor`, or both\nto page through or bound the result set; omit both to receive the most recent page.\nSupply `anchor` and `direction` to fetch a window before, after, or around a\nspecific message. Use `anchor=last_matching&anchor_agent_mode=embedded` to\nresolve the anchor from the latest embedded-agent message, and add\n`anchor_agent` to scope that resolution to a single sender agent.\nSupply `metadata` as a JSON-encoded structured expression to filter message\nmetadata before cursor pagination or anchored window limits are applied.\n\nThe authenticated user must have access to the thread's owner (workspace or user).\nA 403 is returned if the thread exists but is not accessible to the caller; a 404\nis returned if the thread does not exist or is not visible to the authenticated user.\n\nThreads with `kind: feed` return only top-level posts, each with its newest\nreplies inline under `replies` and reply cursors for paging the rest.\nSet `include_replies: true` to page messages and replies together by creation\norder instead, without inline reply previews. Metadata filters and the page\nlimit apply to the updates themselves, before any client-side grouping.\n\nPass `include_reply_counts: true` to annotate each message with the number of\nthreaded replies it has received. This adds a small amount of latency and should\nbe omitted when reply counts are not needed.\n", "operationId": "get_api_v1_threads__thread_messages", "parameters": [ { @@ -78690,6 +89819,16 @@ "type": "integer" } }, + { + "description": "Include replies in feed message pagination instead of returning root posts with inline replies. Defaults to false.", + "example": true, + "in": "query", + "name": "include_replies", + "required": false, + "schema": { + "type": "boolean" + } + }, { "description": "Message ID (`msg_...`) to use as a window anchor, or `last_matching` to resolve the anchor from the latest message matching the anchor filters. Cannot be combined with `before_cursor` or `after_cursor`.", "example": "string", @@ -78867,8 +90006,10 @@ "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, @@ -78882,8 +90023,10 @@ "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 } @@ -78899,7 +90042,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "2024-01-01T00:00:00Z", @@ -79023,8 +90166,10 @@ "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, @@ -79038,8 +90183,10 @@ "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 } @@ -79055,7 +90202,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "2024-01-01T00:00:00Z", @@ -79192,8 +90339,10 @@ "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, @@ -79207,8 +90356,10 @@ "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 } @@ -79224,7 +90375,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "2024-01-01T00:00:00Z", @@ -79340,8 +90491,10 @@ "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, @@ -79355,8 +90508,10 @@ "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 } @@ -79372,7 +90527,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "string", @@ -79476,8 +90631,10 @@ "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, @@ -79491,8 +90648,10 @@ "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 } @@ -79508,7 +90667,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "2024-01-01T00:00:00Z", @@ -79891,8 +91050,10 @@ "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, @@ -79906,8 +91067,10 @@ "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 } @@ -79945,8 +91108,10 @@ "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, @@ -79960,8 +91125,10 @@ "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 } @@ -80118,8 +91285,10 @@ "description": "Array of available encoding variants for the media item (e.g. different resolutions). Present on `media` type only; omitted otherwise.", "example": [ { + "byte_size": 1, "content_type": "application/json", "created_at": "2024-01-01T00:00:00Z", + "duration_ms": 1, "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", "filename": "string", "height": 600, @@ -80133,8 +91302,10 @@ "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 } @@ -80142,8 +91313,10 @@ "items": { "description": "A processed variant of a media item, such as the original upload or a resized thumbnail, including a signed download URL resolved at request time.", "example": { + "byte_size": 1, "content_type": "application/json", "created_at": "2024-01-01T00:00:00Z", + "duration_ms": 1, "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", "filename": "string", "height": 600, @@ -80157,12 +91330,20 @@ "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 }, "properties": { + "byte_size": { + "description": "Size of the stored bytes.", + "example": 1, + "nullable": true, + "type": "integer" + }, "content_type": { "description": "MIME type of this variant's file (e.g., `\"image/jpeg\"`, `\"video/mp4\"`). `null` if the file is not loaded.", "example": "application/json", @@ -80175,6 +91356,12 @@ "format": "date-time", "type": "string" }, + "duration_ms": { + "description": "Client-declared video duration in milliseconds; not server-probed.", + "example": 1, + "nullable": true, + "type": "integer" + }, "file": { "description": "ID of the underlying storage file that backs this variant (`fil_...`).", "example": "fil_0aBcDeFgHiJkLmNoPqRsTu", @@ -80255,6 +91442,12 @@ }, "type": "object" }, + "sha256": { + "description": "Lowercase SHA-256 of the stored bytes.", + "example": "string", + "nullable": true, + "type": "string" + }, "updated_at": { "description": "When this variant was last updated (ISO 8601).", "example": "2024-01-01T00:00:00Z", @@ -80267,6 +91460,13 @@ "nullable": true, "type": "string" }, + "url_expires_at": { + "description": "Expiry of this variant's playable URL.", + "example": "2024-01-01T00:00:00Z", + "format": "date-time", + "nullable": true, + "type": "string" + }, "variant_key": { "description": "Identifier for this variant's processing tier. Common values include `\"original\"` (the unmodified upload) and `\"thumbnail\"` (a resized preview).", "example": "original", @@ -80326,7 +91526,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "items": { @@ -80335,7 +91535,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" }, "properties": { "attributes": { @@ -80357,7 +91557,7 @@ }, "type": { "description": "Stable context kind. Must start with a lowercase letter and contain only lowercase letters, numbers, dots, dashes, or underscores.", - "example": "archdev.pull_request", + "example": "myapp.pull_request", "type": "string" } }, @@ -80569,8 +91769,10 @@ "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, @@ -80584,8 +91786,10 @@ "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 } @@ -80601,7 +91805,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "2024-01-01T00:00:00Z", @@ -80875,7 +92079,11 @@ "summary": "List messages in a thread", "x-auth": [ "publishable_key", - "bearer" + "bearer", + "device_flow" + ], + "x-required-scopes": [ + "threads:read" ] } }, @@ -81257,7 +92465,11 @@ "summary": "Search messages in a thread", "x-auth": [ "publishable_key", - "bearer" + "bearer", + "device_flow" + ], + "x-required-scopes": [ + "threads:read" ] } }, @@ -81933,7 +93145,7 @@ }, "/api/v1/users/{user}": { "get": { - "description": "Returns the user identified by `user`. The authenticated user must share\nat least one team with the target user; requests for users outside any\nshared team are rejected with 403.\n\nA user may always retrieve their own profile with this endpoint. Use the\n`GET /users/me` endpoint as a convenience alias for retrieving the\nauthenticated user without specifying an ID.\n", + "description": "Returns the user identified by `user`. The authenticated user must share\nan organization or at least one team with the target user; other requests\nare rejected with 403.\n\nA user may always retrieve their own profile with this endpoint. Use the\n`GET /users/me` endpoint as a convenience alias for retrieving the\nauthenticated user without specifying an ID.\n", "operationId": "get_api_v1_users__user", "parameters": [ { @@ -82017,6 +93229,34 @@ "example": { "data": [ { + "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" + } + ] + }, "agent": "agt_0aBcDeFgHiJkLmNoPqRsTu", "content_type": "application/json", "created_at": "2024-01-01T00:00:00Z", @@ -82053,6 +93293,34 @@ "description": "Array of artifact objects belonging to the user.", "example": [ { + "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" + } + ] + }, "agent": "agt_0aBcDeFgHiJkLmNoPqRsTu", "content_type": "application/json", "created_at": "2024-01-01T00:00:00Z", @@ -82086,6 +93354,34 @@ "items": { "description": "A versioned artifact produced or managed by an agent, such as a generated file, report, or code output.", "example": { + "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" + } + ] + }, "agent": "agt_0aBcDeFgHiJkLmNoPqRsTu", "content_type": "application/json", "created_at": "2024-01-01T00:00:00Z", @@ -82116,6 +93412,180 @@ "version": 1 }, "properties": { + "acl": { + "description": "Access control list for the artifact. Contains a `grants` array where each entry specifies `principal_type`, `principal`, and `actions` (`read`, `write`). `null` when the artifact has no grants or the viewer is not its owner.", + "example": { + "add": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "grants": [ + { + "actions": [ + "read", + "write" + ], + "principal": "string", + "principal_type": "user" + } + ], + "remove": [ + { + "principal": "string", + "principal_type": "user" + } + ] + }, + "nullable": true, + "properties": { + "add": { + "description": "Patch mode: grants to add or merge into the existing list. Cannot be combined with `grants`.", + "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": [ + { + "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" + }, + "remove": { + "description": "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", + "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" + }, "agent": { "description": "ID of the agent that produced this artifact (`agt_...`). `null` if not agent-produced.", "example": "agt_0aBcDeFgHiJkLmNoPqRsTu", @@ -83111,6 +94581,390 @@ ] } }, + "/api/v1/users/{user}/task_epics": { + "get": { + "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": [ + { + "example": "string", + "in": "query", + "name": "team", + "required": false, + "schema": { + "type": "string" + } + }, + { + "example": "string", + "in": "path", + "name": "user", + "required": true, + "schema": { + "type": "string" + } + }, + { + "example": "string", + "in": "query", + "name": "org", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "Exact source scope; supply all three source fields.", + "example": "string", + "in": "query", + "name": "source_scope", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "Exact source type.", + "example": "string", + "in": "query", + "name": "source_type", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "Exact source ID.", + "example": "string", + "in": "query", + "name": "source_id", + "required": false, + "schema": { + "type": "string" + } + }, + { + "description": "Exact highest open priority, from 0 to 4.", + "example": 1, + "in": "query", + "name": "top_priority", + "required": false, + "schema": { + "type": "integer" + } + }, + { + "description": "Include epics with no non-closed tasks; defaults to false.", + "example": true, + "in": "query", + "name": "include_closed", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "description": "Maximum epics; defaults to 50, capped at 100.", + "example": 1, + "in": "query", + "name": "limit", + "required": false, + "schema": { + "type": "integer" + } + }, + { + "description": "Opaque forward cursor from the preceding 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": [ + { + "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" + } + ], + "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", + "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" + }, + "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" + }, + "type": "array" + }, + "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" + } + }, + "required": [ + "epic", + "counts", + "blocked_count", + "updated_at", + "root_blockers", + "root_blockers_partial", + "next_ready" + ], + "type": "object" + }, + "type": "array" + }, + "has_more": { + "example": true, + "type": "boolean" + }, + "no_epic_open_count": { + "example": 1, + "type": "integer" + } + }, + "required": [ + "data", + "has_more", + "no_epic_open_count" + ], + "type": "object" + } + } + }, + "description": "Successful response" + }, + "401": { + "description": "Unauthorized" + }, + "404": { + "description": "Task owner not found" + }, + "422": { + "description": "Invalid filters or owner context" + } + }, + "summary": "List an owner's epic summaries", + "x-auth": [ + "publishable_key", + "bearer" + ] + } + }, "/api/v1/users/{user}/tasks": { "get": { "description": "Returns tasks owned by the specified user or team. You can narrow results using the\noptional filters below. By default results are returned in reverse chronological\norder (most recently created first); use `sort` and `order` to sort by due date or\npriority instead.\n\nUser-authenticated callers may list their personal tasks or tasks for teams they\nhave joined. Privileged callers provide the owner in the route; the owner's\norganization is implied by that principal. An explicit `org` is optional and,\nwhen set, must match the owner's organization.\n", @@ -83316,6 +95170,16 @@ "type": "boolean" } }, + { + "description": "When true, return paused, failed, or in-progress tasks with no lease or a past lease expiry.", + "example": true, + "in": "query", + "name": "attention", + "required": false, + "schema": { + "type": "boolean" + } + }, { "description": "Maximum number of tasks to return. Capped at 100.", "example": 1, @@ -83380,6 +95244,7 @@ "epic": "string", "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, + "is_stalled": true, "links": { "key": "value" }, @@ -83406,15 +95271,19 @@ "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", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -83470,6 +95339,7 @@ "epic": "string", "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, + "is_stalled": true, "links": { "key": "value" }, @@ -83496,15 +95366,19 @@ "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", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -83546,6 +95420,7 @@ "epic": "string", "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, + "is_stalled": true, "links": { "key": "value" }, @@ -83572,15 +95447,19 @@ "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", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -83600,7 +95479,7 @@ "type": "integer" }, "blocked_by_count": { - "description": "Number of 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.", + "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" }, @@ -83789,7 +95668,12 @@ "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 list/show reads; create/update responses report `false` until the next read.", + "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" }, @@ -83928,7 +95812,7 @@ "type": "string" }, "parent": { - "description": "ID of the parent task when this task is a subtask (`tsk_...`). `null` for top-level tasks. Subtasks nest exactly one level.", + "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" @@ -83938,6 +95822,12 @@ "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", @@ -83962,13 +95852,20 @@ "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 subtasks under this task. Computed on list/show reads; create/update responses may report 0 until the next read. Always 0 for subtasks.", + "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" }, @@ -83982,6 +95879,18 @@ }, "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" + }, "team": { "description": "ID of the team that owns this task (`tem_...`). `null` if the task is not scoped to a team.", "example": "tem_0aBcDeFgHiJkLmNoPqRsTu", @@ -83989,7 +95898,7 @@ "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.", + "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" @@ -84044,7 +95953,11 @@ "summary": "List an owner's tasks", "x-auth": [ "publishable_key", - "bearer" + "bearer", + "device_flow" + ], + "x-required-scopes": [ + "tasks:read" ] }, "post": { @@ -84085,6 +95998,7 @@ "owner_user": "string", "parent": "tsk_01j3k5m7n9p2r4s6t8v0w1x2", "priority": 2, + "project_id": "string", "source_id": "ArchAstro/firstlanding", "source_scope": "github.com", "source_type": "repository", @@ -84093,6 +96007,8 @@ "backend", "q3-launch" ], + "target_binary": "my-cli", + "target_version": "0.48.9", "thread": "thr_01j3k5m7n9p2r4s6t8v0w1x2" }, "team": "string" @@ -84126,6 +96042,7 @@ "owner_user": "string", "parent": "tsk_01j3k5m7n9p2r4s6t8v0w1x2", "priority": 2, + "project_id": "string", "source_id": "ArchAstro/firstlanding", "source_scope": "github.com", "source_type": "repository", @@ -84134,6 +96051,8 @@ "backend", "q3-launch" ], + "target_binary": "my-cli", + "target_version": "0.48.9", "thread": "thr_01j3k5m7n9p2r4s6t8v0w1x2" }, "properties": { @@ -84197,6 +96116,11 @@ "example": 2, "type": "integer" }, + "project_id": { + "description": "Optional project ID (`prj_...`). Pass null to clear it.", + "example": "string", + "type": "string" + }, "source_id": { "description": "Source object identity (for example `ArchAstro/firstlanding`).", "example": "ArchAstro/firstlanding", @@ -84228,6 +96152,16 @@ }, "type": "array" }, + "target_binary": { + "description": "Binary that must run this work, as a lowercase identifier of 1-64 characters (letters, digits, `.`, `_`, `-`; for example `my-cli`). Must be supplied with `target_version`.", + "example": "my-cli", + "type": "string" + }, + "target_version": { + "description": "Minimum semantic version of `target_binary` that can run this work (`MAJOR.MINOR.PATCH` with optional prerelease and build, no leading `v`). Must be supplied with `target_binary`.", + "example": "0.48.9", + "type": "string" + }, "thread": { "description": "Bind the task to a thread (`thr_...`) owned by the same team or user as the task. A bound task appears in that thread's task scope, exactly like a task filed from inside the conversation. Omit for a task not tied to a conversation.", "example": "thr_01j3k5m7n9p2r4s6t8v0w1x2", @@ -84386,6 +96320,7 @@ "epic": "string", "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, + "is_stalled": true, "links": { "key": "value" }, @@ -84412,15 +96347,19 @@ "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", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -84477,6 +96416,7 @@ "epic": "string", "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, + "is_stalled": true, "links": { "key": "value" }, @@ -84503,15 +96443,19 @@ "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", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -84557,6 +96501,7 @@ "epic": "string", "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, + "is_stalled": true, "links": { "key": "value" }, @@ -84583,15 +96528,19 @@ "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", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -84636,6 +96585,7 @@ "epic": "string", "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, + "is_stalled": true, "links": { "key": "value" }, @@ -84662,15 +96612,19 @@ "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", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -84712,6 +96666,7 @@ "epic": "string", "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, + "is_stalled": true, "links": { "key": "value" }, @@ -84738,15 +96693,19 @@ "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", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -84766,7 +96725,7 @@ "type": "integer" }, "blocked_by_count": { - "description": "Number of 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.", + "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" }, @@ -84955,7 +96914,12 @@ "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 list/show reads; create/update responses report `false` until the next read.", + "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" }, @@ -85094,7 +97058,7 @@ "type": "string" }, "parent": { - "description": "ID of the parent task when this task is a subtask (`tsk_...`). `null` for top-level tasks. Subtasks nest exactly one level.", + "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" @@ -85104,6 +97068,12 @@ "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", @@ -85128,13 +97098,20 @@ "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 subtasks under this task. Computed on list/show reads; create/update responses may report 0 until the next read. Always 0 for subtasks.", + "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" }, @@ -85148,6 +97125,18 @@ }, "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" + }, "team": { "description": "ID of the team that owns this task (`tem_...`). `null` if the task is not scoped to a team.", "example": "tem_0aBcDeFgHiJkLmNoPqRsTu", @@ -85155,7 +97144,7 @@ "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.", + "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" @@ -85222,9 +97211,133 @@ ] } }, + "/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.", + "operationId": "put_api_v1_users__user_tasks_by-source", + "parameters": [ + { + "description": "User owner, or explicit acting user on a team route.", + "example": "string", + "in": "path", + "name": "user", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "example": { + "agent": "string", + "description": "An example description.", + "epic": "string", + "name": "Example Name", + "org": "string", + "source_id": "string", + "source_scope": "string", + "source_type": "string", + "status": "string", + "team": "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" + }, + "org": { + "description": "Explicit organization for privileged callers.", + "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" + } + }, + "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/users/{user}/tasks/ready": { "get": { - "description": "Returns open tasks with no unfinished blockers and no active session lease.\nReadiness is calculated by the server from the current task projection. It is\na snapshot, not a reservation; claim a task lease before starting work.\n\nPass `explain=true` to include every open task with a stable readiness reason.\n", + "description": "Returns open tasks with no unfinished blockers and no active session lease.\nReadiness is calculated by the server from the current task projection. It is\na snapshot, not a reservation; claim a task lease before starting 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_users__user_tasks_ready", "parameters": [ { @@ -85385,6 +97498,7 @@ "epic": "string", "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, + "is_stalled": true, "links": { "key": "value" }, @@ -85411,15 +97525,19 @@ "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", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -85481,6 +97599,7 @@ "epic": "string", "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, + "is_stalled": true, "links": { "key": "value" }, @@ -85507,15 +97626,19 @@ "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", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -85561,6 +97684,7 @@ "epic": "string", "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, + "is_stalled": true, "links": { "key": "value" }, @@ -85587,15 +97711,19 @@ "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", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -85658,6 +97786,7 @@ "epic": "string", "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, + "is_stalled": true, "links": { "key": "value" }, @@ -85684,15 +97813,19 @@ "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", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -85712,7 +97845,7 @@ "type": "integer" }, "blocked_by_count": { - "description": "Number of 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.", + "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" }, @@ -85901,7 +98034,12 @@ "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 list/show reads; create/update responses report `false` until the next read.", + "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" }, @@ -86040,7 +98178,7 @@ "type": "string" }, "parent": { - "description": "ID of the parent task when this task is a subtask (`tsk_...`). `null` for top-level tasks. Subtasks nest exactly one level.", + "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" @@ -86050,6 +98188,12 @@ "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", @@ -86074,13 +98218,20 @@ "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 subtasks under this task. Computed on list/show reads; create/update responses may report 0 until the next read. Always 0 for subtasks.", + "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" }, @@ -86094,6 +98245,18 @@ }, "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" + }, "team": { "description": "ID of the team that owns this task (`tem_...`). `null` if the task is not scoped to a team.", "example": "tem_0aBcDeFgHiJkLmNoPqRsTu", @@ -86101,7 +98264,7 @@ "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.", + "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" @@ -86387,6 +98550,7 @@ "epic": "string", "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, + "is_stalled": true, "links": { "key": "value" }, @@ -86413,15 +98577,19 @@ "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", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -86476,6 +98644,7 @@ "epic": "string", "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, + "is_stalled": true, "links": { "key": "value" }, @@ -86502,15 +98671,19 @@ "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", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -86552,6 +98725,7 @@ "epic": "string", "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, + "is_stalled": true, "links": { "key": "value" }, @@ -86578,15 +98752,19 @@ "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", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -86606,7 +98784,7 @@ "type": "integer" }, "blocked_by_count": { - "description": "Number of 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.", + "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" }, @@ -86795,7 +98973,12 @@ "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 list/show reads; create/update responses report `false` until the next read.", + "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" }, @@ -86934,7 +99117,7 @@ "type": "string" }, "parent": { - "description": "ID of the parent task when this task is a subtask (`tsk_...`). `null` for top-level tasks. Subtasks nest exactly one level.", + "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" @@ -86944,6 +99127,12 @@ "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", @@ -86968,13 +99157,20 @@ "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 subtasks under this task. Computed on list/show reads; create/update responses may report 0 until the next read. Always 0 for subtasks.", + "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" }, @@ -86988,6 +99184,18 @@ }, "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" + }, "team": { "description": "ID of the team that owns this task (`tem_...`). `null` if the task is not scoped to a team.", "example": "tem_0aBcDeFgHiJkLmNoPqRsTu", @@ -86995,7 +99203,7 @@ "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.", + "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" @@ -87240,8 +99448,10 @@ "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, @@ -87255,8 +99465,10 @@ "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 } @@ -87272,7 +99484,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "2024-01-01T00:00:00Z", @@ -87652,8 +99864,10 @@ "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, @@ -87667,8 +99881,10 @@ "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 } @@ -87684,7 +99900,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "2024-01-01T00:00:00Z", @@ -88061,8 +100277,10 @@ "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, @@ -88076,8 +100294,10 @@ "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 } @@ -88093,7 +100313,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "2024-01-01T00:00:00Z", @@ -88696,8 +100916,10 @@ "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, @@ -88711,8 +100933,10 @@ "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 } @@ -88728,7 +100952,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "2024-01-01T00:00:00Z", @@ -89104,8 +101328,10 @@ "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, @@ -89119,8 +101345,10 @@ "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 } @@ -89158,8 +101386,10 @@ "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, @@ -89173,8 +101403,10 @@ "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 } @@ -89331,8 +101563,10 @@ "description": "Array of available encoding variants for the media item (e.g. different resolutions). Present on `media` type only; omitted otherwise.", "example": [ { + "byte_size": 1, "content_type": "application/json", "created_at": "2024-01-01T00:00:00Z", + "duration_ms": 1, "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", "filename": "string", "height": 600, @@ -89346,8 +101580,10 @@ "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 } @@ -89355,8 +101591,10 @@ "items": { "description": "A processed variant of a media item, such as the original upload or a resized thumbnail, including a signed download URL resolved at request time.", "example": { + "byte_size": 1, "content_type": "application/json", "created_at": "2024-01-01T00:00:00Z", + "duration_ms": 1, "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", "filename": "string", "height": 600, @@ -89370,12 +101608,20 @@ "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 }, "properties": { + "byte_size": { + "description": "Size of the stored bytes.", + "example": 1, + "nullable": true, + "type": "integer" + }, "content_type": { "description": "MIME type of this variant's file (e.g., `\"image/jpeg\"`, `\"video/mp4\"`). `null` if the file is not loaded.", "example": "application/json", @@ -89388,6 +101634,12 @@ "format": "date-time", "type": "string" }, + "duration_ms": { + "description": "Client-declared video duration in milliseconds; not server-probed.", + "example": 1, + "nullable": true, + "type": "integer" + }, "file": { "description": "ID of the underlying storage file that backs this variant (`fil_...`).", "example": "fil_0aBcDeFgHiJkLmNoPqRsTu", @@ -89468,6 +101720,12 @@ }, "type": "object" }, + "sha256": { + "description": "Lowercase SHA-256 of the stored bytes.", + "example": "string", + "nullable": true, + "type": "string" + }, "updated_at": { "description": "When this variant was last updated (ISO 8601).", "example": "2024-01-01T00:00:00Z", @@ -89480,6 +101738,13 @@ "nullable": true, "type": "string" }, + "url_expires_at": { + "description": "Expiry of this variant's playable URL.", + "example": "2024-01-01T00:00:00Z", + "format": "date-time", + "nullable": true, + "type": "string" + }, "variant_key": { "description": "Identifier for this variant's processing tier. Common values include `\"original\"` (the unmodified upload) and `\"thumbnail\"` (a resized preview).", "example": "original", @@ -89539,7 +101804,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "items": { @@ -89548,7 +101813,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" }, "properties": { "attributes": { @@ -89570,7 +101835,7 @@ }, "type": { "description": "Stable context kind. Must start with a lowercase letter and contain only lowercase letters, numbers, dots, dashes, or underscores.", - "example": "archdev.pull_request", + "example": "myapp.pull_request", "type": "string" } }, @@ -89782,8 +102047,10 @@ "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, @@ -89797,8 +102064,10 @@ "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 } @@ -89814,7 +102083,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "2024-01-01T00:00:00Z", @@ -93658,7 +105927,7 @@ }, "/api/v1/workflows/run": { "post": { - "description": "Executes a single workflow node or a complete workflow graph and returns the result.\nSupply either `node` (to run one node in isolation) or `graph` (to execute a full\ndirected graph); the two parameters are mutually exclusive and exactly one must be\nprovided.\n\nThe authenticated developer is used as the default workflow principal for entitlement\nchecks on billable operations such as LLM calls. Supply `run_as_user` or\n`run_as_agent` to override the acting identity for the execution — at most one\noverride may be set per request.\n\nExecution errors are logged to the activity feed under the acting identity so they\nappear alongside automation-driven workflow errors in operator dashboards. A 422\nresponse is returned when execution fails; the response body includes the error\nmessage and any partial records produced before the failure.\n", + "description": "Executes a single workflow node or a complete workflow graph and returns the result.\nSupply either `node` (to run one node in isolation) or `graph` (to execute a full\ndirected graph); the two parameters are mutually exclusive and exactly one must be\nprovided.\n\nThe authenticated developer is used as the default workflow principal for entitlement\nchecks on billable operations such as LLM calls. Supply `run_as_user` or\n`run_as_agent` to override the acting identity for the execution — at most one\noverride may be set per request. Overrides are subject to the caller's\ndelegation permissions, the same ones `/scripts/run` applies: app secret keys\nand developer tokens may run as any user or agent in the app; other callers may\nrun as themselves, and as an agent they own (org admins as any agent in their\norg). A refused override returns 403 before anything runs.\n\nExecution errors are logged to the activity feed under the acting identity so they\nappear alongside automation-driven workflow errors in operator dashboards. A 422\nresponse is returned when execution fails; the response body includes the error\nmessage and any partial records produced before the failure.\n", "operationId": "post_api_v1_workflows_run", "parameters": [], "requestBody": { @@ -93826,6 +106095,12 @@ "401": { "description": "Unauthorized" }, + "403": { + "description": "Execution identity is not authorized" + }, + "404": { + "description": "Execution identity was not found" + }, "422": { "description": "Execution failed" } @@ -94114,7 +106389,8 @@ "device_code": "string", "grant_type": "string", "redirect_uri": "https://example.com", - "refresh_token": "string" + "refresh_token": "string", + "resource": "string" }, "properties": { "client": { @@ -94151,6 +106427,11 @@ "description": "Refresh token received from a previous token response. Required for `\"refresh_token\"` grants. The token is rotated on each successful call.", "example": "string", "type": "string" + }, + "resource": { + "description": "Resource audience. Required for code exchange and refresh of a token bound to a resource server; must match the consent grant.", + "example": "string", + "type": "string" } }, "required": [ @@ -96501,6 +108782,827 @@ "bearer" ] }, + { + "description": "Authenticated collaborative editing for durable Artifacts.\n\nThe live OT revision and `dirty` flag describe synchronization, not durability.\nOnly `checkpointed_revision` and checkpoint events confirm a completed save;\nprocess or node loss can discard the dirty tail after the last successful save.\n", + "joins": [ + { + "description": "Join an Artifact's authenticated live editing session.", + "name": "join_artifact", + "params": { + "example": { + "artifact_id": "string", + "as_agent": "string" + }, + "properties": { + "artifact_id": { + "example": "string", + "type": "string" + }, + "as_agent": { + "example": "string", + "type": "string" + } + }, + "required": [ + "artifact_id" + ], + "type": "object" + }, + "pattern": "api:artifact:{artifact_id}", + "returns": { + "description": "Authoritative live Artifact snapshot returned by an editing-channel join.", + "example": { + "actor_id": "string", + "actors": [ + { + "actor_id": "string", + "cursor": { + "position": 1, + "selection_end": 1 + }, + "meta": {} + } + ], + "artifact": "string", + "artifact_version": "string", + "artifact_version_number": 1, + "can_write": true, + "checkpoint_error": "string", + "checkpointed_revision": 1, + "connection_id": "string", + "content": "string", + "dirty": true, + "incarnation": "string", + "revision": 1 + }, + "properties": { + "actor_id": { + "description": "Server-issued identity for this channel join.", + "example": "string", + "type": "string" + }, + "actors": { + "example": [ + { + "actor_id": "string", + "cursor": { + "position": 1, + "selection_end": 1 + }, + "meta": {} + } + ], + "items": { + "description": "A server-issued collaborator identity and its ephemeral presence.", + "example": { + "actor_id": "string", + "cursor": { + "position": 1, + "selection_end": 1 + }, + "meta": {} + }, + "properties": { + "actor_id": { + "description": "Opaque identity unique to this channel join.", + "example": "string", + "type": "string" + }, + "cursor": { + "description": "Current code-point cursor, or null.", + "example": { + "position": 1, + "selection_end": 1 + }, + "nullable": true, + "properties": { + "position": { + "description": "Zero-based Unicode code-point position.", + "example": 1, + "type": "integer" + }, + "selection_end": { + "description": "Zero-based Unicode code-point selection endpoint.", + "example": 1, + "type": "integer" + } + }, + "required": [ + "position" + ], + "type": "object" + }, + "meta": { + "description": "Server-derived collaborator display metadata.", + "example": {}, + "type": "object" + } + }, + "required": [ + "actor_id", + "meta" + ], + "type": "object" + }, + "type": "array" + }, + "artifact": { + "description": "Public Artifact ID (`art_...`).", + "example": "string", + "type": "string" + }, + "artifact_version": { + "description": "Durable version ID (`artv_...`).", + "example": "string", + "type": "string" + }, + "artifact_version_number": { + "example": 1, + "type": "integer" + }, + "can_write": { + "example": true, + "type": "boolean" + }, + "checkpoint_error": { + "description": "Last durable-save failure reason, or null.", + "example": "string", + "nullable": true, + "type": "string" + }, + "checkpointed_revision": { + "description": "Latest revision known durable.", + "example": 1, + "type": "integer" + }, + "connection_id": { + "description": "Server-issued connection identity.", + "example": "string", + "type": "string" + }, + "content": { + "description": "UTF-8 document content.", + "example": "string", + "type": "string" + }, + "dirty": { + "description": "True while a live tail remains crash-loss exposed.", + "example": true, + "type": "boolean" + }, + "incarnation": { + "description": "Opaque live-session fence token.", + "example": "string", + "type": "string" + }, + "revision": { + "description": "Live OT revision in Unicode code points.", + "example": 1, + "type": "integer" + } + }, + "required": [ + "artifact", + "artifact_version", + "artifact_version_number", + "actor_id", + "connection_id", + "incarnation", + "content", + "revision", + "checkpointed_revision", + "dirty", + "can_write", + "actors" + ], + "type": "object" + } + } + ], + "messages": [ + { + "description": "Submit an OT operation against a live revision; success replies only after application.", + "event": "operation", + "params": { + "example": { + "cursor": { + "position": 1, + "selection_end": 1 + }, + "op": [], + "op_id": "string", + "revision": 1 + }, + "properties": { + "cursor": { + "description": "A Unicode code-point cursor and optional selection endpoint.", + "example": { + "position": 1, + "selection_end": 1 + }, + "properties": { + "position": { + "description": "Zero-based Unicode code-point position.", + "example": 1, + "type": "integer" + }, + "selection_end": { + "description": "Zero-based Unicode code-point selection endpoint.", + "example": 1, + "type": "integer" + } + }, + "required": [ + "position" + ], + "type": "object" + }, + "op": { + "example": [], + "type": "array" + }, + "op_id": { + "example": "string", + "type": "string" + }, + "revision": { + "example": 1, + "type": "integer" + } + }, + "required": [ + "revision", + "op" + ], + "type": "object" + }, + "returns": { + "description": "Acknowledges an operation only after the authoritative OT server applied it.", + "example": { + "revision": 1 + }, + "properties": { + "revision": { + "description": "Authoritative live revision after application.", + "example": 1, + "type": "integer" + } + }, + "required": [ + "revision" + ], + "type": "object" + } + }, + { + "description": "Publish a cursor mapped from the supplied revision to the current head.", + "event": "cursor", + "params": { + "example": { + "cursor": { + "position": 1, + "selection_end": 1 + }, + "revision": 1 + }, + "properties": { + "cursor": { + "description": "A Unicode code-point cursor and optional selection endpoint.", + "example": { + "position": 1, + "selection_end": 1 + }, + "properties": { + "position": { + "description": "Zero-based Unicode code-point position.", + "example": 1, + "type": "integer" + }, + "selection_end": { + "description": "Zero-based Unicode code-point selection endpoint.", + "example": 1, + "type": "integer" + } + }, + "required": [ + "position" + ], + "type": "object" + }, + "revision": { + "example": 1, + "type": "integer" + } + }, + "type": "object" + }, + "returns": { + "description": "Acknowledges an Artifact editing presence or leave request.", + "example": { + "ok": true + }, + "properties": { + "ok": { + "example": true, + "type": "boolean" + } + }, + "required": [ + "ok" + ], + "type": "object" + } + }, + { + "description": "Relay opaque, transient coordination to joined actors in document order.", + "event": "signal", + "params": { + "example": { + "kind": "string", + "payload": {}, + "to": "string" + }, + "properties": { + "kind": { + "example": "string", + "type": "string" + }, + "payload": { + "example": {}, + "type": "object" + }, + "to": { + "example": "string", + "type": "string" + } + }, + "required": [ + "kind", + "to", + "payload" + ], + "type": "object" + }, + "returns": { + "description": "Acknowledges an Artifact editing presence or leave request.", + "example": { + "ok": true + }, + "properties": { + "ok": { + "example": true, + "type": "boolean" + } + }, + "required": [ + "ok" + ], + "type": "object" + } + }, + { + "description": "Persist the current live snapshot as a new durable ArtifactVersion.", + "event": "checkpoint", + "params": { + "properties": {}, + "type": "object" + }, + "returns": { + "description": "Confirms the exact live revision that reached durable ArtifactVersion storage.", + "example": { + "artifact_version": "string", + "artifact_version_number": 1, + "checkpointed_revision": 1, + "dirty": true, + "incarnation": "string" + }, + "properties": { + "artifact_version": { + "description": "New durable ArtifactVersion ID.", + "example": "string", + "type": "string" + }, + "artifact_version_number": { + "example": 1, + "type": "integer" + }, + "checkpointed_revision": { + "example": 1, + "type": "integer" + }, + "dirty": { + "description": "True when later live operations remain unsaved.", + "example": true, + "type": "boolean" + }, + "incarnation": { + "example": "string", + "type": "string" + } + }, + "required": [ + "incarnation", + "checkpointed_revision", + "artifact_version", + "artifact_version_number", + "dirty" + ], + "type": "object" + } + }, + { + "description": "Detach this server-issued actor from the live session.", + "event": "leave", + "params": { + "properties": {}, + "type": "object" + }, + "returns": { + "description": "Acknowledges an Artifact editing presence or leave request.", + "example": { + "ok": true + }, + "properties": { + "ok": { + "example": true, + "type": "boolean" + } + }, + "required": [ + "ok" + ], + "type": "object" + } + } + ], + "name": "ApiArtifactChannel", + "pushes": [ + { + "description": "An identified operation was refused; it was not applied.", + "event": "op_rejected", + "payload": { + "example": { + "op_id": "string", + "reason": "string" + }, + "properties": { + "op_id": { + "example": "string", + "type": "string" + }, + "reason": { + "example": "string", + "type": "string" + } + }, + "required": [ + "op_id", + "reason" + ], + "type": "object" + } + }, + { + "description": "A peer operation applied by the authoritative OT server.", + "event": "operation", + "payload": { + "example": { + "actor_id": "string", + "cursor": { + "position": 1, + "selection_end": 1 + }, + "incarnation": "string", + "op": [], + "revision": 1 + }, + "properties": { + "actor_id": { + "example": "string", + "type": "string" + }, + "cursor": { + "description": "A Unicode code-point cursor and optional selection endpoint.", + "example": { + "position": 1, + "selection_end": 1 + }, + "nullable": true, + "properties": { + "position": { + "description": "Zero-based Unicode code-point position.", + "example": 1, + "type": "integer" + }, + "selection_end": { + "description": "Zero-based Unicode code-point selection endpoint.", + "example": 1, + "type": "integer" + } + }, + "required": [ + "position" + ], + "type": "object" + }, + "incarnation": { + "example": "string", + "type": "string" + }, + "op": { + "example": [], + "type": "array" + }, + "revision": { + "example": 1, + "type": "integer" + } + }, + "required": [ + "actor_id", + "revision", + "op", + "cursor", + "incarnation" + ], + "type": "object" + } + }, + { + "description": "Opaque coordination from another joined actor; never persisted or replayed.", + "event": "signal", + "payload": { + "example": { + "from": "string", + "incarnation": "string", + "kind": "string", + "payload": {}, + "revision": 1, + "to": "string" + }, + "properties": { + "from": { + "example": "string", + "type": "string" + }, + "incarnation": { + "example": "string", + "type": "string" + }, + "kind": { + "example": "string", + "type": "string" + }, + "payload": { + "example": {}, + "type": "object" + }, + "revision": { + "example": 1, + "type": "integer" + }, + "to": { + "example": "string", + "type": "string" + } + }, + "required": [ + "kind", + "to", + "from", + "revision", + "payload", + "incarnation" + ], + "type": "object" + } + }, + { + "description": "A peer joined, moved its cursor, or left.", + "event": "presence", + "payload": { + "example": { + "actor_id": "string", + "cursor": { + "position": 1, + "selection_end": 1 + }, + "incarnation": "string", + "meta": {}, + "revision": 1, + "type": "joined" + }, + "properties": { + "actor_id": { + "example": "string", + "type": "string" + }, + "cursor": { + "description": "A Unicode code-point cursor and optional selection endpoint.", + "example": { + "position": 1, + "selection_end": 1 + }, + "nullable": true, + "properties": { + "position": { + "description": "Zero-based Unicode code-point position.", + "example": 1, + "type": "integer" + }, + "selection_end": { + "description": "Zero-based Unicode code-point selection endpoint.", + "example": 1, + "type": "integer" + } + }, + "required": [ + "position" + ], + "type": "object" + }, + "incarnation": { + "example": "string", + "type": "string" + }, + "meta": { + "example": {}, + "nullable": true, + "type": "object" + }, + "revision": { + "example": 1, + "nullable": true, + "type": "integer" + }, + "type": { + "enum": [ + "joined", + "cursor", + "left" + ], + "example": "joined", + "type": "string" + } + }, + "required": [ + "revision", + "type", + "actor_id", + "meta", + "cursor", + "incarnation" + ], + "type": "object" + } + }, + { + "description": "A live revision reached durable ArtifactVersion storage.", + "event": "checkpoint", + "payload": { + "example": { + "artifact_version": "string", + "artifact_version_number": 1, + "checkpointed_revision": 1, + "dirty": true, + "incarnation": "string" + }, + "properties": { + "artifact_version": { + "example": "string", + "type": "string" + }, + "artifact_version_number": { + "example": 1, + "type": "integer" + }, + "checkpointed_revision": { + "example": 1, + "type": "integer" + }, + "dirty": { + "example": true, + "type": "boolean" + }, + "incarnation": { + "example": "string", + "type": "string" + } + }, + "required": [ + "incarnation", + "checkpointed_revision", + "artifact_version", + "artifact_version_number", + "dirty" + ], + "type": "object" + } + }, + { + "description": "A save failed; the dirty live tail remains crash-loss exposed.", + "event": "checkpoint_failed", + "payload": { + "example": { + "automatic": true, + "checkpointed_revision": 1, + "dirty": true, + "incarnation": "string", + "reason": "string", + "revision": 1 + }, + "properties": { + "automatic": { + "example": true, + "type": "boolean" + }, + "checkpointed_revision": { + "example": 1, + "type": "integer" + }, + "dirty": { + "example": true, + "type": "boolean" + }, + "incarnation": { + "example": "string", + "type": "string" + }, + "reason": { + "example": "string", + "type": "string" + }, + "revision": { + "example": 1, + "type": "integer" + } + }, + "required": [ + "incarnation", + "checkpointed_revision", + "revision", + "dirty", + "reason", + "automatic" + ], + "type": "object" + } + }, + { + "description": "The live version was replaced, archived, or deleted and this incarnation is terminal.", + "event": "session_invalid", + "payload": { + "example": { + "incarnation": "string", + "reason": "replaced" + }, + "properties": { + "incarnation": { + "example": "string", + "type": "string" + }, + "reason": { + "enum": [ + "replaced", + "archived", + "deleted", + "owner_down" + ], + "example": "replaced", + "type": "string" + } + }, + "required": [ + "reason", + "incarnation" + ], + "type": "object" + } + }, + { + "description": "Current read authority failed; this subscriber was detached before further egress.", + "event": "access_revoked", + "payload": { + "example": { + "reason": "string" + }, + "properties": { + "reason": { + "example": "string", + "type": "string" + } + }, + "required": [ + "reason" + ], + "type": "object" + } + } + ], + "x-auth": [ + "bearer" + ] + }, { "description": "Channel for real-time chat messaging.\n\nSupports team-scoped and user-scoped threads with keyed, transient, and direct\nthread access patterns, plus org-scoped joins for organization-visibility\nthreads, where org membership alone grants read and post.\n", "joins": [ @@ -97421,8 +110523,10 @@ "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, @@ -97436,8 +110540,10 @@ "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 } @@ -97453,7 +110559,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "2024-01-01T00:00:00Z", @@ -97632,8 +110738,10 @@ "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, @@ -97647,8 +110755,10 @@ "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 } @@ -97664,7 +110774,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "2024-01-01T00:00:00Z", @@ -98083,8 +111193,10 @@ "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, @@ -98098,8 +111210,10 @@ "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 } @@ -98115,7 +111229,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "2024-01-01T00:00:00Z", @@ -98881,8 +111995,10 @@ "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, @@ -98896,8 +112012,10 @@ "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 } @@ -98913,7 +112031,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "2024-01-01T00:00:00Z", @@ -99092,8 +112210,10 @@ "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, @@ -99107,8 +112227,10 @@ "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 } @@ -99124,7 +112246,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "2024-01-01T00:00:00Z", @@ -103666,8 +116788,10 @@ "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, @@ -103681,8 +116805,10 @@ "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 } @@ -103698,7 +116824,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "2024-01-01T00:00:00Z", @@ -103814,8 +116940,10 @@ "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, @@ -103829,8 +116957,10 @@ "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 } @@ -103846,7 +116976,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "string", @@ -103950,8 +117080,10 @@ "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, @@ -103965,8 +117097,10 @@ "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 } @@ -103982,7 +117116,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "2024-01-01T00:00:00Z", @@ -104365,8 +117499,10 @@ "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, @@ -104380,8 +117516,10 @@ "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 } @@ -104419,8 +117557,10 @@ "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, @@ -104434,8 +117574,10 @@ "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 } @@ -104592,8 +117734,10 @@ "description": "Array of available encoding variants for the media item (e.g. different resolutions). Present on `media` type only; omitted otherwise.", "example": [ { + "byte_size": 1, "content_type": "application/json", "created_at": "2024-01-01T00:00:00Z", + "duration_ms": 1, "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", "filename": "string", "height": 600, @@ -104607,8 +117751,10 @@ "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 } @@ -104616,8 +117762,10 @@ "items": { "description": "A processed variant of a media item, such as the original upload or a resized thumbnail, including a signed download URL resolved at request time.", "example": { + "byte_size": 1, "content_type": "application/json", "created_at": "2024-01-01T00:00:00Z", + "duration_ms": 1, "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", "filename": "string", "height": 600, @@ -104631,12 +117779,20 @@ "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 }, "properties": { + "byte_size": { + "description": "Size of the stored bytes.", + "example": 1, + "nullable": true, + "type": "integer" + }, "content_type": { "description": "MIME type of this variant's file (e.g., `\"image/jpeg\"`, `\"video/mp4\"`). `null` if the file is not loaded.", "example": "application/json", @@ -104649,6 +117805,12 @@ "format": "date-time", "type": "string" }, + "duration_ms": { + "description": "Client-declared video duration in milliseconds; not server-probed.", + "example": 1, + "nullable": true, + "type": "integer" + }, "file": { "description": "ID of the underlying storage file that backs this variant (`fil_...`).", "example": "fil_0aBcDeFgHiJkLmNoPqRsTu", @@ -104729,6 +117891,12 @@ }, "type": "object" }, + "sha256": { + "description": "Lowercase SHA-256 of the stored bytes.", + "example": "string", + "nullable": true, + "type": "string" + }, "updated_at": { "description": "When this variant was last updated (ISO 8601).", "example": "2024-01-01T00:00:00Z", @@ -104741,6 +117909,13 @@ "nullable": true, "type": "string" }, + "url_expires_at": { + "description": "Expiry of this variant's playable URL.", + "example": "2024-01-01T00:00:00Z", + "format": "date-time", + "nullable": true, + "type": "string" + }, "variant_key": { "description": "Identifier for this variant's processing tier. Common values include `\"original\"` (the unmodified upload) and `\"thumbnail\"` (a resized preview).", "example": "original", @@ -104800,7 +117975,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "items": { @@ -104809,7 +117984,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" }, "properties": { "attributes": { @@ -104831,7 +118006,7 @@ }, "type": { "description": "Stable context kind. Must start with a lowercase letter and contain only lowercase letters, numbers, dots, dashes, or underscores.", - "example": "archdev.pull_request", + "example": "myapp.pull_request", "type": "string" } }, @@ -105043,8 +118218,10 @@ "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, @@ -105058,8 +118235,10 @@ "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 } @@ -105075,7 +118254,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "2024-01-01T00:00:00Z", @@ -105716,8 +118895,10 @@ "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, @@ -105731,8 +118912,10 @@ "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 } @@ -105748,7 +118931,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "2024-01-01T00:00:00Z", @@ -106351,8 +119534,10 @@ "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, @@ -106366,8 +119551,10 @@ "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 } @@ -106383,7 +119570,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "2024-01-01T00:00:00Z", @@ -106759,8 +119946,10 @@ "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, @@ -106774,8 +119963,10 @@ "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 } @@ -106813,8 +120004,10 @@ "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, @@ -106828,8 +120021,10 @@ "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 } @@ -106986,8 +120181,10 @@ "description": "Array of available encoding variants for the media item (e.g. different resolutions). Present on `media` type only; omitted otherwise.", "example": [ { + "byte_size": 1, "content_type": "application/json", "created_at": "2024-01-01T00:00:00Z", + "duration_ms": 1, "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", "filename": "string", "height": 600, @@ -107001,8 +120198,10 @@ "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 } @@ -107010,8 +120209,10 @@ "items": { "description": "A processed variant of a media item, such as the original upload or a resized thumbnail, including a signed download URL resolved at request time.", "example": { + "byte_size": 1, "content_type": "application/json", "created_at": "2024-01-01T00:00:00Z", + "duration_ms": 1, "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", "filename": "string", "height": 600, @@ -107025,12 +120226,20 @@ "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 }, "properties": { + "byte_size": { + "description": "Size of the stored bytes.", + "example": 1, + "nullable": true, + "type": "integer" + }, "content_type": { "description": "MIME type of this variant's file (e.g., `\"image/jpeg\"`, `\"video/mp4\"`). `null` if the file is not loaded.", "example": "application/json", @@ -107043,6 +120252,12 @@ "format": "date-time", "type": "string" }, + "duration_ms": { + "description": "Client-declared video duration in milliseconds; not server-probed.", + "example": 1, + "nullable": true, + "type": "integer" + }, "file": { "description": "ID of the underlying storage file that backs this variant (`fil_...`).", "example": "fil_0aBcDeFgHiJkLmNoPqRsTu", @@ -107123,6 +120338,12 @@ }, "type": "object" }, + "sha256": { + "description": "Lowercase SHA-256 of the stored bytes.", + "example": "string", + "nullable": true, + "type": "string" + }, "updated_at": { "description": "When this variant was last updated (ISO 8601).", "example": "2024-01-01T00:00:00Z", @@ -107135,6 +120356,13 @@ "nullable": true, "type": "string" }, + "url_expires_at": { + "description": "Expiry of this variant's playable URL.", + "example": "2024-01-01T00:00:00Z", + "format": "date-time", + "nullable": true, + "type": "string" + }, "variant_key": { "description": "Identifier for this variant's processing tier. Common values include `\"original\"` (the unmodified upload) and `\"thumbnail\"` (a resized preview).", "example": "original", @@ -107194,7 +120422,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "items": { @@ -107203,7 +120431,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" }, "properties": { "attributes": { @@ -107225,7 +120453,7 @@ }, "type": { "description": "Stable context kind. Must start with a lowercase letter and contain only lowercase letters, numbers, dots, dashes, or underscores.", - "example": "archdev.pull_request", + "example": "myapp.pull_request", "type": "string" } }, @@ -107437,8 +120665,10 @@ "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, @@ -107452,8 +120682,10 @@ "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 } @@ -107469,7 +120701,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "2024-01-01T00:00:00Z", @@ -110393,8 +123625,10 @@ "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, @@ -110408,8 +123642,10 @@ "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 } @@ -110425,7 +123661,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "2024-01-01T00:00:00Z", @@ -111028,8 +124264,10 @@ "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, @@ -111043,8 +124281,10 @@ "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 } @@ -111060,7 +124300,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "2024-01-01T00:00:00Z", @@ -111436,8 +124676,10 @@ "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, @@ -111451,8 +124693,10 @@ "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 } @@ -111490,8 +124734,10 @@ "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, @@ -111505,8 +124751,10 @@ "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 } @@ -111663,8 +124911,10 @@ "description": "Array of available encoding variants for the media item (e.g. different resolutions). Present on `media` type only; omitted otherwise.", "example": [ { + "byte_size": 1, "content_type": "application/json", "created_at": "2024-01-01T00:00:00Z", + "duration_ms": 1, "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", "filename": "string", "height": 600, @@ -111678,8 +124928,10 @@ "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 } @@ -111687,8 +124939,10 @@ "items": { "description": "A processed variant of a media item, such as the original upload or a resized thumbnail, including a signed download URL resolved at request time.", "example": { + "byte_size": 1, "content_type": "application/json", "created_at": "2024-01-01T00:00:00Z", + "duration_ms": 1, "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", "filename": "string", "height": 600, @@ -111702,12 +124956,20 @@ "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 }, "properties": { + "byte_size": { + "description": "Size of the stored bytes.", + "example": 1, + "nullable": true, + "type": "integer" + }, "content_type": { "description": "MIME type of this variant's file (e.g., `\"image/jpeg\"`, `\"video/mp4\"`). `null` if the file is not loaded.", "example": "application/json", @@ -111720,6 +124982,12 @@ "format": "date-time", "type": "string" }, + "duration_ms": { + "description": "Client-declared video duration in milliseconds; not server-probed.", + "example": 1, + "nullable": true, + "type": "integer" + }, "file": { "description": "ID of the underlying storage file that backs this variant (`fil_...`).", "example": "fil_0aBcDeFgHiJkLmNoPqRsTu", @@ -111800,6 +125068,12 @@ }, "type": "object" }, + "sha256": { + "description": "Lowercase SHA-256 of the stored bytes.", + "example": "string", + "nullable": true, + "type": "string" + }, "updated_at": { "description": "When this variant was last updated (ISO 8601).", "example": "2024-01-01T00:00:00Z", @@ -111812,6 +125086,13 @@ "nullable": true, "type": "string" }, + "url_expires_at": { + "description": "Expiry of this variant's playable URL.", + "example": "2024-01-01T00:00:00Z", + "format": "date-time", + "nullable": true, + "type": "string" + }, "variant_key": { "description": "Identifier for this variant's processing tier. Common values include `\"original\"` (the unmodified upload) and `\"thumbnail\"` (a resized preview).", "example": "original", @@ -111871,7 +125152,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "items": { @@ -111880,7 +125161,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" }, "properties": { "attributes": { @@ -111902,7 +125183,7 @@ }, "type": { "description": "Stable context kind. Must start with a lowercase letter and contain only lowercase letters, numbers, dots, dashes, or underscores.", - "example": "archdev.pull_request", + "example": "myapp.pull_request", "type": "string" } }, @@ -112114,8 +125395,10 @@ "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, @@ -112129,8 +125412,10 @@ "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 } @@ -112146,7 +125431,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "2024-01-01T00:00:00Z", @@ -114796,8 +128081,10 @@ "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, @@ -114811,8 +128098,10 @@ "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 } @@ -114828,7 +128117,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "2024-01-01T00:00:00Z", @@ -114947,8 +128236,10 @@ "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, @@ -114962,8 +128253,10 @@ "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 } @@ -114979,7 +128272,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "2024-01-01T00:00:00Z", @@ -115095,8 +128388,10 @@ "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, @@ -115110,8 +128405,10 @@ "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 } @@ -115127,7 +128424,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "string", @@ -115231,8 +128528,10 @@ "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, @@ -115246,8 +128545,10 @@ "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 } @@ -115263,7 +128564,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "2024-01-01T00:00:00Z", @@ -115646,8 +128947,10 @@ "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, @@ -115661,8 +128964,10 @@ "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 } @@ -115700,8 +129005,10 @@ "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, @@ -115715,8 +129022,10 @@ "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 } @@ -115873,8 +129182,10 @@ "description": "Array of available encoding variants for the media item (e.g. different resolutions). Present on `media` type only; omitted otherwise.", "example": [ { + "byte_size": 1, "content_type": "application/json", "created_at": "2024-01-01T00:00:00Z", + "duration_ms": 1, "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", "filename": "string", "height": 600, @@ -115888,8 +129199,10 @@ "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 } @@ -115897,8 +129210,10 @@ "items": { "description": "A processed variant of a media item, such as the original upload or a resized thumbnail, including a signed download URL resolved at request time.", "example": { + "byte_size": 1, "content_type": "application/json", "created_at": "2024-01-01T00:00:00Z", + "duration_ms": 1, "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", "filename": "string", "height": 600, @@ -115912,12 +129227,20 @@ "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 }, "properties": { + "byte_size": { + "description": "Size of the stored bytes.", + "example": 1, + "nullable": true, + "type": "integer" + }, "content_type": { "description": "MIME type of this variant's file (e.g., `\"image/jpeg\"`, `\"video/mp4\"`). `null` if the file is not loaded.", "example": "application/json", @@ -115930,6 +129253,12 @@ "format": "date-time", "type": "string" }, + "duration_ms": { + "description": "Client-declared video duration in milliseconds; not server-probed.", + "example": 1, + "nullable": true, + "type": "integer" + }, "file": { "description": "ID of the underlying storage file that backs this variant (`fil_...`).", "example": "fil_0aBcDeFgHiJkLmNoPqRsTu", @@ -116010,6 +129339,12 @@ }, "type": "object" }, + "sha256": { + "description": "Lowercase SHA-256 of the stored bytes.", + "example": "string", + "nullable": true, + "type": "string" + }, "updated_at": { "description": "When this variant was last updated (ISO 8601).", "example": "2024-01-01T00:00:00Z", @@ -116022,6 +129357,13 @@ "nullable": true, "type": "string" }, + "url_expires_at": { + "description": "Expiry of this variant's playable URL.", + "example": "2024-01-01T00:00:00Z", + "format": "date-time", + "nullable": true, + "type": "string" + }, "variant_key": { "description": "Identifier for this variant's processing tier. Common values include `\"original\"` (the unmodified upload) and `\"thumbnail\"` (a resized preview).", "example": "original", @@ -116081,7 +129423,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "items": { @@ -116090,7 +129432,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" }, "properties": { "attributes": { @@ -116112,7 +129454,7 @@ }, "type": { "description": "Stable context kind. Must start with a lowercase letter and contain only lowercase letters, numbers, dots, dashes, or underscores.", - "example": "archdev.pull_request", + "example": "myapp.pull_request", "type": "string" } }, @@ -116324,8 +129666,10 @@ "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, @@ -116339,8 +129683,10 @@ "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 } @@ -116356,7 +129702,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "2024-01-01T00:00:00Z", @@ -117121,8 +130467,10 @@ "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, @@ -117136,8 +130484,10 @@ "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 } @@ -117153,7 +130503,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "2024-01-01T00:00:00Z", @@ -117332,8 +130682,10 @@ "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, @@ -117347,8 +130699,10 @@ "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 } @@ -117364,7 +130718,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "2024-01-01T00:00:00Z", @@ -118131,8 +131485,10 @@ "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, @@ -118146,8 +131502,10 @@ "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 } @@ -118163,7 +131521,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "2024-01-01T00:00:00Z", @@ -118342,8 +131700,10 @@ "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, @@ -118357,8 +131717,10 @@ "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 } @@ -118374,7 +131736,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "2024-01-01T00:00:00Z", @@ -122916,8 +136278,10 @@ "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, @@ -122931,8 +136295,10 @@ "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 } @@ -122948,7 +136314,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "2024-01-01T00:00:00Z", @@ -123064,8 +136430,10 @@ "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, @@ -123079,8 +136447,10 @@ "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 } @@ -123096,7 +136466,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "string", @@ -123200,8 +136570,10 @@ "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, @@ -123215,8 +136587,10 @@ "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 } @@ -123232,7 +136606,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "2024-01-01T00:00:00Z", @@ -123615,8 +136989,10 @@ "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, @@ -123630,8 +137006,10 @@ "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 } @@ -123669,8 +137047,10 @@ "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, @@ -123684,8 +137064,10 @@ "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 } @@ -123842,8 +137224,10 @@ "description": "Array of available encoding variants for the media item (e.g. different resolutions). Present on `media` type only; omitted otherwise.", "example": [ { + "byte_size": 1, "content_type": "application/json", "created_at": "2024-01-01T00:00:00Z", + "duration_ms": 1, "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", "filename": "string", "height": 600, @@ -123857,8 +137241,10 @@ "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 } @@ -123866,8 +137252,10 @@ "items": { "description": "A processed variant of a media item, such as the original upload or a resized thumbnail, including a signed download URL resolved at request time.", "example": { + "byte_size": 1, "content_type": "application/json", "created_at": "2024-01-01T00:00:00Z", + "duration_ms": 1, "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", "filename": "string", "height": 600, @@ -123881,12 +137269,20 @@ "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 }, "properties": { + "byte_size": { + "description": "Size of the stored bytes.", + "example": 1, + "nullable": true, + "type": "integer" + }, "content_type": { "description": "MIME type of this variant's file (e.g., `\"image/jpeg\"`, `\"video/mp4\"`). `null` if the file is not loaded.", "example": "application/json", @@ -123899,6 +137295,12 @@ "format": "date-time", "type": "string" }, + "duration_ms": { + "description": "Client-declared video duration in milliseconds; not server-probed.", + "example": 1, + "nullable": true, + "type": "integer" + }, "file": { "description": "ID of the underlying storage file that backs this variant (`fil_...`).", "example": "fil_0aBcDeFgHiJkLmNoPqRsTu", @@ -123979,6 +137381,12 @@ }, "type": "object" }, + "sha256": { + "description": "Lowercase SHA-256 of the stored bytes.", + "example": "string", + "nullable": true, + "type": "string" + }, "updated_at": { "description": "When this variant was last updated (ISO 8601).", "example": "2024-01-01T00:00:00Z", @@ -123991,6 +137399,13 @@ "nullable": true, "type": "string" }, + "url_expires_at": { + "description": "Expiry of this variant's playable URL.", + "example": "2024-01-01T00:00:00Z", + "format": "date-time", + "nullable": true, + "type": "string" + }, "variant_key": { "description": "Identifier for this variant's processing tier. Common values include `\"original\"` (the unmodified upload) and `\"thumbnail\"` (a resized preview).", "example": "original", @@ -124050,7 +137465,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "items": { @@ -124059,7 +137474,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" }, "properties": { "attributes": { @@ -124081,7 +137496,7 @@ }, "type": { "description": "Stable context kind. Must start with a lowercase letter and contain only lowercase letters, numbers, dots, dashes, or underscores.", - "example": "archdev.pull_request", + "example": "myapp.pull_request", "type": "string" } }, @@ -124293,8 +137708,10 @@ "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, @@ -124308,8 +137725,10 @@ "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 } @@ -124325,7 +137744,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "2024-01-01T00:00:00Z", @@ -124966,8 +138385,10 @@ "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, @@ -124981,8 +138402,10 @@ "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 } @@ -124998,7 +138421,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "2024-01-01T00:00:00Z", @@ -125601,8 +139024,10 @@ "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, @@ -125616,8 +139041,10 @@ "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 } @@ -125633,7 +139060,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "2024-01-01T00:00:00Z", @@ -126009,8 +139436,10 @@ "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, @@ -126024,8 +139453,10 @@ "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 } @@ -126063,8 +139494,10 @@ "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, @@ -126078,8 +139511,10 @@ "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 } @@ -126236,8 +139671,10 @@ "description": "Array of available encoding variants for the media item (e.g. different resolutions). Present on `media` type only; omitted otherwise.", "example": [ { + "byte_size": 1, "content_type": "application/json", "created_at": "2024-01-01T00:00:00Z", + "duration_ms": 1, "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", "filename": "string", "height": 600, @@ -126251,8 +139688,10 @@ "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 } @@ -126260,8 +139699,10 @@ "items": { "description": "A processed variant of a media item, such as the original upload or a resized thumbnail, including a signed download URL resolved at request time.", "example": { + "byte_size": 1, "content_type": "application/json", "created_at": "2024-01-01T00:00:00Z", + "duration_ms": 1, "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", "filename": "string", "height": 600, @@ -126275,12 +139716,20 @@ "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 }, "properties": { + "byte_size": { + "description": "Size of the stored bytes.", + "example": 1, + "nullable": true, + "type": "integer" + }, "content_type": { "description": "MIME type of this variant's file (e.g., `\"image/jpeg\"`, `\"video/mp4\"`). `null` if the file is not loaded.", "example": "application/json", @@ -126293,6 +139742,12 @@ "format": "date-time", "type": "string" }, + "duration_ms": { + "description": "Client-declared video duration in milliseconds; not server-probed.", + "example": 1, + "nullable": true, + "type": "integer" + }, "file": { "description": "ID of the underlying storage file that backs this variant (`fil_...`).", "example": "fil_0aBcDeFgHiJkLmNoPqRsTu", @@ -126373,6 +139828,12 @@ }, "type": "object" }, + "sha256": { + "description": "Lowercase SHA-256 of the stored bytes.", + "example": "string", + "nullable": true, + "type": "string" + }, "updated_at": { "description": "When this variant was last updated (ISO 8601).", "example": "2024-01-01T00:00:00Z", @@ -126385,6 +139846,13 @@ "nullable": true, "type": "string" }, + "url_expires_at": { + "description": "Expiry of this variant's playable URL.", + "example": "2024-01-01T00:00:00Z", + "format": "date-time", + "nullable": true, + "type": "string" + }, "variant_key": { "description": "Identifier for this variant's processing tier. Common values include `\"original\"` (the unmodified upload) and `\"thumbnail\"` (a resized preview).", "example": "original", @@ -126444,7 +139912,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "items": { @@ -126453,7 +139921,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" }, "properties": { "attributes": { @@ -126475,7 +139943,7 @@ }, "type": { "description": "Stable context kind. Must start with a lowercase letter and contain only lowercase letters, numbers, dots, dashes, or underscores.", - "example": "archdev.pull_request", + "example": "myapp.pull_request", "type": "string" } }, @@ -126687,8 +140155,10 @@ "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, @@ -126702,8 +140172,10 @@ "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 } @@ -126719,7 +140191,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "2024-01-01T00:00:00Z", @@ -129267,10 +142739,16 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "idempotency_key": "string", + "mentions": [ + "string" + ], + "metadata": { + "key": "value" + }, "reply_to": "string", "uploads": [ {} @@ -129287,7 +142765,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "items": { @@ -129296,7 +142774,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" }, "properties": { "attributes": { @@ -129318,7 +142796,7 @@ }, "type": { "description": "Stable context kind. Must start with a lowercase letter and contain only lowercase letters, numbers, dots, dashes, or underscores.", - "example": "archdev.pull_request", + "example": "myapp.pull_request", "type": "string" } }, @@ -129333,6 +142811,21 @@ "example": "string", "type": "string" }, + "mentions": { + "example": [ + "string" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "metadata": { + "example": { + "key": "value" + }, + "type": "object" + }, "reply_to": { "example": "string", "type": "string" @@ -129430,8 +142923,10 @@ "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, @@ -129445,8 +142940,10 @@ "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 } @@ -129462,7 +142959,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "2024-01-01T00:00:00Z", @@ -129579,8 +143076,10 @@ "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, @@ -129594,8 +143093,10 @@ "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 } @@ -129611,7 +143112,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "2024-01-01T00:00:00Z", @@ -129986,8 +143487,10 @@ "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, @@ -130001,8 +143504,10 @@ "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 } @@ -130040,8 +143545,10 @@ "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, @@ -130055,8 +143562,10 @@ "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 } @@ -130213,8 +143722,10 @@ "description": "Array of available encoding variants for the media item (e.g. different resolutions). Present on `media` type only; omitted otherwise.", "example": [ { + "byte_size": 1, "content_type": "application/json", "created_at": "2024-01-01T00:00:00Z", + "duration_ms": 1, "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", "filename": "string", "height": 600, @@ -130228,8 +143739,10 @@ "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 } @@ -130237,8 +143750,10 @@ "items": { "description": "A processed variant of a media item, such as the original upload or a resized thumbnail, including a signed download URL resolved at request time.", "example": { + "byte_size": 1, "content_type": "application/json", "created_at": "2024-01-01T00:00:00Z", + "duration_ms": 1, "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", "filename": "string", "height": 600, @@ -130252,12 +143767,20 @@ "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 }, "properties": { + "byte_size": { + "description": "Size of the stored bytes.", + "example": 1, + "nullable": true, + "type": "integer" + }, "content_type": { "description": "MIME type of this variant's file (e.g., `\"image/jpeg\"`, `\"video/mp4\"`). `null` if the file is not loaded.", "example": "application/json", @@ -130270,6 +143793,12 @@ "format": "date-time", "type": "string" }, + "duration_ms": { + "description": "Client-declared video duration in milliseconds; not server-probed.", + "example": 1, + "nullable": true, + "type": "integer" + }, "file": { "description": "ID of the underlying storage file that backs this variant (`fil_...`).", "example": "fil_0aBcDeFgHiJkLmNoPqRsTu", @@ -130350,6 +143879,12 @@ }, "type": "object" }, + "sha256": { + "description": "Lowercase SHA-256 of the stored bytes.", + "example": "string", + "nullable": true, + "type": "string" + }, "updated_at": { "description": "When this variant was last updated (ISO 8601).", "example": "2024-01-01T00:00:00Z", @@ -130362,6 +143897,13 @@ "nullable": true, "type": "string" }, + "url_expires_at": { + "description": "Expiry of this variant's playable URL.", + "example": "2024-01-01T00:00:00Z", + "format": "date-time", + "nullable": true, + "type": "string" + }, "variant_key": { "description": "Identifier for this variant's processing tier. Common values include `\"original\"` (the unmodified upload) and `\"thumbnail\"` (a resized preview).", "example": "original", @@ -130421,7 +143963,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "items": { @@ -130430,7 +143972,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" }, "properties": { "attributes": { @@ -130452,7 +143994,7 @@ }, "type": { "description": "Stable context kind. Must start with a lowercase letter and contain only lowercase letters, numbers, dots, dashes, or underscores.", - "example": "archdev.pull_request", + "example": "myapp.pull_request", "type": "string" } }, @@ -130664,8 +144206,10 @@ "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, @@ -130679,8 +144223,10 @@ "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 } @@ -130696,7 +144242,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "2024-01-01T00:00:00Z", @@ -130954,10 +144500,16 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "idempotency_key": "string", + "mentions": [ + "string" + ], + "metadata": { + "key": "value" + }, "reply_to": "string" }, "properties": { @@ -130971,7 +144523,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "items": { @@ -130980,7 +144532,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" }, "properties": { "attributes": { @@ -131002,7 +144554,7 @@ }, "type": { "description": "Stable context kind. Must start with a lowercase letter and contain only lowercase letters, numbers, dots, dashes, or underscores.", - "example": "archdev.pull_request", + "example": "myapp.pull_request", "type": "string" } }, @@ -131017,6 +144569,21 @@ "example": "string", "type": "string" }, + "mentions": { + "example": [ + "string" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "metadata": { + "example": { + "key": "value" + }, + "type": "object" + }, "reply_to": { "example": "string", "type": "string" @@ -131102,8 +144669,10 @@ "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, @@ -131117,8 +144686,10 @@ "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 } @@ -131134,7 +144705,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "2024-01-01T00:00:00Z", @@ -131251,8 +144822,10 @@ "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, @@ -131266,8 +144839,10 @@ "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 } @@ -131283,7 +144858,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "2024-01-01T00:00:00Z", @@ -131658,8 +145233,10 @@ "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, @@ -131673,8 +145250,10 @@ "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 } @@ -131712,8 +145291,10 @@ "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, @@ -131727,8 +145308,10 @@ "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 } @@ -131885,8 +145468,10 @@ "description": "Array of available encoding variants for the media item (e.g. different resolutions). Present on `media` type only; omitted otherwise.", "example": [ { + "byte_size": 1, "content_type": "application/json", "created_at": "2024-01-01T00:00:00Z", + "duration_ms": 1, "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", "filename": "string", "height": 600, @@ -131900,8 +145485,10 @@ "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 } @@ -131909,8 +145496,10 @@ "items": { "description": "A processed variant of a media item, such as the original upload or a resized thumbnail, including a signed download URL resolved at request time.", "example": { + "byte_size": 1, "content_type": "application/json", "created_at": "2024-01-01T00:00:00Z", + "duration_ms": 1, "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", "filename": "string", "height": 600, @@ -131924,12 +145513,20 @@ "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 }, "properties": { + "byte_size": { + "description": "Size of the stored bytes.", + "example": 1, + "nullable": true, + "type": "integer" + }, "content_type": { "description": "MIME type of this variant's file (e.g., `\"image/jpeg\"`, `\"video/mp4\"`). `null` if the file is not loaded.", "example": "application/json", @@ -131942,6 +145539,12 @@ "format": "date-time", "type": "string" }, + "duration_ms": { + "description": "Client-declared video duration in milliseconds; not server-probed.", + "example": 1, + "nullable": true, + "type": "integer" + }, "file": { "description": "ID of the underlying storage file that backs this variant (`fil_...`).", "example": "fil_0aBcDeFgHiJkLmNoPqRsTu", @@ -132022,6 +145625,12 @@ }, "type": "object" }, + "sha256": { + "description": "Lowercase SHA-256 of the stored bytes.", + "example": "string", + "nullable": true, + "type": "string" + }, "updated_at": { "description": "When this variant was last updated (ISO 8601).", "example": "2024-01-01T00:00:00Z", @@ -132034,6 +145643,13 @@ "nullable": true, "type": "string" }, + "url_expires_at": { + "description": "Expiry of this variant's playable URL.", + "example": "2024-01-01T00:00:00Z", + "format": "date-time", + "nullable": true, + "type": "string" + }, "variant_key": { "description": "Identifier for this variant's processing tier. Common values include `\"original\"` (the unmodified upload) and `\"thumbnail\"` (a resized preview).", "example": "original", @@ -132093,7 +145709,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "items": { @@ -132102,7 +145718,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" }, "properties": { "attributes": { @@ -132124,7 +145740,7 @@ }, "type": { "description": "Stable context kind. Must start with a lowercase letter and contain only lowercase letters, numbers, dots, dashes, or underscores.", - "example": "archdev.pull_request", + "example": "myapp.pull_request", "type": "string" } }, @@ -132336,8 +145952,10 @@ "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, @@ -132351,8 +145969,10 @@ "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 } @@ -132368,7 +145988,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "2024-01-01T00:00:00Z", @@ -133114,8 +146734,10 @@ "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, @@ -133129,8 +146751,10 @@ "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 } @@ -133146,7 +146770,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "2024-01-01T00:00:00Z", @@ -133272,8 +146896,10 @@ "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, @@ -133287,8 +146913,10 @@ "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 } @@ -133304,7 +146932,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "2024-01-01T00:00:00Z", @@ -133679,8 +147307,10 @@ "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, @@ -133694,8 +147324,10 @@ "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 } @@ -133733,8 +147365,10 @@ "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, @@ -133748,8 +147382,10 @@ "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 } @@ -133906,8 +147542,10 @@ "description": "Array of available encoding variants for the media item (e.g. different resolutions). Present on `media` type only; omitted otherwise.", "example": [ { + "byte_size": 1, "content_type": "application/json", "created_at": "2024-01-01T00:00:00Z", + "duration_ms": 1, "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", "filename": "string", "height": 600, @@ -133921,8 +147559,10 @@ "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 } @@ -133930,8 +147570,10 @@ "items": { "description": "A processed variant of a media item, such as the original upload or a resized thumbnail, including a signed download URL resolved at request time.", "example": { + "byte_size": 1, "content_type": "application/json", "created_at": "2024-01-01T00:00:00Z", + "duration_ms": 1, "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", "filename": "string", "height": 600, @@ -133945,12 +147587,20 @@ "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 }, "properties": { + "byte_size": { + "description": "Size of the stored bytes.", + "example": 1, + "nullable": true, + "type": "integer" + }, "content_type": { "description": "MIME type of this variant's file (e.g., `\"image/jpeg\"`, `\"video/mp4\"`). `null` if the file is not loaded.", "example": "application/json", @@ -133963,6 +147613,12 @@ "format": "date-time", "type": "string" }, + "duration_ms": { + "description": "Client-declared video duration in milliseconds; not server-probed.", + "example": 1, + "nullable": true, + "type": "integer" + }, "file": { "description": "ID of the underlying storage file that backs this variant (`fil_...`).", "example": "fil_0aBcDeFgHiJkLmNoPqRsTu", @@ -134043,6 +147699,12 @@ }, "type": "object" }, + "sha256": { + "description": "Lowercase SHA-256 of the stored bytes.", + "example": "string", + "nullable": true, + "type": "string" + }, "updated_at": { "description": "When this variant was last updated (ISO 8601).", "example": "2024-01-01T00:00:00Z", @@ -134055,6 +147717,13 @@ "nullable": true, "type": "string" }, + "url_expires_at": { + "description": "Expiry of this variant's playable URL.", + "example": "2024-01-01T00:00:00Z", + "format": "date-time", + "nullable": true, + "type": "string" + }, "variant_key": { "description": "Identifier for this variant's processing tier. Common values include `\"original\"` (the unmodified upload) and `\"thumbnail\"` (a resized preview).", "example": "original", @@ -134114,7 +147783,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "items": { @@ -134123,7 +147792,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" }, "properties": { "attributes": { @@ -134145,7 +147814,7 @@ }, "type": { "description": "Stable context kind. Must start with a lowercase letter and contain only lowercase letters, numbers, dots, dashes, or underscores.", - "example": "archdev.pull_request", + "example": "myapp.pull_request", "type": "string" } }, @@ -134357,8 +148026,10 @@ "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, @@ -134372,8 +148043,10 @@ "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 } @@ -134389,7 +148062,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "2024-01-01T00:00:00Z", @@ -134717,8 +148390,10 @@ "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, @@ -134732,8 +148407,10 @@ "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 } @@ -134749,7 +148426,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "2024-01-01T00:00:00Z", @@ -134867,8 +148544,10 @@ "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, @@ -134882,8 +148561,10 @@ "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 } @@ -134899,7 +148580,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "2024-01-01T00:00:00Z", @@ -135274,8 +148955,10 @@ "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, @@ -135289,8 +148972,10 @@ "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 } @@ -135328,8 +149013,10 @@ "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, @@ -135343,8 +149030,10 @@ "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 } @@ -135501,8 +149190,10 @@ "description": "Array of available encoding variants for the media item (e.g. different resolutions). Present on `media` type only; omitted otherwise.", "example": [ { + "byte_size": 1, "content_type": "application/json", "created_at": "2024-01-01T00:00:00Z", + "duration_ms": 1, "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", "filename": "string", "height": 600, @@ -135516,8 +149207,10 @@ "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 } @@ -135525,8 +149218,10 @@ "items": { "description": "A processed variant of a media item, such as the original upload or a resized thumbnail, including a signed download URL resolved at request time.", "example": { + "byte_size": 1, "content_type": "application/json", "created_at": "2024-01-01T00:00:00Z", + "duration_ms": 1, "file": "fil_0aBcDeFgHiJkLmNoPqRsTu", "filename": "string", "height": 600, @@ -135540,12 +149235,20 @@ "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 }, "properties": { + "byte_size": { + "description": "Size of the stored bytes.", + "example": 1, + "nullable": true, + "type": "integer" + }, "content_type": { "description": "MIME type of this variant's file (e.g., `\"image/jpeg\"`, `\"video/mp4\"`). `null` if the file is not loaded.", "example": "application/json", @@ -135558,6 +149261,12 @@ "format": "date-time", "type": "string" }, + "duration_ms": { + "description": "Client-declared video duration in milliseconds; not server-probed.", + "example": 1, + "nullable": true, + "type": "integer" + }, "file": { "description": "ID of the underlying storage file that backs this variant (`fil_...`).", "example": "fil_0aBcDeFgHiJkLmNoPqRsTu", @@ -135638,6 +149347,12 @@ }, "type": "object" }, + "sha256": { + "description": "Lowercase SHA-256 of the stored bytes.", + "example": "string", + "nullable": true, + "type": "string" + }, "updated_at": { "description": "When this variant was last updated (ISO 8601).", "example": "2024-01-01T00:00:00Z", @@ -135650,6 +149365,13 @@ "nullable": true, "type": "string" }, + "url_expires_at": { + "description": "Expiry of this variant's playable URL.", + "example": "2024-01-01T00:00:00Z", + "format": "date-time", + "nullable": true, + "type": "string" + }, "variant_key": { "description": "Identifier for this variant's processing tier. Common values include `\"original\"` (the unmodified upload) and `\"thumbnail\"` (a resized preview).", "example": "original", @@ -135709,7 +149431,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "items": { @@ -135718,7 +149440,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" }, "properties": { "attributes": { @@ -135740,7 +149462,7 @@ }, "type": { "description": "Stable context kind. Must start with a lowercase letter and contain only lowercase letters, numbers, dots, dashes, or underscores.", - "example": "archdev.pull_request", + "example": "myapp.pull_request", "type": "string" } }, @@ -135952,8 +149674,10 @@ "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, @@ -135967,8 +149691,10 @@ "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 } @@ -135984,7 +149710,7 @@ "attributes": {}, "content": "string", "title": "PR #10458", - "type": "archdev.pull_request" + "type": "myapp.pull_request" } ], "created_at": "2024-01-01T00:00:00Z", @@ -136944,16 +150670,22 @@ "event": "object_deleted", "payload": { "example": { - "id": "string" + "id": "string", + "reason": "string" }, "properties": { "id": { "example": "string", "type": "string" + }, + "reason": { + "example": "string", + "type": "string" } }, "required": [ - "id" + "id", + "reason" ], "type": "object" } @@ -137089,6 +150821,7 @@ "epic": "string", "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, + "is_stalled": true, "links": { "key": "value" }, @@ -137115,15 +150848,19 @@ "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", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -137167,6 +150904,7 @@ "epic": "string", "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, + "is_stalled": true, "links": { "key": "value" }, @@ -137193,15 +150931,19 @@ "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", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -137243,6 +150985,7 @@ "epic": "string", "id": "tsk_0aBcDeFgHiJkLmNoPqRsTu", "is_blocked": true, + "is_stalled": true, "links": { "key": "value" }, @@ -137269,15 +151012,19 @@ "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", "team": "tem_0aBcDeFgHiJkLmNoPqRsTu", "thread": "thr_0aBcDeFgHiJkLmNoPqRsTu", "updated_at": "2024-01-01T00:00:00Z", @@ -137297,7 +151044,7 @@ "type": "integer" }, "blocked_by_count": { - "description": "Number of 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.", + "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" }, @@ -137486,7 +151233,12 @@ "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 list/show reads; create/update responses report `false` until the next read.", + "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" }, @@ -137625,7 +151377,7 @@ "type": "string" }, "parent": { - "description": "ID of the parent task when this task is a subtask (`tsk_...`). `null` for top-level tasks. Subtasks nest exactly one level.", + "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" @@ -137635,6 +151387,12 @@ "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", @@ -137659,13 +151417,20 @@ "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 subtasks under this task. Computed on list/show reads; create/update responses may report 0 until the next read. Always 0 for subtasks.", + "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" }, @@ -137679,6 +151444,18 @@ }, "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" + }, "team": { "description": "ID of the team that owns this task (`tem_...`). `null` if the task is not scoped to a team.", "example": "tem_0aBcDeFgHiJkLmNoPqRsTu", @@ -137686,7 +151463,7 @@ "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.", + "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" diff --git a/packages/sdk/src/channels/api_artifact_channel.ts b/packages/sdk/src/channels/api_artifact_channel.ts new file mode 100644 index 0000000..8b4a571 --- /dev/null +++ b/packages/sdk/src/channels/api_artifact_channel.ts @@ -0,0 +1,99 @@ +// Copyright (c) 2026 ArchAstro Inc. Licensed under the MIT License. +// This file is auto-generated by @archastro/sdk-generator. Do not edit. +// Content hash: 495a74539cbf + +import type { Channel } from "../phx_channel/channel.js"; +import type { Socket } from "../phx_channel/socket.js"; + +/** + * Authenticated collaborative editing for durable Artifacts. + * The live OT revision and `dirty` flag describe synchronization, not durability. + * Only `checkpointed_revision` and checkpoint events confirm a completed save; + * process or node loss can discard the dirty tail after the last successful save. + */ +export class ApiArtifactChannel { + constructor(private channel: Channel, public readonly joinResponse?: unknown) {} + + /** Join an Artifact's authenticated live editing session. */ + static topicArtifact(artifactId: string): string { + return `api:artifact:${artifactId}`; + } + + /** Join an Artifact's authenticated live editing session. */ + static async joinArtifact(socket: Socket, artifactId: string, payload?: { as_agent?: string }): Promise { + const topic = ApiArtifactChannel.topicArtifact(artifactId); + const channel = socket.channel(topic); + const joinResponse = await channel.join(payload); + return new ApiArtifactChannel(channel, joinResponse); + } + + /** Leave the underlying channel. */ + async leave(): Promise { + await this.channel.leave(); + } + + /** Submit an OT operation against a live revision; success replies only after application. */ + async operation(payload: Record): Promise { + return this.channel.push("operation", payload); + } + + /** Publish a cursor mapped from the supplied revision to the current head. */ + async cursor(payload: Record): Promise { + return this.channel.push("cursor", payload); + } + + /** Relay opaque, transient coordination to joined actors in document order. */ + async signal(payload: Record): Promise { + return this.channel.push("signal", payload); + } + + /** Persist the current live snapshot as a new durable ArtifactVersion. */ + async checkpoint(payload: Record): Promise { + return this.channel.push("checkpoint", payload); + } + + /** Detach this server-issued actor from the live session. */ + async leaveMessage(payload: Record): Promise { + return this.channel.push("leave", payload); + } + + /** An identified operation was refused; it was not applied. */ + onOpRejected(callback: (payload: unknown) => void): () => void { + return this.channel.on("op_rejected", callback); + } + + /** A peer operation applied by the authoritative OT server. */ + onOperation(callback: (payload: unknown) => void): () => void { + return this.channel.on("operation", callback); + } + + /** Opaque coordination from another joined actor; never persisted or replayed. */ + onSignal(callback: (payload: unknown) => void): () => void { + return this.channel.on("signal", callback); + } + + /** A peer joined, moved its cursor, or left. */ + onPresence(callback: (payload: unknown) => void): () => void { + return this.channel.on("presence", callback); + } + + /** A live revision reached durable ArtifactVersion storage. */ + onCheckpoint(callback: (payload: unknown) => void): () => void { + return this.channel.on("checkpoint", callback); + } + + /** A save failed; the dirty live tail remains crash-loss exposed. */ + onCheckpointFailed(callback: (payload: unknown) => void): () => void { + return this.channel.on("checkpoint_failed", callback); + } + + /** The live version was replaced, archived, or deleted and this incarnation is terminal. */ + onSessionInvalid(callback: (payload: unknown) => void): () => void { + return this.channel.on("session_invalid", callback); + } + + /** Current read authority failed; this subscriber was detached before further egress. */ + onAccessRevoked(callback: (payload: unknown) => void): () => void { + return this.channel.on("access_revoked", callback); + } +} diff --git a/packages/sdk/src/client.ts b/packages/sdk/src/client.ts index 694cfa5..7e9910a 100644 --- a/packages/sdk/src/client.ts +++ b/packages/sdk/src/client.ts @@ -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: 9a31ed5d2774 +// Content hash: 3ccf0790693a import { forApp } from "./app-session.js"; import { AuthClient } from "./auth.js"; @@ -13,6 +13,7 @@ import type { AgentComputerResource } from "./v1/resources/agent_computers.js"; import type { AgentEnvVarResource } from "./v1/resources/agent_env_vars.js"; import type { AgentHealthActionResource } from "./v1/resources/agent_health_actions.js"; import type { AgentInstallationResource } from "./v1/resources/agent_installations.js"; +import type { AgentRequestResource } from "./v1/resources/agent_requests.js"; import type { AgentRoutineRunResource } from "./v1/resources/agent_routine_runs.js"; import type { AgentRoutineResource } from "./v1/resources/agent_routines.js"; import type { AgentSessionResource } from "./v1/resources/agent_sessions.js"; @@ -45,6 +46,7 @@ import type { OrgResource } from "./v1/resources/orgs.js"; import type { PrivateServiceDefinitionResource } from "./v1/resources/private_service_definitions.js"; import type { PrivateServiceEnrollmentResource } from "./v1/resources/private_service_enrollments.js"; import type { PrivateServiceResource } from "./v1/resources/private_services.js"; +import type { RelayResource } from "./v1/resources/relays.js"; import type { SandboxResource } from "./v1/resources/sandboxes.js"; import type { ScriptResource } from "./v1/resources/scripts.js"; import type { SlackChannelBindingResource } from "./v1/resources/slack_channel_bindings.js"; @@ -54,6 +56,7 @@ import type { SolutionTagResource } from "./v1/resources/solution_tags.js"; import type { SolutionResource } from "./v1/resources/solutions.js"; import type { SshKeyResource } from "./v1/resources/ssh_keys.js"; import type { StatuResource } from "./v1/resources/status.js"; +import type { TaskOwnershipConversionResource } from "./v1/resources/task_ownership_conversions.js"; import type { TaskResource } from "./v1/resources/tasks.js"; import type { TeamMembershipResource } from "./v1/resources/team_memberships.js"; import type { TeamResource } from "./v1/resources/teams.js"; @@ -102,6 +105,7 @@ export class PlatformClient { readonly agent_env_vars: AgentEnvVarResource; readonly agent_health_actions: AgentHealthActionResource; readonly agent_installations: AgentInstallationResource; + readonly agent_requests: AgentRequestResource; readonly agent_routine_runs: AgentRoutineRunResource; readonly agent_routines: AgentRoutineResource; readonly agent_sessions: AgentSessionResource; @@ -133,6 +137,7 @@ export class PlatformClient { readonly private_service_definitions: PrivateServiceDefinitionResource; readonly private_service_enrollments: PrivateServiceEnrollmentResource; readonly private_services: PrivateServiceResource; + readonly relays: RelayResource; readonly sandboxes: SandboxResource; readonly scripts: ScriptResource; readonly slack_channel_bindings: SlackChannelBindingResource; @@ -142,6 +147,7 @@ export class PlatformClient { readonly solutions: SolutionResource; readonly ssh_keys: SshKeyResource; readonly status: StatuResource; + readonly task_ownership_conversions: TaskOwnershipConversionResource; readonly tasks: TaskResource; readonly team_memberships: TeamMembershipResource; readonly teams: TeamResource; @@ -172,6 +178,7 @@ export class PlatformClient { this.agent_env_vars = this.v1.agent_env_vars; this.agent_health_actions = this.v1.agent_health_actions; this.agent_installations = this.v1.agent_installations; + this.agent_requests = this.v1.agent_requests; this.agent_routine_runs = this.v1.agent_routine_runs; this.agent_routines = this.v1.agent_routines; this.agent_sessions = this.v1.agent_sessions; @@ -203,6 +210,7 @@ export class PlatformClient { this.private_service_definitions = this.v1.private_service_definitions; this.private_service_enrollments = this.v1.private_service_enrollments; this.private_services = this.v1.private_services; + this.relays = this.v1.relays; this.sandboxes = this.v1.sandboxes; this.scripts = this.v1.scripts; this.slack_channel_bindings = this.v1.slack_channel_bindings; @@ -212,6 +220,7 @@ export class PlatformClient { this.solutions = this.v1.solutions; this.ssh_keys = this.v1.ssh_keys; this.status = this.v1.status; + this.task_ownership_conversions = this.v1.task_ownership_conversions; this.tasks = this.v1.tasks; this.team_memberships = this.v1.team_memberships; this.teams = this.v1.teams; diff --git a/packages/sdk/src/index.ts b/packages/sdk/src/index.ts index 2153f05..bfe94bf 100644 --- a/packages/sdk/src/index.ts +++ b/packages/sdk/src/index.ts @@ -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: 1937d98c7354 +// Content hash: 26de9a54a9c4 export * from "./types/index.js"; export { V1 } from "./v1.js"; @@ -9,6 +9,7 @@ export { PlatformClient, type PlatformClientConfig, type PlatformClientConstruct export type { AppPlatformClient, ForAppOptions, SessionStorage, AppSession } from "./client.js"; export { AuthClient, type AuthTokens } from "./auth.js"; export { ApiActivityFeedChannel } from "./channels/api_activity_feed_channel.js"; +export { ApiArtifactChannel } from "./channels/api_artifact_channel.js"; export { ApiChatChannel } from "./channels/api_chat_channel.js"; export { ApiObjectChannel } from "./channels/api_object_channel.js"; export { ApiTasksChannel } from "./channels/api_tasks_channel.js"; diff --git a/packages/sdk/src/types/ai.ts b/packages/sdk/src/types/ai.ts index e243406..9431090 100644 --- a/packages/sdk/src/types/ai.ts +++ b/packages/sdk/src/types/ai.ts @@ -1,11 +1,31 @@ // Copyright (c) 2026 ArchAstro Inc. Licensed under the MIT License. // This file is auto-generated by @archastro/sdk-generator. Do not edit. -// Content hash: ba7d38c074da +// Content hash: 063420a5fcf7 import { z } from "zod"; +import { refusalSchema } from "./common.js"; +import type { Refusal } from "./common.js"; + +/** One accepted provider completion. An empty record preserves an unknown identity. */ +export interface AICompletionProvenance { + /** Model identity reported by the provider response, not the requested model or usage key. */ + response_model?: string | undefined; + /** Optional monotonic timing for this accepted completion and its retries. request_ms includes all attempts, backoff and local processing; provider_attempts_ms is the sum of provider request wall times, including transport and parsing; retry_backoff_ms is measured retry sleep. attempt_count includes the accepted call and retry_count counts earlier attempts. These overlapping measurements are not provider-internal inference time. Missing timing is unknown, not zero. */ + timing?: Record | undefined; +} + +/** Runtime validator for {@link AICompletionProvenance}. */ +export const aICompletionProvenanceSchema = z.object({ + /** Model identity reported by the provider response, not the requested model or usage key. */ + response_model: z.string().optional().describe("Model identity reported by the provider response, not the requested model or usage key."), + /** Optional monotonic timing for this accepted completion and its retries. request_ms includes all attempts, backoff and local processing; provider_attempts_ms is the sum of provider request wall times, including transport and parsing; retry_backoff_ms is measured retry sleep. attempt_count includes the accepted call and retry_count counts earlier attempts. These overlapping measurements are not provider-internal inference time. Missing timing is unknown, not zero. */ + timing: z.record(z.custom<{} | null>((value) => value !== undefined)).optional().describe("Optional monotonic timing for this accepted completion and its retries. request_ms includes all attempts, backoff and local processing; provider_attempts_ms is the sum of provider request wall times, including transport and parsing; retry_backoff_ms is measured retry sleep. attempt_count includes the accepted call and retry_count counts earlier attempts. These overlapping measurements are not provider-internal inference time. Missing timing is unknown, not zero."), +}).describe("One accepted provider completion. An empty record preserves an unknown identity.") satisfies z.ZodType; /** Terminal event marking the end of a streaming chat completion (SSE `done` event). */ export interface AIChatStreamDone { + /** Ordered accepted completions; empty records retain unknown identities. */ + completions?: AICompletionProvenance[] | undefined; /** The overall finish reason for the completion. */ finish_reason?: string | undefined; /** Number of model runs executed, including continuations triggered by tool calls. */ @@ -18,6 +38,8 @@ export interface AIChatStreamDone { /** Runtime validator for {@link AIChatStreamDone}. */ export const aIChatStreamDoneSchema = z.object({ + /** Ordered accepted completions; empty records retain unknown identities. */ + completions: z.array(aICompletionProvenanceSchema).optional().describe("Ordered accepted completions; empty records retain unknown identities."), /** The overall finish reason for the completion. */ finish_reason: z.string().optional().describe("The overall finish reason for the completion."), /** Number of model runs executed, including continuations triggered by tool calls. */ @@ -32,12 +54,20 @@ export const aIChatStreamDoneSchema = z.object({ export interface AIChatStreamError { /** Human-readable description of the error that terminated the stream. */ message: string; + /** Whether the provider failure can be retried. */ + retryable?: boolean | null | undefined; + /** Upstream HTTP status, when reported. */ + status?: number | null | undefined; } /** Runtime validator for {@link AIChatStreamError}. */ export const aIChatStreamErrorSchema = z.object({ /** Human-readable description of the error that terminated the stream. */ message: z.string().describe("Human-readable description of the error that terminated the stream."), + /** Whether the provider failure can be retried. */ + retryable: z.boolean().nullable().optional().describe("Whether the provider failure can be retried."), + /** Upstream HTTP status, when reported. */ + status: z.number().int().nullable().optional().describe("Upstream HTTP status, when reported."), }).describe("Terminal error event for a streaming chat completion (SSE `error` event).") satisfies z.ZodType; /** A tool (function) call emitted by the assistant within an AI message. Mirrors the OpenAI tool-call object format. */ @@ -130,6 +160,8 @@ export interface AIChatStreamMessageComplete { finish_reason?: string | undefined; /** The complete assistant message for this run, assembled from the preceding deltas. */ message: AIMessage; + /** Provider-reported model identity for this accepted completion. */ + response_model?: string | undefined; /** Token consumption for this run, keyed by model ID. `null` when usage data is unavailable. */ usage?: Record | undefined; } @@ -140,6 +172,8 @@ export const aIChatStreamMessageCompleteSchema = z.object({ finish_reason: z.string().optional().describe("Why the model stopped generating this message, e.g. `\"stop\"`, `\"length\"`, or `\"tool_calls\"`."), /** The complete assistant message for this run, assembled from the preceding deltas. */ message: aIMessageSchema.describe("The complete assistant message for this run, assembled from the preceding deltas."), + /** Provider-reported model identity for this accepted completion. */ + response_model: z.string().optional().describe("Provider-reported model identity for this accepted completion."), /** Token consumption for this run, keyed by model ID. `null` when usage data is unavailable. */ usage: z.record(z.custom<{} | null>((value) => value !== undefined)).optional().describe("Token consumption for this run, keyed by model ID. `null` when usage data is unavailable."), }).describe("The fully assembled assistant message for one run of a streaming chat completion (SSE `message_complete` event).") satisfies z.ZodType; @@ -214,26 +248,34 @@ export const aIChatStreamToolResultSchema = z.object({ /** The result of an AI chat completion request. Returned by chat completion endpoints after the model finishes generating. */ export interface AICompletionResult { + /** Ordered accepted provider completions, including empty records for unknown identities. */ + completions?: AICompletionProvenance[] | undefined; /** The reason the model stopped generating. Common values include `"stop"` (natural end), `"length"` (token limit reached), and `"tool_calls"` (the model invoked a tool). */ finish_reason: string; /** The final assistant message produced by the completion. */ message: AIMessage; /** The complete message history for the conversation, including all user, assistant, and tool messages in order. */ messages: AIMessage[]; - /** Token consumption breakdown keyed by model ID. Each value is a map with `"input_tokens"` and `"output_tokens"` counts. `null` when usage data is unavailable. */ + /** Final accepted completion provider-reported identity; absent when unknown. */ + response_model?: string | undefined; + /** Token consumption keyed by model ID. Each value has `input` (all prompt tokens, including cache reads and writes) and `output` counts. When reported, `fresh_input`, `cache_read`, and `cache_creation` are disjoint input buckets; missing cache counts remain unknown. `null` when usage data is unavailable. */ token_usage?: Record | undefined; } /** Runtime validator for {@link AICompletionResult}. */ export const aICompletionResultSchema = z.object({ + /** Ordered accepted provider completions, including empty records for unknown identities. */ + completions: z.array(aICompletionProvenanceSchema).optional().describe("Ordered accepted provider completions, including empty records for unknown identities."), /** The reason the model stopped generating. Common values include `"stop"` (natural end), `"length"` (token limit reached), and `"tool_calls"` (the model invoked a tool). */ finish_reason: z.string().describe("The reason the model stopped generating. Common values include `\"stop\"` (natural end), `\"length\"` (token limit reached), and `\"tool_calls\"` (the model invoked a tool)."), /** The final assistant message produced by the completion. */ message: aIMessageSchema.describe("The final assistant message produced by the completion."), /** The complete message history for the conversation, including all user, assistant, and tool messages in order. */ messages: z.array(aIMessageSchema).describe("The complete message history for the conversation, including all user, assistant, and tool messages in order."), - /** Token consumption breakdown keyed by model ID. Each value is a map with `"input_tokens"` and `"output_tokens"` counts. `null` when usage data is unavailable. */ - token_usage: z.record(z.custom<{} | null>((value) => value !== undefined)).optional().describe("Token consumption breakdown keyed by model ID. Each value is a map with `\"input_tokens\"` and `\"output_tokens\"` counts. `null` when usage data is unavailable."), + /** Final accepted completion provider-reported identity; absent when unknown. */ + response_model: z.string().optional().describe("Final accepted completion provider-reported identity; absent when unknown."), + /** Token consumption keyed by model ID. Each value has `input` (all prompt tokens, including cache reads and writes) and `output` counts. When reported, `fresh_input`, `cache_read`, and `cache_creation` are disjoint input buckets; missing cache counts remain unknown. `null` when usage data is unavailable. */ + token_usage: z.record(z.custom<{} | null>((value) => value !== undefined)).optional().describe("Token consumption keyed by model ID. Each value has `input` (all prompt tokens, including cache reads and writes) and `output` counts. When reported, `fresh_input`, `cache_read`, and `cache_creation` are disjoint input buckets; missing cache counts remain unknown. `null` when usage data is unavailable."), }).describe("The result of an AI chat completion request. Returned by chat completion endpoints after the model finishes generating.") satisfies z.ZodType; /** Probability that the statement is true, in `[0, 1]`. */ @@ -289,12 +331,12 @@ export const aIEvaluationAnswerScoreSchema = z.object({ }).describe("Probability-weighted position along the caller-defined levels.") satisfies z.ZodType; /** - * One typed evaluation answer. `type` selects boolean, choice, or score. + * One typed evaluation answer. `type` selects boolean, choice, score, or refusal. * `id` matches the question id. */ -export const aIEvaluationAnswerSchema = z.discriminatedUnion("type", [aIEvaluationAnswerBooleanSchema, aIEvaluationAnswerChoiceSchema, aIEvaluationAnswerScoreSchema]); +export const aIEvaluationAnswerSchema = z.discriminatedUnion("type", [aIEvaluationAnswerBooleanSchema, aIEvaluationAnswerChoiceSchema, aIEvaluationAnswerScoreSchema, refusalSchema]); /** - * One typed evaluation answer. `type` selects boolean, choice, or score. + * One typed evaluation answer. `type` selects boolean, choice, score, or refusal. * `id` matches the question id. */ export type AIEvaluationAnswer = z.infer; @@ -320,7 +362,7 @@ export const aIEvaluationUsageSchema = z.object({ * token usage. */ export interface AIEvaluationResult { - /** Typed answers. Each value is a boolean, choice, or score object with the question `id`. */ + /** Typed boolean, choice, score, or refusal answers with the question `id`. */ answers: AIEvaluationAnswer[]; /** Model identifier that produced the answers. */ model: string; @@ -332,8 +374,8 @@ export interface AIEvaluationResult { /** Runtime validator for {@link AIEvaluationResult}. */ export const aIEvaluationResultSchema = z.object({ - /** Typed answers. Each value is a boolean, choice, or score object with the question `id`. */ - answers: z.array(aIEvaluationAnswerSchema).describe("Typed answers. Each value is a boolean, choice, or score object with the question `id`."), + /** Typed boolean, choice, score, or refusal answers with the question `id`. */ + answers: z.array(aIEvaluationAnswerSchema).describe("Typed boolean, choice, score, or refusal answers with the question `id`."), /** Model identifier that produced the answers. */ model: z.string().describe("Model identifier that produced the answers."), /** UUID grouping this evaluation's usage record. Generated when omitted on the request. */ diff --git a/packages/sdk/src/types/artifacts.ts b/packages/sdk/src/types/artifacts.ts index 4d4ee4a..b2588f8 100644 --- a/packages/sdk/src/types/artifacts.ts +++ b/packages/sdk/src/types/artifacts.ts @@ -1,13 +1,17 @@ // Copyright (c) 2026 ArchAstro Inc. Licensed under the MIT License. // This file is auto-generated by @archastro/sdk-generator. Do not edit. -// Content hash: 0e1768d2cc71 +// Content hash: 6ae93195aa02 import { z } from "zod"; +import { aclSchema } from "./common.js"; import { imageSourceSchema } from "./image.js"; +import type { Acl } from "./common.js"; import type { ImageSource } from "./image.js"; /** A versioned artifact produced or managed by an agent, such as a generated file, report, or code output. */ export interface Artifact { + /** Access control list for the artifact. Contains a `grants` array where each entry specifies `principal_type`, `principal`, and `actions` (`read`, `write`). `null` when the artifact has no grants or the viewer is not its owner. */ + acl?: Acl | null | undefined; /** ID of the agent that produced this artifact (`agt_...`). `null` if not agent-produced. */ agent?: string | undefined; /** MIME type of the current version's file, e.g. `"text/csv"` or `"image/png"`. `null` if no file is attached. */ @@ -52,6 +56,8 @@ export interface Artifact { /** Runtime validator for {@link Artifact}. */ export const artifactSchema = z.object({ + /** Access control list for the artifact. Contains a `grants` array where each entry specifies `principal_type`, `principal`, and `actions` (`read`, `write`). `null` when the artifact has no grants or the viewer is not its owner. */ + acl: aclSchema.nullable().optional().describe("Access control list for the artifact. Contains a `grants` array where each entry specifies `principal_type`, `principal`, and `actions` (`read`, `write`). `null` when the artifact has no grants or the viewer is not its owner."), /** ID of the agent that produced this artifact (`agt_...`). `null` if not agent-produced. */ agent: z.string().optional().describe("ID of the agent that produced this artifact (`agt_...`). `null` if not agent-produced."), /** MIME type of the current version's file, e.g. `"text/csv"` or `"image/png"`. `null` if no file is attached. */ @@ -93,3 +99,137 @@ export const artifactSchema = z.object({ /** Current version number of the artifact. Increments each time a new version is published. */ version: z.number().int().optional().describe("Current version number of the artifact. Increments each time a new version is published."), }).describe("A versioned artifact produced or managed by an agent, such as a generated file, report, or code output.") satisfies z.ZodType; + +/** Acknowledges an Artifact editing presence or leave request. */ +export interface ArtifactEditingAck { + ok: boolean; +} + +/** Runtime validator for {@link ArtifactEditingAck}. */ +export const artifactEditingAckSchema = z.object({ + ok: z.boolean(), +}).describe("Acknowledges an Artifact editing presence or leave request.") satisfies z.ZodType; + +/** A Unicode code-point cursor and optional selection endpoint. */ +export interface ArtifactEditingCursor { + /** Zero-based Unicode code-point position. */ + position: number; + /** Zero-based Unicode code-point selection endpoint. */ + selection_end?: number | undefined; +} + +/** Runtime validator for {@link ArtifactEditingCursor}. */ +export const artifactEditingCursorSchema = z.object({ + /** Zero-based Unicode code-point position. */ + position: z.number().int().describe("Zero-based Unicode code-point position."), + /** Zero-based Unicode code-point selection endpoint. */ + selection_end: z.number().int().optional().describe("Zero-based Unicode code-point selection endpoint."), +}).describe("A Unicode code-point cursor and optional selection endpoint.") satisfies z.ZodType; + +/** A server-issued collaborator identity and its ephemeral presence. */ +export interface ArtifactEditingActor { + /** Opaque identity unique to this channel join. */ + actor_id: string; + /** Current code-point cursor, or null. */ + cursor?: ArtifactEditingCursor | null | undefined; + /** Server-derived collaborator display metadata. */ + meta: Record; +} + +/** Runtime validator for {@link ArtifactEditingActor}. */ +export const artifactEditingActorSchema = z.object({ + /** Opaque identity unique to this channel join. */ + actor_id: z.string().describe("Opaque identity unique to this channel join."), + /** Current code-point cursor, or null. */ + cursor: artifactEditingCursorSchema.nullable().optional().describe("Current code-point cursor, or null."), + /** Server-derived collaborator display metadata. */ + meta: z.record(z.custom<{} | null>((value) => value !== undefined)).describe("Server-derived collaborator display metadata."), +}).describe("A server-issued collaborator identity and its ephemeral presence.") satisfies z.ZodType; + +/** Confirms the exact live revision that reached durable ArtifactVersion storage. */ +export interface ArtifactEditingCheckpointResponse { + /** New durable ArtifactVersion ID. */ + artifact_version: string; + artifact_version_number: number; + checkpointed_revision: number; + /** True when later live operations remain unsaved. */ + dirty: boolean; + incarnation: string; +} + +/** Runtime validator for {@link ArtifactEditingCheckpointResponse}. */ +export const artifactEditingCheckpointResponseSchema = z.object({ + /** New durable ArtifactVersion ID. */ + artifact_version: z.string().describe("New durable ArtifactVersion ID."), + artifact_version_number: z.number().int(), + checkpointed_revision: z.number().int(), + /** True when later live operations remain unsaved. */ + dirty: z.boolean().describe("True when later live operations remain unsaved."), + incarnation: z.string(), +}).describe("Confirms the exact live revision that reached durable ArtifactVersion storage.") satisfies z.ZodType; + +/** Authoritative live Artifact snapshot returned by an editing-channel join. */ +export interface ArtifactEditingJoinResponse { + /** Server-issued identity for this channel join. */ + actor_id: string; + actors: ArtifactEditingActor[]; + /** Public Artifact ID (`art_...`). */ + artifact: string; + /** Durable version ID (`artv_...`). */ + artifact_version: string; + artifact_version_number: number; + can_write: boolean; + /** Last durable-save failure reason, or null. */ + checkpoint_error?: string | null | undefined; + /** Latest revision known durable. */ + checkpointed_revision: number; + /** Server-issued connection identity. */ + connection_id: string; + /** UTF-8 document content. */ + content: string; + /** True while a live tail remains crash-loss exposed. */ + dirty: boolean; + /** Opaque live-session fence token. */ + incarnation: string; + /** Live OT revision in Unicode code points. */ + revision: number; +} + +/** Runtime validator for {@link ArtifactEditingJoinResponse}. */ +export const artifactEditingJoinResponseSchema = z.object({ + /** Server-issued identity for this channel join. */ + actor_id: z.string().describe("Server-issued identity for this channel join."), + actors: z.array(artifactEditingActorSchema), + /** Public Artifact ID (`art_...`). */ + artifact: z.string().describe("Public Artifact ID (`art_...`)."), + /** Durable version ID (`artv_...`). */ + artifact_version: z.string().describe("Durable version ID (`artv_...`)."), + artifact_version_number: z.number().int(), + can_write: z.boolean(), + /** Last durable-save failure reason, or null. */ + checkpoint_error: z.string().nullable().optional().describe("Last durable-save failure reason, or null."), + /** Latest revision known durable. */ + checkpointed_revision: z.number().int().describe("Latest revision known durable."), + /** Server-issued connection identity. */ + connection_id: z.string().describe("Server-issued connection identity."), + /** UTF-8 document content. */ + content: z.string().describe("UTF-8 document content."), + /** True while a live tail remains crash-loss exposed. */ + dirty: z.boolean().describe("True while a live tail remains crash-loss exposed."), + /** Opaque live-session fence token. */ + incarnation: z.string().describe("Opaque live-session fence token."), + /** Live OT revision in Unicode code points. */ + revision: z.number().int().describe("Live OT revision in Unicode code points."), +}).describe("Authoritative live Artifact snapshot returned by an editing-channel join.") satisfies z.ZodType; + +/** Acknowledges an operation only after the authoritative OT server applied it. */ +export interface ArtifactEditingOperationAck { + /** Authoritative live revision after application. */ + revision: number; +} + +/** Runtime validator for {@link ArtifactEditingOperationAck}. */ +export const artifactEditingOperationAckSchema = z.object({ + /** Authoritative live revision after application. */ + revision: z.number().int().describe("Authoritative live revision after application."), +}).describe("Acknowledges an operation only after the authoritative OT server applied it.") satisfies z.ZodType; diff --git a/packages/sdk/src/types/automations.ts b/packages/sdk/src/types/automations.ts index 0bca6af..5151c31 100644 --- a/packages/sdk/src/types/automations.ts +++ b/packages/sdk/src/types/automations.ts @@ -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: 3334c83f45c4 +// Content hash: 810d52f31fad import { z } from "zod"; @@ -52,24 +52,24 @@ export interface AutomationRun { automation: string; /** When the automation run was created (ISO 8601). */ created_at?: string | undefined; - /** ID of the platform event that triggered this run. `null` for directly invoked automations. */ - event_id?: string | undefined; + /** Event or invocation identifier for this run. Direct invocations use the supplied idempotency key or a generated UUID. `null` when no event identifier was recorded. */ + event_id?: string | null | undefined; /** Automation run ID (`atr_...`). */ id: string; /** Invoke-time map of symbolic participant references to agent IDs. `null` when no participants were supplied. */ - participants?: Record | undefined; + participants?: Record | null | undefined; /** The input event payload that triggered this run. Structure varies by automation type. Defaults to an empty object if no payload was provided. */ payload?: Record | undefined; /** The output produced after the automation finished executing. Contains workflow-defined keys alongside any returned output. `null` if the run has not yet completed. */ - result?: Record | undefined; + result?: Record | null | undefined; /** Current execution status of the run. One of `"pending"` (queued, not yet started), `"running"` (actively executing), `"completed"` (finished successfully), `"failed"` (finished with an error), or `"cancelled"` (stopped before completion). */ status: string; /** ID of the team that owns this run (`tea_...`). `null` if the run is owned by a user rather than a team. */ - team?: string | undefined; + team?: string | null | undefined; /** When the automation run record was last updated (ISO 8601). */ updated_at?: string | undefined; /** ID of the user that owns this run (`usr_...`). `null` if the run is owned by a team rather than a user. */ - user?: string | undefined; + user?: string | null | undefined; } /** Runtime validator for {@link AutomationRun}. */ @@ -80,22 +80,22 @@ export const automationRunSchema = z.object({ automation: z.string().describe("ID of the automation that was executed (`aut_...`)."), /** When the automation run was created (ISO 8601). */ created_at: z.string().optional().describe("When the automation run was created (ISO 8601)."), - /** ID of the platform event that triggered this run. `null` for directly invoked automations. */ - event_id: z.string().optional().describe("ID of the platform event that triggered this run. `null` for directly invoked automations."), + /** Event or invocation identifier for this run. Direct invocations use the supplied idempotency key or a generated UUID. `null` when no event identifier was recorded. */ + event_id: z.string().nullable().optional().describe("Event or invocation identifier for this run. Direct invocations use the supplied idempotency key or a generated UUID. `null` when no event identifier was recorded."), /** Automation run ID (`atr_...`). */ id: z.string().describe("Automation run ID (`atr_...`)."), /** Invoke-time map of symbolic participant references to agent IDs. `null` when no participants were supplied. */ - participants: z.record(z.custom<{} | null>((value) => value !== undefined)).optional().describe("Invoke-time map of symbolic participant references to agent IDs. `null` when no participants were supplied."), + participants: z.record(z.custom<{} | null>((value) => value !== undefined)).nullable().optional().describe("Invoke-time map of symbolic participant references to agent IDs. `null` when no participants were supplied."), /** The input event payload that triggered this run. Structure varies by automation type. Defaults to an empty object if no payload was provided. */ payload: z.record(z.custom<{} | null>((value) => value !== undefined)).optional().describe("The input event payload that triggered this run. Structure varies by automation type. Defaults to an empty object if no payload was provided."), /** The output produced after the automation finished executing. Contains workflow-defined keys alongside any returned output. `null` if the run has not yet completed. */ - result: z.record(z.custom<{} | null>((value) => value !== undefined)).optional().describe("The output produced after the automation finished executing. Contains workflow-defined keys alongside any returned output. `null` if the run has not yet completed."), + result: z.record(z.custom<{} | null>((value) => value !== undefined)).nullable().optional().describe("The output produced after the automation finished executing. Contains workflow-defined keys alongside any returned output. `null` if the run has not yet completed."), /** Current execution status of the run. One of `"pending"` (queued, not yet started), `"running"` (actively executing), `"completed"` (finished successfully), `"failed"` (finished with an error), or `"cancelled"` (stopped before completion). */ status: z.string().describe("Current execution status of the run. One of `\"pending\"` (queued, not yet started), `\"running\"` (actively executing), `\"completed\"` (finished successfully), `\"failed\"` (finished with an error), or `\"cancelled\"` (stopped before completion)."), /** ID of the team that owns this run (`tea_...`). `null` if the run is owned by a user rather than a team. */ - team: z.string().optional().describe("ID of the team that owns this run (`tea_...`). `null` if the run is owned by a user rather than a team."), + team: z.string().nullable().optional().describe("ID of the team that owns this run (`tea_...`). `null` if the run is owned by a user rather than a team."), /** When the automation run record was last updated (ISO 8601). */ updated_at: z.string().optional().describe("When the automation run record was last updated (ISO 8601)."), /** ID of the user that owns this run (`usr_...`). `null` if the run is owned by a team rather than a user. */ - user: z.string().optional().describe("ID of the user that owns this run (`usr_...`). `null` if the run is owned by a team rather than a user."), + user: z.string().nullable().optional().describe("ID of the user that owns this run (`usr_...`). `null` if the run is owned by a team rather than a user."), }).describe("A single execution of an automation triggered by a platform event or direct invocation. Captures the run's status, input payload, and final result.") satisfies z.ZodType; diff --git a/packages/sdk/src/types/common.ts b/packages/sdk/src/types/common.ts index 624cea1..84c0e82 100644 --- a/packages/sdk/src/types/common.ts +++ b/packages/sdk/src/types/common.ts @@ -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: afbd6dd19860 +// Content hash: e9c10f6c8b7c import { z } from "zod"; import { automationParticipantSlotSchema, automationPrefillsSchema } from "./automations.js"; @@ -14,6 +14,18 @@ import type { ImageSource } from "./image.js"; import type { User } from "./users.js"; import type { WorkflowJournal, WorkflowJournalEntry } from "./workflows.js"; +/** The model declined to judge this question. */ +export interface Refusal { + id: string; + type: "refusal"; +} + +/** Runtime validator for {@link Refusal}. */ +export const refusalSchema = z.object({ + id: z.string(), + type: z.literal("refusal"), +}).describe("The model declined to judge this question.") satisfies z.ZodType; + /** A single access-control grant that pairs a principal with the set of actions it is allowed to perform. */ export interface AclGrant { /** Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry. */ @@ -274,6 +286,64 @@ export const installedConfigEntrySchema = z.object({ lookup_key: z.string().nullable().optional().describe("Stored `lookup_key` for this config after any suffix has been applied. `null` for `File` children inside a skill bundle, which are keyed by `(parent_id, relative_path)` rather than by `lookup_key`."), }).describe("A slim summary of a single config record created during an agent install transaction. Returned as an entry in `AgentCreateResponse.installed_configs`.") satisfies z.ZodType; +/** Approval policy, excluding user IDs. */ +export interface Approvers { + mode: string; +} + +/** Runtime validator for {@link Approvers}. */ +export const approversSchema = z.object({ + mode: z.string(), +}).describe("Approval policy, excluding user IDs.") satisfies z.ZodType; + +/** Origin references. */ +export interface Origin { + routine_id?: string | null | undefined; + session_id?: string | null | undefined; + thread_id?: string | null | undefined; +} + +/** Runtime validator for {@link Origin}. */ +export const originSchema = z.object({ + routine_id: z.string().nullable().optional(), + session_id: z.string().nullable().optional(), + thread_id: z.string().nullable().optional(), +}).describe("Origin references.") satisfies z.ZodType; + +/** Question request payload. */ +export interface Payload { + question: string; +} + +/** Runtime validator for {@link Payload}. */ +export const payloadSchema = z.object({ + question: z.string(), +}).describe("Question request payload.") satisfies z.ZodType; + +/** Answer or rejection reason; null before resolution. */ +export interface Resolution { + answer?: string | undefined; + reason?: string | undefined; +} + +/** Runtime validator for {@link Resolution}. */ +export const resolutionSchema = z.object({ + answer: z.string().optional(), + reason: z.string().optional(), +}).describe("Answer or rejection reason; null before resolution.") satisfies z.ZodType; + +/** Kind-provided summary. */ +export interface Summary { + lines: string[]; + title: string; +} + +/** Runtime validator for {@link Summary}. */ +export const summarySchema = z.object({ + lines: z.array(z.string()), + title: z.string(), +}).describe("Kind-provided summary.") satisfies z.ZodType; + /** Controls visibility and canonical recipient selection for routine-emitted messages. */ export interface MessagePolicy { /** Required and non-empty for private visibility. Sources are additive. Routine owner includes the agent owner and optional user co-owner. */ @@ -372,10 +442,14 @@ export const setupSchema = z.object({ /** A processed variant of a media item, such as the original upload or a resized thumbnail, including a signed download URL resolved at request time. */ export interface MediaVariant { + /** Size of the stored bytes. */ + byte_size?: number | null | undefined; /** MIME type of this variant's file (e.g., `"image/jpeg"`, `"video/mp4"`). `null` if the file is not loaded. */ content_type?: string | null | undefined; /** When this variant was created (ISO 8601). */ created_at?: string | undefined; + /** Client-declared video duration in milliseconds; not server-probed. */ + duration_ms?: number | null | undefined; /** ID of the underlying storage file that backs this variant (`fil_...`). */ file?: string | undefined; /** Original filename of the uploaded file for this variant. `null` if the file is not loaded. */ @@ -386,10 +460,14 @@ export interface MediaVariant { id: string; /** Resolved image delivery metadata for this variant, including dimensions and CDN URL. `null` for non-image content types. */ image_source?: ImageSource | null | undefined; + /** Lowercase SHA-256 of the stored bytes. */ + sha256?: string | null | undefined; /** When this variant was last updated (ISO 8601). */ updated_at?: string | undefined; /** Signed download URL for this variant, resolved at request time. `null` if the file is unavailable. */ url?: string | null | undefined; + /** Expiry of this variant's playable URL. */ + url_expires_at?: string | null | undefined; /** Identifier for this variant's processing tier. Common values include `"original"` (the unmodified upload) and `"thumbnail"` (a resized preview). */ variant_key?: string | undefined; /** Width of this variant in pixels. `null` if not recorded. */ @@ -398,10 +476,14 @@ export interface MediaVariant { /** Runtime validator for {@link MediaVariant}. */ export const mediaVariantSchema = z.object({ + /** Size of the stored bytes. */ + byte_size: z.number().int().nullable().optional().describe("Size of the stored bytes."), /** MIME type of this variant's file (e.g., `"image/jpeg"`, `"video/mp4"`). `null` if the file is not loaded. */ content_type: z.string().nullable().optional().describe("MIME type of this variant's file (e.g., `\"image/jpeg\"`, `\"video/mp4\"`). `null` if the file is not loaded."), /** When this variant was created (ISO 8601). */ created_at: z.string().optional().describe("When this variant was created (ISO 8601)."), + /** Client-declared video duration in milliseconds; not server-probed. */ + duration_ms: z.number().int().nullable().optional().describe("Client-declared video duration in milliseconds; not server-probed."), /** ID of the underlying storage file that backs this variant (`fil_...`). */ file: z.string().optional().describe("ID of the underlying storage file that backs this variant (`fil_...`)."), /** Original filename of the uploaded file for this variant. `null` if the file is not loaded. */ @@ -412,10 +494,14 @@ export const mediaVariantSchema = z.object({ id: z.string().describe("Media variant ID (`mvr_...`)."), /** Resolved image delivery metadata for this variant, including dimensions and CDN URL. `null` for non-image content types. */ image_source: imageSourceSchema.nullable().optional().describe("Resolved image delivery metadata for this variant, including dimensions and CDN URL. `null` for non-image content types."), + /** Lowercase SHA-256 of the stored bytes. */ + sha256: z.string().nullable().optional().describe("Lowercase SHA-256 of the stored bytes."), /** When this variant was last updated (ISO 8601). */ updated_at: z.string().optional().describe("When this variant was last updated (ISO 8601)."), /** Signed download URL for this variant, resolved at request time. `null` if the file is unavailable. */ url: z.string().nullable().optional().describe("Signed download URL for this variant, resolved at request time. `null` if the file is unavailable."), + /** Expiry of this variant's playable URL. */ + url_expires_at: z.string().nullable().optional().describe("Expiry of this variant's playable URL."), /** Identifier for this variant's processing tier. Common values include `"original"` (the unmodified upload) and `"thumbnail"` (a resized preview). */ variant_key: z.string().optional().describe("Identifier for this variant's processing tier. Common values include `\"original\"` (the unmodified upload) and `\"thumbnail\"` (a resized preview)."), /** Width of this variant in pixels. `null` if not recorded. */ @@ -899,22 +985,6 @@ export const commandSchema = z.object({ successOutput: z.record(z.custom<{} | null>((value) => value !== undefined)).optional().describe("JSON Schema describing the shape of a successful output. `null` if the command produces no output on success."), }).describe("A workflow command that a workflow node can invoke, including its identifier, human-readable name, and JSON schemas for its inputs and outputs.") satisfies z.ZodType; -/** The result of executing a shell command on an agent's computer environment. Contains the captured output and the process exit code. */ -export interface ComputerExecResult { - /** The UNIX exit code returned by the process. `0` indicates success; any non-zero value indicates an error. `null` if the process did not terminate normally. */ - exit_code?: number | undefined; - /** The combined stdout and stderr output produced by the command. `null` if the command produced no output. */ - output?: string | undefined; -} - -/** Runtime validator for {@link ComputerExecResult}. */ -export const computerExecResultSchema = z.object({ - /** The UNIX exit code returned by the process. `0` indicates success; any non-zero value indicates an error. `null` if the process did not terminate normally. */ - exit_code: z.number().int().optional().describe("The UNIX exit code returned by the process. `0` indicates success; any non-zero value indicates an error. `null` if the process did not terminate normally."), - /** The combined stdout and stderr output produced by the command. `null` if the command produced no output. */ - output: z.string().optional().describe("The combined stdout and stderr output produced by the command. `null` if the command produced no output."), -}).describe("The result of executing a shell command on an agent's computer environment. Contains the captured output and the process exit code.") satisfies z.ZodType; - /** A context document stored within a context source. Carries metadata and size information only; retrieve the full text content via the `/content` endpoint. */ export interface ContextDocument { /** ID of the agent that owns this document (`agi_...`). `null` if owned by a user or team. */ @@ -1160,12 +1230,20 @@ export interface EffectiveAccessEntitlement { granted: boolean; /** Stable entitlement catalog key. */ key: string; + /** Unexpired metered allowance, including exhausted grants; null for boolean entitlements. */ + limit?: number | null | undefined; /** Privacy-safe principal kinds that contribute to the effective value. */ provided_by: ("personal" | "organization")[]; + /** Effective purchased quantity from the recurring terms linked to this key (for example seats), summed across granting principals. `null` when the key is not granted or no granting plan links a term to it. */ + quantity?: number | null | undefined; + /** Remaining metered allowance credits; null for boolean entitlements. */ + remaining?: number | null | undefined; + /** Signed metered consumption in the allowance window; may be negative after reversals. Null for boolean entitlements. */ + used?: number | null | undefined; /** Merged entitlement value, or `null` when the key is not granted. */ value?: boolean | null | undefined; /** Catalog type used to interpret `value`. */ - value_type: "boolean"; + value_type: "boolean" | "metered"; } /** Runtime validator for {@link EffectiveAccessEntitlement}. */ @@ -1174,12 +1252,20 @@ export const effectiveAccessEntitlementSchema = z.object({ granted: z.boolean().describe("Whether any eligible source grants the key."), /** Stable entitlement catalog key. */ key: z.string().describe("Stable entitlement catalog key."), + /** Unexpired metered allowance, including exhausted grants; null for boolean entitlements. */ + limit: z.number().int().nullable().optional().describe("Unexpired metered allowance, including exhausted grants; null for boolean entitlements."), /** Privacy-safe principal kinds that contribute to the effective value. */ provided_by: z.array(z.enum(["personal", "organization"])).describe("Privacy-safe principal kinds that contribute to the effective value."), + /** Effective purchased quantity from the recurring terms linked to this key (for example seats), summed across granting principals. `null` when the key is not granted or no granting plan links a term to it. */ + quantity: z.number().int().nullable().optional().describe("Effective purchased quantity from the recurring terms linked to this key (for example seats), summed across granting principals. `null` when the key is not granted or no granting plan links a term to it."), + /** Remaining metered allowance credits; null for boolean entitlements. */ + remaining: z.number().int().nullable().optional().describe("Remaining metered allowance credits; null for boolean entitlements."), + /** Signed metered consumption in the allowance window; may be negative after reversals. Null for boolean entitlements. */ + used: z.number().int().nullable().optional().describe("Signed metered consumption in the allowance window; may be negative after reversals. Null for boolean entitlements."), /** Merged entitlement value, or `null` when the key is not granted. */ value: z.boolean().nullable().optional().describe("Merged entitlement value, or `null` when the key is not granted."), /** Catalog type used to interpret `value`. */ - value_type: z.literal("boolean").describe("Catalog type used to interpret `value`."), + value_type: z.enum(["boolean", "metered"]).describe("Catalog type used to interpret `value`."), }).describe("A billing-derived effective entitlement for the authenticated user.") satisfies z.ZodType; /** Live effective access, billing authority, and relevant trials for the authenticated user. */ @@ -1220,6 +1306,8 @@ export interface CurrentUser { name?: string | null | undefined; /** The authenticated user's notification preferences. */ notification_settings: Record; + /** Registered display name of the verified OAuth client, when available. Not a verified vendor identity. */ + oauth_client_name?: string | undefined; /** ID of the current organization (`org_...`). */ org?: string | null | undefined; /** Whether the current organization is company-domain or person-owned. */ @@ -1262,6 +1350,8 @@ export const currentUserSchema = z.object({ name: z.string().nullable().optional().describe("Full display name of the user."), /** The authenticated user's notification preferences. */ notification_settings: z.record(z.custom<{} | null>((value) => value !== undefined)).describe("The authenticated user's notification preferences."), + /** Registered display name of the verified OAuth client, when available. Not a verified vendor identity. */ + oauth_client_name: z.string().optional().describe("Registered display name of the verified OAuth client, when available. Not a verified vendor identity."), /** ID of the current organization (`org_...`). */ org: z.string().nullable().optional().describe("ID of the current organization (`org_...`)."), /** Whether the current organization is company-domain or person-owned. */ @@ -1286,8 +1376,12 @@ export const currentUserSchema = z.object({ export interface CustomObject { /** Access control list governing read and write access to this custom object. Only returned to resource owners and privileged or organization-admin viewers; `null` for everyone else. */ acl?: Acl | undefined; + /** ID of the agent that owns this object (`agt_...`). `null` for other ownership types. */ + agent?: string | undefined; /** When the custom object was created (ISO 8601). */ created_at?: string | undefined; + /** Absolute expiry time (RFC 3339). Null when no expiry is set. */ + expires_at?: string | null | undefined; /** Map of field names to their current values as defined by the object's schema type. */ fields?: Record | undefined; /** Unique identifier for the custom object (`cobj_...`). */ @@ -1314,8 +1408,12 @@ export interface CustomObject { export const customObjectSchema = z.object({ /** Access control list governing read and write access to this custom object. Only returned to resource owners and privileged or organization-admin viewers; `null` for everyone else. */ acl: aclSchema.optional().describe("Access control list governing read and write access to this custom object. Only returned to resource owners and privileged or organization-admin viewers; `null` for everyone else."), + /** ID of the agent that owns this object (`agt_...`). `null` for other ownership types. */ + agent: z.string().optional().describe("ID of the agent that owns this object (`agt_...`). `null` for other ownership types."), /** When the custom object was created (ISO 8601). */ created_at: z.string().optional().describe("When the custom object was created (ISO 8601)."), + /** Absolute expiry time (RFC 3339). Null when no expiry is set. */ + expires_at: z.string().nullable().optional().describe("Absolute expiry time (RFC 3339). Null when no expiry is set."), /** Map of field names to their current values as defined by the object's schema type. */ fields: z.record(z.custom<{} | null>((value) => value !== undefined)).optional().describe("Map of field names to their current values as defined by the object's schema type."), /** Unique identifier for the custom object (`cobj_...`). */ @@ -1378,10 +1476,10 @@ export interface CustomObjectListResponse { page: number; /** Maximum number of results returned per page. */ page_size: number; - /** Total number of custom objects matching the query across all pages. */ - total_entries: number; - /** Total number of pages available for the current query. */ - total_pages: number; + /** Total number of custom objects matching the query across all pages; null when include_count is false. */ + total_entries: number | null; + /** Total number of pages available for the current query; null when include_count is false. */ + total_pages: number | null; } /** Runtime validator for {@link CustomObjectListResponse}. */ @@ -1396,10 +1494,10 @@ export const customObjectListResponseSchema = z.object({ page: z.number().int().describe("The current page number (1-indexed)."), /** Maximum number of results returned per page. */ page_size: z.number().int().describe("Maximum number of results returned per page."), - /** Total number of custom objects matching the query across all pages. */ - total_entries: z.number().int().describe("Total number of custom objects matching the query across all pages."), - /** Total number of pages available for the current query. */ - total_pages: z.number().int().describe("Total number of pages available for the current query."), + /** Total number of custom objects matching the query across all pages; null when include_count is false. */ + total_entries: z.number().int().nullable().describe("Total number of custom objects matching the query across all pages; null when include_count is false."), + /** Total number of pages available for the current query; null when include_count is false. */ + total_pages: z.number().int().nullable().describe("Total number of pages available for the current query; null when include_count is false."), }).describe("A paginated page of custom objects returned by a list operation. Use the pagination fields to navigate through result sets.") satisfies z.ZodType; /** Acknowledges an ephemeral custom-object presence update. */ @@ -1911,44 +2009,68 @@ export const installationSourceListResponseSchema = z.object({ data: z.array(installationSourceSchema).describe("Array of installation source objects returned for the current page."), }).describe("Paginated list response containing installation source objects attached to an installation.") satisfies z.ZodType; -/** A single key-value storage entry belonging to a user. Represents one key/value pair written to a user's isolated storage namespace within an app. */ +/** An owner-scoped key/value pair within an app, optionally expiring. */ export interface KeyValueStorageEntry { + /** Agent owner, if any. */ + agent?: string | undefined; /** When this storage entry was first created (ISO 8601). `null` if not yet persisted. */ created_at?: string | undefined; + /** Expiry deadline, or null for entries without expiry. */ + expires_at?: string | undefined; /** The string key used to store and look up this entry. */ key: string; + /** Organization scope. */ + org?: string | undefined; + /** Team owner, if any. */ + team?: string | undefined; /** When this storage entry was last updated (ISO 8601). `null` if not yet persisted. */ updated_at?: string | undefined; - /** ID of the user who owns this storage entry (`usr_...`). */ - user: string; + /** ID of the user owner, or null for non-user ownership. */ + user?: string | undefined; /** The string value stored under `key` for this user. */ value: string; } /** Runtime validator for {@link KeyValueStorageEntry}. */ export const keyValueStorageEntrySchema = z.object({ + /** Agent owner, if any. */ + agent: z.string().optional().describe("Agent owner, if any."), /** When this storage entry was first created (ISO 8601). `null` if not yet persisted. */ created_at: z.string().optional().describe("When this storage entry was first created (ISO 8601). `null` if not yet persisted."), + /** Expiry deadline, or null for entries without expiry. */ + expires_at: z.string().optional().describe("Expiry deadline, or null for entries without expiry."), /** The string key used to store and look up this entry. */ key: z.string().describe("The string key used to store and look up this entry."), + /** Organization scope. */ + org: z.string().optional().describe("Organization scope."), + /** Team owner, if any. */ + team: z.string().optional().describe("Team owner, if any."), /** When this storage entry was last updated (ISO 8601). `null` if not yet persisted. */ updated_at: z.string().optional().describe("When this storage entry was last updated (ISO 8601). `null` if not yet persisted."), - /** ID of the user who owns this storage entry (`usr_...`). */ - user: z.string().describe("ID of the user who owns this storage entry (`usr_...`)."), + /** ID of the user owner, or null for non-user ownership. */ + user: z.string().optional().describe("ID of the user owner, or null for non-user ownership."), /** The string value stored under `key` for this user. */ value: z.string().describe("The string value stored under `key` for this user."), -}).describe("A single key-value storage entry belonging to a user. Represents one key/value pair written to a user's isolated storage namespace within an app.") satisfies z.ZodType; +}).describe("An owner-scoped key/value pair within an app, optionally expiring.") satisfies z.ZodType; /** A key-value storage entry enriched with owner information. Developer and server-to-server callers receive `user_email` and `user_name` populated; end-user (user-JWT) callers receive those fields as `null`. */ export interface KeyValueStorageEntryWithUser { + /** Agent owner, if any. */ + agent?: string | undefined; /** When this storage entry was first created (ISO 8601). */ created_at: string; + /** Expiry deadline, or null for entries without expiry. */ + expires_at?: string | undefined; /** The string key used to store and look up this entry. */ key: string; + /** Organization scope. */ + org?: string | undefined; + /** Team owner, if any. */ + team?: string | undefined; /** When this storage entry was last updated (ISO 8601). */ updated_at: string; - /** ID of the user who owns this storage entry (`usr_...`). */ - user: string; + /** ID of the user owner, or null for non-user ownership. */ + user?: string | undefined; /** Email address of the owning user. `null` for end-user (user-JWT) callers; populated for developer and server-to-server callers. */ user_email?: string | undefined; /** Display name of the owning user. `null` for end-user (user-JWT) callers; populated for developer and server-to-server callers. */ @@ -1959,14 +2081,22 @@ export interface KeyValueStorageEntryWithUser { /** Runtime validator for {@link KeyValueStorageEntryWithUser}. */ export const keyValueStorageEntryWithUserSchema = z.object({ + /** Agent owner, if any. */ + agent: z.string().optional().describe("Agent owner, if any."), /** When this storage entry was first created (ISO 8601). */ created_at: z.string().describe("When this storage entry was first created (ISO 8601)."), + /** Expiry deadline, or null for entries without expiry. */ + expires_at: z.string().optional().describe("Expiry deadline, or null for entries without expiry."), /** The string key used to store and look up this entry. */ key: z.string().describe("The string key used to store and look up this entry."), + /** Organization scope. */ + org: z.string().optional().describe("Organization scope."), + /** Team owner, if any. */ + team: z.string().optional().describe("Team owner, if any."), /** When this storage entry was last updated (ISO 8601). */ updated_at: z.string().describe("When this storage entry was last updated (ISO 8601)."), - /** ID of the user who owns this storage entry (`usr_...`). */ - user: z.string().describe("ID of the user who owns this storage entry (`usr_...`)."), + /** ID of the user owner, or null for non-user ownership. */ + user: z.string().optional().describe("ID of the user owner, or null for non-user ownership."), /** Email address of the owning user. `null` for end-user (user-JWT) callers; populated for developer and server-to-server callers. */ user_email: z.string().optional().describe("Email address of the owning user. `null` for end-user (user-JWT) callers; populated for developer and server-to-server callers."), /** Display name of the owning user. `null` for end-user (user-JWT) callers; populated for developer and server-to-server callers. */ @@ -3231,7 +3361,7 @@ export const agentSchema = z.object({ /** A cloud computer resource provisioned for an agent to use for browser and desktop automation tasks. */ export interface AgentComputer { /** ID of the agent that owns this computer (`agi_...`). `null` if the computer is not yet assigned to an agent. */ - agent?: string | undefined; + agent?: string | null | undefined; /** ID of the app this computer belongs to (`dap_...`). */ app?: string | undefined; /** Provider-specific configuration key-value pairs for the computer. Structure depends on the underlying compute provider. */ @@ -3239,25 +3369,29 @@ export interface AgentComputer { /** When the computer was created (ISO 8601). */ created_at?: string | undefined; /** Human-readable error description when `status` is `"error"`. `null` otherwise. */ - error_message?: string | undefined; + error_message?: string | null | undefined; /** Computer ID (`cmp_...`). */ id: string; + /** Stable key unique within the thread, or null if unset. */ + key?: string | null | undefined; /** When the computer last reported activity or received a command. `null` if the computer has never been active. */ - last_active_at?: string | undefined; + last_active_at?: string | null | undefined; /** Unique, stable identifier you assign to this computer within its app. `null` if not set. */ - lookup_key?: string | undefined; + lookup_key?: string | null | undefined; /** Arbitrary key-value metadata you attached to the computer. `null` if none was provided. */ metadata?: Record | undefined; /** Human-readable display name for the computer. `null` if not set. */ name?: string | undefined; - /** Compute backend powering this computer: `"sprites"` (Fly Sprites) or `"vercel"` (Vercel Sandbox). */ + /** Compute backend powering this computer: `"sprites"` (Fly Sprites), `"vercel"` (Vercel Sandbox) or `"e2b"` (E2B). */ provider?: string | undefined; - /** 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"`). */ - region?: string | undefined; + /** 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"`). */ + region?: string | null | undefined; /** URL of the live screenshot sprite used to render a real-time preview of the computer's screen. `null` when no sprite is available. */ - sprite_url?: string | undefined; + sprite_url?: string | null | undefined; /** Current lifecycle state of the computer. Common values include `"provisioning"`, `"ready"`, `"error"`, and `"terminated"`. */ - status?: string | undefined; + status?: string | null | undefined; + /** Thread this computer belongs to, or null for a non-thread computer. */ + thread_id?: string | null | undefined; /** When the computer record was last modified (ISO 8601). */ updated_at?: string | undefined; } @@ -3265,7 +3399,7 @@ export interface AgentComputer { /** Runtime validator for {@link AgentComputer}. */ export const agentComputerSchema = z.object({ /** ID of the agent that owns this computer (`agi_...`). `null` if the computer is not yet assigned to an agent. */ - agent: z.string().optional().describe("ID of the agent that owns this computer (`agi_...`). `null` if the computer is not yet assigned to an agent."), + agent: z.string().nullable().optional().describe("ID of the agent that owns this computer (`agi_...`). `null` if the computer is not yet assigned to an agent."), /** ID of the app this computer belongs to (`dap_...`). */ app: z.string().optional().describe("ID of the app this computer belongs to (`dap_...`)."), /** Provider-specific configuration key-value pairs for the computer. Structure depends on the underlying compute provider. */ @@ -3273,25 +3407,29 @@ export const agentComputerSchema = z.object({ /** When the computer was created (ISO 8601). */ created_at: z.string().optional().describe("When the computer was created (ISO 8601)."), /** Human-readable error description when `status` is `"error"`. `null` otherwise. */ - error_message: z.string().optional().describe("Human-readable error description when `status` is `\"error\"`. `null` otherwise."), + error_message: z.string().nullable().optional().describe("Human-readable error description when `status` is `\"error\"`. `null` otherwise."), /** Computer ID (`cmp_...`). */ id: z.string().describe("Computer ID (`cmp_...`)."), + /** Stable key unique within the thread, or null if unset. */ + key: z.string().nullable().optional().describe("Stable key unique within the thread, or null if unset."), /** When the computer last reported activity or received a command. `null` if the computer has never been active. */ - last_active_at: z.string().optional().describe("When the computer last reported activity or received a command. `null` if the computer has never been active."), + last_active_at: z.string().nullable().optional().describe("When the computer last reported activity or received a command. `null` if the computer has never been active."), /** Unique, stable identifier you assign to this computer within its app. `null` if not set. */ - lookup_key: z.string().optional().describe("Unique, stable identifier you assign to this computer within its app. `null` if not set."), + lookup_key: z.string().nullable().optional().describe("Unique, stable identifier you assign to this computer within its app. `null` if not set."), /** Arbitrary key-value metadata you attached to the computer. `null` if none was provided. */ metadata: z.record(z.custom<{} | null>((value) => value !== undefined)).optional().describe("Arbitrary key-value metadata you attached to the computer. `null` if none was provided."), /** Human-readable display name for the computer. `null` if not set. */ name: z.string().optional().describe("Human-readable display name for the computer. `null` if not set."), - /** Compute backend powering this computer: `"sprites"` (Fly Sprites) or `"vercel"` (Vercel Sandbox). */ - provider: z.string().optional().describe("Compute backend powering this computer: `\"sprites\"` (Fly Sprites) or `\"vercel\"` (Vercel Sandbox)."), - /** 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"`). */ - region: z.string().optional().describe("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\"`)."), + /** Compute backend powering this computer: `"sprites"` (Fly Sprites), `"vercel"` (Vercel Sandbox) or `"e2b"` (E2B). */ + provider: z.string().optional().describe("Compute backend powering this computer: `\"sprites\"` (Fly Sprites), `\"vercel\"` (Vercel Sandbox) or `\"e2b\"` (E2B)."), + /** 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"`). */ + region: z.string().nullable().optional().describe("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\"`)."), /** URL of the live screenshot sprite used to render a real-time preview of the computer's screen. `null` when no sprite is available. */ - sprite_url: z.string().optional().describe("URL of the live screenshot sprite used to render a real-time preview of the computer's screen. `null` when no sprite is available."), + sprite_url: z.string().nullable().optional().describe("URL of the live screenshot sprite used to render a real-time preview of the computer's screen. `null` when no sprite is available."), /** Current lifecycle state of the computer. Common values include `"provisioning"`, `"ready"`, `"error"`, and `"terminated"`. */ - status: z.string().optional().describe("Current lifecycle state of the computer. Common values include `\"provisioning\"`, `\"ready\"`, `\"error\"`, and `\"terminated\"`."), + status: z.string().nullable().optional().describe("Current lifecycle state of the computer. Common values include `\"provisioning\"`, `\"ready\"`, `\"error\"`, and `\"terminated\"`."), + /** Thread this computer belongs to, or null for a non-thread computer. */ + thread_id: z.string().nullable().optional().describe("Thread this computer belongs to, or null for a non-thread computer."), /** When the computer record was last modified (ISO 8601). */ updated_at: z.string().optional().describe("When the computer record was last modified (ISO 8601)."), }).describe("A cloud computer resource provisioned for an agent to use for browser and desktop automation tasks.") satisfies z.ZodType; @@ -3532,6 +3670,94 @@ export const agentListResponseSchema = z.object({ total_pages: z.number().int().optional().describe("Total number of pages available given the current `page_size`."), }).describe("Paginated list of agent objects. Use the pagination fields to traverse multiple pages of results.") satisfies z.ZodType; +/** Originating agent. */ +export interface AgentRequestAgent { + id: string; + name?: string | null | undefined; +} + +/** Runtime validator for {@link AgentRequestAgent}. */ +export const agentRequestAgentSchema = z.object({ + id: z.string(), + name: z.string().nullable().optional(), +}).describe("Originating agent.") satisfies z.ZodType; + +/** A request for human approval or input. Secret input is never returned. */ +export interface AgentRequest { + /** Originating agent. */ + agent?: AgentRequestAgent | undefined; + /** Approval policy, excluding user IDs. */ + approvers?: Approvers | undefined; + /** Expiration time. */ + expires_at?: string | undefined; + /** Request ID (`arq_...`). */ + id: string; + /** Whether the authenticated caller is an approver, regardless of request status. */ + is_approver?: boolean | undefined; + /** Registered request kind. */ + kind?: string | undefined; + /** Origin references. */ + origin?: Origin | undefined; + /** Question request payload. */ + payload?: Payload | undefined; + /** Answer or rejection reason; null before resolution. */ + resolution?: Resolution | null | undefined; + /** Resolution time. */ + resolved_at?: string | undefined; + /** Resolving user ID. */ + resolved_by?: string | undefined; + /** Request status. */ + status?: string | undefined; + /** Kind-provided summary. */ + summary?: Summary | undefined; +} + +/** Runtime validator for {@link AgentRequest}. */ +export const agentRequestSchema = z.object({ + /** Originating agent. */ + agent: agentRequestAgentSchema.optional().describe("Originating agent."), + /** Approval policy, excluding user IDs. */ + approvers: approversSchema.optional().describe("Approval policy, excluding user IDs."), + /** Expiration time. */ + expires_at: z.string().optional().describe("Expiration time."), + /** Request ID (`arq_...`). */ + id: z.string().describe("Request ID (`arq_...`)."), + /** Whether the authenticated caller is an approver, regardless of request status. */ + is_approver: z.boolean().optional().describe("Whether the authenticated caller is an approver, regardless of request status."), + /** Registered request kind. */ + kind: z.string().optional().describe("Registered request kind."), + /** Origin references. */ + origin: originSchema.optional().describe("Origin references."), + /** Question request payload. */ + payload: payloadSchema.optional().describe("Question request payload."), + /** Answer or rejection reason; null before resolution. */ + resolution: resolutionSchema.nullable().optional().describe("Answer or rejection reason; null before resolution."), + /** Resolution time. */ + resolved_at: z.string().optional().describe("Resolution time."), + /** Resolving user ID. */ + resolved_by: z.string().optional().describe("Resolving user ID."), + /** Request status. */ + status: z.string().optional().describe("Request status."), + /** Kind-provided summary. */ + summary: summarySchema.optional().describe("Kind-provided summary."), +}).describe("A request for human approval or input. Secret input is never returned.") satisfies z.ZodType; + +/** A page of visible agent requests. */ +export interface AgentRequestListResponse { + /** Visible requests. */ + data: AgentRequest[]; + /** Pass as cursor for the next page; null at the end. */ + next_cursor?: string | undefined; +} + +/** Runtime validator for {@link AgentRequestListResponse}. */ +export const agentRequestListResponseSchema = z.object({ + /** Visible requests. */ + data: z.array(agentRequestSchema).describe("Visible requests."), + /** Pass as cursor for the next page; null at the end. */ + next_cursor: z.string().optional().describe("Pass as cursor for the next page; null at the end."), +}).describe("A page of visible agent requests.") satisfies z.ZodType; + /** An agent routine defines a reusable handler — script, preset, or chain — that runs in response to events or on a schedule. */ export interface AgentRoutine { /** Access control list for the routine. Contains a `grants` array where each entry specifies `principal_type`, `principal`, and `actions` (`"read"`, `"invoke"`, or `"assign"` — an `"assign"` grant names the agents or orgs that may be handed this routine's embedded work items). `null` when no ACL restrictions are applied and the routine is accessible to all members of its scope. */ @@ -3932,6 +4158,34 @@ export const agentSessionSchema = z.object({ trajectory: z.string().optional().describe("ID of the trajectory that records the full message history for this session (`trj_...`). `null` until the session has started."), }).describe("A durable agent session record representing a single AI task execution. Tracks status, trajectory, result, and any inbox messages delivered to the session.") satisfies z.ZodType; +/** One event from the coding harness running an agent session on a computer. */ +export interface AgentSessionEvent { + /** Event name: `session_started`, `message`, `tool_use`, `needs_input`, `activity`, `error`, `turn_complete`, `finished`, `adopted`, or `harness_raw`. */ + event?: string | undefined; + /** Harness that emitted it. */ + harness?: string | null | undefined; + /** Event ID; pass as `after` to page. */ + id?: string | undefined; + /** When the event happened in the sandbox. */ + occurred_at?: string | undefined; + /** Harness-specific event data. */ + payload?: Record | null | undefined; +} + +/** Runtime validator for {@link AgentSessionEvent}. */ +export const agentSessionEventSchema = z.object({ + /** Event name: `session_started`, `message`, `tool_use`, `needs_input`, `activity`, `error`, `turn_complete`, `finished`, `adopted`, or `harness_raw`. */ + event: z.string().optional().describe("Event name: `session_started`, `message`, `tool_use`, `needs_input`, `activity`, `error`, `turn_complete`, `finished`, `adopted`, or `harness_raw`."), + /** Harness that emitted it. */ + harness: z.string().nullable().optional().describe("Harness that emitted it."), + /** Event ID; pass as `after` to page. */ + id: z.string().optional().describe("Event ID; pass as `after` to page."), + /** When the event happened in the sandbox. */ + occurred_at: z.string().optional().describe("When the event happened in the sandbox."), + /** Harness-specific event data. */ + payload: z.record(z.custom<{} | null>((value) => value !== undefined)).nullable().optional().describe("Harness-specific event data."), +}).describe("One event from the coding harness running an agent session on a computer.") satisfies z.ZodType; + /** Paginated list response containing an array of agent session objects. */ export interface AgentSessionListResponse { /** Array of agent session objects for the current page. */ diff --git a/packages/sdk/src/types/computers.ts b/packages/sdk/src/types/computers.ts new file mode 100644 index 0000000..045674c --- /dev/null +++ b/packages/sdk/src/types/computers.ts @@ -0,0 +1,21 @@ +// Copyright (c) 2026 ArchAstro Inc. Licensed under the MIT License. +// This file is auto-generated by @archastro/sdk-generator. Do not edit. +// Content hash: 946c53eabd10 + +import { z } from "zod"; + +/** The result of executing a shell command on an agent's computer environment. Contains the captured output and the process exit code. */ +export interface ComputerExecResult { + /** The UNIX exit code returned by the process. `0` indicates success; any non-zero value indicates an error. `null` if the process did not terminate normally. */ + exit_code?: number | undefined; + /** The combined stdout and stderr output produced by the command. `null` if the command produced no output. */ + output?: string | undefined; +} + +/** Runtime validator for {@link ComputerExecResult}. */ +export const computerExecResultSchema = z.object({ + /** The UNIX exit code returned by the process. `0` indicates success; any non-zero value indicates an error. `null` if the process did not terminate normally. */ + exit_code: z.number().int().optional().describe("The UNIX exit code returned by the process. `0` indicates success; any non-zero value indicates an error. `null` if the process did not terminate normally."), + /** The combined stdout and stderr output produced by the command. `null` if the command produced no output. */ + output: z.string().optional().describe("The combined stdout and stderr output produced by the command. `null` if the command produced no output."), +}).describe("The result of executing a shell command on an agent's computer environment. Contains the captured output and the process exit code.") satisfies z.ZodType; diff --git a/packages/sdk/src/types/events.ts b/packages/sdk/src/types/events.ts index e558f0e..8fb6445 100644 --- a/packages/sdk/src/types/events.ts +++ b/packages/sdk/src/types/events.ts @@ -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: 26f39841b6c8 +// Content hash: f25f65229e6a import { z } from "zod"; import { domainEventSchema } from "./common.js"; @@ -14,6 +14,7 @@ export interface EventSubscription { dropped_events_total: number; dropped_through_position: number; event_names: string[]; + filter?: Record | undefined; id: string; last_overflow_at?: string | undefined; leased_count: number; @@ -28,6 +29,7 @@ export interface EventSubscription { updated_at: string; user?: string | undefined; visibility_timeout_seconds: number; + watch_key?: string | undefined; } /** Runtime validator for {@link EventSubscription}. */ @@ -38,6 +40,7 @@ export const eventSubscriptionSchema = z.object({ dropped_events_total: z.number().int(), dropped_through_position: z.number().int(), event_names: z.array(z.string()), + filter: z.record(z.custom<{} | null>((value) => value !== undefined)).optional(), id: z.string(), last_overflow_at: z.string().optional(), leased_count: z.number().int(), @@ -52,6 +55,7 @@ export const eventSubscriptionSchema = z.object({ updated_at: z.string(), user: z.string().optional(), visibility_timeout_seconds: z.number().int(), + watch_key: z.string().optional(), }).describe("An app-scoped subscription to exact domain-event names.") satisfies z.ZodType; /** A domain event leased from a subscription queue. */ diff --git a/packages/sdk/src/types/index.ts b/packages/sdk/src/types/index.ts index c0312f8..74bc1a4 100644 --- a/packages/sdk/src/types/index.ts +++ b/packages/sdk/src/types/index.ts @@ -1,12 +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: 1ea7b1aa9d2e +// Content hash: 2a0a33136e83 export * from "./ai.js"; export * from "./artifacts.js"; export * from "./automations.js"; export * from "./chat.js"; export * from "./common.js"; +export * from "./computers.js"; export * from "./config.js"; export * from "./device.js"; export * from "./events.js"; @@ -17,6 +18,7 @@ export * from "./image.js"; export * from "./invites.js"; export * from "./notifications.js"; export * from "./oauth.js"; +export * from "./relays.js"; export * from "./scripts.js"; export * from "./status.js"; export * from "./system.js"; diff --git a/packages/sdk/src/types/relays.ts b/packages/sdk/src/types/relays.ts new file mode 100644 index 0000000..4455fb8 --- /dev/null +++ b/packages/sdk/src/types/relays.ts @@ -0,0 +1,21 @@ +// Copyright (c) 2026 ArchAstro Inc. Licensed under the MIT License. +// This file is auto-generated by @archastro/sdk-generator. Do not edit. +// Content hash: 5c8bc55afc71 + +import { z } from "zod"; + +/** Public relay authorization record. */ +export interface Relay { + /** Relay expiry. */ + expires_at: string; + /** Relay ID. */ + id: string; +} + +/** Runtime validator for {@link Relay}. */ +export const relaySchema = z.object({ + /** Relay expiry. */ + expires_at: z.string().describe("Relay expiry."), + /** Relay ID. */ + id: z.string().describe("Relay ID."), +}).describe("Public relay authorization record.") satisfies z.ZodType; diff --git a/packages/sdk/src/types/tasks.ts b/packages/sdk/src/types/tasks.ts index 0e8c5c4..73a366c 100644 --- a/packages/sdk/src/types/tasks.ts +++ b/packages/sdk/src/types/tasks.ts @@ -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: 22d7ccfda7c8 +// Content hash: 5ce6eba81c55 import { z } from "zod"; import { actorSchema } from "./common.js"; @@ -32,7 +32,7 @@ export interface Task { agent?: string | null | undefined; /** Event-stream version for optimistic update fencing. Pass this value as `expected_version` on an update to reject concurrent writes. */ aggregate_version?: number | null | undefined; - /** Number of 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. */ + /** 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. */ blocked_by_count?: number | undefined; /** When the task was marked as done or otherwise closed (ISO 8601). `null` if the task is still open. */ closed_at?: string | null | undefined; @@ -56,8 +56,10 @@ export interface Task { epic?: string | null | undefined; /** Task ID (`tsk_...`). */ id: string; - /** `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 list/show reads; create/update responses report `false` until the next read. */ + /** `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_blocked?: boolean | undefined; + /** 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. */ + is_stalled?: boolean | undefined; /** Key-value map of named URLs or references associated with the task. Returns an empty object when no links have been set. */ links?: Record | undefined; /** Arbitrary key-value map of application-specific data stored alongside the task. Returns an empty object when no metadata has been set. */ @@ -72,10 +74,12 @@ export interface Task { owner_agent?: string | null | undefined; /** 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. */ owner_user?: string | null | undefined; - /** ID of the parent task when this task is a subtask (`tsk_...`). `null` for top-level tasks. Subtasks nest exactly one level. */ + /** 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. */ parent?: string | null | undefined; /** Priority level of the task from `0` (highest) to `4` (lowest). Defaults to `2` (medium) when not explicitly set. */ priority?: number | undefined; + /** Optional project ID (`prj_...`). Membership does not change task visibility. */ + project_id?: string | null | undefined; /** ID of the developer sandbox this task is scoped to (`dsb_...`). `null` for tasks outside a sandbox environment. */ sandbox?: string | null | undefined; /** Source object identity (for example `ArchAstro/firstlanding`). `null` when the task has no source. */ @@ -84,15 +88,21 @@ export interface Task { source_scope?: string | null | undefined; /** Kind of source object (for example `repository`). `null` when the task has no source. */ source_type?: string | null | undefined; + /** Lease expiry for a stalled task, or its last update when no lease expiry exists. Null when not stalled. */ + stalled_since?: string | null | undefined; /** Current status of the task. One of `"open"`, `"in_progress"`, `"in_review"`, `"paused"`, `"failed"`, `"superseding"`, `"done"`, or `"cancelled"`. */ status: string; - /** Number of subtasks under this task. Computed on list/show reads; create/update responses may report 0 until the next read. Always 0 for subtasks. */ + /** 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. */ subtasks_count?: number | undefined; /** Labels for grouping and filtering, stored lowercase and de-duplicated. Empty array when untagged. */ tags?: string[] | undefined; + /** 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_binary?: string | null | undefined; + /** 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. */ + target_version?: string | null | undefined; /** ID of the team that owns this task (`tem_...`). `null` if the task is not scoped to a team. */ team?: string | null | undefined; - /** 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. */ + /** 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. */ thread?: string | null | undefined; /** When the task was last modified (ISO 8601). */ updated_at?: string | undefined; @@ -106,8 +116,8 @@ export const taskSchema = z.object({ agent: z.string().nullable().optional().describe("ID of the agent that owns this task (`agi_...`). `null` if the task is scoped to a team or user."), /** Event-stream version for optimistic update fencing. Pass this value as `expected_version` on an update to reject concurrent writes. */ aggregate_version: z.number().int().nullable().optional().describe("Event-stream version for optimistic update fencing. Pass this value as `expected_version` on an update to reject concurrent writes."), - /** Number of 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. */ - blocked_by_count: z.number().int().optional().describe("Number of 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."), + /** 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. */ + blocked_by_count: z.number().int().optional().describe("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."), /** When the task was marked as done or otherwise closed (ISO 8601). `null` if the task is still open. */ closed_at: z.string().nullable().optional().describe("When the task was marked as done or otherwise closed (ISO 8601). `null` if the task is still open."), /** Total number of comments posted on this task. */ @@ -130,8 +140,10 @@ export const taskSchema = z.object({ epic: z.string().nullable().optional().describe("Free-form grouping label. `null` when the task is not in an epic."), /** Task ID (`tsk_...`). */ id: z.string().describe("Task ID (`tsk_...`)."), - /** `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 list/show reads; create/update responses report `false` until the next read. */ - is_blocked: z.boolean().optional().describe("`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 list/show reads; create/update responses report `false` until the next read."), + /** `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_blocked: z.boolean().optional().describe("`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."), + /** 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. */ + is_stalled: z.boolean().optional().describe("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."), /** Key-value map of named URLs or references associated with the task. Returns an empty object when no links have been set. */ links: z.record(z.custom<{} | null>((value) => value !== undefined)).optional().describe("Key-value map of named URLs or references associated with the task. Returns an empty object when no links have been set."), /** Arbitrary key-value map of application-specific data stored alongside the task. Returns an empty object when no metadata has been set. */ @@ -146,10 +158,12 @@ export const taskSchema = z.object({ owner_agent: z.string().nullable().optional().describe("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."), /** 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. */ owner_user: z.string().nullable().optional().describe("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."), - /** ID of the parent task when this task is a subtask (`tsk_...`). `null` for top-level tasks. Subtasks nest exactly one level. */ - parent: z.string().nullable().optional().describe("ID of the parent task when this task is a subtask (`tsk_...`). `null` for top-level tasks. Subtasks nest exactly one level."), + /** 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. */ + parent: z.string().nullable().optional().describe("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 level of the task from `0` (highest) to `4` (lowest). Defaults to `2` (medium) when not explicitly set. */ priority: z.number().int().optional().describe("Priority level of the task from `0` (highest) to `4` (lowest). Defaults to `2` (medium) when not explicitly set."), + /** Optional project ID (`prj_...`). Membership does not change task visibility. */ + project_id: z.string().nullable().optional().describe("Optional project ID (`prj_...`). Membership does not change task visibility."), /** ID of the developer sandbox this task is scoped to (`dsb_...`). `null` for tasks outside a sandbox environment. */ sandbox: z.string().nullable().optional().describe("ID of the developer sandbox this task is scoped to (`dsb_...`). `null` for tasks outside a sandbox environment."), /** Source object identity (for example `ArchAstro/firstlanding`). `null` when the task has no source. */ @@ -158,16 +172,22 @@ export const taskSchema = z.object({ source_scope: z.string().nullable().optional().describe("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`."), /** Kind of source object (for example `repository`). `null` when the task has no source. */ source_type: z.string().nullable().optional().describe("Kind of source object (for example `repository`). `null` when the task has no source."), + /** Lease expiry for a stalled task, or its last update when no lease expiry exists. Null when not stalled. */ + stalled_since: z.string().nullable().optional().describe("Lease expiry for a stalled task, or its last update when no lease expiry exists. Null when not stalled."), /** Current status of the task. One of `"open"`, `"in_progress"`, `"in_review"`, `"paused"`, `"failed"`, `"superseding"`, `"done"`, or `"cancelled"`. */ status: z.string().describe("Current status of the task. One of `\"open\"`, `\"in_progress\"`, `\"in_review\"`, `\"paused\"`, `\"failed\"`, `\"superseding\"`, `\"done\"`, or `\"cancelled\"`."), - /** Number of subtasks under this task. Computed on list/show reads; create/update responses may report 0 until the next read. Always 0 for subtasks. */ - subtasks_count: z.number().int().optional().describe("Number of subtasks under this task. Computed on list/show reads; create/update responses may report 0 until the next read. Always 0 for subtasks."), + /** 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. */ + subtasks_count: z.number().int().optional().describe("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."), /** Labels for grouping and filtering, stored lowercase and de-duplicated. Empty array when untagged. */ tags: z.array(z.string()).optional().describe("Labels for grouping and filtering, stored lowercase and de-duplicated. Empty array when untagged."), + /** 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_binary: z.string().nullable().optional().describe("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`."), + /** 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. */ + target_version: z.string().nullable().optional().describe("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."), /** ID of the team that owns this task (`tem_...`). `null` if the task is not scoped to a team. */ team: z.string().nullable().optional().describe("ID of the team that owns this task (`tem_...`). `null` if the task is not scoped to a team."), - /** 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. */ - thread: z.string().nullable().optional().describe("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."), + /** 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. */ + thread: z.string().nullable().optional().describe("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."), /** When the task was last modified (ISO 8601). */ updated_at: z.string().optional().describe("When the task was last modified (ISO 8601)."), /** ID of the user that owns this task (`usr_...`). `null` if the task is scoped to a team. */ @@ -226,6 +246,22 @@ export const taskCommentSchema = z.object({ updated_at: z.string().optional().describe("When this comment was last edited (ISO 8601)."), }).describe("A comment posted on a task by a user or an agent, including resolved author information.") satisfies z.ZodType; +/** The current source task and whether this request created it. */ +export interface TaskEnsureResult { + /** Whether this request created the task. */ + created: boolean; + /** The current task. */ + task: Task; +} + +/** Runtime validator for {@link TaskEnsureResult}. */ +export const taskEnsureResultSchema = z.object({ + /** Whether this request created the task. */ + created: z.boolean().describe("Whether this request created the task."), + /** The current task. */ + task: taskSchema.describe("The current task."), +}).describe("The current source task and whether this request created it.") satisfies z.ZodType; + /** An indexed external object linked to a task. */ export interface TaskExternalLink { /** External container identity. */ @@ -246,6 +282,26 @@ export const taskExternalLinkSchema = z.object({ object_type: z.string().describe("External object kind."), }).describe("An indexed external object linked to a task.") satisfies z.ZodType; +/** The background job accepted for a task ownership conversion. */ +export interface TaskOwnershipJob { + /** Background job ID. */ + job_id: number; + /** Completed transfers are still reaching task read models. */ + projection_pending?: boolean | undefined; + /** Current background job state. */ + status: string; +} + +/** Runtime validator for {@link TaskOwnershipJob}. */ +export const taskOwnershipJobSchema = z.object({ + /** Background job ID. */ + job_id: z.number().int().describe("Background job ID."), + /** Completed transfers are still reaching task read models. */ + projection_pending: z.boolean().optional().describe("Completed transfers are still reaching task read models."), + /** Current background job state. */ + status: z.string().describe("Current background job state."), +}).describe("The background job accepted for a task ownership conversion.") satisfies z.ZodType; + /** A task-session lease returned only to its matching holder. */ export interface TaskSessionLease { /** Server-calculated lease expiry in ISO 8601 format. */ @@ -254,12 +310,18 @@ export interface TaskSessionLease { harness: string; /** Caller-generated fencing token required for renewal and release. */ lease_id: string; + /** Milliseconds of lease left when the response was built, clamped at zero. A renewal made while more than half the lease remains appends no event and leaves the expiry unchanged, so clients derive their deadline from this value. */ + lease_remaining_ms: number; /** Server timestamp for the most recent claim, reclaim, or renewal. */ renewed_at: string; /** Opaque caller-generated coding-session identifier. */ session_id: string; /** Display name supplied by the matching coding session. */ session_name: string; + /** Task aggregate version including the claim, reclaim, or renewal event. */ + task_aggregate_version: number; + /** Native task status after the lease event. */ + task_status: string; } /** Runtime validator for {@link TaskSessionLease}. */ @@ -270,10 +332,16 @@ export const taskSessionLeaseSchema = z.object({ harness: z.string().describe("Bounded harness identifier for the matching coding session."), /** Caller-generated fencing token required for renewal and release. */ lease_id: z.string().describe("Caller-generated fencing token required for renewal and release."), + /** Milliseconds of lease left when the response was built, clamped at zero. A renewal made while more than half the lease remains appends no event and leaves the expiry unchanged, so clients derive their deadline from this value. */ + lease_remaining_ms: z.number().int().describe("Milliseconds of lease left when the response was built, clamped at zero. A renewal made while more than half the lease remains appends no event and leaves the expiry unchanged, so clients derive their deadline from this value."), /** Server timestamp for the most recent claim, reclaim, or renewal. */ renewed_at: z.string().describe("Server timestamp for the most recent claim, reclaim, or renewal."), /** Opaque caller-generated coding-session identifier. */ session_id: z.string().describe("Opaque caller-generated coding-session identifier."), /** Display name supplied by the matching coding session. */ session_name: z.string().describe("Display name supplied by the matching coding session."), + /** Task aggregate version including the claim, reclaim, or renewal event. */ + task_aggregate_version: z.number().int().describe("Task aggregate version including the claim, reclaim, or renewal event."), + /** Native task status after the lease event. */ + task_status: z.string().describe("Native task status after the lease event."), }).describe("A task-session lease returned only to its matching holder.") satisfies z.ZodType; diff --git a/packages/sdk/src/v1.ts b/packages/sdk/src/v1.ts index e0d2036..f668ff0 100644 --- a/packages/sdk/src/v1.ts +++ b/packages/sdk/src/v1.ts @@ -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: f1f76ecf4db2 +// Content hash: 100ac0fa75a6 import { HttpClient } from "./runtime/http-client.js"; import { ActivityFeedResource } from "./v1/resources/activity_feed.js"; @@ -8,6 +8,7 @@ import { AgentComputerResource } from "./v1/resources/agent_computers.js"; import { AgentEnvVarResource } from "./v1/resources/agent_env_vars.js"; import { AgentHealthActionResource } from "./v1/resources/agent_health_actions.js"; import { AgentInstallationResource } from "./v1/resources/agent_installations.js"; +import { AgentRequestResource } from "./v1/resources/agent_requests.js"; import { AgentRoutineRunResource } from "./v1/resources/agent_routine_runs.js"; import { AgentRoutineResource } from "./v1/resources/agent_routines.js"; import { AgentSessionResource } from "./v1/resources/agent_sessions.js"; @@ -40,6 +41,7 @@ import { OrgResource } from "./v1/resources/orgs.js"; import { PrivateServiceDefinitionResource } from "./v1/resources/private_service_definitions.js"; import { PrivateServiceEnrollmentResource } from "./v1/resources/private_service_enrollments.js"; import { PrivateServiceResource } from "./v1/resources/private_services.js"; +import { RelayResource } from "./v1/resources/relays.js"; import { SandboxResource } from "./v1/resources/sandboxes.js"; import { ScriptResource } from "./v1/resources/scripts.js"; import { SlackChannelBindingResource } from "./v1/resources/slack_channel_bindings.js"; @@ -49,6 +51,7 @@ import { SolutionTagResource } from "./v1/resources/solution_tags.js"; import { SolutionResource } from "./v1/resources/solutions.js"; import { SshKeyResource } from "./v1/resources/ssh_keys.js"; import { StatuResource } from "./v1/resources/status.js"; +import { TaskOwnershipConversionResource } from "./v1/resources/task_ownership_conversions.js"; import { TaskResource } from "./v1/resources/tasks.js"; import { TeamMembershipResource } from "./v1/resources/team_memberships.js"; import { TeamResource } from "./v1/resources/teams.js"; @@ -65,6 +68,7 @@ export class V1 { readonly agent_env_vars: AgentEnvVarResource; readonly agent_health_actions: AgentHealthActionResource; readonly agent_installations: AgentInstallationResource; + readonly agent_requests: AgentRequestResource; readonly agent_routine_runs: AgentRoutineRunResource; readonly agent_routines: AgentRoutineResource; readonly agent_sessions: AgentSessionResource; @@ -96,6 +100,7 @@ export class V1 { readonly private_service_definitions: PrivateServiceDefinitionResource; readonly private_service_enrollments: PrivateServiceEnrollmentResource; readonly private_services: PrivateServiceResource; + readonly relays: RelayResource; readonly sandboxes: SandboxResource; readonly scripts: ScriptResource; readonly slack_channel_bindings: SlackChannelBindingResource; @@ -105,6 +110,7 @@ export class V1 { readonly solutions: SolutionResource; readonly ssh_keys: SshKeyResource; readonly status: StatuResource; + readonly task_ownership_conversions: TaskOwnershipConversionResource; readonly tasks: TaskResource; readonly team_memberships: TeamMembershipResource; readonly teams: TeamResource; @@ -122,6 +128,7 @@ export class V1 { this.agent_env_vars = new AgentEnvVarResource(http); this.agent_health_actions = new AgentHealthActionResource(http); this.agent_installations = new AgentInstallationResource(http); + this.agent_requests = new AgentRequestResource(http); this.agent_routine_runs = new AgentRoutineRunResource(http); this.agent_routines = new AgentRoutineResource(http); this.agent_sessions = new AgentSessionResource(http); @@ -153,6 +160,7 @@ export class V1 { this.private_service_definitions = new PrivateServiceDefinitionResource(http); this.private_service_enrollments = new PrivateServiceEnrollmentResource(http); this.private_services = new PrivateServiceResource(http); + this.relays = new RelayResource(http); this.sandboxes = new SandboxResource(http); this.scripts = new ScriptResource(http); this.slack_channel_bindings = new SlackChannelBindingResource(http); @@ -162,6 +170,7 @@ export class V1 { this.solutions = new SolutionResource(http); this.ssh_keys = new SshKeyResource(http); this.status = new StatuResource(http); + this.task_ownership_conversions = new TaskOwnershipConversionResource(http); this.tasks = new TaskResource(http); this.team_memberships = new TeamMembershipResource(http); this.teams = new TeamResource(http); diff --git a/packages/sdk/src/v1/resources/agent_computers.ts b/packages/sdk/src/v1/resources/agent_computers.ts index 9980c9d..b32bcce 100644 --- a/packages/sdk/src/v1/resources/agent_computers.ts +++ b/packages/sdk/src/v1/resources/agent_computers.ts @@ -1,9 +1,10 @@ // Copyright (c) 2026 ArchAstro Inc. Licensed under the MIT License. // This file is auto-generated by @archastro/sdk-generator. Do not edit. -// Content hash: 2c4fbb4f908b +// Content hash: b30cd80116d4 import { HttpClient } from "../../runtime/http-client.js"; -import type { AgentComputer, ComputerExecResult } from "../../types/common.js"; +import type { AgentComputer } from "../../types/common.js"; +import type { ComputerExecResult } from "../../types/computers.js"; export class AgentComputerResource { constructor(private http: HttpClient) {} @@ -36,6 +37,23 @@ export class AgentComputerResource { return this.http.request(`/api/v1/agent_computers/${computer}`); } + /** + * Update a computer + * Updates the computer's direct access grants. Requires permission to modify + * the computer. Read grants allow retrieval and command execution; write grants + * also allow management and deletion. Use acl.grants to replace grants, or + * acl.add/acl.remove to patch them. An empty acl.grants array revokes all direct + * grants; omitting acl preserves them. Sharing does not add the computer to + * agent or thread lists. + * @param computer - Computer ID (`cmp_...`). + * @param input - Request body. + * @param input.acl - Access control list replacement or add/remove operations. + * @returns Empty response body. Returns HTTP 204 on success. + */ + async update(computer: string, input: { acl?: { add?: { actions: string[]; principal?: string | undefined; principal_type: string }[] | undefined; grants?: { actions: string[]; principal?: string | undefined; principal_type: string }[] | undefined; remove?: { principal?: string | undefined; principal_type: string }[] | undefined } | undefined }): Promise { + await this.http.request(`/api/v1/agent_computers/${computer}`, { method: "PATCH", body: input }); + } + /** * Execute a command on a computer * Runs a shell command on the specified computer and returns its combined diff --git a/packages/sdk/src/v1/resources/agent_requests.ts b/packages/sdk/src/v1/resources/agent_requests.ts new file mode 100644 index 0000000..361dbb1 --- /dev/null +++ b/packages/sdk/src/v1/resources/agent_requests.ts @@ -0,0 +1,76 @@ +// Copyright (c) 2026 ArchAstro Inc. Licensed under the MIT License. +// This file is auto-generated by @archastro/sdk-generator. Do not edit. +// Content hash: fa766d4d051a + +import { HttpClient } from "../../runtime/http-client.js"; +import type { AgentRequest, AgentRequestListResponse } from "../../types/common.js"; + +export class AgentRequestResource { + constructor(private http: HttpClient) {} + + /** + * List agent requests + * Lists requests visible under the context policy, newest first. Filters are combined. Pagination is not a snapshot; later pages continue after the last returned request. + * @param params - Query parameters. + * @param params.agent - Filter by agent ID. + * @param params.status - open, resolved, rejected, expired or cancelled. + * @param params.kind - Filter by registered kind. + * @param params.limit - Page size, 1–100; default 25. + * @param params.cursor - Opaque next_cursor from a prior page. + * @returns A page of visible requests. + */ + async list(params?: { agent?: string; status?: string; kind?: string; limit?: number; cursor?: string }): Promise { + const query: Record | undefined> = {}; + if (params?.agent !== undefined) { + query["agent"] = params?.agent; + } + if (params?.status !== undefined) { + query["status"] = params?.status; + } + if (params?.kind !== undefined) { + query["kind"] = params?.kind; + } + if (params?.limit !== undefined) { + query["limit"] = params?.limit; + } + if (params?.cursor !== undefined) { + query["cursor"] = params?.cursor; + } + + return this.http.request(`/api/v1/agent_requests`, { query }); + } + + /** + * Show an agent request + * Uses the request context visibility and approver policy. Agents cannot resolve or reject requests. + * @param agentRequest - Request ID (`arq_...`). + * @returns The request, without secret input. + */ + async get(agentRequest: string): Promise { + return this.http.request(`/api/v1/agent_requests/${agentRequest}`); + } + + /** + * Reject an agent request + * Uses the request context visibility and approver policy. Agents cannot resolve or reject requests. + * @param agentRequest - Request ID (`arq_...`). + * @param input - Request body. + * @param input.reason - Reason for rejecting the request. + * @returns The request, without secret input. + */ + async reject(agentRequest: string, input: { reason: string }): Promise { + return this.http.request(`/api/v1/agent_requests/${agentRequest}/reject`, { method: "POST", body: input }); + } + + /** + * Resolve an agent request + * Uses the request context visibility and approver policy. Agents cannot resolve or reject requests. + * @param agentRequest - Request ID (`arq_...`). + * @param input - Request body. + * @param input.input - Kind-specific input. Secrets must use secret_value. + * @returns The request, without secret input. + */ + async resolve(agentRequest: string, input: { input: Record }): Promise { + return this.http.request(`/api/v1/agent_requests/${agentRequest}/resolve`, { method: "POST", body: input }); + } +} diff --git a/packages/sdk/src/v1/resources/agent_sessions.ts b/packages/sdk/src/v1/resources/agent_sessions.ts index afe1890..ccbe2d4 100644 --- a/packages/sdk/src/v1/resources/agent_sessions.ts +++ b/packages/sdk/src/v1/resources/agent_sessions.ts @@ -1,9 +1,9 @@ // Copyright (c) 2026 ArchAstro Inc. Licensed under the MIT License. // This file is auto-generated by @archastro/sdk-generator. Do not edit. -// Content hash: c1dde0539d26 +// Content hash: 85132b864ec0 import { HttpClient } from "../../runtime/http-client.js"; -import type { AgentSession, AgentSessionListResponse } from "../../types/common.js"; +import type { AgentSession, AgentSessionEvent, AgentSessionListResponse } from "../../types/common.js"; export class AgentSessionResource { constructor(private http: HttpClient) {} @@ -148,6 +148,30 @@ export class AgentSessionResource { return this.http.request(`/api/v1/agent_sessions/${agentSession}/cancel`, { method: "POST" }); } + /** + * List an agent session's harness events + * Returns what the coding harness (Claude Code, Codex) running an agent + * session on a computer has done so far: messages, tool use, turn + * completions, in order. Events arrive while the harness runs; page with + * `after`. The session stream endpoint pushes the same events live. + * @param agentSession - Agent session ID (`ase_...`). + * @param params - Query parameters. + * @param params.after - Return events after this event ID (`cse_...`). + * @param params.limit - Maximum events to return (default 200, max 1000). + * @returns Events in the order they happened. + */ + async events(agentSession: string, params?: { after?: string; limit?: number }): Promise { + const query: Record | undefined> = {}; + if (params?.after !== undefined) { + query["after"] = params?.after; + } + if (params?.limit !== undefined) { + query["limit"] = params?.limit; + } + + return this.http.request(`/api/v1/agent_sessions/${agentSession}/events`, { query }); + } + /** * Send a message to an agent session * Appends a message to the inbox of the specified agent session. The agent @@ -174,10 +198,13 @@ export class AgentSessionResource { * Opens a Server-Sent Events connection that emits a `session_update` event * whenever the agent session's status changes, replaying the current status on * connect and closing on a terminal status (`completed`, `failed`, `cancelled`). + * Sessions that run a coding harness on a computer also emit a `session_event` + * for each harness event (messages, tool use, turn completion) as it happens; + * list earlier ones with the session events endpoint. * @param agentSession - ID of the agent session to stream. * @returns Server-Sent Events stream */ - async *stream(agentSession: string): AsyncIterable<{ event: "session_update"; data: AgentSession }> { - yield* this.http.streamSSE(`/api/v1/agent_sessions/${agentSession}/stream`) as AsyncIterable<{ event: "session_update"; data: AgentSession }>; + async *stream(agentSession: string): AsyncIterable<{ event: "session_event"; data: AgentSessionEvent } | { event: "session_update"; data: AgentSession }> { + yield* this.http.streamSSE(`/api/v1/agent_sessions/${agentSession}/stream`) as AsyncIterable<{ event: "session_event"; data: AgentSessionEvent } | { event: "session_update"; data: AgentSession }>; } } diff --git a/packages/sdk/src/v1/resources/agents.ts b/packages/sdk/src/v1/resources/agents.ts index d92155f..395c0ac 100644 --- a/packages/sdk/src/v1/resources/agents.ts +++ b/packages/sdk/src/v1/resources/agents.ts @@ -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: e8ef3fd45f72 +// Content hash: 2620d537ef1c import { HttpClient } from "../../runtime/http-client.js"; import type { Agent, AgentComputer, AgentComputerListResponse, AgentCreateResponse, AgentEnvVarMasked, AgentEnvVarMaskedList, AgentExport, AgentHealth, AgentListResponse, AgentRoutine, AgentSchedule, AgentTool, AgentToolListResponse, AgentUpgradeResponse, HealthActionListResponse, Installation, InstallationKindListResponse, InstallationListResponse, WorkingMemoryEntry, WorkingMemoryEntryListResponse } from "../../types/common.js"; @@ -35,15 +35,16 @@ export class AgentAgentComputerResource { * later without storing its ID — the key must be unique within the app. * @param agent - Agent IDs (`agi_...`). When provided, only computers belonging to these agents are returned. Multiple values are OR'd. * @param input - Request body. + * @param input.acl - Initial access control list. * @param input.config - Provider-specific configuration for the computer. Supported keys vary by provider. A top-level `provider` takes precedence over `config.provider`. * @param input.lookup_key - Stable, user-defined key for this computer. Must be unique within the app. Use it to look up the computer without storing its ID. * @param input.metadata - Arbitrary key-value metadata to attach to the computer. Not interpreted by the platform; returned as-is on all subsequent reads. * @param input.name - Human-readable display name for the computer. - * @param input.provider - Compute backend for the computer: `"sprites"` (Fly Sprites, the default) or `"vercel"` (Vercel Sandbox). Folded into `config.provider`. + * @param input.provider - Compute backend for the computer: `"sprites"` (Fly Sprites, the default), `"vercel"` (Vercel Sandbox) or `"e2b"` (E2B). Folded into `config.provider`. * @param input.region - Region in which to provision the computer, e.g. `"iad"`. Defaults to `"iad"` when omitted. * @returns The newly provisioned computer. */ - async create(agent: string, input: { config?: Record | undefined; lookup_key?: string | undefined; metadata?: Record | undefined; name: string; provider?: string | undefined; region?: string | undefined }): Promise { + async create(agent: string, input: { acl?: { add?: { actions: string[]; principal?: string | undefined; principal_type: string }[] | undefined; grants?: { actions: string[]; principal?: string | undefined; principal_type: string }[] | undefined; remove?: { principal?: string | undefined; principal_type: string }[] | undefined } | undefined; config?: Record | undefined; lookup_key?: string | undefined; metadata?: Record | undefined; name: string; provider?: string | undefined; region?: string | undefined }): Promise { return this.http.request(`/api/v1/agents/${agent}/agent_computers`, { method: "POST", body: input }); } } @@ -683,10 +684,20 @@ export class AgentResource { * @param input.source_types - Exact source-type slugs filtering both chunks and documents, e.g. `["knowledge/documents"]` for authored documents or `["thread/messages"]` for conversation memory. Omit or pass an empty array to include all source types. * @returns Successful response */ - async search(agent: string, input: { max_results?: number | undefined; min_similarity?: number | undefined; mode?: string | undefined; query: string; recency_days?: number | undefined; source_types?: string[] | undefined }): Promise<{ data: ({ content?: string | undefined; content_type?: string | undefined; created_at?: string | undefined; id: string; kind: "chunk"; metadata?: Record | undefined; raw_content?: Record | undefined; type?: string | undefined } | { id: string; kind: "document"; metadata?: Record | undefined; snippet?: string | undefined; title?: string | undefined; total_lines?: number | undefined; total_size?: number | undefined; type?: string | undefined })[] }> { + async search(agent: string, input: { max_results?: number | undefined; min_similarity?: number | undefined; mode?: string | undefined; query: string; recency_days?: number | undefined; source_types?: string[] | undefined }): Promise<{ data: ({ content?: string | undefined; content_type?: string | undefined; created_at?: string | undefined; id: string; kind: "chunk"; metadata?: Record | undefined; raw_content?: Record | undefined; structured_data?: string | null | undefined; structured_data_summary?: string | null | undefined; type?: string | undefined } | { id: string; kind: "document"; metadata?: Record | undefined; snippet?: string | undefined; title?: string | undefined; total_lines?: number | undefined; total_size?: number | undefined; type?: string | undefined })[] }> { return this.http.request(`/api/v1/agents/${agent}/search`, { method: "POST", body: input }); } + /** + * Ensure an agent's private self-solution + * Lazily snapshots an authorized agent into its single private, versioned Solution. + * @param agent - Agent ID or lookup key. + * @returns Successful response + */ + async selfSolution(agent: string): Promise<{ lookup_key: string; solution_id: string; solution_version: string }> { + return this.http.request(`/api/v1/agents/${agent}/self_solution`); + } + /** * Create a thread for an agent * Creates a new thread owned by the specified agent. The thread is scoped to the diff --git a/packages/sdk/src/v1/resources/ai.ts b/packages/sdk/src/v1/resources/ai.ts index 2135045..825c253 100644 --- a/packages/sdk/src/v1/resources/ai.ts +++ b/packages/sdk/src/v1/resources/ai.ts @@ -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: 0a43815e1d53 +// Content hash: 5498da2b5813 import { HttpClient } from "../../runtime/http-client.js"; import type { AIChatStreamDone, AIChatStreamError, AIChatStreamMessageComplete, AIChatStreamMessageDelta, AIChatStreamThinkingDelta, AIChatStreamToolCallDelta, AIChatStreamToolResult, AICompletionResult, AIEvaluationResult, AIImageResult } from "../../types/ai.js"; @@ -110,19 +110,23 @@ export class EvaluationResource { * model and returns typed answers. This is not chat completion and not * JSON-schema structured output: there is no generated text. * Each question is a `boolean`, `choice`, or `score` object with its own - * `id`. Answers come back as the same three typed objects, each carrying - * that `id`. + * `id`. Answers carry that `id`, including a `refusal` answer containing + * only `id` and `type` when the model declines to judge a question. + * Image input, labelled score levels, and refusal answers are model-dependent. + * Images are separate from `state` and use the chat completion image-part format. + * Models without image support reject image input with `400 unsupported_capability`. * The authenticated app must have the `llm_calls` entitlement enabled on its * plan. Requests that exceed the plan quota are rejected with `402`. Token * usage is recorded against the authenticated app and organization. * @param input - Request body. + * @param input.images - Optional image content parts. Omitted or empty means no images. Requires model image support. * @param input.model - Evaluation model identifier. Omit to use the platform default. * @param input.questions - Nonempty list of boolean, choice, or score questions. Each question must include `id`, `type`, and `instructions`. * @param input.session_id - Optional UUID grouping this evaluation under one session in the Developers dashboard. Generated when omitted. * @param input.state - Shared content the model judges. A string, JSON object, or JSON array. Every question in the request sees this same state. - * @returns Typed answers as a list of boolean, choice, or score objects, plus model and usage. + * @returns Typed boolean, choice, score, or refusal answers, plus model and usage. */ - async evaluations(input: { model?: string | undefined; questions: ({ criteria?: { false_description?: string | undefined; true_description?: string | undefined } | undefined; id: string; instructions: string; type: "boolean" } | { criteria: Record; id: string; instructions: string; type: "choice" } | { criteria: string[]; id: string; instructions: string; type: "score" })[]; session_id?: string | undefined; state: unknown }): Promise { + async evaluations(input: { images?: { image_data?: string | undefined; image_type?: string | undefined; image_url?: string | undefined; type: "image" }[] | undefined; model?: string | undefined; questions: ({ criteria?: { false_description?: string | undefined; true_description?: string | undefined } | undefined; id: string; instructions: string; type: "boolean" } | { criteria: Record; id: string; instructions: string; type: "choice" } | { criteria: unknown[]; id: string; instructions: string; type: "score" })[]; session_id?: string | undefined; state: unknown }): Promise { return this.http.request(`/api/v1/ai/evaluation/evaluations`, { method: "POST", body: input }); } @@ -241,4 +245,42 @@ export class AiResource { async sessionToken(input: { entitlement?: "llm_calls" | "run_automation" | undefined; restrictions?: Record | undefined; ttl?: number | undefined; user_id: string }): Promise<{ expires_at: string; token: string }> { return this.http.request(`/api/v1/ai/session_token`, { method: "POST", body: input }); } + + /** + * Read the authenticated user's LLM usage + * Returns the authenticated user's own LLM usage aggregated over a bounded + * time window. Each row carries request and token sums plus the customer-billed + * cost for the group. Cost is derived from the customer's active billing plan; + * provider-reported cost is never returned. + * Pass `group_by` one or more times to choose the grouping dimensions + * (`task`, `model`, `agent_kind`, `agent_id`, `hour`). The window (`since` to + * `until`) may span at most 31 days. Results are capped at `limit` groups. + * @param params - Query parameters. + * @param params.since - Window start as an ISO 8601 timestamp (inclusive). Defaults to 7 days before `until`. + * @param params.until - Window end as an ISO 8601 timestamp (inclusive). Defaults to now. + * @param params.groupBy - Grouping dimensions. Repeat for multiple dimensions (e.g. `group_by[]=task&group_by[]=model`). Defaults to `model`. + * @param params.task - Restrict results to these caller task IDs. Omit to include every task. + * @param params.limit - Maximum number of groups to return. Defaults to 50; maximum is 200. + * @returns Successful response + */ + async usage(params?: { since?: string; until?: string; groupBy?: ("task" | "model" | "agent_kind" | "agent_id" | "hour")[]; task?: string[]; limit?: number }): Promise<{ data: { agent_id?: string | null | undefined; agent_kind?: string | null | undefined; billed_usd?: number | null | undefined; cache_read_tokens: number; cache_write_tokens: number; completion_tokens: number; hour?: string | null | undefined; model?: string | null | undefined; priced: boolean; prompt_tokens: number; requests: number; task?: string | null | undefined }[]; since: string; until: string }> { + const query: Record | undefined> = {}; + if (params?.since !== undefined) { + query["since"] = params?.since; + } + if (params?.until !== undefined) { + query["until"] = params?.until; + } + if (params?.groupBy !== undefined) { + query["group_by"] = params?.groupBy; + } + if (params?.task !== undefined) { + query["task"] = params?.task; + } + if (params?.limit !== undefined) { + query["limit"] = params?.limit; + } + + return this.http.request(`/api/v1/ai/usage`, { query }); + } } diff --git a/packages/sdk/src/v1/resources/artifacts.ts b/packages/sdk/src/v1/resources/artifacts.ts index 1197f04..8388919 100644 --- a/packages/sdk/src/v1/resources/artifacts.ts +++ b/packages/sdk/src/v1/resources/artifacts.ts @@ -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: a7e803c2e79d +// Content hash: c4c86309e387 import { HttpClient } from "../../runtime/http-client.js"; import type { Artifact } from "../../types/artifacts.js"; @@ -23,6 +23,7 @@ export class ArtifactResource { * `thread` or `agent`. Legacy requests that wrap fields in an `artifact` object * are still accepted. * @param input - Request body. + * @param input.acl - Initial access control list. Grants add read or write access beyond the owner. * @param input.agent - Agent ID (`agt_...`) to associate with the artifact. * @param input.artifact - Legacy wrapper object containing artifact attributes. Prefer top-level fields. * @param input.description - Optional longer artifact description. @@ -31,14 +32,13 @@ export class ArtifactResource { * @param input.idempotency_key - Optional PR-evidence retry key, limited to 255 characters. Requires both team and thread. Matching app, team, thread, name, and key values return the original artifact. * @param input.name - Human-readable artifact name. * @param input.org - Organization owning a system artifact. Requires an organization admin or system viewer. - * @param input.permissions - Optional artifact permissions map. * @param input.system - When true, create a system-owned artifact. Mutually exclusive with `team` and `user`. * @param input.team - Team ID (`tem_...`) that should own the artifact. Mutually exclusive with `user`. * @param input.thread - Thread ID (`thr_...`) to associate with the artifact. * @param input.user - User ID (`usr_...`) that should own the artifact. Defaults to the authenticated user when omitted and no team is supplied. * @returns The newly created artifact. */ - async create(input: { agent?: string | undefined; artifact?: Record | undefined; description?: string | undefined; file?: { data: string; encoding?: "base64" | "utf8" | undefined; filename?: string | undefined; mime_type?: string | undefined } | undefined; group_key?: string | null | undefined; idempotency_key?: string | undefined; name?: string | undefined; org?: string | undefined; permissions?: Record | undefined; system?: boolean | undefined; team?: string | undefined; thread?: string | undefined; user?: string | undefined }): Promise { + async create(input: { acl?: { add?: { actions: string[]; principal?: string | undefined; principal_type: string }[] | undefined; grants?: { actions: string[]; principal?: string | undefined; principal_type: string }[] | undefined; remove?: { principal?: string | undefined; principal_type: string }[] | undefined } | undefined; agent?: string | undefined; artifact?: Record | undefined; description?: string | undefined; file?: { data: string; encoding?: "base64" | "utf8" | undefined; filename?: string | undefined; mime_type?: string | undefined } | undefined; group_key?: string | null | undefined; idempotency_key?: string | undefined; name?: string | undefined; org?: string | undefined; system?: boolean | undefined; team?: string | undefined; thread?: string | undefined; user?: string | undefined }): Promise { return this.http.request(`/api/v1/artifacts`, { method: "POST", body: input }); } @@ -85,6 +85,7 @@ export class ArtifactResource { * artifact's owner. * @param artifact - Artifact ID (`art_...`) of the artifact to update. * @param input - Request body. + * @param input.acl - Access control list replacement (`grants`) or add/remove operations. Omit to leave grants unchanged. ACL-only updates do not increment the content version. * @param input.description - New description for the artifact. Omit to leave the existing description unchanged. * @param input.file - Replacement file payload. Omit to leave the current file unchanged. * @param input.file_content - Legacy flat Base64 file content. Prefer `file.data`. @@ -95,7 +96,7 @@ export class ArtifactResource { * @param input.name - New display name for the artifact. Omit to leave the existing name unchanged. * @returns The artifact after applying the update, reflecting the new version number and any changed metadata or file. */ - async replace(artifact: string, input: { description?: string | undefined; file?: { data: string; encoding?: "base64" | "utf8" | undefined; filename?: string | undefined; mime_type?: string | undefined } | undefined; file_content?: string | undefined; file_content_type?: string | undefined; file_name?: string | undefined; from_version: number; group_key?: string | null | undefined; name?: string | undefined }): Promise { + async replace(artifact: string, input: { acl?: { add?: { actions: string[]; principal?: string | undefined; principal_type: string }[] | undefined; grants?: { actions: string[]; principal?: string | undefined; principal_type: string }[] | undefined; remove?: { principal?: string | undefined; principal_type: string }[] | undefined } | undefined; description?: string | undefined; file?: { data: string; encoding?: "base64" | "utf8" | undefined; filename?: string | undefined; mime_type?: string | undefined } | undefined; file_content?: string | undefined; file_content_type?: string | undefined; file_name?: string | undefined; from_version: number; group_key?: string | null | undefined; name?: string | undefined }): Promise { return this.http.request(`/api/v1/artifacts/${artifact}`, { method: "PUT", body: input }); } diff --git a/packages/sdk/src/v1/resources/custom_objects.ts b/packages/sdk/src/v1/resources/custom_objects.ts index 11d11f6..44a36ab 100644 --- a/packages/sdk/src/v1/resources/custom_objects.ts +++ b/packages/sdk/src/v1/resources/custom_objects.ts @@ -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: c398450206df +// Content hash: 3d3dbbdec656 import { HttpClient } from "../../runtime/http-client.js"; import type { CustomObject, CustomObjectListResponse } from "../../types/common.js"; @@ -28,8 +28,12 @@ export class CustomObjectResource { * @param params - Query parameters. * @param params.type - Schema type identifier (`lookup_key`) to filter by. Only objects of this type are returned. Alias of `schema_key`; either name is accepted. * @param params.schemaKey - Legacy alias for `type`. Prefer `type` on new clients. When both are supplied, `type` wins. + * @param params.fieldFilters - JSON containment predicates on fields, applied before pagination and counting. + * @param params.systemOnly - Only system-owned objects (no user, team, agent or thread owner). Visibility is unchanged. + * @param params.orderByField - Top-level JSON field for descending text order, with ID tie-breaker. Full-text relevance takes precedence. * @param params.rowKey - Exact `row_key` value to match. When supplied, only objects with this partition key are returned. * @param params.sortKey - One or more `sort_key` values to match within the `row_key` partition. Requires `row_key` to be set. + * @param params.keys - JSON-encoded array of up to 100 objects with required string row_key and optional string-array sort_key. Missing or empty sort_key selects the whole partition. Mutually exclusive with row_key and sort_key. Pagination applies globally across all matched partitions. * @param params.team - One or more team IDs (`team_...`) to filter by owning team. Returns objects owned by any of the supplied teams. * @param params.user - One or more user IDs (`user_...`) to filter by owning user. Returns objects owned by any of the supplied users. * @param params.agent - One or more agent IDs to filter by owning agent. Returns objects owned by any of the supplied agents. @@ -37,10 +41,12 @@ export class CustomObjectResource { * @param params.query - Full-text search string matched against the schema's configured search fields. When supplied, results are ordered by relevance score descending instead of creation time descending. * @param params.search - Case-insensitive substring search applied across the schema type and serialized field values. Deprecated — prefer `query` for full-text search. Retained for developer-namespace clients. * @param params.page - Page number to retrieve (1-indexed). Defaults to `1`. + * @param params.updatedSince - Include only objects updated at or after this ISO 8601 timestamp. Applies before pagination and counting. * @param params.pageSize - Number of objects per page. Defaults to `25`; maximum is `100`. + * @param params.includeCount - Include total_entries and total_pages (default true). When false, totals are null, has_next uses one extra row, and pages beyond the end return an empty list without clamping. The page offset must fit PostgreSQL's signed 64-bit integer range. * @returns Paginated list of custom objects matching the supplied filters. */ - async list(params?: { type?: string; schemaKey?: string; rowKey?: string; sortKey?: string[]; team?: string[]; user?: string[]; agent?: string[]; org?: string[]; query?: string; search?: string; page?: number; pageSize?: number }): Promise { + async list(params?: { type?: string; schemaKey?: string; fieldFilters?: Record; systemOnly?: boolean; orderByField?: string; rowKey?: string; sortKey?: string[]; keys?: Record[]; team?: string[]; user?: string[]; agent?: string[]; org?: string[]; query?: string; search?: string; page?: number; updatedSince?: string; pageSize?: number; includeCount?: boolean }): Promise { const query: Record | undefined> = {}; if (params?.type !== undefined) { query["type"] = params?.type; @@ -48,12 +54,24 @@ export class CustomObjectResource { if (params?.schemaKey !== undefined) { query["schema_key"] = params?.schemaKey; } + if (params?.fieldFilters !== undefined) { + query["field_filters"] = JSON.stringify(params?.fieldFilters); + } + if (params?.systemOnly !== undefined) { + query["system_only"] = params?.systemOnly; + } + if (params?.orderByField !== undefined) { + query["order_by_field"] = params?.orderByField; + } if (params?.rowKey !== undefined) { query["row_key"] = params?.rowKey; } if (params?.sortKey !== undefined) { query["sort_key"] = params?.sortKey; } + if (params?.keys !== undefined) { + query["keys"] = JSON.stringify(params?.keys); + } if (params?.team !== undefined) { query["team"] = params?.team; } @@ -75,9 +93,15 @@ export class CustomObjectResource { if (params?.page !== undefined) { query["page"] = params?.page; } + if (params?.updatedSince !== undefined) { + query["updated_since"] = params?.updatedSince; + } if (params?.pageSize !== undefined) { query["page_size"] = params?.pageSize; } + if (params?.includeCount !== undefined) { + query["include_count"] = params?.includeCount; + } return this.http.request(`/api/v1/custom_objects`, { query }); } @@ -104,6 +128,7 @@ export class CustomObjectResource { * @param input.acl - Access control list for the custom object. Supports explicit `read` and `write` grants to users, teams, organizations, organization roles, agents, or everyone. * @param input.agent - Agent user ID to set as the object owner. Used when neither `team` nor `user` is supplied. * @param input.config - Config ID (`cfg_...`) that resolves to the target schema. Provide one of `type`, `schema_key`, or `config`. + * @param input.expires_at - Absolute expiry time in RFC 3339 format. Pass null to clear; omit to leave unchanged on update. * @param input.fields - Key-value map of field values for the new object. Must conform to the schema's field definitions. Omit to create an object with all fields at their default or null values. * @param input.org - Organization ID (`org_...`) to associate with the object. Typically required for system-owned objects. * @param input.schema_key - Legacy alias for `type` (schema `lookup_key`). Prefer `type` on new clients. Provide one of `type`, `schema_key`, or `config`. @@ -114,10 +139,43 @@ export class CustomObjectResource { * @param input.user - User ID (`user_...`) to set as the object owner. Used when neither `team` nor a higher-priority owner is set. * @returns The created (or upserted) custom object. */ - async create(input: { acl?: { add?: { actions: string[]; principal?: string | undefined; principal_type: string }[] | undefined; grants?: { actions: string[]; principal?: string | undefined; principal_type: string }[] | undefined; remove?: { principal?: string | undefined; principal_type: string }[] | undefined } | undefined; agent?: string | undefined; config?: string | undefined; fields?: Record | undefined; org?: string | undefined; schema_key?: string | undefined; system?: boolean | undefined; team?: string | undefined; type?: string | undefined; upsert?: boolean | undefined; user?: string | undefined }): Promise { + async create(input: { acl?: { add?: { actions: string[]; principal?: string | undefined; principal_type: string }[] | undefined; grants?: { actions: string[]; principal?: string | undefined; principal_type: string }[] | undefined; remove?: { principal?: string | undefined; principal_type: string }[] | undefined } | undefined; agent?: string | undefined; config?: string | undefined; expires_at?: string | null | undefined; fields?: Record | undefined; org?: string | undefined; schema_key?: string | undefined; system?: boolean | undefined; team?: string | undefined; type?: string | undefined; upsert?: boolean | undefined; user?: string | undefined }): Promise { return this.http.request(`/api/v1/custom_objects`, { method: "POST", body: input }); } + /** + * Apply numeric patch ops to a custom object + * Applies numeric patch ops (`increment`, `max`, `min`, `set_if_newer` with + * dotted `path`s) atomically to a custom object and returns the updated + * object along with per-op results. The authenticated viewer must have + * permission to modify the object. + * Address the row in one of two ways: by `object` ID (`cobj_...`), or by + * `schema` + `row_key` (with optional `sort_key` for schemas that declare + * one). The keyed form resolves the row for the same owner the create + * contract would use and, when no row exists yet, creates it from + * `create_with` merged over the key fields before applying the ops — so an + * aggregator's first call creates the counter and later calls increment it. + * A racing create resolves to the same row instead of a duplicate. + * Pass `idempotency_key` to make retries safe: a retry with the same key and + * ops replays the stored result without re-applying the write (survives + * server restarts); reusing a key with different ops returns 409. + * @param input - Request body. + * @param input.agent - Agent user ID owning the keyed row. At most one owner selector may be present. + * @param input.create_with - Field values used to create the row when the keyed form finds no existing row. Merged over the key fields before validation; ignored by the `object` form. + * @param input.idempotency_key - Client-supplied deduplication key for this patch. A retry with the same key and the same ops replays the stored result without re-applying the write (survives server restarts); reusing a key with different ops returns 409. + * @param input.object - Custom object ID (`cobj_...`) to patch. Exactly one of `object` or `schema` + `row_key` is required. + * @param input.ops - Numeric patch ops to apply in order (e.g. `[%{"op" => "increment", "path" => "count", "by" => 1}]`). Supported ops: `increment` (`by`), `max`/`min` (`value`), `set_if_newer` (`value`, `fence_path`, `fence`). + * @param input.row_key - Row key naming the row within `schema` (e.g. a counter name). Requires `schema`. + * @param input.schema - Schema type identifier (`lookup_key`) for the keyed form. Requires `row_key`. + * @param input.sort_key - Sort-key segments partitioning rows within the `row_key` bucket. Only meaningful for schemas that declare a `sort_key`. + * @param input.team - Team ID (`tem_...`) owning the keyed row. Defaults to the viewer's owner like the create contract. + * @param input.user - User ID (`usr_...`) owning the keyed row. At most one owner selector may be present. + * @returns Successful response + */ + async patch(input: { agent?: string | undefined; create_with?: Record | undefined; idempotency_key?: string | undefined; object?: string | undefined; ops: Record[]; row_key?: string | undefined; schema?: string | undefined; sort_key?: string[] | undefined; team?: string | undefined; user?: string | undefined }): Promise<{ data: { acl?: { add?: { actions: string[]; principal?: string | undefined; principal_type: string }[] | undefined; grants?: { actions: string[]; principal?: string | undefined; principal_type: string }[] | undefined; remove?: { principal?: string | undefined; principal_type: string }[] | undefined } | undefined; agent?: string | undefined; created_at?: string | undefined; expires_at?: string | null | undefined; fields?: Record | undefined; id: string; org?: string | undefined; row_key?: string | undefined; sandbox?: string | undefined; schema_type?: string | undefined; team?: string | undefined; updated_at?: string | undefined; user?: string | undefined; version?: number | undefined }; meta?: Record | undefined }> { + return this.http.request(`/api/v1/custom_objects/patch`, { method: "POST", body: input }); + } + /** * Delete a custom object * Permanently deletes the custom object identified by `object`. The caller @@ -170,12 +228,14 @@ export class CustomObjectResource { * @param input - Request body. * @param input.acl - Updated access control list. Supports full replacement via `grants` or targeted `add`/`remove` operations. * @param input.expected_version - Version number the caller expects to be current. If the object's actual current version does not match, the request returns 409 to signal a concurrent modification. Omit to skip optimistic locking and keep the existing OCC merge retry. + * @param input.expires_at - Absolute expiry time in RFC 3339 format. Pass null to clear; omit to leave unchanged on update. * @param input.field_ops - Granular array operations to apply per field (e.g. append, prepend, remove). A field must not appear in both `fields` and `field_ops`. * @param input.fields - Key-value map of field values to merge into the object. Only the supplied keys are affected. + * @param input.idempotency_key - Client-supplied deduplication key for this write. A retry with the same key and the same body replays the stored result without re-applying the write (survives server restarts); reusing a key with a different body returns 409. * @param input.type - Schema type identifier (`lookup_key`) of the object. Optional; used for routing context only. * @returns Successful response */ - async replace(object: string, input: { acl?: { add?: { actions: string[]; principal?: string | undefined; principal_type: string }[] | undefined; grants?: { actions: string[]; principal?: string | undefined; principal_type: string }[] | undefined; remove?: { principal?: string | undefined; principal_type: string }[] | undefined } | undefined; expected_version?: number | undefined; field_ops?: Record | undefined; fields?: Record | undefined; type?: string | undefined }): Promise<{ data: { acl?: { add?: { actions: string[]; principal?: string | undefined; principal_type: string }[] | undefined; grants?: { actions: string[]; principal?: string | undefined; principal_type: string }[] | undefined; remove?: { principal?: string | undefined; principal_type: string }[] | undefined } | undefined; created_at?: string | undefined; fields?: Record | undefined; id: string; org?: string | undefined; row_key?: string | undefined; sandbox?: string | undefined; schema_type?: string | undefined; team?: string | undefined; updated_at?: string | undefined; user?: string | undefined; version?: number | undefined }; meta?: Record | undefined }> { + async replace(object: string, input: { acl?: { add?: { actions: string[]; principal?: string | undefined; principal_type: string }[] | undefined; grants?: { actions: string[]; principal?: string | undefined; principal_type: string }[] | undefined; remove?: { principal?: string | undefined; principal_type: string }[] | undefined } | undefined; expected_version?: number | undefined; expires_at?: string | null | undefined; field_ops?: Record | undefined; fields?: Record | undefined; idempotency_key?: string | undefined; type?: string | undefined }): Promise<{ data: { acl?: { add?: { actions: string[]; principal?: string | undefined; principal_type: string }[] | undefined; grants?: { actions: string[]; principal?: string | undefined; principal_type: string }[] | undefined; remove?: { principal?: string | undefined; principal_type: string }[] | undefined } | undefined; agent?: string | undefined; created_at?: string | undefined; expires_at?: string | null | undefined; fields?: Record | undefined; id: string; org?: string | undefined; row_key?: string | undefined; sandbox?: string | undefined; schema_type?: string | undefined; team?: string | undefined; updated_at?: string | undefined; user?: string | undefined; version?: number | undefined }; meta?: Record | undefined }> { return this.http.request(`/api/v1/custom_objects/${object}`, { method: "PUT", body: input }); } } diff --git a/packages/sdk/src/v1/resources/event_subscriptions.ts b/packages/sdk/src/v1/resources/event_subscriptions.ts index 906aadf..8564c52 100644 --- a/packages/sdk/src/v1/resources/event_subscriptions.ts +++ b/packages/sdk/src/v1/resources/event_subscriptions.ts @@ -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: 8b62c42d68b6 +// Content hash: af1ab6877b8e import { HttpClient } from "../../runtime/http-client.js"; import type { EventSubscription, EventSubscriptionClaim, EventSubscriptionHead, EventSubscriptionPage, EventSubscriptionQueue } from "../../types/events.js"; @@ -33,14 +33,19 @@ export class EventSubscriptionResource { * Creates a durable subscription that receives exportable domain events matching its exact event names. Matching events fan out into a per-subscription queue bounded by max_pending_events and retention_seconds; consume with claim and acknowledge. * @param input - Request body. * @param input.event_names - Exact event names to receive. + * @param input.filter - Optional match over subject_key, actor_key, and allowlisted dims. Only valid when every event name is a custom (script-emitted) event type. Missing filter matches all events. * @param input.max_pending_events - Queue cap. Defaults to 100; maximum 1000. * @param input.name - Customer-defined subscription name. + * @param input.previous_filter - Expected legacy filter for atomic watch-key adoption. + * @param input.previous_filters - Additional exact historical filters accepted for atomic watch-key adoption. + * @param input.previous_watch_key - Optionally adopt an existing key in the exact same owner and residence when the destination is absent and its filter exactly matches previous_filter, one of previous_filters, or filter. Preserves queue identity and deliveries; mismatches reject the request without changing either queue. * @param input.retention_seconds - Delivery retention in seconds. Defaults to 86400 (24 hours); between 7200 and 2592000. Applies to future deliveries only. * @param input.status - Initial status. Defaults to active. * @param input.visibility_timeout_seconds - Default claim lease in seconds. Defaults to 300. + * @param input.watch_key - Optional durable identity within the caller owner and residence. Repeated creates replace routes and filter on that queue; omission creates a new queue regardless of name. * @returns The new volatile subscription. */ - async create(input: { event_names: string[]; max_pending_events?: number | undefined; name: string; retention_seconds?: number | undefined; status?: "active" | "paused" | undefined; visibility_timeout_seconds?: number | undefined }): Promise { + async create(input: { event_names: string[]; filter?: Record | undefined; max_pending_events?: number | undefined; name: string; previous_filter?: Record | undefined; previous_filters?: Record[] | undefined; previous_watch_key?: string | undefined; retention_seconds?: number | undefined; status?: "active" | "paused" | undefined; visibility_timeout_seconds?: number | undefined; watch_key?: string | undefined }): Promise { return this.http.request(`/api/v1/event_subscriptions`, { method: "POST", body: input }); } @@ -69,10 +74,11 @@ export class EventSubscriptionResource { * Updates matching, status, or queue limits for future fanout. Already queued deliveries remain unless a lower cap trims the oldest entries; retention changes apply to future deliveries only. * @param subscription - Subscription ID (`esub_...`). * @param input - Request body. + * @param input.filter - Optional match over subject_key, actor_key, and allowlisted dims. Only valid when every event name is a custom (script-emitted) event type. Missing filter matches all events. * @param input.retention_seconds - Delivery retention in seconds. Defaults to 86400 (24 hours); between 7200 and 2592000. Applies to future deliveries only. * @returns Successful response */ - async update(subscription: string, input: { event_names?: string[] | undefined; max_pending_events?: number | undefined; name?: string | undefined; retention_seconds?: number | undefined; status?: "active" | "paused" | undefined; visibility_timeout_seconds?: number | undefined }): Promise { + async update(subscription: string, input: { event_names?: string[] | undefined; filter?: Record | undefined; max_pending_events?: number | undefined; name?: string | undefined; retention_seconds?: number | undefined; status?: "active" | "paused" | undefined; visibility_timeout_seconds?: number | undefined }): Promise { return this.http.request(`/api/v1/event_subscriptions/${subscription}`, { method: "PATCH", body: input }); } diff --git a/packages/sdk/src/v1/resources/files.ts b/packages/sdk/src/v1/resources/files.ts index 1953093..65ade5a 100644 --- a/packages/sdk/src/v1/resources/files.ts +++ b/packages/sdk/src/v1/resources/files.ts @@ -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: e7ffe7568735 +// Content hash: 713012a0ac62 import { HttpClient } from "../../runtime/http-client.js"; import type { StorageFile } from "../../types/common.js"; @@ -14,7 +14,7 @@ export class FileResource { * including a signed download URL. Use this endpoint to store images, documents, or * other binary assets that can then be referenced by agents, teams, or users. * The JSON body uses Platform's default 8,000,000-byte parser budget; the - * ArchDev Platform proxy has a separate 32 MiB request cap. Base64 requires + * an upstream proxy in front of Platform may have a separate 32 MiB request cap. Base64 requires * `4 * ceil(binary_bytes / 3)` bytes, plus the UTF-8 JSON envelope (including * filename, owner IDs, escaping and other fields). For an envelope of E bytes, * budget at most `3 * floor((8,000,000 - E) / 4)` binary bytes: less than @@ -75,23 +75,23 @@ export class FileResource { } /** - * Fetch an agent avatar image - * Returns the raw image bytes for an agent's profile picture identified by `file`. - * This endpoint is designed for integration partners (such as Slack) that fetch - * avatar URLs via plain GET requests without bearer token support. Authorization - * is performed via a short, stable capability `token` rather than an HTTP header. + * Fetch an agent or user avatar image + * Returns the raw image bytes for an agent's or user's profile picture identified + * by `file`. Chat messages and integration partners (such as Slack) fetch avatars + * through it with plain GET requests, without bearer tokens. Authorization is + * performed via a short, stable capability `token` rather than an HTTP header. * The `token` is an HMAC-based capability tied to the file ID. It does not expire, - * but it is invalidated when the agent's profile picture is replaced or the agent is - * deleted — shared caches may continue serving the old image until the + * but it is invalidated when the profile picture is replaced or its agent or user + * is deleted — shared caches may continue serving the old image until the * `Cache-Control` max-age of one hour elapses. The endpoint never redirects to * a signed storage URL; bytes are served inline so behavior is consistent across * storage backends. * All failure modes — invalid file ID, invalid token, file not currently referenced * as an agent avatar — return a uniform `404` to avoid acting as an existence oracle. - * @param file - File ID of the agent's profile picture (`fil_...`). Must be currently set as an agent's profile picture within the same app. + * @param file - File ID of the profile picture (`fil_...`). Must be currently set as an agent's or user's profile picture within the same app. * @param params - Query parameters. * @param params.token - HMAC capability token authorizing access to this specific file. Obtained from the avatar URL minted when the profile picture was set. - * @returns Raw image bytes of the agent avatar, served with the file's original content type. + * @returns Raw image bytes of the avatar, served with the file's original content type. */ async avatar(file: string, params?: { token?: string }): Promise<{ content: ArrayBuffer; mimeType: string }> { const query: Record | undefined> = {}; @@ -100,6 +100,28 @@ export class FileResource { return this.http.requestRaw(`/api/v1/files/${file}/avatar`, { query }); } + /** + * Download a file's bytes + * Returns the raw binary content of a file the authenticated viewer may see. + * The response `Content-Type` header reflects the file's stored MIME type and + * `Content-Disposition` names the file as an attachment, so a browser can hand + * the body to the download manager directly. + * Unlike `Show` (which mints a storage URL the browser must resolve itself), + * this endpoint serves bytes inline through the authenticated API mount, so it + * behaves identically across storage backends: local files are not exposed as + * unauthenticated static paths, and signed GCS URLs never cross the browser + * boundary. A file that exists but is not visible to the current viewer + * returns `404` rather than `403` to avoid revealing the file's existence. + * Byte downloads are limited to 32 MiB (33,554,432 bytes). The storage provider + * enforces this limit on actual content, independently of stored size metadata. + * Larger content returns HTTP `413` with error code `content_too_large`. + * @param file - File ID (`fil_...`) of the file to download. + * @returns Raw binary content of the file, served with the file's stored MIME type. + */ + async download(file: string): Promise<{ content: ArrayBuffer; mimeType: string }> { + return this.http.requestRaw(`/api/v1/files/${file}/download`); + } + /** * Fetch an org logo image * Returns the raw image bytes for an organization's logo identified by `file`. diff --git a/packages/sdk/src/v1/resources/index.ts b/packages/sdk/src/v1/resources/index.ts index 5d566e7..cae3069 100644 --- a/packages/sdk/src/v1/resources/index.ts +++ b/packages/sdk/src/v1/resources/index.ts @@ -1,12 +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: d1e6c3b22213 +// Content hash: 7322b35399ce export { ActivityFeedResource } from "./activity_feed.js"; export { AgentComputerResource } from "./agent_computers.js"; export { AgentEnvVarResource } from "./agent_env_vars.js"; export { AgentHealthActionResource } from "./agent_health_actions.js"; export { AgentInstallationResource } from "./agent_installations.js"; +export { AgentRequestResource } from "./agent_requests.js"; export { AgentRoutineRunResource } from "./agent_routine_runs.js"; export { AgentRoutineResource } from "./agent_routines.js"; export { AgentSessionResource } from "./agent_sessions.js"; @@ -38,6 +39,7 @@ export { OrgResource } from "./orgs.js"; export { PrivateServiceDefinitionResource } from "./private_service_definitions.js"; export { PrivateServiceEnrollmentResource } from "./private_service_enrollments.js"; export { PrivateServiceResource } from "./private_services.js"; +export { RelayResource } from "./relays.js"; export { SandboxResource } from "./sandboxes.js"; export { ScriptResource } from "./scripts.js"; export { SlackChannelBindingResource } from "./slack_channel_bindings.js"; @@ -47,6 +49,7 @@ export { SolutionTagResource } from "./solution_tags.js"; export { SolutionResource } from "./solutions.js"; export { SshKeyResource } from "./ssh_keys.js"; export { StatuResource } from "./status.js"; +export { TaskOwnershipConversionResource } from "./task_ownership_conversions.js"; export { TaskResource } from "./tasks.js"; export { TeamMembershipResource } from "./team_memberships.js"; export { TeamResource } from "./teams.js"; diff --git a/packages/sdk/src/v1/resources/knowledge_sources.ts b/packages/sdk/src/v1/resources/knowledge_sources.ts index 2c979a9..e3ea5cc 100644 --- a/packages/sdk/src/v1/resources/knowledge_sources.ts +++ b/packages/sdk/src/v1/resources/knowledge_sources.ts @@ -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: 1d8e477605f2 +// Content hash: 917b6361c987 import { HttpClient } from "../../runtime/http-client.js"; import type { ContextIngestion, KnowledgeSource, KnowledgeSourceKindListResponse } from "../../types/common.js"; @@ -210,7 +210,7 @@ export class KnowledgeSourceResource { * @param input.recency_days - When set, limits results to documents ingested within the last N days. Omit to search across all documents regardless of age. * @returns Successful response */ - async search(source: string, input: { max_results?: number | undefined; min_similarity?: number | undefined; mode?: string | undefined; query: string; recency_days?: number | undefined }): Promise<{ data: { content?: string | undefined; content_type?: string | undefined; created_at?: string | undefined; id: string; kind: "chunk"; metadata?: Record | undefined; raw_content?: Record | undefined; type?: string | undefined }[] }> { + async search(source: string, input: { max_results?: number | undefined; min_similarity?: number | undefined; mode?: string | undefined; query: string; recency_days?: number | undefined }): Promise<{ data: { content?: string | undefined; content_type?: string | undefined; created_at?: string | undefined; id: string; kind: "chunk"; metadata?: Record | undefined; raw_content?: Record | undefined; structured_data?: string | null | undefined; structured_data_summary?: string | null | undefined; type?: string | undefined }[]; degraded?: boolean | undefined; effective_mode?: "hybrid" | "vector" | "fulltext" | undefined }> { return this.http.request(`/api/v1/knowledge_sources/${source}/search`, { method: "POST", body: input }); } } diff --git a/packages/sdk/src/v1/resources/kv.ts b/packages/sdk/src/v1/resources/kv.ts index 6b71956..fdb09aa 100644 --- a/packages/sdk/src/v1/resources/kv.ts +++ b/packages/sdk/src/v1/resources/kv.ts @@ -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: c73677fe802c +// Content hash: 271b64d3faf3 import { HttpClient } from "../../runtime/http-client.js"; import type { KeyValueStorageEntry, KeyValueStorageEntryPage } from "../../types/common.js"; @@ -19,8 +19,13 @@ export class KvResource { * response across all users within the caller's app. Use `user` to scope results * to a single user, `user_search` to do a substring match on email or full name, * and `key` to filter entries whose key starts with the given prefix. Results are - * ordered by creation time descending. + * ordered by update time descending. Supplying org, team, agent, or system selects + * a single owner's flat list instead. Expired entries are excluded in every mode. * @param params - Query parameters. + * @param params.org - Organization scope for the owner. + * @param params.team - Team owner ID. + * @param params.agent - Agent owner ID. + * @param params.system - Select system ownership within the app or organization. * @param params.page - Page number to retrieve. Applies to developer and server-to-server callers only. Defaults to 1. * @param params.pageSize - Number of entries per page. Applies to developer and server-to-server callers only. Defaults to 25; maximum is 100. * @param params.user - Filter results to entries belonging to this user ID. Applies to developer and server-to-server callers only. @@ -28,8 +33,20 @@ export class KvResource { * @param params.key - Prefix filter on the storage key. Returns only entries whose key starts with this string. Applies to developer and server-to-server callers only. * @returns Key-value storage entries for the current page, with pagination metadata for developer and server-to-server callers. */ - async list(params?: { page?: number; pageSize?: number; user?: string; userSearch?: string; key?: string }): Promise { + async list(params?: { org?: string; team?: string; agent?: string; system?: boolean; page?: number; pageSize?: number; user?: string; userSearch?: string; key?: string }): Promise { const query: Record | undefined> = {}; + if (params?.org !== undefined) { + query["org"] = params?.org; + } + if (params?.team !== undefined) { + query["team"] = params?.team; + } + if (params?.agent !== undefined) { + query["agent"] = params?.agent; + } + if (params?.system !== undefined) { + query["system"] = params?.system; + } if (params?.page !== undefined) { query["page"] = params?.page; } @@ -51,52 +68,77 @@ export class KvResource { /** * Create a key-value storage entry - * Creates a new key-value storage entry for the target user under the given key. - * The key must not already exist for this user; use the upsert endpoint to create - * or overwrite in a single call. - * End-user (user-JWT) callers always write to their own storage. Developer and - * server-to-server callers must supply a `user` param identifying the target user - * within their app's scope. Attempting to write for a user in a different app - * returns 404. + * Creates a key once per owner. An existing key returns HTTP 409 conflict, including expired rows awaiting sweep. + * User-JWT callers use their own storage. Elevated callers select an owner with + * system: true, team, user, or agent (in that priority order). An org alone selects + * system ownership within that organization; all owners must be in the app scope. + * Create and upsert accept a positive ttl_seconds; absent means no expiry. + * Script binding (`kv.create`): the entry is owned by the triggering + * automation's owner; scripts pass no owner params. A duplicate key + * returns a script Err with code "conflict" instead of raising. * @param input - Request body. + * @param input.agent - Agent owner ID. * @param input.key - Storage key for the entry. Must be a non-empty string unique to this user. - * @param input.user - Target user ID. Required when calling as a developer or with a server-to-server key; ignored for end-user callers. + * @param input.org - Organization scope for the owner. + * @param input.system - Select system ownership within the app or organization. + * @param input.team - Team owner ID. + * @param input.ttl_seconds - Positive lifetime in seconds; omitted means no expiry. + * @param input.user - User owner ID. Elevated callers may instead select team, agent, org, or system ownership. * @param input.value - Value to store under `key`. Must be a non-empty string. * @returns The newly created key-value storage entry. */ - async create(input: { key: string; user?: string | undefined; value: string }): Promise { + async create(input: { agent?: string | undefined; key: string; org?: string | undefined; system?: boolean | undefined; team?: string | undefined; ttl_seconds?: number | undefined; user?: string | undefined; value: string }): Promise { return this.http.request(`/api/v1/kv`, { method: "POST", body: input }); } /** * Delete a key-value storage entry - * Permanently deletes the key-value storage entry identified by `key` for the - * target user. Returns 204 No Content on success and 404 if the entry does not - * exist. - * End-user (user-JWT) callers can only delete entries they own. Developer and - * server-to-server callers must supply a `user` param identifying the target user - * within their app's scope. + * Deletes an unexpired entry by owner and key. Returns 204, or 404 when absent. + * User-JWT callers use their own storage. Elevated callers select an owner with + * system: true, team, user, or agent (in that priority order). An org alone selects + * system ownership within that organization; all owners must be in the app scope. + * Create and upsert accept a positive ttl_seconds; absent means no expiry. + * Script binding (`kv.delete`): removes the entry owned by the triggering + * automation's owner; scripts pass no owner params. * @param key - Storage key of the entry to delete. Must be a non-empty string. - * @returns Empty response body. HTTP 204 No Content on success. + * @returns Successful response */ - async delete(key: string): Promise { - await this.http.request(`/api/v1/kv/${key}`, { method: "DELETE" }); + async delete(key: string): Promise<{ deleted: boolean; key: string }> { + return this.http.request(`/api/v1/kv/${key}`, { method: "DELETE" }); } /** * Retrieve a key-value storage entry - * Returns the key-value storage entry identified by `key` for the target user. - * Returns 404 if no entry exists for that key. - * End-user (user-JWT) callers retrieve entries from their own storage. Developer - * and server-to-server callers must supply a `user` param identifying the target - * user within their app's scope. + * Returns an unexpired entry by owner and key, or 404. + * User-JWT callers use their own storage. Elevated callers select an owner with + * system: true, team, user, or agent (in that priority order). An org alone selects + * system ownership within that organization; all owners must be in the app scope. + * Create and upsert accept a positive ttl_seconds; absent means no expiry. + * Script binding (`kv.get`): reads the entry owned by the triggering + * automation's owner; scripts pass no owner params. * @param key - Storage key of the entry to retrieve. Must be a non-empty string. * @param params - Query parameters. - * @param params.user - Target user ID. Required when calling as a developer or with a server-to-server key; ignored for end-user callers. + * @param params.org - Organization scope for the owner. + * @param params.team - Team owner ID. + * @param params.agent - Agent owner ID. + * @param params.system - Select system ownership within the app or organization. + * @param params.user - User owner ID. Elevated callers may instead select team, agent, org, or system ownership. * @returns The key-value storage entry for the given key. */ - async get(key: string, params?: { user?: string }): Promise { + async get(key: string, params?: { org?: string; team?: string; agent?: string; system?: boolean; user?: string }): Promise { const query: Record | undefined> = {}; + if (params?.org !== undefined) { + query["org"] = params?.org; + } + if (params?.team !== undefined) { + query["team"] = params?.team; + } + if (params?.agent !== undefined) { + query["agent"] = params?.agent; + } + if (params?.system !== undefined) { + query["system"] = params?.system; + } if (params?.user !== undefined) { query["user"] = params?.user; } @@ -106,20 +148,25 @@ export class KvResource { /** * Create or update a key-value storage entry - * Creates a new key-value storage entry for the given `key`, or overwrites the - * value if an entry already exists. This is the idempotent alternative to the - * create endpoint: safe to call regardless of whether the key already exists. - * End-user (user-JWT) callers always write to their own storage. Developer and - * server-to-server callers must supply a `user` param identifying the target user - * within their app's scope. Attempting to write for a user in a different app - * returns 404. + * Creates or replaces a value and its expiry. Omitted ttl_seconds clears any previous expiry. + * User-JWT callers use their own storage. Elevated callers select an owner with + * system: true, team, user, or agent (in that priority order). An org alone selects + * system ownership within that organization; all owners must be in the app scope. + * Create and upsert accept a positive ttl_seconds; absent means no expiry. + * Script binding (`kv.upsert`): overwrites the entry owned by the triggering + * automation's owner; scripts pass no owner params. * @param key - Storage key to create or overwrite. Must be a non-empty string. * @param input - Request body. - * @param input.user - Target user ID. Required when calling as a developer or with a server-to-server key; ignored for end-user callers. + * @param input.agent - Agent owner ID. + * @param input.org - Organization scope for the owner. + * @param input.system - Select system ownership within the app or organization. + * @param input.team - Team owner ID. + * @param input.ttl_seconds - Positive lifetime in seconds; omitted means no expiry. + * @param input.user - User owner ID. Elevated callers may instead select team, agent, org, or system ownership. * @param input.value - New value to store under `key`. Must be a non-empty string. Replaces any existing value. * @returns The created or updated key-value storage entry. */ - async upsert(key: string, input: { user?: string | undefined; value: string }): Promise { + async upsert(key: string, input: { agent?: string | undefined; org?: string | undefined; system?: boolean | undefined; team?: string | undefined; ttl_seconds?: number | undefined; user?: string | undefined; value: string }): Promise { return this.http.request(`/api/v1/kv/${key}`, { method: "PUT", body: input }); } } diff --git a/packages/sdk/src/v1/resources/notifications.ts b/packages/sdk/src/v1/resources/notifications.ts index 958e211..866febe 100644 --- a/packages/sdk/src/v1/resources/notifications.ts +++ b/packages/sdk/src/v1/resources/notifications.ts @@ -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: 20a294b0a2cf +// Content hash: 4059b479e7c9 import { HttpClient } from "../../runtime/http-client.js"; import type { Notification } from "../../types/notifications.js"; @@ -65,6 +65,16 @@ export class NotificationResource { * 403. The app scope is stamped onto the notification automatically; an app * cannot target recipients outside its tenant. Built-in platform types such as * `"app_info"` and `"billing_alert"` are not accepted here. + * The `notifications.send` script binding also accepts the viewer a script runs + * as: a user, an agent, or a team's system viewer. Such a sender may notify only + * a user it can see in its own organization and sandbox. When the sender is a + * user, the recipient must also be able to see the sender. An agent cannot see + * user records, so an agent sender must name a source message: it may then + * notify a user in its own organization and sandbox who can read that message. + * Pass `thread` and `message` together to name the message the notification is + * about. The send is then refused unless that message is in that thread and both + * the sender and the recipient can read it, so a notification cannot quote a + * message its recipient cannot open. * Pass `idempotency_key` to deduplicate sends. If you call this endpoint twice * with the same `idempotency_key` for the same recipient, the second call * returns the original notification without creating a duplicate. The key is @@ -73,11 +83,13 @@ export class NotificationResource { * @param input - Request body. * @param input.data - Arbitrary key-value payload merged with platform-provided context (recipient, app, org, brand) when rendering the notification's display fields. Defaults to an empty object when omitted. * @param input.idempotency_key - Optional deduplication key. A second call with the same `idempotency_key` for the same recipient returns the originally-created notification without inserting a new record. Scoped per calling app. + * @param input.message - Source message (`msg_...`) that the sender and the recipient must both be able to read. + * @param input.thread - Thread (`thr_...`) of the source message. Requires `message`. * @param input.type - Custom notification type identifier in the form `"custom:"`, where `` matches a `NotificationType` config declared in the calling app's bundle. * @param input.user - Recipient user ID (`usr_...`). Must be a member of the calling app's tenant. * @returns The created notification, or the existing notification when deduplicated by `idempotency_key`. */ - async send(input: { data?: Record | undefined; idempotency_key?: string | undefined; type: string; user: string }): Promise { + async send(input: { data?: Record | undefined; idempotency_key?: string | undefined; message?: string | undefined; thread?: string | undefined; type: string; user: string }): Promise { return this.http.request(`/api/v1/notifications/send`, { method: "POST", body: input }); } diff --git a/packages/sdk/src/v1/resources/oauth.ts b/packages/sdk/src/v1/resources/oauth.ts index eebc86f..78e545e 100644 --- a/packages/sdk/src/v1/resources/oauth.ts +++ b/packages/sdk/src/v1/resources/oauth.ts @@ -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: 7edd64bbf9cc +// Content hash: 31d084134ed0 import { HttpClient } from "../../runtime/http-client.js"; import type { DeviceAuthorizationDetailsResponse, DeviceAuthorizationResponse, DeviceAuthorizationStatusResponse } from "../../types/device.js"; @@ -127,9 +127,10 @@ export class OauthResource { * @param input.grant_type - The OAuth 2.0 grant type. One of `"authorization_code"`, `"refresh_token"`, or `"urn:ietf:params:oauth:grant-type:device_code"`. * @param input.redirect_uri - Redirect URI that was used in the original authorization request. Must exactly match the URI on record for the client. Required for `"authorization_code"` grants. * @param input.refresh_token - Refresh token received from a previous token response. Required for `"refresh_token"` grants. The token is rotated on each successful call. + * @param input.resource - Resource audience. Required for code exchange and refresh of a token bound to a resource server; must match the consent grant. * @returns Token pair issued for the authenticated user. */ - async token(input: { client?: string | undefined; code?: string | undefined; code_verifier?: string | undefined; device_code?: string | undefined; grant_type: string; redirect_uri?: string | undefined; refresh_token?: string | undefined }): Promise { + async token(input: { client?: string | undefined; code?: string | undefined; code_verifier?: string | undefined; device_code?: string | undefined; grant_type: string; redirect_uri?: string | undefined; refresh_token?: string | undefined; resource?: string | undefined }): Promise { return this.http.request(`/oauth/token`, { method: "POST", body: input }); } } diff --git a/packages/sdk/src/v1/resources/orgs.ts b/packages/sdk/src/v1/resources/orgs.ts index 776789c..a77c94e 100644 --- a/packages/sdk/src/v1/resources/orgs.ts +++ b/packages/sdk/src/v1/resources/orgs.ts @@ -1,10 +1,329 @@ // Copyright (c) 2026 ArchAstro Inc. Licensed under the MIT License. // This file is auto-generated by @archastro/sdk-generator. Do not edit. -// Content hash: 794b80fb564b +// Content hash: 367c947ef3ac import { HttpClient } from "../../runtime/http-client.js"; +import type { Task, TaskEnsureResult } from "../../types/tasks.js"; import type { Thread } from "../../types/threads.js"; +export class OrgTaskResource { + constructor(private http: HttpClient) {} + + /** + * List an organization's tasks + * Returns org-owned tasks for the specified organization: rows with the org + * tenant and no narrower user/team/agent scope. Explicitly personal, team, or + * agent tasks are excluded here; list those via the user/team collections or + * fetch them directly when authorized. + * Every organization member may list. App-scoped developer and + * server-to-server callers supply the org in the route. + * @param org - Organization ID (`org_...`) whose org-owned tasks should be returned. + * @param params - Query parameters. + * @param params.status - Filter tasks by status. One of `"open"`, `"in_progress"`, `"in_review"`, or `"done"`. Omit to return tasks in all statuses. + * @param params.ownerUser - Filter tasks assigned to a specific user. Provide the user's public ID (`usr_...`). + * @param params.ownerAgent - Filter tasks assigned to a specific agent. Provide the agent's public ID (`agi_...`). + * @param params.priority - Filter tasks by priority, from 0 (highest) to 4 (lowest). + * @param params.tag - Return only tasks carrying this tag (matched against the canonical lowercase form). + * @param params.parent - Return only subtasks of the given task (`tsk_...`), or pass `none` to return only top-level tasks. + * @param params.sourceScope - Return only tasks whose source matches this container. Must be supplied with `source_type` and `source_id`. + * @param params.sourceType - Return only tasks whose source matches this object kind. Must be supplied with the other source filters. + * @param params.sourceId - Return only tasks whose source matches this object identity. Must be supplied with the other source filters. + * @param params.epic - Return only tasks with this exact epic label. + * @param params.search - Restrict results to tasks whose name or description contains this string. + * @param params.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. + * @param params.order - Sort direction, `"asc"` or `"desc"`. Defaults to `"desc"` for `created` and `"asc"` for `due_date` and `priority`. + * @param params.dueBefore - 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. + * @param params.dueAfter - Return only tasks with a due date strictly after this ISO 8601 datetime or date. Tasks without a due date are excluded. + * @param params.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. + * @param params.ready - When true, return only open tasks with no unfinished blockers and no active session lease. This is a projection snapshot; claim a lease before starting work. + * @param params.attention - When true, return paused, failed, or in-progress tasks with no lease or a past lease expiry. + * @param params.limit - Maximum number of tasks to return. Capped at 100. + * @param params.afterCursor - Opaque cursor returned by the previous page. + * @returns Successful response + */ + async list(org: string, params?: { status?: string; ownerUser?: string; ownerAgent?: string; priority?: number; tag?: string; parent?: string; sourceScope?: string; sourceType?: string; sourceId?: string; epic?: string; search?: string; sort?: string; order?: string; dueBefore?: string; dueAfter?: string; overdue?: boolean; ready?: boolean; attention?: boolean; limit?: number; afterCursor?: string }): Promise<{ after_cursor?: string | null | undefined; before_cursor?: string | null | undefined; data: { agent?: string | null | undefined; aggregate_version?: number | null | undefined; blocked_by_count?: number | undefined; closed_at?: string | null | undefined; comments_count?: number | undefined; created_at?: string | undefined; created_by_actor?: { alias?: string | null | undefined; id?: string | null | undefined; name?: string | null | undefined; profile_picture?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined } | null | undefined; created_by_agent?: string | null | undefined; created_by_user?: string | null | undefined; current_lease?: { expires_at: string; harness: string; session_name: string } | null | undefined; description?: string | null | undefined; due_date?: string | null | undefined; epic?: string | null | undefined; id: string; is_blocked?: boolean | undefined; is_stalled?: boolean | undefined; links?: Record | undefined; metadata?: Record | undefined; name: string; org?: string | null | undefined; owner_actor?: { alias?: string | null | undefined; id?: string | null | undefined; name?: string | null | undefined; profile_picture?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined } | null | undefined; owner_agent?: string | null | undefined; owner_user?: string | null | undefined; parent?: string | null | undefined; priority?: number | undefined; project_id?: string | null | undefined; sandbox?: string | null | undefined; source_id?: string | null | undefined; source_scope?: string | null | undefined; source_type?: string | null | undefined; stalled_since?: string | null | undefined; status: string; subtasks_count?: number | undefined; tags?: string[] | undefined; target_binary?: string | null | undefined; target_version?: string | null | undefined; team?: string | null | undefined; thread?: string | null | undefined; updated_at?: string | undefined; user?: string | null | undefined }[]; has_more: boolean }> { + const query: Record | undefined> = {}; + if (params?.status !== undefined) { + query["status"] = params?.status; + } + if (params?.ownerUser !== undefined) { + query["owner_user"] = params?.ownerUser; + } + if (params?.ownerAgent !== undefined) { + query["owner_agent"] = params?.ownerAgent; + } + if (params?.priority !== undefined) { + query["priority"] = params?.priority; + } + if (params?.tag !== undefined) { + query["tag"] = params?.tag; + } + if (params?.parent !== undefined) { + query["parent"] = params?.parent; + } + if (params?.sourceScope !== undefined) { + query["source_scope"] = params?.sourceScope; + } + if (params?.sourceType !== undefined) { + query["source_type"] = params?.sourceType; + } + if (params?.sourceId !== undefined) { + query["source_id"] = params?.sourceId; + } + if (params?.epic !== undefined) { + query["epic"] = params?.epic; + } + if (params?.search !== undefined) { + query["search"] = params?.search; + } + if (params?.sort !== undefined) { + query["sort"] = params?.sort; + } + if (params?.order !== undefined) { + query["order"] = params?.order; + } + if (params?.dueBefore !== undefined) { + query["due_before"] = params?.dueBefore; + } + if (params?.dueAfter !== undefined) { + query["due_after"] = params?.dueAfter; + } + if (params?.overdue !== undefined) { + query["overdue"] = params?.overdue; + } + if (params?.ready !== undefined) { + query["ready"] = params?.ready; + } + if (params?.attention !== undefined) { + query["attention"] = params?.attention; + } + if (params?.limit !== undefined) { + query["limit"] = params?.limit; + } + if (params?.afterCursor !== undefined) { + query["after_cursor"] = params?.afterCursor; + } + + return this.http.request(`/api/v1/orgs/${org}/tasks`, { query }); + } + + /** + * Create a task for an organization + * Creates a new org-owned task (org tenant, no narrower user/team/agent + * scope) and returns the full task object. User-authenticated calls are + * attributed to the authenticated user or agent. App-scoped developer and + * server-to-server callers must provide an explicit `user` or `agent` actor + * for the organization. Every referenced principal is validated against the + * app and organization before creation. + * @param org - Organization ID (`org_...`) whose org-owned tasks should be returned. + * @param input - Request body. + * @param input.agent - Explicit acting agent (`agi_...`) for a developer or server-to-server call. Mutually exclusive with an acting `user`; the agent must belong to the organization. + * @param input.task - Attributes for the task to create. `name` is required; all other fields are optional. + * @param input.user - Explicit acting user (`usr_...`) for a developer or server-to-server call. Mutually exclusive with an acting `agent`. + * @returns The newly created task. + */ + async create(org: string, input: { agent?: string | undefined; task: { description?: string | undefined; due_date?: string | undefined; epic?: string | undefined; id?: string | undefined; links?: Record | undefined; metadata?: Record | undefined; name: string; owner_agent?: string | undefined; owner_user?: string | undefined; parent?: string | undefined; priority?: number | undefined; project_id?: string | undefined; source_id?: string | undefined; source_scope?: string | undefined; source_type?: string | undefined; status?: string | undefined; tags?: string[] | undefined; target_binary?: string | undefined; target_version?: string | undefined; thread?: string | undefined }; user?: string | undefined }): Promise { + return this.http.request(`/api/v1/orgs/${org}/tasks`, { method: "POST", body: input }); + } + + /** + * List task blocker cycles for an organization + * Runs an on-demand diagnostic over unfinished org-owned tasks for the + * specified organization and returns a forward cursor-paginated page of + * complete cyclic blocker components. Detection is bounded to owners with at + * most 100 unfinished tasks. This endpoint is read-only: cycles do not prevent + * task updates, lease acquisition, or completion. + * @param org - Organization ID (`org_...`) whose org-owned tasks should be returned. + * @param params - Query parameters. + * @param params.limit - Maximum cycle components to return. Defaults to 50; maximum is 100. + * @param params.afterCursor - Opaque cursor returned by the preceding page. + * @returns Successful response + */ + async blockerCycles(org: string, params?: { limit?: number; afterCursor?: string }): Promise<{ after_cursor?: string | undefined; before_cursor?: string | undefined; data: { tasks: { agent?: string | null | undefined; aggregate_version?: number | null | undefined; blocked_by_count?: number | undefined; closed_at?: string | null | undefined; comments_count?: number | undefined; created_at?: string | undefined; created_by_actor?: { alias?: string | null | undefined; id?: string | null | undefined; name?: string | null | undefined; profile_picture?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined } | null | undefined; created_by_agent?: string | null | undefined; created_by_user?: string | null | undefined; current_lease?: { expires_at: string; harness: string; session_name: string } | null | undefined; description?: string | null | undefined; due_date?: string | null | undefined; epic?: string | null | undefined; id: string; is_blocked?: boolean | undefined; is_stalled?: boolean | undefined; links?: Record | undefined; metadata?: Record | undefined; name: string; org?: string | null | undefined; owner_actor?: { alias?: string | null | undefined; id?: string | null | undefined; name?: string | null | undefined; profile_picture?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined } | null | undefined; owner_agent?: string | null | undefined; owner_user?: string | null | undefined; parent?: string | null | undefined; priority?: number | undefined; project_id?: string | null | undefined; sandbox?: string | null | undefined; source_id?: string | null | undefined; source_scope?: string | null | undefined; source_type?: string | null | undefined; stalled_since?: string | null | undefined; status: string; subtasks_count?: number | undefined; tags?: string[] | undefined; target_binary?: string | null | undefined; target_version?: string | null | undefined; team?: string | null | undefined; thread?: string | null | undefined; updated_at?: string | undefined; user?: string | null | undefined }[] }[]; has_more: boolean }> { + const query: Record | undefined> = {}; + if (params?.limit !== undefined) { + query["limit"] = params?.limit; + } + if (params?.afterCursor !== undefined) { + query["after_cursor"] = params?.afterCursor; + } + + return this.http.request(`/api/v1/orgs/${org}/tasks/blocker_cycles`, { query }); + } + + /** + * Find or create a task by source + * 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. + * @param org - Organization ID (`org_...`) whose org-owned tasks should be returned. + * @param input - Request body. + * @param input.agent - Explicit acting agent for privileged callers. + * @param input.description - Initial task description. + * @param input.epic - Initial epic grouping. + * @param input.name - Initial task name. + * @param input.source_id - Source identity, for example owner/repo#123. + * @param input.source_scope - Source scope, for example github. + * @param input.source_type - Source type, for example pull_request. + * @param input.status - Initial task status. + * @param input.team - Team owner. + * @param input.user - User owner, or explicit acting user on a team route. + * @returns The task and whether this request created it. + */ + async bySource(org: string, input: { agent?: string | undefined; description?: string | undefined; epic?: string | undefined; name: string; source_id: string; source_scope: string; source_type: string; status?: string | undefined; team?: string | undefined; user?: string | undefined }): Promise { + return this.http.request(`/api/v1/orgs/${org}/tasks/by-source`, { method: "PUT", body: input }); + } + + /** + * Get task activity metrics for an organization + * Returns task activity metrics scoped to org-owned tasks (org tenant, no + * narrower user/team/agent scope). `open` counts currently open or + * in-progress org tasks, `created` counts tasks inserted in the UTC-day + * window, and `completed` counts tasks whose `closed_at` falls in that window + * while still in a closed status. Hard-deleted tasks are absent from the + * projection and therefore omitted. The daily series is zero-filled across + * the requested window and includes reconstructed end-of-day `open` stock. + * Any organization member may read this count-only summary. Requests from + * callers without org access return 404 so organization existence is not + * disclosed. + * @param org - Organization ID (`org_...`) whose org-owned tasks should be returned. + * @param params - Query parameters. + * @param params.days - UTC-day window. One of 7, 30, 90, or 365; defaults to 30. + * @returns Successful response + */ + async metrics(org: string, params?: { days?: number }): Promise<{ completed: number; created: number; days: number; end_at: string; open: number; series: Record[]; start_at: string }> { + const query: Record | undefined> = {}; + if (params?.days !== undefined) { + query["days"] = params?.days; + } + + return this.http.request(`/api/v1/orgs/${org}/tasks/metrics`, { query }); + } + + /** + * List an organization's ready tasks + * Returns open org-owned tasks with no unfinished blockers and no active + * session lease. Readiness is calculated by the server from the current task + * projection. It is a snapshot, not a reservation; claim a task lease before + * starting work. + * Results are ordered by priority (0, the most urgent, first), then oldest + * first, so the first page is always the most urgent ready work. + * Pass `explain=true` to include every open task with a stable readiness reason. + * @param org - Organization ID (`org_...`) whose org-owned tasks should be returned. + * @param params - Query parameters. + * @param params.explain - Include blocked and actively leased open tasks with exclusion reasons. + * @param params.assignedToMe - Only include tasks assigned to the authenticated user. + * @param params.sourceScope - Only include tasks whose source matches this container. Must be supplied with `source_type` and `source_id`. + * @param params.sourceType - Only include tasks whose source matches this object kind. + * @param params.sourceId - Only include tasks whose source matches this object identity. + * @param params.epic - Only include tasks with this exact epic label. + * @param params.limit - Maximum number of readiness entries to return. Capped at 100. + * @param params.afterCursor - Opaque cursor returned by the previous page. + * @returns Successful response + */ + async ready(org: string, params?: { explain?: boolean; assignedToMe?: boolean; sourceScope?: string; sourceType?: string; sourceId?: string; epic?: string; limit?: number; afterCursor?: string }): Promise<{ after_cursor?: string | undefined; authoritative: boolean; before_cursor?: string | undefined; data: { readiness: "ready" | "blocked" | "leased"; reason?: "open_blockers" | "active_lease" | null | undefined; task: { agent?: string | null | undefined; aggregate_version?: number | null | undefined; blocked_by_count?: number | undefined; closed_at?: string | null | undefined; comments_count?: number | undefined; created_at?: string | undefined; created_by_actor?: { alias?: string | null | undefined; id?: string | null | undefined; name?: string | null | undefined; profile_picture?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined } | null | undefined; created_by_agent?: string | null | undefined; created_by_user?: string | null | undefined; current_lease?: { expires_at: string; harness: string; session_name: string } | null | undefined; description?: string | null | undefined; due_date?: string | null | undefined; epic?: string | null | undefined; id: string; is_blocked?: boolean | undefined; is_stalled?: boolean | undefined; links?: Record | undefined; metadata?: Record | undefined; name: string; org?: string | null | undefined; owner_actor?: { alias?: string | null | undefined; id?: string | null | undefined; name?: string | null | undefined; profile_picture?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined } | null | undefined; owner_agent?: string | null | undefined; owner_user?: string | null | undefined; parent?: string | null | undefined; priority?: number | undefined; project_id?: string | null | undefined; sandbox?: string | null | undefined; source_id?: string | null | undefined; source_scope?: string | null | undefined; source_type?: string | null | undefined; stalled_since?: string | null | undefined; status: string; subtasks_count?: number | undefined; tags?: string[] | undefined; target_binary?: string | null | undefined; target_version?: string | null | undefined; team?: string | null | undefined; thread?: string | null | undefined; updated_at?: string | undefined; user?: string | null | undefined } }[]; has_more: boolean }> { + const query: Record | undefined> = {}; + if (params?.explain !== undefined) { + query["explain"] = params?.explain; + } + if (params?.assignedToMe !== undefined) { + query["assigned_to_me"] = params?.assignedToMe; + } + if (params?.sourceScope !== undefined) { + query["source_scope"] = params?.sourceScope; + } + if (params?.sourceType !== undefined) { + query["source_type"] = params?.sourceType; + } + if (params?.sourceId !== undefined) { + query["source_id"] = params?.sourceId; + } + if (params?.epic !== undefined) { + query["epic"] = params?.epic; + } + if (params?.limit !== undefined) { + query["limit"] = params?.limit; + } + if (params?.afterCursor !== undefined) { + query["after_cursor"] = params?.afterCursor; + } + + return this.http.request(`/api/v1/orgs/${org}/tasks/ready`, { query }); + } + + /** + * Search an organization's tasks + * Performs a full-text search over org-owned tasks for the specified + * organization and returns matching results. Combine `q` with the optional + * filters to narrow the result set further. When no query is provided, the + * endpoint behaves like a filtered list. + * The `query` field in the response echoes the effective search query. + * Explicitly personal, team, or agent tasks are excluded here. + * @param org - Organization ID (`org_...`) whose org-owned tasks should be returned. + * @param params - Query parameters. + * @param params.q - Full-text search query matched against task names and descriptions. Takes precedence over `query` when both are provided. + * @param params.query - Alias for `q`. Use `q` when possible; this parameter exists for compatibility. + * @param params.status - Filter results by status. One of `"open"`, `"in_progress"`, `"in_review"`, or `"done"`. Omit to include all statuses. + * @param params.ownerUser - Filter tasks assigned to a specific user. Provide the user's public ID (`usr_...`). + * @param params.ownerAgent - Filter tasks assigned to a specific agent. Provide the agent's public ID (`agi_...`). + * @param params.priority - Filter tasks by priority, from 0 (highest) to 4 (lowest). + * @param params.tag - Return only tasks carrying this tag (matched against the canonical lowercase form). + * @param params.parent - Return only subtasks of the given task (`tsk_...`), or pass `none` to return only top-level tasks. + * @param params.sourceScope - Return only tasks whose source matches this container. Must be supplied with `source_type` and `source_id`. + * @param params.sourceType - Return only tasks whose source matches this object kind. Must be supplied with the other source filters. + * @param params.sourceId - Return only tasks whose source matches this object identity. Must be supplied with the other source filters. + * @param params.epic - Return only tasks with this exact epic label. + * @param params.limit - Maximum number of tasks to return. Capped at 100. + * @param params.afterCursor - Opaque cursor returned by the previous page. + * @returns Successful response + */ + async search(org: string, params?: { q?: string; query?: string; status?: string; ownerUser?: string; ownerAgent?: string; priority?: number; tag?: string; parent?: string; sourceScope?: string; sourceType?: string; sourceId?: string; epic?: string; limit?: number; afterCursor?: string }): Promise<{ after_cursor?: string | undefined; before_cursor?: string | undefined; data: { agent?: string | null | undefined; aggregate_version?: number | null | undefined; blocked_by_count?: number | undefined; closed_at?: string | null | undefined; comments_count?: number | undefined; created_at?: string | undefined; created_by_actor?: { alias?: string | null | undefined; id?: string | null | undefined; name?: string | null | undefined; profile_picture?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined } | null | undefined; created_by_agent?: string | null | undefined; created_by_user?: string | null | undefined; current_lease?: { expires_at: string; harness: string; session_name: string } | null | undefined; description?: string | null | undefined; due_date?: string | null | undefined; epic?: string | null | undefined; id: string; is_blocked?: boolean | undefined; is_stalled?: boolean | undefined; links?: Record | undefined; metadata?: Record | undefined; name: string; org?: string | null | undefined; owner_actor?: { alias?: string | null | undefined; id?: string | null | undefined; name?: string | null | undefined; profile_picture?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined } | null | undefined; owner_agent?: string | null | undefined; owner_user?: string | null | undefined; parent?: string | null | undefined; priority?: number | undefined; project_id?: string | null | undefined; sandbox?: string | null | undefined; source_id?: string | null | undefined; source_scope?: string | null | undefined; source_type?: string | null | undefined; stalled_since?: string | null | undefined; status: string; subtasks_count?: number | undefined; tags?: string[] | undefined; target_binary?: string | null | undefined; target_version?: string | null | undefined; team?: string | null | undefined; thread?: string | null | undefined; updated_at?: string | undefined; user?: string | null | undefined }[]; has_more: boolean; query: string }> { + const query: Record | undefined> = {}; + if (params?.q !== undefined) { + query["q"] = params?.q; + } + if (params?.query !== undefined) { + query["query"] = params?.query; + } + if (params?.status !== undefined) { + query["status"] = params?.status; + } + if (params?.ownerUser !== undefined) { + query["owner_user"] = params?.ownerUser; + } + if (params?.ownerAgent !== undefined) { + query["owner_agent"] = params?.ownerAgent; + } + if (params?.priority !== undefined) { + query["priority"] = params?.priority; + } + if (params?.tag !== undefined) { + query["tag"] = params?.tag; + } + if (params?.parent !== undefined) { + query["parent"] = params?.parent; + } + if (params?.sourceScope !== undefined) { + query["source_scope"] = params?.sourceScope; + } + if (params?.sourceType !== undefined) { + query["source_type"] = params?.sourceType; + } + if (params?.sourceId !== undefined) { + query["source_id"] = params?.sourceId; + } + if (params?.epic !== undefined) { + query["epic"] = params?.epic; + } + if (params?.limit !== undefined) { + query["limit"] = params?.limit; + } + if (params?.afterCursor !== undefined) { + query["after_cursor"] = params?.afterCursor; + } + + return this.http.request(`/api/v1/orgs/${org}/tasks/search`, { query }); + } +} + export class OrgThreadResource { constructor(private http: HttpClient) {} @@ -15,10 +334,10 @@ export class OrgThreadResource { * App-scoped developer tokens for the organization's app can list them too. * @param org - Organization ID (`org_...`) whose org-visibility threads should be listed. * @param params - Query parameters. - * @param params.key - Optional exact thread key, for example `archdev-room`. + * @param params.key - Optional exact thread key, for example `support-room`. * @returns Successful response */ - async list(org: string, params?: { key?: string }): Promise<{ data: { agent_user?: string | null | undefined; created_at?: string | undefined; creator?: string | { alias?: string | null | undefined; app?: string | null | undefined; app_name?: string | null | undefined; created_by_agent_user?: string | null | undefined; created_by_developer?: string | null | undefined; created_by_org?: string | null | undefined; created_by_team?: string | null | undefined; created_by_user?: string | null | undefined; email?: string | null | undefined; id: string; is_system_user?: boolean | undefined; metadata?: Record | undefined; name?: string | null | undefined; org?: string | null | undefined; org_name?: string | null | undefined; org_role?: string | null | undefined; org_slug?: string | null | undefined; sandbox?: string | null | undefined; sandbox_name?: string | null | undefined } | null | undefined; description?: string | null | undefined; id: string; is_channel?: boolean | undefined; is_default?: boolean | undefined; is_transient?: boolean | undefined; is_unlisted?: boolean | undefined; key?: string | null | undefined; kind?: string | null | undefined; last_activity?: string | null | undefined; last_message_preview?: string | null | undefined; last_message_sender?: string | null | undefined; metadata?: Record | null | undefined; muted?: boolean | undefined; org?: string | null | undefined; parent_message?: { acl?: { add?: { actions: string[]; principal?: string | undefined; principal_type: string }[] | undefined; grants?: { actions: string[]; principal?: string | undefined; principal_type: string }[] | undefined; remove?: { principal?: string | undefined; principal_type: string }[] | undefined } | null | undefined; actors?: { alias?: string | null | undefined; id?: string | null | undefined; name?: string | null | undefined; profile_picture?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined }[] | undefined; agent?: string | null | undefined; agent_mode?: "cli" | "embedded" | null | undefined; attachments?: { content_type?: string | null | undefined; description?: string | null | undefined; filename?: string | null | undefined; height?: number | null | undefined; id: string; image_height?: number | null | undefined; image_source?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined; image_url?: string | null | undefined; image_width?: number | null | undefined; key?: string | null | undefined; media_type?: string | undefined; name?: string | null | undefined; object?: Record | undefined; title?: string | null | undefined; type: string; url?: string | null | undefined; variants?: { content_type?: string | null | undefined; created_at?: string | undefined; file?: string | undefined; filename?: string | null | undefined; height?: number | null | undefined; id: string; image_source?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined; updated_at?: string | undefined; url?: string | null | undefined; variant_key?: string | undefined; width?: number | null | undefined }[] | undefined; version?: number | null | undefined; width?: number | null | undefined }[] | undefined; branched_thread?: string | null | undefined; content?: string | null | undefined; context?: { attributes?: Record | undefined; content?: string | null | undefined; title?: string | null | undefined; type: string }[] | undefined; created_at?: string | undefined; has_replies?: boolean | undefined; id: string; idempotency_key?: string | null | undefined; is_deleted?: boolean | undefined; legacy_agent?: string | null | undefined; metadata?: Record | undefined; org?: string | null | undefined; reactions?: { payload?: Record | undefined; type: string; user?: string | undefined }[] | undefined; rendering_mode?: string | null | undefined; replies?: Record[] | undefined; replies_after_cursor?: string | null | undefined; replies_before_cursor?: string | null | undefined; reply_count?: number | undefined; reply_to?: Record | null | undefined; root_message_id?: string | null | undefined; sandbox?: string | null | undefined; team?: string | null | undefined; thread?: string | undefined; type?: string | null | undefined; user?: string | { alias?: string | null | undefined; app?: string | null | undefined; app_name?: string | null | undefined; created_by_agent_user?: string | null | undefined; created_by_developer?: string | null | undefined; created_by_org?: string | null | undefined; created_by_team?: string | null | undefined; created_by_user?: string | null | undefined; email?: string | null | undefined; id: string; is_system_user?: boolean | undefined; metadata?: Record | undefined; name?: string | null | undefined; org?: string | null | undefined; org_name?: string | null | undefined; org_role?: string | null | undefined; org_slug?: string | null | undefined; sandbox?: string | null | undefined; sandbox_name?: string | null | undefined } | null | undefined; visibility?: "default" | "private" | undefined } | null | undefined; participant?: string[] | undefined; participants?: { alias?: string | null | undefined; app?: string | null | undefined; app_name?: string | null | undefined; created_by_agent_user?: string | null | undefined; created_by_developer?: string | null | undefined; created_by_org?: string | null | undefined; created_by_team?: string | null | undefined; created_by_user?: string | null | undefined; email?: string | null | undefined; id: string; is_system_user?: boolean | undefined; metadata?: Record | undefined; name?: string | null | undefined; org?: string | null | undefined; org_name?: string | null | undefined; org_role?: string | null | undefined; org_slug?: string | null | undefined; sandbox?: string | null | undefined; sandbox_name?: string | null | undefined }[] | undefined; participating_actor?: string[] | undefined; participating_agents?: { acl?: { add?: { actions: string[]; principal?: string | undefined; principal_type: string }[] | undefined; grants?: { actions: string[]; principal?: string | undefined; principal_type: string }[] | undefined; remove?: { principal?: string | undefined; principal_type: string }[] | undefined } | null | undefined; app?: string | undefined; created_at?: string | undefined; default_model?: string | null | undefined; description?: string | null | undefined; email?: string | null | undefined; id: string; identity?: string | null | undefined; last_applied_template_config?: string | null | undefined; lookup_key?: string | null | undefined; metadata?: Record | undefined; name?: string | undefined; org?: string | null | undefined; org_name?: string | null | undefined; originator?: string | null | undefined; phone_number?: string | null | undefined; sandbox?: string | null | undefined; source_solution?: { current_solution?: { category_keys?: string[] | undefined; created_at?: string | undefined; description?: string | null | undefined; events?: Record | undefined; id: string; image_url?: string | null | undefined; installed_config_ids: string[]; kind: string; latest_solution?: string | null | undefined; latest_version?: string | null | undefined; lookup_key?: string | null | undefined; metadata?: Record | undefined; name?: string | null | undefined; org?: string | null | undefined; org_logo?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined; org_name?: string | null | undefined; org_slug?: string | null | undefined; owners: string[]; readme_url?: string | null | undefined; screenshot_urls?: string[] | undefined; solution_id?: string | null | undefined; solution_version?: string | null | undefined; tag_keys?: string[] | undefined; template_kind?: string | null | undefined; templates: { description?: string | null | undefined; details?: { automation_type?: string | null | undefined; invoke_contract?: { input_schema?: Record | null | undefined; participants?: { description?: string | null | undefined; name: string; required: boolean; type: string }[] | null | undefined; prefills: { participants?: Record | undefined; payload?: Record | undefined } } | null | undefined; type: "automation" } | null | undefined; display_name?: string | null | undefined; id?: string | null | undefined; kind: string; lookup_key?: string | null | undefined; name?: string | null | undefined; readme_url?: string | null | undefined; virtual_path?: string | null | undefined }[]; updated_at?: string | undefined; upgrade_available: boolean; virtual_path?: string | null | undefined } | undefined; solution: { category_keys?: string[] | undefined; created_at?: string | undefined; description?: string | null | undefined; events?: Record | undefined; id: string; image_url?: string | null | undefined; installed_config_ids: string[]; kind: string; latest_solution?: string | null | undefined; latest_version?: string | null | undefined; lookup_key?: string | null | undefined; metadata?: Record | undefined; name?: string | null | undefined; org?: string | null | undefined; org_logo?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined; org_name?: string | null | undefined; org_slug?: string | null | undefined; owners: string[]; readme_url?: string | null | undefined; screenshot_urls?: string[] | undefined; solution_id?: string | null | undefined; solution_version?: string | null | undefined; tag_keys?: string[] | undefined; template_kind?: string | null | undefined; templates: { description?: string | null | undefined; details?: { automation_type?: string | null | undefined; invoke_contract?: { input_schema?: Record | null | undefined; participants?: { description?: string | null | undefined; name: string; required: boolean; type: string }[] | null | undefined; prefills: { participants?: Record | undefined; payload?: Record | undefined } } | null | undefined; type: "automation" } | null | undefined; display_name?: string | null | undefined; id?: string | null | undefined; kind: string; lookup_key?: string | null | undefined; name?: string | null | undefined; readme_url?: string | null | undefined; virtual_path?: string | null | undefined }[]; updated_at?: string | undefined; upgrade_available: boolean; virtual_path?: string | null | undefined }; template: { created_at?: string | undefined; description?: string | null | undefined; display_name?: string | null | undefined; id: string; kind: string; lookup_key?: string | null | undefined; name?: string | null | undefined; updated_at?: string | undefined; virtual_path?: string | null | undefined } } | null | undefined; team?: string | null | undefined; template_upgrade_available?: boolean | null | undefined; updated_at?: string | undefined; user?: string | null | undefined }[] | null | undefined; role?: string | null | undefined; sandbox?: string | null | undefined; settings?: { agent_enabled?: boolean | null | undefined } | undefined; slug?: string | null | undefined; sub_threads?: Record[] | null | undefined; tags?: string[] | undefined; team?: string | null | undefined; title?: string | null | undefined; ttl?: string | null | undefined; unread_count?: number | null | undefined; updated_at?: string | undefined; user?: string | null | undefined; visibility: "team" | "restricted" | "private" | "org" }[] }> { + async list(org: string, params?: { key?: string }): Promise<{ data: { agent_user?: string | null | undefined; created_at?: string | undefined; creator?: string | { alias?: string | null | undefined; app?: string | null | undefined; app_name?: string | null | undefined; created_by_agent_user?: string | null | undefined; created_by_developer?: string | null | undefined; created_by_org?: string | null | undefined; created_by_team?: string | null | undefined; created_by_user?: string | null | undefined; email?: string | null | undefined; id: string; is_system_user?: boolean | undefined; metadata?: Record | undefined; name?: string | null | undefined; org?: string | null | undefined; org_name?: string | null | undefined; org_role?: string | null | undefined; org_slug?: string | null | undefined; sandbox?: string | null | undefined; sandbox_name?: string | null | undefined } | null | undefined; description?: string | null | undefined; id: string; is_channel?: boolean | undefined; is_default?: boolean | undefined; is_transient?: boolean | undefined; is_unlisted?: boolean | undefined; key?: string | null | undefined; kind?: string | null | undefined; last_activity?: string | null | undefined; last_message_preview?: string | null | undefined; last_message_sender?: string | null | undefined; metadata?: Record | null | undefined; muted?: boolean | undefined; org?: string | null | undefined; parent_message?: { acl?: { add?: { actions: string[]; principal?: string | undefined; principal_type: string }[] | undefined; grants?: { actions: string[]; principal?: string | undefined; principal_type: string }[] | undefined; remove?: { principal?: string | undefined; principal_type: string }[] | undefined } | null | undefined; actors?: { alias?: string | null | undefined; id?: string | null | undefined; name?: string | null | undefined; profile_picture?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined }[] | undefined; agent?: string | null | undefined; agent_mode?: "cli" | "embedded" | null | undefined; attachments?: { content_type?: string | null | undefined; description?: string | null | undefined; filename?: string | null | undefined; height?: number | null | undefined; id: string; image_height?: number | null | undefined; image_source?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined; image_url?: string | null | undefined; image_width?: number | null | undefined; key?: string | null | undefined; media_type?: string | undefined; name?: string | null | undefined; object?: Record | undefined; title?: string | null | undefined; type: string; url?: string | null | undefined; variants?: { byte_size?: number | null | undefined; content_type?: string | null | undefined; created_at?: string | undefined; duration_ms?: number | null | undefined; file?: string | undefined; filename?: string | null | undefined; height?: number | null | undefined; id: string; image_source?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined; sha256?: string | null | undefined; updated_at?: string | undefined; url?: string | null | undefined; url_expires_at?: string | null | undefined; variant_key?: string | undefined; width?: number | null | undefined }[] | undefined; version?: number | null | undefined; width?: number | null | undefined }[] | undefined; branched_thread?: string | null | undefined; content?: string | null | undefined; context?: { attributes?: Record | undefined; content?: string | null | undefined; title?: string | null | undefined; type: string }[] | undefined; created_at?: string | undefined; has_replies?: boolean | undefined; id: string; idempotency_key?: string | null | undefined; is_deleted?: boolean | undefined; legacy_agent?: string | null | undefined; metadata?: Record | undefined; org?: string | null | undefined; reactions?: { payload?: Record | undefined; type: string; user?: string | undefined }[] | undefined; rendering_mode?: string | null | undefined; replies?: Record[] | undefined; replies_after_cursor?: string | null | undefined; replies_before_cursor?: string | null | undefined; reply_count?: number | undefined; reply_to?: Record | null | undefined; root_message_id?: string | null | undefined; sandbox?: string | null | undefined; team?: string | null | undefined; thread?: string | undefined; type?: string | null | undefined; user?: string | { alias?: string | null | undefined; app?: string | null | undefined; app_name?: string | null | undefined; created_by_agent_user?: string | null | undefined; created_by_developer?: string | null | undefined; created_by_org?: string | null | undefined; created_by_team?: string | null | undefined; created_by_user?: string | null | undefined; email?: string | null | undefined; id: string; is_system_user?: boolean | undefined; metadata?: Record | undefined; name?: string | null | undefined; org?: string | null | undefined; org_name?: string | null | undefined; org_role?: string | null | undefined; org_slug?: string | null | undefined; sandbox?: string | null | undefined; sandbox_name?: string | null | undefined } | null | undefined; visibility?: "default" | "private" | undefined } | null | undefined; participant?: string[] | undefined; participants?: { alias?: string | null | undefined; app?: string | null | undefined; app_name?: string | null | undefined; created_by_agent_user?: string | null | undefined; created_by_developer?: string | null | undefined; created_by_org?: string | null | undefined; created_by_team?: string | null | undefined; created_by_user?: string | null | undefined; email?: string | null | undefined; id: string; is_system_user?: boolean | undefined; metadata?: Record | undefined; name?: string | null | undefined; org?: string | null | undefined; org_name?: string | null | undefined; org_role?: string | null | undefined; org_slug?: string | null | undefined; sandbox?: string | null | undefined; sandbox_name?: string | null | undefined }[] | undefined; participating_actor?: string[] | undefined; participating_agents?: { acl?: { add?: { actions: string[]; principal?: string | undefined; principal_type: string }[] | undefined; grants?: { actions: string[]; principal?: string | undefined; principal_type: string }[] | undefined; remove?: { principal?: string | undefined; principal_type: string }[] | undefined } | null | undefined; app?: string | undefined; created_at?: string | undefined; default_model?: string | null | undefined; description?: string | null | undefined; email?: string | null | undefined; id: string; identity?: string | null | undefined; last_applied_template_config?: string | null | undefined; lookup_key?: string | null | undefined; metadata?: Record | undefined; name?: string | undefined; org?: string | null | undefined; org_name?: string | null | undefined; originator?: string | null | undefined; phone_number?: string | null | undefined; sandbox?: string | null | undefined; source_solution?: { current_solution?: { category_keys?: string[] | undefined; created_at?: string | undefined; description?: string | null | undefined; events?: Record | undefined; id: string; image_url?: string | null | undefined; installed_config_ids: string[]; kind: string; latest_solution?: string | null | undefined; latest_version?: string | null | undefined; lookup_key?: string | null | undefined; metadata?: Record | undefined; name?: string | null | undefined; org?: string | null | undefined; org_logo?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined; org_name?: string | null | undefined; org_slug?: string | null | undefined; owners: string[]; readme_url?: string | null | undefined; screenshot_urls?: string[] | undefined; solution_id?: string | null | undefined; solution_version?: string | null | undefined; tag_keys?: string[] | undefined; template_kind?: string | null | undefined; templates: { description?: string | null | undefined; details?: { automation_type?: string | null | undefined; invoke_contract?: { input_schema?: Record | null | undefined; participants?: { description?: string | null | undefined; name: string; required: boolean; type: string }[] | null | undefined; prefills: { participants?: Record | undefined; payload?: Record | undefined } } | null | undefined; type: "automation" } | null | undefined; display_name?: string | null | undefined; id?: string | null | undefined; kind: string; lookup_key?: string | null | undefined; name?: string | null | undefined; readme_url?: string | null | undefined; virtual_path?: string | null | undefined }[]; updated_at?: string | undefined; upgrade_available: boolean; virtual_path?: string | null | undefined } | undefined; solution: { category_keys?: string[] | undefined; created_at?: string | undefined; description?: string | null | undefined; events?: Record | undefined; id: string; image_url?: string | null | undefined; installed_config_ids: string[]; kind: string; latest_solution?: string | null | undefined; latest_version?: string | null | undefined; lookup_key?: string | null | undefined; metadata?: Record | undefined; name?: string | null | undefined; org?: string | null | undefined; org_logo?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined; org_name?: string | null | undefined; org_slug?: string | null | undefined; owners: string[]; readme_url?: string | null | undefined; screenshot_urls?: string[] | undefined; solution_id?: string | null | undefined; solution_version?: string | null | undefined; tag_keys?: string[] | undefined; template_kind?: string | null | undefined; templates: { description?: string | null | undefined; details?: { automation_type?: string | null | undefined; invoke_contract?: { input_schema?: Record | null | undefined; participants?: { description?: string | null | undefined; name: string; required: boolean; type: string }[] | null | undefined; prefills: { participants?: Record | undefined; payload?: Record | undefined } } | null | undefined; type: "automation" } | null | undefined; display_name?: string | null | undefined; id?: string | null | undefined; kind: string; lookup_key?: string | null | undefined; name?: string | null | undefined; readme_url?: string | null | undefined; virtual_path?: string | null | undefined }[]; updated_at?: string | undefined; upgrade_available: boolean; virtual_path?: string | null | undefined }; template: { created_at?: string | undefined; description?: string | null | undefined; display_name?: string | null | undefined; id: string; kind: string; lookup_key?: string | null | undefined; name?: string | null | undefined; updated_at?: string | undefined; virtual_path?: string | null | undefined } } | null | undefined; team?: string | null | undefined; template_upgrade_available?: boolean | null | undefined; updated_at?: string | undefined; user?: string | null | undefined }[] | null | undefined; role?: string | null | undefined; sandbox?: string | null | undefined; settings?: { agent_enabled?: boolean | null | undefined } | undefined; slug?: string | null | undefined; sub_threads?: Record[] | null | undefined; tags?: string[] | undefined; team?: string | null | undefined; title?: string | null | undefined; ttl?: string | null | undefined; unread_count?: number | null | undefined; updated_at?: string | undefined; user?: string | null | undefined; visibility: "team" | "restricted" | "private" | "org" }[] }> { const query: Record | undefined> = {}; if (params?.key !== undefined) { query["key"] = params?.key; @@ -48,9 +367,11 @@ export class OrgThreadResource { } export class OrgResource { + readonly tasks: OrgTaskResource; readonly threads: OrgThreadResource; constructor(private http: HttpClient) { + this.tasks = new OrgTaskResource(http); this.threads = new OrgThreadResource(http); } @@ -98,7 +419,7 @@ export class OrgResource { * @param params.groupKeyPrefix - Nonempty literal group prefix; mutually exclusive with group_key. * @returns Successful response */ - async artifacts(org: string, params?: { limit?: number; afterCursor?: string; groupKey?: string; groupKeyPrefix?: string }): Promise<{ after_cursor?: string | null | undefined; before_cursor?: string | null | undefined; data: { agent?: string | undefined; content_type?: string | undefined; created_at?: string | undefined; current_version?: string | undefined; description?: string | undefined; file?: string | undefined; file_name?: string | undefined; file_url?: string | undefined; group_key?: string | null | undefined; id: string; image_source?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | undefined; name?: string | undefined; org?: string | undefined; sandbox?: string | undefined; system?: boolean | undefined; team?: string | undefined; thread?: string | undefined; updated_at?: string | undefined; user?: string | undefined; version?: number | undefined }[]; has_more: boolean }> { + async artifacts(org: string, params?: { limit?: number; afterCursor?: string; groupKey?: string; groupKeyPrefix?: string }): Promise<{ after_cursor?: string | null | undefined; before_cursor?: string | null | undefined; data: { acl?: { add?: { actions: string[]; principal?: string | undefined; principal_type: string }[] | undefined; grants?: { actions: string[]; principal?: string | undefined; principal_type: string }[] | undefined; remove?: { principal?: string | undefined; principal_type: string }[] | undefined } | null | undefined; agent?: string | undefined; content_type?: string | undefined; created_at?: string | undefined; current_version?: string | undefined; description?: string | undefined; file?: string | undefined; file_name?: string | undefined; file_url?: string | undefined; group_key?: string | null | undefined; id: string; image_source?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | undefined; name?: string | undefined; org?: string | undefined; sandbox?: string | undefined; system?: boolean | undefined; team?: string | undefined; thread?: string | undefined; updated_at?: string | undefined; user?: string | undefined; version?: number | undefined }[]; has_more: boolean }> { const query: Record | undefined> = {}; if (params?.limit !== undefined) { query["limit"] = params?.limit; @@ -146,4 +467,45 @@ export class OrgResource { return this.http.request(`/api/v1/orgs/${org}/linked_accounts`, { query }); } + + /** + * 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. + * @param org - Organization ID (`org_...`) owning the tasks. + * @param params - Query parameters. + * @param params.sourceScope - Exact source scope; supply all three source fields. + * @param params.sourceType - Exact source type. + * @param params.sourceId - Exact source ID. + * @param params.topPriority - Exact highest open priority, from 0 to 4. + * @param params.includeClosed - Include epics with no non-closed tasks; defaults to false. + * @param params.limit - Maximum epics; defaults to 50, capped at 100. + * @param params.afterCursor - Opaque forward cursor from the preceding page. + * @returns Successful response + */ + async taskEpics(org: string, params?: { sourceScope?: string; sourceType?: string; sourceId?: string; topPriority?: number; includeClosed?: boolean; limit?: number; afterCursor?: string }): Promise<{ after_cursor?: string | null | undefined; before_cursor?: string | null | undefined; data: { blocked_count: number; counts: Record; epic: string; next_ready: { id: string; name: string; priority: number; status: string }[]; root_blockers: { downstream_count: number; id: string; name: string; priority: number; status: string }[]; root_blockers_partial: boolean; top_open_priority?: number | null | undefined; updated_at: string }[]; has_more: boolean; no_epic_open_count: number }> { + const query: Record | undefined> = {}; + if (params?.sourceScope !== undefined) { + query["source_scope"] = params?.sourceScope; + } + if (params?.sourceType !== undefined) { + query["source_type"] = params?.sourceType; + } + if (params?.sourceId !== undefined) { + query["source_id"] = params?.sourceId; + } + if (params?.topPriority !== undefined) { + query["top_priority"] = params?.topPriority; + } + if (params?.includeClosed !== undefined) { + query["include_closed"] = params?.includeClosed; + } + if (params?.limit !== undefined) { + query["limit"] = params?.limit; + } + if (params?.afterCursor !== undefined) { + query["after_cursor"] = params?.afterCursor; + } + + return this.http.request(`/api/v1/orgs/${org}/task_epics`, { query }); + } } diff --git a/packages/sdk/src/v1/resources/private_service_enrollments.ts b/packages/sdk/src/v1/resources/private_service_enrollments.ts index 3ad7d77..9d70548 100644 --- a/packages/sdk/src/v1/resources/private_service_enrollments.ts +++ b/packages/sdk/src/v1/resources/private_service_enrollments.ts @@ -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: d0e14fba7255 +// Content hash: 77f2252f7043 import { HttpClient } from "../../runtime/http-client.js"; import type { CreatedPrivateServiceEnrollment, PrivateServiceEnrollment, PrivateServiceEnrollmentPage } from "../../types/common.js"; @@ -43,6 +43,16 @@ export class PrivateServiceEnrollmentResource { return this.http.request(`/api/v1/private_service_enrollments`, { method: "POST", body: input }); } + /** + * Revoke a private service enrollment + * Removes online connector authorization and prevents credential renewal. + * @param privateServiceEnrollmentId - Canonical certificate-bound service identity. + * @returns Authorization was durably revoked. + */ + async delete(privateServiceEnrollmentId: string): Promise { + await this.http.request(`/api/v1/private_service_enrollments/${privateServiceEnrollmentId}`, { method: "DELETE" }); + } + /** * Retrieve a private service enrollment * @param privateServiceEnrollmentId - Canonical certificate-bound service identity. diff --git a/packages/sdk/src/v1/resources/relays.ts b/packages/sdk/src/v1/resources/relays.ts new file mode 100644 index 0000000..f093fc5 --- /dev/null +++ b/packages/sdk/src/v1/resources/relays.ts @@ -0,0 +1,48 @@ +// Copyright (c) 2026 ArchAstro Inc. Licensed under the MIT License. +// This file is auto-generated by @archastro/sdk-generator. Do not edit. +// Content hash: 85c52128edb0 + +import { HttpClient } from "../../runtime/http-client.js"; +import type { Relay } from "../../types/relays.js"; + +export class RelayResource { + constructor(private http: HttpClient) {} + + /** + * Create an owner-only relay + * Only the owning user in the same app may access this relay. + * @param input - Request body. + * @returns Successful response + */ + async create(input: { purpose: string; ttl_seconds: number }): Promise { + return this.http.request(`/api/v1/relays`, { method: "POST", body: input }); + } + + /** + * Delete an owner-only relay + * Only the owning user in the same app may access this relay. + * @returns Successful response + */ + async delete(relay: string): Promise { + return this.http.request(`/api/v1/relays/${relay}`, { method: "DELETE" }); + } + + /** + * Show an owner-only relay + * Only the owning user in the same app may access this relay. + * @returns Successful response + */ + async get(relay: string): Promise { + return this.http.request(`/api/v1/relays/${relay}`); + } + + /** + * Extend an owner-only relay + * Only the owning user in the same app may access this relay. + * @param input - Request body. + * @returns Successful response + */ + async extend(relay: string, input: { ttl_seconds: number }): Promise { + return this.http.request(`/api/v1/relays/${relay}/extend`, { method: "POST", body: input }); + } +} diff --git a/packages/sdk/src/v1/resources/scripts.ts b/packages/sdk/src/v1/resources/scripts.ts index 8e4985a..ae35415 100644 --- a/packages/sdk/src/v1/resources/scripts.ts +++ b/packages/sdk/src/v1/resources/scripts.ts @@ -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: b80adc3ed55c +// Content hash: d6da382f5036 import { HttpClient } from "../../runtime/http-client.js"; import type { RuntimeEnvVarList } from "../../types/common.js"; @@ -40,27 +40,35 @@ export class ScriptResource { /** * Execute a workflow script - * Executes the provided script source and returns the result value together - * with any `print` output captured during the run. Use this endpoint to - * evaluate scripts interactively during development, or to drive automation - * from external tooling. - * The script runs with the authenticated viewer's identity by default. Pass - * `run_as_user` to impersonate a specific user, or `run_as_agent` to run as - * a specific agent, subject to the caller's delegation permissions. These two params are mutually exclusive — supplying both - * returns a 422 error. + * Executes script source and returns the result value together with any + * `print` output captured during the run. Pass `script` for interactive + * evaluation, or `config` to run a stored Script config by ID. Server-side + * producers (for example a webhook service emitting through `events.emit`) + * must use `config`; raw source from those callers is not an authorized + * application script. + * The script runs with the authenticated viewer's identity by default. Org + * targeting for secret-key callers comes from the `X-ArchAstro-Org-Id` + * header, not from the body. Pass `run_as_user` to impersonate a specific + * user, or `run_as_agent` to run as a specific agent, subject to the + * caller's delegation permissions. These two params are mutually exclusive + * — supplying both returns a 422 error. `script` and `config` are also + * mutually exclusive. * Runtime environment variables resolved for the execution identity's app and organization are automatically injected * into the script's `variables.env` scope. When the script raises a runtime * error, the response still returns HTTP 200 with `error`, `findings`, and any * partial output; the error is also recorded in the app's activity feed. * @param input - Request body. + * @param input.config - Stored Script config ID (`cfg_...`) whose current version is executed. Mutually exclusive with `script`. Required for server-side producers that must not supply raw source. + * @param input.config_key - `lookup_key` of an app-level Script config whose current version is executed. Resolved among the app's configs that belong to no organization, never an organization's config with the same key. Mutually exclusive with `script` and `config`. * @param input.resolution_context_config - Optional Script config ID establishing the authorized installation context for imports. * @param input.run_as_agent - Agent ID (`agt_...`) to impersonate during execution. When set, the script's `system.viewer` is replaced with a viewer for this agent. Mutually exclusive with `run_as_user`. `null` by default. * @param input.run_as_user - User ID (`usr_...`) to impersonate during execution. When set, the script's `system.viewer` is replaced with a viewer for this user. Mutually exclusive with `run_as_agent`. `null` by default. * @param input.scope - Initial scope injected into the script execution context. Use this to supply `variables`, `system`, or other top-level scope keys. - * @param input.script - The script source to execute. Defaults to an empty string. + * @param input.script - The script source to execute. Defaults to an empty string. Mutually exclusive with `config`. + * @param input.thread - Optional thread ID for agent execution. Requires run_as_agent, caller access to the thread, matching agent app and organization, and agent membership in the thread. * @returns The script execution result, including the return value, captured output, and any runtime error or diagnostic findings. */ - async run(input: { resolution_context_config?: string | undefined; run_as_agent?: string | undefined; run_as_user?: string | undefined; scope?: Record | undefined; script?: string | undefined }): Promise { + async run(input: { config?: string | undefined; config_key?: string | undefined; resolution_context_config?: string | undefined; run_as_agent?: string | undefined; run_as_user?: string | undefined; scope?: Record | undefined; script?: string | undefined; thread?: string | undefined }): Promise { return this.http.request(`/api/v1/scripts/run`, { method: "POST", body: input }); } diff --git a/packages/sdk/src/v1/resources/task_ownership_conversions.ts b/packages/sdk/src/v1/resources/task_ownership_conversions.ts new file mode 100644 index 0000000..ff61685 --- /dev/null +++ b/packages/sdk/src/v1/resources/task_ownership_conversions.ts @@ -0,0 +1,20 @@ +// Copyright (c) 2026 ArchAstro Inc. Licensed under the MIT License. +// This file is auto-generated by @archastro/sdk-generator. Do not edit. +// Content hash: de4fe00eab1d + +import { HttpClient } from "../../runtime/http-client.js"; +import type { TaskOwnershipJob } from "../../types/tasks.js"; + +export class TaskOwnershipConversionResource { + constructor(private http: HttpClient) {} + + /** + * Read the status of a task ownership conversion + * Returns only the requesting user's job status, even after task visibility changes. + * @param jobId - The accepted background job ID. + * @returns Current background job state. + */ + async get(jobId: string): Promise { + return this.http.request(`/api/v1/task_ownership_conversions/${jobId}`); + } +} diff --git a/packages/sdk/src/v1/resources/tasks.ts b/packages/sdk/src/v1/resources/tasks.ts index 48c5698..0df8218 100644 --- a/packages/sdk/src/v1/resources/tasks.ts +++ b/packages/sdk/src/v1/resources/tasks.ts @@ -1,9 +1,9 @@ // Copyright (c) 2026 ArchAstro Inc. Licensed under the MIT License. // This file is auto-generated by @archastro/sdk-generator. Do not edit. -// Content hash: d9aba586a396 +// Content hash: c5dbb9f09d7f import { HttpClient } from "../../runtime/http-client.js"; -import type { Task, TaskComment, TaskExternalLink, TaskSessionLease, TaskSessionLeaseSummary } from "../../types/tasks.js"; +import type { Task, TaskComment, TaskExternalLink, TaskOwnershipJob, TaskSessionLease, TaskSessionLeaseSummary } from "../../types/tasks.js"; export class BlockerResource { constructor(private http: HttpClient) {} @@ -24,7 +24,7 @@ export class BlockerResource { * @param params.afterCursor - Opaque cursor returned by the previous page. * @returns Successful response */ - async list(task: string, params?: { team?: string; user?: string; agent?: string; org?: string; limit?: number; afterCursor?: string }): Promise<{ after_cursor?: string | undefined; before_cursor?: string | undefined; data: { agent?: string | null | undefined; aggregate_version?: number | null | undefined; blocked_by_count?: number | undefined; closed_at?: string | null | undefined; comments_count?: number | undefined; created_at?: string | undefined; created_by_actor?: { alias?: string | null | undefined; id?: string | null | undefined; name?: string | null | undefined; profile_picture?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined } | null | undefined; created_by_agent?: string | null | undefined; created_by_user?: string | null | undefined; current_lease?: { expires_at: string; harness: string; session_name: string } | null | undefined; description?: string | null | undefined; due_date?: string | null | undefined; epic?: string | null | undefined; id: string; is_blocked?: boolean | undefined; links?: Record | undefined; metadata?: Record | undefined; name: string; org?: string | null | undefined; owner_actor?: { alias?: string | null | undefined; id?: string | null | undefined; name?: string | null | undefined; profile_picture?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined } | null | undefined; owner_agent?: string | null | undefined; owner_user?: string | null | undefined; parent?: string | null | undefined; priority?: number | undefined; sandbox?: string | null | undefined; source_id?: string | null | undefined; source_scope?: string | null | undefined; source_type?: string | null | undefined; status: string; subtasks_count?: number | undefined; tags?: string[] | undefined; team?: string | null | undefined; thread?: string | null | undefined; updated_at?: string | undefined; user?: string | null | undefined }[]; has_more: boolean }> { + async list(task: string, params?: { team?: string; user?: string; agent?: string; org?: string; limit?: number; afterCursor?: string }): Promise<{ after_cursor?: string | undefined; before_cursor?: string | undefined; data: { agent?: string | null | undefined; aggregate_version?: number | null | undefined; blocked_by_count?: number | undefined; closed_at?: string | null | undefined; comments_count?: number | undefined; created_at?: string | undefined; created_by_actor?: { alias?: string | null | undefined; id?: string | null | undefined; name?: string | null | undefined; profile_picture?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined } | null | undefined; created_by_agent?: string | null | undefined; created_by_user?: string | null | undefined; current_lease?: { expires_at: string; harness: string; session_name: string } | null | undefined; description?: string | null | undefined; due_date?: string | null | undefined; epic?: string | null | undefined; id: string; is_blocked?: boolean | undefined; is_stalled?: boolean | undefined; links?: Record | undefined; metadata?: Record | undefined; name: string; org?: string | null | undefined; owner_actor?: { alias?: string | null | undefined; id?: string | null | undefined; name?: string | null | undefined; profile_picture?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined } | null | undefined; owner_agent?: string | null | undefined; owner_user?: string | null | undefined; parent?: string | null | undefined; priority?: number | undefined; project_id?: string | null | undefined; sandbox?: string | null | undefined; source_id?: string | null | undefined; source_scope?: string | null | undefined; source_type?: string | null | undefined; stalled_since?: string | null | undefined; status: string; subtasks_count?: number | undefined; tags?: string[] | undefined; target_binary?: string | null | undefined; target_version?: string | null | undefined; team?: string | null | undefined; thread?: string | null | undefined; updated_at?: string | undefined; user?: string | null | undefined }[]; has_more: boolean }> { const query: Record | undefined> = {}; if (params?.team !== undefined) { query["team"] = params?.team; @@ -132,9 +132,10 @@ export class CommentResource { * @param task - Task ID (`tsk_...`). * @param input - Request body. * @param input.comment - Parameters for the comment to create, including its body. + * @param input.expected_version - Reject the comment if the task changed since this version. * @returns The newly created comment. */ - async create(task: string, input: { comment: { body: string } }): Promise { + async create(task: string, input: { comment: { body: string }; expected_version?: number | undefined }): Promise { return this.http.request(`/api/v1/tasks/${task}/comments`, { method: "POST", body: input }); } @@ -419,16 +420,20 @@ export class TaskResource { * @param input.owner_user - Assign to a user by public ID (`usr_...`). * @param input.parent - Move this task under a top-level parent (`tsk_...`), or pass null to promote it to a top-level task. A task that has subtasks cannot become one. * @param input.priority - Updated priority from 0 (highest) to 4 (lowest). + * @param input.project_id - Project ID (`prj_...`). Omit to preserve; pass null to clear. + * @param input.require_status_lease - Session clients must set true for status changes. A live lease then requires the holder's lease_id and lease_session_id; human and host overrides remain available. * @param input.source_id - Replacement source object identity. Must be supplied with the other source fields. * @param input.source_scope - Replacement source container. Pass together with `source_type` and `source_id`, or pass all three as null to clear the source. * @param input.source_type - Replacement source object kind. Must be supplied with the other source fields. * @param input.status - Updated status: `open`, `in_progress`, `in_review`, or `done`. * @param input.tags - Replacement tag list (max 20, each up to 40 characters; normalized to lowercase). Pass an empty array to clear all tags. + * @param input.target_binary - Replacement target binary (for example `my-cli`): a lowercase identifier of 1-64 characters. Pass together with `target_version`, or pass both as null to clear the target. + * @param input.target_version - Replacement minimum semantic version of `target_binary` (for example `0.48.9`). Must be supplied with `target_binary`. * @param input.team - Explicit owning team (`tem_...`) for a developer or server-to-server call. * @param input.user - Explicit user (`usr_...`) for a developer or server-to-server call. With `team`, this identifies the acting team member. * @returns The updated task. */ - async replace(task: string, input: { agent?: string | undefined; description?: string | undefined; due_date?: string | undefined; epic?: string | undefined; expected_version?: number | undefined; lease_id?: string | undefined; lease_session_id?: string | undefined; links?: Record | undefined; metadata?: Record | undefined; name?: string | undefined; org?: string | undefined; owner_agent?: string | undefined; owner_user?: string | undefined; parent?: string | undefined; priority?: number | undefined; source_id?: string | undefined; source_scope?: string | undefined; source_type?: string | undefined; status?: string | undefined; tags?: string[] | undefined; team?: string | undefined; user?: string | undefined }): Promise { + async replace(task: string, input: { agent?: string | undefined; description?: string | undefined; due_date?: string | undefined; epic?: string | undefined; expected_version?: number | undefined; lease_id?: string | undefined; lease_session_id?: string | undefined; links?: Record | undefined; metadata?: Record | undefined; name?: string | undefined; org?: string | undefined; owner_agent?: string | undefined; owner_user?: string | undefined; parent?: string | undefined; priority?: number | undefined; project_id?: string | undefined; require_status_lease?: boolean | undefined; source_id?: string | undefined; source_scope?: string | undefined; source_type?: string | undefined; status?: string | undefined; tags?: string[] | undefined; target_binary?: string | undefined; target_version?: string | undefined; team?: string | undefined; user?: string | undefined }): Promise { return this.http.request(`/api/v1/tasks/${task}`, { method: "PUT", body: input }); } @@ -486,7 +491,7 @@ export class TaskResource { * @param params.afterCursor - Opaque cursor returned by the previous page. * @returns Successful response */ - async blocking(task: string, params?: { team?: string; user?: string; agent?: string; org?: string; limit?: number; afterCursor?: string }): Promise<{ after_cursor?: string | undefined; before_cursor?: string | undefined; data: { agent?: string | null | undefined; aggregate_version?: number | null | undefined; blocked_by_count?: number | undefined; closed_at?: string | null | undefined; comments_count?: number | undefined; created_at?: string | undefined; created_by_actor?: { alias?: string | null | undefined; id?: string | null | undefined; name?: string | null | undefined; profile_picture?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined } | null | undefined; created_by_agent?: string | null | undefined; created_by_user?: string | null | undefined; current_lease?: { expires_at: string; harness: string; session_name: string } | null | undefined; description?: string | null | undefined; due_date?: string | null | undefined; epic?: string | null | undefined; id: string; is_blocked?: boolean | undefined; links?: Record | undefined; metadata?: Record | undefined; name: string; org?: string | null | undefined; owner_actor?: { alias?: string | null | undefined; id?: string | null | undefined; name?: string | null | undefined; profile_picture?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined } | null | undefined; owner_agent?: string | null | undefined; owner_user?: string | null | undefined; parent?: string | null | undefined; priority?: number | undefined; sandbox?: string | null | undefined; source_id?: string | null | undefined; source_scope?: string | null | undefined; source_type?: string | null | undefined; status: string; subtasks_count?: number | undefined; tags?: string[] | undefined; team?: string | null | undefined; thread?: string | null | undefined; updated_at?: string | undefined; user?: string | null | undefined }[]; has_more: boolean }> { + async blocking(task: string, params?: { team?: string; user?: string; agent?: string; org?: string; limit?: number; afterCursor?: string }): Promise<{ after_cursor?: string | undefined; before_cursor?: string | undefined; data: { agent?: string | null | undefined; aggregate_version?: number | null | undefined; blocked_by_count?: number | undefined; closed_at?: string | null | undefined; comments_count?: number | undefined; created_at?: string | undefined; created_by_actor?: { alias?: string | null | undefined; id?: string | null | undefined; name?: string | null | undefined; profile_picture?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined } | null | undefined; created_by_agent?: string | null | undefined; created_by_user?: string | null | undefined; current_lease?: { expires_at: string; harness: string; session_name: string } | null | undefined; description?: string | null | undefined; due_date?: string | null | undefined; epic?: string | null | undefined; id: string; is_blocked?: boolean | undefined; is_stalled?: boolean | undefined; links?: Record | undefined; metadata?: Record | undefined; name: string; org?: string | null | undefined; owner_actor?: { alias?: string | null | undefined; id?: string | null | undefined; name?: string | null | undefined; profile_picture?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined } | null | undefined; owner_agent?: string | null | undefined; owner_user?: string | null | undefined; parent?: string | null | undefined; priority?: number | undefined; project_id?: string | null | undefined; sandbox?: string | null | undefined; source_id?: string | null | undefined; source_scope?: string | null | undefined; source_type?: string | null | undefined; stalled_since?: string | null | undefined; status: string; subtasks_count?: number | undefined; tags?: string[] | undefined; target_binary?: string | null | undefined; target_version?: string | null | undefined; team?: string | null | undefined; thread?: string | null | undefined; updated_at?: string | undefined; user?: string | null | undefined }[]; has_more: boolean }> { const query: Record | undefined> = {}; if (params?.team !== undefined) { query["team"] = params?.team; @@ -510,6 +515,21 @@ export class TaskResource { return this.http.request(`/api/v1/tasks/${task}/blocking`, { query }); } + /** + * 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. + * @param task - Root task (`tsk_...`). + * @param input - Request body. + * @param input.dest_agent - Destination agent (`agi_...`). + * @param input.dest_org - Destination organization (`org_...`). + * @param input.dest_team - Destination team (`tem_...`). + * @param input.dest_user - Destination user (`usr_...`). Supply exactly one destination. + * @returns The queued background job. + */ + async ownershipConversions(task: string, input: { dest_agent?: string | undefined; dest_org?: string | undefined; dest_team?: string | undefined; dest_user?: string | undefined }): Promise { + return this.http.request(`/api/v1/tasks/${task}/ownership_conversions`, { method: "POST", body: input }); + } + /** * List a task's subtasks * Returns a bounded page of the specified task's subtasks (tasks whose @@ -526,7 +546,7 @@ export class TaskResource { * @param params.afterCursor - Opaque cursor returned by the previous page. * @returns Successful response */ - async subtasks(task: string, params?: { team?: string; user?: string; agent?: string; org?: string; limit?: number; afterCursor?: string }): Promise<{ after_cursor?: string | undefined; before_cursor?: string | undefined; data: { agent?: string | null | undefined; aggregate_version?: number | null | undefined; blocked_by_count?: number | undefined; closed_at?: string | null | undefined; comments_count?: number | undefined; created_at?: string | undefined; created_by_actor?: { alias?: string | null | undefined; id?: string | null | undefined; name?: string | null | undefined; profile_picture?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined } | null | undefined; created_by_agent?: string | null | undefined; created_by_user?: string | null | undefined; current_lease?: { expires_at: string; harness: string; session_name: string } | null | undefined; description?: string | null | undefined; due_date?: string | null | undefined; epic?: string | null | undefined; id: string; is_blocked?: boolean | undefined; links?: Record | undefined; metadata?: Record | undefined; name: string; org?: string | null | undefined; owner_actor?: { alias?: string | null | undefined; id?: string | null | undefined; name?: string | null | undefined; profile_picture?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined } | null | undefined; owner_agent?: string | null | undefined; owner_user?: string | null | undefined; parent?: string | null | undefined; priority?: number | undefined; sandbox?: string | null | undefined; source_id?: string | null | undefined; source_scope?: string | null | undefined; source_type?: string | null | undefined; status: string; subtasks_count?: number | undefined; tags?: string[] | undefined; team?: string | null | undefined; thread?: string | null | undefined; updated_at?: string | undefined; user?: string | null | undefined }[]; has_more: boolean }> { + async subtasks(task: string, params?: { team?: string; user?: string; agent?: string; org?: string; limit?: number; afterCursor?: string }): Promise<{ after_cursor?: string | undefined; before_cursor?: string | undefined; data: { agent?: string | null | undefined; aggregate_version?: number | null | undefined; blocked_by_count?: number | undefined; closed_at?: string | null | undefined; comments_count?: number | undefined; created_at?: string | undefined; created_by_actor?: { alias?: string | null | undefined; id?: string | null | undefined; name?: string | null | undefined; profile_picture?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined } | null | undefined; created_by_agent?: string | null | undefined; created_by_user?: string | null | undefined; current_lease?: { expires_at: string; harness: string; session_name: string } | null | undefined; description?: string | null | undefined; due_date?: string | null | undefined; epic?: string | null | undefined; id: string; is_blocked?: boolean | undefined; is_stalled?: boolean | undefined; links?: Record | undefined; metadata?: Record | undefined; name: string; org?: string | null | undefined; owner_actor?: { alias?: string | null | undefined; id?: string | null | undefined; name?: string | null | undefined; profile_picture?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined } | null | undefined; owner_agent?: string | null | undefined; owner_user?: string | null | undefined; parent?: string | null | undefined; priority?: number | undefined; project_id?: string | null | undefined; sandbox?: string | null | undefined; source_id?: string | null | undefined; source_scope?: string | null | undefined; source_type?: string | null | undefined; stalled_since?: string | null | undefined; status: string; subtasks_count?: number | undefined; tags?: string[] | undefined; target_binary?: string | null | undefined; target_version?: string | null | undefined; team?: string | null | undefined; thread?: string | null | undefined; updated_at?: string | undefined; user?: string | null | undefined }[]; has_more: boolean }> { const query: Record | undefined> = {}; if (params?.team !== undefined) { query["team"] = params?.team; @@ -549,4 +569,20 @@ export class TaskResource { return this.http.request(`/api/v1/tasks/${task}/subtasks`, { query }); } + + /** + * Transfer one task to a different owner + * Changes one task’s privacy owner at the supplied aggregate version. Assignment, creator, source identity, comments, and relationship IDs remain unchanged. Source and destination must have the same app and sandbox; the authenticated user must have authority over both scopes. + * @param task - Task (`tsk_...`). + * @param input - Request body. + * @param input.dest_agent - Destination agent (`agi_...`). + * @param input.dest_org - Destination organization (`org_...`). + * @param input.dest_team - Destination team (`tem_...`). + * @param input.dest_user - Destination user (`usr_...`). Supply exactly one destination. + * @param input.expected_version - The task version reviewed by the caller. + * @returns The task with its new owner. + */ + async transferOwnership(task: string, input: { dest_agent?: string | undefined; dest_org?: string | undefined; dest_team?: string | undefined; dest_user?: string | undefined; expected_version: number }): Promise { + return this.http.request(`/api/v1/tasks/${task}/transfer_ownership`, { method: "POST", body: input }); + } } diff --git a/packages/sdk/src/v1/resources/teams.ts b/packages/sdk/src/v1/resources/teams.ts index 10a2b15..31767f2 100644 --- a/packages/sdk/src/v1/resources/teams.ts +++ b/packages/sdk/src/v1/resources/teams.ts @@ -1,10 +1,10 @@ // Copyright (c) 2026 ArchAstro Inc. Licensed under the MIT License. // This file is auto-generated by @archastro/sdk-generator. Do not edit. -// Content hash: f7ab381fb0fa +// Content hash: 1b5cd505003a import { HttpClient } from "../../runtime/http-client.js"; import type { CustomObject } from "../../types/common.js"; -import type { Task } from "../../types/tasks.js"; +import type { Task, TaskEnsureResult } from "../../types/tasks.js"; import type { Team, TeamDeleteImpactResponse, TeamInvite, TeamMembership } from "../../types/teams.js"; import type { Thread } from "../../types/threads.js"; @@ -34,7 +34,7 @@ export class TeamCustomObjectResource { * @param params.query - Full-text search string matched against the schema's configured `search_fields`. When provided, results are ordered by relevance score descending instead of creation time descending. * @returns Successful response */ - async list(team: string, params?: { type?: string; limit?: number; offset?: number; rowKey?: string; sortKey?: string; query?: string }): Promise<{ data: { acl?: { add?: { actions: string[]; principal?: string | undefined; principal_type: string }[] | undefined; grants?: { actions: string[]; principal?: string | undefined; principal_type: string }[] | undefined; remove?: { principal?: string | undefined; principal_type: string }[] | undefined } | undefined; created_at?: string | undefined; fields?: Record | undefined; id: string; org?: string | undefined; row_key?: string | undefined; sandbox?: string | undefined; schema_type?: string | undefined; team?: string | undefined; updated_at?: string | undefined; user?: string | undefined; version?: number | undefined }[]; meta?: Record | undefined }> { + async list(team: string, params?: { type?: string; limit?: number; offset?: number; rowKey?: string; sortKey?: string; query?: string }): Promise<{ data: { acl?: { add?: { actions: string[]; principal?: string | undefined; principal_type: string }[] | undefined; grants?: { actions: string[]; principal?: string | undefined; principal_type: string }[] | undefined; remove?: { principal?: string | undefined; principal_type: string }[] | undefined } | undefined; agent?: string | undefined; created_at?: string | undefined; expires_at?: string | null | undefined; fields?: Record | undefined; id: string; org?: string | undefined; row_key?: string | undefined; sandbox?: string | undefined; schema_type?: string | undefined; team?: string | undefined; updated_at?: string | undefined; user?: string | undefined; version?: number | undefined }[]; meta?: Record | undefined }> { const query: Record | undefined> = {}; query["type"] = params?.type; if (params?.limit !== undefined) { @@ -230,11 +230,12 @@ export class TeamTaskResource { * @param params.dueAfter - Return only tasks with a due date strictly after this ISO 8601 datetime or date. Tasks without a due date are excluded. * @param params.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. * @param params.ready - When true, return only open tasks with no unfinished blockers and no active session lease. This is a projection snapshot; claim a lease before starting work. + * @param params.attention - When true, return paused, failed, or in-progress tasks with no lease or a past lease expiry. * @param params.limit - Maximum number of tasks to return. Capped at 100. * @param params.afterCursor - Opaque cursor returned by the previous page. * @returns Successful response */ - async list(team: string, params?: { user?: string; org?: string; status?: string; ownerUser?: string; ownerAgent?: string; priority?: number; tag?: string; parent?: string; sourceScope?: string; sourceType?: string; sourceId?: string; epic?: string; search?: string; sort?: string; order?: string; dueBefore?: string; dueAfter?: string; overdue?: boolean; ready?: boolean; limit?: number; afterCursor?: string }): Promise<{ after_cursor?: string | null | undefined; before_cursor?: string | null | undefined; data: { agent?: string | null | undefined; aggregate_version?: number | null | undefined; blocked_by_count?: number | undefined; closed_at?: string | null | undefined; comments_count?: number | undefined; created_at?: string | undefined; created_by_actor?: { alias?: string | null | undefined; id?: string | null | undefined; name?: string | null | undefined; profile_picture?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined } | null | undefined; created_by_agent?: string | null | undefined; created_by_user?: string | null | undefined; current_lease?: { expires_at: string; harness: string; session_name: string } | null | undefined; description?: string | null | undefined; due_date?: string | null | undefined; epic?: string | null | undefined; id: string; is_blocked?: boolean | undefined; links?: Record | undefined; metadata?: Record | undefined; name: string; org?: string | null | undefined; owner_actor?: { alias?: string | null | undefined; id?: string | null | undefined; name?: string | null | undefined; profile_picture?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined } | null | undefined; owner_agent?: string | null | undefined; owner_user?: string | null | undefined; parent?: string | null | undefined; priority?: number | undefined; sandbox?: string | null | undefined; source_id?: string | null | undefined; source_scope?: string | null | undefined; source_type?: string | null | undefined; status: string; subtasks_count?: number | undefined; tags?: string[] | undefined; team?: string | null | undefined; thread?: string | null | undefined; updated_at?: string | undefined; user?: string | null | undefined }[]; has_more: boolean }> { + async list(team: string, params?: { user?: string; org?: string; status?: string; ownerUser?: string; ownerAgent?: string; priority?: number; tag?: string; parent?: string; sourceScope?: string; sourceType?: string; sourceId?: string; epic?: string; search?: string; sort?: string; order?: string; dueBefore?: string; dueAfter?: string; overdue?: boolean; ready?: boolean; attention?: boolean; limit?: number; afterCursor?: string }): Promise<{ after_cursor?: string | null | undefined; before_cursor?: string | null | undefined; data: { agent?: string | null | undefined; aggregate_version?: number | null | undefined; blocked_by_count?: number | undefined; closed_at?: string | null | undefined; comments_count?: number | undefined; created_at?: string | undefined; created_by_actor?: { alias?: string | null | undefined; id?: string | null | undefined; name?: string | null | undefined; profile_picture?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined } | null | undefined; created_by_agent?: string | null | undefined; created_by_user?: string | null | undefined; current_lease?: { expires_at: string; harness: string; session_name: string } | null | undefined; description?: string | null | undefined; due_date?: string | null | undefined; epic?: string | null | undefined; id: string; is_blocked?: boolean | undefined; is_stalled?: boolean | undefined; links?: Record | undefined; metadata?: Record | undefined; name: string; org?: string | null | undefined; owner_actor?: { alias?: string | null | undefined; id?: string | null | undefined; name?: string | null | undefined; profile_picture?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined } | null | undefined; owner_agent?: string | null | undefined; owner_user?: string | null | undefined; parent?: string | null | undefined; priority?: number | undefined; project_id?: string | null | undefined; sandbox?: string | null | undefined; source_id?: string | null | undefined; source_scope?: string | null | undefined; source_type?: string | null | undefined; stalled_since?: string | null | undefined; status: string; subtasks_count?: number | undefined; tags?: string[] | undefined; target_binary?: string | null | undefined; target_version?: string | null | undefined; team?: string | null | undefined; thread?: string | null | undefined; updated_at?: string | undefined; user?: string | null | undefined }[]; has_more: boolean }> { const query: Record | undefined> = {}; if (params?.user !== undefined) { query["user"] = params?.user; @@ -293,6 +294,9 @@ export class TeamTaskResource { if (params?.ready !== undefined) { query["ready"] = params?.ready; } + if (params?.attention !== undefined) { + query["attention"] = params?.attention; + } if (params?.limit !== undefined) { query["limit"] = params?.limit; } @@ -320,7 +324,7 @@ export class TeamTaskResource { * @param input.user - User ID (`usr_...`). On a user route this is the task owner and creator; on a team route it is the explicit acting user for a developer or server-to-server call. * @returns The newly created task. */ - async create(team: string, input: { agent?: string | undefined; org?: string | undefined; task: { description?: string | undefined; due_date?: string | undefined; epic?: string | undefined; id?: string | undefined; links?: Record | undefined; metadata?: Record | undefined; name: string; owner_agent?: string | undefined; owner_user?: string | undefined; parent?: string | undefined; priority?: number | undefined; source_id?: string | undefined; source_scope?: string | undefined; source_type?: string | undefined; status?: string | undefined; tags?: string[] | undefined; thread?: string | undefined }; user?: string | undefined }): Promise { + async create(team: string, input: { agent?: string | undefined; org?: string | undefined; task: { description?: string | undefined; due_date?: string | undefined; epic?: string | undefined; id?: string | undefined; links?: Record | undefined; metadata?: Record | undefined; name: string; owner_agent?: string | undefined; owner_user?: string | undefined; parent?: string | undefined; priority?: number | undefined; project_id?: string | undefined; source_id?: string | undefined; source_scope?: string | undefined; source_type?: string | undefined; status?: string | undefined; tags?: string[] | undefined; target_binary?: string | undefined; target_version?: string | undefined; thread?: string | undefined }; user?: string | undefined }): Promise { return this.http.request(`/api/v1/teams/${team}/tasks`, { method: "POST", body: input }); } @@ -339,7 +343,7 @@ export class TeamTaskResource { * @param params.afterCursor - Opaque cursor returned by the preceding page. * @returns Successful response */ - async blockerCycles(team: string, params?: { user?: string; org?: string; limit?: number; afterCursor?: string }): Promise<{ after_cursor?: string | undefined; before_cursor?: string | undefined; data: { tasks: { agent?: string | null | undefined; aggregate_version?: number | null | undefined; blocked_by_count?: number | undefined; closed_at?: string | null | undefined; comments_count?: number | undefined; created_at?: string | undefined; created_by_actor?: { alias?: string | null | undefined; id?: string | null | undefined; name?: string | null | undefined; profile_picture?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined } | null | undefined; created_by_agent?: string | null | undefined; created_by_user?: string | null | undefined; current_lease?: { expires_at: string; harness: string; session_name: string } | null | undefined; description?: string | null | undefined; due_date?: string | null | undefined; epic?: string | null | undefined; id: string; is_blocked?: boolean | undefined; links?: Record | undefined; metadata?: Record | undefined; name: string; org?: string | null | undefined; owner_actor?: { alias?: string | null | undefined; id?: string | null | undefined; name?: string | null | undefined; profile_picture?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined } | null | undefined; owner_agent?: string | null | undefined; owner_user?: string | null | undefined; parent?: string | null | undefined; priority?: number | undefined; sandbox?: string | null | undefined; source_id?: string | null | undefined; source_scope?: string | null | undefined; source_type?: string | null | undefined; status: string; subtasks_count?: number | undefined; tags?: string[] | undefined; team?: string | null | undefined; thread?: string | null | undefined; updated_at?: string | undefined; user?: string | null | undefined }[] }[]; has_more: boolean }> { + async blockerCycles(team: string, params?: { user?: string; org?: string; limit?: number; afterCursor?: string }): Promise<{ after_cursor?: string | undefined; before_cursor?: string | undefined; data: { tasks: { agent?: string | null | undefined; aggregate_version?: number | null | undefined; blocked_by_count?: number | undefined; closed_at?: string | null | undefined; comments_count?: number | undefined; created_at?: string | undefined; created_by_actor?: { alias?: string | null | undefined; id?: string | null | undefined; name?: string | null | undefined; profile_picture?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined } | null | undefined; created_by_agent?: string | null | undefined; created_by_user?: string | null | undefined; current_lease?: { expires_at: string; harness: string; session_name: string } | null | undefined; description?: string | null | undefined; due_date?: string | null | undefined; epic?: string | null | undefined; id: string; is_blocked?: boolean | undefined; is_stalled?: boolean | undefined; links?: Record | undefined; metadata?: Record | undefined; name: string; org?: string | null | undefined; owner_actor?: { alias?: string | null | undefined; id?: string | null | undefined; name?: string | null | undefined; profile_picture?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined } | null | undefined; owner_agent?: string | null | undefined; owner_user?: string | null | undefined; parent?: string | null | undefined; priority?: number | undefined; project_id?: string | null | undefined; sandbox?: string | null | undefined; source_id?: string | null | undefined; source_scope?: string | null | undefined; source_type?: string | null | undefined; stalled_since?: string | null | undefined; status: string; subtasks_count?: number | undefined; tags?: string[] | undefined; target_binary?: string | null | undefined; target_version?: string | null | undefined; team?: string | null | undefined; thread?: string | null | undefined; updated_at?: string | undefined; user?: string | null | undefined }[] }[]; has_more: boolean }> { const query: Record | undefined> = {}; if (params?.user !== undefined) { query["user"] = params?.user; @@ -357,6 +361,27 @@ export class TeamTaskResource { return this.http.request(`/api/v1/teams/${team}/tasks/blocker_cycles`, { query }); } + /** + * Find or create a task by source + * 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. + * @param team - Team ID (`tem_...`). Only tasks belonging to this team are returned. + * @param input - Request body. + * @param input.agent - Explicit acting agent for privileged callers. + * @param input.description - Initial task description. + * @param input.epic - Initial epic grouping. + * @param input.name - Initial task name. + * @param input.org - Explicit organization for privileged callers. + * @param input.source_id - Source identity, for example owner/repo#123. + * @param input.source_scope - Source scope, for example github. + * @param input.source_type - Source type, for example pull_request. + * @param input.status - Initial task status. + * @param input.user - User owner, or explicit acting user on a team route. + * @returns The task and whether this request created it. + */ + async bySource(team: string, input: { agent?: string | undefined; description?: string | undefined; epic?: string | undefined; name: string; org?: string | undefined; source_id: string; source_scope: string; source_type: string; status?: string | undefined; user?: string | undefined }): Promise { + return this.http.request(`/api/v1/teams/${team}/tasks/by-source`, { method: "PUT", body: input }); + } + /** * Get task activity metrics for a team * Returns task activity metrics scoped to one team (the Network in ArchAgents). @@ -388,6 +413,8 @@ export class TeamTaskResource { * Returns open tasks with no unfinished blockers and no active session lease. * Readiness is calculated by the server from the current task projection. It is * a snapshot, not a reservation; claim a task lease before starting work. + * Results are ordered by priority (0, the most urgent, first), then oldest + * first, so the first page is always the most urgent ready work. * Pass `explain=true` to include every open task with a stable readiness reason. * @param team - Team ID (`tem_...`). Only tasks belonging to this team are returned. * @param params - Query parameters. @@ -403,7 +430,7 @@ export class TeamTaskResource { * @param params.afterCursor - Opaque cursor returned by the previous page. * @returns Successful response */ - async ready(team: string, params?: { user?: string; org?: string; explain?: boolean; assignedToMe?: boolean; sourceScope?: string; sourceType?: string; sourceId?: string; epic?: string; limit?: number; afterCursor?: string }): Promise<{ after_cursor?: string | undefined; authoritative: boolean; before_cursor?: string | undefined; data: { readiness: "ready" | "blocked" | "leased"; reason?: "open_blockers" | "active_lease" | null | undefined; task: { agent?: string | null | undefined; aggregate_version?: number | null | undefined; blocked_by_count?: number | undefined; closed_at?: string | null | undefined; comments_count?: number | undefined; created_at?: string | undefined; created_by_actor?: { alias?: string | null | undefined; id?: string | null | undefined; name?: string | null | undefined; profile_picture?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined } | null | undefined; created_by_agent?: string | null | undefined; created_by_user?: string | null | undefined; current_lease?: { expires_at: string; harness: string; session_name: string } | null | undefined; description?: string | null | undefined; due_date?: string | null | undefined; epic?: string | null | undefined; id: string; is_blocked?: boolean | undefined; links?: Record | undefined; metadata?: Record | undefined; name: string; org?: string | null | undefined; owner_actor?: { alias?: string | null | undefined; id?: string | null | undefined; name?: string | null | undefined; profile_picture?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined } | null | undefined; owner_agent?: string | null | undefined; owner_user?: string | null | undefined; parent?: string | null | undefined; priority?: number | undefined; sandbox?: string | null | undefined; source_id?: string | null | undefined; source_scope?: string | null | undefined; source_type?: string | null | undefined; status: string; subtasks_count?: number | undefined; tags?: string[] | undefined; team?: string | null | undefined; thread?: string | null | undefined; updated_at?: string | undefined; user?: string | null | undefined } }[]; has_more: boolean }> { + async ready(team: string, params?: { user?: string; org?: string; explain?: boolean; assignedToMe?: boolean; sourceScope?: string; sourceType?: string; sourceId?: string; epic?: string; limit?: number; afterCursor?: string }): Promise<{ after_cursor?: string | undefined; authoritative: boolean; before_cursor?: string | undefined; data: { readiness: "ready" | "blocked" | "leased"; reason?: "open_blockers" | "active_lease" | null | undefined; task: { agent?: string | null | undefined; aggregate_version?: number | null | undefined; blocked_by_count?: number | undefined; closed_at?: string | null | undefined; comments_count?: number | undefined; created_at?: string | undefined; created_by_actor?: { alias?: string | null | undefined; id?: string | null | undefined; name?: string | null | undefined; profile_picture?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined } | null | undefined; created_by_agent?: string | null | undefined; created_by_user?: string | null | undefined; current_lease?: { expires_at: string; harness: string; session_name: string } | null | undefined; description?: string | null | undefined; due_date?: string | null | undefined; epic?: string | null | undefined; id: string; is_blocked?: boolean | undefined; is_stalled?: boolean | undefined; links?: Record | undefined; metadata?: Record | undefined; name: string; org?: string | null | undefined; owner_actor?: { alias?: string | null | undefined; id?: string | null | undefined; name?: string | null | undefined; profile_picture?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined } | null | undefined; owner_agent?: string | null | undefined; owner_user?: string | null | undefined; parent?: string | null | undefined; priority?: number | undefined; project_id?: string | null | undefined; sandbox?: string | null | undefined; source_id?: string | null | undefined; source_scope?: string | null | undefined; source_type?: string | null | undefined; stalled_since?: string | null | undefined; status: string; subtasks_count?: number | undefined; tags?: string[] | undefined; target_binary?: string | null | undefined; target_version?: string | null | undefined; team?: string | null | undefined; thread?: string | null | undefined; updated_at?: string | undefined; user?: string | null | undefined } }[]; has_more: boolean }> { const query: Record | undefined> = {}; if (params?.user !== undefined) { query["user"] = params?.user; @@ -469,7 +496,7 @@ export class TeamTaskResource { * @param params.afterCursor - Opaque cursor returned by the previous page. * @returns Successful response */ - async search(team: string, params?: { user?: string; org?: string; q?: string; query?: string; status?: string; ownerUser?: string; ownerAgent?: string; priority?: number; tag?: string; parent?: string; sourceScope?: string; sourceType?: string; sourceId?: string; epic?: string; limit?: number; afterCursor?: string }): Promise<{ after_cursor?: string | undefined; before_cursor?: string | undefined; data: { agent?: string | null | undefined; aggregate_version?: number | null | undefined; blocked_by_count?: number | undefined; closed_at?: string | null | undefined; comments_count?: number | undefined; created_at?: string | undefined; created_by_actor?: { alias?: string | null | undefined; id?: string | null | undefined; name?: string | null | undefined; profile_picture?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined } | null | undefined; created_by_agent?: string | null | undefined; created_by_user?: string | null | undefined; current_lease?: { expires_at: string; harness: string; session_name: string } | null | undefined; description?: string | null | undefined; due_date?: string | null | undefined; epic?: string | null | undefined; id: string; is_blocked?: boolean | undefined; links?: Record | undefined; metadata?: Record | undefined; name: string; org?: string | null | undefined; owner_actor?: { alias?: string | null | undefined; id?: string | null | undefined; name?: string | null | undefined; profile_picture?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined } | null | undefined; owner_agent?: string | null | undefined; owner_user?: string | null | undefined; parent?: string | null | undefined; priority?: number | undefined; sandbox?: string | null | undefined; source_id?: string | null | undefined; source_scope?: string | null | undefined; source_type?: string | null | undefined; status: string; subtasks_count?: number | undefined; tags?: string[] | undefined; team?: string | null | undefined; thread?: string | null | undefined; updated_at?: string | undefined; user?: string | null | undefined }[]; has_more: boolean; query: string }> { + async search(team: string, params?: { user?: string; org?: string; q?: string; query?: string; status?: string; ownerUser?: string; ownerAgent?: string; priority?: number; tag?: string; parent?: string; sourceScope?: string; sourceType?: string; sourceId?: string; epic?: string; limit?: number; afterCursor?: string }): Promise<{ after_cursor?: string | undefined; before_cursor?: string | undefined; data: { agent?: string | null | undefined; aggregate_version?: number | null | undefined; blocked_by_count?: number | undefined; closed_at?: string | null | undefined; comments_count?: number | undefined; created_at?: string | undefined; created_by_actor?: { alias?: string | null | undefined; id?: string | null | undefined; name?: string | null | undefined; profile_picture?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined } | null | undefined; created_by_agent?: string | null | undefined; created_by_user?: string | null | undefined; current_lease?: { expires_at: string; harness: string; session_name: string } | null | undefined; description?: string | null | undefined; due_date?: string | null | undefined; epic?: string | null | undefined; id: string; is_blocked?: boolean | undefined; is_stalled?: boolean | undefined; links?: Record | undefined; metadata?: Record | undefined; name: string; org?: string | null | undefined; owner_actor?: { alias?: string | null | undefined; id?: string | null | undefined; name?: string | null | undefined; profile_picture?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined } | null | undefined; owner_agent?: string | null | undefined; owner_user?: string | null | undefined; parent?: string | null | undefined; priority?: number | undefined; project_id?: string | null | undefined; sandbox?: string | null | undefined; source_id?: string | null | undefined; source_scope?: string | null | undefined; source_type?: string | null | undefined; stalled_since?: string | null | undefined; status: string; subtasks_count?: number | undefined; tags?: string[] | undefined; target_binary?: string | null | undefined; target_version?: string | null | undefined; team?: string | null | undefined; thread?: string | null | undefined; updated_at?: string | undefined; user?: string | null | undefined }[]; has_more: boolean; query: string }> { const query: Record | undefined> = {}; if (params?.user !== undefined) { query["user"] = params?.user; @@ -543,7 +570,7 @@ export class TeamThreadResource { * @param params.tags - Optional: only return threads tagged with at least one of these tags (OR-match). Repeated query params, e.g. `?tags[]=blocked&tags[]=needs-review`. * @returns Successful response */ - async list(team: string, params?: { tags?: string[] }): Promise<{ data: { agent_user?: string | null | undefined; created_at?: string | undefined; creator?: string | { alias?: string | null | undefined; app?: string | null | undefined; app_name?: string | null | undefined; created_by_agent_user?: string | null | undefined; created_by_developer?: string | null | undefined; created_by_org?: string | null | undefined; created_by_team?: string | null | undefined; created_by_user?: string | null | undefined; email?: string | null | undefined; id: string; is_system_user?: boolean | undefined; metadata?: Record | undefined; name?: string | null | undefined; org?: string | null | undefined; org_name?: string | null | undefined; org_role?: string | null | undefined; org_slug?: string | null | undefined; sandbox?: string | null | undefined; sandbox_name?: string | null | undefined } | null | undefined; description?: string | null | undefined; id: string; is_channel?: boolean | undefined; is_default?: boolean | undefined; is_transient?: boolean | undefined; is_unlisted?: boolean | undefined; key?: string | null | undefined; kind?: string | null | undefined; last_activity?: string | null | undefined; last_message_preview?: string | null | undefined; last_message_sender?: string | null | undefined; metadata?: Record | null | undefined; muted?: boolean | undefined; org?: string | null | undefined; parent_message?: { acl?: { add?: { actions: string[]; principal?: string | undefined; principal_type: string }[] | undefined; grants?: { actions: string[]; principal?: string | undefined; principal_type: string }[] | undefined; remove?: { principal?: string | undefined; principal_type: string }[] | undefined } | null | undefined; actors?: { alias?: string | null | undefined; id?: string | null | undefined; name?: string | null | undefined; profile_picture?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined }[] | undefined; agent?: string | null | undefined; agent_mode?: "cli" | "embedded" | null | undefined; attachments?: { content_type?: string | null | undefined; description?: string | null | undefined; filename?: string | null | undefined; height?: number | null | undefined; id: string; image_height?: number | null | undefined; image_source?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined; image_url?: string | null | undefined; image_width?: number | null | undefined; key?: string | null | undefined; media_type?: string | undefined; name?: string | null | undefined; object?: Record | undefined; title?: string | null | undefined; type: string; url?: string | null | undefined; variants?: { content_type?: string | null | undefined; created_at?: string | undefined; file?: string | undefined; filename?: string | null | undefined; height?: number | null | undefined; id: string; image_source?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined; updated_at?: string | undefined; url?: string | null | undefined; variant_key?: string | undefined; width?: number | null | undefined }[] | undefined; version?: number | null | undefined; width?: number | null | undefined }[] | undefined; branched_thread?: string | null | undefined; content?: string | null | undefined; context?: { attributes?: Record | undefined; content?: string | null | undefined; title?: string | null | undefined; type: string }[] | undefined; created_at?: string | undefined; has_replies?: boolean | undefined; id: string; idempotency_key?: string | null | undefined; is_deleted?: boolean | undefined; legacy_agent?: string | null | undefined; metadata?: Record | undefined; org?: string | null | undefined; reactions?: { payload?: Record | undefined; type: string; user?: string | undefined }[] | undefined; rendering_mode?: string | null | undefined; replies?: Record[] | undefined; replies_after_cursor?: string | null | undefined; replies_before_cursor?: string | null | undefined; reply_count?: number | undefined; reply_to?: Record | null | undefined; root_message_id?: string | null | undefined; sandbox?: string | null | undefined; team?: string | null | undefined; thread?: string | undefined; type?: string | null | undefined; user?: string | { alias?: string | null | undefined; app?: string | null | undefined; app_name?: string | null | undefined; created_by_agent_user?: string | null | undefined; created_by_developer?: string | null | undefined; created_by_org?: string | null | undefined; created_by_team?: string | null | undefined; created_by_user?: string | null | undefined; email?: string | null | undefined; id: string; is_system_user?: boolean | undefined; metadata?: Record | undefined; name?: string | null | undefined; org?: string | null | undefined; org_name?: string | null | undefined; org_role?: string | null | undefined; org_slug?: string | null | undefined; sandbox?: string | null | undefined; sandbox_name?: string | null | undefined } | null | undefined; visibility?: "default" | "private" | undefined } | null | undefined; participant?: string[] | undefined; participants?: { alias?: string | null | undefined; app?: string | null | undefined; app_name?: string | null | undefined; created_by_agent_user?: string | null | undefined; created_by_developer?: string | null | undefined; created_by_org?: string | null | undefined; created_by_team?: string | null | undefined; created_by_user?: string | null | undefined; email?: string | null | undefined; id: string; is_system_user?: boolean | undefined; metadata?: Record | undefined; name?: string | null | undefined; org?: string | null | undefined; org_name?: string | null | undefined; org_role?: string | null | undefined; org_slug?: string | null | undefined; sandbox?: string | null | undefined; sandbox_name?: string | null | undefined }[] | undefined; participating_actor?: string[] | undefined; participating_agents?: { acl?: { add?: { actions: string[]; principal?: string | undefined; principal_type: string }[] | undefined; grants?: { actions: string[]; principal?: string | undefined; principal_type: string }[] | undefined; remove?: { principal?: string | undefined; principal_type: string }[] | undefined } | null | undefined; app?: string | undefined; created_at?: string | undefined; default_model?: string | null | undefined; description?: string | null | undefined; email?: string | null | undefined; id: string; identity?: string | null | undefined; last_applied_template_config?: string | null | undefined; lookup_key?: string | null | undefined; metadata?: Record | undefined; name?: string | undefined; org?: string | null | undefined; org_name?: string | null | undefined; originator?: string | null | undefined; phone_number?: string | null | undefined; sandbox?: string | null | undefined; source_solution?: { current_solution?: { category_keys?: string[] | undefined; created_at?: string | undefined; description?: string | null | undefined; events?: Record | undefined; id: string; image_url?: string | null | undefined; installed_config_ids: string[]; kind: string; latest_solution?: string | null | undefined; latest_version?: string | null | undefined; lookup_key?: string | null | undefined; metadata?: Record | undefined; name?: string | null | undefined; org?: string | null | undefined; org_logo?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined; org_name?: string | null | undefined; org_slug?: string | null | undefined; owners: string[]; readme_url?: string | null | undefined; screenshot_urls?: string[] | undefined; solution_id?: string | null | undefined; solution_version?: string | null | undefined; tag_keys?: string[] | undefined; template_kind?: string | null | undefined; templates: { description?: string | null | undefined; details?: { automation_type?: string | null | undefined; invoke_contract?: { input_schema?: Record | null | undefined; participants?: { description?: string | null | undefined; name: string; required: boolean; type: string }[] | null | undefined; prefills: { participants?: Record | undefined; payload?: Record | undefined } } | null | undefined; type: "automation" } | null | undefined; display_name?: string | null | undefined; id?: string | null | undefined; kind: string; lookup_key?: string | null | undefined; name?: string | null | undefined; readme_url?: string | null | undefined; virtual_path?: string | null | undefined }[]; updated_at?: string | undefined; upgrade_available: boolean; virtual_path?: string | null | undefined } | undefined; solution: { category_keys?: string[] | undefined; created_at?: string | undefined; description?: string | null | undefined; events?: Record | undefined; id: string; image_url?: string | null | undefined; installed_config_ids: string[]; kind: string; latest_solution?: string | null | undefined; latest_version?: string | null | undefined; lookup_key?: string | null | undefined; metadata?: Record | undefined; name?: string | null | undefined; org?: string | null | undefined; org_logo?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined; org_name?: string | null | undefined; org_slug?: string | null | undefined; owners: string[]; readme_url?: string | null | undefined; screenshot_urls?: string[] | undefined; solution_id?: string | null | undefined; solution_version?: string | null | undefined; tag_keys?: string[] | undefined; template_kind?: string | null | undefined; templates: { description?: string | null | undefined; details?: { automation_type?: string | null | undefined; invoke_contract?: { input_schema?: Record | null | undefined; participants?: { description?: string | null | undefined; name: string; required: boolean; type: string }[] | null | undefined; prefills: { participants?: Record | undefined; payload?: Record | undefined } } | null | undefined; type: "automation" } | null | undefined; display_name?: string | null | undefined; id?: string | null | undefined; kind: string; lookup_key?: string | null | undefined; name?: string | null | undefined; readme_url?: string | null | undefined; virtual_path?: string | null | undefined }[]; updated_at?: string | undefined; upgrade_available: boolean; virtual_path?: string | null | undefined }; template: { created_at?: string | undefined; description?: string | null | undefined; display_name?: string | null | undefined; id: string; kind: string; lookup_key?: string | null | undefined; name?: string | null | undefined; updated_at?: string | undefined; virtual_path?: string | null | undefined } } | null | undefined; team?: string | null | undefined; template_upgrade_available?: boolean | null | undefined; updated_at?: string | undefined; user?: string | null | undefined }[] | null | undefined; role?: string | null | undefined; sandbox?: string | null | undefined; settings?: { agent_enabled?: boolean | null | undefined } | undefined; slug?: string | null | undefined; sub_threads?: Record[] | null | undefined; tags?: string[] | undefined; team?: string | null | undefined; title?: string | null | undefined; ttl?: string | null | undefined; unread_count?: number | null | undefined; updated_at?: string | undefined; user?: string | null | undefined; visibility: "team" | "restricted" | "private" | "org" }[] }> { + async list(team: string, params?: { tags?: string[] }): Promise<{ data: { agent_user?: string | null | undefined; created_at?: string | undefined; creator?: string | { alias?: string | null | undefined; app?: string | null | undefined; app_name?: string | null | undefined; created_by_agent_user?: string | null | undefined; created_by_developer?: string | null | undefined; created_by_org?: string | null | undefined; created_by_team?: string | null | undefined; created_by_user?: string | null | undefined; email?: string | null | undefined; id: string; is_system_user?: boolean | undefined; metadata?: Record | undefined; name?: string | null | undefined; org?: string | null | undefined; org_name?: string | null | undefined; org_role?: string | null | undefined; org_slug?: string | null | undefined; sandbox?: string | null | undefined; sandbox_name?: string | null | undefined } | null | undefined; description?: string | null | undefined; id: string; is_channel?: boolean | undefined; is_default?: boolean | undefined; is_transient?: boolean | undefined; is_unlisted?: boolean | undefined; key?: string | null | undefined; kind?: string | null | undefined; last_activity?: string | null | undefined; last_message_preview?: string | null | undefined; last_message_sender?: string | null | undefined; metadata?: Record | null | undefined; muted?: boolean | undefined; org?: string | null | undefined; parent_message?: { acl?: { add?: { actions: string[]; principal?: string | undefined; principal_type: string }[] | undefined; grants?: { actions: string[]; principal?: string | undefined; principal_type: string }[] | undefined; remove?: { principal?: string | undefined; principal_type: string }[] | undefined } | null | undefined; actors?: { alias?: string | null | undefined; id?: string | null | undefined; name?: string | null | undefined; profile_picture?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined }[] | undefined; agent?: string | null | undefined; agent_mode?: "cli" | "embedded" | null | undefined; attachments?: { content_type?: string | null | undefined; description?: string | null | undefined; filename?: string | null | undefined; height?: number | null | undefined; id: string; image_height?: number | null | undefined; image_source?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined; image_url?: string | null | undefined; image_width?: number | null | undefined; key?: string | null | undefined; media_type?: string | undefined; name?: string | null | undefined; object?: Record | undefined; title?: string | null | undefined; type: string; url?: string | null | undefined; variants?: { byte_size?: number | null | undefined; content_type?: string | null | undefined; created_at?: string | undefined; duration_ms?: number | null | undefined; file?: string | undefined; filename?: string | null | undefined; height?: number | null | undefined; id: string; image_source?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined; sha256?: string | null | undefined; updated_at?: string | undefined; url?: string | null | undefined; url_expires_at?: string | null | undefined; variant_key?: string | undefined; width?: number | null | undefined }[] | undefined; version?: number | null | undefined; width?: number | null | undefined }[] | undefined; branched_thread?: string | null | undefined; content?: string | null | undefined; context?: { attributes?: Record | undefined; content?: string | null | undefined; title?: string | null | undefined; type: string }[] | undefined; created_at?: string | undefined; has_replies?: boolean | undefined; id: string; idempotency_key?: string | null | undefined; is_deleted?: boolean | undefined; legacy_agent?: string | null | undefined; metadata?: Record | undefined; org?: string | null | undefined; reactions?: { payload?: Record | undefined; type: string; user?: string | undefined }[] | undefined; rendering_mode?: string | null | undefined; replies?: Record[] | undefined; replies_after_cursor?: string | null | undefined; replies_before_cursor?: string | null | undefined; reply_count?: number | undefined; reply_to?: Record | null | undefined; root_message_id?: string | null | undefined; sandbox?: string | null | undefined; team?: string | null | undefined; thread?: string | undefined; type?: string | null | undefined; user?: string | { alias?: string | null | undefined; app?: string | null | undefined; app_name?: string | null | undefined; created_by_agent_user?: string | null | undefined; created_by_developer?: string | null | undefined; created_by_org?: string | null | undefined; created_by_team?: string | null | undefined; created_by_user?: string | null | undefined; email?: string | null | undefined; id: string; is_system_user?: boolean | undefined; metadata?: Record | undefined; name?: string | null | undefined; org?: string | null | undefined; org_name?: string | null | undefined; org_role?: string | null | undefined; org_slug?: string | null | undefined; sandbox?: string | null | undefined; sandbox_name?: string | null | undefined } | null | undefined; visibility?: "default" | "private" | undefined } | null | undefined; participant?: string[] | undefined; participants?: { alias?: string | null | undefined; app?: string | null | undefined; app_name?: string | null | undefined; created_by_agent_user?: string | null | undefined; created_by_developer?: string | null | undefined; created_by_org?: string | null | undefined; created_by_team?: string | null | undefined; created_by_user?: string | null | undefined; email?: string | null | undefined; id: string; is_system_user?: boolean | undefined; metadata?: Record | undefined; name?: string | null | undefined; org?: string | null | undefined; org_name?: string | null | undefined; org_role?: string | null | undefined; org_slug?: string | null | undefined; sandbox?: string | null | undefined; sandbox_name?: string | null | undefined }[] | undefined; participating_actor?: string[] | undefined; participating_agents?: { acl?: { add?: { actions: string[]; principal?: string | undefined; principal_type: string }[] | undefined; grants?: { actions: string[]; principal?: string | undefined; principal_type: string }[] | undefined; remove?: { principal?: string | undefined; principal_type: string }[] | undefined } | null | undefined; app?: string | undefined; created_at?: string | undefined; default_model?: string | null | undefined; description?: string | null | undefined; email?: string | null | undefined; id: string; identity?: string | null | undefined; last_applied_template_config?: string | null | undefined; lookup_key?: string | null | undefined; metadata?: Record | undefined; name?: string | undefined; org?: string | null | undefined; org_name?: string | null | undefined; originator?: string | null | undefined; phone_number?: string | null | undefined; sandbox?: string | null | undefined; source_solution?: { current_solution?: { category_keys?: string[] | undefined; created_at?: string | undefined; description?: string | null | undefined; events?: Record | undefined; id: string; image_url?: string | null | undefined; installed_config_ids: string[]; kind: string; latest_solution?: string | null | undefined; latest_version?: string | null | undefined; lookup_key?: string | null | undefined; metadata?: Record | undefined; name?: string | null | undefined; org?: string | null | undefined; org_logo?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined; org_name?: string | null | undefined; org_slug?: string | null | undefined; owners: string[]; readme_url?: string | null | undefined; screenshot_urls?: string[] | undefined; solution_id?: string | null | undefined; solution_version?: string | null | undefined; tag_keys?: string[] | undefined; template_kind?: string | null | undefined; templates: { description?: string | null | undefined; details?: { automation_type?: string | null | undefined; invoke_contract?: { input_schema?: Record | null | undefined; participants?: { description?: string | null | undefined; name: string; required: boolean; type: string }[] | null | undefined; prefills: { participants?: Record | undefined; payload?: Record | undefined } } | null | undefined; type: "automation" } | null | undefined; display_name?: string | null | undefined; id?: string | null | undefined; kind: string; lookup_key?: string | null | undefined; name?: string | null | undefined; readme_url?: string | null | undefined; virtual_path?: string | null | undefined }[]; updated_at?: string | undefined; upgrade_available: boolean; virtual_path?: string | null | undefined } | undefined; solution: { category_keys?: string[] | undefined; created_at?: string | undefined; description?: string | null | undefined; events?: Record | undefined; id: string; image_url?: string | null | undefined; installed_config_ids: string[]; kind: string; latest_solution?: string | null | undefined; latest_version?: string | null | undefined; lookup_key?: string | null | undefined; metadata?: Record | undefined; name?: string | null | undefined; org?: string | null | undefined; org_logo?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined; org_name?: string | null | undefined; org_slug?: string | null | undefined; owners: string[]; readme_url?: string | null | undefined; screenshot_urls?: string[] | undefined; solution_id?: string | null | undefined; solution_version?: string | null | undefined; tag_keys?: string[] | undefined; template_kind?: string | null | undefined; templates: { description?: string | null | undefined; details?: { automation_type?: string | null | undefined; invoke_contract?: { input_schema?: Record | null | undefined; participants?: { description?: string | null | undefined; name: string; required: boolean; type: string }[] | null | undefined; prefills: { participants?: Record | undefined; payload?: Record | undefined } } | null | undefined; type: "automation" } | null | undefined; display_name?: string | null | undefined; id?: string | null | undefined; kind: string; lookup_key?: string | null | undefined; name?: string | null | undefined; readme_url?: string | null | undefined; virtual_path?: string | null | undefined }[]; updated_at?: string | undefined; upgrade_available: boolean; virtual_path?: string | null | undefined }; template: { created_at?: string | undefined; description?: string | null | undefined; display_name?: string | null | undefined; id: string; kind: string; lookup_key?: string | null | undefined; name?: string | null | undefined; updated_at?: string | undefined; virtual_path?: string | null | undefined } } | null | undefined; team?: string | null | undefined; template_upgrade_available?: boolean | null | undefined; updated_at?: string | undefined; user?: string | null | undefined }[] | null | undefined; role?: string | null | undefined; sandbox?: string | null | undefined; settings?: { agent_enabled?: boolean | null | undefined } | undefined; slug?: string | null | undefined; sub_threads?: Record[] | null | undefined; tags?: string[] | undefined; team?: string | null | undefined; title?: string | null | undefined; ttl?: string | null | undefined; unread_count?: number | null | undefined; updated_at?: string | undefined; user?: string | null | undefined; visibility: "team" | "restricted" | "private" | "org" }[] }> { const query: Record | undefined> = {}; if (params?.tags !== undefined) { query["tags"] = params?.tags; @@ -764,7 +791,7 @@ export class TeamResource { * @param params.groupKeyPrefix - Nonempty case-sensitive literal prefix (percent, underscore and backslash are literal). Mutually exclusive with group_key. * @returns Successful response */ - async artifacts(team: string, params?: { groupKey?: string; groupKeyPrefix?: string }): Promise<{ data: { agent?: string | undefined; content_type?: string | undefined; created_at?: string | undefined; current_version?: string | undefined; description?: string | undefined; file?: string | undefined; file_name?: string | undefined; file_url?: string | undefined; group_key?: string | null | undefined; id: string; image_source?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | undefined; name?: string | undefined; org?: string | undefined; sandbox?: string | undefined; system?: boolean | undefined; team?: string | undefined; thread?: string | undefined; updated_at?: string | undefined; user?: string | undefined; version?: number | undefined }[] }> { + async artifacts(team: string, params?: { groupKey?: string; groupKeyPrefix?: string }): Promise<{ data: { acl?: { add?: { actions: string[]; principal?: string | undefined; principal_type: string }[] | undefined; grants?: { actions: string[]; principal?: string | undefined; principal_type: string }[] | undefined; remove?: { principal?: string | undefined; principal_type: string }[] | undefined } | null | undefined; agent?: string | undefined; content_type?: string | undefined; created_at?: string | undefined; current_version?: string | undefined; description?: string | undefined; file?: string | undefined; file_name?: string | undefined; file_url?: string | undefined; group_key?: string | null | undefined; id: string; image_source?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | undefined; name?: string | undefined; org?: string | undefined; sandbox?: string | undefined; system?: boolean | undefined; team?: string | undefined; thread?: string | undefined; updated_at?: string | undefined; user?: string | undefined; version?: number | undefined }[] }> { const query: Record | undefined> = {}; if (params?.groupKey !== undefined) { query["group_key"] = params?.groupKey; @@ -866,4 +893,50 @@ export class TeamResource { return this.http.request(`/api/v1/teams/${team}/task_assignees`, { query }); } + + /** + * 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. + * @param params - Query parameters. + * @param params.sourceScope - Exact source scope; supply all three source fields. + * @param params.sourceType - Exact source type. + * @param params.sourceId - Exact source ID. + * @param params.topPriority - Exact highest open priority, from 0 to 4. + * @param params.includeClosed - Include epics with no non-closed tasks; defaults to false. + * @param params.limit - Maximum epics; defaults to 50, capped at 100. + * @param params.afterCursor - Opaque forward cursor from the preceding page. + * @returns Successful response + */ + async taskEpics(team: string, params?: { user?: string; org?: string; sourceScope?: string; sourceType?: string; sourceId?: string; topPriority?: number; includeClosed?: boolean; limit?: number; afterCursor?: string }): Promise<{ after_cursor?: string | null | undefined; before_cursor?: string | null | undefined; data: { blocked_count: number; counts: Record; epic: string; next_ready: { id: string; name: string; priority: number; status: string }[]; root_blockers: { downstream_count: number; id: string; name: string; priority: number; status: string }[]; root_blockers_partial: boolean; top_open_priority?: number | null | undefined; updated_at: string }[]; has_more: boolean; no_epic_open_count: number }> { + const query: Record | undefined> = {}; + if (params?.user !== undefined) { + query["user"] = params?.user; + } + if (params?.org !== undefined) { + query["org"] = params?.org; + } + if (params?.sourceScope !== undefined) { + query["source_scope"] = params?.sourceScope; + } + if (params?.sourceType !== undefined) { + query["source_type"] = params?.sourceType; + } + if (params?.sourceId !== undefined) { + query["source_id"] = params?.sourceId; + } + if (params?.topPriority !== undefined) { + query["top_priority"] = params?.topPriority; + } + if (params?.includeClosed !== undefined) { + query["include_closed"] = params?.includeClosed; + } + if (params?.limit !== undefined) { + query["limit"] = params?.limit; + } + if (params?.afterCursor !== undefined) { + query["after_cursor"] = params?.afterCursor; + } + + return this.http.request(`/api/v1/teams/${team}/task_epics`, { query }); + } } diff --git a/packages/sdk/src/v1/resources/threads.ts b/packages/sdk/src/v1/resources/threads.ts index 9d57172..1f82df2 100644 --- a/packages/sdk/src/v1/resources/threads.ts +++ b/packages/sdk/src/v1/resources/threads.ts @@ -1,11 +1,44 @@ // Copyright (c) 2026 ArchAstro Inc. Licensed under the MIT License. // This file is auto-generated by @archastro/sdk-generator. Do not edit. -// Content hash: be2fed0336bc +// Content hash: f285eb136004 import { HttpClient } from "../../runtime/http-client.js"; import type { ChatMember } from "../../types/chat.js"; +import type { AgentComputer, AgentComputerListResponse } from "../../types/common.js"; import type { Thread, ThreadReadStatus, ThreadSettings } from "../../types/threads.js"; +export class ComputerResource { + constructor(private http: HttpClient) {} + + /** + * List a thread's computers + * Returns all live computers in the visible thread, oldest first, without pagination. + * @param thread - Thread ID (`thr_...`). + * @returns The thread's live computers. + */ + async list(thread: string): Promise { + return this.http.request(`/api/v1/threads/${thread}/computers`); + } + + /** + * 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. + * @param thread - Thread ID (`thr_...`). + * @param input - Request body. + * @param input.acl - Initial access control list. + * @param input.config - Provider configuration; top-level provider takes precedence. + * @param input.key - Stable key unique within this thread. + * @param input.metadata - Arbitrary computer metadata. + * @param input.name - Human-readable computer name. + * @param input.provider - Compute backend: sprites (default), vercel or e2b. + * @param input.region - Provider region; defaults to iad. + * @returns The newly created computer. Returns HTTP 201. + */ + async create(thread: string, input: { acl?: { add?: { actions: string[]; principal?: string | undefined; principal_type: string }[] | undefined; grants?: { actions: string[]; principal?: string | undefined; principal_type: string }[] | undefined; remove?: { principal?: string | undefined; principal_type: string }[] | undefined } | undefined; config?: Record | undefined; key?: string | undefined; metadata?: Record | undefined; name: string; provider?: string | undefined; region?: string | undefined }): Promise { + return this.http.request(`/api/v1/threads/${thread}/computers`, { method: "POST", body: input }); + } +} + export class ThreadMemberResource { constructor(private http: HttpClient) {} @@ -148,11 +181,13 @@ export class TagResource { } export class ThreadResource { + readonly computers: ComputerResource; readonly members: ThreadMemberResource; readonly settings: SettingResource; readonly tags: TagResource; constructor(private http: HttpClient) { + this.computers = new ComputerResource(http); this.members = new ThreadMemberResource(http); this.settings = new SettingResource(http); this.tags = new TagResource(http); @@ -245,7 +280,7 @@ export class ThreadResource { * @param params.groupKeyPrefix - Nonempty case-sensitive literal prefix (percent, underscore and backslash are literal). Mutually exclusive with group_key. * @returns Successful response */ - async artifacts(thread: string, params?: { groupKey?: string; groupKeyPrefix?: string }): Promise<{ data: { agent?: string | undefined; content_type?: string | undefined; created_at?: string | undefined; current_version?: string | undefined; description?: string | undefined; file?: string | undefined; file_name?: string | undefined; file_url?: string | undefined; group_key?: string | null | undefined; id: string; image_source?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | undefined; name?: string | undefined; org?: string | undefined; sandbox?: string | undefined; system?: boolean | undefined; team?: string | undefined; thread?: string | undefined; updated_at?: string | undefined; user?: string | undefined; version?: number | undefined }[] }> { + async artifacts(thread: string, params?: { groupKey?: string; groupKeyPrefix?: string }): Promise<{ data: { acl?: { add?: { actions: string[]; principal?: string | undefined; principal_type: string }[] | undefined; grants?: { actions: string[]; principal?: string | undefined; principal_type: string }[] | undefined; remove?: { principal?: string | undefined; principal_type: string }[] | undefined } | null | undefined; agent?: string | undefined; content_type?: string | undefined; created_at?: string | undefined; current_version?: string | undefined; description?: string | undefined; file?: string | undefined; file_name?: string | undefined; file_url?: string | undefined; group_key?: string | null | undefined; id: string; image_source?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | undefined; name?: string | undefined; org?: string | undefined; sandbox?: string | undefined; system?: boolean | undefined; team?: string | undefined; thread?: string | undefined; updated_at?: string | undefined; user?: string | undefined; version?: number | undefined }[] }> { const query: Record | undefined> = {}; if (params?.groupKey !== undefined) { query["group_key"] = params?.groupKey; @@ -293,6 +328,9 @@ export class ThreadResource { * is returned if the thread does not exist or is not visible to the authenticated user. * Threads with `kind: feed` return only top-level posts, each with its newest * replies inline under `replies` and reply cursors for paging the rest. + * Set `include_replies: true` to page messages and replies together by creation + * order instead, without inline reply previews. Metadata filters and the page + * limit apply to the updates themselves, before any client-side grouping. * Pass `include_reply_counts: true` to annotate each message with the number of * threaded replies it has received. This adds a small amount of latency and should * be omitted when reply counts are not needed. @@ -302,6 +340,7 @@ export class ThreadResource { * @param params.afterCursor - Opaque cursor returned in a previous response's `after_cursor` field. When provided, returns messages immediately after that position. May be combined with `before_cursor` to bound a range. * @param params.metadata - Structured metadata filter expression. Only messages whose `metadata` object satisfies the expression are returned. The filter is applied before cursor pagination and anchored window limits. * @param params.limit - Maximum number of messages to return per page. Defaults to 20; maximum is 100. + * @param params.includeReplies - Include replies in feed message pagination instead of returning root posts with inline replies. Defaults to false. * @param params.anchor - Message ID (`msg_...`) to use as a window anchor, or `last_matching` to resolve the anchor from the latest message matching the anchor filters. Cannot be combined with `before_cursor` or `after_cursor`. * @param params.direction - Window direction relative to `anchor`. `before` returns older messages, `after` returns newer messages, and `around` returns messages on both sides. Defaults to `after` when `anchor` is supplied. `direction=around` cannot be combined with an explicit `limit`; use `before_limit` and `after_limit`. * @param params.beforeLimit - For `direction=around`, maximum number of messages older than the anchor. Defaults to 20; maximum is 100. @@ -312,7 +351,7 @@ export class ThreadResource { * @param params.includeReplyCounts - When `true`, each message in the response is annotated with its threaded reply count. Defaults to `false`. Adds latency; omit when reply counts are not needed. * @returns Successful response */ - async messages(thread: string, params?: { beforeCursor?: string; afterCursor?: string; metadata?: { clause?: Record | undefined; clauses?: Record[] | undefined; key?: string | undefined; operator?: "and" | "or" | "eq" | "contains" | "exists" | "not" | undefined; path?: string[] | undefined; type?: string | undefined; value?: unknown | undefined }; limit?: number; anchor?: string; direction?: "before" | "after" | "around"; beforeLimit?: number; afterLimit?: number; includeAnchor?: boolean; anchorAgentMode?: "cli" | "embedded"; anchorAgent?: string; includeReplyCounts?: boolean }): Promise<{ data: { after_cursor?: string | null | undefined; anchor?: string | null | undefined; before_cursor?: string | null | undefined; messages: { acl?: { add?: { actions: string[]; principal?: string | undefined; principal_type: string }[] | undefined; grants?: { actions: string[]; principal?: string | undefined; principal_type: string }[] | undefined; remove?: { principal?: string | undefined; principal_type: string }[] | undefined } | null | undefined; actors?: { alias?: string | null | undefined; id?: string | null | undefined; name?: string | null | undefined; profile_picture?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined }[] | undefined; agent?: string | null | undefined; agent_mode?: "cli" | "embedded" | null | undefined; attachments?: { content_type?: string | null | undefined; description?: string | null | undefined; filename?: string | null | undefined; height?: number | null | undefined; id: string; image_height?: number | null | undefined; image_source?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined; image_url?: string | null | undefined; image_width?: number | null | undefined; key?: string | null | undefined; media_type?: string | undefined; name?: string | null | undefined; object?: Record | undefined; title?: string | null | undefined; type: string; url?: string | null | undefined; variants?: { content_type?: string | null | undefined; created_at?: string | undefined; file?: string | undefined; filename?: string | null | undefined; height?: number | null | undefined; id: string; image_source?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined; updated_at?: string | undefined; url?: string | null | undefined; variant_key?: string | undefined; width?: number | null | undefined }[] | undefined; version?: number | null | undefined; width?: number | null | undefined }[] | undefined; branched_thread?: string | null | undefined; content?: string | null | undefined; context?: { attributes?: Record | undefined; content?: string | null | undefined; title?: string | null | undefined; type: string }[] | undefined; created_at?: string | undefined; has_replies?: boolean | undefined; id: string; idempotency_key?: string | null | undefined; is_deleted?: boolean | undefined; legacy_agent?: string | null | undefined; metadata?: Record | undefined; org?: string | null | undefined; reactions?: { payload?: Record | undefined; type: string; user?: string | undefined }[] | undefined; rendering_mode?: string | null | undefined; replies?: Record[] | undefined; replies_after_cursor?: string | null | undefined; replies_before_cursor?: string | null | undefined; reply_count?: number | undefined; reply_to?: Record | null | undefined; root_message_id?: string | null | undefined; sandbox?: string | null | undefined; team?: string | null | undefined; thread?: string | undefined; type?: string | null | undefined; user?: string | { alias?: string | null | undefined; app?: string | null | undefined; app_name?: string | null | undefined; created_by_agent_user?: string | null | undefined; created_by_developer?: string | null | undefined; created_by_org?: string | null | undefined; created_by_team?: string | null | undefined; created_by_user?: string | null | undefined; email?: string | null | undefined; id: string; is_system_user?: boolean | undefined; metadata?: Record | undefined; name?: string | null | undefined; org?: string | null | undefined; org_name?: string | null | undefined; org_role?: string | null | undefined; org_slug?: string | null | undefined; sandbox?: string | null | undefined; sandbox_name?: string | null | undefined } | null | undefined; visibility?: "default" | "private" | undefined }[] } }> { + async messages(thread: string, params?: { beforeCursor?: string; afterCursor?: string; metadata?: { clause?: Record | undefined; clauses?: Record[] | undefined; key?: string | undefined; operator?: "and" | "or" | "eq" | "contains" | "exists" | "not" | undefined; path?: string[] | undefined; type?: string | undefined; value?: unknown | undefined }; limit?: number; includeReplies?: boolean; anchor?: string; direction?: "before" | "after" | "around"; beforeLimit?: number; afterLimit?: number; includeAnchor?: boolean; anchorAgentMode?: "cli" | "embedded"; anchorAgent?: string; includeReplyCounts?: boolean }): Promise<{ data: { after_cursor?: string | null | undefined; anchor?: string | null | undefined; before_cursor?: string | null | undefined; messages: { acl?: { add?: { actions: string[]; principal?: string | undefined; principal_type: string }[] | undefined; grants?: { actions: string[]; principal?: string | undefined; principal_type: string }[] | undefined; remove?: { principal?: string | undefined; principal_type: string }[] | undefined } | null | undefined; actors?: { alias?: string | null | undefined; id?: string | null | undefined; name?: string | null | undefined; profile_picture?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined }[] | undefined; agent?: string | null | undefined; agent_mode?: "cli" | "embedded" | null | undefined; attachments?: { content_type?: string | null | undefined; description?: string | null | undefined; filename?: string | null | undefined; height?: number | null | undefined; id: string; image_height?: number | null | undefined; image_source?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined; image_url?: string | null | undefined; image_width?: number | null | undefined; key?: string | null | undefined; media_type?: string | undefined; name?: string | null | undefined; object?: Record | undefined; title?: string | null | undefined; type: string; url?: string | null | undefined; variants?: { byte_size?: number | null | undefined; content_type?: string | null | undefined; created_at?: string | undefined; duration_ms?: number | null | undefined; file?: string | undefined; filename?: string | null | undefined; height?: number | null | undefined; id: string; image_source?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined; sha256?: string | null | undefined; updated_at?: string | undefined; url?: string | null | undefined; url_expires_at?: string | null | undefined; variant_key?: string | undefined; width?: number | null | undefined }[] | undefined; version?: number | null | undefined; width?: number | null | undefined }[] | undefined; branched_thread?: string | null | undefined; content?: string | null | undefined; context?: { attributes?: Record | undefined; content?: string | null | undefined; title?: string | null | undefined; type: string }[] | undefined; created_at?: string | undefined; has_replies?: boolean | undefined; id: string; idempotency_key?: string | null | undefined; is_deleted?: boolean | undefined; legacy_agent?: string | null | undefined; metadata?: Record | undefined; org?: string | null | undefined; reactions?: { payload?: Record | undefined; type: string; user?: string | undefined }[] | undefined; rendering_mode?: string | null | undefined; replies?: Record[] | undefined; replies_after_cursor?: string | null | undefined; replies_before_cursor?: string | null | undefined; reply_count?: number | undefined; reply_to?: Record | null | undefined; root_message_id?: string | null | undefined; sandbox?: string | null | undefined; team?: string | null | undefined; thread?: string | undefined; type?: string | null | undefined; user?: string | { alias?: string | null | undefined; app?: string | null | undefined; app_name?: string | null | undefined; created_by_agent_user?: string | null | undefined; created_by_developer?: string | null | undefined; created_by_org?: string | null | undefined; created_by_team?: string | null | undefined; created_by_user?: string | null | undefined; email?: string | null | undefined; id: string; is_system_user?: boolean | undefined; metadata?: Record | undefined; name?: string | null | undefined; org?: string | null | undefined; org_name?: string | null | undefined; org_role?: string | null | undefined; org_slug?: string | null | undefined; sandbox?: string | null | undefined; sandbox_name?: string | null | undefined } | null | undefined; visibility?: "default" | "private" | undefined }[] } }> { const query: Record | undefined> = {}; if (params?.beforeCursor !== undefined) { query["before_cursor"] = params?.beforeCursor; @@ -326,6 +365,9 @@ export class ThreadResource { if (params?.limit !== undefined) { query["limit"] = params?.limit; } + if (params?.includeReplies !== undefined) { + query["include_replies"] = params?.includeReplies; + } if (params?.anchor !== undefined) { query["anchor"] = params?.anchor; } diff --git a/packages/sdk/src/v1/resources/users.ts b/packages/sdk/src/v1/resources/users.ts index 79034a0..afc8f7e 100644 --- a/packages/sdk/src/v1/resources/users.ts +++ b/packages/sdk/src/v1/resources/users.ts @@ -1,11 +1,11 @@ // Copyright (c) 2026 ArchAstro Inc. Licensed under the MIT License. // This file is auto-generated by @archastro/sdk-generator. Do not edit. -// Content hash: 2b68891c9d43 +// Content hash: 9c34967d89f6 import { HttpClient } from "../../runtime/http-client.js"; import type { CurrentUser } from "../../types/common.js"; import type { SystemAccessToken } from "../../types/system.js"; -import type { Task } from "../../types/tasks.js"; +import type { Task, TaskEnsureResult } from "../../types/tasks.js"; import type { Thread } from "../../types/threads.js"; import type { User, UserInvite, UserSSHKey } from "../../types/users.js"; @@ -106,11 +106,12 @@ export class UserTaskResource { * @param params.dueAfter - Return only tasks with a due date strictly after this ISO 8601 datetime or date. Tasks without a due date are excluded. * @param params.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. * @param params.ready - When true, return only open tasks with no unfinished blockers and no active session lease. This is a projection snapshot; claim a lease before starting work. + * @param params.attention - When true, return paused, failed, or in-progress tasks with no lease or a past lease expiry. * @param params.limit - Maximum number of tasks to return. Capped at 100. * @param params.afterCursor - Opaque cursor returned by the previous page. * @returns Successful response */ - async list(user: string, params?: { team?: string; org?: string; status?: string; ownerUser?: string; ownerAgent?: string; priority?: number; tag?: string; parent?: string; sourceScope?: string; sourceType?: string; sourceId?: string; epic?: string; search?: string; sort?: string; order?: string; dueBefore?: string; dueAfter?: string; overdue?: boolean; ready?: boolean; limit?: number; afterCursor?: string }): Promise<{ after_cursor?: string | null | undefined; before_cursor?: string | null | undefined; data: { agent?: string | null | undefined; aggregate_version?: number | null | undefined; blocked_by_count?: number | undefined; closed_at?: string | null | undefined; comments_count?: number | undefined; created_at?: string | undefined; created_by_actor?: { alias?: string | null | undefined; id?: string | null | undefined; name?: string | null | undefined; profile_picture?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined } | null | undefined; created_by_agent?: string | null | undefined; created_by_user?: string | null | undefined; current_lease?: { expires_at: string; harness: string; session_name: string } | null | undefined; description?: string | null | undefined; due_date?: string | null | undefined; epic?: string | null | undefined; id: string; is_blocked?: boolean | undefined; links?: Record | undefined; metadata?: Record | undefined; name: string; org?: string | null | undefined; owner_actor?: { alias?: string | null | undefined; id?: string | null | undefined; name?: string | null | undefined; profile_picture?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined } | null | undefined; owner_agent?: string | null | undefined; owner_user?: string | null | undefined; parent?: string | null | undefined; priority?: number | undefined; sandbox?: string | null | undefined; source_id?: string | null | undefined; source_scope?: string | null | undefined; source_type?: string | null | undefined; status: string; subtasks_count?: number | undefined; tags?: string[] | undefined; team?: string | null | undefined; thread?: string | null | undefined; updated_at?: string | undefined; user?: string | null | undefined }[]; has_more: boolean }> { + async list(user: string, params?: { team?: string; org?: string; status?: string; ownerUser?: string; ownerAgent?: string; priority?: number; tag?: string; parent?: string; sourceScope?: string; sourceType?: string; sourceId?: string; epic?: string; search?: string; sort?: string; order?: string; dueBefore?: string; dueAfter?: string; overdue?: boolean; ready?: boolean; attention?: boolean; limit?: number; afterCursor?: string }): Promise<{ after_cursor?: string | null | undefined; before_cursor?: string | null | undefined; data: { agent?: string | null | undefined; aggregate_version?: number | null | undefined; blocked_by_count?: number | undefined; closed_at?: string | null | undefined; comments_count?: number | undefined; created_at?: string | undefined; created_by_actor?: { alias?: string | null | undefined; id?: string | null | undefined; name?: string | null | undefined; profile_picture?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined } | null | undefined; created_by_agent?: string | null | undefined; created_by_user?: string | null | undefined; current_lease?: { expires_at: string; harness: string; session_name: string } | null | undefined; description?: string | null | undefined; due_date?: string | null | undefined; epic?: string | null | undefined; id: string; is_blocked?: boolean | undefined; is_stalled?: boolean | undefined; links?: Record | undefined; metadata?: Record | undefined; name: string; org?: string | null | undefined; owner_actor?: { alias?: string | null | undefined; id?: string | null | undefined; name?: string | null | undefined; profile_picture?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined } | null | undefined; owner_agent?: string | null | undefined; owner_user?: string | null | undefined; parent?: string | null | undefined; priority?: number | undefined; project_id?: string | null | undefined; sandbox?: string | null | undefined; source_id?: string | null | undefined; source_scope?: string | null | undefined; source_type?: string | null | undefined; stalled_since?: string | null | undefined; status: string; subtasks_count?: number | undefined; tags?: string[] | undefined; target_binary?: string | null | undefined; target_version?: string | null | undefined; team?: string | null | undefined; thread?: string | null | undefined; updated_at?: string | undefined; user?: string | null | undefined }[]; has_more: boolean }> { const query: Record | undefined> = {}; if (params?.team !== undefined) { query["team"] = params?.team; @@ -169,6 +170,9 @@ export class UserTaskResource { if (params?.ready !== undefined) { query["ready"] = params?.ready; } + if (params?.attention !== undefined) { + query["attention"] = params?.attention; + } if (params?.limit !== undefined) { query["limit"] = params?.limit; } @@ -196,7 +200,7 @@ export class UserTaskResource { * @param input.team - Team ID (`tem_...`). The task will be owned by this team. * @returns The newly created task. */ - async create(user: string, input: { agent?: string | undefined; org?: string | undefined; task: { description?: string | undefined; due_date?: string | undefined; epic?: string | undefined; id?: string | undefined; links?: Record | undefined; metadata?: Record | undefined; name: string; owner_agent?: string | undefined; owner_user?: string | undefined; parent?: string | undefined; priority?: number | undefined; source_id?: string | undefined; source_scope?: string | undefined; source_type?: string | undefined; status?: string | undefined; tags?: string[] | undefined; thread?: string | undefined }; team?: string | undefined }): Promise { + async create(user: string, input: { agent?: string | undefined; org?: string | undefined; task: { description?: string | undefined; due_date?: string | undefined; epic?: string | undefined; id?: string | undefined; links?: Record | undefined; metadata?: Record | undefined; name: string; owner_agent?: string | undefined; owner_user?: string | undefined; parent?: string | undefined; priority?: number | undefined; project_id?: string | undefined; source_id?: string | undefined; source_scope?: string | undefined; source_type?: string | undefined; status?: string | undefined; tags?: string[] | undefined; target_binary?: string | undefined; target_version?: string | undefined; thread?: string | undefined }; team?: string | undefined }): Promise { return this.http.request(`/api/v1/users/${user}/tasks`, { method: "POST", body: input }); } @@ -215,7 +219,7 @@ export class UserTaskResource { * @param params.afterCursor - Opaque cursor returned by the preceding page. * @returns Successful response */ - async blockerCycles(user: string, params?: { team?: string; org?: string; limit?: number; afterCursor?: string }): Promise<{ after_cursor?: string | undefined; before_cursor?: string | undefined; data: { tasks: { agent?: string | null | undefined; aggregate_version?: number | null | undefined; blocked_by_count?: number | undefined; closed_at?: string | null | undefined; comments_count?: number | undefined; created_at?: string | undefined; created_by_actor?: { alias?: string | null | undefined; id?: string | null | undefined; name?: string | null | undefined; profile_picture?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined } | null | undefined; created_by_agent?: string | null | undefined; created_by_user?: string | null | undefined; current_lease?: { expires_at: string; harness: string; session_name: string } | null | undefined; description?: string | null | undefined; due_date?: string | null | undefined; epic?: string | null | undefined; id: string; is_blocked?: boolean | undefined; links?: Record | undefined; metadata?: Record | undefined; name: string; org?: string | null | undefined; owner_actor?: { alias?: string | null | undefined; id?: string | null | undefined; name?: string | null | undefined; profile_picture?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined } | null | undefined; owner_agent?: string | null | undefined; owner_user?: string | null | undefined; parent?: string | null | undefined; priority?: number | undefined; sandbox?: string | null | undefined; source_id?: string | null | undefined; source_scope?: string | null | undefined; source_type?: string | null | undefined; status: string; subtasks_count?: number | undefined; tags?: string[] | undefined; team?: string | null | undefined; thread?: string | null | undefined; updated_at?: string | undefined; user?: string | null | undefined }[] }[]; has_more: boolean }> { + async blockerCycles(user: string, params?: { team?: string; org?: string; limit?: number; afterCursor?: string }): Promise<{ after_cursor?: string | undefined; before_cursor?: string | undefined; data: { tasks: { agent?: string | null | undefined; aggregate_version?: number | null | undefined; blocked_by_count?: number | undefined; closed_at?: string | null | undefined; comments_count?: number | undefined; created_at?: string | undefined; created_by_actor?: { alias?: string | null | undefined; id?: string | null | undefined; name?: string | null | undefined; profile_picture?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined } | null | undefined; created_by_agent?: string | null | undefined; created_by_user?: string | null | undefined; current_lease?: { expires_at: string; harness: string; session_name: string } | null | undefined; description?: string | null | undefined; due_date?: string | null | undefined; epic?: string | null | undefined; id: string; is_blocked?: boolean | undefined; is_stalled?: boolean | undefined; links?: Record | undefined; metadata?: Record | undefined; name: string; org?: string | null | undefined; owner_actor?: { alias?: string | null | undefined; id?: string | null | undefined; name?: string | null | undefined; profile_picture?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined } | null | undefined; owner_agent?: string | null | undefined; owner_user?: string | null | undefined; parent?: string | null | undefined; priority?: number | undefined; project_id?: string | null | undefined; sandbox?: string | null | undefined; source_id?: string | null | undefined; source_scope?: string | null | undefined; source_type?: string | null | undefined; stalled_since?: string | null | undefined; status: string; subtasks_count?: number | undefined; tags?: string[] | undefined; target_binary?: string | null | undefined; target_version?: string | null | undefined; team?: string | null | undefined; thread?: string | null | undefined; updated_at?: string | undefined; user?: string | null | undefined }[] }[]; has_more: boolean }> { const query: Record | undefined> = {}; if (params?.team !== undefined) { query["team"] = params?.team; @@ -233,11 +237,34 @@ export class UserTaskResource { return this.http.request(`/api/v1/users/${user}/tasks/blocker_cycles`, { query }); } + /** + * Find or create a task by source + * 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. + * @param user - User ID (`usr_...`) for user-scoped tasks. + * @param input - Request body. + * @param input.agent - Explicit acting agent for privileged callers. + * @param input.description - Initial task description. + * @param input.epic - Initial epic grouping. + * @param input.name - Initial task name. + * @param input.org - Explicit organization for privileged callers. + * @param input.source_id - Source identity, for example owner/repo#123. + * @param input.source_scope - Source scope, for example github. + * @param input.source_type - Source type, for example pull_request. + * @param input.status - Initial task status. + * @param input.team - Team owner. + * @returns The task and whether this request created it. + */ + async bySource(user: string, input: { agent?: string | undefined; description?: string | undefined; epic?: string | undefined; name: string; org?: string | undefined; source_id: string; source_scope: string; source_type: string; status?: string | undefined; team?: string | undefined }): Promise { + return this.http.request(`/api/v1/users/${user}/tasks/by-source`, { method: "PUT", body: input }); + } + /** * List an owner's ready tasks * Returns open tasks with no unfinished blockers and no active session lease. * Readiness is calculated by the server from the current task projection. It is * a snapshot, not a reservation; claim a task lease before starting work. + * Results are ordered by priority (0, the most urgent, first), then oldest + * first, so the first page is always the most urgent ready work. * Pass `explain=true` to include every open task with a stable readiness reason. * @param user - User ID (`usr_...`) for user-scoped tasks. * @param params - Query parameters. @@ -253,7 +280,7 @@ export class UserTaskResource { * @param params.afterCursor - Opaque cursor returned by the previous page. * @returns Successful response */ - async ready(user: string, params?: { team?: string; org?: string; explain?: boolean; assignedToMe?: boolean; sourceScope?: string; sourceType?: string; sourceId?: string; epic?: string; limit?: number; afterCursor?: string }): Promise<{ after_cursor?: string | undefined; authoritative: boolean; before_cursor?: string | undefined; data: { readiness: "ready" | "blocked" | "leased"; reason?: "open_blockers" | "active_lease" | null | undefined; task: { agent?: string | null | undefined; aggregate_version?: number | null | undefined; blocked_by_count?: number | undefined; closed_at?: string | null | undefined; comments_count?: number | undefined; created_at?: string | undefined; created_by_actor?: { alias?: string | null | undefined; id?: string | null | undefined; name?: string | null | undefined; profile_picture?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined } | null | undefined; created_by_agent?: string | null | undefined; created_by_user?: string | null | undefined; current_lease?: { expires_at: string; harness: string; session_name: string } | null | undefined; description?: string | null | undefined; due_date?: string | null | undefined; epic?: string | null | undefined; id: string; is_blocked?: boolean | undefined; links?: Record | undefined; metadata?: Record | undefined; name: string; org?: string | null | undefined; owner_actor?: { alias?: string | null | undefined; id?: string | null | undefined; name?: string | null | undefined; profile_picture?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined } | null | undefined; owner_agent?: string | null | undefined; owner_user?: string | null | undefined; parent?: string | null | undefined; priority?: number | undefined; sandbox?: string | null | undefined; source_id?: string | null | undefined; source_scope?: string | null | undefined; source_type?: string | null | undefined; status: string; subtasks_count?: number | undefined; tags?: string[] | undefined; team?: string | null | undefined; thread?: string | null | undefined; updated_at?: string | undefined; user?: string | null | undefined } }[]; has_more: boolean }> { + async ready(user: string, params?: { team?: string; org?: string; explain?: boolean; assignedToMe?: boolean; sourceScope?: string; sourceType?: string; sourceId?: string; epic?: string; limit?: number; afterCursor?: string }): Promise<{ after_cursor?: string | undefined; authoritative: boolean; before_cursor?: string | undefined; data: { readiness: "ready" | "blocked" | "leased"; reason?: "open_blockers" | "active_lease" | null | undefined; task: { agent?: string | null | undefined; aggregate_version?: number | null | undefined; blocked_by_count?: number | undefined; closed_at?: string | null | undefined; comments_count?: number | undefined; created_at?: string | undefined; created_by_actor?: { alias?: string | null | undefined; id?: string | null | undefined; name?: string | null | undefined; profile_picture?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined } | null | undefined; created_by_agent?: string | null | undefined; created_by_user?: string | null | undefined; current_lease?: { expires_at: string; harness: string; session_name: string } | null | undefined; description?: string | null | undefined; due_date?: string | null | undefined; epic?: string | null | undefined; id: string; is_blocked?: boolean | undefined; is_stalled?: boolean | undefined; links?: Record | undefined; metadata?: Record | undefined; name: string; org?: string | null | undefined; owner_actor?: { alias?: string | null | undefined; id?: string | null | undefined; name?: string | null | undefined; profile_picture?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined } | null | undefined; owner_agent?: string | null | undefined; owner_user?: string | null | undefined; parent?: string | null | undefined; priority?: number | undefined; project_id?: string | null | undefined; sandbox?: string | null | undefined; source_id?: string | null | undefined; source_scope?: string | null | undefined; source_type?: string | null | undefined; stalled_since?: string | null | undefined; status: string; subtasks_count?: number | undefined; tags?: string[] | undefined; target_binary?: string | null | undefined; target_version?: string | null | undefined; team?: string | null | undefined; thread?: string | null | undefined; updated_at?: string | undefined; user?: string | null | undefined } }[]; has_more: boolean }> { const query: Record | undefined> = {}; if (params?.team !== undefined) { query["team"] = params?.team; @@ -319,7 +346,7 @@ export class UserTaskResource { * @param params.afterCursor - Opaque cursor returned by the previous page. * @returns Successful response */ - async search(user: string, params?: { team?: string; org?: string; q?: string; query?: string; status?: string; ownerUser?: string; ownerAgent?: string; priority?: number; tag?: string; parent?: string; sourceScope?: string; sourceType?: string; sourceId?: string; epic?: string; limit?: number; afterCursor?: string }): Promise<{ after_cursor?: string | undefined; before_cursor?: string | undefined; data: { agent?: string | null | undefined; aggregate_version?: number | null | undefined; blocked_by_count?: number | undefined; closed_at?: string | null | undefined; comments_count?: number | undefined; created_at?: string | undefined; created_by_actor?: { alias?: string | null | undefined; id?: string | null | undefined; name?: string | null | undefined; profile_picture?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined } | null | undefined; created_by_agent?: string | null | undefined; created_by_user?: string | null | undefined; current_lease?: { expires_at: string; harness: string; session_name: string } | null | undefined; description?: string | null | undefined; due_date?: string | null | undefined; epic?: string | null | undefined; id: string; is_blocked?: boolean | undefined; links?: Record | undefined; metadata?: Record | undefined; name: string; org?: string | null | undefined; owner_actor?: { alias?: string | null | undefined; id?: string | null | undefined; name?: string | null | undefined; profile_picture?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined } | null | undefined; owner_agent?: string | null | undefined; owner_user?: string | null | undefined; parent?: string | null | undefined; priority?: number | undefined; sandbox?: string | null | undefined; source_id?: string | null | undefined; source_scope?: string | null | undefined; source_type?: string | null | undefined; status: string; subtasks_count?: number | undefined; tags?: string[] | undefined; team?: string | null | undefined; thread?: string | null | undefined; updated_at?: string | undefined; user?: string | null | undefined }[]; has_more: boolean; query: string }> { + async search(user: string, params?: { team?: string; org?: string; q?: string; query?: string; status?: string; ownerUser?: string; ownerAgent?: string; priority?: number; tag?: string; parent?: string; sourceScope?: string; sourceType?: string; sourceId?: string; epic?: string; limit?: number; afterCursor?: string }): Promise<{ after_cursor?: string | undefined; before_cursor?: string | undefined; data: { agent?: string | null | undefined; aggregate_version?: number | null | undefined; blocked_by_count?: number | undefined; closed_at?: string | null | undefined; comments_count?: number | undefined; created_at?: string | undefined; created_by_actor?: { alias?: string | null | undefined; id?: string | null | undefined; name?: string | null | undefined; profile_picture?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined } | null | undefined; created_by_agent?: string | null | undefined; created_by_user?: string | null | undefined; current_lease?: { expires_at: string; harness: string; session_name: string } | null | undefined; description?: string | null | undefined; due_date?: string | null | undefined; epic?: string | null | undefined; id: string; is_blocked?: boolean | undefined; is_stalled?: boolean | undefined; links?: Record | undefined; metadata?: Record | undefined; name: string; org?: string | null | undefined; owner_actor?: { alias?: string | null | undefined; id?: string | null | undefined; name?: string | null | undefined; profile_picture?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined } | null | undefined; owner_agent?: string | null | undefined; owner_user?: string | null | undefined; parent?: string | null | undefined; priority?: number | undefined; project_id?: string | null | undefined; sandbox?: string | null | undefined; source_id?: string | null | undefined; source_scope?: string | null | undefined; source_type?: string | null | undefined; stalled_since?: string | null | undefined; status: string; subtasks_count?: number | undefined; tags?: string[] | undefined; target_binary?: string | null | undefined; target_version?: string | null | undefined; team?: string | null | undefined; thread?: string | null | undefined; updated_at?: string | undefined; user?: string | null | undefined }[]; has_more: boolean; query: string }> { const query: Record | undefined> = {}; if (params?.team !== undefined) { query["team"] = params?.team; @@ -395,7 +422,7 @@ export class UserThreadResource { * @param params.filter - Array of metadata filter objects. Each filter matches threads whose `metadata` map contains the specified key/value pair. All filters must match (logical AND). Omit to return threads regardless of metadata. * @returns Successful response */ - async list(user: string, params?: { agent?: string[]; filter?: { key: string; type: string; value: string }[] }): Promise<{ data: { agent_user?: string | null | undefined; created_at?: string | undefined; creator?: string | { alias?: string | null | undefined; app?: string | null | undefined; app_name?: string | null | undefined; created_by_agent_user?: string | null | undefined; created_by_developer?: string | null | undefined; created_by_org?: string | null | undefined; created_by_team?: string | null | undefined; created_by_user?: string | null | undefined; email?: string | null | undefined; id: string; is_system_user?: boolean | undefined; metadata?: Record | undefined; name?: string | null | undefined; org?: string | null | undefined; org_name?: string | null | undefined; org_role?: string | null | undefined; org_slug?: string | null | undefined; sandbox?: string | null | undefined; sandbox_name?: string | null | undefined } | null | undefined; description?: string | null | undefined; id: string; is_channel?: boolean | undefined; is_default?: boolean | undefined; is_transient?: boolean | undefined; is_unlisted?: boolean | undefined; key?: string | null | undefined; kind?: string | null | undefined; last_activity?: string | null | undefined; last_message_preview?: string | null | undefined; last_message_sender?: string | null | undefined; metadata?: Record | null | undefined; muted?: boolean | undefined; org?: string | null | undefined; parent_message?: { acl?: { add?: { actions: string[]; principal?: string | undefined; principal_type: string }[] | undefined; grants?: { actions: string[]; principal?: string | undefined; principal_type: string }[] | undefined; remove?: { principal?: string | undefined; principal_type: string }[] | undefined } | null | undefined; actors?: { alias?: string | null | undefined; id?: string | null | undefined; name?: string | null | undefined; profile_picture?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined }[] | undefined; agent?: string | null | undefined; agent_mode?: "cli" | "embedded" | null | undefined; attachments?: { content_type?: string | null | undefined; description?: string | null | undefined; filename?: string | null | undefined; height?: number | null | undefined; id: string; image_height?: number | null | undefined; image_source?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined; image_url?: string | null | undefined; image_width?: number | null | undefined; key?: string | null | undefined; media_type?: string | undefined; name?: string | null | undefined; object?: Record | undefined; title?: string | null | undefined; type: string; url?: string | null | undefined; variants?: { content_type?: string | null | undefined; created_at?: string | undefined; file?: string | undefined; filename?: string | null | undefined; height?: number | null | undefined; id: string; image_source?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined; updated_at?: string | undefined; url?: string | null | undefined; variant_key?: string | undefined; width?: number | null | undefined }[] | undefined; version?: number | null | undefined; width?: number | null | undefined }[] | undefined; branched_thread?: string | null | undefined; content?: string | null | undefined; context?: { attributes?: Record | undefined; content?: string | null | undefined; title?: string | null | undefined; type: string }[] | undefined; created_at?: string | undefined; has_replies?: boolean | undefined; id: string; idempotency_key?: string | null | undefined; is_deleted?: boolean | undefined; legacy_agent?: string | null | undefined; metadata?: Record | undefined; org?: string | null | undefined; reactions?: { payload?: Record | undefined; type: string; user?: string | undefined }[] | undefined; rendering_mode?: string | null | undefined; replies?: Record[] | undefined; replies_after_cursor?: string | null | undefined; replies_before_cursor?: string | null | undefined; reply_count?: number | undefined; reply_to?: Record | null | undefined; root_message_id?: string | null | undefined; sandbox?: string | null | undefined; team?: string | null | undefined; thread?: string | undefined; type?: string | null | undefined; user?: string | { alias?: string | null | undefined; app?: string | null | undefined; app_name?: string | null | undefined; created_by_agent_user?: string | null | undefined; created_by_developer?: string | null | undefined; created_by_org?: string | null | undefined; created_by_team?: string | null | undefined; created_by_user?: string | null | undefined; email?: string | null | undefined; id: string; is_system_user?: boolean | undefined; metadata?: Record | undefined; name?: string | null | undefined; org?: string | null | undefined; org_name?: string | null | undefined; org_role?: string | null | undefined; org_slug?: string | null | undefined; sandbox?: string | null | undefined; sandbox_name?: string | null | undefined } | null | undefined; visibility?: "default" | "private" | undefined } | null | undefined; participant?: string[] | undefined; participants?: { alias?: string | null | undefined; app?: string | null | undefined; app_name?: string | null | undefined; created_by_agent_user?: string | null | undefined; created_by_developer?: string | null | undefined; created_by_org?: string | null | undefined; created_by_team?: string | null | undefined; created_by_user?: string | null | undefined; email?: string | null | undefined; id: string; is_system_user?: boolean | undefined; metadata?: Record | undefined; name?: string | null | undefined; org?: string | null | undefined; org_name?: string | null | undefined; org_role?: string | null | undefined; org_slug?: string | null | undefined; sandbox?: string | null | undefined; sandbox_name?: string | null | undefined }[] | undefined; participating_actor?: string[] | undefined; participating_agents?: { acl?: { add?: { actions: string[]; principal?: string | undefined; principal_type: string }[] | undefined; grants?: { actions: string[]; principal?: string | undefined; principal_type: string }[] | undefined; remove?: { principal?: string | undefined; principal_type: string }[] | undefined } | null | undefined; app?: string | undefined; created_at?: string | undefined; default_model?: string | null | undefined; description?: string | null | undefined; email?: string | null | undefined; id: string; identity?: string | null | undefined; last_applied_template_config?: string | null | undefined; lookup_key?: string | null | undefined; metadata?: Record | undefined; name?: string | undefined; org?: string | null | undefined; org_name?: string | null | undefined; originator?: string | null | undefined; phone_number?: string | null | undefined; sandbox?: string | null | undefined; source_solution?: { current_solution?: { category_keys?: string[] | undefined; created_at?: string | undefined; description?: string | null | undefined; events?: Record | undefined; id: string; image_url?: string | null | undefined; installed_config_ids: string[]; kind: string; latest_solution?: string | null | undefined; latest_version?: string | null | undefined; lookup_key?: string | null | undefined; metadata?: Record | undefined; name?: string | null | undefined; org?: string | null | undefined; org_logo?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined; org_name?: string | null | undefined; org_slug?: string | null | undefined; owners: string[]; readme_url?: string | null | undefined; screenshot_urls?: string[] | undefined; solution_id?: string | null | undefined; solution_version?: string | null | undefined; tag_keys?: string[] | undefined; template_kind?: string | null | undefined; templates: { description?: string | null | undefined; details?: { automation_type?: string | null | undefined; invoke_contract?: { input_schema?: Record | null | undefined; participants?: { description?: string | null | undefined; name: string; required: boolean; type: string }[] | null | undefined; prefills: { participants?: Record | undefined; payload?: Record | undefined } } | null | undefined; type: "automation" } | null | undefined; display_name?: string | null | undefined; id?: string | null | undefined; kind: string; lookup_key?: string | null | undefined; name?: string | null | undefined; readme_url?: string | null | undefined; virtual_path?: string | null | undefined }[]; updated_at?: string | undefined; upgrade_available: boolean; virtual_path?: string | null | undefined } | undefined; solution: { category_keys?: string[] | undefined; created_at?: string | undefined; description?: string | null | undefined; events?: Record | undefined; id: string; image_url?: string | null | undefined; installed_config_ids: string[]; kind: string; latest_solution?: string | null | undefined; latest_version?: string | null | undefined; lookup_key?: string | null | undefined; metadata?: Record | undefined; name?: string | null | undefined; org?: string | null | undefined; org_logo?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined; org_name?: string | null | undefined; org_slug?: string | null | undefined; owners: string[]; readme_url?: string | null | undefined; screenshot_urls?: string[] | undefined; solution_id?: string | null | undefined; solution_version?: string | null | undefined; tag_keys?: string[] | undefined; template_kind?: string | null | undefined; templates: { description?: string | null | undefined; details?: { automation_type?: string | null | undefined; invoke_contract?: { input_schema?: Record | null | undefined; participants?: { description?: string | null | undefined; name: string; required: boolean; type: string }[] | null | undefined; prefills: { participants?: Record | undefined; payload?: Record | undefined } } | null | undefined; type: "automation" } | null | undefined; display_name?: string | null | undefined; id?: string | null | undefined; kind: string; lookup_key?: string | null | undefined; name?: string | null | undefined; readme_url?: string | null | undefined; virtual_path?: string | null | undefined }[]; updated_at?: string | undefined; upgrade_available: boolean; virtual_path?: string | null | undefined }; template: { created_at?: string | undefined; description?: string | null | undefined; display_name?: string | null | undefined; id: string; kind: string; lookup_key?: string | null | undefined; name?: string | null | undefined; updated_at?: string | undefined; virtual_path?: string | null | undefined } } | null | undefined; team?: string | null | undefined; template_upgrade_available?: boolean | null | undefined; updated_at?: string | undefined; user?: string | null | undefined }[] | null | undefined; role?: string | null | undefined; sandbox?: string | null | undefined; settings?: { agent_enabled?: boolean | null | undefined } | undefined; slug?: string | null | undefined; sub_threads?: Record[] | null | undefined; tags?: string[] | undefined; team?: string | null | undefined; title?: string | null | undefined; ttl?: string | null | undefined; unread_count?: number | null | undefined; updated_at?: string | undefined; user?: string | null | undefined; visibility: "team" | "restricted" | "private" | "org" }[] }> { + async list(user: string, params?: { agent?: string[]; filter?: { key: string; type: string; value: string }[] }): Promise<{ data: { agent_user?: string | null | undefined; created_at?: string | undefined; creator?: string | { alias?: string | null | undefined; app?: string | null | undefined; app_name?: string | null | undefined; created_by_agent_user?: string | null | undefined; created_by_developer?: string | null | undefined; created_by_org?: string | null | undefined; created_by_team?: string | null | undefined; created_by_user?: string | null | undefined; email?: string | null | undefined; id: string; is_system_user?: boolean | undefined; metadata?: Record | undefined; name?: string | null | undefined; org?: string | null | undefined; org_name?: string | null | undefined; org_role?: string | null | undefined; org_slug?: string | null | undefined; sandbox?: string | null | undefined; sandbox_name?: string | null | undefined } | null | undefined; description?: string | null | undefined; id: string; is_channel?: boolean | undefined; is_default?: boolean | undefined; is_transient?: boolean | undefined; is_unlisted?: boolean | undefined; key?: string | null | undefined; kind?: string | null | undefined; last_activity?: string | null | undefined; last_message_preview?: string | null | undefined; last_message_sender?: string | null | undefined; metadata?: Record | null | undefined; muted?: boolean | undefined; org?: string | null | undefined; parent_message?: { acl?: { add?: { actions: string[]; principal?: string | undefined; principal_type: string }[] | undefined; grants?: { actions: string[]; principal?: string | undefined; principal_type: string }[] | undefined; remove?: { principal?: string | undefined; principal_type: string }[] | undefined } | null | undefined; actors?: { alias?: string | null | undefined; id?: string | null | undefined; name?: string | null | undefined; profile_picture?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined }[] | undefined; agent?: string | null | undefined; agent_mode?: "cli" | "embedded" | null | undefined; attachments?: { content_type?: string | null | undefined; description?: string | null | undefined; filename?: string | null | undefined; height?: number | null | undefined; id: string; image_height?: number | null | undefined; image_source?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined; image_url?: string | null | undefined; image_width?: number | null | undefined; key?: string | null | undefined; media_type?: string | undefined; name?: string | null | undefined; object?: Record | undefined; title?: string | null | undefined; type: string; url?: string | null | undefined; variants?: { byte_size?: number | null | undefined; content_type?: string | null | undefined; created_at?: string | undefined; duration_ms?: number | null | undefined; file?: string | undefined; filename?: string | null | undefined; height?: number | null | undefined; id: string; image_source?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined; sha256?: string | null | undefined; updated_at?: string | undefined; url?: string | null | undefined; url_expires_at?: string | null | undefined; variant_key?: string | undefined; width?: number | null | undefined }[] | undefined; version?: number | null | undefined; width?: number | null | undefined }[] | undefined; branched_thread?: string | null | undefined; content?: string | null | undefined; context?: { attributes?: Record | undefined; content?: string | null | undefined; title?: string | null | undefined; type: string }[] | undefined; created_at?: string | undefined; has_replies?: boolean | undefined; id: string; idempotency_key?: string | null | undefined; is_deleted?: boolean | undefined; legacy_agent?: string | null | undefined; metadata?: Record | undefined; org?: string | null | undefined; reactions?: { payload?: Record | undefined; type: string; user?: string | undefined }[] | undefined; rendering_mode?: string | null | undefined; replies?: Record[] | undefined; replies_after_cursor?: string | null | undefined; replies_before_cursor?: string | null | undefined; reply_count?: number | undefined; reply_to?: Record | null | undefined; root_message_id?: string | null | undefined; sandbox?: string | null | undefined; team?: string | null | undefined; thread?: string | undefined; type?: string | null | undefined; user?: string | { alias?: string | null | undefined; app?: string | null | undefined; app_name?: string | null | undefined; created_by_agent_user?: string | null | undefined; created_by_developer?: string | null | undefined; created_by_org?: string | null | undefined; created_by_team?: string | null | undefined; created_by_user?: string | null | undefined; email?: string | null | undefined; id: string; is_system_user?: boolean | undefined; metadata?: Record | undefined; name?: string | null | undefined; org?: string | null | undefined; org_name?: string | null | undefined; org_role?: string | null | undefined; org_slug?: string | null | undefined; sandbox?: string | null | undefined; sandbox_name?: string | null | undefined } | null | undefined; visibility?: "default" | "private" | undefined } | null | undefined; participant?: string[] | undefined; participants?: { alias?: string | null | undefined; app?: string | null | undefined; app_name?: string | null | undefined; created_by_agent_user?: string | null | undefined; created_by_developer?: string | null | undefined; created_by_org?: string | null | undefined; created_by_team?: string | null | undefined; created_by_user?: string | null | undefined; email?: string | null | undefined; id: string; is_system_user?: boolean | undefined; metadata?: Record | undefined; name?: string | null | undefined; org?: string | null | undefined; org_name?: string | null | undefined; org_role?: string | null | undefined; org_slug?: string | null | undefined; sandbox?: string | null | undefined; sandbox_name?: string | null | undefined }[] | undefined; participating_actor?: string[] | undefined; participating_agents?: { acl?: { add?: { actions: string[]; principal?: string | undefined; principal_type: string }[] | undefined; grants?: { actions: string[]; principal?: string | undefined; principal_type: string }[] | undefined; remove?: { principal?: string | undefined; principal_type: string }[] | undefined } | null | undefined; app?: string | undefined; created_at?: string | undefined; default_model?: string | null | undefined; description?: string | null | undefined; email?: string | null | undefined; id: string; identity?: string | null | undefined; last_applied_template_config?: string | null | undefined; lookup_key?: string | null | undefined; metadata?: Record | undefined; name?: string | undefined; org?: string | null | undefined; org_name?: string | null | undefined; originator?: string | null | undefined; phone_number?: string | null | undefined; sandbox?: string | null | undefined; source_solution?: { current_solution?: { category_keys?: string[] | undefined; created_at?: string | undefined; description?: string | null | undefined; events?: Record | undefined; id: string; image_url?: string | null | undefined; installed_config_ids: string[]; kind: string; latest_solution?: string | null | undefined; latest_version?: string | null | undefined; lookup_key?: string | null | undefined; metadata?: Record | undefined; name?: string | null | undefined; org?: string | null | undefined; org_logo?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined; org_name?: string | null | undefined; org_slug?: string | null | undefined; owners: string[]; readme_url?: string | null | undefined; screenshot_urls?: string[] | undefined; solution_id?: string | null | undefined; solution_version?: string | null | undefined; tag_keys?: string[] | undefined; template_kind?: string | null | undefined; templates: { description?: string | null | undefined; details?: { automation_type?: string | null | undefined; invoke_contract?: { input_schema?: Record | null | undefined; participants?: { description?: string | null | undefined; name: string; required: boolean; type: string }[] | null | undefined; prefills: { participants?: Record | undefined; payload?: Record | undefined } } | null | undefined; type: "automation" } | null | undefined; display_name?: string | null | undefined; id?: string | null | undefined; kind: string; lookup_key?: string | null | undefined; name?: string | null | undefined; readme_url?: string | null | undefined; virtual_path?: string | null | undefined }[]; updated_at?: string | undefined; upgrade_available: boolean; virtual_path?: string | null | undefined } | undefined; solution: { category_keys?: string[] | undefined; created_at?: string | undefined; description?: string | null | undefined; events?: Record | undefined; id: string; image_url?: string | null | undefined; installed_config_ids: string[]; kind: string; latest_solution?: string | null | undefined; latest_version?: string | null | undefined; lookup_key?: string | null | undefined; metadata?: Record | undefined; name?: string | null | undefined; org?: string | null | undefined; org_logo?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | null | undefined; org_name?: string | null | undefined; org_slug?: string | null | undefined; owners: string[]; readme_url?: string | null | undefined; screenshot_urls?: string[] | undefined; solution_id?: string | null | undefined; solution_version?: string | null | undefined; tag_keys?: string[] | undefined; template_kind?: string | null | undefined; templates: { description?: string | null | undefined; details?: { automation_type?: string | null | undefined; invoke_contract?: { input_schema?: Record | null | undefined; participants?: { description?: string | null | undefined; name: string; required: boolean; type: string }[] | null | undefined; prefills: { participants?: Record | undefined; payload?: Record | undefined } } | null | undefined; type: "automation" } | null | undefined; display_name?: string | null | undefined; id?: string | null | undefined; kind: string; lookup_key?: string | null | undefined; name?: string | null | undefined; readme_url?: string | null | undefined; virtual_path?: string | null | undefined }[]; updated_at?: string | undefined; upgrade_available: boolean; virtual_path?: string | null | undefined }; template: { created_at?: string | undefined; description?: string | null | undefined; display_name?: string | null | undefined; id: string; kind: string; lookup_key?: string | null | undefined; name?: string | null | undefined; updated_at?: string | undefined; virtual_path?: string | null | undefined } } | null | undefined; team?: string | null | undefined; template_upgrade_available?: boolean | null | undefined; updated_at?: string | undefined; user?: string | null | undefined }[] | null | undefined; role?: string | null | undefined; sandbox?: string | null | undefined; settings?: { agent_enabled?: boolean | null | undefined } | undefined; slug?: string | null | undefined; sub_threads?: Record[] | null | undefined; tags?: string[] | undefined; team?: string | null | undefined; title?: string | null | undefined; ttl?: string | null | undefined; unread_count?: number | null | undefined; updated_at?: string | undefined; user?: string | null | undefined; visibility: "team" | "restricted" | "private" | "org" }[] }> { const query: Record | undefined> = {}; if (params?.agent !== undefined) { query["agent"] = params?.agent; @@ -525,8 +552,8 @@ export class UserResource { /** * Retrieve a user by ID * Returns the user identified by `user`. The authenticated user must share - * at least one team with the target user; requests for users outside any - * shared team are rejected with 403. + * an organization or at least one team with the target user; other requests + * are rejected with 403. * A user may always retrieve their own profile with this endpoint. Use the * `GET /users/me` endpoint as a convenience alias for retrieving the * authenticated user without specifying an ID. @@ -554,7 +581,7 @@ export class UserResource { * @param params.groupKeyPrefix - Nonempty case-sensitive literal prefix (percent, underscore and backslash are literal). Mutually exclusive with group_key. * @returns Successful response */ - async artifacts(user: string, params?: { groupKey?: string; groupKeyPrefix?: string }): Promise<{ data: { agent?: string | undefined; content_type?: string | undefined; created_at?: string | undefined; current_version?: string | undefined; description?: string | undefined; file?: string | undefined; file_name?: string | undefined; file_url?: string | undefined; group_key?: string | null | undefined; id: string; image_source?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | undefined; name?: string | undefined; org?: string | undefined; sandbox?: string | undefined; system?: boolean | undefined; team?: string | undefined; thread?: string | undefined; updated_at?: string | undefined; user?: string | undefined; version?: number | undefined }[] }> { + async artifacts(user: string, params?: { groupKey?: string; groupKeyPrefix?: string }): Promise<{ data: { acl?: { add?: { actions: string[]; principal?: string | undefined; principal_type: string }[] | undefined; grants?: { actions: string[]; principal?: string | undefined; principal_type: string }[] | undefined; remove?: { principal?: string | undefined; principal_type: string }[] | undefined } | null | undefined; agent?: string | undefined; content_type?: string | undefined; created_at?: string | undefined; current_version?: string | undefined; description?: string | undefined; file?: string | undefined; file_name?: string | undefined; file_url?: string | undefined; group_key?: string | null | undefined; id: string; image_source?: { file?: string | null | undefined; height?: number | null | undefined; media?: string | null | undefined; mime_type?: string | null | undefined; refresh_url?: string | null | undefined; url?: string | null | undefined; width?: number | null | undefined } | undefined; name?: string | undefined; org?: string | undefined; sandbox?: string | undefined; system?: boolean | undefined; team?: string | undefined; thread?: string | undefined; updated_at?: string | undefined; user?: string | undefined; version?: number | undefined }[] }> { const query: Record | undefined> = {}; if (params?.groupKey !== undefined) { query["group_key"] = params?.groupKey; @@ -623,4 +650,50 @@ export class UserResource { async profile(user: string, input: { alias?: string | undefined; clear_full_name?: boolean | undefined; clear_profile_picture?: boolean | undefined; full_name?: string | null | undefined; metadata?: Record | undefined; profile_picture?: { data?: string | undefined; filename?: string | undefined; mime_type?: string | undefined } | null | undefined }): Promise { return this.http.request(`/api/v1/users/${user}/profile`, { method: "PUT", body: input }); } + + /** + * 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. + * @param params - Query parameters. + * @param params.sourceScope - Exact source scope; supply all three source fields. + * @param params.sourceType - Exact source type. + * @param params.sourceId - Exact source ID. + * @param params.topPriority - Exact highest open priority, from 0 to 4. + * @param params.includeClosed - Include epics with no non-closed tasks; defaults to false. + * @param params.limit - Maximum epics; defaults to 50, capped at 100. + * @param params.afterCursor - Opaque forward cursor from the preceding page. + * @returns Successful response + */ + async taskEpics(user: string, params?: { team?: string; org?: string; sourceScope?: string; sourceType?: string; sourceId?: string; topPriority?: number; includeClosed?: boolean; limit?: number; afterCursor?: string }): Promise<{ after_cursor?: string | null | undefined; before_cursor?: string | null | undefined; data: { blocked_count: number; counts: Record; epic: string; next_ready: { id: string; name: string; priority: number; status: string }[]; root_blockers: { downstream_count: number; id: string; name: string; priority: number; status: string }[]; root_blockers_partial: boolean; top_open_priority?: number | null | undefined; updated_at: string }[]; has_more: boolean; no_epic_open_count: number }> { + const query: Record | undefined> = {}; + if (params?.team !== undefined) { + query["team"] = params?.team; + } + if (params?.org !== undefined) { + query["org"] = params?.org; + } + if (params?.sourceScope !== undefined) { + query["source_scope"] = params?.sourceScope; + } + if (params?.sourceType !== undefined) { + query["source_type"] = params?.sourceType; + } + if (params?.sourceId !== undefined) { + query["source_id"] = params?.sourceId; + } + if (params?.topPriority !== undefined) { + query["top_priority"] = params?.topPriority; + } + if (params?.includeClosed !== undefined) { + query["include_closed"] = params?.includeClosed; + } + if (params?.limit !== undefined) { + query["limit"] = params?.limit; + } + if (params?.afterCursor !== undefined) { + query["after_cursor"] = params?.afterCursor; + } + + return this.http.request(`/api/v1/users/${user}/task_epics`, { query }); + } } diff --git a/packages/sdk/src/v1/resources/workflows.ts b/packages/sdk/src/v1/resources/workflows.ts index 8e7103a..4ddc760 100644 --- a/packages/sdk/src/v1/resources/workflows.ts +++ b/packages/sdk/src/v1/resources/workflows.ts @@ -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: cc892020c789 +// Content hash: b640b48b7d64 import { HttpClient } from "../../runtime/http-client.js"; import type { Command, NodeType } from "../../types/common.js"; @@ -188,7 +188,11 @@ export class WorkflowResource { * The authenticated developer is used as the default workflow principal for entitlement * checks on billable operations such as LLM calls. Supply `run_as_user` or * `run_as_agent` to override the acting identity for the execution — at most one - * override may be set per request. + * override may be set per request. Overrides are subject to the caller's + * delegation permissions, the same ones `/scripts/run` applies: app secret keys + * and developer tokens may run as any user or agent in the app; other callers may + * run as themselves, and as an agent they own (org admins as any agent in their + * org). A refused override returns 403 before anything runs. * Execution errors are logged to the activity feed under the acting identity so they * appear alongside automation-driven workflow errors in operator dashboards. A 422 * response is returned when execution fails; the response body includes the error