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>
The plan-39 em-dash purge hand-wrote six baked plugin.json copies without
the trailing newline that sync-builtin-frontends.mjs emits, tripping the
CI drift gate (--check). Regenerated via the script; content unchanged.
Guard suite test_extension_manifests.py: 28 passed.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Introduce serverkit-gpu extension: backend plugin with GPU API and service (nvidia-smi based) providing per-GPU metrics and best-effort container resolution for GPU processes. Files added: backend/app/plugins/serverkit-gpu/{__init__.py,gpu.py,gpu_service.py,plugin.json}. Also update several frontend plugin.json files (including serverkit-gpu) to match manifest formatting (trailing newline adjustments). The GPU service degrades gracefully when nvidia-smi or Docker info is unavailable.
Move serverkit-gpu from CONVERTED_BUILTIN_SLUGS into GATED_BUILTIN_SLUGS behind
a _gpu_present() predicate (shutil.which('nvidia-smi')), mirroring the email
gate: fresh installs stay marketplace-only, upgraded panels without a GPU no
longer get it, upgraded panels with a GPU keep it (D3 continuity). Rewrite the
12 builtin + baked extension descriptions that used em dashes into plain
sentences, keeping every pair in sync. New test_extension_manifests.py walks
both manifest trees to assert no em/en dashes and per-slug description parity.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Three more tab-group conversions on the #43 primitive, completing the
plan''s Phase 1 seed list:
- serverkit-cloud-provision — "Cloud Servers" tab in the Servers group
(order 4 keeps its original strip position)
- serverkit-remote-access — "Remote Access" tab in the Servers group
(order 5), plus the command-palette entry the core page never had;
pages/RemoteAccess.jsx stays core (the server detail page embeds it
with serverId, independent of install state)
- serverkit-status — "Status Pages" tab in the Observability group; the
public /status/:slug route and PublicStatusPage stay core
Backends stay core per D2 (two-speed). All three added to
CONVERTED_BUILTIN_SLUGS so upgraded panels auto-install them once;
fresh installs see them in the Marketplace (10 builtins total).
Full backend suite 1215 passed; lint 0 errors; build clean; builtin
frontend sync --check green.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>