Give bots tools and MCP servers per bot and workspace, with status and tests

- Bots and workspaces get tools and MCP servers from their settings
  pages; bots also from chips under the chat composer, removable there
- "Every bot" now gives one to every bot now and every new bot; each can
  still drop it (attach-every-bot-extensions.ts moves old installs over)
- Status lines: MCP servers record whether they connect, tools whether
  their last run worked
- Test connection in the MCP form and a Test panel in the tool form check
  the form as it is, without saving
- Hide Google sign-in on the login form

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
2026-10-19 15:35:13 +01:00
co-authored by Claude Opus 5.5
parent c6ec7d77a2
commit 6294b911e6
69 changed files with 2026 additions and 271 deletions
@@ -0,0 +1,17 @@
import relativeTime from "@/src/utils/relative-time";
type Params = {
at: number;
};
/**
* When a status was last checked, for a sentence: "just now", "5m ago",
* "on Tue".
*/
export default function checkedAgo({ at }: Params) {
const time = relativeTime({ at });
if (time == "now") return "just now";
return /^\d/.test(time) ? `${time} ago` : `on ${time}`;
}
@@ -5,13 +5,12 @@ type Params = {
};
/**
* Who gets an MCP server or tool, in a few words: "Every bot",
* "2 bots · 1 workspace", or "No bots yet".
* Who gets an MCP server or tool, in a few words: "2 bots · 1 workspace",
* "Every bot by default · 5 bots", or "No bots yet".
*/
export default function extensionAccessLabel({ access }: Params) {
if (access.all_bots) return "Every bot";
const parts = [
access.all_bots ? "Every bot by default" : "",
access.bot_ids.length ? `${access.bot_ids.length} ${access.bot_ids.length == 1 ? "bot" : "bots"}` : "",
access.workspace_ids.length
? `${access.workspace_ids.length} ${access.workspace_ids.length == 1 ? "workspace" : "workspaces"}`