324 Commits
Author SHA1 Message Date
Juan DenisandClaude Opus 5 5b26e427a1 fix(wordpress): create a site from the same drawer as everything else
"Create WordPress Site" was a centred modal while services and templates
deploy from a right-hand drawer, and its own styling was broken: an icon
stranded on its own line, an unspaced list running straight into the
first field, and a footer that floated over the form.

Two causes, both structural. It rendered legacy .modal-body and
.modal-footer *inside* the shared Modal, which already supplies a body
and takes a footer prop — the chrome was nested twice. And its
.install-warning callout is styled under `.wordpress-page`, while the
dialog renders in a portal, so it is not a descendant of the page that
opened it and none of those rules ever applied.

So the drawer styling moves out of _templates.scss into the design system
as .sk-formdrawer, shared by both pages. That is the fix for the class of
bug, not just this instance: a portalled surface cannot rely on
page-scoped SCSS, so its styles belong somewhere unscoped. The block also
now covers bare <select> and checkbox rows, which otherwise render with
the browser's own white chrome on a dark panel, and the callout.

Verified in a browser: drawer settles at the right edge at its declared
560px, callout renders with its background and spacing, selects pick up
the surface colour, and no .modal-body/.modal-footer/.install-warning
remain in the tree.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-25 12:07:06 -04:00
Juan DenisandClaude Opus 5 6508c15ddb docs: screenshot the template card-click deploy drawer
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-25 11:35:05 -04:00
Juan DenisandClaude Opus 5 40cef81b3c docs: capture the loading-skeleton archetypes and refresh shots
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-25 05:41:15 -04:00
Juan DenisandClaude Opus 5 5b1403dfaa feat(ui): shape loading skeletons to the page that is loading
Every one of the ~40 loaders went through EmptyState's single hardcoded
shape — an avatar, three cards, three lines — whether the page was a
table, a console, a form or a chart. A skeleton exists to predict the
layout about to arrive so that arrival is a fill-in rather than a jump;
one shape reused everywhere mispredicts on all but the page it was drawn
for, which is worse than honest, because it promises a layout that never
comes.

PageSkeleton provides ten layout archetypes — panel, table, feed, cards,
detail, console, form, chart, tree, split — driven by SCSS so widths stay
responsive instead of being guessed in pixels. Repeated lines use a
deterministic ragged width, so they read as text and don't reshuffle each
render the way Math.random() would.

EmptyState takes `loadingVariant` (defaulting to the old `panel`, so
nothing regresses) and 41 call sites now name their real shape.
ResourceListPage picks table or cards from its own view state.

All ten are on the style guide under Feedback & Loading, and captured as
one screenshot so a regression in any of them is visible in one shot.

Captured bones (npm run capture:skeletons) remain the pixel-exact option
for individual regions; these archetypes are the broad-coverage answer
for the pages that will never be worth capturing one by one.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-25 04:46:16 -04:00
Juan DenisandClaude Opus 5 1254dda17f docs: refresh Services-group screenshots + changelog
Recaptured against the ported design, plus new shots for the templates
catalog, its filter and deploy drawers, and the Services card view.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-25 04:40:35 -04:00
Juan DenisandClaude Fable 5 f2cf89563a fix(deployments): full-width jobs table + console polish (plan 51.5 UI pass)
/deployments still reserved a second grid column for the detail pane plan 51
removed — the table sat at half width with its Started column clipped by
overflow:hidden. Single full-width panel now; pruned ~150 lines of dead
detail-pane SCSS; status badge + progress colors move from inline styles to
modifier classes; kinds humanized; skeleton loading rows; removed the topbar
New Service button duplicating the adjacent tab. Console: fills the viewport
(calc-based min-height), wider step rail (248px), flexible log search, denser
toolbar. Adds deploy-console screenshots (4 sections, mock-data captures).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 17:11:55 -04:00
Juan DenisandClaude Fable 5 31d13c6370 docs: theme screenshots live only in the serverkit-themes registry
Drop docs/screenshots/themes/ from the panel repo; THEMING.md and the
README roadmap now link to the registry's gallery instead.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 12:16:40 -04:00
Juan DenisandClaude Fable 5 24ee204294 docs(themes): add live screenshots of all 19 themes + gallery page
One dashboard capture per theme (mock-data rig, capture-themes.mjs) under
docs/screenshots/themes/ with a grouped gallery README, linked from
THEMING.md.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 10:42:14 -04:00
Juan Denis 8180ff4474 docs(mcp): recommend Faro Agent Bridge + faro-cli as primary server access 2026-07-23 08:55:57 -04:00
Juan DenisandClaude Opus 4.8 e09a6c2948 feat(themes): registry browse, import, panel default, and Theme Studio (plan 60 Phase 2-4)
- ThemeContext: fetch pre-auth panel default (/public/active) and follow it
  until a user picks a skin; ThemeSync bridge loads installed themes after auth
