robodev 0.22.0 → 0.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (178) hide show
  1. package/package.json +1 -1
  2. package/src/emit-starter.test.ts +36 -0
  3. package/templates/auth-chat/package.json +1 -1
  4. package/templates/backend/api/_lib.ts +9 -2
  5. package/templates/backend/package.json +1 -1
  6. package/templates/catalog.json +5 -0
  7. package/templates/empty/package.json +1 -1
  8. package/templates/marketplace/.config/local.spa.template.yml +27 -0
  9. package/templates/marketplace/.oxlint-base.json +29 -0
  10. package/templates/marketplace/.oxlintrc.json +78 -0
  11. package/templates/marketplace/.rulesync/rules/frontend-api-boundary.md +36 -0
  12. package/templates/marketplace/.rulesync/rules/frontend-component-structure.md +38 -0
  13. package/templates/marketplace/.rulesync/rules/frontend-forms.md +32 -0
  14. package/templates/marketplace/.rulesync/rules/frontend-notifications.md +24 -0
  15. package/templates/marketplace/.rulesync/rules/frontend-povio-components.md +42 -0
  16. package/templates/marketplace/.rulesync/rules/frontend-povio-ui.md +45 -0
  17. package/templates/marketplace/.rulesync/rules/frontend-query-autocomplete.md +29 -0
  18. package/templates/marketplace/.rulesync/rules/frontend-tables-and-lists.md +34 -0
  19. package/templates/marketplace/.rulesync/rules/frontend-translations.md +26 -0
  20. package/templates/marketplace/.rulesync/rules/project-overview.md +32 -0
  21. package/templates/marketplace/.rulesync/rules/robodev-api.md +30 -0
  22. package/templates/marketplace/.rulesync/rules/robodev-auth.md +40 -0
  23. package/templates/marketplace/.rulesync/rules/robodev-database.md +22 -0
  24. package/templates/marketplace/.rulesync/rules/role-based-app-structure.md +36 -0
  25. package/templates/marketplace/.rulesync/skills/media-feature/SKILL.md +21 -0
  26. package/templates/marketplace/.rulesync/skills/povio-ui-styling/SKILL.md +208 -0
  27. package/templates/marketplace/.rulesync/skills/povio-ui-styling/agents/openai.yaml +4 -0
  28. package/templates/marketplace/.rulesync/skills/robodev-api-route/SKILL.md +13 -0
  29. package/templates/marketplace/.rulesync/skills/robodev-table/SKILL.md +12 -0
  30. package/templates/marketplace/README.md +40 -0
  31. package/templates/marketplace/api/_lib.ts +677 -0
  32. package/templates/marketplace/api/cart/[id].ts +51 -0
  33. package/templates/marketplace/api/cart.ts +70 -0
  34. package/templates/marketplace/api/categories.ts +11 -0
  35. package/templates/marketplace/api/checkout.ts +157 -0
  36. package/templates/marketplace/api/health.ts +7 -0
  37. package/templates/marketplace/api/listings/[id].ts +101 -0
  38. package/templates/marketplace/api/listings/paginate.ts +29 -0
  39. package/templates/marketplace/api/listings.ts +90 -0
  40. package/templates/marketplace/api/me.ts +14 -0
  41. package/templates/marketplace/api/orders/[id]/complete.ts +27 -0
  42. package/templates/marketplace/api/orders/[id]/ship.ts +24 -0
  43. package/templates/marketplace/api/orders/[id].ts +15 -0
  44. package/templates/marketplace/api/purchases.ts +19 -0
  45. package/templates/marketplace/api/reviews.ts +58 -0
  46. package/templates/marketplace/api/sales.ts +19 -0
  47. package/templates/marketplace/api/watches/[listingId].ts +18 -0
  48. package/templates/marketplace/api/watches.ts +51 -0
  49. package/templates/marketplace/apps/fe/index.html +24 -0
  50. package/templates/marketplace/apps/fe/openapi-codegen.config.ts +72 -0
  51. package/templates/marketplace/apps/fe/package.json +84 -0
  52. package/templates/marketplace/apps/fe/public/apple-touch-icon.png +0 -0
  53. package/templates/marketplace/apps/fe/public/favicon-96x96.png +0 -0
  54. package/templates/marketplace/apps/fe/public/favicon.ico +0 -0
  55. package/templates/marketplace/apps/fe/public/favicon.svg +3 -0
  56. package/templates/marketplace/apps/fe/public/site.webmanifest +21 -0
  57. package/templates/marketplace/apps/fe/public/web-app-manifest-192x192.png +0 -0
  58. package/templates/marketplace/apps/fe/public/web-app-manifest-512x512.png +0 -0
  59. package/templates/marketplace/apps/fe/src/assets/fonts/GeneralSans-Bold.otf +0 -0
  60. package/templates/marketplace/apps/fe/src/assets/fonts/GeneralSans-Medium.otf +0 -0
  61. package/templates/marketplace/apps/fe/src/assets/fonts/GeneralSans-Regular.otf +0 -0
  62. package/templates/marketplace/apps/fe/src/assets/fonts/GeneralSans-Semibold.otf +0 -0
  63. package/templates/marketplace/apps/fe/src/assets/locales/en/translation.json +335 -0
  64. package/templates/marketplace/apps/fe/src/assets/locales/sl/translation.json +335 -0
  65. package/templates/marketplace/apps/fe/src/clients/app-rest-client.ts +15 -0
  66. package/templates/marketplace/apps/fe/src/clients/auth-token-store.ts +101 -0
  67. package/templates/marketplace/apps/fe/src/clients/rest/app-error-handler.ts +31 -0
  68. package/templates/marketplace/apps/fe/src/clients/rest/interceptors/authorization-header.interceptor.ts +15 -0
  69. package/templates/marketplace/apps/fe/src/clients/rest/interceptors/refresh-token.interceptor.ts +37 -0
  70. package/templates/marketplace/apps/fe/src/clients/rest/interceptors/response.interceptor.ts +17 -0
  71. package/templates/marketplace/apps/fe/src/components/404.tsx +18 -0
  72. package/templates/marketplace/apps/fe/src/components/features/auth/AuthBrandPanel.tsx +60 -0
  73. package/templates/marketplace/apps/fe/src/components/features/auth/AuthLayout.tsx +23 -0
  74. package/templates/marketplace/apps/fe/src/components/features/auth/LoginPage.tsx +111 -0
  75. package/templates/marketplace/apps/fe/src/components/features/auth/RegisterPage.tsx +143 -0
  76. package/templates/marketplace/apps/fe/src/components/features/marketplace/BrowsePage.tsx +76 -0
  77. package/templates/marketplace/apps/fe/src/components/features/marketplace/CartPage.tsx +88 -0
  78. package/templates/marketplace/apps/fe/src/components/features/marketplace/CheckoutPage.tsx +193 -0
  79. package/templates/marketplace/apps/fe/src/components/features/marketplace/ListingCard.tsx +50 -0
  80. package/templates/marketplace/apps/fe/src/components/features/marketplace/ListingDetailsPage.tsx +152 -0
  81. package/templates/marketplace/apps/fe/src/components/features/marketplace/ListingFormPage.tsx +243 -0
  82. package/templates/marketplace/apps/fe/src/components/features/marketplace/MyListingsPage.tsx +84 -0
  83. package/templates/marketplace/apps/fe/src/components/features/marketplace/OrdersPage.tsx +224 -0
  84. package/templates/marketplace/apps/fe/src/components/features/marketplace/WatchlistPage.tsx +56 -0
  85. package/templates/marketplace/apps/fe/src/components/features/profile/ProfilePage.tsx +96 -0
  86. package/templates/marketplace/apps/fe/src/components/googleAnalytics/GoogleAnalytics.tsx +35 -0
  87. package/templates/marketplace/apps/fe/src/components/layout/AppLayout.tsx +19 -0
  88. package/templates/marketplace/apps/fe/src/components/layout/app-header/AppHeader.tsx +95 -0
  89. package/templates/marketplace/apps/fe/src/components/layout/app-header/MobileNavigation.tsx +55 -0
  90. package/templates/marketplace/apps/fe/src/components/layout/app-header/NavLink.tsx +29 -0
  91. package/templates/marketplace/apps/fe/src/components/shared/branding/BrandLogo.tsx +13 -0
  92. package/templates/marketplace/apps/fe/src/components/shared/error/ErrorFallback.tsx +43 -0
  93. package/templates/marketplace/apps/fe/src/components/shared/error/ErrorText.tsx +20 -0
  94. package/templates/marketplace/apps/fe/src/components/shared/error/NotFound.tsx +36 -0
  95. package/templates/marketplace/apps/fe/src/components/shared/forms/RequiredLabel.tsx +21 -0
  96. package/templates/marketplace/apps/fe/src/components/shared/forms/RowInputWrapper.tsx +50 -0
  97. package/templates/marketplace/apps/fe/src/components/shared/head/AppHead.tsx +32 -0
  98. package/templates/marketplace/apps/fe/src/components/shared/head/DefaultAppHead.tsx +34 -0
  99. package/templates/marketplace/apps/fe/src/components/shared/layout/LoadingState.tsx +9 -0
  100. package/templates/marketplace/apps/fe/src/components/shared/layout/ThinPageWrapper.tsx +5 -0
  101. package/templates/marketplace/apps/fe/src/components/shared/page/PageHeader.tsx +69 -0
  102. package/templates/marketplace/apps/fe/src/components/shared/ui/Card.tsx +60 -0
  103. package/templates/marketplace/apps/fe/src/components/shared/ui/GoogleLoginButton.tsx +19 -0
  104. package/templates/marketplace/apps/fe/src/components/shared/ui/RequiredLabel.tsx +22 -0
  105. package/templates/marketplace/apps/fe/src/components/shared/ui/TableActions.tsx +22 -0
  106. package/templates/marketplace/apps/fe/src/config/app.config.ts +35 -0
  107. package/templates/marketplace/apps/fe/src/config/i18n.ts +43 -0
  108. package/templates/marketplace/apps/fe/src/config/inits/a11y.ts +14 -0
  109. package/templates/marketplace/apps/fe/src/config/inits/logger.ts +7 -0
  110. package/templates/marketplace/apps/fe/src/config/inits/sentry.ts +21 -0
  111. package/templates/marketplace/apps/fe/src/config/jwt.config.ts +2 -0
  112. package/templates/marketplace/apps/fe/src/config/query.config.ts +20 -0
  113. package/templates/marketplace/apps/fe/src/hooks/useAuth.ts +5 -0
  114. package/templates/marketplace/apps/fe/src/main.tsx +52 -0
  115. package/templates/marketplace/apps/fe/src/pages/(guest)/login.tsx +23 -0
  116. package/templates/marketplace/apps/fe/src/pages/(guest)/register.tsx +23 -0
  117. package/templates/marketplace/apps/fe/src/pages/(guest)/route.tsx +18 -0
  118. package/templates/marketplace/apps/fe/src/pages/(private)/cart.tsx +22 -0
  119. package/templates/marketplace/apps/fe/src/pages/(private)/checkout.tsx +22 -0
  120. package/templates/marketplace/apps/fe/src/pages/(private)/index.tsx +22 -0
  121. package/templates/marketplace/apps/fe/src/pages/(private)/listings/$id/index.tsx +37 -0
  122. package/templates/marketplace/apps/fe/src/pages/(private)/my-listings.tsx +22 -0
  123. package/templates/marketplace/apps/fe/src/pages/(private)/orders/$id.tsx +40 -0
  124. package/templates/marketplace/apps/fe/src/pages/(private)/orders/index.tsx +22 -0
  125. package/templates/marketplace/apps/fe/src/pages/(private)/profile.tsx +23 -0
  126. package/templates/marketplace/apps/fe/src/pages/(private)/route.tsx +18 -0
  127. package/templates/marketplace/apps/fe/src/pages/(private)/sales.tsx +22 -0
  128. package/templates/marketplace/apps/fe/src/pages/(private)/sell/$id.tsx +44 -0
  129. package/templates/marketplace/apps/fe/src/pages/(private)/sell/index.tsx +19 -0
  130. package/templates/marketplace/apps/fe/src/pages/(private)/watchlist.tsx +22 -0
  131. package/templates/marketplace/apps/fe/src/pages/(public)/auth.tsx +37 -0
  132. package/templates/marketplace/apps/fe/src/pages/(public)/route.tsx +9 -0
  133. package/templates/marketplace/apps/fe/src/pages/__root.tsx +164 -0
  134. package/templates/marketplace/apps/fe/src/providers/AppErrorBoundary.tsx +10 -0
  135. package/templates/marketplace/apps/fe/src/providers/OpenApiRuntimeProvider.tsx +31 -0
  136. package/templates/marketplace/apps/fe/src/providers/index.tsx +44 -0
  137. package/templates/marketplace/apps/fe/src/providers/jwt.provider.tsx +95 -0
  138. package/templates/marketplace/apps/fe/src/routeTree.gen.ts +435 -0
  139. package/templates/marketplace/apps/fe/src/styles/base.css +103 -0
  140. package/templates/marketplace/apps/fe/src/styles/fonts/fonts.tsx +10 -0
  141. package/templates/marketplace/apps/fe/src/styles/fonts/general-sans.css +31 -0
  142. package/templates/marketplace/apps/fe/src/styles/globals.css +28 -0
  143. package/templates/marketplace/apps/fe/src/styles/overrides/defaults/button.override.ts +536 -0
  144. package/templates/marketplace/apps/fe/src/styles/overrides/defaults/checkbox.override.ts +71 -0
  145. package/templates/marketplace/apps/fe/src/styles/overrides/defaults/input.override.ts +252 -0
  146. package/templates/marketplace/apps/fe/src/styles/overrides/defaults/label.override.ts +91 -0
  147. package/templates/marketplace/apps/fe/src/styles/overrides/defaults/modal.override.ts +57 -0
  148. package/templates/marketplace/apps/fe/src/styles/overrides/defaults/radio.override.ts +46 -0
  149. package/templates/marketplace/apps/fe/src/styles/overrides/defaults/table.override.ts +104 -0
  150. package/templates/marketplace/apps/fe/src/styles/overrides/defaults/tag.override.ts +66 -0
  151. package/templates/marketplace/apps/fe/src/styles/overrides/defaults/typography.override.ts +115 -0
  152. package/templates/marketplace/apps/fe/src/styles/overrides/outline.clsx.ts +10 -0
  153. package/templates/marketplace/apps/fe/src/styles/overrides/uiOverrides.override.ts +60 -0
  154. package/templates/marketplace/apps/fe/src/styles/theme.css +2177 -0
  155. package/templates/marketplace/apps/fe/src/types/i18next.d.ts +12 -0
  156. package/templates/marketplace/apps/fe/src/types/table.d.ts +17 -0
  157. package/templates/marketplace/apps/fe/src/types/ui.d.ts +26 -0
  158. package/templates/marketplace/apps/fe/src/types/vite-env.d.ts +20 -0
  159. package/templates/marketplace/apps/fe/src/utils/date.utils.ts +17 -0
  160. package/templates/marketplace/apps/fe/src/utils/image-fallback.ts +9 -0
  161. package/templates/marketplace/apps/fe/src/utils/listing-form.test.ts +69 -0
  162. package/templates/marketplace/apps/fe/src/utils/listing-form.ts +77 -0
  163. package/templates/marketplace/apps/fe/src/utils/listing-submit.ts +29 -0
  164. package/templates/marketplace/apps/fe/src/utils/number.utils.ts +12 -0
  165. package/templates/marketplace/apps/fe/src/utils/string.utils.ts +5 -0
  166. package/templates/marketplace/apps/fe/src/vite-env.d.ts +1 -0
  167. package/templates/marketplace/apps/fe/tsconfig.app.json +32 -0
  168. package/templates/marketplace/apps/fe/tsconfig.json +9 -0
  169. package/templates/marketplace/apps/fe/tsconfig.node.json +31 -0
  170. package/templates/marketplace/apps/fe/vite.config.ts +125 -0
  171. package/templates/marketplace/database.ts +154 -0
  172. package/templates/marketplace/openapi.json +2303 -0
  173. package/templates/marketplace/oxfmt.config.js +23 -0
  174. package/templates/marketplace/package.json +18 -0
  175. package/templates/marketplace/rulesync.jsonc +18 -0
  176. package/templates/marketplace/tsconfig.json +11 -0
  177. package/templates/space/api/_lib.ts +9 -2
  178. package/templates/space/package.json +1 -1
