CallMeDaniel Claude Opus 4.6 (1M context) commited on
Commit
dacf755
·
1 Parent(s): 7d49731

docs: add generation pipeline, 3MF export, and download panel to planning spec

Browse files
docs/superpowers/specs/2026-04-12-planning-review-gate-design.md CHANGED
@@ -374,35 +374,203 @@ When the scoring threshold triggers in chat mode, an interactive plan card appea
374
  - Only one plan card active at a time
375
  - All labels go through `I18N` / `t()` for i18n support
376
 
377
- ## Files Changed
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
378
 
379
  | File | Change |
380
  |------|--------|
381
  | `agents/design_state.py` | Add `phase`, `plan` fields to `DesignState`; add `DesignPlan` model; add `compute_score()` function |
382
  | `agents/crew_orchestrator.py` | Add phase branching, plan generation, plan trigger keyword detection, approved-phase context injection, routing override |
383
- | `agents/base.py` | No changes (interface unchanged) |
384
  | `config/settings.py` | Add `PlanningConfig` model, add `planning` field to `Settings` |
385
  | `config/config.yaml` | Add `planning` section with threshold, weights, caps, keywords, approved_agents |
386
- | `server/routes.py` | Add `POST /api/plan/approve` and `POST /api/plan/reject` endpoints; add `PlanApproveRequest`, `PlanRejectRequest` models |
387
- | `web/index.html` | Add tab switcher, guided wizard UI, plan card component, state sync logic, i18n entries |
 
 
388
 
389
  ## Files Not Changed
390
 
391
  | File | Reason |
392
  |------|--------|
393
  | `agents/orchestrator.py` (MockChatBackend) | Mock backend does not need planning — it's for testing only |
 
394
  | `agents/routing.py` | Routing logic unchanged; override happens in orchestrator |
395
  | `agents/definitions.py` | No new agents |
396
  | `agents/tools.py` | No new tools |
397
- | `core/executor.py` | Execution pipeline unchanged |
398
  | `core/validator.py` | Validation unchanged |
399
- | `core/cam.py` | CAM pipeline unchanged |
400
 
401
  ## Testing Strategy
402
 
403
  - **Unit tests for `compute_score()`** — verify scoring with various `DesignState` configurations, cap behavior, threshold edge cases
404
  - **Unit tests for plan generation** — verify `DesignPlan` is correctly synthesized from `DesignState`
405
  - **Unit tests for phase transitions** — verify all state machine transitions (exploring->planning->approved, approved->exploring on NOT READY, etc.)
 
406
  - **Integration test for `chat_turn` with planning** — verify auto-trigger when score crosses threshold, verify manual trigger via keywords, verify approved phase routes to CAD+CNC
407
- - **API tests** — verify `/api/plan/approve` and `/api/plan/reject` endpoints
408
- - **Frontend manual testing** — tab switching, wizard step navigation, state sync between tabs, plan card approve/reject, i18n
 
 
374
  - Only one plan card active at a time
375
  - All labels go through `I18N` / `t()` for i18n support
376
 
