Promotes legacy views to modern UI.Widget classes, hooks up performUpdate() rendering, and exports default views.
61
72%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
Fix and improve this skill with Tessl
tessl review fix ./.agents/skills/ui-eng-vision-widget-promoter/SKILL.mdThis subskill completes the architectural transition, upgrading the component
from legacy base classes (like SimpleView or custom wrapper layouts) into
clean UI.Widget classes that use native update rendering delegates.
devtools-ui-widgets.Change Class Inheritance:
UI.Widget (or specialized
sub-layouts like UI.Widget.VBox)..element directly for manual append
operations.VBox and HBox inherit directly from Widget. They fully support view injection (view = DEFAULT_VIEW), performUpdate(), and requestUpdate() without modification.Upgrade View Delegates & Inject View:
Migrate the local Lit template strings into a formally exported default view layout:
export const DEFAULT_VIEW: View = (input, output, target) => {
Lit.render(html`...`, target);
};Make the view injectable in the constructor for testability (as per docs/ui_engineering.md), and use static INJECT if requesting dependencies from Universe:
class MyWidget extends UI.Widget.VBox {
static override readonly INJECT = [SDK.TargetManager.TargetManager] as const;
#targetManager: SDK.TargetManager.TargetManager;
#view: View;
constructor(
element?: HTMLElement,
[targetManager]: UI.Widget.WidgetDependencies<typeof MyWidget> = [],
view: View = DEFAULT_VIEW,
) {
super(element);
this.#targetManager = targetManager;
this.#view = view;
}Implement the standard modern performUpdate() override on the widget:
override performUpdate(): void {
this.#view(this.viewInput, this.viewOutput, this.contentElement);
}Clean Up Legacy Wrappers:
Remove any LegacyWrapper bindings or custom wrappable custom elements.
Replace old panel instantiations with standard <devtools-widget>
declarative entries:
html`<devtools-widget .widgetConfig=${widgetConfig(MyWidgetClass, [params])}></devtools-widget>`Inspect instantiator files (e.g., ApplicationPanelSidebar.ts) and
decouple any direct accesses to .element.
Before reporting back or committing, re-read the instructions and verify:
.element or .contentElement couplings from instantiator files?UI.Widget or its variants?184a74d
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.