Repository navigation
Turn the web dashboard into a control center - #11
Open
ZackLiuzeyu wants to merge 20 commits into
Open
ZackLiuzeyu wants to merge 20 commits into
ZackLiuzeyu wants to merge 20 commits into
Conversation
The web dashboard could watch a team but not act on it. It now covers the CLI and orchestrator operations used day to day: messaging and broadcast, session and agent pause/resume, release (all, or approved only), add, remove, rename and change role of agents, New Team, session create, relaunch, archive, end, export and delete, plan and knowledge editing, file locks and ownership zones, and guardrail steppers. Agent processes live in the memory of the process that launched them, so the orchestrator's tools move to orchestrator/runtime.ts. The MCP server and the web dashboard both host it, and the web runs the same create_team, add_agent, release_agent, end_session and resume_session code instead of a copy. dashboard/control.ts is the API: every mutation names its session, checks that the slot belongs to it, and returns the broker's answer or an error. A human gate (session config human_gate, on for teams started from the browser, create_team's human_gate for MCP) keeps a fully approved session waiting instead of ending itself. From there the person releases the agents or sends one back with actionable feedback. The broker gains plan item add/edit/delete and a merging config_patch on session update. Messages from the browser use sender id "human". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SP5EAuSkQZm3jj3PTTWDfN
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
Turn the web dashboard into a control center
slugify kept only a-z and 0-9, so a session named "食物过敏论文" got the id
"". The dashboard then could not open or end it ("session_id is required",
HTTP 400 on switch). Slugs now keep letters and digits of any script and
fall back to "session"; the broker refuses an empty id and, on startup,
renames a session stored under "" in every table. A failed session switch
shows the server's reason instead of the status code.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SP5EAuSkQZm3jj3PTTWDfN
The dashboard becomes a three-pane workspace: sessions and a file explorer of the project on the left, the team chat in the middle, and a file preview plus team roster on the right. Side panes collapse and resize, and turn into drawers on narrow screens. - Chat: your messages on the right, agents on the left with avatar, role and message kind; system notices fold into centered lines; one-to-many sends show once. Enter sends without cutting off IME input. Markdown renders safely, and file names agents mention become links once the project is found to contain them. - Preview: Markdown, code with line numbers, images, PDF, .docx, CSV, sandboxed HTML, audio and video; it follows the open file as agents edit it. - Themes: light, dark, or follow the system. dashboard/files.ts serves the project read-only under GET /api/fs/*, resolving every path with realpath so neither ".." nor a symlink leaves the project. HTML and SVG get a sandbox CSP, and .docx is rendered server-side with a small zip reader. The UI moves to index.html, app.js and styles.css. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SP5EAuSkQZm3jj3PTTWDfN
ZackLiuzeyu
force-pushed
the
claude/adoring-goodall-vg29z0
branch
from
October 22, 2026 03:15
8bb2c02 to
2325506
Compare
Web dashboard: team chat, file explorer and preview; fix non-ASCII session names
Activity: a live timeline of every agent's work in the dashboard — thinking, tool calls with their inputs, edits as diffs, commands with output, turn costs. orchestrator/activity.ts maps Claude stream-json, Codex app-server items and Gemini stream-json onto one shape, written to the broker (/activity/*) by the host that runs the agent. Approvals: each agent has an approval mode (bypass, auto, accept_edits, ask). Claude now runs with --permission-prompt-tool stdio, so its can_use_tool control requests reach the driver; Codex's approval requests are no longer auto-accepted when a handler is set. Both are stored in the broker (/approvals/*) and wait for a person, so any dashboard can answer: Allow, Always allow (the tool, or the shell program, for the rest of the agent's session) or Deny with a note. Team-protocol tools never ask. Models and effort: settings live in the slot snapshot, and the runtime syncs running drivers with them each delivery tick. Claude switches live (set_model, set_permission_mode); Codex picks them up at its next turn; Gemini and Claude's effort at the next start. Pausing a slot now also interrupts its running turn. Usage and limits: Claude's reported cost is metered per slot (cost_usd), Gemini's token stats are counted, and session config.limits (per agent or per session, tokens or USD) pause and interrupt an agent that reaches them. The dashboard gains the Activity tab, approval cards and banner, a Settings dialog per agent, and a Usage tab with limit locks. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SP5EAuSkQZm3jj3PTTWDfN
- dashboard/i18n.js: tr(english, vars) with a Chinese dictionary, pattern rules for server-generated text (activity titles, toasts), and in-place translation of the static HTML and modal bodies. Language button in the top bar; Chinese is the default for zh browsers; dates use the locale. - Avatars default to the agent CLI's icon (Claude, Gemini from Simple Icons; a neutral terminal glyph for Codex). Click an avatar to use initials, a color or an uploaded image instead; your own avatar too. - Appearance dialog: background image under the whole page, image and panel opacity, optional blur. All per-browser localStorage. - tests/web-i18n.test.ts checks every UI string has a Chinese entry. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SP5EAuSkQZm3jj3PTTWDfN
Web dashboard: agent activity and step approvals, model switching, usage limits, i18n, avatars and background
A dashboard server started before an update serves the new index.html and app.js from disk but 404s i18n.js, which it doesn't know. app.js then threw at boot and the page sat on "connecting…". It now falls back to English and says the server needs a restart. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SP5EAuSkQZm3jj3PTTWDfN
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SP5EAuSkQZm3jj3PTTWDfN
ZackLiuzeyu
force-pushed
the
claude/adoring-goodall-vg29z0
branch
from
October 22, 2026 05:23
5b4d6b5 to
55c4dd4
Compare
…m thinking Plan limits: the Usage tab (and a top-bar meter) shows each CLI's subscription windows, read without a model turn — Claude's 5-hour and weekly windows (get_usage control request on a throwaway claude -p), Codex's 5-hour and weekly windows (account/rateLimits/read), Gemini's daily per-model quota (Code Assist retrieveUserQuota with the stored Google login, never refreshed here). Cached two minutes. Talking to agents: agents can now reply to "human" (the broker refused it) and are told the id to use. "Interrupt" on the composer stops one agent's turn so it answers first. Q&A mode holds the team: running turns stop, agents hear only the person, edits and commands are refused (reads stay allowed; Codex turns run read-only), teammates' messages wait, and nudges, respawns and auto-end pause until it ends. Live view: Claude runs with --include-partial-messages; a LiveTracker per agent turns Claude, Codex and Gemini deltas into the block being written and the current step, kept in memory on the broker. The chat shows typing dots, the step and the thinking as it forms. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SP5EAuSkQZm3jj3PTTWDfN
detectAgent looked for the real claude / codex binaries even when MULTIAGENTS_CLAUDE_COMMAND / MULTIAGENTS_CODEX_COMMAND replace them, so on a machine without the CLI (CI) every team launch was refused although the override would have run. The override's program is what has to exist. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SP5EAuSkQZm3jj3PTTWDfN
Web dashboard: plan limits, talking to agents (interrupt, Q&A mode), live thinking
…nswered
The broker is a daemon that keeps its old code across updates, so replies
to the person, Q&A mode and the live thinking view silently did nothing
until it was restarted. /health now lists the broker's features; the
dashboard restarts an idle outdated broker at startup and otherwise shows
a banner with a Restart button. A restart leaves agents running: current
brokers exit on SIGUSR2 without the SIGTERM handler that kills every
registered peer, older ones are ended with SIGKILL (WAL keeps the data).
The chat now also shows an agent that was asked something and has not
answered yet, from the messages alone, so every agent gets a "working"
row even when no live report reaches the dashboard.
Codex plan limits: older app-servers take no params on
account/rateLimits/read ("invalid type: map, expected unit"); send null,
which every version accepts.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SP5EAuSkQZm3jj3PTTWDfN
Driver-run Codex agents have a connected slot but no peer row, so the zero-peer check could restart an outdated broker under them at dashboard startup. brokerIsIdle also requires no connected slot in any open session. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SP5EAuSkQZm3jj3PTTWDfN
The dead-slot loop deleted every slot disconnected for 5 minutes. Agents that exit when done (Gemini after approval, exit 0) vanished from the team list — also while the session was paused or waiting on a person. deadSlotVerdict now decides: a slot is deleted only if its agent connected, never worked (task_state idle), never sent a message or held a plan item, and the session is not paused, in Q&A mode or at the human gate. Everything else stays listed as offline until a person removes it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SP5EAuSkQZm3jj3PTTWDfN
Restart an outdated broker without killing agents; keep finished agents; show who has not answered; fix Codex plan limits
A new agent type, api, runs an agent on any chat-completions API configured under API providers (name, base URL, key, default model, optional prices, context window and extra request fields). Keys live in ~/.multiagents/providers.json (0600) and never reach the page; slots keep the provider id. ApiDriver runs the agent in-process: it spawns the team-tools MCP server in driver mode and speaks MCP to it, adds local tools with Claude's names (Read, Write, Edit, LS, Glob, Grep, Bash, WebFetch) confined to the project, streams completions (reasoning_content becomes thinking) and emits Claude's stream-json events. It implements ClaudeSession, so delivery, approvals per permission mode, the activity timeline, the live view, token and cost accounting, Q&A mode, interrupts and live model switches all reuse the Claude paths. The dashboard gets an API providers dialog with presets and model fetching, the "Other (OpenAI-compatible API)" type in Add Agent and New Team, provider names on cards and a plug avatar. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SP5EAuSkQZm3jj3PTTWDfN
…how to sign in Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SP5EAuSkQZm3jj3PTTWDfN
- A new file whose parent directories do not exist yet is resolved through its nearest existing ancestor, so a symlinked directory in the project cannot carry a Write outside it. - The team-tools adapter of an API agent registers as "api" (not "claude"), so peer lists and type filters report it correctly. - Clearing an API agent's model is refused when the provider has no default model, since a restarted agent could not launch without one. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SP5EAuSkQZm3jj3PTTWDfN
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The web dashboard could watch a team but not act on it. It now covers the CLI and orchestrator operations used day to day: messaging and broadcast, session and agent pause/resume, release (all, or approved only), add, remove, rename and change role of agents, New Team, session create, relaunch, archive, end, export and delete, plan and knowledge editing, file locks and ownership zones, and guardrail steppers.
Agent processes live in the memory of the process that launched them, so the orchestrator's tools move to orchestrator/runtime.ts. The MCP server and the web dashboard both host it, and the web runs the same create_team, add_agent, release_agent, end_session and resume_session code instead of a copy. dashboard/control.ts is the API: every mutation names its session, checks that the slot belongs to it, and returns the broker's answer or an error.
A human gate (session config human_gate, on for teams started from the browser, create_team's human_gate for MCP) keeps a fully approved session waiting instead of ending itself. From there the person releases the agents or sends one back with actionable feedback.
The broker gains plan item add/edit/delete and a merging config_patch on session update. Messages from the browser use sender id "human".
Claude-Session: https://claude.ai/code/session_01SP5EAuSkQZm3jj3PTTWDfN