- Theme Gallery admin actions: set panel default, remove installed themes
- Browse modal: install community themes from the registry (offline-tolerant)
- Import theme.json (admin, paste/upload)
- Theme Studio: grouped color editor over the LIVE panel, start-from any
  installed theme, Export theme.json, Save-to-panel, and Submit = a prefilled
  GitHub new-file PR against serverkit-themes
- docs/THEMING.md (token reference + rules + submit flow); README docs table +
  ROADMAP "Recently Completed"

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-23 00:24:10 -04:00
Juan Denis e8d84297f2 Marketplace trust: split 409 reasons, hide unreviewed outside dev mode
Review feedback + follow-up on the review-stamps feature:

- The 409 trust gate now distinguishes reason 'unreviewed' (community
  code not vetted) from 'unverified' (no pinned checksum, possible even
  for first_party), each with an accurate message; the risk dialog
  carries the reason and matches its title/body to the actual case
  instead of always claiming 'unreviewed community extension'
- Unreviewed registry entries are now developer-stage content: hidden
  from the Marketplace catalog and refused at the install endpoint
  (404) unless the panel runs in a development context (Flask debug /
  testing config, or the dev_mode setting). Hidden means not
  installable; the 409 acknowledgment flow only exists where they list
- dev_mode setting description mentions the Marketplace effect
- tests: reason assertions on both 409 cases; catalog visibility and
  404-on-hidden-install coverage (38 passing)
2026-07-22 23:18:33 -04:00
Juan Denis 02bb7666e2 Marketplace: hash-bound review stamps and trust levels for registry extensions
The registry index (schema v3) can now carry a review object per entry
(reviewer, date, sha256, optional commit/notes) asserting that someone
inspected the exact artifact being listed. The stamp is bound to the
artifact hash: review.sha256 must equal the entry sha256, so any change
to the released zip invalidates the review.

- registry_service: keep review through normalization (validated),
  derive trust per entry: first_party, reviewed (stamp matches the
  pinned hash), or unreviewed
- marketplace install route: unreviewed (or sha256-less) entries return
  409 requires_acknowledgment unless the admin posts
  acknowledge_risk: true; acknowledged installs record trust in the
  audit log. Consent gate, consistent with ADR 0002
- Marketplace UI: Reviewed badge (reviewer + date tooltip) and
  Unreviewed warning badge on registry cards, plus a risk confirmation
  modal that retries the install with acknowledge_risk
