feat(settings): Activity category — conversation fold level (T-453)
The first real settings tab. The Claude extension contributes an Activity SettingsCategory whose fold-level select binds to app.claude.activityFoldLevel; the activity panes already rebuild off the settings notifier, so a pick applies live. Proves the schema-driven engine end to end with a production setting — opening Settings now shows a populated, working category. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
+12
-13
@@ -25,30 +25,29 @@ heading, and (b) bumping `pubspec.yaml` `version:` in the same commit.
|
||||
✕, Esc, or a barrier tap. (T-445)
|
||||
|
||||
- **Schema-driven settings engine.** Subsystems register a `SettingsCategory`
|
||||
(a `SettingsCategoryContribution` routed into the kernel `SettingsRegistry`);
|
||||
the panel renders it as carded sections of field rows — toggle, select,
|
||||
text, number, and an "opens external file" button — each bound to a
|
||||
`SettingsStore` key with help text and reset-to-default. Inputs recede to
|
||||
`panelBackground` inside the elevated `panelHeader` cards (ui-design
|
||||
surface.md). Categories are data; registering one surfaces a new tab. (T-448)
|
||||
(via `SettingsCategoryContribution` → the kernel `SettingsRegistry`); the
|
||||
panel renders it as carded sections of toggle/select/text/number/file rows,
|
||||
each bound to a `SettingsStore` key with help and reset-to-default.
|
||||
Registering a category surfaces a new tab. (T-448)
|
||||
|
||||
- **Settings category rail.** The modal's left rail lists the registered
|
||||
categories (icon + title, data-driven from the registry) with an accent
|
||||
left-stripe + surfaceHi selection; picking one swaps the panel. (T-447)
|
||||
|
||||
- **Per-field scope tags.** Each settings field shows where its value lives —
|
||||
folder = Project (`.clide`), globe = Always (`~/.clide`), circle-dashed =
|
||||
Default/unset — colour-coded with a tooltip. Tapping opens a menu to move the
|
||||
value between the scopes the key supports or reset it to default. Backed by
|
||||
scope-explicit `SettingsStore` access (`rawAt`/`setAt`/`removeAt`/
|
||||
`effectiveLayer`/`writableLayers`); `ext.*` keys layer project-over-app,
|
||||
`app.*`/`project.*` keys live in their prefix's file. (T-449)
|
||||
- **Per-field scope tags.** Each field shows where its value lives — folder =
|
||||
Project (`.clide`), globe = Always (`~/.clide`), circle-dashed =
|
||||
Default/unset — with a tooltip and a menu to move the value between scopes or
|
||||
reset it. Backed by scope-explicit `SettingsStore` access. (T-449)
|
||||
|
||||
- **Cross-category settings search.** A search box atop the rail filters fields
|
||||
across every category; the panel shows the matches grouped under category
|
||||
subheaders (editable inline), and each rail row shows its match count with
|
||||
zero-match categories dimmed. (T-450)
|
||||
|
||||
- **Settings → Activity category.** The first real settings tab: the
|
||||
conversation fold level (none / tools / thinking / everything) as a schema
|
||||
field; picking a level applies live to the activity stream. (T-453)
|
||||
|
||||
### Changed
|
||||
|
||||
- **Theme picker relabelled "Theme…".** The ⌘K theme picker's command title
|
||||
|
||||
@@ -100,6 +100,38 @@ class ClaudeExtension extends ClideExtension {
|
||||
title: 'Claude: cycle activity fold level',
|
||||
run: _cycleFoldLevel,
|
||||
),
|
||||
// Activity settings category (T-453) — the fold level as a schema field,
|
||||
// written to kActivityFoldLevelKey; the panes already rebuild off the
|
||||
// settings notifier, so picking a level applies live.
|
||||
const SettingsCategoryContribution(
|
||||
id: 'activity',
|
||||
category: SettingsCategory(
|
||||
id: 'activity',
|
||||
title: 'Activity',
|
||||
iconName: 'cards-three',
|
||||
priority: 50,
|
||||
sections: [
|
||||
SettingsSection(
|
||||
label: 'Conversation',
|
||||
fields: [
|
||||
SettingsField(
|
||||
key: kActivityFoldLevelKey,
|
||||
kind: SettingsFieldKind.select,
|
||||
label: 'Fold level',
|
||||
help: 'How aggressively the conversation folds tool calls, thinking, and results.',
|
||||
defaultValue: 'tools',
|
||||
options: [
|
||||
SettingsOption(value: 'none', label: 'Show everything'),
|
||||
SettingsOption(value: 'tools', label: 'Fold tool calls'),
|
||||
SettingsOption(value: 'thinking', label: 'Fold tools + thinking'),
|
||||
SettingsOption(value: 'everything', label: 'Fold all but prose'),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
// T-171: agent roster controls (D-6 CLI/UI parity).
|
||||
// Usage: clide claude.agent.show <sessionId>
|
||||
CommandContribution(
|
||||
|
||||
@@ -145,4 +145,16 @@ void main() {
|
||||
expect(activeClaudeConfig, isNull);
|
||||
});
|
||||
});
|
||||
|
||||
group('Activity settings category (T-453)', () {
|
||||
final category = ext.contributions.whereType<SettingsCategoryContribution>().firstWhere((c) => c.id == 'activity').category;
|
||||
|
||||
test('contributes an Activity category with the fold-level field', () {
|
||||
expect(category.title, 'Activity');
|
||||
final field = category.sections.expand((s) => s.fields).firstWhere((f) => f.key == kActivityFoldLevelKey);
|
||||
expect(field.kind, SettingsFieldKind.select);
|
||||
expect(field.defaultValue, 'tools');
|
||||
expect(field.options.map((o) => o.value), containsAll(['none', 'tools', 'thinking', 'everything']));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user