Pack catalog
Every pack ships inside the CLI, so there is one install and nothing else to add:
npm install --save-dev @suss/cliSixty-two packs read code today, across fifty-one frameworks, eight HTTP and GraphQL clients, and the Node runtime. Ten contract readers turn a declared artifact into summaries in the same format. @suss/contract-intent reads the intent documents your team writes, separately from all of those.
Most of that is TypeScript and JavaScript. Four of the packs read another language: flask-restx and FastAPI read Python through @suss/adapter-python, and graphql-ruby and rails read Ruby through @suss/adapter-ruby. suss extract runs those two adapters as well, and the Python and Ruby guide shows how.
The quickest way to find your packs is to let suss look:
suss initIt reads your dependencies, tells you which packs match, and offers to write them into suss.json. The add-to-project guide goes through the whole setup.
What to run, by stack
The first column of every table below is the name -f takes, and -f is repeatable. suss contract --from <source> reads a declared artifact, so there is no pack for one.
| Stack | What to run |
|---|---|
| ts-rest full-stack | -f ts-rest, which reads the provider and the client through the contract |
| Hono and fetch | -f hono -f fetch |
| Express and fetch | -f express -f fetch |
| Next.js route handlers | -f nextjs |
| React and GraphQL | -f react -f apollo-client |
| Lambda and SQS | -f aws-sqs -f node, and contract --from cloudformation |
| BullMQ workers and the code that adds jobs | add -f bullmq |
| Cloudflare Worker | -f cloudflare-workers, and contract --from wrangler |
| Postgres through Prisma | add -f prisma, and contract --from prisma |
| Postgres through Drizzle | add -f drizzle |
| MongoDB through Mongoose | add -f mongoose |
| NestJS with TypeORM repositories | add -f typeorm |
Frameworks
A framework pack finds the units a framework defines: a route handler, a component, a resolver, a queue consumer. Run one of these and suss extract has something to describe.
| Name | What it reads | Coverage |
|---|---|---|
activejob | ActiveJob jobs and ActionMailer messages (Ruby): each job's perform and each mailer method is a consumer of an activejob channel, and perform_later or deliver_later a send to it. | |
apollo | Apollo Server resolvers (code-first). | |
aws-lambda | AWS Lambda HTTP handlers, paired with the routes a SAM template or serverless.yml declares. | |
aws-lambda-python | AWS Lambda handlers written in Python, found from the Handler a SAM template or serverless.yml gives each function. | |
aws-lambda-ruby | AWS Lambda handlers written in Ruby, found from the Handler a SAM template or serverless.yml gives each function, including a class method written file.Module::Class.method. | |
bullmq | BullMQ workers and queues: each worker's processor is a consumer on its queue, and each add to a queue is a message send on it. | |
celery | Celery tasks (Python). A function under @app.task or @shared_task is the consumer of its task, and .delay, .apply_async and send_task are sends to it, so a route that enqueues a task reaches what the task does. | |
cloudflare-workers | A Cloudflare Workers entrypoint: one unit per trigger the default export defines, and the bindings its code reads off the argument they arrive in. | |
express | Express handlers. | |
fabrication | Fabrication builds in tests (Ruby), typed by the class each fabricator builds, so a test's calls on them are followed. | |
factory-bot | factory_bot builds in tests (Ruby), typed by the class each factory builds, so a test's calls on them are followed. | |
fastapi | FastAPI routes (Python). The verb comes from the decorator's attribute name, APIRouter prefixes are composed one include_router hop deep, and response_model and status_code are taken as the declared contract. | |
fastify | Fastify handlers. | |
flask-restx | flask-restx Resource routes (Python), including a project's own wrapper module that re-exports the route decorator. | |
graphql-ruby | graphql-ruby class-based field DSL (Ruby). The pack follows mutation: and resolver: wiring to the referenced class, wherever the run declares it, and reads its arguments, its payload, its resolve method and the ready? and authorized? hooks that run first. It follows resolver_method: to the type's own method. Each path through that method records what the field returns, from its declared type with null where the schema allows it and the object type's fields, and the errors it raises or returns. It also records the model a resolver reads through dataloader, when a storage pack in the run recognizes that model. | |
hono | Hono handlers, including the c.json(body, status) argument order. | |
minitest | Minitest and Rails test cases (Ruby), named by class and test method, so a PRD scenario can say which test covers it. | |
nestjs-graphql | NestJS GraphQL resolvers. | |
nestjs-microservices | NestJS microservice handlers: @EventPattern and @MessagePattern consumers on the channel the decorator states. | |
nestjs-rest | NestJS REST controllers. | |
nextjs | Next.js route handlers, pages and server actions. The route comes from where the file is on disk, and a "use server" function becomes an action unit. | |
package-exports | The boundary between packages in one workspace: public exports on the provider side, and imports of them on the consumer side. The pack reads the workspace manifest, so nobody has to list the packages for each project. | |
pytest | pytest tests (Python), named by their node ids, so a PRD scenario can say which test covers it. | |
rails | Rails controller actions (Ruby), bound to the method and path config/routes.rb gives each one. An action the routes file does not reach is still discovered, with no boundary. The YAML files under config/ that Rails renders through ERB at boot are read as code that runs when the app loads. | |
react | React function components, event handlers and useEffect bodies. | |
react-query | TanStack Query hooks. The pack links a component to the query function that its useQuery or useMutation call runs. | |
react-router | React Router loaders, actions and routes. | |
rspec | RSpec examples, named by their group titles, so a PRD scenario can say which test covers it. | |
sidekiq | Sidekiq jobs (Ruby): each job's perform is a consumer of a sidekiq channel, and perform_async, perform_in or perform_at a send to it. | |
ts-rest | ts-rest handlers and clients, and the contract both sides are built from. | |
vitest | vitest cases, named by their titles, so a PRD scenario can say which test covers it. |
Clients
A client pack finds the call sites on the other side and binds each one to the method and path it sends. The checker uses that binding to pair a call with whatever serves the route.
| Name | What it reads | Coverage |
|---|---|---|
aiohttp | aiohttp call sites (Python): the request methods on a ClientSession, opened with async with or held in an assignment. | |
apollo-client | @apollo/client hooks and imperative client.query calls. | |
axios | axios call sites, including calls on a client that axios.create made. | |
faraday | Faraday call sites (Ruby): a request method on the module itself or on a connection Faraday.new built, served under the path that connection's own URL states. | |
fetch | Global fetch call sites. | |
httpx | httpx call sites (Python): the verb functions, httpx.request, and a Client or AsyncClient held in an assignment or opened with with. | |
net-http | Net::HTTP call sites (Ruby): the module methods that send on their own, and a request object built with Net::HTTP::Get and its siblings, with the URL read through URI. | |
requests | requests call sites (Python): the seven verb functions, requests.request, and a Session, each bound to the method and path the call states. |
What your code reaches
An effects pack reads the calls inside a unit another pack discovered: a query, a publish, a read of the environment. On its own it comes back empty, so run it alongside the pack that finds the units.
| Name | What it reads | Coverage |
|---|---|---|
activerecord | ActiveRecord calls (Ruby): a call matches when its method is one ActiveRecord defines as a read or a write and the class behind its receiver reaches ActiveRecord::Base, following what each class extends through the project. Statements the project wrote itself are read for the tables they touch, whether they went through find_by_sql and count_by_sql or through the connection. A write also runs the model's callbacks, and what they reach is recorded on the body that did the write. | |
aws-dynamodb | AWS SDK v3 DynamoDB calls. Each one becomes a storage-access interaction. | |
aws-eventbridge | AWS EventBridge PutEvents producer calls. Each one becomes a message-bus interaction. | |
aws-s3 | AWS SDK v3 S3 object calls. Each one becomes a storage-access interaction. | |
aws-secrets-manager | AWS Secrets Manager calls. Each one becomes a storage-access interaction on the secret. | |
aws-sns | AWS SDK v3 SNS Publish and PublishBatch calls. Each one becomes a message-send interaction on the topic. | |
aws-sqs | AWS SDK v3 SQS producer calls. Each one becomes a message-send interaction. | |
aws-ssm | AWS SSM Parameter Store calls. Each one becomes a storage-access interaction on the parameter. | |
bigquery | BigQuery queries and table calls. Each one becomes a storage-access interaction scoped to its dataset. | |
bigquery-python | BigQuery calls (Python). The statement a client or an Airflow hook is handed is read for the tables it touches. Calls such as get_table and insert_rows take a table name instead of SQL, and that name is read too. | |
bigquery-ruby | google-cloud-bigquery calls (Ruby): a call matches when its receiver follows back to a client the gem handed out, and the statement it was given is parsed for the tables it touches. | |
drizzle | Drizzle ORM query-builder and relational-query calls. Each one becomes a storage-access interaction on the SQL table it touches. | |
gcs | Google Cloud Storage calls. Each one becomes a storage-access interaction. | |
mongoose | Mongoose model calls. Each one becomes a storage-access interaction on the collection that the model's .model(...) call declares. | |
node | Node.js runtime primitives, scheduling and the process surface, each recorded as an interaction effect. A process.env.X or import.meta.env.X read, or a key of a schema parsed against either, becomes a config-read interaction. A module-loading global becomes a metadata-read interaction. A console call or a write to process.stdout or process.stderr becomes a stream-write interaction on the stream it goes to. | |
pg | node-postgres queries. Each one becomes a storage-access interaction on the tables its statement touches. | |
pg-ruby | pg gem calls (Ruby): a call matches when its receiver follows back to a connection the gem handed out, and the statement it was given is parsed for the tables it touches. | |
prisma | Prisma client calls. Each read and each write becomes a storage-access interaction. | |
redis | Redis, Valkey and node-redis commands. Each one becomes a storage-access interaction. | |
sqlalchemy | SQLAlchemy calls (Python). The pack declares which types a query returns and which methods write. The adapter matches a call chain by following a project's own base class to the method behind the call, and reads that method's declared return type. | |
sqlmodel | SQLModel calls (Python). The pack declares which types a query returns and which methods write, under the modules SQLModel exports them from. It also includes the SQLAlchemy patterns, since a SQLModel project reaches those too. | |
typeorm | TypeORM repositories that NestJS injects with @InjectRepository. Each read and write becomes a storage-access interaction on the entity's table, and a query on an injected data source or entity manager is read as SQL. | |
zustand | zustand stores: setState writes and getState reads against the store as a client-side container. |
Contract sources
These are not packs. A contract source reads something the project already declares and writes the same summaries the extractor writes, and you reach it through suss contract --from <name>. Contract sources shows a command and its output for each one.
| Reader | --from | What it reads | Coverage |
|---|---|---|---|
@suss/contract-openapi | openapi | An OpenAPI 3.x document, JSON or YAML. | |
@suss/contract-graphql | graphql, graphql-documents | A GraphQL SDL file becomes one resolver-kind summary per Query, Mutation and Subscription field. Committed .graphql and .gql operation documents become one client-kind summary per operation, with fragment spreads inlined, so a repo that keeps its queries in files pairs against its resolvers without any call site being traced. | |
@suss/contract-cloudformation | cloudformation | CloudFormation and SAM templates. It delegates to the OpenAPI and API Gateway readers, and handles SQS event-source mappings and a function's Environment itself. | |
@suss/contract-serverless | serverless | A Serverless Framework service file. The reader rewrites the functions block in SAM's form and passes it to the CloudFormation reader, so a route, a queue consumer or an environment contract comes out the same whichever manifest language declared it. ${self:} resolves against the document, and a deploy-time reference keeps its token. | |
@suss/contract-terraform | terraform | A .tf file or the directory a module lives in. The AWS and Google Cloud provider vocabularies both load. | |
@suss/contract-wrangler | wrangler | A Cloudflare Worker's wrangler.toml or wrangler.jsonc. The Worker comes out as a deployable with its configuration, values included, so a store addressed through a variable resolves. The reader also writes a summary for each KV namespace, R2 bucket, D1 database and Queues channel the Worker is bound to. | |
@suss/contract-appsync | appsync | An AppSync GraphQL schema and its resolver mapping templates. | |
@suss/contract-prisma | prisma | A schema.prisma file, one storage provider summary per model. | |
@suss/contract-storybook | storybook | Storybook CSF3 stories, one component contract summary per story. | |
@suss/contract-aws-apigateway | (through the readers above) | API Gateway resource semantics for REST and HTTP APIs, including the transitions the platform injects. The CloudFormation, Serverless and Terraform readers all delegate to it. | |
@suss/contract-intent | (through check --intent) | Team-authored intent specs, *.intent and *.prd. |
Asking for a pack
If the framework you use is not in a table above, open an issue with the library, a link to its docs, and ten or fifteen lines of code showing how your project registers a handler and returns a response. A pack is written from that material, and a snippet from a project that uses the library settles questions the library's own docs leave open.
You do not have to wait for one. A pack is a data object of about a hundred lines that can live in a package of your own, and -f @your-scope/your-pack loads it with nothing else to configure. Write a pack goes through building one from start to finish.
If a pack exists and comes back with nothing, that is a different problem: Fix a run that found nothing.
Everything else in the box
@suss/cli also installs the IR the summaries are written in, the language adapters, the checker, and the shared code the packs run on.
| Package | What it is | Coverage |
|---|---|---|
@suss/ir-core | Shared IR primitives, type shapes, boundary bindings + constructors, source locations, confidence. Base for behavioral-ir and intent-ir. | |
@suss/behavioral-ir | zod schemas, types, parsers, and generated JSON Schema. Install this to consume summaries. | |
@suss/intent-ir | Team-authored intent: system intent (what a boundary should do) + PRD outcome intent, paired against derived summaries. | |
@suss/datalog | Small semi-naive Datalog evaluator with stratified negation; the rules engine behind derived program facts. | |
@suss/resolution | Datalog rules for following a value back to the function it resolves to: a factory's argument, a re-exported wrapper, a closure three levels down. Language-neutral, so an adapter supplies facts and inherits the rules. | |
@suss/values | Bounded evaluator over an abstract value domain: strings as pieces with named holes, sequences, records. An adapter supplies a lowering of its AST and a row table for its operators and library methods, and readers ask what an expression is worth instead of matching one spelling at a time. | |
@suss/extractor | Assembly engine. It converts raw extracted structure into BehavioralSummary. | |
@suss/recognize | Write a pack as data: a chain of named links, compiled to the recognizer hooks, run by any adapter that implements the executor ops. | |
@suss/packs | Every pack, one subpath each, so @suss/packs/express reaches the Express pack. The CLI resolves -f names to these on its own. | tested through each pack |
@suss/adapter-typescript | TypeScript language adapter via ts-morph. | |
@suss/adapter-python | Python language adapter: tree-sitter (WASM) parsing, a lexical binder, repo-scoped module resolution. v0, no path-engine work yet. | |
@suss/adapter-ruby | Ruby language adapter: tree-sitter (WASM) parsing, a lexical binder over class/module nesting, Rails' constant-to-path convention for mutation: / resolver: wiring and controller discovery. v0, graphql-ruby and rails, no path-engine work yet. | |
@suss/checker | Pairwise cross-boundary checker (behavioral). | |
@suss/checker-intent | Pairs team-authored intent against derived code; emits IntentFinding coverage. | |
@suss/cli | CLI wrapper. | |
@suss/mcp | An MCP server over the CLI, so a coding agent can ask about a boundary while it works. It keeps its summaries current as files change. | |
@suss/sql | Reads what a SQL statement touches, for packs that find a raw query. | |
@suss/manifest-aws | Parses CloudFormation and SAM templates into a shared facts layer that the contract readers and the manifest-driven framework packs both read. | |
@suss/terraform-aws | What AWS's Terraform provider declares, as data for that reader. | |
@suss/terraform-gcp | What Google Cloud's Terraform provider declares, as data for that reader. |