{"ok":true,"site":{"host":"cnc-utils.web.app","url":"https://cnc-utils.web.app/","type":"live","desc":"Browser-based CAM: design shapes, set up tools and operations, preview toolpaths in 3D and download G-code.","tools":[{"name":"get_project","kind":"answer","impl":"imperative","description":"The CNC project open in the app (CAM for a router: 2D shapes, cutting tools, operations that turn shapes into toolpaths, stock and G-code settings), with an outline of its items (ids, names, what each does). The model has: variables (named values for expressions), shapes (each with a type, its fields and a list of transforms), tools (bits, numbered T1, T2… by `index`), operations (in cutting order; each cuts a shape `shapeId` with a tool `toolId`), stock and gcode settings. Items are referred to by `id`. Long embedded files (SVG, pictures) are shown as placeholders: pass them back unchanged to keep them. Lengths are in mm, angles in degrees. Any number field also takes an expression (a string such as \"width / 2 + 3\", using the project’s variables, functions such as sqrt, sin, min, and units such as \"1cm\" or \"1/4in\"). Use describe_fields for the fields of each item type.","title":"Read the project","annotations":{"readOnlyHint":true},"inputSchema":{"type":"object","properties":{"outline_only":{"type":"boolean","description":"Only the outline, not the whole model."}}},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"describe_fields","kind":"answer","impl":"imperative","description":"The fields of the project’s items, as the editor has them: for a list (variables, shapes, transforms, tools, operations) or settings section (stock, gcode). Without `type`, a typed list gives its item types and the fields all items have; with `type`, that type’s fields too. Fields marked `conditional` only apply in some cases (another field’s value, the tool’s kind, the stock) and are dropped when they don’t. A field missing from an item takes its default. Lengths are in mm, angles in degrees. Any number field also takes an expression (a string such as \"width / 2 + 3\", using the project’s variables, functions such as sqrt, sin, min, and units such as \"1cm\" or \"1/4in\").","title":"Describe item fields","annotations":{"readOnlyHint":true},"inputSchema":{"type":"object","properties":{"list":{"type":"string","enum":["variables","shapes","tools","operations","transforms","stock","gcode"]},"type":{"type":"string","description":"An item type of the list, e.g. \"rectangle\", \"pocket\", \"translate\"."}},"required":["list"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"evaluate_expression","kind":"act","impl":"imperative","description":"What an expression works out to with the project’s variables, e.g. \"width / 2 - 3mm\", or why it can’t be worked out. Also lists the variables’ values.","title":"Work out an expression","annotations":{"readOnlyHint":true},"inputSchema":{"type":"object","properties":{"expression":{"type":"string"}},"required":["expression"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"get_shape_geometry","kind":"answer","impl":"imperative","description":"A shape as made (after its transforms): its bounds in mm, how many outlines it has, and, unless `bounds_only`, the outlines as SVG (mm, Y up as in the design is flipped to SVG’s Y down). Single points (drill points) have no area.","title":"Shape geometry","annotations":{"readOnlyHint":true},"inputSchema":{"type":"object","properties":{"shape_id":{"type":"string"},"bounds_only":{"type":"boolean"}},"required":["shape_id"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"add_items","kind":"act","impl":"imperative","description":"Adds items to a list of the project: variables ({name, value}), shapes, tools, operations — or, with `parent_id`, to an item’s own list: a shape’s `transforms`, a rotary repeat’s `operations`. Give each item its `type` (for typed lists) and the fields to set; the rest take their defaults (see describe_fields). An item may carry its own unique `id` so later items in the same call can refer to it (e.g. an operation’s shapeId); otherwise ids are made. Tools without an `index` get the lowest free one. Returns the new items’ ids. Undo takes it back.","title":"Add items","inputSchema":{"type":"object","properties":{"list":{"type":"string","enum":["variables","shapes","tools","operations"]},"parent_id":{"type":"string","description":"The shape (for transforms) or rotary repeat (for operations) whose list to add to."},"index":{"type":"integer","description":"Where in the list (from 0); the end without."},"items":{"type":"array","items":{"type":"object"}}},"required":["list","items"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"update_item","kind":"act","impl":"imperative","description":"Changes fields of any item by its id (a variable, shape, transform, point, tool, operation…): each key in `changes` is set to its value; null resets it to its default. Lists (a shape’s transforms, a point list) are replaced whole. Lengths are in mm, angles in degrees. Any number field also takes an expression (a string such as \"width / 2 + 3\", using the project’s variables, functions such as sqrt, sin, min, and units such as \"1cm\" or \"1/4in\"). Returns the item as it is afterwards. Undo takes it back.","title":"Change an item","inputSchema":{"type":"object","properties":{"id":{"type":"string"},"changes":{"type":"object"}},"required":["id","changes"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"update_settings","kind":"act","impl":"imperative","description":"Changes the stock settings (`stock`: size, material, where it’s held — on the table or a rotary axis —, where zero is) or the G-code settings (`gcode`: machine, safe height, arcs, comments…): each key set to its value, null resets it. See describe_fields for the fields. To turn the rotary axis to lie along the other direction, use turn_rotary_axis.","title":"Change stock or G-code settings","inputSchema":{"type":"object","properties":{"section":{"type":"string","enum":["stock","gcode"]},"changes":{"type":"object"}},"required":["section","changes"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"remove_items","kind":"act","impl":"imperative","description":"Removes items by id (with whatever they hold: a shape’s transforms…). When other items refer to them (an operation cutting a removed shape, a boolean using it), nothing is removed and those references are listed, unless `force`. Undo takes it back.","title":"Remove items","inputSchema":{"type":"object","properties":{"ids":{"type":"array","items":{"type":"string"}},"force":{"type":"boolean"}},"required":["ids"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"move_item","kind":"act","impl":"imperative","description":"Moves an item within its list: to `index`, or just `before` / `after` another item of the same list. Operations are cut in list order; transforms apply in list order; variables can only use the ones above them.","title":"Reorder an item","inputSchema":{"type":"object","properties":{"id":{"type":"string"},"index":{"type":"integer"},"before":{"type":"string"},"after":{"type":"string"}},"required":["id"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"replace_model","kind":"act","impl":"imperative","description":"Puts a whole model in place of the project’s (as get_project returns it, in format `formatVersion`; an older format is brought up to date when `version` is given). Stays the same project, and undo takes it back. Prefer the item tools for small changes.","title":"Replace the whole model","annotations":{"consequentialHint":true},"inputSchema":{"type":"object","properties":{"model":{"type":"object"},"version":{"type":"integer"}},"required":["model"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"undo","kind":"act","impl":"imperative","description":"Undoes the last change to the project.","title":"Undo","hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"redo","kind":"act","impl":"imperative","description":"Redoes the last change undone.","title":"Redo","hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"fit_stock","kind":"act","impl":"imperative","description":"Turns on the stock size and sizes it round every operation’s cuts (each shape cut, grown by its tool’s diameter).","title":"Fit the stock","hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"turn_rotary_axis","kind":"act","impl":"imperative","description":"With the stock on a rotary axis: makes the axis lie along X or Y. With `turn_project` (the default), the shapes, the stock and every setting with a direction turn a quarter turn with it, so everything stays where it was on the blank.","title":"Turn the rotary axis","inputSchema":{"type":"object","properties":{"along":{"type":"string","enum":["x","y"]},"turn_project":{"type":"boolean"}},"required":["along"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"show_shape","kind":"act","impl":"imperative","description":"Opens a shape in the editor and highlights it in the preview, to show the user; its points can then be dragged there. Without shape_id, closes it.","title":"Show a shape","inputSchema":{"type":"object","properties":{"shape_id":{"type":"string"}}},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"set_simulation","kind":"act","impl":"imperative","description":"Shows (or hides) in the preview the material left once every enabled operation is cut, and sets how finely it’s simulated.","title":"Simulate the material","inputSchema":{"type":"object","properties":{"on":{"type":"boolean"},"quality":{"type":"string","enum":["draft","standard","fine","finest"]}},"required":["on"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"get_job_summary","kind":"answer","impl":"imperative","description":"The job as it stands once the toolpaths are made: the stock and where the G-code’s zero is, the tools in use, the operations with how long each takes, the total time, and the checks to look at before cutting (warnings: likely to spoil the job or the machine; notes: worth a look) — moves into uncut material, cuts deeper than the flutes or into the spoilboard, parts cut free without tabs, toolpaths near clamps…","title":"Job summary","annotations":{"readOnlyHint":true},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"get_gcode","kind":"answer","impl":"imperative","description":"The job’s G-code once the toolpaths are made: one program, or with `per_tool` one file per tool run (for machines without a tool changer). Long output comes in pages: pass `offset` (characters) to read on. Without `include_project`, the embedded project line (to load the file back into the app) is left out.","title":"Read the G-code","annotations":{"readOnlyHint":true},"inputSchema":{"type":"object","properties":{"per_tool":{"type":"boolean"},"include_project":{"type":"boolean"},"offset":{"type":"integer"}}},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"get_cut_list","kind":"answer","impl":"imperative","description":"The parts with their sizes (mm): every nest’s parts with their sheet and place, or, without nests, the parts the outside profiles cut out. With `csv`, as CSV text.","title":"Cut list","annotations":{"readOnlyHint":true},"inputSchema":{"type":"object","properties":{"csv":{"type":"boolean"}}},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"get_setup_sheet","kind":"answer","impl":"imperative","description":"The printable setup sheet: stock, zero, tools in order, operations with their times and the checks — as its text, or with `html` the whole page (large: it has a drawing from above).","title":"Setup sheet","annotations":{"readOnlyHint":true},"inputSchema":{"type":"object","properties":{"html":{"type":"boolean"}}},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"download","kind":"act","impl":"imperative","description":"Saves a file through the browser’s download, for the user: `gcode` (the program, with the project embedded so it can be loaded back), `gcode-per-tool` (a zip with one file per tool run), `cut-list` (CSV), or `shape-svg` (one shape as SVG in mm, with `shape_id`).","title":"Download a file","inputSchema":{"type":"object","properties":{"what":{"type":"string","enum":["gcode","gcode-per-tool","cut-list","shape-svg"]},"shape_id":{"type":"string"}},"required":["what"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"get_share_link","kind":"answer","impl":"imperative","description":"A link that opens a copy of the project in the app: the project is in the link itself (its fragment, never sent to a server). Links of projects with pictures or imported files get long.","title":"Share link","annotations":{"readOnlyHint":true},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"list_templates","kind":"answer","impl":"imperative","description":"The example projects that come with the app, by group, with their descriptions (open one with open_template).","title":"List templates","annotations":{"readOnlyHint":true},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"open_template","kind":"act","impl":"imperative","description":"Replaces the project with an example project (by its `file` from list_templates). When there are unsaved changes, the user is asked first.","title":"Open a template","annotations":{"consequentialHint":true},"inputSchema":{"type":"object","properties":{"file":{"type":"string"}},"required":["file"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"new_project","kind":"act","impl":"imperative","description":"Replaces the project with an empty one. When there are unsaved changes, the user is asked first.","title":"New project","annotations":{"consequentialHint":true},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"list_saved_projects","kind":"answer","impl":"imperative","description":"The projects saved by name in this browser, most recent first, and which one is open.","title":"List saved projects","annotations":{"readOnlyHint":true},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"open_saved_project","kind":"act","impl":"imperative","description":"Replaces the work with a project saved in this browser (by id or name). When there are unsaved changes, the user is asked first.","title":"Open a saved project","annotations":{"consequentialHint":true},"inputSchema":{"type":"object","properties":{"project":{"type":"string","description":"Id or name."}},"required":["project"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"save_project","kind":"act","impl":"imperative","description":"Saves the work in this browser: over the project it belongs to, or with `name` as a project of that name. Saving under the name of another saved project replaces it only with `overwrite`.","title":"Save the project","inputSchema":{"type":"object","properties":{"name":{"type":"string"},"overwrite":{"type":"boolean"}}},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"delete_saved_project","kind":"transact","impl":"imperative","description":"Deletes a project saved in this browser (by id or name), once the user confirms. When it’s the open one, the work stays open as unsaved work.","title":"Delete a saved project","annotations":{"consequentialHint":true},"inputSchema":{"type":"object","properties":{"project":{"type":"string","description":"Id or name."}},"required":["project"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"import_parts","kind":"act","impl":"imperative","description":"Copies shapes from a project saved in this browser into this one, with the shapes they’re made from, and (with `with_operations`) the operations that cut them, their tools (an identical tool here is used instead) and the variables they use. Everything gets new ids and goes at the end of the lists. Read the saved project’s shapes with `list_only` first.","title":"Import parts","inputSchema":{"type":"object","properties":{"project":{"type":"string","description":"Id or name."},"shape_ids":{"type":"array","items":{"type":"string"}},"with_operations":{"type":"boolean"},"list_only":{"type":"boolean","description":"Only list the saved project’s shapes."}},"required":["project"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"load_gcode_project","kind":"act","impl":"imperative","description":"Replaces the work with the project embedded in a .nc file this app wrote (its \"; model=\" line). When there are unsaved changes, the user is asked first.","title":"Load a project from G-code","annotations":{"consequentialHint":true,"untrustedContentHint":true},"inputSchema":{"type":"object","properties":{"gcode":{"type":"string"}},"required":["gcode"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"open_share_link","kind":"act","impl":"imperative","description":"Replaces the work with the project in a share link of this app (…#project=…). When there are unsaved changes, the user is asked first.","title":"Open a share link","annotations":{"consequentialHint":true,"untrustedContentHint":true},"inputSchema":{"type":"object","properties":{"link":{"type":"string"}},"required":["link"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"list_tool_library","kind":"answer","impl":"imperative","description":"The tools kept in this browser’s library for every project (by `key`); add them to the project with add_library_tools.","title":"List the tool library","annotations":{"readOnlyHint":true},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"add_library_tools","kind":"act","impl":"imperative","description":"Adds library tools (by key) to the project. Each keeps its index (T number) unless a tool here has it; then it gets a free one.","title":"Add tools from the library","inputSchema":{"type":"object","properties":{"keys":{"type":"array","items":{"type":"string"}}},"required":["keys"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"save_tool_to_library","kind":"act","impl":"imperative","description":"Keeps one of the project’s tools (by id) in this browser’s library, for every project. A library tool of the same name is replaced.","title":"Keep a tool in the library","inputSchema":{"type":"object","properties":{"tool_id":{"type":"string"}},"required":["tool_id"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"},{"name":"remove_library_tool","kind":"act","impl":"imperative","description":"Removes a tool (by key) from this browser’s library. Projects using it keep their own copy.","title":"Remove a library tool","annotations":{"consequentialHint":true},"inputSchema":{"type":"object","properties":{"key":{"type":"string"}},"required":["key"]},"hasHandler":true,"hasExecute":true,"__source":"spec","executable":true,"handlerField":"execute"}],"category":"Developer Tools","favicon":"/favicons/cnc-utils.web.app.ico","apiSurface":"spec","toolCount":36}}