Frontend standards for atopile extension webviews: architecture, contracts, design system, and testing workflow.
cd ~/.claude/skills
git clone https://github.com/atopile/atopile.git atopile mkdir -p ~/.claude/skills/frontend
curl -fsSL https://raw.githubusercontent.com/atopile/atopile/HEAD/.claude/skills/frontend/SKILL.md \
-o ~/.claude/skills/frontend/SKILL.md 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 Creating algorithmic art using p5.js with seeded randomness and interactive parameter exploration. Use this when users request creating art using code, generative art, algorithmic art, flow fields, or particle systems. Create original algorithmic art rather than copying existing artists' work to avoid copyright violations.
Applies Anthropic's official brand colors and typography to any sort of artifact that may benefit from having Anthropic's look-and-feel. Use it when brand colors or style guidelines, visual formatting, or company design standards apply.
Build, debug, and optimize Claude API / Anthropic SDK apps. Apps built with this skill should include prompt caching. Also handles migrating existing Claude API code between Claude model versions (4.5 → 4.6, 4.6 → 4.7, retired-model replacements). TRIGGER when: code imports `anthropic`/`@anthropic-ai/sdk`; user asks for the Claude API, Anthropic SDK, or Managed Agents; user adds/modifies/tunes a C
Create distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, artifacts, posters, or applications (examples include websites, landing pages, dashboards, React components, HTML/CSS layouts, or when styling/beautifying any web UI). Generates creative, polished code and UI design that avoids generic AI aesthetics.
Guide for creating high-quality MCP (Model Context Protocol) servers that enable LLMs to interact with external services through well-designed tools. Use when building MCP servers to integrate external APIs or services, whether in Python (FastMCP) or Node/TypeScript (MCP SDK).
Knowledge and utilities for creating animated GIFs optimized for Slack. Provides constraints, validation tools, and animation concepts. Use when users request animated GIFs for Slack like "make me a GIF of X doing Y for Slack.