Watch
0
0
Fork
You've already forked hyperhive
0

swarm-ui: choosing a subagent in the subagents menu splits its terminal in beside the agent's

The menu on an agent's terminal page used to open the subagent on a tab of
its own. It now starts a group of this terminal and the subagent's, split to
the right; in a group's pane it splits that pane. A pane's layout key is the
agent, or `agent/subagent` for a subagent's pane, so the layout operations
stay as they are and a destroyed agent takes its subagent panes with it. A
subagent already in the group shows a marker and does nothing when chosen,
and maximize opens a subagent pane's terminal on its own.
This commit is contained in:
iris 2026-11-05 12:45:35 +01:00
commit d733b1e2a9

View file

@ -41,6 +41,22 @@ export const MIN_SHARE = 0.02;
export const pane = (agent: string): Pane => ({ kind: "pane", agent });
/**
* What a pane goes by in a layout: an agent's name, or `agent/subagent` for
* one of that agent's subagents. Neither name holds a `/`.
*/
export function paneKey(agent: string, subagent?: string): string {
return subagent === undefined ? agent : `${agent}/${subagent}`;
}
/** The agent and, for a subagent's pane, the subagent a pane key names. */
export function splitKey(key: string): { agent: string; subagent?: string } {
const at = key.indexOf("/");
return at < 0
? { agent: key }
: { agent: key.slice(0, at), subagent: key.slice(at + 1) };
}
/** The agents of a layout, in reading order (left to right, top to bottom). */
export function agentsIn(node: Node): string[] {
return node.kind === "pane" ? [node.agent] : node.children.flatMap(agentsIn);
@ -198,8 +214,10 @@ export function pruneMissing(
existing: ReadonlySet<string>,
): Node | null {
let out: Node | null = root;
for (const agent of agentsIn(root)) {
if (out !== null && !existing.has(agent)) out = removeAgent(out, agent);
for (const key of agentsIn(root)) {
if (out !== null && !existing.has(splitKey(key).agent)) {
out = removeAgent(out, key);
}
}
return out;
}