Skip to content

Releases: 0xSMW/pulse-uptime

0.3.3

Choose a tag to compare

@0xSMW 0xSMW released this 13 Aug 08:18
d1991f4

0.3.3 hardens the boundaries that protect Pulse under hostile input, high load, and stalled providers. Normal dashboard behavior and successful API contracts stay the same.

What’s new

  • Password changes end machine access. Changing an account password now invalidates every API token and CLI credential issued from the account’s previous credential epoch, including legacy descendant chains.
  • Abusive traffic stops earlier. Account and IP login limits reserve attempts atomically. Health, readiness, onboarding, and avatar upload limits reject excess work before it can consume scarce database, network, or image-processing capacity.
  • Webhooks finish cleanly. Porkbun deliveries get cheap header, size, and timestamp validation before secret access. Irrelevant events are consumed, permanent failures move to a dead letter state, and retryable configuration failures release safely.
  • Private images stay owner-bound. Avatar ownership is enforced through upload, replacement, retrieval, and cleanup. Pending uploads have owner quotas, superseded blobs are removed, and authenticated image responses use private no-store caching.
  • Network probes stay on public routes. RDAP follows redirects through peer validation and SSRF-safe address checks. Onboarding probes use per-user, per-target, and shared concurrency limits.
  • Safer local CLI operations. Forced exports publish atomically with owner-only permissions and reject symlink destinations. File, stdin, and token readers are bounded, and resource IDs cannot inject terminal control sequences into prompts or tables.
  • Monitoring keeps moving through stalls. Notification claims, database work, and provider sends have explicit deadlines. Unstarted work is released for a later retry while monitor scheduling retains time to finish.
  • Shared workflows drift less. CLI pagination, monitor form adapters, and cron route behavior now each have one tested implementation shared by every caller.
  • Patched dependencies. Sharp is on 0.35.3, Nano ID on 3.3.18, and PostCSS on 8.5.26. Production dependency audit reports no known vulnerabilities.

Upgrade notes

Migrations 0029_porkbun_receipt_dead_letters.sql, 0030_image_avatar_ownership.sql, and 0031_credential_epoch.sql add webhook terminal state, owner-bound avatars, and credential epochs. Existing installs apply them through the migrate-before-traffic gate. Existing avatars are claimed by their current account during migration.

After a password change, integrations authenticated with that account’s earlier API or CLI credentials must sign in again. During active abuse, login and probe limits can ask legitimate clients to retry. Authenticated images may refetch after navigation because they are no longer browser-cacheable. Unsafe referrer metadata, malformed UUIDs, oversized CLI inputs, unsafe redirects, and symlink exports now fail clearly.

Verification

  • Full web lint, typecheck, 2,686 tests, and production build
  • Full Go race test, vet, native build, and Windows compile checks
  • Fresh PostgreSQL 16 migration through 0031 and 47 integration tests
  • Credential rotation, login concurrency, image ownership, webhook retry, SSRF redirect, bounded input, and notification deadline exploit regressions
  • Real Neon-backed roadmap preview migrated and tested end to end
  • Production release-bound deploy proof passed

0.3.2

Choose a tag to compare

@0xSMW 0xSMW released this 26 Jul 04:30
05c86f0

0.3.2 makes domain renewal state accurate, compact, and actionable.

What’s new

  • Authoritative Porkbun renewal data. Connect a Porkbun account to show the real registration expiry, registrar, status, and auto-renew state for covered domains. Certificate inspection stays on direct TLS probes.
  • Signed renewal webhooks. Pulse registers domain.renewed and domain.expiring events, verifies HMAC signatures against the raw request body, rejects stale or malformed deliveries, stores receipts durably, and refreshes only after a confirmed Porkbun lookup.
  • Advance expiry alerts. Optional email alerts fire at 30 and 14 days, retain auto-renew context, deduplicate by domain and renewal cycle, and link directly to Porkbun’s domain manager.
  • Clearer expiry presentation. Renewal and certificate warnings now sit beside the monitor URL, tooltips stay inline, and detail views explain the active verification source without false expired states after renewal.
  • Operational controls. System settings expose connection health, covered-domain count, webhook state, polling, tests, and alert controls. The REST API, OpenAPI contract, help, deployment guide, operations guide, README, and marketing site cover the integration.

