154 Commits
Author SHA1 Message Date
Hermes 954be9e868 feat: auto-restart policies, SSL monitoring, DNS propagation, dependency tracking, config drift detection
CI / Test & Lint (push) Has been cancelled
CI / Security audit (push) Has been cancelled
v1.9.0
2026-06-10 14:43:46 -07:00
Hermes afcccf811e release: 1.8.0 — service categories, monitoring widgets, update UX, fail2ban watchdog
CI / Test & Lint (push) Has been cancelled
CI / Security audit (push) Has been cancelled
v1.8.0
2026-06-10 12:52:13 -07:00
hermes 0aa7244cf4 infra: Samihost fail2ban watchdog (auto-unban trusted IPs, drift guard, cap at 200)
CI / Test & Lint (push) Has been cancelled
CI / Security audit (push) Has been cancelled
2026-06-10 11:28:42 -07:00
Hermes 1d8919532b feat: service categories end-to-end + monitoring widgets on main dashboard
CI / Test & Lint (push) Has been cancelled
CI / Security audit (push) Has been cancelled
Service categories (described in README roadmap, never wired):
- Backend: POST /services now persists category/containerId/port/ip/tailscaleOnly
- Backend: POST /services/update accepts category for in-place changes
- Frontend: category <select> in add-service modal (local + external)
- Frontend: category <select> in edit-service modal with current value
- Frontend: All Categories dropdown in service filter bar (auto-populated
  from both API categories and any categories present on rendered cards)
- Frontend: colored category badge (icon + name) on service cards
- Frontend: filter auto-refreshes after buildGrid

Monitoring on main dashboard (replaces orphaned monitoring-dashboard.html):
- New monitoring-widgets.js embeds a 5-card System Overview panel above
  the filter bar: Services, Containers Up, Avg CPU, Avg Memory, Health
- Pulls /api/v1/monitoring/stats + /api/v1/health-checks/status
- Auto-refreshes on DC.POLL.STATS (5s), color-coded bars (warn >=65%, bad >=85%)

Build:
- Added monitoring-widgets.js to init.js bundle in build.js
- Rebuilt dist/ bundles (core.js, features.js, init.js)
- sw.js cache version bumped automatically
- CSP hash regenerated
2026-06-10 01:49:27 -07:00
Hermes ea9bdf9598 Backup data/ dir before update, restore on rollback
- Add backup_data_dir() and restore_data_dir() using rsync
- Data backed up to backups/{version}/data-backup/ alongside code
- restore_data_dir() called in all three rollback paths (build fail, restart fail, health check fail)
- Add restart_container() that does rm + run to apply new env vars
- Handle action=rollback explicitly (no new version deployment)
- Uses standalone docker build instead of compose for reliability
- Add start.sh at /opt/dashcaddy/start.sh for reboot survival
2026-05-28 02:34:27 -07:00
Hermes c52016d727 fix: backup and restore data/ dir on update and rollback
The data/ directory (services.json, config.json, credentials,
TOTP config, notifications) was never included in the update
backup. Every update wiped user data — services, licenses,
credentials — requiring manual restore.

Now the host-side updater:
- Backs up data/ alongside code files before any update
- Restores data/ on rollback (build failure, restart failure,
  or health-check failure)
2026-05-28 02:08:33 -07:00
Hermes 588188edb5 update UX: badge→modal flow, orange update button, Update All, toast notifications, workflow triggers 2026-05-27 23:57:32 -07:00
Hermes 11823a1466 feat: premium tier features — auto-backup scheduling, resource alerting, bundled workflows, one-click revert, notification manager v1.7.0 2026-05-27 23:39:46 -07:00
Hermes 6ce0a18f98 release: 1.6.0 — openclaw routes, docker.client fix, /apps/ path deduplication v1.6.0 2026-05-27 22:22:37 -07:00
Hermes e07375f642 fix: mount openclaw routes at /openclaw prefix + fix docker.client wrapper + strip duplicate /apps/ paths across sub-routers
- openClawRoutes was mounted at root causing /status vs /openclaw/status mismatch
- ctx.docker is a typed wrapper {client,pull,...} — all calls now use docker.client.*
- templates/deploy/removal/restore sub-routers had /apps/ hardcoded in inner routes
  causing double-stacking when mounted under /apps (→ /apps/apps/templates etc)
