robodev 0.47.3 → 0.49.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 (175) hide show
  1. package/package.json +3 -3
  2. package/src/dev-inspect.test.ts +15 -0
  3. package/src/dev-inspect.ts +10 -3
  4. package/src/dev-server.ts +6 -0
  5. package/src/emit-starter.test.ts +6 -3
  6. package/templates/auth-chat/ROBODEV.md +7 -1
  7. package/templates/auth-chat/package.json +2 -2
  8. package/templates/backend/ROBODEV.md +7 -1
  9. package/templates/backend/package.json +2 -2
  10. package/templates/catalog.json +5 -0
  11. package/templates/empty/ROBODEV.md +7 -1
  12. package/templates/empty/package.json +2 -2
  13. package/templates/marketplace/ROBODEV.md +7 -1
  14. package/templates/marketplace/package.json +2 -2
  15. package/templates/povio/.config/local.spa.template.yml +27 -0
  16. package/templates/povio/.oxlint-base.json +29 -0
  17. package/templates/povio/.oxlintrc.json +78 -0
  18. package/templates/povio/.rulesync/rules/frontend-api-boundary.md +36 -0
  19. package/templates/povio/.rulesync/rules/frontend-component-structure.md +40 -0
  20. package/templates/povio/.rulesync/rules/frontend-forms.md +27 -0
  21. package/templates/povio/.rulesync/rules/frontend-notifications.md +24 -0
  22. package/templates/povio/.rulesync/rules/frontend-povio-components.md +42 -0
  23. package/templates/povio/.rulesync/rules/frontend-povio-ui.md +45 -0
  24. package/templates/povio/.rulesync/rules/frontend-query-autocomplete.md +24 -0
  25. package/templates/povio/.rulesync/rules/frontend-tables-and-lists.md +26 -0
  26. package/templates/povio/.rulesync/rules/frontend-translations.md +25 -0
  27. package/templates/povio/.rulesync/rules/project-overview.md +32 -0
  28. package/templates/povio/.rulesync/rules/robodev-api.md +30 -0
  29. package/templates/povio/.rulesync/rules/robodev-auth.md +40 -0
  30. package/templates/povio/.rulesync/rules/robodev-database.md +22 -0
  31. package/templates/povio/.rulesync/rules/role-based-app-structure.md +36 -0
  32. package/templates/povio/.rulesync/skills/media-feature/SKILL.md +21 -0
  33. package/templates/povio/.rulesync/skills/povio-ui-styling/SKILL.md +211 -0
  34. package/templates/povio/.rulesync/skills/povio-ui-styling/agents/openai.yaml +4 -0
  35. package/templates/povio/.rulesync/skills/robodev-api-route/SKILL.md +13 -0
  36. package/templates/povio/.rulesync/skills/robodev-table/SKILL.md +12 -0
  37. package/templates/povio/README.md +40 -0
  38. package/templates/povio/ROBODEV.md +84 -0
  39. package/templates/povio/apps/fe/index.html +24 -0
  40. package/templates/povio/apps/fe/openapi-codegen.config.ts +72 -0
  41. package/templates/povio/apps/fe/package.json +71 -0
  42. package/templates/povio/apps/fe/public/apple-touch-icon.png +0 -0
  43. package/templates/povio/apps/fe/public/favicon-96x96.png +0 -0
  44. package/templates/povio/apps/fe/public/favicon.ico +0 -0
  45. package/templates/povio/apps/fe/public/favicon.svg +3 -0
  46. package/templates/povio/apps/fe/public/site.webmanifest +21 -0
  47. package/templates/povio/apps/fe/public/web-app-manifest-192x192.png +0 -0
  48. package/templates/povio/apps/fe/public/web-app-manifest-512x512.png +0 -0
  49. package/templates/povio/apps/fe/src/assets/locales/en/translation.json +166 -0
  50. package/templates/povio/apps/fe/src/clients/app-rest-client.ts +15 -0
  51. package/templates/povio/apps/fe/src/clients/auth-token-store.ts +101 -0
  52. package/templates/povio/apps/fe/src/clients/rest/app-error-handler.ts +31 -0
  53. package/templates/povio/apps/fe/src/clients/rest/interceptors/authorization-header.interceptor.ts +15 -0
  54. package/templates/povio/apps/fe/src/clients/rest/interceptors/refresh-token.interceptor.ts +45 -0
  55. package/templates/povio/apps/fe/src/clients/rest/interceptors/response.interceptor.ts +17 -0
  56. package/templates/povio/apps/fe/src/components/404.tsx +18 -0
  57. package/templates/povio/apps/fe/src/components/features/auth/AuthBrandPanel.tsx +60 -0
  58. package/templates/povio/apps/fe/src/components/features/auth/AuthLayout.tsx +23 -0
  59. package/templates/povio/apps/fe/src/components/features/auth/LoginPage.tsx +111 -0
  60. package/templates/povio/apps/fe/src/components/features/auth/RegisterPage.tsx +143 -0
  61. package/templates/povio/apps/fe/src/components/features/home/HomePage.tsx +21 -0
  62. package/templates/povio/apps/fe/src/components/features/profile/ProfilePage.tsx +96 -0
  63. package/templates/povio/apps/fe/src/components/layout/AppLayout.tsx +19 -0
  64. package/templates/povio/apps/fe/src/components/layout/app-header/AppHeader.tsx +91 -0
  65. package/templates/povio/apps/fe/src/components/layout/app-header/MobileNavigation.tsx +51 -0
  66. package/templates/povio/apps/fe/src/components/layout/app-header/NavLink.tsx +29 -0
  67. package/templates/povio/apps/fe/src/components/shared/branding/BrandLogo.tsx +13 -0
  68. package/templates/povio/apps/fe/src/components/shared/error/ErrorFallback.tsx +43 -0
  69. package/templates/povio/apps/fe/src/components/shared/error/ErrorText.tsx +20 -0
  70. package/templates/povio/apps/fe/src/components/shared/error/NotFound.tsx +36 -0
  71. package/templates/povio/apps/fe/src/components/shared/forms/RequiredLabel.tsx +21 -0
  72. package/templates/povio/apps/fe/src/components/shared/forms/RowInputWrapper.tsx +50 -0
  73. package/templates/povio/apps/fe/src/components/shared/head/AppHead.tsx +32 -0
  74. package/templates/povio/apps/fe/src/components/shared/head/DefaultAppHead.tsx +34 -0
  75. package/templates/povio/apps/fe/src/components/shared/layout/LoadingState.tsx +9 -0
  76. package/templates/povio/apps/fe/src/components/shared/layout/ThinPageWrapper.tsx +5 -0
  77. package/templates/povio/apps/fe/src/components/shared/page/PageHeader.tsx +69 -0
  78. package/templates/povio/apps/fe/src/components/shared/ui/Card.tsx +60 -0
  79. package/templates/povio/apps/fe/src/components/shared/ui/GoogleLoginButton.tsx +19 -0
  80. package/templates/povio/apps/fe/src/components/shared/ui/RequiredLabel.tsx +22 -0
  81. package/templates/povio/apps/fe/src/components/shared/ui/TableActions.tsx +22 -0
  82. package/templates/povio/apps/fe/src/config/app.config.ts +23 -0
  83. package/templates/povio/apps/fe/src/config/i18n.ts +37 -0
  84. package/templates/povio/apps/fe/src/config/inits/logger.ts +7 -0
  85. package/templates/povio/apps/fe/src/config/jwt.config.ts +2 -0
  86. package/templates/povio/apps/fe/src/config/query.config.ts +20 -0
  87. package/templates/povio/apps/fe/src/hooks/useAuth.ts +5 -0
  88. package/templates/povio/apps/fe/src/main.tsx +52 -0
  89. package/templates/povio/apps/fe/src/pages/(guest)/login.tsx +23 -0
  90. package/templates/povio/apps/fe/src/pages/(guest)/register.tsx +23 -0
  91. package/templates/povio/apps/fe/src/pages/(guest)/route.tsx +18 -0
  92. package/templates/povio/apps/fe/src/pages/(private)/index.tsx +23 -0
  93. package/templates/povio/apps/fe/src/pages/(private)/profile.tsx +23 -0
  94. package/templates/povio/apps/fe/src/pages/(private)/route.tsx +18 -0
  95. package/templates/povio/apps/fe/src/pages/(public)/auth.tsx +37 -0
  96. package/templates/povio/apps/fe/src/pages/(public)/route.tsx +9 -0
  97. package/templates/povio/apps/fe/src/pages/__root.tsx +133 -0
  98. package/templates/povio/apps/fe/src/providers/AppErrorBoundary.tsx +44 -0
  99. package/templates/povio/apps/fe/src/providers/OpenApiRuntimeProvider.tsx +31 -0
  100. package/templates/povio/apps/fe/src/providers/index.tsx +44 -0
  101. package/templates/povio/apps/fe/src/providers/jwt.provider.tsx +95 -0
  102. package/templates/povio/apps/fe/src/routeTree.gen.ts +225 -0
  103. package/templates/povio/apps/fe/src/styles/base.css +84 -0
  104. package/templates/povio/apps/fe/src/styles/fonts/fonts.tsx +10 -0
  105. package/templates/povio/apps/fe/src/styles/globals.css +26 -0
  106. package/templates/povio/apps/fe/src/styles/overrides/defaults/button.override.ts +536 -0
  107. package/templates/povio/apps/fe/src/styles/overrides/defaults/checkbox.override.ts +71 -0
  108. package/templates/povio/apps/fe/src/styles/overrides/defaults/input.override.ts +252 -0
  109. package/templates/povio/apps/fe/src/styles/overrides/defaults/label.override.ts +91 -0
  110. package/templates/povio/apps/fe/src/styles/overrides/defaults/modal.override.ts +62 -0
  111. package/templates/povio/apps/fe/src/styles/overrides/defaults/radio.override.ts +46 -0
  112. package/templates/povio/apps/fe/src/styles/overrides/defaults/table.override.ts +104 -0
  113. package/templates/povio/apps/fe/src/styles/overrides/defaults/tag.override.ts +66 -0
  114. package/templates/povio/apps/fe/src/styles/overrides/defaults/typography.override.ts +115 -0
  115. package/templates/povio/apps/fe/src/styles/overrides/outline.clsx.ts +10 -0
  116. package/templates/povio/apps/fe/src/styles/overrides/uiOverrides.override.ts +60 -0
  117. package/templates/povio/apps/fe/src/styles/theme.css +2177 -0
  118. package/templates/povio/apps/fe/src/types/i18next.d.ts +12 -0
  119. package/templates/povio/apps/fe/src/types/table.d.ts +17 -0
  120. package/templates/povio/apps/fe/src/types/ui.d.ts +26 -0
  121. package/templates/povio/apps/fe/src/types/vite-env.d.ts +13 -0
  122. package/templates/povio/apps/fe/src/utils/date.utils.ts +17 -0
  123. package/templates/povio/apps/fe/src/utils/image-fallback.ts +9 -0
  124. package/templates/povio/apps/fe/src/utils/number.utils.ts +12 -0
  125. package/templates/povio/apps/fe/src/utils/string.utils.ts +5 -0
  126. package/templates/povio/apps/fe/src/vite-env.d.ts +1 -0
  127. package/templates/povio/apps/fe/tsconfig.app.json +32 -0
  128. package/templates/povio/apps/fe/tsconfig.json +9 -0
  129. package/templates/povio/apps/fe/tsconfig.node.json +31 -0
  130. package/templates/povio/apps/fe/vite.config.ts +150 -0
  131. package/templates/povio/openapi.json +911 -0
  132. package/templates/povio/oxfmt.config.js +23 -0
  133. package/templates/povio/package.json +19 -0
  134. package/templates/povio/robodev/api/_lib.ts +99 -0
  135. package/templates/povio/robodev/api/health.ts +7 -0
  136. package/templates/povio/robodev/database.ts +28 -0
  137. package/templates/povio/robodev/package.json +4 -0
  138. package/templates/povio/rulesync.jsonc +18 -0
  139. package/templates/povio/tsconfig.json +11 -0
  140. package/templates/shadcn/.rulesync/rules/frontend-api-boundary.md +29 -0
  141. package/templates/shadcn/.rulesync/rules/frontend-component-structure.md +19 -0
  142. package/templates/shadcn/.rulesync/rules/frontend-hosted-ui.md +38 -0
  143. package/templates/shadcn/.rulesync/rules/project-overview.md +29 -0
  144. package/templates/shadcn/.rulesync/rules/robodev-api.md +22 -0
  145. package/templates/shadcn/.rulesync/rules/robodev-auth.md +47 -0
  146. package/templates/shadcn/.rulesync/rules/robodev-database.md +21 -0
  147. package/templates/shadcn/.rulesync/skills/robodev-crud-page/SKILL.md +181 -0
  148. package/templates/shadcn/README.md +9 -4
  149. package/templates/shadcn/ROBODEV.md +14 -6
  150. package/templates/shadcn/package.json +4 -6
  151. package/templates/shadcn/rulesync.jsonc +18 -0
  152. package/templates/shadcn/src/App.tsx +12 -3
  153. package/templates/shadcn/src/app.css +359 -0
  154. package/templates/shadcn/src/components/auth/AuthCard.tsx +29 -0
  155. package/templates/shadcn/src/components/ui/badge.tsx +17 -0
  156. package/templates/shadcn/src/components/ui/card.tsx +28 -0
  157. package/templates/shadcn/src/components/ui/dialog.tsx +38 -0
  158. package/templates/shadcn/src/components/ui/empty-state.tsx +17 -0
  159. package/templates/shadcn/src/components/ui/input.tsx +8 -0
  160. package/templates/shadcn/src/components/ui/label.tsx +8 -0
  161. package/templates/shadcn/src/components/ui/skeleton.tsx +6 -0
  162. package/templates/shadcn/src/components/ui/spinner.tsx +3 -0
  163. package/templates/shadcn/src/components/ui/table.tsx +30 -0
  164. package/templates/shadcn/src/components/ui/textarea.tsx +8 -0
  165. package/templates/shadcn/src/lib/auth.tsx +72 -0
  166. package/templates/shadcn/src/lib/client.ts +8 -0
  167. package/templates/shadcn/src/pages/Home.tsx +15 -0
  168. package/templates/shadcn/src/pages/Login.tsx +70 -0
  169. package/templates/shadcn/src/pages/NotFound.tsx +14 -0
  170. package/templates/shadcn/src/pages/Register.tsx +82 -0
  171. package/templates/space/ROBODEV.md +7 -1
  172. package/templates/space/package.json +2 -2
  173. package/templates/shadcn/components.json +0 -21
  174. package/templates/shadcn/postcss.config.js +0 -6
  175. package/templates/shadcn/tailwind.config.ts +0 -42