- tests: trust derivation and the install gate (409 + acknowledge path)
- docs: EXTENSIONS_REGISTRY.md documents the field and the flow
2026-07-22 22:45:57 -04:00
Juan DenisandClaude Opus 4.8 fb19778e7f docs(wordpress): correct extraction audit — frontend not yet extracted
The audit overstated the WP frontend as contributed by the extension; in the
tree the extension index.jsx is still a re-export shell over core pages/
components/SCSS. Corrected to match reality before plan 52 Phase 4 moves it.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-22 17:31:29 -04:00
Juan DenisandClaude Opus 4.8 ffc1fd7728 feat(extensions): deliver runtime ESM frontends to production panels (#39)
Wire the server half of runtime-frontend delivery: get_active_contributions()
now emits panel sdk_version and a 'frontends' descriptor map {slug: {entry,
hashes, sdk_version}} for every active extension whose frontend_entry is a .mjs
ESM bundle. The bundle sha256 is pinned at install time into the plugin config
under the reserved _frontend_hashes key (no migration — reuses config_json);
update_plugin_config() and the config API preserve/hide reserved keys. Add the
extensions.runtime_frontend kill switch (default on). The client loader already
consumed this shape, so an installed extension's UI now renders on a pre-built
panel with no Vite rebuild. Un-skips the restored plan-25 recovery suites.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-22 17:24:36 -04:00
Juan DenisandClaude Opus 4.8 6bf8c87b9d docs(deploy): document the Deploy Console; update CHANGELOG and ROADMAP
Add docs/DEPLOY_CONSOLE.md (the feature + architecture), an architecture section
in docs/ARCHITECTURE.md, a CHANGELOG (Unreleased) entry, and move the Deploy
Console into the ROADMAP's Recently Completed list with its Active Development
checkboxes ticked.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-22 16:43:50 -04:00
Juan Denis d80518966b Add Trendshift badge to all README variants
Adds the Trendshift repository badge to the main README and the Spanish, Portuguese, and Simplified Chinese README files so project visibility/trend metrics are shown consistently across all language entry points.
2026-07-22 09:08:26 -04:00
Juan Denis baebb92d3a feat(registry): default to serverkit.ai index and ship logo fields
Flip DEFAULT_REGISTRY_URL to https://serverkit.ai/ext/index.json (the
long-planned go-live default: cached proxy of the raw index with logo URL
rewriting). Add logo fields to the bundled offline index so Marketplace
cards get real art even before the first successful fetch, and update the
registry tests + docs for the new default.
2026-07-20 23:46:02 -04:00
Juan Denis b4ff7a07d5 Update login and WordPress screenshots
Refresh the documentation screenshots for the login and WordPress screens to reflect the current UI.
2026-07-20 01:29:14 -04:00
Juan DenisandClaude Opus 4.8 f8ff93a4bd docs(readme): accept crypto donations
Adds USDT (TRC-20 and ERC-20), BTC and SOL to the Support section of all four
READMEs, with the network in its own column — USDT exists on several chains
whose addresses look alike, and the network is what tells a donor which one to
send on.

QR codes come from scripts/generate-funding-qr.mjs rather than a web generator,
since an online tool sits in a position to encode a different address than the
one entered and the resulting image looks perfectly normal. The script holds the
addresses as the single source of truth and checksum-validates each before
encoding — base58check for Tron, EIP-55 casing for Ethereum, bech32 for Bitcoin,
32-byte base58 for Solana — refusing to emit anything if one fails. Every code
was decoded back and diffed against its source string. `--check` re-verifies the
committed PNGs so an address edit with a stale QR cannot pass unnoticed.

These are self-custody wallets rather than exchange deposit addresses, which can
be rotated out from under a published README and turn third-party donations into
an AML review on the receiving account.

Adds CODEOWNERS over the READMEs, the QR script, the funding images,
FUNDING.yml, LICENSE and SECURITY.md. Swapping a donation address through an
innocuous-looking docs PR is a known attack on open-source projects; this
requests maintainer review on every path that carries one. It takes effect once
"Require review from Code Owners" is on in branch protection.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-20 01:19:54 -04:00
Juan DenisandClaude Opus 4.8 4f08ae47a9 fix(docs): commit the architecture diagrams that .gitignore swallowed
A blanket `*.png` rule meant the eight diagrams added alongside the
ARCHITECTURE.md rewrite were silently skipped — `git add` reported nothing and
the doc landed referencing images that were not in the repo. Every diagram
rendered as a broken image on GitHub.

Force-includes docs/images/ the same way docs/screenshots/ and the extension
cover icons already are, covering both the architecture diagrams and the
funding QR codes that follow.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-20 01:19:30 -04:00
Juan DenisandClaude Opus 4.8 a83dbd3e37 docs(readme): refresh the English README and rebuild all three translations
English: drops the retired Workflow Builder — its screenshot showed a sidebar
entry and canvas that no longer exist — promoting Agent Fleet into that grid
slot, and renames the feature card to Automations with the managed-container
model it actually uses. Template counts go 60+ to 100+, the architecture section
leads with a diagram over an ASCII-only block, and the Tech Stack no longer
claims GeventWebSocket workers. Two links to agent/README.md are repointed at
the serverkit-agent repo; that directory left this tree when the agent was
extracted, so both were 404s.

