2496 Commits
Author SHA1 Message Date
Juan Denis d780d37515 Merge pull request #152 from jhd3197/dev
Complete the Traditional Chinese translation
v1.11.11
2026-09-27 16:16:47 -04:00
github-actions[bot] ed5ab63aa2 chore: bump version to 1.11.11 [skip ci] 2026-09-27 18:11:30 +00:00
Juan Denis 6000d5c849 Merge pull request #151 from PeterDaveHelloKitchen/zh-Hant
Update and improve Traditional Chinese locale
2026-09-27 14:08:38 -04:00
Peter Dave Hello ad97c9f658 Update and improve Traditional Chinese locale 2026-09-27 22:49:18 +08:00
Juan Denis d15f79746f Merge pull request #149 from jhd3197/dev
Ubuntu 26.04 installs, a setup code for the first admin, and working Git deploys
v1.11.10
2026-09-24 01:45:46 -04:00
github-actions[bot] 1e9a96deb6 chore: bump version to 1.11.10 [skip ci] 2026-09-24 05:28:49 +00:00
Juan Denis d692e998b5 Fix CI: test seeds and leaked SQLite FK mode
The new Git deploy tests built Application rows by hand, which the
seed ratchet forbids; they use make_application now. A test that
enables foreign keys could leave a pooled connection enforcing them,
failing unrelated tests depending on shard order; every checkout now
starts with enforcement off.
2026-09-24 01:20:45 -04:00
Juan Denis 45bc3c70bd Guard first admin with a setup code, fix Git deploys
A fresh panel no longer lets whoever reaches it first become admin:
registering the first account needs a one-time code the installer
prints (`serverkit setup-code` repeats it). SERVERKIT_ADMIN_EMAIL and
SERVERKIT_ADMIN_PASSWORD create the admin unattended instead.

