From c1d4001e9ac5f1d6da2e695f2ecc5582ffc42908 Mon Sep 17 00:00:00 2001 From: jlightner Date: Thu, 26 Mar 2026 06:46:20 +0000 Subject: [PATCH] =?UTF-8?q?docs:=20Rewrote=20README.md=20with=208=20sectio?= =?UTF-8?q?ns:=20quick=20start,=20repo=20structure,=20a=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - "README.md" GSD-Task: S02/T02 --- .gsd/event-log.jsonl | 1 + .gsd/milestones/M003/slices/S02/S02-PLAN.md | 2 +- .../M003/slices/S02/tasks/T01-VERIFY.json | 52 ++++ .../M003/slices/S02/tasks/T02-SUMMARY.md | 75 ++++++ .gsd/state-manifest.json | 40 ++- README.md | 247 +++++++++++++++++- 6 files changed, 394 insertions(+), 23 deletions(-) create mode 100644 .gsd/milestones/M003/slices/S02/tasks/T01-VERIFY.json create mode 100644 .gsd/milestones/M003/slices/S02/tasks/T02-SUMMARY.md diff --git a/.gsd/event-log.jsonl b/.gsd/event-log.jsonl index b37837a..864907d 100644 --- a/.gsd/event-log.jsonl +++ b/.gsd/event-log.jsonl @@ -38,3 +38,4 @@ {"cmd":"complete-slice","params":{"milestoneId":"M003","sliceId":"S01"},"ts":"2026-03-26T06:35:25.542Z","actor":"agent","hash":"165605976be6d69e","session_id":"49f8e0fe-34a0-4608-b519-eca93850ed7c"} {"cmd":"plan-slice","params":{"milestoneId":"M003","sliceId":"S02"},"ts":"2026-03-26T06:39:00.941Z","actor":"agent","hash":"24790b4f3bd69e22","session_id":"49f8e0fe-34a0-4608-b519-eca93850ed7c"} {"cmd":"complete-task","params":{"milestoneId":"M003","sliceId":"S02","taskId":"T01"},"ts":"2026-03-26T06:43:57.680Z","actor":"agent","hash":"bd4dc62bfd702053","session_id":"49f8e0fe-34a0-4608-b519-eca93850ed7c"} +{"cmd":"complete-task","params":{"milestoneId":"M003","sliceId":"S02","taskId":"T02"},"ts":"2026-03-26T06:46:18.215Z","actor":"agent","hash":"6adfe7bebac07a1a","session_id":"49f8e0fe-34a0-4608-b519-eca93850ed7c"} diff --git a/.gsd/milestones/M003/slices/S02/S02-PLAN.md b/.gsd/milestones/M003/slices/S02/S02-PLAN.md index b8f57e1..80692c4 100644 --- a/.gsd/milestones/M003/slices/S02/S02-PLAN.md +++ b/.gsd/milestones/M003/slices/S02/S02-PLAN.md @@ -20,7 +20,7 @@ - Estimate: 45m - Files: docker/Dockerfile.app, docker/nginx.conf, docker-compose.yml - Verify: docker compose build && docker compose up -d && sleep 12 && docker compose ps && curl -sf http://localhost:8000/engine/health && curl -sf http://localhost:3000/ | head -c 100 && curl -sf http://localhost:3000/engine/health && docker compose down -- [ ] **T02: Rewrite README.md with project overview, quick start, API reference, and usage docs** — Replace the placeholder README with comprehensive documentation covering: what Kerf is, quick start with Docker Compose, engine API reference (all 4 endpoints with request/response examples), font system explanation, preset system, engine standalone usage, repository structure, and known limitations. +- [x] **T02: Rewrote README.md with 8 sections: quick start, repo structure, all 4 API endpoints with parameter tables and curl examples, preset table, font system, standalone usage, dev setup, and known limitations** — Replace the placeholder README with comprehensive documentation covering: what Kerf is, quick start with Docker Compose, engine API reference (all 4 endpoints with request/response examples), font system explanation, preset system, engine standalone usage, repository structure, and known limitations. **Content outline:** 1. Project title + one-paragraph description diff --git a/.gsd/milestones/M003/slices/S02/tasks/T01-VERIFY.json b/.gsd/milestones/M003/slices/S02/tasks/T01-VERIFY.json new file mode 100644 index 0000000..b086135 --- /dev/null +++ b/.gsd/milestones/M003/slices/S02/tasks/T01-VERIFY.json @@ -0,0 +1,52 @@ +{ + "schemaVersion": 1, + "taskId": "T01", + "unitId": "M003/S02/T01", + "timestamp": 1774507440008, + "passed": true, + "discoverySource": "task-plan", + "checks": [ + { + "command": "docker compose build", + "exitCode": 0, + "durationMs": 1902, + "verdict": "pass" + }, + { + "command": "docker compose up -d", + "exitCode": 0, + "durationMs": 6395, + "verdict": "pass" + }, + { + "command": "sleep 12", + "exitCode": 0, + "durationMs": 12006, + "verdict": "pass" + }, + { + "command": "docker compose ps", + "exitCode": 0, + "durationMs": 80, + "verdict": "pass" + }, + { + "command": "curl -sf http://localhost:8000/engine/health", + "exitCode": 0, + "durationMs": 13, + "verdict": "pass" + }, + { + "command": "curl -sf http://localhost:3000/engine/health", + "exitCode": 0, + "durationMs": 14, + "verdict": "pass" + }, + { + "command": "docker compose down", + "exitCode": 0, + "durationMs": 1208, + "verdict": "pass" + } + ] +} diff --git a/.gsd/milestones/M003/slices/S02/tasks/T02-SUMMARY.md b/.gsd/milestones/M003/slices/S02/tasks/T02-SUMMARY.md new file mode 100644 index 0000000..bd5fc8f --- /dev/null +++ b/.gsd/milestones/M003/slices/S02/tasks/T02-SUMMARY.md @@ -0,0 +1,75 @@ +--- +id: T02 +parent: S02 +milestone: M003 +provides: [] +requires: [] +affects: [] +key_files: ["README.md"] +key_decisions: ["Documented all four engine endpoints with full parameter tables and curl examples", "Included preset comparison table with mode, epsilon, and usage notes for all 5 presets"] +patterns_established: [] +drill_down_paths: [] +observability_surfaces: [] +duration: "" +verification_result: "Ran task verification: grep -c '^## ' README.md confirms 8 H2 sections (≥6 required), grep checks confirm 'docker compose up', '/engine/trace', '/engine/simplify', '/engine/presets', and '/engine/health' are all present. All checks passed with exit code 0." +completed_at: 2026-03-26T06:46:18.173Z +blocker_discovered: false +--- + +# T02: Rewrote README.md with 8 sections: quick start, repo structure, all 4 API endpoints with parameter tables and curl examples, preset table, font system, standalone usage, dev setup, and known limitations + +> Rewrote README.md with 8 sections: quick start, repo structure, all 4 API endpoints with parameter tables and curl examples, preset table, font system, standalone usage, dev setup, and known limitations + +## What Happened +--- +id: T02 +parent: S02 +milestone: M003 +key_files: + - README.md +key_decisions: + - Documented all four engine endpoints with full parameter tables and curl examples + - Included preset comparison table with mode, epsilon, and usage notes for all 5 presets +duration: "" +verification_result: passed +completed_at: 2026-03-26T06:46:18.181Z +blocker_discovered: false +--- + +# T02: Rewrote README.md with 8 sections: quick start, repo structure, all 4 API endpoints with parameter tables and curl examples, preset table, font system, standalone usage, dev setup, and known limitations + +**Rewrote README.md with 8 sections: quick start, repo structure, all 4 API endpoints with parameter tables and curl examples, preset table, font system, standalone usage, dev setup, and known limitations** + +## What Happened + +Read all source files (routes.py, preset JSONs, fontService.ts, Dockerfiles, docker-compose.yml) to extract accurate API signatures, parameter defaults, preset configurations, and bundled font metadata. Wrote a comprehensive 253-line README.md replacing the placeholder with: project description, Docker Compose quick start, repository structure tree, engine API reference documenting all 4 endpoints with full parameter tables and curl examples, preset comparison table with all 5 presets, font system explanation, standalone engine usage, development setup for engine and app, and known limitations. + +## Verification + +Ran task verification: grep -c '^## ' README.md confirms 8 H2 sections (≥6 required), grep checks confirm 'docker compose up', '/engine/trace', '/engine/simplify', '/engine/presets', and '/engine/health' are all present. All checks passed with exit code 0. + +## Verification Evidence + +| # | Command | Exit Code | Verdict | Duration | +|---|---------|-----------|---------|----------| +| 1 | `grep -c '^## ' README.md | xargs test 6 -le && grep -q 'docker compose up' README.md && grep -q '/engine/trace' README.md && grep -q '/engine/simplify' README.md && grep -q '/engine/presets' README.md && grep -q '/engine/health' README.md && echo 'README OK'` | 0 | ✅ pass | 50ms | + + +## Deviations + +None. + +## Known Issues + +None. + +## Files Created/Modified + +- `README.md` + + +## Deviations +None. + +## Known Issues +None. diff --git a/.gsd/state-manifest.json b/.gsd/state-manifest.json index f798dd3..ef740b2 100644 --- a/.gsd/state-manifest.json +++ b/.gsd/state-manifest.json @@ -1,6 +1,6 @@ { "version": 1, - "exported_at": "2026-03-26T06:43:57.678Z", + "exported_at": "2026-03-26T06:46:18.213Z", "milestones": [ { "id": "M001", @@ -1677,19 +1677,24 @@ "milestone_id": "M003", "slice_id": "S02", "id": "T02", - "title": "Rewrite README.md with project overview, quick start, API reference, and usage docs", - "status": "pending", - "one_liner": "", - "narrative": "", - "verification_result": "", + "title": "Rewrote README.md with 8 sections: quick start, repo structure, all 4 API endpoints with parameter tables and curl examples, preset table, font system, standalone usage, dev setup, and known limitations", + "status": "complete", + "one_liner": "Rewrote README.md with 8 sections: quick start, repo structure, all 4 API endpoints with parameter tables and curl examples, preset table, font system, standalone usage, dev setup, and known limitations", + "narrative": "Read all source files (routes.py, preset JSONs, fontService.ts, Dockerfiles, docker-compose.yml) to extract accurate API signatures, parameter defaults, preset configurations, and bundled font metadata. Wrote a comprehensive 253-line README.md replacing the placeholder with: project description, Docker Compose quick start, repository structure tree, engine API reference documenting all 4 endpoints with full parameter tables and curl examples, preset comparison table with all 5 presets, font system explanation, standalone engine usage, development setup for engine and app, and known limitations.", + "verification_result": "Ran task verification: grep -c '^## ' README.md confirms 8 H2 sections (≥6 required), grep checks confirm 'docker compose up', '/engine/trace', '/engine/simplify', '/engine/presets', and '/engine/health' are all present. All checks passed with exit code 0.", "duration": "", - "completed_at": null, + "completed_at": "2026-03-26T06:46:18.173Z", "blocker_discovered": false, - "deviations": "", - "known_issues": "", - "key_files": [], - "key_decisions": [], - "full_summary_md": "", + "deviations": "None.", + "known_issues": "None.", + "key_files": [ + "README.md" + ], + "key_decisions": [ + "Documented all four engine endpoints with full parameter tables and curl examples", + "Included preset comparison table with mode, epsilon, and usage notes for all 5 presets" + ], + "full_summary_md": "---\nid: T02\nparent: S02\nmilestone: M003\nkey_files:\n - README.md\nkey_decisions:\n - Documented all four engine endpoints with full parameter tables and curl examples\n - Included preset comparison table with mode, epsilon, and usage notes for all 5 presets\nduration: \"\"\nverification_result: passed\ncompleted_at: 2026-03-26T06:46:18.181Z\nblocker_discovered: false\n---\n\n# T02: Rewrote README.md with 8 sections: quick start, repo structure, all 4 API endpoints with parameter tables and curl examples, preset table, font system, standalone usage, dev setup, and known limitations\n\n**Rewrote README.md with 8 sections: quick start, repo structure, all 4 API endpoints with parameter tables and curl examples, preset table, font system, standalone usage, dev setup, and known limitations**\n\n## What Happened\n\nRead all source files (routes.py, preset JSONs, fontService.ts, Dockerfiles, docker-compose.yml) to extract accurate API signatures, parameter defaults, preset configurations, and bundled font metadata. Wrote a comprehensive 253-line README.md replacing the placeholder with: project description, Docker Compose quick start, repository structure tree, engine API reference documenting all 4 endpoints with full parameter tables and curl examples, preset comparison table with all 5 presets, font system explanation, standalone engine usage, development setup for engine and app, and known limitations.\n\n## Verification\n\nRan task verification: grep -c '^## ' README.md confirms 8 H2 sections (≥6 required), grep checks confirm 'docker compose up', '/engine/trace', '/engine/simplify', '/engine/presets', and '/engine/health' are all present. All checks passed with exit code 0.\n\n## Verification Evidence\n\n| # | Command | Exit Code | Verdict | Duration |\n|---|---------|-----------|---------|----------|\n| 1 | `grep -c '^## ' README.md | xargs test 6 -le && grep -q 'docker compose up' README.md && grep -q '/engine/trace' README.md && grep -q '/engine/simplify' README.md && grep -q '/engine/presets' README.md && grep -q '/engine/health' README.md && echo 'README OK'` | 0 | ✅ pass | 50ms |\n\n\n## Deviations\n\nNone.\n\n## Known Issues\n\nNone.\n\n## Files Created/Modified\n\n- `README.md`\n", "description": "Replace the placeholder README with comprehensive documentation covering: what Kerf is, quick start with Docker Compose, engine API reference (all 4 endpoints with request/response examples), font system explanation, preset system, engine standalone usage, repository structure, and known limitations.\n\n**Content outline:**\n1. Project title + one-paragraph description\n2. Quick Start — `docker compose up`, then visit localhost:3000\n3. Repository Structure — engine/, app/, docker/ directories\n4. Engine API Reference — document all 4 endpoints:\n - `GET /engine/health` — healthcheck\n - `GET /engine/presets` — list available presets\n - `POST /engine/trace` — raster-to-vector with preprocessing+vectorization+postprocessing\n - `POST /engine/simplify` — SVG simplification with optional DXF export (units, scale_factor)\n5. Font System — bundled fonts (Lato, OpenSans, Roboto), text-to-path conversion\n6. Presets — 5 built-in presets (sign, patch, stencil, detailed, custom), how they work\n7. Engine Standalone Usage — running engine independently, Docker image, API examples\n8. Development — local setup for engine (Python venv) and app (npm), dev proxy setup\n9. Known Limitations\n\n**Sources for API details:** `engine/api/routes.py` for endpoint signatures, `engine/presets/*.json` for preset list, `app/src/utils/fontService.ts` for font system.", "estimate": "30m", "files": [ @@ -2420,6 +2425,17 @@ "verdict": "✅ pass", "duration_ms": 3000, "created_at": "2026-03-26T06:43:57.639Z" + }, + { + "id": 55, + "task_id": "T02", + "slice_id": "S02", + "milestone_id": "M003", + "command": "grep -c '^## ' README.md | xargs test 6 -le && grep -q 'docker compose up' README.md && grep -q '/engine/trace' README.md && grep -q '/engine/simplify' README.md && grep -q '/engine/presets' README.md && grep -q '/engine/health' README.md && echo 'README OK'", + "exit_code": 0, + "verdict": "✅ pass", + "duration_ms": 50, + "created_at": "2026-03-26T06:46:18.174Z" } ] } \ No newline at end of file diff --git a/README.md b/README.md index 91a5596..530aa1f 100644 --- a/README.md +++ b/README.md @@ -1,26 +1,253 @@ # Kerf -Modular raster-to-vector conversion engine + 2D sign/patch design canvas. +Modular raster-to-vector conversion engine paired with a 2D sign and patch design canvas. Upload a raster image (PNG, JPEG, BMP), trace it into clean vector paths using Potrace or VTracer, and export as SVG or DXF — ready for CNC routers, vinyl cutters, laser engravers, and embroidery machines. + +## Quick Start + +```bash +docker compose up -d +``` + +Once both services are healthy: + +- **Web App** → [http://localhost:3000](http://localhost:3000) +- **Engine API** → [http://localhost:8000/engine/health](http://localhost:8000/engine/health) +- **Interactive API Docs** → [http://localhost:8000/docs](http://localhost:8000/docs) + +Check service health: + +```bash +docker compose ps +``` + +Tear down: + +```bash +docker compose down +``` ## Repository Structure ``` -engine/ — Kerf Engine (standalone API, Python/FastAPI) -app/ — Kerf App frontend (React) [future] -server/ — Kerf App backend API [future] -docker/ — Dockerfiles and compose configs [future] +engine/ Kerf Engine — standalone Python/FastAPI vectorization API + api/ API route definitions + pipeline/ Preprocessing, vectorization, and post-processing stages + output/ SVG, DXF, and JSON output generators + presets/ Built-in preset configurations (JSON) + tests/ Engine test suite (pytest) +app/ Kerf App — React/TypeScript design canvas (Vite + Konva) + src/ Application source code + public/ Static assets including bundled fonts +docker/ Dockerfiles and nginx configuration + Dockerfile.engine Multi-stage build for the engine (Python 3.11) + Dockerfile.app Multi-stage build for the app (Node 22 → nginx 1.27) + nginx.conf SPA routing + /engine reverse-proxy +docker-compose.yml Full-stack orchestration with healthchecks ``` -## Kerf Engine +## Engine API Reference -The engine is a self-contained FastAPI service that accepts raster images and returns clean vector output (SVG, DXF). +The engine exposes four endpoints under the `/engine` prefix. All endpoints accept and return JSON unless otherwise noted. -### Quick Start +### `GET /engine/health` + +Healthcheck endpoint for container orchestration. + +**Response:** + +```json +{ "status": "ok" } +``` + +### `GET /engine/presets` + +List all available presets and their parameter values. + +**Response:** + +```json +{ + "presets": { + "sign": { "name": "sign", "description": "Metal signage, bold text cutouts", "..." : "..." }, + "patch": { "name": "patch", "description": "Embroidered patches, fabric cutting", "..." : "..." } + } +} +``` + +### `POST /engine/trace` + +Convert a raster image to vector output through the full preprocessing → vectorization → post-processing pipeline. + +**Content-Type:** `multipart/form-data` + +| Field | Type | Default | Description | +|-----------------|--------|------------|-------------| +| `file` | file | (required) | Raster image (PNG, JPEG, BMP) | +| `mode` | string | from preset | Vectorization engine: `potrace` or `vtracer` | +| `output_format` | string | `svg` | Output format: `svg`, `dxf`, or `json` | +| `preset` | string | `sign` | Preset name (see [Presets](#presets)) | +| `params` | string | `{}` | JSON string of parameter overrides | + +**Example — trace with the sign preset:** + +```bash +curl -X POST http://localhost:8000/engine/trace \ + -F file=@logo.png \ + -F preset=sign \ + -F output_format=svg +``` + +**Example — trace with custom parameters:** + +```bash +curl -X POST http://localhost:8000/engine/trace \ + -F file=@photo.jpg \ + -F preset=detailed \ + -F mode=vtracer \ + -F 'params={"filter_speckle": 4, "epsilon": 0.3}' +``` + +**Response (SVG/JSON formats):** + +```json +{ + "output": "...", + "format": "svg", + "metadata": { + "format": "svg", + "path_count": 12, + "node_count_total": 483, + "open_paths": 0, + "island_count": 2, + "warnings": [], + "processing_ms": 142.57 + } +} +``` + +**Response (DXF format):** Raw DXF bytes with `Content-Type: application/dxf` and metadata in the `X-Kerf-Metadata` response header. + +### `POST /engine/simplify` + +Simplify an existing SVG using Ramer–Douglas–Peucker path simplification. Optionally export to DXF with unit and scale control. + +**Content-Type:** `multipart/form-data` + +| Field | Type | Default | Description | +|-----------------|--------|------------|-------------| +| `file` | file | (required) | SVG file to simplify | +| `epsilon` | float | `1.0` | RDP simplification tolerance (higher = fewer points) | +| `output_format` | string | `svg` | Output format: `svg`, `dxf`, or `json` | +| `units` | string | none | DXF unit metadata: `inches` or `mm` | +| `scale_factor` | float | `1.0` | DXF coordinate scale factor | + +**Example — simplify and export to DXF in millimeters:** + +```bash +curl -X POST http://localhost:8000/engine/simplify \ + -F file=@drawing.svg \ + -F epsilon=2.0 \ + -F output_format=dxf \ + -F units=mm \ + -F scale_factor=25.4 +``` + +## Presets + +Presets bundle tuned parameter sets for each pipeline stage — preprocessing, vectorization, and post-processing — optimized for specific use cases. + +| Preset | Description | Mode | Epsilon | Notes | +|------------|------------------------------------|----------|---------|-------| +| `sign` | Metal signage, bold text cutouts | potrace | 2.5 | Aggressive denoising, auto-close enabled | +| `patch` | Embroidered patches, fabric cutting| potrace | 1.0 | Moderate smoothing, fine detail retention | +| `stencil` | Physical stencil cutting | potrace | 3.0 | Heavy simplification, fixed threshold at 128 | +| `detailed` | High-fidelity illustration work | potrace | 0.5 | Minimal smoothing, preserves fine curves | +| `custom` | All params exposed, no defaults | potrace | — | Pass all parameters explicitly via `params` | + +Use the `params` field on `/engine/trace` to override any preset value. For example, to use the `sign` preset but switch to VTracer mode: + +```bash +curl -X POST http://localhost:8000/engine/trace \ + -F file=@image.png \ + -F preset=sign \ + -F 'params={"mode": "vtracer"}' +``` + +## Font System + +The web app bundles three fonts for text-to-path conversion, enabling text elements to be converted to SVG outlines for cutting/engraving: + +| Font | File | +|------------|-------------------------| +| Roboto | `Roboto-Regular.ttf` | +| Open Sans | `OpenSans-Regular.ttf` | +| Lato | `Lato-Regular.ttf` | + +Fonts are parsed client-side using [opentype.js](https://opentype.js.org/) and converted to SVG path data with configurable font size and letter spacing. The conversion handles glyph positioning, coordinate system flipping, and path assembly — no server round-trip required. + +## Engine Standalone Usage + +The engine runs independently of the web app. Use it as a standalone API service or build just the engine Docker image: + +**Docker (standalone):** + +```bash +docker build -f docker/Dockerfile.engine -t kerf-engine . +docker run -p 8000:8000 kerf-engine +``` + +**Local development (Python):** ```bash cd engine +python -m venv .venv +source .venv/bin/activate pip install -e ".[dev]" -uvicorn main:app --host 0.0.0.0 --port 8000 +uvicorn main:app --host 0.0.0.0 --port 8000 --reload ``` -API docs available at `http://localhost:8000/docs`. +API docs are available at [http://localhost:8000/docs](http://localhost:8000/docs) (Swagger UI) and [http://localhost:8000/redoc](http://localhost:8000/redoc) (ReDoc). + +## Development + +### Engine (Python) + +```bash +cd engine +python -m venv .venv +source .venv/bin/activate +pip install -e ".[dev]" + +# Run the API server with auto-reload +uvicorn main:app --host 0.0.0.0 --port 8000 --reload + +# Run tests +pytest +``` + +System dependencies for pypotrace: `libpotrace-dev`, `libpotrace0`, `libagg-dev` (Debian/Ubuntu). + +### App (React/TypeScript) + +```bash +npm install +npm run dev --workspace=app +``` + +The Vite dev server proxies `/engine/*` requests to `http://localhost:8000` — start the engine first for full functionality. + +### Full Stack (Docker Compose) + +```bash +docker compose up --build +``` + +The app is served on port 3000 with nginx reverse-proxying `/engine/*` to the engine container. + +## Known Limitations + +- **Single-image processing** — the engine processes one image per request; batch endpoints are not yet available. +- **Binary vectorization only** — both Potrace and VTracer operate in binary (black/white) mode; color/multi-layer tracing is not supported. +- **No authentication** — the API is open; add a reverse proxy with auth for production deployments. +- **Font selection** — the app ships with three bundled fonts; custom font upload is not yet supported. +- **DXF fidelity** — DXF export covers basic polyline geometry; advanced CAD features (layers, blocks, hatches) are not included.