Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
88 commits
Select commit Hold shift + click to select a range
71b341e
Add plugin system (backend + frontend)
jhd3197 Mar 28, 2026
808078f
chore: bump version to 1.4.14 [skip ci]
github-actions[bot] Mar 28, 2026
9c053c9
Add developer Style Guide page and styles
jhd3197 Mar 29, 2026
c811fd8
chore: bump version to 1.4.15 [skip ci]
github-actions[bot] Mar 29, 2026
099c7a3
EmptyState loading/size + theme SCSS refactor
jhd3197 Mar 29, 2026
cdf951a
chore: bump version to 1.4.16 [skip ci]
github-actions[bot] Mar 29, 2026
313f1a8
Remote Docker remove, normalize API & permissions
jhd3197 Apr 29, 2026
cc1151d
Add deployment jobs and remote deployment runner
jhd3197 Apr 29, 2026
e9d8af2
Add Deployments page and fix templates SCSS build
jhd3197 Apr 29, 2026
e25cf6f
Add tunnel mode and enhance servers UI
jhd3197 Apr 29, 2026
e5a90a3
Add short-code agent pairing flow
jhd3197 Apr 29, 2026
f82c12a
Pin agent to Go 1.23 for CI compatibility
jhd3197 Apr 29, 2026
05a70f1
Bump vulnerable backend deps flagged by Safety
jhd3197 Apr 29, 2026
2f25fd8
chore: bump version to 1.4.17 [skip ci]
github-actions[bot] Apr 29, 2026
3a0fd76
Fix Docker (Go 1.23) + MSI (pin WiX v5) builds in agent-release
jhd3197 Apr 29, 2026
2ed3b50
chore: bump version to 1.4.18 [skip ci]
github-actions[bot] Apr 29, 2026
956c8e7
Add browser setup wizard and MSI shortcuts
jhd3197 Apr 29, 2026
21b5715
Merge branch 'dev' of https://github.com/jhd3197/ServerKit into dev
jhd3197 Apr 29, 2026
e734fd6
Add setup debug logging & refactor security UI
jhd3197 Apr 29, 2026
b0b2f57
Replace native controls with UI components
jhd3197 Apr 29, 2026
c62497b
Style tabs as underline bar and enable scrolling
jhd3197 Apr 29, 2026
0d76726
Add native Windows desktop wizard & ARM64 builds
jhd3197 Apr 29, 2026
bcaa3df
Windows setup UI + MSI launcher & frontend tweaks
jhd3197 Apr 29, 2026
4d6e712
Generate and display pairing passphrase
jhd3197 Apr 29, 2026
11e3b1c
Add WebView2-based agent console and UI
jhd3197 Apr 29, 2026
04571a8
Add metrics sampler and new agent console UI
jhd3197 Apr 30, 2026
3ff432b
Add activity event store and UI
jhd3197 Apr 30, 2026
354c625
Add console actions, logs UI, and log rotation
jhd3197 Apr 30, 2026
96a6f31
Add poll transport; Windows UI & service fixes
jhd3197 May 1, 2026
19c727b
Add Windows service support and new UI components
jhd3197 May 1, 2026
8ea0586
Agent key migration, DB fix, UI tabs/page cleanup
jhd3197 May 1, 2026
a93697c
Add agent capability probing and reporting
jhd3197 May 1, 2026
3963321
Add GUI capture SDK; refactor UI components
jhd3197 May 1, 2026
dca5c3a
Add remote cron management (agent, API, UI)
jhd3197 May 1, 2026
8ddd60f
Add Cloudflared tunnel management
jhd3197 May 1, 2026
611e332
Add file manager UI components and features
jhd3197 May 1, 2026
1f61513
Add agent Phase4 primitives, remote files & UI
jhd3197 May 1, 2026
07a778d
Add log viewer UI and plugin local/upload install
jhd3197 May 1, 2026
e71099a
Add remote packages, services, sudo, job streaming and capability re-…
jhd3197 May 1, 2026
a534fbf
Add Packages/Services tabs, JobProgressModal, pyenv runtime mgmt and …
jhd3197 May 1, 2026
930705f
Mirror agent version; plugin install & UI improvements
jhd3197 May 1, 2026
32bf2b8
Cache agent capabilities to DB and surface them in System Status card
jhd3197 May 1, 2026
af60b4c
Re-send agent capabilities on a periodic cadence
jhd3197 May 1, 2026
244eef8
Push system_info from agent and persist server IP
jhd3197 May 1, 2026
7d55a9c
Add panel-driven cloudflared login flow
jhd3197 May 1, 2026
d528d27
Bypass per-server ACL for control-plane actions; add diagnostic logs
jhd3197 May 1, 2026
6e5bccd
Permission expansion + Go probe + persisted system info fallback
jhd3197 May 1, 2026
19907de
Stop dropping capability/sysinfo payloads on transient /poll failures
jhd3197 May 1, 2026
e99e65c
Auto-correct stale 'online' status when no in-memory agent
jhd3197 May 1, 2026
c31da72
Detect WS flapping and fall back to polling permanently
jhd3197 May 1, 2026
5541504
Fix the systemic silent failures: empty log, dead WS, locked-out agents
jhd3197 May 1, 2026
a79bbc2
Add connstring, file handlers, and security tests
jhd3197 May 2, 2026
fea0698
UI: revamp dialogs, badges, and alerts tab
jhd3197 May 2, 2026
fe736fc
Add alerts and notification styles
jhd3197 May 2, 2026
a358300
Refine system status card and button styles
jhd3197 May 2, 2026
cd8c9bd
Refine Button component sizing and leading
jhd3197 May 2, 2026
6dc9bd7
Migrate UI components to SCSS .ui-* classes
jhd3197 May 2, 2026
4f9d4de
Enhance .empty-state-sm styles and relocate
jhd3197 May 2, 2026
b4414aa
Introduce unified dev launcher and SCSS migration
jhd3197 May 3, 2026
85fb3b5
Add compose list API and overhaul Docker UI
jhd3197 May 3, 2026
31dd984
Add bulk container stats and UI workspace revamp
jhd3197 May 3, 2026
c18d0d8
Add New Service (repo) creation and UI
jhd3197 May 3, 2026
96db8df
Add GitHub source connections & repo picker
jhd3197 May 3, 2026
99abf8f
Add repository manifest detection and templates
jhd3197 May 3, 2026
ddcf0b2
Add plugin contributions system, SDK, and integration
jhd3197 May 3, 2026
b4f5a46
Add audit fallback, builtin extensions, and ports
jhd3197 May 3, 2026
9f7bd23
Improve plugin loading, API client & marketplace UI
jhd3197 May 3, 2026
35f4607
Monitoring UI, public page & slug validation
jhd3197 May 4, 2026
3c4a2c0
Make Git extension canonical at /git
jhd3197 May 4, 2026
4db9300
Introduce sk1 connection string format and GUI plugin
jhd3197 May 5, 2026
cf88e54
chore: bump version to 1.6.2 [skip ci]
github-actions[bot] May 5, 2026
abb8889
Add Multipass-based E2E test harness
jhd3197 May 17, 2026
2a2764d
chore: bump version to 1.6.3 [skip ci]
github-actions[bot] May 17, 2026
37d9c63
Strip non-ASCII chars from test harness PS scripts
jhd3197 May 17, 2026
8f523f2
chore: bump version to 1.6.4 [skip ci]
github-actions[bot] May 17, 2026
099c61d
Make E2E test harness actually run end-to-end on Windows
jhd3197 May 17, 2026
191c6fd
Fix plugin loader ordering + add live test report
jhd3197 May 17, 2026
b0f31ac
Export InstalledPlugin from app/models so create_all sees it
jhd3197 May 17, 2026
1f7a0a2
Stop live report flashing FAIL/VMs:0 on first open
jhd3197 May 17, 2026
eaad020
chore: bump version to 1.6.5 [skip ci]
github-actions[bot] May 17, 2026
5a5e5e2
Address Copilot review: plugin security + correctness
jhd3197 May 17, 2026
049e80f
chore: bump version to 1.6.6 [skip ci]
github-actions[bot] May 17, 2026
3b29741
Add Vagrant + Hyper-V runner for Debian/Fedora/Rocky coverage
jhd3197 May 17, 2026
4657483
Detect missing admin elevation when Vagrant distros are requested
jhd3197 May 17, 2026
939575f
chore: bump version to 1.6.7 [skip ci]
github-actions[bot] May 17, 2026
59e2874
Pin Hyper-V switch in Vagrantfile to avoid interactive prompt
jhd3197 May 17, 2026
18d25c6
Stream vagrant up output to terminal so prompts are visible
jhd3197 May 17, 2026
e3337f0
Stop vagrant up output from corrupting test status
jhd3197 May 17, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
7 changes: 7 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,13 @@ DATABASE_URL=sqlite:///serverkit.db
# CORS Origins - your domain(s), comma-separated
CORS_ORIGINS=http://localhost,https://your-domain.com

