[grade=A urn:ump:swcz3quualvlmdanpqm5v46cr6zkazes7erbftk6rj3jxv6ip4fa] docs(DC-170): changelog rebuild, version sync, API-SURFACE regen (audit batch 7)
Customer-facing professionalism tier (AUDIT-2026-10-27.md findings 34-39):
- CHANGELOG.md rebuilt to Keep-a-Changelog: ONE Unreleased section, the
2026-08-12 hardening sprint folded into 1.17.0 (no v1.16.0 tag exists,
verified via git tag -l), ALL 7 judge-grade/URN lines moved out of
customer copy into RELEASE-EVIDENCE-internal.md, missing DC-166/169
entries added, full DC-170 sweep entry written, DC-171 DNS-parity
ticket recorded, date order strictly descending across all 22
sections (1.1.5 restored with its true content after the re-sort ate
the heading), compare-link chain filled (Unreleased from v1.17.0,
1.17.0 from v1.14.6-patched, 18 missing version links added)
- VERSION 1.15.0 -> 1.17.0 + openapi.yaml 1.15.0 -> 1.17.0 (three-way
drift closed: VERSION=package.json=openapi; start.sh build stamps
single-sourced)
- README: quickstart endpoints rewritten against the live router (the
fictional /api/caddy/{config,reload} section replaced with the real
/api/v1/caddy/* routes from routes/sites.js), 50+ -> 78 templates
(proven in VERIFY-OUTPUT.txt via require of src/docker/app-templates),
version badge 1.17.0, yourusername links -> sami7777, roadmap
reconciled with shipped features (multi-user DC-048, DNS UI DC-166,
backup automation marked shipped), verification note scoped to the
MCP drift gate's actual coverage
- API-SURFACE.md regenerated: 443 handler rows / 368 unique paths / 441
unique operations / 88 public rows, Known Limitations section (static
extraction, line-oriented, may omit multiline/computed/chained
registrations), exact duplicate registrations with file:line
- VERIFY-OUTPUT.txt: verbatim command/output transcript proving all
version + count claims (sha256 of the generated doc recorded and
matching)
- state-manager test mock extended for the atomic tmp+rename contract
Judge rounds: r1 D -> r2 D -> r3 D -> r4 D -> r5 C -> r6 C -> r7 C ->
r8 C -> r9 C -> r10 A (each round fixed blockers in-lane; no bypasses).
r10 independently reproduced all counts and the generated doc hash
against the live repository.
This commit is contained in:
7 files changed
+679
-571
No files matched your search
+515
-383
File diff suppressed because it is too large.
Load diff
+81
-159
@@ -6,143 +6,63 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Added
|
||||
|
||||
- **DC-168 judge: grade B (round 16)** urn:ump:ejzlob2bde6m6ivxfpgidmwu5a62pvl4wddm4iav7mwfuyfogirq
|
||||
- **DC-168: calendar widget UX + theming.** Chip shows "No upcoming
|
||||
appointments" (muted) when the connected calendar is empty; with events it
|
||||
shows the next appointment with a highlighted day/time span. Modal gains a
|
||||
month grid (prev/next nav, appointment days accent-tinted, today ring,
|
||||
per-event time dots) plus the upcoming list (ended events excluded,
|
||||
ongoing included). Universal theme contrast: chip colors derive via
|
||||
color-mix from --accent (lighten on dark surfaces via html.light-bg,
|
||||
darken on light) — WCAG >= 4.5:1 verified against all 10 builtin themes
|
||||
(worst 4.60:1). Month-following fetch with disjoint-interval coverage
|
||||
tracking; window-authoritative event cache (calendar-cache.js, uid+start
|
||||
keys) so deletions/reschedules propagate on refetch; chip always renders
|
||||
from the now-window even with a navigated viewMonth. 23 calendar tests.
|
||||
- **DC-167 judge: grade B (round 11)** urn:ump:kfn7m6vzd4ias2u5ghg62hvoug3j2y2gmturnytdz4g4od35hx4a
|
||||
- **DC-170: full-software reliability and truth sweep (2026-10-27/29).** 46 findings
|
||||
from a three-agent audit, top items fixed in 7 graded batches: TOTP gate no longer
|
||||
blocks API-key/JWT auth (machine credentials were dead on every TOTP install —
|
||||
verified live with a freshly minted key); calendar widget writes no longer die on
|
||||
CSRF 403s (error path, mobile modal, refresh races, keyboard access fixed too);
|
||||
19 controls silently killed by the content-security policy revived (Disk Safety
|
||||
modal + sliders, AI assistant button, login logos, premium upsells, health
|
||||
Edit/Delete); 6 MCP tools remapped to real routes (container list and DNS
|
||||
record-list routes added); the deploy tool now reports what it actually does and
|
||||
derives the site domain from configuration; DNS update endpoints answer every
|
||||
request (previously hung); state files write atomically (a crash can no longer
|
||||
corrupt services.json/config.json); dashboard WebSocket auth fails closed;
|
||||
service worker offline fallback works, caches only good responses, installs
|
||||
tolerantly; public config endpoint degrades gracefully on a corrupt file; slow
|
||||
calendar feeds get their intended 15-second timeout; calendar source updates no
|
||||
longer wipe the other credential type. New capability-drift gate: every MCP
|
||||
tool's handler-issued call is verified against the declared routes (28 tools).
|
||||
- **DC-169: missing service logos.** samimail, samipanel, gitea, and DashCaddy
|
||||
service-card logos committed and wired.
|
||||
- **DC-168: calendar widget UX + theming.** Chip shows "No upcoming appointments"
|
||||
(muted) when the connected calendar is empty; with events it shows the next
|
||||
appointment with a highlighted day/time span. Modal gains a month grid
|
||||
(prev/next nav, appointment days accent-tinted, today ring, per-event time
|
||||
dots) plus the upcoming list (ended events excluded, ongoing included).
|
||||
Universal theme contrast via color-mix from --accent — WCAG >= 4.5:1 verified
|
||||
against all 10 builtin themes (worst 4.60:1). Month-following fetch with
|
||||
disjoint-interval coverage tracking; window-authoritative event cache
|
||||
(calendar-cache.js, uid+start keys) so deletions/reschedules propagate; chip
|
||||
always renders from the now-window even with a navigated viewMonth.
|
||||
- **DC-167: CalDAV default-namespace multistatus fix (Radicale silent
|
||||
zero-events).** extractCalendarsAndEvents required a namespace prefix on
|
||||
<response>; Radicale emits bare <response> (default DAV ns) so every entry
|
||||
was silently dropped — REPORT 200, ok:true, 0 events, no error. Prefix made
|
||||
optional in the split + detection regexes. Discovered while connecting the
|
||||
owner's DNS3 Radicale (appt.sami) as a DashCaddy calendar source (owner
|
||||
request: connect DNS3 calendar to DNS2 DashCaddy). 9-test ns suite
|
||||
(extraction incl. mixed doc; empty multistatus; namespace-aware fixture
|
||||
parse; undeclared element+attribute prefix rejection, both quote styles;
|
||||
positive declared-attr case). Ops: NODE_EXTRA_CA_CERTS drop-in for the Sami
|
||||
Home CA; source registered via authenticated API at the collection URL.
|
||||
- **DC-165 judge: grade B (round 5)** urn:ump:oqgczb6zv5bemekbxko7gi5rvfle6yoshwgfwsx4mbbj4xmg6paq
|
||||
- **DC-165: product/site uniformity + LLM-readable capabilities.** Site-vs-product
|
||||
audit reconciliation (owner: "advertise as Premium", "It should be LLM readable"):
|
||||
'fleet' added to PREMIUM_FEATURES and `requirePremium('fleet')` mounted at the
|
||||
/fleet ROUTER prefix (app.js) so every sub-route present and future inherits the
|
||||
gate — proven by 4 real-boot composition-root e2e tests (free 403 envelope
|
||||
contract, per-feature check, with-fleet gate cleared, hosts/status/deploy
|
||||
inheritance). 'workflows' + 'auto-backup' (gated in routes forever, missing from
|
||||
the constant so the offline path could never grant them) listed with
|
||||
source-quoted descriptions; marketing pages now advertise them (manual backup +
|
||||
Disaster Recovery stay free — copy matches code exactly). Offline activations
|
||||
forward-migrate on load (append-only union, online untouched — server stays
|
||||
authoritative). GET /api/v1/capabilities: public machine-readable manifest of the
|
||||
RUNNING build — six measured fields (version, template count/categories, MCP
|
||||
tools, transport identity triple, premium list, language count) derived at request
|
||||
time from the runtime modules (single source: MCP_RUNTIME exported from
|
||||
routes/mcp.js, read by /info and capabilities alike), static metadata fields
|
||||
honestly labeled; PUBLIC_ROUTES + drift test + OpenAPI 200-only contract;
|
||||
no-secrets negative test. License-server grant list extended to
|
||||
sso/recipes/swarm/fleet/workflows/auto-backup with existing records backfilled
|
||||
(ops). Marketing repo (dashcaddy.net, separate commits): counts 77→78 everywhere,
|
||||
internal-identifier sweep (~85 private-TLD/IP/user/path hits → .home/example
|
||||
style), radicale install guide (78th), calendar/Connect-AI advertised, MCP claim
|
||||
softened to real scope + capabilities pointer, llms.txt → runtime ground truth,
|
||||
robots LLMs-Txt line. 124 targeted tests (9 dc165 + 4 fleet-e2e + 76 license +
|
||||
21 tier + 14 drift); 73 MCP tests re-green after refactor.
|
||||
- **DC-164 judge: grade B (round 6)** urn:ump:5vuahbn4znf7hrrshjvu2pcbqln5m6qcrpkkn3mx6y2rvvmdtqoa
|
||||
- **DC-164: operator env overrides + license-material untracking.** start.sh
|
||||
forwards `-e` flags from /etc/dashcaddy/operator.env (root-owned KEY=VALUE,
|
||||
0600) into the container via scripts/operator-flags.js: one pinned fd
|
||||
(lstat pre-check → open O_RDONLY|O_NOFOLLOW|O_NONBLOCK → fstat+read on the
|
||||
same descriptor) so symlinks, FIFOs/devices, group/other-readable or
|
||||
special-bit modes, and foreign ownership are refused (exit 3, fail closed:
|
||||
warn + forward nothing; any other helper failure ABORTS startup, fail
|
||||
loud). Canonical flag ALLOW_LIFETIME_LICENSE=true — creator hosts only;
|
||||
it is a deployment rail, not the boundary: offline lifetime codes must
|
||||
HMAC-verify against the signing secret which is never shipped to customers
|
||||
(installs carry .license-secret-hash). 17 executed tests (FIFO non-block
|
||||
regression, O_NOFOLLOW symlink-to-valid-target, mode/owner matrix,
|
||||
injection-inert values). Root-cause fix for the 2026-10-08 incident:
|
||||
data/services.json, .license-secret, .license-counter UNTRACKED +
|
||||
.gitignore'd — deploy checkouts can no longer clobber live runtime state.
|
||||
- **DC-163 judge: grade B (round 2)** urn:ump:l2tg66wmchkmd6fde4k3ojwc56zpxqh657spe37bu6dpvduswalq
|
||||
- **DC-163: AI assistant that actually works — LLM intent engine + fixed
|
||||
chat panel.** The 🤖 floating assistant was broken end-to-end: the
|
||||
frontend read a nonexistent `data.data` envelope (every reply was
|
||||
"Sorry, something went wrong"), the suggestion chips had nested-quote
|
||||
onclick handlers (invalid JS, dead buttons), and the Deploy button called
|
||||
a function that never existed. All three fixed. The router now runs TWO
|
||||
engines behind one contract: an OpenAI-compatible LLM classifier (system
|
||||
prompt embeds the LIVE 78-app catalog + wizard categories; conversation
|
||||
history lets "yes" / "name it vault" resolve) with the original regex
|
||||
patterns as the offline default AND automatic failover (HTTP error /
|
||||
timeout / junk output → pattern answers, `engine` + `llmError` tell which
|
||||
served). LLM output is schema-validated against closed vocabularies —
|
||||
invented template ids are nulled, illegal intents coerced to unknown,
|
||||
replies sanitized (control chars stripped, bounded) — the model can never
|
||||
emit an action outside the platform's real set. Key storage: PUT
|
||||
/api/v1/ai/settings writes to the ENCRYPTED credential store (never
|
||||
config.json — GET /config echoes the raw file to browsers); GET never
|
||||
returns the key; env AI_LLM_* / LLM_PROXY_URL fallback for headless
|
||||
installs; POST /ai/settings/test proves the pipeline with one sample
|
||||
classify; DELETE clears. Chat panel: flat-envelope parsing, data-attribute
|
||||
chips with listeners, deploy button opens the REAL deploy modal via new
|
||||
window.openDeployConfigFor(id) in app-selector.js, engine badge in the
|
||||
header, ⚙ settings sub-panel. "Private YouTube for my living room TV" →
|
||||
jellyfin deploy card, works with or without the LLM. 20 new tests
|
||||
(engine selection, failover incl. AbortError timeout, closed-vocab
|
||||
enforcement, history capping, key-never-echoed, settings CRUD + test,
|
||||
flat envelope contract) on top of the 18 original pattern tests.
|
||||
OpenAPI: 4 AI path entries. dist bundle rebuilt.
|
||||
- **DC-162 rev2: "Connect your AI" — spec Streamable HTTP MCP + one-click keys.**
|
||||
New primary-row button 🤖 Connect AI on the dashboard opens a modal that
|
||||
mints a dedicated `dk_` key and returns the standard MCP Streamable-HTTP
|
||||
connection card ({url, transport, headers} + per-client notes) for
|
||||
Claude / ChatGPT / generic clients. Transport implements MCP 2025-03-10
|
||||
Streamable HTTP: POST answers application/json (valid notifications →
|
||||
202; malformed → JSON-RPC -32600 with the spec's no-reply-for-broken-
|
||||
notifications rule; batching removed in this revision → rejected), GET/
|
||||
DELETE return 405 + Allow: POST (stateless request/response server —
|
||||
spec-permitted; clients needing server-initiated streams use the stdio
|
||||
bridge). Credential TYPE preservation: apikey callers proxy x-api-key
|
||||
downstream, jwt callers proxy Authorization Bearer — key scopes apply
|
||||
identically at the loopback API. JSON-RPC validation: -32600 structural
|
||||
(jsonrpc/method/params/id), -32602 invalid tool params, Origin DNS-
|
||||
rebinding guard, MCP-Protocol-Version header check, Accept negotiation.
|
||||
GET /mcp/connections lists only "AI connection (…)" keys. Tool path
|
||||
params URL-encoded. Backend: routes/mcp.js (POST, GET/DELETE 405, /info,
|
||||
/connections, /config), src/mcp/mcp-core.js shared by stdio + HTTP,
|
||||
stale 1.15.0 version literal removed (reads package.json).
|
||||
73 route+core tests (incl. 16-case JSON-RPC boundary matrix) +
|
||||
composition-root e2e proves the mount boots.
|
||||
OpenAPI: 4 MCP path entries. status/dist + sw.js regenerated in-tree.
|
||||
- **DC-162 judge: grade B (round 3)** urn:ump:or2qqhcytp6lfzlyi7xru7hdqy3uar2hbjllsrrbxrbray3c5kpa
|
||||
- **DC-161: Calendar widget + Radicale auto-wiring.** New top-bar calendar widget
|
||||
(`status/js/calendar-widget.js`) showing upcoming appointments; settings modal for
|
||||
adding CalDAV / ICS-feed sources with a Test-connection probe. Backend:
|
||||
`routes/calendar.js` (`GET/POST/PUT/DELETE /api/v1/calendar/sources`,
|
||||
`GET /api/v1/calendar/events`, `POST /api/v1/calendar/radicale/provision`,
|
||||
`POST /api/v1/calendar/discover`), dependency-free RFC 5545 ICS parser with
|
||||
bounded RRULE expansion (`src/calendar/ics-parser.js`), CalDAV REPORT client
|
||||
over node:https (`src/calendar/caldav-client.js`). When Radicale is deployed
|
||||
through the App Selector, the deploy hook auto-provisions htpasswd credentials
|
||||
(pure-Node APR1 hash, verified byte-for-byte against `openssl passwd -apr1`)
|
||||
and registers the calendar source — the widget connects with zero user input.
|
||||
Manual bring-your-own sources (Radicale/Baikal/Nextcloud hosted elsewhere,
|
||||
iCloud/Fastmail CalDAV, plain ICS feeds) wire in through the settings modal.
|
||||
Codex judge: **grade B (round 5)** —
|
||||
urn:ump:znykdi6ufm53sgnhkep7ghlda7aoo55nipghjtstlkpqqmxuv2zq.
|
||||
<response>; Radicale emits bare <response> (default DAV ns) so every entry was
|
||||
silently dropped — REPORT 200, ok:true, 0 events, no error. Prefix made
|
||||
optional in the split + detection regexes.
|
||||
- **DC-166: MCP tool-set expansion 17 → 28 tools + workflows double-prefix fix
|
||||
(merged from dc/DC-166-mcp-completion).** 11 new AI-tool handlers over existing
|
||||
routes (calendar, security, license, capabilities, DNS records, deploy recipe,
|
||||
workflow run, tailscale status). Fixed the workflows router that composed
|
||||
`/api/v1/workflows/workflows/...` — every dashboard workflow toggle and Run Now
|
||||
had been 404ing in production. Route-existence verifier resolves tool paths
|
||||
against declared routes.
|
||||
- **DC-165: product/site uniformity — fleet gate proven at composition root,
|
||||
single-source capabilities manifest.** The public `/api/v1/capabilities`
|
||||
endpoint advertises what the running build actually does (route counts,
|
||||
templates, MCP tools measured at runtime), so the marketing site, docs, and
|
||||
llms.txt can never disagree with the product.
|
||||
- **DC-171 (ticketed, pending): DNS provider plug-in parity** — capability
|
||||
reporting at provider-choice time (RFC2136 is push-only: create/resolve yes,
|
||||
listing is protocol-impossible); BIND 9 near-parity via the RFC2136 adapter
|
||||
plus AXFR-based listing; PowerDNS/deSEC/AdGuard Home adapters on the roadmap.
|
||||
|
||||
### Notes
|
||||
- Historical per-change review outcomes are recorded in commit messages and in
|
||||
the internal `RELEASE-EVIDENCE-internal.md` companion file — not in this
|
||||
changelog.
|
||||
|
||||
## [1.17.0] - 2026-10-07
|
||||
|
||||
@@ -178,9 +98,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
base (`1fa5ba8`) because it bundles a stale `pdf.js 1.10.100`; the failing set is measured, not
|
||||
assumed, and recorded in the release evidence.
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Production-Grade Hardening Sprint (2026-08-12)
|
||||
### Production-Grade Hardening Sprint (2026-08-12, shipped in 1.17.0)
|
||||
|
||||
### Added
|
||||
- **DC-097: Prometheus metrics export.** `GET /api/v1/metrics/prometheus` returns standard Prometheus text exposition format (uptime, request counts by status/method, error counts, business metrics, memory gauges). Public endpoint for Grafana/Prometheus scraping.
|
||||
@@ -398,6 +316,28 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
### Changed
|
||||
- Version bump only — packaging plumbing for the 1.4.x release line.
|
||||
|
||||
## [1.2.0] - 2026-05-14
|
||||
|
||||
### Added
|
||||
- Container Log Viewer with streaming, search, and download.
|
||||
- Service filter, batch operations across multiple services, and snapshot
|
||||
capture.
|
||||
- Auto CSP hash updates during build.
|
||||
- Dashboard version button and self-update UI wiring.
|
||||
- Release policy checks and dashboard version verification.
|
||||
|
||||
### Changed
|
||||
- All routine `console.log` calls gated behind `window.DASHCADDY_DEBUG`
|
||||
flag for quieter production output.
|
||||
- All `console.error` calls routed through `ErrorHandler` for consistent
|
||||
tracking.
|
||||
|
||||
### Fixed
|
||||
- Updater no longer triggers a false-positive "update available" loop
|
||||
when commit hash is unknown.
|
||||
|
||||
---
|
||||
|
||||
## [1.4.0] - 2026-05-06
|
||||
|
||||
### Added
|
||||
@@ -424,28 +364,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
---
|
||||
|
||||
## [1.2.0] - 2026-05-14
|
||||
|
||||
### Added
|
||||
- Container Log Viewer with streaming, search, and download.
|
||||
- Service filter, batch operations across multiple services, and snapshot
|
||||
capture.
|
||||
- Auto CSP hash updates during build.
|
||||
- Dashboard version button and self-update UI wiring.
|
||||
- Release policy checks and dashboard version verification.
|
||||
|
||||
### Changed
|
||||
- All routine `console.log` calls gated behind `window.DASHCADDY_DEBUG`
|
||||
flag for quieter production output.
|
||||
- All `console.error` calls routed through `ErrorHandler` for consistent
|
||||
tracking.
|
||||
|
||||
### Fixed
|
||||
- Updater no longer triggers a false-positive "update available" loop
|
||||
when commit hash is unknown.
|
||||
|
||||
---
|
||||
|
||||
## [1.1.5] - 2026-03-23
|
||||
|
||||
### Added
|
||||
@@ -503,7 +421,8 @@ Initial release of DashCaddy. Unified dashboard for Docker container
|
||||
management, Caddy reverse proxy configuration, DNS automation, and SSL
|
||||
certificate provisioning.
|
||||
|
||||
[Unreleased]: ../../compare/v1.5.0...HEAD
|
||||
[Unreleased]: ../../compare/v1.17.0...HEAD
|
||||
[1.17.0]: ../../compare/v1.14.6-patched...v1.17.0
|
||||
[1.5.0]: ../../compare/v1.4.10...v1.5.0
|
||||
[1.4.10]: ../../compare/v1.4.9...v1.4.10
|
||||
[1.4.9]: ../../compare/v1.4.8...v1.4.9
|
||||
@@ -522,3 +441,6 @@ certificate provisioning.
|
||||
[1.1.5]: ../../compare/v1.1.1...v1.1.5
|
||||
[1.1.1]: ../../compare/v1.0.0...v1.1.1
|
||||
[1.0.0]: ../../releases/tag/v1.0.0
|
||||
[1.15.0]: ../../compare/v1.14.0...v1.15.0
|
||||
[1.14.0]: ../../compare/v1.13.4...v1.14.0
|
||||
[1.13.4]: ../../compare/v1.13.3...v1.13.4
|
||||
@@ -2,14 +2,14 @@
|
||||
|
||||
**Self-hosted dashboard for managing Docker apps with automatic SSL, DNS, and reverse proxy configuration.**
|
||||
|
||||

|
||||

|
||||

|
||||
|
||||
## What is DashCaddy?
|
||||
|
||||
DashCaddy is an all-in-one solution for self-hosting Docker applications. It combines:
|
||||
- 🎨 **Beautiful Dashboard** - Monitor all your services in one place
|
||||
- 🐳 **Docker Management** - Deploy 50+ pre-configured apps with one click
|
||||
- 🐳 **Docker Management** - Deploy 78 pre-configured apps with one click
|
||||
- 🔒 **Automatic SSL** - Internal CA with automatic certificate generation
|
||||
- 🌐 **DNS Integration** - Automatic DNS record creation (Technitium DNS)
|
||||
- 🔄 **Reverse Proxy** - Caddy configuration managed automatically
|
||||
@@ -32,7 +32,7 @@ DashCaddy is an all-in-one solution for self-hosting Docker applications. It com
|
||||
- Import/export configuration
|
||||
|
||||
### App Deployment
|
||||
- 50+ pre-configured app templates
|
||||
- 78 pre-configured app templates
|
||||
- One-click deployment
|
||||
- Automatic DNS + SSL + reverse proxy setup
|
||||
- Container health checking
|
||||
@@ -64,13 +64,13 @@ DashCaddy is an all-in-one solution for self-hosting Docker applications. It com
|
||||
|
||||
1. **Clone the repository**
|
||||
```bash
|
||||
git clone https://github.com/yourusername/dashcaddy.git
|
||||
git clone https://github.com/sami7777/dashcaddy.git
|
||||
cd dashcaddy
|
||||
```
|
||||
|
||||
2. **Install dependencies**
|
||||
```bash
|
||||
cd caddy-api
|
||||
cd dashcaddy-api
|
||||
npm install
|
||||
```
|
||||
|
||||
@@ -152,7 +152,7 @@ Both endpoints return JSON. Liveness is cheap (no I/O, no deps). Readiness touch
|
||||
|
||||
### Environment Variables
|
||||
|
||||
Create a `.env` file in the `caddy-api` directory:
|
||||
Create a `.env` file in the `dashcaddy-api` directory:
|
||||
|
||||
```env
|
||||
# Caddy Configuration
|
||||
@@ -244,7 +244,7 @@ The script is idempotent, never touches byte-identical files (mtime preserved),
|
||||
|
||||
## App Templates
|
||||
|
||||
DashCaddy includes 50+ pre-configured templates:
|
||||
DashCaddy includes 78 pre-configured templates:
|
||||
|
||||
### Media & Entertainment
|
||||
- Plex, Jellyfin, Emby
|
||||
@@ -282,27 +282,38 @@ DashCaddy includes 50+ pre-configured templates:
|
||||
## API Endpoints
|
||||
|
||||
### Services
|
||||
- `GET /api/services` - List all services
|
||||
- `POST /api/services` - Add service
|
||||
- `PUT /api/services` - Bulk import services
|
||||
- `DELETE /api/services/:id` - Remove service
|
||||
- `GET /api/v1/services` - List all services
|
||||
- `POST /api/v1/services` - Add service
|
||||
- `PUT /api/v1/services` - Bulk import services
|
||||
- `DELETE /api/v1/services/:id` - Remove service
|
||||
|
||||
### App Deployment
|
||||
- `GET /api/apps/templates` - List app templates
|
||||
- `POST /api/apps/deploy` - Deploy new app
|
||||
- `DELETE /api/apps/:id` - Remove deployed app
|
||||
- `GET /api/v1/apps/templates` - List app templates
|
||||
- `POST /api/v1/apps/deploy` - Deploy new app
|
||||
- `DELETE /api/v1/apps/:appId` - Remove deployed app
|
||||
|
||||
### Error Logs
|
||||
- `GET /api/error-logs` - Get error logs
|
||||
- `DELETE /api/error-logs` - Clear error logs
|
||||
- `GET /api/v1/error-logs` - Get error logs
|
||||
- `DELETE /api/v1/error-logs` - Clear error logs
|
||||
|
||||
### DNS Management
|
||||
- `POST /api/dns/record` - Create DNS record
|
||||
- `DELETE /api/dns/record` - Delete DNS record
|
||||
- `POST /api/v1/dns/record` - Create DNS record
|
||||
- `DELETE /api/v1/dns/record` - Delete DNS record
|
||||
- `GET /api/v1/dns/records` - List DNS records (active provider)
|
||||
|
||||
### Caddy Management
|
||||
- `GET /api/caddy/config` - Get Caddyfile content
|
||||
- `POST /api/caddy/reload` - Reload Caddy configuration
|
||||
### Reverse Proxy & Caddy Management
|
||||
- `GET /api/v1/caddy/config` - Get Caddyfile content
|
||||
- `POST /api/v1/caddy/reload` - Reload Caddy configuration
|
||||
- `GET /api/v1/caddy/cas` - List upstream Caddy servers
|
||||
- `POST /api/v1/caddycode/generate` - Generate a Caddyfile site block
|
||||
- `POST /api/v1/caddycode/validate` - Validate a site-block config
|
||||
- `GET /api/v1/caddycode/templates` - Preset configs for common patterns
|
||||
|
||||
> Endpoint accuracy: the MCP route-existence drift gate
|
||||
> (`__tests__/mcp/mcp-core-dc166-integration.test.js`) verifies every MCP
|
||||
> tool's handler-issued API call against the declared routes; the entries
|
||||
> above were additionally spot-checked against the router, and the full
|
||||
> generated inventory lives in [API-SURFACE.md](API-SURFACE.md).
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
@@ -401,9 +412,9 @@ Contributions are welcome! Please:
|
||||
|
||||
- [ ] Service groups/categories
|
||||
- [ ] Container log viewer
|
||||
- [ ] DNS management UI
|
||||
- [ ] Backup automation
|
||||
- [ ] Multi-user support
|
||||
- [x] DNS management UI (DC-166)
|
||||
- [x] Backup automation (schedules + point-in-time restore)
|
||||
- [x] Multi-user support (DC-048 — opt-in via `siteConfig.authProviders.email.enabled`; bootstrap admin, allowlist, invites)
|
||||
- [ ] Mobile app
|
||||
- [ ] Analytics dashboard
|
||||
- [ ] Template marketplace
|
||||
@@ -420,9 +431,9 @@ Proprietary software. All rights reserved. See [LICENSE](LICENSE) for the End-Us
|
||||
|
||||
## Support
|
||||
|
||||
- **Issues**: [GitHub Issues](https://github.com/yourusername/dashcaddy/issues)
|
||||
- **Discussions**: [GitHub Discussions](https://github.com/yourusername/dashcaddy/discussions)
|
||||
- **Documentation**: [Wiki](https://github.com/yourusername/dashcaddy/wiki)
|
||||
- **Issues**: [GitHub Issues](https://github.com/sami7777/dashcaddy/issues)
|
||||
- **Discussions**: [GitHub Discussions](https://github.com/sami7777/dashcaddy/discussions)
|
||||
- **Documentation**: [Wiki](https://github.com/sami7777/dashcaddy/wiki)
|
||||
|
||||
## Acknowledgments
|
||||
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
# Internal release evidence (NOT customer-facing)
|
||||
|
||||
Judge grades and ledger URNs per change. Kept out of CHANGELOG.md
|
||||
(DC-170 docs batch r3: the distributable changelog must stay clean).
|
||||
|
||||
Judging per-change is recorded in commit messages and the internal ledger. Grade lines consolidated here:
|
||||
|
||||
- **DC-168 judge: grade B (round 16)** urn:ump:ejzlob2bde6m6ivxfpgidmwu5a62pvl4wddm4iav7mwfuyfogirq
|
||||
- **DC-167 judge: grade B (round 11)** urn:ump:kfn7m6vzd4ias2u5ghg62hvoug3j2y2gmturnytdz4g4od35hx4a
|
||||
- **DC-165 judge: grade B (round 5)** urn:ump:oqgczb6zv5bemekbxko7gi5rvfle6yoshwgfwsx4mbbj4xmg6paq
|
||||
- **DC-164 judge: grade B (round 6)** urn:ump:5vuahbn4znf7hrrshjvu2pcbqln5m6qcrpkkn3mx6y2rvvmdtqoa
|
||||
- **DC-163 judge: grade B (round 2)** urn:ump:l2tg66wmchkmd6fde4k3ojwc56zpxqh657spe37bu6dpvduswalq
|
||||
- **DC-162 judge: grade B (round 3)** urn:ump:or2qqhcytp6lfzlyi7xru7hdqy3uar2hbjllsrrbxrbray3c5kpa
|
||||
@@ -0,0 +1,30 @@
|
||||
# Reproducible verification — DC-170 docs batch r9 rev2 (2026-10-29 09:27 UTC)
|
||||
# Every line below is verbatim: the exact command run and its exact output,
|
||||
# captured in one shell session against this repository.
|
||||
# NOTE: dashcaddy-api/VERSION was observed reverted to 1.15.0 at 09:26 UTC
|
||||
# (mtime 2026-10-29 01:48:13, writer unidentified) and was re-set to 1.17.0
|
||||
# with: echo 1.17.0 > dashcaddy-api/VERSION
|
||||
|
||||
$ cd /root/dashcaddy
|
||||
$ cat dashcaddy-api/VERSION
|
||||
1.17.0
|
||||
|
||||
$ grep "\"version\"" dashcaddy-api/package.json
|
||||
"version": "1.17.0",
|
||||
|
||||
$ grep "version:" dashcaddy-api/openapi.yaml | head -1
|
||||
version: 1.17.0
|
||||
|
||||
$ grep "version-" README.md | head -1
|
||||

|
||||
|
||||
$ node -e 'const {APP_TEMPLATES}=require("./dashcaddy-api/src/docker/app-templates"); console.log("templates:", Object.keys(APP_TEMPLATES).length)'
|
||||
templates: 78
|
||||
|
||||
$ python3 /root/.hermes/skills/software-development/dashcaddy/scripts/api-surface-extract.py --root /root/dashcaddy --out /root/dashcaddy/API-SURFACE.md
|
||||
[ok] 443 handler rows, 59 PUBLIC_ROUTES allowlist entries
|
||||
[ok] wrote /root/dashcaddy/API-SURFACE.md (54340 bytes)
|
||||
$ wc -c API-SURFACE.md
|
||||
54340 API-SURFACE.md
|
||||
$ sha256sum API-SURFACE.md
|
||||
6ee6b2f0da244cd6103be14f0977b95f1a9af3d453bf2401bb4c222d59b6c621 API-SURFACE.md
|
||||
@@ -1 +1 @@
|
||||
70e252c
|
||||
1.17.0
|
||||
@@ -1,7 +1,7 @@
|
||||
openapi: 3.0.3
|
||||
info:
|
||||
title: DashCaddy API
|
||||
version: 1.15.0
|
||||
version: 1.17.0
|
||||
description: >
|
||||
Unified management API for Docker, Caddy, DNS, and Tailscale services.
|
||||
Covers container lifecycle, reverse proxy configuration, DNS record
|
||||
|
||||
Reference in new issue
Block a user