---
canonical: "https://agi-labo.com/tools/cockpit/docs/cockpit-cli/reference/crew"
title: "cockpit crew"
description: "cockpit crewの構文、オプション、結果、制約をcockpit CLIの正本から自動生成したリファレンスです。"
section: "リファレンス"
order: 115
pageType: reference
lastVerifiedVersion: 4.61.0
lastVerifiedAt: "2026-08-27"
draft: false
surfaces:
  - cli
operatingSystems:
  - windows
  - macos
  - linux
plans:
  - guest
  - member
navigation: false
---

このReference本文は、アプリが配布するcockpit CLIヘルプと同じ英語の正本から自動生成されています。日本語の概念説明と安全な使い方は[cockpit CLI](/tools/cockpit/docs/cockpit-cli)を参照してください。

Crews are in alpha: how they work and their settings may change. A Crew is a resident agent that talks with people in chat (Discord today). It receives requests in DMs, channels, and threads, works on them itself or delegates them to child tasks, and replies in the chat. A Crew also works without any chat connection: the owner can talk to it inside Cockpit and send it Autoruns. A Crew is meant for its owner: every turn, including one started by another person the owner lets talk to it, runs on the owner's agent account (subscription sign-in or API key). Some AI services forbid letting others use an account or reaching it through automated means, so whether to add other people, and on which account, is the owner's decision under each service's terms. Each Crew has its own home folder (`AGENTS.md`, `memory/`, `.agents/skills/`, `work/`, `archive/`) under the Cockpit data folder. A Crew works in its home unless the owner chooses a project for it when creating it on the New Task screen (Task / Crew at the top) or later in its settings; then it works in the project's folder, its home stays the place for those files and is given to the agent as an extra folder with its `AGENTS.md`, its child tasks belong to that project, and the task list shows the Crew inside that project's group. Changing the place starts a new session that carries the conversation; A Crew's icon is its chat avatar when it has one; otherwise the icon chosen in its settings in Cockpit (the center of the image, cropped to a square), or its initial. Choosing an icon for a Crew connected to Discord also sets its Discord avatar (Discord limits how often that can change; a refused change changes nothing), and removing the icon also removes the Discord avatar. Cockpit reads the connected Discord account's name and avatar again each time it connects; Cockpit keeps the credentials, the people who may talk to it, and the places it listens to. Every command returns JSON and is local-only. `<crew>` is a Crew id or its name (names match without regard to case; when two Crews share a name, use the id).

## Manage Crews

```bash
cockpit crew list
cockpit crew get <crew>                                    # Settings and runtime status (credentials are never returned)
cockpit crew create --name <name> [--agent-type <type>] [--model <model>] [--effort <effort>] [--approval-mode <mode>]
cockpit crew update <crew> [--name <name>] [--agent-type <type>] [--model <model>] [--effort <effort>] [--approval-mode <mode>]
                   [--heartbeat on|off] [--heartbeat-interval <minutes>] [--heartbeat-hours <HH:MM-HH:MM>|always] [--heartbeat-skip on|off]
                   [--member-trust colleagues|strict]
cockpit crew instructions <crew> --get                     # Read AGENTS.md
cat AGENTS.md | cockpit crew instructions <crew> --set-stdin   # Replace AGENTS.md (4,000 characters at most) and commit it
cockpit crew open-home <crew>                              # Open the home folder in the file manager
cockpit crew start <crew>
cockpit crew stop <crew>
cockpit crew restart [<crew>]                              # From the Crew's own session, the Crew itself
cockpit crew status [<crew>]                               # One-screen summary for the Crew (see below)
cockpit crew check [<crew>]                                # Everything a periodic check looks at, in one answer
cockpit crew check [<crew>] --settled [--next <time>] [--note <text>]   # Declare that nothing needs the Crew until then
cockpit crew send <crew> --text "..."                      # Talk to the Crew inside Cockpit (also --stdin, --text-file)
cockpit crew remove <crew>                                 # Deletes the settings; the home folder moves to the Trash (homeTrashed)
```

`create` makes the home folder, commits its first version with git, and starts the Crew. `--agent-type` accepts the same agents as tasks except `terminal` and `antigravity` (Antigravity's terms treat access through software other than Google's own as a breach that can suspend the account; a Crew saved on it comes back on Claude) (default: the default agent); an empty `--model` uses the agent's default model. `open-home` opens the home folder on the computer that runs Cockpit, like **Open folder** in Settings; `cockpit crew get <crew>` returns its path. `start` resumes delivery from the Crew's Queue and connects every chat connection whose setup is finished; on a running Crew it reconnects a connection that the platform refused (`state` `error`, for example after you turn on the Message Content Intent). `stop` disconnects them and stops the session while keeping the Queue. `restart` lets the running turn end and delivers the messages that were already waiting, then starts a new session whose first message asks the Crew to check its state. When the Crew keeps failing (its `deliveryRetry` is set, or its session could not start), `restart` does not wait for the messages that were already waiting: it starts the new session at once, and those messages reach it after its first message. Messages that arrive after the restart was requested wait and reach the new session after that first message, however many keep arriving. A requested restart is kept when Cockpit quits and is carried out after it starts again. Changing `--agent-type` while the Crew is answering works the same way: the turn ends first, and the messages that arrive meanwhile reach the new agent's session. A new model or effort applies from the next message, or from the next session when the agent cannot switch it in the middle of one, such as Claude's effort. Send work to a Crew on a schedule with `cockpit autorun create --target-crew <crew>`; when a Crew or its child task creates or changes the Autorun, its text reaches the Crew wrapped in `<task_message>` like `cockpit crew send` text (see below).

