Skip to content

A chief for every crew, who suggests new bots - #20

Merged
httpsphl merged 9 commits into
mainfrom
feat/crew-chief
Sep 29, 2026
Merged

httpsphl merged 9 commits into
mainfrom
feat/crew-chief

Conversation

@httpsphl

Copy link
Copy Markdown
Owner

Every new crew starts with a chief, who plans the work, hands out tasks and suggests new bots when the crew lacks a specialist. The owner stays in charge of each new bot. Stacked on #19.

What changes

  • A chief for every new crew. "New crew" asks what the crew is for and the chief's model; the goal becomes the chief's instructions, and the app opens the chief's chat right away. crews.create {lead} saves the crew and its chief before the supervisor can start it, so its first start already reads that it leads.
  • The chief's rules add a "You lead this crew" section: split the work into parallel tasks with send_message, check results before reporting, suggest a bot when a specialist is missing, pick models by the work (haiku for simple tasks, sonnet for most, opus/fable for the hardest), keep the crew small, and tell the owner what each bot does. Other bots read that new bots come from the chief, whom crew_roster marks with chief.
  • suggest_bot, a new MCP tool: name, role, instructions, model and why. Only the chief may use it; the others are told to ask the chief. Before bothering the owner the daemon checks the fields, that the name is free and that the crew has fewer than max_per_crew bots (12 by default).
  • The owner decides, in a card. The suggestion goes through the same path as approvals: the chief waits in needs_approval and the card shows the reason and editable name, model, role and instructions, with Create bot and Not now (plus a note for the chief). approvals.answer {input} carries the owner's changes and replaces what is stored, so the card shows what was created. Once created, the bot starts at once, shows in the sidebar with its own chat, and the tool result reminds the chief to hand it a task.
  • A chief that bypasses permissions creates the bot without asking, as that mode does everything; the bypass confirmation says so when the bot is the chief.
  • Moving the chief: a crown marks it in the sidebar, crew cards and header, and the bot menu has "Make crew chief" and "Stop being chief" (crews.setLead). Archiving the chief leaves the crew without one. Crews from before have no chief until the owner picks one.
  • Approvals split into the waiting itself, now shared by permission requests and suggestions, and Claude Code's permission prompt. The welcome screen now says each crew starts with a chief.
  • Storage: migration 0007 (crews.lead_bot_id); protocol: crews.create {lead}, crews.setLead, approvals.answer {input}, Crew.leadBotId; config: [bots] max_per_crew.

Spec: new 10.2, plus 2, 5.1, 6, 10, 11.2, 12, 13, 15.1 and a section 19 row.

