# WoodShop **Voice-driven conversational 3D woodworking & furniture modeler.** Talk to it like the Star Trek holodeck and watch furniture build itself: > *"Place a 6 foot 2x4, sand it, then attach a 2 foot 2x4 at 90 degrees, 10 inches from the end."* > *"Build a coffee table: a four foot by two foot frame from 2x4s, with four legs 18 inches tall standing at the corners."* Each board is real dimensional lumber (a 2x4 is modeled at its true 1.5″ × 3.5″), so the result is buildable — export to **STEP** (CAD/CNC) or **STL** (3D print), and get a **cut list with board-feet and a shopping estimate**. ## How it works WoodShop reuses the existing [CmdForge](https://gitea.brrd.tech/rob/cmdforge) tool ecosystem for everything that isn't woodworking-specific, so no wheels are reinvented: ``` woodshop-talk ── the conversational loop │ dictate ............. speech → text (CmdForge tool) │ pa-load-tools ....... wood-* → Claude schemas (CmdForge tool) │ claude -p ........... interpret → tool calls (provider) │ pa-execute-tool ..... dispatch each wood-* (CmdForge tool) │ read-aloud .......... speak confirmation (CmdForge tool) ▼ scene.json ← single source of truth (parts, joints, selection, undo) ▲ │ writes │ reads/mutates ▼ wood-* CmdForge tools woodshop-view (place/join/stand/move/...) live pyvista 3D, watches scene.json ``` The `wood-*` tools are thin wrappers over the `woodshop` CLI, so the modeling logic lives in one place and the tools double as the LLM's documented command vocabulary. ## Installation ```bash python -m venv .venv && source .venv/bin/activate pip install -e ".[viewer,dev]" # 'viewer' pulls build123d + pyvista python scripts/gen_wood_tools.py # register the wood-* CmdForge tools ``` ## Usage ```bash woodshop-view & # live 3D window (watches the scene) woodshop-talk # type commands; --voice to speak them woodshop-talk --once "build a workbench top from five 2x6 boards 6 feet long" ``` Or drive it directly from the CLI: ```bash woodshop place 2x4 "6 ft" # place a board woodshop stand # stand it up (a leg) woodshop join p2 --to p1 --angle 90 --offset "10 in" woodshop rename "front-left leg" woodshop cutlist # bill of materials woodshop export table.step # STEP / STL export woodshop save "coffee table" # named projects woodshop open "coffee table" ``` Run `woodshop --help` for the full command list (place, join, stand, lay, rotate, move, trim, copy, rename, sand, delete, undo, clear, status, cutlist, export, save, open, projects). The active scene lives at `$WOODSHOP_SCENE` or `~/.local/share/woodshop/scene.json`; named projects in `~/.local/share/woodshop/projects/`. ## Development ```bash pytest # 41 tests ``` Key modules: | Module | Role | |--------|------| | `scene.py` | Part/Joint/Scene model, operations, undo, persistence | | `lumber.py` | nominal → actual dimensional lumber table | | `units.py` | parse "6 ft" / "3 ft 6 in" / "-2 ft" → inches | | `cli.py` | the `woodshop` command | | `geometry.py` | build123d solids + STL/STEP export | | `cutlist.py` | cut list, board-feet, shopping estimate | | `viewer.py` | live pyvista 3D viewport (`woodshop-view`) | | `driver.py` | conversational loop (`woodshop-talk`) | | `scripts/gen_wood_tools.py` | (re)generate the `wood-*` CmdForge tools | ### Known limitations - Joints rest boards on each other's faces (Z-stacking); no true mortise/lap joinery geometry yet. - Command interpretation latency is ~7–13s per utterance (one `claude -p` call). ## License MIT