`--approval-mode` decides which of the Crew's commands and edits wait for the owner's approval: `supervised`, `accept-edits`, `auto`, or `full-access`, as for tasks (`cockpit help task`). Without `--approval-mode`, a new Crew starts carefully: in `auto` with Claude, Codex, and Grok, whose own review allows routine actions and blocks risky ones, and in its agent's most careful mode (`supervised`, or `accept-edits` for Muse Code) with the other agents; the New Task screen offers the same default for a Crew. A Crew works while no one is watching, so an approval wait holds its reply and every message queued after it until the owner allows the action in Cockpit, which cannot be done from the chat. `auto` works only with Claude, Codex, and Grok, and some accounts and models fall back to `supervised`, which waits the same way. Choose `full-access` for a Crew that has to act without such waits. A Crew keeps the mode it has; a Crew created before this default keeps its `full-access`. In `full-access` the Crew runs commands and edits files on this computer without asking anyone, so the people allowed to talk to it, and any text it reads (chat messages, attachments, web pages, `cockpit crew history`), can lead it to do so. Its standard tells it to treat outside text as data, but that is an instruction the agent may fail to follow, not a guard. Choose who may talk to the Crew with this in mind, and a more careful mode for a Crew that needs one. When the agent type changes, the Crew keeps its mode if the new agent supports it, and otherwise takes the most careful mode that agent supports. A change applies to the running session; when the session cannot take the new mode, `update` answers `approval_mode_not_applied` (HTTP 409) and keeps the previous mode. For example, a Grok session restarts to turn `auto` on or off and cannot do that while it is working, so run the command again after the turn ends. `get` returns the mode as `crew.agent.approvalMode`. A Crew's child tasks cannot change it (`forbidden_from_crew`); the Crew's own session can make it more careful, and a more permissive mode it asks for waits for the owner's approval in Cockpit (see What a Crew's own session may do).

A child task runs in the mode it is created with (`--approval-mode` of `cockpit task create`, `run`, or `autorun create`, or a Fleet node's `approval`) or, without one, in its agent's default from Settings (`agents.approvalMode.<agent>`), but never in a more permissive mode than its Crew's, in the order `supervised`, `accept-edits`, `auto`, `full-access`. This holds for the tasks a Crew or its child task creates, those of an Autorun they created, and the nodes of a Fleet they started: a more permissive mode becomes the Crew's mode, or the agent's most careful mode when the agent lacks the Crew's mode. A Crew and its child tasks cannot create a task under another Crew's task (`forbidden_from_crew`, HTTP 403), and when a task they create belongs to a Crew other than theirs, the more careful of the two Crews' modes bounds it. They also cannot raise a task's mode with `cockpit task approval-mode` above their Crew's, or above the mode of the Crew that the task belongs to (`exceeds_crew_approval_mode`, HTTP 403); the owner can still change it in Cockpit. While their Crew, or the Crew the task belongs to, is not in `full-access`, they cannot approve what a task waits for with `cockpit task approve` or an empty `cockpit task send` (`approval_requires_owner`, HTTP 403): the owner approves it in Cockpit, and they can still deny it or answer its questions. Unless the Crew is in `full-access`, these tasks always run with an approval mode: Cockpit refuses a terminal task (`--agent-type terminal`), the terminal UI (`--ui-mode terminal`), and a command of the task's own (a `--command` other than the one in Settings), each of which would run outside any approval mode, with `exceeds_crew_approval_mode`, and a task created without `--ui-mode` opens its agent's visual UI. An Autorun of theirs that would start such a task is refused when it is created or changed, and if it would still start one when it runs, for example after the owner changed it in Cockpit, it needs the owner's attention (`crew-approval-limit`) instead. These bounds apply when a task is created and when its mode is changed; making the Crew more careful does not change the child tasks it already has. So a careful Crew hands off work that stays as careful, while a Crew in `full-access` can still give a child any mode, UI, or command its agent supports.

The periodic check (heartbeat) wakes a running Crew at a set interval with a `<heartbeat>` notice, so it follows up on its own work as its standard and the `HEARTBEAT.md` in its home say. `--heartbeat` turns it `on` or `off`, `--heartbeat-interval` takes a multiple of 30 minutes from 30 to 240 (a saved 15 becomes 30), and `--heartbeat-hours` limits it to a daily window in the local time of the computer that runs Cockpit (`22:00-06:00` crosses midnight; `always` runs at any hour; a start equal to its end is rejected with `heartbeat_hours_invalid`, and another interval with `heartbeat_interval_invalid`). Every Crew starts with it on, every 30 minutes, from 08:00 to 23:00. A check that comes due while the Crew is stopped, restarting, at a usage limit, waiting to retry a failed delivery, waiting for a person to approve a command or answer a question, working, holding queued messages, or outside its hours is skipped, not queued; after the computer sleeps, at most one overdue check runs. Each check runs at the Crew's own minute within the interval plus a random delay of up to a fifth of the interval, so checks neither come all at once nor at the exact same minute every time. `--heartbeat-skip on` lets Cockpit leave out a check while the Crew's `crew check --settled` declaration still holds (a declaration made in a turn after the last check, such as a conversation, does not count, so the first check after a conversation always runs); it is on by default; with `--heartbeat-skip off`, every check is sent and Cockpit only records which could have been skipped. A check left out this way has `lastSkipReason` `settled`, and `status.heartbeat.settled` shows the current declaration. `get` returns the settings as `crew.heartbeat` (absent until changed, meaning the defaults) and the last check as `status.heartbeat` (`lastRunAt`, `lastResult` `ok`, `acted`, `skipped`, or `failed`, `lastSkipReason`, `nextRunAt`). A turn that ends with only `HEARTBEAT_OK` counts as `ok`.

`--member-trust` decides whether people other than the owner can have the Crew change its own settings by asking it: `colleagues` (the default) lets a turn that any person allowed to talk to the Crew started make the changes that need a person's request, and `strict` leaves them to the owner's turns. `get` returns it as `crew.memberTrust` (absent means `colleagues`). The Crew's own session can set `strict` itself; going back to `colleagues` from its session waits for the owner's approval.

`remove` answers `home` and `homeTrashed`; when `homeTrashed` is `false`, the Crew is removed but its home folder stays at `home` for you to move or delete.

`instructions --set-stdin` replaces AGENTS.md as given. The AGENTS.md editor in Cockpit saves only over the content it loaded; when the file changed in the meantime (for example the Crew updated it), saving answers `instructions_changed` and writes nothing.

Besides `AGENTS.md`, which the owner edits, Cockpit gives every new session of a Crew its own standard, which the owner cannot edit. The standard defines the outside actions that the new `AGENTS.md` asks the Crew to confirm: posting in another place of its chats needs no confirmation when the requester named both the place and the content; writing to a service outside the chat (mail, social media, GitHub, web forms, external APIs, invitations, permission changes, production deploys) and publishing are always confirmed through an Ask, because a chat cannot tell the owner from other people who may talk to the Crew. When such an Ask comes from a chat request, the Crew also says in that conversation that it waits for confirmation in Cockpit. Replies within the conversation it was asked in need no confirmation. An `AGENTS.md` created before this rule keeps its own wording until the owner changes it.

`get` returns the settings as `crew` and the runtime `status`, with `deliveryRetry` (below) and `connections` that give each connection's `state`, `error`, and `ownerCandidate` (the person whose DM waits for **Yes, it's me** during the owner step, or `null`). `status` returns `state` (`running`, `error` when a connection failed, `stopped`), `restarting`, `restartError` (why the last restart failed, or `null`), `deliveryRetry`, `connections` (`platform`, `state`, `account` name, `workspaces` with the names of the servers the Crew joined, `setup` progress, `error`, and `pending`, the number of people waiting for approval), `childTasks` that are running or waiting for input, open `asks` from the Crew and its child tasks, `queue.queued`, and the `autoruns` that send to the Crew with their `nextRunAt`.

`check` gathers in one answer what a periodic check looks at: child tasks, Asks, the Queue, Autoruns, the items in `HEARTBEAT.md`, requests not yet answered, memories past their date, and the current declaration. `check --settled` declares, after checking, that nothing needs the Crew until `--next` (or, without it, until something changes), with an optional `--note`; while the declaration holds, Cockpit may skip periodic checks. A new message, a notice, a change in the home folder, the `--next` time, or 6 hours after the declaration clears it. `--next` and `--note` need `--settled`.

`deliveryRetry` is `null`, or `{"error":"…","retryAt":"…"}` while the Crew holds its next queued message because the previous delivery or turn failed, or because its session could not start (for example, the agent is not signed in): `error` tells why (or is `null`), and `retryAt` is the ISO time when Cockpit tries again. The messages stay in the Queue meanwhile, so nothing is lost. The Crew waits 30 seconds after a failure and twice as long after each further failure in a row, up to 10 minutes. **Retry delivery** on a failed item in the Crew's Queue in Cockpit, or `cockpit crew restart`, sends again at once.

## Connect a chat

```bash
cockpit crew setup begin <crew> --platform discord
cockpit crew setup next <crew> [--platform discord]       # At the owner step, finishes the setup without an owner
printf '%s' "$TOKEN" | cockpit crew connect <crew> --platform discord --token-stdin
cockpit crew setup cancel <crew> [--platform discord]      # Cancels a token change that connect is still checking or saving
cockpit crew invite-url <crew> [--platform discord]
cockpit crew setup owner <crew> [--platform discord] --yes <user-id>
cockpit crew setup owner <crew> [--platform discord] --no <user-id>
cockpit crew setup redo <crew> [--platform discord] --step <n>
cockpit crew disconnect <crew> [--platform discord]       # Removes the connection and deletes its credentials
```

The setup commands do what the setup steps in Settings do. `setup begin` adds the connection (**Connect a chat**) at its first step, a guide: create an application in the Discord Developer Portal, copy its token with Reset Token, and turn on the Message Content Intent. `setup next` finishes the guide, and `connect` takes the token; Settings asks for the token right in the guide step and checks it as soon as it is pasted, so `connect` finishes the guide too. Then open the `invite-url` in a browser and add the Crew to a server; the step finishes when the Crew joins. Last, the owner sends the Crew a DM. The first person to send one appears in `pending list` and as the connection's `ownerCandidate`, and stays the candidate until the owner answers; a DM from someone else in the meantime only adds that person to `pending list`. Settings shows the candidate's Discord id next to the display name, as for everyone waiting for approval, so check that the id is the owner's before answering. `setup owner --yes <user-id>` (**Yes, it's me**) or `pending approve` adds that person as an owner, finishes the setup, and starts the Crew if it was stopped; at this step, `people add --user <id>` and `people owner --user <id>` finish it too, and `setup next` (**Continue without an owner**) finishes it with no owner. `setup owner --no <user-id>` (**Someone else**) keeps that person pending and waits for a DM from someone else. `setup redo --step <n>` goes back to an earlier step (**Redo**); `status` shows the current one as `setup` (`step` of `total`). `--platform` can be omitted when the Crew has one connection.

