djt-hub Install

Local daemon · 127.0.0.1:7717

A live page for every long-running job.

djt-hub is a small local daemon. Your agent builds a page of steps, stats and logs. You watch it update and click the gates.

Every click comes back to the agent as an event.

  • One Go binarydaemon, CLI, web UI
  • 127.0.0.1 onlyno auth, no cloud
  • Live over SSEno polling, no refresh
  • SQLite + logssurvives restarts
release-42 Release 4.2 oncall armed

Runbook

    Events

      Simulated. Press Approve.

      Ten block types

      Pick blocks. Patch state. The page redraws.

      Each block binds to a path in the hub's JSON state. Change the value and every open tab updates.

      steps

      Runbook steps with status, live timers and approval gates.

      checklist

      Items to tick. Each toggle is an event.

      stats

      Big numbers with units and a tone: ok, warn, bad, info.

      chart

      Line, area or bar. Time series or categories.

      table

      Rows from state. Status columns render as badges.

      log

      Lines from state, or live events filtered by prefix.

      actions

      Buttons. Dangerous ones ask for a second click.

      form

      Fields that submit their values as one event.

      markdown

      Headings, lists, code and links.

      html

      A sandboxed iframe, for when no block fits.

      The loop

      The agent writes the page. You decide. The agent acts.

      Everything is a CLI command that prints JSON. No SDK, no server code.

      quick start
      $ djt-hub create release-42 --title "Release 4.2"
      $ djt-hub block add release-42 '{"id":"run","type":"steps","title":"Runbook","bind":"steps"}'
      $ djt-hub patch release-42 --json '[{"path":"steps","value":[
          {"id":"build","label":"Build","status":"running"},
          {"id":"promote","label":"Promote","status":"waiting","gate":"Promote to prod?"}]}]'
      $ djt-hub open release-42
      $ djt-hub wait release-42 --match block=run --match step=promote --timeout 1h
      $ djt-hub patch release-42 steps.promote.status=running
      $ djt-hub close release-42
      1. 01
        Create a hubOne hub per process. It persists until closed, then archives read-only.
      2. 02
        Add blocks, patch stateGive list items an id. Patch by id, never by position.
      3. 03
        Wait for a clickThe call blocks until a matching event arrives, then prints it.
      4. 04
        Act, then update the pageA click asks. The agent does the work and moves the step on.

      Events

      Every click is an event with a seq.

      Wait for one, or follow the stream while you work. Pass a seq to replay what you missed.

      • gate.approvegate.reject
      • actionbutton press
      • form.submitvalues by field
      • checklist.toggleitem and done
      • svc.*started, exited, failed
      • agent.*done with cost, or failed
      • emit <hub> <type> [json]Agents, services and html blocks can add any type.
      djt-hub wait release-42 …
      {
        "seq": 41,
        "hub": "release-42",
        "source": "user",
        "type": "gate.approve",
        "payload": { "block": "run", "step": "promote", "note": "go" },
        "ts": "2026-10-16T15:42:07Z"
      }

      Services

      The page stays live after the agent leaves.

      The daemon supervises commands in their own process groups. They survive the agent exiting and daemon restarts. Closing the hub stops them.

      supervised commands
      # poll every 30s
      $ djt-hub svc add release-42 p99 --every 30s -- 'djt-hub patch health.p99.value=$(./p99.sh)'
      # keep a tail running
      $ djt-hub svc add release-42 tail --restart always -- kubectl logs -f deploy/api
      # run on a schedule
      $ djt-hub svc add release-42 nightly --cron "0 3 * * *" -- ./report.sh
      # react to a click
      $ djt-hub svc add release-42 on-reject --on gate.reject --match step=promote -- ./rollback.sh
      • 01
        Poll, tail, schedule--every, --restart and --cron cover the usual jobs.
      • 02
        Triggers on eventsThe event JSON arrives on stdin. Runs are one at a time, in order.
      • 03
        Hub-aware by defaultPlain djt-hub patch inside a service targets its own hub.

      Daemon agents

      Claude on call, only when nobody is listening.

      If a click lands while no session waits on the hub, a daemon agent runs claude -p for that event. Your own session always wins.

      an on-call agent
      $ djt-hub agent add release-42 oncall --on gate.approve --match step=promote \
          --prompt "Run the promote step, then mark it done" \
          --allow "Bash(./promote.sh)"
      $ djt-hub agent ls release-42
      $ djt-hub agent reset release-42 oncall
      • 01
        Read-only by defaultRead, Grep, Glob and djt-hub. Widen it per agent with --allow.
      • 02
        One resumed sessionRuns never overlap. The agent remembers earlier events until you reset it.
      • 03
        Every run reports costEach ends in agent.done or agent.failed. Budget caps a run at $1.00 unless you say otherwise.

      Prefer a service or a plain --on trigger. Add an agent only when the event needs judgment.

      Install

      Build it, run it under launchd, open a page.

      Needs Go. Binds to 127.0.0.1 only and keeps its data in ~/.local/share/djt-hub/.

      macOS
      $ git clone https://github.com/tory37/djaunt-agent-hubs.git
      $ cd djaunt-agent-hubs
      $ brew install go
      $ ./install.sh        # build + launchd
      $ djt-hub status
      $ djt-hub docs        # the agent guide
      $ examples/release-runbook.sh
      • 01
        Skip launchdRun ./install.sh --no-launchd to start the daemon yourself.
      • 02
        UpgradePull, then rerun install.sh.
      • 03
        Removedjt-hub uninstall drops the launchd agent and keeps your data.