@warmhub/cli 0.55.0 → 0.57.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/wh.js +264 -5
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -59,8 +59,8 @@ Full command reference: https://docs.warmhub.ai/cli-reference/overview/
|
|
|
59
59
|
## Links
|
|
60
60
|
|
|
61
61
|
- Documentation — https://docs.warmhub.ai
|
|
62
|
-
- Report a bug — support@warmhub.
|
|
62
|
+
- Report a bug — support@warmhub.ai
|
|
63
63
|
|
|
64
64
|
## Security
|
|
65
65
|
|
|
66
|
-
Report security issues to support@warmhub.
|
|
66
|
+
Report security issues to support@warmhub.ai.
|
package/dist/wh.js
CHANGED
|
@@ -21441,7 +21441,7 @@ function findSystemComponent(componentId) {
|
|
|
21441
21441
|
// ../../packages/sdk-ts/package.json
|
|
21442
21442
|
var package_default = {
|
|
21443
21443
|
name: "@warmhub/sdk-ts",
|
|
21444
|
-
version: "0.
|
|
21444
|
+
version: "0.57.0",
|
|
21445
21445
|
private: false,
|
|
21446
21446
|
type: "module",
|
|
21447
21447
|
description: "The TypeScript SDK for WarmHub — create repos, commit and query data, and compound knowledge with your AI agents.",
|
|
@@ -21464,7 +21464,7 @@ var package_default = {
|
|
|
21464
21464
|
},
|
|
21465
21465
|
homepage: "https://docs.warmhub.ai/get-started/quickstart/#connect-via-sdk",
|
|
21466
21466
|
bugs: {
|
|
21467
|
-
email: "support@warmhub.
|
|
21467
|
+
email: "support@warmhub.ai"
|
|
21468
21468
|
},
|
|
21469
21469
|
engines: {
|
|
21470
21470
|
node: ">=22"
|
|
@@ -34183,6 +34183,264 @@ var NOTIFICATIONS_DOMAIN = defineDomain({
|
|
|
34183
34183
|
handler: handleNotifications
|
|
34184
34184
|
});
|
|
34185
34185
|
|
|
34186
|
+
// ../../packages/warmhub-cli/src/domains/onboard-adapters/claude.md
|
|
34187
|
+
var claude_default = `# Adapter: Claude Code
|
|
34188
|
+
|
|
34189
|
+
**How to run this:** paste this whole document into Claude Code as your first
|
|
34190
|
+
message, or save it as a custom slash command and invoke it. Then follow the
|
|
34191
|
+
Conductor Script below, one step per turn.
|
|
34192
|
+
|
|
34193
|
+
**Connecting WarmHub (Act 1 details):** add the MCP server, then complete the
|
|
34194
|
+
auth flow.
|
|
34195
|
+
|
|
34196
|
+
\`\`\`bash
|
|
34197
|
+
claude mcp add --transport http warmhub https://api.warmhub.ai/mcp
|
|
34198
|
+
\`\`\`
|
|
34199
|
+
|
|
34200
|
+
Or add it to \`.mcp.json\` in the project:
|
|
34201
|
+
|
|
34202
|
+
\`\`\`json
|
|
34203
|
+
{ "mcpServers": { "warmhub": { "transport": "http", "url": "https://api.warmhub.ai/mcp" } } }
|
|
34204
|
+
\`\`\`
|
|
34205
|
+
|
|
34206
|
+
After adding, open \`/mcp\` and complete the sign-in when prompted.
|
|
34207
|
+
`;
|
|
34208
|
+
|
|
34209
|
+
// ../../packages/warmhub-cli/src/domains/onboard-adapters/codex.md
|
|
34210
|
+
var codex_default = `# Adapter: OpenAI Codex
|
|
34211
|
+
|
|
34212
|
+
**How to run this:** paste this whole document into your Codex session as your
|
|
34213
|
+
first message, or save it to \`AGENTS.md\` (Codex reads \`AGENTS.md\` natively). Then
|
|
34214
|
+
follow the Conductor Script below, one step per turn.
|
|
34215
|
+
|
|
34216
|
+
**Connecting WarmHub (Act 1 details):** Codex reads MCP servers from
|
|
34217
|
+
\`~/.codex/config.toml\`. Codex talks to MCP servers over stdio, so bridge the
|
|
34218
|
+
WarmHub HTTP endpoint with \`mcp-remote\`.
|
|
34219
|
+
|
|
34220
|
+
Install a **pinned** bridge once (so a compromised future release can't be
|
|
34221
|
+
auto-run with your token in its env), and keep the token in your shell rather
|
|
34222
|
+
than on disk:
|
|
34223
|
+
|
|
34224
|
+
\`\`\`bash
|
|
34225
|
+
npm i -g mcp-remote@<pinned-version> # pin to the current stable release, not @latest
|
|
34226
|
+
export WH_TOKEN="Bearer <your-pat>" # use a least-privilege, short-lived PAT
|
|
34227
|
+
\`\`\`
|
|
34228
|
+
|
|
34229
|
+
Then point Codex at the pinned binary and reference the token by env var, so the
|
|
34230
|
+
literal never sits at rest in the synced config:
|
|
34231
|
+
|
|
34232
|
+
\`\`\`toml
|
|
34233
|
+
[mcp_servers.warmhub]
|
|
34234
|
+
command = "mcp-remote"
|
|
34235
|
+
args = ["https://api.warmhub.ai/mcp", "--header", "Authorization:\${WH_TOKEN}", "--transport", "http-only"]
|
|
34236
|
+
\`\`\`
|
|
34237
|
+
|
|
34238
|
+
Restart Codex after editing the config.
|
|
34239
|
+
`;
|
|
34240
|
+
|
|
34241
|
+
// ../../packages/warmhub-cli/src/domains/onboard-adapters/cursor.md
|
|
34242
|
+
var cursor_default = '# Adapter: Cursor\n\n**How to run this:** paste this whole document into the Cursor chat as your first\nmessage, or save it to `.cursorrules` (or `.cursor/rules/`) so Cursor loads it\nautomatically. Then follow the Conductor Script below, one step per turn.\n\n**Connecting WarmHub (Act 1 details):** Cursor reads MCP servers from\n`.cursor/mcp.json` (project) or `~/.cursor/mcp.json` (global). Add WarmHub as an\nHTTP server:\n\n```json\n{ "mcpServers": { "warmhub": { "url": "https://api.warmhub.ai/mcp" } } }\n```\n\nOpen Cursor Settings → MCP and complete the sign-in when prompted — browser\nsign-in is the preferred path. Only if your setup blocks remote connectors, pass\na personal access token via a header instead. Put it in your **global**\n`~/.cursor/mcp.json`, not a project-local `.cursor/mcp.json` (which is easy to\ncommit by accident), and never commit a file holding a live token:\n\n```json\n{ "mcpServers": { "warmhub": { "url": "https://api.warmhub.ai/mcp", "headers": { "Authorization": "Bearer <your-pat>" } } } }\n```\n';
|
|
34243
|
+
|
|
34244
|
+
// ../../packages/warmhub-cli/src/domains/onboard-adapters/gemini.md
|
|
34245
|
+
var gemini_default = '# Adapter: Gemini CLI\n\n**How to run this:** paste this whole document into your Gemini CLI session as\nyour first message, or save it to `GEMINI.md` in the project so Gemini loads it\nautomatically. Then follow the Conductor Script below, one step per turn.\n\n**Connecting WarmHub (Act 1 details):** Gemini CLI reads MCP servers from its\n`settings.json` (`~/.gemini/settings.json` or the project `.gemini/settings.json`).\nAdd WarmHub as an HTTP server:\n\n```json\n{ "mcpServers": { "warmhub": { "httpUrl": "https://api.warmhub.ai/mcp" } } }\n```\n\nWarmHub authenticates with a bearer token — the browser OAuth flow is the\npreferred path. Only if your Gemini version cannot complete it, pass a personal\naccess token explicitly. Put it in your **global** `~/.gemini/settings.json`, not\nthe project `.gemini/settings.json` (which is easy to commit by accident), and\nnever commit a file holding a live token:\n\n```json\n{ "mcpServers": { "warmhub": { "httpUrl": "https://api.warmhub.ai/mcp", "headers": { "Authorization": "Bearer <your-pat>" } } } }\n```\n\nRestart Gemini CLI after editing settings.\n';
|
|
34246
|
+
|
|
34247
|
+
// ../../packages/warmhub-cli/src/domains/onboard-content.md
|
|
34248
|
+
var onboard_content_default = `# WarmHub Onboarding — Conductor Script
|
|
34249
|
+
|
|
34250
|
+
> You are guiding a new user through their first hour in WarmHub, one step at
|
|
34251
|
+
> a time. They are somewhat technical and comfortable working with an AI agent,
|
|
34252
|
+
> but they are brand new to WarmHub. Your job is to walk them from "just signed
|
|
34253
|
+
> up" to "I wrote real data through my agent" — patiently, one step per message.
|
|
34254
|
+
|
|
34255
|
+
## Operating rules (read before you start)
|
|
34256
|
+
|
|
34257
|
+
- **ONE step per message.** Never combine two steps into one response.
|
|
34258
|
+
- **STOP and wait** after every step. Do not continue until the user responds.
|
|
34259
|
+
- **End every message with a question or a clear prompt** so the user knows it
|
|
34260
|
+
is their turn. Never leave a message without something to respond to.
|
|
34261
|
+
- **Keep each message SHORT** — 3–5 sentences max. If it would be longer, split it.
|
|
34262
|
+
- **When you need the user to choose, {{ASK_PRIMITIVE}}**
|
|
34263
|
+
- **Run the real command yourself** when a step calls for it, then report what
|
|
34264
|
+
came back in plain language. Do not ask the user to run CLI commands unless
|
|
34265
|
+
they prefer the CLI path.
|
|
34266
|
+
- **No jargon.** Explain "thing", "shape", "assertion", and "commit" in plain
|
|
34267
|
+
business language the first time each appears (definitions below).
|
|
34268
|
+
- **Confirm the "Done when" check** before moving to the next step. If it is not
|
|
34269
|
+
met, help them fix it before advancing — do not skip ahead.
|
|
34270
|
+
|
|
34271
|
+
## Plain-language glossary (use these, not jargon)
|
|
34272
|
+
|
|
34273
|
+
- **Thing** — a named record in WarmHub (like a row with a name).
|
|
34274
|
+
- **Shape** — the template that says what fields a thing has (like a form).
|
|
34275
|
+
- **Assertion** — a claim *about* a thing, from a source, with a confidence.
|
|
34276
|
+
- **Commit** — one save. Every change is a commit, with who made it attached.
|
|
34277
|
+
- **Repo** — a workspace that holds your things, like a project folder.
|
|
34278
|
+
- **MCP** — the secure connection that lets your agent call WarmHub directly.
|
|
34279
|
+
|
|
34280
|
+
---
|
|
34281
|
+
|
|
34282
|
+
## The first hour — four acts
|
|
34283
|
+
|
|
34284
|
+
Move through these in order. Each act has a single goal and a concrete
|
|
34285
|
+
"Done when" you must verify before continuing.
|
|
34286
|
+
|
|
34287
|
+
### Act 1 — Get your agent talking to WarmHub (0–15 min)
|
|
34288
|
+
|
|
34289
|
+
**Goal:** the wire is alive — your agent can call a WarmHub tool and get real
|
|
34290
|
+
data back. This is the single most important step; do not rush past a failure here.
|
|
34291
|
+
|
|
34292
|
+
1. Welcome them in one short message. Tell them the first thing you'll do
|
|
34293
|
+
together is connect this agent to their WarmHub account, and ask if they're
|
|
34294
|
+
ready. **Wait.**
|
|
34295
|
+
2. Give them the MCP connection snippet for THIS agent (see the adapter header
|
|
34296
|
+
at the top of this script for the exact config and where it goes). Tell them
|
|
34297
|
+
to paste it, complete the auth flow their adapter described — pasting a
|
|
34298
|
+
personal access token only if it asked for one — and restart the agent. Ask
|
|
34299
|
+
them to tell you once they've done it. **Wait.**
|
|
34300
|
+
3. When they confirm, verify the wire yourself: call \`warmhub_doctor\` (or, if it
|
|
34301
|
+
is unavailable, \`warmhub_org_list\`). Report in one sentence whether the
|
|
34302
|
+
connection worked.
|
|
34303
|
+
|
|
34304
|
+
**Done when:** a WarmHub tool call succeeds and returns real data. If it fails,
|
|
34305
|
+
the usual cause is the token or a missing restart — walk them through it again
|
|
34306
|
+
before moving on.
|
|
34307
|
+
|
|
34308
|
+
### Act 2 — Explore a pre-seeded repo (15–30 min)
|
|
34309
|
+
|
|
34310
|
+
**Goal:** they see what WarmHub stores and why — concretely, before they have
|
|
34311
|
+
data of their own. You read; they watch the data model become legible.
|
|
34312
|
+
|
|
34313
|
+
1. Tell them WarmHub already has public example repos, and you'll explore one
|
|
34314
|
+
together so the concepts are concrete. Ask which interests them more, or
|
|
34315
|
+
offer to pick a good default. **Wait.**
|
|
34316
|
+
2. Describe the repo at a high level: call \`warmhub_repo_describe\` and summarize
|
|
34317
|
+
what kinds of things it holds, in plain language (1–2 sentences). **Wait.**
|
|
34318
|
+
3. Pull a few real records: call \`warmhub_thing_query\` (filter by a shape) and
|
|
34319
|
+
then \`warmhub_thing_get\` on one interesting result. Show them one concrete
|
|
34320
|
+
thing and explain what its fields mean. **Wait.**
|
|
34321
|
+
4. The bridge moment: ask them a real question about the repo, then answer it by
|
|
34322
|
+
querying — so they see the agent get an answer *they didn't have to write*.
|
|
34323
|
+
|
|
34324
|
+
**Done when:** they've seen one real thing explained, and the agent has answered
|
|
34325
|
+
one real question against the repo by querying.
|
|
34326
|
+
|
|
34327
|
+
### Act 3 — Their first write, through the agent (30–45 min)
|
|
34328
|
+
|
|
34329
|
+
**Goal:** they cross from "I see what this is" to "I have one" — a commit
|
|
34330
|
+
authored by their agent lands in a repo of their own.
|
|
34331
|
+
|
|
34332
|
+
1. Tell them it's time to make something of their own, and that you'll create a
|
|
34333
|
+
small starter repo for them under their personal org. Confirm a simple name
|
|
34334
|
+
(offer a default like \`scratch\`). **Wait.**
|
|
34335
|
+
2. Look up their personal org with \`warmhub_org_list\`, then create the repo as
|
|
34336
|
+
\`<their-org>/<name>\`: \`warmhub_repo_create\` (or, for the CLI path,
|
|
34337
|
+
\`wh init <org>/<repo>\`). Confirm in one sentence that the repo exists.
|
|
34338
|
+
3. Define a minimal shape first — a brand-new repo has none, and a thing needs a
|
|
34339
|
+
shape to validate against. Check the repo's write contract
|
|
34340
|
+
(\`warmhub_repo_describe\` → \`commitContract\`) for the exact operation format,
|
|
34341
|
+
then prepare a shape-definition op (e.g. a \`Note\` with a single \`text\` field).
|
|
34342
|
+
Explain in one line that a shape is just the form the data fills in.
|
|
34343
|
+
4. Write their first thing via \`warmhub_commit_submit\` — submit the shape
|
|
34344
|
+
definition and a short note (a \`Note\` that says they finished onboarding)
|
|
34345
|
+
together in one commit. Tell them what you're saving first, then save it.
|
|
34346
|
+
**Wait** for their go-ahead before writing.
|
|
34347
|
+
5. Confirm the write: read it back (\`warmhub_thing_get\`) and tell them the commit
|
|
34348
|
+
landed and that it's attributed to this agent.
|
|
34349
|
+
|
|
34350
|
+
**Done when:** a commit authored by their connected agent exists on HEAD of a
|
|
34351
|
+
repo they own, and you've read it back to confirm.
|
|
34352
|
+
|
|
34353
|
+
### Act 4 — Where to go next (45–60 min)
|
|
34354
|
+
|
|
34355
|
+
**Goal:** leave them oriented and able to keep going on their own. (Workspaces —
|
|
34356
|
+
the publish/accept loop — are coming but not yet agent-callable, so don't promise
|
|
34357
|
+
to run them; describe the idea and point to what works today.)
|
|
34358
|
+
|
|
34359
|
+
1. Recap in 2–3 sentences what they just did: connected an agent, explored real
|
|
34360
|
+
data, and wrote their first thing — all through their agent.
|
|
34361
|
+
2. Offer concrete next steps and let them pick one: (a) write a few more things
|
|
34362
|
+
in their repo, (b) explore another public repo, or (c) learn the full command
|
|
34363
|
+
set. For (c), tell them to run \`wh prime\`, which loads WarmHub's command
|
|
34364
|
+
reference into any agent's context.
|
|
34365
|
+
3. Close warmly in one short message and ask if they'd like to keep going with
|
|
34366
|
+
any of those, or stop here for now.
|
|
34367
|
+
|
|
34368
|
+
**Done when:** they know their three next options and have chosen to continue or
|
|
34369
|
+
to wrap up.
|
|
34370
|
+
|
|
34371
|
+
---
|
|
34372
|
+
|
|
34373
|
+
*This script is delivered by \`wh onboard\`. The pedagogy and steps above are
|
|
34374
|
+
identical for every agent; only the connection details in the header above differ.*
|
|
34375
|
+
`;
|
|
34376
|
+
|
|
34377
|
+
// ../../packages/warmhub-cli/src/domains/onboard.ts
|
|
34378
|
+
var NEUTRAL_ASK = "present the options as a short numbered list and wait for the user to choose before continuing.";
|
|
34379
|
+
var ADAPTERS = {
|
|
34380
|
+
claude: {
|
|
34381
|
+
header: claude_default,
|
|
34382
|
+
ask: "use the AskUserQuestion tool to present the options and wait for their selection."
|
|
34383
|
+
},
|
|
34384
|
+
gemini: {
|
|
34385
|
+
header: gemini_default,
|
|
34386
|
+
ask: NEUTRAL_ASK
|
|
34387
|
+
},
|
|
34388
|
+
codex: {
|
|
34389
|
+
header: codex_default,
|
|
34390
|
+
ask: NEUTRAL_ASK
|
|
34391
|
+
},
|
|
34392
|
+
cursor: {
|
|
34393
|
+
header: cursor_default,
|
|
34394
|
+
ask: NEUTRAL_ASK
|
|
34395
|
+
}
|
|
34396
|
+
};
|
|
34397
|
+
var SUPPORTED_AGENTS = Object.keys(ADAPTERS);
|
|
34398
|
+
function buildOnboarding(opts = {}) {
|
|
34399
|
+
const ask = opts.agent ? ADAPTERS[opts.agent].ask : NEUTRAL_ASK;
|
|
34400
|
+
const body = onboard_content_default.trimEnd().replace("{{ASK_PRIMITIVE}}", ask);
|
|
34401
|
+
if (!opts.agent)
|
|
34402
|
+
return body;
|
|
34403
|
+
const header = ADAPTERS[opts.agent].header.trimEnd();
|
|
34404
|
+
return `${header}
|
|
34405
|
+
|
|
34406
|
+
---
|
|
34407
|
+
|
|
34408
|
+
${body}`;
|
|
34409
|
+
}
|
|
34410
|
+
var onboardFlags = {
|
|
34411
|
+
agent: flag.string({
|
|
34412
|
+
description: `Target agent for kickoff + MCP config (${SUPPORTED_AGENTS.join("|")})`
|
|
34413
|
+
})
|
|
34414
|
+
};
|
|
34415
|
+
var handleOnboard = async (ctx, { flags }) => {
|
|
34416
|
+
const agent = flags.agent;
|
|
34417
|
+
if (agent !== undefined && !SUPPORTED_AGENTS.includes(agent)) {
|
|
34418
|
+
throw new CliError(2 /* UserInput */, "USER_INPUT", `Unknown agent '${agent}'.`, undefined, `Supported agents: ${SUPPORTED_AGENTS.join(", ")}. Omit --agent for the model-agnostic script.`);
|
|
34419
|
+
}
|
|
34420
|
+
const script = buildOnboarding({ agent });
|
|
34421
|
+
writeOutput(ctx, {
|
|
34422
|
+
agent: agent ?? null,
|
|
34423
|
+
supportedAgents: SUPPORTED_AGENTS,
|
|
34424
|
+
script
|
|
34425
|
+
}, () => {
|
|
34426
|
+
ctx.out(script);
|
|
34427
|
+
});
|
|
34428
|
+
};
|
|
34429
|
+
var ONBOARD_DOMAIN = defineDomain({
|
|
34430
|
+
kind: "flat",
|
|
34431
|
+
name: "onboard",
|
|
34432
|
+
summary: "Output an agentic onboarding script for new users",
|
|
34433
|
+
group: "workflow",
|
|
34434
|
+
args: "",
|
|
34435
|
+
flags: onboardFlags,
|
|
34436
|
+
examples: [
|
|
34437
|
+
"wh onboard",
|
|
34438
|
+
"wh onboard --agent claude",
|
|
34439
|
+
"wh onboard --agent gemini --json"
|
|
34440
|
+
],
|
|
34441
|
+
handler: handleOnboard
|
|
34442
|
+
});
|
|
34443
|
+
|
|
34186
34444
|
// ../../packages/warmhub-cli/src/domains/org.ts
|
|
34187
34445
|
var createFlags5 = {
|
|
34188
34446
|
"display-name": flag.string({ description: "Display name for the org" }),
|
|
@@ -37358,6 +37616,7 @@ function registerAllDomains(registry2) {
|
|
|
37358
37616
|
registry2.register(SHAPE_DOMAIN);
|
|
37359
37617
|
registry2.register(DOCTOR_DOMAIN);
|
|
37360
37618
|
registry2.register(PRIME_DOMAIN);
|
|
37619
|
+
registry2.register(ONBOARD_DOMAIN);
|
|
37361
37620
|
registry2.register(UPDATE_DOMAIN);
|
|
37362
37621
|
registry2.register(CHANNEL_DOMAIN);
|
|
37363
37622
|
registry2.register(NOTIFICATIONS_DOMAIN);
|
|
@@ -38477,7 +38736,7 @@ function resolveLogLevel(flags, env) {
|
|
|
38477
38736
|
// package.json
|
|
38478
38737
|
var package_default3 = {
|
|
38479
38738
|
name: "@warmhub/cli",
|
|
38480
|
-
version: "0.
|
|
38739
|
+
version: "0.57.0",
|
|
38481
38740
|
private: false,
|
|
38482
38741
|
type: "module",
|
|
38483
38742
|
description: "The wh CLI for WarmHub — create repos, commit and query data, and compound knowledge with your AI agents.",
|
|
@@ -38500,7 +38759,7 @@ var package_default3 = {
|
|
|
38500
38759
|
},
|
|
38501
38760
|
homepage: "https://docs.warmhub.ai/get-started/quickstart/#connect-via-cli",
|
|
38502
38761
|
bugs: {
|
|
38503
|
-
email: "support@warmhub.
|
|
38762
|
+
email: "support@warmhub.ai"
|
|
38504
38763
|
},
|
|
38505
38764
|
engines: {
|
|
38506
38765
|
node: ">=22"
|
|
@@ -39118,4 +39377,4 @@ if (!updateCheckSuppressedByArgv && shouldRunUpdateCheck(updateEligibility)) {
|
|
|
39118
39377
|
var interceptedExitCode = await maybeHandleComponentShellBoundary(dispatchArgv);
|
|
39119
39378
|
process.exitCode = interceptedExitCode === undefined ? await runCli(dispatchArgv, { version: package_default3.version }) : interceptedExitCode;
|
|
39120
39379
|
|
|
39121
|
-
//# debugId=
|
|
39380
|
+
//# debugId=C665F4BA94FD1E0F64756E2164756E21
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@warmhub/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.57.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "The wh CLI for WarmHub — create repos, commit and query data, and compound knowledge with your AI agents.",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
},
|
|
24
24
|
"homepage": "https://docs.warmhub.ai/get-started/quickstart/#connect-via-cli",
|
|
25
25
|
"bugs": {
|
|
26
|
-
"email": "support@warmhub.
|
|
26
|
+
"email": "support@warmhub.ai"
|
|
27
27
|
},
|
|
28
28
|
"engines": {
|
|
29
29
|
"node": ">=22"
|