Compare commits

...

7 Commits

Author SHA1 Message Date
3e4505e2e3 [refactor] remove 6 floating-promise ignores (#5985)
* Remove trivial floating promise in authMachine

* Add catch statement so LSP promise is considered non-floating

* Remove trivial float in AllSettingsFields

* Add error reporting for ensureWasmInit

* Remove pointless floating promise in Modeling

* Add comment and reportRejection to floating promise in "set selection"

* Read comment, put back await that should be there

* Fix dumb imports rebase botch

* Missed an import

---------

Co-authored-by: Jess Frazelle <jessfraz@users.noreply.github.com>
2025-04-03 02:53:10 +00:00
1fe1cfb397 Syntax sugar booleans (+ and -) which is intuitive for MEs (#6124)
* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* docs

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* docs

Signed-off-by: Jess Frazelle <github@jessfraz.com>

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
2025-04-03 02:13:03 +00:00
2f721c84ed Bump vite from 5.4.12 to 5.4.16 in the security group (#6118)
Bumps the security group with 1 update: [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite).


Updates `vite` from 5.4.12 to 5.4.16
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/v5.4.16/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v5.4.16/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-type: direct:development
  dependency-group: security
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-02 22:46:30 +00:00
9112ff8c0a Bump vite from 5.4.14 to 5.4.16 in /packages/codemirror-lang-kcl in the security group (#6117)
Bump vite in /packages/codemirror-lang-kcl in the security group

Bumps the security group in /packages/codemirror-lang-kcl with 1 update: [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite).


Updates `vite` from 5.4.14 to 5.4.16
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/v5.4.16/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v5.4.16/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-type: indirect
  dependency-group: security
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-02 22:22:17 +00:00
96e12b5aba update transform samples with mesh moving (#6080)
* update transform samples with mesh moving

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* chjanges

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* updates

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* update docs

Signed-off-by: Jess Frazelle <github@jessfraz.com>

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
2025-04-02 15:11:06 -07:00
bec3ba71cd More circular deps fixed (#6121)
* 23

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* 22

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* 21

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* fix known

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* fixes

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* cleanup

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* cleanup

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* 20

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* 11

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* 11

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* fixes

Signed-off-by: Jess Frazelle <github@jessfraz.com>

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
2025-04-02 15:10:57 -07:00
c6766d2a73 bump kcl and friends (#6122)
Signed-off-by: Jess Frazelle <github@jessfraz.com>
2025-04-02 14:28:32 -07:00
63 changed files with 650 additions and 328 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -111905,7 +111905,8 @@
"unpublished": false,
"deprecated": true,
"examples": [
"fn cube(center) {\n return startSketchOn(XY)\n |> startProfileAt([center[0] - 10, center[1] - 10], %)\n |> line(endAbsolute = [center[0] + 10, center[1] - 10])\n |> line(endAbsolute = [center[0] + 10, center[1] + 10])\n |> line(endAbsolute = [center[0] - 10, center[1] + 10])\n |> close()\n |> extrude(length = 10)\n}\n\npart001 = cube([0, 0])\npart002 = cube([8, 8])\n\nintersectedPart = intersect([part001, part002])"
"// Intersect two cubes using the stdlib functions.\n\n\nfn cube(center) {\n return startSketchOn(XY)\n |> startProfileAt([center[0] - 10, center[1] - 10], %)\n |> line(endAbsolute = [center[0] + 10, center[1] - 10])\n |> line(endAbsolute = [center[0] + 10, center[1] + 10])\n |> line(endAbsolute = [center[0] - 10, center[1] + 10])\n |> close()\n |> extrude(length = 10)\n}\n\npart001 = cube([0, 0])\npart002 = cube([8, 8])\n\nintersectedPart = intersect([part001, part002])",
"// Intersect two cubes using operators.\n// NOTE: This will not work when using codemods through the UI.\n// Codemods will generate the stdlib function call instead.\n\n\nfn cube(center) {\n return startSketchOn(XY)\n |> startProfileAt([center[0] - 10, center[1] - 10], %)\n |> line(endAbsolute = [center[0] + 10, center[1] - 10])\n |> line(endAbsolute = [center[0] + 10, center[1] + 10])\n |> line(endAbsolute = [center[0] - 10, center[1] + 10])\n |> close()\n |> extrude(length = 10)\n}\n\npart001 = cube([0, 0])\npart002 = cube([8, 8])\n\n// This is the equivalent of: intersect([part001, part002])\nintersectedPart = part001 & part002"
]
},
{
@ -266059,7 +266060,7 @@
"// Rotate a pipe with roll, pitch, and yaw.\n\n// Create a path for the sweep.\nsweepPath = startSketchOn(XZ)\n |> startProfileAt([0.05, 0.05], %)\n |> line(end = [0, 7])\n |> tangentialArc({ offset = 90, radius = 5 }, %)\n |> line(end = [-3, 0])\n |> tangentialArc({ offset = -90, radius = 5 }, %)\n |> line(end = [0, 7])\n\n// Create a hole for the pipe.\npipeHole = startSketchOn(XY)\n |> circle(center = [0, 0], radius = 1.5)\n\nsweepSketch = startSketchOn(XY)\n |> circle(center = [0, 0], radius = 2)\n |> hole(pipeHole, %)\n |> sweep(path = sweepPath)\n |> rotate(roll = 10, pitch = 10, yaw = 90)",
"// Rotate a pipe with just roll.\n\n// Create a path for the sweep.\nsweepPath = startSketchOn(XZ)\n |> startProfileAt([0.05, 0.05], %)\n |> line(end = [0, 7])\n |> tangentialArc({ offset = 90, radius = 5 }, %)\n |> line(end = [-3, 0])\n |> tangentialArc({ offset = -90, radius = 5 }, %)\n |> line(end = [0, 7])\n\n// Create a hole for the pipe.\npipeHole = startSketchOn(XY)\n |> circle(center = [0, 0], radius = 1.5)\n\nsweepSketch = startSketchOn(XY)\n |> circle(center = [0, 0], radius = 2)\n |> hole(pipeHole, %)\n |> sweep(path = sweepPath)\n |> rotate(roll = 10)",
"// Rotate a pipe about an axis with an angle.\n\n// Create a path for the sweep.\nsweepPath = startSketchOn(XZ)\n |> startProfileAt([0.05, 0.05], %)\n |> line(end = [0, 7])\n |> tangentialArc({ offset = 90, radius = 5 }, %)\n |> line(end = [-3, 0])\n |> tangentialArc({ offset = -90, radius = 5 }, %)\n |> line(end = [0, 7])\n\n// Create a hole for the pipe.\npipeHole = startSketchOn(XY)\n |> circle(center = [0, 0], radius = 1.5)\n\nsweepSketch = startSketchOn(XY)\n |> circle(center = [0, 0], radius = 2)\n |> hole(pipeHole, %)\n |> sweep(path = sweepPath)\n |> rotate(axis = [0, 0, 1.0], angle = 90)",
"// Rotate an imported model.\n\n\nimport \"tests/inputs/cube.sldprt\" as cube\n\ncube\n |> rotate(axis = [0, 0, 1.0], angle = 90)",
"// Rotate an imported model.\n\n\nimport \"tests/inputs/cube.sldprt\" as cube\n\ncube\n |> rotate(axis = [0, 0, 1.0], angle = 9)",
"// Sweep two sketches along the same path.\n\n\nsketch001 = startSketchOn(XY)\nrectangleSketch = startProfileAt([-200, 23.86], sketch001)\n |> angledLine([0, 73.47], %, $rectangleSegmentA001)\n |> angledLine([\n segAng(rectangleSegmentA001) - 90,\n 50.61\n ], %)\n |> angledLine([\n segAng(rectangleSegmentA001),\n -segLen(rectangleSegmentA001)\n ], %)\n |> line(endAbsolute = [profileStartX(%), profileStartY(%)])\n |> close()\n\ncircleSketch = circle(sketch001, center = [200, -30.29], radius = 32.63)\n\nsketch002 = startSketchOn(YZ)\nsweepPath = startProfileAt([0, 0], sketch002)\n |> yLine(length = 231.81)\n |> tangentialArc({ radius = 80, offset = -90 }, %)\n |> xLine(length = 384.93)\n\nparts = sweep([rectangleSketch, circleSketch], path = sweepPath)\n\n// Rotate the sweeps.\nrotate(parts, axis = [0, 0, 1.0], angle = 90)",
"// Translate and rotate a sketch to create a loft.\nsketch001 = startSketchOn(XY)\n\nfn square() {\n return startProfileAt([-10, 10], sketch001)\n |> xLine(length = 20)\n |> yLine(length = -20)\n |> xLine(length = -20)\n |> line(endAbsolute = [profileStartX(%), profileStartY(%)])\n |> close()\n}\n\nprofile001 = square()\n\nprofile002 = square()\n |> translate(x = 0, y = 0, z = 20)\n |> rotate(axis = [0, 0, 1.0], angle = 45)\n\nloft([profile001, profile002])"
]
@ -275841,7 +275842,7 @@
"deprecated": false,
"examples": [
"// Scale a pipe.\n\n// Create a path for the sweep.\nsweepPath = startSketchOn(XZ)\n |> startProfileAt([0.05, 0.05], %)\n |> line(end = [0, 7])\n |> tangentialArc({ offset = 90, radius = 5 }, %)\n |> line(end = [-3, 0])\n |> tangentialArc({ offset = -90, radius = 5 }, %)\n |> line(end = [0, 7])\n\n// Create a hole for the pipe.\npipeHole = startSketchOn(XY)\n |> circle(center = [0, 0], radius = 1.5)\n\nsweepSketch = startSketchOn(XY)\n |> circle(center = [0, 0], radius = 2)\n |> hole(pipeHole, %)\n |> sweep(path = sweepPath)\n |> scale(z = 2.5)",
"// Scale an imported model.\n\n\nimport \"tests/inputs/cube.sldprt\" as cube\n\ncube\n |> scale(z = 2.5)",
"// Scale an imported model.\n\n\nimport \"tests/inputs/cube.sldprt\" as cube\n\ncube\n |> scale(y = 2.5)",
"// Sweep two sketches along the same path.\n\n\nsketch001 = startSketchOn(XY)\nrectangleSketch = startProfileAt([-200, 23.86], sketch001)\n |> angledLine([0, 73.47], %, $rectangleSegmentA001)\n |> angledLine([\n segAng(rectangleSegmentA001) - 90,\n 50.61\n ], %)\n |> angledLine([\n segAng(rectangleSegmentA001),\n -segLen(rectangleSegmentA001)\n ], %)\n |> line(endAbsolute = [profileStartX(%), profileStartY(%)])\n |> close()\n\ncircleSketch = circle(sketch001, center = [200, -30.29], radius = 32.63)\n\nsketch002 = startSketchOn(YZ)\nsweepPath = startProfileAt([0, 0], sketch002)\n |> yLine(length = 231.81)\n |> tangentialArc({ radius = 80, offset = -90 }, %)\n |> xLine(length = 384.93)\n\nparts = sweep([rectangleSketch, circleSketch], path = sweepPath)\n\n// Scale the sweep.\nscale(parts, z = 0.5)"
]
},
@ -294700,7 +294701,7 @@
},
"required": true,
"includeInSnippet": true,
"description": "The solids to intersect.",
"description": "The solids to use as the base to subtract from.",
"labelRequired": false
},
{
@ -297904,7 +297905,8 @@
"unpublished": false,
"deprecated": true,
"examples": [
"fn cube(center) {\n return startSketchOn(XY)\n |> startProfileAt([center[0] - 10, center[1] - 10], %)\n |> line(endAbsolute = [center[0] + 10, center[1] - 10])\n |> line(endAbsolute = [center[0] + 10, center[1] + 10])\n |> line(endAbsolute = [center[0] - 10, center[1] + 10])\n |> close()\n |> extrude(length = 10)\n}\n\npart001 = cube([0, 0])\npart002 = startSketchOn(XY)\n |> circle(center = [0, 0], radius = 2)\n |> extrude(length = 10)\n\nsubtractedPart = subtract([part001], tools = [part002])"
"// Subtract a cylinder from a cube using the stdlib functions.\n\n\nfn cube(center) {\n return startSketchOn(XY)\n |> startProfileAt([center[0] - 10, center[1] - 10], %)\n |> line(endAbsolute = [center[0] + 10, center[1] - 10])\n |> line(endAbsolute = [center[0] + 10, center[1] + 10])\n |> line(endAbsolute = [center[0] - 10, center[1] + 10])\n |> close()\n |> extrude(length = 10)\n}\n\npart001 = cube([0, 0])\npart002 = startSketchOn(XY)\n |> circle(center = [0, 0], radius = 2)\n |> extrude(length = 10)\n\nsubtractedPart = subtract([part001], tools = [part002])",
"// Subtract a cylinder from a cube using operators.\n// NOTE: This will not work when using codemods through the UI.\n// Codemods will generate the stdlib function call instead.\n\n\nfn cube(center) {\n return startSketchOn(XY)\n |> startProfileAt([center[0] - 10, center[1] - 10], %)\n |> line(endAbsolute = [center[0] + 10, center[1] - 10])\n |> line(endAbsolute = [center[0] + 10, center[1] + 10])\n |> line(endAbsolute = [center[0] - 10, center[1] + 10])\n |> close()\n |> extrude(length = 10)\n}\n\npart001 = cube([0, 0])\npart002 = startSketchOn(XY)\n |> circle(center = [0, 0], radius = 2)\n |> extrude(length = 10)\n\n// This is the equivalent of: subtract([part001], tools=[part002])\nsubtractedPart = part001 - part002"
]
},
{
@ -334111,7 +334113,7 @@
"deprecated": false,
"examples": [
"// Move a pipe.\n\n// Create a path for the sweep.\nsweepPath = startSketchOn(XZ)\n |> startProfileAt([0.05, 0.05], %)\n |> line(end = [0, 7])\n |> tangentialArc({ offset = 90, radius = 5 }, %)\n |> line(end = [-3, 0])\n |> tangentialArc({ offset = -90, radius = 5 }, %)\n |> line(end = [0, 7])\n\n// Create a hole for the pipe.\npipeHole = startSketchOn(XY)\n |> circle(center = [0, 0], radius = 1.5)\n\nsweepSketch = startSketchOn(XY)\n |> circle(center = [0, 0], radius = 2)\n |> hole(pipeHole, %)\n |> sweep(path = sweepPath)\n |> translate(x = 1.0, y = 1.0, z = 2.5)",
"// Move an imported model.\n\n\nimport \"tests/inputs/cube.sldprt\" as cube\n\ncube\n |> translate(x = 1.0, y = 1.0, z = 2.5)",
"// Move an imported model.\n\n\nimport \"tests/inputs/cube.sldprt\" as cube\n\n// Circle so you actually see the move.\nstartSketchOn(XY)\n |> circle(center = [-10, -10], radius = 10)\n |> extrude(length = 10)\n\ncube\n |> translate(x = 10.0, y = 10.0, z = 2.5)",
"// Sweep two sketches along the same path.\n\n\nsketch001 = startSketchOn(XY)\nrectangleSketch = startProfileAt([-200, 23.86], sketch001)\n |> angledLine([0, 73.47], %, $rectangleSegmentA001)\n |> angledLine([\n segAng(rectangleSegmentA001) - 90,\n 50.61\n ], %)\n |> angledLine([\n segAng(rectangleSegmentA001),\n -segLen(rectangleSegmentA001)\n ], %)\n |> line(endAbsolute = [profileStartX(%), profileStartY(%)])\n |> close()\n\ncircleSketch = circle(sketch001, center = [200, -30.29], radius = 32.63)\n\nsketch002 = startSketchOn(YZ)\nsweepPath = startProfileAt([0, 0], sketch002)\n |> yLine(length = 231.81)\n |> tangentialArc({ radius = 80, offset = -90 }, %)\n |> xLine(length = 384.93)\n\nparts = sweep([rectangleSketch, circleSketch], path = sweepPath)\n\n// Move the sweeps.\ntranslate(\n parts,\n x = 1.0,\n y = 1.0,\n z = 2.5,\n)",
"// Move a sketch.\n\n\nfn square(length) {\n l = length / 2\n p0 = [-l, -l]\n p1 = [-l, l]\n p2 = [l, l]\n p3 = [l, -l]\n\n return startSketchOn(XY)\n |> startProfileAt(p0, %)\n |> line(endAbsolute = p1)\n |> line(endAbsolute = p2)\n |> line(endAbsolute = p3)\n |> close()\n}\n\nsquare(10)\n |> translate(x = 5, y = 5)\n |> extrude(length = 10)",
"// Translate and rotate a sketch to create a loft.\nsketch001 = startSketchOn(XY)\n\nfn square() {\n return startProfileAt([-10, 10], sketch001)\n |> xLine(length = 20)\n |> yLine(length = -20)\n |> xLine(length = -20)\n |> line(endAbsolute = [profileStartX(%), profileStartY(%)])\n |> close()\n}\n\nprofile001 = square()\n\nprofile002 = square()\n |> translate(z = 20)\n |> rotate(axis = [0, 0, 1.0], angle = 45)\n\nloft([profile001, profile002])"
@ -337325,7 +337327,9 @@
"unpublished": false,
"deprecated": true,
"examples": [
"fn cube(center) {\n return startSketchOn(XY)\n |> startProfileAt([center[0] - 10, center[1] - 10], %)\n |> line(endAbsolute = [center[0] + 10, center[1] - 10])\n |> line(endAbsolute = [center[0] + 10, center[1] + 10])\n |> line(endAbsolute = [center[0] - 10, center[1] + 10])\n |> close()\n |> extrude(length = 10)\n}\n\npart001 = cube([0, 0])\npart002 = cube([20, 10])\n\nunionedPart = union([part001, part002])"
"// Union two cubes using the stdlib functions.\n\n\nfn cube(center) {\n return startSketchOn(XY)\n |> startProfileAt([center[0] - 10, center[1] - 10], %)\n |> line(endAbsolute = [center[0] + 10, center[1] - 10])\n |> line(endAbsolute = [center[0] + 10, center[1] + 10])\n |> line(endAbsolute = [center[0] - 10, center[1] + 10])\n |> close()\n |> extrude(length = 10)\n}\n\npart001 = cube([0, 0])\npart002 = cube([20, 10])\n\nunionedPart = union([part001, part002])",
"// Union two cubes using operators.\n// NOTE: This will not work when using codemods through the UI.\n// Codemods will generate the stdlib function call instead.\n\n\nfn cube(center) {\n return startSketchOn(XY)\n |> startProfileAt([center[0] - 10, center[1] - 10], %)\n |> line(endAbsolute = [center[0] + 10, center[1] - 10])\n |> line(endAbsolute = [center[0] + 10, center[1] + 10])\n |> line(endAbsolute = [center[0] - 10, center[1] + 10])\n |> close()\n |> extrude(length = 10)\n}\n\npart001 = cube([0, 0])\npart002 = cube([20, 10])\n\n// This is the equivalent of: union([part001, part002])\nunionedPart = part001 + part002",
"// Union two cubes using the more programmer-friendly operator.\n// NOTE: This will not work when using codemods through the UI.\n// Codemods will generate the stdlib function call instead.\n\n\nfn cube(center) {\n return startSketchOn(XY)\n |> startProfileAt([center[0] - 10, center[1] - 10], %)\n |> line(endAbsolute = [center[0] + 10, center[1] - 10])\n |> line(endAbsolute = [center[0] + 10, center[1] + 10])\n |> line(endAbsolute = [center[0] - 10, center[1] + 10])\n |> close()\n |> extrude(length = 10)\n}\n\npart001 = cube([0, 0])\npart002 = cube([20, 10])\n\n// This is the equivalent of: union([part001, part002])\n// Programmers will understand `|` as a union operation, but mechanical engineers\n// will understand `+`, we made both work.\nunionedPart = part001 | part002"
]
},
{

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1 +1,13 @@
$ dpdm --no-warning --no-tree -T --skip-dynamic-imports=circular src/index.tsx• Circular Dependencies 01) src/lang/std/sketch.ts -> src/lang/modifyAst.ts -> src/lang/modifyAst/addEdgeTreatment.ts 02) src/lang/std/sketch.ts -> src/lang/modifyAst.ts 03) src/lang/std/sketch.ts -> src/lang/modifyAst.ts -> src/lang/std/sketchcombos.ts 04) src/clientSideScene/CameraControls.ts -> src/clientSideScene/sceneInfra.ts 05) src/lib/singletons.ts -> src/editor/manager.ts -> src/lib/selections.ts 06) src/lib/singletons.ts -> src/editor/manager.ts 07) src/lib/singletons.ts -> src/lang/KclSingleton.ts 08) src/lib/singletons.ts -> src/lang/codeManager.ts 09) src/lib/singletons.ts -> src/clientSideScene/sceneEntities.ts -> src/clientSideScene/segments.ts -> src/components/Toolbar/angleLengthInfo.ts 10) src/lib/singletons.ts -> src/clientSideScene/sceneEntities.ts -> src/clientSideScene/segments.ts -> src/machines/commandBarMachine.ts -> src/lib/commandBarConfigs/authCommandConfig.ts -> src/machines/appMachine.ts -> src/machines/settingsMachine.ts -> src/lib/commandBarConfigs/settingsCommandConfig.ts -> src/lib/createMachineCommand.ts -> src/routes/Settings.tsx -> src/components/Settings/AllSettingsFields.tsx -> src/components/LspProvider.tsx -> src/editor/plugins/lsp/copilot/index.ts 11) src/lib/singletons.ts -> src/clientSideScene/sceneEntities.ts -> src/clientSideScene/segments.ts -> src/machines/commandBarMachine.ts -> src/lib/commandBarConfigs/authCommandConfig.ts -> src/machines/appMachine.ts -> src/machines/settingsMachine.ts -> src/lib/commandBarConfigs/settingsCommandConfig.ts -> src/lib/createMachineCommand.ts -> src/routes/Settings.tsx -> src/components/Settings/AllSettingsFields.tsx -> src/components/LspProvider.tsx -> src/editor/plugins/lsp/kcl/language.ts -> src/editor/plugins/lsp/kcl/index.ts 12) src/lib/singletons.ts -> src/clientSideScene/sceneEntities.ts -> src/clientSideScene/segments.ts -> src/machines/commandBarMachine.ts -> src/lib/commandBarConfigs/authCommandConfig.ts -> src/machines/appMachine.ts -> src/machines/settingsMachine.ts -> src/lib/commandBarConfigs/settingsCommandConfig.ts -> src/lib/createMachineCommand.ts -> src/routes/Settings.tsx -> src/components/Settings/AllSettingsFields.tsx -> src/components/LspProvider.tsx 13) src/machines/appMachine.ts -> src/machines/settingsMachine.ts -> src/lib/commandBarConfigs/settingsCommandConfig.ts -> src/lib/createMachineCommand.ts -> src/routes/Settings.tsx -> src/components/Settings/AllSettingsFields.tsx -> src/components/LspProvider.tsx 14) src/machines/appMachine.ts -> src/machines/settingsMachine.ts -> src/lib/commandBarConfigs/settingsCommandConfig.ts -> src/lib/createMachineCommand.ts -> src/routes/Settings.tsx -> src/components/Settings/AllSettingsFields.tsx -> src/components/Settings/SettingsFieldInput.tsx 15) src/machines/appMachine.ts -> src/machines/settingsMachine.ts -> src/lib/commandBarConfigs/settingsCommandConfig.ts -> src/lib/createMachineCommand.ts -> src/routes/Settings.tsx -> src/components/Settings/AllSettingsFields.tsx 16) src/routes/Settings.tsx -> src/components/Settings/AllSettingsFields.tsx 17) src/machines/appMachine.ts -> src/machines/settingsMachine.ts -> src/lib/commandBarConfigs/settingsCommandConfig.ts -> src/lib/createMachineCommand.ts -> src/routes/Settings.tsx -> src/components/Settings/SettingsSearchBar.tsx 18) src/machines/appMachine.ts -> src/machines/settingsMachine.ts -> src/lib/commandBarConfigs/settingsCommandConfig.ts -> src/lib/createMachineCommand.ts -> src/routes/Settings.tsx -> src/components/Settings/SettingsSectionsList.tsx 19) src/lib/singletons.ts -> src/clientSideScene/sceneEntities.ts -> src/clientSideScene/segments.ts -> src/machines/commandBarMachine.ts -> src/lib/commandBarConfigs/authCommandConfig.ts -> src/machines/appMachine.ts -> src/machines/settingsMachine.ts 20) src/machines/commandBarMachine.ts -> src/lib/commandBarConfigs/authCommandConfig.ts -> src/machines/appMachine.ts -> src/machines/settingsMachine.ts 21) src/hooks/useModelingContext.ts -> src/components/ModelingMachineProvider.tsx -> src/components/Toolbar/Intersect.tsx -> src/components/SetHorVertDistanceModal.tsx -> src/lib/useCalculateKclExpression.ts 22) src/components/ToastTextToCad.tsx -> src/lib/textToCad.ts 23) src/hooks/useModelingContext.ts -> src/components/ModelingMachineProvider.tsx -> src/machines/modelingMachine.ts -> src/clientSideScene/ClientSideSceneComp.tsx 24) src/routes/Onboarding/index.tsx -> src/routes/Onboarding/Camera.tsx -> src/routes/Onboarding/utils.tsx
$ dpdm --no-warning --no-tree -T --skip-dynamic-imports=circular src/index.tsx
• Circular Dependencies
01) src/lang/std/sketch.ts -> src/lang/modifyAst.ts -> src/lang/modifyAst/addEdgeTreatment.ts
02) src/lang/std/sketch.ts -> src/lang/modifyAst.ts
03) src/lang/std/sketch.ts -> src/lang/modifyAst.ts -> src/lang/std/sketchcombos.ts
04) src/lib/singletons.ts -> src/editor/manager.ts -> src/lib/selections.ts
05) src/lib/singletons.ts -> src/lang/KclSingleton.ts
06) src/lib/singletons.ts -> src/lang/codeManager.ts
07) src/lib/singletons.ts -> src/clientSideScene/sceneEntities.ts -> src/clientSideScene/segments.ts -> src/components/Toolbar/angleLengthInfo.ts
08) src/lib/singletons.ts -> src/clientSideScene/sceneEntities.ts -> src/clientSideScene/segments.ts -> src/machines/commandBarMachine.ts -> src/lib/commandBarConfigs/authCommandConfig.ts -> src/machines/appMachine.ts -> src/machines/settingsMachine.ts
09) src/machines/commandBarMachine.ts -> src/lib/commandBarConfigs/authCommandConfig.ts -> src/machines/appMachine.ts -> src/machines/settingsMachine.ts
10) src/hooks/useModelingContext.ts -> src/components/ModelingMachineProvider.tsx -> src/components/Toolbar/Intersect.tsx -> src/components/SetHorVertDistanceModal.tsx -> src/lib/useCalculateKclExpression.ts
11) src/routes/Onboarding/index.tsx -> src/routes/Onboarding/Camera.tsx -> src/routes/Onboarding/utils.tsx

