Skip to main content
A repo is one git repository that holds many Ekanos packages: integrations and experiences side by side. You run them all in one harness, an experience uses an integration from the same repo with no setup, and you publish one package, several, or all of them.
Ekanos calls this a repo, not a workspace. In the Ekanos app a Workspace is a sidebar section, which is a different thing.

Create a repo

--slug names the repo and creates ./acme-platform; --dir . scaffolds in the current directory instead. One of the two is required. If the target is already inside an Ekanos repo, init refuses and points you at ekanos new. It writes:

The root ekanos.json

packages is a list of globs, relative to the repo root. Each directory a glob matches is a package with its own ekanos.json, whose kind is integration or experience. The root file takes no other fields.

Add packages

From the repo root or from anywhere inside it:
ekanos new integration <slug> scaffolds the same project as ekanos init, into integrations/<slug>. ekanos new experience <slug> scaffolds an experience into experiences/<slug>. The slug is kebab-case and unique across the repo; a package is addressed by its slug. Outside a repo, new refuses and tells you to run init --kind repo. If a package directory is not matched by any glob in the root packages, it tells you to add one. The result looks like this:

Run everything together

At the repo root:
One harness serves the whole repo, on port 3100 by default. You get a home page for the repo, a console for each integration at /integrations/<name>, and a view for each experience at /experiences/<name>. See Repo mode. Run ekanos dev inside a single package instead, and the harness serves just that package. Every other command works the same inside a package directory: ekanos validate, ekanos test, ekanos contract, ekanos check, ekanos build. The CLI finds the repo by walking up from the current directory to the nearest ekanos.json with "kind": "repo".

How an experience finds its integrations

When an experience lists acme-cms in its ekanos.json integrations, the harness resolves it in this order:
  1. A local override in the experience’s ekanos.local.json (or EKANOS_INTEGRATION_OVERRIDE_<NAME>), for an integration kept in a folder outside the repo.
  2. An integration package of the same repo with that slug. This needs no setup, runs in fixtures or live, and is shown as “Local · this repo”. It is not an override: it never blocks publishing.
  3. The registry: an integration published to Ekanos that your Source can use, resolved from the session’s catalog, the published package, or a contracts folder, and finally the committed snapshot in the experience’s contracts/ folder.
Whichever it is, the experience is checked against the pinned contract. The pin has to name a compat line the integration provides, and every operation you list has to exist in it. The check does not care where the code runs from.

Mixing local and published integrations

An experience can use some integrations from the repo and others from the registry. Say content-desk uses acme-cms (a package in this repo) and acme-social (published by another team):
acme-cms resolves to integrations/acme-cms. acme-social resolves to its published contract and answers from fixtures until you connect it. Give acme-cms a contract first (see Operation contracts), then pin both:

Pointing at a folder outside the repo

To run an experience against an integration you keep elsewhere, create ekanos.local.json next to the experience’s ekanos.json:
path is a folder holding an integration ekanos.json; mode is "fixtures" (the default) or "live". The file is per-developer: .gitignore it, because ekanos check fails if it is tracked. An override like this is what a host would not resolve, so ekanos publish refuses an experience while one is active. Delete the file, or unset the environment variable, to publish.

Credentials stay with the integration

An experience never holds credentials. When you connect an integration in the harness, its values are written to that integration package’s own .ekanos/local-secrets.json, which is gitignored and never packed. See Repo mode.

Publish from a repo

ekanos publish <name>, ekanos publish a b, and ekanos publish --all plan the packages in dependency order. See Publishing from a repo.

Next steps