Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

## Unreleased

### Added

- Squad MCP now also manages agent profiles, abilities, extra project folders, skills, group chats, channel membership and scheduled routines.
- Squad is built in as an MCP connection. Select an agent in the running app with `/squad`, send it direct messages with `/message`, and read conversation history and delivery receipts. The connection also reads Squad artifacts and memories.

## 0.9.10 - 2026-11-04

### Added
Expand Down
10 changes: 8 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -423,7 +423,7 @@ Node installs use `HTTPS_PROXY`, `HTTP_PROXY` and `NO_PROXY` for requests, inclu
| `/goals complete` | Mark the current goal complete and advance queued work when completion requirements are met |
| `/goals clear` | Clear this session's current goal while retaining queued work |
| `/goals templates` | List reusable goal templates |
| `/squad` | Open/manage the local Autohand Squad runtime |
| `/squad` | Select an agent in the running Squad app; `/squad app` opens or installs it |
| `/go` | Pair this session with the Autohand Code iOS app |
| `/sync` | Sync settings across devices |
| `/add-dir` | Add additional workspace directory |
Expand All @@ -436,12 +436,18 @@ Node installs use `HTTPS_PROXY`, `HTTP_PROXY` and `NO_PROXY` for requests, inclu
| `/mcp install` | Install validated Official MCP Registry servers (stdio and HTTP) |
| `/team` | Manage team collaboration |
| `/tasks` | List team tasks |
| `/message` | Send team message |
| `/message` | Message the selected Squad agent or a local CLI teammate |
| `/import` | Import data from Claude, Codex, Gemini, Cursor, OpenCode, Kimi, Grok hooks, and other agents |
| `/repeat` | Repeat previous actions |
| `/browser` | Browser integration |
| `/review` | Code review |