@@ -0,0 +1,40 @@
1
+ ---
2
+ root: false
3
+ targets: ["claudecode", "codexcli", "cursor"]
4
+ description: "Reserved Robodev /api/user auth contracts."
5
+ globs: ["**/*.ts", "apps/fe/src/**/*.{ts,tsx}"]
6
+ cursor:
7
+ alwaysApply: false
8
+ description: "Apply when touching auth, login, register, or /api/user clients."
9
+ globs:
10
+ [
11
+ "database.ts",
12
+ "api/**/*.ts",
13
+ "apps/fe/src/components/features/auth/**/*.{ts,tsx}",
14
+ "apps/fe/src/clients/**/*.ts",
15
+ ]
16
+ ---
17
+
18
+ # Robodev Auth
19
+
20
+ End-user auth is reserved on the project host. Do not implement `api/user/**` in this project.
21
+
22
+ ## Contracts
23
+
24
+ | Method | Path | Notes |
25
+ | ------- | ----------------------------------------- | ------------------------------------------------------- |
26
+ | POST | `/api/user/auth/login` | `{ email, password }` → `{ accessToken, refreshToken }` |
27
+ | POST | `/api/user/auth/register` | password min 12, 201, token pair |
28
+ | POST | `/api/user/auth/refresh` | `{ refreshToken }` → new pair |
29
+ | GET | `/api/user/auth/magic-link` | query `email`, generic status |
30
+ | GET | `/api/user/auth/magic-link/callback` | query `code` → tokens |
31
+ | POST | `/api/user/auth/forgot-password` | `{ email }` |
32
+ | POST | `/api/user/auth/forgot-password/callback` | `{ code, password }` |
33
+ | GET | `/api/user/auth/google` | start OAuth; `redirect_uri` required |
34
+ | GET/PUT | `/api/user/me` | flat `{ id, name, email }` |
35
+
36
+ Access tokens last 15 minutes. Refresh tokens last 30 days. Frontend stores both and refreshes on 401 via `UserAuthApi.accessToken`.
37
+
38
+ Error `code` is top-level: `invalid-credentials`, `identity-already-exists`, `identity-not-found`, `nonce-invalid`.
39
+
40
+ Codegen operationIds stay Tiny-shaped (`UserAuthLocalPasswordController_login`, `UserMeController_get`, …) in `openapi.json`.
@@ -0,0 +1,22 @@
1
+ ---
2
+ root: false
3
+ targets: ["claudecode", "codexcli", "cursor"]
4
+ description: "Robodev database.ts Drizzle schema and deploy sync."
5
+ globs: ["database.ts"]
6
+ cursor:
7
+ alwaysApply: false
8
+ description: "Apply when editing the Starbase database schema."
9
+ globs: ["database.ts"]
10
+ ---
11
+
12
+ # Robodev Database
13
+
14
+ The backend schema lives in `database.ts` at the project root. Default-export `defineDatabase` with Drizzle `pgTable` definitions. `robodev deploy` from this root creates or syncs the named Postgres database. There are no migration files.
15
+
16
+ ## Rules
17
+
18
+ - Import table helpers from `@robodev-ai/sdk` (`pgTable`, `uuid`, `text`, `timestamp`, `integer`, and query helpers).
19
+ - Do not recreate User or auth tables. End users live in platform `robodev_auth`. Store `userId` as `text` matching `ctx.user.id`.
20
+ - Prefer scalar columns and foreign keys. Destructive drops need deploy confirmation or `--force`.
21
+ - Export named tables so API files can import them from `../database` or `api/_lib.ts`.
22
+ - Seed demo rows in API handlers on first read (see `api/_lib.ts` `ensureSeed`), not with a separate seed runner.
@@ -0,0 +1,36 @@
1
+ ---
2
+ root: false
3
+ targets: ["claudecode", "codexcli", "cursor"]
4
+ description: "Conditional role-based frontend and API structure for apps with distinct user roles."
5
+ globs: ["apps/fe/src/**/*.{ts,tsx}", "api/**/*.ts"]
6
+ cursor:
7
+ alwaysApply: false
8
+ description: "Apply only when an app has multiple user roles with distinct UI surfaces or business workflows."
9
+ globs: ["apps/fe/src/**/*.{ts,tsx}", "api/**/*.ts"]
10
+ ---
11
+
12
+ # Role-Based App Structure
13
+
14
+ Apply this rule only when the app has multiple user roles with meaningfully different UI surfaces or business workflows. For single-role apps or small permission differences, keep normal feature-based structure and express authorization in handlers, ACL metadata, or UI affordances.
15
+
16
+ ## Frontend Structure
17
+
18
+ Split role-specific frontend code by role first:
19
+
20
+ - `apps/fe/src/components/features/<role>/<feature>/...` for role-owned feature UI, such as `admin/companies`, `manager/projects`, or `worker/timesheets`.
21
+ - `apps/fe/src/pages/(private)/(<role>)/...` for role-owned private routes and layout guards.
22
+ - Shared auth, profile, layout, and role-neutral UI should stay outside role folders.
23
+
24
+ When two roles touch the same entity with different screens or permissions, prefer separate role-owned feature components over a single component with many role branches.
25
+
26
+ ## API Structure
27
+
28
+ Create role-prefixed `defineApi` files for role-owned behavior even when the backing table is shared. For example, use `api/manager/projects.ts` and `api/worker/projects.ts` when managers can create projects while workers can only list assigned ones.
29
+
30
+ Role-prefixed routes should keep the role visible across the API surface:
31
+
32
+ - Files: `api/<role>/<resource>.ts`, such as `api/manager/projects.ts`.
33
+ - HTTP paths: `/api/<role>/<resource>`, such as `/api/manager/projects/paginate`.
34
+ - Generated client modules should follow the same names.
35
+
36
+ Keep shared auth, user, and media contracts role-neutral. Auth stays reserved at `/api/user/*`.
@@ -0,0 +1,21 @@
1
+ ---
2
+ name: media-feature
3
+ description: "Use when adding or changing feature-level media/file upload support or frontend FileUpload handling."
4
+ targets: ["claudecode", "codexcli", "cursor"]
5
+ codexcli:
6
+ short-description: Add or update media upload support for features.
7
+ ---
8
+
9
+ # Media Feature Skill
10
+
11
+ Preserve the upload contract:
12
+
13
+ 1. Frontend selects `File` values and keeps them local until submit. Do not call `/api/files/*`.
14
+ 2. Feature create/update is one `multipart/form-data` request (`POST` / `PUT`) with text fields and one or more files (`file` / `files`). Cap is about 8 images (jpeg/png/webp, 2MB each).
15
+ 3. The handler validates text fields, calls `saveListingImage` for each file (`ctx.storage.upload` public, resource name `listing-image`), and writes `listing_images` rows.
16
+ 4. Update may append new files and/or remove existing images by media id (`removeImageIds`). New files are added after remaining images.
17
+ 5. Feature reads resolve stored media IDs to `images: { id, url }[]`.
18
+
19
+ Never use a standalone files API. File bytes stay on the device until submit.
20
+
21
+ Media metadata lives in the `media` table in `database.ts`. Bytes live in Robodev storage. Listing images use resource name `listing-image`.
@@ -0,0 +1,208 @@
1
+ ---
2
+ name: povio-ui-styling
3
+ description: Mandatory first skill for any Tiny Template web frontend UI work in apps/fe. Load and apply it before other frontend, design, UX, accessibility, responsive, animation, or performance skills when creating, changing, reviewing, debugging, polishing, or refactoring pages and React components. It requires checking and using @povio/ui primitives before raw HTML or custom controls, and governs UIConfig defaults, UIOverrides, Tailwind utilities, semantic tokens, shared UI wrappers, and dedicated CSS files.
4
+ ---
5
+
6
+ # Povio UI Styling
7
+
8
+ Apply the narrowest styling layer that expresses the intended scope. Preserve one source of truth for each visual rule.
9
+
10
+ ## Priority and Coordination
11
+
12
+ This is the foundation skill for every UI task under `apps/fe`. Apply it first, before broader design, UX, accessibility, animation, responsive, or React performance skills. Those skills may improve the result, but they must preserve the component and styling decisions defined here.
13
+
14
+ Use this skill for all work that creates, changes, reviews, or diagnoses visible or interactive frontend UI, including:
15
+
16
+ - Pages, layouts, navigation, dashboards, cards, lists, and empty states
17
+ - Forms, filters, search, inputs, validation, uploads, and settings
18
+ - Buttons, links, menus, dialogs, drawers, popovers, tooltips, and toasts
19
+ - Tables, pagination, tags, badges, typography, icons, and loading states
20
+ - Responsive behavior, theming, accessibility, motion, and visual polish
21
+ - Component extraction, shared wrappers, design-system alignment, and Figma implementation
22
+
23
+ This skill does not replace feature-specific skills. Apply the relevant feature skill as well, after establishing the Povio UI component and styling layer.
24
+
25
+ ## Inspect Before Styling
26
+
27
+ 1. Read the target component and nearby feature components.
28
+ 2. Inspect existing `@povio/ui` usage in `apps/fe` for the relevant primitive.
29
+ 3. Inspect `apps/fe/src/styles/overrides/uiOverrides.override.ts` and the matching file under `styles/overrides/defaults` before changing a Povio primitive.
30
+ 4. Inspect `apps/fe/src/styles/theme.css` for available generated tokens, but never edit that file manually.
31
+ 5. Inspect `apps/fe/src/styles/base.css` and `globals.css` before adding global rules or tokens.
32
+
33
+ ## Use This Decision Order
34
+
35
+ ### 1. Use an Existing Povio UI Component
36
+
37
+ Use `@povio/ui` whenever it provides the semantic control or presentation primitive. This includes buttons, links, typography, icons, inputs, textareas, selects, checkboxes, radios, switches, forms, uploads, tags, badges, tables, pagination, menus, tooltips, modals, confirmations, drawers, popovers, toasts, loading indicators, and empty or feedback states.
38
+
39
+ Prefer the component's supported props and variants over restyling its internals. Do not recreate a primitive with a raw HTML element merely to get a different appearance.
40
+
41
+ Before introducing a native interactive element, a custom control, or a third-party UI component, search `@povio/ui` exports and existing feature usage for an existing equivalent. Native structural elements such as `main`, `section`, `article`, `nav`, and layout containers remain appropriate when no Povio semantic component exists.
42
+
43
+ ### 2. Use `UIConfig` for Application-Wide Defaults
44
+
45
+ Use the root `UIConfig.Provider` when an existing Povio variant or option is correct and only its default should change across the application.
46
+
47
+ Examples:
48
+
49
+ - Make all inputs default to `small`.
50
+ - Set the default table-cell typography size.
51
+ - Set the default tag text size.
52
+
53
+ Do not use `UIConfig` for a one-off screen or to invent a new variant.
54
+
55
+ ### 3. Use Tailwind for Composition and Local Presentation
56
+
57
+ Use Tailwind classes in JSX for:
58
+
59
+ - Page and component layout
60
+ - Grid and flex behavior
61
+ - Width, height, spacing, alignment, and overflow
62
+ - Responsive composition
63
+ - A one-instance surface, border, or text treatment
64
+ - State selectors that remain short and readable
65
+
66
+ Use semantic project utilities such as `bg-elevation-fill-default-1`, `text-text-default-1`, and `border-elevation-outline-default-1`. Do not use removed default palette utilities such as `bg-blue-500`, and do not repeat raw hex values in components.
67
+
68
+ Keep Povio component `className` additions focused on outer layout or a genuinely local treatment. Do not pile conflicting utilities onto a component to fight its configured CVA variants. If the same correction is required on most instances, move it to `UIConfig` or `UIOverrides`.
69
+
70
+ ### 4. Use `UIOverrides` for Design-System-Level Povio Changes
71
+
72
+ Use `UIOverrides.defineOverride(...)` when a Povio primitive must change consistently throughout the application:
73
+
74
+ - Change the base classes of every instance.
75
+ - Add or change supported variants.
76
+ - Change compound-variant behavior.
77
+ - Change internal slots not exposed by ordinary component props.
78
+ - Align a primitive with the application's Figma design system.
79
+
80
+ Place overrides under `apps/fe/src/styles/overrides/defaults/<component>.override.ts` and register them in `uiOverrides.override.ts`. Use the existing `mode`, `base`, `config`, variant, and compound-variant patterns.
81
+
82
+ Update `apps/fe/src/types/ui.d.ts` when a new override variant must augment public Povio component types.
83
+
84
+ Do not use `UIOverrides` for:
85
+
86
+ - Page layout
87
+ - One feature's special card
88
+ - One exceptional component instance
89
+ - A workaround that can be expressed through an existing prop
90
+
91
+ Changing an override affects every consumer. Search all uses of the primitive and verify representative screens before finishing.
92
+
93
+ ### 5. Use a Shared Wrapper for Repeated Product Semantics
94
+
95
+ Create a component under `apps/fe/src/components/shared` when several features need the same product-specific composition but the base Povio primitive should remain unchanged.
96
+
97
+ Examples:
98
+
99
+ - `StatusTag` mapping domain statuses to Povio `Tag` variants
100
+ - `WalkSchedule` composing typography, icons, and layout
101
+ - `PageCard` applying a repeated application surface
102
+
103
+ Expose semantic props rather than forwarding a growing collection of styling flags.
104
+
105
+ ### 6. Use Dedicated CSS for Selector-Heavy or Browser-Level Behavior
106
+
107
+ Create or extend a `.css` file when CSS communicates the rule more clearly than Tailwind:
108
+
109
+ - Pseudo-elements used for connected timelines or route lines
110
+ - Multi-step keyframes
111
+ - Complex descendant, sibling, or state selectors
112
+ - Calendar grids and overlapping appointments
113
+ - Map-library markers, popups, or third-party DOM overrides
114
+ - Print styles
115
+ - Browser-global behavior such as scrollbars
116
+ - Rules driven by CSS custom properties that many descendants consume
117
+
118
+ Co-locate feature CSS with its owning component and import it there. Use a narrow, feature-prefixed class namespace, for example `walk-route__marker`. Keep truly global rules in `globals.css` or `base.css`.
119
+
120
+ Do not create a CSS file for ordinary spacing, flex/grid layout, a simple hover, or a semantic color already expressible with a short Tailwind class list.
121
+
122
+ ## Scope Guide
123
+
124
+ | Desired scope | Styling layer |
125
+ | -------------------------------------------------------------- | --------------------------- |
126
+ | Existing primitive behavior | Povio UI props/variants |
127
+ | Default for every instance | `UIConfig` |
128
+ | One page or component composition | Tailwind |
129
+ | Every instance or internal Povio slot | `UIOverrides` |
130
+ | Repeated product-specific composition | Shared wrapper |
131
+ | Pseudo-elements, keyframes, complex selectors, third-party DOM | Scoped `.css` |
132
+ | Generated design tokens | Figma-generated `theme.css` |
133
+ | Handwritten global token or browser rule | `base.css` or `globals.css` |
134
+
135
+ ## Guardrails
136
+
137
+ - Use `@povio/ui` before creating a custom primitive.
138
+ - Do not let guidance from a general frontend or design skill replace an available `@povio/ui` primitive with raw HTML, a local reimplementation, or another component library.
139
+ - Use semantic Tailwind tokens from the project theme.
140
+ - Never manually edit `apps/fe/src/styles/theme.css`.
141
+ - Avoid `!important`; resolve ownership or specificity instead.
142
+ - Avoid inline `style` except for truly runtime numeric values such as map coordinates or calculated dimensions. Prefer CSS custom properties when descendants need the value.
143
+ - Avoid Sass, CSS-in-JS, and a second styling system.
144
+ - Preserve visible focus, disabled, hover, pressed, error, and loading states.
145
+ - Respect `prefers-reduced-motion` for nonessential animation.
146
+ - Keep touch targets at least 44 by 44 CSS pixels where practical.
147
+ - Verify changes at mobile and desktop breakpoints.
148
+
149
+ ## Examples
150
+
151
+ Use Tailwind for local layout:
152
+
153
+ ```tsx
154
+ <section className="grid gap-4 rounded-modal-rounding-default border border-elevation-outline-default-1 bg-elevation-fill-default-1 p-4">
155
+ <Typography size="title-4">{title}</Typography>
156
+ {children}
157
+ </section>
158
+ ```
159
+
160
+ Use `UIConfig` for an existing global default:
161
+
162
+ ```tsx
163
+ <UIConfig.Provider
164
+ config={{
165
+ input: { size: "small" },
166
+ }}
167
+ >
168
+ {children}
169
+ </UIConfig.Provider>
170
+ ```
171
+
172
+ Use a scoped CSS file for a connected route line:
173
+
174
+ ```css
175
+ .walk-route__marker::after {
176
+ content: "";
177
+ position: absolute;
178
+ inset-block: 1.25rem -0.75rem;
179
+ inset-inline-start: 50%;
180
+ width: 0.125rem;
181
+ background: rgb(var(--elevation-outline-default-1-base));
182
+ transform: translateX(-50%);
183
+ }
184
+ ```
185
+
186
+ Use `UIOverrides` only when the same primitive-level change is intentionally global:
187
+
188
+ ```ts
189
+ export const tagOverride = UIOverrides.defineOverride("tag.cva", {
190
+ mode: "overrideCva",
191
+ base: ["inline-flex items-center border"],
192
+ config: {
193
+ variants: {
194
+ color: {
195
+ success: "border-interactive-subtle-success-idle bg-interactive-subtle-success-idle",
196
+ },
197
+ },
198
+ },
199
+ });
200
+ ```
201
+
202
+ ## Verification
203
+
204
+ 1. Run formatting, linting, and TypeScript checks relevant to `apps/fe`.
205
+ 2. Inspect at least one representative use for every globally changed primitive.
206
+ 3. Check keyboard focus and disabled/error states.
207
+ 4. Check mobile and desktop layouts.
208
+ 5. Confirm no raw default-palette classes or duplicated design values were introduced.
@@ -0,0 +1,4 @@
1
+ interface:
2
+ display_name: "Povio UI Styling"
3
+ short_description: "Required first for all apps/fe UI work"
4
+ default_prompt: "Use $povio-ui-styling first for this apps/fe UI task, preserving @povio/ui primitives before applying other frontend guidance."
@@ -0,0 +1,13 @@
1
+ ---
2
+ name: robodev-api-route
3
+ description: Add a defineApi route under api/.
4
+ ---
5
+
6
+ # Add a Robodev API route
7
+
8
+ 1. Create `api/<path>.ts` or `api/<path>/[id].ts`.
9
+ 2. Export HTTP methods with `defineApi` from `@robodev-ai/sdk`.
10
+ 3. Use `auth: "required"` unless the route is public.
11
+ 4. Keep JSON shapes aligned with `openapi.json`.
12
+ 5. Do not create `api/user/**` files.
13
+ 6. Deploy from the project root (`robodev deploy`), then `bun openapi:gen` in `apps/fe` if the contract changed.
@@ -0,0 +1,12 @@
1
+ ---
2
+ name: robodev-table
3
+ description: Add a Drizzle table to database.ts and wire it into defineApi handlers.
4
+ ---
5
+
6
+ # Add a Robodev table
7
+
8
+ 1. Add a `pgTable` to `database.ts` and include it in `defineDatabase({ tables })`.
9
+ 2. Do not add a User table. Auth users are platform-managed; store `userId` as text.
10
+ 3. Import the table in `api/_lib.ts` or the route file that needs it.
11
+ 4. Deploy from the project root with `robodev deploy`. Destructive drops need confirmation or `--force`.
12
+ 5. If the frontend needs the new fields, update `openapi.json` and run `bun openapi:gen` from `apps/fe`.
@@ -0,0 +1,40 @@
1
+ # {{NAME}}
2
+
3
+ Starter from `robodev create --starter marketplace`: Tiny C2C marketplace schema (`categories`, `listings`, `cart_items`, `orders`, `watches`, `reviews`, `media`), file-based APIs in `api/`, and a Povio UI in `apps/fe`.
4
+
5
+ After a CLI create or deploy with `.robodev` `frontend` set (the default for this starter), the project host serves the built Tiny SPA at `GET /`. APIs and Swagger still win over static files.
6
+
7
+ Local Starbase occupies FE **:3000** and BE **:4000**. Point the CLI at it, then run starter Vite on **3001** so it does not steal the dashboard port:
8
+
9
+ ```bash
10
+ STARBASE_URL=http://localhost:4000 STARBASE_FE_URL=http://localhost:3000
11
+ # from starter root: auth / link / deploy as today
12
+ cd apps/fe
13
+ bun install
14
+ bun openapi:gen
15
+ bunx --bun vite --port 3001
16
+ ```
17
+
18
+ `bun` is required for `apps/fe`.
19
+
20
+ Auth, link, and deploy from this **root**:
21
+
22
+ ```bash
23
+ npx robodev auth
24
+ npx robodev link
25
+ npx robodev deploy
26
+ ```
27
+
28
+ `robodev create` / `robodev link` write `VITE_API_URL`, `VITE_PUBLIC_API_URL`, and `APP_PUBLIC_API_URL` in `.env`, rewrite `.config/local.spa.yml` so the FE talks to the project host, and (when `apps/fe/package.json` exists) add a `frontend` block to `.robodev`. `robodev deploy` then runs the local Vite build and uploads the static output.
29
+
30
+ Dashboard create deploys schema + APIs only. The Tiny FE tree is copied by `robodev create`; a later CLI deploy hosts the SPA.
31
+
32
+ Auth stays reserved at `/api/user/*`. Do not add `api/user/**`.
33
+
34
+ Regenerate AI rules after editing `.rulesync/`:
35
+
36
+ ```bash
37
+ bun rules:gen
38
+ ```
39
+
40
+ Docs: https://robodev.povio.dev/docs