# Tasks

Use `kosuke tasks list <workspaceId>` for one workspace and `kosuke tasks list` across your workspaces. Agent credentials stay within their workspace.

When creating a task with `hintProjectId`, attachments use the project's [chat-session upload transport](https://kosuke.ai/docs/endpoint-reference/chat-sessions.md). The CLI stages batches larger than 20 MiB through `/api/projects/{hintProjectId}/attachments` when the operation advertises that path. Tasks without a hint project do not accept attachments.

| Method | Path                                                                                                                                                                                                             | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| GET    | `/api/organizations/{workspaceId}/tasks?status=&owners=&priorities=&labels=&createdBy=&project=&projects=&q=&doneSince=&limit=&cursor=&sortBy=&sortOrder=&includePrompt=&includeOpenCount=&workspace=&threadId=` | List tasks in one workspace. Before you file or propose a ticket, read the open ones (--status todo,in_progress --include-prompt, following meta.pagination.nextCursor with --cursor) and judge overlap by meaning, not title words: work another task or session already covers gets no new ticket.                                                                                                                                                                                                            |
| POST   | `/api/organizations/{workspaceId}/tasks`                                                                                                                                                                         | File a task. A hint files into that project. personal files a task in your Personal space, yours alone; dueOn, threadId and in_progress are for that one, and from a Sensei Turn it joins the Turn's thread unless threadId names another. From Sensei, ownerId is the member, or the teammate they name; leave sandboxSize to the member, who changes it in the task's Properties. Answers shareUrl: link the task's title to it.                                                                              |
| GET    | `/api/organizations/{workspaceId}/tasks/{taskId}`                                                                                                                                                                | Get a task and its execution details.                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| PATCH  | `/api/organizations/{workspaceId}/tasks/{taskId}`                                                                                                                                                                | Edit a task.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| DELETE | `/api/organizations/{workspaceId}/tasks/{taskId}`                                                                                                                                                                | Delete a task.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| POST   | `/api/organizations/{workspaceId}/tasks/{taskId}/move`                                                                                                                                                           | Move a Todo or In progress Personal task into a workspace. Members and Sensei only.                                                                                                                                                                                                                                                                                                                                                                                                                             |
| POST   | `/api/organizations/{workspaceId}/tasks/{taskId}/start`                                                                                                                                                          | Start a Todo task. Members and Sensei only. sandboxSize and appStack set the task's Sandbox size and App stack as it starts; absent keeps what the task holds. The member's ask to start is the yes: start without reading back credits or sandboxes. A refusal leaves it in the Backlog: say what the platform answered and do not retry.                                                                                                                                                                      |
| POST   | `/api/organizations/{workspaceId}/tasks/{taskId}/transfer`                                                                                                                                                       | Move a Todo task and its Backlog session to another deployed repository of the same workspace, in place: same IDs, Assignee, description, messages, attachments and labels; nothing starts. Members and Sensei only, with access to both repositories. Only when the member asks. The same repository again succeeds with the task; a started task, or one with a branch, sandbox or pull request, answers 409 TASK_CONFLICT; a repository not deployed answers 409 TASK_INVALID_PROJECT, one out of reach 404. |
| GET    | `/api/tasks?status=&owners=&priorities=&labels=&createdBy=&project=&projects=&q=&doneSince=&limit=&cursor=&sortBy=&sortOrder=&includePrompt=&includeOpenCount=&workspace=&threadId=`                             | List tasks across your workspaces, your own Personal space included. Agent credentials stay in their workspace. includeOpenCount counts Todo and In progress with the same filters, independent of status and cursor. Before you file or propose a ticket, read the open ones (--status todo,in_progress --include-prompt, following meta.pagination.nextCursor with --cursor) and judge overlap by meaning, not title words: work another task or session already covers gets no new ticket.                   |

