Development
Changing things
Section titled “Changing things”Whatever you touch in the Windmill UI has to come back to git.
pnpm run windmill:diff # what differs between the UI and git (does not push)pnpm run windmill:pull # take the UI's changes into gitpnpm run windmill:push # make git authoritative and apply itBoth directions delete. push removes remote items that are absent locally;
pull removes local files that are absent remotely. Commit before syncing and
push before pulling — see Windmill CE.
windmill/wmill.yaml sets includeSchedules: true. Secrets are not synced
(skipSecrets); u/admin/waggle_token is injected through the API by
scripts/capture-ledger-token.ts.
Re-taking the screenshots
Section titled “Re-taking the screenshots”The PNGs on The UI are generated by scripts/docs-shots.ts —
none are taken by hand. Re-take them when the UI changes (i.e. when you bump
the Windmill pin in docker-compose.yml). check-doc-refs fails when the
compose pin and the version in shots-manifest.json disagree, so CI stops you
if you forget.
# 1. Bring the stack up and create the run history the script needs (two of them):./setup.sh && container-compose up -d -b # + the capture-ledger API / issuer# - one successful crawl_level# - one failed report_level (any failure)# 2. Capture (Chromium is fetched by hand the first time; puppeteer is docs-only)./node_modules/.bin/puppeteer browsers install chromepnpm run docs:shotsWhen you drop puppeteer, drop its //devDependencies note in package.json too.
Layout
Section titled “Layout”| path | what |
|---|---|
windmill/f/waggle/*.ts |
the scripts Windmill runs, under Bun |
windmill/f/waggle/crawl_level.flow/flow.yaml |
the flow that runs one crawl level |
windmill/f/waggle/daily.schedule.yaml |
when the nightly crawl fires |
test/ |
unit tests; never put these under windmill/f/ — sync push would deploy them |
scripts/*.ts |
host-side helpers (bootstrap, tokens, checks) |
.env.local |
written by the tools (WINDMILL_TOKEN); git ignores it |
.dev/capture-ledger.env |
the four lines for capture-ledger. Its pnpm run connect reads them |
Adding an environment variable is a three-part contract, checked in both
directions by scripts/check-env.ts: .env.example, the name lists in
scripts/env.ts, and a literal-string read.
There are two settings files
Section titled “There are two settings files”Every runnable script hands node .env and then .env.local (two
--env-file-if-exists flags). The later one wins, so a name present in both
takes its value from .env.local.
They are split because they have different owners. .env holds what a person
decided; .env.local holds what only running things can decide (the Windmill
token). When a tool reorders or drops a line a person wrote, nobody can tell
afterwards what happened.
Write only inside your own repo; to cross, read. windmill:bootstrap is a
command you run in capture-scheduler, so it never writes into capture-ledger —
the four lines go into .dev/capture-ledger.env, and fetching them is the other
side’s pnpm run connect. A repo changing because of a command typed somewhere
else is not what the person typing it expects.
When you suspect a stale .env.local, the fastest fix is to regenerate both:
run pnpm run windmill:bootstrap again, then pnpm run connect in
capture-ledger. Both are safe to repeat (tokens accumulate, and the old ones
stay valid).
Out of scope
Section titled “Out of scope”- Nobody is told when it fails. Schedule error handlers are a Windmill Enterprise feature. A failure leaves a red entry in the run history and waits to be noticed.
- No production topology is decided. Apple Container is for development.
Licence
Section titled “Licence”Windmill itself is AGPLv3. Running it internally for your own purposes is unconstrained; redistributing it as part of a product means complying with AGPLv3 or buying a commercial licence.