# Sidebars

A sidebar is the navigation of one person in one workspace: a tab under the search bar. Home is the default and always first. Each sidebar is one document in the sidebar language: an ordered list of collapsible blocks. The `sidebar` app gives an agent the same edits that the person has in the UI.

## Where the tools work

- Only in the person's direct message with you, with the person as its only human. Tool results stay in the chat, and every member can read the other chats of a workspace. Anywhere else the tools return `permission_denied`.
- Only with a person at the desk. A routine, a webhook, or a wake from another chat gets `permission_denied`. Tell the person what to add instead.
- Each change shows a row with Undo under your message, only to the person whose sidebar changed.

## Blocks

- `pages`: links to app pages, with a More row for the rest.
- `links`: a link group: a title and links. A link has `target_uri` (`aios://<type>/<uuid>`: artifact, chat, agent, computer, database, routine, site) or `url` with a required `label`.
- `link`: one standalone link between blocks.
- `list`: a live list from a source: chats, tasks, a folder, routines, or rows of a database table.
- `section`: agents, channels, or direct messages.
- `group_ref`: a shared group, shown by reference (see Groups).

Limits: 12 sidebars, 30 blocks and 200 links in a sidebar, 100 links in a group. A destination can be in a sidebar only once.

## Tools

| Tool | Method | What it does |
|---|---|---|
| `sidebar.list` | GET | Every sidebar, Home first, with its document exactly as `update_sidebar` takes it, `destinations` (each link's title and `available`), and `groups` (each block's group, by block id). |
| `sidebar.create_sidebar` | POST | A new sidebar: `name`, optional `icon` and `blocks`. |
| `sidebar.update_sidebar` | POST | A name, an icon, a place among the tabs, or the whole block list. Send `expected_revision` with `blocks`. |
| `sidebar.remove_sidebar` | POST | Remove a custom sidebar. Home cannot be removed. |
| `sidebar.add_link` | POST | Put a destination or a URL in a sidebar (default Home). |
| `sidebar.remove_link` | POST | Remove one link by `link_id` or `target_uri`. |
| `sidebar.list_shared_groups` | GET | The groups others share with the person, with `placed_in`. |
| `sidebar.list_group_shares` | GET | Who one group is shared with (`?sidebar_group_id=`), and `everyone_team_id`. |
| `sidebar.add_group` | POST | Place a shared group in a sidebar by reference. Has Undo. |
| `sidebar.duplicate_group` | POST | The person's own copy of a group, as an inline block. Has Undo. |
| `sidebar.share_group` | POST | Share a group with a member or a team, view or edit. No Undo. |
| `sidebar.unshare_group` | POST | Stop sharing a group with a member or a team. No Undo. |
| `sidebar.set_default_group` | POST | Owners and admins: put a group in every member's Home, or take it out. No Undo. |

## Groups

A `links` or `list` block is a group with a stable id. Find it in the `groups` map of `sidebar.list`:

- an inline block: `{ sidebar_group_id, shareable, shared, default }`;
- a `group_ref` block: `{ sidebar_group_id, ref: true, title, block_type, owner, access, default, available }`.

Rules:

- The group stays in its owner's sidebar. A reference shows it live, with the reader's own access. A link that the reader cannot open shows locked.
- To share with every member, call `list_group_shares` and use its `everyone_team_id` with `share_group` (`principal_type: "team"`). A guest gets view only.
- Edit access lets a person change that block only. To add or remove a link in a group through its reference, pass `sidebar_group_id` instead of `sidebar_id` to `add_link` or `remove_link`.
- To remove a reference, send `update_sidebar` without that block. A workspace default in Home cannot be removed; the person can collapse or move it.
- Ask the person before `share_group` or `set_default_group`. Others then see the group's title and its link titles.
- The service records each group change in the Event Log (`sidebar_group.shared`, `unshared`, `added`, `removed`, `duplicated`, `default_set`, `default_cleared`).

## Errors

`invalid_input` names the path of each problem (`blocks.2.source.table: …`). `not_found` is a sidebar or group that is gone or not visible to the person. `permission_denied` is the DM rule, an unattended run, or missing access (for example `set_default_group` by a member). A conflict on `update_sidebar` means another change wrote the blocks after your read: read again with `sidebar.list`.