Upgrade notes

Migration 0028_dark_aaron_stack.sql adds the Porkbun integration state, durable webhook receipts, registration source and auto-renew facts, and domain-expiry notification support. Production deployments apply it through the existing migrate-before-traffic gate.

Set PORKBUN_API_KEY and PORKBUN_SECRET_KEY, deploy, then open Settings → System → Domain monitoring to check the connection and enable the webhook. Expiry alerts remain off until an administrator enables them.

Verification

  • Full web lint, typecheck, 2,587 tests, and production build
  • Full Go build, vet, test, and vulnerability workflow
  • Isolated Neon preview migrated and tested end to end
  • Production release-bound deploy proof passed
  • Production Porkbun poll covers 8 monitored domains
  • Production signed webhook test persisted and processed
  • Invalid webhook rejected before persistence

0.3.1

Choose a tag to compare

@0xSMW 0xSMW released this 22 Jul 13:32
22367a7

0.3.0 closes the gap between what's happening and what you know. Monitoring tools are full of quiet blind spots. Blank while a monitor warms up. Silent while your certificate runs out. Rounding 99.9942% to something prettier. Locked behind one login. This release closes them: expiry warnings weeks before the browser warning, real uptime from minute one, four decimals of truth, a CLI that answers in one keystroke, and your whole team on one source of truth.

What's new in 0.3.0

  • Bring your team. Multiple users with admin and viewer roles. Mint a single-use invite link from the new Team settings page, valid for 7 days, and the recipient lands signed in with the role you chose. Admins run the system, viewers see everything without the keys. Ships across dashboard, API, and pulsectl users commands, with full OpenAPI coverage.
  • Catch expiry before your users do. Pulse now watches the two clocks every site is racing against, domain registration and TLS certificate. An amber chip appears on the monitor the moment either enters its warning window, and a new Domain & Certificate card shows the expiry dates, issuer, registrar, and how each fact was verified, the certificate by TLS probe and the domain by RDAP. Facts are shared assets deduplicated by root domain, so fifty monitors on one domain cost one lookup, and they refresh every 10 minutes.
  • Content checks. Monitors can assert the response body contains expected text, with a distinct content mismatch failure state. A page that answers 200 with the wrong content is now a caught failure, not a silent one.
  • A CLI you can live in. Type pulsectl and get a full interactive menu covering every feature, monitors through diagnostics, walkable with arrow keys. The Dependencies menu lists what you have installed first, and browsing the catalog flows straight into adding. Scripts keep the flag-driven interface and clean TSV, humans get a menu.
  • Tables that hold their shape. Every CLI table stays aligned and never wraps, whatever the terminal width. Uptime shows four decimals between 99% and 99.9999% with trailing zeros trimmed, and monitors still collecting their first day show real observed uptime instead of a blank.
  • A timeline that only shows what happened. Dependency history no longer paints unknown state over periods with real evidence, so the dark squares that could appear after installing a provider are gone.
  • Hardened in public. Custom status page CSS is served as a real stylesheet behind a nonce-based Content Security Policy and can no longer inject markup. Token revocation is race free, Next.js moves to 16.2.11, and a crash-on-304 in dependency polling is fixed. Existing installs upgrade in place, migrations run on deploy.