The translations had drifted a full generation behind. All three pointed their
Screenshots sections at ad-hoc user-attachments URLs instead of the repo's own
files, and their roadmaps still listed Backups, Mail, RBAC and Marketplace as
unshipped. Each is now a faithful mirror of the English: identical section order
and count, 121 table rows, 41 images, both collapsible folds, and nav anchors
that resolve under GitHub's slugger with accents and CJK preserved. The ASCII
architecture diagram is byte-identical across all four — deliberately untouched
in the Chinese file, where double-width characters would break the box drawing.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-20 01:17:53 -04:00
Juan DenisandClaude Opus 4.8 c6271da13e docs(architecture): rewrite against the current code, add diagrams
The document described a system that partly no longer exists. Removed: the
Workflow Automation section built on a `WorkflowService` that is not in the tree
(Automations replaced it and runs in a managed container), and the claim that
DB credentials are injected as DB_HOST/DB_USER — there is no generic injector,
names are template-authored and the real mechanism is fromSecret/fromService
reference resolution.

Corrected: backups live at /var/backups/serverkit not under /var/serverkit,
/var/serverkit/ssl does not exist, the panel has no config.yaml (only the agent
does), templates merge two directories with backend/templates/ as the source of
truth, and 8000 is the fallback port rather than the start — managed_app_base_port
and the per-template default both take precedence.

Added the three subsystems that were missing entirely — the extension platform,
jobs and scheduling, and the notifications bus — plus a backend layer map and an
agent fleet section absorbing the single-worker constraint.

Every diagram now leads with an image and keeps its ASCII fallback in a
collapsible fold, so the doc still reads as plain text.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-20 01:17:06 -04:00
Juan DenisandClaude Opus 4.8 d595ea14ff fix(docs): remove the broken gunicorn worker class from the install guide
The manual-install systemd unit told operators to run
`--worker-class geventwebsocket.gunicorn.workers.GeventWebSocketWorker`. The app
runs `async_mode='threading'`, where engineio serves WebSocket through
simple-websocket; the gevent-websocket worker also answers the upgrade, so the
handshake is answered twice and the browser reports "Invalid frame header".
Anyone following this guide built a panel with broken live metrics, logs and
terminal.

Now matches what the project actually ships in
templates/serverkit-backend.service.in — `--workers 1 --threads 100`, no worker
class — with a note on why to scale threads rather than workers, since the agent
gateway keeps its registry in one process.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-20 01:16:52 -04:00
Juan DenisandClaude Opus 4.8 9639288494 refactor(extensions): extract seven builtins to standalone repos
Analytics, CrowdSec, DNS Server, GPU Monitor, Kubernetes, Mail Server and
Automations (tramo) now live in their own repositories and install from the
registry as versioned, sha256-pinned zips. Their sources leave
builtin-extensions/, their pre-bundled frontends leave frontend/src/plugins/,
and registry_index.json gains a `bundled: false` entry for each so the
Marketplace offers them as normal registry installs.

The panel keeps only the wiring: comments at the former mount points explain
where each surface now comes from, and the gpu auto-install gate in
extension_migration.py is dropped since a host-probe can no longer decide to
re-vendor an extension that is not in this tree.

Also untracks backend/app/plugins/serverkit-{gpu,k8s,tramo}/, which were the
panel's own install artifacts rather than source. Committing those shipped a
second copy of code that now lives in three other repos, guaranteed to drift.
.gitignore now excludes the install path for every extracted slug on both the
backend and frontend side, so a local install can never be committed back.

Four tests from test_tramo_extension.py exercise panel core rather than the
extension (the retired /api/v1/workflows blueprint, the plan-45 event emitters
ported to EventService, and the docker_service double-emit fix); they move to
test_tramo_panel_core.py and stay here. The rest of the extension suites go
with their repos.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-20 01:16:16 -04:00
Juan DenisandClaude Opus 4.8 bb899522fe docs(analytics): user guide + marketplace recommendations (Phase 7)
- docs/ANALYTICS.md: privacy model, the two data sources, dashboard tour,
  snippet + WordPress mu-plugin + nginx sub_filter install paths, config table,
  geolocation, scale/PostgreSQL guidance, collector protections, and the
  single-worker note. Clarifies the panel-extension vs WP-plugin naming and that
  the Umami/Plausible/PostHog templates remain available.
