A small text language with a constraint solver. When a preference is dropped, the editor marks the statement's source span with a warning.
use icons aws Users: icon aws:users "Users" ChatClient: icon aws:client "Chat client" MainRegion: [ ApiGateway: icon aws:amazon-api-gateway "Amazon\nAPI Gateway" Lambda: icon aws:aws-lambda "AWS\nLambda" Rekognition: icon aws:amazon-rekognition "Amazon\nRekognition" ] "AWS Region" Users -> ChatClient "(1)" ChatClient -> ApiGateway "(2)" ApiGateway -> Lambda "(3)" Lambda <-> Rekognition "(4)" Lambda -> ChatClient "(5)"
Combine icons from ten packs, styled fills, nested groups, and routed connectors while a constraint solver lays it all out for you.
// The load balancer only talks to the app server; the app server owns both stores. // Ideal rendering: tiers side by side, LB above App, and App's two outbound // edges reaching the data tier as separate, non-crossing runs. column Web: LB App column Data: PG Cache Web: [ LB: box "Load Balancer" fill #dbeafe stroke #2563eb App: box "App Server" fill #dbeafe stroke #2563eb ] "Web Tier" fill #2563eb bold Data: [ PG: box "Postgres" fill #dcfce7 stroke #16a34a Cache: box "Redis" fill #fef9c3 stroke #ca8a04 ] "Data Tier" fill #16a34a bold LB -> App App -> PG "SQL" App -> Cache "cache"
direction down require column MainSpine: Start Authn Authz Ok require row AuthenticationReject: Authn Unauth require row AuthorizationReject: Authz Forbid // Two gates that fail differently: 401 means "we don't know who you are", // 403 means "we know, and no". Collapsing them into one check is the usual // bug in a hand-drawn auth flow. // // A column keeps the successful path easy to scan; two rows peel each rejection // away from the main decision spine. Start: box "Request" Authn: box "Authenticated?" fill #fef08a Authz: box "Authorized?" fill #fef08a Out: [ Unauth: box "401 Unauthorized" fill #fee2e2 Forbid: box "403 Forbidden" fill #fee2e2 Ok: box "200 OK" fill #dcfce7 ] "Outcomes" Start -> Authn Authn -> Unauth "no" Authn -> Authz "yes" Authz -> Forbid "no" Authz -> Ok "yes"
Say what is in the diagram and how it connects; the solver places it. Write a constraint only where you mean one; when two of them cannot both hold, SheepText tells you which.