`connect` checks the credentials first. For Discord it needs a token whose application has the Message Content Intent turned on: `token_invalid` means Discord rejected the token (paste a token issued with Reset Token), `intent_disabled` means the intent is off in the Developer Portal. When the connection is removed (`disconnect`, **Cancel**), set up again, taken back to its guide or token step (`setup redo`), or the token change is cancelled while the token is being checked or saved, `connect` answers `setup_changed` and stores nothing, and the connection keeps its previous token. `setup cancel` cancels a token change the way **Cancel** next to the token does in Settings; stopping `connect` itself, for example with Ctrl-C, does not stop Cockpit from checking and saving the token. With no `connect` in progress, `setup cancel` changes nothing. One Discord application can be used either by Ask notifications or by one Crew; reusing it answers `app_in_use`. Connecting an existing connection again replaces its credentials and keeps its people and places.

## People and places

```bash
cockpit crew people add <crew> [--platform discord] --user <id> [--label <name>]   # Also --group <role-id> or --crew <id>
cockpit crew people add <crew> [--platform discord] --group <server-id> --confirm  # Everyone in the server (@everyone); --crew <id> also needs --confirm
cockpit crew people remove <crew> [--platform discord] --user <id>
cockpit crew people owner <crew> [--platform discord] --user <id>   # Make this person an owner
cockpit crew people owner <crew> [--platform discord] --user <id> --remove   # This person stays as a member
cockpit crew pending list <crew> [--platform discord]
cockpit crew pending approve <crew> [--platform discord] <user-id>
cockpit crew pending deny <crew> [--platform discord] <user-id>
cockpit crew place set <crew> [--platform discord] --channel <id> --mode mention|all|off [--name <name>] [--workspace <id>]
cockpit crew place remove <crew> [--platform discord] --channel <id>
cockpit crew place people add <crew> [--platform discord] --channel <id> --user <id> [--label <name>] [--confirm]
cockpit crew place people remove <crew> [--platform discord] --channel <id> --user <id>
cockpit crew place dm <crew> [--platform discord] --mode all|off
cockpit crew place other <crew> [--platform discord] --mode mention|off
cockpit crew channels <crew> [--platform discord]          # Channels in the servers the Crew has joined
cockpit crew groups <crew> [--platform discord]            # Roles in those servers
```