- Recommend serverkit-analytics for the wordpress + web-apps setup-wizard use
  cases (RECOMMENDED_EXTENSIONS_BY_USE_CASE). Onboarding guard test green.
- CHANGELOG (Unreleased): Web Analytics feature entry.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-18 02:58:11 -04:00
Juan DenisandClaude Opus 4.8 176141295f docs(plan47): sync extension manifests, raise ratchet, changelog + docs
Plan 47 Phase 6 (for shipped work). Sync the pre-bundled frontend plugin.json
copies for the four extracted builtins (entry_point/url_prefix + status
description) so builtin-extensions/ and frontend/src/plugins/ agree
(sync-builtin-frontends --check + test_extension_manifests green). Raise the
test-count ratchet 2588 -> 2623. Document the second-speed backend-extraction
recipe in EXTENSIONS.md, add CHANGELOG entries (wizard installs + opt-in
FTP/cloud/remote-access/status), and a README "lean by default" bullet.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-14 23:05:06 -04:00
Juan DenisandClaude Opus 4.8 89af823b39 docs: use new poster as README banner and update tagline
Replace the logo image at the top of the English and translated READMEs with the new docs/screenshots/poster.png banner, and change the tagline to "Deploy, manage, and monitor servers." (translated per language).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-12 06:14:37 -04:00
Juan DenisandClaude Fable 5 284bc02dc1 feat(manifest): dockerfilePath — build services from a repo Dockerfile
A v1 manifest service gains a third image source next to buildpacks and
BYO image: — `dockerfilePath: services/api/Dockerfile`. This is the
monorepo path: one repository, several services, each built from its own
Dockerfile with the repo root as the shared build context.

- spec: new service key (camel + snake alias), validated relative-only
  (no `..`/absolute), mutually exclusive with `image` and `containers`,
  rejected on db services; schema docs copy kept in sync.
- resolve/plan: the path rides the create_app payload (with autoDeploy)
  and shows in the step description; a changed path plans as an app
  update; drift_pair tracks it against the stored build config.
- apply: create clones the project's repository into the managed apps
  dir (idempotent — an existing checkout is reused) and writes the same
  git-deployment + build config the import wizard does, so the existing
  deploy pipeline (push webhook, per-service autoDeploy) takes over
  unchanged. Source resolves from the stored manifest's provenance, else
  a sibling app's git deployment; neither is a plan-time blocker
  (dockerfile_no_source). Remote targets refuse like the other appliance
  features ('a Dockerfile build' joins _service_features).
- scaffold: a dockerfile-built app round-trips its build config instead
  of leaking the built image as a BYO `image:` declaration.
- import wizard: a v1 manifest with dockerfilePath seeds
  build_method=dockerfile + the path.

