بنقرة واحدة
ui-builder
Builds React screen components from Paper design references with navigation wiring and CSS styling
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
Builds React screen components from Paper design references with navigation wiring and CSS styling
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
استنادا إلى تصنيف SOC المهني
Wires bifrost-rs WASM runtime behavior into the web-demo-v2 app — operations dispatch, policy writes, event log subscription, runtime telemetry. Handles features under the M1 / M2 / M3 / M4 milestones and any other feature whose core work is "JS talking to WASM runtime."
Builds or modifies React screens/panels/modals to Paper parity, wires settings persistence, handles IndexedDB writes, and implements UI affordances (QR scan, camera, Copy/Download). Handles features under M5 / M6 settings + backup + QR + nsec-split flows.
Implements multi-step runtime-side protocol flows that span browser JS, relay publish/subscribe, and WASM runtime state — specifically source-side onboarding sponsorship. Handles M7 features where a logged-in device drives a ceremony over a real relay.
| name | ui-builder |
| description | Builds React screen components from Paper design references with navigation wiring and CSS styling |
NOTE: Startup and cleanup are handled by worker-base. This skill defines the WORK PROCEDURE.
Use for any feature that involves creating new screen components, modifying existing screens, adding routes, creating UI components, or wiring navigation. This covers all features in the Igloo Web Demo V2 UI mission.
All fidelity assertions in this mission are validated against the DemoGallery at http://127.0.0.1:5173/demo/{scenario-id} — NOT the main app. Every screen you build or modify must be reachable through a scenario entry in web-demo-v2/src/demo/scenarios.ts. If a feature asks you to adapt screens that don't yet have scenarios (e.g. the rotate-keyset adaptation scenarios), you must also add those entries to scenarios.ts so validators can navigate to them.
Expected copy in the validation contract is quoted directly from igloo-paper/screens/{flow}/{screen}/screen.html. Match that copy character-for-character for headings, labels, CTAs, help text, and error messages. Structural fidelity (sections, order, visual hierarchy) is required; pixel-perfect fidelity is not.
Provider boundary warning (demo → real-app navigation). DemoGallery scenarios mount under MockAppStateProvider, but real-app routes (/dashboard/{id}, /create, /rotate-keyset, etc.) mount under the real AppStateProvider. Click-throughs that cross this boundary drop the mock state unless the app-state bridge is used to hand off state between providers (see .factory/library/app-state-bridge.md). If a feature wires a CTA from /demo/* into a real-app route, verify the destination renders the expected unlocked/runtime state — NOT a redirect back to /. A "click goes to the right URL" check is NOT sufficient; the destination must be functional.
Non-UI feature scope. Some mission features are architecture/state/provider work (e.g. app-state bridge, route plumbing) rather than screen rendering. These are valid ui-builder features. When working on one, place tests under src/app/__tests__/ or next to the module being changed, and focus on provider/hook/helper unit tests rather than Paper-copy assertions.
Contract-vs-feature-description conflicts (IMPORTANT). The validation contract (/Users/plebdev/.factory/missions/{missionId}/validation-contract.md) is ALWAYS the single source of truth for what to build. Feature descriptions in features.json are guidance that may have speculative or outdated copy. When you notice a conflict between the feature description and the contract, DO NOT silently narrow or expand scope. Instead:
discoveredIssues with the exact phrases that disagree.whatWasImplemented so the orchestrator can update the description.This keeps you aligned with validators while flagging the planning-artifact drift for the orchestrator to address.
agent-browser — Used for manual visual verification of built screens. Invoke after implementation to navigate the app and confirm screens render correctly and navigation works.When agent-browser is optional: For pure non-UI features (provider/state/architecture refactors, bridge plumbing, type-only changes, demo-fixture shape changes) where no user-visible rendering is being added or modified, agent-browser verification can be skipped. In those cases, verify via vitest regression tests + tsc instead, and note explicitly in the handoff that agent-browser was skipped and why.
Read the feature description, preconditions, expectedBehavior, and verificationSteps carefully. Identify:
For each screen you're building, read from the igloo-paper repo:
igloo-paper/screens/{flow}/{screen}/README.md — describes the screen purpose, elements, and contextigloo-paper/screens/{flow}/{screen}/screen.html — the HTML reference for layout and contentigloo-paper/screens/{flow}/{screen}/screenshot.png — visual referenceAlso consult:
igloo-paper/design-system/ for component patternsigloo-paper/screens/_shared/ for header/footer referenceUse the Paper HTML as guidance for layout and content, not a pixel-perfect template. Match the general structure, text content, and visual hierarchy.
For each new screen component, write a vitest test BEFORE implementing:
// src/screens/__tests__/NewScreen.test.tsx
import { render, screen } from "@testing-library/react";
import { MemoryRouter } from "react-router-dom";
import { NewScreen } from "../NewScreen";
describe("NewScreen", () => {
it("renders heading and key elements", () => {
render(
<MemoryRouter>
<NewScreen />
</MemoryRouter>
);
expect(screen.getByText("Expected Heading")).toBeInTheDocument();
// Test key interactive elements exist
});
});
Run npx vitest run --config vitest.config.ts to verify tests FAIL before implementation.
TDD ordering note. Strict tests-first is preferred when feasible. Iterative workflows (sketching component structure, then writing tests, then refining) are acceptable for exploratory work. What is NOT acceptable: shipping an implementation without tests that pin the behavioral assertions the feature claims in fulfills. Every VAL-* ID in the feature's fulfills array should have at least one dedicated test case (unit or integration) in the final commit.
Create new screen files in src/screens/. Follow existing patterns:
AppShell component for layout (imported from ../components/shell)../components/ui (Button, TextField, PasswordField, etc.)src/styles/global.cssFor new CSS classes:
src/styles/global.css.import-form, .error-panel)src/styles/paper-tokens.css for colors and typographyRegister new routes in src/app/CoreRoutes.tsx:
<Route path="/..." element={<NewScreen />} /> inside the existing <Routes> blockRegister new demo scenarios in src/demo/scenarios.ts for EVERY new screen or screen variant:
DemoScenario entry with id, flow, pathname, title, paperRef, expectedText, and optional appState preset.canonical: false for variants that should not appear in the gallery index (e.g. error sub-states)./demo/{id} to test the screen; without a scenario entry, validation cannot proceed.onClick={() => navigate("/new-route")} or <Link to="/new-route"> as appropriateBackLink components that navigate to the correct parent screennpx vitest run --config vitest.config.ts
npx tsc -b
Fix any failures before proceeding.
Invoke agent-browser skill to:
cd /Users/plebdev/Desktop/igloo-web-v2-prototype/web-demo-v2 && npx vite --host 127.0.0.1 --port 5173Record each check in the handoff's interactiveChecks array.
After verification, stop the dev server:
lsof -ti :5173 | xargs kill 2>/dev/null
{
"salientSummary": "Built the Import flow (4 screens: Load Backup, Decrypt Backup, Review & Save, Error). Added /import/* routes, enabled the Welcome Import button, wired all navigation. Ran vitest (4 new tests passing) and verified all 4 screens render correctly via agent-browser.",
"whatWasImplemented": "Created ImportLoadBackupScreen, ImportDecryptScreen, ImportReviewSaveScreen, ImportErrorScreen components. Added routes /import, /import/decrypt, /import/review, /import/error to App.tsx. Added CSS classes .import-form, .import-error-panel, .review-card to global.css. Enabled 'Import Device Profile' button on WelcomeScreen. Wired BackLink navigation on all Import screens.",
"whatWasLeftUndone": "",
"verification": {
"commandsRun": [
{ "command": "npx vitest run --config vitest.config.ts", "exitCode": 0, "observation": "6 tests passing (2 existing + 4 new Import screen tests)" },
{ "command": "npx tsc -b", "exitCode": 0, "observation": "No type errors" }
],
"interactiveChecks": [
{ "action": "Navigate to / and click 'Import Device Profile'", "observed": "Navigated to /import. Load Backup screen renders with heading, backup input, upload button, and continue button." },
{ "action": "Type 'bfprofile1test' in backup input and click Continue", "observed": "Navigated to /import/decrypt. Decrypt Backup screen renders with loaded backup display, password input, and decrypt button." },
{ "action": "Click Back on Decrypt screen", "observed": "Returned to /import. Load Backup screen renders with previous input preserved." },
{ "action": "Navigate through to Review & Save, then Error screen", "observed": "All 4 screens render correctly. Error screen shows amber warning styling with retry button." },
{ "action": "Check console for errors across all Import screens", "observed": "No console errors on any Import screen." }
]
},
"tests": {
"added": [
{
"file": "src/screens/__tests__/ImportScreens.test.tsx",
"cases": [
{ "name": "LoadBackupScreen renders heading and input", "verifies": "VAL-IMP-001" },
{ "name": "DecryptBackupScreen renders password input", "verifies": "VAL-IMP-002" },
{ "name": "ReviewSaveScreen renders profile cards", "verifies": "VAL-IMP-003" },
{ "name": "ImportErrorScreen renders error styling", "verifies": "VAL-IMP-004" }
]
}
]
},
"discoveredIssues": []
}