Only people on the list (users, crews, or members of a listed group) reach the Crew; a channel can add people who may talk only there. Adding everyone in a server (`--group` with the server's id, which is the id of its @everyone role) or a crew (`--crew`, the id of a crew or a webhook) lets anyone in that range, including people who join later, give the Crew requests, and in `full-access` those requests can run commands and edit files on this computer without asking. `people add` and `place people add` refuse such an addition with `audience_confirmation_required` unless `--confirm` is given; with it, the answer carries the same warning as `data.warning`. A webhook post never counts as a member of a group. For a DM, Cockpit reads the person's roles from the servers the Crew joined; when Discord cannot answer, the DM is retried for about half a minute instead of being treated as coming from someone without roles, and if Discord still cannot answer, the DM is dropped (Cockpit logs it) and the person needs to send it again. A DM from someone new does not reach the Crew: Cockpit adds the person to `pending` and replies once that they wait for the owner's approval, only once per person, even after `deny` or after newer requests pushed them out of the list (Cockpit remembers the last 1,000 people it told). After `approve`, their next message reaches the Crew; the DMs they sent while waiting are not delivered, so they need to send again. `pending` keeps the newest 50 people; the oldest request is dropped when another arrives. A person whose message reaches the Crew, for example through a role added later, leaves `pending`. A listed channel in `mention` mode delivers messages that mention the Crew and replies in a new thread; `all` delivers every message; `off` stops listening. Channels that are not listed follow `place other`. A thread follows its parent channel. A thread the Crew joined (Cockpit started it for a mention, or the Crew created or posted in it) delivers every message from people who may talk without a mention, even when its channel is not listed and other channels are off; only a listed channel set to `off` stops it. Cockpit remembers the 500 threads the Crew joined most recently. Ids may be given with or without the `discord:` prefix. `--label` sets the display name stored for a person; without it, Cockpit uses a name it already knows, or the id. `--name` and `--workspace` set the channel's display name and its server when the channel list cannot be read.

A connection can have several owners or none (`ownerIds` in `get`): the person who answered **Yes, it's me** at the owner step, and the users the owner marks with `people owner --user <id>` or the **Owner** checkbox in Settings. Marking someone not yet on the list adds them as a user; `people owner --remove` takes the mark off and keeps them as a member, and `people remove` of an owner takes them off the list and the owners. Cockpit marks each message it delivers with `role="owner"` when the author is one of the owners and `role="member"` for everyone else, from the author id the chat reports, so the text of a message cannot claim it. The Crew's standard tells it to take a member's request more carefully: for a member it only looks things up and answers, or makes things inside its home, and it does not read or send files outside its home, change settings, hooks, or Autoruns, touch secrets, delete or do anything it cannot undo, or act on other tasks; when such a request needs doing, it asks the owner through an Ask. This is an instruction the agent may fail to follow, not a guard, and it does not stop text the owner forwards or the Crew reads (web pages, attachments, `cockpit crew history`) from steering it. Whoever controls an owner's Discord account speaks to the Crew as the owner, so keep owners' accounts secure. Without an owner every message is marked `role="member"`, so nobody in chat can ask for what only the owner may ask for; the owner still can in Cockpit.

### Chat platform rules

A Crew talks through the owner's own bot application, so the platform's developer terms apply to it. On Discord, the Developer Policy asks apps not to send unsolicited or automated messages that only keep a server active, not to use message content to train AI models, and to tell users how their data is used. A Crew sends what people say to it to its agent's AI service, so tell the members of each server where it listens, for example by pinning a note such as: "This server has <name>, an AI assistant run by <owner>. Messages that mention it, or are in channels it answers in, are sent to <AI service> to answer them. Ask <owner> to remove it or to stop it reading a channel." A bot in more than 100 servers also needs Discord's approval for the Message Content Intent.

## Chat operations (from the Crew's session)

```bash
cat reply.md | cockpit crew reply --message <message_id> --stdin [--file <path>]...
cockpit crew reply --message <message_id> --text "..." [--file <path>]...
cockpit crew post --place <place_id> --stdin [--file <path>]...
cockpit crew reply --message <message_id> --file <path>...   # Files only
cockpit crew thread --channel <place_id> --name <name>
cockpit crew history --place <place_id> [--limit <n>]     # Recent messages
```

These commands work only from the Crew's own session and act as that Crew. Cockpit identifies the session by a per-task secret that it passes to the session (`AGI_COCKPIT_SECRET_TASK_TOKEN`); `AGI_COCKPIT_CREW_ID` alone is not accepted. From anywhere else they answer `crew_session_required`. `reply` and `post` take their text from one of `--text`, `--text-file <path>`, or `--stdin`; with at least one `--file`, the text can be left out and only the files are sent. `send` always needs text. Text from `--stdin` and `--text-file` is sent as it is, except that NUL characters are dropped and a byte order mark at the start of a file is not part of the text; the same holds for `send` and `instructions --set-stdin`. Chat messages reach the Crew as `<message platform="discord" place="#general › thread" place_id="discord:…" message_id="discord:…:…" author="…" author_id="discord:…" time="…">text</message>`; ids always start with the platform name and are passed back unchanged. Attachments come with the message as files; one over 25 MB, or one that could not be downloaded within a minute, is not loaded, and its name is listed in a `skipped_files` attribute instead. Cockpit keeps each received attachment for seven days from when it arrived, also when the same file arrives again, and longer only while its message still waits in the Queue; copy a file the Crew needs later into its home. Files from answers to Asks and the owner's own files are not removed this way. `reply` answers in the thread Cockpit started for the message, or in the same place, also when someone else started a thread from the message; when Cockpit cannot read whether the message has its thread, `reply` posts nothing and answers `request_failed`. Text longer than the platform limit (2,000 characters on Discord) is split at line breaks into several messages, at most 10 (`text_too_long` otherwise, before anything is posted; post a summary and attach the full text as a file); a line too long for one message is cut only where a message ends, and a code block that a split cuts is closed at the end of one message and opened again at the start of the next. Files are attached to the last message. A Discord message carries at most 10 files, and Cockpit keeps the files of one message within 20 MB in total; the rest follow in further messages. Before posting anything, Cockpit checks that every `--file` exists (`file_not_found`), can be read (`file_unreadable`), and is within the platform limit (`file_too_large`, 20 MB per file on Discord). Posts notify mentioned users and the person replied to, never `@everyone` or `@here`. `thread` creates a thread in a channel and joins it. `history` returns 50 messages by default and 500 at most, even when `--limit` is larger.

```json
{"ok":true,"messageIds":["discord:123:456"]}
{"ok":false,"error":"...","code":"not_connected"}
```

`thread` returns `{"ok":true,"placeId":"discord:…"}` and `history` returns `{"ok":true,"messages":[...]}`.

While the Crew works on a chat message, Cockpit shows the platform's typing indicator (on Discord, "<name> is typing…") where the reply goes: the message's place, or the thread Cockpit started for a mention. It starts with the message's turn, is sent again every 7 seconds, pauses while the turn waits for approval or an answer, and stops when the Crew posts there, when the turn ends, after 30 minutes without a reply, and when the Crew stops, restarts, is removed, or disconnects; Discord hides it at once when the Crew posts there and otherwise within 10 seconds. A post in another place leaves it on. A turn that continues the conversation shows it again in the same place: one the agent starts on its own, such as after a background command finishes, and an answered Ask, a child task's report, or a delivered secret. A turn started by an Autorun, a message from the desktop or another task, or a stop or restart of the Crew ends that conversation, and the turns after it show nothing until the next chat message. A failure to show it, such as a missing permission or a rate limit (Cockpit waits as long as Discord asks), is logged and never holds back a reply.

When a later part of a split message, or a later group of files, fails after earlier parts were posted, the error also tells what was posted and what was not. Do not send the whole message again; post only `unsentText` with `unsentFiles` to `placeId`. `unsentText` is exactly the part of your text that was not posted, so a line that was cut, such as a long URL, stays whole; when that part starts inside a code block, it begins with the line that opens the block. A request that ran out of time (`request_failed`) may still have been posted on Discord, so check `history` before posting the same text again:

```json
{"ok":false,"error":"...","code":"rate_limited","messageIds":["discord:123:456"],"placeId":"discord:123","unsentText":"...","unsentFiles":["/path/to/file"]}
```

Text that a Crew or a Crew's child task sends with `cockpit crew send` reaches the Crew as `<task_message task_id="…" task="…">text</task_message>`, whichever Crew it belongs to; so does the text of an Autorun that a Crew or its child task created or changed, including a reminder a Crew scheduled for itself, which arrives with the Crew's own task id. Text from the owner's other tasks and the master, and the Autoruns they created, arrives unwrapped like the owner's own text. A child task's output inside a Cockpit notice is wrapped as `<task_output task_id="…" task="…">…</task_output>`; a notice without output names the child task in `<task_info task_id="…" task="…" />`, and a Fleet notice names the Fleet in `<fleet_info run_id="…" fleet="…" />`, so a notice's own line carries only ids and the status. Only text outside these wrappers and outside `<message>` comes from the owner or from Cockpit. A child task's result reaches the Crew through `cockpit task run` or `cockpit task wait`. Cockpit also tells the Crew when a child finishes a turn that the Crew's own `cockpit task run` or `cockpit task wait` did not receive (a few seconds after the turn ends, so a wait that is about to pick it up still can), and when a child asks something, waits for approval, stops with an error or at a usage limit, or is completed by anyone other than the Crew itself. The nodes of a Fleet that a Crew or its child task started report to the Fleet instead; the Crew hears once when the Run pauses or ends.

## Limits for a Crew and its child tasks

Child tasks of a Crew (tasks that the Crew or its child tasks created, including the tasks of an Autorun they created, which are children of the Crew, and the nodes of a Fleet they started, even after the starting task stopped) may read their own Crew (`get`, `status`, `instructions --get`, `pending list`, `channels`, `groups`, `invite-url`) and `send` text to any Crew, where it arrives wrapped in `<task_message>`. They cannot change settings, connections, people, or places, cannot use chat operations, and cannot read another Crew (`forbidden_from_crew`). `list` shows them every Crew, but only the `id`, `name`, `running`, and `state` of the others. A request that names the Crew's session without its secret has the same limits.

### What a Crew's own session may do

What the Crew's own session may change depends on who started the turn it is taking. Cockpit knows what it delivered into the turn: the owner's own message in Cockpit or from the CLI, a chat message from an owner (`role="owner"`), the owner's Autorun, or the owner's answer to an Ask count as the owner; a chat message from another person allowed to talk counts as that person; Cockpit notices (child tasks, Fleets, periodic checks, Talk rooms, outcomes of the owner's approvals), `<task_message>` text, an Autorun that a Crew or its child task made, an Ask answered by another task, and a turn the agent started on its own count as no person. When text is steered into a turn, the least trusted one counts. With `--member-trust strict`, another person's turn counts as no person's.

- Always: reading itself (`get`, `status`, `instructions --get`, `pending list`, `channels`, `groups`, `invite-url`), `list`, `send`, `restart` itself, chat operations, making itself more careful (`update --approval-mode` to a more careful or the same mode, `--member-trust strict`), `people remove`, `pending deny`, `place remove`, `place people remove`, setting a channel, `place dm`, or `place other` to `off`, `cockpit talk create`, and `talk join` or `talk call` with its own task (Talk messages reach it as Cockpit notices through its Queue). On its internal task: `rename`, `pin`, `unpin`, `compact`, `reconnect`, `retry-start`, and reading the model, account, project, browser identity, and approval mode.
- In a turn a person started: `update` of the name, agent, model, effort, speed, periodic check, and place, its icon, `instructions --set-stdin` (Cockpit commits it and shows in the Crew's conversation that the Crew changed its `AGENTS.md`), `start` and `stop` of itself, `people add --user`, `pending approve`, `place set --mode mention`, `place people add --user`, reading another Crew (`get`, `status`, `instructions --get`, `pending list`, `channels`, `groups`), and `cockpit task model` on its internal task, which changes the Crew's model like `update --model`.
- In a turn the owner started: `create` of a new Crew, and `cockpit task account` and `task browser-identity` changes on its internal task.
- After the owner approves it in Cockpit, asked for in a turn a person started: a more permissive approval mode, `--member-trust colleagues`, and widening who may talk or where: `people add` and `place people add` of a role (`--group`, including @everyone) or an app (`--crew`), `place set --mode all`, `place dm --mode all`, `place other --mode mention`, and putting a removed channel back. Cockpit changes nothing yet: it shows the owner an Ask in Cockpit that lists the exact change, the Crew, and who started the turn, and answers HTTP 202 `{"ok":true,"code":"owner_confirmation_requested","data":{"askId":"…","applied":false,"changes":[…]}}` (exit 0). Tell the person who asked that it is waiting for the owner. Only an answer in Cockpit, on this computer or in the PWA, approves it; `cockpit ask answer` cannot, and Ask notifications do not carry it. When the owner answers, the Crew gets a Cockpit notice whether Cockpit applied the change (checked again first), could not apply it, or the owner did not approve it; a declined or dismissed Ask changes nothing.
- Never: changing another Crew in any way, `remove`, `connect`, `disconnect`, `setup`, `people owner`, and on its internal task `send`, `complete`, `remove`, `clear`, and answering its own approvals and questions (`approve`, `deny`, `answer`) (`not_allowed_for_crew`, HTTP 403). The owner does these in Cockpit; use `cockpit autorun create --target-crew` to remind itself later.

A change outside what the turn allows answers `owner_request_required` (HTTP 403); nothing changed. Other `cockpit task` commands on the internal task keep answering `task_owned_by_crew`.

Cockpit identifies the calling session by a per-task secret that it passes to every task session (`AGI_COCKPIT_SECRET_TASK_TOKEN`). The secret decides which task is calling for `cockpit crew`, `cockpit autorun`, `cockpit task create`, `run`, and `wait`, and `cockpit fleet run` and `rerun`: a new task becomes a child of the calling task and of its Crew. The CLI sends the secret only to the Cockpit that issued it; a device reached with `--host` never receives it. A request that names one of this Cockpit's tasks without its secret keeps that task's limits, but Cockpit does not accept it for `send`, `restart`, or creating and changing Autoruns (`task_unverified`), or for chat operations (`crew_session_required`).

The Crew's internal task is not an ordinary task. Apart from what its own session may do (above), `cockpit task` commands that would deliver to it, wake it, change it, complete it, or remove it (`send`, `resume`, `retry-start`, `reconnect`, `goal`, `model`, `account`, `browser-identity`, `rename`, `project`, `pin`, `unpin`, `complete`, `remove`, `create --branch-from`, and turn actions other than reading the approval mode) answer `task_owned_by_crew` (HTTP 409), also with `--host`. Cockpit opened on a phone or another computer through Remote Access cannot send to it directly, resume it, switch its agent, change the task's approval mode, start a goal in it, compact or clear its conversation, branch a task from it, move it to another project, or delete, complete, pin, or rename it either; it can read the conversation, stop a turn, answer approvals and questions, add messages to the Crew's Queue and edit or remove those already there, and steer a Crew that is working in a live session. A message added to the Queue reaches the Crew under the Crew's model, effort, speed, and approval mode at delivery, and waits while the Crew is stopped. An Autorun cannot send to it as an existing task, it joins Talk rooms only at its own session's request, and `cockpit task list` does not show it; with `--host` the list also leaves out the Crew's child tasks. Use the `cockpit crew` commands instead; the approval mode of the Crew's session changes only through `cockpit crew update <crew> --approval-mode <mode>` or the approval-mode chip of the Crew's conversation in Cockpit.

A Crew and its child tasks can still use `cockpit task` and `cockpit autorun` on the owner's other tasks and Autoruns like any task, for example to complete or remove a task or to run, toggle, or delete an Autorun; an Autorun they create or change is recorded as theirs (`cockpit help autorun`). `cockpit hooks`, `cockpit settings`, and `cockpit remote-access` have no Crew limits: a Crew session or child task can use them just as the owner can, for example to add a hook that runs a shell command as the owner on later events, to change a setting, or to read the `pairing-code` that lets another device pair as the owner. So these limits stop only mistakes made through the `cockpit crew`, `task`, and `autorun` commands; they do not stop a session that follows instructions injected into what it reads, and they are not a security boundary. Crew sessions and child tasks run as the same OS user as Cockpit and the owner's shell, so a process that removes its Cockpit environment, names a task that this Cockpit does not know, or talks to Cockpit's local connections directly is treated like the owner. Another Cockpit instance on the same computer does not know these tasks, so it also treats their requests as the owner's. Keep secrets and destructive power out of a Crew's reach accordingly.

## Errors

Every error, whether Cockpit or the CLI reports it, is `{"ok":false,"error":"…","code":"…"}`, plus `params` when present, and the command exits 1. `owner_confirmation_requested` is not an error: it answers `{"ok":true,…}` with HTTP 202 and exit 0, and means the change waits for the owner. Errors the CLI reports before sending anything have no `params`. `error` is a message for people; decide by `code`.

| code | Meaning |
|---|---|
| `invalid_arguments` | A field is missing or invalid; `params.field` names it, for example `approvalMode` for an unknown approval mode. The CLI also reports it for an unknown subcommand or option, an option without its value, extra arguments, a missing `<user-id>`, or an empty `--text-file` |
| `option_required` | A required option is missing, for example `--text` when `reply` or `post` has neither text nor a file |
| `option_conflict` | Two options that exclude each other were given |
| `input_source_conflict` | More than one of `--text`, `--text-file`, and `--stdin` was given |
| `option_value_invalid` | An option value is invalid, such as `--step`, `--mode`, or `--limit` |
| `stdin_no_input` | `--stdin`, `--set-stdin`, or `--token-stdin` got no input |
| `host_not_supported` | `--host` was given; Crew commands work only on this computer |
| `cockpit_unreachable` | Cockpit could not be reached or is not running |
| `payload_too_large` | The request is larger than Cockpit accepts: 1,048,576 bytes of JSON, or 8,192 bytes of URL-encoded arguments for a command that reads, such as `get` or `history`. The CLI checks before sending, so nothing was sent. Shorten the text or send it in parts |
| `encoding_failed` | The CLI could not encode the request because `node` failed; nothing was sent. Make sure `node` runs, then try again |
| `cli_unavailable` | The CLI is not installed on this computer yet; launch AGI Cockpit once |
| `node_runtime_unavailable` | Windows only: the file transport found no Node.js runtime; set `AGI_COCKPIT_NODE_PATH` to a Node.js executable (`cockpit help transport`) |
| `node_runtime_failed` | Windows only: the Node.js runtime of the file transport did not answer with JSON; `error` names it (`cockpit help transport`) |
| `unexpected_error` | Windows only: an unexpected failure inside the CLI; `error` describes it |
| `route_not_found` | Cockpit does not know the action |
| `crew_required` | No Crew was given, and the command does not run in a Crew's session. The CLI reports it when a command that needs `<crew>` has none |
| `crew_not_found` | No Crew has that id or name |
| `crew_ambiguous` | Several Crews share the name; use the id |
| `name_required` | The name is empty |
| `agent_invalid` | The agent cannot run a Crew |
| `approval_mode_unsupported` | The Crew's agent does not support that approval mode; `params.approvalMode` and `params.agentType` name them, and `params.supported` is a comma-separated list of the modes the agent supports, such as `supervised, accept-edits, full-access` |
| `approval_mode_not_applied` | The running session could not take the new approval mode (HTTP 409); `error` says why. The setting did not change. For example, a Grok session has to restart to turn `auto` on or off and cannot while it is working; run the command again after the turn ends |
| `instructions_too_long` | `AGENTS.md` is over 4,000 characters |
| `instructions_changed` | `AGENTS.md` changed after the editor loaded it (HTTP 409); nothing was written. Load it again before saving |
| `git_unavailable` | Git is not installed or not on `PATH`; a Crew keeps its home in a git repository (HTTP 500). Install git and try again |
| `platform_invalid` | The platform name is unknown |
| `platform_unavailable` | The platform is not supported yet |
| `platform_required` | The Crew has several connections; pass `--platform` |
| `connection_not_found` | The Crew has no connection for that platform, or none at all |
| `credentials_required` | The token is empty, or the connection has no verified account yet |
| `token_invalid` | The platform rejected the token |
| `intent_disabled` | The Message Content Intent is off |
| `app_in_use` | Ask notifications or another Crew already use the application; `params.usage` is `ask-relay` or `crew`, and `params.name` names the Crew |
| `setup_step_invalid` | The setup cannot move to that step |
| `setup_changed` | The connection was removed, set up again, taken back to its guide or token step, or its token change was cancelled (`setup cancel`, or **Cancel** in Settings) while the token was being checked or saved (HTTP 409); nothing was stored, and the previous token stays. To use the new token, run `connect` again |
| `invite_unavailable` | The platform has no invite link |
| `pending_not_found` | That person is not waiting for approval |
| `audience_confirmation_required` | Adding everyone in a server (@everyone) or a crew needs `--confirm` (HTTP 409); nothing was added. `error` says who could then give the Crew requests, and `params.audience` is `everyone` or `crew` |
| `channel_not_found` | The channel is not in the Crew's places |
| `not_connected` | The connection is not connected now, for example because the Crew is stopped |
| `invalid_id` | The id is malformed or belongs to another platform |
| `text_required` | There is no text or file to send |
| `text_too_long` | The text would need more than 10 messages (`params.limit`); nothing was posted. Post a summary and attach the full text as a file |
| `file_not_found` | An attached file does not exist. The CLI reports it when a `--file` or `--text-file` does not exist or is a directory |
| `file_unreadable` | An attached file exists but cannot be read; nothing was posted. The CLI reports it before sending anything when a `--file` or `--text-file` cannot be read |
| `file_too_large` | An attached file is over the platform limit (20 MB per file on Discord); nothing was posted. `params.limit` is the limit in bytes |
| `missing_permission` | Discord refused for lack of permission in that place |
| `not_found` | Discord could not find the place or message |
| `rate_limited` | Discord's rate limit was reached; wait and try again |
| `request_failed` | Discord could not complete the request, or Cockpit could not check whether Ask notifications use the application; try again |
| `crew_session_required` | A chat operation ran outside the Crew's own session |
| `forbidden_from_crew` | A Crew or its child task asked for something only the owner may do |
| `owner_request_required` | The Crew's own session asked for a change that the turn it is taking cannot make: it needs a turn that a person, or the owner, started (HTTP 403); nothing changed |
| `not_allowed_for_crew` | The Crew's own session asked for something a Crew never does for itself; the owner does it in Cockpit (HTTP 403) |
| `task_unverified` | The request names a task without its secret, so Cockpit does not accept it for this action |
| `task_owned_by_crew` | A `cockpit task` command targeted a Crew's internal task (HTTP 409) |
| `open_failed` | The file manager could not open the home folder |
| `crew_task_missing` | The Crew's internal task is missing; start the Crew again |
| `crew_failed` | An unexpected failure; `error` describes it |
