Conversation
Wrap agent CLI launches (claude, codex, gemini) with agent-relay-broker so agents in different Superset tabs can send messages to each other via Relaycast channels and DMs. Messages are injected directly into the receiving agent's PTY stdin by the broker. Key changes: - Create a shared Relaycast workspace on app startup (env.ts) - Generate friendly agent names (agent-1, agent-2) and pre-register them so agents can chat immediately without manual setup - Modify wrapper scripts to launch agents through `agent-relay-broker wrap` with automatic fallback to direct exec if the broker is not installed - Write .mcp.json with shared workspace credentials so Claude's MCP tools use the same workspace as all other agents - Pass RELAY_API_KEY, RELAY_AGENT_NAME, RELAY_AGENT_TOKEN to both the wrap broker and the MCP server inside each agent Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…s page (superset-sh#2868) The link pointed to docs.superset.sh/integrations which returns a 404. Removed the link and cleaned up the unused COMPANY import.
) Add max-w-full and overflow constraints to user message containers in both workspace chat and new chat to prevent layout breaking when pasting large code blocks. - UserMessageText: add overflow-x-auto to text bubble for horizontal scroll - UserMessage: add max-w-full to outer wrapper - MessageList: add max-w-full to user message container Co-authored-by: Mastra Code (anthropic/claude-opus-4-6) <noreply@mastra.ai>
* fix(desktop): reduce review tab GitHub polling * fix(desktop): prefetch review data from changes view * fix(desktop): address review polling regressions * test(desktop): harden repo context refresh checks * refactor(desktop): centralize GitHub query policies * fix(desktop): restore passive GitHub status policies
…uperset-sh#2827) * fix(desktop): preserve terminal viewport during refits * refactor(desktop): remove terminal viewport restore workaround * revert: keep only terminal fit idempotency guard
… sidebar (superset-sh#2875) The collapsed sidebar's ProjectHeader wrapper used `w-full` without centering, causing the project thumbnail to be left-aligned while workspace icons below were centered via `items-center`. Adding `flex justify-center` to the wrapper aligns all collapsed sidebar icons on the same horizontal center. Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
* Fix org slug sync refresh in Electric collections * Revert org collection refresh experiment * Align TanStack Electric package upgrades * Normalize task detail live query shape * Inline task join type normalization
Replace raw fetch calls and manual binary resolution with SDK modules: - createWorkspace/registerAgent from @agent-relay/sdk/http - getBrokerBinaryPath from @agent-relay/sdk/broker-path Bump @agent-relay/sdk to ^3.2.17 (includes wrap DM routing and presence filtering fixes). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
| const configSignature = JSON.stringify({ | ||
| RELAY_API_KEY: relayApiKey, | ||
| RELAY_AGENT_NAME: relayEnv?.RELAY_AGENT_NAME ?? "", | ||
| RELAY_AGENT_TOKEN: relayEnv?.RELAY_AGENT_TOKEN ?? "", | ||
| RELAY_SKIP_BOOTSTRAP: relayEnv?.RELAY_SKIP_BOOTSTRAP ?? "", | ||
| }); | ||
| if (relayMcpConfigCache.get(projectDir) === configSignature) { | ||
| return; | ||
| } | ||
|
|
||
| const relaycastEntry = { | ||
| command: "npx", | ||
| args: ["-y", "@relaycast/mcp"], | ||
| env: { | ||
| RELAY_API_KEY: relayApiKey, | ||
| RELAY_BASE_URL: "https://api.relaycast.dev", | ||
| }, | ||
| }; | ||
| const agentRelayEntry = { | ||
| command: "npx", | ||
| args: ["-y", "@relaycast/mcp"], | ||
| env: { | ||
| RELAY_API_KEY: relayApiKey, | ||
| RELAY_BASE_URL: "https://api.relaycast.dev", | ||
| ...(relayEnv?.RELAY_AGENT_NAME | ||
| ? { RELAY_AGENT_NAME: relayEnv.RELAY_AGENT_NAME } | ||
| : {}), | ||
| ...(relayEnv?.RELAY_AGENT_TOKEN | ||
| ? { RELAY_AGENT_TOKEN: relayEnv.RELAY_AGENT_TOKEN } | ||
| : {}), | ||
| ...(relayEnv?.RELAY_SKIP_BOOTSTRAP | ||
| ? { RELAY_SKIP_BOOTSTRAP: relayEnv.RELAY_SKIP_BOOTSTRAP } | ||
| : {}), | ||
| RELAY_STRICT_AGENT_NAME: "1", | ||
| }, | ||
| }; | ||
|
|
||
| let config: Record<string, unknown> = { mcpServers: {} }; | ||
| if (fs.existsSync(mcpPath)) { | ||
| try { | ||
| config = JSON.parse(fs.readFileSync(mcpPath, "utf-8")); | ||
| } catch { | ||
| // Corrupted file — overwrite | ||
| } | ||
| } | ||
|
|
||
| const servers = (config.mcpServers ?? {}) as Record<string, unknown>; | ||
| // Use both names: "relaycast" for codex/gemini and "agent-relay" to | ||
| // override Claude's global marketplace plugin with the shared key | ||
| servers.relaycast = relaycastEntry; | ||
| servers["agent-relay"] = agentRelayEntry; | ||
| config.mcpServers = servers; | ||
|
|
||
| fs.writeFileSync(mcpPath, JSON.stringify(config, null, 2)); | ||
| relayMcpConfigCache.set(projectDir, configSignature); |
There was a problem hiding this comment.
🔴 ensureRelayMcpConfig overwrites .mcp.json with per-terminal agent credentials, causing stale identity for concurrent agents
Each call to buildTerminalEnv writes the current terminal's unique RELAY_AGENT_NAME and RELAY_AGENT_TOKEN into ${workspacePath}/.mcp.json via ensureRelayMcpConfig. Because the configSignature at env.ts:103-108 includes these per-terminal values, the in-memory cache never matches across different terminals, so the file is rewritten on every terminal creation. This creates a race condition: if Terminal 1 starts and writes agent-1 credentials, then Terminal 2 starts and overwrites with agent-2 credentials, any agent spawned from Terminal 1 that reads .mcp.json (e.g., Claude launching its MCP server) gets agent-2's credentials. Combined with RELAY_STRICT_AGENT_NAME: "1" at env.ts:136, the MCP server would operate under the wrong agent identity, causing cross-agent identity confusion.
Race condition sequence
- Terminal 1 (
tabId=t1) starts →getOrRegisterRelayAgentreturns{name: "agent-1", token: "tok-1"}→ writes.mcp.jsonwith agent-1 creds - Terminal 2 (
tabId=t2) starts →getOrRegisterRelayAgentreturns{name: "agent-2", token: "tok-2"}→ overwrites.mcp.jsonwith agent-2 creds - Claude from Terminal 1 spawns its MCP server → reads
.mcp.json→ gets agent-2's name and token - MCP server operates as agent-2 instead of agent-1
Prompt for agents
In apps/desktop/src/main/lib/terminal/env.ts, the ensureRelayMcpConfig function (lines 90-164) writes per-terminal agent credentials (RELAY_AGENT_NAME, RELAY_AGENT_TOKEN) into the shared .mcp.json file. Each terminal overwrites the previous terminal's credentials, creating a race condition. To fix this, the .mcp.json should only contain the shared RELAY_API_KEY (which is the same for all terminals), NOT the per-terminal agent credentials. Remove the agent-specific env vars (RELAY_AGENT_NAME, RELAY_AGENT_TOKEN, RELAY_SKIP_BOOTSTRAP) from the agentRelayEntry's env block and from the configSignature. The per-terminal credentials are already passed to agents via the terminal environment variables set in buildTerminalEnv at lines 707-713. This also eliminates the unnecessary per-terminal .mcp.json file rewrites.
Was this helpful? React with 👍 or 👎 to provide feedback.
| if (apiKey) { | ||
| cachedRelayApiKey = apiKey; | ||
| process.env.RELAY_API_KEY = cachedRelayApiKey; | ||
| console.log("[relay] workspace created, key:", `${apiKey.slice(0, 15)}...`); |
There was a problem hiding this comment.
🟡 API key prefix logged to console, potentially exposing short keys entirely
ensureRelayApiKey at env.ts:48 logs apiKey.slice(0, 15) to the Electron console. If the API key is shorter than 15 characters (the test at env.test.ts:743 uses "rk_test_123" which is only 11 chars), the entire key is logged. Even for production keys, logging 15 characters of a secret is a security concern as it significantly reduces the key space for brute-force attacks and could be captured by log aggregation or crash reports.
| console.log("[relay] workspace created, key:", `${apiKey.slice(0, 15)}...`); | |
| console.log("[relay] workspace created, key:", `${apiKey.slice(0, 6)}...(${apiKey.length} chars)`); |
Was this helpful? React with 👍 or 👎 to provide feedback.
Description
Related Issues
Type of Change
Testing
Screenshots (if applicable)
Additional Notes