List responses are `{ data: Task[], meta: { pagination: { pageSize, hasMore, nextCursor } } }`. Pass `nextCursor` as `cursor` for the next page. Ordering defaults to newest creation first. Choose `--sort-by activity|created|priority` and `--sort-order asc|desc` on `tasks list`, with or without a workspace, or `sortBy` and `sortOrder` in the API. Keep the same sort when following a cursor; another sort returns 400 `Invalid cursor`. Filters include comma-separated `status` (`todo`, `in_progress`, `done`, `archived`; every status when absent), `owners` (member IDs, `me`, `none`, `any`), `priorities`, `createdBy` (`agent` or `member`), `project` or `projects`, `q` and `doneSince`, which keeps only the Done and Archived tasks that reached that status since then.

Filter by label with `--labels '["bug","ui"]'` on `tasks list`, with or without a workspace (the API's `labels` query parameter is a URL-encoded JSON array). A task matches any selected label on its Chat Session, combined with the other filters. Tasks with no Chat Session never match. Names are trimmed, normalized to lowercase and deduplicated; at most 20 are accepted. Invalid JSON or names return 400 `Invalid labels filter`. `[]` means no label filter. Pagination and open counts follow the filter.

Read the available names and colors with `kosuke tasks labels list <workspaceId>` (`GET /api/organizations/{workspaceId}/labels`). It returns `{ data: [{ name, color }] }`, one row per name sorted by name, across the workspace's repository catalogs, including unused labels and excluding Apps. The oldest repository holding a name supplies its color (creation time, then project ID). The hidden Personal organization works too. Access follows the task list; an agent or Cron credential without a member identity sees only its permitted projects.

`GET /api/tasks` also includes `meta.workspaces` with workspace IDs and names. `includeOpenCount=true` adds `meta.openCount`: Todo plus In progress across the same workspace and property filters, independent of status and pagination.

`GET /api/organizations/{workspaceId}/tasks/{taskId}` returns `{ data: TaskDetail }`, with the task properties, `chatSession`, full `session`, `description`, `createdBy`, `filedReason`, `doneAt`, `archivedAt`, `hintProjectName` and the viewer's `thread`. Session-less tasks have null execution details.

File with `kosuke tasks create <workspaceId> --title "Fix the export" --description "Include archived records"`. A member or Sensei may omit `--hint-project`. Sandbox and Cron callers must supply a hint and follow the session filing rules, including a reason. Create returns `{ data: { task, sessionId } }`.

Transfer (`kosuke tasks project set <workspaceId> <taskId> --project-id <projectId>`, `POST /api/organizations/{workspaceId}/tasks/{taskId}/transfer` with `{ projectId, ifRevision? }`) moves a Todo task and its Backlog session to another deployed repository of the same workspace, in place. Only a member or Sensei with write access to both repositories may move it, and only when the member asks; a Job Delegate, a sandbox or Cron credential is refused with 403 `TASK_FORBIDDEN`. The task and session keep their IDs, Assignee, creator, filing fields, title, description and its revision, messages, attachments, labels, Sensei thread links and creation times; the session's messages, Queue, attachments and open Sensei cards move to the destination, and the task's `hintProjectId` names it. Labels the destination's catalog lacks join it with their source colors. History stays where it happened, and the move writes a `session_moved` Activity Event. The task's and the session's `updatedAt` move to the time of the move; `lastActivityAt` does not. Nothing starts: no sandbox, agent, branch, Deploy or pull request. Answers `{ data: { task, session, moved } }`; `moved` is false when the task was already in that repository, which is how a retry after a lost response succeeds. `ifRevision` takes the task `updatedAt` you read, which every move changes (a `descriptionRevision` is refused, since a move leaves it as it is); a task changed or moved since answers 409 `TASK_CONFLICT`. Other answers: 409 `TASK_CONFLICT` for a task that is not Todo, has started, has a branch, sandbox, pull request, requested or start branch, or waits on a Deploy, for a task whose files are also attached to another session's or a Deploy's message (the file would be lost with one of the two repositories), and for a task with no repository yet (file it with `hintProjectId`); 409 `TASK_INVALID_PROJECT` for a repository that is not deployed; 404 `TASK_INVALID_PROJECT` for one in another workspace or out of your reach; 404 `TASK_NOT_FOUND`. A Start racing the move either wins, and the move answers 409, or loses and answers 409 itself; the task never ends up in both.

Start takes `projectId`, an optional `skill`, and optional `sandboxSize` and `appStack`, which replace what the task holds. Members and Sensei may start. A draft stays in its filed project; a task without a session needs a deployed Collaboration project. Start preserves the activation response and structured refusal, and a refused activation leaves the task Todo for retry.

Update delegates execution properties to the session, and `status` (`todo`, `done`, `archived`) maps to its Backlog, Completed or Archived status under the session's rules: a Completed session cannot be archived. Without a session, only title, description, priority, ownerId, `sandboxSize`, `appStack`, status and `threadId` are editable; Archive keeps `doneAt`, and `todo` restores the task and clears both times. `threadId` (`kosuke tasks update <workspaceId> <taskId> --thread-id <threadId>`) chooses the thread of your own Sensei that follows the task, or `null` for none, on any task you can reach that is assigned to you or to no one; a task assigned to another member answers 403 `TASK_FORBIDDEN`, and a thread that is not yours answers 400 `TASK_INVALID_THREAD`. It changes only your own link, never another member's, and neither assigns nor starts the task. A task not yet started that was filed in another member's thread keeps that filing as theirs, and you get a link of your own beside it, which becomes your session's thread when it starts. On a started task it moves the session's join in your Sensei, with its news and open cards, as Move to thread does; the session's work goes on. Outside a sessionless Personal task, send `threadId` on its own (else 400), and the answer is `{ data: { thread: { taskId, sessionId, moved, fromThreadId, toThreadId, ... } } }`; `tasks get` then reads the new `thread`. Due dates and manual In progress still require a sessionless Personal task. `hintProjectId`, sent alone with an optional `ifRevision`, files a Todo task with no repository in a deployed Collaboration project without starting it, and keeps its Assignee. The same project again succeeds; another project, or a task that is no longer Todo, returns 409. `sandboxSize` (`small`, `medium`, `large`, `xlarge`; left out, the project's size) and `appStack` (`start`, the default, or `skip`, which boots without the project's services) are refused with `409 SANDBOX_SETTINGS_LOCKED` once the task's session has started; see [Chat sessions](https://kosuke.ai/docs/endpoint-reference/chat-sessions.md#app-stack). A write racing Start returns 409: reload the task before retrying. Deletes return 204.

A Todo task's Repository is the project Sensei filed it in, or the one chosen in the task modal; once set, it is read-only. Its Sandbox size and App stack stay editable until it starts. Cards open the task modal; **Open chat** is the only way to the conversation. Tasks without a session have text-only descriptions, with no files until Start. They cannot be Card or MCP `ship` targets: name them by title and start them with `tasks start`.

The workspace Tasks page has Todo, In progress, Done and Archived (the last two for 7 days). Sensei files tasks; there is no New session button or ⌘J shortcut. Existing `sessions create --status backlog` continues to work.

```sh
kosuke tasks list <workspaceId> --status todo,in_progress
kosuke tasks list <workspaceId> --labels '["bug","ui"]'
kosuke tasks list --labels '["bug"]'
kosuke tasks labels list <workspaceId>
kosuke tasks get <workspaceId> <taskId>
kosuke tasks create <workspaceId> --hint-project <projectId> --title "Fix export" --description "Include archived records" --sandbox-size small --app-stack skip
kosuke tasks update <workspaceId> <taskId> --hint-project <projectId>
kosuke tasks update <workspaceId> <taskId> --status archived
kosuke tasks start <workspaceId> <taskId> --project-id <projectId> --skill ship
```

Lists are paginated; use `--include-prompt` for duplicate checks and read truncated descriptions with `tasks get`.

List with `--include-prompt` (`includePrompt=true`) to return `prompt` and `promptTruncated`: up to 4,000 characters of the description, or the linked session's first user message. Follow `meta.pagination.nextCursor` for subsequent pages.

Create returns `shareUrl`, the absolute workspace Tasks link opening the task, and keeps `sessionId` for execution commands. With a hint project, `--attach <path>` (repeat per file) uploads attachments through multipart to the draft session. Attachments without a hint project return 400 because descriptions without a session are text only.
