Skip to content

Druks v0.3.0

Choose a tag to compare

@czpython czpython released this 22 Aug 14:00
· 224 commits to main since this release
d0a2a35

Added

  • Logged-in browser sessions. An extension declares the browser session a
    site needs, and the operator signs in once through a Druks-hosted login window
    — real Chrome over noVNC, opened on the site itself, with an optional timezone
    and an egress proxy (authenticated if needed) for sign-ins that reject
    datacenter IPs. A workflow then borrows that authenticated browser; the login
    is encrypted, stored the first time a run reaches for it, and reused across
    runs, and a session set to persist saves its refreshed state after each borrow.
  • OAuth connections. You can sign in to an OAuth service more than once, and
    Druks keeps each account as its own connection — one per mailbox, handle, or
    workspace, owned by the account that consented and labeled with the provider's
    own facts. A Connections page in Settings lists them; disconnecting keeps the
    row as a revoked, auditable record rather than deleting it, and a repeat
    sign-in reuses the matching connection instead of duplicating it. Extensions
    build on one engine, OauthClient in druks.services, which runs the
    authorization-code-with-PKCE flow with token caching and refresh; MCP sign-ins
    ride the same engine.
  • Installed apps in the shell. Every installed app appears in the dashboard
    navigation and renders inside the shell instead of a separate page. An app with
    a frontend ships an ESM entry.js and declared tabs and borrows the shell's
    React, components, markdown renderer, and gate controls; an app with no
    frontend still gets pages for free — a home page that stacks its subject
    boards, and a subject page with summary facts, the run timeline, the latest
    transcript, and gate controls.
  • Scheduled workflows can dispatch. A workflow on a cron cadence can declare
    a dispatch(); the schedule fires it instead of run(), so a subject-backed
    workflow resolves its subject and starts the real run without a shim.

Changed

  • Deployment is one profiled compose file. Every service lives in a single
    compose.yaml, with a hosted profile for the edge and janitor and a
    gateway profile for the SSH gateway, so provider choice is a matter of
    profiles and .env. SERVICE_TOKENS renders on every shape with no compose
    default, so a missing token stops the sandbox plane instead of it starting on a
    known one, and install.sh seeds an empty compose.override.yaml it never
    overwrites, so host-local services survive installs and upgrades.
  • A service keys on a derived slug. A service no longer declares a name or
    title; the slug comes from the class name — GoogleCalendar becomes
    google_calendar — and the card heading derives from it. The wire field and
    connect route (/api/services/{slug}) follow, and an extension that still
    declares name or title is rejected at load.
  • Board reads know the calling account. A board scopes its rows to the
    operator reading it, a subject carries a readable label, and a subject page and
    the free board lead with the subject's type and name — pull request: owner/repo#7 — instead of a bare id.
  • One control frame across the shell. The accent color reaches every surface,
    and the status glyph pulses whenever any run is still going.
  • MCP tool names derive from operation_id. An agent-tagged route gives an
    unprefixed operation_id, and Druks prefixes it with the extension name, so an
    author no longer writes the prefix by hand.
  • An app's subjects are checked at load. A declared subject must supply a real
    read-side; the loader rejects the platform stub and fails the boot instead of
    the first request.
  • An approved, clean PR merges directly instead of looping back through the
    work gate; only a PR with unmet requirements falls back to auto-merge.

Removed

  • The per-shape compose files. compose.local.yaml and compose.remote.yaml
    fold into the one profiled compose.yaml; install.sh removes the retired
    overlays on upgrade.

Fixed

  • Connect forms draw every declared field. A bool, int, Literal, or
    multiline field renders through the shared field component wherever it appears,
    instead of falling back to a free-text box, and the replace placeholder
    reflects the stored secret.
  • A spend-controlled Codex plan reports its quota as a weekly window instead
    of reading as a parse failure.
  • Sandbox provisioning failures retry. A transient provisioning error is now
    classified as transient, so the in-run retry covers it.
  • The app engine pool is sized for the run queue, not a single request.