diff --git a/AGENTS.md b/AGENTS.md
index c6a75d6b..22911597 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -3,6 +3,90 @@
[Project architecture](architecture.md)
+
+## usage_rules:elixir usage
+# Elixir Core Usage Rules
+
+## Pattern Matching
+- Use pattern matching over conditional logic when possible
+- Prefer to match on function heads instead of using `if`/`else` or `case` in function bodies
+- `%{}` matches ANY map, not just empty maps. Use `map_size(map) == 0` guard to check for truly empty maps
+
+## Error Handling
+- Use `{:ok, result}` and `{:error, reason}` tuples for operations that can fail
+- Avoid raising exceptions for control flow
+- Use `with` for chaining operations that return `{:ok, _}` or `{:error, _}`
+
+## Common Mistakes to Avoid
+- Elixir has no `return` statement, nor early returns. The last expression in a block is always returned.
+- Don't use `Enum` functions on large collections when `Stream` is more appropriate
+- Avoid nested `case` statements - refactor to a single `case`, `with` or separate functions
+- Don't use `String.to_atom/1` on user input (memory leak risk)
+- Lists and enumerables cannot be indexed with brackets. Use pattern matching or `Enum` functions
+- Prefer `Enum` functions like `Enum.reduce` over recursion
+- When recursion is necessary, prefer to use pattern matching in function heads for base case detection
+- Using the process dictionary is typically a sign of unidiomatic code
+- Only use macros if explicitly requested
+- There are many useful standard library functions, prefer to use them where possible
+
+## Function Design
+- Use guard clauses: `when is_binary(name) and byte_size(name) > 0`
+- Prefer multiple function clauses over complex conditional logic
+- Name functions descriptively: `calculate_total_price/2` not `calc/2`
+- Predicate function names should not start with `is` and should end in a question mark.
+- Names like `is_thing` should be reserved for guards
+
+## Data Structures
+- Use structs over maps when the shape is known: `defstruct [:name, :age]`
+- Prefer keyword lists for options: `[timeout: 5000, retries: 3]`
+- Use maps for dynamic key-value data
+- Prefer to prepend to lists `[new | list]` not `list ++ [new]`
+
+## Mix Tasks
+
+- Use `mix help` to list available mix tasks
+- Use `mix help task_name` to get docs for an individual task
+- Read the docs and options fully before using tasks
+
+## Testing
+- Run tests in a specific file with `mix test test/my_test.exs` and a specific test with the line number `mix test path/to/test.exs:123`
+- Limit the number of failed tests with `mix test --max-failures n`
+- Use `@tag` to tag specific tests, and `mix test --only tag` to run only those tests
+- Use `assert_raise` for testing expected exceptions: `assert_raise ArgumentError, fn -> invalid_function() end`
+- Use `mix help test` to for full documentation on running tests
+
+## Debugging
+
+- Use `dbg/1` to print values while debugging. This will display the formatted value and other relevant information in the console.
+
+
+
+## usage_rules:otp usage
+# OTP Usage Rules
+
+## GenServer Best Practices
+- Keep state simple and serializable
+- Handle all expected messages explicitly
+- Use `handle_continue/2` for post-init work
+- Implement proper cleanup in `terminate/2` when necessary
+
+## Process Communication
+- Use `GenServer.call/3` for synchronous requests expecting replies
+- Use `GenServer.cast/2` for fire-and-forget messages.
+- When in doubt, use `call` over `cast`, to ensure back-pressure
+- Set appropriate timeouts for `call/3` operations
+
+## Fault Tolerance
+- Set up processes such that they can handle crashing and being restarted by supervisors
+- Use `:max_restarts` and `:max_seconds` to prevent restart loops
+
+## Task and Async
+- Use `Task.Supervisor` for better fault tolerance
+- Handle task failures with `Task.yield/2` or `Task.shutdown/2`
+- Set appropriate task timeouts
+- Use `Task.async_stream/3` for concurrent enumeration with back-pressure
+
+
## phoenix:ecto usage
## Ecto Guidelines
@@ -546,2443 +630,6 @@ mix usage_rules.search_docs "Enum.zip" --query-by title
## fluxon usage
_Fluxon UI Components_
-# Fluxon UI Components Usage Rules
-
-This document provides a guide for Large Language Models (LLMs) on how to use Fluxon UI components. It covers component attributes, slots, and provides usage examples for different scenarios.
-
-## Accordion
-
-The Accordion component provides collapsible content sections with headers that toggle panel visibility.
-
-### Components
-- `accordion`: Main container that manages state and accessibility
-- `accordion_item`: Individual collapsible sections
-
-### Attributes
-
-#### accordion
-- `id` (string, optional): Unique identifier for the accordion container
-- `class` (any, optional): Additional CSS classes for the accordion container
-- `multiple` (boolean, default: false): Allow multiple items to be expanded simultaneously
-- `prevent_all_closed` (boolean, default: false): Prevent all items from being closed at once
-- `animation_duration` (integer, default: 300): Duration of expand/collapse animation in milliseconds
-- `rest`: Additional HTML attributes
-
-#### accordion_item
-- `id` (string, optional): Unique identifier for the accordion item
-- `class` (any, optional): Additional CSS classes for the accordion item container
-- `expanded` (boolean, default: false): Initial expanded state of the item
-- `icon` (boolean, default: true): Show/hide the chevron icon
-- `rest`: Additional HTML attributes
-
-### Slots
-
-#### accordion
-- `inner_block` (required): Contains one or more accordion_item components
-
-#### accordion_item
-- `header` (required): Always-visible clickable area that toggles the panel
- - `class` (optional): Additional CSS classes for the header button
-- `panel` (required): Expandable content area
- - `class` (optional): Additional CSS classes for the panel content
-
-### Usage Examples
-
-#### Basic Accordion
-```heex
-<.accordion>
- <.accordion_item>
- <:header>What is Fluxon?
- <:panel>
- Fluxon is a powerful UI component library for Phoenix LiveView applications.
-
-
-
- <.accordion_item>
- <:header>How do I get started?
- <:panel>
- Add Fluxon to your dependencies and follow the installation guide.
-
-
-
-```
-
-#### Multiple Sections and Rich Headers
-```heex
-<.accordion multiple>
- <.accordion_item>
- <:header class="flex items-center gap-3">
- <.icon name="document" class="size-5 text-zinc-400" />
-
-
Documentation
-
View the complete documentation
-
- <.badge class="ml-auto">New
-
- <:panel>Detailed documentation content...
-
-
-```
-
-#### Custom Animation and No Icon
-```heex
-<.accordion animation_duration={500}>
- <.accordion_item icon={false}>
- <:header>Custom Header Without Chevron
- <:panel>No chevron icon is shown for this item
-
-
-```
-
-## Alert
-
-The Alert component displays status messages, notifications, and interactive feedback with various visual styles and interactive elements.
-
-### Attributes
-- `id` (string, optional): Unique identifier for the alert element
-- `class` (any, optional): Additional CSS classes for the alert element
-- `title` (string, optional): Main heading text of the alert
-- `subtitle` (string, optional): Secondary text displayed alongside the title
-- `color` (string, default: "default"): Visual style color - "default", "primary", "danger", "success", "info", "warning"
-- `hide_icon` (boolean, default: false): Hide the alert's status icon
-- `hide_close` (boolean, default: false): Hide the alert's close button
-- `on_close` (JS, default: %JS{}): LiveView JS commands to execute when closed
-
-### Slots
-- `inner_block` (optional): Main content displayed in the alert body
-- `icon` (optional): Custom icon to replace the default status icon
-
-### Usage Examples
-
-#### Basic Alert with Colors
-```heex
-<.alert>Simple alert message
-
-<.alert color="info" title="Update Available">
- A new version of the application is ready to install.
-
-
-<.alert color="success" title="Order Confirmed">
- Your order has been successfully processed.
-
-
-<.alert color="warning" title="Session Expiring">
- Your session will expire in 5 minutes.
-
-
-<.alert color="danger" title="Connection Lost">
- Unable to connect to the server.
-
-```
-
-#### Alert with Actions
-```heex
-<.alert
- color="warning"
- title="Unsaved Changes"
- on_close={JS.push("dismiss_warning")}>
- You have unsaved changes that will be lost.
-
-
-
-
-```
-
-## Radio
-
-A versatile radio component for building single-selection interfaces with rich styling options.
-
-### Attributes
-- `id` (any, default: nil): The unique identifier for the radio group
-- `name` (string, required when not using field): The form name for the radio group
-- `value` (any): The current selected value of the radio group
-- `label` (string, default: nil): The primary label for the radio group
-- `sublabel` (string, default: nil): Additional context displayed beside the main label
-- `description` (string, default: nil): Detailed description below the label
-- `errors` (list, default: []): List of error messages
-- `class` (any, default: nil): Additional CSS classes for the radio group container
-- `field` (Phoenix.HTML.FormField): The form field to bind to
-- `disabled` (boolean, default: false): Disables all radio buttons in the group
-- `variant` (string, default: nil): Visual variant - nil (default) or "card"
-- `control` (string): Controls radio position in card variants - "left" or "right"
-- `rest` (global): Additional attributes
-
-### Slots
-- `radio` (required): Defines individual radio buttons with attributes: `value`, `label`, `sublabel`, `description`, `disabled`, `class`, `checked`
-
-### Usage Examples
-
-#### Basic Radio Group
-```heex
-<.radio_group name="system" value="debian" label="Operating System">
- <:radio value="ubuntu" label="Ubuntu" />
- <:radio value="debian" label="Debian" />
- <:radio value="fedora" label="Fedora" />
-
-```
-
-#### With Context and Form Integration
-```heex
-<.radio_group
- name="system"
- label="Operating System"
- sublabel="Choose your preferred OS"
- description="Select the operating system that best suits your needs"
->
- <:radio
- value="ubuntu"
- label="Ubuntu"
- sublabel="Popular and user-friendly"
- description="Ubuntu is a Debian-based Linux operating system"
- />
- <:radio
- value="debian"
- label="Debian"
- sublabel="Stable and reliable"
- description="Debian is composed of free and open-source software"
- />
-
-
-<.form :let={f} for={@form} phx-change="validate" phx-submit="save">
- <.radio_group
- field={f[:subscription]}
- label="Subscription Plan"
- description="Choose your preferred subscription plan"
- >
- <:radio value="basic" label="Basic Plan" sublabel="$10/month" />
- <:radio value="pro" label="Pro Plan" sublabel="$20/month" />
- <:radio value="enterprise" label="Enterprise Plan" sublabel="$50/month" />
-
-
-```
-
-#### Card Variant
-```heex
-<.radio_group
- name="plan"
- label="Choose a plan"
- description="Choose the plan that best suits your needs."
- variant="card"
- control="left"
- class="gap-0"
->
- <:radio value="basic" label="Basic" sublabel="Perfect for small projects" class="rounded-none -my-px rounded-t-lg" />
- <:radio value="pro" label="Professional" checked sublabel="Most popular for growing teams" class="rounded-none -my-px" />
- <:radio value="business" label="Business" sublabel="Advanced features for larger teams" class="rounded-none -my-px rounded-b-lg" />
-
-
-<.radio_group name="category" label="Category" variant="card" class="grid grid-cols-3">
- <:radio value="web-design" class="flex-1 group has-checked:border-blue-500 has-checked:bg-blue-50">
-
-
-
-```
-
-## Select
-
-A select component that implements a modern, accessible selection interface with support for single and multiple selections.
-
-### Attributes
-- `id` (any, default: nil): The unique identifier for the select component
-- `name` (any, required when not using field): The form name for the select
-- `field` (Phoenix.HTML.FormField): The form field to bind to
-- `native` (boolean, default: false): Renders a native HTML select element instead of custom select
-- `class` (any, default: nil): Additional CSS classes for the select component
-- `label` (string, default: nil): The primary label for the select
-- `sublabel` (string, default: nil): Additional context beside the main label
-- `help_text` (string, default: nil): Help text displayed below the select
-- `description` (string, default: nil): Description below the label but above select
-- `placeholder` (string, default: nil): Text displayed when no option is selected
-- `searchable` (boolean, default: false): Adds search input to filter options (custom select only)
-- `disabled` (boolean, default: false): Disables the select component
-- `size` (string, default: "md"): Controls select size - "xs", "sm", "md", "lg", "xl"
-- `search_input_placeholder` (string, default: "Search..."): Placeholder for search input
-- `search_no_results_text` (string, default: "No results found for %{query}."): No results text
-- `search_threshold` (integer, default: 0): Minimum characters before filtering
-- `debounce` (integer, default: 300): Debounce time for server searches
-- `on_search` (string, default: nil): LiveView event name for server searches
-- `multiple` (boolean, default: false): Allows selecting multiple options (not with native)
-- `value` (any): Current selected value(s)
-- `errors` (list, default: []): List of error messages
-- `options` (list, required): List of options for the select
-- `max` (integer, default: nil): Maximum selections when multiple
-- `clearable` (boolean, default: false): Shows clear button
-- `rest` (global): Additional attributes
-
-### Slots
-- `option`: Optional slot for custom option rendering
-- `toggle`: Optional slot for custom toggle rendering
-- `header`: Optional slot for custom header content
-- `footer`: Optional slot for custom footer content
-- `inner_prefix`: Content inside select field before value display
-- `outer_prefix`: Content outside and before select field
-- `inner_suffix`: Content inside select field after value display
-- `outer_suffix`: Content outside and after select field
-
-### Usage Examples
-
-#### Basic and Full-featured Select
-```heex
-<.select
- name="country"
- options={[{"United States", "US"}, {"Canada", "CA"}]}
-/>
-
-<.select
- name="payment_method"
- label="Payment Method"
- sublabel="Select payment type"
- description="Choose your preferred payment method"
- help_text="We securely process all payment information"
- placeholder="Select payment method"
- options={[
- {"Credit Card", "credit_card"},
- {"PayPal", "paypal"},
- {"Bank Transfer", "bank_transfer"}
- ]}
-/>
-```
-
-#### Native, Searchable and Multiple
-```heex
-<.select
- name="country"
- native
- options={[{"United States", "US"}, {"Canada", "CA"}]}
-/>
-
-<.select
- name="country"
- searchable
- search_input_placeholder="Search for a country"
- search_no_results_text="No countries found for %{query}"
- options={@countries}
-/>
-
-<.select
- name="countries"
- multiple
- max={3}
- clearable
- options={[{"United States", "US"},{"Canada", "CA"},{"Mexico", "MX"}]}
-/>
-```
-
-#### Form Integration and Affixes
-```heex
-<.form :let={f} for={@changeset} phx-change="validate" phx-submit="save">
- <.select
- field={f[:country]}
- label="Country"
- options={@countries}
- />
-
-
-<.select name="category" options={@categories} placeholder="Select category">
- <:inner_prefix>
- <.icon name="hero-folder" class="icon" />
-
- <:outer_suffix>
- <.button size="md">Apply
-
-
-```
-
-#### Custom Option Rendering
-```heex
-<.select
- name="role"
- placeholder="Select role"
- options={[{"Admin", "admin"}, {"Editor", "editor"}, {"Viewer", "viewer"}]}
->
- <:option :let={{label, value}}>
-
-
-
{label}
-
- {case value do
- "admin" -> "Full access to all features"
- "editor" -> "Can create and modify content"
- "viewer" -> "Read-only access to content"
- end}
-
-```
-
-## Sheet
-
-A powerful and accessible sheet component that provides a sliding panel interface for displaying content from screen edges.
-
-### Attributes
-- `id` (string, required): The unique identifier for the sheet component
-- `open` (boolean, default: false): Whether the sheet is initially open
-- `on_close` (JS, default: %JS{}): JavaScript commands to execute when sheet closes
-- `on_open` (JS, default: %JS{}): JavaScript commands to execute when sheet opens
-- `class` (any, default: ""): Additional CSS classes for sheet content container
-- `close_on_esc` (boolean, default: true): Whether to close sheet when Escape is pressed
-- `close_on_outside_click` (boolean, default: true): Whether to close when clicking outside
-- `prevent_closing` (boolean, default: false): Prevents sheet from being closed through standard interactions
-- `hide_close_button` (boolean, default: false): Whether to hide the close button
-- `animation` (string, default: "transition duration-200 ease-in-out"): Base animation classes
-- `animation_enter` (string): Classes applied when sheet enters (auto-set based on placement)
-- `animation_leave` (string): Classes applied when sheet leaves (auto-set based on placement)
-- `backdrop_class` (string, default: ""): Additional CSS classes for backdrop overlay
-- `placement` (string, default: "left"): Edge the sheet slides from - "left", "right", "top", "bottom"
-
-### Slots
-- `inner_block` (required): The content of the sheet
-
-### Usage Examples
-
-#### Basic Client-Side Control
-```heex
-<.button phx-click={Fluxon.open_dialog("filters-sheet")}>Filters
-
-<.sheet id="filters-sheet">
-
-```
-
-#### Form Field Help and Custom Styling
-```heex
-
- <.input type="text" name="api_key" value="">
- <:inner_suffix>
- <.tooltip value="Your API key can be found in the developer settings">
- <.icon name="hero-question-mark-circle" class="text-zinc-400" />
-
-
-
-
-
-<.tooltip
- value="Draft saved"
- class="bg-green-600 text-white"
- arrow={false}
->
- <.badge>Draft
-
-
-<.tooltip value="Archived items are hidden from the main view" delay={300}>
- <.icon name="hero-archive" class="text-zinc-400" />
-
-```
-
-#### User Profile Preview
-```heex
-<.tooltip class="max-w-xs">
- <.link navigate={"/users/#{@user.id}"}>
- {@user.name}
-
-
- <:content>
-
-
{@user.name}
-
{@user.title}
-
{@user.department}
-
-
-
-```
-
+@deps/fluxon/usage-rules.md
diff --git a/mix.exs b/mix.exs
index f5dc3208..4d633c5b 100644
--- a/mix.exs
+++ b/mix.exs
@@ -176,7 +176,15 @@ defmodule MusicLibrary.MixProject do
defp usage_rules do
[
file: "AGENTS.md",
- usage_rules: :all
+ usage_rules: [
+ :elixir,
+ :otp,
+ "phoenix:all",
+ :usage_rules,
+ "usage_rules:all",
+ # link fluxon as it's HUGE
+ {:fluxon, link: :at}
+ ]
]
end
end