Run a workshop where every answer lands as data the moment it is given, the room sees its own results when you choose, and the synthesis starts from clean tallies instead of photographed sticky notes. A Claude Code skill guides you from "we should run a workshop" to a confirmed plan; the tools in this repo then build the forms, the QR landing page, the projector page with live tallies, the print fallback, the charts and the report — all from one spec file.
Built from running requirements workshops with university lecturers (paper first, then paper-free) and generalized so any facilitator can use it with their own Google account or Supabase project. Nothing routes through anyone else's credentials.
| Piece | Where | What it does |
|---|---|---|
Skill workshop-builder |
skills/workshop-builder/ |
Six stages with gates: discover → grill → confirm → build → run → synthesize. Recommends a workshop type (UX research formats first), asks the mandatory questions with defaults, writes the plan and the spec, then drives the tools. |
| SOPs | workflows/ |
One Markdown procedure per stage with preconditions, exact tool order, deliverable, failure and retry. |
| Spec | schema/workshop.schema.json, templates/workshop.template.json |
One workshop.json per workshop: agenda, instruments (forms), what the projector shows, print pages, synthesis groups, decisions. |
| Tools | tools/ |
init-workshop · validate-spec · build-site · deploy · build-forms · serve-live · pull-responses · tally · build-charts · build-report · build-print-pack · make-qr · check-setup. Registry in tools/README.md. |
| Static site | site/ (templates + assets) |
Landing page with QR, projector page (screen.html), facilitator run sheet, A4 code slips, and — on the static backend — the form pages themselves. |
| Backends | docs/setup-google-auth.md, docs/setup-supabase.md |
Google Forms through your own OAuth client, or kit-rendered forms posting to your own Supabase table. |
| Docs | docs/ |
Contracts between tools, architecture, hosting, privacy. |
Participants get an anonymous code at the door; it is the first field of every form. Forms are taps first, one free-text line at most. While a form is open the projector shows its QR and a progress count; when the facilitator closes the block, the tally is revealed — tally first, minority voice first. Designs and proposals come last, as props. Rehearse with a test code, then set a cutoff so rehearsal rows vanish. Paper slips and two fallback forms are printed because Wi-Fi fails in the room where it matters most. Pull, tally and chart the same day; write findings and feed decisions by the date promised in the room.
Requirements: Python ≥ 3.9, a browser. Optional: Chrome/Chromium (PDF and PNG export), Node ≥ 18
(Netlify deploys through npx netlify-cli).
git clone https://github.com/thanthir/workshop-kit.git
cd workshop-kit
python3 -m venv .venv && . .venv/bin/activate
pip install -r tools/requirements.txt # segno (QR), jsonschema
python tools/check-setup.py # what is present, what is missing, how to fix itInstall the skill in Claude Code, either way:
# as a plugin (recommended)
/plugin marketplace add thanthir/workshop-kit
/plugin install workshop-kit@workshop-kit
# or by hand
ln -s "$PWD/skills/workshop-builder" ~/.claude/skills/workshop-builder
export WORKSHOP_KIT_HOME="$PWD" # lets the skill find tools/ and workflows/Then, in Claude Code: /workshop-builder (or just say "plan a workshop"). The skill runs the discovery
and grill sessions, writes workshops/<slug>/plan.md and workshop.json, asks for your confirmation,
and only then builds.
Without Claude:
python tools/init-workshop.py my-workshop-2026-01-31 --title "Requirements workshop" --date 2026-01-31 --lang en --lang2 th
# edit workshops/my-workshop-2026-01-31/workshop.json (replace every <<placeholder>>)
python tools/validate-spec.py workshops/my-workshop-2026-01-31
python tools/build-site.py workshops/my-workshop-2026-01-31 --base-url https://my-site.netlify.app
python tools/deploy.py workshops/my-workshop-2026-01-31 --create-site
python tools/build-forms.py workshops/my-workshop-2026-01-31 # google backend; static needs nothing here
python tools/build-site.py workshops/my-workshop-2026-01-31 && python tools/deploy.py workshops/my-workshop-2026-01-31
python tools/build-print-pack.py workshops/my-workshop-2026-01-31
python tools/serve-live.py workshops/my-workshop-2026-01-31 --open # projector with live tallies
# after the room:
python tools/pull-responses.py workshops/my-workshop-2026-01-31 --tally
python tools/build-charts.py workshops/my-workshop-2026-01-31 --png
python tools/build-report.py workshops/my-workshop-2026-01-31google |
static |
|
|---|---|---|
| Forms | Google Forms built from the spec | HTML pages built from the spec |
| Answers live in | your Google account | your Supabase project (insert-only public key) |
| One-time setup | Google Cloud project + OAuth Desktop client (~20 min) | Supabase project + one SQL paste (~10 min) |
| Participants need | a browser (no Google account) | a browser |
Both show the same projector, tallies, charts and report. Details and trade-offs:
skills/workshop-builder/references/backends.md.
skills/workshop-builder/ SKILL.md + references (types, grill checklist, plan template, instrument and
live-display patterns, run-day protocol, synthesis method, backends, lessons)
workflows/ define · setup-backend · build · rehearse · run · synthesize
tools/ Python CLIs + tools/lib (spec model, tally, backends, charts, gauth)
site/ templates and assets the site builder copies
schema/ templates/ workshop.schema.json · workshop.template.json · plan.md · pack.md · findings.md · invite.md · consent.md
supabase/schema.sql the responses table with row-level security (static backend)
docs/ contracts.md · architecture.md · setup-google-auth.md · setup-supabase.md · hosting.md · privacy.md
tests/ pytest; fixture workshop with no real data
workshops/ your workshops (ignored by git; keep them private)
Codes, not names. Nothing in the kit generates a name or email field. The name→code list, raw responses
and the live tallies stay on the facilitator's machine (.tmp/, live/ — both gitignored and never
deployed). Public pages carry noindex. See docs/privacy.md and templates/consent.md.
Issues and pull requests welcome — especially new workshop types in
skills/workshop-builder/references/workshop-types.md, lessons in lessons-learned.md, and backends.
Keep the rules in docs/contracts.md: one spec, no secrets, nothing named that is real.
Run python -m pytest -q before a PR.
MIT — see LICENSE.