# Public URL that agents should dial back to. Set this whenever the panel
# sits behind a reverse proxy / tunnel / custom domain — the connection
# string the panel issues to agents will embed this URL instead of the
# request's Host header (which would otherwise be the internal IP/port).
# Leave commented out for plain localhost development.
# SERVERKIT_PUBLIC_URL=https://panel.your-domain.com

# Ports (for Docker)
PORT=80
SSL_PORT=443
Expand Down
13 changes: 13 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
* text=auto eol=lf

*.sh text eol=lf
*.ps1 text eol=crlf
*.bat text eol=crlf
*.cmd text eol=crlf

*.png binary
*.jpg binary
*.jpeg binary
*.gif binary
*.ico binary
*.pdf binary
42 changes: 32 additions & 10 deletions .github/workflows/agent-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ on:
type: string

env:
GO_VERSION: '1.21'
GO_VERSION: '1.23'

jobs:
build:
Expand All @@ -31,6 +31,9 @@ jobs:
- goos: windows
goarch: amd64
suffix: '.exe'
- goos: windows
goarch: arm64
suffix: '.exe'

steps:
- name: Checkout code
Expand Down Expand Up @@ -60,7 +63,15 @@ jobs:
CGO_ENABLED: 0
run: |
cd agent
go build -ldflags="-s -w -X main.Version=${{ steps.version.outputs.version }} -X github.com/serverkit/agent/internal/agent.Version=${{ steps.version.outputs.version }}" \
# Windows builds use -H windowsgui so Start-menu launches don't
# flash a console. attachParentConsole() in cmd/agent restores
# stdio when invoked from PowerShell/cmd for CLI subcommands.
if [ "${{ matrix.goos }}" = "windows" ]; then
EXTRA_LDFLAGS="-H=windowsgui"
else
EXTRA_LDFLAGS=""
fi
go build -ldflags="-s -w $EXTRA_LDFLAGS -X main.Version=${{ steps.version.outputs.version }} -X github.com/serverkit/agent/internal/agent.Version=${{ steps.version.outputs.version }}" \
-o ../dist/serverkit-agent-${{ matrix.goos }}-${{ matrix.goarch }}${{ matrix.suffix }} \
./cmd/agent

Expand Down Expand Up @@ -190,12 +201,20 @@ jobs:
path: packages/*.rpm
retention-days: 5

# Build Windows MSI
# Build Windows MSI installers (one per architecture)
build-msi:
name: Build MSI Installer
name: Build MSI Installer (${{ matrix.arch }})
runs-on: windows-latest
needs: build

strategy:
matrix:
include:
- goarch: amd64
arch: x64
- goarch: arm64
arch: arm64

steps:
- name: Checkout code
uses: actions/checkout@v4
Expand All @@ -213,30 +232,30 @@ jobs:

- name: Install WiX Toolset
run: |
dotnet tool install --global wix
dotnet tool install --global wix --version 5.0.2

- name: Download binary
uses: actions/download-artifact@v4
with:
name: serverkit-agent-windows-amd64
name: serverkit-agent-windows-${{ matrix.goarch }}
path: dist/

- name: Extract binary
shell: bash
run: |
cd dist
unzip serverkit-agent-${{ steps.version.outputs.version }}-windows-amd64.zip
unzip serverkit-agent-${{ steps.version.outputs.version }}-windows-${{ matrix.goarch }}.zip

- name: Build MSI
shell: pwsh
run: |
cd agent/packaging/msi
.\build.ps1 -Version "${{ steps.version.outputs.version }}" -BinaryPath "..\..\..\dist\serverkit-agent-windows-amd64.exe" -OutputDir "..\..\..\packages"
.\build.ps1 -Version "${{ steps.version.outputs.version }}" -Arch "${{ matrix.arch }}" -BinaryPath "..\..\..\dist\serverkit-agent-windows-${{ matrix.goarch }}.exe" -OutputDir "..\..\..\packages"

- name: Upload MSI
uses: actions/upload-artifact@v4
with:
name: serverkit-agent-msi
name: serverkit-agent-msi-${{ matrix.arch }}
path: packages/*.msi
retention-days: 5

Expand Down Expand Up @@ -352,6 +371,7 @@ jobs:
| Linux | x64 (amd64) | `serverkit-agent-${{ steps.version.outputs.version }}-linux-amd64.tar.gz` |
| Linux | ARM64 | `serverkit-agent-${{ steps.version.outputs.version }}-linux-arm64.tar.gz` |
| Windows | x64 (amd64) | `serverkit-agent-${{ steps.version.outputs.version }}-windows-amd64.zip` |
| Windows | ARM64 | `serverkit-agent-${{ steps.version.outputs.version }}-windows-arm64.zip` |

#### Linux Packages
| Format | Architecture | Download |
Expand All @@ -365,8 +385,9 @@ jobs:
| Format | Architecture | Download |
|--------|--------------|----------|
| MSI | x64 | `serverkit-agent-${{ steps.version.outputs.version }}-x64.msi` |
| MSI | ARM64 | `serverkit-agent-${{ steps.version.outputs.version }}-arm64.msi` |

> **New:** Run `serverkit-agent tray` to launch the **System Tray Application** which provides a visual indicator that the agent is running, along with quick access to status, logs, and service controls. The MSI installer auto-starts the tray on Windows login.
> **New:** The Windows MSI now opens a native pairing wizard right after install — no browser, no WebView2 runtime needed. The Start-menu shortcut and login autostart both run the unified desktop app: pairing wizard if not yet configured, otherwise the system tray.

#### Docker
```bash
Expand Down Expand Up @@ -458,6 +479,7 @@ jobs:
echo "| RPM | x86_64 | ✅ Built |" >> $GITHUB_STEP_SUMMARY
echo "| RPM | aarch64 | ✅ Built |" >> $GITHUB_STEP_SUMMARY
echo "| MSI | x64 | ✅ Built |" >> $GITHUB_STEP_SUMMARY
echo "| MSI | ARM64 | ✅ Built |" >> $GITHUB_STEP_SUMMARY
echo "| Docker | multi-arch | ✅ Built |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### Release" >> $GITHUB_STEP_SUMMARY
Expand Down
18 changes: 18 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
/backend/*.pyd
/backend/.env
/backend/.venv
/backend/.venv-wsl/
/backend/pip-log.txt
/backend/pip-delete-this-directory.txt
/backend/dev-data/
Expand All @@ -40,6 +41,7 @@
/agent/*.test
/agent/*.out
/agent/bin/
/dist/

# Environment / Secrets
.env
Expand All @@ -53,6 +55,7 @@
*.csr
/backend/.env
/frontend/.env.local
/frontend/.env.development.local

# Docker
.docker-compose.untracked.yml
Expand Down Expand Up @@ -95,4 +98,19 @@ new_templates/
nul
SECURITY_AUDIT.md
APP_IMPROVEMENTS.md
UI_REPORT.md
*.png

# MSI / build artifacts that should not be committed.
/agent/packaging/msi/output/
/agent/packaging/msi/*.wixpdb

# Brand assets that the agent embeds at build time are generated by
# agent/packaging/icons/generate_icons.py from the SVG, but must be checked
# in so CI builds don't have to install cairo/Pillow.
!agent/internal/setupui/serverkit.ico
!agent/internal/setupui/serverkit_header.png
docs/PLAN_AGENT_FLEET.md
/docs/plans
/.agents
/.extension-platform-plan/
122 changes: 122 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
# AGENTS.md

This file provides guidance to Codex (Codex.ai/code) when working with code in this repository.

## Project Overview

ServerKit is a server control panel for managing web applications, databases, Docker containers, and security on VPS/dedicated servers. Flask backend (Python 3.11+), React frontend (Vite + SCSS), SQLite/PostgreSQL database, real-time updates via Socket.IO.

## Development Commands

```bash
# Backend (launcher default port 47927, hot-reload)
cd backend && python -m venv venv && source venv/bin/activate # Windows: venv\Scripts\activate
pip install -r requirements.txt
python run.py

# Frontend (launcher default port 41921, Vite HMR)
cd frontend && npm install && npm run dev

# Both at once (Linux/WSL)
./dev.sh

# Frontend lint
cd frontend && npm run lint

# Frontend production build
cd frontend && npm run build

# Backend tests
cd backend && pytest
cd backend && pytest --cov=app

# Docker
docker compose -f docker-compose.dev.yml up --build
```

Default dev credentials: `admin` / `admin`

## Architecture

### Backend (`backend/`)

Flask app factory in `app/__init__.py` using `create_app()`. Three-layer architecture:

- **`app/api/`** — Flask Blueprints, one file per feature (36 files). All routes prefixed `/api/v1/`. JWT-protected via `@jwt_required()`.
- **`app/services/`** — Business logic (48 files). Services are stateless modules called by API routes. Heavy lifting (shell commands, Docker API, file operations) happens here.
- **`app/models/`** — SQLAlchemy ORM models (15 files). Tables auto-created on startup via `db.create_all()`.

Other backend components:
- `app/sockets.py` — Socket.IO event handlers for real-time metrics, logs, terminal
- `app/agent_gateway.py` — Multi-server agent communication
- `app/middleware/security.py` — Security headers middleware
- `config.py` — Environment-based config (development/production/testing)
- `run.py` — Entry point

### Frontend (`frontend/src/`)

React 18 SPA with client-side routing:

- **`pages/`** — Route-level components (~29 files). Each maps to a route in `App.jsx`.
- **`components/`** — Reusable UI components shared across pages.
- **`contexts/`** — React Context providers: `AuthContext` (JWT auth + token refresh), `ThemeContext`, `ToastContext`, `ResourceTierContext` (feature gating).
- **`services/api.js`** — Centralized `ApiService` class handling all HTTP requests, token management, and auto-refresh.
- **`hooks/`** — Custom React hooks for reusable logic.
- **`styles/`** — SCSS stylesheets with design system variables. Main entry is `main.scss`. Page-specific styles in `styles/pages/`.
- **`layouts/`** — `DashboardLayout` wraps authenticated pages (sidebar + header).

Route guards: `PrivateRoute` (auth check), `PublicRoute` (redirect if logged in), `SetupRoute` (redirect to `/setup` if not configured).

### Request Flow

Browser → Nginx (`:80`/`:443`) → proxy_pass to Docker containers (`:8001-8999`) for managed apps, or to Flask (`:5000`) for the panel API. The 404 handler in Flask serves `index.html` for SPA client-side routing; API routes return JSON errors.

### Production Build

The Dockerfile is multi-stage: Node 20 builds frontend, Python 3.11 serves everything via Gunicorn with GeventWebSocket workers. Built frontend is served from Flask's static folder.

## Platform & Distro Awareness

ServerKit deploys on Linux (bare metal, VPS, or Docker). Development may happen on Windows/macOS.

- **Service layer is Linux-only** — nginx, systemctl, apt/dnf, PHP-FPM, etc. are inherently Linux. No need to abstract these for Windows.
- **Platform-agnostic code** (config management, storage, API layer) should guard Unix-only calls like `os.chmod` with `if os.name != 'nt'` so the dev server can run locally on any OS.
- **Distro differences matter** — use `backend/app/utils/system.py` helpers (`get_package_manager`, `is_package_installed`, `install_package`) instead of calling `apt`/`dpkg`/`dnf` directly. Not all targets are Debian-based.

## Code Style

### Python
- PEP 8, type hints where helpful
- Service functions are standalone (no classes unless stateful)
- Consistent JSON error responses: `{'error': 'message'}, status_code`

### React/JavaScript
- Functional components with hooks only
- PascalCase for components (`Sidebar.jsx`), camelCase for everything else
- SCSS for styling — use existing design system variables (`$bg-card`, `$primary-color`, `$spacing-md`, etc.) and BEM-like naming (`.block__element--modifier`)
- Context API for global state; props drilling is fine for 2-3 levels
- No inline styles; no Tailwind/CSS-in-JS

### Diffs & Commits
- One logical change per commit
- Minimal, focused diffs — don't silently refactor surrounding code
- Branch naming: `feature/`, `fix/`, `docs/`, `refactor/` prefixes

## Adding a New Feature (Full Stack)

1. **Model**: Add SQLAlchemy model in `backend/app/models/`
2. **Service**: Add business logic in `backend/app/services/`
3. **API**: Create Blueprint in `backend/app/api/`, register it in `app/__init__.py` with `url_prefix='/api/v1/<feature>'`
4. **Frontend API**: Add methods to `ApiService` in `frontend/src/services/api.js`
5. **Page**: Create page component in `frontend/src/pages/`, add route in `App.jsx`
6. **Styles**: Add SCSS file in `frontend/src/styles/pages/`, import in `main.scss`

## Key Environment Variables

| Variable | Purpose |
|----------|---------|
| `SECRET_KEY` | Flask session signing |
| `JWT_SECRET_KEY` | JWT token signing |
| `DATABASE_URL` | DB connection string (`sqlite:///...` or PostgreSQL) |
| `CORS_ORIGINS` | Comma-separated allowed origins |
| `FLASK_ENV` | `development` or `production` |
12 changes: 6 additions & 6 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,17 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co

## Project Overview

ServerKit is a server control panel for managing web applications, databases, Docker containers, and security on VPS/dedicated servers. Flask backend (Python 3.11+), React frontend (Vite + LESS), SQLite/PostgreSQL database, real-time updates via Socket.IO.
ServerKit is a server control panel for managing web applications, databases, Docker containers, and security on VPS/dedicated servers. Flask backend (Python 3.11+), React frontend (Vite + SCSS), SQLite/PostgreSQL database, real-time updates via Socket.IO.

## Development Commands

```bash
# Backend (port 5000, hot-reload)
# Backend (launcher default port 47927, hot-reload)
cd backend && python -m venv venv && source venv/bin/activate # Windows: venv\Scripts\activate
pip install -r requirements.txt
python run.py

# Frontend (port 5173, Vite HMR)
# Frontend (launcher default port 41921, Vite HMR)
cd frontend && npm install && npm run dev

# Both at once (Linux/WSL)
Expand Down Expand Up @@ -62,7 +62,7 @@ React 18 SPA with client-side routing:
- **`contexts/`** — React Context providers: `AuthContext` (JWT auth + token refresh), `ThemeContext`, `ToastContext`, `ResourceTierContext` (feature gating).
- **`services/api.js`** — Centralized `ApiService` class handling all HTTP requests, token management, and auto-refresh.
- **`hooks/`** — Custom React hooks for reusable logic.
- **`styles/`** — LESS stylesheets with design system variables. Main entry is `main.less`. Page-specific styles in `styles/pages/`.
- **`styles/`** — SCSS stylesheets with design system variables. Main entry is `main.scss`. Page-specific styles in `styles/pages/`.
- **`layouts/`** — `DashboardLayout` wraps authenticated pages (sidebar + header).

Route guards: `PrivateRoute` (auth check), `PublicRoute` (redirect if logged in), `SetupRoute` (redirect to `/setup` if not configured).
Expand Down Expand Up @@ -93,7 +93,7 @@ ServerKit deploys on Linux (bare metal, VPS, or Docker). Development may happen
### React/JavaScript
- Functional components with hooks only
- PascalCase for components (`Sidebar.jsx`), camelCase for everything else
- LESS for styling — use existing design system variables (`@card-bg`, `@primary-color`, `@spacing-md`, etc.) and BEM-like naming (`.block__element--modifier`)
- SCSS for styling — use existing design system variables (`$bg-card`, `$primary-color`, `$spacing-md`, etc.) and BEM-like naming (`.block__element--modifier`)
- Context API for global state; props drilling is fine for 2-3 levels
- No inline styles; no Tailwind/CSS-in-JS

Expand All @@ -109,7 +109,7 @@ ServerKit deploys on Linux (bare metal, VPS, or Docker). Development may happen
3. **API**: Create Blueprint in `backend/app/api/`, register it in `app/__init__.py` with `url_prefix='/api/v1/<feature>'`
4. **Frontend API**: Add methods to `ApiService` in `frontend/src/services/api.js`
5. **Page**: Create page component in `frontend/src/pages/`, add route in `App.jsx`
6. **Styles**: Add LESS file in `frontend/src/styles/pages/`, import in `main.less`
6. **Styles**: Add SCSS file in `frontend/src/styles/pages/`, import in `main.scss`

## Key Environment Variables

Expand Down
Loading
Loading