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
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.
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.
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.
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.
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>
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.
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
Generate all four README tables from reviewed source and build snapshots, distinguish collection and asset sizes from runtime results, and remove unsupported footprint claims. Add a consistency check in CI and document how to reproduce profiling and measurements.
Centralize backup schedule calculations and shared request/form flows, encode query values, and move repository finalization into its service. Add browser CI coverage, repair stale test fixtures, and provide opt-in request and build measurement tools.
Preserve synthetic historical probes, document fixes and validation, and list upgrade behavior and remaining hardening work with the local implementation commits.
Schedule dependency and extension scans, audit production frontend dependencies, and replace category suppressions with reviewed function-specific exceptions. Preserve full reports and test the exception gate.
Expose MFA and passkey enrollment, use shared confirmations and locale formatting, and guard pending user and invitation actions. Add Chromium regressions for both themes and failure states to frontend CI.
Scope built-in tools to the live caller, recheck write authorization after confirmation, redact structured results, and fail closed when protections fail. Bound chat inputs, concurrent turns, and cancellation-aware streaming queues.
Require valid access-token sessions, scope application and server rooms, and enforce run visibility consistently across sockets and polling. Add positive-delivery and cross-user isolation regressions.
Copilot review on #135:
- `_repo_steps()` now falls back to port 3000 when `params.port` is not
numeric instead of raising ValueError mid-stream.
- `params.pace` must be a positive number; zero, negative and non-numeric
values are ignored so `line_delay` can never go negative.
CI: the ubuntu integration job sat in "Install Python & pytest" for ~2 h on
a wedged apt mirror, and Version Bump waits on every sibling. Cap the job at
15 minutes and give apt retries, a fetch timeout and non-interactive dpkg
conffile options.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LVRnRXqNMZagqQ3RTqG5pz
- The scroll-fade masks added in #134 used `#000`, which the hex-literal
ratchet in check-frontend-boundaries.mjs counts (design-system 2→6,
databases 5→9). Masks only need an opaque colour, so use the keyword.
- intl.test.mjs compared "60 days ago" in en-US vs es; on any date whose
month equals its day-of-month (7 July) the two short dates coincide and the
test fails. Pin the date instead.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LVRnRXqNMZagqQ3RTqG5pz
* fix(navigation): stabilize overflow tab measurement
* fix(databases): prevent mobile toolbar overlap
* fix(navigation): keep mobile actions accessible
* fix(ui): refine mobile scroll affordance
* fix(layout): align status bar with expanded rail
---------
Co-authored-by: Juan Denis <jhd3197@gmail.com>