@drawcall/design 0.13.1 → 0.13.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,2 +1,2 @@
1
- export declare const mcpDesignSkill = "---\nname: drawcall-design\ndescription: Create, modify, inspect, compose, and reuse GLTS scenes, Markdown documents, and image or Market references in Drawcall Design. Use whenever the user names Drawcall Design or one of its projects, canvases, frames, filesystems, GLTS assets, or Markdown frames. Do not use for full games, applications, or unrelated image generation.\n---\n\n# Drawcall Design\n\n## MCP transport\n\nMCP tools are the Drawcall transport in this environment. For Design operations, use only the tools documented here. A failed tool call does not make the transport unavailable.\n\nImage frame creation uses a public HTTP(S) image URL.\n\nUse `generate_design_image` only when the user asks for a 2D image or reference. Its references must be public HTTP(S) URLs. A 3D object, scene, or reusable asset is GLTS work, even when the user calls its canvas container a frame.\n\nTool arguments are JSON objects. `create_design_frame` takes the root file of a glts or markdown frame as `text`, and `create_design_frame`, `write_design_file`, and `edit_design_file` take `imports`, the bounding box of each contextually loaded `.glts` file that does not exist yet, keyed by its URL specifier as written. The create result includes the new frame ID that later paths start with. File tools identify their target with `project` and a project-absolute `path`; they do not accept a separate `frame` argument. Call `list_design_files` and pass one of its returned paths unchanged.\n\nFor comments, call `list_design_comments` and, when needed, `get_design_comment` before changing a thread. Use `create_design_comment`, `reply_to_design_comment`, `resolve_design_comment`, `reopen_design_comment`, and `delete_design_comment` for their named operations. Structured tool calls use `body` for comment text. A positioned create requires the target frame's current `contentRevision` as `expectedContentRevision`; list frames again and re-inspect the position after a conflict.\n\n```json\n[\n {\n \"tool\": \"list_design_projects\",\n \"arguments\": {}\n },\n {\n \"tool\": \"list_design_frames\",\n \"arguments\": {\n \"project\": \"r6z2n9k4x8m1qc\"\n }\n },\n {\n \"tool\": \"create_design_frame\",\n \"arguments\": {\n \"project\": \"r6z2n9k4x8m1qc\",\n \"name\": \"Racecar\",\n \"type\": \"glts\",\n \"width\": 1280,\n \"height\": 800,\n \"text\": \"import { gltsLoader, scene } from \\\"@drawcall/glts\\\";\\n\\nconst wheel = await gltsLoader.loadAsync(\\n new URL(\\\"./parts/wheel.glts\\\", import.meta.url),\\n);\\nscene.add(wheel);\\n\",\n \"imports\": {\n \"./parts/wheel.glts\": {\n \"min\": [\n -0.5,\n 0,\n -0.5\n ],\n \"max\": [\n 0.5,\n 1,\n 0.5\n ]\n }\n }\n }\n },\n {\n \"tool\": \"write_design_file\",\n \"arguments\": {\n \"project\": \"r6z2n9k4x8m1qc\",\n \"path\": \"/a4z8m2q7v9kcde/parts/wheel.glts\",\n \"text\": \"import * as THREE from \\\"three\\\";\\nimport { onDispose, scene } from \\\"@drawcall/glts\\\";\\n\\nconst geometry = new THREE.TorusGeometry(0.4, 0.12, 16, 48);\\nconst material = new THREE.MeshStandardMaterial({ color: 0x222222 });\\nscene.add(new THREE.Mesh(geometry, material));\\n\\nonDispose(() => {\\n geometry.dispose();\\n material.dispose();\\n});\\n\"\n }\n },\n {\n \"tool\": \"list_design_files\",\n \"arguments\": {\n \"project\": \"r6z2n9k4x8m1qc\"\n }\n },\n {\n \"tool\": \"read_design_file\",\n \"arguments\": {\n \"project\": \"r6z2n9k4x8m1qc\",\n \"path\": \"/a4z8m2q7v9kcde/index.glts\"\n }\n },\n {\n \"tool\": \"edit_design_file\",\n \"arguments\": {\n \"project\": \"r6z2n9k4x8m1qc\",\n \"path\": \"/a4z8m2q7v9kcde/index.glts\",\n \"oldText\": \"color: 0xffffff\",\n \"newText\": \"color: 0x000000\"\n }\n },\n {\n \"tool\": \"create_design_comment\",\n \"arguments\": {\n \"project\": \"r6z2n9k4x8m1qc\",\n \"frame\": \"a4z8m2q7v9kcde\",\n \"body\": \"The bevel catches the key light here.\",\n \"position\": {\n \"kind\": \"3d\",\n \"x\": 0.2,\n \"y\": 1.1,\n \"z\": -0.4\n },\n \"expectedContentRevision\": 7\n }\n },\n {\n \"tool\": \"reply_to_design_comment\",\n \"arguments\": {\n \"project\": \"r6z2n9k4x8m1qc\",\n \"comment\": \"c4z8m2q7v9kcdf\",\n \"body\": \"Adjusted the material roughness.\"\n }\n },\n {\n \"tool\": \"resolve_design_comment\",\n \"arguments\": {\n \"project\": \"r6z2n9k4x8m1qc\",\n \"comment\": \"c4z8m2q7v9kcdf\"\n }\n },\n {\n \"tool\": \"generate_design_image\",\n \"arguments\": {\n \"project\": \"r6z2n9k4x8m1qc\",\n \"operation\": \"generate\",\n \"prompt\": \"A product photograph of this object\",\n \"references\": [\n \"https://r6z2n9k4x8m1qc.design.drawcallcontent.com/a4z8m2q7v9kcde.webp\"\n ],\n \"result\": \"new\",\n \"name\": \"Product photograph\"\n }\n },\n {\n \"tool\": \"get_design_frame_preview\",\n \"arguments\": {\n \"project\": \"r6z2n9k4x8m1qc\",\n \"frame\": \"a4z8m2q7v9kcde\"\n }\n }\n]\n```\n\nDesign is a remote, current-state canvas. Inspect the project and its frames before changing them. Use immutable IDs for every project and frame target; names are mutable labels. In user-facing replies, refer to projects, frames, and other named resources by their current names. Do not expose their IDs unless the user explicitly asks for them; IDs may remain embedded in URLs that link to those resources.\n\n## Project filesystem\n\nA project is a hosted filesystem at `https://<project-id>.design.drawcallcontent.com/`. Each frame owns one top-level directory, `/<frame-id>`. Files use project-absolute paths that include that directory, for example `/a4z8m2q7v9kcde/index.glts`.\n\nCreate frames with an explicit type. Choose the type from the requested artifact, not from the word \"frame\": use GLTS for a 3D object or scene, Markdown for a formatted text document, image for an existing 2D image, and Market only for an exact public asset reference, `name@version`. GLTS and Markdown frames require a viewport size; image and Market frames derive their canvas size. A GLTS or Markdown frame accepts its root file at creation.\n\nRead a file before editing it. Use a narrow edit for one known change and write a complete file when replacing it. GLTS and Markdown frame files may be created or deleted. Image and Market frame files are read-only.\n\n## Frame previews\n\nEvery frame has a canonical public WebP preview in `previewUrl` at `https://<project-id>.design.drawcallcontent.com/<frame-id>.webp`, whether its type is GLTS, Markdown, image, or Market. Use `get_design_frame_preview` to inspect it as image content. Use `get_design_frame_screenshot` only when a fresh PNG render is required. Pass `previewUrl` as a reference URL to `generate_design_image` when one frame's appearance should inform another image.\n\n## Markdown documents\n\nA Markdown frame contains one optional source file at `/<frame-id>/index.md`; without it the frame renders as an empty document. Raw HTML is not rendered. Use ordinary Markdown image syntax with a frame's canonical WebP path to embed its current rendering:\n\n```md\n![Descriptive alternative text](/other-frame-id.webp)\n```\n\nAn absolute canonical WebP URL from the same project is equivalent. A Markdown document may embed up to 32 existing GLTS, image, or Market frames. It may not embed itself or another Markdown frame. Use the canonical syntax instead of copying a screenshot URL or source asset so the document follows later frame changes.\n\nPrefer focused Markdown frames. A document that covers separable topics is usually clearer as multiple frames connected with canonical links, `[Related details](/<frame-id>/)`, because readers can navigate directly to the part they need. An embedded frame is useful when its current rendering adds visual context; a link is better when the reader only needs to navigate.\n\n## Comments and annotations\n\nUse comments for review conversations and persistent annotations, including explanations of objects or regions inside 2D and 3D frames. Inspect the current comments before replying, resolving, reopening, or deleting so the action targets the current thread.\n\nA comment without a position applies to its frame. A 2D position is normalized image space and applies only to an image frame. A 3D position is GLTS world space and applies only to a GLTS frame. Add a position only when its coordinates are authoritative; never infer 3D depth from a screenshot. Prefer a frame-level comment when the precise position is unknown.\n\nPositioned comments retain the frame version on which they were placed. If the frame later changes, treat the position as potentially stale and re-inspect the frame before relying on it. Replies belong to the root comment's thread. Resolved threads do not accept replies, so reopen one before continuing it. Resolve a thread when its concern has been addressed. Delete a comment or reply only when explicitly requested because deletion is permanent; deleting a root also deletes its replies. Comment authors come from the authenticated Drawcall account\u2014never invent an author identity.\n\n## Failures\n\nAn error means the requested operation did not happen. Follow its next action without switching transport. Correct invalid arguments from the documented shape. Refresh projects, frames, or files after a not-found or conflict error, then reuse the exact returned IDs and paths. Retry an upstream or internal failure once; if it repeats, report the failed operation and error. Never repeat an unchanged failed operation.\n\n## GLTS assets\n\nMarket assets can be faster and higher quality than recreating them in GLTS. Consider this separately for each substantial model, texture, and environment before hand-authoring it; if a quick search is likely to improve quality relative to latency, first read `get_market_instructions`.\n\nA GLTS frame contains only `.glts` files. `index.glts` is its optional root asset; without it the frame renders empty. Every `.glts` file is a trusted, exportless TypeScript ESM script that builds a native `THREE.Scene` through contextual values from `@drawcall/glts`:\n\n```ts\nimport * as THREE from \"three\";\nimport { onDispose, scene } from \"@drawcall/glts\";\n\nconst geometry = new THREE.BoxGeometry();\nconst material = new THREE.MeshStandardMaterial({ color: \"orange\" });\nscene.add(new THREE.Mesh(geometry, material));\n\nonDispose(() => {\n geometry.dispose();\n material.dispose();\n});\n```\n\nUse named contextual imports: `gltsLoader`, `instanceCount`, `isPreview`, `loadingManager`, `onDispose`, `onFrame`, `onMatrixUpdateAt`, and `scene`. Do not export anything or import `GLTSLoader` or `GLTSRenderer`; the host owns loading and rendering. The script may import `three`, Three addons, and browser-compatible npm packages, but not static `.glts` imports, dynamic imports, import attributes, or sibling `.ts` helpers.\n\nThe host owns the root `scene` transform. Put authored placement and animation under child objects instead of changing the root scene's transform.\n\n### Composition and placeholders\n\nCompose another `.glts` file with the contextual loader and an explicit URL. Every loaded child must be added beneath `scene` before the script finishes:\n\n```ts\nimport * as THREE from \"three\";\nimport { gltsLoader, scene } from \"@drawcall/glts\";\n\nconst wheel = await gltsLoader.loadAsync(\n new URL(\"./parts/wheel.glts\", import.meta.url),\n);\nwheel.position.set(0.8, 0.4, 1.3);\nscene.add(wheel);\n```\n\nFor a 3D object, create the frame with its complete `index.glts` first. When a referenced `.glts` file does not exist yet, give its URL specifier a rough bounding box in `imports`; Design creates a visible placeholder at that path. Then write each placeholder file one call at a time, the most visible first, and take a screenshot once none remain. A nested file that loads another missing file declares that file's box on its own write.\n\nUse relative URLs within a frame. A reusable 3D asset belongs in another frame; load its root by project-absolute URL instead of copying its source:\n\n```ts\nconst chassis = await gltsLoader.loadAsync(\n new URL(\"/other-frame-id/index.glts\", import.meta.url),\n);\nscene.add(chassis);\n```\n\nDo not register `child.dispose()` with `onDispose`; attached GLTS children are owned and disposed recursively. Avoid cyclic loads. Use `loadInstancesAsync(url, count)` for a static mesh hierarchy when repeated copies matter; animated, nested, skinned, or already-instanced content needs native instancing with `instanceCount` and `onMatrixUpdateAt`.\n\n### Resources, updates, and cleanup\n\nFor a non-GLTS file from an image or Market frame, resolve its project filesystem URL through `import.meta.url`:\n\n```ts\nconst modelUrl = new URL(\"/market-frame-id/models/car.glb\", import.meta.url);\n```\n\nPass the contextual `loadingManager` to Three.js loaders during script evaluation so the frame waits for their requests and surfaces failures. Three.js loaders take URL strings; GLTS loader methods accept the `URL` itself. Top-level `await` is supported. Do not start loads from frame, matrix, timer, event, or effect callbacks because the loading scope has closed.\n\n```ts\nimport * as THREE from \"three\";\nimport { loadingManager, scene } from \"@drawcall/glts\";\nimport { GLTFLoader } from \"three/addons/loaders/GLTFLoader.js\";\n\nconst model = await new GLTFLoader(loadingManager).loadAsync(\n new URL(\"./car.glb\", import.meta.url).href,\n);\nscene.add(model.scene);\n```\n\nRelease only resources the script creates. GLTS recursively disposes managed child scenes but does not infer geometry, material, texture, or listener ownership. Close disposal callbacks over the owned values rather than traversing the imported `scene`, whose live binding follows the new revision during reload.\n\nUse `onFrame((delta) => ...)` for animation. Design advances the loaded root every frame, including managed descendants. A failed reload leaves the previous scene mounted.\n\n### Root presentation\n\nNative scene properties such as `scene.background`, `scene.environment`, `scene.fog`, and `scene.overrideMaterial` describe the asset when it is the render root. Assign `scene.defaultCamera` to recommend an authored view; a saved Design frame camera still overrides it. Design autofits the scene when neither exists.\n\nUse `isPreview` for staging that belongs only in the standalone Design frame, such as a floor, light rig, background, fog, or presentation effects. Design loads each displayed root in preview mode; nested GLTS scenes always receive `isPreview === false`, so their presentation does not leak into composition. Keep intrinsic content and each mesh's `castShadow` setting outside this block.\n\n```ts\nimport * as THREE from \"three\";\nimport { isPreview, onDispose, scene } from \"@drawcall/glts\";\nimport { UnrealBloomPass } from \"three/addons/postprocessing/UnrealBloomPass.js\";\n\nscene.defaultCamera = new THREE.PerspectiveCamera(35, 1, 0.1, 100);\nscene.defaultCamera.position.set(4, 3, 6);\nscene.defaultCamera.lookAt(0, 1, 0);\n\nif (isPreview) {\n const floor = new THREE.Mesh(\n new THREE.CircleGeometry(20),\n new THREE.MeshStandardMaterial({ color: \"#333333\" }),\n );\n floor.rotation.x = -Math.PI / 2;\n floor.receiveShadow = true;\n const light = new THREE.DirectionalLight(\"white\", 3);\n light.position.set(4, 6, 3);\n light.castShadow = true;\n\n scene.background = new THREE.Color(\"#171b2b\");\n scene.add(light, light.target, floor);\n scene.rendering.shadows = true;\n scene.rendering.toneMapping = THREE.ACESFilmicToneMapping;\n scene.rendering.toneMappingExposure = 1.1;\n scene.rendering.effects.push(\n ({ height, width }) =>\n new UnrealBloomPass(new THREE.Vector2(width, height), 0.3, 0.4, 0.85),\n );\n\n onDispose(() => {\n light.dispose();\n floor.geometry.dispose();\n floor.material.dispose();\n });\n}\n```\n\n`scene.rendering` supports shadows, clipping planes, tone mapping, exposure, and post-processing effect factories. A factory returns a fresh Three.js `Pass`; do not add `RenderPass` or `OutputPass`, load resources there, or dispose the returned pass yourself. The host renderer owns those passes. Visible shadows require renderer shadows plus a shadow-casting light, casting meshes, and receiving surfaces.\n\nPresentation belongs only to the root. A nested scene's background, environment, fog, default camera, and rendering profile do not override its parent.\n\n### Verification\n\nTreat authoritative source or structured state as sufficient when it directly and completely determines the requested property. Do not take a screenshot merely to reconfirm that evidence. Take one only when the result depends on rendering or visual relationships the source cannot establish, such as layout, overlap, clipping, camera framing, lighting, or runtime-generated appearance, or when the user explicitly asks. Then inspect it against the request and iterate until the evidence supports completion.\n";
2
- export declare const cliDesignSkill = "---\nname: drawcall-design\ndescription: Create, modify, inspect, compose, and reuse GLTS scenes, Markdown documents, and image or Market references in Drawcall Design. Use whenever the user names Drawcall Design or one of its projects, canvases, frames, filesystems, GLTS assets, or Markdown frames. Do not use for full games, applications, or unrelated image generation.\n---\n\n# Drawcall Design\n\n## CLI transport\n\nThe commands below are the Drawcall transport in this environment. For Design operations, use only this documented command interface. A failed command does not make the transport unavailable.\n\nImage frame creation and image-generation references accept public HTTP(S) URLs or local PNG, JPEG, and WebP files.\n\nSelect the project with `-p <project-id>`. File commands take project-absolute paths that include the frame ID. Repeat `--reference` to preserve image-generation reference order.\n\n```sh\nnpx drawcall design project list\nnpx drawcall design -p r6z2n9k4x8m1qc frame list\nnpx drawcall design -p r6z2n9k4x8m1qc frame create Racecar --type glts --size 1280x800 --import ./parts/wheel.glts=-0.5,0,-0.5:0.5,1,0.5 --text - <<'GLTS'\nimport { gltsLoader, scene } from \"@drawcall/glts\";\n\nconst wheel = await gltsLoader.loadAsync(\n new URL(\"./parts/wheel.glts\", import.meta.url),\n);\nscene.add(wheel);\nGLTS\nnpx drawcall design -p r6z2n9k4x8m1qc write /a4z8m2q7v9kcde/parts/wheel.glts - <<'GLTS'\nimport * as THREE from \"three\";\nimport { onDispose, scene } from \"@drawcall/glts\";\n\nconst geometry = new THREE.TorusGeometry(0.4, 0.12, 16, 48);\nconst material = new THREE.MeshStandardMaterial({ color: 0x222222 });\nscene.add(new THREE.Mesh(geometry, material));\n\nonDispose(() => {\n geometry.dispose();\n material.dispose();\n});\nGLTS\nnpx drawcall design -p r6z2n9k4x8m1qc frame preview a4z8m2q7v9kcde\nnpx drawcall design -p r6z2n9k4x8m1qc frame screenshot a4z8m2q7v9kcde\nnpx drawcall design -p r6z2n9k4x8m1qc ls\nnpx drawcall design -p r6z2n9k4x8m1qc read /a4z8m2q7v9kcde/index.glts\nnpx drawcall design -p r6z2n9k4x8m1qc edit /a4z8m2q7v9kcde/index.glts 'color: 0xffffff' 'color: 0x000000'\nnpx drawcall design -p r6z2n9k4x8m1qc comment list a4z8m2q7v9kcde\nnpx drawcall design -p r6z2n9k4x8m1qc comment show c4z8m2q7v9kcdf\nnpx drawcall design -p r6z2n9k4x8m1qc comment create a4z8m2q7v9kcde 'The bevel catches the key light here.' --position-3d 0.2,1.1,-0.4\nnpx drawcall design -p r6z2n9k4x8m1qc comment reply c4z8m2q7v9kcdf 'Adjusted the material roughness.'\nnpx drawcall design -p r6z2n9k4x8m1qc comment resolve c4z8m2q7v9kcdf\nnpx drawcall design -p r6z2n9k4x8m1qc comment delete c4z8m2q7v9kcdf --yes\nnpx drawcall design -p r6z2n9k4x8m1qc frame generate-image 'Product photograph' --prompt 'A product photograph of this object' --reference https://r6z2n9k4x8m1qc.design.drawcallcontent.com/a4z8m2q7v9kcde.webp\nnpx drawcall design -p r6z2n9k4x8m1qc frame edit-image b4z8m2q7v9kcdf --prompt 'Use warmer light' --name 'Warm product photograph' --reference ./lighting.webp\n```\n\n`frame create --text`, `write`, comment create, and reply text accept `-` to read the text from stdin; a quoted heredoc keeps multi-line source intact. `--import <specifier>=<min>:<max>` declares the bounding box of a contextually loaded `.glts` file that does not exist yet, as `x,y,z:x,y,z`, and may repeat. Run one file write per command invocation, never several in one shell command. Use `--position-2d x,y` only for normalized image coordinates and `--position-3d x,y,z` only for authoritative GLTS world coordinates.\n\nDesign is a remote, current-state canvas. Inspect the project and its frames before changing them. Use immutable IDs for every project and frame target; names are mutable labels. In user-facing replies, refer to projects, frames, and other named resources by their current names. Do not expose their IDs unless the user explicitly asks for them; IDs may remain embedded in URLs that link to those resources.\n\n## Project filesystem\n\nA project is a hosted filesystem at `https://<project-id>.design.drawcallcontent.com/`. Each frame owns one top-level directory, `/<frame-id>`. Files use project-absolute paths that include that directory, for example `/a4z8m2q7v9kcde/index.glts`.\n\nCreate frames with an explicit type. Choose the type from the requested artifact, not from the word \"frame\": use GLTS for a 3D object or scene, Markdown for a formatted text document, image for an existing 2D image, and Market only for an exact public asset reference, `name@version`. GLTS and Markdown frames require a viewport size; image and Market frames derive their canvas size. A GLTS or Markdown frame accepts its root file at creation.\n\nRead a file before editing it. Use a narrow edit for one known change and write a complete file when replacing it. GLTS and Markdown frame files may be created or deleted. Image and Market frame files are read-only.\n\n## Frame previews\n\nEvery frame has a canonical public WebP preview in `previewUrl` at `https://<project-id>.design.drawcallcontent.com/<frame-id>.webp`, whether its type is GLTS, Markdown, image, or Market. `frame preview <frame-id>` prints that URL. Use `frame screenshot` only when a fresh PNG render is required. Pass a preview URL with `--reference` when one frame's appearance should inform another image. A reference may instead be a local PNG, JPEG, or WebP file.\n\n## Markdown documents\n\nA Markdown frame contains one optional source file at `/<frame-id>/index.md`; without it the frame renders as an empty document. Raw HTML is not rendered. Use ordinary Markdown image syntax with a frame's canonical WebP path to embed its current rendering:\n\n```md\n![Descriptive alternative text](/other-frame-id.webp)\n```\n\nAn absolute canonical WebP URL from the same project is equivalent. A Markdown document may embed up to 32 existing GLTS, image, or Market frames. It may not embed itself or another Markdown frame. Use the canonical syntax instead of copying a screenshot URL or source asset so the document follows later frame changes.\n\nPrefer focused Markdown frames. A document that covers separable topics is usually clearer as multiple frames connected with canonical links, `[Related details](/<frame-id>/)`, because readers can navigate directly to the part they need. An embedded frame is useful when its current rendering adds visual context; a link is better when the reader only needs to navigate.\n\n## Comments and annotations\n\nUse comments for review conversations and persistent annotations, including explanations of objects or regions inside 2D and 3D frames. Inspect the current comments before replying, resolving, reopening, or deleting so the action targets the current thread.\n\nA comment without a position applies to its frame. A 2D position is normalized image space and applies only to an image frame. A 3D position is GLTS world space and applies only to a GLTS frame. Add a position only when its coordinates are authoritative; never infer 3D depth from a screenshot. Prefer a frame-level comment when the precise position is unknown.\n\nPositioned comments retain the frame version on which they were placed. If the frame later changes, treat the position as potentially stale and re-inspect the frame before relying on it. Replies belong to the root comment's thread. Resolved threads do not accept replies, so reopen one before continuing it. Resolve a thread when its concern has been addressed. Delete a comment or reply only when explicitly requested because deletion is permanent; deleting a root also deletes its replies. Comment authors come from the authenticated Drawcall account\u2014never invent an author identity.\n\n## Failures\n\nAn error means the requested operation did not happen. Follow its next action without switching transport. Correct invalid arguments from the documented shape. Refresh projects, frames, or files after a not-found or conflict error, then reuse the exact returned IDs and paths. Retry an upstream or internal failure once; if it repeats, report the failed operation and error. Never repeat an unchanged failed operation.\n\n## GLTS assets\n\nMarket assets can be faster and higher quality than recreating them in GLTS. Consider this separately for each substantial model, texture, and environment before hand-authoring it; if a quick search is likely to improve quality relative to latency, first read `npx drawcall market skill`.\n\nA GLTS frame contains only `.glts` files. `index.glts` is its optional root asset; without it the frame renders empty. Every `.glts` file is a trusted, exportless TypeScript ESM script that builds a native `THREE.Scene` through contextual values from `@drawcall/glts`:\n\n```ts\nimport * as THREE from \"three\";\nimport { onDispose, scene } from \"@drawcall/glts\";\n\nconst geometry = new THREE.BoxGeometry();\nconst material = new THREE.MeshStandardMaterial({ color: \"orange\" });\nscene.add(new THREE.Mesh(geometry, material));\n\nonDispose(() => {\n geometry.dispose();\n material.dispose();\n});\n```\n\nUse named contextual imports: `gltsLoader`, `instanceCount`, `isPreview`, `loadingManager`, `onDispose`, `onFrame`, `onMatrixUpdateAt`, and `scene`. Do not export anything or import `GLTSLoader` or `GLTSRenderer`; the host owns loading and rendering. The script may import `three`, Three addons, and browser-compatible npm packages, but not static `.glts` imports, dynamic imports, import attributes, or sibling `.ts` helpers.\n\nThe host owns the root `scene` transform. Put authored placement and animation under child objects instead of changing the root scene's transform.\n\n### Composition and placeholders\n\nCompose another `.glts` file with the contextual loader and an explicit URL. Every loaded child must be added beneath `scene` before the script finishes:\n\n```ts\nimport * as THREE from \"three\";\nimport { gltsLoader, scene } from \"@drawcall/glts\";\n\nconst wheel = await gltsLoader.loadAsync(\n new URL(\"./parts/wheel.glts\", import.meta.url),\n);\nwheel.position.set(0.8, 0.4, 1.3);\nscene.add(wheel);\n```\n\nFor a 3D object, create the frame with its complete `index.glts` first. When a referenced `.glts` file does not exist yet, give its URL specifier a rough bounding box in `imports`; Design creates a visible placeholder at that path. Then write each placeholder file one call at a time, the most visible first, and take a screenshot once none remain. A nested file that loads another missing file declares that file's box on its own write.\n\nUse relative URLs within a frame. A reusable 3D asset belongs in another frame; load its root by project-absolute URL instead of copying its source:\n\n```ts\nconst chassis = await gltsLoader.loadAsync(\n new URL(\"/other-frame-id/index.glts\", import.meta.url),\n);\nscene.add(chassis);\n```\n\nDo not register `child.dispose()` with `onDispose`; attached GLTS children are owned and disposed recursively. Avoid cyclic loads. Use `loadInstancesAsync(url, count)` for a static mesh hierarchy when repeated copies matter; animated, nested, skinned, or already-instanced content needs native instancing with `instanceCount` and `onMatrixUpdateAt`.\n\n### Resources, updates, and cleanup\n\nFor a non-GLTS file from an image or Market frame, resolve its project filesystem URL through `import.meta.url`:\n\n```ts\nconst modelUrl = new URL(\"/market-frame-id/models/car.glb\", import.meta.url);\n```\n\nPass the contextual `loadingManager` to Three.js loaders during script evaluation so the frame waits for their requests and surfaces failures. Three.js loaders take URL strings; GLTS loader methods accept the `URL` itself. Top-level `await` is supported. Do not start loads from frame, matrix, timer, event, or effect callbacks because the loading scope has closed.\n\n```ts\nimport * as THREE from \"three\";\nimport { loadingManager, scene } from \"@drawcall/glts\";\nimport { GLTFLoader } from \"three/addons/loaders/GLTFLoader.js\";\n\nconst model = await new GLTFLoader(loadingManager).loadAsync(\n new URL(\"./car.glb\", import.meta.url).href,\n);\nscene.add(model.scene);\n```\n\nRelease only resources the script creates. GLTS recursively disposes managed child scenes but does not infer geometry, material, texture, or listener ownership. Close disposal callbacks over the owned values rather than traversing the imported `scene`, whose live binding follows the new revision during reload.\n\nUse `onFrame((delta) => ...)` for animation. Design advances the loaded root every frame, including managed descendants. A failed reload leaves the previous scene mounted.\n\n### Root presentation\n\nNative scene properties such as `scene.background`, `scene.environment`, `scene.fog`, and `scene.overrideMaterial` describe the asset when it is the render root. Assign `scene.defaultCamera` to recommend an authored view; a saved Design frame camera still overrides it. Design autofits the scene when neither exists.\n\nUse `isPreview` for staging that belongs only in the standalone Design frame, such as a floor, light rig, background, fog, or presentation effects. Design loads each displayed root in preview mode; nested GLTS scenes always receive `isPreview === false`, so their presentation does not leak into composition. Keep intrinsic content and each mesh's `castShadow` setting outside this block.\n\n```ts\nimport * as THREE from \"three\";\nimport { isPreview, onDispose, scene } from \"@drawcall/glts\";\nimport { UnrealBloomPass } from \"three/addons/postprocessing/UnrealBloomPass.js\";\n\nscene.defaultCamera = new THREE.PerspectiveCamera(35, 1, 0.1, 100);\nscene.defaultCamera.position.set(4, 3, 6);\nscene.defaultCamera.lookAt(0, 1, 0);\n\nif (isPreview) {\n const floor = new THREE.Mesh(\n new THREE.CircleGeometry(20),\n new THREE.MeshStandardMaterial({ color: \"#333333\" }),\n );\n floor.rotation.x = -Math.PI / 2;\n floor.receiveShadow = true;\n const light = new THREE.DirectionalLight(\"white\", 3);\n light.position.set(4, 6, 3);\n light.castShadow = true;\n\n scene.background = new THREE.Color(\"#171b2b\");\n scene.add(light, light.target, floor);\n scene.rendering.shadows = true;\n scene.rendering.toneMapping = THREE.ACESFilmicToneMapping;\n scene.rendering.toneMappingExposure = 1.1;\n scene.rendering.effects.push(\n ({ height, width }) =>\n new UnrealBloomPass(new THREE.Vector2(width, height), 0.3, 0.4, 0.85),\n );\n\n onDispose(() => {\n light.dispose();\n floor.geometry.dispose();\n floor.material.dispose();\n });\n}\n```\n\n`scene.rendering` supports shadows, clipping planes, tone mapping, exposure, and post-processing effect factories. A factory returns a fresh Three.js `Pass`; do not add `RenderPass` or `OutputPass`, load resources there, or dispose the returned pass yourself. The host renderer owns those passes. Visible shadows require renderer shadows plus a shadow-casting light, casting meshes, and receiving surfaces.\n\nPresentation belongs only to the root. A nested scene's background, environment, fog, default camera, and rendering profile do not override its parent.\n\n### Verification\n\nTreat authoritative source or structured state as sufficient when it directly and completely determines the requested property. Do not take a screenshot merely to reconfirm that evidence. Take one only when the result depends on rendering or visual relationships the source cannot establish, such as layout, overlap, clipping, camera framing, lighting, or runtime-generated appearance, or when the user explicitly asks. Then inspect it against the request and iterate until the evidence supports completion.\n";
1
+ export declare const mcpDesignSkill = "---\nname: drawcall-design\ndescription: Create, modify, inspect, compose, and reuse GLTS scenes, Markdown documents, and image or Market references in Drawcall Design. Use whenever the user names Drawcall Design or one of its projects, canvases, frames, filesystems, GLTS assets, or Markdown frames. Do not use for full games, applications, or unrelated image generation.\n---\n\n# Drawcall Design\n\n## MCP transport\n\nMCP tools are the Drawcall transport in this environment. For Design operations, use only the tools documented here. A failed tool call does not make the transport unavailable.\n\nImage frame creation uses a public HTTP(S) image URL.\n\nUse `generate_design_image` only when the user asks for a 2D image or reference. Its references must be public HTTP(S) URLs. A 3D object, scene, or reusable asset is GLTS work, even when the user calls its canvas container a frame.\n\nTool arguments are JSON objects. `create_design_frame` takes the root file of a glts or markdown frame as `text`, and `create_design_frame`, `write_design_file`, and `edit_design_file` take `imports`, the bounding box of each contextually loaded `.glts` file that does not exist yet, keyed by its URL specifier as written. The create result includes the new frame ID that later paths start with. File tools identify their target with `project` and a project-absolute `path`; they do not accept a separate `frame` argument. Call `list_design_files` and pass one of its returned paths unchanged.\n\nFor comments, call `list_design_comments` and, when needed, `get_design_comment` before changing a thread. Use `create_design_comment`, `reply_to_design_comment`, `resolve_design_comment`, `reopen_design_comment`, and `delete_design_comment` for their named operations. Structured tool calls use `body` for comment text. A positioned create requires the target frame's current `contentRevision` as `expectedContentRevision`; list frames again and re-inspect the position after a conflict.\n\n```json\n[\n {\n \"tool\": \"list_design_projects\",\n \"arguments\": {}\n },\n {\n \"tool\": \"list_design_frames\",\n \"arguments\": {\n \"project\": \"r6z2n9k4x8m1qc\"\n }\n },\n {\n \"tool\": \"create_design_frame\",\n \"arguments\": {\n \"project\": \"r6z2n9k4x8m1qc\",\n \"name\": \"Racecar\",\n \"type\": \"glts\",\n \"width\": 1280,\n \"height\": 800,\n \"text\": \"import { gltsLoader, scene } from \\\"@drawcall/glts\\\";\\n\\nconst wheel = await gltsLoader.loadAsync(\\n new URL(\\\"./parts/wheel.glts\\\", import.meta.url),\\n);\\nscene.add(wheel);\\n\",\n \"imports\": {\n \"./parts/wheel.glts\": {\n \"min\": [\n -0.5,\n 0,\n -0.5\n ],\n \"max\": [\n 0.5,\n 1,\n 0.5\n ]\n }\n }\n }\n },\n {\n \"tool\": \"write_design_file\",\n \"arguments\": {\n \"project\": \"r6z2n9k4x8m1qc\",\n \"path\": \"/a4z8m2q7v9kcde/parts/wheel.glts\",\n \"text\": \"import * as THREE from \\\"three\\\";\\nimport { onDispose, scene } from \\\"@drawcall/glts\\\";\\n\\nconst geometry = new THREE.TorusGeometry(0.4, 0.12, 16, 48);\\nconst material = new THREE.MeshStandardMaterial({ color: 0x222222 });\\nscene.add(new THREE.Mesh(geometry, material));\\n\\nonDispose(() => {\\n geometry.dispose();\\n material.dispose();\\n});\\n\"\n }\n },\n {\n \"tool\": \"list_design_files\",\n \"arguments\": {\n \"project\": \"r6z2n9k4x8m1qc\"\n }\n },\n {\n \"tool\": \"read_design_file\",\n \"arguments\": {\n \"project\": \"r6z2n9k4x8m1qc\",\n \"path\": \"/a4z8m2q7v9kcde/index.glts\"\n }\n },\n {\n \"tool\": \"edit_design_file\",\n \"arguments\": {\n \"project\": \"r6z2n9k4x8m1qc\",\n \"path\": \"/a4z8m2q7v9kcde/index.glts\",\n \"oldText\": \"color: 0xffffff\",\n \"newText\": \"color: 0x000000\"\n }\n },\n {\n \"tool\": \"create_design_comment\",\n \"arguments\": {\n \"project\": \"r6z2n9k4x8m1qc\",\n \"frame\": \"a4z8m2q7v9kcde\",\n \"body\": \"The bevel catches the key light here.\",\n \"position\": {\n \"kind\": \"3d\",\n \"x\": 0.2,\n \"y\": 1.1,\n \"z\": -0.4\n },\n \"expectedContentRevision\": 7\n }\n },\n {\n \"tool\": \"reply_to_design_comment\",\n \"arguments\": {\n \"project\": \"r6z2n9k4x8m1qc\",\n \"comment\": \"c4z8m2q7v9kcdf\",\n \"body\": \"Adjusted the material roughness.\"\n }\n },\n {\n \"tool\": \"resolve_design_comment\",\n \"arguments\": {\n \"project\": \"r6z2n9k4x8m1qc\",\n \"comment\": \"c4z8m2q7v9kcdf\"\n }\n },\n {\n \"tool\": \"generate_design_image\",\n \"arguments\": {\n \"project\": \"r6z2n9k4x8m1qc\",\n \"operation\": \"generate\",\n \"prompt\": \"A product photograph of this object\",\n \"references\": [\n \"https://r6z2n9k4x8m1qc.design.drawcallcontent.com/a4z8m2q7v9kcde.webp\"\n ],\n \"result\": \"new\",\n \"name\": \"Product photograph\"\n }\n },\n {\n \"tool\": \"get_design_frame_preview\",\n \"arguments\": {\n \"project\": \"r6z2n9k4x8m1qc\",\n \"frame\": \"a4z8m2q7v9kcde\"\n }\n }\n]\n```\n\nDesign is a remote, current-state canvas. Inspect the project and its frames before changing them. Use immutable IDs for every project and frame target; names are mutable labels. In user-facing replies, refer to projects, frames, and other named resources by their current names. Do not expose their IDs unless the user explicitly asks for them; IDs may remain embedded in URLs that link to those resources.\n\n## Project filesystem\n\nA project is a hosted filesystem at `https://<project-id>.design.drawcallcontent.com/`. Each frame owns one top-level directory, `/<frame-id>`. Files use project-absolute paths that include that directory, for example `/a4z8m2q7v9kcde/index.glts`.\n\nCreate frames with an explicit type. Choose the type from the requested artifact, not from the word \"frame\": use GLTS for a 3D object or scene, Markdown for a formatted text document, image for an existing 2D image, and Market only for an exact public asset reference, `name@version`. GLTS and Markdown frames require a viewport size; image and Market frames derive their canvas size. A GLTS or Markdown frame accepts its root file at creation.\n\nRead a file before editing it. Use a narrow edit for one known change and write a complete file when replacing it. GLTS and Markdown frame files may be created or deleted. Image and Market frame files are read-only.\n\n## Frame previews\n\nEvery frame has a canonical public WebP preview in `previewUrl` at `https://<project-id>.design.drawcallcontent.com/<frame-id>.webp`, whether its type is GLTS, Markdown, image, or Market. Use `get_design_frame_preview` to inspect it as image content. Use `get_design_frame_screenshot` only when a fresh PNG render is required. Pass `previewUrl` as a reference URL to `generate_design_image` when one frame's appearance should inform another image.\n\n## Markdown documents\n\nA Markdown frame contains one optional source file at `/<frame-id>/index.md`; without it the frame renders as an empty document. Raw HTML is not rendered. Use ordinary Markdown image syntax with a frame's canonical WebP path to embed its current rendering:\n\n```md\n![Descriptive alternative text](/other-frame-id.webp)\n```\n\nAn absolute canonical WebP URL from the same project is equivalent. A Markdown document may embed up to 32 existing GLTS, image, or Market frames. It may not embed itself or another Markdown frame. Use the canonical syntax instead of copying a screenshot URL or source asset so the document follows later frame changes.\n\nPrefer focused Markdown frames. A document that covers separable topics is usually clearer as multiple frames connected with canonical links, `[Related details](/<frame-id>/)`, because readers can navigate directly to the part they need. An embedded frame is useful when its current rendering adds visual context; a link is better when the reader only needs to navigate.\n\n## Comments and annotations\n\nUse comments for review conversations and persistent annotations, including explanations of objects or regions inside 2D and 3D frames. Inspect the current comments before replying, resolving, reopening, or deleting so the action targets the current thread.\n\nA comment without a position applies to its frame. A 2D position is normalized image space and applies only to an image frame. A 3D position is GLTS world space and applies only to a GLTS frame. Add a position only when its coordinates are authoritative; never infer 3D depth from a screenshot. Prefer a frame-level comment when the precise position is unknown.\n\nPositioned comments retain the frame version on which they were placed. If the frame later changes, treat the position as potentially stale and re-inspect the frame before relying on it. Replies belong to the root comment's thread. Resolved threads do not accept replies, so reopen one before continuing it. Resolve a thread when its concern has been addressed. Delete a comment or reply only when explicitly requested because deletion is permanent; deleting a root also deletes its replies. Comment authors come from the authenticated Drawcall account\u2014never invent an author identity.\n\n## Failures\n\nAn error means the requested operation did not happen. Follow its next action without switching transport. Correct invalid arguments from the documented shape. Refresh projects, frames, or files after a not-found or conflict error, then reuse the exact returned IDs and paths. Retry an upstream or internal failure once; if it repeats, report the failed operation and error. Never repeat an unchanged failed operation.\n\n## GLTS assets\n\n### Market check\n\nBefore hand-authoring a substantial model, texture, or environment, first read `get_market_instructions`, search Market once, and preview the best close match. Do not skip this check to save time; skip it only for simple or inherently procedural elements. Use the asset only if it beats hand-authoring on quality relative to latency; otherwise name the rejected asset and why.\n\nA GLTS frame contains only `.glts` files. `index.glts` is its optional root asset; without it the frame renders empty. Every `.glts` file is a trusted, exportless TypeScript ESM script that builds a native `THREE.Scene` through contextual values from `@drawcall/glts`:\n\n```ts\nimport * as THREE from \"three\";\nimport { onDispose, scene } from \"@drawcall/glts\";\n\nconst geometry = new THREE.BoxGeometry();\nconst material = new THREE.MeshStandardMaterial({ color: \"orange\" });\nscene.add(new THREE.Mesh(geometry, material));\n\nonDispose(() => {\n geometry.dispose();\n material.dispose();\n});\n```\n\nUse named contextual imports: `gltsLoader`, `instanceCount`, `isPreview`, `loadingManager`, `onDispose`, `onFrame`, `onMatrixUpdateAt`, and `scene`. Do not export anything or import `GLTSLoader` or `GLTSRenderer`; the host owns loading and rendering. The script may import `three`, Three addons, and browser-compatible npm packages, but not static `.glts` imports, dynamic imports, import attributes, or sibling `.ts` helpers.\n\nThe host owns the root `scene` transform. Put authored placement and animation under child objects instead of changing the root scene's transform.\n\n### Composition and placeholders\n\nCompose another `.glts` file with the contextual loader and an explicit URL. Every loaded child must be added beneath `scene` before the script finishes:\n\n```ts\nimport * as THREE from \"three\";\nimport { gltsLoader, scene } from \"@drawcall/glts\";\n\nconst wheel = await gltsLoader.loadAsync(\n new URL(\"./parts/wheel.glts\", import.meta.url),\n);\nwheel.position.set(0.8, 0.4, 1.3);\nscene.add(wheel);\n```\n\nFor a 3D object, create the frame with its complete `index.glts` first. When a referenced `.glts` file does not exist yet, give its URL specifier a rough bounding box in `imports`; Design creates a visible placeholder at that path. Then write each placeholder file one call at a time, the most visible first, and take a screenshot once none remain. A nested file that loads another missing file declares that file's box on its own write.\n\nUse relative URLs within a frame. A reusable 3D asset belongs in another frame; load its root by project-absolute URL instead of copying its source:\n\n```ts\nconst chassis = await gltsLoader.loadAsync(\n new URL(\"/other-frame-id/index.glts\", import.meta.url),\n);\nscene.add(chassis);\n```\n\nDo not register `child.dispose()` with `onDispose`; attached GLTS children are owned and disposed recursively. Avoid cyclic loads. Use `loadInstancesAsync(url, count)` for a static mesh hierarchy when repeated copies matter; animated, nested, skinned, or already-instanced content needs native instancing with `instanceCount` and `onMatrixUpdateAt`.\n\n### Resources, updates, and cleanup\n\nFor a non-GLTS file from an image or Market frame, resolve its project filesystem URL through `import.meta.url`:\n\n```ts\nconst modelUrl = new URL(\"/market-frame-id/models/car.glb\", import.meta.url);\n```\n\nPass the contextual `loadingManager` to Three.js loaders during script evaluation so the frame waits for their requests and surfaces failures. Three.js loaders take URL strings; GLTS loader methods accept the `URL` itself. Top-level `await` is supported. Do not start loads from frame, matrix, timer, event, or effect callbacks because the loading scope has closed.\n\n```ts\nimport * as THREE from \"three\";\nimport { loadingManager, scene } from \"@drawcall/glts\";\nimport { GLTFLoader } from \"three/addons/loaders/GLTFLoader.js\";\n\nconst model = await new GLTFLoader(loadingManager).loadAsync(\n new URL(\"./car.glb\", import.meta.url).href,\n);\nscene.add(model.scene);\n```\n\nRelease only resources the script creates. GLTS recursively disposes managed child scenes but does not infer geometry, material, texture, or listener ownership. Close disposal callbacks over the owned values rather than traversing the imported `scene`, whose live binding follows the new revision during reload.\n\nUse `onFrame((delta) => ...)` for animation. Design advances the loaded root every frame, including managed descendants. A failed reload leaves the previous scene mounted.\n\n### Root presentation\n\nNative scene properties such as `scene.background`, `scene.environment`, `scene.fog`, and `scene.overrideMaterial` describe the asset when it is the render root. Assign `scene.defaultCamera` to recommend an authored view; a saved Design frame camera still overrides it. Design autofits the scene when neither exists.\n\nUse `isPreview` for staging that belongs only in the standalone Design frame, such as a floor, light rig, background, fog, or presentation effects. Design loads each displayed root in preview mode; nested GLTS scenes always receive `isPreview === false`, so their presentation does not leak into composition. Keep intrinsic content and each mesh's `castShadow` setting outside this block.\n\n```ts\nimport * as THREE from \"three\";\nimport { isPreview, onDispose, scene } from \"@drawcall/glts\";\nimport { UnrealBloomPass } from \"three/addons/postprocessing/UnrealBloomPass.js\";\n\nscene.defaultCamera = new THREE.PerspectiveCamera(35, 1, 0.1, 100);\nscene.defaultCamera.position.set(4, 3, 6);\nscene.defaultCamera.lookAt(0, 1, 0);\n\nif (isPreview) {\n const floor = new THREE.Mesh(\n new THREE.CircleGeometry(20),\n new THREE.MeshStandardMaterial({ color: \"#333333\" }),\n );\n floor.rotation.x = -Math.PI / 2;\n floor.receiveShadow = true;\n const light = new THREE.DirectionalLight(\"white\", 3);\n light.position.set(4, 6, 3);\n light.castShadow = true;\n\n scene.background = new THREE.Color(\"#171b2b\");\n scene.add(light, light.target, floor);\n scene.rendering.shadows = true;\n scene.rendering.toneMapping = THREE.ACESFilmicToneMapping;\n scene.rendering.toneMappingExposure = 1.1;\n scene.rendering.effects.push(\n ({ height, width }) =>\n new UnrealBloomPass(new THREE.Vector2(width, height), 0.3, 0.4, 0.85),\n );\n\n onDispose(() => {\n light.dispose();\n floor.geometry.dispose();\n floor.material.dispose();\n });\n}\n```\n\n`scene.rendering` supports shadows, clipping planes, tone mapping, exposure, and post-processing effect factories. A factory returns a fresh Three.js `Pass`; do not add `RenderPass` or `OutputPass`, load resources there, or dispose the returned pass yourself. The host renderer owns those passes. Visible shadows require renderer shadows plus a shadow-casting light, casting meshes, and receiving surfaces.\n\nPresentation belongs only to the root. A nested scene's background, environment, fog, default camera, and rendering profile do not override its parent.\n\n### Verification\n\nTreat authoritative source or structured state as sufficient when it directly and completely determines the requested property. Do not take a screenshot merely to reconfirm that evidence. Take one only when the result depends on rendering or visual relationships the source cannot establish, such as layout, overlap, clipping, camera framing, lighting, or runtime-generated appearance, or when the user explicitly asks. Then inspect it against the request and iterate until the evidence supports completion.\n";
2
+ export declare const cliDesignSkill = "---\nname: drawcall-design\ndescription: Create, modify, inspect, compose, and reuse GLTS scenes, Markdown documents, and image or Market references in Drawcall Design. Use whenever the user names Drawcall Design or one of its projects, canvases, frames, filesystems, GLTS assets, or Markdown frames. Do not use for full games, applications, or unrelated image generation.\n---\n\n# Drawcall Design\n\n## CLI transport\n\nThe commands below are the Drawcall transport in this environment. For Design operations, use only this documented command interface. A failed command does not make the transport unavailable.\n\nImage frame creation and image-generation references accept public HTTP(S) URLs or local PNG, JPEG, and WebP files.\n\nSelect the project with `-p <project-id>`. File commands take project-absolute paths that include the frame ID. Repeat `--reference` to preserve image-generation reference order.\n\n```sh\nnpx drawcall design project list\nnpx drawcall design -p r6z2n9k4x8m1qc frame list\nnpx drawcall design -p r6z2n9k4x8m1qc frame create Racecar --type glts --size 1280x800 --import ./parts/wheel.glts=-0.5,0,-0.5:0.5,1,0.5 --text - <<'GLTS'\nimport { gltsLoader, scene } from \"@drawcall/glts\";\n\nconst wheel = await gltsLoader.loadAsync(\n new URL(\"./parts/wheel.glts\", import.meta.url),\n);\nscene.add(wheel);\nGLTS\nnpx drawcall design -p r6z2n9k4x8m1qc write /a4z8m2q7v9kcde/parts/wheel.glts - <<'GLTS'\nimport * as THREE from \"three\";\nimport { onDispose, scene } from \"@drawcall/glts\";\n\nconst geometry = new THREE.TorusGeometry(0.4, 0.12, 16, 48);\nconst material = new THREE.MeshStandardMaterial({ color: 0x222222 });\nscene.add(new THREE.Mesh(geometry, material));\n\nonDispose(() => {\n geometry.dispose();\n material.dispose();\n});\nGLTS\nnpx drawcall design -p r6z2n9k4x8m1qc frame preview a4z8m2q7v9kcde\nnpx drawcall design -p r6z2n9k4x8m1qc frame screenshot a4z8m2q7v9kcde\nnpx drawcall design -p r6z2n9k4x8m1qc ls\nnpx drawcall design -p r6z2n9k4x8m1qc read /a4z8m2q7v9kcde/index.glts\nnpx drawcall design -p r6z2n9k4x8m1qc edit /a4z8m2q7v9kcde/index.glts 'color: 0xffffff' 'color: 0x000000'\nnpx drawcall design -p r6z2n9k4x8m1qc comment list a4z8m2q7v9kcde\nnpx drawcall design -p r6z2n9k4x8m1qc comment show c4z8m2q7v9kcdf\nnpx drawcall design -p r6z2n9k4x8m1qc comment create a4z8m2q7v9kcde 'The bevel catches the key light here.' --position-3d 0.2,1.1,-0.4\nnpx drawcall design -p r6z2n9k4x8m1qc comment reply c4z8m2q7v9kcdf 'Adjusted the material roughness.'\nnpx drawcall design -p r6z2n9k4x8m1qc comment resolve c4z8m2q7v9kcdf\nnpx drawcall design -p r6z2n9k4x8m1qc comment delete c4z8m2q7v9kcdf --yes\nnpx drawcall design -p r6z2n9k4x8m1qc frame generate-image 'Product photograph' --prompt 'A product photograph of this object' --reference https://r6z2n9k4x8m1qc.design.drawcallcontent.com/a4z8m2q7v9kcde.webp\nnpx drawcall design -p r6z2n9k4x8m1qc frame edit-image b4z8m2q7v9kcdf --prompt 'Use warmer light' --name 'Warm product photograph' --reference ./lighting.webp\n```\n\n`frame create --text`, `write`, comment create, and reply text accept `-` to read the text from stdin; a quoted heredoc keeps multi-line source intact. `--import <specifier>=<min>:<max>` declares the bounding box of a contextually loaded `.glts` file that does not exist yet, as `x,y,z:x,y,z`, and may repeat. Run one file write per command invocation, never several in one shell command. Use `--position-2d x,y` only for normalized image coordinates and `--position-3d x,y,z` only for authoritative GLTS world coordinates.\n\nDesign is a remote, current-state canvas. Inspect the project and its frames before changing them. Use immutable IDs for every project and frame target; names are mutable labels. In user-facing replies, refer to projects, frames, and other named resources by their current names. Do not expose their IDs unless the user explicitly asks for them; IDs may remain embedded in URLs that link to those resources.\n\n## Project filesystem\n\nA project is a hosted filesystem at `https://<project-id>.design.drawcallcontent.com/`. Each frame owns one top-level directory, `/<frame-id>`. Files use project-absolute paths that include that directory, for example `/a4z8m2q7v9kcde/index.glts`.\n\nCreate frames with an explicit type. Choose the type from the requested artifact, not from the word \"frame\": use GLTS for a 3D object or scene, Markdown for a formatted text document, image for an existing 2D image, and Market only for an exact public asset reference, `name@version`. GLTS and Markdown frames require a viewport size; image and Market frames derive their canvas size. A GLTS or Markdown frame accepts its root file at creation.\n\nRead a file before editing it. Use a narrow edit for one known change and write a complete file when replacing it. GLTS and Markdown frame files may be created or deleted. Image and Market frame files are read-only.\n\n## Frame previews\n\nEvery frame has a canonical public WebP preview in `previewUrl` at `https://<project-id>.design.drawcallcontent.com/<frame-id>.webp`, whether its type is GLTS, Markdown, image, or Market. `frame preview <frame-id>` prints that URL. Use `frame screenshot` only when a fresh PNG render is required. Pass a preview URL with `--reference` when one frame's appearance should inform another image. A reference may instead be a local PNG, JPEG, or WebP file.\n\n## Markdown documents\n\nA Markdown frame contains one optional source file at `/<frame-id>/index.md`; without it the frame renders as an empty document. Raw HTML is not rendered. Use ordinary Markdown image syntax with a frame's canonical WebP path to embed its current rendering:\n\n```md\n![Descriptive alternative text](/other-frame-id.webp)\n```\n\nAn absolute canonical WebP URL from the same project is equivalent. A Markdown document may embed up to 32 existing GLTS, image, or Market frames. It may not embed itself or another Markdown frame. Use the canonical syntax instead of copying a screenshot URL or source asset so the document follows later frame changes.\n\nPrefer focused Markdown frames. A document that covers separable topics is usually clearer as multiple frames connected with canonical links, `[Related details](/<frame-id>/)`, because readers can navigate directly to the part they need. An embedded frame is useful when its current rendering adds visual context; a link is better when the reader only needs to navigate.\n\n## Comments and annotations\n\nUse comments for review conversations and persistent annotations, including explanations of objects or regions inside 2D and 3D frames. Inspect the current comments before replying, resolving, reopening, or deleting so the action targets the current thread.\n\nA comment without a position applies to its frame. A 2D position is normalized image space and applies only to an image frame. A 3D position is GLTS world space and applies only to a GLTS frame. Add a position only when its coordinates are authoritative; never infer 3D depth from a screenshot. Prefer a frame-level comment when the precise position is unknown.\n\nPositioned comments retain the frame version on which they were placed. If the frame later changes, treat the position as potentially stale and re-inspect the frame before relying on it. Replies belong to the root comment's thread. Resolved threads do not accept replies, so reopen one before continuing it. Resolve a thread when its concern has been addressed. Delete a comment or reply only when explicitly requested because deletion is permanent; deleting a root also deletes its replies. Comment authors come from the authenticated Drawcall account\u2014never invent an author identity.\n\n## Failures\n\nAn error means the requested operation did not happen. Follow its next action without switching transport. Correct invalid arguments from the documented shape. Refresh projects, frames, or files after a not-found or conflict error, then reuse the exact returned IDs and paths. Retry an upstream or internal failure once; if it repeats, report the failed operation and error. Never repeat an unchanged failed operation.\n\n## GLTS assets\n\n### Market check\n\nBefore hand-authoring a substantial model, texture, or environment, first read `npx drawcall market skill`, search Market once, and preview the best close match. Do not skip this check to save time; skip it only for simple or inherently procedural elements. Use the asset only if it beats hand-authoring on quality relative to latency; otherwise name the rejected asset and why.\n\nA GLTS frame contains only `.glts` files. `index.glts` is its optional root asset; without it the frame renders empty. Every `.glts` file is a trusted, exportless TypeScript ESM script that builds a native `THREE.Scene` through contextual values from `@drawcall/glts`:\n\n```ts\nimport * as THREE from \"three\";\nimport { onDispose, scene } from \"@drawcall/glts\";\n\nconst geometry = new THREE.BoxGeometry();\nconst material = new THREE.MeshStandardMaterial({ color: \"orange\" });\nscene.add(new THREE.Mesh(geometry, material));\n\nonDispose(() => {\n geometry.dispose();\n material.dispose();\n});\n```\n\nUse named contextual imports: `gltsLoader`, `instanceCount`, `isPreview`, `loadingManager`, `onDispose`, `onFrame`, `onMatrixUpdateAt`, and `scene`. Do not export anything or import `GLTSLoader` or `GLTSRenderer`; the host owns loading and rendering. The script may import `three`, Three addons, and browser-compatible npm packages, but not static `.glts` imports, dynamic imports, import attributes, or sibling `.ts` helpers.\n\nThe host owns the root `scene` transform. Put authored placement and animation under child objects instead of changing the root scene's transform.\n\n### Composition and placeholders\n\nCompose another `.glts` file with the contextual loader and an explicit URL. Every loaded child must be added beneath `scene` before the script finishes:\n\n```ts\nimport * as THREE from \"three\";\nimport { gltsLoader, scene } from \"@drawcall/glts\";\n\nconst wheel = await gltsLoader.loadAsync(\n new URL(\"./parts/wheel.glts\", import.meta.url),\n);\nwheel.position.set(0.8, 0.4, 1.3);\nscene.add(wheel);\n```\n\nFor a 3D object, create the frame with its complete `index.glts` first. When a referenced `.glts` file does not exist yet, give its URL specifier a rough bounding box in `imports`; Design creates a visible placeholder at that path. Then write each placeholder file one call at a time, the most visible first, and take a screenshot once none remain. A nested file that loads another missing file declares that file's box on its own write.\n\nUse relative URLs within a frame. A reusable 3D asset belongs in another frame; load its root by project-absolute URL instead of copying its source:\n\n```ts\nconst chassis = await gltsLoader.loadAsync(\n new URL(\"/other-frame-id/index.glts\", import.meta.url),\n);\nscene.add(chassis);\n```\n\nDo not register `child.dispose()` with `onDispose`; attached GLTS children are owned and disposed recursively. Avoid cyclic loads. Use `loadInstancesAsync(url, count)` for a static mesh hierarchy when repeated copies matter; animated, nested, skinned, or already-instanced content needs native instancing with `instanceCount` and `onMatrixUpdateAt`.\n\n### Resources, updates, and cleanup\n\nFor a non-GLTS file from an image or Market frame, resolve its project filesystem URL through `import.meta.url`:\n\n```ts\nconst modelUrl = new URL(\"/market-frame-id/models/car.glb\", import.meta.url);\n```\n\nPass the contextual `loadingManager` to Three.js loaders during script evaluation so the frame waits for their requests and surfaces failures. Three.js loaders take URL strings; GLTS loader methods accept the `URL` itself. Top-level `await` is supported. Do not start loads from frame, matrix, timer, event, or effect callbacks because the loading scope has closed.\n\n```ts\nimport * as THREE from \"three\";\nimport { loadingManager, scene } from \"@drawcall/glts\";\nimport { GLTFLoader } from \"three/addons/loaders/GLTFLoader.js\";\n\nconst model = await new GLTFLoader(loadingManager).loadAsync(\n new URL(\"./car.glb\", import.meta.url).href,\n);\nscene.add(model.scene);\n```\n\nRelease only resources the script creates. GLTS recursively disposes managed child scenes but does not infer geometry, material, texture, or listener ownership. Close disposal callbacks over the owned values rather than traversing the imported `scene`, whose live binding follows the new revision during reload.\n\nUse `onFrame((delta) => ...)` for animation. Design advances the loaded root every frame, including managed descendants. A failed reload leaves the previous scene mounted.\n\n### Root presentation\n\nNative scene properties such as `scene.background`, `scene.environment`, `scene.fog`, and `scene.overrideMaterial` describe the asset when it is the render root. Assign `scene.defaultCamera` to recommend an authored view; a saved Design frame camera still overrides it. Design autofits the scene when neither exists.\n\nUse `isPreview` for staging that belongs only in the standalone Design frame, such as a floor, light rig, background, fog, or presentation effects. Design loads each displayed root in preview mode; nested GLTS scenes always receive `isPreview === false`, so their presentation does not leak into composition. Keep intrinsic content and each mesh's `castShadow` setting outside this block.\n\n```ts\nimport * as THREE from \"three\";\nimport { isPreview, onDispose, scene } from \"@drawcall/glts\";\nimport { UnrealBloomPass } from \"three/addons/postprocessing/UnrealBloomPass.js\";\n\nscene.defaultCamera = new THREE.PerspectiveCamera(35, 1, 0.1, 100);\nscene.defaultCamera.position.set(4, 3, 6);\nscene.defaultCamera.lookAt(0, 1, 0);\n\nif (isPreview) {\n const floor = new THREE.Mesh(\n new THREE.CircleGeometry(20),\n new THREE.MeshStandardMaterial({ color: \"#333333\" }),\n );\n floor.rotation.x = -Math.PI / 2;\n floor.receiveShadow = true;\n const light = new THREE.DirectionalLight(\"white\", 3);\n light.position.set(4, 6, 3);\n light.castShadow = true;\n\n scene.background = new THREE.Color(\"#171b2b\");\n scene.add(light, light.target, floor);\n scene.rendering.shadows = true;\n scene.rendering.toneMapping = THREE.ACESFilmicToneMapping;\n scene.rendering.toneMappingExposure = 1.1;\n scene.rendering.effects.push(\n ({ height, width }) =>\n new UnrealBloomPass(new THREE.Vector2(width, height), 0.3, 0.4, 0.85),\n );\n\n onDispose(() => {\n light.dispose();\n floor.geometry.dispose();\n floor.material.dispose();\n });\n}\n```\n\n`scene.rendering` supports shadows, clipping planes, tone mapping, exposure, and post-processing effect factories. A factory returns a fresh Three.js `Pass`; do not add `RenderPass` or `OutputPass`, load resources there, or dispose the returned pass yourself. The host renderer owns those passes. Visible shadows require renderer shadows plus a shadow-casting light, casting meshes, and receiving surfaces.\n\nPresentation belongs only to the root. A nested scene's background, environment, fog, default camera, and rendering profile do not override its parent.\n\n### Verification\n\nTreat authoritative source or structured state as sufficient when it directly and completely determines the requested property. Do not take a screenshot merely to reconfirm that evidence. Take one only when the result depends on rendering or visual relationships the source cannot establish, such as layout, overlap, clipping, camera framing, lighting, or runtime-generated appearance, or when the user explicitly asks. Then inspect it against the request and iterate until the evidence supports completion.\n";
@@ -1,3 +1,3 @@
1
1
  // Generated from skill/SKILL.template.md.
