The block library Blockwork shows under My Blocks > Browse library, served by a Cloudflare Worker. People sign in with GitHub or Google to submit packs; every upload is reviewed before it's listed.
GET /index.jsonlists each listed pack's newest approved version, in the format Blockwork reads. Each entry pins the file's SHA-256, andofficialmarks the team account's packs (Blockwork shows a verified badge for them, from this library only).GET /packs/<sha256>.jsonserves an approved pack file./lists packs with search (names, blocks, descriptions, authors) and filters for permissions, official packs and sort order, all as query parameters (?q=&uses=&official=1&sort=)./packs/<id>is a pack's page: its blocks, what they can do, its versions and comments./packs/<id>/sourceshows the pack in Blockwork's own editor or as the pack file (?view=json,?v=<sha256>for an older version)./authors/<public id>lists one account's packs.- The site never draws blocks itself. The source view embeds the pack viewer,
blockworked.com's web build of the editor (
/packview/, built fromqt-demo/PackView.qmlin that repo), and/browse.jshands it the pack. Cards and block lists show pictures that viewer drew (src/renders.ts): opening a version's review page draws and saves them (PNGs per theme in R2 underrenders/<sha256>/), and/admin/rendersdraws any still missing.MAIN_SITE_URLsays where the viewer lives (and goes in the CSP'sframe-src). - Signed-in accounts can comment on a pack; the writer, the pack's owner and admins can delete a comment.
/submittakes uploads,/meshows their status,/adminis the review queue (approve, reject with a reason, take a pack down, ban an account).
A pack id belongs to the account that first submitted it, so only that account can publish new versions. A new upload stays pending, and the listed version stays up until it's approved.
packs/ and index.json hold the starter packs. Blockwork releases that
still read index.json from this repo keep working, and npm run seed:*
loads the same packs into the Worker.
- Make the blocks in a macro, then right-click one in the My Blocks palette and pick "Share blocks as a pack...". Blocks they call come along.
- Sign in on the library site, open Submit a pack and upload the file. Keep the same id for later versions so they replace the old blocks.
Each entry in blocks.block_defs can include identifier (for example,
ClickGrid) and description for Blockwork's Details screen. These can
also be set in the app's Make/Edit Block dialog. Keep the internal id
stable across versions so installed calls continue to match. An uploaded
identifier can't contain :; the site stores each one as
<uploader>:<identifier> (letters and digits of the account name, then the
ID), so JohnDoe:OpenYouTubeStudio, and sets the file's author to the
account name. The starter packs predate this and keep Blockworked_ClickGrid,
which Blockwork shows as Blockworked:ClickGrid. Set description on each
block to explain its inputs and behavior. Older packs without these fields still load.
Run python3 scripts/build-block-index.py after editing starter packs to
refresh their checksums.
A pack's variables are private to it in Blockwork, so use plain names
(line, not Author pack: line); they can't clash with the user's own.
Starter packs before 1.1.0 carried a Blockworked <pack>: prefix.
Inputs can include an optional default_value literal. Blockwork uses it in
the sidebar and for new calls; updating a pack preserves existing call values.
For example, an active-window input can start empty and a monitor input at 1:
[
{"kind":"Input","id":"window-input","name":"window","value_type":"Any","default_value":{"kind":"Text","value":""}},
{"kind":"Input","id":"monitor-input","name":"monitor","value_type":"Any","default_value":{"kind":"Number","value":1}}
]Any inputs accept Text or finite Number defaults. Bool inputs accept
{"kind":"Bool","value":true} or false in the same shape. Defaults cannot
contain expressions or custom block calls. Without a default, inputs keep the
legacy zero or empty Boolean slot. Older app versions ignore the new field.
These packs combine multiple built-in blocks into reusable workflows. Their definitions were checked against Blockwork's instruction and operator palettes.
| Pack | Blocks |
|---|---|
| Clipboard tools | Remove duplicate lines, remove blank lines, clean whitespace |
| Text extraction | Text between literal markers, all lines containing text, value for a key=value key |
| Window layouts | Center on a monitor, tile two windows side by side, capture geometry, restore geometry |
| Mouse patterns | Click a grid, drag through points, click relative to a window |
Clipboard tools replace clipboard text after processing it. Line-based blocks
accept LF, CRLF and CR, and produce LF. Duplicate lines and text markers match
exactly, including case. Key lookup trims keys and values, uses the first
matching entry and preserves additional = signs in its value.
Window patterns match the first window whose title or app contains the text. Use patterns that identify different windows for tiling. Monitor numbers start at 1; layouts use the full monitor rectangle, including panels. Window control depends on the desktop, and window managers may enforce minimum sizes. Save the geometry reporter's JSON in a variable, then pass it to the restore block; it records position and size, not maximized or minimized state.
Mouse grids use absolute screen coordinates and visit columns within each row.
Rows and columns are nonnegative whole numbers; spacing may be negative.
Drag paths contain at least two x,y pairs separated by semicolons, such as
100,100; 200,200. Line-separated paths are also supported. Pauses
are in milliseconds. Window-relative clicks use offsets from the client area's
top-left and focus the window before clicking.
The four packs are generated with stable IDs:
python3 scripts/build-official-packs.py
python3 scripts/build-block-index.pyFor behavior tests using Blockwork's actual Rust parser and interpreter, first
build blockwork-core in a Blockwork checkout with the current Rust toolchain,
then run:
npm run test:runtime -- /path/to/Blockwork/target/debug/depsThese tests simulate clipboard/window I/O and record mouse events without controlling the desktop. They cover all 13 new blocks, Unicode and literal matching, line endings, invalid inputs, monitor offsets and action order.
Reviewers: read the whole pack. The review page lists what its blocks can do, but a pack in this library should not run commands, go online, write files or read secrets unless that's plainly its purpose.
Needs Node and a Cloudflare account.
npm install
npm run migrate:local && npm run seed:local
npm run dev # http://localhost:8787
npm test # pack checks
npm run typecheckLocally, put the secrets in .dev.vars:
SITE_URL=http://localhost:8787
ADMINS=github:<your GitHub user id>
GITHUB_CLIENT_ID=...
GITHUB_CLIENT_SECRET=...
GOOGLE_CLIENT_ID=...
GOOGLE_CLIENT_SECRET=...
Blockwork signs in through the browser: it listens on 127.0.0.1, opens
/app/login?port&state&challenge&label, and the page sends a one-time code
back to that port once the person confirms. The app swaps the code and its
PKCE verifier at POST /api/v1/app/token for a token that lasts a year.
Everything under /api/v1/ takes that token as Authorization: Bearer,
never the site's cookie:
GET /api/v1/packs/:id: a pack's versions and commentsPOST /api/v1/packs/:id/comments,DELETE /api/v1/comments/:idGET /api/v1/me: the account and its packs, every upload with its review statusPOST /api/v1/packs: upload a.blockpack(a new pack or an update), reviewed like the form'sPOST /api/v1/app/logout
npx wrangler d1 create blockwork-libraryand put the id inwrangler.toml;npx wrangler r2 bucket create blockwork-library.- Set
SITE_URLandADMINSinwrangler.toml. - Create a GitHub OAuth app and a Google OAuth client with callbacks
<SITE_URL>/auth/github/callbackand<SITE_URL>/auth/google/callback, thennpx wrangler secret puteach of the four client values. npm run migrate:remote && npm run seed:remote && npm run deploy.
After that, every push to master deploys on its own
(.github/workflows/deploy.yml): it typechecks, runs the tests, applies any
new migrations and deploys the Worker. When a push changes packs/, it
then runs npm run seed:remote to publish the starter packs to the live
library. Manual workflow runs also reseed, so they can retry a failed seed.
It needs two repository secrets: CLOUDFLARE_API_TOKEN (a token from the
"Edit Cloudflare Workers" template, with permission to edit D1 and write
R2 objects) and CLOUDFLARE_ACCOUNT_ID.
Anyone can host a library: an index.json in this format plus the pack
files, over https://. People add its address in Blockwork's settings.