with one click
frontend
// Frontend standards for atopile extension webviews: architecture, contracts, design system, and testing workflow.
// Frontend standards for atopile extension webviews: architecture, contracts, design system, and testing workflow.
Core runtime behavior for the atopile sidebar agent: identity, persistence model, execution rules, and tool recipes.
Generate short live progress summaries for the atopile agent from recent tool events, preambles, checklist changes, and build state. Use for ephemeral UI activity text only, never for transcript replies or autonomous reasoning.
Authoritative ato authoring and review skill: language reference, stdlib, design patterns, and end-to-end board design workflow.
Spec-driven planning for complex design tasks: when to plan, how to write specs as .ato files, and how to verify against requirements.
Reference for the `.ato` declarative DSL: type system, connection semantics, constraint model, and standard library. Use when authoring or reviewing `.ato` code.
How the Faebryk component library is structured, how `_F.py` is generated, and the conventions/invariants for adding new library modules. Use when adding or modifying library components, traits, or module definitions.
| name | frontend |
| description | Frontend standards for atopile extension webviews: architecture, contracts, design system, and testing workflow. |
Use this skill when building or modifying frontend features in atopile.
Default target is extension webviews (ui-server + vscode-atopile).
Dependency install:
cd src/ui-server
bun install
Frontend-only loop (no backend integration):
cd src/ui-server
bun run dev
bun run test
bun run build
Webview integration loop (backend + Vite):
cd src/ui-server
./dev.sh
Extension package/install loop:
ato dev compile && ato dev install cursor
# or
ato dev compile && ato dev install vscode
Command reference:
bun install: install/sync JS dependencies.bun run dev: start local Vite dev server (frontend-only iteration).bun run test: run local Vitest suite once.bun run build: run local tsc && vite build../dev.sh: run backend + Vite for integration testing in browser.ato dev compile: build extension artifacts (default target all).ato dev install cursor|vscode: install latest built extension .vsix.ato dev ui: open a webpage for the user showing the shared component library components.src/ui-server/src/src/ui-server/src/api/src/ui-server/src/store/src/ui-server/src/hooks/src/ui-server/src/components/src/ui-server/src/components/shared/src/ui-server/src/utils/src/ui-server/src/styles/src/ui-server/src/types/src/ui-server/src/__tests__/src/vscode-atopile/src/src/atopile/visualizer/web/src/src/atopile/layout_server/frontend/src/src/ui-server and loaded by src/vscode-atopile.ato dev compile and ato dev install are the common extension developer loop.src/atopile/visualizer/web is a separate app and reference pattern, not default target.Use these patterns to keep changes scoped and predictable.
components/, styles/, small hooks/ usageapi/ mapping + store state transitions + UIDefault architecture:
Layer boundaries:
api/: HTTP + WS transport and payload mappingstore/: typed app state, actions, selectorscomponents/: rendering/compositionutils/lib: pure transforms/logicSchema-first contract workflow:
Do not:
Implement one canonical user flow per feature.
Do not introduce fallback flow branches. If dependency/state is unavailable, surface a clear stop-state error in the same flow context.
Use WebSocket for:
Use HTTP for:
Required WS client behavior:
Recommended WS client behavior:
api/ moduleExample envelope shape:
type WsMessage =
| { type: "state"; data: AppState }
| { type: "event"; event: EventType; data: EventPayload }
| {
type: "action_result";
action: string;
requestId?: string;
result: { success: boolean; error?: string };
};
Before creating new primitives:
src/ui-server/src/components/shared/.src/ui-server/src/utils/ for existing logic.src/atopile/visualizer/web/src/lib/ and src/atopile/visualizer/web/src/workers/.src/vscode-atopile/src/.Promote to shared when:
Prefer reusing the components in src/ui-server/src/components/shared/ before creating equivalents.
If a new component is needed, create it in src/ui-server/src/components/shared/ and reuse it in the feature.
If possible, compose complex components from existing shared components.
Prefer extending these utilities:
src/ui-server/src/utils/codeHighlight.tsxsrc/ui-server/src/utils/nameValidation.tssrc/ui-server/src/utils/packageUtils.tssrc/ui-server/src/utils/searchUtils.tsUseful standalone reference:
src/atopile/visualizer/web/src/lib/exportUtils.tsExample typed API boundary:
export async function fetchBuilds(
projectRoot: string,
): Promise<BuildSummary[]> {
const res = await fetch(
`/api/builds?project_root=${encodeURIComponent(projectRoot)}`,
);
if (!res.ok) throw new APIError(res.status, "Failed to fetch builds");
const data = (await res.json()) as { builds: BuildSummary[] };
return data.builds;
}
Apply across all surfaces:
default/hover/focus-visible/active/disabled/loading)Example tokenized control:
.btn-default {
background: var(--accent);
color: var(--text-on-accent);
border: 1px solid var(--accent);
border-radius: var(--radius-md);
padding: 0 var(--spacing-md);
}
.btn-default:hover:not(:disabled) {
background: var(--accent-hover);
border-color: var(--accent-hover);
}
.btn-default:focus-visible {
outline: 2px solid var(--info);
outline-offset: 1px;
}
.btn:disabled {
opacity: 0.5;
cursor: not-allowed;
}
Required:
Required:
requestAnimationFrame for drag/resize animation pathsOperational checks:
ui-server)src/ui-server/src/api/store/components/components/shared/ primitives where possibleutils/ or specialized lib/ module.Use one canonical flow:
Required:
At minimum test:
Recommended:
Minimum per feature:
Example matrix (build queue):
Agents should self-test in browser flow first:
cd src/ui-server
./dev.sh
Then:
Relevant pages:
http://127.0.0.1:5173/http://127.0.0.1:5173/log-viewer.htmlhttp://127.0.0.1:5173/migrate.htmlhttp://127.0.0.1:5173/test-explorer.htmlUse these built-in dev endpoints:
curl -sS -X POST http://127.0.0.1:5173/api/screenshot \
-H 'Content-Type: application/json' \
-d '{"path":"/","name":"default","waitMs":1200}'
curl -sS -X POST http://127.0.0.1:5173/api/screenshot \
-H 'Content-Type: application/json' \
-d '{"path":"/","name":"projects-expanded","uiActions":[{"type":"openSection","sectionId":"projects"}],"uiActionWaitMs":600}'
curl -sS http://127.0.0.1:5173/api/ui-logs
Automation guardrails:
data-testid or semantic roles)A feature is done only when all are true:
- [ ] Single canonical flow preserved (no fallback path added)
- [ ] Pydantic models updated for API/WS changes
- [ ] Generated TS schema/types regenerated and committed
- [ ] WS reconnect/resync behavior verified
- [ ] Browser dev viewer flow validated (`./dev.sh`)
- [ ] Screenshots + UI logs reviewed (no unapproved runtime errors)
- [ ] Added/updated: store test, transport test, UI interaction test
- [ ] Asked user to test in extension host only after browser checks passed