- openclaw.js: GET /status, POST /deploy, GET/POST /proxy/*, DELETE /
2026-05-27 22:20:21 -07:00
Hermes 17edb3bc90 Fix 5 critical security vulnerabilities
1. WebSocket exec auth bypass (exec.js): Require valid JWT or API key
   before accepting WebSocket upgrade. Reject unauthenticated requests
   with 401 before the upgrade completes.

2. Shell injection in router auto-login (session-handlers.js): Validate
   baseUrl against safe hostname pattern before embedding in wget shell
   command. Reject with null session if invalid.

3. Path traversal in credentials routes (services.js): Add explicit
   serviceId validation (alphanumeric + dash/underscore/dot, max 100
   chars) to all three credential endpoints. Removed redundant
   try/catch wrapper.

4. execSync injection in CA CSR generation (ca.js): Add sanitize step
   replacing any non-alphanumeric domain chars with underscore before
   interpolation into shell subj argument. Redundant with existing
   validation but provides defense-in-depth.

5. Auth bypass when TOTP disabled (middleware.js): Split the logic
   cleanly — disabled TOTP means no auth (initial setup state), enabled
   TOTP means all auth methods checked (session/JWT/API key). Removed
   the sessionDuration:never conflating shortcut.
2026-05-27 18:05:35 -07:00
Coderbot 445da9f5fc fix: cross-subdomain SSO auto-login for *arr services
- Set Domain=.sami on session + CSRF cookies so browsers send them to all subdomains
- This fixes Caddy forward_auth returning 401 for radarr/sonarr/prowlarr
- Fix login URL concatenation bug (radarr.samilogin -> radarr.sami/login)
- Fix getSetCookie() missing from _httpsFetch/_httpFetch response objects
- Fix array/string handling for set-cookie header in session-handlers fallback
- Refactor csrf-protection to createCSRFMiddleware() factory with cookieDomain support
- Pass renewCSRFToken through middleware deps chain to TOTP route
2026-05-23 16:15:56 -07:00
Coderbot fe0f52ce17 fix: services/status probe fails with self-signed certs when CA is missing in container
The /api/v1/services/status endpoint (dashboard card ON/OFF) uses an
HTTPS agent to probe each service. When /app/pki/root.crt is missing
inside the container, it fell back to new https.Agent() which rejects
self-signed certificates. This caused all .sami domain probes to fail
with UNABLE_TO_GET_ISSUER_CERT_LOCALLY, making dashboard cards randomly
flip between ON and OFF depending on whether the Pylon relay responded
before the 10s deadline.

Fix: use rejectUnauthorized: false as fallback when CA cert is absent.
2026-05-23 14:35:39 -07:00
Coderbot 8df5214a45 fix: fetchT() now handles self-signed HTTPS certs
- Node.js native fetch() (undici) cannot use rejectUnauthorized:false
- Added _httpsFetch() using raw https module for internal .sami endpoints
- Fixes quality profile fetch for Sonarr/Radarr (was returning "fetch failed")
- Also fixed corrupted proces..._KEY -> process.env.PYLON_KEY in pylon

Coderbot fix #1
2026-05-23 14:16:18 -07:00
SamiandClaude Opus 4.7 2457d30ed3 fix(installer): point dashcaddy_auth snippet at /api/v1/auth/gate
The 1.5.0 API cutover removed the legacy `/api` mount, but the
`dashcaddy_auth` Caddy snippet generated by the installer still called
`uri /api/auth/gate/{args[0]}`. forward_auth then hit the notFoundHandler
and propagated a DC-404 to the browser instead of a 401-redirect to the
login flow (seen on requests.sami).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 01:33:50 -07:00
Sami a3ec1ffbb3 chore(release): bump to 1.5.0 2026-05-17 11:39:13 -07:00
SamiandClaude Opus 4.7 d36705bd90 feat: 1.5.0 prep — API v1 cutover, LICENSE, CHANGELOG, CI
- Remove legacy /api/ mount; all routes now under /api/v1/ only
- Update path matchers (CSRF excludes, public routes, audit log, rate limits)
- Move standalone routes (/api/network/ips, /api/docs, /api/docs/spec) to v1
- Update openapi.yaml (110 paths), CA pages, and 4 lingering frontend files
- Add LICENSE (proprietary EULA), CHANGELOG.md (Keep a Changelog format)
- Add .gitea/workflows/ci.yml (test+lint and security audit jobs)
- Fix 9 pre-existing no-empty lint errors so CI starts green
- Drop ad-hoc scratch reports and *.bak files from repo root

All 739 jest tests pass. Lint is clean.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17 11:38:45 -07:00
Sami cd8ccaba2b chore(release): bump to 1.4.10 2026-05-17 02:44:40 -07:00
Sami fd2e906963 fix(release): stage build-rewritten files (sw.js, index.html) in release.sh
build.js rewrites three things during `node build.js`:
  - status/dist/*.js (bundle output)
  - status/index.html (CSP hash for inline bootstrap)
  - status/sw.js     (cache name derived from bundle content)

release.sh was only staging status/dist/. Result: when a release didn't
touch index.html or sw.js source, the post-build modifications to those
two files were left unstaged, the commit included only dist/, and the
tarball shipped the stale sw.js. Clients then kept the previous SW
cache name -> activate handler never wiped the cache -> precached old
bundles served forever even after they were "updated" on disk.

Now stage index.html and sw.js too. They're tracked (not gitignored)
so a plain `git add` is enough; the commit is a no-op when nothing
actually changed.
2026-05-17 02:44:35 -07:00
Sami 68bcc0cb5f chore(release): bump to 1.4.9 2026-05-17 02:34:56 -07:00
Sami 7e4c3a0963 fix(frontend): container-logs misuse of wireModal blocked rest of features.js
container-logs.js called `wireModal(modal, null, closeModal)` — passing
the local `closeModal()` function as a third arg where wireModal expects
button elements. wireModal then did `closeModal.addEventListener('click',...)`,
threw TypeError, and because each module's IIFE is a top-level statement
in the concatenated features.js bundle, every IIFE *after* container-logs
silently skipped: snapshot, smart-arr-connect, notification-settings,
panel-tabs, backup-restore, resource-monitor, health-check, update-
management, docker-resources, compose-import, container-exec, audit-log,
weather, clock, card-badges, theme-builder, and license. Symptoms:
"Customize Theme" did nothing on click, license badge stuck at "FREE TIER"
(because license.js never ran), no weather, etc.

- container-logs.js: drop the wireModal call, wire backdrop click directly
  to the local closeModal so the SSE log stream actually stops on close.
- globals.js: harden wireModal — skip any closeBtn that isn't a real
  EventTarget. One typo upstream shouldn't take down the rest of features.js
  init silently.
2026-05-17 02:34:51 -07:00
Sami ac723630f2 chore(release): bump to 1.4.8 2026-05-17 02:20:41 -07:00
Sami 49c8ecfb73 fix(build): compute CSP hash on LF-normalized index.html
When the build runs on a Windows checkout, fs.readFileSync returns the
file with CRLF intact, and the hash of the inline bootstrap script's
body reflects those CRLFs. The release tarball / git transport / Linux
file system strip CRLF on the publishing host, so the browser sees the
LF-only version and computes a different sha256. CSP then blocks the
script — disabling the version widget, theme switcher, and any other
DOM bindings set up in that inline block.

Normalize CRLF -> LF before computing the hash (the on-disk file keeps
its native line endings; only the hash input is normalized). The CSP
allowlist now matches whatever Caddy actually serves.
2026-05-17 02:20:36 -07:00
Sami 939f95d147 chore(release): bump to 1.4.7 2026-05-17 02:03:36 -07:00
Sami bab5105e48 fix(frontend): unbreak dashboard — bundle order, IIFE close, dup const
Three merge-fallout bugs that combined to leave the services grid empty
and most UI inert:

1. error-handler.js was bundled into onboarding.js (loaded 3rd), but
   globals.js in core.js (loaded 1st) does `const errorHandler = new
   ErrorHandler()` at top level. ErrorHandler was undefined when core.js
   ran -> ReferenceError -> globals.js stopped, so window.APPS,
   _showTotpOverlay, loadServices, etc. were never set, and init.js
   blew up on every call into core's exports.

   Moved error-handler.js to the start of the core.js bundle so the
   class is on window before any other script touches it.

2. setup-wizard.js also declared `const errorHandler = new ErrorHandler()`
   at top level. Classic scripts share the document's top-level lexical
   environment, so this collided with globals.js's declaration ->
   redeclaration SyntaxError in features.js. Removed setup-wizard.js's
   copy; it picks up the global one.

3. tooltip-definitions.js closed its `(function(window){...})(window);`
   IIFE at line ~171 ("Validation module loaded"), then the TOOLTIP_
   DEFINITIONS array, getter helpers, window.TooltipDefinitions export,
   and final `debug(...)` log all sat at top level — outside the IIFE,
   where `debug` was no longer in scope. Removed the early close and
   added one at EOF so the whole file is in one IIFE.
2026-05-17 02:03:31 -07:00
Sami f9dad0abb4 chore(release): bump to 1.4.6 2026-05-17 01:41:52 -07:00
Sami ebfc3be9d1 fix(build): derive sw.js cache tag from bundle content hash
The service worker uses staleWhileRevalidate on /dist/*, so after a
release it would serve old bundles from cache indefinitely (cache is
only wiped when the cache *name* changes, which was hardcoded to
'dashcaddy-shell-v10'). Result: dashboard appears unchanged after a
self-update until the user manually unregisters the SW.

build.js now hashes the concatenated dist bundles and writes
`dashcaddy-shell-<10-hex-chars>` into sw.js. Any change in dist/
produces a fresh cache name; on the next page load the SW's activate
handler deletes all older caches and the new bundles are fetched.
2026-05-17 01:41:47 -07:00
Sami 3878509fc5 chore(release): bump to 1.4.5 2026-05-17 01:29:19 -07:00
Sami d7804d6b68 fix(updates): route frontend deploy through host-side updater
When DashCaddy is installed without `${DASHBOARD_DIR}:/app/dashboard` bind
mounted into the container (e.g. legacy DNS2 setup where Caddy serves from
/var/www/dashcaddy-status/), the self-updater's in-container copy to
/app/dashboard was a silent no-op — leaving the dashboard stale across
self-updates, which led to CSP-hash mismatches and a broken UI.

- self-updater: new hostFrontendDir option (default `/var/www/dashcaddy-status`
  on Linux, overridable via DASHCADDY_HOST_FRONTEND_DIR). When set, defer the
  frontend copy to the host-side updater by passing frontendStagingDir +
  frontendTargetDir in trigger.json. Now also includes `js/` in the copy list.
- dashcaddy-update.sh: read those new trigger fields and sync the dashboard
  files on the host. Auto-detect fallback for older self-updaters (no fields
  in trigger.json) so a single release upgrade self-heals.
2026-05-17 01:29:07 -07:00
Sami 5b12c5c9c0 chore(release): bump to 1.4.4 2026-05-16 23:55:17 -07:00
Sami 7e23cb5b06 fix(updates): allow notify endpoint past CSRF + portable JSON parse in release.sh
- csrf-protection: skip CSRF validation on /api/system/update-notify. The
  endpoint has its own X-DashCaddy-Notify-Secret auth and is only ever called
  machine-to-machine; browsers never reach it. Without this, the CSRF cookie
  check rejects the notify POST before the secret comparison runs.
- release.sh: the verify step piped curl into `node -p ".../dev/stdin"` which
  works on Linux but blows up on Windows/git-bash. Replaced with portable
  grep+sed extraction so the same script works on both publisher OSes.
2026-05-16 23:55:08 -07:00
Sami 850db40479 chore(release): bump to 1.4.3 2026-05-16 23:47:34 -07:00
Sami c66fe498b6 feat(updates): seamless release flow — push-notify, VERSION copy, robust mirror
- self-updater: per-instance notify secret (auto-generated), notifyAndApply()
  triggers an immediate check+apply for the publishing host
- routes: POST /api/system/update-notify (X-DashCaddy-Notify-Secret gated,
  added to public-routes allowlist so TOTP doesn't block machine-to-machine)
- dashcaddy-update.sh: include VERSION in backup/deploy/rollback copy lists;
  belt-and-suspenders write trigger.json commit to VERSION post-deploy.
  Fixes drift where /app/VERSION stayed at the old commit after self-update.
- release.sh: mirror failures are non-fatal+loud; HTTP-verify get2 after
  rsync; auto-notify co-located instance via /opt/dashcaddy/updates/notify-secret
  (or honour DASHCADDY_NOTIFY_TARGETS for multi-instance setups).
2026-05-16 23:46:53 -07:00
Sami edac587c5c Merge branch 'main' of http://100.98.123.59:3000/sami7777/dashcaddy
# Conflicts:
#	status/dist/features.js
2026-05-16 22:52:07 -07:00
Sami 824313c411 chore(release): bump to 1.4.2 2026-05-16 22:36:30 -07:00
Sami d3cef9ed86 chore(release): bump to 1.4.1 2026-05-16 00:34:17 -07:00
Krystie 77688daec7 Add service filter, batch operations, and snapshot features
- Service Filter Bar: search by name, filter by status (online/offline)
- Batch Operations: multi-select containers for start/stop/restart
- Container Snapshots: create and manage Docker checkpoints
- Added filter bar and batch action bar to index.html
- Added snapshot button to Admin tools section
- New JS modules: service-filter.js, batch-operations.js, snapshot.js
- Updated build.js to include new modules in bundle
2026-05-15 02:17:24 -07:00
Krystie 0cec447bf1 Expose openContainerLogsModal function for service card buttons
- Added window.openContainerLogsModal(containerId, containerName) function
- Service cards (grid.js) already call this when clicking the 📋 logs button
- Modal now pre-selects the correct container when called from a card
- Rebuilt dist files
2026-05-15 01:51:51 -07:00
Krystie c50b106faf Add Container Log Viewer UI with streaming, search, and download
- New container-logs.js module for viewing Docker container logs
- Integrated with existing API endpoints (/logs/containers, /logs/container/:id, /logs/stream/:id)
- Features:
  - Select container from dropdown
  - View logs with stdout/stderr color coding
  - Real-time log streaming via SSE
  - Search/filter within logs
  - Download logs as text file
  - Line count and filter indicators
- Added '📜 Container Logs' button to Tools section in index.html
- Added to features.js bundle via build.js
- Rebuilt dist files
2026-05-15 01:27:56 -07:00
Krystie 22c48076c0 Merge remote changes - resolve conflicts: keep remote package.json v1.4.0, keep local self-updater.js logic, features.js regenerated by build 2026-05-14 21:08:20 -07:00
Krystie 947007438f Update: version 1.2.0, new version UI features, CSP hash auto-update, bug fixes 2026-05-14 21:04:35 -07:00
Krystie f60a3370db fix: route all console.error through ErrorHandler for consistent tracking
Converted 35+ raw console.error calls to use ErrorHandler.logError() across
12 files. ErrorHandler provides structured logging, local error storage,
and error tracking integration.

Files:
- app-selector.js: 4 errors (fetch templates, port check, suggested port, deploy)
- globals.js: 2 errors (CSRF token get/add)
- service-credentials.js: 2 errors (save/clear credentials)
- totp-settings.js: 4 errors (TOTP setup, session duration, disable, AuthCard)
- notification-settings.js: 2 errors (load config, load history)
- setup-wizard.js: 2 errors (save config to server)
- progress-tracker.js: 4 errors (storage read/write/session/fallback)
- tooltip-definitions.js: 2 errors (validation, condition eval)
- tour-manager.js: 2 errors (Driver.js not loaded, tooltip not found)
- theme-adapter.js: 1 error (theme change callback)
- weather.js: 1 error (weather update)
- onboarding.js: removed duplicate console.error, fixed 2 remaining calls

All console.error calls in the DashCaddy frontend now go through ErrorHandler.
2026-05-14 01:31:55 -07:00
Krystie 5d404f5733 cleanup: wrap console.log calls behind window.DASHCADDY_DEBUG flag
Wrapped 22 console.log calls across 6 files with a debug() helper
that only logs when window.DASHCADDY_DEBUG is true in the browser console.

Files:
- tour-manager.js: 10 calls
- theme-adapter.js: 4 calls
- keyboard-shortcuts.js: 4 calls
- tooltip-definitions.js: 2 calls
- progress-tracker.js: 1 call
- live-events.js: 1 call

console.error and console.warn calls preserved — those indicate
real issues worth seeing in production.
2026-05-14 00:48:51 -07:00
Krystie 8ecae81703 frontend: gate routine console.log behind window.DASHCADDY_DEBUG
Suppress noisy module-load and initialization logs in production.
Logs still appear when window.DASHCADDY_DEBUG is set (e.g. during dev).
2026-05-14 00:13:50 -07:00
SamiandClaude Opus 4.7 f65af5d7fd fix(updater): stop false-positive "update available" loop when commit is unknown
Dockerfile never received DASHCADDY_COMMIT at build, so /app/VERSION held
'unknown'. _isNewer then treated same-version-different-commit as newer,
making the auto-updater rebuild the container indefinitely (each rebuild
still produced commit='unknown').

- self-updater._isNewer: normalize commits; treat unknown/null/empty as no
  commit info and fall back to pure version comparison
- self-updater._autoCheckAndApply + routes/updates: refuse to apply when
  local version >= remote version (belt-and-suspenders)
- update-management.js: hide '(unknown)' from version label
- Dockerfile: COPY VERSION instead of writing from build arg
- VERSION: committed placeholder ('dev'); scripts/release.sh now writes
  the real short SHA into the tarball's VERSION before tar-ing, so every
  published release ships with an accurate commit

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 18:20:59 -07:00
Sami 88206ff215 chore(release): bump to 1.4.0 2026-05-06 20:29:04 -07:00
SamiandClaude Opus 4.7 54196a2d4f chore: add scripts/release.sh for cutting + publishing releases
Automates what was previously a six-step manual process that, twice
in this codebase's history, has produced version skew between git and
the released tarball (v1.2.0 was published with package.json 1.2.0 in
the tarball but the bump was never committed back to gitea — making
"what code is in v1.2.0?" answerable only by extracting the tarball).

The script:
- Refuses to run with a dirty tree, off main, or already at the
  target version.
- Bumps dashcaddy-api/package.json, rebuilds status/dist/, commits
  + pushes to gitea — so the released artifact and gitea HEAD are
  always in lockstep.
- Clones gitea HEAD on the release host, verifies the cloned commit
  matches what we just pushed (catches a stale clone or a missed
  push), tars it, computes sha256, writes version.json.
- Refreshes install.sh on the release host alongside the tarball
  (fresh installs use the install.sh from the latest release).
- Mirrors the release dir to the get2 backup via rsync.
- Verifies live by curling version.json and re-hashing the served
  tarball.

Hosts overridable via DASHCADDY_RELEASE_HOST / DASHCADDY_MIRROR_HOST
/ DASHCADDY_GITEA_URL env vars.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 20:28:45 -07:00
Sami d81d1183db Merge feature/cloud-backups-and-history: cloud backups + resource history 2026-05-06 19:15:01 -07:00
SamiandClaude Opus 4.7 f537a0dd25 feat: cloud backup destinations + long-term resource history
Cloud backups (Dropbox / WebDAV / SFTP):
- backup-manager.js: save + load handlers per provider, credential
  resolution via credentialManager, destination probe.
- routes/backups.js: /credentials/{provider} (masked GET, POST, DELETE),
  /test-destination, scheduling endpoints.
- status/js/backup-restore.js: destination picker, provider-specific
  credential forms, test button wired to backend probe.
- npm deps already present (dropbox 10.34.0, webdav 5.7.1,
  ssh2-sftp-client 11.0.0).

Resource history:
- resource-monitor.js: three-tier rollup storage — raw 10s samples
  (7-day retention), hourly rollups (30-day), daily rollups
  (365-day). getHistoryByRange() auto-selects the appropriate tier.
- routes/monitoring.js: /monitoring/history/:containerId now supports
  startTime/endTime range mode (legacy ?hours=N still works).
- status/js/resource-monitor.js + dashboard.css: "History" tab with
  range buttons (1h/24h/7d/30d/1y), SVG sparklines for
  CPU / memory / network. Renderer handles raw and rolled-up shapes.

status/dist/features.js rebuilt from source via build.js.

Lifted out of wip/cloud-backups-and-history; the half-finished
app-deps feature from that branch (frontend calls /api/v1/apps/
check-dependencies but the endpoint doesn't exist) is preserved
separately on wip/app-deps for later.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 19:14:38 -07:00
SamiandClaude Opus 4.7 6e47df0d3c fix(installer): add src/ deploy + drop MakeDirectory=yes; bump 1.3.1
- install.sh now deploys the src/ directory alongside routes/.
  Without this, fresh installs of v1.3.0+ produce containers whose
  Dockerfile references src/ but the directory is missing on the host
  filesystem, so docker build fails with "/src: not found".

- The fallback heredoc that writes /etc/systemd/system/dashcaddy-
  updater.path drops MakeDirectory=yes for the same reason it was
  removed from the on-disk unit (e994ad1): systemd creates the watched
  trigger.json path as an empty directory on unit start, blocking
  every subsequent update with EISDIR.

Bumped to 1.3.1 so the existing v1.3.0 instance auto-updates and
picks up these and the host-script fix from 0cf6323.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 18:42:23 -07:00