377
+ ## Generation Pipeline (Post-Approval)
378
+
379
+ When `phase == "approved"` and the chat turn runs with CAD + CNC agents, the orchestrator executes a full generation pipeline. This is not a new pipeline — it's the existing flow, but now it only runs after explicit user approval.
380
+
381
+ ### Generation Steps
382
+
383
+ ```
384
+ Plan approved (phase = "approved")
385
+ |
386
+ v
387
+ 1. CAD GENERATION
388
+ - CAD agent receives approved plan in context
389
+ - Generates CadQuery code
390
+ - Executor runs code -> cq.Workplane result
391
+ - Geometry metadata extracted (volume, bbox, faces, edges)
392
+ |
393
+ v
394
+ 2. EXPORT 3D FILES
395
+ - STEP export: output/{part_name}.step (precision CAD format)
396
+ - STL export: output/{part_name}.stl (mesh for 3D preview)
397
+ - 3MF export: output/{part_name}.3mf (slicer-ready format)
398
+ |
399
+ v
400
+ 3. CNC VALIDATION
401
+ - Manufacturability check (wall thickness, pocket depth, undercuts)
402
+ - Axis recommendation (3-axis / 3+2 / 5-axis)
403
+ - Issues list (errors + warnings)
404
+ |
405
+ v
406
+ 4. CAM / G-CODE GENERATION
407
+ - CAM agent creates machining plan (operations, tool config, post-processor)
408
+ - core/cam.py generates G-code from shape + plan
409
+ - G-code saved to output/{part_name}.gcode
410
+ |
411
+ v
412
+ 5. 3D PREVIEW
413
+ - STL loaded into Three.js viewport
414
+ - G-code toolpath rendered as 3D lines (if generated)
415
+ - View toggle: Part / Toolpath / Overlay
416
+ |
417
+ v
418
+ 6. DOWNLOADS AVAILABLE
419
+ - All export files served and download buttons shown
420
+ ```
421
+
422
+ ### 3MF Export (New)
423
+
424
+ CadQuery supports 3MF via OCCT. Add `export_3mf()` to `core/executor.py`:
425
+
426
+ ```python
427
+ def export_3mf(result: cq.Workplane, path: str | Path) -> Path:
428
+ """Export a CadQuery workplane to 3MF format (slicer-ready)."""
429
+ path = Path(path)
430
+ cq.exporters.export(result, str(path), exportType="3MF")
431
+ return path
432
+ ```
433
+
434
+ Update `export_all()` to include 3MF:
435
+
436
+ ```python
437
+ def export_all(result: cq.Workplane, base_path: str | Path) -> dict[str, Path]:
438
+ """Export to STEP, STL, and 3MF."""
439
+ base = Path(base_path)
440
+ return {
441
+ "step": export_step(result, base.with_suffix(".step")),
442
+ "stl": export_stl(result, base.with_suffix(".stl")),
443
+ "3mf": export_3mf(result, base.with_suffix(".3mf")),
444
+ }
445
+ ```
446
+
447
+ ### New Endpoint: GET /api/models/{name}.3mf
448
+
449
+ ```python
450
+ @app.get("/api/models/{name}.3mf")
451
+ async def get_3mf(name: str):
452
+ path = OUTPUT_DIR / f"{name}.3mf"
453
+ if not path.exists():
454
+ return JSONResponse({"error": f"3MF not found: {name}"}, status_code=404)
455
+ return FileResponse(path, media_type="model/3mf", filename=f"{name}.3mf")
456
+ ```
457
+
458
+ ### Updated Preview Response
459
+
460
+ The preview response returned after generation includes all file URLs:
461
+
462
+ ```json
463
+ {
464
+ "success": true,
465
+ "part_name": "bracket",
466
+ "stl_url": "/api/models/bracket.stl",
467
+ "step_url": "/api/models/bracket.step",
468
+ "threemf_url": "/api/models/bracket.3mf",
469
+ "gcode_url": "/api/models/bracket.gcode",
470
+ "execution": {
471
+ "success": true,
472
+ "volume_mm3": 48000,
473
+ "bounding_box_mm": [60, 40, 20],
474
+ "face_count": 14,
475
+ "edge_count": 24
476
+ },
477
+ "validation": {
478
+ "machinable": true,
479
+ "axis_recommendation": "3-axis",
480
+ "issues": [],
481
+ "error_count": 0,
482
+ "warning_count": 0
483
+ },
484
+ "cam": {
485
+ "success": true,
486
+ "operations": ["adaptive", "profile"],
487
+ "tool_config": {"diameter": 6, "h_feed": 800, "v_feed": 200, "speed": 18000},
488
+ "post_processor": "grbl"
489
+ }
490
+ }
491
+ ```
492
+
493
+ ### Download Panel (Updated)
494
+
495
+ The existing download buttons panel gains a 3MF button and is reorganized by purpose:
496
+
497
+ ```
498
+ +------------------------------------------+
499
+ | DOWNLOADS |
500
+ | |
501
+ | 3D Files: |
502
+ | [STEP] [STL] [3MF] |
503
+ | |
504
+ | CNC Files: |
505
+ | [G-CODE] |
506
+ | |
507
+ | Documentation: |
508
+ | [REPORT] |
509
+ +------------------------------------------+
510
+ ```
511
+
512
+ - **STEP** — precision CAD interchange format (for CAD software)
513
+ - **STL** — triangulated mesh (for 3D printing, basic viewing)
514
+ - **3MF** — slicer-ready format (for Cura, PrusaSlicer, Bambu Studio)
515
+ - **G-CODE** — CNC machining program (only visible when CAM has run)
516
+ - **REPORT** — design report JSON
517
+
518
+ Each button is only visible when its corresponding file exists. The G-CODE button remains hidden until CAM generation succeeds. The 3MF button is always shown alongside STL (both are generated by `export_all`).
519
+
520
+ ### Gallery Card Downloads
521
+
522
+ Gallery cards also updated to show all available formats:
523
+
524
+ ```html
525
+ <div class="gallery-card-downloads">
526
+ <a href="/api/models/{name}.step" download>STEP</a>
527
+ <a href="/api/models/{name}.stl" download>STL</a>
528
+ <a href="/api/models/{name}.3mf" download>3MF</a>
529
+ <a href="/api/models/{name}.gcode" download>GCODE</a>
530
+ </div>
531
+ ```
532
+
533
+ ### 3D Preview Behavior
534
+
535
+ After generation, the 3D viewer automatically:
536
+ 1. Loads the STL into the Three.js viewport
537
+ 2. If G-code exists, parses and renders toolpath lines (existing G-code preview feature)
538
+ 3. Shows view toggle buttons: Part / Toolpath / Overlay
539
+ 4. Shows geometry stats (volume, bounding box, face count)
540
+ 5. Shows CNC validation badge (machinable / warnings / errors)
541
+
542
+ ## Files Changed (Updated)
543
 
