Project Structure
caddy-ui/
├── .devcontainer/
│ └── devcontainer.example.json
├── .github/
│ ├── scripts/
│ │ ├── dockerhub-docs.mjs
│ │ ├── dockerhub-docs.test.mjs
│ │ ├── publish-versions.sh
│ │ └── record-versions.mjs
│ ├── workflows/
│ │ ├── beta.yml
│ │ ├── conventional-commits.yml
│ │ ├── docs.yml
│ │ ├── edge.yml
│ │ ├── localization-preview-data.yml
│ │ ├── release-please.yml
│ │ ├── release.yml
│ │ ├── stale.yml
│ │ ├── sync-caddyfile-vocab.yml
│ │ └── test.yml
│ ├── FUNDING.yml
│ └── dependabot.yml
├── dev/ ← development tooling, integration fixtures and browser scenarios
│ ├── cloud-metadata/
│ │ ├── results/
│ │ │ ├── README.md
│ │ │ └── snapshot.json
│ │ ├── .gitignore
│ │ ├── README.md
│ │ ├── collect.py
│ │ ├── reference.json
│ │ └── test_collect.py
│ ├── dev-caddy/ ← disposable Caddy lifecycle commands and ownership checks
│ │ ├── cli.mjs
│ │ ├── dev.mjs
│ │ ├── examples.mjs
│ │ ├── harness.mjs
│ │ └── harness.test.mjs
│ ├── e2e/ ← browser fixtures and scenarios
│ │ ├── api-tokens.mjs
│ │ ├── auth-notifications.mjs
│ │ ├── auth.mjs
│ │ ├── cross-site.mjs
│ │ ├── error-logging.mjs
│ │ ├── fixture.mjs
│ │ ├── history.mjs
│ │ ├── languages.mjs
│ │ └── totp.mjs
│ ├── integration/ ← real-service fixtures and lifecycle/readiness tests
│ │ ├── api.mjs
│ │ ├── caddy.mjs
│ │ ├── diagnostics.mjs
│ │ ├── examples.mjs
│ │ ├── lifecycle.mjs
│ │ ├── lifecycle.test.mjs
│ │ ├── network-readiness.test.mjs
│ │ ├── nginx-config.test.mjs
│ │ ├── rate-limits.mjs
│ │ ├── readiness.test.mjs
│ │ ├── stack.mjs
│ │ └── startup.mjs
│ ├── playground/ ← localization preview and captured-response tooling
│ │ ├── captures/
│ │ │ └── dashboard.json
│ │ ├── test/
│ │ │ ├── playground-capture.test.js
│ │ │ └── playground.test.jsx
│ │ ├── PreviewFrame.jsx
│ │ ├── README.md
│ │ ├── Workbench.jsx
│ │ ├── capture-format.js
│ │ ├── capture-source.mjs
│ │ ├── capture.integration.mjs
│ │ ├── capture.mjs
│ │ ├── check-browser.mjs
│ │ ├── dom-context.js
│ │ ├── fixtures.jsx
│ │ ├── frame.html
│ │ ├── frame.jsx
│ │ ├── index.html
│ │ ├── main.jsx
│ │ ├── model.js
│ │ ├── registry.jsx
│ │ ├── vite.config.js
│ │ └── workbench.css
│ ├── eslint.config.js
│ ├── package-lock.json
│ └── package.json ← shared development dependencies and commands
├── docs/ ← mdBook source, theme, and build tooling
│ ├── screenshots/
│ │ ├── captures/
│ │ │ └── screenshots.json
│ │ ├── capture.integration.mjs
│ │ ├── capture.mjs
│ │ ├── replay.mjs
│ │ └── screenshot.mjs
│ ├── scripts/
│ │ ├── html-region.mjs
│ │ ├── project-structure.mjs
│ │ ├── project-structure.test.mjs
│ │ └── screenshots.test.mjs
│ ├── src/
│ │ ├── SUMMARY.md
│ │ ├── about.md
│ │ ├── api-tokens.md
│ │ ├── api.md
│ │ ├── architecture.md
│ │ ├── building.md
│ │ ├── caddyfile.md
│ │ ├── configuration.md
│ │ ├── contributing-codebase.md
│ │ ├── contributing-documentation.md
│ │ ├── contributing-feedback.md
│ │ ├── contributing-localization.md
│ │ ├── contributing.md
│ │ ├── development-caddy.md
│ │ ├── features.md
│ │ ├── instances.md
│ │ ├── integrations.md
│ │ ├── passkeys.md
│ │ ├── project-structure.md
│ │ ├── releases.md
│ │ ├── screenshots.md
│ │ ├── setup.md
│ │ ├── themes.md
│ │ └── totp.md
│ ├── theme/
│ │ ├── caddy-ui.css
│ │ ├── favicon.ico
│ │ ├── favicon.svg
│ │ ├── mermaid-init.js
│ │ ├── palettes.css
│ │ └── sidebar.js
│ ├── README.md
│ ├── book.toml
│ ├── package-lock.json
│ ├── package.json
│ └── project-structure-notes.json ← persistent annotations keyed by repository path
├── src/ ← independently buildable application packages
│ ├── backend/ ← Express API and Caddy integration
│ │ ├── src/
│ │ │ ├── middleware/
│ │ │ │ ├── apiToken.js
│ │ │ │ ├── auth.js
│ │ │ │ ├── crossSite.js
│ │ │ │ ├── csrf.js
│ │ │ │ └── instance.js
│ │ │ ├── routes/
│ │ │ │ ├── auth.js
│ │ │ │ ├── caddyfile.js
│ │ │ │ ├── customThemes.js
│ │ │ │ ├── health.js
│ │ │ │ ├── instances.js
│ │ │ │ ├── logs.js
│ │ │ │ ├── metrics.js
│ │ │ │ ├── notifications.js
│ │ │ │ ├── pages.js
│ │ │ │ ├── routenotes.js
│ │ │ │ ├── routes.js
│ │ │ │ ├── servernames.js
│ │ │ │ ├── settings.js
│ │ │ │ ├── status.js
│ │ │ │ └── tls.js
│ │ │ ├── AppError.js
│ │ │ ├── apiTokenPolicy.js
│ │ │ ├── authEvents.js
│ │ │ ├── authService.js
│ │ │ ├── authSessions.js
│ │ │ ├── authStore.js
│ │ │ ├── caddy.js
│ │ │ ├── caddyfileBlocks.js
│ │ │ ├── caddyfileHistory.js
│ │ │ ├── caddyfileTitles.js
│ │ │ ├── containerFs.js ← docker exec wrapper for file operations inside Caddy containers
│ │ │ ├── customThemes.js
│ │ │ ├── docker.js
│ │ │ ├── dockerDiscovery.js ← auto-discover Caddy containers via Docker socket
│ │ │ ├── errorRegistry.js
│ │ │ ├── errorReporting.js
│ │ │ ├── index.js
│ │ │ ├── instances.js
│ │ │ ├── languages.js
│ │ │ ├── logReadError.js
│ │ │ ├── logger.js
│ │ │ ├── maintenance.js
│ │ │ ├── notifications.js
│ │ │ ├── observations.js
│ │ │ ├── passkeyPolicy.js
│ │ │ ├── passkeys.js
│ │ │ ├── routeChecks.js
│ │ │ ├── routeMonitor.js
│ │ │ ├── routeNotes.js
│ │ │ ├── serverNames.js
│ │ │ ├── settings.js
│ │ │ ├── totp.js
│ │ │ ├── totpPolicy.js
│ │ │ ├── trustedProxies.js
│ │ │ ├── updateCheck.js
│ │ │ ├── upstreamChecks.js
│ │ │ ├── upstreamMonitor.js
│ │ │ ├── uptimeHistory.js
│ │ │ ├── validation.js
│ │ │ └── webhookTransport.js
│ │ ├── test/
│ │ │ ├── fixtures/
│ │ │ │ ├── app.example.com.crt
│ │ │ │ ├── auth.mjs
│ │ │ │ ├── crossSite.mjs
│ │ │ │ └── webauthn.mjs
│ │ │ ├── actorIdentity.test.js
│ │ │ ├── apiTokens.test.js
│ │ │ ├── appError.test.js
│ │ │ ├── auth.test.js
│ │ │ ├── authAudit.test.js
│ │ │ ├── authConfiguration.test.js
│ │ │ ├── authCredentials.test.js
│ │ │ ├── authEvents.test.js
│ │ │ ├── authSessions.test.js
│ │ │ ├── authStore.test.js
│ │ │ ├── authStoreMigration.test.js
│ │ │ ├── authenticationNotifications.test.js
│ │ │ ├── caddyfile.test.js
│ │ │ ├── caddyfileBlocks.test.js
│ │ │ ├── caddyfileHistory.test.js
│ │ │ ├── caddyfileTitles.test.js
│ │ │ ├── containerFs.test.js
│ │ │ ├── credentialReauthentication.test.js
│ │ │ ├── crossSite.test.js
│ │ │ ├── customThemes.test.js
│ │ │ ├── errorReporting.test.js
│ │ │ ├── healthRoute.test.js
│ │ │ ├── instanceMiddleware.test.js
│ │ │ ├── instances.test.js
│ │ │ ├── languages.test.js
│ │ │ ├── listAvailability.test.js
│ │ │ ├── logReadErrors.test.js
│ │ │ ├── logger.test.js
│ │ │ ├── logs.test.js
│ │ │ ├── logsConfigRoute.test.js
│ │ │ ├── maintenance.test.js
│ │ │ ├── maintenanceInstances.test.js
│ │ │ ├── metrics.test.js
│ │ │ ├── notificationCategoryIsolation.test.js
│ │ │ ├── notifications.test.js
│ │ │ ├── notificationsRoute.test.js
│ │ │ ├── observations.test.js
│ │ │ ├── passkeyLogin.test.js
│ │ │ ├── passkeyRegistration.test.js
│ │ │ ├── passkeyStore.test.js
│ │ │ ├── readFailures.test.js
│ │ │ ├── routeChecks.test.js
│ │ │ ├── routeNotesInstances.test.js
│ │ │ ├── routes.test.js
│ │ │ ├── saveCaddyfileChange.test.js
│ │ │ ├── serverNames.test.js
│ │ │ ├── status.test.js
│ │ │ ├── statusRoute.test.js
│ │ │ ├── tls.test.js
│ │ │ ├── totpAuthentication.test.js
│ │ │ ├── totpStore.test.js
│ │ │ ├── trustedProxies.test.js
│ │ │ ├── updateCheck.test.js
│ │ │ ├── upstreamChecks.test.js
│ │ │ ├── upstreamRetries.test.js
│ │ │ ├── uptimeHistory.test.js
│ │ │ ├── validation.test.js
│ │ │ └── webhookTransport.test.js
│ │ ├── DOCKERHUB.md
│ │ ├── Dockerfile
│ │ ├── LICENSE
│ │ ├── eslint.config.js
│ │ ├── package-lock.json
│ │ └── package.json
│ └── frontend/ ← React application
│ ├── eslint/
│ │ ├── i18n-literal-options.mjs
│ │ ├── localized-error-toast.mjs
│ │ └── test-localized-error-toast.mjs
│ ├── public/
│ │ └── licenses/
│ │ └── noto-sans-arabic-OFL.txt
│ ├── scripts/
│ │ ├── fetch-caddyfile-mode.mjs
│ │ └── localization.mjs
│ ├── src/
│ │ ├── components/
│ │ │ ├── ApiTokens.jsx
│ │ │ ├── AuthRecovery.jsx
│ │ │ ├── AuthSetup.jsx
│ │ │ ├── AuthenticatorCode.jsx
│ │ │ ├── CaddyFile.jsx
│ │ │ ├── Confirm.jsx
│ │ │ ├── CredentialVerification.jsx
│ │ │ ├── Dashboard.jsx
│ │ │ ├── Icons.jsx
│ │ │ ├── Instances.jsx ← instance management page with discovery
│ │ │ ├── LanguagePicker.jsx
│ │ │ ├── Login.jsx
│ │ │ ├── Logs.jsx
│ │ │ ├── Metrics.jsx
│ │ │ ├── Notifications.jsx
│ │ │ ├── PaneDivider.jsx
│ │ │ ├── Passkeys.jsx
│ │ │ ├── RouteHistoryModal.jsx
│ │ │ ├── Routes.jsx
│ │ │ ├── SecuritySettings.jsx
│ │ │ ├── Sidebar.jsx
│ │ │ ├── TLS.jsx
│ │ │ ├── ThemePicker.jsx
│ │ │ ├── ThemeWelcome.jsx
│ │ │ ├── Toasts.jsx
│ │ │ ├── TotpLogin.jsx
│ │ │ ├── TotpSettings.jsx
│ │ │ ├── UpstreamUptime.jsx
│ │ │ └── UserSettings.jsx
│ │ ├── hooks/
│ │ │ ├── useClickOutside.js
│ │ │ └── useInstanceStatus.js
│ │ ├── i18n/
│ │ │ ├── fonts/
│ │ │ │ └── arabic.css
│ │ │ ├── locales/
│ │ │ │ ├── ar.js
│ │ │ │ ├── de.js
│ │ │ │ ├── en.js
│ │ │ │ ├── es-es.js
│ │ │ │ └── es-mx.js
│ │ │ ├── fonts.js
│ │ │ └── index.js
│ │ ├── utils/
│ │ │ ├── api.js
│ │ │ ├── caddyfileHistory.js
│ │ │ ├── credentialVerification.js
│ │ │ ├── errorMessages.js
│ │ │ ├── errorRegistry.js
│ │ │ ├── format.js
│ │ │ ├── lineDiff.js
│ │ │ ├── logSource.js
│ │ │ ├── notificationCenter.js
│ │ │ ├── passkeys.js
│ │ │ ├── routes.js
│ │ │ └── updateLink.js
│ │ ├── App.jsx
│ │ ├── main.jsx
│ │ └── styles.js
│ ├── test/
│ │ ├── api.test.js
│ │ ├── caddyfileHistory.test.js
│ │ ├── credentialVerification.test.js
│ │ ├── errorMessages.test.js
│ │ ├── errorRegistry.test.js
│ │ ├── fonts.test.js
│ │ ├── i18n.test.jsx
│ │ ├── localization.test.js
│ │ ├── logSource.test.js
│ │ ├── notificationCenter.test.js
│ │ ├── passkeys.test.js
│ │ ├── routes.test.js
│ │ └── updateLink.test.js
│ ├── DOCKERHUB.md
│ ├── Dockerfile
│ ├── caddyfile-mode.sha
│ ├── caddyui-logo.ico
│ ├── caddyui-logo.png
│ ├── caddyui-logo.svg
│ ├── eslint.config.js
│ ├── index.html
│ ├── nginx.conf
│ ├── package-lock.json
│ ├── package.json
│ ├── trusted-upstreams.sh
│ └── vite.config.js
├── .gitignore
├── .release-please-manifest.json
├── AGENTS.md
├── CHANGELOG.md
├── CLAUDE.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── package.json ← stable repository-level command entry points
└── release-please-config.json
src/frontend/src/lib/caddyfileMode.js is fetched at frontend build time and ignored
by Git, so it is intentionally absent from this tree.