Tests: 10 new (spec exclusivity/traversal + plan/apply/blocker wiring);
manifest suite 96/96, full backend suite green except 3 pre-existing
test_server_time_timezone failures also present on a clean tree.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-10 01:13:14 -04:00
Juan DenisandClaude Opus 4.8 0b21ef93f5 feat(manifest): network identity — fromServer, SERVER_PUBLIC_IP, shared net (plan 35 ph5)
Add a fromServer env binder ({property: publicIp|hostname}) resolved against the
target server or panel host, with a fromserver_no_ip plan-time blocker. Add the
${SERVER_PUBLIC_IP} template magic variable. Attach manifest-generated app
projects to a shared external `serverkit` docker network (DockerService.
ensure_network + networks param on create_docker_app/buildpack generate_compose)
so a fromService host reference resolves cross-app by container name at runtime.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-09 03:28:08 -04:00
Juan DenisandClaude Opus 4.8 619b2215da feat(manifest): BYO image + host requirements (plan 35 ph4)
Add first-class `image:`/`registry:` (apply stamps Application.docker_image +
registry_id, resolved by registry name; registry_credential blocker on
unknown/uncredentialed registries, ECR accepted) and `hostRequirements`
(privileged/capAdd/sysctls/devices/kernelModules). create_docker_app emits the
host-requirement fields; every requirement is listed in plain words as a plan
issue and audited via manifest.host_requirements on apply. kernelModules get an
advisory /proc/modules check that warns but never silently passes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-09 03:21:14 -04:00
Juan DenisandClaude Opus 4.8 fdc3d45749 feat(manifest): multi-container units (plan 35 ph3)
Add a `containers:` map that turns one service into one Application rendered as
one compose project. Normalizer validates mutual-exclusion with buildpack keys,
dependsOn references, and rejects cycles (DFS). New UnitComposeService renders
container_name prefixing, healthcheck blocks (cmd->CMD-SHELL, httpPath->wget),
depends_on.condition mapping, raw port publishes, and per-container synthetic
named volumes. resolve_service flattens container ports/bootstraps/host-reqs/env
to the unit (unified `bootstraps` list under one bootstrap_done flag); unit disk
backups route at the docker-volume name. Seams: unit_compose/unit_container_names.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-09 03:13:54 -04:00
Juan DenisandClaude Opus 4.8 be3a9f9bcd feat(manifest): finish appliance volumes + one-shot bootstrap (plan 35 ph2)
Persist manifest disk `size` onto AppVolume.declared_size; route disk backups to
the docker volume's live host mountpoint (VolumeService.host_path_for_mount +
volume_mount meta in BackupPolicyService._resolve_target). Add `bootstrap`
schema + BootstrapService.run_once (docker compose run --rm, injectable runner
seam), a bootstrap apply step that stamps applications.bootstrap_done once, and
POST /manifests/bootstrap/reset to re-arm it. Scaffold round-trips disk size.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-09 03:05:08 -04:00
Juan DenisandClaude Opus 4.8 06c3fcf28c feat(manifest): appliance-tier typed L4 ports + plan-time blockers rail (plan 35 ph1)
Rebuild of plan 35 Phase 1 against the surviving migrations (ports as a JSON
column on applications, not a separate table). Adds typed `ports[]` to the
serverkit.yaml schema/normalizer, AppPortService (persist/compose-emit/firewall),
open_port apply step + firewall open on apply / close on app delete, and the
blockers engine (port_conflict/remote_target/observed_server/firewall_undetected)
that refuses apply instead of half-deploying.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-09 02:57:23 -04:00
Juan DenisandClaude Opus 4.8 9062f1d47a docs(extensions): document the installable-straight-from-GitHub contract
EXTENSIONS.md gains an 'Installable straight from GitHub' section: plugin.json
at archive root, release .zip preferred over zipball fallback, accepted URL
forms incl. owner/repo[@tag], and how the preview/consent flow presents your
declared permissions (checksum-pinned install). Keeps the GitHub docs and the
serverkit.ai Installing page telling the same story.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-09 02:05:32 -04:00
Juan DenisandClaude Opus 4.8 dc628aabba docs(manifest): point serverkit.yaml $schema at serverkit.ai
Single home for the schema on the product domain (serverkit.dev -> serverkit.ai
in SERVERKIT_YAML.md examples and the schema $id), matching the new
serverkit.ai/serverkit-yaml.schema.json endpoint. Also documents the deferred
registry-URL flip (plan 40 task 11): DEFAULT_REGISTRY_URL stays raw-GitHub
until the serverkit.ai /ext endpoints are deployed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-09 01:57:11 -04:00
Juan DenisandClaude Opus 4.8 bd6b8eff33 feat(plugins): GitHub-native install with preview + permissions consent
Add POST /api/v1/plugins/preview: resolve a GitHub/zip source, download,
read plugin.json, and return slug/version/permissions/panel-gate + the
resolved URL, sha256, and warnings — without installing. The manual-install
URL flow becomes two-step (Resolve -> consent card -> Install), pinning the
install to the previewed sha256 so installed bytes match previewed bytes.

- owner/repo and owner/repo@tag shorthand normalization (install accepts it too).
- Actionable resolve errors: rate limit (with reset ETA), 404/private, no
  plugin.json at archive root.
- Optional SERVERKIT_GITHUB_TOKEN: Bearer auth on GitHub hosts only (never
  leaked to third-party mirrors, never logged); lifts the anon rate limit and
  enables private-repo installs.
