@codectyl/agnostic-core owns the external seams of the system. Each seam is a
vendor-neutral port such as StoragePort or AuthPort.
An adapter satisfies a port. Adapters contain SDK imports, connection setup, query details, serialization choices, and vendor-specific error handling.
@codectyl/agnostic-adapter-* ──depends on──> @codectyl/agnostic-core
Core never imports an adapter or a vendor SDK.
@codectyl/agnostic-core contains AuthPort, CachePort, QueuePort, StoragePort,
FileReference, and FileReferenceSchema. It also contains the dependency-free
InMemoryCache and LocalAsyncQueue implementations.
StoragePort operates on paths. Bucket names, namespaces, and other storage
layout decisions belong to the adapter configuration rather than the core
interface.
The Port suffix identifies a contract. Concrete classes should use a name
such as SupabaseStorageAdapter.
Use one package per meaningful vendor or infrastructure dependency:
packages/adapter-supabase → @codectyl/agnostic-adapter-supabase
packages/adapter-redis → @codectyl/agnostic-adapter-redis
packages/adapter-s3 → @codectyl/agnostic-adapter-s3
Do not create an adapter package for code with no external dependency that can be shared safely from core. Examples include local caches and queues.
- Confirm the behavior varies by vendor or external dependency.
- Add
@codectyl/agnostic-adapter-<vendor>as a workspace package. - Depend on
@codectyl/agnostic-corethrough the workspace protocol. - Implement one or more core ports with explicit adapter classes.
- Keep vendor types at the adapter edge and return core types.
- Add contract tests for the selected port.
- Document configuration, lifecycle, errors, and unsupported operations.
There is currently no database port. Persistence contracts should be added only when the domain entities and operations are defined clearly enough to make a useful vendor-neutral interface. Do not add a generic pass-through database client to core.