Skip to content
8

Architecture ​

pulse-cli speaks to an engine through a port. Each engine has its own adapter behind that port. Today every adapter passes straight through to the Camunda 7 REST API. When an engine diverges, only its adapter changes.

Layers ​

FolderWhat it holds
src/engine-portWhat pulse-cli needs from an engine: EnginePort and EngineAdapter. Types only
src/enginesOne adapter per engine: operaton, cibseven, camunda7
src/apiOne folder per engine API. camunda7-rest builds catalog and port
src/workflowThe workflow commands. They know the port, never an adapter or an API
src/cliSelects the adapter and registers its commands

dependency-cruiser enforces the boundaries (pnpm lint:architecture && pnpm lint:architecture:cli):

  • workflow imports engine-port, never engines or api.
  • Only engines/<name>/adapter.ts imports api.
  • Adapters do not import each other. An API does not import another API.
  • engine-port imports types only. api, engine-port and engines use no Node built-ins.
  • An adapter reads only its own catalog, src/generated/catalog.<name>.json.

From spec to request ​

The commands are data. A generator turns the OpenAPI spec into one catalog per engine. The selected adapter hands its catalog to the CLI, which registers commands, help and describe from it and sends requests over HTTP.

Selecting the engine ​

run.ts picks the adapter before it registers a single command. Only then do commands, help and describe match the catalog of that engine.

A config file that cannot be read does not stop the selection: pulse-cli falls back to camunda7, and the command reports the problem when it reads its configuration.

A workflow command ​

The decisions behind this: Architecture decisions.