2
- export const mcpDesignSkill = '---\nname: drawcall-design\ndescription: Create, modify, inspect, compose, and reuse GLTS scenes, Markdown documents, and image or Market references in Drawcall Design. Use whenever the user names Drawcall Design or one of its projects, canvases, frames, filesystems, GLTS assets, or Markdown frames. Do not use for full games, applications, or unrelated image generation.\n---\n\n# Drawcall Design\n\n## MCP transport\n\nMCP tools are the Drawcall transport in this environment. For Design operations, use only the tools documented here. A failed tool call does not make the transport unavailable.\n\nImage frame creation uses a public HTTP(S) image URL.\n\nUse `generate_design_image` only when the user asks for a 2D image or reference. Its references must be public HTTP(S) URLs. A 3D object, scene, or reusable asset is GLTS work, even when the user calls its canvas container a frame.\n\nTool arguments are JSON objects. `create_design_frame` takes the root file of a glts or markdown frame as `text`, and `create_design_frame`, `write_design_file`, and `edit_design_file` take `imports`, the bounding box of each contextually loaded `.glts` file that does not exist yet, keyed by its URL specifier as written. The create result includes the new frame ID that later paths start with. File tools identify their target with `project` and a project-absolute `path`; they do not accept a separate `frame` argument. Call `list_design_files` and pass one of its returned paths unchanged.\n\nFor comments, call `list_design_comments` and, when needed, `get_design_comment` before changing a thread. Use `create_design_comment`, `reply_to_design_comment`, `resolve_design_comment`, `reopen_design_comment`, and `delete_design_comment` for their named operations. Structured tool calls use `body` for comment text. A positioned create requires the target frame\'s current `contentRevision` as `expectedContentRevision`; list frames again and re-inspect the position after a conflict.\n\n```json\n[\n {\n "tool": "list_design_projects",\n "arguments": {}\n },\n {\n "tool": "list_design_frames",\n "arguments": {\n "project": "r6z2n9k4x8m1qc"\n }\n },\n {\n "tool": "create_design_frame",\n "arguments": {\n "project": "r6z2n9k4x8m1qc",\n "name": "Racecar",\n "type": "glts",\n "width": 1280,\n "height": 800,\n "text": "import { gltsLoader, scene } from \\"@drawcall/glts\\";\\n\\nconst wheel = await gltsLoader.loadAsync(\\n new URL(\\"./parts/wheel.glts\\", import.meta.url),\\n);\\nscene.add(wheel);\\n",\n "imports": {\n "./parts/wheel.glts": {\n "min": [\n -0.5,\n 0,\n -0.5\n ],\n "max": [\n 0.5,\n 1,\n 0.5\n ]\n }\n }\n }\n },\n {\n "tool": "write_design_file",\n "arguments": {\n "project": "r6z2n9k4x8m1qc",\n "path": "/a4z8m2q7v9kcde/parts/wheel.glts",\n "text": "import * as THREE from \\"three\\";\\nimport { onDispose, scene } from \\"@drawcall/glts\\";\\n\\nconst geometry = new THREE.TorusGeometry(0.4, 0.12, 16, 48);\\nconst material = new THREE.MeshStandardMaterial({ color: 0x222222 });\\nscene.add(new THREE.Mesh(geometry, material));\\n\\nonDispose(() => {\\n geometry.dispose();\\n material.dispose();\\n});\\n"\n }\n },\n {\n "tool": "list_design_files",\n "arguments": {\n "project": "r6z2n9k4x8m1qc"\n }\n },\n {\n "tool": "read_design_file",\n "arguments": {\n "project": "r6z2n9k4x8m1qc",\n "path": "/a4z8m2q7v9kcde/index.glts"\n }\n },\n {\n "tool": "edit_design_file",\n "arguments": {\n "project": "r6z2n9k4x8m1qc",\n "path": "/a4z8m2q7v9kcde/index.glts",\n "oldText": "color: 0xffffff",\n "newText": "color: 0x000000"\n }\n },\n {\n "tool": "create_design_comment",\n "arguments": {\n "project": "r6z2n9k4x8m1qc",\n "frame": "a4z8m2q7v9kcde",\n "body": "The bevel catches the key light here.",\n "position": {\n "kind": "3d",\n "x": 0.2,\n "y": 1.1,\n "z": -0.4\n },\n "expectedContentRevision": 7\n }\n },\n {\n "tool": "reply_to_design_comment",\n "arguments": {\n "project": "r6z2n9k4x8m1qc",\n "comment": "c4z8m2q7v9kcdf",\n "body": "Adjusted the material roughness."\n }\n },\n {\n "tool": "resolve_design_comment",\n "arguments": {\n "project": "r6z2n9k4x8m1qc",\n "comment": "c4z8m2q7v9kcdf"\n }\n },\n {\n "tool": "generate_design_image",\n "arguments": {\n "project": "r6z2n9k4x8m1qc",\n "operation": "generate",\n "prompt": "A product photograph of this object",\n "references": [\n "https://r6z2n9k4x8m1qc.design.drawcallcontent.com/a4z8m2q7v9kcde.webp"\n ],\n "result": "new",\n "name": "Product photograph"\n }\n },\n {\n "tool": "get_design_frame_preview",\n "arguments": {\n "project": "r6z2n9k4x8m1qc",\n "frame": "a4z8m2q7v9kcde"\n }\n }\n]\n```\n\nDesign is a remote, current-state canvas. Inspect the project and its frames before changing them. Use immutable IDs for every project and frame target; names are mutable labels. In user-facing replies, refer to projects, frames, and other named resources by their current names. Do not expose their IDs unless the user explicitly asks for them; IDs may remain embedded in URLs that link to those resources.\n\n## Project filesystem\n\nA project is a hosted filesystem at `https://<project-id>.design.drawcallcontent.com/`. Each frame owns one top-level directory, `/<frame-id>`. Files use project-absolute paths that include that directory, for example `/a4z8m2q7v9kcde/index.glts`.\n\nCreate frames with an explicit type. Choose the type from the requested artifact, not from the word "frame": use GLTS for a 3D object or scene, Markdown for a formatted text document, image for an existing 2D image, and Market only for an exact public asset reference, `name@version`. GLTS and Markdown frames require a viewport size; image and Market frames derive their canvas size. A GLTS or Markdown frame accepts its root file at creation.\n\nRead a file before editing it. Use a narrow edit for one known change and write a complete file when replacing it. GLTS and Markdown frame files may be created or deleted. Image and Market frame files are read-only.\n\n## Frame previews\n\nEvery frame has a canonical public WebP preview in `previewUrl` at `https://<project-id>.design.drawcallcontent.com/<frame-id>.webp`, whether its type is GLTS, Markdown, image, or Market. Use `get_design_frame_preview` to inspect it as image content. Use `get_design_frame_screenshot` only when a fresh PNG render is required. Pass `previewUrl` as a reference URL to `generate_design_image` when one frame\'s appearance should inform another image.\n\n## Markdown documents\n\nA Markdown frame contains one optional source file at `/<frame-id>/index.md`; without it the frame renders as an empty document. Raw HTML is not rendered. Use ordinary Markdown image syntax with a frame\'s canonical WebP path to embed its current rendering:\n\n```md\n![Descriptive alternative text](/other-frame-id.webp)\n```\n\nAn absolute canonical WebP URL from the same project is equivalent. A Markdown document may embed up to 32 existing GLTS, image, or Market frames. It may not embed itself or another Markdown frame. Use the canonical syntax instead of copying a screenshot URL or source asset so the document follows later frame changes.\n\nPrefer focused Markdown frames. A document that covers separable topics is usually clearer as multiple frames connected with canonical links, `[Related details](/<frame-id>/)`, because readers can navigate directly to the part they need. An embedded frame is useful when its current rendering adds visual context; a link is better when the reader only needs to navigate.\n\n## Comments and annotations\n\nUse comments for review conversations and persistent annotations, including explanations of objects or regions inside 2D and 3D frames. Inspect the current comments before replying, resolving, reopening, or deleting so the action targets the current thread.\n\nA comment without a position applies to its frame. A 2D position is normalized image space and applies only to an image frame. A 3D position is GLTS world space and applies only to a GLTS frame. Add a position only when its coordinates are authoritative; never infer 3D depth from a screenshot. Prefer a frame-level comment when the precise position is unknown.\n\nPositioned comments retain the frame version on which they were placed. If the frame later changes, treat the position as potentially stale and re-inspect the frame before relying on it. Replies belong to the root comment\'s thread. Resolved threads do not accept replies, so reopen one before continuing it. Resolve a thread when its concern has been addressed. Delete a comment or reply only when explicitly requested because deletion is permanent; deleting a root also deletes its replies. Comment authors come from the authenticated Drawcall account—never invent an author identity.\n\n## Failures\n\nAn error means the requested operation did not happen. Follow its next action without switching transport. Correct invalid arguments from the documented shape. Refresh projects, frames, or files after a not-found or conflict error, then reuse the exact returned IDs and paths. Retry an upstream or internal failure once; if it repeats, report the failed operation and error. Never repeat an unchanged failed operation.\n\n## GLTS assets\n\nMarket assets can be faster and higher quality than recreating them in GLTS. Consider this separately for each substantial model, texture, and environment before hand-authoring it; if a quick search is likely to improve quality relative to latency, first read `get_market_instructions`.\n\nA GLTS frame contains only `.glts` files. `index.glts` is its optional root asset; without it the frame renders empty. Every `.glts` file is a trusted, exportless TypeScript ESM script that builds a native `THREE.Scene` through contextual values from `@drawcall/glts`:\n\n```ts\nimport * as THREE from "three";\nimport { onDispose, scene } from "@drawcall/glts";\n\nconst geometry = new THREE.BoxGeometry();\nconst material = new THREE.MeshStandardMaterial({ color: "orange" });\nscene.add(new THREE.Mesh(geometry, material));\n\nonDispose(() => {\n geometry.dispose();\n material.dispose();\n});\n```\n\nUse named contextual imports: `gltsLoader`, `instanceCount`, `isPreview`, `loadingManager`, `onDispose`, `onFrame`, `onMatrixUpdateAt`, and `scene`. Do not export anything or import `GLTSLoader` or `GLTSRenderer`; the host owns loading and rendering. The script may import `three`, Three addons, and browser-compatible npm packages, but not static `.glts` imports, dynamic imports, import attributes, or sibling `.ts` helpers.\n\nThe host owns the root `scene` transform. Put authored placement and animation under child objects instead of changing the root scene\'s transform.\n\n### Composition and placeholders\n\nCompose another `.glts` file with the contextual loader and an explicit URL. Every loaded child must be added beneath `scene` before the script finishes:\n\n```ts\nimport * as THREE from "three";\nimport { gltsLoader, scene } from "@drawcall/glts";\n\nconst wheel = await gltsLoader.loadAsync(\n new URL("./parts/wheel.glts", import.meta.url),\n);\nwheel.position.set(0.8, 0.4, 1.3);\nscene.add(wheel);\n```\n\nFor a 3D object, create the frame with its complete `index.glts` first. When a referenced `.glts` file does not exist yet, give its URL specifier a rough bounding box in `imports`; Design creates a visible placeholder at that path. Then write each placeholder file one call at a time, the most visible first, and take a screenshot once none remain. A nested file that loads another missing file declares that file\'s box on its own write.\n\nUse relative URLs within a frame. A reusable 3D asset belongs in another frame; load its root by project-absolute URL instead of copying its source:\n\n```ts\nconst chassis = await gltsLoader.loadAsync(\n new URL("/other-frame-id/index.glts", import.meta.url),\n);\nscene.add(chassis);\n```\n\nDo not register `child.dispose()` with `onDispose`; attached GLTS children are owned and disposed recursively. Avoid cyclic loads. Use `loadInstancesAsync(url, count)` for a static mesh hierarchy when repeated copies matter; animated, nested, skinned, or already-instanced content needs native instancing with `instanceCount` and `onMatrixUpdateAt`.\n\n### Resources, updates, and cleanup\n\nFor a non-GLTS file from an image or Market frame, resolve its project filesystem URL through `import.meta.url`:\n\n```ts\nconst modelUrl = new URL("/market-frame-id/models/car.glb", import.meta.url);\n```\n\nPass the contextual `loadingManager` to Three.js loaders during script evaluation so the frame waits for their requests and surfaces failures. Three.js loaders take URL strings; GLTS loader methods accept the `URL` itself. Top-level `await` is supported. Do not start loads from frame, matrix, timer, event, or effect callbacks because the loading scope has closed.\n\n```ts\nimport * as THREE from "three";\nimport { loadingManager, scene } from "@drawcall/glts";\nimport { GLTFLoader } from "three/addons/loaders/GLTFLoader.js";\n\nconst model = await new GLTFLoader(loadingManager).loadAsync(\n new URL("./car.glb", import.meta.url).href,\n);\nscene.add(model.scene);\n```\n\nRelease only resources the script creates. GLTS recursively disposes managed child scenes but does not infer geometry, material, texture, or listener ownership. Close disposal callbacks over the owned values rather than traversing the imported `scene`, whose live binding follows the new revision during reload.\n\nUse `onFrame((delta) => ...)` for animation. Design advances the loaded root every frame, including managed descendants. A failed reload leaves the previous scene mounted.\n\n### Root presentation\n\nNative scene properties such as `scene.background`, `scene.environment`, `scene.fog`, and `scene.overrideMaterial` describe the asset when it is the render root. Assign `scene.defaultCamera` to recommend an authored view; a saved Design frame camera still overrides it. Design autofits the scene when neither exists.\n\nUse `isPreview` for staging that belongs only in the standalone Design frame, such as a floor, light rig, background, fog, or presentation effects. Design loads each displayed root in preview mode; nested GLTS scenes always receive `isPreview === false`, so their presentation does not leak into composition. Keep intrinsic content and each mesh\'s `castShadow` setting outside this block.\n\n```ts\nimport * as THREE from "three";\nimport { isPreview, onDispose, scene } from "@drawcall/glts";\nimport { UnrealBloomPass } from "three/addons/postprocessing/UnrealBloomPass.js";\n\nscene.defaultCamera = new THREE.PerspectiveCamera(35, 1, 0.1, 100);\nscene.defaultCamera.position.set(4, 3, 6);\nscene.defaultCamera.lookAt(0, 1, 0);\n\nif (isPreview) {\n const floor = new THREE.Mesh(\n new THREE.CircleGeometry(20),\n new THREE.MeshStandardMaterial({ color: "#333333" }),\n );\n floor.rotation.x = -Math.PI / 2;\n floor.receiveShadow = true;\n const light = new THREE.DirectionalLight("white", 3);\n light.position.set(4, 6, 3);\n light.castShadow = true;\n\n scene.background = new THREE.Color("#171b2b");\n scene.add(light, light.target, floor);\n scene.rendering.shadows = true;\n scene.rendering.toneMapping = THREE.ACESFilmicToneMapping;\n scene.rendering.toneMappingExposure = 1.1;\n scene.rendering.effects.push(\n ({ height, width }) =>\n new UnrealBloomPass(new THREE.Vector2(width, height), 0.3, 0.4, 0.85),\n );\n\n onDispose(() => {\n light.dispose();\n floor.geometry.dispose();\n floor.material.dispose();\n });\n}\n```\n\n`scene.rendering` supports shadows, clipping planes, tone mapping, exposure, and post-processing effect factories. A factory returns a fresh Three.js `Pass`; do not add `RenderPass` or `OutputPass`, load resources there, or dispose the returned pass yourself. The host renderer owns those passes. Visible shadows require renderer shadows plus a shadow-casting light, casting meshes, and receiving surfaces.\n\nPresentation belongs only to the root. A nested scene\'s background, environment, fog, default camera, and rendering profile do not override its parent.\n\n### Verification\n\nTreat authoritative source or structured state as sufficient when it directly and completely determines the requested property. Do not take a screenshot merely to reconfirm that evidence. Take one only when the result depends on rendering or visual relationships the source cannot establish, such as layout, overlap, clipping, camera framing, lighting, or runtime-generated appearance, or when the user explicitly asks. Then inspect it against the request and iterate until the evidence supports completion.\n';
3
- export const cliDesignSkill = '---\nname: drawcall-design\ndescription: Create, modify, inspect, compose, and reuse GLTS scenes, Markdown documents, and image or Market references in Drawcall Design. Use whenever the user names Drawcall Design or one of its projects, canvases, frames, filesystems, GLTS assets, or Markdown frames. Do not use for full games, applications, or unrelated image generation.\n---\n\n# Drawcall Design\n\n## CLI transport\n\nThe commands below are the Drawcall transport in this environment. For Design operations, use only this documented command interface. A failed command does not make the transport unavailable.\n\nImage frame creation and image-generation references accept public HTTP(S) URLs or local PNG, JPEG, and WebP files.\n\nSelect the project with `-p <project-id>`. File commands take project-absolute paths that include the frame ID. Repeat `--reference` to preserve image-generation reference order.\n\n```sh\nnpx drawcall design project list\nnpx drawcall design -p r6z2n9k4x8m1qc frame list\nnpx drawcall design -p r6z2n9k4x8m1qc frame create Racecar --type glts --size 1280x800 --import ./parts/wheel.glts=-0.5,0,-0.5:0.5,1,0.5 --text - <<\'GLTS\'\nimport { gltsLoader, scene } from "@drawcall/glts";\n\nconst wheel = await gltsLoader.loadAsync(\n new URL("./parts/wheel.glts", import.meta.url),\n);\nscene.add(wheel);\nGLTS\nnpx drawcall design -p r6z2n9k4x8m1qc write /a4z8m2q7v9kcde/parts/wheel.glts - <<\'GLTS\'\nimport * as THREE from "three";\nimport { onDispose, scene } from "@drawcall/glts";\n\nconst geometry = new THREE.TorusGeometry(0.4, 0.12, 16, 48);\nconst material = new THREE.MeshStandardMaterial({ color: 0x222222 });\nscene.add(new THREE.Mesh(geometry, material));\n\nonDispose(() => {\n geometry.dispose();\n material.dispose();\n});\nGLTS\nnpx drawcall design -p r6z2n9k4x8m1qc frame preview a4z8m2q7v9kcde\nnpx drawcall design -p r6z2n9k4x8m1qc frame screenshot a4z8m2q7v9kcde\nnpx drawcall design -p r6z2n9k4x8m1qc ls\nnpx drawcall design -p r6z2n9k4x8m1qc read /a4z8m2q7v9kcde/index.glts\nnpx drawcall design -p r6z2n9k4x8m1qc edit /a4z8m2q7v9kcde/index.glts \'color: 0xffffff\' \'color: 0x000000\'\nnpx drawcall design -p r6z2n9k4x8m1qc comment list a4z8m2q7v9kcde\nnpx drawcall design -p r6z2n9k4x8m1qc comment show c4z8m2q7v9kcdf\nnpx drawcall design -p r6z2n9k4x8m1qc comment create a4z8m2q7v9kcde \'The bevel catches the key light here.\' --position-3d 0.2,1.1,-0.4\nnpx drawcall design -p r6z2n9k4x8m1qc comment reply c4z8m2q7v9kcdf \'Adjusted the material roughness.\'\nnpx drawcall design -p r6z2n9k4x8m1qc comment resolve c4z8m2q7v9kcdf\nnpx drawcall design -p r6z2n9k4x8m1qc comment delete c4z8m2q7v9kcdf --yes\nnpx drawcall design -p r6z2n9k4x8m1qc frame generate-image \'Product photograph\' --prompt \'A product photograph of this object\' --reference https://r6z2n9k4x8m1qc.design.drawcallcontent.com/a4z8m2q7v9kcde.webp\nnpx drawcall design -p r6z2n9k4x8m1qc frame edit-image b4z8m2q7v9kcdf --prompt \'Use warmer light\' --name \'Warm product photograph\' --reference ./lighting.webp\n```\n\n`frame create --text`, `write`, comment create, and reply text accept `-` to read the text from stdin; a quoted heredoc keeps multi-line source intact. `--import <specifier>=<min>:<max>` declares the bounding box of a contextually loaded `.glts` file that does not exist yet, as `x,y,z:x,y,z`, and may repeat. Run one file write per command invocation, never several in one shell command. Use `--position-2d x,y` only for normalized image coordinates and `--position-3d x,y,z` only for authoritative GLTS world coordinates.\n\nDesign is a remote, current-state canvas. Inspect the project and its frames before changing them. Use immutable IDs for every project and frame target; names are mutable labels. In user-facing replies, refer to projects, frames, and other named resources by their current names. Do not expose their IDs unless the user explicitly asks for them; IDs may remain embedded in URLs that link to those resources.\n\n## Project filesystem\n\nA project is a hosted filesystem at `https://<project-id>.design.drawcallcontent.com/`. Each frame owns one top-level directory, `/<frame-id>`. Files use project-absolute paths that include that directory, for example `/a4z8m2q7v9kcde/index.glts`.\n\nCreate frames with an explicit type. Choose the type from the requested artifact, not from the word "frame": use GLTS for a 3D object or scene, Markdown for a formatted text document, image for an existing 2D image, and Market only for an exact public asset reference, `name@version`. GLTS and Markdown frames require a viewport size; image and Market frames derive their canvas size. A GLTS or Markdown frame accepts its root file at creation.\n\nRead a file before editing it. Use a narrow edit for one known change and write a complete file when replacing it. GLTS and Markdown frame files may be created or deleted. Image and Market frame files are read-only.\n\n## Frame previews\n\nEvery frame has a canonical public WebP preview in `previewUrl` at `https://<project-id>.design.drawcallcontent.com/<frame-id>.webp`, whether its type is GLTS, Markdown, image, or Market. `frame preview <frame-id>` prints that URL. Use `frame screenshot` only when a fresh PNG render is required. Pass a preview URL with `--reference` when one frame\'s appearance should inform another image. A reference may instead be a local PNG, JPEG, or WebP file.\n\n## Markdown documents\n\nA Markdown frame contains one optional source file at `/<frame-id>/index.md`; without it the frame renders as an empty document. Raw HTML is not rendered. Use ordinary Markdown image syntax with a frame\'s canonical WebP path to embed its current rendering:\n\n```md\n![Descriptive alternative text](/other-frame-id.webp)\n```\n\nAn absolute canonical WebP URL from the same project is equivalent. A Markdown document may embed up to 32 existing GLTS, image, or Market frames. It may not embed itself or another Markdown frame. Use the canonical syntax instead of copying a screenshot URL or source asset so the document follows later frame changes.\n\nPrefer focused Markdown frames. A document that covers separable topics is usually clearer as multiple frames connected with canonical links, `[Related details](/<frame-id>/)`, because readers can navigate directly to the part they need. An embedded frame is useful when its current rendering adds visual context; a link is better when the reader only needs to navigate.\n\n## Comments and annotations\n\nUse comments for review conversations and persistent annotations, including explanations of objects or regions inside 2D and 3D frames. Inspect the current comments before replying, resolving, reopening, or deleting so the action targets the current thread.\n\nA comment without a position applies to its frame. A 2D position is normalized image space and applies only to an image frame. A 3D position is GLTS world space and applies only to a GLTS frame. Add a position only when its coordinates are authoritative; never infer 3D depth from a screenshot. Prefer a frame-level comment when the precise position is unknown.\n\nPositioned comments retain the frame version on which they were placed. If the frame later changes, treat the position as potentially stale and re-inspect the frame before relying on it. Replies belong to the root comment\'s thread. Resolved threads do not accept replies, so reopen one before continuing it. Resolve a thread when its concern has been addressed. Delete a comment or reply only when explicitly requested because deletion is permanent; deleting a root also deletes its replies. Comment authors come from the authenticated Drawcall account—never invent an author identity.\n\n## Failures\n\nAn error means the requested operation did not happen. Follow its next action without switching transport. Correct invalid arguments from the documented shape. Refresh projects, frames, or files after a not-found or conflict error, then reuse the exact returned IDs and paths. Retry an upstream or internal failure once; if it repeats, report the failed operation and error. Never repeat an unchanged failed operation.\n\n## GLTS assets\n\nMarket assets can be faster and higher quality than recreating them in GLTS. Consider this separately for each substantial model, texture, and environment before hand-authoring it; if a quick search is likely to improve quality relative to latency, first read `npx drawcall market skill`.\n\nA GLTS frame contains only `.glts` files. `index.glts` is its optional root asset; without it the frame renders empty. Every `.glts` file is a trusted, exportless TypeScript ESM script that builds a native `THREE.Scene` through contextual values from `@drawcall/glts`:\n\n```ts\nimport * as THREE from "three";\nimport { onDispose, scene } from "@drawcall/glts";\n\nconst geometry = new THREE.BoxGeometry();\nconst material = new THREE.MeshStandardMaterial({ color: "orange" });\nscene.add(new THREE.Mesh(geometry, material));\n\nonDispose(() => {\n geometry.dispose();\n material.dispose();\n});\n```\n\nUse named contextual imports: `gltsLoader`, `instanceCount`, `isPreview`, `loadingManager`, `onDispose`, `onFrame`, `onMatrixUpdateAt`, and `scene`. Do not export anything or import `GLTSLoader` or `GLTSRenderer`; the host owns loading and rendering. The script may import `three`, Three addons, and browser-compatible npm packages, but not static `.glts` imports, dynamic imports, import attributes, or sibling `.ts` helpers.\n\nThe host owns the root `scene` transform. Put authored placement and animation under child objects instead of changing the root scene\'s transform.\n\n### Composition and placeholders\n\nCompose another `.glts` file with the contextual loader and an explicit URL. Every loaded child must be added beneath `scene` before the script finishes:\n\n```ts\nimport * as THREE from "three";\nimport { gltsLoader, scene } from "@drawcall/glts";\n\nconst wheel = await gltsLoader.loadAsync(\n new URL("./parts/wheel.glts", import.meta.url),\n);\nwheel.position.set(0.8, 0.4, 1.3);\nscene.add(wheel);\n```\n\nFor a 3D object, create the frame with its complete `index.glts` first. When a referenced `.glts` file does not exist yet, give its URL specifier a rough bounding box in `imports`; Design creates a visible placeholder at that path. Then write each placeholder file one call at a time, the most visible first, and take a screenshot once none remain. A nested file that loads another missing file declares that file\'s box on its own write.\n\nUse relative URLs within a frame. A reusable 3D asset belongs in another frame; load its root by project-absolute URL instead of copying its source:\n\n```ts\nconst chassis = await gltsLoader.loadAsync(\n new URL("/other-frame-id/index.glts", import.meta.url),\n);\nscene.add(chassis);\n```\n\nDo not register `child.dispose()` with `onDispose`; attached GLTS children are owned and disposed recursively. Avoid cyclic loads. Use `loadInstancesAsync(url, count)` for a static mesh hierarchy when repeated copies matter; animated, nested, skinned, or already-instanced content needs native instancing with `instanceCount` and `onMatrixUpdateAt`.\n\n### Resources, updates, and cleanup\n\nFor a non-GLTS file from an image or Market frame, resolve its project filesystem URL through `import.meta.url`:\n\n```ts\nconst modelUrl = new URL("/market-frame-id/models/car.glb", import.meta.url);\n```\n\nPass the contextual `loadingManager` to Three.js loaders during script evaluation so the frame waits for their requests and surfaces failures. Three.js loaders take URL strings; GLTS loader methods accept the `URL` itself. Top-level `await` is supported. Do not start loads from frame, matrix, timer, event, or effect callbacks because the loading scope has closed.\n\n```ts\nimport * as THREE from "three";\nimport { loadingManager, scene } from "@drawcall/glts";\nimport { GLTFLoader } from "three/addons/loaders/GLTFLoader.js";\n\nconst model = await new GLTFLoader(loadingManager).loadAsync(\n new URL("./car.glb", import.meta.url).href,\n);\nscene.add(model.scene);\n```\n\nRelease only resources the script creates. GLTS recursively disposes managed child scenes but does not infer geometry, material, texture, or listener ownership. Close disposal callbacks over the owned values rather than traversing the imported `scene`, whose live binding follows the new revision during reload.\n\nUse `onFrame((delta) => ...)` for animation. Design advances the loaded root every frame, including managed descendants. A failed reload leaves the previous scene mounted.\n\n### Root presentation\n\nNative scene properties such as `scene.background`, `scene.environment`, `scene.fog`, and `scene.overrideMaterial` describe the asset when it is the render root. Assign `scene.defaultCamera` to recommend an authored view; a saved Design frame camera still overrides it. Design autofits the scene when neither exists.\n\nUse `isPreview` for staging that belongs only in the standalone Design frame, such as a floor, light rig, background, fog, or presentation effects. Design loads each displayed root in preview mode; nested GLTS scenes always receive `isPreview === false`, so their presentation does not leak into composition. Keep intrinsic content and each mesh\'s `castShadow` setting outside this block.\n\n```ts\nimport * as THREE from "three";\nimport { isPreview, onDispose, scene } from "@drawcall/glts";\nimport { UnrealBloomPass } from "three/addons/postprocessing/UnrealBloomPass.js";\n\nscene.defaultCamera = new THREE.PerspectiveCamera(35, 1, 0.1, 100);\nscene.defaultCamera.position.set(4, 3, 6);\nscene.defaultCamera.lookAt(0, 1, 0);\n\nif (isPreview) {\n const floor = new THREE.Mesh(\n new THREE.CircleGeometry(20),\n new THREE.MeshStandardMaterial({ color: "#333333" }),\n );\n floor.rotation.x = -Math.PI / 2;\n floor.receiveShadow = true;\n const light = new THREE.DirectionalLight("white", 3);\n light.position.set(4, 6, 3);\n light.castShadow = true;\n\n scene.background = new THREE.Color("#171b2b");\n scene.add(light, light.target, floor);\n scene.rendering.shadows = true;\n scene.rendering.toneMapping = THREE.ACESFilmicToneMapping;\n scene.rendering.toneMappingExposure = 1.1;\n scene.rendering.effects.push(\n ({ height, width }) =>\n new UnrealBloomPass(new THREE.Vector2(width, height), 0.3, 0.4, 0.85),\n );\n\n onDispose(() => {\n light.dispose();\n floor.geometry.dispose();\n floor.material.dispose();\n });\n}\n```\n\n`scene.rendering` supports shadows, clipping planes, tone mapping, exposure, and post-processing effect factories. A factory returns a fresh Three.js `Pass`; do not add `RenderPass` or `OutputPass`, load resources there, or dispose the returned pass yourself. The host renderer owns those passes. Visible shadows require renderer shadows plus a shadow-casting light, casting meshes, and receiving surfaces.\n\nPresentation belongs only to the root. A nested scene\'s background, environment, fog, default camera, and rendering profile do not override its parent.\n\n### Verification\n\nTreat authoritative source or structured state as sufficient when it directly and completely determines the requested property. Do not take a screenshot merely to reconfirm that evidence. Take one only when the result depends on rendering or visual relationships the source cannot establish, such as layout, overlap, clipping, camera framing, lighting, or runtime-generated appearance, or when the user explicitly asks. Then inspect it against the request and iterate until the evidence supports completion.\n';
2
+ export const mcpDesignSkill = '---\nname: drawcall-design\ndescription: Create, modify, inspect, compose, and reuse GLTS scenes, Markdown documents, and image or Market references in Drawcall Design. Use whenever the user names Drawcall Design or one of its projects, canvases, frames, filesystems, GLTS assets, or Markdown frames. Do not use for full games, applications, or unrelated image generation.\n---\n\n# Drawcall Design\n\n## MCP transport\n\nMCP tools are the Drawcall transport in this environment. For Design operations, use only the tools documented here. A failed tool call does not make the transport unavailable.\n\nImage frame creation uses a public HTTP(S) image URL.\n\nUse `generate_design_image` only when the user asks for a 2D image or reference. Its references must be public HTTP(S) URLs. A 3D object, scene, or reusable asset is GLTS work, even when the user calls its canvas container a frame.\n\nTool arguments are JSON objects. `create_design_frame` takes the root file of a glts or markdown frame as `text`, and `create_design_frame`, `write_design_file`, and `edit_design_file` take `imports`, the bounding box of each contextually loaded `.glts` file that does not exist yet, keyed by its URL specifier as written. The create result includes the new frame ID that later paths start with. File tools identify their target with `project` and a project-absolute `path`; they do not accept a separate `frame` argument. Call `list_design_files` and pass one of its returned paths unchanged.\n\nFor comments, call `list_design_comments` and, when needed, `get_design_comment` before changing a thread. Use `create_design_comment`, `reply_to_design_comment`, `resolve_design_comment`, `reopen_design_comment`, and `delete_design_comment` for their named operations. Structured tool calls use `body` for comment text. A positioned create requires the target frame\'s current `contentRevision` as `expectedContentRevision`; list frames again and re-inspect the position after a conflict.\n\n```json\n[\n {\n "tool": "list_design_projects",\n "arguments": {}\n },\n {\n "tool": "list_design_frames",\n "arguments": {\n "project": "r6z2n9k4x8m1qc"\n }\n },\n {\n "tool": "create_design_frame",\n "arguments": {\n "project": "r6z2n9k4x8m1qc",\n "name": "Racecar",\n "type": "glts",\n "width": 1280,\n "height": 800,\n "text": "import { gltsLoader, scene } from \\"@drawcall/glts\\";\\n\\nconst wheel = await gltsLoader.loadAsync(\\n new URL(\\"./parts/wheel.glts\\", import.meta.url),\\n);\\nscene.add(wheel);\\n",\n "imports": {\n "./parts/wheel.glts": {\n "min": [\n -0.5,\n 0,\n -0.5\n ],\n "max": [\n 0.5,\n 1,\n 0.5\n ]\n }\n }\n }\n },\n {\n "tool": "write_design_file",\n "arguments": {\n "project": "r6z2n9k4x8m1qc",\n "path": "/a4z8m2q7v9kcde/parts/wheel.glts",\n "text": "import * as THREE from \\"three\\";\\nimport { onDispose, scene } from \\"@drawcall/glts\\";\\n\\nconst geometry = new THREE.TorusGeometry(0.4, 0.12, 16, 48);\\nconst material = new THREE.MeshStandardMaterial({ color: 0x222222 });\\nscene.add(new THREE.Mesh(geometry, material));\\n\\nonDispose(() => {\\n geometry.dispose();\\n material.dispose();\\n});\\n"\n }\n },\n {\n "tool": "list_design_files",\n "arguments": {\n "project": "r6z2n9k4x8m1qc"\n }\n },\n {\n "tool": "read_design_file",\n "arguments": {\n "project": "r6z2n9k4x8m1qc",\n "path": "/a4z8m2q7v9kcde/index.glts"\n }\n },\n {\n "tool": "edit_design_file",\n "arguments": {\n "project": "r6z2n9k4x8m1qc",\n "path": "/a4z8m2q7v9kcde/index.glts",\n "oldText": "color: 0xffffff",\n "newText": "color: 0x000000"\n }\n },\n {\n "tool": "create_design_comment",\n "arguments": {\n "project": "r6z2n9k4x8m1qc",\n "frame": "a4z8m2q7v9kcde",\n "body": "The bevel catches the key light here.",\n "position": {\n "kind": "3d",\n "x": 0.2,\n "y": 1.1,\n "z": -0.4\n },\n "expectedContentRevision": 7\n }\n },\n {\n "tool": "reply_to_design_comment",\n "arguments": {\n "project": "r6z2n9k4x8m1qc",\n "comment": "c4z8m2q7v9kcdf",\n "body": "Adjusted the material roughness."\n }\n },\n {\n "tool": "resolve_design_comment",\n "arguments": {\n "project": "r6z2n9k4x8m1qc",\n "comment": "c4z8m2q7v9kcdf"\n }\n },\n {\n "tool": "generate_design_image",\n "arguments": {\n "project": "r6z2n9k4x8m1qc",\n "operation": "generate",\n "prompt": "A product photograph of this object",\n "references": [\n "https://r6z2n9k4x8m1qc.design.drawcallcontent.com/a4z8m2q7v9kcde.webp"\n ],\n "result": "new",\n "name": "Product photograph"\n }\n },\n {\n "tool": "get_design_frame_preview",\n "arguments": {\n "project": "r6z2n9k4x8m1qc",\n "frame": "a4z8m2q7v9kcde"\n }\n }\n]\n```\n\nDesign is a remote, current-state canvas. Inspect the project and its frames before changing them. Use immutable IDs for every project and frame target; names are mutable labels. In user-facing replies, refer to projects, frames, and other named resources by their current names. Do not expose their IDs unless the user explicitly asks for them; IDs may remain embedded in URLs that link to those resources.\n\n## Project filesystem\n\nA project is a hosted filesystem at `https://<project-id>.design.drawcallcontent.com/`. Each frame owns one top-level directory, `/<frame-id>`. Files use project-absolute paths that include that directory, for example `/a4z8m2q7v9kcde/index.glts`.\n\nCreate frames with an explicit type. Choose the type from the requested artifact, not from the word "frame": use GLTS for a 3D object or scene, Markdown for a formatted text document, image for an existing 2D image, and Market only for an exact public asset reference, `name@version`. GLTS and Markdown frames require a viewport size; image and Market frames derive their canvas size. A GLTS or Markdown frame accepts its root file at creation.\n\nRead a file before editing it. Use a narrow edit for one known change and write a complete file when replacing it. GLTS and Markdown frame files may be created or deleted. Image and Market frame files are read-only.\n\n## Frame previews\n\nEvery frame has a canonical public WebP preview in `previewUrl` at `https://<project-id>.design.drawcallcontent.com/<frame-id>.webp`, whether its type is GLTS, Markdown, image, or Market. Use `get_design_frame_preview` to inspect it as image content. Use `get_design_frame_screenshot` only when a fresh PNG render is required. Pass `previewUrl` as a reference URL to `generate_design_image` when one frame\'s appearance should inform another image.\n\n## Markdown documents\n\nA Markdown frame contains one optional source file at `/<frame-id>/index.md`; without it the frame renders as an empty document. Raw HTML is not rendered. Use ordinary Markdown image syntax with a frame\'s canonical WebP path to embed its current rendering:\n\n```md\n![Descriptive alternative text](/other-frame-id.webp)\n```\n\nAn absolute canonical WebP URL from the same project is equivalent. A Markdown document may embed up to 32 existing GLTS, image, or Market frames. It may not embed itself or another Markdown frame. Use the canonical syntax instead of copying a screenshot URL or source asset so the document follows later frame changes.\n\nPrefer focused Markdown frames. A document that covers separable topics is usually clearer as multiple frames connected with canonical links, `[Related details](/<frame-id>/)`, because readers can navigate directly to the part they need. An embedded frame is useful when its current rendering adds visual context; a link is better when the reader only needs to navigate.\n\n## Comments and annotations\n\nUse comments for review conversations and persistent annotations, including explanations of objects or regions inside 2D and 3D frames. Inspect the current comments before replying, resolving, reopening, or deleting so the action targets the current thread.\n\nA comment without a position applies to its frame. A 2D position is normalized image space and applies only to an image frame. A 3D position is GLTS world space and applies only to a GLTS frame. Add a position only when its coordinates are authoritative; never infer 3D depth from a screenshot. Prefer a frame-level comment when the precise position is unknown.\n\nPositioned comments retain the frame version on which they were placed. If the frame later changes, treat the position as potentially stale and re-inspect the frame before relying on it. Replies belong to the root comment\'s thread. Resolved threads do not accept replies, so reopen one before continuing it. Resolve a thread when its concern has been addressed. Delete a comment or reply only when explicitly requested because deletion is permanent; deleting a root also deletes its replies. Comment authors come from the authenticated Drawcall account—never invent an author identity.\n\n## Failures\n\nAn error means the requested operation did not happen. Follow its next action without switching transport. Correct invalid arguments from the documented shape. Refresh projects, frames, or files after a not-found or conflict error, then reuse the exact returned IDs and paths. Retry an upstream or internal failure once; if it repeats, report the failed operation and error. Never repeat an unchanged failed operation.\n\n## GLTS assets\n\n### Market check\n\nBefore hand-authoring a substantial model, texture, or environment, first read `get_market_instructions`, search Market once, and preview the best close match. Do not skip this check to save time; skip it only for simple or inherently procedural elements. Use the asset only if it beats hand-authoring on quality relative to latency; otherwise name the rejected asset and why.\n\nA GLTS frame contains only `.glts` files. `index.glts` is its optional root asset; without it the frame renders empty. Every `.glts` file is a trusted, exportless TypeScript ESM script that builds a native `THREE.Scene` through contextual values from `@drawcall/glts`:\n\n```ts\nimport * as THREE from "three";\nimport { onDispose, scene } from "@drawcall/glts";\n\nconst geometry = new THREE.BoxGeometry();\nconst material = new THREE.MeshStandardMaterial({ color: "orange" });\nscene.add(new THREE.Mesh(geometry, material));\n\nonDispose(() => {\n geometry.dispose();\n material.dispose();\n});\n```\n\nUse named contextual imports: `gltsLoader`, `instanceCount`, `isPreview`, `loadingManager`, `onDispose`, `onFrame`, `onMatrixUpdateAt`, and `scene`. Do not export anything or import `GLTSLoader` or `GLTSRenderer`; the host owns loading and rendering. The script may import `three`, Three addons, and browser-compatible npm packages, but not static `.glts` imports, dynamic imports, import attributes, or sibling `.ts` helpers.\n\nThe host owns the root `scene` transform. Put authored placement and animation under child objects instead of changing the root scene\'s transform.\n\n### Composition and placeholders\n\nCompose another `.glts` file with the contextual loader and an explicit URL. Every loaded child must be added beneath `scene` before the script finishes:\n\n```ts\nimport * as THREE from "three";\nimport { gltsLoader, scene } from "@drawcall/glts";\n\nconst wheel = await gltsLoader.loadAsync(\n new URL("./parts/wheel.glts", import.meta.url),\n);\nwheel.position.set(0.8, 0.4, 1.3);\nscene.add(wheel);\n```\n\nFor a 3D object, create the frame with its complete `index.glts` first. When a referenced `.glts` file does not exist yet, give its URL specifier a rough bounding box in `imports`; Design creates a visible placeholder at that path. Then write each placeholder file one call at a time, the most visible first, and take a screenshot once none remain. A nested file that loads another missing file declares that file\'s box on its own write.\n\nUse relative URLs within a frame. A reusable 3D asset belongs in another frame; load its root by project-absolute URL instead of copying its source:\n\n```ts\nconst chassis = await gltsLoader.loadAsync(\n new URL("/other-frame-id/index.glts", import.meta.url),\n);\nscene.add(chassis);\n```\n\nDo not register `child.dispose()` with `onDispose`; attached GLTS children are owned and disposed recursively. Avoid cyclic loads. Use `loadInstancesAsync(url, count)` for a static mesh hierarchy when repeated copies matter; animated, nested, skinned, or already-instanced content needs native instancing with `instanceCount` and `onMatrixUpdateAt`.\n\n### Resources, updates, and cleanup\n\nFor a non-GLTS file from an image or Market frame, resolve its project filesystem URL through `import.meta.url`:\n\n```ts\nconst modelUrl = new URL("/market-frame-id/models/car.glb", import.meta.url);\n```\n\nPass the contextual `loadingManager` to Three.js loaders during script evaluation so the frame waits for their requests and surfaces failures. Three.js loaders take URL strings; GLTS loader methods accept the `URL` itself. Top-level `await` is supported. Do not start loads from frame, matrix, timer, event, or effect callbacks because the loading scope has closed.\n\n```ts\nimport * as THREE from "three";\nimport { loadingManager, scene } from "@drawcall/glts";\nimport { GLTFLoader } from "three/addons/loaders/GLTFLoader.js";\n\nconst model = await new GLTFLoader(loadingManager).loadAsync(\n new URL("./car.glb", import.meta.url).href,\n);\nscene.add(model.scene);\n```\n\nRelease only resources the script creates. GLTS recursively disposes managed child scenes but does not infer geometry, material, texture, or listener ownership. Close disposal callbacks over the owned values rather than traversing the imported `scene`, whose live binding follows the new revision during reload.\n\nUse `onFrame((delta) => ...)` for animation. Design advances the loaded root every frame, including managed descendants. A failed reload leaves the previous scene mounted.\n\n### Root presentation\n\nNative scene properties such as `scene.background`, `scene.environment`, `scene.fog`, and `scene.overrideMaterial` describe the asset when it is the render root. Assign `scene.defaultCamera` to recommend an authored view; a saved Design frame camera still overrides it. Design autofits the scene when neither exists.\n\nUse `isPreview` for staging that belongs only in the standalone Design frame, such as a floor, light rig, background, fog, or presentation effects. Design loads each displayed root in preview mode; nested GLTS scenes always receive `isPreview === false`, so their presentation does not leak into composition. Keep intrinsic content and each mesh\'s `castShadow` setting outside this block.\n\n```ts\nimport * as THREE from "three";\nimport { isPreview, onDispose, scene } from "@drawcall/glts";\nimport { UnrealBloomPass } from "three/addons/postprocessing/UnrealBloomPass.js";\n\nscene.defaultCamera = new THREE.PerspectiveCamera(35, 1, 0.1, 100);\nscene.defaultCamera.position.set(4, 3, 6);\nscene.defaultCamera.lookAt(0, 1, 0);\n\nif (isPreview) {\n const floor = new THREE.Mesh(\n new THREE.CircleGeometry(20),\n new THREE.MeshStandardMaterial({ color: "#333333" }),\n );\n floor.rotation.x = -Math.PI / 2;\n floor.receiveShadow = true;\n const light = new THREE.DirectionalLight("white", 3);\n light.position.set(4, 6, 3);\n light.castShadow = true;\n\n scene.background = new THREE.Color("#171b2b");\n scene.add(light, light.target, floor);\n scene.rendering.shadows = true;\n scene.rendering.toneMapping = THREE.ACESFilmicToneMapping;\n scene.rendering.toneMappingExposure = 1.1;\n scene.rendering.effects.push(\n ({ height, width }) =>\n new UnrealBloomPass(new THREE.Vector2(width, height), 0.3, 0.4, 0.85),\n );\n\n onDispose(() => {\n light.dispose();\n floor.geometry.dispose();\n floor.material.dispose();\n });\n}\n```\n\n`scene.rendering` supports shadows, clipping planes, tone mapping, exposure, and post-processing effect factories. A factory returns a fresh Three.js `Pass`; do not add `RenderPass` or `OutputPass`, load resources there, or dispose the returned pass yourself. The host renderer owns those passes. Visible shadows require renderer shadows plus a shadow-casting light, casting meshes, and receiving surfaces.\n\nPresentation belongs only to the root. A nested scene\'s background, environment, fog, default camera, and rendering profile do not override its parent.\n\n### Verification\n\nTreat authoritative source or structured state as sufficient when it directly and completely determines the requested property. Do not take a screenshot merely to reconfirm that evidence. Take one only when the result depends on rendering or visual relationships the source cannot establish, such as layout, overlap, clipping, camera framing, lighting, or runtime-generated appearance, or when the user explicitly asks. Then inspect it against the request and iterate until the evidence supports completion.\n';
3
+ export const cliDesignSkill = '---\nname: drawcall-design\ndescription: Create, modify, inspect, compose, and reuse GLTS scenes, Markdown documents, and image or Market references in Drawcall Design. Use whenever the user names Drawcall Design or one of its projects, canvases, frames, filesystems, GLTS assets, or Markdown frames. Do not use for full games, applications, or unrelated image generation.\n---\n\n# Drawcall Design\n\n## CLI transport\n\nThe commands below are the Drawcall transport in this environment. For Design operations, use only this documented command interface. A failed command does not make the transport unavailable.\n\nImage frame creation and image-generation references accept public HTTP(S) URLs or local PNG, JPEG, and WebP files.\n\nSelect the project with `-p <project-id>`. File commands take project-absolute paths that include the frame ID. Repeat `--reference` to preserve image-generation reference order.\n\n```sh\nnpx drawcall design project list\nnpx drawcall design -p r6z2n9k4x8m1qc frame list\nnpx drawcall design -p r6z2n9k4x8m1qc frame create Racecar --type glts --size 1280x800 --import ./parts/wheel.glts=-0.5,0,-0.5:0.5,1,0.5 --text - <<\'GLTS\'\nimport { gltsLoader, scene } from "@drawcall/glts";\n\nconst wheel = await gltsLoader.loadAsync(\n new URL("./parts/wheel.glts", import.meta.url),\n);\nscene.add(wheel);\nGLTS\nnpx drawcall design -p r6z2n9k4x8m1qc write /a4z8m2q7v9kcde/parts/wheel.glts - <<\'GLTS\'\nimport * as THREE from "three";\nimport { onDispose, scene } from "@drawcall/glts";\n\nconst geometry = new THREE.TorusGeometry(0.4, 0.12, 16, 48);\nconst material = new THREE.MeshStandardMaterial({ color: 0x222222 });\nscene.add(new THREE.Mesh(geometry, material));\n\nonDispose(() => {\n geometry.dispose();\n material.dispose();\n});\nGLTS\nnpx drawcall design -p r6z2n9k4x8m1qc frame preview a4z8m2q7v9kcde\nnpx drawcall design -p r6z2n9k4x8m1qc frame screenshot a4z8m2q7v9kcde\nnpx drawcall design -p r6z2n9k4x8m1qc ls\nnpx drawcall design -p r6z2n9k4x8m1qc read /a4z8m2q7v9kcde/index.glts\nnpx drawcall design -p r6z2n9k4x8m1qc edit /a4z8m2q7v9kcde/index.glts \'color: 0xffffff\' \'color: 0x000000\'\nnpx drawcall design -p r6z2n9k4x8m1qc comment list a4z8m2q7v9kcde\nnpx drawcall design -p r6z2n9k4x8m1qc comment show c4z8m2q7v9kcdf\nnpx drawcall design -p r6z2n9k4x8m1qc comment create a4z8m2q7v9kcde \'The bevel catches the key light here.\' --position-3d 0.2,1.1,-0.4\nnpx drawcall design -p r6z2n9k4x8m1qc comment reply c4z8m2q7v9kcdf \'Adjusted the material roughness.\'\nnpx drawcall design -p r6z2n9k4x8m1qc comment resolve c4z8m2q7v9kcdf\nnpx drawcall design -p r6z2n9k4x8m1qc comment delete c4z8m2q7v9kcdf --yes\nnpx drawcall design -p r6z2n9k4x8m1qc frame generate-image \'Product photograph\' --prompt \'A product photograph of this object\' --reference https://r6z2n9k4x8m1qc.design.drawcallcontent.com/a4z8m2q7v9kcde.webp\nnpx drawcall design -p r6z2n9k4x8m1qc frame edit-image b4z8m2q7v9kcdf --prompt \'Use warmer light\' --name \'Warm product photograph\' --reference ./lighting.webp\n```\n\n`frame create --text`, `write`, comment create, and reply text accept `-` to read the text from stdin; a quoted heredoc keeps multi-line source intact. `--import <specifier>=<min>:<max>` declares the bounding box of a contextually loaded `.glts` file that does not exist yet, as `x,y,z:x,y,z`, and may repeat. Run one file write per command invocation, never several in one shell command. Use `--position-2d x,y` only for normalized image coordinates and `--position-3d x,y,z` only for authoritative GLTS world coordinates.\n\nDesign is a remote, current-state canvas. Inspect the project and its frames before changing them. Use immutable IDs for every project and frame target; names are mutable labels. In user-facing replies, refer to projects, frames, and other named resources by their current names. Do not expose their IDs unless the user explicitly asks for them; IDs may remain embedded in URLs that link to those resources.\n\n## Project filesystem\n\nA project is a hosted filesystem at `https://<project-id>.design.drawcallcontent.com/`. Each frame owns one top-level directory, `/<frame-id>`. Files use project-absolute paths that include that directory, for example `/a4z8m2q7v9kcde/index.glts`.\n\nCreate frames with an explicit type. Choose the type from the requested artifact, not from the word "frame": use GLTS for a 3D object or scene, Markdown for a formatted text document, image for an existing 2D image, and Market only for an exact public asset reference, `name@version`. GLTS and Markdown frames require a viewport size; image and Market frames derive their canvas size. A GLTS or Markdown frame accepts its root file at creation.\n\nRead a file before editing it. Use a narrow edit for one known change and write a complete file when replacing it. GLTS and Markdown frame files may be created or deleted. Image and Market frame files are read-only.\n\n## Frame previews\n\nEvery frame has a canonical public WebP preview in `previewUrl` at `https://<project-id>.design.drawcallcontent.com/<frame-id>.webp`, whether its type is GLTS, Markdown, image, or Market. `frame preview <frame-id>` prints that URL. Use `frame screenshot` only when a fresh PNG render is required. Pass a preview URL with `--reference` when one frame\'s appearance should inform another image. A reference may instead be a local PNG, JPEG, or WebP file.\n\n## Markdown documents\n\nA Markdown frame contains one optional source file at `/<frame-id>/index.md`; without it the frame renders as an empty document. Raw HTML is not rendered. Use ordinary Markdown image syntax with a frame\'s canonical WebP path to embed its current rendering:\n\n```md\n![Descriptive alternative text](/other-frame-id.webp)\n```\n\nAn absolute canonical WebP URL from the same project is equivalent. A Markdown document may embed up to 32 existing GLTS, image, or Market frames. It may not embed itself or another Markdown frame. Use the canonical syntax instead of copying a screenshot URL or source asset so the document follows later frame changes.\n\nPrefer focused Markdown frames. A document that covers separable topics is usually clearer as multiple frames connected with canonical links, `[Related details](/<frame-id>/)`, because readers can navigate directly to the part they need. An embedded frame is useful when its current rendering adds visual context; a link is better when the reader only needs to navigate.\n\n## Comments and annotations\n\nUse comments for review conversations and persistent annotations, including explanations of objects or regions inside 2D and 3D frames. Inspect the current comments before replying, resolving, reopening, or deleting so the action targets the current thread.\n\nA comment without a position applies to its frame. A 2D position is normalized image space and applies only to an image frame. A 3D position is GLTS world space and applies only to a GLTS frame. Add a position only when its coordinates are authoritative; never infer 3D depth from a screenshot. Prefer a frame-level comment when the precise position is unknown.\n\nPositioned comments retain the frame version on which they were placed. If the frame later changes, treat the position as potentially stale and re-inspect the frame before relying on it. Replies belong to the root comment\'s thread. Resolved threads do not accept replies, so reopen one before continuing it. Resolve a thread when its concern has been addressed. Delete a comment or reply only when explicitly requested because deletion is permanent; deleting a root also deletes its replies. Comment authors come from the authenticated Drawcall account—never invent an author identity.\n\n## Failures\n\nAn error means the requested operation did not happen. Follow its next action without switching transport. Correct invalid arguments from the documented shape. Refresh projects, frames, or files after a not-found or conflict error, then reuse the exact returned IDs and paths. Retry an upstream or internal failure once; if it repeats, report the failed operation and error. Never repeat an unchanged failed operation.\n\n## GLTS assets\n\n### Market check\n\nBefore hand-authoring a substantial model, texture, or environment, first read `npx drawcall market skill`, search Market once, and preview the best close match. Do not skip this check to save time; skip it only for simple or inherently procedural elements. Use the asset only if it beats hand-authoring on quality relative to latency; otherwise name the rejected asset and why.\n\nA GLTS frame contains only `.glts` files. `index.glts` is its optional root asset; without it the frame renders empty. Every `.glts` file is a trusted, exportless TypeScript ESM script that builds a native `THREE.Scene` through contextual values from `@drawcall/glts`:\n\n```ts\nimport * as THREE from "three";\nimport { onDispose, scene } from "@drawcall/glts";\n\nconst geometry = new THREE.BoxGeometry();\nconst material = new THREE.MeshStandardMaterial({ color: "orange" });\nscene.add(new THREE.Mesh(geometry, material));\n\nonDispose(() => {\n geometry.dispose();\n material.dispose();\n});\n```\n\nUse named contextual imports: `gltsLoader`, `instanceCount`, `isPreview`, `loadingManager`, `onDispose`, `onFrame`, `onMatrixUpdateAt`, and `scene`. Do not export anything or import `GLTSLoader` or `GLTSRenderer`; the host owns loading and rendering. The script may import `three`, Three addons, and browser-compatible npm packages, but not static `.glts` imports, dynamic imports, import attributes, or sibling `.ts` helpers.\n\nThe host owns the root `scene` transform. Put authored placement and animation under child objects instead of changing the root scene\'s transform.\n\n### Composition and placeholders\n\nCompose another `.glts` file with the contextual loader and an explicit URL. Every loaded child must be added beneath `scene` before the script finishes:\n\n```ts\nimport * as THREE from "three";\nimport { gltsLoader, scene } from "@drawcall/glts";\n\nconst wheel = await gltsLoader.loadAsync(\n new URL("./parts/wheel.glts", import.meta.url),\n);\nwheel.position.set(0.8, 0.4, 1.3);\nscene.add(wheel);\n```\n\nFor a 3D object, create the frame with its complete `index.glts` first. When a referenced `.glts` file does not exist yet, give its URL specifier a rough bounding box in `imports`; Design creates a visible placeholder at that path. Then write each placeholder file one call at a time, the most visible first, and take a screenshot once none remain. A nested file that loads another missing file declares that file\'s box on its own write.\n\nUse relative URLs within a frame. A reusable 3D asset belongs in another frame; load its root by project-absolute URL instead of copying its source:\n\n```ts\nconst chassis = await gltsLoader.loadAsync(\n new URL("/other-frame-id/index.glts", import.meta.url),\n);\nscene.add(chassis);\n```\n\nDo not register `child.dispose()` with `onDispose`; attached GLTS children are owned and disposed recursively. Avoid cyclic loads. Use `loadInstancesAsync(url, count)` for a static mesh hierarchy when repeated copies matter; animated, nested, skinned, or already-instanced content needs native instancing with `instanceCount` and `onMatrixUpdateAt`.\n\n### Resources, updates, and cleanup\n\nFor a non-GLTS file from an image or Market frame, resolve its project filesystem URL through `import.meta.url`:\n\n```ts\nconst modelUrl = new URL("/market-frame-id/models/car.glb", import.meta.url);\n```\n\nPass the contextual `loadingManager` to Three.js loaders during script evaluation so the frame waits for their requests and surfaces failures. Three.js loaders take URL strings; GLTS loader methods accept the `URL` itself. Top-level `await` is supported. Do not start loads from frame, matrix, timer, event, or effect callbacks because the loading scope has closed.\n\n```ts\nimport * as THREE from "three";\nimport { loadingManager, scene } from "@drawcall/glts";\nimport { GLTFLoader } from "three/addons/loaders/GLTFLoader.js";\n\nconst model = await new GLTFLoader(loadingManager).loadAsync(\n new URL("./car.glb", import.meta.url).href,\n);\nscene.add(model.scene);\n```\n\nRelease only resources the script creates. GLTS recursively disposes managed child scenes but does not infer geometry, material, texture, or listener ownership. Close disposal callbacks over the owned values rather than traversing the imported `scene`, whose live binding follows the new revision during reload.\n\nUse `onFrame((delta) => ...)` for animation. Design advances the loaded root every frame, including managed descendants. A failed reload leaves the previous scene mounted.\n\n### Root presentation\n\nNative scene properties such as `scene.background`, `scene.environment`, `scene.fog`, and `scene.overrideMaterial` describe the asset when it is the render root. Assign `scene.defaultCamera` to recommend an authored view; a saved Design frame camera still overrides it. Design autofits the scene when neither exists.\n\nUse `isPreview` for staging that belongs only in the standalone Design frame, such as a floor, light rig, background, fog, or presentation effects. Design loads each displayed root in preview mode; nested GLTS scenes always receive `isPreview === false`, so their presentation does not leak into composition. Keep intrinsic content and each mesh\'s `castShadow` setting outside this block.\n\n```ts\nimport * as THREE from "three";\nimport { isPreview, onDispose, scene } from "@drawcall/glts";\nimport { UnrealBloomPass } from "three/addons/postprocessing/UnrealBloomPass.js";\n\nscene.defaultCamera = new THREE.PerspectiveCamera(35, 1, 0.1, 100);\nscene.defaultCamera.position.set(4, 3, 6);\nscene.defaultCamera.lookAt(0, 1, 0);\n\nif (isPreview) {\n const floor = new THREE.Mesh(\n new THREE.CircleGeometry(20),\n new THREE.MeshStandardMaterial({ color: "#333333" }),\n );\n floor.rotation.x = -Math.PI / 2;\n floor.receiveShadow = true;\n const light = new THREE.DirectionalLight("white", 3);\n light.position.set(4, 6, 3);\n light.castShadow = true;\n\n scene.background = new THREE.Color("#171b2b");\n scene.add(light, light.target, floor);\n scene.rendering.shadows = true;\n scene.rendering.toneMapping = THREE.ACESFilmicToneMapping;\n scene.rendering.toneMappingExposure = 1.1;\n scene.rendering.effects.push(\n ({ height, width }) =>\n new UnrealBloomPass(new THREE.Vector2(width, height), 0.3, 0.4, 0.85),\n );\n\n onDispose(() => {\n light.dispose();\n floor.geometry.dispose();\n floor.material.dispose();\n });\n}\n```\n\n`scene.rendering` supports shadows, clipping planes, tone mapping, exposure, and post-processing effect factories. A factory returns a fresh Three.js `Pass`; do not add `RenderPass` or `OutputPass`, load resources there, or dispose the returned pass yourself. The host renderer owns those passes. Visible shadows require renderer shadows plus a shadow-casting light, casting meshes, and receiving surfaces.\n\nPresentation belongs only to the root. A nested scene\'s background, environment, fog, default camera, and rendering profile do not override its parent.\n\n### Verification\n\nTreat authoritative source or structured state as sufficient when it directly and completely determines the requested property. Do not take a screenshot merely to reconfirm that evidence. Take one only when the result depends on rendering or visual relationships the source cannot establish, such as layout, overlap, clipping, camera framing, lighting, or runtime-generated appearance, or when the user explicitly asks. Then inspect it against the request and iterate until the evidence supports completion.\n';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@drawcall/design",
3
- "version": "0.13.1",
3
+ "version": "0.13.3",
4
4
  "description": "Typed API and remote CLI for Drawcall Design",
5
5
  "repository": {
6
6
  "type": "git",
@@ -94,7 +94,9 @@ An error means the requested operation did not happen. Follow its next action wi
94
94
 
95
95
  ## GLTS assets
96
96
 
97
- Market assets can be faster and higher quality than recreating them in GLTS. Consider this separately for each substantial model, texture, and environment before hand-authoring it; if a quick search is likely to improve quality relative to latency, first read `npx drawcall market skill`.
97
+ ### Market check
98
+
99
+ Before hand-authoring a substantial model, texture, or environment, first read `npx drawcall market skill`, search Market once, and preview the best close match. Do not skip this check to save time; skip it only for simple or inherently procedural elements. Use the asset only if it beats hand-authoring on quality relative to latency; otherwise name the rejected asset and why.
98
100
 
99
101
  A GLTS frame contains only `.glts` files. `index.glts` is its optional root asset; without it the frame renders empty. Every `.glts` file is a trusted, exportless TypeScript ESM script that builds a native `THREE.Scene` through contextual values from `@drawcall/glts`:
100
102