Skip to content
open tomato/ rafa-hub
GitHub
rafa-hub pages
  1. rafa-hub
  2. Connect devices

Connect devices

Point a rafa project at a hub, store the token each device sends, and know what happens when the hub cannot be reached.

A device syncs through the hub when its project sets effort.sync: service. Two things must be in place: the project's config names the hub, and rafa can load the service strategy, a module called @open-tomato/rafa-sync-service.

WARN

At 0.47.0, rafa loads modules from a folder only. The service module is not on npm and is not bundled into the @open-tomato/rafa package, so a device installed from npm cannot load it on its own: it needs a checkout of rafa's repository to load it from. Installing modules from npm is a later phase of the add-ons work (#29). [TBD: the npm form of this step, once add-ons install from npm]

1. Load the service module

In the project's .rafa/config.yaml, name the module's folder in your rafa checkout and trust it by name:

modules:
  - path: /path/to/rafa/packages/rafa-sync-service
allowList:
  - "@open-tomato/rafa-sync-service"

A fresh clone of the repository at v0.47.0, with nothing installed in it, loads the module for rafa 0.47.0. [verify: other tags; only v0.47.0 was run] Check that it loaded:

rafa module list
Modules:
  @open-tomato/rafa-sync-service 0.0.0: loaded, enabled; types sync; from path <rafa checkout>/packages/rafa-sync-service
    adapter: sync/service

2. Name the hub

effort:
  sync: service
hub:
  url: https://hub.example.org
  tokenSecret: rafa-hub-token

With both blocks in place, rafa doctor reads the strategy as served by the module:

Effort sync: ok, service (module)

Without the module lines it fails instead, saying no module registers a sync adapter of that kind.

hub.url is required with service; without it the config is refused when it loads:

effort.sync is "service" and no config file names hub.url; expected hub.url, the address of the hub, such as https://hub.example.org

The URL is used as written, so a hub served under a path names that path too. hub.timeout (default 3s, from 1s to 30s) sets how long one request may take.

3. Store the token

hub.tokenSecret is the name the token is stored under in your system's secret store, never the token itself. rafa reads it through Bun's secrets interface, under the service name rafa and the name you gave. The token is a GitHub token for a login with write access or above on the hub's repository. [verify: the command that stores the secret on each operating system; not documented in the package and not run here]

When the hub cannot be reached

Nothing stops. A command that cannot reach the hub prints one line saying so, uses the local store as if sync: local were set, and exits as it would have; its rows sync on the next contact. [verify: the offline line, from the package's README; not run here]

Commands contact the hub at fixed points: rafa effort collect pushes then pulls; rafa loop start pushes then pulls at the end of each task; rafa status, rafa next and rafa effort report pull before they read. [verify: the contact points, from the package's README; not run against a hub here]

When a project cannot sync

  • The store is in the old NDJSON format. rafa effort move --to=sqlite moves it to SQLite first.
  • The store has no origin, because it was only ever written outside a git repository. Running a command inside the project's repository gives it one.
  • The hub holds migrations this rafa does not know. The pull is refused until this device's rafa is updated; pushes still queue.

[verify: these three refusals, from the package's README; not run here]