Fixes and improvements in 0.3.1

  • Expiry monitoring that actually collects. Every domain and certificate check in 0.3.0 silently rolled back at its final cleanup step, leaving the new expiry data empty in production. The cleanup is fixed and covered by a regression test against real Postgres, so the Domain & Certificate card fills in from the first check after upgrading.
  • Honest run accounting. Domains that RDAP simply has no data for now count as unknown instead of failures, so a TLD without coverage can never mask a real probe regression. Certificate probes that cannot complete a handshake remain failures, because they are.
  • Sign-in that survives a bad connection. A network failure during sign-in or invite acceptance no longer strands the button at Signing In forever. Both forms recover with a clear message, keyboard focus is restored for a retry, and the button holds its busy state through the redirect instead of flickering back to idle.
  • Sharper auth flows. Native form validation runs before any server round trip, join errors focus the field they are about, the invalid-invite screen ends in a real button instead of a footnote link, and the already-signed-in state offers an actual sign-out action.
  • Polish everywhere else. Roles read Admin and Viewer in every picker, visitors with a stored light or system theme no longer see a dark flash on first paint, incident detail explains an undetermined cause instead of rendering blank, and small tap targets across incident and invite screens now clear the accessibility minimum.

0.3.0

Choose a tag to compare

@0xSMW 0xSMW released this 22 Jul 09:39
2b076f3

0.3.0 closes the gap between what's happening and what you know. Monitoring tools are full of quiet blind spots. Blank while a monitor warms up. Silent while your certificate runs out. Rounding 99.9942% to something prettier. Locked behind one login. This release closes them: expiry warnings weeks before the browser warning, real uptime from minute one, four decimals of truth, a CLI that answers in one keystroke, and your whole team on one source of truth.

What's new in 0.3.0

  • Bring your team. Multiple users with admin and viewer roles. Mint a single-use invite link from the new Team settings page, valid for 7 days, and the recipient lands signed in with the role you chose. Admins run the system, viewers see everything without the keys. Ships across dashboard, API, and pulsectl users commands, with full OpenAPI coverage.
  • Catch expiry before your users do. Pulse now watches the two clocks every site is racing against, domain registration and TLS certificate. An amber chip appears on the monitor the moment either enters its warning window, and a new Domain & Certificate card shows the expiry dates, issuer, registrar, and how each fact was verified, the certificate by TLS probe and the domain by RDAP. Facts are shared assets deduplicated by root domain, so fifty monitors on one domain cost one lookup, and they refresh every 10 minutes.
  • Content checks. Monitors can assert the response body contains expected text, with a distinct content mismatch failure state. A page that answers 200 with the wrong content is now a caught failure, not a silent one.
  • A CLI you can live in. Type pulsectl and get a full interactive menu covering every feature, monitors through diagnostics, walkable with arrow keys. The Dependencies menu lists what you have installed first, and browsing the catalog flows straight into adding. Scripts keep the flag-driven interface and clean TSV, humans get a menu.
  • Tables that hold their shape. Every CLI table stays aligned and never wraps, whatever the terminal width. Uptime shows four decimals between 99% and 99.9999% with trailing zeros trimmed, and monitors still collecting their first day show real observed uptime instead of a blank.
  • A timeline that only shows what happened. Dependency history no longer paints unknown state over periods with real evidence, so the dark squares that could appear after installing a provider are gone.
  • Hardened in public. Custom status page CSS is served as a real stylesheet behind a nonce-based Content Security Policy and can no longer inject markup. Token revocation is race free, Next.js moves to 16.2.11, and a crash-on-304 in dependency polling is fixed. Existing installs upgrade in place, migrations run on deploy.

0.2.1

Choose a tag to compare

@0xSMW 0xSMW released this 21 Jul 12:04
d25ad7b

Pulse 0.2.0 answers the question every outage starts with: is it us, or is it a provider? The new Dependencies feature puts a provider's officially reported status beside your own endpoint checks, one click, no credentials, no setup. Around that headliner, this release makes the write path exactly-once under retries and crashes, makes a new monitor show real results in its first minutes instead of a blank chart, and rebuilds every cross-cutting rule around a single owner so the API, dashboard, CLI, SQL, and OpenAPI spec can no longer drift apart. It closes with a repo-wide audit pass: 21 verified sources of duplication eliminated, dead code deleted, and one orphaned table dropped.

