@hailer/app-sdk
v2.8.0
Published
SDK for building Hailer Apps
Downloads
949
Readme
@hailer/app-sdk
SDK for building Hailer Apps — web apps that run as iframes inside the Hailer frontend.
The SDK gives your app a HailerApi client that talks to the host frame — so runtime calls inherit the user's session and you don't deal with auth or API tokens. It also ships a publish CLI for pushing your built app to a Hailer instance (or to the Hailer marketplace); that one does need a user API key.
Install
npm install @hailer/app-sdkQuick start
The fastest way to start is the official scaffolder, which sets up a Vite project with the SDK already wired up:
npm create @hailer/app@latest
cd my-app
npm install
npm run devThen in Hailer, create a "Local Development" app pointing to http://localhost:3000 and open it — changes reload automatically.
See @hailer/create-app for templates, non-interactive flags, and publishing instructions.
Modules
The HailerApi instance exposes these modules:
| Module | Purpose |
|--------|---------|
| hailer.user | current(), get(userId), list(). |
| hailer.workspace | current(), list(), plus hailer.workspace.product for product/template install lookups. |
| hailer.workflow | list(), get(workflowId), install(spec, options?). |
| hailer.activity | list, get, create, update, remove, print, plus hailer.activity.kanban (list/load/updatePriority) and hailer.activity.ball (pass/take/list) sub-modules. |
| hailer.team | list() — teams grouped by workspace. |
| hailer.permission | map({ workspaceId? }) — permission map for the current user. |
| hailer.file | get(fileId), upload(file, filename, options?), addTags(fileId, tags), removeTags(fileId, tags). |
| hailer.insight | list(), data(insightId, options). |
| hailer.app | hailer.app.product: isProductInstalled, get, install, getInstalledVersion, getManifest — marketplace lookups for the running app. |
| hailer.product | Full CRUD on your own marketplace products: list, get, create, update, remove, setPublic. |
| hailer.payment | Pricing and purchases: createPricing, updatePricing, getPricing, createPurchase, getPurchases, calculateStripeTax. |
| hailer.admin | Admin-only endpoints (workspace overrides, invoices, revenue, token transactions, referrals, etc). |
| hailer.metrics | Read usage metrics: list(options?), get(metricTypes, options?). |
| hailer.http | Authenticated proxy through the parent frame: fetch, upload, openWebSocket. |
| hailer.public | Endpoints callable without a Hailer session — talks directly to the public backend (https://api.hailer.com by default). Sub-modules: .app (public app config), .form (public form submit/read), .insight (public insight viewing), .product (marketplace lookup). The only namespace usable in outside mode. |
| hailer.ui | Sub-modules for commanding the host frame: .activity, .discussion, .snackbar, .workflow, .insight, .files. |
Each module is fully typed. Browse the type definitions at src/types.ts, or generate a typedoc site locally with npm run docs from a clone of this repo.
Publishing an app
Note: The
npm run publish-*scripts shown below only exist in projects scaffolded with@hailer/create-app. They are not defined in@hailer/app-sdkitself — what the SDK ships is the underlyingpublish.cjsbinary that those scripts invoke. If you're integrating into a non-scaffolded project, run it directly:node node_modules/@hailer/app-sdk/lib/tools/publish.cjs <path-to-bundle> --user-api-key <key>.
# Authenticate with an API key and publish a built bundle
npm run publish-production -- --user-api-key <key>
# Create and publish in one go
npm run publish-production -- --create \
--app-name "My App" \
--workspace <workspaceId> \
--user-api-key <key> \
--forceAuth
Provide one of:
--user-api-key <key>(orUSER_API_KEY/HAILER_USER_API_KEYenv vars)--email <email>(will prompt for password)
The publish script will also load ~/.env via dotenv, so a key set there works automatically — handy for AI agents. To use a different env file, pass --env-file <path>; values from that file take precedence over ~/.env, and real environment variables take precedence over both.
Flags
| Flag | Purpose |
|------|---------|
| --user-api-key <key> | API-key auth. |
| --email <email> | Email auth (password prompt). |
| --create | Create a new app before publishing. |
| --app-name <name> | App name (with --create). |
| --workspace <id> | Workspace ID (with --create). |
| --market | Also publish to the Hailer marketplace. |
| --force | Skip confirmation prompt. |
| --host <url> | Override target host URL. |
| --env-file <path> | Load env vars from a specific file, falling back to ~/.env. |
| --development / --staging / --production / --local | Pick a default host. |
Workflow
Create a new branch for every feature or fix — don't commit directly to
master.Document your change. Whenever you add, remove, or change a method, type, or behavior, update the documentation in the same change: edit the matching reference file in
docs/api/(one file per module) or the relevant guide indocs/guides/, and create a new file when you add a new module or topic. Keep the Modules table in this README in sync too.Before publishing, document what changed in
CHANGELOG.mdunder a new version heading. The format follows Keep a Changelog:## [2.4.2] - 25-05-2026 ### Changed - Updated `Workflow`, `WorkflowField`, and `WorkflowPhase` types to match more closely the actual shape of the objects. - Updated `README.md` file to explain more clearly what the `hailer-app-sdk` package is.Publish with one of the
release:*scripts below — these bump the version, tag the commit, and push.
Dev commands
npm run build # Build the SDK + publish CLI
npm run watch # Rebuild on change (tsc + esbuild)
npm test # Run vitest test suite
npm run docs # Generate typedoc and open itDeveloping against a local app
When you're changing the SDK and want to test it inside a real app without publishing to npm, point that app at your local clone.
Build the SDK at least once, then keep it rebuilding while you work:
cd hailer-app-sdk npm install npm run watch # rebuilds lib/ on every change (tsc + esbuild)The package's entry points (
lib/app-sdk.jsand the.d.tsfiles) live inlib/, so the consuming app always imports the freshly built output.Link the local SDK into your app. Two ways — pick one:
Option A —
file:dependency (recommended). In the app'spackage.json, point the dependency at your clone, then install:// app/package.json "dependencies": { "@hailer/app-sdk": "file:../hailer-app-sdk" }cd my-app npm installnpm symlinks the clone into
node_modules/@hailer/app-sdk, so eachnpm run watchrebuild is picked up live. (This is the same mechanism the integration test in__tests__/publish.test.tsuses.)Option B —
npm link. Register a global link from the SDK, then consume it from the app:cd hailer-app-sdk && npm link cd ../my-app && npm link @hailer/app-sdkRun your app's dev server (
npm run dev). Because the SDK is symlinked, edits →watchrebuild → the app's bundler reloads.
When you're done, restore the real dependency in the app (
"@hailer/app-sdk": "^x.y.z"+npm install, ornpm unlink) so you don't accidentally ship the local path.
Releasing
This project follows Semantic Versioning. Pick the script that matches the kind of change:
| Script | When to use | Example bump |
|--------|-------------|--------------|
| npm run release:patch | Bug fix, no API change | 1.1.1 → 1.1.2 |
| npm run release:minor | New feature, backwards compatible | 1.1.1 → 1.2.0 |
| npm run release:major | Breaking change | 1.1.1 → 2.0.0 |
| npm run release:beta-patch | Pre-release patch | 1.1.1 → 1.1.2-beta.0 |
| npm run release:beta-minor | Pre-release minor | 1.1.1 → 1.2.0-beta.0 |
| npm run release:beta-major | Pre-release major | 1.1.1 → 2.0.0-beta.0 |
Each script runs npm version <type>, creates a commit + tag (chore: release vX.Y.Z), and pushes both to the remote. Tagging every release means we can check out and patch any historical version cleanly.
Publishing to npm
@hailer/app-sdk is published to the public npm registry. There is no CI publish step — a maintainer runs it by hand. Releases are cut from master, so the release:* script tags the version there.
One-time setup: you must be a member of the @hailer npm org with publish rights. Authenticate once per machine:
npm login # opens npmjs.com to authenticate
npm whoami # confirm you're logged inEach release:
Land your change on
master(merge the branch) and pull the latest:git checkout master && git pullUpdate
CHANGELOG.md— add a new version heading describing what changed if not done already, (see the format under Publishing an app → Workflow). Commit it.Bump the version, tag, and push with the matching release script (this updates
package.json, commitschore: release vX.Y.Z, tags it, and pushes the commit + tag to GitLab):npm run release:patch # or release:minor / release:majorPublish to npm. The
prepublishOnlyhook rebuilds automatically, and only the files inpackage.json'sfilesarray (lib/**) are published:npm publishFor a pre-release (any
release:beta-*version), publish it under thebetadist-tag so it doesn't become the defaultlatest:npm publish --tag betaVerify the new version is live:
npm view @hailer/app-sdk version
Order matters: always run the
release:*script (step 3) beforenpm publish(step 4) — the script sets the version thatnpm publishthen ships. Ifnpm publishfails after the tag was already pushed, fix the issue and re-runnpm publishfor the same version (don't bump again).
