home-hosted 0.8.3 → 0.9.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/AGENTS.md +9 -5
- package/README.md +16 -5
- package/dist/cli.js +888 -232
- package/dist/cli.js.map +1 -1
- package/docs/DDNS.md +2 -1
- package/docs/NOTIFICATIONS.md +72 -20
- package/docs/SERVERS.md +1 -0
- package/docs/UI_CREATION.md +16 -6
- package/package.json +24 -24
- package/uis/stock/dist/assets/de-DL4xkOYj.js +1 -0
- package/uis/stock/dist/assets/es-CKj-v3FY.js +1 -0
- package/uis/stock/dist/assets/fr-72WremqT.js +1 -0
- package/uis/stock/dist/assets/index-BNSSU69y.js +47 -0
- package/uis/stock/dist/assets/index-GxTN2fYn.css +2 -0
- package/uis/stock/dist/assets/ja-BU4XyMbC.js +1 -0
- package/uis/stock/dist/assets/ko-Db8xtJ0N.js +1 -0
- package/uis/stock/dist/assets/ru-Bs8KXP2O.js +1 -0
- package/uis/stock/dist/assets/vi-DdQD4h7B.js +1 -0
- package/uis/stock/dist/assets/zh-CN-DIrw2Ubv.js +1 -0
- package/uis/stock/dist/index.html +2 -2
- package/uis/stock/dist/ui.json +3 -3
- package/uis/stock/dist/assets/de-CiT_tMnf.js +0 -1
- package/uis/stock/dist/assets/es-JJDGEbt0.js +0 -1
- package/uis/stock/dist/assets/fr-CYIAuJgb.js +0 -1
- package/uis/stock/dist/assets/index-BCPp9MUj.js +0 -46
- package/uis/stock/dist/assets/index-Skf2FzpK.css +0 -2
- package/uis/stock/dist/assets/ja-DmykOijW.js +0 -1
- package/uis/stock/dist/assets/ko-C4EcOJB0.js +0 -1
- package/uis/stock/dist/assets/ru-Dlbre_Q1.js +0 -1
- package/uis/stock/dist/assets/vi-DhBWYY9I.js +0 -1
- package/uis/stock/dist/assets/zh-CN-BI0ZDO_Y.js +0 -1
package/AGENTS.md
CHANGED
|
@@ -10,8 +10,8 @@ level: `settings.json` (listener, auth, TLS policy, host vitals, backups, revers
|
|
|
10
10
|
`.ui/`, `.logs/` (the panel console), `.proxy/` (the engine, its generated config and nanny state), and
|
|
11
11
|
`run.json` (the live daemon's pid/url/token, 0600). Every workspace owns `.hh/<id>/`: `settings.json`
|
|
12
12
|
(server defaults, log retention, notifications, DDNS), `servers.config.json`, `.secrets.json` (0600:
|
|
13
|
-
Telegram
|
|
14
|
-
is sealed, because it is the one thing replayed to a third party), `.logs/` (per server, `<id>.log`
|
|
13
|
+
Telegram bot tokens, one per destination, plus DDNS credentials sealed with AES-256-GCM under
|
|
14
|
+
`HHOSTED_DDNS_SECRET` — only DDNS is sealed, because it is the one thing replayed to a third party), `.logs/` (per server, `<id>.log`
|
|
15
15
|
plus `<id>.log.1` when it rotates), and `.state/` (nanny state, its 0600 spawn spec until read,
|
|
16
16
|
`ddns.json`). A home still on the 0.6.x layout is **refused** by `ensureLayout()`, which names the file
|
|
17
17
|
and tells the person to install the latest 0.7.x; 0.8.0 does not relocate it. **The package ships no
|
|
@@ -39,7 +39,7 @@ Where knowledge lives, and when to reach for each:
|
|
|
39
39
|
| [`.agentDocs/COMPATIBILITY.md`](.agentDocs/COMPATIBILITY.md) | config and UI compatibility, migrations |
|
|
40
40
|
| [`.agentDocs/RELEASING.md`](.agentDocs/RELEASING.md) | how a release is cut, and which version to dispatch |
|
|
41
41
|
| [`docs/SERVERS.md`](docs/SERVERS.md) | entries, port conflicts, persistent entries |
|
|
42
|
-
| [`docs/NOTIFICATIONS.md`](docs/NOTIFICATIONS.md) | Telegram
|
|
42
|
+
| [`docs/NOTIFICATIONS.md`](docs/NOTIFICATIONS.md) | notification destinations: Telegram, webhooks, shared defaults |
|
|
43
43
|
| [`docs/DDNS.md`](docs/DDNS.md) | dynamic-DNS providers and hostnames |
|
|
44
44
|
| [`docs/REVERSE_PROXY.md`](docs/REVERSE_PROXY.md) | the Caddy engine, routes, certificates |
|
|
45
45
|
| [`docs/UI_CREATION.md`](docs/UI_CREATION.md) | the contract for a new UI |
|
|
@@ -56,6 +56,8 @@ pnpm run start # up --foreground (systemd, docker, a foregro
|
|
|
56
56
|
pnpm exec tsx src/cli.ts logs # the panel's own console output (--lines, --follow, --json)
|
|
57
57
|
pnpm dev # tsx-watch panel :6000 + the stock UI's Vite :6001, state in .dev-state/
|
|
58
58
|
pnpm dev --ui noc-console # the same, for another UI; --port/--ui-port override
|
|
59
|
+
pnpm dev --home /tmp/hh-dev # state elsewhere; HHOSTED_HOME is IGNORED here, and the real
|
|
60
|
+
# ~/.home-hosted is refused. Dev password: `dev`
|
|
59
61
|
pnpm run build # dist/cli.js + the stock UI (uis/stock/dist)
|
|
60
62
|
pnpm run build:uis # every UI under uis/, zipped into uis/dist/ (release assets)
|
|
61
63
|
pnpm run build:locales # i18n/sheets/*.csv -> the git-ignored i18n/generated/*.json (also
|
|
@@ -69,7 +71,8 @@ pnpm run set-password # non-interactive through HHOSTED_PASSWORD
|
|
|
69
71
|
pnpm run set-token # --generate prints a new API token once
|
|
70
72
|
pnpm run migrate # bring the config up to this release's schema
|
|
71
73
|
pnpm exec tsx src/cli.ts init # scaffold a project (interactive; --yes for defaults)
|
|
72
|
-
pnpm run media # regenerate docs/media
|
|
74
|
+
pnpm run media # regenerate docs/media; needs `pnpm exec playwright install chromium`
|
|
75
|
+
# once (browser only; `gif` alone does not)
|
|
73
76
|
```
|
|
74
77
|
|
|
75
78
|
The published bin is `home-hosted`, with an `hh` alias: both names run the same CLI.
|
|
@@ -128,7 +131,8 @@ These prevent defects if broken. The *why* for the non-obvious ones is in
|
|
|
128
131
|
**refuses** a commit that changed a shipped UI without raising it (a UI's `test/` and its own
|
|
129
132
|
`README.md` are exempt — neither is in the built asset).
|
|
130
133
|
`src/shared/**` is a UI build input, so a runtime contract needs the bump too — the hook does not
|
|
131
|
-
inspect that commit.
|
|
134
|
+
inspect that commit. **`tag` and `unix` are build provenance**, stamped into `dist/ui.json` by
|
|
135
|
+
`build-uis.mjs`; never committed to `public/ui.json`.
|
|
132
136
|
- **Paths.** `dataRoot` is state, under `dataRoot/.hh`; `projectDir` is the base for relative entry
|
|
133
137
|
paths. `{…}` and `${ENV}` expand in config — the full list is the table in
|
|
134
138
|
[`docs/SERVERS.md`](docs/SERVERS.md), which is what to keep in step. No package-relative state.
|
package/README.md
CHANGED
|
@@ -277,7 +277,7 @@ can be told what to be: *"Help me build a UI for home-hosted: nostalgic game the
|
|
|
277
277
|
| 📈 **Resources** | CPU and RSS of the whole process tree, with an optional memory ceiling that triggers a restart. |
|
|
278
278
|
| 🌡️ **Host vitals** | Load, memory, swap, disk and CPU temperature, with thresholds that notify once and again on recovery. |
|
|
279
279
|
| 🤖 **Token API** | Scripts and agents drive it with `Authorization: Bearer` — no browser, no session. [↑](#-agents-scripts-and-tools) |
|
|
280
|
-
| 🔔 **Notifications** | Telegram on crash, unhealthy, forced restart, recovery, host thresholds and DNS changes
|
|
280
|
+
| 🔔 **Notifications** | One list of **destinations** — Telegram chats and webhooks (ntfy, Discord, Slack, your own endpoint) — on crash, unhealthy, forced restart, recovery, host thresholds and DNS changes. The event toggles and throttle are set once, and each destination may inherit them or carry its own. [Setup here](./docs/NOTIFICATIONS.md). |
|
|
281
281
|
| 🌐 **Dynamic DNS** | Keep hostnames pointed at your public IP — Cloudflare, Namecheap, Spaceship, Porkbun, GoDaddy, Gandi and more. [DDNS.md](./docs/DDNS.md) |
|
|
282
282
|
| 🔀 **Reverse proxy** | One engine in front of everything, with automatic HTTPS: `git.example.com` → a Gitea entry, `media.example.com` → a service on another box, `panel.example.com` → the panel. Caddy, installed and supervised by the panel. [REVERSE_PROXY.md](./docs/REVERSE_PROXY.md) |
|
|
283
283
|
| 💾 **Backups** | Global settings, TLS, workspaces, and inside each one its settings, servers, secrets and declared data — plain `.zip`, or AES-256 with a password. Each secret is picked separately, and a restore can be customized. |
|
|
@@ -467,10 +467,15 @@ Everything binds `127.0.0.1` until you say otherwise.
|
|
|
467
467
|
|
|
468
468
|
## 🔔 Notifications
|
|
469
469
|
|
|
470
|
-
|
|
470
|
+
A message when something happens while you are not looking: a server that gave up restarting, a
|
|
471
471
|
failing health check, a forced restart, a recovery, a host threshold (disk, memory, swap, load,
|
|
472
|
-
temperature), or a dynamic DNS change.
|
|
473
|
-
|
|
472
|
+
temperature), or a dynamic DNS change.
|
|
473
|
+
|
|
474
|
+
Every alert goes to a list of **destinations** — a Telegram chat, a webhook, or several of each. The
|
|
475
|
+
event toggles and the throttle are set **once**, and each destination either inherits them or carries
|
|
476
|
+
its own. Rate-limited per destination, server *and* reason. Bot tokens and webhook credentials stay in
|
|
477
|
+
the secrets file, never in a config. **Two minutes of setup:
|
|
478
|
+
[NOTIFICATIONS.md](./docs/NOTIFICATIONS.md).**
|
|
474
479
|
|
|
475
480
|
---
|
|
476
481
|
|
|
@@ -495,6 +500,12 @@ ordinary `.zip`, or WinZip AES-256 with a password, restored per path. Known bui
|
|
|
495
500
|
dependency directories (`node_modules`, `dist`, `.next`, framework caches) are skipped per entry;
|
|
496
501
|
`backupIgnoreGenerated: false` captures them anyway.
|
|
497
502
|
|
|
503
|
+
**Automatic backups** write one archive on a schedule you set — the page asks in hours; the config
|
|
504
|
+
stores `intervalMs` — with a retention of its own (`Keep automatic`). The two counts are independent: `Keep` bounds the archives you take by hand,
|
|
505
|
+
and a scheduled pass never prunes one of yours to make room for its own. Both live in the same
|
|
506
|
+
directory, and an automatic archive is named `auto-…` so you can tell them apart — a name you drop
|
|
507
|
+
in by hand with that prefix is treated as one, so do not use it.
|
|
508
|
+
|
|
498
509
|
<details>
|
|
499
510
|
<summary><b>🔑 Restoring a secret</b></summary>
|
|
500
511
|
|
|
@@ -690,7 +701,7 @@ plus types; `pnpm test` is vitest; `pnpm run media` regenerates the GIF above.
|
|
|
690
701
|
| if you want to… | read |
|
|
691
702
|
| --- | --- |
|
|
692
703
|
| declare a server: every field, placeholders, port conflicts | [SERVERS.md](./docs/SERVERS.md) |
|
|
693
|
-
| get Telegram alerts working end to end | [NOTIFICATIONS.md](./docs/NOTIFICATIONS.md) |
|
|
704
|
+
| get Telegram or webhook alerts working end to end | [NOTIFICATIONS.md](./docs/NOTIFICATIONS.md) |
|
|
694
705
|
| expose the stack behind one hostname, with HTTPS | [REVERSE_PROXY.md](./docs/REVERSE_PROXY.md) |
|
|
695
706
|
| build a UI against the API | [UI_CREATION.md](./docs/UI_CREATION.md) |
|
|
696
707
|
| change the internals: architecture and the rules | [AGENTS.md](./AGENTS.md) |
|