add-port-adapter
Add or extend a driven port and its adapter in agent-office's hexagonal core — storage/persistence, OS integration, clock/scheduling, external services, a new notification channel. Use whenever the co
SKILL.md.claude/skills/add-port-adapter/SKILL.md
GitHubAdd a driven port and adapter
Rules: ARCHITECTURE.md (ports are additive; only the composition root knows concrete classes), TESTING.md (TDD; contract suites are mandatory).
- Can an existing port do it? Check
packages/core/src/ports/driven.tsfirst. Prefer a new, narrow port over growing an existing one, and never change an existing method's signature. - Red: contract suite. Add
xxxContract(name, make)inpackages/core/test/contracts/. It describes the behavior every implementation must have: round trips, errors as domain errors (ValidationError, …), idempotency and isolation. - Fake. Add a fake or recording implementation to
packages/core/test/fakes/index.tsand run it through the contract inpackages/core/test/fakes.test.ts. - Use case. Write a failing test in
core/src/application/*.test.tsusing the fake, then implement it so it depends on the port only. Wire it intocreateOffice(OfficeDeps) if it's office-wide. - Real adapter.
- Node:
packages/adapters/src/<area>/. Electron:packages/desktop/src/main/adapters/electron-*.ts. - Run the same contract suite against it, using temp dirs and never real user files.
- Node:
- Wire it in
packages/desktop/src/main/composition.ts(Electron objects come in throughShell, built inindex.ts). Extendcomposition.test.ts. make arch(the dependency rule) andmake check. For Electron adapters, alsomake build test-ui.