Squad MCP is built in. Select an agent with `/squad`, then use `/message <text>`
and `/squad history`. `/message squad <agent-id> <text>` addresses an agent
explicitly; `/message team <name> <text>` addresses your local CLI team.
See [Squad connection and commands](docs/mcp.md#built-in-autohand-squad) for
delivery receipts, Library tools, bridge discovery and opt-out settings.

Persistent goal data remains in the workspace across conversations, but execution does not silently transfer work owned by another live session. Bare `/goal` inspects prior state and starts the next queued item when this session has no goal and no live peer owns the backlog. Use `/goal resume` to resume this session's paused goal or explicitly start queued work.

Published CLI announcements appear as a cached launch block and a persistent line above the composer. Press `Ctrl+X` to dismiss the visible item, or use `/whatsnew` to review and dismiss all active announcements. Dismissal is per announcement; `--offline` keeps cached announcements visible without making announcement requests.
Expand Down
136 changes: 136 additions & 0 deletions docs/adr/2026-11-05-built-in-squad-messaging.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
# Built-in Squad messaging uses the running app's queues

Date: 2026-11-05

## Context

`/message` only addressed the active local CLI team, while `/squad` opened
or installed the app. Squad's external `send_message` started independent
Mission Control runs. Those paths could not select a desktop agent and send
a message into its actual direct conversation. The app already owns durable
message queues, saved agent permissions, transcripts, artifacts and memories.

## Decision

Add a session-owned Squad connection and a keyboard agent picker using the
existing Ink modal and input pause/resume hooks. A selected desktop agent
receives `/message <text>`; `/message team` explicitly addresses the existing
local team. Explicit `/message squad <agent-id>` is a one-off recipient.
IDs disambiguate duplicate names. Preserve top-level `autohand squad` app
launch and legacy standalone commands. No implicit app install/start is
performed when using the connection.

Bundle the Squad operator MCP schemas/runtime from `autohandai/squad`, with
MIT attribution and source revision, instead of requiring another package or
an installed app executable. Inject it into the runtime MCP list without
persisting or syncing it. Node/Bun source installs launch their entrypoint
with the current runtime; standalone binaries launch themselves directly.
Honor disabled MCP, opt-out, bare, offline and no-daemon behavior. Configured
Squad entries win. Managed member environment/connection markers prevent
operator access from being added to an agent already inside Squad.

Both slash commands and MCP use the same loopback bridge/tool implementation.
Direct sends enqueue in the actual member conversation; they preserve busy
work and paused queues, and return a durable receipt. The CLI sends no model,
engine or permission override. Library access is read-only. Existing normal
MCP discovery, permission checks and tool execution remain in the path.

## Evidence and limits

Focused command/MCP/installer/computer-use tests pass (41 tests), as do
type checking and lint. `tests/tuistory/squad-connection.tuistory.test.ts`
drives the built CLI through keyboard selection, direct delivery/history and
normal `tool_search`/`run_tool_script` invocation of the bundled MCP against
an isolated HTTP fixture. Squad's `scripts/check-control-plane.mjs` separately
checks actual bridge delivery and transcript persistence with a fake engine.
No live agent/provider is used as a test destination. Full `bun run proof`
is required before integration; its final result is recorded with the change.

`AUTOHAND_TEST_WORKERS=1 bun run proof` passed lint, type checking and all
965 executed unit files: 13,786 tests passed and 80 were skipped. Earlier
parallel runs exposed an old exact-context assertion (updated for the new
connection) and intermittent cancellation/file-lock deadlines in unchanged
tests. Those timing tests pass in isolation; the memory-index test also
passes on unchanged `main`. Their implementation and timeout budgets were
left intact. The serial run removes competing test workers without skipping
coverage; terminal proof follows the rebuilt CLI in the same command.

The complete terminal run executed 538 cases across 110 files: 532 passed,
four failed and two were skipped, so the overall proof command exited 1.
The orchestration-toggle and caret cases passed focused reruns; all 20
resize cases passed a full-file rerun. Console connector synchronization
failed again at `toolsListed > 0` on both this branch and an independently
built, unchanged `9d10d59d` checkout. The baseline orchestration file (11
cases), resize case and caret case passed. These results distinguish the
existing reproducible connector issue from intermittent terminal failures;
they do not establish that the full repository proof is green. No production
orchestration, resize, caret or Console-sync code was changed here.

The new Squad scenarios pass in both full-screen and standard layouts on
the built Node CLI and compiled macOS ARM64 CLI. Their explicit fixture
connection also passes with the terminal runner's default opt-out enabled.

Unit and terminal runners disable automatic Squad connections by default,
including scenarios that launch the CLI through a custom driver. The Squad
fixture explicitly opts back in against its isolated HTTP server, so generic
tests do not depend on an installed app or accidentally use its bridge.

The same Tuistory flow also passes with the compiled macOS ARM64 binary
(`AUTOHAND_SQUAD_TEST_BINARY`), including its automatic MCP self-launch.
Before the management expansion, compiled stdio initialization/tool listing
succeeded offline with protocol-only stdout and 18 tools. A separate read-only roster
check against the installed Squad bridge recognized 18 members with presence;
it sent zero messages and made no app lifecycle calls. Local evidence is in
`.artifacts/squad-mcp/compiled-mcp-proof.json` and `live-readonly-proof.json`.

## Expanded operator management

The canonical Squad MCP now exposes 37 tools, adding saved member profiles,
abilities, directory grants, skill selections, channel settings/membership,
private groups and scheduled routines. Bundle its `management.mjs` alongside
the runtime and schemas. This keeps tool behavior identical between Squad
and CLI without introducing a second client implementation. Management
requires an updated bridge; a missing member-management endpoint explains
that the app must be updated, without starting an upgrade.

Profile edits use canonical revisions. Folder grants and skill selections
apply during later engine preparation, preserving current work. Groups reuse
private channels and dispatch only explicit recipients; the bridge persists
replies after client disconnect. Routines require a timezone and are disabled
by default. Operator powers remain unavailable to managed Squad members.
The rationale and controlled bridge evidence are in
[Squad ADR-0181](https://github.com/autohandai/squad/blob/main/docs/adrs/ADR-0181-operator-mcp-manages-saved-members-and-work.md).

Focused CLI validation: typecheck, 13 related unit tests, and the actual
Tuistory flow in both standard and fullscreen layouts pass. The terminal
scenario now discovers and calls the new `get_member_profile` tool through
the ordinary MCP tool-search/permission path, against an isolated fixture.
Both layouts also pass with the compiled macOS ARM64 executable. Its offline
stdio smoke now lists all 37 tools with protocol-only stdout. The
required full `AUTOHAND_TEST_WORKERS=1 AUTOHAND_TUISTORY_WORKERS=2 bun run proof`
completed: lint/typecheck and all unit files passed (965 files; 13,787 tests,
80 skipped). Terminal results were 108 passing files and two failing files
(527 passed tests, nine failed, two skipped). Console connector sync failed
at `toolsListed > 0`, previously reproduced on the unchanged base. The
extension file had one nonzero process exit and seven explicit `ENOSPC`
fixture-creation failures. This is not a green local aggregate result.

All 24 reported CI checks on implementation commit `3478d59a` passed,
including the four terminal shards and Windows terminal checks; the optional
manual `proof` job was skipped. Local aggregate evidence is in
`.artifacts/squad-mcp/management-proof.log`. After removing an obsolete generated binary, the focused extension file
passed all 12 tests. The full local aggregate remains failed; this rerun does
not replace it. These results do not claim a published CLI or installed
Squad upgrade.

## Consequences

Desktop selection changes the unqualified `/message` recipient for this
session; the selection receipt documents the local-team escape and clearing
command. Selection is not persisted between sessions. There is no continuous
desktop roster polling or composer alias expansion in this change. A paused
queue requires a person in Squad. Send retries are not automatic/idempotent;
after a lost receipt inspect the queue before resending. Read history is
bounded to bridge chat turns; it does not load archived chat files or execute
artifact HTML. The vendored protocol needs deliberate synchronized updates;
no shared package or automatic Squad/CLI release is introduced.
7 changes: 7 additions & 0 deletions docs/config-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -2491,6 +2491,13 @@ sync:

Configure MCP (Model Context Protocol) servers to extend Autohand with external tools.

The effective runtime list also includes the built-in `autohand-squad` server;
it is not written into this configuration or synced to your account. Set
`AUTOHAND_DISABLE_SQUAD=1` to opt out, or `mcp.enabled: false` to disable all
MCP connections. Bare, offline and no-daemon sessions omit it, as do managed
Squad members with an existing identity-scoped connection. See
[built-in Squad commands and bridge discovery](mcp.md#built-in-autohand-squad).

```json
{
"mcp": {
Expand Down
86 changes: 86 additions & 0 deletions docs/mcp.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ Autohand includes a built-in MCP client that connects to external MCP servers, e

## Table of Contents

- [Built-in Autohand Squad](#built-in-autohand-squad)
- [Overview](#overview)
- [Quick Start](#quick-start)
- [Configuration](#configuration)
Expand All @@ -27,6 +28,91 @@ MCP is an open protocol for connecting AI agents to external tools. Autohand's M
- **Non-blocking startup** -- servers connect in the background without delaying the prompt
- **Interactive management** -- toggle servers on/off with the `/mcp` command

## Built-in Autohand Squad

Autohand Code adds `autohand-squad` to its runtime MCP servers automatically.
It uses this CLI's bundled stdio server, so no separate MCP install or saved
configuration is needed. Tools are available through normal tool discovery
and permission checks, under `mcp__autohand-squad__<tool>`.

Open the Squad app, then in an interactive CLI session:

```text
/squad choose an agent with the keyboard
/squad agents list agent IDs and presence
/squad select kai select by ID or exact name
/message Please review this message the selected agent
/message squad iris Review this message another agent explicitly
/squad history read the selected agent's replies
/squad queue inspect delivery receipts and pause state
/message team local Check this message a local CLI teammate
/squad clear clear the selected desktop recipient
/squad app open or install the app
```

Selection belongs to the current CLI session. An explicit one-off recipient
does not change it. Local `/message <name> <text>` behavior continues when no
desktop recipient is selected. Escape cancels the picker and restores input.
Top-level `autohand squad` still opens the app; `autohand squad agents`,
`autohand squad message <agent-id> <text>` and `autohand squad history <agent-id>`
work without an interactive agent session. Legacy standalone runtime actions
remain available, including top-level `autohand squad queue`.

The server exposes 37 tools: the existing channel/run/goal tools plus direct messaging
(`message_member`, `get_conversation`, `get_member_queue`, `wait_for_message`),
published artifacts (`list_artifacts`, `get_artifact`) and the knowledge
library (`list_memories`, `read_memory`). These direct messages enter Squad's
durable conversation queue, wait behind busy work and retain saved member
permissions. A receipt means queued, not completed. Paused queues stay paused.
Repeat `wait_for_message` using the same receipt after a timeout; inspect the
queue before retrying a send whose response was lost. Creating members and
changing their models still happens in the app.

Member management is also built in: `get_member_profile`,
`update_member_profile`, `set_member_abilities`, `add_member_directory`,
`remove_member_directory`, `list_skills` and `set_member_skills`. Read the
saved revision before editing; pass `expected_revision` to reject stale
changes. Folder grants use the existing engine directory settings on later
turns; current work continues. Skill selection is distinct from installation
on the next turn. Policy edits preserve other settings and OS grants.

Channels support `get_channel`, `update_channel`, `set_channel_members`,
`list_channel_threads`, `create_group_chat` and `send_channel_message`.
Groups are private channels with at least two existing members. Creation
does not dispatch work. Sending dispatches only explicit `member_ids`;
omitting them posts without starting agents. Replies persist on the bridge
even after this CLI disconnects. Check per-recipient receipts before retrying.

Use `list_routines`, `get_routine`, `preview_routine`, `create_routine`,
`update_routine` and `run_routine` for scheduled work. Schedules require an
explicit IANA timezone. New routines default to disabled; set `enabled:true`
to schedule, `enabled:false` to pause, or run a saved routine manually.
These tools require an updated Squad bridge; older versions return an
upgrade instruction. The CLI never upgrades or restarts the app automatically.
The [canonical tool reference](https://github.com/autohandai/squad/blob/main/docs/integration/control-plane.md)
contains arguments and examples.

Use a current Squad release for Library tools; older app versions may lack
the artifact or knowledge-library endpoints. Updating the app does not
require reinstalling the CLI's built-in MCP.

Bridge discovery: explicit `AUTOHAND_SQUAD_BRIDGE_URL`, then
`$AUTOHAND_SQUAD_HOME/web-server.json` (default `~/.autohand/squad`), then
`http://127.0.0.1:19821`. Only loopback origins are accepted; redirects are
refused. MCP initialization succeeds while the app is offline, and calls
explain how to open it. Startup does not install or start Squad.

Disable with `AUTOHAND_DISABLE_SQUAD=1` or `mcp.enabled: false`. Bare, offline
and no-daemon sessions do not add this built-in server. An existing configured
`autohand-squad`/`autohand_squad` entry wins. A CLI launched as a managed Squad
member keeps its identity-scoped connection and never receives operator
access to another member's private memories.

For another MCP client, use `autohand squad mcp` as the command/arguments
(`--bridge http://127.0.0.1:19821` is optional). It emits protocol messages
only on stdout. See the [Squad control-plane reference](https://github.com/autohandai/squad/blob/main/docs/integration/control-plane.md)
for the complete tool schemas and scope.

---

## Quick Start
Expand Down
3 changes: 2 additions & 1 deletion src/commands/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ Each command is a separate TypeScript file that exports:
| `/experiments` | `features.ts` | List and toggle experiments |
| `/goal` | `goal.ts` | Manage session-attached persistent goals, budgets, templates, and queued work; bare `/goal` recovers a stranded queue only when no live peer owns it. Enabled by default from 0.9.9; explicit `slash_goal` settings are preserved. |
| `/goals` | `goal.ts` | Open the live goal queue with keyboard and mouse editing. Accepts `/goal` subcommands and returns the queue as text without an interactive panel. Shares `slash_goal`; `/experiments enable slash_goals` enables the same local feature. |
| `/squad` | `squad.ts`, `squadDesktop.ts` | Open the Autohand Squad app, installing the latest release when missing; subcommands manage the standalone runtime. |
| `/squad` | `squad.ts`, `squadConnection.ts` | Select an agent in the running Squad app; `/squad agents`, `select`, `history`, `queue`, and `clear` manage the desktop recipient. `/squad app` opens or installs the app. |
| `/message` | `message.ts` | Send text to the selected Squad agent, `/message squad <agent-id> <text>` to an explicit agent, or `/message team <name> <text>` to a local CLI teammate. Without a desktop selection, existing `/message <name> <text>` team behavior remains. |
| `/squad view` | `squad.ts` | Inspect recorded independent Squad sessions for the current workspace |
| `/usage` | `usage.ts` | Show Autohand plan limits and project token activity |
| `/statusline` | `statusline.ts` | Configure composer status-line fields |
Expand Down
Loading
Loading