What's new in 0.2.0

  • Dependencies. Add OpenAI, Vercel, Stripe, Clerk, Neon, and 10 more providers in one click and see their official status beside your own checks. 15 providers, 30 curated presets, five feed adapters, a per-minute poller with SSRF-safe allowlisted fetches, and incident overlap surfaced on monitor and incident detail as neutral timing context. Provider status is attribution, not proof, so a failed feed reads Unknown, never Outage. Ships across dashboard, API, and pulsectl dependency commands.
  • Live from the first check. New monitors walk through visible first-run phases and their detail pages update live as results land. Recent Checks now shows real per-check rows, and uptime percentages drop their trailing zeros.
  • Exactly-once writes. The idempotency layer survived an adversarial review and came out stricter: completion is persisted atomically with the mutation, completed records are never reclaimed, deterministic errors replay as the same response instead of retrying the work, jsonb parameters bind as text so Postgres cannot double encode them, and Edge Config is written after every abortable statement.
  • One owner per rule. Public URL policy, accepted-config reads, Edge Config writes, deterministic UUIDs, client IP extraction, timezone validity, and the storage budget with its retention ladder each live in exactly one module now, enforced identically at every surface. The settings form can no longer accept a URL the checker rejects, and rate limiting keys on the same IP the session records.
  • A hardened CLI. pulsectl shows a braille spinner on stderr while requests are in flight, requests the new dependency scopes, caps admin list responses at 64 MiB against hostile servers, and defers config validation to the server so Go and Zod cannot disagree about what is valid.
  • Failures that explain themselves. A diagnostic error boundary probes system health when a page breaks and tells you whether the database, the config store, or the app itself is the problem.
  • Faster backfill. Gap backfill reads the accepted config snapshot once per range instead of once per minute, and the benchmark harness now measures the exact query shapes production runs.
  • Leaner by design. The unused daily_rollups table is dropped by migration, dead notification and status-page code paths are deleted, and the marketing site shares the app's design tokens with new performance trace cards and live monitor-add feedback.

Fixes and improvements in 0.2.1

  • Deploys that prove themselves. Every deployment now runs database migrations as a gate before traffic shifts, and a post-deploy canary confirms the cron loops are healthy on the new release. A bad build stops itself before anyone sees it.
  • More providers, clearer status. AWS, Auth0, and DigitalOcean join the catalog alongside richer incident-feed support. Every provider row now carries its brand mark, the add flow is faster to scan, and incident-only feeds explain exactly what they cover.
  • Alerts that survive a crash. System alert delivery is durable through restarts and retries, and availability numbers now come straight from raw check batches for accuracy at every zoom level.
  • A stricter, faster foundation. One toolchain checks the entire repo in about a second, TypeScript now proves every indexed read, and security-sensitive paths fail closed instead of assuming. Dead code across the codebase is gone, verified by test suites at every gate.
  • Small touches everywhere. Whole-row click targets, keyboard-reachable tooltips, live-updating dependency detail, and an onboarding flow that asks only for what it needs.

0.2.0

Choose a tag to compare

@0xSMW 0xSMW released this 20 Jul 07:33

Pulse 0.2.0 answers the question every outage starts with: is it us, or is it a provider? The new Dependencies feature puts a provider's officially reported status beside your own endpoint checks, one click, no credentials, no setup. Around that headliner, this release makes the write path exactly-once under retries and crashes, makes a new monitor show real results in its first minutes instead of a blank chart, and rebuilds every cross-cutting rule around a single owner so the API, dashboard, CLI, SQL, and OpenAPI spec can no longer drift apart. It closes with a repo-wide audit pass: 21 verified sources of duplication eliminated, dead code deleted, and one orphaned table dropped.

