Skip to content

Commit efcb910

Browse files
committed
feat(ui): show target Space in approval dialog + teach the @mux trigger
- MetaToolApprovalDialog renders a "Space: <name>" chip from the new payload field so a user can see (and reject) a write aimed at a Space other than the one they expect — important now that a client may pass any space_id. - Tool Optimization shelf shows an @mux tip so users learn the trigger word for driving these tools from their AI client (reads silent, writes approved). - e2e (meta-tools.wdio): assert the @mux tip renders, and that the approval dialog surfaces the target-Space chip; synthetic payloads use the real manage_feature_set / bind_current_workspace tool names with space_name. Signed-off-by: Mohammod Al Amin Ashik <maa.ashik00@gmail.com>
1 parent fcac5df commit efcb910

3 files changed

Lines changed: 49 additions & 8 deletions

File tree

apps/desktop/src/features/builtinServers/BuiltinServersPage.tsx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,20 @@ export function BuiltinServersPage() {
263263
</span>
264264
)}
265265
</div>
266+
<p
267+
className="mb-3 text-xs text-[rgb(var(--muted))]"
268+
data-testid="builtin-mux-trigger-tip"
269+
>
270+
Tip: in your AI client, start a request with{' '}
271+
<code className="rounded bg-[rgb(var(--surface))] px-1 py-0.5 font-mono text-[11px]">
272+
@mux
273+
</code>{' '}
274+
so it knows to drive these tools — e.g.{' '}
275+
<span className="italic">
276+
“@mux build a minimal toolset for this repo”
277+
</span>
278+
. Reads are silent; writes ask for your approval.
279+
</p>
266280
<div
267281
className={`overflow-hidden rounded-xl border border-[rgb(var(--border))] transition-opacity ${
268282
selected.enabled ? '' : 'opacity-50'

apps/desktop/src/features/metaTools/MetaToolApprovalDialog.tsx

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,13 @@ export interface ApprovalRequest {
1414
payload: {
1515
tool_name: string;
1616
summary: string;
17+
/**
18+
* Name of the Space this write targets. Surfaced as a chip so a change
19+
* aimed at a Space other than the one the user expects is obvious — a
20+
* client may now pass any `space_id`. Absent for writes with no single
21+
* target Space.
22+
*/
23+
space_name?: string | null;
1724
/**
1825
* Tool-list diff the dialog renders. Freeform by design — the backend's
1926
* `ApprovalPayload.diff` is an arbitrary JSON value and each write tool
@@ -112,9 +119,19 @@ export function MetaToolApprovalDialog() {
112119
<CardContent className="space-y-4">
113120
<div className="text-sm">
114121
<p className="font-medium">{current.payload.summary}</p>
115-
<p className="text-xs text-[rgb(var(--muted))] mt-1 font-mono">
116-
tool:&nbsp;{current.payload.tool_name}
117-
</p>
122+
<div className="flex flex-wrap items-center gap-2 mt-1">
123+
{current.payload.space_name && (
124+
<span
125+
className="inline-flex items-center gap-1 rounded-full border border-[rgb(var(--border-subtle))] bg-[rgb(var(--surface))] px-2 py-0.5 text-xs"
126+
data-testid="meta-tool-approval-space"
127+
>
128+
Space:&nbsp;<span className="font-medium">{current.payload.space_name}</span>
129+
</span>
130+
)}
131+
<span className="text-xs text-[rgb(var(--muted))] font-mono">
132+
tool:&nbsp;{current.payload.tool_name}
133+
</span>
134+
</div>
118135
</div>
119136

120137
{current.payload.affects_other_clients && (

tests/e2e/specs/meta-tools.wdio.ts

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ describe('Built-in Servers - Tool Optimization UI', () => {
2929
const card = await byTestId('builtin-server-tool-optimization');
3030
await expect(card).toBeDisplayed();
3131

32+
// Selecting the capability surfaces the `@mux` trigger tip so users learn
33+
// the language for driving these tools from their AI client.
34+
await safeClick(card);
35+
await expect(await byTestId('builtin-mux-trigger-tip')).toBeDisplayed();
36+
3237
const space = await getDefaultSpace();
3338
if (!space) throw new Error('No default space — cannot set up test');
3439

@@ -79,8 +84,9 @@ describe('Meta tools - Approval dialog', () => {
7984
request_id: requestId,
8085
client_id: '00000000-0000-0000-0000-0000000000aa',
8186
payload: {
82-
tool_name: 'mcpmux_pin_this_session',
83-
summary: 'E2E: pin to FeatureSet "tiny" (3 tools)',
87+
tool_name: 'mcpmux_manage_feature_set',
88+
summary: "Update FeatureSet 'tiny' in Space 'My Space': +0 / -2",
89+
space_name: 'My Space',
8490
diff: {
8591
before: ['github_create_issue', 'firebase_deploy', 'slack_send'],
8692
after: ['github_create_issue'],
@@ -96,6 +102,9 @@ describe('Meta tools - Approval dialog', () => {
96102
const dialog = await byTestId('meta-tool-approval-dialog');
97103
await dialog.waitForDisplayed({ timeout: TIMEOUT.medium });
98104

105+
// The target Space is named so cross-Space changes are obvious.
106+
await expect(await byTestId('meta-tool-approval-space')).toBeDisplayed();
107+
99108
// Every button is present and clickable.
100109
await expect(await byTestId('meta-tool-approval-allow-once')).toBeDisplayed();
101110
await expect(await byTestId('meta-tool-approval-always')).toBeDisplayed();
@@ -110,10 +119,11 @@ describe('Meta tools - Approval dialog', () => {
110119
request_id: requestId,
111120
client_id: '00000000-0000-0000-0000-0000000000bb',
112121
payload: {
113-
tool_name: 'mcpmux_set_space_active',
114-
summary: 'E2E deny: change space active FS',
122+
tool_name: 'mcpmux_bind_current_workspace',
123+
summary: "E2E deny: bind workspace in Space 'My Space'",
124+
space_name: 'My Space',
115125
diff: null,
116-
raw_args: {},
126+
raw_args: { space_id: '22222222-2222-2222-2222-222222222222' },
117127
affects_other_clients: true,
118128
},
119129
expires_at_unix_secs: Math.floor(Date.now() / 1000) + 60,

0 commit comments

Comments
 (0)