General
hanami-workflow - Claude MCP Skill
Hanami framework workflow guidelines. Activate when working with Hanami projects, Hanami CLI, or Hanami-specific patterns.
SEO Guide: Enhance your AI agent with the hanami-workflow tool. This Model Context Protocol (MCP) server allows Claude Desktop and other LLMs to hanami framework workflow guidelines. activate when working with hanami projects, hanami cli, or han... Download and configure this skill to unlock new capabilities for your AI workflow.
Documentation
SKILL.mdThe key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.
# Hanami Workflow
## Tool Grid
| Task | Tool | Command |
|------|------|---------|
| Lint | StandardRB | `bundle exec standardrb` |
| Test | RSpec | `bundle exec rspec` |
| Console | Hanami CLI | `bundle exec hanami console` |
| Server | Hanami CLI | `bundle exec hanami server` |
| Generate | Hanami CLI | `bundle exec hanami generate <type>` |
| DB Migrate | Hanami CLI | `bundle exec hanami db migrate` |
| Routes | Hanami CLI | `bundle exec hanami routes` |
## Slices Architecture
Hanami applications MUST be organized into isolated slices (`slices/admin/`, `slices/api/`, `slices/main/`).
- Each slice MUST have its own container and dependencies
- Slices SHOULD NOT directly depend on other slices
- Cross-slice communication SHOULD use explicit interfaces or events
- Shared code MUST live in `lib/` or `app/` (application layer)
```ruby
# slices/admin/config/slice.rb
module Admin
class Slice < Hanami::Slice
import keys: ["persistence.rom"], from: :main
end
end
```
## Dependency Injection via Deps
Hanami uses dry-system for dependency injection. All dependencies MUST be injected, not hardcoded.
```ruby
module Main::Actions::Books
class Show < Main::Action
include Deps["repositories.book_repository"]
def handle(request, response)
book = book_repository.find(request.params[:id])
response.body = book.to_json
end
end
end
```
- MUST use `include Deps[...]` for injecting dependencies
- SHOULD prefer constructor injection for testability
- MUST NOT use global state or singletons directly
## Entities, Relations, and Repositories (ROM)
Hanami uses ROM (Ruby Object Mapper) for persistence.
### Entities
Entities MUST be simple domain objects without persistence logic.
```ruby
module MyApp::Entities
class Book < Hanami::Entity
attribute :id, Types::Integer
attribute :title, Types::String
end
end
```
### Relations
Relations MUST define the database schema mapping.
```ruby
module MyApp::Relations
class Books < Hanami::DB::Relation
schema :books, infer: true do
associations { belongs_to :author; has_many :reviews }
end
end
end
```
### Repositories
Repositories MUST encapsulate all persistence operations.
```ruby
module MyApp::Repositories
class BookRepository < Hanami::DB::Repo
def find(id) = books.by_pk(id).one
def published = books.where { published_at <= Date.today }.to_a
def create(attrs) = books.changeset(:create, attrs).commit
end
end
```
- Repositories MUST NOT expose ROM internals to actions
- Relations SHOULD use `infer: true` when schema matches database
- Changesets SHOULD be used for create/update operations
## Validation with dry-validation
Input validation MUST use dry-validation contracts.
```ruby
module Main::Contracts::Books
class Create < Hanami::Action::Contract
params do
required(:title).filled(:string, min_size?: 1)
required(:author).filled(:string)
optional(:published_at).maybe(:date)
end
rule(:title) do
key.failure("must be unique") if BookRepository.new.exists?(title: value)
end
end
end
```
- Contracts MUST validate all external input
- Params SHOULD define type coercion
- Error messages MUST be user-friendly
## Actions
Actions MUST be single-purpose request handlers.
```ruby
module Main::Actions::Books
class Create < Main::Action
include Deps["repositories.book_repository"]
contract Contracts::Books::Create
def handle(request, response)
result = request.params
if result.valid?
book = book_repository.create(result.to_h)
response.status = 201
response.body = book.to_json
else
response.status = 422
response.body = { errors: result.errors.to_h }.to_json
end
end
end
end
```
- Each action MUST handle exactly one request type
- Actions MUST use contracts for input validation
- Actions SHOULD delegate business logic to interactors/services
## Views and Templates
Views MUST separate presentation logic from templates.
```ruby
module Main::Views::Books
class Show < Main::View
expose :book do |book:|
BookPresenter.new(book)
end
end
end
```
```erb
<%# slices/main/templates/books/show.html.erb %>
<article>
<h1><%= book.title %></h1>
<p>By <%= book.author %></p>
</article>
```
- Views MUST use `expose` for passing data to templates
- Templates SHOULD contain minimal logic
- Presenters SHOULD format data for display
## Configuration
```ruby
# config/app.rb
module MyApp
class App < Hanami::App
config.actions.content_security_policy[:script_src] = "'self'"
config.logger.level = :info
end
end
# slices/api/config/slice.rb
module Api
class Slice < Hanami::Slice
config.actions.format :json
config.actions.default_response_format = :json
end
end
```
- Sensitive config MUST use environment variables
- Per-slice config SHOULD override app defaults only when needed
## Testing Patterns
```ruby
# Action test - mock dependencies
RSpec.describe Main::Actions::Books::Show do
subject(:action) { described_class.new(book_repository: repository) }
let(:repository) { instance_double(BookRepository) }
it "returns book" do
allow(repository).to receive(:find).with(1).and_return(Book.new(id: 1))
expect(action.call(id: 1).status).to eq(200)
end
end
# Repository test - real database
RSpec.describe BookRepository, type: :database do
it "finds published" do
subject.create(title: "Old", published_at: Date.today - 30)
expect(subject.published.map(&:title)).to eq(["Old"])
end
end
```
- Actions MUST be tested with mocked dependencies
- Repositories SHOULD be tested against real database
## Interactor/Service Pattern
```ruby
module MyApp::Interactors::Books
class Publish
include Deps["repositories.book_repository", "events.publisher"]
def call(book_id)
book = book_repository.find(book_id) or return Failure(:not_found)
updated = book_repository.update(book_id, published_at: Date.today)
publisher.publish("book.published", book_id: book_id)
Success(updated)
end
end
end
```
- Services SHOULD return Result objects (Success/Failure)
- Actions SHOULD use `halt` for error responsesSignals
Information
- Repository
- ilude/claude-code-config
- Author
- ilude
- Last Sync
- 3/13/2026
- Repo Updated
- 2/15/2026
- Created
- 1/12/2026
Reviews (0)
No reviews yet. Be the first to review this skill!
Related Skills
mem0
Integrate Mem0 Platform into AI applications for persistent memory, personalization, and semantic search. Use this skill when the user mentions "mem0", "memory layer", "remember user preferences", "persistent context", "personalization", or needs to add long-term memory to chatbots, agents, or AI apps. Covers Python and TypeScript SDKs, framework integrations (LangChain, CrewAI, Vercel AI SDK, OpenAI Agents SDK, Pipecat), and the full Platform API. Use even when the user doesn't explicitly say "mem0" but describes needing conversation memory, user context retention, or knowledge retrieval across sessions.
upgrade-nodejs
Upgrading Bun's Self-Reported Node.js Version
cursorrules
CrewAI Development Rules
cn-check
Install and run the Continue CLI (`cn`) to execute AI agent checks on local code changes. Use when asked to "run checks", "lint with AI", "review my changes with cn", or set up Continue CI locally.
Related Guides
Bear Notes Claude Skill: Your AI-Powered Note-Taking Assistant
Learn how to use the bear-notes Claude skill. Complete guide with installation instructions and examples.
Mastering tmux with Claude: A Complete Guide to the tmux Claude Skill
Learn how to use the tmux Claude skill. Complete guide with installation instructions and examples.
OpenAI Whisper API Claude Skill: Complete Guide to AI-Powered Audio Transcription
Learn how to use the openai-whisper-api Claude skill. Complete guide with installation instructions and examples.