@@ -0,0 +1,45 @@
1
+ ---
2
+ root: false
3
+ targets: ["claudecode", "codexcli", "cursor"]
4
+ description: "Frontend UI uses Povio UI primitives first and semantic Tailwind tokens."
5
+ globs: ["apps/fe/src/**/*.{ts,tsx,css}"]
6
+ cursor:
7
+ alwaysApply: false
8
+ description: "Apply when editing frontend UI, styling, layout, components, or CSS."
9
+ globs: ["apps/fe/src/**/*.{ts,tsx,css}"]
10
+ ---
11
+
12
+ # Frontend UI
13
+
14
+ ## Use `@povio/ui` First
15
+
16
+ Always use components and hooks from `@povio/ui` when a suitable primitive exists, including `Button`, `Typography`, `Table`, `Modal`, `Confirmation`, `TextButton`, `TextInput`, `TextArea`, `PasswordInput`, `FileUpload`, `useForm`, `useToast`, and `Tag`.
17
+
18
+ Create project-specific UI only when `@povio/ui` does not provide the needed primitive. Shared custom primitives live under `apps/fe/src/components/shared/ui`.
19
+
20
+ Feature components should compose existing layout and shared primitives such as `PageHeader`, `BackHeader`, `LoadingState`, `ErrorText`, and `Card` before introducing new wrappers.
21
+
22
+ Add new product pages to the navigation in `apps/fe/src/components/layout/app-header/AppHeader.tsx` and `MobileNavigation.tsx` so they are reachable.
23
+
24
+ ## Tailwind Tokens
25
+
26
+ The default Tailwind color palette is removed in `apps/fe/src/styles/base.css`. Do not use default color utilities such as:
27
+
28
+ - `text-red-500`
29
+ - `bg-blue-600`
30
+ - `border-gray-200`
31
+ - `ring-emerald-400`
32
+
33
+ Use semantic tokens exported from Figma in `apps/fe/src/styles/theme.css` and exposed through Tailwind, for example:
34
+
35
+ - Surface, fill, and outline: `bg-elevation-fill-default-1`, `border-elevation-outline-default-1`
36
+ - Text: `text-text-default-1`, `text-text-default-2`, `text-text-error-1`
37
+ - Interactive: `bg-interactive-contained-primary-idle`, `hover:bg-interactive-contained-primary-hover`
38
+
39
+ Do not manually edit `apps/fe/src/styles/theme.css`; it is exported from Figma. If a hand-written semantic token or Tailwind theme mapping is needed, add it only in `apps/fe/src/styles/base.css` before referencing it from JSX or CSS.
40
+
41
+ ## Forms And API Data
42
+
43
+ For forms backed by API requests, prefer generated OpenAPI model schemas with `@povio/ui` `useForm`, for example `useForm({ zodSchema: UserModels.UpdateProfileBodySchema })`.
44
+
45
+ Use generated OpenAPI queries and mutations for all API state. Keep API side effects, toast feedback, loading states, and query invalidation close to the feature that owns the interaction. For mutation invalidation, pass generated mutation options such as `invalidateModules`; do not import `queryClient` into feature code for generated API queries.
@@ -0,0 +1,24 @@
1
+ ---
2
+ root: false
3
+ targets: ["claudecode", "codexcli", "cursor"]
4
+ description: "Frontend QueryAutocomplete usage for database-entity dropdowns with generated label queries and queryParams."
5
+ globs: ["apps/fe/src/**/*.{ts,tsx}"]
6
+ cursor:
7
+ alwaysApply: false
8
+ description: "Apply when a frontend form or filter needs a dropdown/search picker of database entities."
9
+ globs: ["apps/fe/src/**/*.{ts,tsx}"]
10
+ ---
11
+
12
+ # Frontend QueryAutocomplete
13
+
14
+ Use this pattern whenever the UI needs a dropdown/search picker of entities from the database, such as selecting a company, project, user, category, or any other related row in a form or filter.
15
+
16
+ Use `QueryAutocomplete` for these database-entity dropdowns. It should call a generated labels endpoint such as `CategoriesQueries.useListLabels`, not load full related records into the form.
17
+
18
+ The matching labels endpoint input schema must define `search`, usually as `search: z.string().optional()`, because `QueryAutocomplete` passes search text through that parameter.
19
+
20
+ If a labels endpoint needs extra context, pass it through `QueryAutocomplete` with `queryParams`. The matching labels endpoint input schema can include optional parameters beyond `search`, such as extra filters or flags that control how rows map into `{ id, label }`.
21
+
22
+ When the autocomplete belongs to a form, import it from `@povio/ui/tanstack` and prefer `field={{ form, name }}`. When it belongs to filters, read and write through the `useFilters` store.
23
+
24
+ Real app features should use generated labels queries from `@/openapi`.
@@ -0,0 +1,26 @@
1
+ ---
2
+ root: false
3
+ targets: ["claudecode", "codexcli", "cursor"]
4
+ description: "Frontend list and table patterns for grids, Table, InfiniteTable, filters, and sorting."
5
+ globs: ["apps/fe/src/**/*.{ts,tsx}"]
6
+ cursor:
7
+ alwaysApply: false
8
+ description: "Apply when building or changing list pages, grids, tables, filters, sorting, pagination, or row actions."
9
+ globs: ["apps/fe/src/**/*.{ts,tsx}"]
10
+ ---
11
+
12
+ # Frontend Tables And Lists
13
+
14
+ Real feature pages should choose one list pattern (grid cards, table, or infinite table) and use it consistently.
15
+
16
+ Prefer paginated API queries for database-backed collections. Use regular generated list queries only for data that is guaranteed to stay short, such as enums, compact option lists, or label-style endpoints.
17
+
18
+ Use `Table` from `@povio/ui` for small bounded table lists and `InfiniteTable` when incremental loading is useful for the feature. Infinite tables require a paginated backend endpoint and generated `use<Endpoint>Infinite` query. Even non-infinite collection views should normally be backed by a paginated endpoint unless the collection is intentionally bounded.
19
+
20
+ When a feature needs filters, define a filter schema on the API model, expose it through OpenAPI when useful, and use `useFilters` on the frontend. Put filter controls in a focused component such as `TodosFilters`. Use `as="filter"` on Povio UI filter controls.
21
+
22
+ When a feature needs sorting, expose an enum of sortable keys from the API layer and pass the generated enum schema into `dynamicColumns({ options: { sortable } })`. Use `useSorting` on the frontend and pass its `order` string to the generated query.
23
+
24
+ Use wrapper components around table primitives. A table wrapper should accept `TableWrapperProps<T>` or `InfiniteTableWrapperProps<T>` from `@povio/ui` and spread props into `Table` or `InfiniteTable`, while defining columns locally with a `getColumns` helper above the component.
25
+
26
+ Keep per-row actions in a small action component, such as `TodosTableActions`, and use a shared row-action wrapper when available so clicks do not accidentally trigger row navigation.
@@ -0,0 +1,25 @@
1
+ ---
2
+ root: false
3
+ targets: ["claudecode", "codexcli", "cursor"]
4
+ description: "Frontend translation key structure and no-hardcoded-text conventions."
5
+ globs: ["apps/fe/src/**/*.{ts,tsx,json}"]
6
+ cursor:
7
+ alwaysApply: false
8
+ description: "Apply when adding or changing frontend user-facing text, locale files, or translation keys."
9
+ globs: ["apps/fe/src/**/*.{ts,tsx,json}"]
10
+ ---
11
+
12
+ # Frontend Translations
13
+
14
+ Do not hardcode user-facing frontend text. Add copy to locale files and access it through `useTranslation`.
15
+
16
+ Translation key structure should generally follow the feature/component tree. For a `todos` feature that would look like:
17
+
18
+ - `todos.page.*`
19
+ - `todos.filters.*`
20
+ - `todos.createModal.*`
21
+ - `todos.editModal.*`
22
+ - `todos.table.*`
23
+ - `todos.detail.*`
24
+
25
+ The seeded `auth`, `layout`, `home`, and `profile` keys show the pattern.
@@ -0,0 +1,32 @@
1
+ ---
2
+ root: true
3
+ targets: ["claudecode", "codexcli", "cursor"]
4
+ description: "Project overview and Rulesync source-of-truth guidance."
5
+ globs: ["**/*"]
6
+ cursor:
7
+ alwaysApply: true
8
+ description: "Project overview and Rulesync source-of-truth guidance."
9
+ globs: ["**/*"]
10
+ ---
11
+
12
+ # Povio UI starter AI rules
13
+
14
+ This project is a Vite React frontend in `apps/fe` plus a Robodev backend under **`robodev/`** (`robodev/database.ts` + `robodev/api/**/*.ts` using `@robodev-ai/sdk`). There is no Expo / mobile app in this starter. End-user auth is reserved on the project host at `/api/user/*`. There is no in-browser fake backend.
15
+
16
+ `robodev deploy` from this root uploads schema, APIs, and (when `.robodev` has a `frontend` block) the local Vite build as a hosted static SPA. Use bun in `apps/fe` to iterate locally.
17
+
18
+ Shared AI rules and skills are authored in `.rulesync/`. Generated files for Codex, Claude Code, and Cursor are local outputs and should be regenerated with `bun rules:gen`.
19
+
20
+ This is a blank seed: no sample features. The backend ships `robodev/database.ts` (placeholder `items` table + `media`) and `GET /api/health`; the frontend ships auth (login/register), a Home page, and a profile page built with `@povio/ui`. Build product features on these seams instead of restructuring them.
21
+
22
+ When an app has multiple user roles with distinct UI or business workflows, use the conditional role-based app structure rule. Do not apply role splitting to simple single-role apps or small permission differences.
23
+
24
+ Use the more specific generated rules for:
25
+
26
+ - Robodev `defineDatabase` tables in `robodev/database.ts`.
27
+ - Robodev `defineApi` routes in `api/`.
28
+ - Reserved `/api/user/*` auth contracts (do not implement `api/user/**` in the project).
29
+ - Frontend API boundaries around generated `@/openapi` queries and models.
30
+ - Povio UI and semantic Tailwind token usage.
31
+ - Frontend forms, tables/lists, `QueryAutocomplete`, translations, and component structure.
32
+ - Role-based frontend structure when the app has multiple distinct user roles.
@@ -0,0 +1,30 @@
1
+ ---
2
+ root: false
3
+ targets: ["claudecode", "codexcli", "cursor"]
4
+ description: "Robodev defineApi file routes and handler conventions."
5
+ globs: ["robodev/api/**/*.ts"]
6
+ cursor:
7
+ alwaysApply: false
8
+ description: "Apply when editing Starbase API routes."
9
+ globs: ["robodev/api/**/*.ts"]
10
+ ---
11
+
12
+ # Robodev API
13
+
14
+ Project APIs live in `robodev/api/`. `robodev/api/todos.ts` would be served at `/todos` and `/api/todos`. Prefer the `/api/...` path in OpenAPI and frontend clients.
15
+
16
+ ## File layout
17
+
18
+ - `robodev/api/foo.ts` → `/api/foo`
19
+ - `robodev/api/foo/[id].ts` → `/api/foo/:id`
20
+ - Export `get` / `post` / `put` / `patch` / `delete` as `defineApi(...)`.
21
+ - Shared helpers belong in `robodev/api/_lib.ts`. Do not export `defineApi` from `_lib.ts`.
22
+ - Do not add `robodev/api/user/**`. Those paths are reserved for Robodev Auth.
23
+
24
+ ## Handlers
25
+
26
+ - Use `auth: "required"` on routes that Tiny marked authenticated.
27
+ - Handler context includes `db`, `user`, `email`, `storage`, `params`, `query`, `body`.
28
+ - Return JSON for 200, or `{ status, body }` for errors (404/403/400).
29
+ - Keep request/response shapes compatible with `openapi.json` so OpenAPI codegen stays stable.
30
+ - After changing public contracts, update `openapi.json` if needed and run `bun openapi:gen` from `apps/fe`.
@@ -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
+ "robodev/database.ts",
12
+ "robodev/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: ["robodev/database.ts"]
6
+ cursor:
7
+ alwaysApply: false
8
+ description: "Apply when editing the Starbase database schema."
9
+ globs: ["robodev/database.ts"]
10
+ ---
11
+
12
+ # Robodev Database
13
+
14
+ The backend schema lives in `robodev/database.ts`. 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 `robodev/api/_lib.ts`.
22
+ - Seed demo rows in API handlers on first read (see `robodev/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}", "robodev/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}", "robodev/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 a `File` and keeps it 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 an optional `file`.
15
+ 3. The handler validates text fields, optionally calls `saveImage` from `robodev/api/_lib.ts` (`ctx.storage.upload` public), and writes the feature row.
16
+ 4. Update may send `clearImage=true` when the user cleared an existing image and picked nothing new. A new `file` wins over `clearImage`.
17
+ 5. Feature reads resolve the stored media ID to `image: { 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 `robodev/database.ts`. Bytes live in Robodev storage.
@@ -0,0 +1,211 @@
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
+ Retheming the app means overriding tokens in `globals.css`, in `@layer base`, after the
136
+ `theme.css` import — nowhere else redeclares them, so the last declaration in that layer wins.
137
+
138
+ ## Guardrails
139
+
140
+ - Use `@povio/ui` before creating a custom primitive.
141
+ - 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.
142
+ - Use semantic Tailwind tokens from the project theme.
143
+ - Never manually edit `apps/fe/src/styles/theme.css`.
144
+ - Avoid `!important`; resolve ownership or specificity instead.
145
+ - 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.
146
+ - Avoid Sass, CSS-in-JS, and a second styling system.
147
+ - Preserve visible focus, disabled, hover, pressed, error, and loading states.
148
+ - Respect `prefers-reduced-motion` for nonessential animation.
149
+ - Keep touch targets at least 44 by 44 CSS pixels where practical.
150
+ - Verify changes at mobile and desktop breakpoints.
151
+
152
+ ## Examples
153
+
154
+ Use Tailwind for local layout:
155
+
156
+ ```tsx
157
+ <section className="grid gap-4 rounded-modal-rounding-default border border-elevation-outline-default-1 bg-elevation-fill-default-1 p-4">
158
+ <Typography size="title-4">{title}</Typography>
159
+ {children}
160
+ </section>
161
+ ```
162
+
163
+ Use `UIConfig` for an existing global default:
164
+
165
+ ```tsx
166
+ <UIConfig.Provider
167
+ config={{
168
+ input: { size: "small" },
169
+ }}
170
+ >
171
+ {children}
172
+ </UIConfig.Provider>
173
+ ```
174
+
175
+ Use a scoped CSS file for a connected route line:
176
+
177
+ ```css
178
+ .walk-route__marker::after {
179
+ content: "";
180
+ position: absolute;
181
+ inset-block: 1.25rem -0.75rem;
182
+ inset-inline-start: 50%;
183
+ width: 0.125rem;
184
+ background: rgb(var(--elevation-outline-default-1-base));
185
+ transform: translateX(-50%);
186
+ }
187
+ ```
188
+
189
+ Use `UIOverrides` only when the same primitive-level change is intentionally global:
190
+
191
+ ```ts
192
+ export const tagOverride = UIOverrides.defineOverride("tag.cva", {
193
+ mode: "overrideCva",
194
+ base: ["inline-flex items-center border"],
195
+ config: {
196
+ variants: {
197
+ color: {
198
+ success: "border-interactive-subtle-success-idle bg-interactive-subtle-success-idle",
199
+ },
200
+ },
201
+ },
202
+ });
203
+ ```
204
+
205
+ ## Verification
206
+
207
+ 1. Run formatting, linting, and TypeScript checks relevant to `apps/fe`.
208
+ 2. Inspect at least one representative use for every globally changed primitive.
209
+ 3. Check keyboard focus and disabled/error states.
210
+ 4. Check mobile and desktop layouts.
211
+ 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 robodev/api/.
4
+ ---
5
+
6
+ # Add a Robodev API route
7
+
8
+ 1. Create `robodev/api/<path>.ts` or `robodev/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 `robodev/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 robodev/database.ts and wire it into defineApi handlers.
4
+ ---
5
+
6
+ # Add a Robodev table
7
+
8
+ 1. Add a `pgTable` to `robodev/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
+ Blank starter with the real `@povio/ui` kit: empty schema (placeholder `items` + `media`), `GET /api/health`, file-based APIs in `robodev/api/`, and a Povio UI frontend in `apps/fe` with seeded auth (login/register), Home, and profile — no sample features. Agents: read `ROBODEV.md`.
4
+
5
+ After a CLI create or deploy with `.robodev` `frontend` set (the default for this starter), the project host serves the built 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 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 `robodev/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