- ManualInstallModal: PreviewConsent card with permission chips + warnings +
  'GitHub · unverified' badge; SCSS added.

Tests (test_plugin_preview.py, 15): shorthand, happy/warning preview paths,
token header injection + host scoping, preview->install checksum continuity +
tamper rejection. Full plugin suites green; frontend lint 0 errors, build clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-09 01:52:38 -04:00
Juan DenisandClaude Opus 4.8 c7b12b3095 feat(marketplace): surface registry v2 logo/repo/bundled fields
Stop stripping the v2 fields in registry_service normalization: add repo,
logo, bundled to _FIELDS. Repo-relative logos (assets/<slug>/<file>) are
resolved to absolute URLs against the index URL they came from, so one
relative path works for both the raw-GitHub index and the serverkit.ai
/ext endpoint. Bundled entries are excluded from the Browse catalog by
default (they duplicate builtin cards) and reachable via
?include_bundled=true. Detail modal gains a Source repo link.

Tests: v2 normalization, relative-logo resolution, v1 unaffected, bundled
exclusion + include_bundled endpoint flag. Full test_registry.py green (19).
Docs: EXTENSIONS_REGISTRY.md documents schema_version 2 + v2 fields.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-09 01:43:34 -04:00
Juan Denis d8bfb5cf41 docs: recovery record + recovered original commit messages 2026-07-07 20:32:54 -04:00
Juan Denis 6e32519f7e restore: remaining reconstructed July 5-7 changes (clean recovered files not attributable to one plan) 2026-07-07 20:29:31 -04:00
Juan Denis 28129e7848 feat(cloudflare): round 2 — DNSSEC, Origin CA, rules, R2 preset (plan 36) 2026-07-07 20:29:31 -04:00
Juan Denis 59e92c64a6 feat(manifest): appliance tier — ports/volumes/multi-container units (plan 35) 2026-07-07 20:29:30 -04:00
Juan Denis 45942339eb feat(notifications): polish — digests, prefs, deep-links (plans 24/33) 2026-07-07 20:29:29 -04:00
Juan Denis c96a476a74 feat(extensions): runtime-frontend hardening + GPU core-slim (plan 32) 2026-07-07 20:29:28 -04:00
Juan Denis a882d35db9 feat(adoption): DNS cutover+verify, snapshots, SSH import (plan 31) 2026-07-07 20:29:26 -04:00
Juan Denis 7d045f32af feat(backup): trust round 2 — restore drills, offsite/verify (plan 30) 2026-07-07 20:29:25 -04:00
Juan Denis 44892d3314 feat(agent): V2 capability pack — survey/doctor/fleet sweep+repair (plan 28) 2026-07-07 20:29:24 -04:00
Juan Denis 782ea70c8b feat(workspace): scoping audit + per-scope matrix (plan 19) 2026-07-07 20:29:22 -04:00
Juan DenisandClaude Opus 4.8 8c5ede0cfd feat(manifest): v1 serverkit.yaml spec, normalizer, scaffold (Phase 0)
Add the declarative serverkit.yaml v1 spec: JSON Schema + reference doc, a pure
parse/validate/normalize service, version:1 recognition in the repo manifest
detector (legacy flat files unchanged), and a scaffold endpoint that renders a
manifest from a live app.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-04 01:11:50 -04:00
Juan Denis fe9e924626 polish(marketplace): extension copy sweep, publisher filter chips, docs + screenshot 2026-07-03 04:20:53 -04:00
Juan DenisandClaude Fable 5 af777a87b3 feat(marketplace): default the registry to the public serverkit-extensions index
SERVERKIT_REGISTRY_URL unset now resolves to the curated raw index at
jhd3197/serverkit-extensions (the go-live step for the registry infra);
set-but-empty explicitly disables remote fetching (air-gapped panels,
and how the test suite stays offline — pinned in conftest). URL is
resolved per fetch so env changes apply without a restart. Cache ->
bundled fallback chain unchanged; the Marketplace never blanks.

3 proving tests (default, empty-disables, override); registry/plugin
selection 76 passed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 03:57:23 -04:00