Pull requests and sync
To open a session's pull request, send /kosuke:open-pr as a message, or $kosuke:open-pr on a Codex session. The agent commits and pushes the work, writes the title and body, and opens the pull request against the Target Branch. To sync the branch, send /kosuke:sync-branch ($kosuke:sync-branch on Codex) as a message.
Pick the invocation character
The character follows the session's provider. Read model from GET /api/projects/{projectId}/chat-sessions/{sessionId}.
Session model starts with | Send |
|---|---|
anthropic:, zai:, moonshot: or deepseek: | /kosuke:open-pr, /kosuke:sync-branch |
openai: | $kosuke:open-pr, $kosuke:sync-branch |
A session that has not run a turn yet may have no model. It takes the provider of its Assignee's Default Model.
Open a pull request
-
Send the invocation to
POST .../jobs/chat, with any flags after it.curl -s -X POST "https://app.kosuke.ai/api/projects/$PROJECT_ID/chat-sessions/$SESSION_ID/jobs/chat" \-H "Authorization: Bearer $KOSUKE_API_KEY" \-H "Content-Type: application/json" \-d '{"content": "/kosuke:open-pr -r alice,bruno -e https://example.com/checkout-demo.mp4"}' -
Read
deliveryin the answer. Withjob, follow the turn by itschatJobId. Withqueued, a turn was running and the message waits Up next. It starts its own turn when the running one completes, unless that turn fails, is stopped or asks a Clarification, or the session is then Under Review, which pauses Up next. -
Wait for the turn to end, as Messages and turns shows.
-
When it ends
completed, readprUrlfromGET /api/projects/{projectId}/chat-sessions/{sessionId}.
The CLI sends the same message:
kosuke sessions send $PROJECT_ID $SESSION_ID --content "/kosuke:open-pr -d"
From the MCP server, the submit tool picks the character and sends the skill for you.
Flags
Write the flags after the command in the same message.
| Flag | What it does |
|---|---|
-d, --draft | Opens the pull request as a draft. Ignored when a pull request is already open. |
-r <names>, --reviewers <names> | Requests reviewers. Separate names with commas or spaces. The agent matches them loosely against GitHub logins. |
-e <links>, --evidence <links> | Adds an evidence section with these links, such as a recording, a screenshot or a preview URL. |
| Any other text | Extra context for the pull request body. |
Without -d, the pull request opens ready for review, and the session's status becomes under-review. A draft keeps it active. When the session already has an open pull request, /kosuke:open-pr brings it up to date. It rewrites the body and, when you pass -r, the reviewer list.
Outcomes
| The turn ends | What it means | What to do |
|---|---|---|
completed | The pull request is open or up to date. | Read prUrl from the session. |
awaiting_response | The agent needs a decision. It asks which GitHub login a -r name means when several or none match. It also asks which branch to target when the Target Branch changed after the pull request opened. | Send your answer as the next message. |
failed | The turn stopped early. | Read error on the job and prUrl on the session, then send /kosuke:open-pr again. |
cancelled | A member stopped the turn. | Send /kosuke:open-pr again. |
To mark a draft ready for review, set status to under-review with PUT on Chat sessions. Setting it back to active turns the pull request into a draft again. A merge on GitHub moves the session to Completed, and closing the pull request moves it to Archived.
Sync with the Target Branch
A session needs a sync when GET /api/projects/{projectId}/chat-sessions/{sessionId} shows isBehind: true. In the list from GET /api/chat-sessions, a session with an open pull request that has not run /kosuke:ship then carries needsYouReason: behind, unless a more severe reason wins. See Chat sessions.
To sync the branch on GitHub alone, run GitHub's own command with your identity: gh pr update-branch <number>. CI checks the merged code. The Sync button in the app does the same and refreshes the sandbox; the API and the CLI have no sync verb of their own.
Sync with the agent
When GitHub cannot merge the branch cleanly, or the sandbox holds local work, the agent syncs it.
- Send
/kosuke:sync-branchtoPOST .../jobs/chat, or$kosuke:sync-branchfor a Codex session. Use{"content":"/kosuke:sync-branch"}as the request body. It needs no flags. - Follow the Turn. The agent merges and resolves conflicts by what each side meant. It runs the cheapest check that proves the merge, leaving the full suite, build and lint to CI.
- If the Turn ends
awaiting_response, a conflict needs your call. The Clarification names the file and shows both versions. Send your choice as the next message. - When the Turn ends
completed, read the reply for what came in and how each conflict was resolved. After the push, setup or services run only when the incoming changes need them.
The agent commits and pushes the merge after its checks pass. When the sync finishes, the session stops reading behind.
Limits
- A message sent to an Under Review session keeps it Under Review, and its pull request stays ready. The agent turns the pull request back into a draft itself (
gh pr ready --undo) before it changes it, and the session follows GitHub to Active. A sync alone keeps it ready. - Queued behind a running turn, a member's message starts its own turn when it reaches the front of Up next. The messages behind it wait for the review to end.
- A Cron or another session gets
400on an Under Review session. A Merge agent run of the same project may write into it. - A Backlog session has no branch yet. Start it with
POST .../activatebefore you send either skill.
Errors
Skill messages go through POST .../jobs/chat and return its errors. The ones you meet most here:
| Status | Code | When |
|---|---|---|
| 400 | BAD_REQUEST | The session is Backlog, Completed or Archived. |
| 400 | SESSION_UNDER_REVIEW | The session is Under Review and the sender may not write into it: a Cron, or a session other than a Merge agent run of the project. |
| 402 | CREDIT_LIMIT_REACHED | The workspace is blocked on billing. |
| 409 | SANDBOX_STARTING | The sandbox is still starting. Send again in a few seconds. |
| 409 | SANDBOX_LIMIT_REACHED | Waking the paused sandbox, or starting a missing one, would pass the workspace's concurrent sandbox limit. |
Messages and turns lists the codes a send returns, and Responses and errors has the full table.