shape permission-prompt input rendering per tool
Bash, Write, and Edit/MultiEdit each get a tool-appropriate body in the permission card instead of the indented-JSON dump: Bash renders the command as a shell code block with a background/timeout footer, Write shows path + content syntax-highlighted from the extension, and Edit shows path + before/after blocks. Unknown tools keep the JSON fallback. Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude
parent
25c11c1edb
commit
762d66e819
@@ -18,6 +18,11 @@ heading, and (b) bumping `pubspec.yaml` `version:` in the same commit.
|
|||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
|
- Permission prompt cards render the tool input in the shape that fits the
|
||||||
|
tool — Bash shows the command as a shell code block (with a footer for
|
||||||
|
`run_in_background` / `timeout`), Write shows the path plus the content
|
||||||
|
highlighted from its extension, Edit shows the path plus before/after
|
||||||
|
blocks. Unknown tools fall back to the indented-JSON dump.
|
||||||
- Claude meta sidebar is now tabbed — Activity / Team / Config (T-182).
|
- Claude meta sidebar is now tabbed — Activity / Team / Config (T-182).
|
||||||
Activity shows usage stats plus the primary session's live runtime; Team
|
Activity shows usage stats plus the primary session's live runtime; Team
|
||||||
holds the roster and auto-fronts when a team spawns; Config shows the
|
holds the roster and auto-fronts when a team spawns; Config shows the
|
||||||
|
|||||||
Binary file not shown.
@@ -101,6 +101,52 @@ void main() {
|
|||||||
expect(find.byType(ClideCodeBlock), findsOneWidget);
|
expect(find.byType(ClideCodeBlock), findsOneWidget);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testWidgets('permission card: Bash renders the command as a shell code block, not JSON', (tester) async {
|
||||||
|
const prompt = ToolPrompt(
|
||||||
|
promptId: 'req-b',
|
||||||
|
toolName: 'Bash',
|
||||||
|
displayName: 'Bash',
|
||||||
|
description: 'Read IDE lock files',
|
||||||
|
input: {'command': 'cat ~/.claude/ide/97632.lock', 'description': 'Read IDE lock files'},
|
||||||
|
);
|
||||||
|
await tester.pumpWidget(harness(f, ToolPromptCard(prompt: prompt, onResolve: (_, __) {})));
|
||||||
|
await tester.pump();
|
||||||
|
|
||||||
|
final block = tester.widget<ClideCodeBlock>(find.byType(ClideCodeBlock));
|
||||||
|
expect(block.language, 'bash');
|
||||||
|
expect(block.source, 'cat ~/.claude/ide/97632.lock');
|
||||||
|
// The raw `description` key shouldn't bleed into the body — it's already
|
||||||
|
// shown above as the prompt's description line.
|
||||||
|
expect(find.textContaining('"description"'), findsNothing);
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('permission card: Bash shows background/timeout footer when set', (tester) async {
|
||||||
|
const prompt = ToolPrompt(
|
||||||
|
promptId: 'req-b2',
|
||||||
|
toolName: 'Bash',
|
||||||
|
displayName: 'Bash',
|
||||||
|
description: 'long task',
|
||||||
|
input: {'command': 'sleep 30', 'run_in_background': true, 'timeout': 60000},
|
||||||
|
);
|
||||||
|
await tester.pumpWidget(harness(f, ToolPromptCard(prompt: prompt, onResolve: (_, __) {})));
|
||||||
|
await tester.pump();
|
||||||
|
expect(find.text('background · timeout 60000ms'), findsOneWidget);
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('permission card: unknown tool falls back to JSON', (tester) async {
|
||||||
|
const prompt = ToolPrompt(
|
||||||
|
promptId: 'req-x',
|
||||||
|
toolName: 'NovelTool',
|
||||||
|
displayName: 'NovelTool',
|
||||||
|
input: {'foo': 'bar'},
|
||||||
|
);
|
||||||
|
await tester.pumpWidget(harness(f, ToolPromptCard(prompt: prompt, onResolve: (_, __) {})));
|
||||||
|
await tester.pump();
|
||||||
|
final block = tester.widget<ClideCodeBlock>(find.byType(ClideCodeBlock));
|
||||||
|
expect(block.language, 'json');
|
||||||
|
expect(block.source, contains('"foo"'));
|
||||||
|
});
|
||||||
|
|
||||||
testWidgets('permission card: Deny returns DenyTool with a message', (tester) async {
|
testWidgets('permission card: Deny returns DenyTool with a message', (tester) async {
|
||||||
ToolDecision? decision;
|
ToolDecision? decision;
|
||||||
await tester.pumpWidget(harness(
|
await tester.pumpWidget(harness(
|
||||||
|
|||||||
Reference in New Issue
Block a user