Component Lifecycle
Install
Section titled “Install”wh component install <source> --repo org/repoThe 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:
-
Source resolution — Determines if the source is a local directory or GitHub URL. GitHub sources are shallow-cloned and cached at
~/.warmhub/components/<name>/. -
Parse and validate — Reads
warmhub/component.jsonandwarmhub/manifest.json. Validates JSON structure, required fields, and cross-references (e.g., subscriptions reference valid actions). -
Ensure shared infrastructure — Creates the
ComponentInstallandComponentConfigshapes if they don’t already exist in the repo. These are system-managed shapes shared across all components. -
Record install — Creates a
ComponentInstall/<component-id>thing with stateinstallingand the serialized manifest. This is the tracking record for all future operations. -
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
ComponentConfigand other shapes are batched.
-
Compute state — Checks whether all resources were created successfully and whether credentials need values. Sets the final state (
ready,credentials-required, ordegraded). -
Finalize — Updates the
ComponentInstallrecord with the final state and a hash of the manifest for change detection.
Action compilation
Section titled “Action compilation”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.authis 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.
Reconciliation (reinstall)
Section titled “Reconciliation (reinstall)”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, orerror, 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.
Doctor
Section titled “Doctor”wh component doctor <name> --repo org/repoDoctor 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:
| Check | Pass | Fail |
|---|---|---|
| Shape exists and is active | ok | missing or inactive |
| Subscription exists and is active | ok | missing or inactive |
| Credential set exists with all required keys populated | ok | missing keys listed |
| Seed things exist | ok | missing |
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
Teardown
Section titled “Teardown”wh component teardown <name> --repo org/repoTeardown 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:
wh sub resume <subscription-name> --repo org/repoState transitions
Section titled “State transitions”install (new) → installing → ready | credentials-required | degraded | errorinstall (exists) → reconcile → ready | credentials-required | degradeddoctor → ready | credentials-required | degraded | pausedteardown → paused | degradedValidate (offline)
Section titled “Validate (offline)”wh component validate ./my-componentRuns 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.jsonandmanifest.json