Add per-leaf mcpAllow flag for MCP visibility gating (default-deny)
This commit is contained in:
parent
b35a5b282d
commit
6068522ee3
2 changed files with 39 additions and 0 deletions
|
|
@ -12,6 +12,7 @@ import {
|
|||
setLeafShell,
|
||||
changeLabel,
|
||||
toggleBroadcast,
|
||||
toggleMcpAllow,
|
||||
adjustFontSize,
|
||||
adjustAllFontSizes,
|
||||
resolveFontSize,
|
||||
|
|
@ -363,6 +364,27 @@ describe("toggleBroadcast", () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe("toggleMcpAllow", () => {
|
||||
it("default-undefined toggles to true", () => {
|
||||
const leaf = newLeaf();
|
||||
expect(leaf.mcpAllow).toBeUndefined();
|
||||
const on = toggleMcpAllow(leaf, leaf.id) as LeafNode;
|
||||
expect(on.mcpAllow).toBe(true);
|
||||
});
|
||||
|
||||
it("true toggles to false", () => {
|
||||
const leaf = newLeaf({ mcpAllow: true });
|
||||
const off = toggleMcpAllow(leaf, leaf.id) as LeafNode;
|
||||
expect(off.mcpAllow).toBe(false);
|
||||
});
|
||||
|
||||
it("MUST NOT swap the leaf id (metadata-only, no PTY respawn)", () => {
|
||||
const leaf = newLeaf();
|
||||
const next = toggleMcpAllow(leaf, leaf.id) as LeafNode;
|
||||
expect(next.id).toBe(leaf.id);
|
||||
});
|
||||
});
|
||||
|
||||
describe("resolveFontSize", () => {
|
||||
it("returns the default when offset is undefined or 0", () => {
|
||||
expect(resolveFontSize(undefined)).toBe(DEFAULT_FONT_SIZE);
|
||||
|
|
|
|||
|
|
@ -44,6 +44,13 @@ export interface LeafNode {
|
|||
* later doesn't require migrating saved workspaces.
|
||||
*/
|
||||
fontSizeOffset?: number;
|
||||
/**
|
||||
* If true, this pane is visible to the MCP server (Claude can list it,
|
||||
* read its scrollback, etc.). Default-DENY: when undefined or false, the
|
||||
* MCP surface filters this pane out entirely. Toggled via the per-pane
|
||||
* MCP chip in the toolbar.
|
||||
*/
|
||||
mcpAllow?: boolean;
|
||||
}
|
||||
|
||||
/** Base xterm.js font size in px. Per-leaf offset adds on top of this. */
|
||||
|
|
@ -262,6 +269,15 @@ export function toggleBroadcast(root: TreeNode, leafId: NodeId): TreeNode {
|
|||
});
|
||||
}
|
||||
|
||||
/** Toggle a leaf's mcpAllow flag. Metadata-only — does NOT swap the id.
|
||||
* Drives whether the MCP server includes this pane in its surface. */
|
||||
export function toggleMcpAllow(root: TreeNode, leafId: NodeId): TreeNode {
|
||||
return replaceById(root, leafId, (node) => {
|
||||
if (node.kind !== "leaf") return node;
|
||||
return { ...node, mcpAllow: !node.mcpAllow };
|
||||
});
|
||||
}
|
||||
|
||||
/** Compute the actual pixel font size from a leaf's offset, clamped to
|
||||
* [MIN_FONT_SIZE, MAX_FONT_SIZE]. */
|
||||
export function resolveFontSize(offset: number | undefined): number {
|
||||
|
|
@ -351,6 +367,7 @@ export function reshapeToPreset(
|
|||
if (src.label !== undefined) slot.label = src.label;
|
||||
if (src.broadcast !== undefined) slot.broadcast = src.broadcast;
|
||||
if (src.fontSizeOffset !== undefined) slot.fontSizeOffset = src.fontSizeOffset;
|
||||
if (src.mcpAllow !== undefined) slot.mcpAllow = src.mcpAllow;
|
||||
}
|
||||
|
||||
for (let i = slots.length; i < existingLeaves.length; i++) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue