907 Commits
Author SHA1 Message Date
Juan Denis fbccb7eab4 Merge pull request #47 from jhd3197/dev
Add release smoke test workflow and refine rsync excludes
v1.6.29
2026-06-22 08:12:34 -04:00
github-actions[bot] e192250ef1 chore: bump version to 1.6.29 [skip ci] 2026-06-22 12:11:23 +00:00
Juan Denis d3b41f4f2a Merge branch 'dev' of https://github.com/jhd3197/ServerKit into dev 2026-06-22 08:11:07 -04:00
Juan Denis f0ee3b2e3d Add release smoke test and refine rsync excludes
Introduce a GitHub Actions workflow (release-smoke.yml) that builds the release tarball on pushes/PRs to dev/main for relevant paths, catching release-script issues early. Adjust scripts/build-release.sh rsync excludes to explicitly target backups directories (root/backups and backend instance/dev-data backups) instead of a broader exclude, preventing accidental omission of needed files during release packaging.
2026-06-22 08:09:29 -04:00
Juan Denis f01b7cde7f Merge pull request #46 from jhd3197/dev
Unified jobs, notification bus, telemetry stream, and workspace/service UI refresh
v1.6.28
2026-06-22 01:51:02 -04:00
github-actions[bot] aafbc39332 chore: bump version to 1.6.28 [skip ci] 2026-06-22 05:45:25 +00:00
Juan Denis 0e29978e7b Truncate large telemetry payloads & UI robustness fixes
Telemetry: ensure sanitized payloads bigger than the 32KiB threshold are replaced with a {_truncated: True} marker before storage, and add a unit test covering that behavior.

Backend API: adjust imports in secrets_webhooks to use WorkspaceService and include User model.

Frontend: make Sidebar resilient to malformed active_workspace JSON in localStorage (try/catch), and ensure socketService.disconnect() is called when user becomes unauthenticated in NotificationsProvider to clear notifications and unread count.

Files: backend/services/telemetry_service.py, backend/tests/test_telemetry.py, backend/app/api/secrets_webhooks.py, frontend/src/components/Sidebar.jsx, frontend/src/contexts/NotificationsContext.jsx
2026-06-22 01:45:15 -04:00
github-actions[bot] f31edb8c2f chore: bump version to 1.6.27 [skip ci] 2026-06-22 05:38:42 +00:00
Juan Denis 10ca0b3970 Refactor sidebar, workspace list, and Git settings UI
Rename service settings 'repository' → 'git' (routes, labels, and links) and update App route comment. Reorder sidebar footer so user mini and notification bell share a single row and add accessible user-mini button. Adjust notification panel positioning, add show animation, and responsive layout tweaks. Replace Workspaces card grid with a dense table view: add search, status segment control, bulk select checkboxes, and selection state. Minor SCSS tweaks for sidebar button sizing and WordPress action width. These changes improve discoverability and bulk management UX.
2026-06-22 01:35:36 -04:00
Juan Denis bb0bd7ba1d Workspace and queue bus improvements
- Add workspace detail routes, tabs, and page title handling
- Add workspace switcher select component and updated workspace styles
- Add queue detail page and protect system queue groups from REST mutations
- Update sidebar layout styles and queue operations UI
2026-06-22 01:16:00 -04:00
Juan Denis 9b7f69e654 Normalize service detail page with WordPress layout and add Domain & SSL
- Rename service Environment tab to Env Vars and settings Environment to Environment Type
- Add Domain & SSL section to service settings with attach domain + Let's Encrypt flow
- Surface primary domain from domains array in service subtitle
- Add prominent repo connection pill to WordPress detail header
- Apply WordPress list layout to Services page (drop KPIs, tabs+search toolbar)
2026-06-22 01:15:53 -04:00
github-actions[bot] c9d50788e3 chore: bump version to 1.6.26 [skip ci] 2026-06-22 02:11:23 +00:00
Juan DenisandClaude Opus 4.8 6f99bef3a9 refactor(jobs): dispatch workflow events via a workflow.dispatch job (no thread)
WorkflowEventBus.emit no longer spawns a per-event daemon thread to match +
trigger workflows. It now enqueues a single 'workflow.dispatch' job; the new
WorkflowEventBus.dispatch_event handler does the matching (active event-trigger
workflows whose eventType matches, honoring the 60s cooldown) and enqueues a
workflow.execute job per match. emit is a non-blocking enqueue, best-effort
(never raises into the caller), and the whole event -> dispatch -> execute path
now flows through the bus (observable, persistent across restart). Removes the
last ad-hoc thread on the workflow path.

Registered alongside workflow.execute in WorkflowEngine.register_jobs.

tests: dispatch handler registered; emit enqueues a dispatch job (not a thread);
dispatch fans out only to the matching event workflow.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 22:01:38 -04:00
Juan DenisandClaude Opus 4.8 fe7415842f feat(jobs): scheduled backups as backup.run jobs; fix dormant scheduler (Phase 7)
Wire scheduled backups onto the unified job system and retire the orphaned
backup scheduler thread.

- BackupService.start_scheduler/_scheduler_loop were defined but NEVER called,
  so scheduled backups never actually ran. Replace with check_backup_schedules()
  (enqueues a backup.run job per due schedule) driven by a new
  builtin.backup_scheduler tick, plus a run_backup_job handler that executes one
  schedule via the existing _run_scheduled_backup. max_attempts=1 (backups
  aren't idempotent); a failed run marks the job failed. This activates
  scheduled backups, but stays gated by the existing backup config.enabled
  (default False), so installs without configured backups are unaffected.
- Fix a latent bug in _send_backup_notification: it called
  NotificationService.send_all(title=, message=, severity=) but send_all takes
  a list of alert dicts — corrected (faithful: still routes to system channels
  via the queue-backed bus).
- Monitoring intentionally left as-is: a user-toggled continuous stream whose
  alert delivery already goes through the queued send_all. Phase 8 orchestration
  is already met — send_all is a non-blocking shim over broadcast_system.
- tests: backup.run register/handler success+failure; scheduler tick enqueues
  only due+enabled schedules and is inert when disabled.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 21:50:27 -04:00
Juan DenisandClaude Opus 4.8 70f8697586 feat(jobs): admin Jobs UI page over the unified job API (Phase 9)
Add /jobs — the single pane to observe and manage all background work, built
on the /api/v1/jobs API. Mirrors the DeliveryLog/Telemetry admin pages.

- Jobs table polls every 5s: status Pills (succeeded/running/pending/failed/
  cancelled), kind, owner, attempts, age. Status/kind filters. Per-row Cancel
  (pending/running) and Retry (failed/cancelled) with toast feedback. Row
  expands to a detail view (payload/result/error/correlation/timing) via getJob.
- Scheduled-jobs table: name, kind, schedule (cron or "every Nh"), next/last run,
  with Run-now and Pause/Enable.
- Stat cards (total/running/pending/succeeded/failed) from /jobs/stats.
- Wiring: services/api/jobs.js module bound into ApiService; route + page title
  in App.jsx; "Jobs" item in the sidebar "system" group; _jobs.scss imported
  in main.scss. Admin-gated client-side via useAuth().isAdmin.

Lint clean (0 errors) and production build passes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 21:28:41 -04:00
Juan DenisandClaude Opus 4.8 c0cb0f088e feat(jobs): run workflow executions as a workflow.execute unified job (Phase 6)
Migrate workflow executions onto the unified job system (single-job wrap).
WorkflowEngine is split into _create_execution (validate graph + persist the
running WorkflowExecution row) + run_execution (the synchronous DAG core) +
enqueue_execution (create row, enqueue a 'workflow.execute' job, return the
execution id immediately). execute_workflow stays as the synchronous primitive.

- All four triggers route through enqueue_execution: manual API, webhook,
  cron tick (builtin.workflow_schedules), and the WorkflowEventBus. The manual
  and webhook endpoints no longer block the HTTP request on the whole DAG; the
  cron tick enqueues one job per due workflow instead of running them serially
  inside the tick; the event bus thread now only matches + enqueues.
- max_attempts=1 (workflows deploy/script/notify — not idempotent). A failed
  run raises so the unified job is marked failed; the WorkflowExecution row
  keeps the detailed per-node status/logs. Graph validation still happens
  synchronously at enqueue, so an invalid workflow surfaces immediately.
- tests: register, enqueue-creates-row+job, empty workflow runs to success,
  failure path marks the job failed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 21:13:55 -04:00
Juan Denis 73d611966f ci(release): build and attach linux amd64/arm64 tarballs
The release workflow was publishing Docker assets and source but never
the serverkit-vX.Y.Z-linux-{amd64,arm64}.tar.gz files that install.sh,
update.sh, and 'serverkit update' expect to download. This caused release
updates to fail with 'Failed to download the release tarball.'

- Make scripts/build-release.sh honor BUILD_ARCH for CI matrix builds.
- Add a build-release job that builds tarballs on native amd64 and arm64
  runners and uploads them as artifacts.
- Wire the release job to download those artifacts, include them in the
  GitHub Release, and checksum them.
- Add the one-line installer to the release notes body.
2026-06-21 21:13:10 -04:00
Juan Denis ed7296500c Ignore new roadmap docs in .gitignore
Add docs/NOTIFICATIONS_ROADMAP.md and docs/ORCHESTRATION_ROADMAP.md to .gitignore so newly added roadmap documents are not tracked by Git. This keeps in-progress planning files out of commits until ready for publishing.
2026-06-21 21:06:35 -04:00
Juan DenisandClaude Opus 4.8 85265df138 feat(jobs): run template installs as a deploy.install unified job (Phase 5)
Migrate deployment installs off their ad-hoc daemon thread onto the unified
job system. DeploymentJobService.install_template now enqueues a
'deploy.install' Job instead of spawning a thread via _start_background_job
(retired); the JobConsumer runs it by calling the existing run_job.

- max_attempts=1: installs create containers/files/an app row and are not
  idempotent, so no auto-retry (preserves prior single-shot behavior).
- The unified Job shares the DeploymentJob's correlation_id and links back via
  owner_type='deployment_job'/owner_id; the DeploymentJob row stays the rich
  record (plan/steps/logs/progress). A failed run raises so both rows show failed.
- Bonus: CLI `deploy-template` (no --wait) now persists to the queue and runs
  when a consumer is available, instead of dying with the CLI process.
- tests: handler success/failure mapping + install_template enqueues-not-threads.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 21:01:38 -04:00
Juan DenisandClaude Opus 4.8 8428326a26 feat(jobs): unified background-job orchestration on the Queue Bus
Generalize the Notification Bus pattern (thin {id} message -> fat DB row
-> single consumer) into a Job/WorkUnit layer on top of the Queue Bus, so
background work flows through one pipe instead of many ad-hoc threads.

- app/jobs: Job + ScheduledJob models, handler registry, JobService +
  ScheduledJobService, one generic JobConsumer, one JobScheduler ticker,
  and a plugin SDK surface (app.plugins_sdk.jobs).
- Migrate the 8 per-domain daemon scheduler threads (auto-sync,
  snapshot-retention, workflow, health-check, wp-update, api-background,
  pairing-prune, registrar-expiry) to ScheduledJob rows + built-in
  handlers that reuse the exact prior check functions: cadence and
  per-task de-dup unchanged, only the trigger moved.
- Retire the orphaned in-memory BackgroundJobService; repoint
  /api/v1/performance/jobs at JobService.
- Add /api/v1/jobs (list/get/cancel/retry/stats; scheduled list/run/
  toggle) as a single pane over all background work.
- tests/test_jobs.py: enqueue->run->succeed, dead-letter->failed,
  unknown-kind, cancel, retry, scheduler tick/advance, built-ins.

No Alembic migration (tables created via create_all), avoiding a
multi-head clash with the in-flight telemetry work. Plan lives in
docs/ORCHESTRATION_ROADMAP.md (local/git-ignored).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 20:44:12 -04:00
Juan Denis 3d3975fa3a feat(telemetry): unified system event stream with correlation
Add SystemEvent model, TelemetryService, /api/v1 telemetry endpoints, and
a /telemetry UI page. Instrument audit, notification, webhook, backup,
deployment, and monitoring paths. Add correlation_id to Notification,
EventDelivery, and DeploymentJob so related events can be grouped.

- 18 backend tests added and passing
- Frontend production build clean
2026-06-21 20:19:57 -04:00
Juan DenisandClaude Opus 4.8 a33b2f7f38 feat(frontend): notification center, delivery log, email providers
- NotificationsContext + header bell/dropdown (sidebar + mobile top bar)
  with a live unread badge over Socket.IO and a /notifications history page.
- Admin /admin/notifications delivery log (stat cards, status/channel
  filters, retry) and an email-provider management UI (add/test/
  set-default/delete) for SMTP/SendGrid/Postmark/SES/Mailgun.
- api/notifications.js methods, socket 'notification' forwarding, a timeAgo
  util, and themed sk-notif* / sk-dlog / sk-eprov styles.

Builds clean (vite) and lints clean (eslint exit 0).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 19:57:18 -04:00
Juan DenisandClaude Opus 4.8 a661212d50 feat(notifications): queue-backed Notification Bus + email system
Reusable, non-blocking notification layer on top of the Queue Bus:
notify.send(event, to, data) records a Notification + per-channel
NotificationDelivery, queues them, and a daemon consumer delivers via
pluggable channel adapters (in-app, email, chat) inheriting retry,
backoff and dead-letter.

- Jinja2 email system: branded, dark-mode, Outlook-safe base layout +
  per-event templates (security/backup/monitoring/welcome/invitation).
  The legacy inline f-string email was removed and now renders here.
- In-app center API (inbox/unread-count/mark-read) + per-user Socket.IO push.
- Admin delivery log (stats/filter/retry).
- Email providers (SMTP/SendGrid/Postmark/SES/Mailgun) with encrypted
  credentials + test; the email adapter prefers the default provider and
  falls back to the legacy SMTP config; surfaced in ConnectionRegistry.
- NotificationService.send_all() is now a non-blocking shim that routes
  system alerts through the bus. Migrations 023 + 024.

Tests: backend/tests/test_notification_bus.py (20). Full suite: 391 passed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 19:57:02 -04:00
Juan Denis cbf64dfbaa feat(workspaces): enforce server quotas and add nav permissions UI
- Enforce max_servers quota on server creation and workspace moves
- Add my_role/my_effective_role to single workspace GET response
- Add Navigation Permissions editor to Workspace Settings
- Store full active workspace object for nav/brand settings
2026-06-21 18:44:08 -04:00
Juan Denis 45f754abc0 feat(workspaces): improve workspace switching and secrets/webhooks UI
- Update workspace API and service for workspace context handling
- Refine Sidebar and WorkspaceSwitcher components
- Update sidebar navigation items for workspace-aware routing
- Enhance SecretsWebhooks page and API client integration
2026-06-21 18:32:25 -04:00
Juan Denis aafeedd65d Merge pull request #45 from jhd3197/dev
Lean sidebar, split settings, per-server remote access
v1.6.25
2026-06-21 13:20:15 -04:00
github-actions[bot] 2f75f3fadc chore: bump version to 1.6.25 [skip ci] 2026-06-21 17:06:09 +00:00
Juan Denis bb30b2b4be ci: add ServerKit release workflow on push to main
Mirror the Mapanare release pattern for the ServerKit panel:

- Trigger release on push to main (PR merge), v* tags, and workflow_dispatch
- Add workflow_call to backend-ci.yml so release can use it as a CI gate
- Read VERSION file, create/push v{VERSION} tag when releasing from main
- Build and push multi-arch Docker image jhd3197/serverkit:{VERSION} + latest
- Create GitHub Release with Docker install instructions
2026-06-21 03:38:26 -04:00
Juan Denis f9d0610452 chore: remove agent code now living in serverkit-agent repo
The Go agent has moved to its own repository:
https://github.com/jhd3197/serverkit-agent

Changes:
- Delete agent/ directory and all source, build, and packaging files
- Delete .github/workflows/agent-ci.yml and agent-release.yml
- Delete scripts/test/agent-test.ps1 (agent now builds in separate repo)
- Remove committed dist/serverkit-agent-windows-amd64.exe build artifact
- Update docs/INSTALLATION.md and docs/README.md links to point to the new repo
- Add migration notes to docs/AGENT_AUDIT.md, docs/REMOTE_ACCESS_ROADMAP.md,
  SECURITY_AUDIT.md, and docs/plans/AGENT_FLEET_PHASES_3-4.md

Panel agent API endpoints under /api/v1/servers/agent/ and /api/v1/agent/
are retained — they are the control-plane contract with the standalone agent.

Verified:
- backend: pytest (371 passed, 12 skipped)
- frontend: npm run lint (0 errors)
2026-06-21 03:30:57 -04:00
Juan Denis 35270cd76d Merge branch 'dev' of https://github.com/jhd3197/ServerKit into dev 2026-06-21 03:11:23 -04:00
Juan DenisandClaude Opus 4.8 a5455c4655 feat(frontend): lean default sidebar + split Settings into account/admin
Sidebar — leaner default + setup wiring:
- Add a "Recommended" preset (Full minus Marketplace, Queue Bus, and
  Secrets & Webhooks) and make it the default for unconfigured users, so
  fresh installs aren't maximalist. The three demoted items stay fully
  routable and one click away via the "Full" view or Customize Sidebar.
- Factor the three into a shared ADVANCED_ITEM_IDS list so every curated
  preset hides them consistently.
- Wire the Setup wizard's use-case answer to an initial preset
  (presetForUseCases): a single WordPress intent -> Web Hosting, a single
  DevOps intent -> Docker/DevOps, anything mixed/general -> Recommended.

Settings — split the 17-item rail:
- Add a two-way "My Account" / "Admin" segmented switch (admin-only) so
  personal preferences aren't interleaved with server-wide system
  controls. The active group is derived from the tab, so deep links
  (e.g. /settings/users) open the right group. About moves into My
  Account; the dev/local-dev tools consolidate under Admin.

Verified: eslint (0 errors) and vite build both pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 03:11:12 -04:00
Juan Denis b15d12e1af Add per-server Remote Access tab and UI tweaks
Expose Remote Access as a per-server tab and adapt the fleet page for server-scoped views. RemoteAccess now accepts serverId, filters/labels tunnels involving that server, renders inline action button when embedded, disables private-server select for scoped views, and links nodes to per-server Remote Access pages from fleet view. Added tab to ServerDetail when wireguard is supported and updated styles for responsive intro, node links, and a “this server” tag. Small refactors: useMemo/useCallback optimizations and cleaner topbar action handling.
2026-06-21 02:47:36 -04:00
Juan Denis 37ce7b8a3c Merge pull request #44 from jhd3197/dev
Consolidate navigation, add the Queue Bus, and unify Git connect
2026-06-21 02:40:29 -04:00
github-actions[bot] 38073a543c chore: bump version to 1.6.24 [skip ci] 2026-06-21 06:26:11 +00:00
Juan Denis 4dc71d5774 fix(frontend): hide single-target picker, clean up terminal routing and errors
- TargetPicker now renders a static label when only one target option is available,
  removing the pointless/disabled dropdown on single-server setups.
- Change Terminal tab route from /terminal/terminal to /terminal/shell and add
  a redirect for the old URL.
- Terminal shell tab only lists agents advertising terminal capability, preventing
  'Agent not connected' errors on local/WSL dev installs.
- Add per-server creation guard in RemoteTerminal to avoid duplicate session
  attempts on remounts or rapid server switches.
2026-06-21 02:25:31 -04:00
Juan DenisandClaude Opus 4.8 467ebc51b0 chore(docs): track regenerated UI screenshots
Drop the stray /docs/screenshots ignore that overrode the existing negation (.gitignore:117-118), so the 23 mock-data README screenshots are committed assets again, and add the freshly regenerated set (ServiceDetail header selector updated in the local capture skill).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 02:21:47 -04:00
Juan Denis 9f9d868085 refactor(backend): extract reusable format_bytes, admin_required, and validate_app_name
- Add app/utils/formatting.py with format_bytes() and delegate 9 duplicated
  human-readable byte formatters across services.
- Import admin_required from app.middleware.rbac in 15 API modules instead of
  redefining it locally.
- Extend app/utils/slug.py with validate_app_name() and use it for template
  install/validation and apps slug normalization.
2026-06-21 02:11:47 -04:00
Juan Denis 32e6def0e6 Add ClamAV start action and UI posture fixes
Add a POST /security/clamav/start endpoint and SecurityService.start_clamav() to enable+start the ClamAV daemon (tries clamav-daemon and clamd). Add unit tests that mock ServiceControl to verify success/failure and auth. Wire a startClamAV API call into the frontend and extend the Security Overview: richer posture UI, one-click fixes (install, start service, init integrity, update defs), KPIs, icons, and accessibility improvements. Update related styles and file-manager minor styles. This improves operator workflows by allowing a one-click "Start service" posture fix and provides immediate UI feedback when fixes run.
2026-06-21 01:54:51 -04:00
Juan Denis c4e8235746 style(lint): fix pre-existing ESLint errors across frontend 2026-06-21 01:32:01 -04:00
Juan Denis 58b6b831c1 refactor: migrate remaining tables/forms and clean Terminal inline styles 2026-06-21 01:31:57 -04:00
Juan Denis e9083da189 refactor: migrate pages to shared primitives and add lint guardrails
- Standardize toast usage in AgentFleet and FleetMonitor (toast.success/error/info)
- Replace inline full-page spinners with PageLoader in CloudProvision, DNSZones, DynamicDns, Marketplace, ServerTemplates, StatusPages
- Migrate Servers and Domains tables to DataTable
- Migrate DynamicDns create form to FormField
- Adopt SearchFilterBar in Applications
- Adopt CopyButton in DynamicDns token callout
- Replace raw buttons with Button in Servers, Terminal, Docker
- Move Domains error-banner close button inline styles to SCSS class
- New ErrorState, SearchFilterBar, CopyButton utility components
- Add ESLint rules warning on inline styles, raw <button>, and legacy .card divs
2026-06-21 01:10:35 -04:00
Juan Denis 7f50e741cd feat: add shared primitives and extract reusable overflow logic
- New useOverflowItems hook for tab overflow menus
- Refactor ui/tabs and ds/PageTopbar to share overflow logic
- New PageLoader component for full-page loading states
- New DataTable component with sorting, empty/loading states, custom rows
- New ResourceCard / ResourceList for servers/apps/domains/containers
- New FormField / FormRow wrappers for consistent forms
- New IconButton wrapper for accessible icon-only actions
- Add supporting styles in _design-system.scss and _forms.scss
2026-06-21 01:10:23 -04:00
Juan Denis b96626f96f cleanup: remove orphaned components and unused shadcn primitives
- Delete unused app components: QueryRunner, AuditLogTab, Toast, UptimeGraph, BaseNode
- Delete unused shadcn primitives: accordion, avatar, progress, scroll-area, separator, tooltip
- Normalize AuthContext.jsx line endings to LF
- Remove no-op badgeVariants() shim from ui/badge
2026-06-21 01:10:12 -04:00
Juan DenisandClaude Opus 4.8 1c519a24a2 feat(services): URL-route detail tabs and adopt the shared repo-connect form
Bring the Service detail page to parity with the WordPress detail page:

- Routes: add services/:id/:tab and services/:id/:tab/:section so the active
  tab and the Settings sub-section live in the URL (shareable, survive refresh).
  ServiceDetail drives its tab via useTabParam; SettingsTab reads/writes the
  section via useParams + navigate.
- Repository: the Settings -> Repository section now renders the shared
  RepoConnectForm (the same component the WordPress Git settings use) instead
  of the bespoke GitConnectModal — provider picker (GitHub/GitLab/Bitbucket/
  Gitea) with URL fallback and a connected summary + Disconnect. Existing
  deploy scripts are preserved on connect. The top 'connect a repository' pill
  now navigates to .../settings/repository, and GitConnectModal is removed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 00:42:03 -04:00
Juan DenisandClaude Opus 4.8 429e6ef344 fix(settings): make settings sub-nav items fill the column width
A flex <button> keeps its shrink-to-fit intrinsic width, so each settings
nav item's box was sized to its label (e.g. the active 'Git' box only as wide
as the word) instead of the 200px column. Add width:100% (box-sizing is
border-box) so every item's box is the same full width, text still left-aligned.
Applies to both the WordPress (.wp-settings__navitem) and Service
(.svc-settings__navitem) detail settings.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 00:27:26 -04:00
Juan DenisandClaude Opus 4.8 03504c6517 feat(connections): GitLab/Gitea/Bitbucket repo pickers + path selector
Adds source-connection support for browsing repositories on GitLab, Gitea, and
Bitbucket (new *RepoPicker components) plus a PathSelector, wired through
RepoConnectForm / GitProviders / ConnectionsHub / providerCatalog and the
sourceConnections + files APIs, backed by additions to the source_connections
API and service.

Bundled from in-progress work in a concurrent session at the user's request.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 00:20:10 -04:00
Juan DenisandClaude Opus 4.8 e46c0d685e redesign(services): WordPress-style grouped Settings sub-nav
Restructure the service Settings tab from a flat stack into a grouped left
sub-nav + content pane (.svc-settings grid), mirroring the WordPress detail
page: General -> Environment, Connections -> Repository, Advanced -> Danger
Zone, each with an icon. Section is local state; the existing panels are
unchanged, only reorganized.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 00:19:20 -04:00
Juan DenisandClaude Opus 4.8 6fb0454ac6 fix(services): center the Events tab empty-state icon
The empty-state used text-align:center, but svgs are display:block (Tailwind
preflight) so the clock glyph left-aligned while the text centered. Flex-center
the container so the icon and text share the same axis.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 00:17:30 -04:00
Juan DenisandClaude Opus 4.8 a69d67afcb feat(services): add tab icons and pin Settings to the far right
Give each Service detail tab a lucide glyph (TAB_ICONS) and pin the Settings
tab to the right of the strip via app-detail-tab--end, matching the WordPress
detail tab bar. The strip wraps (flex-wrap + overflow-x:visible) so the
right-pinned Settings tab can never get pushed off-screen.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 00:09:16 -04:00
Juan DenisandClaude Opus 4.8 1079c3b98d redesign(services): migrate Service detail to the sk-topbar layout
Reuse the WordPress detail page's shell so /services/:id matches /wordpress/🆔
a full-bleed PageTopbar (.sk-topbar) with the breadcrumb in the title slot and
the Deploy/Restart/more actions on the right, above a centered .app-detail-body
holding a flat .app-detail-header (ServiceTile + name + status Pill + type
badge + mono subtitle), the repo-connection pill, the versions panel, the
shared .app-detail-tabs underline strip, and .app-detail-content.

Drops the bespoke .svc-detail__{breadcrumb,header,title-row,tabs,content}
chrome in favour of the shared app-detail-* base classes, and runs the page
full-bleed via .main-content:has(.svc-detail).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 00:08:34 -04:00