Commit Graph
2452 Commits
Author SHA1 Message Date
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
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
Juan Denis 4dc281ce58 test(settings): await both mobile footer actions [skip version] 2026-09-08 09:40:06 -04:00
Juan Denis 0fc47c3d3e fix(ai): normalize usage quota scope IDs [skip version] 2026-09-08 09:34:35 -04:00
Juan Denis 172e410ce3 chore: prepare 1.11.0 and refresh release inventories [skip version] 2026-09-08 09:31:21 -04:00
Juan Denis 8468ab79f2 test(ai): verify management UI and document completed integration 2026-09-08 04:10:21 -04:00
Juan Denis 7d5623bccb feat(settings): add connected AI model policies and usage views 2026-09-08 04:09:54 -04:00
Juan Denis bebc69f71c feat(ai): connect task routing, guarded fallback, and scoped run accounting 2026-09-08 04:09:27 -04:00
Juan Denis 6a77f5e5ae docs(skills): revise pull request description guidance 2026-09-08 03:05:19 -04:00
Juan Denis 9bb474e111 docs(ai): document settings standards and Prompture integration review 2026-09-08 03:03:58 -04:00
Juan Denis 891666786c test(settings): cover AI controls and responsive settings surfaces in browsers 2026-09-08 03:03:43 -04:00
Juan Denis 8e9c4fa6b0 fix(settings): unify forms, notifications, and AI configuration controls 2026-09-08 03:03:19 -04:00
Juan Denis 54028fbff4 fix(ai): enforce assistant enable state and conversation cost limits 2026-09-08 03:03:00 -04:00
Juan Denis 5a4036e9b2 fix: resolve credential draft and backup fallback review [skip version] 2026-09-08 01:39:54 -04:00
Juan Denis fde0acee6d fix(ai): satisfy release gates and prepare 1.10.0 [skip version]
Keep connection persistence behind the service boundary, use typed errors and shared JSON parsing, and refresh reviewed inventories. The new GET connection catalog accepts API keys so API clients managing connections can discover IDs without exposing credentials; existing JWT-only routes stay unchanged. Add regression coverage and release notes.
2026-09-08 01:30:03 -04:00
Juan Denis add2f713a5 feat(ai): use Prompture 1.11 native gateway streaming 2026-09-08 00:47:58 -04:00
Juan Denis 569b052659 feat(ai): expose Prompture providers and saved connections 2026-09-08 00:42:54 -04:00
Juan DenisandClaude Fable 5.1 55291c3c10 fix(update): stop snapshotting the SQLite DB twice per update; test vendor shim MIME
The tree backup rsync copied backend/instance/serverkit.db even though the
same database had just been written as the pre-upgrade copy, and rollback
only ever restores from that copy. On a 450 MB database that made every
update cost ~900 MB of backups, which is how small VPSes kept filling up.
Exclude the SQLite files from the tree snapshot. Retention is unchanged
(SERVERKIT_BACKUP_RETENTION, default 3, plus the 15% disk budget).