Tested

  • cargo fmt, clippy -D warnings, cargo test (new crew_chief tests over the real WebSocket and MCP: a crew born with its chief, approving, changing before approving, declining, bypass, only the chief and only while there is room, moving and archiving the chief) and pnpm check (the new-crew flow, the card's create/change/decline, moving the chief).
  • With the real Claude Code 2.1.284 (dev daemon and app): a crew created in the app started its chief on Sonnet. Asked for a website, the chief loaded its tools through ToolSearch and suggested a Designer with a role, detailed instructions, a model and a reason; the call waited for the card. With the model changed to Haiku in the card, the bot started on --model haiku and the chief noticed the change. The chief sent it a task, the Designer delivered with complete_task, and the chief reviewed the result and fixed its HTML to match. The debug log held no message text.

A bot's avatar is now just the mascot in its color, with a thin edge
(dark on the light theme, light on the dark one) so light colors such as
the palette's beige keep their shape. Botloft's own white mascot, in the
title bar and on the daemon's messages, keeps the black square of the
app icon: without it, it would vanish on the light theme.
The whole window is now drawn at 125% (the webview's zoom), so text,
spacing, icons and avatars grow together; at 100% the app looked tiny on
a monitor without Windows scaling. A Size menu in the title bar picks
100%, 110%, 125% or 150%, Ctrl+= and Ctrl+- step through them and Ctrl+0
goes back to the default. The choice is remembered and applied before
the first paint, so the window never flashes small.
Like the account corner of a chat app: the owner's name (the Windows
account's display name), their Claude plan and a menu with Usage,
Settings, Language, What's new and Help. Usage shows each window of the
plan the bots have used and when it resets; Settings holds the theme,
size and language, and the versions. Theme, size and language leave the
title bar, which keeps only the language on the setup screens that have
no sidebar. The sidebar now shows from the welcome screen on.

The daemon reads the owner's display name once (GetUserNameExW) and the
email, plan and organization from `claude auth status`, and sends them
in `system.status.account`.
Buttons, fields and menu rows get 8 px corners, cards and menus 12 px,
the chat's bubbles, cards and dialogs 16 px. Menus and dialogs float on
a light themed shadow. The chat is a centered column with the day as a
pill, and the open conversation in the sidebar is an inset rounded
block instead of a full-width bar. Menus share one popover look and one
hook that closes them.
Like Claude Code's mode picker, below the chat: Auto, Manual, Accept
edits and Plan, each described by what the bot does ("Scout decides
what needs your OK"), and Bypass permissions behind a confirmation that
says the bot is then not held to its folder. A bot that asks nothing is
marked in red in the picker and its header.

The daemon stores the mode (migration 0004) and starts the bot with it.
Claude Code reads --permission-mode only at start, so a new mode
restarts the process with --resume once nothing is in progress, and
never cuts a turn short. When an approved plan moves the bot out of plan
mode, the system/init of the next turn says so and the stored mode
follows.

A bot in plan mode asks to go ahead with ExitPlanMode: the chat shows
the whole plan (kept up to 32 KB) with Approve plan and Keep planning,
which sends back what should change.

Spec: 7.4, 10.1, 11.2, 12, 13 (what bypassing means on Windows), 15.1,
15.3 and two rows in section 19 to check with the real Claude Code.
Bots ran on whatever the account's default is. The owner now picks
Fable, Opus, Sonnet, Haiku or the plan's default per bot, in the chat
and when creating or editing a bot. Claude Code only reads --model at
start, so a new model restarts the bot with --resume once nothing is in
progress, like a new permission mode (the relaunch code now serves both).

system/init names the model in use; the daemon keeps it so the app can
say which model the plan's default is. A model the account cannot use
fails the turn with model_not_found, now told as its own notice.

Plan exit now follows the mode the process started with, so a pending
model change no longer hides an approved plan.
A crew worked only in its shared folder, which sat outside each bot's
workspace: Claude Code asked before every edit there, even in accept
edits mode. Every bot now gets the crew's work folder with --add-dir,
and loads its CLAUDE.md with the bot's memory.

The owner can pick that folder when creating a crew, or move the crew
later, with Windows' folder picker (tauri-plugin-dialog). The daemon
never writes into a chosen folder, refuses drives, Botloft's own data
and the folder of every bot, and restarts each bot once it is idle.
Every new crew now starts with a chief, made from the goal the owner
writes for it. The chief plans the work, hands out tasks and, when the
crew lacks a specialist, calls the new suggest_bot tool. The suggestion
shows in its chat as a card: the owner can change the name, role, model
and instructions, then create the bot or say no with a note. A chief
that bypasses permissions creates it at once. Only the chief may suggest,
up to max_per_crew bots; the owner can move the chief or remove it.

Approvals split into the waiting itself, now shared by permission
requests and suggestions, and Claude Code's permission prompt.
A chief on Sonnet suggested a designer, waited for the card, got it on
Haiku after the owner changed the model, handed it a task and checked
its result. The welcome screen now says each crew starts with a chief.
@httpsphl
httpsphl changed the base branch from feat/crew-folder to main September 29, 2026 04:25
@httpsphl
httpsphl enabled auto-merge September 29, 2026 04:25
@httpsphl
httpsphl merged commit 354e8bf into main Sep 29, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant