einar-ioc
Purpose
This skill is 100% oriented to vibe-coding: the agent scaffolds, wires, and modifies code by following these rules. Einar CLI is never used—the agent replicates its behavior manually. The Einar CLI equivalents and .einar.template.json are described only as reference so the agent understands how Einar CLI works and can produce equivalent output.
When to use
Use this skill whenever you are writing or modifying Go code that uses the github.com/Ignaciojeria/ioc library, or when you are creating APIs, event-driven components, or database adapters in a Hexagonal Architecture. When adding new components (controllers, repositories, consumers, etc.), apply the patterns from the rules—including adding blank imports to cmd/api/main.go—as if Einar CLI had scaffolded them.
[!TIP] Living Documentation: The rules in
./rules/are generated from the actual.gofiles. Read the source code inapp/adapterandapp/sharedas your primary reference—the rules reflect the template as it exists.
Quick reference
| Domain | Rule files |
|---|---|
| Einar CLI config | einar-template – template config for generators |
| Structure & main | structure, main, archetype-version |
| Configuration | configuration |
| HTTP / REST | httpserver, request-logger-middleware, fuegoapi-controllers |
| EventBus | eventbus-strategy, eventbus-gcp, eventbus-nats, consumer, publisher |
| Database | postgresql-connection, postgresql-migrations, postgres-repository |
| Observability | observability |
Dependency Injection (IoC)
All components MUST be registered in the IoC container via var _ = ioc.Register(Constructor). See any rule file (e.g. httpserver, fuegoapi-controllers) for the exact pattern.
Blank imports are critical: Each package that registers constructors MUST be imported in cmd/api/main.go via a blank import (_ "archetype/path/to/package"). Without it, the package never loads and the IoC container will not receive those constructors. When adding a new component, the agent must add the corresponding blank import—the user does not do this manually.
Einar CLI equivalents (reference only—do not run the CLI)
The following section explains how Einar CLI works so the agent can replicate it. Never execute Einar CLI commands. When the user asks for something Einar CLI would do, scaffold the equivalent manually: use the rules as templates, apply the replacements, create modular files, and add the blank import to cmd/api/main.go.
New components not in the template: The user can request components not covered by the template (e.g. a new adapter type, a custom handler). The agent may create them freely but must follow the same structure and practices as the generator: one file per component, ioc.Register, constructor injection, blank import in main.go, and consistent naming (PascalCase for types, snake_case for files). For functions that are not candidates to be registered as singletons (helpers, pure functions, utilities), create them as you see fit—adjusted to the structure and following best practices.
How Einar CLI works (template + replace)
Einar CLI generates and renames .go files guided by .einar.template.json. That file defines, per generator: source_file (template), destination_dir, replace_holders (PascalCase/SnakeCase), and ioc_discovery (add blank import). The agent must:
- Take the template from the corresponding rule (e.g. fuegoapi-controllers for get.go).
- Create a new modular file (one file per operation/entity).
- Apply PascalCase/SnakeCase replacements:
Template→{OperationName}. - Add the blank import to
cmd/api/main.go(the agent does this; the user does nothing).
Replace holders by component (see einar-template for full config)
| Component | Template placeholder | Replace with (PascalCase X = operation name) |
|---|---|---|
| get-controller | NewTemplateGet |
New{X} (e.g. NewGetUser) |
| post/put/patch-controller | NewTemplatePost, TemplatePostRequest, TemplatePostResponse |
New{X}, {X}Request, {X}Response |
| delete-controller | NewTemplateDelete |
New{X} |
| postgres-repository | NewTemplateRepository, TemplateRepository, TemplateStruct |
New{X}Repository, {X}Repository, {X} (and template_table → {x}_table) |
| pubsub-consumer | NewTemplateConsumer, TemplateConsumer, TemplateMessage, template_topic_or_hook |
New{X}Consumer, {X}Consumer, {X}Message, {x}_topic (SnakeCase) |
| publisher | NewTemplatePublisher, TemplatePublisher |
New{X}Publisher, {X}Publisher |
Commands reference
| User intent / Einar CLI command | Template rule | Output (modular files) | Blank import |
|---|---|---|---|
einar install fuego |
httpserver, request-logger-middleware | server.go, request_logger.go | _ "archetype/app/shared/infrastructure/httpserver", middleware |
einar install postgresql |
postgresql-connection, postgresql-migrations | connection.go, migrations/*.sql | _ "archetype/app/shared/infrastructure/postgresql" |
einar install gcp-pubsub |
eventbus-strategy, eventbus-gcp | gcp_*.go | _ "archetype/app/shared/infrastructure/eventbus" |
einar generate get-controller X |
fuegoapi-controllers (get.go) | get_{x}.go in fuegoapi/ |
_ "archetype/app/adapter/in/fuegoapi" |
einar generate post-controller X |
post.go | post_{x}.go |
same |
einar generate postgres-repository X |
postgres-repository | {x}_repository.go in postgres/ |
_ "archetype/app/adapter/out/postgres" |
einar generate pubsub-consumer X |
consumer | {x}_consumer.go in eventbus/ |
_ "archetype/app/adapter/in/eventbus" |
einar generate publisher X |
publisher | {x}_publisher.go in eventbus/ |
_ "archetype/app/adapter/out/eventbus" |
Constraints (from README)
- No
init()for business components. Useioc.Registerat package level instead. - No
os.Getenvin logic. Injectconfiguration.Confas a dependency. - No ORMs with auto-migrations. Schema changes go in
.sqlfiles underapp/shared/infrastructure/postgresql/migrations/. Usesqlx+golang-migrate. - Don't extract variables for testability. Avoid
var jsonMarshal = json.Marshalor injectable stubs just to reach 100% coverage. Prefer constructor injection; accept slightly lower coverage for unreachable error paths.
Rules by domain
Einar CLI / generators
- einar-template –
.einar.template.json: how Einar CLI generates and renames files
Structure and entry point
- structure – Project directory tree (
app/adapter,app/shared,cmd,scripts) - main – Entry point and
ioc.LoadDependencies() - archetype-version – Embedded
Versionfrom.versionfile
Configuration
- configuration – Environment config with caarlos0/env and godotenv
HTTP / REST (Fuego)
Use github.com/go-fuego/fuego for REST. Do not use net/http, gin, or fiber directly.
- httpserver – Fuego server, healthcheck, graceful shutdown
- request-logger-middleware – HTTP request logging
- fuegoapi-controllers – REST controller scaffold (GET, POST, PUT, PATCH, DELETE)
EventBus (CloudEvents, GCP / NATS)
- eventbus-strategy – Interfaces, factory, and strategy pattern
- eventbus-gcp – GCP Pub/Sub client, publisher, subscriber
- eventbus-nats – NATS client, publisher, subscriber
- consumer – Inbound consumer pattern
- publisher – Outbound publisher adapter
Database (PostgreSQL)
- postgresql-connection – SQLx + golang-migrate, connection lifecycle
- postgresql-migrations – Example migrations: naming (
NNNNNN_name.up/down.sql), up/down pattern - postgres-repository – Repository pattern with sqlx and go-sqlmock
Observability
- observability – OpenTelemetry, slog injection, context propagation