runJobsOnCreate now awaits each job before starting the next,
ensuring they don't stomp each other's DB writes in parallel.
getInstanceHistory changed to ORDER BY changed_at ASC, id ASC so
the creation event (lowest id) is always first regardless of
same-second timestamps.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Jobs with run_on_create=true in their config fire automatically
after a new instance is created. Runs fire-and-forget so they don't
delay the 201 response. Option exposed as a checkbox in each job's
detail panel.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Fetches Semaphore project inventory via Bearer auth, parses the
Ansible INI format to extract hostnames, and sets semaphore=1/0
on matching instances.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Syncs patchmon field on instances by querying the Patchmon hosts API
and matching hostnames. API token masked as REDACTED in responses.
seedJobs now uses INSERT OR IGNORE so new jobs are seeded on existing
installs without re-running the full seed.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replaces ad-hoc Tailscale config tracking with a proper jobs system.
Jobs get their own nav page (master/detail layout), a dedicated DB
table, and full run history persisted forever. Tailscale connection
settings move from the Settings modal into the Jobs page. Registry
pattern makes adding future jobs straightforward.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds a background job system that polls the Tailscale API on a configurable
interval and syncs tailscale status and IPs to instances by hostname match.
- New config table (key/value) in SQLite for persistent server-side settings
- New server/jobs.js: runTailscaleSync + restartJobs scheduler
- GET/PUT /api/config — read and write Tailscale settings; API key masked as **REDACTED** on GET
- POST /api/jobs/tailscale/run — immediate manual sync
- Settings modal: new Tailscale Sync section with enable toggle, tailnet, API key, poll interval, Save + Run Now buttons, last-run status
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>