Add a test that every shipped nginx vhost forces a JavaScript MIME type for
/serverkit-vendor/*.mjs and that the regex cannot capture the
/api/v1/plugins/<slug>/assets/... route.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NWc84WDsWR7M55Mn7qtpie
2026-09-08 00:27:42 -04:00
Juan DenisandClaude Fable 5.1 bbce447e85 fix(nginx): serve /serverkit-vendor/*.mjs shims as text/javascript
Stock nginx (1.18-1.24 on Debian/Ubuntu) has no `.mjs` entry in mime.types,
so the runtime-extension vendor shims the import map points at came back as
application/octet-stream. Browsers refuse to execute an ES module with that
type, so every runtime-loaded extension (WordPress, Git, Mail, Fail2ban, ...)
failed on fresh installs with "Failed to fetch dynamically imported module:
blob:..." (Chrome) or "'application/octet-stream' is not a valid JavaScript
MIME type" (Safari).

Add a location block to the shipped vhosts (and the container frontend
config) that forces text/javascript for /serverkit-vendor/*.mjs. The regex is
anchored to that folder: a bare `\.mjs$` would also capture the
/api/v1/plugins/<slug>/assets/dist/index.mjs route and 404 every bundle.
update.sh already re-copies these vhosts, so existing installs pick it up on
their next update.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NWc84WDsWR7M55Mn7qtpie
2026-09-08 00:25:25 -04:00
Juan Denis 1ace946ab9 Keep service metrics stable across metadata refreshes [skip version] 2026-09-07 23:34:57 -04:00
Juan Denis 116f817197 Clarify PR description guidance
Refines the create-pr skill to keep PR bodies concise and structured. Large changes should use a short body with Highlights, Upgrade notes, and Validation outside the accordion, while implementation details stay inside the technical appendix.
2026-09-07 23:33:13 -04:00
github-actions[bot] 3ca9255d81 chore: bump version to 1.9.29 [skip ci] 2026-09-08 03:14:16 +00:00
Juan Denis d5577e8bda fix(logs): keep remote runtime lookups off the panel host 2026-09-07 22:46:16 -04:00
Juan Denis 0f32593a38 Raise backend test baseline for PR #136/#139 tests 2026-09-07 20:11:45 -04:00
Juan Denis ef0f9481af Update changelog for PRs #136/#137/#139 and fix hook dep warnings 2026-09-07 20:08:29 -04:00
Juan DenisandMax Freedom Pollard 32d8e76587 Merge PR #139: fix(bitbucket): send redirect_uri on the authorize hop
Co-authored-by: Max Freedom Pollard <272618364+MaxFreedomPollard@users.noreply.github.com>
2026-09-07 20:08:29 -04:00
Juan Denisandjrbertt 225dfdfc18 Merge PR #137: fix(docker): prevent inspector from covering Logs and Exec
Co-authored-by: jrbertt <joaorebertt0219@gmail.com>
2026-09-07 20:08:28 -04:00
Juan Denisandjrbertt 4f361fa3d1 Merge PR #136: fix(observability): resolve container runtime logs and metrics
Co-authored-by: jrbertt <joaorebertt0219@gmail.com>
2026-09-07 20:08:16 -04:00
Juan Denis d88f1cbf55 Make service detail chips scroll on mobile
Updates the service detail status chip layout for small screens from wrapped columns to a single horizontal, non-wrapping scroll row. It flattens group wrappers, hides group labels on phones, and prevents chip/ring clipping with small spacing and padding adjustments so pills remain readable and tappable.
2026-09-07 19:51:22 -04:00
Max Freedom Pollard bedf5640fd fix(bitbucket): send redirect_uri on the authorize hop
generate_bitbucket_authorize_url() takes a redirect_uri and leaves it
out of the query string, so Bitbucket returns the user to whatever
callback is registered on the OAuth consumer rather than the one the
panel asked for. complete_bitbucket_callback() then posts that same
redirect_uri to the token endpoint, so the two halves of one flow name
different callbacks.

Both sibling generators in the same file send it
(generate_github_authorize_url line 207, generate_gitlab_authorize_url
line 446), as does generate_auth_url in sso_service.py; Bitbucket was
the only one that dropped it. GET /source-connections/bitbucket/authorize
already rejects a request without redirect_uri, so the value was always
present and always discarded.

Adds the parameter, plus a regression test parametrised over all three
providers so the next one added is held to the same contract.
2026-09-07 06:12:48 -04:00
Juan Denis 7dfc0c8b68 docs: align award badge heights across README languages 2026-09-07 02:36:37 -04:00
Juan Denis 63d1fe8e4e docs: show deployment videos side by side in all languages 2026-09-07 02:35:15 -04:00
Juan Denis cacd3a2625 docs: add deployment video walkthrough in all README languages 2026-09-07 02:32:59 -04:00
Juan Denis f0b7ecabd9 Backfill changelog and tighten release-note policy
Reworked `CHANGELOG.md` into a Keep a Changelog-style release history backfilled from published GitHub releases (starting at 1.6.25), added a structured `Unreleased` section, and linked each version to release/comparison URLs. Updated contributor guidance and the PR template to require concise user-facing changelog notes (or justification when not needed), and added a direct changelog link in the README navigation to make release history easier to find.
2026-09-07 02:25:38 -04:00
Juan DenisandClaude Opus 5 ade0088777 Make fleet monitoring actually monitor
Three defects, found together because they are the same failure wearing
three hats: monitoring that looks configured and is not.

Fleet alert thresholds were never evaluated. check_fleet_thresholds was
written, was correct, and had no caller anywhere in the backend, so a
threshold set on the Fleet page was checked against nothing and a server
could sit at 99% CPU for a week in silence. It now runs every minute as a
built-in scheduled job alongside every other recurring task, and each
alert it opens or resolves goes to admins through the Notification Bus.
An evaluation nobody is told about is most of the way to no monitoring.

The agent heartbeat was throwing metrics away. It built its own
ServerMetrics row and filled five of the model's thirteen columns,
dropping memory_used, disk_used, the network totals, both network rates
and extra. The two rates are exactly what the threshold checker reads, so
a network threshold could never fire for an agent-reported server: the
data needed to evaluate it was discarded on the way in. Heartbeats now go
through ServerMetricsService, the writer everything else already used.

Metric history outlived its own retention. The history and aggregate
endpoints offered 7-day and 30-day windows while cleanup deleted every
sample after seven days, and two constants described hourly and daily
aggregate retention that nothing produced. A 30-day chart came back
holding at most seven days and said nothing about it. Both endpoints now
return a coverage block — the retention in force, the earliest point they
can answer for, and whether the window asked for was truncated — and the
two constants that promised retention nobody implemented are gone. Real
rolled-up aggregates are the other way to fix this and would need their
own tables and writer; until they exist, saying what we have is the
honest answer.

Two more things surfaced while writing the tests.

get_aggregated_metrics grouped by date_trunc, which is PostgreSQL's alone,
so the endpoint raised "no such function: date_trunc" on every SQLite
deployment — one of the two supported databases. Buckets are now built
with the right function for the database in use.

And an escalation is not a recovery. warning -> critical closes the
warning row, so both a genuine recovery and a worsening breach end up as
status='resolved'; announcing the second as "recovered" would tell an
operator the problem went away at the moment it got worse. Supersession is
tracked separately and is not notified twice, because the new alert
already says what happened.

The two built-in-job counts in test_jobs.py move from 16 to 17 and 24 to
25, and BASELINE_COUNT is raised for the new tests.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-06 21:04:17 -04:00
Juan Denis 1b3d556c84 Merge branch 'dev' of https://github.com/jhd3197/ServerKit into dev 2026-09-05 21:20:24 -04:00
Juan Denis e211cd7af2 ci: rerun promotion checks [skip version] 2026-09-05 16:37:53 -04:00
Juan Denis 7564f8b977 Revise create-pr diff-based drafting
This updates the create-pr skill to build PR drafts from the actual branch diff against a resolved base ref, rather than assuming `main`/commit history alone. It adds clearer instructions for checking refs, reading `git diff BASE...HEAD`, documenting comparison scope, handling empty or missing comparisons, and writing a local `.pr/YYYY-MM-DD.md` draft without opening or publishing a remote PR. The guidance also tightens review expectations around validation evidence, upgrade/security notes, contributor attribution, and concise, evidence-based writing.
2026-09-05 16:37:02 -04:00
Juan Denis b2dbd2386d chore: bump version to 1.9.28 [skip ci] 2026-09-05 16:27:36 -04:00
Juan DenisandClaude Fable 5.1 01e0925c2a fix(auth): backfill users.auth_version so upgrades keep logins working
On an existing install the startup schema sync runs before alembic and
added users.auth_version as a bare nullable TEXT, so migration 097 saw the
column and skipped its '0' default. Every pre-existing user then carried
a NULL auth_version that no JWT claim could match: 2FA verification and
plain logins both failed with "Invalid or expired token" (reproduced on
the builditdesign test box after `update.sh --branch dev`).

- _fix_missing_columns now renders a literal server_default as a SQLite
  DEFAULT, so pre-alembic column adds backfill existing rows.
- migration 097 always backfills NULL/empty auth_version to '0'.
- tests pin both paths plus the default rendering.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LVRnRXqNMZagqQ3RTqG5pz
2026-09-05 16:27:35 -04:00
Juan Denis 3c925f10fe fix: clear stale service metrics across runtime changes [skip version] 2026-09-05 15:24:58 -04:00
jrbertt 4ab6d37160 fix(docker): prevent inspector from covering actions 2026-09-05 15:22:32 -04:00