Local compose now uses deploy/backend.Dockerfile with build context at the outer repo root, so the engine (Mark/easystitch) is layered into the backend image at build time. This replaces the implicit sibling-repo editable install that worked when the engine sat beside it on disk. Two fixes folded in: combined pip install to resolve numpy consistently (engine pins <2, scikit-learn wants 2.x), and opencv-python-headless swap because opencv-python's libGL dep is missing from python:3.11-slim and the service never opens a display. Verified end-to-end: POST /api/easystitch/v1/digitize → 4178 stitches, 2 colors, 393ms POST /api/easystitch/v1/export → valid DST, correct counts |
||
|---|---|---|
| backend@e452c59ccc | ||
| deploy | ||
| docs | ||
| engine@c0c9044285 | ||
| scripts | ||
| webui@1c76516ccb | ||
| .gitmodules | ||
| README.md | ||
ThreadCraft
Embroidery digitizing for Brother Entrepreneur PR-10 — a web application that takes artwork, auto-digitizes it into stitch plans, and exports PES/DST files ready for production.
This is the project-level repo. It is a thin wrapper that pulls the three real components together as git submodules and owns the cross-cutting deploy and documentation.
What the project is
A web user opens ThreadCraft, uploads a PNG, configures a hoop and stitch preferences, and the app produces a stitch file. The endpoint renders the stitches on Fabric.js. The digitizing itself is a CPU-bound pipeline (scipy + scikit-learn + scikit-image) that no JS port would replicate, so the browser hits a FastAPI service over HTTP. That service wraps an embroidery CAM engine.
┌──────────────────────┐ HTTP ┌────────────────────────┐
│ webui/ (ThreadCraft │ ─────────▶ │ backend/ │
│ React+Vite SPA) │ /v1/* │ (easystitch-service, │
│ │ ◀───────── │ FastAPI on :8080) │
└──────────────────────┘ JSON │ │
│ │ imports easystitch │
│ builds from │ │ │
│ webui/Dockerfile │ ▼ │
│ │ engine/ │
│ │ (Mark/easystitch, │
│ │ EmbroideryPipeline) │
▼ └────────────────────────┘
served by nginx
/api/easystitch/* proxied to backend
Repos
| Path | Repo | Role |
|---|---|---|
engine/ |
Mark/easystitch | The embroidery CAM engine (Python). |
backend/ |
Mark/easystitch-service | FastAPI wrapper exposing /v1/digitize, /v1/export, /v1/threads/*. |
webui/ |
Mark/Kimi_Agent_Brother_10_Digitizing_App | The ThreadCraft React/Vite SPA. |
Each component has its own repo, history, CI, and semver. This repo is the outer landing that expresses them as one product: shared docs, project-level deployment, and the coupling between submodule versions.
Project metadata
- Who it's for: SMB-pro embroidery shops — print-on-demand houses, promotional product shops, in-house corporate design teams. Operators running 1–10 embroidery machines currently paying $2–8k/seat for Wilcom/Hatch.
- Pricing (planned): $49 / $149 / $399 / wholesale tiers (see
backend/README.mdfor the full pitch). - Hardware: Brother Entrepreneur PR-10 (10-needle). PES and DST exports are the machine formats.
Quick start (local)
git clone https://forgejo.tail018ac4.ts.net/Mark/threadcrafter.git
cd threadcrafter
./scripts/bootstrap.sh
docker compose -f deploy/docker-compose.yml up --build
Then open http://localhost:8080.
The bootstrap script:
- Initialises submodules.
- Installs the
engine/repo into the backend's Python env in editable mode so local backend code can importeasystitchfrom the submodule working tree.
The compose stack brings up:
webui— Vite-built SPA served by nginx, with/api/easystitch/*proxied to the backend container.backend— FastAPI service on its internal port (not exposed to the host directly; the webui proxies all/v1/*traffic).
Development in a single submodule
Most work happens inside one submodule at a time. The outer repo's main is mostly frozen between deliberate submodule bumps. To work on the webui:
cd webui
npm install
npm run dev
# Vite dev server proxies /api/easystitch/* to localhost:8080 —
# start the backend separately (see backend/README.md) or use the
# outer compose stack.
For backend changes:
cd backend
source .venv/bin/activate # if you ran bootstrap.sh
uvicorn app:app --reload --port 8080
API contract
The backend's /v1/digitize, /v1/export, /v1/threads/resolve,
/v1/threads/catalog endpoints are the public surface between all
submodules. The full contract lives in
backend/docs/api.md. Pydantic models in
backend/models.py and the TypeScript client in
webui/src/lib/easystitch-client.ts must match.
Bumping the API is a major version event in the backend — it must
be coordinated with the webui (and any future clients) before the
bumped submodule version lands on main here.
Deploying
Project-level deployment artifacts live in deploy/:
deploy/docker-compose.yml— the canonical local "bring up everything" stack. Uses submodule paths for build contexts.
Per-submodule production deployment (node_hub manifests, wild/production
configs, etc.) continues to live in each submodule's own deploy/
directory. The backend deploys as its own node_hub app
(Mark/easystitch-service); the webui has its own per-submodule
production manifests (webui/deploy/web/, webui/deploy/actors/). This
outer repo is the integration point, not a replacement for those.
Versioning policy
This outer repo pins each submodule to a specific commit. A submodule bump is a deliberate change here, visible in PRs. CI for the outer repo rebuilds the compose stack and smoke-tests the integration.
The backend pins engine/ to a git tag in production (per
backend/README.md); the editable submodule install is a local-only
convenience so backend changes pick up engine changes immediately.
Layout
threadcrafter/
├── README.md ← you are here
├── docs/
│ └── architecture.md ← cross-cutting architecture notes
├── deploy/
│ └── docker-compose.yml ← canonical full-stack local compose
├── scripts/
│ └── bootstrap.sh ← submodule init + engine editable install
├── .gitmodules
├── engine/ → Mark/easystitch (submodule)
├── backend/ → Mark/easystitch-service (submodule)
└── webui/ → Mark/Kimi_Agent_Brother_10_Digitizing_App (submodule)
Related repos
Mark/easystitch— embroidery CAM engine (the algorithms).Mark/easystitch-service— FastAPI wrapper / contract / deployment surface.Mark/Kimi_Agent_Brother_10_Digitizing_App— ThreadCraft frontend.Mark/infrastructure— node_hub, tailnet, deployment infrastructure.
License
TBD. The easystitch engine inherits whatever license applies to its repo; the wrapper inherits that. The frontend license is set in its own README.