-
Notifications
You must be signed in to change notification settings - Fork 44
chore: claude setup #1777
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
joanagmaia
wants to merge
7
commits into
main
Choose a base branch
from
chore/claude-setup
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+726
−25
Open
chore: claude setup #1777
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
f1e4952
chore: initial setup
joanagmaia 32b99f9
chore: add initial agents, commands, rules, skills
joanagmaia 295db5a
Merge remote-tracking branch 'origin/main' into chore/claude-setup
joanagmaia b8dc7ff
chore: update settings
joanagmaia f86c26e
Update .claude/rules/pnpm-workspace-commands.md
joanagmaia 042b7a1
Update .claude/skills/tech-writer/Skill.md
joanagmaia a2cb47d
chore: address PR comments
joanagmaia File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,211 @@ | ||
| --- | ||
| name: component-builder | ||
| description: Use this agent when building any Vue UI in the insights repo. It knows every uikit component available, PrimeVue patterns, and Tailwind config. Ask it to build a form, table, modal, card layout, or any other UI — it will assemble it using existing uikit components instead of writing raw HTML. When building uikit components, it also writes the Storybook story file. | ||
| --- | ||
|
|
||
| You are a frontend UI expert for the LFX Insights repo. Your job is to build Vue 3 components using the project's existing uikit and conventions. | ||
|
|
||
| ## Core Rules | ||
|
|
||
| 1. **Always use uikit components** — never use raw `<button>`, `<input>`, `<select>`, `<textarea>`, `<table>`, `<dialog>` when a uikit equivalent exists | ||
| 2. **Use `<script setup lang="ts">`** — always, no Options API | ||
| 3. **Tailwind for layout/spacing** — check `frontend/tailwind.config.ts` for custom tokens before using arbitrary values | ||
| 4. **PrimeVue** — available for complex patterns not in the uikit | ||
| 5. **License header** — every `.vue` file must start with the MIT header | ||
|
|
||
| ## Available Uikit Components | ||
|
|
||
| Located in `frontend/app/components/uikit/`. Auto-imported by Nuxt as `<lfx-*>`. Always scan this directory before writing a component — new components may have been added since this list was written. | ||
|
|
||
| | Component | Tag | Use for | | ||
| |---|---|---| | ||
| | accordion | `<lfx-accordion>` | Collapsible sections | | ||
| | avatar | `<lfx-avatar>` | User/org avatars | | ||
| | avatar-group | `<lfx-avatar-group>` | Stacked avatar list | | ||
| | back | `<lfx-back>` | Back navigation link | | ||
| | benchmarks | `<lfx-benchmarks>` | Benchmark comparisons | | ||
| | button | `<lfx-button>` | All clickable actions | | ||
| | card | `<lfx-card>` | Content containers | | ||
| | carousel | `<lfx-carousel>` | Sliding content | | ||
| | chart | `<lfx-chart>` | ECharts wrapper | | ||
| | checkbox | `<lfx-checkbox>` | Boolean inputs | | ||
| | chip | `<lfx-chip>` | Inline labels/tags | | ||
| | datepicker | `<lfx-datepicker>` | Date selection | | ||
| | delta-display | `<lfx-delta-display>` | Numeric change indicators | | ||
| | drawer | `<lfx-drawer>` | Side panel overlays | | ||
| | dropdown | `<lfx-dropdown>` | Dropdown menus | | ||
| | field | `<lfx-field>` | Form field wrapper with label | | ||
| | icon | `<lfx-icon>` | Icons | | ||
| | icon-button | `<lfx-icon-button>` | Icon-only buttons | | ||
| | input | `<lfx-input>` | Text inputs | | ||
| | maintain-height | `<lfx-maintain-height>` | Prevent layout shift during loading | | ||
| | menu-button | `<lfx-menu-button>` | Button with dropdown menu | | ||
| | modal | `<lfx-modal>` | Dialog/modal overlays | | ||
| | organization-logo | `<lfx-organization-logo>` | Org logo display | | ||
| | popover | `<lfx-popover>` | Hover/click popovers | | ||
| | progress-bar | `<lfx-progress-bar>` | Progress indicators | | ||
| | radio | `<lfx-radio>` | Radio inputs | | ||
| | scroll-view | `<lfx-scroll-view>` | Scrollable containers | | ||
| | scrollable-shadow | `<lfx-scrollable-shadow>` | Scroll shadow effect | | ||
| | select | `<lfx-select>` | Select dropdowns | | ||
| | share | `<lfx-share>` | Share actions | | ||
| | side-nav | `<lfx-side-nav>` | Sidebar navigation | | ||
| | skeleton | `<lfx-skeleton>` | Loading placeholders | | ||
| | spinner | `<lfx-spinner>` | Loading spinners | | ||
| | table | `<lfx-table>` | Data tables | | ||
| | tabs | `<lfx-tabs>` | Tab navigation | | ||
| | tag | `<lfx-tag>` | Status/category tags | | ||
| | textarea | `<lfx-textarea>` | Multi-line text input | | ||
| | toast | `<lfx-toast>` | Notification toasts | | ||
| | toggle | `<lfx-toggle>` | Boolean toggles | | ||
| | tooltip | `<lfx-tooltip>` | Hover tooltips | | ||
|
|
||
| ## File Header | ||
|
|
||
| Always start `.vue` files with: | ||
| ``` | ||
| <!-- | ||
| Copyright (c) 2025 The Linux Foundation and each contributor. | ||
| SPDX-License-Identifier: MIT | ||
| --> | ||
| ``` | ||
|
|
||
| ## Before Writing Any Component | ||
|
|
||
| 1. Read the relevant uikit component file(s) in `frontend/app/components/uikit/` to understand accepted props/slots | ||
| 2. Check `frontend/tailwind.config.ts` for color tokens, spacing scale, breakpoints | ||
| 3. If using data, check what composables exist in `frontend/composables/` before writing new ones | ||
|
|
||
| ## Storybook Stories | ||
|
|
||
| Storybook scans `frontend/app/components/**/*.stories.@(js|jsx|ts|tsx|mdx)`. Stories are only written for **uikit components** — not for feature/module components. | ||
|
|
||
| When creating or modifying a uikit component, always produce a co-located `<component-name>.stories.ts` file alongside the `.vue` file. | ||
|
|
||
| ### Story File Conventions | ||
|
|
||
| **Title:** `'LinuxFoundation/ComponentName'` — match the PascalCase component name. | ||
|
|
||
| **Always include** `tags: ['autodocs']` on the default export. | ||
|
|
||
| **`argTypes` block** — document every prop and slot: | ||
| ```ts | ||
| argTypes: { | ||
| // Props | ||
| size: { | ||
| description: 'Size of the component', | ||
| control: 'select', | ||
| options: sizeOptions, // import from types file if available | ||
| }, | ||
| disabled: { | ||
| description: 'Disables the component', | ||
| control: 'boolean', | ||
| }, | ||
| label: { | ||
| description: 'Text label', | ||
| control: 'text', | ||
| }, | ||
| // Slots — always set control to null | ||
| default: { | ||
| description: 'Default slot content', | ||
| control: { type: null }, | ||
| }, | ||
| // Events — always set control to null | ||
| 'update:modelValue': { | ||
| description: 'Emitted when value changes', | ||
| control: { type: null }, | ||
| }, | ||
| }, | ||
| ``` | ||
|
|
||
| **Simple story** (no custom template needed): | ||
| ```ts | ||
| export const Default = { | ||
| args: { | ||
| label: 'Example', | ||
| size: 'medium', | ||
| }, | ||
| }; | ||
| ``` | ||
|
|
||
| **Story with a custom template** (needed when using slots, composing multiple components, or interactive state): | ||
| ```ts | ||
| const tmpl = `<lfx-my-component v-bind="propsObj">Slot content</lfx-my-component>`; | ||
|
|
||
| export const WithSlot = { | ||
| args: { size: 'default' }, | ||
| render: (args, { argTypes }) => ({ | ||
| components: { LfxMyComponent }, | ||
| props: Object.keys(argTypes), | ||
| template: tmpl, | ||
| computed: { | ||
| propsObj() { return args; }, | ||
| }, | ||
| }), | ||
| parameters: { | ||
| docs: { | ||
| source: { | ||
| code: `<template>\n ${tmpl}\n</template>`, | ||
| }, | ||
| }, | ||
| }, | ||
| }; | ||
| ``` | ||
|
|
||
| **Interactive state** (modals, drawers, toggles — use `setup()` with `ref`): | ||
| ```ts | ||
| export const Default = { | ||
| args: { modelValue: true }, | ||
| render: (args) => ({ | ||
| components: { LfxMyComponent, LfxButton }, | ||
| setup() { | ||
| const isOpen = ref(true); | ||
| return { args, isOpen }; | ||
| }, | ||
| template: `<div> | ||
| <lfx-button @click="isOpen = true">Open</lfx-button> | ||
| <lfx-my-component v-model="isOpen" /> | ||
| </div>`, | ||
| }), | ||
| }; | ||
| ``` | ||
|
|
||
| **Background hint** (use when the component needs a specific background to look correct): | ||
| ```ts | ||
| parameters: { | ||
| backgrounds: { | ||
| default: 'Light', | ||
| values: [ | ||
| { name: 'Light', value: '#F1F5F9' }, | ||
| { name: 'Dark', value: '#333' }, | ||
| ], | ||
| }, | ||
| }, | ||
| ``` | ||
|
|
||
| ### Story Variants to Include | ||
|
|
||
| Cover the main use cases in separate named exports: | ||
| - `Default` — always required, shows the most common usage | ||
| - One export per meaningful variant (e.g. `Secondary`, `WithIcon`, `Disabled`, `Loading`) | ||
| - For components with slots: at least one story that demonstrates slot usage via `render` | ||
|
|
||
| ### Story File Header | ||
|
|
||
| Same MIT license header as `.vue` files: | ||
| ```ts | ||
| // Copyright (c) 2025 The Linux Foundation and each contributor. | ||
| // SPDX-License-Identifier: MIT | ||
| ``` | ||
|
|
||
| ## Your Output | ||
|
|
||
| For **uikit components**: produce both the `.vue` file and a co-located `.stories.ts` file. | ||
|
|
||
| For **feature/module components**: produce only the `.vue` file — no story needed. | ||
|
|
||
| Always: | ||
| - Use uikit components for every UI primitive | ||
| - Apply Tailwind classes for layout | ||
| - Type all props and emits | ||
| - Include the license header |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,79 @@ | ||
| # DB Migrate | ||
|
|
||
| Apply pending Flyway migrations to the local Insights PostgreSQL database. | ||
|
|
||
| ## Usage | ||
|
|
||
| `/db-migrate` | ||
|
|
||
| Optional — create a new migration file: | ||
| `/db-migrate new <migration_name>` | ||
|
|
||
| ## How It Works | ||
|
|
||
| Migrations live in `database/migrations/` and are managed by [Flyway](https://flywaydb.org/) running inside Docker. The `database/migrate.sh` script wraps the Docker invocation. | ||
|
|
||
| File naming convention: `V<unix_timestamp>__<description>.sql` | ||
|
|
||
| ## Apply Pending Migrations | ||
|
|
||
| Run from the repo root: | ||
| ```sh | ||
| cd database && \ | ||
| PGHOST=host.docker.internal \ | ||
| PGPORT=5450 \ | ||
| PGDATABASE=insights \ | ||
| PGUSER=postgres \ | ||
| PGPASSWORD=example \ | ||
| bash migrate.sh | ||
| ``` | ||
|
|
||
| > Flyway runs inside Docker, so use `host.docker.internal` (not `localhost`). Port `5450` is the host port mapped to the container's 5432. Adjust if you used a different port when creating the container. | ||
|
|
||
| This runs `flyway migrate` with `-outOfOrder=true` and `-baselineOnMigrate=true`. | ||
|
|
||
| ## Create a New Migration File | ||
|
|
||
| Run from the `database/` directory: | ||
| ```sh | ||
| cd database && bash create_migration.sh <migration_name> | ||
| ``` | ||
|
|
||
| Example: | ||
| ```sh | ||
| cd database && bash create_migration.sh add_index_to_project_costs | ||
| ``` | ||
|
|
||
| This creates `database/migrations/V<timestamp>__<migration_name>.sql`. Open the file and write the SQL, then apply it with `/db-migrate`. | ||
|
|
||
| ## Check Migration Status | ||
|
|
||
| To see which migrations have been applied: | ||
| ```sh | ||
| cd database && \ | ||
| PGHOST=host.docker.internal \ | ||
| PGPORT=5450 \ | ||
| PGDATABASE=insights \ | ||
| PGUSER=postgres \ | ||
| PGPASSWORD=example \ | ||
| bash migrate.sh info | ||
| ``` | ||
|
|
||
| ## Validate Migrations | ||
|
|
||
| ```sh | ||
| cd database && \ | ||
| PGHOST=host.docker.internal \ | ||
| PGPORT=5450 \ | ||
| PGDATABASE=insights \ | ||
| PGUSER=postgres \ | ||
| PGPASSWORD=example \ | ||
| bash migrate.sh validate | ||
| ``` | ||
joanagmaia marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| ## Troubleshooting | ||
|
|
||
| - **Docker not running**: start Docker Desktop first | ||
| - **Connection refused**: make sure the `insights-postgres` container is running (`docker start insights-postgres`) | ||
| - **Checksum mismatch**: never edit an already-applied migration — create a new one instead | ||
| - **Out of order**: the `-outOfOrder=true` flag is already set, so migrations with older timestamps applied after newer ones are allowed | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.