Skip to content

Component Lifecycle

Terminal window
wh component install <source> --repo org/repo

The source can be a registered component reference (org/name), a GitHub URL, or a local path. For components with manifest-provisioned subscriptions, the source must resolve to a GitHub repo URL or a git checkout with a GitHub origin remote. The installer runs through these stages:

com.warmhub.identity is a reserved bundled system source. Installing it calls the backend by id and does not require a registry entry, local package, GitHub source, or filesystem warmhub/manifest.json.

  1. Source resolution — Determines if the source is a registered component reference, local directory, or GitHub URL. GitHub sources are shallow-cloned and cached at ~/.warmhub/components/<name>/; registered sources are resolved through the component registry and downloaded through the backend.

  2. Parse and validate — Reads warmhub/component.json and warmhub/manifest.json. Validates JSON structure, required fields, and cross-references (for example, credentials and shapes referenced by subscriptions and seeds).

  3. Ensure shared infrastructure — Creates the ComponentInstall and ComponentConfig shapes if they don’t already exist in the repo. These are system-managed shapes shared across all components.

  4. Record install — Creates a ComponentInstall/<component-id> thing with state installing and the serialized manifest. This is the tracking record for all future operations.

  5. Apply manifest-provisioned resources — In order:

    • Shapes: Created if they don’t exist. Tagged with the component’s ID.
    • Credential sets: Created if they don’t exist. Keys are declared but not populated — the user must set values after install.
    • Subscriptions: Manifest subscriptions are compiled into normal WarmHub webhook or cron subscriptions, then bound to credential sets.
    • Seeds: Initial things created via a commit. Seeds targeting ComponentConfig and other shapes are batched.

    Resources marked provisioning: "setup" are skipped by the local installer and are expected to be created by the registered component’s setup callback.

  6. Run registered setup — If a registered component advertises a setup endpoint, the CLI calls it after the local install succeeds. Setup-provisioned shapes, credential sets, and subscriptions are created by that external service.

  7. Compute state — Checks whether all resources were created successfully and whether credentials need values. Sets the final state (ready, credentials-required, or degraded).

  8. Finalize — Updates the ComponentInstall record with the final state and a hash of the manifest for change detection.

The installer derives the effective subscription kind from trigger.kind:

  • event triggers compile to normal webhook subscriptions with shape, filter, and webhookUrl
  • cron triggers compile to normal cron subscriptions with cronConfig and webhookUrl

Component manifests no longer declare action-container runtimes or local action programs. Handlers live outside the manifest and are referenced only by webhook URL.

If a component is already installed (a ComponentInstall record exists), the installer enters reconciliation mode:

  • Missing resources are added — New shapes, subscriptions, and seeds from the updated manifest are created.
  • Existing resources are preserved — The reconciler does not delete resources that were in the old manifest but absent from the new one.
  • Seeds are updated — If a seed thing already exists, its data is revised to match the new manifest.
  • Failed installs are retried — If the previous state was installing, degraded, or error, the reconciler treats the old manifest as empty and retries all resources.
  • Paused subscriptions are not automatically resumed — Reinstall adds missing subscriptions, but a subscription that still exists in paused state stays paused until you resume or recreate it yourself.
  • Registered setup is not replayed on updatewh component update for a registered install re-downloads source through the registry and reruns the local installer, but it does not call the setup endpoint again. Setup-provisioned resources and minted setup/runtime tokens are not rotated by update today.
Terminal window
wh component doctor <name> --repo org/repo

Doctor reads the installed component’s manifest snapshot from ComponentInstall/<id> rather than reading local files from disk. It also writes back the computed component state after the checks complete. It checks:

CheckPassFail
Shape exists and is activeokmissing or inactive
Subscription exists and is activeokmissing or inactive
Credential set exists with all required keys populatedokmissing keys listed
Seed things existokmissing

Doctor computes and persists the component state:

  • All subscriptions paused, nothing else wrong → paused
  • Missing resources, or inactive non-subscription resources → degraded
  • A mix of active and paused subscriptions does not by itself move the component out of ready
  • Resources ok but credentials missing → credentials-required
  • Everything healthy → ready
Terminal window
wh component teardown <name> --repo org/repo

Teardown pauses all subscriptions declared in the component’s manifest. Current CLI behavior only uses teardown.subscriptions.onDisable:

  • onDisable: "pause" — Subscriptions are paused (can be resumed later).

onUninstall is accepted by the manifest schema but is not executed by the current CLI teardown flow.

After teardown, the component state is set to paused. Shapes, seeds, and credential sets are preserved.

To restore a torn-down component, resume or recreate the paused subscriptions. Reinstall alone does not automatically unpause existing subscriptions:

Terminal window
wh sub resume <subscription-name> --repo org/repo
install (new) → installing → ready | credentials-required | degraded | error
install (exists) → reconcile → ready | credentials-required | degraded
doctor → ready | credentials-required | degraded | paused
teardown → paused | degraded
Terminal window
wh component validate ./my-component

Runs all checks without connecting to a repo:

  • JSON syntax and schema validation
  • Cross-reference checks (credential refs, shape refs)
  • Duplicate name detection
  • Subscription trigger and webhook validation
  • Component ID format
  • Consistency between component.json and manifest.json