16 KiB
WorkUtils Unified UI P3 Limited Adaptation and Finalization Implementation Plan
For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (
- [ ]) syntax for tracking.
Goal: Apply the unified theme to Git review, mobile UI automation, settings, and plugin management without structural rewrites, then remove remaining application-level visual inconsistencies and complete full regression/visual acceptance.
Architecture: Treat the four limited modules as compatibility consumers of P0 components. Only replace visual construction, style classes, fonts, icons, and shell entry points; retain their existing controllers, panes, services, and state machines. Finish with repository-wide architecture guards that prevent regression to Emoji, duplicate settings navigation, arbitrary fonts, and ad-hoc loading code.
Tech Stack: Java 17, JavaFX 17.0.15, AtlantaFX 2.0.1, P0–P2 shared UI components, JUnit 5, Maven Wrapper.
Global Constraints
- Do not refactor Git review window structure, review workflow, service boundaries, or DiffEngine.
- Do not split mobile UI automation or rewrite its run/record state machine.
- Do not change settings information architecture, persistence, validation, or plugin-management behavior.
- Preserve Windows native title-bar controls and the light-only theme.
- Settings remains top-right-only in the application shell; no sidebar duplicate may return.
- Use Feather through
AppIcon/IconFactory; no visible Emoji or mixed icon set in the application UI. - Visual checks are read-only: do not submit reviews, run mobile automation, change settings, reorder plugins, synchronize Git, or write exports.
File Structure
Create
src/test/java/com/example/workutils/system/ui/UnifiedUiArchitectureTest.java— repository-wide regression guard.
Modify
src/main/java/com/example/workutils/biz/gitreview/GitReviewWindow.javasrc/main/java/com/example/workutils/biz/mobileuiauto/MobileUiAutomationWindow.javasrc/main/java/com/example/workutils/system/config/SettingsWindow.javasrc/main/java/com/example/workutils/system/plugin/PluginManagementWindow.javasrc/main/java/com/example/workutils/system/plugin/PluginDescriptor.java- Plugin descriptor/factory classes under
src/main/java/com/example/workutils/biz/*/*Plugin.java src/main/resources/css/light-theme.csssrc/test/java/com/example/workutils/system/ui/SharedPaneAccessibilityTest.javasrc/test/java/com/example/workutils/system/plugin/DefaultPluginConfigurationTest.java
Task 1: Add repository-wide visual architecture guards
Files:
- Create:
src/test/java/com/example/workutils/system/ui/UnifiedUiArchitectureTest.java
Interfaces:
-
Produces
source(String): SourceFileand an explicitlimitedUiSources()list. Start with Git review only; append mobile, settings/plugin management, then all plugin descriptors in their migration tasks so every task ends green. -
Step 1: Write the failing architecture tests
private record SourceFile(Path path, String text) {}
private static SourceFile source(String relativePath) throws IOException {
Path path = Path.of("src/main/java/com/example/workutils", relativePath);
return new SourceFile(path, Files.readString(path));
}
private static List<SourceFile> limitedUiSources() throws IOException {
return List.of(source("biz/gitreview/GitReviewWindow.java"));
}
private static long count(List<SourceFile> files, String needle) {
return files.stream()
.mapToLong(file -> (file.text().length()
- file.text().replace(needle, "").length()) / needle.length())
.sum();
}
@Test
void applicationUiDoesNotUseEmojiIconsOrHardcodedMicrosoftYaHei() throws IOException {
for (SourceFile file : limitedUiSources()) {
assertFalse(file.text().contains("Microsoft YaHei"), file.path().toString());
assertFalse(file.text().matches("(?s).*new Label\\(\"[⚙🛠✅❌❓▶].*"),
file.path().toString());
}
}
@Test
void settingsAndLoadingHaveSingleOwners() throws IOException {
String app = Files.readString(Path.of(
"src/main/java/com/example/workutils/WorkUtilsApplication.java"));
assertFalse(app.contains("new MainWindow.NavItem(\n AppIcon.SETTINGS, \"系统设置\""));
assertEquals(0, count(limitedUiSources(), "setBtnLoading("));
}
Limit Emoji scanning to JavaFX application controls. Exclude ApiDocGenerator HTML output where symbols may be document content rather than application chrome.
- Step 2: Run and record failures
Run: .\mvnw.cmd -q -Dtest=UnifiedUiArchitectureTest test
Expected: FAIL on Git review fonts/icons. Continue directly to Task 2 before committing.
Task 2: Theme-adapt Git review without structural refactoring
Files:
- Modify:
src/main/java/com/example/workutils/biz/gitreview/GitReviewWindow.java - Modify:
src/main/resources/css/light-theme.css - Include:
src/test/java/com/example/workutils/system/ui/UnifiedUiArchitectureTest.java
Interfaces:
-
Preserves every existing method signature, pane hierarchy, review action, service call, and loading behavior.
-
Consumes only P0 tokens/icons/style classes.
-
Step 1: Add a structural checksum assertion before edits
assertTrue(source.contains("class GitReviewWindow"));
assertTrue(source.contains("GitReviewService"));
assertFalse(source.contains("new AppShell("));
The window must remain a plugin content view and must not create its own shell.
- Step 2: Replace visual literals only
Replace direct fonts, colors, button graphics, and local spinner construction with semantic style classes, IconFactory, and LoadingButtonBinder. Do not extract panes, rename business methods, or change action ordering.
- Step 3: Run Git review compilation/architecture checks
Run: .\mvnw.cmd -q -Dtest=UnifiedUiArchitectureTest,WindowNotificationDependencyTest test
Expected: Git review visual assertions pass; notification boundary remains intact.
- Step 4: Capture read-only Git review states
Capture initial/empty/configured views without starting a review. Verify shell typography and icons while confirming the internal layout is structurally unchanged.
- Step 5: Commit
git add src/main/java/com/example/workutils/biz/gitreview/GitReviewWindow.java src/main/resources/css/light-theme.css src/test/java/com/example/workutils/system/ui/UnifiedUiArchitectureTest.java
git commit -m "适配 Git 评审统一主题"
Task 3: Theme-adapt mobile UI automation without state-machine changes
Files:
- Modify:
src/main/java/com/example/workutils/biz/mobileuiauto/MobileUiAutomationWindow.java - Modify:
src/test/java/com/example/workutils/system/ui/UnifiedUiArchitectureTest.java
Interfaces:
-
Preserves
MobileAutomationService,AutomationRunHandle, callback types, run/record controls, and current window composition. -
Step 1: Add source boundary assertions
First append biz/mobileuiauto/MobileUiAutomationWindow.java to limitedUiSources(), then add:
assertTrue(source.contains("MobileAutomationService"));
assertTrue(source.contains("AutomationRunHandle"));
assertFalse(source.contains("class RecordingStateMachine"));
assertFalse(source.contains("class RunStateMachine"));
- Step 2: Replace only theme consumers
Use token fonts, shared controls, Feather icons, and CSS classes. Preserve current button event handlers and every service/callback interaction. If a control has ad-hoc spinner code, bind its existing operation state through LoadingButtonBinder only when an AsyncOperationController already exists; otherwise style the existing state without creating a new state machine in P3.
- Step 3: Run compile and architecture tests
Run: .\mvnw.cmd -q -Dtest=UnifiedUiArchitectureTest test
Run: .\mvnw.cmd -q -DskipTests compile
Expected: both pass; no new run/record state types appear.
- Step 4: Capture read-only states
Capture the idle screen only. Do not connect devices, start recordings, run scripts, or alter execution history.
- Step 5: Commit
git add src/main/java/com/example/workutils/biz/mobileuiauto/MobileUiAutomationWindow.java src/test/java/com/example/workutils/system/ui/UnifiedUiArchitectureTest.java src/main/resources/css/light-theme.css
git commit -m "适配手机 UI 自动化统一主题"
Task 4: Theme-adapt settings and plugin management
Files:
- Modify:
src/main/java/com/example/workutils/system/config/SettingsWindow.java - Modify:
src/main/java/com/example/workutils/system/plugin/PluginManagementWindow.java - Modify:
src/test/java/com/example/workutils/system/ui/SharedPaneAccessibilityTest.java - Modify:
src/test/java/com/example/workutils/system/plugin/DefaultPluginConfigurationTest.java - Modify:
src/test/java/com/example/workutils/system/ui/UnifiedUiArchitectureTest.java
Interfaces:
-
Preserves all settings tabs, save/reload behavior, config files, data-source management, plugin enable/order behavior, and drag/drop semantics.
-
Step 1: Add failing unique-entry and accessibility assertions
First append system/config/SettingsWindow.java and system/plugin/PluginManagementWindow.java to limitedUiSources(), then add:
String app = Files.readString(Path.of(
"src/main/java/com/example/workutils/WorkUtilsApplication.java"));
String management = Files.readString(Path.of(
"src/main/java/com/example/workutils/system/plugin/PluginManagementWindow.java"));
assertFalse(app.contains("AppIcon.SETTINGS, \"系统设置\","));
assertTrue(management.contains("setAccessibleText(\"拖动调整插件顺序\")"));
- Step 2: Run focused tests and verify failure
Run: .\mvnw.cmd -q -Dtest=DefaultPluginConfigurationTest,SharedPaneAccessibilityTest,UnifiedUiArchitectureTest test
Expected: FAIL on remaining Unicode grip/icon or missing accessible labels.
- Step 3: Apply theme classes without changing information architecture
Replace fonts/icons/inline styles; keep all current tabs and field grouping. Replace the ≡ drag label with Feather MENU, preserving drag handlers and user data. Do not move settings sections or change persistence.
- Step 4: Run focused tests and capture
Run: .\mvnw.cmd -q -Dtest=DefaultPluginConfigurationTest,SharedPaneAccessibilityTest,UnifiedUiArchitectureTest test
Expected: PASS. Open settings from the top-right entry and inspect tabs without saving or reordering anything.
- Step 5: Commit
git add src/main/java/com/example/workutils/system/config/SettingsWindow.java src/main/java/com/example/workutils/system/plugin/PluginManagementWindow.java src/test/java/com/example/workutils/system/ui/SharedPaneAccessibilityTest.java src/test/java/com/example/workutils/system/plugin/DefaultPluginConfigurationTest.java src/test/java/com/example/workutils/system/ui/UnifiedUiArchitectureTest.java src/main/resources/css/light-theme.css
git commit -m "适配设置与插件管理统一主题"
Task 5: Replace remaining descriptor Emoji with semantic icons
Files:
- Modify:
src/main/java/com/example/workutils/system/plugin/PluginDescriptor.java - Modify: plugin classes matching
src/main/java/com/example/workutils/biz/*/*Plugin.java - Modify:
src/main/java/com/example/workutils/WorkUtilsApplication.java - Modify:
src/test/java/com/example/workutils/system/plugin/DefaultPluginConfigurationTest.java - Modify:
src/test/java/com/example/workutils/system/ui/UnifiedUiArchitectureTest.java
Interfaces:
-
Changes
PluginDescriptor.iconfromStringtoAppIcon. -
Changes
getIcon(): StringtogetIcon(): AppIconand all factory/embedding call sites accordingly. -
Step 1: Add a failing descriptor type assertion
Expand limitedUiSources() to all JavaFX application UI and plugin descriptor/factory sources using Files.walk, while explicitly excluding biz/apidoc/generator/ApiDocGenerator.java because it renders document content rather than application chrome. Then add:
@Test
void descriptorCarriesSemanticIconType() {
PluginDescriptor descriptor = PluginDescriptor.builder()
.id("scan")
.name("扫描功能")
.icon(AppIcon.SCANNER)
.build();
AppIcon icon = descriptor.getIcon();
assertEquals(AppIcon.SCANNER, icon);
}
Add a compile-time expectation in call sites by assigning AppIcon icon = descriptor.getIcon().
- Step 2: Run and verify failure
Run: .\mvnw.cmd -q -Dtest=DefaultPluginConfigurationTest,UnifiedUiArchitectureTest test
Expected: FAIL/compile failure while descriptors still return strings.
- Step 3: Migrate the descriptor type atomically
Update constructor, getter, all plugin declarations, MainWindow.NavItem, plugin management rows, and embed calls in one changeset. Use the semantic mappings defined in P0; do not expose Feather enum types outside system.ui.icon.
- Step 4: Run full tests
Run: .\mvnw.cmd -q test
Expected: PASS with zero failures/errors.
- Step 5: Commit
git add src/main/java/com/example/workutils/system/plugin src/main/java/com/example/workutils/biz src/main/java/com/example/workutils/WorkUtilsApplication.java src/test/java/com/example/workutils/system/plugin src/test/java/com/example/workutils/system/ui/UnifiedUiArchitectureTest.java
git commit -m "完成插件语义图标迁移"
Task 6: Full visual, accessibility, and regression acceptance
Files:
- Modify only when acceptance finds a concrete defect in a previously touched P0–P3 file.
- Update tests first for every discovered defect.
Interfaces:
-
Produces no new product API; this task validates the approved design and guards.
-
Step 1: Run all automated gates fresh
Run: .\mvnw.cmd -q test
Run: .\mvnw.cmd -q -DskipTests compile
Run: git diff --check
Expected: all exit 0, zero test failures/errors.
- Step 2: Run repository scans
Run: rg -n 'Microsoft YaHei|setBtnLoading\(|new ProgressIndicator\(|⚙️|🛠|▶' src/main/java/com/example/workutils
Expected: no application-chrome matches. Document-content matches are allowed only where UnifiedUiArchitectureTest explicitly excludes them.
- Step 3: Capture the full read-only screenshot matrix
Capture welcome plus every enabled plugin at 1440px expanded, 1440px collapsed, and 1024px expanded. For API export also capture a controlled loading state. Use non-sensitive fixture/sample data and do not trigger external/file-changing operations.
- Step 4: Compare against the approved visual baseline
Place the approved reference and each implementation screenshot side by side at matching viewport/state. Check header 48px, rail 214/56px, unique settings location, type scale, icon baseline, 8px spacing rhythm, control height, row height, border/radius, focus visibility, loading stability, and clipping.
- Step 5: Keyboard/accessibility smoke test
Tab through header settings, navigation, primary form controls, action buttons, cancel controls where real, tabs, history actions, and collapsed-rail tooltips. Confirm accessible text changes with operation state and focus never disappears.
- Step 6: Fix defects through red-green cycles
For each defect: add one failing focused test, run it to confirm failure, make the smallest P0–P3 file change, rerun the focused test, then rerun the full gate. Do not bundle unrelated visual polish.
- Step 7: Commit final verified fixes
git add src/main src/test
git commit -m "完成统一 UI 视觉验收"
If acceptance requires no code changes, do not create an empty commit.
P3 Completion Gate
Completion requires fresh evidence from full tests, compile, git diff --check, repository scans, the complete screenshot matrix, side-by-side reference comparisons, and keyboard/accessibility smoke checks. Do not claim the unified UI complete from automated tests alone.