544
  | File | Change |
545
  |------|--------|
546
  | `agents/design_state.py` | Add `phase`, `plan` fields to `DesignState`; add `DesignPlan` model; add `compute_score()` function |
547
  | `agents/crew_orchestrator.py` | Add phase branching, plan generation, plan trigger keyword detection, approved-phase context injection, routing override |
 
548
  | `config/settings.py` | Add `PlanningConfig` model, add `planning` field to `Settings` |
549
  | `config/config.yaml` | Add `planning` section with threshold, weights, caps, keywords, approved_agents |
550
+ | `server/routes.py` | Add `POST /api/plan/approve` and `POST /api/plan/reject` endpoints |
551
+ | `server/web.py` | Add `GET /api/models/{name}.3mf` endpoint |
552
+ | `core/executor.py` | Add `export_3mf()` function; update `export_all()` to include 3MF |
553
+ | `web/index.html` | Add tab switcher, guided wizard UI, plan card component, state sync, download panel with 3MF button, gallery card 3MF download, i18n entries |
554
 
555
  ## Files Not Changed
556
 
557
  | File | Reason |
558
  |------|--------|
559
  | `agents/orchestrator.py` (MockChatBackend) | Mock backend does not need planning — it's for testing only |
560
+ | `agents/base.py` | Interface unchanged |
561
  | `agents/routing.py` | Routing logic unchanged; override happens in orchestrator |
562
  | `agents/definitions.py` | No new agents |
563
  | `agents/tools.py` | No new tools |
 
564
  | `core/validator.py` | Validation unchanged |
565
+ | `core/cam.py` | CAM pipeline unchanged — already generates G-code when CAM agent is active |
566
 
567
  ## Testing Strategy
568
 
569
  - **Unit tests for `compute_score()`** — verify scoring with various `DesignState` configurations, cap behavior, threshold edge cases
570
  - **Unit tests for plan generation** — verify `DesignPlan` is correctly synthesized from `DesignState`
571
  - **Unit tests for phase transitions** — verify all state machine transitions (exploring->planning->approved, approved->exploring on NOT READY, etc.)
572
+ - **Unit tests for `export_3mf()`** — verify 3MF export produces valid file
573
  - **Integration test for `chat_turn` with planning** — verify auto-trigger when score crosses threshold, verify manual trigger via keywords, verify approved phase routes to CAD+CNC
574
+ - **Integration test for generation pipeline** — verify that approved phase produces all outputs: STEP, STL, 3MF, G-code (when CAM active), validation results
575
+ - **API tests** — verify `/api/plan/approve`, `/api/plan/reject`, and `/api/models/{name}.3mf` endpoints
576
+ - **Frontend manual testing** — tab switching, wizard step navigation, state sync between tabs, plan card approve/reject, download buttons visibility (STEP/STL/3MF always, G-CODE only after CAM), gallery card downloads, i18n