View File

@ -103,6 +103,7 @@
"lint-fix": "eslint --fix --ext .ts --ext .tsx src e2e packages/codemirror-lsp-client/src rust/kcl-language-server/client/src",
"lint": "eslint --max-warnings 0 --ext .ts --ext .tsx src e2e packages/codemirror-lsp-client/src rust/kcl-language-server/client/src",
"circular-deps": "dpdm --no-warning --no-tree -T --skip-dynamic-imports=circular src/index.tsx",
"circular-deps:overwrite": "yarn circular-deps | sed '$d' | grep -v '^yarn run' > known-circular.txt",
"circular-deps:diff": "./scripts/diff-circular-deps.sh",
"files:set-version": "echo \"$(jq --arg v \"$VERSION\" '.version=$v' package.json --indent 2)\" > package.json",
"files:set-notes": "./scripts/set-files-notes.sh",
@ -232,7 +233,7 @@
"ts-node": "^10.0.0",
"typescript": "^5.8.2",
"typescript-eslint": "^8.26.1",
"vite": "^5.4.12",
"vite": "^5.4.16",
"vite-plugin-package-version": "^1.1.0",
"vite-plugin-top-level-await": "^1.5.0",
"vite-tsconfig-paths": "^4.3.2",

View File

@ -683,9 +683,9 @@ vite-tsconfig-paths@^4.3.2:
tsconfck "^3.0.3"
vite@^5.0.0:
version "5.4.14"
resolved "https://registry.yarnpkg.com/vite/-/vite-5.4.14.tgz#ff8255edb02134df180dcfca1916c37a6abe8408"
integrity sha512-EK5cY7Q1D8JNhSaPKVK4pwBFvaTmZxEnoKXLG/U9gmdDcihQGNzFlgIvaxezFR4glP1LsuiedwMBqCXH3wZccA==
version "5.4.16"
resolved "https://registry.yarnpkg.com/vite/-/vite-5.4.16.tgz#471983257a890ef33f2700cbbbc2134f2d08abf1"
integrity sha512-Y5gnfp4NemVfgOTDQAunSD4346fal44L9mszGGY/e+qxsRT5y1sMlS/8tiQ8AFAp+MFgYNSINdfEchJiPm41vQ==
dependencies:
esbuild "^0.21.3"
postcss "^8.4.43"

