home-hosted 0.6.7 → 0.6.8
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 +20 -7
- package/README.md +12 -6
- package/dist/cli.js +852 -615
- package/dist/cli.js.map +1 -1
- package/docs/DDNS.md +14 -10
- package/docs/UI_CREATION.md +1 -1
- package/package.json +1 -1
- package/uis/stock/dist/assets/index-B_4sGjNj.css +2 -0
- package/uis/stock/dist/assets/{index-C6tbSbCK.js → index-BuB3VX_S.js} +4 -4
- package/uis/stock/dist/index.html +2 -2
- package/uis/stock/dist/assets/index-Do5DvzS4.css +0 -2
package/AGENTS.md
CHANGED
|
@@ -6,11 +6,12 @@ and serves a UI. User docs: `README.md`, `docs/SERVERS.md` (entries and port con
|
|
|
6
6
|
`docs/NOTIFICATIONS.md`, `docs/DDNS.md`; UI authors: `docs/UI_CREATION.md`.
|
|
7
7
|
|
|
8
8
|
State lives only in `$HHOSTED_HOME` (default `~/.home-hosted`): `servers.config.json`,
|
|
9
|
-
`.control-secrets.json` (0600: password hash, API token hash, Telegram bot token, DDNS
|
|
10
|
-
`.logs/`, `.tls/`, `.backups/`,
|
|
11
|
-
|
|
12
|
-
`
|
|
13
|
-
config, a seed entry, or a path
|
|
9
|
+
`.control-secrets.json` (0600: password hash, API token hash, Telegram bot token, and DDNS
|
|
10
|
+
credentials sealed with AES-256-GCM under `HHOSTED_DDNS_SECRET`), `.logs/`, `.tls/`, `.backups/`,
|
|
11
|
+
`.ui/`, `.state/` (a persistent entry's nanny state, plus its 0600 spawn spec until the nanny reads
|
|
12
|
+
it, plus `ddns.json` — the last address each target confirmed), and `run.json` — the live daemon's
|
|
13
|
+
pid/url/token, 0600. The package ships **no servers**: never commit a config, a seed entry, or a path
|
|
14
|
+
that names one.
|
|
14
15
|
|
|
15
16
|
## Commands
|
|
16
17
|
|
|
@@ -149,7 +150,9 @@ a minor without one.
|
|
|
149
150
|
envelope `{ message, code, detail }`. Never hand-roll `c.json({ error })`.
|
|
150
151
|
- Document routes with `describeRoute` + `jsonBody(schema)`; `jsonBody` needs a real schema.
|
|
151
152
|
- Patch schemas carry no defaults; nested groups (`restart`/`health`/`stop`/`auth`/`tls`/`telegram`/
|
|
152
|
-
`http`) merge key-by-key, and an explicit `null` clears a key.
|
|
153
|
+
`http`) merge key-by-key, and an explicit `null` clears a key. `ddns` is the exception: its
|
|
154
|
+
`accounts`/`domains` lists are **replaced** (a merge cannot express removing a hostname), and only
|
|
155
|
+
`ipv4`/`ipv6` merge.
|
|
153
156
|
- Two-sided bounds read inclusively (`'1 <= number.integer <= 512'`). `test/shared/contracts.test.ts`
|
|
154
157
|
pins every boundary and the patch/schema parity — update it with any schema change.
|
|
155
158
|
- A new field in a **response** DTO is optional (`'x?'`) and its clients read it defensively. An
|
|
@@ -165,6 +168,12 @@ a minor without one.
|
|
|
165
168
|
- A destructive action that is one click away confirms in a **popover** (`KillPortButton.vue`),
|
|
166
169
|
never by arming the same button for a second press: an impatient double click on an arming
|
|
167
170
|
button fires it. Keep the safe choice first in the popover's tab order.
|
|
171
|
+
- **Docs ship with the change.** A user-visible change updates the docs that describe it
|
|
172
|
+
(`README.md`, `docs/*.md`) in the same commit — do not forget them; a stale doc is a bug like
|
|
173
|
+
stale code.
|
|
174
|
+
- **UIs move together.** `uis/stock` is not the only client: a change to it — or to a shared
|
|
175
|
+
contract it reads — lands in every other UI under `uis/`, and each altered UI bumps its
|
|
176
|
+
`ui.json` per the rule above.
|
|
168
177
|
|
|
169
178
|
## Compatibility
|
|
170
179
|
|
|
@@ -194,6 +203,9 @@ either is a last resort, and never an accidental one.
|
|
|
194
203
|
- **Unknown keys are dropped from the resolved config, kept on disk, and listed in a startup
|
|
195
204
|
warning.** Dropping one is the normal way a newer config looks here, so it must never fail the
|
|
196
205
|
group it sits in (that used to reset `control` — port, bind, auth policy — to schema defaults).
|
|
206
|
+
A *write* to a group validates the same tolerant way (`parseTolerant` via the store), so a key this
|
|
207
|
+
release does not know never blocks a save — removing a key from a schema must not brick the page
|
|
208
|
+
that writes it.
|
|
197
209
|
- **Migrations ship inside the package** (`src/config/migrations.ts`), are ordered, idempotent and
|
|
198
210
|
described in one line each. `home-hosted migrate` prints the plan, keeps `servers.config.json.bak`,
|
|
199
211
|
refuses to write a config it cannot read, and needs consent: `--yes`, `HHOSTED_MIGRATE=allow`, or a
|
|
@@ -348,7 +360,8 @@ either is a last resort, and never an accidental one.
|
|
|
348
360
|
- **Server field**: `serverSchema` + its patch in contracts, merge keys in `config/store.ts` when
|
|
349
361
|
nested, the form in `uis/stock/src/components/settings/`, and the contract tests.
|
|
350
362
|
- **UI**: a new `uis/<name>/` with a `vite.config.ts` from the shared factory;
|
|
351
|
-
`node scripts/build-uis.mjs <name> --zip`. The contract is `docs/UI_CREATION.md`.
|
|
363
|
+
`node scripts/build-uis.mjs <name> --zip`. The contract is `docs/UI_CREATION.md`. A change to one
|
|
364
|
+
UI (`stock`, `noc-console`) is carried to the others in the same commit.
|
|
352
365
|
- **Capability**: a stateless `src/providers/*` returning plain data; a DDNS provider is one file plus
|
|
353
366
|
a registry line (`src/providers/ddns/index.ts`), and the settings form, credentials and validation
|
|
354
367
|
follow from its metadata — see `docs/DDNS.md`.
|
package/README.md
CHANGED
|
@@ -375,8 +375,10 @@ Everything binds `127.0.0.1` until you say otherwise.
|
|
|
375
375
|
never taken from the message, and anything the panel supervises is refused, not killed. A server
|
|
376
376
|
that [restarts itself](./docs/SERVERS.md#when-a-program-restarts-itself) can be followed, or replaced
|
|
377
377
|
with a supervised copy.
|
|
378
|
-
- **Secrets never enter the config**: the password hash, the API token hash
|
|
379
|
-
token live in `$HHOSTED_HOME/.control-secrets.json` with mode `0600`; the
|
|
378
|
+
- **Secrets never enter the config**: the password hash, the API token hash, the Telegram bot
|
|
379
|
+
token and the DDNS credentials live in `$HHOSTED_HOME/.control-secrets.json` with mode `0600`; the
|
|
380
|
+
TLS pair in `.tls/`. DDNS credentials are sealed with AES-256-GCM under `HHOSTED_DDNS_SECRET`
|
|
381
|
+
(default `hh` — set your own).
|
|
380
382
|
- **Behind a proxy** turn on `trustProxy` and let `cookieSecure: auto` add `Secure` on https, or
|
|
381
383
|
upload a PEM pair and let home-hosted terminate TLS itself.
|
|
382
384
|
|
|
@@ -403,9 +405,11 @@ tokens stay in the secrets file. **Providers and the config shape: [DDNS.md](./d
|
|
|
403
405
|
## 💾 Backups
|
|
404
406
|
|
|
405
407
|
**Settings → Backups** archives the config, secrets, TLS pair and every data directory your entries
|
|
406
|
-
declare — an ordinary `.zip`, or WinZip AES-256 with a password, restored per path.
|
|
407
|
-
and
|
|
408
|
-
|
|
408
|
+
declare — an ordinary `.zip`, or WinZip AES-256 with a password, restored per path. *Create backup…*
|
|
409
|
+
lists what the archive will hold and lets you drop any item; *Restore…* shows the same list from an
|
|
410
|
+
archive before anything is written. Known build output and dependency directories (`node_modules`,
|
|
411
|
+
`dist`, `.next`, framework caches) are skipped per entry; `backupIgnoreGenerated: false` captures them
|
|
412
|
+
anyway.
|
|
409
413
|
|
|
410
414
|
<details>
|
|
411
415
|
<summary><b>🚚 One archive is a whole setup</b></summary>
|
|
@@ -416,7 +420,9 @@ archive and restore. Definitions come back, data lands where *this* machine's co
|
|
|
416
420
|
|
|
417
421
|
It works because an archive carries its own `servers.config.json` and paths are matched by the
|
|
418
422
|
**declaration** (`omniroute:DATA_DIR`), not by an absolute path from the source machine. A restore never
|
|
419
|
-
writes where no config declares.
|
|
423
|
+
writes where no config declares. A declaration using `{projectDir}`, `{dataRoot}` or `{home}` follows
|
|
424
|
+
the restoring panel (`{projectDir}` is `HHOSTED_PROJECT` or the panel's cwd, not `HHOSTED_HOME`); a
|
|
425
|
+
literal absolute path is restored to that same path.
|
|
420
426
|
|
|
421
427
|
</details>
|
|
422
428
|
|