Skip to content

Component Lifecycle

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

The source can be a GitHub URL or a local path. For components with 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:

  1. Source resolution — Determines if the source is a local directory or GitHub URL. GitHub sources are shallow-cloned and cached at ~/.warmhub/components/<name>/.

  2. Parse and validate — Reads warmhub/component.json and warmhub/manifest.json. Validates JSON structure, required fields, and cross-references (e.g., subscriptions reference valid actions).

  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 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: Actions are compiled into the current managed action runtime configuration (see below), then subscriptions are created and bound to credential sets.
    • Seeds: Initial things created via a commit. Seeds targeting ComponentConfig and other shapes are batched.
  6. Compute state — Checks whether all resources were created successfully and whether credentials need values. Sets the final state (ready, credentials-required, or degraded).

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

The installer doesn’t pass manifest actions directly to the subscription system. Instead, the action compiler translates each action definition into a command for the current managed action runtime:

  • Public repos: The runtime clones the component repo. The compiler generates a command that sets env vars and runs the program.
  • Private repos: When source.auth is set, the runtime’s built-in clone is disabled. The compiler generates a wrapper script that exports credentials, clones the repo with authentication, and pipes the saved input to the user’s program.

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.
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 (action refs, credential refs, shape refs)
  • Duplicate name detection
  • Reserved env variable names
  • Local file existence (action scripts referenced in execution.args)
  • Component ID format
  • Consistency between component.json and manifest.json