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.
Styling 1 of 6
// 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"
direction right group EscalationTeam "Human escalation": EscalationLead SeniorAnalyst ForensicsAnalyst CommsLead row MainFlow: Sensors DetectionHub Triage Sensors: box "Telemetry\nsensors" DetectionHub: box "Detection hub" Triage: box "Automated triage" AutoContain: box "Automated\ncontainment" EscalationLead: box "Escalation lead" SeniorAnalyst: box "Senior incident analyst" ForensicsAnalyst: box "Forensics and evidence analyst" CommsLead: box "Communications and stakeholder lead" Sensors -> DetectionHub "alerts" DetectionHub -> Triage "auto triage" DetectionHub -> AutoContain "contain" DetectionHub -> EscalationLead "escalate" EscalationLead -> SeniorAnalyst "assign" EscalationLead -> ForensicsAnalyst "collect evidence" EscalationLead -> CommsLead "notify stakeholders"
direction right Checkout: box "Checkout API" Payment: box "Payment service" Inventory: box "Inventory service" Fraud: box "Fraud screening" Notify: box "Notification service" Checkout -> Payment "authorize" Payment -> Checkout "auth result" Checkout -> Inventory "reserve" Inventory -> Checkout "stock result" Checkout -> Fraud "screen" Fraud -> Checkout "risk score" Checkout -> Notify "enqueue" Notify -> Checkout "receipt sent"
direction right row Pipeline: Commit Build Test Review Merge Commit: box "Commit" Build: box "Build" Test: box "Test suite" Review: box "Code review" Merge: box "Merge" Commit -> Build "trigger" Build -> Test "artifacts" Test -> Review "report" Review -> Merge "approve" Test -> Commit "failures" route above Review -> Commit "changes requested" route above
Compiler pipeline 6 of 6
direction down column CompilerPath: Source LA P Sem column Correctors: LC Syn DMP row LexicalRepair: LA LC row SyntaxRepair: P Syn row Diagnostics: Sem DMP ST Source: text "source\ncode" LA: box "lexical\nanalyzer" P: box "parser" Sem: box "semantic\nchecker" LC: box "lexical\ncorrector" Syn: box "syntactic\ncorrector" DMP: box "diagnostic\nmessage\nprinter" ST: box "symbol\ntable" Source -> LA "source" LA -> P "tokens" P -> Sem "AST" LC <-> LA "lexical repair" Syn <-> P "syntax repair" Syn -> DMP "diagnostics" DMP <-> ST "lookup" LC -> DMP "messages" Sem -> DMP "messages" Sem <-> ST "symbols"
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.