Git apps now deploy what users expect: a repository with a compose
file deploys every service it declares, "Deploy latest" builds the
branch's newest commit, and push webhooks rebuild the containers.
Also fixes branch switching on single-branch clones, uploads of a
lone file, compose v1 port preflight, and CLI commands that ignored
their flags.
2026-09-24 00:50:02 -04:00
github-actions[bot] 230d0d8b1a chore: bump version to 1.11.9 [skip ci] 2026-09-24 00:33:42 +00:00
Juan Denis 8affffef63 Let dev.sh use another database
SERVERKIT_DEV_DATABASE_URL points the dev panel at, e.g., a throwaway
sqlite file, so it starts in first-run setup like a fresh install
without touching the usual dev database. The release lab's local
browser journey relies on it.
2026-09-23 20:23:33 -04:00
Juan Denis 606aa41081 Point postgres templates at the published icon
postgresql.svg was never in the registry's icons/, so serverkit.ai
answered 404 and the catalog fell back to a built-in icon. The logo
the registry publishes is postgres.svg.
2026-09-23 20:23:33 -04:00
Juan Denis a22eaa8f14 Merge branch 'main' into dev 2026-09-20 23:51:08 -04:00
github-actions[bot] 156e0beee5 chore: bump version to 1.11.8 [skip ci] 2026-09-21 03:42:42 +00:00
Juan Denis 5ffc7257a3 fix(installer): require build tools only for local venv builds 2026-09-20 23:02:09 -04:00
Juan Denis b63427e2a2 fix(installer): provision native Python build dependencies (#148) 2026-09-20 22:29:53 -04:00
Juan Denis 824e2d79df Merge pull request #146 from jhd3197/dev
Passive runtime baselines for full installs
v1.11.7
2026-09-19 05:27:49 -04:00
Juan Denis e4275feed4 Merge remote-tracking branch 'origin/dev' into dev 2026-09-19 05:17:56 -04:00
Juan Denis e6abcf3603 Merge remote-tracking branch 'origin/main' into dev 2026-09-19 05:17:22 -04:00
github-actions[bot] a3b6e4d647 chore: bump version to 1.11.7 [skip ci] 2026-09-19 09:16:34 +00:00
Juan Denis 04eecd5eb3 docs(api): regenerate API_SURFACE.md for the managed-profile route
The connect managed presentation profile (d866de54) added
GET /connect/managed-profile without regenerating the committed
inventory, failing test_committed_surface_matches_served_surface.
2026-09-19 05:09:53 -04:00
Juan Denis b18015b6fc Merge branch 'feature/test-runtime-baseline' into dev 2026-09-19 04:57:34 -04:00
Juan Denis ff3c928917 feat(test): passive cgroup-v2 runtime baselines for full installs
Full VM installs and Test Sandbox full mode now record a short
post-install runtime observation (60s settle + 120s sampling) with an
explicit measured/unavailable/failed/interrupted status that never
rewrites install success. Adds the standalone scripts/measure-runtime.py
sampler, the measure-installed-runtime.py harness wrapper, E2E report
rendering, results-API summaries, CI coverage and METRICS.md accounting
boundaries.
2026-09-19 04:52:24 -04:00
github-actions[bot] 46b85b2def chore: bump version to 1.11.6 [skip ci] 2026-09-18 13:28:56 +00:00
Juan Denis 41c079a874 docs(readme): add Vela to Related Projects in the translated READMEs 2026-09-18 01:52:07 -04:00
Juan Denis b548e8a5f3 docs(readme): add Vela to Related Projects 2026-09-18 01:50:20 -04:00
Juan Denis 0aea7e3787 fix(plugins): hot-load extension blueprints on a live app (#144)
Flask refuses register_blueprint once the app has handled its first
request, so on any running panel — where login and dashboard requests
long precede the first extension install — the hot-load in
_register_plugin_blueprint always raised, the installer only logged a
'will load on restart' warning, and the extension's routes stayed
missing. Its pages rendered (frontend is static) while every API call
failed: GETs were swallowed by the tabs' console.error handlers, and the
first POST fell through to the static-file route, surfacing as the 405
reported for the Malware Scanner custom-path scan.

_register_blueprint_live waives Flask's setup guard for the duration of
the registration call. That is safe in this deployment shape: the panel
runs a single gunicorn worker with threads, so the process installing
the plugin is the process serving its routes, and werkzeug rebuilds its
URL matcher lazily on the next bind while in-flight requests keep the
matcher they already bound.
2026-09-18 01:28:59 -04:00
Juan Denis 8837a26af0 fix(logs): keep panel-internal roots out of the log viewer
PR #145 closed the prefix-sibling hole in LogService.is_path_allowed but
left the gap its author named: unlike FileService, the log viewer had no
PROTECTED_ROOTS exclusion. On the install.sh layout the install dir sits
under the allowed root /opt, so the Log Files tab could read — and,
through clear_log, truncate — the backend .env, the SQLite instance dir
and the generated deploy config, the same hole the file manager closed
for GHSA-rm3m-9mvw-68fh.

Share FileService.PROTECTED_ROOTS rather than copying the list, so the
two surfaces cannot drift apart, and reject protected paths before the
allowed-root check. Panel logs live under /var/log and SERVERKIT_DIR,
which are untouched, so legitimate viewing is unaffected.
2026-09-18 01:05:13 -04:00
Juan Denis 8859922b8a Merge pull request #145 from MaxFreedomPollard/fix/log-path-segment-containment
fix(logs): compare whole segments in path guard
2026-09-18 00:59:02 -04:00
Max Freedom Pollard 50d64e9d72 fix(logs): compare whole segments in path guard
LogService.is_path_allowed resolved the requested path with realpath and
then asked whether the result merely started with one of
ALLOWED_LOG_DIRECTORIES. That is a text comparison rather than a
containment test, so a directory whose name only begins with an allowed
root was accepted as if it sat inside it. With the roots shipped at
backend/app/services/log_service.py:30-36, both /opt-private and
/homestead pass on the strength of /opt and /home, which is not what the
comment above the list at line 29 says the list does.

FileService guards the same roots and gets this right at
backend/app/services/file_service.py:96-100, comparing real_path == root
or real_path.startswith(root + os.sep). The same form appears at
backend/app/api/deploy.py:197, backend/app/services/upload_service.py:66
and backend/app/services/linked_panel_agent.py:251. LogService does not,
and its guard also gates truncation through clear_log at
backend/app/services/log_service.py:367.

The loop now compares against the separator-terminated root, so a
sibling sharing a name prefix is rejected while everything genuinely
inside a root still resolves, including paths reached through .. because
realpath has already collapsed them. A regression test covering the
shipped /opt constant, a sandboxed root and the clear_log door ships
with it.
2026-09-15 19:39:37 -04:00
Juan Denis d866de5439 feat(connect): apply the managed presentation profile (plan 25)
Panel side of the managed profile: the panel receives a presentation
profile from Cloud over the existing command channel, stores it,
acknowledges it, and hides or simplifies fleet-owner-only surfaces
until the profile is lifted or the link is revoked.

- ui.managed_profile command handler with managed-profile.json
  storage, audit entries, and ack-by-output; profile is cleared on
  disconnect and on consent revoke
- GET /api/v1/connect/managed-profile for the local UI
- ManagedProfileContext with capability-driven filtering of sidebar
  items, command palette actions, and sidebar settings; ManagedCard
  explains the managed state
- In-page collapses for Templates deploy, About self-update, and
  Backup schedules/storage (restore stays available)
- Settings gains a ServerKit Cloud tab showing link and profile state

Local verification: 153 backend tests pass, 198 frontend node tests
pass, lint clean, build ok. No live policy has been pushed to a real
panel yet.
2026-09-13 03:50:02 -04:00
github-actions[bot] f4c641032a chore: bump version to 1.11.5 [skip ci] 2026-09-13 03:26:48 +00:00
Juan DenisandClaude Fable 5.1 9e320586f3 test(templates): certify an external registry tree, and bring the changelog up to 1.11.4
The catalog certification test now reads SERVERKIT_TEMPLATES_DIR and
SERVERKIT_TEMPLATES_INDEX, so the official template registry's CI can
run the installer's own rules against its tree before a merge publishes
it to every panel. The build_repo_index() check stays bundled-only and
skips under the override.

The changelog had stopped at "1.11.1 - Unreleased" while 1.11.2 through
1.11.4 shipped: the Connect revocation, JWKS refetch, metrics-warning and
sidebar fixes are now recorded under the published 1.11.4 release.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JtgcyJ75YEozymcrWDyedu
2026-09-12 22:51:54 -04:00
Juan Denis 1a6ee54890 Merge pull request #143 from jhd3197/dev
Publish inventory, diagnostics and bounded logs to Cloud
v1.11.4
2026-09-12 19:31:33 -04:00
github-actions[bot] 5e94e3d544 chore: bump version to 1.11.4 [skip ci] 2026-09-12 19:31:12 +00:00
Juan Denis 9d12bf6417 Merge branch 'dev' of https://github.com/jhd3197/ServerKit into dev 2026-09-12 15:11:08 -04:00
Juan Denis 386cd6aa3a fix(connect): stop the client loop when poll mode learns of revocation
_poll_session reports 'revoked' when ServerKit Cloud refuses the poll
with the revoked reason, but the loop only honored 'stopped' and fell
through to re-probe the websocket: ws refused, poll revoked, ws
refused — forever, and the panel never wrote the revoked state. This
is the path a panel behind a close-code-stripping edge depends on, old
builds unconditionally and current ones whenever they are in limited
mode. The poll outcome now gets the same terminal handling as the
websocket one.
2026-09-12 15:09:28 -04:00
Juan Denis 60f8bd8c60 fix(connect): learn revocation from the relay's close-reason frame
The production edge strips non-standard WebSocket close codes, so the
relay's 4009 never reached the panel: a revoked panel kept reconnecting
forever instead of stopping. ServerKit Cloud's relay now sends the
reason as a text frame before closing, and the panel honors it both
during the hello exchange and mid-session, ending the session as
revoked either way. The numeric code still serves direct connections,
and the long-poll fallback's HTTP refusal is unchanged.
2026-09-12 06:31:50 -04:00
github-actions[bot] 6ef6d27e9a chore: bump version to 1.11.3 [skip ci] 2026-09-12 08:46:48 +00:00
Juan Denis 58880b4033 Merge branch 'dev' of https://github.com/jhd3197/ServerKit into dev 2026-09-12 04:39:20 -04:00
Juan Denis fda418d5fa fix(connect): refetch the JWKS when a command arrives signed with an unknown key
ServerKit Cloud mints each signing key the first time it is used and
rotates keys on its own schedule, so a command can legitimately arrive
signed with a key the connection's cached JWKS predates. The panel used
to refuse it as untrusted; it now refetches the JWKS once on an unknown
kid and only refuses a key that is still unknown afterwards.
2026-09-11 22:16:40 -04:00
github-actions[bot] 7b53584045 chore: bump version to 1.11.2 [skip ci] 2026-09-11 23:19:06 +00:00
Juan Denis 1f652adab4 fix(connect): surface silent metrics collection failures
A metrics build that keeps raising, and a sampler that keeps producing
nothing, both used to log at debug level: ServerKit Cloud showed no
telemetry and the panel had nothing to act on locally. A failing build
now warns on the first failure of a streak and logs its recovery, and
five consecutive empty collects warn that the panel sampler may not be
running. The healthy path stays quiet.

Raises the test-count floor to 5271 (check_test_count.py --update): the
three new publisher tests plus the floor never having been bumped for
the 63 cases added since the last update.
2026-09-11 19:08:37 -04:00
Juan Denis fc5a041764 Fix first-run sidebar preferences and extension loading [skip version] 2026-09-11 00:17:39 -04:00
Juan Denis fb0be688dd chore: prepare 1.11.1 release [skip version] 2026-09-10 22:23:42 -04:00
Juan Denis 2fd6f3c97c test(settings): await desktop footer actions before measuring [skip version] 2026-09-10 22:11:35 -04:00
Juan Denis b181e32674 fix(connect): enforce consent and recover bounded log delivery [skip version] 2026-09-10 22:05:21 -04:00
Juan Denis b90931317c fix(ci): isolate dev release publication from PR builds [skip version] 2026-09-10 22:05:17 -04:00
Juan Denis 693ba8e322 docs: update demo links in all README translations [skip version] 2026-09-10 22:05:14 -04:00
Juan DenisandClaude Fable 5.1 3f60148214 feat(connect): publish inventory, diagnostics and bounded logs to Cloud [skip version]
connect_inventory builds inventory/1 (applications keyed on the row id so a
rename is not a new application; slug, branch and commit instead of a repo
URL; a WordPress admin URL only where this panel installed it; databases as
names, engines and states) and diagnostics/1 (busiest processes and mounts,
never a command line). connect_logs tails the panel and web error logs by
offset with a generation per rotation, reads application output and build
logs through the existing services, applies every Cloud bound locally,
redacts before sending, and stops on collect: false.

The relay client publishes inventory on connect and every five minutes,
diagnostics each minute while Cloud allows it with a fifteen-minute back-off
after a refusal, and logs every five seconds while sources are wanted.
Older Clouds keep answering the facts stream as before.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JtgcyJ75YEozymcrWDyedu
2026-09-10 21:35:18 -04:00
Juan DenisandClaude Fable 5.1 e6cac95f0f ci(release-smoke): publish every dev push as a pre-release for the Cloud release lab [skip version]
The smoke job already builds the release tarball on every push to dev and
threw it away. It now names the build v<VERSION>-dev.<sha7>, writes that
into VERSION so the installed panel reports it, and publishes the tarball
and checksums as a GitHub pre-release. The three newest dev builds are
kept; older ones and their tags are removed. Pull-request runs are
unchanged. The ServerKit Cloud release lab lists these rows as dev builds
and can install and upgrade-test a commit before it is promoted to main.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VndLQNwYw4vYNxQhAFosHY
2026-09-10 21:35:12 -04:00