Skip to content
6 changes: 6 additions & 0 deletions cmd/codeaf/chatv3.go
Original file line number Diff line number Diff line change
Expand Up @@ -2108,6 +2108,12 @@ func v3BuiltinApprovals() map[string]any {
// A conflict raised to the manager above the parties: a packet and a
// line of Traffic, and nothing spent or started.
"team_raise": "allow",
// A manager taking back a team that never held anyone, which the
// person declined in its own conversation: one record nobody used is
// forgotten, and nothing is started, stopped or spent. A team that
// was used is refused by the store ([teams.Dissolve]), whatever this
// row says.
"team_dissolve": "allow",
}
}

Expand Down
5 changes: 3 additions & 2 deletions cmd/codeaf/chatv3_approvalfloor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -209,13 +209,14 @@ func TestTheFloorDoesNotWidenAnySafetyFloor(t *testing.T) {
// THE TEAM VERBS SPLIT READ AND MESSAGE FROM START (internal/session's
// tools_team.go). A manager looking at its team, sending it a line, ending a
// member's turn and a member posting to its room stay inside the team the person
// made and are logged in its traffic, so they sit on the floor; a new member is a
// made and are logged in its traffic, so they sit on the floor, and so does a
// manager taking back a team that never held anyone; a new member is a
// new conversation that spends money, so team_start is the blanket mode's and
// asks under the shipped default.
func TestTheTeamVerbsAreAllowedAndTeamStartAsks(t *testing.T) {
dir := v3Profile(t, map[string]any{"tools.approvalMode": "prompt"})
policy := gateOf(t, dir)
for _, tool := range []string{"team_status", "team_read", "team_send", "team_stop", "team_post", "team_decide", "team_escalate", "team_close_report", "team_raise"} {
for _, tool := range []string{"team_status", "team_read", "team_send", "team_stop", "team_post", "team_decide", "team_escalate", "team_close_report", "team_raise", "team_dissolve"} {
wantAction(t, policy, tool, `{"to":"web","text":"x","handle":"web"}`, approval.ActionAllow)
}
wantAction(t, policy, "team_start", `{"handle":"docs","brief":"write the README"}`, approval.ActionPrompt)
Expand Down
13 changes: 13 additions & 0 deletions docs/changes/unreleased/1881-helpers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
kind: added
title: /helpers makes the conversation you are in a new team's manager, which proposes helpers
pr: 1881
surface: [chat, engine, docs]
invalidates:
- "Every way to make a team started from the team, and a team was made without a manager; the only way to make an existing conversation one was Add chat, then Choose AI manager. `/helpers` makes a new top-level team with the conversation in front as its manager, in one save, then sends exactly the words after it (bare, a default ask shown in full) as the person's message."
- "The Teams ▾ chip was absent with no teams, and its dropdown printed an up/down, enter, esc footer. The chip shows with no teams, the footer is gone, and with no team selected the dropdown ends with `+ New from this session`, which puts `/helpers` and the default ask in the box. With a team selected the row is absent and `/helpers` refuses: the team it makes is top-level, and nesting is + Add subteam."
- "A manager had no way to take its team back. `team_dissolve` forgets a team that has never held anyone but its manager (no member, former member, subteam or Traffic); it is on the belt only while that is true, for every team however it was made, and does not ask first."
- "A member a manager started with team_start never took its first turn on an ordinary launch: the engine's teams door stamps a new member's join time, the join bound dropped the start that made it, and the member sat idle with nothing addressed to it. A member's own start is exempt from the bound now, and it wakes with its brief; every other line from before the join is still withheld."
- "There are twenty-five tips, not twenty-four: `/helpers makes this conversation the manager of a new team`."
- "An interactive conversation in no team is now told once, after the person's fourth message, that it may suggest /helpers when the work is long and has parts a few helpers could take on at once. It is a note, not a paragraph of the system prompt."
---
1 change: 1 addition & 0 deletions internal/manual/chat/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,7 @@ command).
| `/spend` | none | none | opens the spend place, what this machine has cost, by the day (also `alt+5`) |
| `/wall` | | | every saved conversation at once, with live or saved previews and card-based team creation (also `alt+v`, or `▦` under the box) |
| `/teams` | | | the teams page: your teams as a tree, what waits on you, member previews and the selected team's interaction table (also `alt+2`, or `teams` on the tab bar) |
| `/helpers` | | `<what to ask the manager>` | makes this conversation a new team's manager, then sends your words after it (bare, a default ask to suggest two or three helpers, shown in full) for you to accept, change or cancel; `+ New from this session`, last in the Teams dropdown while no team is selected, puts `/helpers` and that ask in the box; with a team selected it refuses; on home it says to open a conversation first |
| `/cost` | `/usage`, `/tokens` | — | prints what this conversation has spent, and on what |
| `/effort` | `/think`, `/thinking` | — | opens this conversation's thinking levels; says it is unavailable when the session has no dial |
| `/effort` | `/think`, `/thinking` | `<rung>` | sets this conversation's thinking level; an unknown rung lists the accepted levels and changes nothing |
Expand Down
19 changes: 14 additions & 5 deletions internal/manual/chat/conversations-and-teams.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ with no team overlay selected. Clearing the team's visual overlay does not end
membership, change reporting authority, or stop background work.
The composer has no team-recipient hint and the sidebar uses the ordinary task view.

With no overlay, the strip shows **Teams ▾**. Selecting a team replaces it with a coloured
With no overlay, the strip shows **Teams ▾**, even before you have a team. Selecting a team replaces it with a coloured
team chip and a separate **x**. Click the name to switch teams; click x to remove the
overlay and restore ordinary Chats. Clearing selects **All teams** in Teams without
changing membership or background work. The dropdown lists actual teams only, with no **None** option.
changing membership or background work. The dropdown lists actual teams, with no **None** option,
and, with no team selected, ends with **+ New from this session**, which makes a team of the conversation in front.
The **▦ All** button still opens the independent conversation grid.

The Teams dropdown is the only team selector in Chats; there are no membership buttons
Expand Down Expand Up @@ -216,14 +217,20 @@ them; Undo does not reopen them. Organization otherwise only adds memberships: i
not rename teams or remove conversations. Nothing runs automatically. Press Organize
again to refresh suggestions. The conversation grid has no Organize or Undo control.

## The team switcher on the tab strip
## The team switcher on the tab strip — the Teams dropdown and + New from this session

The dropdown is first on the Chats tab strip. With no overlay its label is **Teams ▾**;
with one selected it shows that team's name, colour and a separate **x** to clear it.
The dropdown offers **All teams** when a global manager exists, then the active team hierarchy.
All teams selects the global-manager overlay; it is separate from the team-agnostic `▦ All` grid.
A root without a manager or with a known missing manager transcript has no All teams choice.
The picker has no None option or management actions, and is absent when no overlay is available.
The picker has no None option or management actions. With **no team selected**, its last row,
under a rule, is **+ New from this session**: it puts `/helpers` and a default ask in the message
box, replacing what was there (that draft is kept in `/drafts`), and nothing happens until you
edit it and press enter (see *Turn this conversation into a team* on the team manager page). So
the chip is there even with no teams yet; it is absent only over `--host` to an engine without
teams. With a team selected the row is not offered: it makes a top-level team, and a team inside
another is `+ Add subteam` on Teams.
Closed teams are available through Show closed on Teams, not through this picker.

Selecting a team restores its conversation and horizontal strip position. A new overlay
Expand All @@ -239,7 +246,9 @@ it does not select an overlay.

A **manager** is a conversation that runs the team: you talk to it, it sends work to members
and reports progress. Teams offers **Choose AI manager** for existing members and **+ Manager**
when a team has none. Add a new member first when you need a new conversation to replace
when a team has none. In the conversation you are working in, **`/helpers`** (or **`+ New
from this session`**, last in the Teams dropdown) makes a new team with that conversation
as its manager, which then proposes helpers for you to accept, change or cancel. Add a new member first when you need a new conversation to replace
an existing manager. All teams has a dedicated Global manager card. `+ Global manager` creates its optional
conversation. Its reports are the managers of open top-level teams; subteam managers
report to their parent. Its card's `x` deletes the global-manager conversation with the
Expand Down
8 changes: 6 additions & 2 deletions internal/manual/chat/hints-and-tips.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ screen you pass through, so the tip worth saying differs: a conversation gets th
urgent thing that is true right now, and home gets everything in turn. Home's row does not
wait for quiet; a conversation's waits 15 seconds.

Both rows draw from **one list** of twenty-four tips (below), and using a gesture on
Both rows draw from **one list** of twenty-five tips (below), and using a gesture on
either retires it on both.

**A conversation's tip has moved several times.** It was the keys row's lowest rung until
Expand Down Expand Up @@ -121,7 +121,7 @@ later when the ring comes round. It jumps once and then takes its turn like the

## Every hint codeaf can show, and what makes each one go away

There are twenty-four, one list for both boxes. Each one says the moment it first appears
There are twenty-five, one list for both boxes. Each one says the moment it first appears
and the gesture that retires it. The list is the program's own table (the surface refuses to
build if the two disagree), so a tip you saw is on it word for word.

Expand Down Expand Up @@ -150,6 +150,10 @@ build if the two disagree), so a tip you saw is on it word for word.
it. It is the first tip a conversation says, ahead of `/task`.
- `/task starts a single-shot task on the side` — after the first exchange. Retired when
`/task` is typed, bare or with a brief.
- `/helpers makes this conversation the manager of a new team` — after the first exchange,
in a conversation with no team selected on the strip that does not already manage a team;
never on home. Retired the first time `/helpers` is typed or the Teams dropdown's
`+ New from this session` is chosen.
- `/automations add sets one up exactly · or just say when, like every Monday at 9` — from
the first minute on home and after the first exchange in a conversation. It is the other
half of the `/automations` row above — the place lists them, and this is how one is made,
Expand Down
2 changes: 1 addition & 1 deletion internal/manual/chat/home.md
Original file line number Diff line number Diff line change
Expand Up @@ -1342,7 +1342,7 @@ one behind your back. This is every fate, in the words the drop-up draws them in
| **`this list is /resume`** | `/resume` `/sessions` | Says `this list is /resume · enter opens a row` — home *is* that list. |
| **`onto home's tray`** | `/attach <path>` | The file — or picture — rides on home's own tray into the conversation you open next. Home says `attached · notes.md · rides with the next conversation`. A bare `/attach` opens the browser aimed at the next conversation's folder, and a file chosen there lands on the tray. |
| **`opens a conversation here first`** | `/files` · `/folder` `/place` `/dir` · `/manual` · `/permissions` `/perms` · `/connect` · `/harness` · `/subharness` · `/skill` `/skills` · `/copy` · `/select` · `/rewind` `/undo` `/back` · `/compact` · `/export` `/save` · `/task <brief>` | Opens a conversation at the target — the folder at the right of the keys row and the model on the rule above the box — then runs there. Home closes, exactly as `enter` closes it. `/manual` is on this road since 2026-09-22: it is a question put to the model, so it needs a conversation to be asked in. `/folder` joined it the same day — it gives THIS conversation a folder, and home has no this; the pin it used to be here is `/project`. |
| **`answers here`** | `/help` · `/status` · `/cost` · `/cache` · `/budget` · `/debug` · `/stop` · `/remember` · `/always` · `/always <text>` · a word nobody defined | Answers with a note, and the first line of that note is put on home's own line under the box. `there is no command called /pricing · / lists them` is now something you can read. |
| **`answers here`** | `/help` · `/status` · `/cost` · `/cache` · `/budget` · `/debug` · `/stop` · `/remember` · `/always` · `/always <text>` · `/helpers` · a word nobody defined | Answers with a note, and the first line of that note is put on home's own line under the box. `there is no command called /pricing · / lists them` is now something you can read. `/helpers` makes a team of the conversation you are working in, and home has none in front, so it says `/helpers makes a team of the conversation you are in · open one first`. |
| **`opens the crew panel`** | `/crew` and every `/crew` shortcut | Home steps aside and the crew panel opens over the conversation behind it; `esc` on the panel brings you back to home. A shortcut opens it with a tick on the row it changed. |
| **`runs on the conversation behind home`** | `/land` · `/land <folder>` · `/workspace <path>` · `/delete` | `/delete` asks to permanently delete the conversation behind Home; it opens its confirmation here and never starts a new conversation. The other commands act on the conversation this window is holding behind the screen — not on the one `enter` would open — and its answer is echoed onto home's line. |
| **`a fresh conversation behind home`** | `/new` `/clear` `/clean` `/reset` | Replaces the conversation behind the screen and says `started a fresh conversation behind home`. It is not the same act as `enter`, which opens a conversation at the target. |
Expand Down
Loading
Loading