The build loop
This is the whole path from an empty directory to a released module. You test every change on a draft version installed in the human's own test company, read its logs and problems, fix, and only then release.
login → namespace → scaffold → method → OVE page → choose company
→ publish draft → install → logs / problems / call → fix → publish draft → update
→ (repeat) → publish --release
Steps marked Human need the person you work for. Ask, then wait. Never type a password, never choose the company yourself, never release without an explicit "yes".
Rules for every omm command
- Add
--jsonto every command you run. Output is then plain JSON on stdout; a failure prints{ "error": "Module instance not found", "status": 404 }on stderr and exits with a non-zero code. - Only
omm login,omm company usewithout an argument andomm initwithout--namespaceon an account with several namespaces ask questions on the terminal (with--jsonthatomm initfails instead of asking). Every other command is non-interactive and safe to run unattended. - Run commands in the module directory, or pass
-C <dir>. Module code and version always come frommodule.json. - The default instance is the only instance of the module in the working company. When there are several, commands fail with the list of instances; pick one with
--instance <id>. - The core URL defaults to
https://my.orbi.do/api.OMM_CORE,OMM_CORE_TOKENandOMM_COMPANYoverride the core URL, the core session token and the working company. ommprints update notices on stderr: in text mode lines starting with!, with--jsonone line{"notices": [...]}after the result. Read them: a neweromm, SDK or skill may change the commands on this page. Each notice carries the fix and links to the changelog.
0. Prerequisites (Human)
Node.js 18.13 or newer.
ommand the skill installed, npm configured for the@orbitoscope.@orbito/ommand@orbito/api-libare not on npmjs.org; they live in the Orbito npm registry, which allows anonymous downloads but needs one scope line in~/.npmrc. Without itnpm installin a module fails with 404. No token is needed. Once per machine, on Windows, macOS and Linux:npm i -g @orbito/omm --@orbito:registry=https://git.kozminski.net.pl/api/packages/orbito/npm/ omm skill install # copies the skill for Claude Code, Codex and OpenCode and saves the scope line in ~/.npmrcThe flag on the first line is enough to install
ommwithout the scope line;omm skill installthen writes it for good. Skill copies in the current project:omm skill install --project. On Linux and macOS the installer (curl -fsSL https://orbito.pl/docs/skill/install.sh | sh) runs the same steps. Ifnpm i -gfails withEACCES, the global npm directory is root-owned: run only the install step withsudoandomm skill installwithout it, or move npm to a user-owned prefix (the installer prints both fixes).Environment checked:
omm doctor --jsonright after installingomm. It checks Node.js, theommversion, the@orbitoscope line in npm config, both logins, the working company, the SDK of the module in the current directory and the installed skill; the checks come in thechecksarray as{ name, status: ok|warn|fail, message, fix }and update notices undernotices. Fix what the checks report before you continue; it exits with 1 only when a check fails.An Orbito account at my.orbi.do with a company used for testing. The same account logs in to the registry modules.orbito.pl; the registry has no accounts of its own.
1. Log in and pick a namespace (Human)
omm login # e-mail and password of the Orbito account: core session + publish token
omm whoami --json # registry account and its namespaces: { email, namespaces: [{ id, name, role }] }
One omm login logs in to both Orbito Core and the registry. When the human hands you a token instead: omm login --token <core JWT> logs in to both, omm login --token omm_... (a publish token, CI) to the registry only.
A module belongs to a namespace, not to a person; its code is <namespace>/<slug>. Every member of the namespace can create, publish and configure its modules; only the owner manages members. When namespaces is empty, ask the human: create one (the name is permanent and part of every module code: a-z, 0-9, -, 3 to 30 characters, globally unique) or ask the owner of an existing one to invite them by e-mail.
omm namespace create acme --json # only with the name the human chose
omm namespace list --json # [{ id, name, role: owner|member }]
More: Account and namespaces (Polish).
2. Scaffold
omm init "Hello" --namespace acme --json
cd hello
npm install # needs the @orbito scope line from step 0
omm init <name> creates the module card in the registry with the display name <name> and writes the example module into a new directory: module.json, package.json, index.js, pages/hello.yaml and .gitignore (one method, one OVE page, an onEnabled handler). The registry assigns the code <namespace>/<slug of name>, for example acme/hello, and omm writes it to name in module.json. Without --namespace it uses the account's only namespace; with several namespaces and --json it fails until you pass one. omm init does not run npm install; run it yourself.
With --json it prints { "code": "acme/hello", "dir": "hello", "files": [...], "cardCreated": true }.
| Option | Does |
|---|---|
--namespace <name> | namespace of the new module card; required when the account has several |
--code <namespace/name> | use an existing module card with this code; no network call, cardCreated is false |
--dir <dir> | target directory; default: the part of the code after / |
--description <text> | description of the new module card |
Use the module name and namespace the human gave you. When the human already has a module card, pass its exact code with --code.
3. Write a method
Add or change methods in index.js with Core.registerMethod. Validate every input yourself, the core never does. Patterns: cheatsheet, method with validation.
node --check index.js
4. Add an OVE page
Put the view in pages/<name>.yaml and register it with Pages.registerPages. A view calls your methods with callMethod and reads their result as $response.0. Patterns: cheatsheet, OVE page.
omm pack --dry-run --json # what will be uploaded
5. Check the core session
omm whoami --core --json # Orbito account and working company
omm login from step 1 saved the core session too; omm refreshes it before it expires. Another core: omm login --core <url>. Not logged in to <core>: ask the human to run omm login again.
6. Choose the test company (Human)
omm company list --json # companies of the logged-in user, * = working company
omm company use <companyId> # the human tells you which one
Drafts (and a module that was never released) are visible and installable only for members of the module namespace and for companies granted access to the module. As a namespace member you can install your draft in any company you belong to: the first omm install or omm update of a draft grants that company access for good, so the module keeps running after a container restart and the other users of the company see it in their marketplace. Access for another company is granted in the developer panel of the registry with the company id (id in omm company list --json). Published versions need no access.
7. Publish a draft
omm publish --json
Packs the module, uploads it as a draft and waits for the Docker image build. A draft is visible only to the members of the module namespace and to companies with access to the module. Build errors are printed in full; fix and run the same command again, a draft of the same version is overwritten.
8. Install in the test company
omm install --json # installs the version from module.json with its dependencies
omm install --name "Shop PL" --json # a second instance of a non-singleton module needs a name
omm instances --json # id, version and state of each instance
Optional: if the module registers automation triggers or actions, compose a test automation from them once the draft runs. omm automation elements --query <module code> --json must list them; then build a graph, save it as a disabled draft with omm automation create -f graph.json --json and enable it only after the human agrees. The whole loop: Company automations.
9. Check: logs, problems, calls
Always read the logs right after an install or update.
omm logs --json # module logs (Log.info / Log.error), today
omm logs --since 2026-10-13T09:00:00Z --json
omm logs --day 2026-10-12 --json
omm logs --container --json # Docker stdout/stderr: crashes, stack traces, require errors
omm problems --json # problems the module reported (Problems.report)
omm problems --status waiting --json # waiting | solved | discarded
omm call greet --params '{"name":"Ada"}' --json
omm call listGreetings --json
omm call calls the method as the logged-in user, exactly like an OVE page does. Over REST the result travels in the RPC envelope (a one-element array); omm call unwraps it and prints the element itself, for example { "_id": "65f0c3a1e4b0a1b2c3d4e5f6", "message": "Hello, Ada!" }. When the handler throws, the command fails and error carries the handler's message.
What to look for:
omm installoromm updatefails with 404 (Module image not found, with ahintabout namespace members): the registry does not hand out the draft to this account and company. Check withomm whoami --jsonthat the logged-in account is a member of the module namespace (the part of the code before/); if not, ask the human to log in with the right account or get invited.omm logs --containershows an exception at start: the module crashed before registering. Fixindex.js.registerPagesorregisterConfigBlockserrors in the logs: the page or config block was rejected, its message names the field.omm callanswersMethod not found: <name>: the method is not registered in the running version.
10. Fix and update
- Change the code. Keep the same
version. - Publish the draft again and update the instance:
omm publish --json # overwrites the draft of this version
omm update --json # same version: reloads the instance with the new draft; --instance <id> when there are several
omm logs --json
omm update on the version the instance already runs reloads it: the core stops the container and starts it again, and every start pulls the image anew, so the instance runs the draft you have just published.
Repeat steps 9 and 10 until the logs are clean, omm problems is empty and omm call returns what you expect. Then ask the human to check the page in the panel.
11. Release (Human)
Only after the human says so. Make sure version in module.json (and package.json) is the number to release and higher than the last released version, for example 0.1.0 for the first release or 0.1.1 after it. This is the moment to bump the version, not every draft.
omm publish --release --changelog "First version: greet and list greetings" --json
The version is published in the registry and every company can install it; the previous published version becomes deprecated. A released version can never be changed: the next change needs a higher version, set it before the first draft of that change. Warnings about secrets without a value are printed with ⚠; set them with omm secrets set NAME (Human, the value is a secret).
Command summary
| Command | Does | Human? |
|---|---|---|
omm login / omm login --token <token> | log in to Orbito Core and the registry (a publish token omm_...: registry only) | yes |
omm whoami / omm whoami --core | registry account and namespaces / core account and working company | no |
omm namespace list / omm namespace members <name> | your namespaces with role / owner, members and invitations | no |
omm namespace create <name> / invite <name> <email> / remove <name> <email> | create a namespace / add or remove a member (owner only) | yes |
omm init <name> [--namespace <name>] [--dir <dir>] [--code <namespace/name>] [--description <text>] | create the module card in a namespace and scaffold the module from the built-in template | no |
omm company list / omm company use <id> | list companies, set the working company | yes (choice) |
omm repo [set [url] | unset] | show, save (default: git remote get-url origin) or remove the git repository link of the module card; visible only to namespace members | no |
omm pack --dry-run | list files that would be uploaded | no |
omm publish | upload a draft and wait for the build | no |
omm install [--name <name>] | install the module.json version in the working company | no |
omm update [--instance <id>] | update the instance to the module.json version; same version → reload with the fresh draft image | no |
omm instances | instances of the module in the company | no |
omm logs [--instance <id>] [--since <iso>] [--day <YYYY-MM-DD>] [--container] | module or container logs | no |
omm problems [--status <status>] | problems reported by the module | no |
omm call <method> [--params <json>] [--instance <id>] | call a method as the logged-in user | no |
omm automation elements [--kind trigger|action] [--query <text>] / omm automation element <type> | automation triggers and actions available in the company / one element's full definition | no |
omm automation create -f <file> / omm automation update <id> -f <file> | save an automation graph as a disabled draft (validated by the core) / replace graph fields | no; yes when the automation is enabled |
omm automation get <id> / omm automation runs [--automation <id>] / omm automation run <runId> | graph and validation / runs / steps of one run | no |
omm automation enable <id> / omm automation delete <id> --yes | enable an automation / delete it with its runs and problems | yes |
omm publish --release | publish the version for all companies | yes |
omm secrets set <NAME> | set an application secret | yes |
