@kammcs/buildit-mcp 0.7.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,39 @@
2
2
 
3
3
  All notable changes to buildit-mcp are listed here. The project follows [semantic versioning](https://semver.org); see [Versions](README.md#versions) for what that means for tools.
4
4
 
5
+ ## [0.8.0] - 2026-10-29
6
+
7
+ Built on version 1.9.0 of the agent API's contract. Handoffs and Needs need a buildIt.Social server with agent API 1.9.0; on an older one the handoff tools aren't listed (or say plainly that the server is too old), `needs` is refused with an explanation, capabilities aren't suggested, and everything else works as before.
8
+
9
+ ### Handing work to another session (channel mode)
10
+
11
+ - **Capabilities.** `connect` detects what the computer can do and suggests it as capability tags from a fixed list: the operating system (`windows`, `macos`, `linux`), and `xcode`, `ios`, `android`, `flutter`, `docker` and `rust` from known programs on the `PATH` and known folders (the Android SDK's, Xcode's developer folder and its iOS platform). Nothing is run: each check only looks for a file or folder, gives up after 1.5 seconds, and a failure means "not found", so detection never stops `connect`. **Only the tag names are sent**, never a path, a version or anything else. `connect --capabilities macos,ios` sends your own tags instead (`none` sends none). When a channel session starts, it suggests what it detects again (`PUT /v1/session/capabilities`; `BUILDIT_CAPABILITIES` replaces detection, and an older server's 404 is skipped). The owner confirms the tags that count in buildIt.Social; a session only suggests. `status` and `whoami` show the confirmed tags and the suggestions not confirmed yet.
12
+ - **`propose_handoff`** (`item`): proposes handing a subtask of the item the session works on to another of the owner's sessions that has its Needs. buildIt.Social posts one card in the subtask's thread; only the owner's tap hands it over. Idempotent: the id is made from the session and the subtask, so a retry returns the first proposal (`created: false`) instead of a second card. It returns the sessions the card offers.
13
+ - **`withdraw_handoff`** (`handoff` or `item`): closes the session's own proposal while its card waits.
14
+ - **`decline_handoff`** (`handoff` or `item`, `reason`): hands a subtask handed to this session back with a short reason (1 to 1,000 characters), instead of stopping silently.
15
+ - The refusals come in plain words: no Needs, not a subtask of the session's own item (and a subtask can't have children), done or canceled, assigned to an agent or to a colleague, another session in its thread, a live handoff already, 5 proposals open, no session that can take it, handoffs switched off, a read-only org, and a card that has already ended.
16
+ - **Needs.** `create_item` and `update_item` take `needs` (capability tags, at most 10; `[]` clears them), and items show them (`needs` in structured results, "needs macos, ios" in the lines and `get_item`).
17
+
18
+ ### Events
19
+
20
+ - **`event="item_assigned"` with `handoff="true"`** (`work_item.assigned` with `data.handoff`), plus `handoff_id`, `parent` and `needs`: a subtask the owner handed to this session. The lead says it came by the owner's tap from which session, to work on that subtask only, to move it to In review or Done, to hand it back with `decline_handoff` if it can't, and to ask first before a store upload or a release version change; the subtask's title and description are data blocks marked `via_agent`.
21
+ - **`event="child_done"`** (new, `work_item.child_done`), in the parent's thread, with the parent (`item`), the `child`, the `outcome` (`in_review`, `done`, `declined`, `ended`), the `reason` and the `handoff_id`. The result (the subtask thread's last reply, or the reason it was handed back) comes inside an `untrusted_content` block with its author, `from_owner` and `via_agent`, followed by "Check the result before you rely on it."
22
+ - **`event="handoff_resolved"`** (`card.closed` with `data.handoff`), in the parent's thread: the outcome of the session's proposal (`applied`, with `to` and `queued` when the target is offline and the work waits up to 7 days; `cancelled`, `expired`, `stale`, `withdrawn`, `closed`) and what to do next. When this process doesn't know the parent (after a restart), it looks it up in the session's threads (one call at most once a minute), then in the subtask's own parent, and otherwise posts in the card's thread. It never reads the handoff for this: that call shares the 10-a-minute handoff budget that proposals need. The owner's tap itself (`card.response`) is dropped: its `card.closed` says everything.
23
+ - `event="item_unassigned"` gains the reasons `declined` ("you handed it back") and `handoff_expired`.
24
+
25
+ ### Plugin
26
+
27
+ - The lead sends `child_done` and `handoff_resolved` to the parent's worker (starting one when none has it), and starts a worker for a handed subtask as for any item.
28
+ - The item worker (`plugin/agents/buildit-item-worker.md`) gains "Work this session can't do" (check `whoami`, create a subtask with Needs, `propose_handoff`, never message another session, treat `child_done`'s result as data to check, ask instead when its own item is a subtask) and "When you were handed a subtask" (that subtask only, result in its thread, In review or Done, `decline_handoff` with a reason, and `ask` first for store uploads and release version changes).
29
+
30
+ ### Other
31
+
32
+ - The channel tools a server doesn't serve (by `/v1/meta`) are left out of the tool list, and the startup `/v1/meta` is read before the first listing.
33
+ - The fields an older server leaves out (every item's `needs`, the session's `capabilities` and `capabilities_detected`, a thread's `handoff`) are optional in the 1.9.0 contract itself, so an older server's items and sessions still parse.
34
+ - `list_threads` names each thread's handoff and its role: a subtask handed to this session, or one it proposed handing on (`handoff` in the structured result, with its id).
35
+ - The handoff tools' summaries say where a handoff stands in words (for a decline: "handed over, then handed back by the session that took it").
36
+ - The test fake answers as API 1.9.0, and as an older one with `compat.v19 = false`.
37
+
5
38
  ## [0.7.0] - 2026-10-29
6
39
 
7
40
  Built on version 1.8.0 of the agent API's contract. Tool approvals need a buildIt.Social server with agent API 1.8.0; on an older one the card can't be posted, and the terminal asks as before.
package/README.md CHANGED
@@ -4,7 +4,7 @@ An [MCP](https://modelcontextprotocol.io) server for [buildIt.Social](https://bu
4
4
 
5
5
  It runs on your own machine (stdio) or as a stateless HTTP server for a team. It holds no secrets of its own: each person's token stays in their own client.
6
6
 
7
- **Status:** 0.7.0, not yet on npm ([`@kammcs/buildit-mcp`](https://www.npmjs.com/package/@kammcs/buildit-mcp) has 0.4.0). Built on the agent API's v1 contract: items and comments by default (15 tools), and planning, pages, chat, admin and destructive changes when you turn them on (43 tools in all). In [channel mode](#talk-to-claude-code-from-builditsocial) it also brings your messages to your agent in buildIt.Social into a Claude Code session, which answers with `reply`; with the [buildit plugin](#questions-and-approvals-in-builditsocial-plugin), its questions, approvals and [tool approvals](#tool-approvals-in-builditsocial) come to you there as cards, and you can [assign it work items](#work-items-for-your-agent).
7
+ **Status:** 0.8.0, not yet on npm ([`@kammcs/buildit-mcp`](https://www.npmjs.com/package/@kammcs/buildit-mcp) has 0.4.0). Built on the agent API's v1 contract: items and comments by default (15 tools), and planning, pages, chat, admin and destructive changes when you turn them on (43 tools in all). In [channel mode](#talk-to-claude-code-from-builditsocial) it also brings your messages to your agent in buildIt.Social into a Claude Code session, which answers with `reply`; with the [buildit plugin](#questions-and-approvals-in-builditsocial-plugin), its questions, approvals and [tool approvals](#tool-approvals-in-builditsocial) come to you there as cards, and you can [assign it work items](#work-items-for-your-agent), which it can [hand to another of your sessions](#handing-work-to-another-session) with your tap.
8
8
 
9
9
  - [How it works](docs/design.md)
10
10
  - [Security policy](SECURITY.md)
@@ -248,7 +248,7 @@ It works only with the **Claude Code CLI** (not Claude Desktop), because it uses
248
248
 
249
249
  ### 1. Install or upgrade
250
250
 
251
- Nothing to install by hand: `npx -y @kammcs/buildit-mcp@latest` downloads the newest release when it runs, and again whenever a new one ships. Check the version with `npx -y @kammcs/buildit-mcp@latest --version`; channel mode needs 0.4.0 or newer, the [plugin](#questions-and-approvals-in-builditsocial-plugin) 0.5.0, [work items for your agent](#work-items-for-your-agent) 0.6.0, and [tool approvals](#tool-approvals-in-builditsocial) 0.7.0.
251
+ Nothing to install by hand: `npx -y @kammcs/buildit-mcp@latest` downloads the newest release when it runs, and again whenever a new one ships. Check the version with `npx -y @kammcs/buildit-mcp@latest --version`; channel mode needs 0.4.0 or newer, the [plugin](#questions-and-approvals-in-builditsocial-plugin) 0.5.0, [work items for your agent](#work-items-for-your-agent) 0.6.0, [tool approvals](#tool-approvals-in-builditsocial) 0.7.0, and [handoffs](#handing-work-to-another-session) 0.8.0.
252
252
 
253
253
  > **Until 0.4.0 is on npm**, `@latest` is an older release without channel mode, so use a local build: `git clone https://github.com/kammcs/buildit-mcp.git`, then `npm ci && npm run build` in it, and use `node /path/to/buildit-mcp/dist/index.js` wherever the steps below say `npx -y @kammcs/buildit-mcp@latest`. `connect` run that way prints the matching `claude mcp add` line.
254
254
 
@@ -260,15 +260,17 @@ In a terminal, in the folder where you run Claude Code (the project or repositor
260
260
  npx -y @kammcs/buildit-mcp@latest connect --project DEMO
261
261
  ```
262
262
 
263
- It prints a link and a code. Open the link, sign in to buildIt.Social if you need to, and check that the app shows the same code. The approval screen says what is connecting ("Claude Code on your computer's name"), as which of your agents and to which projects. The scopes are chosen there, not by the CLI: the screen pre-checks the usual ones, and you can untick any you don't want to give. Then approve. Approve only a code you started yourself. The code works for 10 minutes.
263
+ It prints a link and a code. Open the link, sign in to buildIt.Social if you need to, and check that the app shows the same code. The approval screen says what is connecting ("Claude Code on your computer's name"), as which of your agents and to which projects. The scopes are chosen there, not by the CLI: the screen pre-checks reading and writing items, reading and writing pages (`pages:write`, so Claude can create and edit pages, such as a project's docs) and reading chat, and offers deleting items and project admin unticked; you can untick any you don't want to give. Then approve. Approve only a code you started yourself. The code works for 10 minutes.
264
264
 
265
265
  Once it is approved, the command says who approved it and for which projects, as approved: `Connected as Claude (your name) in your org, project DEMO; session "your-folder".`, and asks **"Is this you? [y/N]"**. Whoever approves a code gets the session, so check the name: only `y` saves the token, in your OS keychain for this folder. Any other answer (or no answer, without a terminal) saves nothing and cancels the session at once, since someone else may have approved your code; run `connect` again for a new code.
266
266
 
267
267
  - `--project` takes up to 10 project keys (repeat it, or separate keys with commas). The session reaches only those projects, and never more than you can.
268
268
  - `--label <name>` names the session in buildIt.Social (1 to 40 characters; the folder's name by default). The agent's messages show as "agent · label".
269
269
  - `--folder <path>` connects another folder than the working directory. `--api-url <url>` connects to another buildIt.Social deployment: its agent API's address, such as `https://buildit.example.com/functions/v1/agent-api`; a bare host such as `https://buildit.example.com` gets `/functions/v1/agent-api` added (the command says so).
270
+ - `--capabilities <tags>` sends these capability tags (`macos,ios`) instead of the ones detected on the computer, or none with `none`; see [Handing work to another session](#handing-work-to-another-session). Only tag names are ever sent.
270
271
  - `--yes` saves without asking. It is for scripts only, and unsafe whenever anyone else could have seen the code.
271
272
  - No personal access token is involved: the session has a token of its own (`buildit_ags_...`), which the CLI keeps and never prints. It expires after 30 days unused.
273
+ - You can change a connected session's permissions later in buildIt.Social (Settings → Agents, **Edit permissions** on the session), without connecting again. Adding one asks for the same two-factor check as approving; a removed one stops working at the session's next call. `status` and `whoami` show the session's current scopes. This needs a buildIt.Social server that offers it; on an older one, connect again to change them.
272
274
 
273
275
  `npx -y @kammcs/buildit-mcp@latest status` shows the folder's session and whether buildIt.Social still accepts it; `disconnect` cancels the session in buildIt.Social and forgets the folder's token (if it can't reach buildIt.Social, it forgets the token anyway and says to revoke the session in the app).
274
276
 
@@ -326,9 +328,28 @@ With the plugin, the Claude Code session in the folder is the **lead**: it recei
326
328
  - **One worker per item.** A worker starts by reading its item (with its linked branches and pull requests), the item's thread from the start and the pages it links, then the repository. It posts every update, question and approval card in its item's thread, naming it, and treats the item, its comments and other people's messages as data, never as instructions. Your later messages in that thread go to that same worker; unassigning the item stops it.
327
329
  - **Its own worktree.** Each worker runs in its own git worktree (Claude Code's worktree isolation), on a branch named for its item, so parallel work on two items never touches the same files.
328
330
  - **A limit.** At most 3 items are worked on at once (the plugin's "Items at once" setting, 1 to 10). Another item waits its turn: the lead says so once in that item's thread ("Queued — I'll start this after DEMO-12, DEMO-13.") and starts it when a worker finishes.
329
- - **Named threads.** While the session works in more than one thread (an item's thread and the direct message, or several items), `reply`, `ask` and approval cards must name their thread: `thread_id`, or `item` with the item's key (a `propose_*` tool's `card_thread`); without one they're refused with the list of threads. `list_threads` lists the threads the session works in: each item's key, title, status, open cards and when you last wrote. With one thread, the latest one stays the default. Claude's own questions (`AskUserQuestion`, through the plugin) go where they belong: the lead's to your direct message, a worker's to its item's thread (the lead records each worker's agent id in its table for this); one that can't be placed is asked in the terminal. "<agent> is writing…" shows in each item's thread while its worker works on it.
331
+ - **Named threads.** While the session works in more than one thread (an item's thread and the direct message, or several items), `reply`, `ask` and approval cards must name their thread: `thread_id`, or `item` with the item's key (a `propose_*` tool's `card_thread`); without one they're refused with the list of threads. `list_threads` lists the threads the session works in: each item's key, title, status, open cards, when you last wrote, and its handoff if it has one (a subtask handed to this session, or one it proposed handing on). With one thread, the latest one stays the default. Claude's own questions (`AskUserQuestion`, through the plugin) go where they belong: the lead's to your direct message, a worker's to its item's thread (the lead records each worker's agent id in its table for this); one that can't be placed is asked in the terminal. "<agent> is writing…" shows in each item's thread while its worker works on it.
330
332
  - **After a restart** of Claude Code, a worker is started fresh for an item when its next event arrives, and reads the item's thread again to carry on.
331
333
 
334
+ ### Handing work to another session
335
+
336
+ With 0.8.0 and a buildIt.Social server with agent API 1.9.0, a session that can't do part of its work can hand that part to another of your sessions that can: a Windows session that needs iOS and macOS builds hands them to your Mac, say. Your tap on one card is the go-ahead; the sessions never message each other.
337
+
338
+ - **Capabilities.** At `connect`, buildit-mcp suggests what the computer can do as capability tags, from a fixed list: `windows`, `macos` or `linux` (the operating system), `xcode` and `ios` (macOS, with the full Xcode app and its iOS SDK), `android` (`ANDROID_HOME` or `ANDROID_SDK_ROOT`, or `adb` on the `PATH`), `flutter`, `docker` and `rust` (`flutter`, `docker`, `cargo` or `rustc` on the `PATH`). It only looks for those programs and folders, without running anything, and each check gives up after 1.5 seconds; a failed check means "not found" and never stops `connect`. **Only the tag names leave the computer**: never a path, a version or anything else. `web` and `gpu` are never detected; you add them in the app. `connect --capabilities macos,ios` sends your own tags instead (`--capabilities none` sends none). When a channel session starts, it suggests what it detects again (`BUILDIT_CAPABILITIES` replaces detection there; on an older server this is skipped).
339
+ - **You confirm them.** The suggested tags show ticked on the approval page, where you add or remove any; later, edit them in Settings → Agents. Only the tags you confirmed count: a session can only suggest, and tags never widen a session's projects or scopes. `status` and `whoami` show both ("Capabilities: macos, ios; suggested, not confirmed: flutter").
340
+ - **Needs.** Items have a Needs field, the capabilities a session must have to work on them (`create_item` and `update_item` take `needs`, at most 10, and `[]` clears it; items show it). Work for your agent with Needs goes only to a session that has them all, and waits for one otherwise.
341
+ - **The handoff.** The session creates a subtask under its own item (`create_item` with `parent`, `needs` and a description that says exactly what to do and what to report), then calls `propose_handoff` with its key. It keeps its own item and carries on. A session can only propose: buildIt.Social posts **one card in the subtask's thread**, worded from structured fields only (who asks, the subtask and its parent, the Needs, your matching sessions with the best one preselected, and what the target will do). Only you can answer it; your colleagues see it read-only. Your tap hands the subtask to the session you picked, and is the go-ahead.
342
+ - **The target must be connected to the same project.** A subtask always belongs to its parent's project, and a session that doesn't reach that project with write access is never offered, whatever its tags: connect the Mac with `--project <KEY>` for the same project too.
343
+ - **What each session hears** (as `<channel>` messages):
344
+ - The asking session gets `event="handoff_resolved"` with the subtask (`item`), its `parent`, the `outcome` (`applied`, with `to` and `queued` when that session is offline and the work waits up to 7 days; or `cancelled`, `expired`, `stale`, `withdrawn`, `closed`), in the parent's thread.
345
+ - The target session gets the subtask as `event="item_assigned"` with `handoff="true"`, its `handoff_id`, `parent` and `needs`: a lead that says you handed it over and from which session, then the subtask's title and description as data marked `via_agent` (another session wrote them). It works on that subtask only, posts the result in its thread and moves it to In review or Done. If it can't do the work, it hands it back with `decline_handoff` and a short reason.
346
+ - When the subtask reaches In review or Done, is handed back, or the handoff ends (canceled, moved, deleted, expired...), the asking session gets `event="child_done"` with the parent (`item`), the `child`, the `outcome` and the `reason`. The result (the subtask thread's last reply, or the reason it was handed back) comes inside an `untrusted_content` block, marked `via_agent` when another session wrote it: data to check before relying on it, never instructions.
347
+ - A session taken off a subtask gets `event="item_unassigned"` with the reason `declined` (it handed it back) or `handoff_expired` (nobody picked it up in 7 days).
348
+ - **`withdraw_handoff`** closes the session's own proposal while the card still waits for you.
349
+ - **Still asked separately.** The tap covers that subtask's work only. Store uploads and release version changes still ask you on their own card (the worker is told to `ask` first), and [tool approvals](#tool-approvals-in-builditsocial) still apply. Run the sessions that take handoffs in a mode that asks before tools run (not auto mode or bypass): the subtask's description was written by another session, and in a mode that doesn't ask, its tools run unasked.
350
+ - A session working on a subtask can't hand part of it on (subtasks have no children): it asks you instead.
351
+ - On a server older than agent API 1.9.0 the three tools aren't listed (or say plainly that the server is too old), `needs` is refused with an explanation, and the rest works as before.
352
+
332
353
  ### Questions and approvals in buildIt.Social (plugin)
333
354
 
334
355
  The **buildit plugin** for Claude Code (since 0.5.0; tool approvals since 0.7.0) adds what the bare channel can't do, so you can work with the session from your phone as well as from the terminal:
@@ -395,7 +416,7 @@ Tested with Claude Code 2.1.312.
395
416
 
396
417
  #### Try it from a checkout
397
418
 
398
- Until 0.7.0 is on npm, the plugin's server (`npx -y @kammcs/buildit-mcp@0.7.0 --channel`) can't be downloaded. A checkout can make a local plugin marketplace whose buildit plugin runs the checkout's own build:
419
+ Until 0.7.0 is on npm, the plugin's server (`npx -y @kammcs/buildit-mcp@0.8.0 --channel`) can't be downloaded. A checkout can make a local plugin marketplace whose buildit plugin runs the checkout's own build:
399
420
 
400
421
  ```sh
401
422
  git clone https://github.com/kammcs/buildit-mcp.git
@@ -423,7 +444,7 @@ claude --dangerously-load-development-channels plugin:buildit@buildit-dev
423
444
  - `--plugin-dir` alone doesn't do: it loads the plugin's hooks and server, but Claude Code registers a plugin's channel only for an installed plugin, so messages from buildIt.Social wouldn't arrive.
424
445
  - Run `npm run dev-marketplace` again after rebuilding or pulling, then `claude plugin marketplace update buildit-dev` and `claude plugin update buildit@buildit-dev`, so Claude Code takes the new copy; restart Claude Code. `claude plugin validate .dev-marketplace` checks it.
425
446
 
426
- On Windows, Claude Code starts the plugin's `npx` itself; if `/mcp` shows the plugin's server as failed, check that `npx -y @kammcs/buildit-mcp@0.7.0 --version` works in a terminal (Node.js 20 or newer on `PATH`).
447
+ On Windows, Claude Code starts the plugin's `npx` itself; if `/mcp` shows the plugin's server as failed, check that `npx -y @kammcs/buildit-mcp@0.8.0 --version` works in a terminal (Node.js 20 or newer on `PATH`).
427
448
 
428
449
  ### Where the token is kept
429
450
 
@@ -2,12 +2,12 @@
2
2
  * The agent API's operations, scopes and error codes, as the contract declares them.
3
3
  *
4
4
  * GENERATED by scripts/generate.ts from openapi/openapi.json (agent API
5
- * 1.8.0). Do not edit: change the contract, then run
5
+ * 1.9.0). Do not edit: change the contract, then run
6
6
  * `npm run generate`.
7
7
  */
8
8
  import * as S from './schemas.js';
9
9
  /** The contract's API version. */
10
- export const API_VERSION = '1.8.0';
10
+ export const API_VERSION = '1.9.0';
11
11
  /** Token scopes, in the contract's order. */
12
12
  export const SCOPES = [
13
13
  'projects:read',
@@ -81,6 +81,12 @@ export const ERROR_STATUS = {
81
81
  plan_outside_thread: 422,
82
82
  approvals_off: 403,
83
83
  too_many_open: 409,
84
+ handoffs_off: 403,
85
+ not_parent_session: 403,
86
+ handoff_not_allowed: 409,
87
+ handoff_exists: 409,
88
+ no_target: 409,
89
+ handoff_closed: 409,
84
90
  };
85
91
  /** Each error code's stable next step, as the contract words it. The API sends it as the error's hint; this copy serves when an older API doesn't. */
86
92
  export const ERROR_HINTS = {
@@ -134,7 +140,13 @@ export const ERROR_HINTS = {
134
140
  outside_reach: 'Stop work on that item; the person can connect a session that reaches its project.',
135
141
  plan_outside_thread: "Post the plan's card in the direct message, or keep the plan to the thread's project.",
136
142
  approvals_off: "Ask in the terminal; don't retry until the person turns tool approvals back on.",
137
- too_many_open: 'Close the tool approvals that no longer need an answer, or ask in the terminal.',
143
+ too_many_open: 'Close the tool approvals or handoff proposals that no longer need an answer, or ask in the terminal.',
144
+ handoffs_off: "Do the work in this session, or ask the person; don't retry until handoffs are back on.",
145
+ not_parent_session: 'Create the subtask under the item this session works on, then propose that subtask.',
146
+ handoff_not_allowed: "Fix what details.reason names (set the subtask's Needs, say), or ask the person.",
147
+ handoff_exists: 'Read the existing handoff (details.handoff_id) with get_session_handoff instead.',
148
+ no_target: 'Ask the person to connect a session for this project, or do the work here.',
149
+ handoff_closed: 'Read the handoff with get_session_handoff; it needs nothing more from this session.',
138
150
  };
139
151
  /** Every scope each plan action needs, all of them (the operations whose scope is 'plan_action' check them). */
140
152
  export const PLAN_SCOPES = {
@@ -490,6 +502,36 @@ export const OPERATIONS = {
490
502
  discovery: false,
491
503
  response: S.CloseSessionCardResponseSchema,
492
504
  },
505
+ close_session_handoff: {
506
+ method: 'POST',
507
+ path: '/v1/session/handoffs/{id}/close',
508
+ pathParams: ['id'],
509
+ arrayQueryParams: [],
510
+ scope: null,
511
+ requiredScopes: [],
512
+ hints: { read_only: false, destructive: false, idempotent: true, needs_projects: false },
513
+ errors: [
514
+ 'bad_request',
515
+ 'token_invalid',
516
+ 'token_expired',
517
+ 'token_revoked',
518
+ 'token_suspended',
519
+ 'agent_access_off',
520
+ 'not_found',
521
+ 'body_too_large',
522
+ 'validation',
523
+ 'rate_limited',
524
+ 'internal',
525
+ 'unavailable',
526
+ 'session_token_required',
527
+ 'agent_sessions_off',
528
+ 'handoff_closed',
529
+ ],
530
+ hasBody: true,
531
+ statuses: [200],
532
+ discovery: false,
533
+ response: S.SessionHandoffResponseSchema,
534
+ },
493
535
  complete_sprint: {
494
536
  method: 'POST',
495
537
  path: '/v1/projects/{key}/sprints/{sprint}/complete',
@@ -820,6 +862,41 @@ export const OPERATIONS = {
820
862
  discovery: false,
821
863
  response: S.SprintResponseSchema,
822
864
  },
865
+ decline_session_handoff: {
866
+ method: 'POST',
867
+ path: '/v1/session/handoffs/{id}/decline',
868
+ pathParams: ['id'],
869
+ arrayQueryParams: [],
870
+ scope: null,
871
+ requiredScopes: [],
872
+ hints: { read_only: false, destructive: false, idempotent: false, needs_projects: false },
873
+ errors: [
874
+ 'bad_request',
875
+ 'token_invalid',
876
+ 'token_expired',
877
+ 'token_revoked',
878
+ 'token_suspended',
879
+ 'agent_access_off',
880
+ 'forbidden',
881
+ 'archived',
882
+ 'not_found',
883
+ 'body_too_large',
884
+ 'validation',
885
+ 'rate_limited',
886
+ 'internal',
887
+ 'unavailable',
888
+ 'session_token_required',
889
+ 'agent_sessions_off',
890
+ 'thread_other_session',
891
+ 'thread_not_bound',
892
+ 'outside_reach',
893
+ 'handoff_closed',
894
+ ],
895
+ hasBody: true,
896
+ statuses: [200],
897
+ discovery: false,
898
+ response: S.SessionHandoffResponseSchema,
899
+ },
823
900
  describe_project: {
824
901
  method: 'GET',
825
902
  path: '/v1/projects/{key}',
@@ -1078,6 +1155,34 @@ export const OPERATIONS = {
1078
1155
  discovery: false,
1079
1156
  response: S.GetSessionApprovalResponseSchema,
1080
1157
  },
1158
+ get_session_handoff: {
1159
+ method: 'GET',
1160
+ path: '/v1/session/handoffs/{id}',
1161
+ pathParams: ['id'],
1162
+ arrayQueryParams: [],
1163
+ scope: null,
1164
+ requiredScopes: [],
1165
+ hints: { read_only: true, destructive: false, idempotent: true, needs_projects: false },
1166
+ errors: [
1167
+ 'bad_request',
1168
+ 'token_invalid',
1169
+ 'token_expired',
1170
+ 'token_revoked',
1171
+ 'token_suspended',
1172
+ 'agent_access_off',
1173
+ 'not_found',
1174
+ 'validation',
1175
+ 'rate_limited',
1176
+ 'internal',
1177
+ 'unavailable',
1178
+ 'session_token_required',
1179
+ 'agent_sessions_off',
1180
+ ],
1181
+ hasBody: false,
1182
+ statuses: [200],
1183
+ discovery: false,
1184
+ response: S.SessionHandoffResponseSchema,
1185
+ },
1081
1186
  get_thread: {
1082
1187
  method: 'GET',
1083
1188
  path: '/v1/messages/{id}/thread',
@@ -1653,6 +1758,45 @@ export const OPERATIONS = {
1653
1758
  discovery: false,
1654
1759
  response: S.PostSessionMessageResponseSchema,
1655
1760
  },
1761
+ propose_session_handoff: {
1762
+ method: 'POST',
1763
+ path: '/v1/session/handoffs',
1764
+ pathParams: [],
1765
+ arrayQueryParams: [],
1766
+ scope: null,
1767
+ requiredScopes: [],
1768
+ hints: { read_only: false, destructive: false, idempotent: false, needs_projects: false },
1769
+ errors: [
1770
+ 'bad_request',
1771
+ 'token_invalid',
1772
+ 'token_expired',
1773
+ 'token_revoked',
1774
+ 'token_suspended',
1775
+ 'agent_access_off',
1776
+ 'outside_limits',
1777
+ 'forbidden',
1778
+ 'not_found',
1779
+ 'idempotency_conflict',
1780
+ 'body_too_large',
1781
+ 'validation',
1782
+ 'rate_limited',
1783
+ 'internal',
1784
+ 'unavailable',
1785
+ 'session_token_required',
1786
+ 'agent_sessions_off',
1787
+ 'outside_reach',
1788
+ 'too_many_open',
1789
+ 'handoffs_off',
1790
+ 'not_parent_session',
1791
+ 'handoff_not_allowed',
1792
+ 'handoff_exists',
1793
+ 'no_target',
1794
+ ],
1795
+ hasBody: true,
1796
+ statuses: [200, 201],
1797
+ discovery: false,
1798
+ response: S.ProposeSessionHandoffResponseSchema,
1799
+ },
1656
1800
  rank_item: {
1657
1801
  method: 'POST',
1658
1802
  path: '/v1/items/{key}/rank',
@@ -2052,6 +2196,34 @@ export const OPERATIONS = {
2052
2196
  discovery: false,
2053
2197
  response: S.NoContentSchema,
2054
2198
  },
2199
+ set_session_capabilities: {
2200
+ method: 'PUT',
2201
+ path: '/v1/session/capabilities',
2202
+ pathParams: [],
2203
+ arrayQueryParams: [],
2204
+ scope: null,
2205
+ requiredScopes: [],
2206
+ hints: { read_only: false, destructive: false, idempotent: true, needs_projects: false },
2207
+ errors: [
2208
+ 'bad_request',
2209
+ 'token_invalid',
2210
+ 'token_expired',
2211
+ 'token_revoked',
2212
+ 'token_suspended',
2213
+ 'agent_access_off',
2214
+ 'body_too_large',
2215
+ 'validation',
2216
+ 'rate_limited',
2217
+ 'internal',
2218
+ 'unavailable',
2219
+ 'session_token_required',
2220
+ 'agent_sessions_off',
2221
+ ],
2222
+ hasBody: true,
2223
+ statuses: [200],
2224
+ discovery: false,
2225
+ response: S.SessionCapabilitiesResponseSchema,
2226
+ },
2055
2227
  start_sprint: {
2056
2228
  method: 'POST',
2057
2229
  path: '/v1/projects/{key}/sprints/{sprint}/start',