mirror of
https://github.com/Studio-Saelix/sencho.git
synced 2026-08-06 00:47:52 +00:00
5240957ff370e2fa2362772c7afdbfae369c9746
29 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
c170c3f30c |
fix(ui): default Reduced Motion on Calm and quiet decorative rails (#1622)
* fix(ui): default Reduced Motion on Calm and quiet decorative rails Calm (and Reset to default) enables Reduced Motion; Signature clears it. Manual Motion stays independent of the visual-style card. Reduced Effects also stops decorative masthead rail animations. Related to #1614; does not close that issue. * test(e2e): fix Calm Motion specs racing empty-create compose edit Stop appearance init-script reseeding after mid-test mutations, and wait for Save and Deploy / mobile compose editor after empty create instead of assuming Anatomy Edit compose. |
||
|
|
c01f2479b9 |
fix(ui): lower-overhead Reduced effects for constrained GPUs (#1616)
* fix(ui): lower-overhead Reduced effects path for constrained GPUs Disable backdrop-filter glass and solidify chrome fills when data-effects is reduced (Calm default), with Appearance warning and docs for constrained rendering devices. Related to #1614. * test(ui): harden Reduced effects glass e2e and docs wording Parse Color Level 4 slash alpha so opacity asserts are not vacuously true, cover dialog/toast/overlay both ways with stable data-sn hooks, and soften troubleshooting copy that overstated the unmeasured diagnosis. * docs(ui): lead constrained-GPU guidance with Reduced Motion Rename the troubleshooting section to neutral GPU framing, point Appearance and docs at Reduced Motion first, and show the callout whenever Motion is off so Calm or Reduced effects alone do not hide the validated workaround. |
||
|
|
3fed67a3f1 |
fix: assorted UI polish across Home, Security, and Resources pages (#1590)
* fix: polish stack health table, security card heights, and scanner-gate copy - Remove state dot column from Stack Health rows; state still signaled via row tinting and sparkline color - Reposition Update available badge adjacent to stack name and track the theme accent (--brand) instead of static fuchsia - Equalize Top exploit-risk findings and Severity x exploitability card heights via h-full in a stretching grid - Add resolution prop to CapabilityGate so scanner-gated tabs show "Install a scanner from the Scanner setup tab." instead of the misleading "Upgrade the node" message * fix: scope Resources scroll area to table contents only - Remove bg-background from the outer wrapper so search/filter bars no longer sit on a dark strip - Replace outer ScrollArea with a plain div so search and filter controls stay fixed while only table rows scroll - Add ScrollArea (max-h-[62vh]) inside each table card for Images, Volumes, and Networks tabs * fix: remove static bg-background from Security table scroll areas Images and History tab tables used bg-background on their ScrollArea, forcing a near-black fill that didn't adapt to the theme. Removing it lets the parent card's bg-card show through, matching the Resources table pattern that correctly respects DIM, OLED, and Light modes. * fix: collapsible search icon and transparent Combobox across Resources and Security - Replace always-visible search inputs on Resources tabs (Images, Volumes, Networks) and Security Images (desktop + mobile) with Fleet-style collapsible search: an icon button that expands to a full input on click, collapses on blur when empty - Add [&>button]:!bg-background to Security Images severity Combobox, matching Fleet's transparent dropdown design * fix: remove redundant orange badge from Unmanaged tab label The count was shown twice: once as inline text in the tab and again as an orange bg-warning pill badge. The inline text remains; the duplicate badge is removed. * fix: outline buttons invisible in Light mode - Changed outline variant border from border-input to border so it uses --card-border, which maintains a visible 0.035 lightness gap from --background in Light mode (was 0.005, essentially invisible) - Boosted Light-mode --button-inner-glow from a 4% white inset to a 10% inset plus a subtle drop shadow for the physical-key feel * fix: bump table cell horizontal padding from 8px to density-aware token Changed TableHead and TableCell px-2 (8px) to px-[var(--density-row-x)] which resolves to 20px comfortable / 16px compact. Matches the density system used by StackHealthTable and gives every shadcn-based table proper breathing room on both edges. * fix: expand collapsible search before typing in ImagesTab test The test was written for the old always-visible search input. Now that the search bar collapses to an icon, click it first to expand before interacting with the input. * fix: reorder Settings Infrastructure to Nodes, Stacks, Fleet Move the Stacks section directly below Nodes so the Infrastructure sidebar reads Nodes, Stacks, Fleet. Pure array-element relocation in the settings registry; the sidebar renders in array order. * fix: simplify pilot enroll command and add Step 2 copy button Step 2 of the pilot-agent enrollment modal now shows "docker compose up -d" instead of the redundant "-f compose.yaml" form, since Step 1 already has the operator save the file as the default compose.yaml. Add an inline copy button next to the command so it can be copied without selecting the text by hand. * fix: stack Fleet/Security tab heading actions on mobile The shared FleetTabHeading kept its title and action buttons on one row at every width, so on phones the Security Suppressions heading and its Export VEX / Add suppression buttons were crammed together. Stack the heading and actions vertically below the md breakpoint and restore the original row layout at md and up, so desktop is unchanged. * feat: add node selector to mobile Home masthead The mobile Home page showed the active node as static text, so switching nodes was only possible from the Stacks page. Render the same compact NodeSwitcher in the Home masthead kicker slot, giving a second place to view and switch the active node with the identical popover and Manage nodes action. |
||
|
|
bbcc4b59e4 |
fix: UI polish - tooltips, masthead, tabs, settings, and layout consistency (#1563)
* fix: increase masthead rail shimmer visibility Bumped shimmer highlight opacity from 25% to 50% and reduced animation duration from 11s to 5s, matching the login page AuthCanvas shimmer precedent (via-white/60 at 4.5s). * fix: reduce masthead rail opacity to match login page pattern Changed all MastheadRail background classes from 100% to 70% opacity (bg-brand → bg-brand/70, etc.) so the shimmer highlight reads as a surface reflection rather than a detached floating bar. Matches the AuthCanvas login card precedent. * fix: improve masthead rail glow visibility Replaced the invisible inset box-shadow glow (10px blur inside a 3px element) with a white overlay that pulses opacity 0.15-0.55 over 4s. Sped up glow animation from 5.5s to 4s for a more noticeable breath. * fix: replace cursor-follow tooltip with standard Radix tooltip in sidebar rows Replaced the Cursor/CursorFollow animate-ui primitives in StackRow with the standard Radix Tooltip/TooltipTrigger/TooltipContent already used throughout the app. The custom cursor dot that followed the mouse is gone; tooltips now appear as static popovers on hover/touch. * fix: wrap tooltip icon triggers in span for Radix compatibility TooltipTrigger asChild requires a native element to forward props. Lucide icon components did not reliably receive data-state and event handlers, so tooltips on the check-failed and git-pending indicators did not open. Wrapped each icon in a span. * fix: rename Notification Routing to Routing in settings sidebar * fix: replace Timeline/All tasks buttons with SegmentedControl The two loose Button elements had indistinguishable selected/unselected states (secondary vs ghost). Replaced with the SegmentedControl component already used elsewhere on the same page, which has a clear active highlight indicator. * fix: standardize Blueprint empty state headings to font-heading Replaced manual font-serif [font-style:var(--heading-style)] with the font-heading class on the main heading and three step titles so the Deployments empty state follows the same heading convention as the rest of the app and respects the Calm/Signature theme toggle. * fix: remove custom tooltip styling, use standard TooltipContent defaults The RowTooltip wrapped its label in a font-mono text-stat-value span instead of using the TooltipContent base styling (text-xs text-popover-foreground) like every other tooltip in the app. * Revert "fix: remove custom tooltip styling, use standard TooltipContent defaults" This reverts commit |
||
|
|
322d337d20 |
fix: polish sidebar and masthead chrome, scroll setup preflight (#1522)
Remove redundant nav and label dots, move desktop masthead status to animated left rails, and let AuthCanvas scroll long preflight content on small viewports. |
||
|
|
b5810a9b55 |
feat: add Reduced motion setting and polish chrome, files, and stack-detail (#1501)
A batch of UI/UX polish: - New independent "Reduced motion" appearance setting (separate from Reduced effects). Drives framer-motion via MotionConfig and clamps CSS transitions via data-motion on <html>; toasts are unaffected. Defaults off (OS preference still honored). - Stack-detail Files tab: rename "Files & Volumes" to "Files", add a persisted word-wrap toggle to the file viewer (default on), and add a fullscreen toggle that collapses the Command Center + Logs column so the editor fills the width. - Create Stack > From Git: remove the nested scroll clamp so the deploy toggle and footer are reachable. - Fleet: full-width tab band with icon-only Refresh / Export Dossier, icon-only Check-for-updates / Add-node on the Overview toolbar, theme-aware empty-state headings (calm drops the italic), and fix the Actions card body overlapping the action-row divider. - Snapshots: restyle Restore and Restore all to the ghost button design used by View / Preview / Download, and right-align the per-stack Restore. - Settings sidebar: App Store gradient active style and standard font size. - Compose Doctor: dismiss the high-risk banner (and clear the tab dot) until the findings change, via a shared fingerprint-keyed hook. - Stack-detail Storage: link the "no recent fleet snapshot" warning to the Fleet Snapshots tab (FleetView tabs are now controlled to support the deep link). |
||
|
|
8d9e6574cc |
feat(appearance): add Calm/Signature visual style, readability mode, and chart palette (#1407)
* feat(appearance): add Calm/Signature visual style, readability mode, and chart palette Turn the "too intense / italic headers hurt / the security graph fights my eyes" feedback into a token-driven Visual style with Calm as the new default and Signature one click back to the prior look. - Heading family routes through a `.font-heading` utility driven by `--font-heading`/`--heading-style`: operational headings render upright in the interface face under Calm and italic Instrument Serif under Signature. Base rule sets family + style only, so each call site keeps its own weight/tracking and Signature stays a true no-op; the Calm lift is a `[data-headings="clean"]` descendant rule. Brand lockup, empty-state heroes, and onboarding stay serif. - Severity charts resolve through `--sev-*` tokens with Muted, Heat, and Signature palettes; FindingsByType routes its series through the severity ramp plus a neutral so no brand-cyan sits next to rose. The risk trend flattens its gradient under Muted/Heat/reduced and keeps the gradient under Signature. - Appearance settings gain Visual style cards, a Security visualization palette, a Readability master toggle, a Motion & effects group, and a "Reset to default" button (restores the Calm axes, disabled while readability is on). Contrast moves under Readability and Ambient glow under Motion & effects. A card is selected only while the stored sub-axes match its preset, so a custom combination de-selects both. - The topbar Theme quick-switch swaps the interface/data font pickers for a Visual style switch and a Readability toggle (text size kept); its footer Settings link jumps straight to Appearance. - Readability is a sticky master that forces the calm resolution and a contrast lift at apply time without mutating the stored sub-axes. - New users default to Calm; any pre-existing persisted appearance state keeps the Signature look. The pre-paint script mirrors the store. - SegmentedControl gains a `disabled` prop and a nullable value (no active segment for a custom combination, with a roving-tabindex keyboard anchor). Adds unit/component coverage for the store, migration, chart shape logic, the disabled control, the reset/de-selection, and the quick-switch. * fix(appearance): migrate Blueprint serif headings and surface readability locks - Migrate the two operational Blueprint headings (catalog tile name, drift-policy option title) from font-serif italic to the .font-heading utility; the first pass only covered font-display, so Calm still left these italic. font-serif and font-display both resolve to the same display face, so this is the same fix. - Lock the Visual style cards under Readability (parity with the topbar switch and the on-screen guidance to turn Readability off to choose a style by hand). - Lock the Border brightness slider under Readability and show its forced +0.03 readout, since Readability overrides the stored value; dragging it previously appeared to do nothing. - Correct the Appearance docs sentence for the topbar quick switch (it listed fonts; the quick switch now carries visual style, readability, and text size). |
||
|
|
e8f271f5f6 |
feat(ui): make the core stack flow usable on mobile (#1327)
* feat(ui): make the core stack flow usable on mobile Below the md breakpoint the app collapses to a single full-width column: the stack list is full-screen, tapping a stack opens a full-screen detail with a Health / Logs / Compose segmented control (Logs first) and a back button, and a bottom tab bar switches Stacks, Fleet, Schedules, and Settings. Compose is read-only on a phone with a prompt to edit on desktop. Desktop (md and up) is unchanged: the mobile shell is gated behind a useIsMobile hook plus max-md/md variants, and the stack-detail blocks are shared with the desktop two-pane view so it renders identically. Also generalizes the unsaved-changes guard so leaving a dirty editor (back, tab bar, hamburger) prompts before discarding; adds 44px touch targets on list rows, filter chips, and actions; makes log and shell modals full-screen on mobile; and offsets toasts and the deploy pill above the bottom tab bar. * fix(ui): keep mobile nav in sync when opening views from outside the bottom bar On a phone the sidebar activity actions, the node switcher's Manage Nodes, the profile Settings entry, and the dashboard configuration links set the active view without flipping the mobile surface to content, so the user stayed on the stack list and never saw the destination. Route these through the mobile-aware navigation and settings helpers (a no-op on desktop). |
||
|
|
622af7e0b3 |
fix(theme): make sheets and dialogs track the active theme (#1315)
* fix(theme): make sheets and dialogs track the active theme Portaled panels (scan-history and other sheets, dialogs, confirm modals) only partially followed the theme: their popover surface was a flat per-theme literal, so OLED mode never reached true black inside them and the contrast control did not move their fill. The accent stopped at the thin rail because the ambient glow was painted only on the main app shell, never inside a portaled panel, and the overlay scrim was a hardcoded black. - Derive the popover surface from per-theme lightness and alpha plus the contrast spread, the same way the page background is derived, so every floating surface tones with the active theme (including OLED true black) and deepens with contrast. Dim and Light are unchanged at the default contrast. - Add an accent wash to sheets and large dialogs so the chosen accent reads inside them, matching the page. Small dropdowns and tooltips keep the themed tone without the wash. - Replace the hardcoded modal and sheet scrim with a theme-aware token that softens to a light dim in the Light theme. Tested across Dim, OLED, and Light with multiple accents and contrast levels. * fix(theme): keep the command palette token-only (no accent wash) The command palette renders through DialogContent, so it picked up the accent wash meant for content sheets and dialogs. It is a command menu, so it should stay token-only like dropdowns and tooltips. Add an optional panelGlow flag to DialogContent (on by default, so every other dialog is unchanged) and turn it off for the palette. |
||
|
|
c0a252026d |
feat(appearance): add theme, accent, contrast, and typography personalization (#1307)
* feat(appearance): add theme, accent, contrast, and typography personalization Expand Settings to Appearance into a full personalization surface and add a quick switcher to the top bar (the palette button between search and notifications). Choices are saved to the browser, sync across tabs, and apply before first paint so there is no flash on reload. - Themes: Dim (the default raised charcoal), OLED true black, Light, and Auto (follows the OS and re-resolves live when it flips). - Accent: an eight-hue wheel (cyan default) that drives the one data color across charts, rails, focus rings, active states, and the ambient glow. - Fine-tune sliders: a master Contrast that spreads page, ink, and borders together, plus Border brightness and Ambient glow. - Typography: swappable interface (Geist / IBM Plex Sans / Hanken Grotesk) and data (Geist Mono / IBM Plex Mono / Fira Code) faces, and a text-size control (continuous slider in Settings, S/M/L/XL presets in the popover, kept in sync). The display serif stays locked as the signature face. Surfaces, borders, and ink derive from per-theme lightness values so the live knobs scale the whole UI through CSS, and the opaque directional borders read on every panel including true black. A live preview reflects changes in real time. Adds a documentation page under Features. * fix(appearance): keep contrast-driven tokens in gamut and add picker keyboard nav Clamp the contrast and knob driven surface, border, and ink lightness so the full slider range stays a valid color. The page now always sits below the card tone, so page/card separation no longer collapses at high contrast in Light; the lit border edge never reaches white in Light at the low end of the knobs; and the OLED and Dim extremes resolve to valid black/white instead of out-of-range values. Add the radiogroup keyboard model (roving tabindex plus Arrow / Home / End) to the accent and type pickers through a shared hook, matching the segmented control. One item is tabbable and arrow keys move focus and selection together. |
||
|
|
6f301e005a |
feat(fleet): redesign Fleet Action cards to the System Sheet recipe (#1137)
Lift <FleetActionCard> primitive from audit §20 / DESIGN §9.12. Migrate the three v1 cards (stop-by-label, bulk-label-assign, prune-fleet-wide) to consume it: cyan rail on every card, action class as a chip, blast radius as a live readout in the toolbar, preview section replaces the warning banner, footer carries reversibility plus freshness. Drop the per-card tone rail, the icon prop, and cards/tone.ts. Add /fleet/labels/match-preview and /fleet/prune/estimate for the live blast readouts (chrome falls back to "preview unavailable" if either 404s). Add dryRun: true to the existing fleet-stop and fleet-prune endpoints so the Dry run button rehearses the full code path (locks, per-node fan-out, remote propagation) without firing the destructive leaf call. Result flows into the existing ResultsList. Extend <SheetSection> with optional meta. Add --action-transformative semantic token. |
||
|
|
f62716f557 |
refactor(design): align typography, colors, and card surfaces to DESIGN.md (#859)
* refactor(design): align surface tokens to DESIGN.md §2 * refactor(design): canonicalize tracked-mono kickers and display rungs * refactor(design): collapse to five-slot palette and align card surfaces |
||
|
|
d47f6b40e4 |
fix(login): remove branding duplication, add shimmer and ping dot (#727)
- Remove redundant SENCHO prefix from kicker (already shown in card header) - Animate the left accent bar with a slow back-and-forth shimmer sweep - Replace static status dot with animated ping pulse |
||
|
|
2b499cb2c9 |
feat(design-system): retune oklch tokens to cozy-pebble palette (#709)
Apply design audit section 13's proposed chroma/lightness values to frontend/src/index.css. Dark-theme accents now match the audit swatches exactly: brand 0.78 0.11 195, success 0.78 0.16 155, warning 0.82 0.14 75, destructive 0.72 0.18 20. Surface hierarchy shifts to a warm pebble cast (hue 80, chroma 0.003 to 0.01); card anchors to the audit's 0.14 0.005 80 surface swatch; popover bumps to 0.16 to preserve the 4 percent lightness gap against card. Light theme mirrors symmetrically. NetworkTopologyView keeps the react-flow inline-style escape hatch but hoists the brand literal into a BRAND_COLOR constant so MiniMap and EDGE_COLORS share one source of truth. Also normalize em-dash comment separators to colons across index.css and drop a duplicated dark-background literal in favor of var(--background). |
||
|
|
c7dfde4b79 |
fix(sidebar): distinct fuchsia notification dot for update indicator (#708)
The pulsing dot signaling an available image update used --info (blue hue 250), the same hue as --label-blue, so the two blended visually when a stack carried a blue label. Introduce a dedicated --update token in vibrant fuchsia (hue 320) sitting outside the label palette, and render both the sidebar StackRow and the fleet NodeManager indicator as a notification-dot pattern (solid stationary core with animate-ping halo). Aligns with the design rule that static state should not pulse. |
||
|
|
5589110925 |
feat(ui): redesign top bar as chrome-glass masthead (#696)
Extract the app header into a dedicated TopBar component and apply the same translucent chrome language used by the sidebar: bg-sidebar + backdrop-blur-md + inset top highlight. A new --chrome-top-highlight token drives the highlight in both themes via the shadow-chrome-top utility alias. Restore the pulsing-dot unread indicator on the notification bell (replaces the temporary count pill) and keep its aria-label dynamic so screen readers still hear the unread count. Tighten nav a11y with aria-current on the active item, aria-label on icon-only buttons, and a proper <nav> landmark around the desktop Highlight group. |
||
|
|
ad90bd9404 |
feat(settings): add comfortable/compact density toggle (#683)
Adds a per-device appearance preference that compresses row, cell, and tile padding across dashboard, settings, audit log, and every shared table without changing typography or layout structure. Density is stored in localStorage and applied to the document body as a class that swaps a set of CSS variables. Components opt in by consuming the tokens, so the global table primitive scales all seven consumers at once. A new Appearance section in the Identity group lets users pick between Comfortable and Compact via a Combobox, with a helper line that reflects the current choice. |
||
|
|
7ec189dc35 |
feat(design-system): adopt cyan as data color, add Instrument Serif, introduce label roles (#674)
- Repoint --chart-1..3 to brand/warning/destructive so cyan leads as the primary data color, amber marks peaks, rose marks errors. --chart-4/5 fall back to neutral greyscale tones tuned per theme. - Add --data-line-width (1.25px) and --data-peak tokens so sparklines across dashboard, stack table, and readiness views share one source of truth instead of re-deriving per component. - Introduce five semantic label role aliases (env, role, owner, risk, custom) mapped to existing hues. Raw ten-hue palette stays in place for existing consumers; new labels should consume roles. - Replace Georgia serif with Instrument Serif and add --font-display alias in both :root and .dark; expose font-display via @theme inline so Tailwind utility classes can use it. Load the family from Google Fonts alongside Geist + Geist Mono. |
||
|
|
718c1eb1ea |
fix(host-console): harden with security fixes, validation, and test coverage (#580)
Security: - Enforce RBAC (system:console permission) on WebSocket upgrade - Validate token_version for user sessions on WS connections - Expand env var sanitization to cover additional secret patterns (PRIVATE, AUTH, PASSPHRASE, ENCRYPT, SIGNING) and connection strings (REDIS_URL, MONGO_URI, AMQP_URL, DSN) Reliability: - Add session tracking with max 5 concurrent console sessions - Add WebSocket heartbeat (30s ping, 60s pong timeout) to detect and clean up dead connections and orphaned PTY processes - Differentiate PTY spawn error messages (shell not found, permission denied, generic failure) - Guard against duplicate cleanup when both WS close and PTY exit fire Observability: - Add structured logging with [HostConsole] prefix for session lifecycle (open, close, duration, user, pid) - Add diagnostic logging behind developer_mode for terminal resize events and message parse errors Frontend: - Replace hardcoded hex colors with oklch CSS custom properties (--terminal-bg, --terminal-fg, --terminal-cursor, etc.) - Apply design system material tokens (shadow-card-bevel, recessed well shadow, card border hierarchy, strokeWidth 1.5) Tests: - Add 20 tests covering env sanitization patterns (10 keyword categories + safe vars + case insensitivity), session tracking, and console-token RBAC (admin, viewer, deployer, API tokens) Docs: - Document admin role requirement and session limits - Add troubleshooting section (session limits, shell not found, proxy timeouts, missing console tab) - Update security section with expanded env var coverage |
||
|
|
f9ebd1d77c |
feat: UI polish sprint — 7 items + logs toolbar redesign (#365)
* feat: UI polish sprint — tag filters, toast tokens, logs toolbar, billing portal, editor UX - Fleet: replace inline tag pills with multi-select combobox dropdown - Toast: remap all notification colors to oklch design tokens - Logs: convert floating hover toolbar to permanent pinned toolbar, replace all hardcoded colors with design tokens for theme support - Audit: fix dropdown scroll-lock (modal=false), light theme button contrast - Resources: remove redundant inner border/bg on tab wrapper - Editor: add ⌘K/Ctrl+K shortcut hint and handler, standardize button heights - Billing: signed Lemon Squeezy portal URLs via sencho.io proxy for all tiers - New MultiSelectCombobox UI component * feat(editor): replace button row with split-button dropdown Replace three separate editor buttons (Discard, Save Only, Save & Deploy) with a compact split-button dropdown. Primary action is "Save & Deploy"; chevron opens dropdown with "Save Only" and "Discard Changes" options. |
||
|
|
28e7be652c |
feat(labels): add stack labels for organizing, filtering, and bulk actions (#341)
* feat(labels): add stack_labels schema and DatabaseService CRUD methods
* feat(labels): add label CRUD, assignment, and bulk action API routes
* feat(labels): add oklch label color palette for light and dark themes
* feat(labels): add LabelPill and LabelDot reusable components
* feat(labels): add LabelAssignPopover component for inline label management
* feat(labels): add label pill bar, label dots, and label assignment to sidebar
* feat(labels): add label filtering and label dots to fleet view
* feat(labels): add label-scoped bulk actions (deploy/stop/restart all)
* docs: add Stack Labels feature documentation
* fix(labels): use context menu sub-menu for label assignment and add settings integration
Replace broken Popover-inside-ContextMenu pattern with native Radix
ContextMenuSub for reliable label toggling on right-click. Wrap
ContextMenuSubContent in a Portal to prevent overflow clipping. Add
"Manage labels..." item that opens Settings directly to Labels section.
Fix close button overlap in LabelsSection header. Add LabelsSection
settings component with full CRUD, assignment counts, and ProGate.
Add initialSection prop to SettingsModal for deep-linking. Include
screenshots for documentation.
* docs: update stack labels documentation with screenshots and corrected instructions
* fix(labels): address security and quality issues from code review
- Add NaN validation on parseInt(req.params.id) in label routes
- Scope updateLabel/deleteLabel by nodeId to prevent cross-node IDOR
- Validate labelIds belong to correct node in setStackLabels
- Add requireAdmin check on bulk action endpoint
- Replace error: any with error: unknown and proper narrowing
- Remove unused Label import from index.ts
- Remove unused isPro prop from LabelsSection
- Add strokeWidth={1.5} to Check icons per design system
* chore: update CHANGELOG with stack labels feature
|
||
|
|
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. |
||
|
|
32a7d53b2b |
feat: RBAC, atomic deployments, fleet backups, and licensing (Pro) (#185)
* feat: add RBAC viewer accounts, atomic deployments, and fleet-wide backups (Pro) Introduces three Pro-tier features: - RBAC: Multi-user system with admin/viewer roles, user management UI, automatic migration from single-admin credentials, viewer restrictions across the entire UI (read-only editor, hidden action buttons) - Atomic Deployments: Pre-deploy file backup to .sencho-backup/, automatic rollback on health probe failure, manual rollback button, health probes added to stack updates, webhook-triggered deploys use atomic rollback - Fleet-Wide Backups: Point-in-time snapshots of compose files across all nodes (local + remote), stored centrally in SQLite, per-stack restore with optional redeploy, graceful handling of offline nodes * fix(settings): use correct ProGate prop name in UsersSection * fix(settings): remove unused isPro prop from UsersSection * fix(auth): fetch user info after login and setup so isAdmin is set correctly * feat(pricing): revise pricing strategy and enforce variant-based seat limits Raise Personal Pro from $49/yr to $69/yr with 3 viewer seats (up from 1). Add $15/mo billing option for Team Pro. Mark lifetime pricing as a 90-day early-adopter offer. Store Lemon Squeezy variant_name on activation/validation and enforce seat limits server-side per variant. * feat(licensing): add Lemon Squeezy checkout, webhook, and billing portal integration Server-side checkout URL generation (POST /api/checkout) with admin email pre-fill and instance_id custom data. HMAC-SHA256 verified webhook endpoint (POST /api/webhooks/lemonsqueezy) handling order, subscription, and payment lifecycle events for automatic license activation. Customer billing portal link stored from webhook events and exposed via GET /api/billing/portal. In-app checkout buttons in Settings with manual license key fallback. * fix(licensing): exempt Lemon Squeezy webhook from auth middleware The catch-all auth middleware on /api/* was blocking the public webhook endpoint. Added /webhooks/lemonsqueezy to the exemption list alongside /auth/* and /webhooks/:id/trigger. * feat(pricing): update pricing to final live rates Personal Pro: $7.99/month, $69.99/year, $249 lifetime. Team Pro: $49.99/month, $499.99/year, $1,499 lifetime. Added personal_monthly checkout variant across backend, frontend, and website. * refactor(licensing): remove server-side checkout/webhook for self-hosted model Sencho is self-hosted — each user runs their own instance, so there is no central server to receive webhooks or hold the store API key. Replaced in-app checkout buttons with a "View Pricing" redirect to sencho.io and kept manual license key activation as the primary flow. - Delete LemonSqueezyService (checkout, webhook, HMAC verification) - Remove POST /api/checkout, GET /api/billing/portal, POST /api/webhooks/lemonsqueezy - Remove raw body parser and auth exemption for webhook route - Remove all LEMONSQUEEZY_* env vars from .env.example - Replace checkout buttons in SettingsModal with single "View Pricing" button - Simplify LicenseContext checkout to open sencho.io pricing page - Update licensing docs to reflect website-based purchase flow * chore: normalize em-dashes to hyphens across codebase (linter) * chore: remove accidentally tracked directories from index |
||
|
|
0cb5fae947 |
feat(design): animated design system foundation with animate-ui and motion
Install motion + animate-ui, overhaul design tokens with brand cyan accent, and replace CSS keyframe animations in Dialog, Tabs, Switch, and Tooltip with spring-physics and blur-fade transitions via animate-ui Radix primitives. |
||
|
|
69408257d2 | fix: implement atomic deployment rollbacks and custom scrollbar UI | ||
|
|
aeb3d6e812 | feat: implement initial frontend application with Monaco editor, Docker Compose stack management, and container monitoring. | ||
|
|
cd006feb6a | feat: Initialize React frontend project with Vite, Tailwind CSS, Radix UI, and global styling. | ||
|
|
431f29c490 | feat: Initialize global CSS with Tailwind directives, theme variables for light/dark mode, and base styling. | ||
|
|
293f9cef26 | Initial commit: Sencho V1 complete with Auth and Dockerization |