Commit Graph

1810 Commits

Author SHA1 Message Date
Anso 8d988d6b08 docs: disable API playground for self-hosted compatibility (#295)
Sencho is self-hosted so the Mintlify "Try it" playground can never
reach a user's instance (CORS + localhost). Switch to "simple" mode
which keeps the endpoint URL/method as a copyable reference without
the misleading Send button.
2026-03-31 18:57:38 -04:00
Anso eae83c997b docs: add OpenAPI 3.1 spec and API Reference tab (#294)
Add a complete OpenAPI 3.1 specification covering ~55 public API endpoints
across 8 categories (Stacks, Containers, API Tokens, Webhooks, Nodes, Fleet,
Scheduled Tasks, Health). Wire it into Mintlify via native OpenAPI rendering
with an interactive "Try It" playground and a dedicated API Reference tab.

Includes an API overview page documenting authentication, token scopes,
node routing, error format, license tier requirements, and WebSocket endpoints.
2026-03-31 16:13:07 -04:00
Anso 574fa9a36b chore(main): release 0.23.0 (#293) 2026-03-31 13:07:14 -04:00
Anso e587256086 feat(multi-node): warn when configuring remote node with plain HTTP URL (#292)
Show an inline warning banner in the Add Node form when the user enters
an http:// URL, recommending HTTPS or VPN for public internet connections.
HTTP remains fully supported for private networks (LAN, VPN, VPC).

Also returns an optional `warning` field in POST/PUT /api/nodes responses
for API-only consumers, and expands the multi-node security documentation
with concrete deployment guidance (reverse proxy, VPN, private network).
2026-03-31 12:45:07 -04:00
Anso 2d7115e33f docs: refresh screenshots (#291) 2026-03-31 11:02:18 -04:00
Anso f17090a90b chore(main): release 0.22.1 (#290) 2026-03-31 10:59:29 -04:00
Anso 71ce6b3e1b fix(fleet): navigate to editor instead of dashboard on "Open in Editor" click (#289)
The Fleet View's "Open in Editor" button on container rows was navigating
to the dashboard instead of opening the stack in the editor. Fixed by
threading the stackName through the callback chain and using a pending
ref to survive the node-switch effect reset.
2026-03-31 10:45:54 -04:00
Anso 50c29b4248 docs: refresh screenshots (#288) 2026-03-31 10:26:31 -04:00
Anso 6c759b6228 chore(main): release 0.22.0 (#287) 2026-03-31 10:23:37 -04:00
Anso eccdd1b879 feat(scheduled-ops): add failure notifications, granular targeting, and history export (#286)
- Dispatch error alerts via NotificationService when scheduled tasks fail,
  with info-level recovery notifications when a previously-failing task succeeds
- Per-service restart targeting: scheduled stack restarts can target specific
  services instead of restarting the entire stack
- Prune label filter: scheduled prune operations can be scoped to resources
  matching a specific Docker label
- CSV export button in the execution history panel for one-click download
- Fix: prune_targets was silently dropped on task creation (missing in INSERT)
2026-03-31 09:51:53 -04:00
Anso 633208185d docs: refresh screenshots (#285) 2026-03-30 17:57:19 -04:00
Anso 5b8cce5811 chore(main): release 0.21.2 (#284) 2026-03-30 17:54:35 -04:00
Anso 36ebd5a9c1 fix(docker): upgrade Compose v2.40.3 → v5.1.1 to remediate dependency CVEs (#283)
Compose v2.40.3 was compiled with Go 1.24.9, grpc 1.74.2, and
x/crypto 0.38.0 — all below the minimum safe versions identified
in the March 2026 security audit. Upgrading to v5.1.1 (Go 1.25.8,
x/crypto 0.46.0) resolves CVE-2025-68121, CVE-2025-61726,
CVE-2025-61729, CVE-2026-25679, and CVE-2025-47913.

CVE-2026-33186 (grpc ≥1.79.3) remains unresolved — no upstream
Docker CLI or Compose release includes grpc past 1.78.0 yet.

CVE-2026-33671 (picomatch) and CVE-2026-33747/33748 (buildkit) were
already patched in prior releases.
2026-03-30 17:46:44 -04:00
Anso 20b09b03b1 docs: refresh screenshots (#282) 2026-03-30 17:25:30 -04:00
Anso 9072f23b13 chore(main): release 0.21.1 (#281) 2026-03-30 17:22:53 -04:00
Anso 9e14ce999f fix(ui): settings modal sidebar nav clipped on smaller viewports (#280)
Add min-h-0 to sidebar container and flex-1 overflow-y-auto to the
nav element so the settings navigation scrolls when items exceed
the available height. Support and About were previously unreachable.
2026-03-30 17:19:11 -04:00
Anso 3fb6d93a16 docs: refresh screenshots (#279) 2026-03-30 16:57:06 -04:00
Anso b7e571fa31 chore(main): release 0.21.0 (#278) 2026-03-30 16:54:18 -04:00
Anso b5d3f497cb feat(host-console): gate Host Console behind Admiral tier (#277)
* feat(host-console): gate Host Console behind Admiral tier

Move the Host Console from the Community (free) tier to Admiral,
enforcing the gate at every layer: UI nav visibility, AdmiralGate
wrapper, POST /api/system/console-token endpoint, and the WebSocket
upgrade handler for /api/system/host-console.

* test(auth): mock Admiral license for console-token test

The console-token endpoint now requires Admiral tier. Mock
LicenseService in the test to return pro/team so the happy-path
test passes in CI where no license is activated.
2026-03-30 15:56:58 -04:00
Anso ccf6062473 docs: refresh screenshots (#276) 2026-03-30 12:58:23 -04:00
Anso 428f180c2e chore(main): release 0.20.0 (#275) 2026-03-30 12:55:26 -04:00
Anso 7637091e84 feat(ui): glassmorphism redesign with settings decomposition (#274)
* feat(ui): add glassmorphism design tokens and utility classes

Introduce glass design system foundation: translucent oklch color
variables for both light and dark themes, glass/glass-border/glass-highlight
tokens, semantic status colors (success/warning/info), .glass and
.glass-strong utility classes with backdrop-filter, reduced shadow
values, and standardized spring animation presets in lib/motion.ts.

* feat(ui): apply glass treatment to core components

Update card, dialog, input, button, popover, sheet, tooltip,
dropdown-menu, context-menu, select, alert-dialog, and tabs
components with glassmorphism styling: translucent backgrounds via
new CSS variables, backdrop-blur layers, glass-border luminous
edges, and glass-highlight hover states.

* refactor(settings): decompose Settings Modal into section components

Extract 10 inline sections from the 1,987-line SettingsModal into
dedicated files under components/settings/. Introduce section
registry pattern replacing 14 conditional blocks. Add shared types,
sidebar navigation grouping with separators, glass treatment on
sidebar and nav buttons, and responsive modal height. SettingsModal
shell shrinks to ~380 lines.

* refactor(ui): unify all tabs to animate-ui TabsHighlight with glass styling

Migrate 4 tab instances (EditorLayout, FleetView, ResourcesView,
NotificationsSection) from inconsistent patterns (manual layoutId,
underline border-b-2, default fade) to the shared TabsHighlight
primitive with glass-highlight indicator and springs.snappy
transition. Standardize EditorLayout nav highlight spring config,
apply glass-highlight to sidebar stack list hover/active states,
and update mobile nav styling.

* refactor(ui): migrate hardcoded colors to semantic CSS variables

Replace hardcoded Tailwind color classes across ~19 component files
with semantic CSS variable classes: emerald/green to success,
orange/amber to warning, blue to info. Preserves brand/decorative
colors (Crown amber, Admiral blue). Enables consistent theming of
status indicators across the entire application.

* refactor(ui): Linear dark precision aesthetic — solid surfaces, depth cues, text hierarchy

Replace glassmorphism with Linear.app-inspired design: solid surface tokens
(card #111111, sidebar #0d0d0d, root #0a0a0a), backdrop-blur restricted to
floating overlays only (blur(10px) saturate(1.15)), desaturated teal accent,
font-weight 500 everywhere, monochrome chart palette, and three depth cues:
root ambient glow, luminous card top-edge, steep text brightness ramp.

* refactor(ui): precision polish — fix muddy dark, snowblind light, add design anchors

- Replace 34 hardcoded rgba values with theme-aware stat-* CSS tokens
- Fix light theme: solid white cards, off-white background, readable text
- Add card-border tokens with sharper directional lighting (top edge 2x)
- Add chart-grid/chart-tick tokens for theme-aware axis rendering
- Upgrade body glow: teal-tinted (dark), warm amber (light)
- Terminal-inspired sidebar: monospaced UP/DN status codes, Geist Mono
- Add tabular-nums to stat values to prevent layout jitter
- Light mode cards get shadow-sm for depth against off-white background

* refactor(ui): Linear materiality pass — ghosted nav, translucent sidebar, font unity

- De-escalate Delete button from solid destructive to ghost with hover fill
- Make sidebar translucent (80% opacity + backdrop-blur) so body glow bleeds through
- Bump dark nav accent to 0.07 for ghosted backlit selection
- Unify all terminal/editor fonts to Geist Mono (was JetBrains/Consolas mix)
- Add Monaco editor fontFamily for YAML/env editing consistency
- Add threshold-based color to Host RAM and Host Disk stat values (warn/crit)

* refactor(ui): material simulation — inherent depth, layer separation, recessed terminal

- Bump dark background 0.065→0.08, card surfaces 0.10→0.12 for 4% layer separation
- Add card-bevel token (inset top shimmer) for permanent structural depth
- Add button-inner-glow token for physical key feel on outline buttons
- Recess terminal with inset shadow and dimmed label
- Reduce action icon strokeWidth to 1.5 for refined industrial feel
- Add teal LED backlight bar on active nav item via blur pseudo-element

* fix(ui): parse usagePercent string to number for getValueColor

usagePercent is typed as string in SystemStats but getValueColor
expects number, causing TS2345 in CI builds.
2026-03-30 12:48:42 -04:00
Anso cd4aa746ab docs: refresh screenshots (#273) 2026-03-30 00:07:43 -04:00
Anso 7584bb8258 chore(main): release 0.19.4 (#272) 2026-03-30 00:04:54 -04:00
Anso 10d16361fa fix(stacks): avoid resource busy error in Docker fallback deletion (#271)
The previous command `rm -rf /cleanup` tried to remove the bind mount
point itself, which the kernel rejects with EBUSY. Changed to
`find /cleanup -mindepth 1 -maxdepth 1 -exec rm -rf {} +` which
removes all contents without touching the mount point. The existing
fsPromises.rmdir() call then cleans up the empty host directory.
2026-03-29 23:52:40 -04:00
Anso a334d714ce docs: refresh screenshots (#270) 2026-03-29 23:35:26 -04:00
Anso dd043cd4b1 chore(main): release 0.19.3 (#269) 2026-03-29 23:32:43 -04:00
Anso f9b86e6f53 fix(docker): install Docker CLI v29.3.1 from static binaries to resolve CVEs (#268)
Alpine 3.23 ships docker-cli 29.1.3 which contains unpatched vulnerabilities:
- CVE-2026-33186 (Critical): gRPC-Go authorization bypass
- CVE-2026-34040 (High): Moby AuthZ plugin bypass
- CVE-2026-33747 (High): BuildKit path traversal via frontend
- CVE-2026-33748 (High): BuildKit path traversal via git URL

Replace apk-based docker-cli and docker-cli-compose with official static
binaries (Docker CLI v29.3.1 + Compose v2.40.3) pinned via build args.
2026-03-29 23:28:55 -04:00
Anso 8eff3fe876 docs: refresh screenshots (#267) 2026-03-29 22:41:01 -04:00
Anso 0eb12b137a chore(main): release 0.19.2 (#266) 2026-03-29 22:38:16 -04:00
Anso 59fd528535 fix: remediate Dependabot and Docker Scout security vulnerabilities (#265)
- Upgrade Docker base image from node:20-alpine to node:22-alpine
  (Node 22.22.2, Alpine 3.23.3) to resolve 31 CVEs flagged by Docker Scout
- Add apk upgrade to runtime stage for latest Alpine security patches
- Force dompurify to 3.3.3 via npm overrides to fix two XSS advisories
  (transitive dep of monaco-editor pinned at 3.2.7)
2026-03-29 22:31:19 -04:00
Anso c0b53e469a ci: fix screenshot PR auto-merge on private repos (#264)
gh pr merge --auto requires branch protection with required status
checks. This repo has no branch protection, so GitHub rejects --auto
with "clean status" error. Remove --auto to merge immediately.
2026-03-29 21:52:56 -04:00
Anso e8c87fdc05 docs: refresh screenshots (#263) 2026-03-29 21:51:18 -04:00
Anso e9e0df8998 chore(main): release 0.19.1 (#262) 2026-03-29 21:39:11 -04:00
Anso 116f15dae9 fix(stacks): resolve permission denied error on stack deletion (#261)
* fix(stacks): resolve permission denied error when deleting stacks with root-owned files

When Docker Compose creates files as root inside a stack directory, the
non-root Sencho process cannot remove them. This adds a Docker-based
fallback: if fsPromises.rm fails with EACCES/EPERM, Sencho spawns a
short-lived Alpine container to clean up the root-owned files.

Also enhances docker compose down with --volumes --remove-orphans to let
Docker clean up its own resources before filesystem deletion.

* docs: clarify that pre-existing root-owned stacks can be deleted

* fix(stacks): include Docker stderr in fallback deletion error message

Fixes CI lint failure: 'stderr' was assigned but never read in
forceDeleteViaDocker(). Now surfaces Docker stderr output in the error
message when the fallback cleanup fails.
2026-03-29 21:32:05 -04:00
Anso f760ea6563 docs: refresh screenshots (#260) 2026-03-29 20:26:22 -04:00
Anso f73e9f4db6 chore(main): release 0.19.0 (#259) 2026-03-29 20:23:39 -04:00
Anso d586ce393a feat(audit-log): add configurable retention, export, Auditor role, and enhanced filtering (#258)
- Configurable retention: audit_retention_days setting (1-365 days, default 90)
  replaces hardcoded 90-day retention, exposed in Settings > Data Retention
- Export: one-click CSV/JSON export of filtered audit data via new
  GET /api/audit-log/export endpoint (capped at 10,000 entries)
- Auditor role: read-only role with system:audit permission for viewing
  and exporting audit logs without admin privileges (Admiral tier)
- Enhanced filtering: full-text search across summaries/paths/usernames,
  date range picker, and expandable row details showing request path,
  IP address, node ID, and entry ID
2026-03-29 20:18:51 -04:00
Anso f4428a394c refactor: use nautical icons for Skipper and Admiral tiers (#257)
* refactor: use nautical icons for Skipper and Admiral tiers

Replace Crown/Users with Compass (Skipper) and ShipWheel (Admiral)
across TierBadge, ProGate, AdmiralGate, and SettingsModal upgrade cards.

* feat(sso): add Admiral tier badge next to SSO Authentication title
2026-03-29 19:09:21 -04:00
Anso c328b7f49a refactor: rename Personal Pro to Skipper and Team Pro to Admiral (#256)
Align paid tier names with Sencho's nautical identity. Internal variant
values ('personal'/'team') remain unchanged in code, database, and
Lemon Squeezy integration — only user-facing display names updated.

- Backend: requireTeamPro → requireAdmiral, TEAM_PRO_REQUIRED → ADMIRAL_REQUIRED
- Frontend: TeamProGate.tsx → AdmiralGate.tsx, TierBadge labels updated
- Website: PricingSection tier names and nautical descriptions
- Docs: all 11 affected pages renamed, nautical footnote added to licensing
2026-03-29 18:00:29 -04:00
Anso 7838d6c32a docs: refresh screenshots (#255) 2026-03-29 17:10:22 -04:00
Anso b6e5a0f196 chore(main): release 0.18.0 (#254) 2026-03-29 17:07:28 -04:00
Anso 8380fbad4b feat(rbac): add Deployer & Node Admin roles with scoped permissions (Team Pro) (#253)
* feat(rbac): add Deployer & Node Admin roles with scoped permissions (Team Pro)

Add intermediate RBAC roles gated to Team Pro tier:
- Deployer: can deploy/restart/stop/start stacks but cannot edit compose files, delete stacks, or access system settings
- Node Admin: full stack and node management within scope, no system settings access
- Scoped permissions: assign roles per-stack or per-node for fine-grained access control
- Permission engine with checkPermission/requirePermission guards replacing requireAdmin on stack/node routes
- Frontend can() function with /api/permissions/me endpoint for client-side permission checks
- User management UI updated with 4-role selector and scoped permission editor
- Documentation updated with permission matrix, scoped permission docs, and screenshots

* fix(rbac): remove unused RoleAssignment import to fix lint error
2026-03-29 17:02:56 -04:00
Anso 37701d5281 docs: refresh screenshots (#245) 2026-03-29 18:50:54 +00:00
Anso b396bf3d95 chore(main): release 0.17.0 (#241) 2026-03-29 14:46:00 -04:00
Anso 244c83a0c3 feat(registries): add private registry credential management (Team Pro) (#240)
Add centralized credential storage for private Docker registries with
support for Docker Hub, GHCR, AWS ECR, and self-hosted registries.

- New `registries` table with AES-256-GCM encrypted secrets
- RegistryService with CRUD, test connectivity, Docker config generation
- 5 API endpoints gated by requireTeamPro + requireAdmin
- ComposeService injects credentials via temp DOCKER_CONFIG on deploy/pull
- ImageUpdateService passes stored credentials for private registry checks
- AWS ECR just-in-time token refresh via @aws-sdk/client-ecr
- RegistriesSection UI in Settings Hub with type-aware form
- Documentation with screenshots
2026-03-29 12:56:30 -04:00
Anso 362b4a43d0 docs: refresh screenshots (#239) 2026-03-29 07:17:18 +00:00
Anso 92147974cd chore(main): release 0.16.0 (#238) 2026-03-29 03:12:08 -04:00
Anso b7e7ee8f55 feat(ui): redesign top bar with three-zone navigation layout (#237)
Replace flat row of 10 individual buttons with a structured three-zone
layout: node context pill (left), animated navigation group (center),
and utility actions (right). Uses the Highlight component from
animate-ui for a spring-animated sliding indicator between nav items.

Responsive: icon+text labels at xl, icons-only at md, sheet drawer
for mobile. Navigation is data-driven via a permission-aware array
that conditionally includes admin and Team Pro items.
2026-03-29 03:04:31 -04:00
Anso 40c09cce23 docs: refresh screenshots (#236) 2026-03-29 05:33:10 +00:00