Install
$ agentstack add skill-linux-root-scala-zio-skills-zio-reference ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
ZIO Coding Reference
You are an expert Scala/ZIO developer. Follow these rules strictly when generating ZIO code.
Core Concepts
- ZIO[R, E, A]: Immutable effect description.
R= environment (contravariant),E= error (covariant),A= success (covariant). Effects are descriptions, not running computations. - Fibers: Lightweight virtual threads managed by ZIO runtime. Millions can run concurrently. Fork starts one, join awaits it.
- ZLayer: Recipe for constructing services from dependencies with effectful init/finalize. Automates dependency graph wiring.
- Scope: Resource lifetime manager. Finalizers run on success, failure, or interruption.
- Typed Errors vs Defects:
Echannel = expected domain failures (compiler-checked). Defects = unexpected bugs captured inCause, not inE.
> Deep dive: references/core-concepts.md
Coding Rules
Error Handling
> Deep dive: references/error-handling-deep-dive.md
- Model domain errors as sealed trait ADTs:
sealed trait UserError; case class NotFound(id: UUID) extends UserError - Use
ZIO.fail(NotFound(id))notZIO.fail(new Exception("not found")) - Use
orDieto shiftThrowableto defect channel when unrecoverable:ZIO.attempt(expr).orDie - Use
refineToOrDie[SpecificError]to keep one error type, defect the rest - Never swallow defects:
effect.tapDefect(c => ZIO.logErrorCause("Unexpected", c))noteffect.catchAllDefect(_ => ZIO.unit) - Use
mapErrorto unify error hierarchies across layers - Use
catchAllfor recovery,foldZIOfor transforming both paths - Low-level: broad errors (
IOException). High-level: refined domain ADTs or defects. - Use
Eitheronly when errors are unrelated and you want to avoid wideningEtoAny
Composition
- For-comprehensions for sequential composition:
``scala for { user (zipRight) / runTask ``
Dependencies (Service Pattern)
- Trait defines interface (methods return
IO[E, A]withR = Any) - Case class implements trait, receives dependencies via constructor
- Companion object provides
ZLayer
trait Greeter { def sayHello(name: String): UIO[Unit] }
case class GreeterLive(console: Console) extends Greeter {
def sayHello(name: String): UIO[Unit] = console.printLine(s"Hello, $name!").orDie
}
object Greeter {
val layer: URLayer[Console, Greeter] = ZLayer.derive[GreeterLive]
}
Resources
- Always use
ZIO.acquireReleaseorZIO.acquireReleaseWith, neverensuringfor resource cleanup - Use
ZIO.scopedfor narrowest possible resource lifetime:
``scala ZIO.scoped { ZIO.acquireRelease(open)(r => ZIO.succeed(r.close())).flatMap(use) } ``
Concurrency
> Deep dive: references/concurrency-and-fiber.md
- Prefer
foreachPar,zipPar,raceover manualfork/join - Always
joinorinterruptany manually forked fiber - Use
ZIO.attemptBlockingorZIO.attemptBlockingIOfor blocking I/O, neverZIO.attempt - Use
ZIO.uninterruptibleMask(restore => setup *> restore(task) *> cleanup)for custom operators - Use
Reffor single atomic state,STM/TReffor multi-variable transactional updates - Don't wrap monolithic loops in
ZIO.succeed— runtime can't interrupt inside them
Anti-Patterns (Never Do These)
> Deep dive: references/anti-patterns.md
| Anti-Pattern | Correct | |---|---| | Task[A] for business logic | IO[DomainError, A] with sealed trait ADT | | val f = api(); ZIO.fromFuture(_ => f) | ZIO.fromFuture(ec => api()(ec)) | | trait Svc { def get: ZIO[Database, E, A] } | case class LiveSvc(db: Database) extends Svc { def get: IO[E, A] } | | acquire.flatMap(r => use(r).ensuring(release(r))) | ZIO.acquireReleaseWith(acquire)(release)(use) | | ZIO.attempt(blockingIOCall()) | ZIO.attemptBlockingIO(blockingIOCall()) | | effect.catchAllDefect(_ => ZIO.unit) | effect.tapDefect(c => ZIO.logErrorCause("err", c)) | | effect.fork *> ZIO.unit | effect.fork.flatMap(_.join) or use structured concurrency | | ZIO.succeed(while(true) { ... }) | Recursive ZIO effect or .forever | | object Svc { def method(a: A): ZIO[Svc, E, B] = ZIO.serviceWithZIO(_.method(a)) } | Call ZIO.serviceWithZIO[Svc](_.method(a)) directly at call sites |
Decision Guide: Which Abstraction?
> Deep dive: references/when-to-use-what.md
| Need | Use | Not | |---|---|---| | Service wiring + lifecycle | ZLayer | Manual instance passing | | Single shared mutable state | Ref | var, AtomicReference | | Multi-variable atomic updates | STM / TRef | Multiple Ref updates | | Work distribution (one consumer per item) | Queue | Hub | | Broadcast (all consumers get every item) | Hub | Queue | | Retry with backoff / repeat on schedule | Schedule | Manual recursion | | One-shot synchronization between fibers | Promise | Queue, Ref | | Limit concurrent access | Semaphore | Manual counting | | Incremental / infinite data processing | ZStream | ZIO returning List | | Resource with finalization | Scope + acquireRelease | ensuring | | Low-level fiber control | Fiber + fork | Default; prefer foreachPar/zipPar |
Key Patterns
> More patterns: references/minimal-working-patterns.md | references/idioms.md
Service Pattern (Repository variant)
trait UserRepo { def findById(id: UUID): IO[RepoError, Option[User]] }
case class PostgresUserRepo(ds: DataSource) extends UserRepo {
def findById(id: UUID): IO[RepoError, Option[User]] =
ZIO.attemptBlocking(query(ds, id)).mapError(DbError(_))
}
object UserRepo {
val layer: ZLayer[DataSource, Nothing, UserRepo] = ZLayer.derive[PostgresUserRepo]
}
Background Worker
def startWorker(queue: Queue[Job]): ZIO[Any, Nothing, Fiber.Runtime[Nothing, Nothing]] =
queue.take.flatMap(job => process(job).ignoreLogged).forever.forkDaemon
Retry with Backoff
val policy = Schedule.exponential(1.second) && Schedule.recurs(5)
ZIO.attempt(unstableCall()).retry(policy)
Parallel with Limit
ZIO.foreachPar(urls)(fetch).withParallelism(10)
HTTP Route (ZIO HTTP)
val route: Route[UserRepo, Nothing] =
Method.GET / "users" / uuid("id") -> handler { (id: UUID, req: Request) =>
ZIO.serviceWithZIO[UserRepo](_.findById(id)).map {
case Some(user) => Response.json(user.toJson)
case None => Response.notFound
}.orDie
}
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: linux-root
- Source: linux-root/scala-zio-skills
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.