Config tab → live control panel; sidebar styling pass (T-414)
The Claude sidebar's settings table was read-only 12px rows. It becomes the power panel's core: - model / effort / permission-mode rows are popover controls on the owned anchored-menu primitive (ClideAnchoredOverlay + ClideMenu), showing the LIVE session values (SessionStatus, falling back to the probe/settings) with the active option marked. - Picking an option publishes the explicit slash command (`/effort xhigh`) on builtin.claude/command; the PRIMARY pane subscribes and executes it through the same _send routing the composer uses — the control and the typed command are one code path (D-6), which is also what lets the sidebar drive /effort's respawn flow without reaching into the pane. Only the primary pane listens (controls target the primary session; a second listener would double-execute). - Styling pass (user request): shared meta tables move from 12px- everything to 13px labels/values, accent-coloured section headers, wider row pitch; control rows get hover affordance + caret. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -133,6 +133,33 @@ void main() {
|
||||
expect(find.text('Claude environment not loaded.'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('a settings control publishes its slash command on pick (T-414)', (tester) async {
|
||||
final dir = Directory.systemTemp.createTempSync('cfg');
|
||||
addTearDown(() => dir.deleteSync(recursive: true));
|
||||
final config = ClaudeConfig(globalDir: dir, cacheDir: dir);
|
||||
final published = <Message>[];
|
||||
final sub = f.services.messages.subscribe(publisher: 'builtin.claude', channel: 'command').listen(published.add);
|
||||
addTearDown(sub.cancel);
|
||||
|
||||
await tester.pumpWidget(harness(f, sidebar(config: config, initialTab: SidebarTab.config)));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// The three live controls render alongside the read-only rows.
|
||||
expect(find.text('model'), findsOneWidget);
|
||||
expect(find.text('effort'), findsOneWidget);
|
||||
expect(find.text('permission mode'), findsOneWidget);
|
||||
|
||||
// Open the effort control and pick a level → the explicit slash command
|
||||
// goes out on the bus (the primary pane executes it via _send, D-6).
|
||||
await tester.tap(find.bySemanticsLabel(RegExp('effort: .*Click to change.')));
|
||||
await tester.pumpAndSettle();
|
||||
await tester.tap(find.textContaining('xhigh'));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(published, hasLength(1));
|
||||
expect(published.single.data['text'], '/effort xhigh');
|
||||
});
|
||||
|
||||
testWidgets('a meta.tab message switches the sub-tab (T-413 slash navigation)', (tester) async {
|
||||
await tester.pumpWidget(harness(f, sidebar(stats: stats)));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
Reference in New Issue
Block a user