20
rust/Cargo.lock generated
View File

@ -1780,7 +1780,7 @@ dependencies = [
[[package]]
name = "kcl-bumper"
version = "0.1.57"
version = "0.1.58"
dependencies = [
"anyhow",
"clap",
@ -1791,7 +1791,7 @@ dependencies = [
[[package]]
name = "kcl-derive-docs"
version = "0.1.57"
version = "0.1.58"
dependencies = [
"Inflector",
"anyhow",
@ -1810,7 +1810,7 @@ dependencies = [
[[package]]
name = "kcl-directory-test-macro"
version = "0.1.57"
version = "0.1.58"
dependencies = [
"proc-macro2",
"quote",
@ -1819,7 +1819,7 @@ dependencies = [
[[package]]
name = "kcl-language-server"
version = "0.2.57"
version = "0.2.58"
dependencies = [
"anyhow",
"clap",
@ -1840,7 +1840,7 @@ dependencies = [
[[package]]
name = "kcl-language-server-release"
version = "0.1.57"
version = "0.1.58"
dependencies = [
"anyhow",
"clap",
@ -1860,7 +1860,7 @@ dependencies = [
[[package]]
name = "kcl-lib"
version = "0.2.57"
version = "0.2.58"
dependencies = [
"anyhow",
"approx 0.5.1",
@ -1928,7 +1928,7 @@ dependencies = [
[[package]]
name = "kcl-python-bindings"
version = "0.3.57"
version = "0.3.58"
dependencies = [
"anyhow",
"kcl-lib",
@ -1943,7 +1943,7 @@ dependencies = [
[[package]]
name = "kcl-test-server"
version = "0.1.57"
version = "0.1.58"
dependencies = [
"anyhow",
"hyper 0.14.32",
@ -1956,7 +1956,7 @@ dependencies = [
[[package]]
name = "kcl-to-core"
version = "0.1.57"
version = "0.1.58"
dependencies = [
"anyhow",
"async-trait",
@ -1970,7 +1970,7 @@ dependencies = [
[[package]]
name = "kcl-wasm-lib"
version = "0.1.57"
version = "0.1.58"
dependencies = [
"bson",
"console_error_panic_hook",

View File

@ -1,7 +1,7 @@
[package]
name = "kcl-bumper"
version = "0.1.57"
version = "0.1.58"
edition = "2021"
repository = "https://github.com/KittyCAD/modeling-api"
rust-version = "1.76"

View File

@ -1,7 +1,7 @@
[package]
name = "kcl-derive-docs"
description = "A tool for generating documentation from Rust derive macros"
version = "0.1.57"
version = "0.1.58"
edition = "2021"
license = "MIT"
repository = "https://github.com/KittyCAD/modeling-app"

View File

@ -1,7 +1,7 @@
[package]
name = "kcl-directory-test-macro"
description = "A tool for generating tests from a directory of kcl files"
version = "0.1.57"
version = "0.1.58"
edition = "2021"
license = "MIT"
repository = "https://github.com/KittyCAD/modeling-app"

View File

@ -1,6 +1,6 @@
[package]
name = "kcl-language-server-release"
version = "0.1.57"
version = "0.1.58"
edition = "2021"
authors = ["KittyCAD Inc <kcl@kittycad.io>"]
publish = false

View File

@ -2,7 +2,7 @@
name = "kcl-language-server"
description = "A language server for KCL."
authors = ["KittyCAD Inc <kcl@kittycad.io>"]
version = "0.2.57"
version = "0.2.58"
edition = "2021"
license = "MIT"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

View File

@ -1,7 +1,7 @@
[package]
name = "kcl-lib"
description = "KittyCAD Language implementation and tools"
version = "0.2.57"
version = "0.2.58"
edition = "2021"
license = "MIT"
repository = "https://github.com/KittyCAD/modeling-app"

View File

@ -902,6 +902,33 @@ impl Node<BinaryExpression> {
}
}
// Then check if we have solids.
if self.operator == BinaryOperator::Add || self.operator == BinaryOperator::Or {
if let (KclValue::Solid { value: left }, KclValue::Solid { value: right }) = (&left_value, &right_value) {
let args = crate::std::Args::new(Default::default(), self.into(), ctx.clone(), None);
let result =
crate::std::csg::inner_union(vec![*left.clone(), *right.clone()], exec_state, args).await?;
return Ok(result.into());
}
} else if self.operator == BinaryOperator::Sub {
// Check if we have solids.
if let (KclValue::Solid { value: left }, KclValue::Solid { value: right }) = (&left_value, &right_value) {
let args = crate::std::Args::new(Default::default(), self.into(), ctx.clone(), None);
let result =
crate::std::csg::inner_subtract(vec![*left.clone()], vec![*right.clone()], exec_state, args)
.await?;
return Ok(result.into());
}
} else if self.operator == BinaryOperator::And {
// Check if we have solids.
if let (KclValue::Solid { value: left }, KclValue::Solid { value: right }) = (&left_value, &right_value) {
let args = crate::std::Args::new(Default::default(), self.into(), ctx.clone(), None);
let result =
crate::std::csg::inner_intersect(vec![*left.clone(), *right.clone()], exec_state, args).await?;
return Ok(result.into());
}
}
// Check if we are doing logical operations on booleans.
if self.operator == BinaryOperator::Or || self.operator == BinaryOperator::And {
let KclValue::Bool {

View File

@ -28,6 +28,8 @@ pub async fn union(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
/// Union two or more solids into a single solid.
///
/// ```no_run
/// // Union two cubes using the stdlib functions.
///
/// fn cube(center) {
/// return startSketchOn('XY')
/// |> startProfileAt([center[0] - 10, center[1] - 10], %)
@ -43,6 +45,52 @@ pub async fn union(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
///
/// unionedPart = union([part001, part002])
/// ```
///
/// ```no_run
/// // Union two cubes using operators.
/// // NOTE: This will not work when using codemods through the UI.
/// // Codemods will generate the stdlib function call instead.
///
/// fn cube(center) {
/// return startSketchOn('XY')
/// |> startProfileAt([center[0] - 10, center[1] - 10], %)
/// |> line(endAbsolute = [center[0] + 10, center[1] - 10])
/// |> line(endAbsolute = [center[0] + 10, center[1] + 10])
/// |> line(endAbsolute = [center[0] - 10, center[1] + 10])
/// |> close()
/// |> extrude(length = 10)
/// }
///
/// part001 = cube([0, 0])
/// part002 = cube([20, 10])
///
/// // This is the equivalent of: union([part001, part002])
/// unionedPart = part001 + part002
/// ```
///
/// ```no_run
/// // Union two cubes using the more programmer-friendly operator.
/// // NOTE: This will not work when using codemods through the UI.
/// // Codemods will generate the stdlib function call instead.
///
/// fn cube(center) {
/// return startSketchOn('XY')
/// |> startProfileAt([center[0] - 10, center[1] - 10], %)
/// |> line(endAbsolute = [center[0] + 10, center[1] - 10])
/// |> line(endAbsolute = [center[0] + 10, center[1] + 10])
/// |> line(endAbsolute = [center[0] - 10, center[1] + 10])
/// |> close()
/// |> extrude(length = 10)
/// }
///
/// part001 = cube([0, 0])
/// part002 = cube([20, 10])
///
/// // This is the equivalent of: union([part001, part002])
/// // Programmers will understand `|` as a union operation, but mechanical engineers
/// // will understand `+`, we made both work.
/// unionedPart = part001 | part002
/// ```
#[stdlib {
name = "union",
feature_tree_operation = true,
@ -53,7 +101,11 @@ pub async fn union(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
solids = {docs = "The solids to union."},
}
}]
async fn inner_union(solids: Vec<Solid>, exec_state: &mut ExecState, args: Args) -> Result<Vec<Solid>, KclError> {
pub(crate) async fn inner_union(
solids: Vec<Solid>,
exec_state: &mut ExecState,
args: Args,
) -> Result<Vec<Solid>, KclError> {
// Flush the fillets for the solids.
args.flush_batch_for_solids(exec_state, &solids).await?;
@ -90,6 +142,8 @@ pub async fn intersect(exec_state: &mut ExecState, args: Args) -> Result<KclValu
/// verifying fit, and analyzing overlapping geometries in assemblies.
///
/// ```no_run
/// // Intersect two cubes using the stdlib functions.
///
/// fn cube(center) {
/// return startSketchOn('XY')
/// |> startProfileAt([center[0] - 10, center[1] - 10], %)
@ -105,6 +159,28 @@ pub async fn intersect(exec_state: &mut ExecState, args: Args) -> Result<KclValu
///
/// intersectedPart = intersect([part001, part002])
/// ```
///
/// ```no_run
/// // Intersect two cubes using operators.
/// // NOTE: This will not work when using codemods through the UI.
/// // Codemods will generate the stdlib function call instead.
///
/// fn cube(center) {
/// return startSketchOn('XY')
/// |> startProfileAt([center[0] - 10, center[1] - 10], %)
/// |> line(endAbsolute = [center[0] + 10, center[1] - 10])
/// |> line(endAbsolute = [center[0] + 10, center[1] + 10])
/// |> line(endAbsolute = [center[0] - 10, center[1] + 10])
/// |> close()
/// |> extrude(length = 10)
/// }
///
/// part001 = cube([0, 0])
/// part002 = cube([8, 8])
///
/// // This is the equivalent of: intersect([part001, part002])
/// intersectedPart = part001 & part002
/// ```
#[stdlib {
name = "intersect",
feature_tree_operation = true,
@ -115,7 +191,11 @@ pub async fn intersect(exec_state: &mut ExecState, args: Args) -> Result<KclValu
solids = {docs = "The solids to intersect."},
}
}]
async fn inner_intersect(solids: Vec<Solid>, exec_state: &mut ExecState, args: Args) -> Result<Vec<Solid>, KclError> {
pub(crate) async fn inner_intersect(
solids: Vec<Solid>,
exec_state: &mut ExecState,
args: Args,
) -> Result<Vec<Solid>, KclError> {
// Flush the fillets for the solids.
args.flush_batch_for_solids(exec_state, &solids).await?;
@ -145,6 +225,8 @@ pub async fn subtract(exec_state: &mut ExecState, args: Args) -> Result<KclValue
/// and complex multi-body part modeling.
///
/// ```no_run
/// // Subtract a cylinder from a cube using the stdlib functions.
///
/// fn cube(center) {
/// return startSketchOn('XY')
/// |> startProfileAt([center[0] - 10, center[1] - 10], %)
@ -162,6 +244,30 @@ pub async fn subtract(exec_state: &mut ExecState, args: Args) -> Result<KclValue
///
/// subtractedPart = subtract([part001], tools=[part002])
/// ```
///
/// ```no_run
/// // Subtract a cylinder from a cube using operators.
/// // NOTE: This will not work when using codemods through the UI.
/// // Codemods will generate the stdlib function call instead.
///
/// fn cube(center) {
/// return startSketchOn('XY')
/// |> startProfileAt([center[0] - 10, center[1] - 10], %)
/// |> line(endAbsolute = [center[0] + 10, center[1] - 10])
/// |> line(endAbsolute = [center[0] + 10, center[1] + 10])
/// |> line(endAbsolute = [center[0] - 10, center[1] + 10])
/// |> close()
/// |> extrude(length = 10)
/// }
///
/// part001 = cube([0, 0])
/// part002 = startSketchOn('XY')
/// |> circle(center = [0, 0], radius = 2)
/// |> extrude(length = 10)
///
/// // This is the equivalent of: subtract([part001], tools=[part002])
/// subtractedPart = part001 - part002
/// ```
#[stdlib {
name = "subtract",
feature_tree_operation = true,
@ -169,11 +275,11 @@ pub async fn subtract(exec_state: &mut ExecState, args: Args) -> Result<KclValue
unlabeled_first = true,
deprecated = true,
args = {
solids = {docs = "The solids to intersect."},
solids = {docs = "The solids to use as the base to subtract from."},
tools = {docs = "The solids to subtract."},
}
}]
async fn inner_subtract(
pub(crate) async fn inner_subtract(
solids: Vec<Solid>,
tools: Vec<Solid>,
exec_state: &mut ExecState,

View File

@ -104,7 +104,7 @@ pub async fn scale(exec_state: &mut ExecState, args: Args) -> Result<KclValue, K
///
/// cube
/// |> scale(
/// z = 2.5,
/// y = 2.5,
/// )
/// ```
///
@ -278,10 +278,20 @@ pub async fn translate(exec_state: &mut ExecState, args: Args) -> Result<KclValu
///
/// import "tests/inputs/cube.sldprt" as cube
///
/// // Circle so you actually see the move.
/// startSketchOn('XY')
/// |> circle(
/// center = [-10, -10],
/// radius = 10,
/// )
/// |> extrude(
/// length = 10,
/// )
///
/// cube
/// |> translate(
/// x = 1.0,
/// y = 1.0,
/// x = 10.0,
/// y = 10.0,
/// z = 2.5,
/// )
/// ```
@ -680,7 +690,7 @@ pub async fn rotate(exec_state: &mut ExecState, args: Args) -> Result<KclValue,
/// cube
/// |> rotate(
/// axis = [0, 0, 1.0],
/// angle = 90,
/// angle = 9,
/// )
/// ```
///

Binary file not shown.

Before

Width:  |  Height:  |  Size: 65 KiB

After

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 74 KiB

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 73 KiB

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 74 KiB

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

View File

@ -1,6 +1,6 @@
[package]
name = "kcl-python-bindings"
version = "0.3.57"
version = "0.3.58"
edition = "2021"
repository = "https://github.com/kittycad/modeling-app"
exclude = ["tests/*", "files/*", "venv/*"]

View File

@ -1,7 +1,7 @@
[package]
name = "kcl-test-server"
description = "A test server for KCL"
version = "0.1.57"
version = "0.1.58"
edition = "2021"
license = "MIT"

View File

@ -1,7 +1,7 @@
[package]
name = "kcl-to-core"
description = "Utility methods to convert kcl to engine core executable tests"
version = "0.1.57"
version = "0.1.58"
edition = "2021"
license = "MIT"
repository = "https://github.com/KittyCAD/modeling-app"

View File

@ -1,6 +1,6 @@
[package]
name = "kcl-wasm-lib"
version = "0.1.57"
version = "0.1.58"
edition = "2021"
repository = "https://github.com/KittyCAD/modeling-app"
rust-version = "1.83"

View File

@ -1,5 +1,5 @@
#!/bin/bash
set -euo pipefail
yarn circular-deps | sed '$d' | grep -v '^yarn run' | tr -d '\n' > /tmp/circular-deps.txt
diff -w /tmp/circular-deps.txt ./known-circular.txt
yarn circular-deps | sed '$d' | grep -v '^yarn run' > /tmp/circular-deps.txt
diff --ignore-blank-lines -w /tmp/circular-deps.txt ./known-circular.txt

View File

@ -20,7 +20,7 @@ import {
INTERSECTION_PLANE_LAYER,
SKETCH_LAYER,
ZOOM_MAGIC_NUMBER,
} from '@src/clientSideScene/sceneInfra'
} from '@src/clientSideScene/sceneUtils'
import type { EngineCommand } from '@src/lang/std/artifactGraph'
import type {
EngineCommandManager,

View File

@ -1,8 +1,6 @@
import { Dialog, Popover, Transition } from '@headlessui/react'
import { Fragment, useEffect, useMemo, useRef, useState } from 'react'
import { Popover } from '@headlessui/react'
import { useEffect, useMemo, useRef, useState } from 'react'
import toast from 'react-hot-toast'
import type { InstanceProps } from 'react-modal-promise'
import { create } from 'react-modal-promise'
import type { Node } from '@rust/kcl-lib/bindings/Node'
@ -15,16 +13,11 @@ import {
import {
ARROWHEAD,
DEBUG_SHOW_BOTH_SCENES,
} from '@src/clientSideScene/sceneInfra'
import { ActionButton } from '@src/components/ActionButton'
} from '@src/clientSideScene/sceneUtils'
import type { CustomIconName } from '@src/components/CustomIcon'
import { CustomIcon } from '@src/components/CustomIcon'
import { useModelingContext } from '@src/hooks/useModelingContext'
import { executeAstMock } from '@src/lang/langHelpers'
import {
deleteSegmentFromPipeExpression,
removeSingleConstraintInfo,
} from '@src/lang/modifyAst'
import { removeSingleConstraintInfo } from '@src/lang/modifyAst'
import { findUsesOfTagInPipe, getNodeFromPath } from '@src/lang/queryAst'
import { getConstraintInfo, getConstraintInfoKw } from '@src/lang/std/sketch'
import type { ConstrainInfo } from '@src/lang/std/stdTypes'
@ -34,7 +27,6 @@ import type {
CallExpressionKw,
Expr,
PathToNode,
Program,
} from '@src/lang/wasm'
import { defaultSourceRange, parse, recast, resultIsOk } from '@src/lang/wasm'
import { cameraMouseDragGuards } from '@src/lib/cameraControls'
@ -43,7 +35,6 @@ import {
editorManager,
engineCommandManager,
kclManager,
rustContext,
sceneEntitiesManager,
sceneInfra,
} from '@src/lib/singletons'
@ -51,10 +42,7 @@ import { err, reportRejection, trap } from '@src/lib/trap'
import { throttle, toSync } from '@src/lib/utils'
import type { useSettings } from '@src/machines/appMachine'
import { commandBarActor } from '@src/machines/commandBarMachine'
import type {
SegmentOverlay,
SketchDetails,
} from '@src/machines/modelingMachine'
import type { SegmentOverlay } from '@src/machines/modelingMachine'
function useShouldHideScene(): { hideClient: boolean; hideServer: boolean } {
const [isCamMoving, setIsCamMoving] = useState(false)
@ -343,130 +331,6 @@ const Overlay = ({
)
}
type ConfirmModalProps = InstanceProps<boolean, boolean> & { text: string }
export const ConfirmModal = ({
isOpen,
onResolve,
onReject,
text,
}: ConfirmModalProps) => {
return (
<Transition appear show={isOpen} as={Fragment}>
<Dialog
as="div"
className="relative z-10"
onClose={() => onResolve(false)}
>
<Transition.Child
as={Fragment}
enter="ease-out duration-300"
enterFrom="opacity-0"
enterTo="opacity-100"
leave="ease-in duration-200"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<div className="fixed inset-0 bg-black bg-opacity-25" />
</Transition.Child>
<div className="fixed inset-0 overflow-y-auto">
<div className="flex min-h-full items-center justify-center p-4 text-center">
<Transition.Child
as={Fragment}
enter="ease-out duration-300"
enterFrom="opacity-0 scale-95"
enterTo="opacity-100 scale-100"
leave="ease-in duration-200"
leaveFrom="opacity-100 scale-100"
leaveTo="opacity-0 scale-95"
>
<Dialog.Panel className="rounded relative mx-auto px-4 py-8 bg-chalkboard-10 dark:bg-chalkboard-100 border dark:border-chalkboard-70 max-w-xl w-full shadow-lg">
<div>{text}</div>
<div className="mt-8 flex justify-between">
<ActionButton
Element="button"
onClick={() => onResolve(true)}
>
Continue and unconstrain
</ActionButton>
<ActionButton
Element="button"
onClick={() => onReject(false)}
>
Cancel
</ActionButton>
</div>
</Dialog.Panel>
</Transition.Child>
</div>
</div>
</Dialog>
</Transition>
)
}
export const confirmModal = create<ConfirmModalProps, boolean, boolean>(
ConfirmModal
)
export async function deleteSegment({
pathToNode,
sketchDetails,
}: {
pathToNode: PathToNode
sketchDetails: SketchDetails | null
}) {
let modifiedAst: Node<Program> | Error = kclManager.ast
const dependentRanges = findUsesOfTagInPipe(modifiedAst, pathToNode)
const shouldContinueSegDelete = dependentRanges.length
? await confirmModal({
text: `At least ${dependentRanges.length} segment rely on the segment you're deleting.\nDo you want to continue and unconstrain these segments?`,
isOpen: true,
})
: true
if (!shouldContinueSegDelete) return
modifiedAst = deleteSegmentFromPipeExpression(
dependentRanges,
modifiedAst,
kclManager.variables,
codeManager.code,
pathToNode
)
if (err(modifiedAst)) return Promise.reject(modifiedAst)
const newCode = recast(modifiedAst)
const pResult = parse(newCode)
if (err(pResult) || !resultIsOk(pResult)) return Promise.reject(pResult)
modifiedAst = pResult.program
const testExecute = await executeAstMock({
ast: modifiedAst,
usePrevMemory: false,
rustContext: rustContext,
})
if (testExecute.errors.length) {
toast.error('Segment tag used outside of current Sketch. Could not delete.')
return
}
if (!sketchDetails) return
await sceneEntitiesManager.updateAstAndRejigSketch(
pathToNode,
sketchDetails.sketchNodePaths,
sketchDetails.planeNodePath,
modifiedAst,
sketchDetails.zAxis,
sketchDetails.yAxis,
sketchDetails.origin
)
// Now 'Set sketchDetails' is called with the modified pathToNode
}
const SegmentMenu = ({
verticalPosition,
pathToNode,

View File

@ -0,0 +1,72 @@
import { Fragment } from 'react'
import { create, type InstanceProps } from 'react-modal-promise'
import { Dialog, Transition } from '@headlessui/react'
import { ActionButton } from '@src/components/ActionButton'
type ConfirmModalProps = InstanceProps<boolean, boolean> & { text: string }
export const ConfirmModal = ({
isOpen,
onResolve,
onReject,
text,
}: ConfirmModalProps) => {
return (
<Transition appear show={isOpen} as={Fragment}>
<Dialog
as="div"
className="relative z-10"
onClose={() => onResolve(false)}
>
<Transition.Child
as={Fragment}
enter="ease-out duration-300"
enterFrom="opacity-0"
enterTo="opacity-100"
leave="ease-in duration-200"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<div className="fixed inset-0 bg-black bg-opacity-25" />
</Transition.Child>
<div className="fixed inset-0 overflow-y-auto">
<div className="flex min-h-full items-center justify-center p-4 text-center">
<Transition.Child
as={Fragment}
enter="ease-out duration-300"
enterFrom="opacity-0 scale-95"
enterTo="opacity-100 scale-100"
leave="ease-in duration-200"
leaveFrom="opacity-100 scale-100"
leaveTo="opacity-0 scale-95"
>
<Dialog.Panel className="rounded relative mx-auto px-4 py-8 bg-chalkboard-10 dark:bg-chalkboard-100 border dark:border-chalkboard-70 max-w-xl w-full shadow-lg">
<div>{text}</div>
<div className="mt-8 flex justify-between">
<ActionButton
Element="button"
onClick={() => onResolve(true)}
>
Continue and unconstrain
</ActionButton>
<ActionButton
Element="button"
onClick={() => onReject(false)}
>
Cancel
</ActionButton>
</div>
</Dialog.Panel>
</Transition.Child>
</div>
</div>
</Dialog>
</Transition>
)
}
export const confirmModal = create<ConfirmModalProps, boolean, boolean>(
ConfirmModal
)

View File

@ -0,0 +1,75 @@
import toast from 'react-hot-toast'
import type { Node } from '@rust/kcl-lib/bindings/Node'
import { confirmModal } from '@src/clientSideScene/confirmModal'
import { executeAstMock } from '@src/lang/langHelpers'
import { deleteSegmentFromPipeExpression } from '@src/lang/modifyAst'
import { findUsesOfTagInPipe } from '@src/lang/queryAst'
import type { PathToNode, Program } from '@src/lang/wasm'
import { parse, recast, resultIsOk } from '@src/lang/wasm'
import {
codeManager,
kclManager,
rustContext,
sceneEntitiesManager,
} from '@src/lib/singletons'
import { err } from '@src/lib/trap'
import type { SketchDetails } from '@src/machines/modelingMachine'
export async function deleteSegment({
pathToNode,
sketchDetails,
}: {
pathToNode: PathToNode
sketchDetails: SketchDetails | null
}) {
let modifiedAst: Node<Program> | Error = kclManager.ast
const dependentRanges = findUsesOfTagInPipe(modifiedAst, pathToNode)
const shouldContinueSegDelete = dependentRanges.length
? await confirmModal({
text: `At least ${dependentRanges.length} segment rely on the segment you're deleting.\nDo you want to continue and unconstrain these segments?`,
isOpen: true,
})
: true
if (!shouldContinueSegDelete) return
modifiedAst = deleteSegmentFromPipeExpression(
dependentRanges,
modifiedAst,
kclManager.variables,
codeManager.code,
pathToNode
)
if (err(modifiedAst)) return Promise.reject(modifiedAst)
const newCode = recast(modifiedAst)
const pResult = parse(newCode)
if (err(pResult) || !resultIsOk(pResult)) return Promise.reject(pResult)
modifiedAst = pResult.program
const testExecute = await executeAstMock({
ast: modifiedAst,
usePrevMemory: false,
rustContext: rustContext,
})
if (testExecute.errors.length) {
toast.error('Segment tag used outside of current Sketch. Could not delete.')
return
}
if (!sketchDetails) return
await sceneEntitiesManager.updateAstAndRejigSketch(
pathToNode,
sketchDetails.sketchNodePaths,
sketchDetails.planeNodePath,
modifiedAst,
sketchDetails.zAxis,
sketchDetails.yAxis,
sketchDetails.origin
)
// Now 'Set sketchDetails' is called with the modified pathToNode
}

View File

@ -86,7 +86,7 @@ import {
X_AXIS,
Y_AXIS,
getSceneScale,
} from '@src/clientSideScene/sceneInfra'
} from '@src/clientSideScene/sceneUtils'
import type { SegmentUtils } from '@src/clientSideScene/segments'
import {
createProfileStartHandle,

View File

@ -14,7 +14,6 @@ import {
GridHelper,
LineBasicMaterial,
OrthographicCamera,
PerspectiveCamera,
Raycaster,
Scene,
TextureLoader,
@ -26,6 +25,16 @@ import { CSS2DRenderer } from 'three/examples/jsm/renderers/CSS2DRenderer'
import { CameraControls } from '@src/clientSideScene/CameraControls'
import { orthoScale, perspScale } from '@src/clientSideScene/helpers'
import {
AXIS_GROUP,
DEBUG_SHOW_INTERSECTION_PLANE,
INTERSECTION_PLANE_LAYER,
RAYCASTABLE_PLANE,
SKETCH_LAYER,
X_AXIS,
Y_AXIS,
getSceneScale,
} from '@src/clientSideScene/sceneUtils'
import type { useModelingContext } from '@src/hooks/useModelingContext'
import type { EngineCommandManager } from '@src/lang/std/engineConnection'
import type { Coords2d } from '@src/lang/std/sketch'
@ -41,37 +50,6 @@ import type {
type SendType = ReturnType<typeof useModelingContext>['send']
// 63.5 is definitely a bit of a magic number, play with it until it looked right
// if it were 64, that would feel like it's something in the engine where a random
// power of 2 is used, but it's the 0.5 seems to make things look much more correct
export const ZOOM_MAGIC_NUMBER = 63.5
export const INTERSECTION_PLANE_LAYER = 1
export const SKETCH_LAYER = 2
// redundant types so that it can be changed temporarily but CI will catch the wrong type
export const DEBUG_SHOW_INTERSECTION_PLANE = false
export const DEBUG_SHOW_BOTH_SCENES = false
export const RAYCASTABLE_PLANE = 'raycastable-plane'
export const X_AXIS = 'xAxis'
export const Y_AXIS = 'yAxis'
/** If a segment angle is less than this many degrees off a meanginful angle it'll snap to it */
export const ANGLE_SNAP_THRESHOLD_DEGREES = 3
/** the THREEjs representation of the group surrounding a "snapped" point that is not yet placed */
export const DRAFT_POINT_GROUP = 'draft-point-group'
/** the THREEjs representation of a "snapped" point that is not yet placed */
export const DRAFT_POINT = 'draft-point'
export const AXIS_GROUP = 'axisGroup'
export const SKETCH_GROUP_SEGMENTS = 'sketch-group-segments'
export const ARROWHEAD = 'arrowhead'
export const SEGMENT_LENGTH_LABEL = 'segment-length-label'
export const SEGMENT_LENGTH_LABEL_TEXT = 'segment-length-label-text'
export const SEGMENT_LENGTH_LABEL_OFFSET_PX = 30
export const CIRCLE_3_POINT_DRAFT_POINT = 'circle-3-point-draft-point'
export const CIRCLE_3_POINT_DRAFT_CIRCLE = 'circle-3-point-draft-circle'
export interface OnMouseEnterLeaveArgs {
selected: Object3D<Object3DEventMap>
dragSelected?: Object3D<Object3DEventMap>
@ -689,24 +667,6 @@ export class SceneInfra {
}
}
export function getSceneScale(
camera: PerspectiveCamera | OrthographicCamera,
target: Vector3
): number {
const distance =
camera instanceof PerspectiveCamera
? camera.position.distanceTo(target)
: 63.7942123 / camera.zoom
if (distance <= 20) return 0.1
else if (distance > 20 && distance <= 200) return 1
else if (distance > 200 && distance <= 2000) return 10
else if (distance > 2000 && distance <= 20000) return 100
else if (distance > 20000) return 1000
return 1
}
function baseUnitTomm(baseUnit: BaseUnit) {
switch (baseUnit) {
case 'mm':

View File

@ -0,0 +1,52 @@
// 63.5 is definitely a bit of a magic number, play with it until it looked right
// if it were 64, that would feel like it's something in the engine where a random
import type { OrthographicCamera, Vector3 } from 'three'
import { PerspectiveCamera } from 'three'
// power of 2 is used, but it's the 0.5 seems to make things look much more correct
export const ZOOM_MAGIC_NUMBER = 63.5
export const INTERSECTION_PLANE_LAYER = 1
export const SKETCH_LAYER = 2
// redundant types so that it can be changed temporarily but CI will catch the wrong type
export const DEBUG_SHOW_INTERSECTION_PLANE = false
export const DEBUG_SHOW_BOTH_SCENES = false
export const RAYCASTABLE_PLANE = 'raycastable-plane'
export const X_AXIS = 'xAxis'
export const Y_AXIS = 'yAxis'
/** If a segment angle is less than this many degrees off a meanginful angle it'll snap to it */
export const ANGLE_SNAP_THRESHOLD_DEGREES = 3
/** the THREEjs representation of the group surrounding a "snapped" point that is not yet placed */
export const DRAFT_POINT_GROUP = 'draft-point-group'
/** the THREEjs representation of a "snapped" point that is not yet placed */
export const DRAFT_POINT = 'draft-point'
export const AXIS_GROUP = 'axisGroup'
export const SKETCH_GROUP_SEGMENTS = 'sketch-group-segments'
export const ARROWHEAD = 'arrowhead'
export const SEGMENT_LENGTH_LABEL = 'segment-length-label'
export const SEGMENT_LENGTH_LABEL_TEXT = 'segment-length-label-text'
export const SEGMENT_LENGTH_LABEL_OFFSET_PX = 30
export const CIRCLE_3_POINT_DRAFT_POINT = 'circle-3-point-draft-point'
export const CIRCLE_3_POINT_DRAFT_CIRCLE = 'circle-3-point-draft-circle'
export function getSceneScale(
camera: PerspectiveCamera | OrthographicCamera,
target: Vector3
): number {
const distance =
camera instanceof PerspectiveCamera
? camera.position.distanceTo(target)
: 63.7942123 / camera.zoom
if (distance <= 20) return 0.1
else if (distance > 20 && distance <= 200) return 1
else if (distance > 200 && distance <= 2000) return 10
else if (distance > 2000 && distance <= 20000) return 100
else if (distance > 20000) return 1000
return 1
}

View File

@ -71,7 +71,7 @@ import {
SEGMENT_LENGTH_LABEL,
SEGMENT_LENGTH_LABEL_OFFSET_PX,
SEGMENT_LENGTH_LABEL_TEXT,
} from '@src/clientSideScene/sceneInfra'
} from '@src/clientSideScene/sceneUtils'
import { angleLengthInfo } from '@src/components/Toolbar/angleLengthInfo'
import type { Coords2d } from '@src/lang/std/sketch'
import type { SegmentInputs } from '@src/lang/std/stdTypes'

View File

@ -13,7 +13,7 @@ import type { CoreDumpManager } from '@src/lib/coredump'
import openWindow, { openExternalBrowserIfDesktop } from '@src/lib/openWindow'
import { PATHS } from '@src/lib/paths'
import { reportRejection } from '@src/lib/trap'
import { APP_VERSION, getReleaseUrl } from '@src/routes/Settings'
import { APP_VERSION, getReleaseUrl } from '@src/routes/utils'
export function LowerRightControls({
children,

View File

@ -445,10 +445,15 @@ export const ModelingMachineProvider = ({
},
})
}
// If there are engine commands that need sent off, send them
// TODO: This should be handled outside of an action as its own
// actor, so that the system state is more controlled.
engineEvents &&
engineEvents.forEach((event) => {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
engineCommandManager.sendSceneCommand(event)
engineCommandManager
.sendSceneCommand(event)
.catch(reportRejection)
})
updateSceneObjectColors()
@ -1566,9 +1571,7 @@ export const ModelingMachineProvider = ({
data
)
if (err(result)) return reject(result)
// eslint-disable-next-line @typescript-eslint/no-floating-promises
codeManager.updateEditorWithAstAndWriteToFile(kclManager.ast)
await codeManager.updateEditorWithAstAndWriteToFile(kclManager.ast)
return result
}

View File

@ -30,7 +30,7 @@ import {
import { reportRejection } from '@src/lib/trap'
import { toSync } from '@src/lib/utils'
import { settingsActor, useSettings } from '@src/machines/appMachine'
import { APP_VERSION, IS_NIGHTLY, getReleaseUrl } from '@src/routes/Settings'
import { APP_VERSION, IS_NIGHTLY, getReleaseUrl } from '@src/routes/utils'
interface AllSettingsFieldsProps {
searchParamTab: SettingsLevel
@ -96,8 +96,7 @@ export const AllSettingsFields = forwardRef(
}
}
}
// eslint-disable-next-line @typescript-eslint/no-floating-promises
navigateToOnboardingStart()
navigateToOnboardingStart().catch(reportRejection)
}, [
isFileSettings,
navigate,

View File

@ -30,7 +30,7 @@ import { isDesktop } from '@src/lib/isDesktop'
import { openExternalBrowserIfDesktop } from '@src/lib/openWindow'
import { PATHS } from '@src/lib/paths'
import { codeManager, kclManager } from '@src/lib/singletons'
import { sendTelemetry } from '@src/lib/textToCad'
import { sendTelemetry } from '@src/lib/textToCadTelemetry'
import type { Themes } from '@src/lib/theme'
import { reportRejection } from '@src/lib/trap'
import { commandBarActor } from '@src/machines/commandBarMachine'

View File

@ -5,7 +5,7 @@ import toast from 'react-hot-toast'
import { ActionButton } from '@src/components/ActionButton'
import { SafeRenderer } from '@src/lib/markdown'
import { openExternalBrowserIfDesktop } from '@src/lib/openWindow'
import { getReleaseUrl } from '@src/routes/Settings'
import { getReleaseUrl } from '@src/routes/utils'
export function ToastUpdate({
version,

View File

@ -11,10 +11,11 @@ import {
addLineHighlight,
addLineHighlightEvent,
} from '@src/editor/highlightextension'
import type { KclManager } from '@src/lang/KclSingleton'
import type { EngineCommandManager } from '@src/lang/std/engineConnection'
import { markOnce } from '@src/lib/performance'
import type { Selection, Selections } from '@src/lib/selections'
import { processCodeMirrorRanges } from '@src/lib/selections'
import { engineCommandManager, kclManager } from '@src/lib/singletons'
import { kclEditorActor } from '@src/machines/kclEditorMachine'
import type {
ModelingMachineEvent,
@ -44,6 +45,8 @@ export const setDiagnosticsEvent = setDiagnosticsAnnotation.of(true)
export default class EditorManager {
private _copilotEnabled: boolean = true
private engineCommandManager: EngineCommandManager
private kclManager: KclManager
private _isAllTextSelected: boolean = false
private _isShiftDown: boolean = false
@ -64,6 +67,14 @@ export default class EditorManager {
public _editorView: EditorView | null = null
constructor(
engineCommandManager: EngineCommandManager,
kclManager: KclManager
) {
this.engineCommandManager = engineCommandManager
this.kclManager = kclManager
}
setCopilotEnabled(enabled: boolean) {
this._copilotEnabled = enabled
}
@ -379,8 +390,8 @@ export default class EditorManager {
codeMirrorRanges: viewUpdate.state.selection.ranges,
selectionRanges: this._selectionRanges,
isShiftDown: this._isShiftDown,
ast: kclManager.ast,
artifactGraph: kclManager.artifactGraph,
ast: this.kclManager.ast,
artifactGraph: this.kclManager.artifactGraph,
})
if (!eventInfo) {
@ -407,7 +418,7 @@ export default class EditorManager {
this._modelingSend(eventInfo.modelingEvent)
eventInfo.engineEvents.forEach((event) => {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
engineCommandManager.sendSceneCommand(event)
this.engineCommandManager.sendSceneCommand(event)
})
}
}

View File

@ -102,11 +102,14 @@ onmessage = function (event: MessageEvent) {
intoServer.enqueue(data)
const json: jsrpc.JSONRPCRequest = Codec.decode(data)
if (null != json.id) {
// eslint-disable-next-line @typescript-eslint/no-floating-promises, @typescript-eslint/no-non-null-assertion
fromServer.responses.get(json.id)!.then((response) => {
const encoded = Codec.encode(response as jsrpc.JSONRPCResponse)
postMessage(encoded)
})
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
fromServer.responses
.get(json.id)!
.then((response) => {
const encoded = Codec.encode(response as jsrpc.JSONRPCResponse)
postMessage(encoded)
})
.catch(reportRejection)
}
break
default:

View File

@ -28,7 +28,7 @@ import type { Selections } from '@src/lib/selections'
import { codeManager, kclManager } from '@src/lib/singletons'
import { err } from '@src/lib/trap'
import type { SketchTool, modelingMachine } from '@src/machines/modelingMachine'
import { IS_NIGHTLY_OR_DEBUG } from '@src/routes/Settings'
import { IS_NIGHTLY_OR_DEBUG } from '@src/routes/utils'
type OutputFormat = Models['OutputFormat3d_type']
type OutputTypeKey = OutputFormat['type']

View File

@ -12,7 +12,7 @@ import type {
import { isDesktop } from '@src/lib/isDesktop'
import type RustContext from '@src/lib/rustContext'
import screenshot from '@src/lib/screenshot'
import { APP_VERSION } from '@src/routes/Settings'
import { APP_VERSION } from '@src/routes/utils'
/* eslint-disable suggest-no-throw/suggest-no-throw --
* All the throws in CoreDumpManager are intentional and should be caught and handled properly

View File

@ -16,7 +16,7 @@ import type {
StateMachineCommandSetSchema,
} from '@src/lib/commandTypes'
import { isDesktop } from '@src/lib/isDesktop'
import { IS_NIGHTLY_OR_DEBUG } from '@src/routes/Settings'
import { IS_NIGHTLY_OR_DEBUG } from '@src/routes/utils'
interface CreateMachineCommandProps<
T extends AnyStateMachine,

View File

@ -20,7 +20,7 @@ import {
import type ModelingAppFile from '@src/lib/modelingAppFile'
import type { DefaultPlaneStr } from '@src/lib/planes'
import { defaultPlaneStrToKey } from '@src/lib/planes'
import { err } from '@src/lib/trap'
import { err, reportRejection } from '@src/lib/trap'
import type { DeepPartial } from '@src/lib/types'
import type { ModuleType } from '@src/lib/wasm_lib_wrapper'
import { getModule } from '@src/lib/wasm_lib_wrapper'
@ -48,10 +48,11 @@ export default class RustContext {
constructor(engineCommandManager: EngineCommandManager) {
this.engineCommandManager = engineCommandManager
// eslint-disable-next-line @typescript-eslint/no-floating-promises
this.ensureWasmInit().then(async () => {
this.ctxInstance = await this.create()
})
this.ensureWasmInit()
.then(async () => {
this.ctxInstance = await this.create()
})
.catch(reportRejection)
}
// Create a new context instance

View File

@ -10,7 +10,7 @@ import {
SEGMENT_BODIES_PLUS_PROFILE_START,
getParentGroup,
} from '@src/clientSideScene/sceneConstants'
import { AXIS_GROUP, X_AXIS } from '@src/clientSideScene/sceneInfra'
import { AXIS_GROUP, X_AXIS } from '@src/clientSideScene/sceneUtils'
import { getNodeFromPath, isSingleCursorInPipe } from '@src/lang/queryAst'
import { getNodePathFromSourceRange } from '@src/lang/queryAstNodePathUtils'
import type { Artifact, ArtifactId, CodeRef } from '@src/lang/std/artifactGraph'

View File

@ -34,7 +34,7 @@ kclManager.sceneInfraBaseUnitMultiplierSetter = (unit: BaseUnit) => {
}
// This needs to be after sceneInfra and engineCommandManager are is created.
export const editorManager = new EditorManager()
export const editorManager = new EditorManager(engineCommandManager, kclManager)
export const rustContext = new RustContext(engineCommandManager)

View File

@ -251,19 +251,3 @@ export async function submitAndAwaitTextToKcl({
)
return textToCadOutputCreated
}
export async function sendTelemetry(
id: string,
feedback: Models['MlFeedback_type'],
token?: string
): Promise<void> {
const url =
VITE_KC_API_BASE_URL + '/user/text-to-cad/' + id + '?feedback=' + feedback
await crossPlatformFetch(
url,
{
method: 'POST',
},
token
)
}

View File

@ -0,0 +1,19 @@
import type { Models } from '@kittycad/lib/dist/types/src'
import { VITE_KC_API_BASE_URL } from '@src/env'
import crossPlatformFetch from '@src/lib/crossPlatformFetch'
export async function sendTelemetry(
id: string,
feedback: Models['MlFeedback_type'],
token?: string
): Promise<void> {
const url =
VITE_KC_API_BASE_URL + '/user/text-to-cad/' + id + '?feedback=' + feedback
await crossPlatformFetch(
url,
{
method: 'POST',
},
token
)
}

View File

@ -9,7 +9,7 @@ import {
isEditingExistingSketch,
pipeHasCircle,
} from '@src/machines/modelingMachine'
import { IS_NIGHTLY_OR_DEBUG } from '@src/routes/Settings'
import { IS_NIGHTLY_OR_DEBUG } from '@src/routes/utils'
export type ToolbarModeName = 'modeling' | 'sketching'

View File

@ -238,8 +238,9 @@ async function getAndSyncStoredToken(input: {
if (token) {
// has just logged in, update storage
localStorage.setItem(TOKEN_PERSIST_KEY, token)
// eslint-disable-next-line @typescript-eslint/no-floating-promises
isDesktop() && writeTokenFile(token)
if (isDesktop()) {
await writeTokenFile(token)
}
return token
}
if (!isDesktop()) return ''

View File

@ -4,13 +4,13 @@ import { assign, fromPromise, setup } from 'xstate'
import type { Node } from '@rust/kcl-lib/bindings/Node'
import { deleteSegment } from '@src/clientSideScene/ClientSideSceneComp'
import { deleteSegment } from '@src/clientSideScene/deleteSegment'
import {
orthoScale,
quaternionFromUpNForward,
} from '@src/clientSideScene/helpers'
import { DRAFT_DASHED_LINE } from '@src/clientSideScene/sceneConstants'
import { DRAFT_POINT } from '@src/clientSideScene/sceneInfra'
import { DRAFT_POINT } from '@src/clientSideScene/sceneUtils'
import { createProfileStartHandle } from '@src/clientSideScene/segments'
import type { MachineManager } from '@src/components/MachineManagerProvider'
import type { ModelingMachineContext } from '@src/components/ModelingMachineProvider'

View File

@ -1,11 +1,8 @@
import { Dialog, Transition } from '@headlessui/react'
import { NODE_ENV } from '@src/env'
import { Fragment, useEffect, useRef } from 'react'
import { useHotkeys } from 'react-hotkeys-hook'
import { useLocation, useNavigate, useSearchParams } from 'react-router-dom'
import { IS_PLAYWRIGHT_KEY } from '@e2e/playwright/storageStates'
import { CustomIcon } from '@src/components/CustomIcon'
import { AllKeybindingsFields } from '@src/components/Settings/AllKeybindingsFields'
import { AllSettingsFields } from '@src/components/Settings/AllSettingsFields'
@ -14,35 +11,9 @@ import { SettingsSearchBar } from '@src/components/Settings/SettingsSearchBar'
import { SettingsSectionsList } from '@src/components/Settings/SettingsSectionsList'
import { SettingsTabs } from '@src/components/Settings/SettingsTabs'
import { useDotDotSlash } from '@src/hooks/useDotDotSlash'
import { isDesktop } from '@src/lib/isDesktop'
import { PATHS } from '@src/lib/paths'
import type { SettingsLevel } from '@src/lib/settings/settingsTypes'
const isTestEnv = window?.localStorage.getItem(IS_PLAYWRIGHT_KEY) === 'true'
export const APP_VERSION =
isTestEnv && NODE_ENV === 'development'
? '11.22.33'
: isDesktop()
? // @ts-ignore
window.electron.packageJson.version
: 'main'
export const PACKAGE_NAME = isDesktop()
? window.electron.packageJson.name
: 'zoo-modeling-app'
export const IS_NIGHTLY = PACKAGE_NAME.indexOf('-nightly') > -1
export const IS_NIGHTLY_OR_DEBUG =
IS_NIGHTLY || APP_VERSION === '0.0.0' || APP_VERSION === '11.22.33'
export function getReleaseUrl(version: string = APP_VERSION) {
return `https://github.com/KittyCAD/modeling-app/releases/tag/${
IS_NIGHTLY ? 'nightly-' : ''
}v${version}`
}
export const Settings = () => {
const navigate = useNavigate()
const [searchParams, setSearchParams] = useSearchParams()

View File

@ -15,7 +15,7 @@ import { Themes, getSystemTheme } from '@src/lib/theme'
import { reportRejection } from '@src/lib/trap'
import { toSync } from '@src/lib/utils'
import { authActor, useSettings } from '@src/machines/appMachine'
import { APP_VERSION } from '@src/routes/Settings'
import { APP_VERSION } from '@src/routes/utils'
const subtleBorder =
'border border-solid border-chalkboard-30 dark:border-chalkboard-80'

29
src/routes/utils.ts Normal file
View File

@ -0,0 +1,29 @@
import { NODE_ENV } from '@src/env'
import { isDesktop } from '@src/lib/isDesktop'
import { IS_PLAYWRIGHT_KEY } from '@e2e/playwright/storageStates'
const isTestEnv = window?.localStorage.getItem(IS_PLAYWRIGHT_KEY) === 'true'
export const APP_VERSION =
isTestEnv && NODE_ENV === 'development'
? '11.22.33'
: isDesktop()
? // @ts-ignore
window.electron.packageJson.version
: 'main'
export const PACKAGE_NAME = isDesktop()
? window.electron.packageJson.name
: 'zoo-modeling-app'
export const IS_NIGHTLY = PACKAGE_NAME.indexOf('-nightly') > -1
export const IS_NIGHTLY_OR_DEBUG =
IS_NIGHTLY || APP_VERSION === '0.0.0' || APP_VERSION === '11.22.33'
export function getReleaseUrl(version: string = APP_VERSION) {
return `https://github.com/KittyCAD/modeling-app/releases/tag/${
IS_NIGHTLY ? 'nightly-' : ''
}v${version}`
}

View File

@ -9446,10 +9446,10 @@ vite-tsconfig-paths@^4.3.2:
globrex "^0.1.2"
tsconfck "^3.0.3"
vite@^5.0.0, vite@^5.4.12:
version "5.4.12"
resolved "https://registry.yarnpkg.com/vite/-/vite-5.4.12.tgz#627d12ff06de3942557dfe8632fd712a12a072c7"
integrity sha512-KwUaKB27TvWwDJr1GjjWthLMATbGEbeWYZIbGZ5qFIsgPP3vWzLu4cVooqhm5/Z2SPDUMjyPVjTztm5tYKwQxA==
vite@^5.0.0, vite@^5.4.16:
version "5.4.16"
resolved "https://registry.yarnpkg.com/vite/-/vite-5.4.16.tgz#471983257a890ef33f2700cbbbc2134f2d08abf1"
integrity sha512-Y5gnfp4NemVfgOTDQAunSD4346fal44L9mszGGY/e+qxsRT5y1sMlS/8tiQ8AFAp+MFgYNSINdfEchJiPm41vQ==
dependencies:
esbuild "^0.21.3"
postcss "^8.4.43"