Skip to content

Generators & CLI

Protege ships Rails generators for everything you scaffold — the initial install, each extension type, and the self-hosted mail server — plus three rake tasks. This page is the reference for each.

protege:install

The one command that takes a host app from gem "protege" to a runnable dashboard.

bash
bin/rails g protege:install

It does the wiring it can do safely, and prints the rest as next steps. Specifically, it:

  • Installs the Rails frameworks Protege builds on — Active Storage (attachments) and Action Mailbox (inbound mail; this also creates app/mailboxes/application_mailbox.rb).
  • Writes config/initializers/protege.rb — a fully-documented initializer with ENV-backed defaults.
  • Mounts the engine at /protege, with a loud TODO to wrap the mount in your own authentication — the engine ships none.
  • Wires the Loop's recurring tick into config/recurring.yml (protege_responsibility_tick, every minute) for both production and development. Idempotent — a second run is a no-op.
  • Scaffolds a starter ExecutiveAgent so there's something to route mail to.

The steps it deliberately leaves to you — running migrations, wrapping the mount in auth, setting provider credentials, enabling eager_load in development — are printed at the end.

Extension generators

Five generators scaffold the extension surfaces — one per extension type, plus protege:agent. Each writes a correctly-shaped starter file into the configured path and applies the type suffix idempotently (see below).

protege:tool

bash
bin/rails g protege:tool lookup_order

Scaffolds a Protege::Tool subclass into config.tools_path (default app/tools). Loading the subclass registers the tool in the manifest, but registration alone grants nothing — an agent can use it only through a toolkit attached to that agent. Run bin/rails protege:toolkits:sync to fold the new tool into the All Tools system toolkit.

protege:resolver

bash
bin/rails g protege:resolver customer_context

Scaffolds a Protege::Resolver subclass into config.resolvers_path (default app/resolvers). Resolvers are not auto-discovered — add the new one to an agent's chain.

protege:hook

bash
bin/rails g protege:hook refund_audit

Scaffolds a Protege::Hook subclass into config.hooks_path (default app/hooks). Hooks are auto-discovered and wired to the event bus at boot.

protege:provider

bash
bin/rails g protege:provider scoop_llm

Scaffolds a Protege::Provider subclass into config.providers_path (default app/providers), with a protege_id derived from the name. Activate it by pointing config.provider_id at that id.

protege:agent

bash
bin/rails g protege:agent customer_service

Scaffolds a Protege::Agent subclass into config.agents_path (default app/agents). Remember the class is the rolecustomer_service becomes CustomerServiceAgent — and the individual agent (Sundae) is a record you create from it. See Agents.

The type-suffix rule

The extension generators apply their type suffix idempotently, so you can name a generation however reads best and get the same result. All three of these produce class SendEmailTool in send_email_tool.rb:

bash
bin/rails g protege:tool send_email
bin/rails g protege:tool SendEmail
bin/rails g protege:tool SendEmailTool

The same holds for Resolver, Hook, Provider, and Agent suffixes.

protege:postfix

Scaffolds a self-hosted Postfix + OpenDKIM mail server you run yourself, for hosts that want no email provider in the loop.

bash
bin/rails g protege:postfix

It vendors the container build into deploy/mail/ (Dockerfile, Postfix/OpenDKIM/OpenDMARC config, the provisioning listener, and a full MAIL.md deploy guide), plus a Kamal accessory example and a GitHub Actions workflow to build the image. The files are copied verbatim — runtime values are substituted at container start. See Mail transport for the full deployment path.

rake protege:setup:dev

bash
bin/rails protege:setup:dev

One command from protege:install to a first conversation. Provisions everything a development environment needs except the provider API key: syncs the system toolkits, registers the protege.local email domain, generates the ExecutiveAgent class if the app doesn't have one (through the same protege:agent generator the installer uses), creates Phoenix — an ExecutiveAgent at phoenix@protege.local with starter instructions — and attaches All Tools with an open gate and scheduled-runs use enabled, so every registered tool is exercisable.

Idempotent, and it refuses to run outside the development environment (it seeds play data). When it finishes, set your API key, bin/dev, and message Phoenix from the Inbox.

rake protege:toolkits:sync

bash
bin/rails protege:toolkits:sync

Creates and maintains the two system toolkits: All Tools is rewritten to mirror the full tool registry, so a tool added in code shows up automatically; Default Tools — auto-attached to every new agent — is created once (seeded with every engine built-in tool) and its membership is then left to you to curate. The task eager-loads the app first so the tool manifest is complete, and it's idempotent — run it on every deploy, after db:migrate. To run the same sync from db/seeds.rb, call Rails.application.eager_load! and then Protege::SystemToolkits.sync!.

rake protege:css:build

bash
bin/rails protege:css:build

Rebuilds the engine's compiled Tailwind CSS (app/assets/builds/protege.css) from the engine's views and helpers. It needs tailwindcss-rails in the host. You only need this if you're modifying the engine's own views — a normal host app never runs it.

  • Extensions — what each extension generator scaffolds.
  • Toolkits — the system toolkits protege:toolkits:sync maintains.
  • Configuration — the initializer protege:install writes.
  • Mail transport — deploying what protege:postfix scaffolds.