* fix(openapi): recognize bare `object` type in annotation parser
The @openapi annotation parser's parseMiniSchema() only recognized the
bare words integer/number/boolean/string as scalar types. Any other
bare word - including `object`, used in 16 route annotations across
the codebase (e.g. severity:object, envVars:object on
POST /api/stacks/{name}/validate) - silently fell through to the
generic string fallback, so these fields were documented in
static/openapi.json as {"type": "string"} instead of
{"type": "object"}.
Add a dedicated branch for bare `object`, producing an opaque object
schema (no declared properties, since the bare word carries no shape
information of its own - a documented shape should use the existing
{...} form).
Verified no other bare non-standard word is used in any body:/resp-*:
annotation line across the 257 route files, so this closes the gap
completely for the current codebase.
Fixes#1531
* docs(openapi): document the existing field on POST /api/stacks/{name}/validate
The handler reads body.existing (an optional boolean, undocumented)
to control self-exclusion of the stack's own running containers/ports
from the cross-stack collision checks - the exact case the endpoint's
own summary advertises as handled. Without it, a client built strictly
from the OpenAPI document has no way to learn the field exists, and
will validate an existing stack the same way as a new one, silently
reintroducing false-positive collision findings against the stack's
own containers.
Add existing:boolean to the body: annotation, plus a one-line
description explaining the true/omitted semantics.
Fixes#1530
---------
Co-authored-by: Jarek Krochmalski <jotka@users.noreply.github.com>
fs-guard.test.ts pins process.env.DATA_DIR=/app/data at module load (needed
before the fs-guard import) but never restored it. Under Bun's single-process
run this leaked into every later test file; selfhst-icons then did
mkdirSync('/app/data/icon-cache/...') and failed EACCES on CI, turning main red
in a file-order-dependent way. Save and restore DATA_DIR in an afterAll.
When STACKS_DIR is set, local managed stacks are stored in a flat
$STACKS_DIR/<stackName>/ layout instead of $DATA_DIR/stacks/<env>/<stack>/.
Existing stacks are not moved automatically and continue to resolve from
their existing locations. Invalid or unwritable STACKS_DIR values produce a
warning and fall back to $DATA_DIR/stacks instead of aborting startup. With
this layout, local stack names must be unique across environments.
Hawser agents report their remote stacks directory on hello. That path is
persisted on the environment as hawser_stacks_dir so compose APIs and the UI
can show host paths rather than Dockhand staging paths. Staging paths are
remapped to and from the remote stack dir for compose files, backups, and
environment settings. Backup restore may write under either the default
staging root or the configured STACKS_DIR.
Co-authored-by: xd003 <xd003@users.noreply.github.com>