Repository navigation
The Asset Contract
Any plugin that needs a 3D model asks for it through one folder: polywright fills it, the caller reads manifest.json and takes files from out/. The full description is in the hub skill's contract.md.
<asset>/
brief.md what, why, targets, real size, must-haves, can-skips
manifest.json the contract
refs/ reference images, blueprints, measured photos, textures
work/ .blend files and intermediates; generator runs leave *.gen.json beside their output
out/ deliverables, one or more per target
renders/ review sheets per step
pw.py new makes it:
python pw.py new fountain --name Fountain --kind imagined --route generate --targets game-roblox,print-fdm --real-size-m 1.0{
"ok": true,
"dir": "fountain",
"manifest": "fountain\\manifest.json",
"layout": {
"refs/": "reference images, blueprints, textures (each listed in sources)",
"work/": ".blend and intermediates",
"out/": "deliverables, one per target",
"renders/": "review sheets"
}
}
Exit code 0.
python pw.py manifest fountain --add-output park/solid.stl --target print-fdm
python pw.py manifest fountain --add-source https://example.com/ref.png --what "reference photo" --author "A. Person"
python pw.py manifest fountain --validate{
"ok": true,
"manifest": "fountain\\manifest.json",
"status": "brief",
"outputs": 1,
"sources": 0,
"problems": []
}
Exit code 0.
Each output entry holds its path relative to the folder, the target, a SHA-256, its size, and with --inspect its triangles, size, watertightness and materials. --validate reports outputs missing on disk and outputs whose hash changed since they were recorded.
A source without a licence is kept and reported until it has one:
{
"ok": false,
"manifest": "fountain\\manifest.json",
"status": "brief",
"outputs": 1,
"sources": 1,
"problems": [
"source without a licence: https://example.com/ref.png"
]
}
Exit code 1.
| Field | Values |
|---|---|
kind |
real, imagined, hybrid |
route |
found, capture, place, generate, procedural, cad, hand, mixed |
targets |
the names from pw.py check --list
|
units |
m; print targets are in mm |
up |
+Z in .blend, +Y in glTF |
sources |
what, url, author, licence, retrieved |
tools |
name and version of every tool or AI model that made a part (--add-tool, --tool-version) |
outputs |
path, target, sha256, bytes, added, and inspect figures |
reviews |
render, verdict, by |
status |
brief, references, blockout, model, review, delivered |
tools is what answers the AI-disclosure questions stores ask (Fab, Sketchfab, the Unity Asset Store, Steam, MakerWorld).
| Caller | Target | Takes |
|---|---|---|
| a three.js page (threewright) | web-threejs | a GLB with meshopt or Draco and KTX2 textures |
| film and AI video (cinewright) | video-blockout | a blockout at real scale, turntables, depth and normal passes |
| a Roblox place (roblox-agent) | game-roblox | a mesh per MeshPart under 20,000 triangles, or a place's scene.glb and place.json
|
| a Unity project (unity-agent) | game-unity | a GLB, or an FBX with baked axes, with LODs |
| a printer or slicer skill | print-fdm, print-resin | a watertight STL in mm and a 3MF |
This wiki describes polywright 0.1.2 and was last updated on 2026-10-11. The plugin is MIT licensed. Report problems in the issues.
Using it
- Getting started
- The skills
- Commands
- How checks decide
- The asset contract
- Errors and edge cases
- Recipes
- FAQ
The releases
Contributing
Elsewhere