What's new in 0.2.0

  • Dependencies. Add OpenAI, Vercel, Stripe, Clerk, Neon, and 10 more providers in one click and see their official status beside your own checks. 15 providers, 30 curated presets, five feed adapters, a per-minute poller with SSRF-safe allowlisted fetches, and incident overlap surfaced on monitor and incident detail as neutral timing context. Provider status is attribution, not proof, so a failed feed reads Unknown, never Outage. Ships across dashboard, API, and pulsectl dependency commands.
  • Live from the first check. New monitors walk through visible first-run phases and their detail pages update live as results land. Recent Checks now shows real per-check rows, and uptime percentages drop their trailing zeros.
  • Exactly-once writes. The idempotency layer survived an adversarial review and came out stricter: completion is persisted atomically with the mutation, completed records are never reclaimed, deterministic errors replay as the same response instead of retrying the work, jsonb parameters bind as text so Postgres cannot double encode them, and Edge Config is written after every abortable statement.
  • One owner per rule. Public URL policy, accepted-config reads, Edge Config writes, deterministic UUIDs, client IP extraction, timezone validity, and the storage budget with its retention ladder each live in exactly one module now, enforced identically at every surface. The settings form can no longer accept a URL the checker rejects, and rate limiting keys on the same IP the session records.
  • A hardened CLI. pulsectl shows a braille spinner on stderr while requests are in flight, requests the new dependency scopes, caps admin list responses at 64 MiB against hostile servers, and defers config validation to the server so Go and Zod cannot disagree about what is valid.
  • Failures that explain themselves. A diagnostic error boundary probes system health when a page breaks and tells you whether the database, the config store, or the app itself is the problem.
  • Faster backfill. Gap backfill reads the accepted config snapshot once per range instead of once per minute, and the benchmark harness now measures the exact query shapes production runs.
  • Leaner by design. The unused daily_rollups table is dropped by migration, dead notification and status-page code paths are deleted, and the marketing site shares the app's design tokens with new performance trace cards and live monitor-add feedback.

0.1.0

Choose a tag to compare

@0xSMW 0xSMW released this 19 Jul 07:17
8de24a5

Pulse 0.1.0 is the first tagged release of a self-hosted uptime monitor that runs entirely on infrastructure you own: a Next.js app on Vercel, Postgres on Neon, and email through Resend. It ships the complete monitoring loop, HTTP checks on your schedule, incidents that open and resolve themselves, email alerts, and a personalizable public status page, wrapped in an API-first design where the dashboard, the pulsectl CLI, and coding agents all drive the same versioned API. This release folds in three major workstreams: streaming navigation performance, a full settings and status-reporting expansion, and a database layer tuned to stay fast at fleet scale.

What's in 0.1.0

  • Monitoring core. HTTP(S) checks with per-monitor intervals, timeouts, expected status ranges, and failure and recovery thresholds, organized into groups for up to 100 monitors.
  • Automatic incidents. Outages open incidents, recoveries resolve them, and every transition fans out email notifications with a single insert regardless of recipient count.
  • Public status page. Personalize the name, logo, favicon, theme, and custom CSS. Group pages, 90-day uptime history, and published incident and maintenance reports with timelines and affected-monitor snapshots that survive monitor archival. The page degrades gracefully instead of 500ing when its own database is unreachable.
  • Settings, rebuilt. Dedicated account, security, notifications, status page, monitors, access, and system pages, with unsaved-change guards and effective-privilege display for CLI sessions.
  • pulsectl CLI. Validate, plan, and apply monitoring config as code, manage status pages and reports, and script everything in CI. Hardened against hostile servers: bounded pagination, control-character rejection, and stdin conflict guards.
  • API-first. A versioned REST API with an OpenAPI spec, scoped tokens, and device authorization, so agents and people share one control surface. The docs include a one-shot agent prompt that provisions Vercel, Neon, Edge Config, and Resend end to end.
  • Security by default. SSRF-proof checking with DNS answer validation and socket pinning, Argon2id passwords, a token-gated first-admin bootstrap, rate-limited login, and hashed tokens with lineage.
  • Fast where it counts. Streaming page shells paint navigation instantly, monitor rows prefetch on hover intent, registry sync dropped from roughly 401 SQL statements to 5, and six new indexes plus a deterministic 19-query benchmark harness keep the database layer honest as you grow.
  • Operates within a budget. A database health dashboard, adaptive telemetry retention, and self-maintaining rollups keep storage bounded on the free tiers this stack was designed for.