* Add NodePath to operations
* Change to use nodePath to get pathToNode instead of sourceRange
* Add additional node path unit test
* Update output
* Fix import statement NodePaths
* Update output
* Factor into function
* remove nested <button> elements to avoid dom warning about nested buttons
* keep using Popover.Button to allow popover functionality
* fmt
* match ShareButton margin to main branch to make snapshot tests happy
Previously in a member expression like `foo.x` or `foo[3]`, `foo` had to be an identifier. You could not do something like `f().x` (and if you tried, you got a cryptic error). Rather than make the error better, we should just accept any expression to be the LHS of a member expression (aka its 'object').
This does knock our "parse lots of function calls" from 58 to 55 calls before it stack overflows. But I think it's fine, we'll address this in https://github.com/KittyCAD/modeling-app/pull/6226 when I get back to it.
Closes https://github.com/KittyCAD/modeling-app/issues/7273
* Move import graph to execution
Signed-off-by: Nick Cameron <nrc@ncameron.org>
* Refactor artifact handling
Signed-off-by: Nick Cameron <nrc@ncameron.org>
* Refactor caching to separate global state from per-module state
Signed-off-by: Nick Cameron <nrc@ncameron.org>
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
This brings the `execute_mock` function into line with the `execute` function, which I tweaked in https://github.com/KittyCAD/modeling-app/pull/7351. Now mock execution, like real execution, will always return a properly-formatted KCL error, instead of any possible JS value.
Also, incidentally, I noticed that send_response always succeeds, so I changed it from Result<()> to void.
Specifically this warning:
```
[vite] warning: This case clause will never be evaluated because it duplicates an earlier case clause
| case 'angledLine':
| case 'startProfile':
| case 'arcTo':
| ^
| return fnName
| default:
```
* Fix the black screen of death
* fmt
* make check
* Clean up
* Fix up zoom to fit
* Change how emulateNetworkConditions work
* Do NOT use browser's offline/online mechanisms
* Fix test
* Improve network error messages
* Signal offline when failed event comes in
* Don't use logic on components that only want a loader
* Remove unnecessary pause state transition
---------
Co-authored-by: jacebrowning <jacebrowning@gmail.com>
* fix test
* fix e2e test in another way so it doesnt break unit tests
* Cleanup
* Update src/hooks/useQueryParamEffects.ts
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
* hasAskToOpen should only be used if not in desktop
---------
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
# Symptoms
This code produces a big ugly confusing error in the frontend, see #7340.
# Root cause
I added a new test case, with an unknown type. In `ast.snap` under `body[0].declaration.init.ty` there two different `type` fields in the AST node for the type's name, and they have conflicting values Primitive and Identifier.
<img width="602" alt="Screenshot 2025-06-03 at 4 04 55 PM" src="https://github.com/user-attachments/assets/913a0fa0-3e8d-473f-bb64-003d44915be0" />
# Solution
Change the `enum PrimitiveType` variant from `Named(Node<Identifier>)` to `Named { name: Node<Identifier> }` so that the fields nest differently.
Now the error correctly points out to the user that the type `NotARealType` can't be found. Much better error message that shows the user the problem.
# Alternative solutions
Stop the duplicated JSON fields altogether. I tried this previously in https://github.com/KittyCAD/modeling-app/pull/4369 but it was very involved, and I didn't think it was worth it. Maybe I should reopen that PR and solve this properly.
Closes#7340
I ignored some new clippy lints about large differences between enum variants.
We can always revisit these later (the compiler suggests boxing them so
that the enum variants are similar size)
There's some bug in the frontend or KCL somewhere, which results in the TypeScript frontend sending an AST (serialized to JSON) to the KCL executor, but the JSON cannot be deserialized into an AST. If this happens, it's a bug in ZDS, not a user error.
The problem is that this sort of error will cause the frontend to silently stop rendering KCL, and it won't show the user any errors. They need to open up the console and look at the error there, and even if they do, it's hard to understand.
This PR changes how we report these unexpected errors due to bugs in ZDS. ZDS should not silently stop working, it should at least print a half-decent error like this:
<img width="527" alt="nicer error" src="https://github.com/user-attachments/assets/1bb37a64-0915-4472-849c-d146f397356b" />
## Fix
Right now, the wasm library exports a function `execute`. It previous returned an error as a String if one occurred. The frontend assumed this error string would be JSON that matched the schema `KclErrorWithOutputs`. This was not always true! For example, if something couldn't be serialized to JSON, we'd take the raw Serde error and stringify that. It wouldn't match `KclErrorWithOutputs`.
Now I've changed `execute` so that if it errors, it'll returns a JsValue not a string. So that's one check (can this string be deserialized into a JSON object) that can be removed -- it'll return a JSON object directly now. The next check is "does this JSON object conform to the KclErrorWithOutputs schema". To prove that's correct, I changed `execute` to be a thin wrapper around `fn execute_typed` which returns `Result<ExecOutcome, KclErrorWithOutputs>`. Now we know the error will be the right type.
* Fix orbit style setting not updating in camControls
* Break apart camera movement tests, add trackball to orbit one
* I don't think zoom was actually testing changes, this fixes that
* test refactor: pass in expected cam pos, not its inverse
* Lints
* Lint fix broke the test, fix fix
* Gah biome whyyy did you format other test names like that?
Previously, `x = cos(x)` would just say "`x` is undefined". Now it says that `x` cannot be referenced in its own definition, try using a different variable instead.
To do this, I've added a new `Option<String>` field to the mod-local executor context, tracking the current variable declaration. This means cloning some strings, implying a small performance hit. I think it's fine, for the better diagnostics.
In the future we could refactor this to use a &str or store variable labels in stack-allocated strings like docs.rs/compact_str or something.
Closes https://github.com/KittyCAD/modeling-app/issues/6072
We've changed the unnamed field of `KclError` variants to a named called `details`.
To clarify: previously KCL errors looked like this:
```rust
pub enum KclError {
Lexical(KclErrorDetails),
Syntax(KclErrorDetails),
```
Now they look like this:
```rust
pub enum KclError {
Lexical { details: KclErrorDetails },
Syntax { details: KclErrorDetails },
}
```
This lets us more easily add fields to the errors. For example, in the UndefinedValue case, adding a field for what the undefined name was. This PR refactors the code to make my PR in https://github.com/KittyCAD/modeling-app/pull/7309 much easier.
Pure refactor, should not change any behaviour.
* fix bug of not saving project when dragging a segment, add a test
* Update e2e/playwright/projects.spec.ts
Co-authored-by: Jace Browning <jacebrowning@gmail.com>
---------
Co-authored-by: Jace Browning <jacebrowning@gmail.com>
* Don't use WEAK and yellow
* fmt && lint && tsc
* Fix up the rebase & dark mode colors
* Update src/hooks/useNetworkStatus.tsx
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
* Change Weak to Ok
* Change Connected to Strong
* fmt
* Sync selectors for start sketch
* Remove unused test-util brought back in a rebase
* Align the other OKs
* Add an else statement to overallState
---------
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
This program:
```kcl
1
|> extrude(
length=depth,
})
```
was giving this bad error:
```
unexpected token |>
```
Now it gives
```kcl
There was an unexpected }. Try removing it.
```
and it correctly puts the diagnostic on the extra }.
Fixes https://github.com/KittyCAD/modeling-app/issues/6126
Previously, this KCL
```
arc(
endAbsolute = [0, 50]
interiorAbsolute = [-50, 0]
)
```
gave the error `This argument has a label, but no value. Put some value after the equals sign`.
Now it gives this much better error `Missing comma between arguments, try adding a comma in`, and its source range (red underline) is on the whitespace which was missing a comma:
<img width="666" src="https://github.com/user-attachments/assets/aa5035f5-f748-4dab-b918-b81b05733323" />
Thanks for reporting this @benjamaan476
* first step of UI using trelative angentialArc
* use tangentialArcTo when snapping to one of the axes
* remove duplications via tangentialArcHelpers
* update test: snapToProfile start only works for current profile
* add test: Can add multiple profiles to a sketch (all tool types)
* update test: Straight line snapping to previous tangent
* fixes for removing individual constraints (should keep endAbsolute for lines, tangentialArcs)
* fix fnNameToToolTipFromSegment arcTo
* update snapshot test to use relative tangentialArc
* stabilize some snapshot tests
* stabilize and update Inch snapshot test on ubuntu
* fix tsc
* stabilize and update Millimeter scale snapshot test on ubuntu
* update snapshot for Inch scale test
* Update snapshots
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
* Move some sketch functions to KCL
Signed-off-by: Nick Cameron <nrc@ncameron.org>
* Move asserts to KCL
Signed-off-by: Nick Cameron <nrc@ncameron.org>
* sweep, loft -> KCL
Signed-off-by: Nick Cameron <nrc@ncameron.org>
* Move pattern transforms to KCL
Signed-off-by: Nick Cameron <nrc@ncameron.org>
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
* Fix the black screen of death
* fmt
* make check
* Clean up
* Fix up zoom to fit
* Change how emulateNetworkConditions work
* Do NOT use browser's offline/online mechanisms
* Fix test
* Rename desktop e2e scripts and tags for consistency
* Show local command in main test step
* Restore 'e2e' prefix to clarify GitHub UI
* Add web script to contributor guide
* Replace uses of get_unlabeled_kw_arg with _typed version
Signed-off-by: Nick Cameron <nrc@ncameron.org>
* Remove more untyped arg getters
Signed-off-by: Nick Cameron <nrc@ncameron.org>
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
* Don't error if no `angle` arg is present in revolve, use `360`
KCL uses a default value if the keyword argument isn't present, so the
feature tree edit flow should do the same. In the future these should
flow from the same source of truth so that the feature tree doesn't have
to duplicate default arg values like this.
* Use `360deg` for more definite UoM
* Only consider staight lines for colinear check
* Neaten up code and add test
* Sir, a second sphere has hit the unit test
* Update test snapshots
---------
Co-authored-by: Adam Chalmers <adam.chalmers@zoo.dev>
* fix: implemented a fix to read from settings before restoring camera view and log if it desyncs
* fix: reverting testing code
* fix: always enable ortho scale enabled mode
* fix: fixed the ortho_scale_enabled boolean, do not touch it. Set it to true and never touch it again
Closes https://github.com/KittyCAD/modeling-app/issues/6805. Enables users to programatically construct colors, which will be helpful for
- Applying color to visualize program execution and help debugging
- Doing weird cool shit
In #7179 I added exclusive ranges for KCL, but I forgot to update the
formatter/unparser to handle them. So it was silently changing exclusive-end
ranges to inclusive-end ranges.
* Fix error of not showing errors when reopening KCL code pane
* add test for errors not shown after reopening code pane
* rename test
* typo in e2e/playwright/editor-tests.spec.ts
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
* lint
* fmt
* fix test: Opening and closing the code pane will consistently show error diagnostics
* PR feedback: use catch(reportRejection) for safeParse
* no need for lint rule
---------
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
Our team started getting *rate limited* with access to the font, which
meant the app wasn't loading for them 😱. I don't want us to risk any
user being rate limited because of a font ever.
@JBEmbedded pointed this out, and we don't want a bad look for website
browsers who click a stray "Try in Browser" link. There's a little
message saying we're working on touch controls for now, and we steal
their signin button.
KCL's `fillet` function takes an array of edges to fillet. Previously this would do `n` fillet API commands, one per edge. This PR combines them all into one call, which should improve performance. You can see the effect in the artifact_commands snapshots, e.g. `rust/kcl-lib/tests/kcl_samples/axial-fan/artifact_commands.snap`
Besides performance, this should fix a bug where some KCL fillets would fail, when they should have succeeded. Example from @max-mrgrsk:
```kcl
sketch001 = startSketchOn(XY)
|> startProfile(at = [-12, -6])
|> line(end = [0, 12], tag = $seg04)
|> line(end = [24, 0], tag = $seg03)
|> line(end = [0, -12], tag = $seg02)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)], tag = $seg01)
|> close()
extrude001 = extrude(
sketch001,
length = 12,
tagEnd = $capEnd001,
tagStart = $capStart001,
)
|> fillet(
radius = 5,
tags = [
getCommonEdge(faces = [seg02, capEnd001]),
getCommonEdge(faces = [seg01, capEnd001]),
getCommonEdge(faces = [seg03, capEnd001]),
getCommonEdge(faces = [seg04, capEnd001])
],
)
```
This program fails on main, but succeeds on this branch.
Previously KCL bezier curves could only use relative control points. Now you can use absolute control points too.
Here's an example of the new arguments:
```kcl
startSketchOn(XY)
|> startProfile(at = [300, 300])
|> bezierCurve(control1Absolute = [600, 300], control2Absolute = [-300, -100], endAbsolute = [600, 300])
|> close()
|> extrude(length = 10)
```
Closes https://github.com/KittyCAD/modeling-app/issues/7083
Closes#5792. I tried to move these over to our new component test
bucket, but Remark doesn't play nice with that testing setup at least in
my initial attempts.
In #7156, I allowed KCL to set specific snippet completions for each arg of each function. They're optional -- if you don't set one, it'll fall back to the type-driven defaults.
That PR only worked for KCL stdlib functions defined in Rust. This PR enables the same feature, but for functions defined in KCL.
Before, the LSP snippet for `startProfile` was
```
startProfile(%, at = [3.14, 3.14])
```
Now it's
```
startProfile(%, at = [0, 0])
```
This is configured by adding a `snippet_value=` field to the stdlib macro. For example:
```diff
#[stdlib {
name = "startProfile",
keywords = true,
unlabeled_first = true,
args = {
sketch_surface = { docs = "What to start the profile on" },
- at = { docs = "Where to start the profile. An absolute point." },
+ at = { docs = "Where to start the profile. An absolute point.", snippet_value = "[0, 0]" }, tag = { docs = "Tag this first starting point" },
},
tags = ["sketch"]
}]
```
## Work for follow-up PRs
- Make this work for KCL functions defined in KCL, e.g. [`fn circle`](36c8ad439d/rust/kcl-lib/std/sketch.kcl (L31-L32)) -- something like `@(snippet_value = "[0, 0]")` perhaps
- Go through the stdlib and change defaults where appropriate
* Update telemetry antenna entity names
Changed the generic sketch and profile entity names to more specific names
* Update kcl-samples simulation test output
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
* Pass the query parameters through to sign-in flow
So users can return to their invoked command after signing in
* Don't run query param commands if not logged in
* Turn sketch exit execute into actor, no more racey exits
* Turn sketch exit execute into actor, no more racey exits
* Fix types
---------
Co-authored-by: Frank Noirot <frank@zoo.dev>
* fix: saving off code
* fix: saving off progress
* chore: implemented kcl sample assembly unique sub dir creation
* fix: removing testing console logs
* fix: cleaning up old comment
* fix: add to file always does subdir/main.kcl now for single files
* fix: auto fmt
* fix: delete project and folder from ttc
* fix: fixed deleting projects and subdirs
* fix: if statement logic fixed for deleting project or subdir
* fix: TTC isProjectNew makes main.kcl not a subdir.
* fix: fixing e2e test
* fix: this should pass now
* pierremtb/make-insert-take-over-the-import-world
* Add test that doesn't work locally yet :(
* Fix test 🤦
* Change splice for push
* Fix up windows path
---------
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Kevin Nadro <nadr0@users.noreply.github.com>
* fix: saving off code
* fix: saving off progress
* chore: implemented kcl sample assembly unique sub dir creation
* fix: removing testing console logs
* fix: cleaning up old comment
* fix: add to file always does subdir/main.kcl now for single files
* fix: auto fmt
* fix: delete project and folder from ttc
* fix: fixed deleting projects and subdirs
* fix: if statement logic fixed for deleting project or subdir
* fix: TTC isProjectNew makes main.kcl not a subdir.
* fix: fixing e2e test
* fix: this should pass now
* Revert "Update failing E2E tests with new behavior, which allows skip with preselection"
This reverts commit d72bee8637.
* Fix: Can't go back to Profiles step in sweep commands
Fixes#7080
* Make it better but still not quite there
* I think I got it: this was likely the real bug making submit fire twice
* Bring timemouts back
Paul's been requesting this for a long time. Now that we're fully using keyword args, this is easy to do.
We should probably add a similar `diameter` arg to `arc`, `tangentialArc`, `polygon` etc. And _maybe_ to `fillet`, but that might not be as helpful.
* Remove old ZMA logos, rip out JS theme state from open-in-desktop view
Make this page dumber so that it doesn't break
* Lint and remove kcma refs
---------
Co-authored-by: Pierre Jacquier <pierre@zoo.dev>
* successfully transition to sketch idle
* get constraint to mod code
* clean up
* remove .only
* Fixed tsc
---------
Co-authored-by: lee-at-zoo-corp <lee@zoo.dev>
* use effect for focus of command palette submit button, not autoFocus
autoFocus is being overridden by the Headless UI Dialog component's
focus management here
https://headlessui.com/v1/react/dialog#focus-management (we do not have
access to pass back initialFocus in this case). So we can use an effect
to imperatively focus the button when this component is mounted.
* Update sweep tests to submit the command with Enter
* Style the experimental badge to match the website
* Match the styling of the rest of the app
We don't use all apps monospace fonts anywhere.
* Bring back all caps
We have a hook to auto-grow the textarea input but it wasn't running
once initially. This is noticable on the onboarding, where we show the
user a long Text-to-CAD Edit prompt that overflows.
We want users to make edits first and foremost within projects, so we're
going to surface it as the default workflow button in the toolbar. WIP
until I verify that tests are okay with this.
* Declare pattern transform using KCL
Signed-off-by: Nick Cameron <nrc@ncameron.org>
* Boolean function param defaults
Signed-off-by: Nick Cameron <nrc@ncameron.org>
* Parse empty record types in fn types
Signed-off-by: Nick Cameron <nrc@ncameron.org>
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Give a default value to projectName
This argument is hidden since it's marked as skip, so browser users who
must now invoke the command through the command palette have no way of
setting the value. Since it is also required, the command palette fails
silently on submission (which we need to fix more broadly). This gives
it a default value so that users can submit properly.
* Add backtrace to errors
* Add display of backtraces with hints
* Change pane badge to only show count of errors
* Fix property name to not collide with Error superclass
* Increase min stack again
* Add e2e test that checks that the diagnostics are created in CodeMirror
* Remove unneeded code
* Change to the new hotness
* Submit selection to command on unmount of selection arg input
This fixes#7024 by saving the user's selection to the command even if
they click another argument in the command palette's header. It does no
harm to save the selection to the argument, even if it's being torn down
because the user dismissed it has no negative effect.
* Refactor to not auto-submit before selection is cleared on mount
Thanks E2E test suite
* Update failing E2E tests with new behavior, which allows skip with preselection
---------
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
* Disallow segment selection in sweep, plus displayName: Profiles for clarity
Fixes#7044
* Change selection hints for solid2d to be profile instead of face
* Update tests
* More fixes
* Fix tests following behavior change: we don't select segments in code anymore but profiles
* Shuffle around function call code
Signed-off-by: Nick Cameron <nrc@ncameron.org>
* Refactor function calls to share more code
Signed-off-by: Nick Cameron <nrc@ncameron.org>
* Hack to leave the result of revolve as a singleton rather than array
Signed-off-by: Nick Cameron <nrc@ncameron.org>
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
* Remove Create with Text-to-CAD from the toolbar
* Remove "prompt-to-edit" wording, call commands "create" and "edit"
* Use sparkles for the ML feature, not chat
* lints
* Start fixing up tests, there are probably more though
* Fix up a few more tests
* Fix up prompt-to-edit tests (yay using fixtures!)
* Fix native file menu tests
* Update snapshots
* Fix menu test
* Fix snaps
---------
Co-authored-by: Pierre Jacquier <pierre@zoo.dev>
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
* Make warning toast not appear if the URL has any search params
This should avoid the scenario where someone clicks an "open sample"
type link and dismisses the command palette before they can finish what
they're doing.
* Update src/App.tsx
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
---------
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
* fix: when creating a t2c in a new project make the file name main.kcl
* fix: when creating a sample in a new project and there is only 1 file make the filename main.kcl
* fix: auto fixes
* fix: share links generate main.kcl
* fix: codespell typoe
* fix: fixing E2E tests
* Fix 3 more tests
* fix: share url link e2e file name fix
---------
Co-authored-by: Pierre Jacquier <pierre@zoo.dev>
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
Co-authored-by: Frank Noirot <frank@zoo.dev>
* Improve url sharing for orgs and pros
* Remove sharing via menu item
* fmt
* Not sure what's different but it is
* fmt & lint
* whoops
* Update snapshots
* Typos from codespell
* Fix alignment
* Update snapshots
* Prune
---------
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
Co-authored-by: Pierre Jacquier <pierre@zoo.dev>
* Make "skip = false" non-required args appear in header
* Make non-required, unskippable selection args work
* Make prompt-to-edit's selection arg optional but non-skippable
* Update src/components/CommandBar/CommandBarSelectionInput.tsx
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
* Fix dumb logic bug
Thanks for user testing @Irev-dev
* Update mixed input to show selection
Feel free to revert @Irev-Dev if this is the wrong move, but I found it
odd that this component doesn't show the current selection in the text
like the other selection input does, so I copied that over.
* Merge branch 'main' into franknoirot/adhoc/optional-selection-args
* Merge branch 'main' into franknoirot/adhoc/optional-selection-args
* Merge remote-tracking branch 'origin' into franknoirot/adhoc/optional-selection-args
* fix tests
* change copy again
* Update src/components/CommandBar/CommandBarSelectionMixedInput.tsx
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
* Remove tan warning from ml commands, move to experimental green branding
* Oops
* Removed unused var
---------
Co-authored-by: Frank Noirot <frankjohnson1993@gmail.com>
1. Remove all `waitFor` hidden states for the post-dismiss toast:
something about Playwright is making toasts hang in a way I've never
seen in real use. Not something I'm worried about, and we still test
that the toast fires the first time we dismiss.
2. Remove all `scene.connectionEstablished()` calls. This has me more
worried because some of the flakiness on this front seems like we're not
able to handle the rapid machine-speed navigation and overwriting that
this test does when it doesn't have to `waitFor` toasts to disappear.
But that is not the point of this test, which is just to ensure the
onboarding plays correctly and initiates correctly.
* Fix to add NodePaths to SketchOnFace and SketchOnPlane artifacts
* Fix to only compute the new part of the artifact graph
* Change to early-return sooner when in mock mode
* Add another test
* Fix to propagate NodePath for sketch on face
* Update output
* Helix can't be selected as path arg in point-and-click sweep
Fixes#6966
* Remove old dry-run validations on Sweep, Loft, Revolve, and Shell
* Base on dry-run validation remove branch
* Add test
* handle Plane in get_autocomplete_snippet to fix missing default plane value for offsetPlane
* adds test for offsetPlane default plane value
* cleanup test
* use XY instead of XZ for default plane
* add rust test for offsetplane autocomplete
* remove playwright test for offestPlane, as it has rust test now and there are autocomplete tests already
* First pass at consistency in modelingMachine codemods
* Add 'no kcl errors' guard instead of if check for all the existing ones
* Add more commands and improve consistency
* Add comments
* Fix test with old kcl that was showcasing the very behavior we're trying to fix
https://kittycadworkspace.slack.com/archives/C07A80B83FS/p1747231832870739?thread_ts=1747231178.515289&cid=C07A80B83FS
* Add test for sketch and helix
* Remove guard use and move hasErrors check closer to updateAst calls
* Revert "Remove guard use and move hasErrors check closer to updateAst calls"
This reverts commit 868ea4b605.
* Remove toasts from guards
* Remove some scene.settled calls
* Lint
* More shaky fixes
* Clean up and more test fixes
---------
Co-authored-by: Frank Noirot <frankjohnson1993@gmail.com>
* Add a Stop command that does a bit of cleanup in the engineStateMachine
* Major network code startup refactor; backoff reconnect; many more logs for us
* Save camera state after every user interaction in case of disconnection and restoral
* Translate basic WebSocket error numbers into useful text
* Add a RestartRequest event to the engineCommandManager
* Adjust for a rebase
* Add E2E test for stream pause behavior
* Fix snapshot test
* fmt, lint
* small issue
* Fix tests
* Fix up idle test
* One last fix
* fixes
* Remove circ dep
* fix test
* use a const for time
* TEST -> isPlaywright instead
* whoops
* fix: symbol replace text box dark mode contrast (#6827)
* fix: symbol replace text box dark mode contrast (#6827)
* correct fix for rename popup white text on white background #6827
* correct fix for rename popup white text on white background #6827
* added comments explaining the change
---------
Co-authored-by: rajgandhi1 <rajgandhi9952@gmail.com>
* Make the Reset View button do the same view_isometric behavior as load
Just copying some logic from the EngineStream code to make that button
behave the same way: old initial camera position while in Playwright,
isometric view for normal users.
* Move duplicate code into shared `resetCameraPosition` function
* Fix lints
* Keep test toast messages around for longer
* Check for at least two locators
I wasn't able to reproduce, but it's possible one stuck around from a previous test.
* Fix "include settings" setting to have an effect
I'm not sold on if we should have this setting, but this fixes it for
now. The issue is was that the new callback actor approach was using a
stale version of the settings every time it received an "update" event:
JS closure problems. Now it receives the new settings as an event
payload.
* Update src/machines/settingsMachine.ts
---------
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
* Restore the native file menu tests
* fix: saving off progress
* chore: making progress cleaning up these verbose tests and improving app logic for e2e
* chore: rewriting tests
* fix: reworking application logic for file menu in the scene and e2e scene file menu test
* chore: updating more e2e tests
* fix: updated all the tests, auto fixers
* fix: trying to improve tests within E2E, they aren't failing locally even with --repeat-each=10
* fix: application logic has a bug that you can navigate instantly but the scroll to view code will not trigger which breaks end to end tests
* fix: improving E2E tests
* fix: fixing clipboard typo
* fix: porting test() for each native file menu to a test.step to speed it up
* fix: auto fixes and console log helper function for playwright runtimes
* fix: more cleanup
* fix: trying to fix these...
* fix: got the tests working
* fix: addressing PR comments
* fix: trying to stablize the tests
* fix: auto fixes
* fix: trying to make it the command name and not arg? could be a source of race condition if the input is not written fast enough?
* fix: maybe because this close locator was running too quickly?
* fix: panic timeout, classic
* fix: these are gone
* fix: shorter waits
---------
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Kevin Nadro <nadr0@users.noreply.github.com>
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
* Display NodePath in artifact graph mermaid charts
* Update output
* Change node path display to be only comments
* Update output
* Update output after rebase
Avoid using revolve for now
When we moved to concurrent execution of KCL modules, we begun to see an
error we never fully understood, and because it was pretty hard to
trigger, we wound up never being able to fix it. Today we were able to
track it down to the `revolve` call here.
Specifically, the problem is triggered when we're doing a "Full Revolve"
(e.g., `angle = 359.999999` passes, but *not* `angle = 360` or the
default, as it is in `main`), and concurrently executing modules will
see something weird happen with `getNextAdjacentEdge`.
From all the smoke I believe this happens only when we are doing a *full
revolve*, *AND* we're executing other modules which are calling
`getNextAdjacentEdge`.
When the `revolve` is present, we can lose the race in *either*
`talk-button.kcl` OR `case.kcl`.
If I move back to single-threaded execution OR I add imports to sequence
things carefully, I can get the tests to pass. If the revolve is an
`extrude` or not a full revolve, it works fine.
My best guess is that it seems like the world got flipped upside down or
something, such that "next edge" has a different orentation for two
calls. My even further guess is that inside `revolve` we mutate
something connection-global such that it alters the intepretation of
calls made during the revolve implementation's "critical section".
* Give example info for failing std example tests
Signed-off-by: Nick Cameron <nrc@ncameron.org>
* Shard example tests into 10
Signed-off-by: Nick Cameron <nrc@ncameron.org>
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
* fix: clear scene and bust cache if rust panics
* Update onboarding following @jgomez720
* chore: hopefully made a safe navigate to kcl file to call executeAST without a race condition
* chore: hopefully made a safe navigate to kcl file to call executeAST without a race condition
* fix: clean up
* fix: FUCK
* fix: FUCK 2.0
* fix: oh boi
* fix: oh boi
* fix: idk man
* updates
Signed-off-by: Jess Frazelle <github@jessfraz.com>
* fix: take main on this, do not need a single line from my testing code
* fix: more PR cleanup from all of the testing code
* fix: trying to clean up more, ope this has a lot of other code
* fix: PR clean up
* fix: trying to get a clean branch, I had multiple other branches in here ope
* fix: more cleanup
* fix: another one
* fix: fixed the comment to be accurate
* fix: removed confusing comment
---------
Signed-off-by: Jess Frazelle <github@jessfraz.com>
Co-authored-by: Frank Noirot <frankjohnson1993@gmail.com>
Co-authored-by: Jess Frazelle <github@jessfraz.com>
Only include the file pane on desktop. This should encourage users to
try point-and-click and feature tree workflows. After #6629 is
completed, we should default to the code pane being closed.
* Change Fn to fn for function types
Signed-off-by: Nick Cameron <nrc@ncameron.org>
* Support args and return types in function types
Signed-off-by: Nick Cameron <nrc@ncameron.org>
* Use fancy function types in the docs
Signed-off-by: Nick Cameron <nrc@ncameron.org>
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
* Allow adding and removing commands from any command bar state
* Allow commands to be configured disabled in the combobox
* Set up modeling commands to toggle `disabled` based on network status, instead of filtering
* Fix tsc
**Problem:**
KCL's xLine and yLine functions were telling users to supply either "end" or "endAbsolute" arguments. But "end" is not a valid argument for xLine/yLine, it's actually "length" instead.
**Cause:**
xLine/yLine were using a helper function designed for `line` KCL stdlib functions, which do use `end`.
**Solution**
Add a new param to the helper function, indicating what the label should be for relative lines. "end" for `line` calls, `length` for x/yline
* Move the leg functions to KCL
Signed-off-by: Nick Cameron <nrc@ncameron.org>
* Move array functions to KCL
Signed-off-by: Nick Cameron <nrc@ncameron.org>
* Move clone to KCL
Signed-off-by: Nick Cameron <nrc@ncameron.org>
* Add a function type
Signed-off-by: Nick Cameron <nrc@ncameron.org>
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
* fix going into rename mode for files with parents
* lastDirectoryClicked is not used
* fix file/folder rename bugs: renaming within folders
* Turn form into div to fix issue of child renaming continues into renaming the parent folder when hitting enter
* ContextMenu stopPropagation not needed anymore, maybe because of form refactor
* ContextMenu IS needed actually, with multiple nested folders
* make lint happy
* Update src/components/ContextMenu.tsx
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
* re-add <form> instead of <div> for file renaming
---------
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
* pierremtb/adhoc/clean-up-nightly-on-merge
* To revert: test to upload builds at test/nightly
* Remove + suffix trim that's not needed anymore
* Revert "To revert: test to upload builds at test/nightly"
This reverts commit b0549d426f.
* Fix bug with `undo startSketchOn` removing existing sketch
Fixes#6822, I believe. in this case the `variableName` was not being
marked as in-use, so I just logged out the AST and made sure this case
was covered. @Irev-Dev this is probably worth a check from you.
* Add a regression test
It's an E2E test because I'm being lazy, but it should probably be an
XState unit test at some point.
* check what's checked
---------
Co-authored-by: Kurt Hutten <k.hutten@protonmail.ch>
* Treat number as any rather than default
Signed-off-by: Nick Cameron <nrc@ncameron.org>
* Don't square root negative numbers
Signed-off-by: Nick Cameron <nrc@ncameron.org>
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
* Add sim test for any type
* Fix doc comments to match code
* Add array ascription tests
* Commit new test output
* Fix to not panic when type is undefined
* Fix to not panic on use of the any type
* Update test and generated output
* Fix error message after rebase
* Fix subtype of any
* Fix KCL to use new keyword args
* Fix to not nest MixedArray in HomArray
* Update output
* Remove all creation of MixedArray and use HomArray instead
* Rename MixedArray to Tuple
* Fix to coerce arrays the way tuples are done
* Restructure to appease the type signature extraction
* Fix TS unit test
* Update output after switch to HomArray
* Update docs
* Fix to remove edge case when creating points
* Update docs with broken point signature
* Fix display of tuples to not collide with arrays
* Change push to an array with type mismatch to be an error
* Add sim test for push type error
* Fix acription to more general array element type
* Fix to coerce point types
* Change array push to not error when item type differs
* Fix coercion tests
* Change to only flatten as a last resort and remove flattening tuples
* Contort code to appease doc generation
* Update docs
* Fix coerce axes
* Fix flattening test to test arrays instead of tuples
* Remove special subtype case for singleton coercion
* Document the units of PI
Signed-off-by: Nick Cameron <nrc@ncameron.org>
* Add links between lang and std references
Signed-off-by: Nick Cameron <nrc@ncameron.org>
* Change signature of conversion functions
Signed-off-by: Nick Cameron <nrc@ncameron.org>
* Split foreign imports out of modules docs
Signed-off-by: Nick Cameron <nrc@ncameron.org>
* More docs for Plane
Signed-off-by: Nick Cameron <nrc@ncameron.org>
* Update docs/kcl-std/consts/std-math-PI.md
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
* Update rust/kcl-lib/std/math.kcl
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: Jess Frazelle <jessfraz@users.noreply.github.com>
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
* Add documentation to modules, and some constants and types
Signed-off-by: Nick Cameron <nrc@ncameron.org>
* Improve the language reference
Signed-off-by: Nick Cameron <nrc@ncameron.org>
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
* Hide "Allow orbit in sketch mode" setting from the app
The ability to orbit while in sketch mode is not well-tested or
well-used, so we should pull it from the app. The easiest way to do that
is leave the setting in the WASM definition, but configure the setting
to be uneditable from the interface.
* pierremtb/adhoc/force-idle-stream-and-hide
---------
Co-authored-by: Frank Noirot <frankjohnson1993@gmail.com>
Co-authored-by: Frank Noirot <frank@zoo.dev>
* oops, make it nicer for no reason
* tests
* deleteTopLevelStatement
* little swap
* astMod edits
* typos
* add playwright test for chamfers
* scene.settled instead of page.waitForTimeout
* unfuck circular dep - move locateExtrudeDeclarator
* locateExtrudeDeclarator > locateVariableWithCallOrPipe
* fmt
* edit the comment
* constrain profile start
* add test
* make sure it works on segment drag too, fix tests
* remove old log
* some tests fixes
* Bump more segment counters
* Two more fixes
* Two more test fixes
* small test fix
* moretest fixes
* another test
---------
Co-authored-by: Pierre Jacquier <pierrejacquier39@gmail.com>
Co-authored-by: Pierre Jacquier <pierre@zoo.dev>
The ability to orbit while in sketch mode is not well-tested or
well-used, so we should pull it from the app. The easiest way to do that
is leave the setting in the WASM definition, but configure the setting
to be uneditable from the interface.
* Remove gnarly fake union hotkeys
* Enable hotkey for items buried in ActionButtonDropdown
I'm kinda over `useHotkeys` as a hook
* Add hotkeys for other sketch tools
* Fix lint and tsc
* Fix duplicate locator
* The circular dependecies got reordered somehow
* Update src/lib/toolbar.ts
* Add `cursor-not-allowed` to onboarding backdrops that block clicks
Some follow-up feedback after #6714 from @jacebrowning, so that users
know why they can't click around.
* Make anything in the onboarding card `cursor-auto`
* Remove snapshottoken
Fixes#6800
* Add placeholder in .env.development
* Clean up language
* Update CONTRIBUTING.md
Co-authored-by: Jace Browning <jacebrowning@gmail.com>
* Add dotenv to secrets for local testing
* Lint
* Reorg things
* Quick fix
* Last one for windows
---------
Co-authored-by: Jace Browning <jacebrowning@gmail.com>
* Remove unused `telemetryLoader`
* Remove onboarding redirect behavior
* Allow subRoute to be passed to navigateToProject
* Replace warning dialog routes with toasts
* Wire up new utilities and toasts to UI components
* Add home sidebar buttons for tutorial flow
* Rename menu item
* Add flex-1 so home-layout fills available space
* Remove onboarding avatar tests, they are becoming irrelevant
* Consolidate onboarding tests to one longer one
and update it to not use pixel color checks, and use fixtures.
* Shorten warning toast button text
* tsc, lint, and circular deps
* Update circular dep file
* Fix mistakes made in circular update tweaking
* One more dumb created circular dep
* Update src/routes/Onboarding/utils.tsx
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
* Fix narrow screen home layout breaking
* fix: kevin, navigation routes fixed
* fix: filename parsing is correct now for onboarding with the last file sep
* Fix e2e test state checks that are diff on Linux
* Create onboarding project entirely through systemIOMachine
* Fix Windows path construction
* Make utility to verify a string is an onboarding value
* Little biome formatting suggestion fix
* Units onboarding step was not using OnboardingButtons
* Add type checking of next and previous status, fix useNextClick
* Update `OnboardingStatus` type on WASM side
* Make onboarding different on browser and web, placeholder component
* Show proof of concept with custom content per route
* Make text type args not insta dismiss when you click anywhere
* Make some utility hooks for the onboarding
* Update requestedProjectName along with requestedProjectName
* Build out a rough draft of desktop onboarding
* Remove unused onboarding route files
* Build out rough draft of browser onboarding content
* @jgomez720 browser flow feedback
* @jgomez420 desktop feedback
* tsc and lints
* Tweaks
* Import is dead, long live Add files
* What's up with my inability to type "highlight"?
* Codespell and String casting
* Update browser sample to be axial fan
* lint and tsc
* codespell again
* Remove unused nightmare function `useDemoCode`
* Add a few unit tests
* Update desktop to use bulk file creation from #6747
* Oops overwrote main.kcl on the modify with text-to-cad step
* Undo the dumb use of `sep` that I introduced
* Fix up project test
which was fragile to the number of steps in the onboarding smh
* Fix up onboarding flow test
* typo
---------
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
* fix: how?
* fix: 0 byte thumbnail png loading bug
* fix: adding navigate to single file back
* fix: cargo fmt
* fix: sorting files to match manifest and unit test
* fix: restoring back to main
* fix: cargo fmt
* fix: ope, I forgot I deleted some code that renamed single files to the samples name to track easier within the file tree
* fix: ope
* Update src/lib/commandBarConfigs/applicationCommandConfig.ts
Co-authored-by: Frank Noirot <frank@zoo.dev>
* fix: unique name for project, ope
* fix: filtered samples for web and skeleton create a sample command
* fix: Create A Sample specifically desktop home page instead of overloading the add to file
* fix: hiding source
* fix: gotcha on add to file with existing project default args and assemblies
---------
Co-authored-by: Frank Noirot <frank@zoo.dev>
* Change array functions to call user function with keyword args
* Fix KCL to use keyword params
* Remove unneeded positional call code
* Update docs
* Update output
* Fix trackball camera by weaving through EngineStream
Fixes#6472. Just a missing setting moved in #5312, which wasn't caught
because testing that the orbit maneuver is actually performing a
"trackball-like" movement is nonexistent. I don't know how to test that
reliably, but typing this object provides the red squiggles to reveal
the missing property.
* Update src/components/EngineStream.tsx
---------
Co-authored-by: Kurt Hutten <k.hutten@protonmail.ch>
Breaking changes:
- Fully removed positional arguments from function calls. Keyword arguments are now the only way to call a function.
Added:
- Warn on usage of the unknown numeric suffix (#6690)
Fixed:
- Fix units bug with involuteCircular (#6711)
- Importing 3D files on Windows (#6697)
* Fix various docs errors around std module
Signed-off-by: Nick Cameron <nrc@ncameron.org>
* remove KCL from lang docs titles and move settings docs
Signed-off-by: Nick Cameron <nrc@ncameron.org>
* Include functions declared in Rust in module docs
Signed-off-by: Nick Cameron <nrc@ncameron.org>
---------
Signed-off-by: Nick Cameron <nrc@ncameron.org>
* start of migrate to multi file endpoint
* get some relative path stuff sorted
* blobifying files, and making selections work with imports working
* add write to disk
* warn about big projects
* update known circular
* update snapshot
* remove log
* tweak selection filters
* Update src/components/ModelingMachineProvider.tsx
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
* fmt
* fix one thing
* typo
* raw dog form data like a fucking peasant
* remove fake data
* fmt
* steal Kevin's stuff
* good progress
* clean up
* fix writing to files when response returns
* comment the terriable code
* push fix of sorts
* better fix
* spot of clean up
* fix: Needed to support the bad request flow, the toast will hang forever, the return control flows don't dismiss a forever toast
* fix: handling more error flows by dismissing the toast
* chore: leaving a comment for a confusing workflow
* fix: trying to clean up some async logic
* fix: trying to fix a few things at once...
* fix: fixing toast success
* fix: how did this desync?
* fix: removing useless logic, we write to disk ahead of time, the continue is to say ya no problem
* fix: typo
* Change back to `spawnChild`, forego `actors` by reference
* fix: updating PR comments
* fix: found a bug with paths from rust! it is actually OS paths!
* fix: updated type still is failing tsc
* fix: the type of the machine was wrong, we always set it to at least ''
* fix: idk man
* Fix happy path test (button labels)
---------
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
Co-authored-by: Kevin Nadro <kevin@zoo.dev>
Co-authored-by: Frank Noirot <frankjohnson1993@gmail.com>
Co-authored-by: Kevin Nadro <nadr0@users.noreply.github.com>
Co-authored-by: Pierre Jacquier <pierre@zoo.dev>
* put xy back into default plane feature tree
* color code
* Update src/components/ModelingSidebar/ModelingPanes/FeatureTreePane.tsx
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
---------
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
const message = '`public/kcl-samples/bracket/main.kcl` or `src/lib/exampleKcl.ts` has been updated in this PR, please review and update the `src/routes/onboarding`, if needed.';
Install a node version manager such as [fnm](https://github.com/Schniz/fnm?tab=readme-ov-#installation).
@ -31,7 +31,9 @@ npm run install:rust:windows
npm run install:wasm-pack:cargo
```
Then to build the WASM layer, run:
## Building the app
To build the WASM layer, run:
```
# macOS/Linux
@ -63,7 +65,7 @@ If you're not a Zoo employee you won't be able to access the dev environment, yo
### Development environment variables
The Copilot LSP plugin in the editor requires a Zoo API token to run. In production, we authenticate this with a token via cookie in the browser and device auth token in the desktop environment, but this token is inaccessible in the dev browser version because the cookie is considered "cross-site" (from `localhost` to `dev.zoo.dev`). There is an optional environment variable called `VITE_KC_DEV_TOKEN` that you can populate with a dev token in a `.env.development.local` file to not check it into Git, which will use that token instead of other methods for the LSP service.
The Copilot LSP plugin in the editor requires a Zoo API token to run. In production, we authenticate this with a token via cookie in the browser and device auth token in the desktop environment, but this token is inaccessible in the dev browser version because the cookie is considered "cross-site" (from `localhost` to `zoo.dev`). There is an optional environment variable called `VITE_KC_DEV_TOKEN` that you can populate with a dev token in a `.env.development.local` file to not check it into Git, which will use that token instead of other methods for the LSP service.
### Developing in Chrome
@ -74,7 +76,7 @@ enable third-party cookies. You can enable third-party cookies by clicking on
the eye with a slash through it in the URL bar, and clicking on "Enable
Third-Party Cookies".
## Desktop
### Developing with Electron
To spin up the desktop app, `npm install` and `npm run build:wasm` need to have been done before hand then:
@ -88,129 +90,17 @@ Devtools can be opened with the usual Command-Option-I (macOS) or Ctrl-Shift-I (
To package the app for your platform with electron-builder, run `npm run tronb:package:dev` (or `npm run tronb:package:prod` to point to the .env.production variables).
## Checking out commits / Bisecting
Which commands from setup are one off vs. need to be run every time?
The following will need to be run when checking out a new commit and guarantees the build is not stale:
```bash
npm install
npm run build:wasm
npm start
```
## Before submitting a PR
Before you submit a contribution PR to this repo, please ensure that:
- There is a corresponding issue for the changes you want to make, so that discussion of approach can be had before work begins.
- You have separated out refactoring commits from feature commits as much as possible
- You have run all of the following commands locally:
-`npm run fmt`
-`npm run tsc`
-`npm run test`
- Here they are all together: `npm run fmt && npm run tsc && npm run test`
## Release a new version
#### 1. Create a 'Cut release $VERSION' issue
It will be used to document changelog discussions and release testing.
Create a new tag and push it to the repo. The `semantic-release.sh` script will automatically bump the minor part, which we use the most. For instance going from `v0.27.0` to `v0.28.0`.
```
VERSION=$(./scripts/semantic-release.sh)
git tag $VERSION
git push origin --tags
```
This will trigger the `build-apps` workflow, set the version, build & sign the apps, and generate release files as well as updater-test artifacts.
The workflow should be listed right away [in this list](https://github.com/KittyCAD/modeling-app/actions/workflows/build-apps.yml?query=event%3Apush)).
#### 3. Manually test artifacts
##### Release builds
The release builds can be found under the `out-{arch}-{platform}` zip files, at the very bottom of the `build-apps` summary page for the workflow (triggered by the tag in 2.).
Manually test against this [list](https://github.com/KittyCAD/modeling-app/issues/3588) across Windows, MacOS, Linux and posting results as comments in the issue.
##### Updater-test builds
The other `build-apps` output in the release `build-apps` workflow (triggered by 2.) is `updater-test-{arch}-{platform}`. It's a semi-automated process: for macOS, Windows, and Linux, download the corresponding updater-test artifact file, install the app, run it, expect an updater prompt to a dummy v0.255.255, install it and check that the app comes back at that version.
The only difference with these builds is that they point to a different update location on the release bucket, with this dummy v0.255.255 always available. This helps ensuring that the version we release will be able to update to the next one available.
If the prompt doesn't show up, start the app in command line to grab the electron-updater logs. This is likely an issue with the current build that needs addressing (or the updater-test location in the storage bucket).
Head over to https://github.com/KittyCAD/modeling-app/releases/new, pick the newly created tag and type it in the _Release title_ field as well.
Hit _Generate release notes_ as a starting point to discuss the changelog in the issue. Once done, make sure _Set as the latest release_ is checked, and hit _Publish release_.
A new `publish-apps-release` will kick in and you should be able to find it [here](https://github.com/KittyCAD/modeling-app/actions?query=event%3Arelease). On success, the files will be uploaded to the public bucket as well as to the GitHub release, and the announcement on Discord will be sent.
#### 5. Close the issue
If everything is well and the release is out to the public, the issue tracking the release shall be closed.
You will need a `./e2e/playwright/playwright-secrets.env` file:
Prepare these system dependencies:
```bash
$ touch ./e2e/playwright/playwright-secrets.env
$ cat ./e2e/playwright/playwright-secrets.env
token=<dev.zoo.dev/account/api-tokens>
snapshottoken=<zoo.dev/account/api-tokens>
```
or use `export` to set the environment variables `token` and `snapshottoken`.
- Set $token from https://zoo.dev/account/api-tokens
#### Snapshot tests (Google Chrome on Ubuntu only)
Only Ubunu and Google Chrome is supported for the set of tests evaluating screenshot snapshots.
Only Ubuntu and Google Chrome is supported for the set of tests evaluating screenshot snapshots.
If you don't run Ubuntu locally or in a VM, you may use a GitHub Codespace.
```
npm run playwright -- install chrome
@ -218,14 +108,21 @@ npm run test:snapshots
```
You may use `-- --update-snapshots` as needed.
#### Electron flow tests (Chromium on Ubuntu, macOS, Windows)
#### Desktop tests (Electron on all platforms)
```
npm run playwright -- install chromium
npm run test:playwright:electron:local
npm run test:e2e:desktop:local
```
You may use `-- -g "my test"` to match specific test titles, or `-- path/to/file.spec.ts` for a test file.
#### Web tests (Google Chrome on all platforms)
```
npm run test:e2e:web
```
#### Debugger
However, if you want a debugger I recommend using VSCode and the `playwright` extension, as the above command is a cruder debugger that steps into every function call which is annoying.
@ -300,133 +197,114 @@ Which will run our suite of [Vitest unit](https://vitest.dev/) and [React Testin
### Rust tests
**Dependencies**
Prepare these system dependencies:
-`KITTYCAD_API_TOKEN`
-`cargo-nextest`
-`just`
- Set`$KITTYCAD_API_TOKEN` from https://zoo.dev/account/api-tokens
-Install `just` following [these instructions](https://just.systems/man/en/packages.html)
#### Setting KITTYCAD_API_TOKEN
Use the production zoo.dev token, set this environment variable before running the tests
# Make sure KITTYCAD_API_TOKEN=<prod zoo.dev token> is set
# Make sure you installed cargo-nextest
# Make sure you installed just
cd rust
just test
$ cargo install cargo-fuzz
```
```bash
# Without just
# Make sure KITTYCAD_API_TOKEN=<prod zoo.dev token> is set
# Make sure you installed cargo-nextest
cd rust
exportRUST_BRACKTRACE="full"&& cargo nextest run --workspace --test-threads=1
$ cd rust/kcl-lib
# list the fuzz targets
$ cargo fuzz list
# run the parser fuzzer
$ cargo +nightly fuzz run parser
```
Where `XXX` is an API token from the production engine (NOT the dev environment).
We recommend using [nextest](https://nexte.st/) to run the Rust tests (its faster and is used in CI). Once installed, run the tests using
```
cd rust
KITTYCAD_API_TOKEN=XXX cargo run nextest
```
### Mapping CI CD jobs to local commands
When you see the CI CD fail on jobs you may wonder three things
- Do I have a bug in my code?
- Is the test flaky?
- Is there a bug in `main`?
To answer these questions the following commands will give you confidence to locate the issue.
#### Static Analysis
Part of the CI CD pipeline performs static analysis on the code. Use the following commands to mimic the CI CD jobs.
The following set of commands should get us closer to one and done commands to instantly retest issues.
```
npm run test-setup
```
> Gotcha, are packages up to date and is the wasm built?
```
npm run tsc
npm run fmt:check
npm run lint
npm run test:unit:local
```
> Gotcha: Our unit tests have integration tests in them. You need to run a localhost server to run the unit tests.
#### E2E Tests
**Playwright Electron**
These E2E tests run in electron. There are tests that are skipped if they are ran in a windows, linux, or macos environment. We can use playwright tags to implement test skipping.
```
npm run test:playwright:electron:local
npm run test:playwright:electron:windows:local
npm run test:playwright:electron:macos:local
npm run test:playwright:electron:ubuntu:local
```
> Why does it say local? The CI CD commands that run in the pipeline cannot be ran locally. A single command will not properly setup the testing environment locally.
#### Some notes on CI
The tests are broken into snapshot tests and non-snapshot tests, and they run in that order, they automatically commit new snap shots, so if you see an image commit check it was an intended change. If we have non-determinism in the snapshots such that they are always committing new images, hopefully this annoyance makes us fix them asap, if you notice this happening let Kurt know. But for the odd occasion `git reset --hard HEAD~ && git push -f` is your friend.
How to interpret failing playwright tests?
If your tests fail, click through to the action and see that the tests failed on a line that includes `await page.getByTestId('loading').waitFor({ state: 'detached' })`, this means the test fail because the stream never started. It's you choice if you want to re-run the test, or ignore the failure.
We run on ubuntu and macos, because safari doesn't work on linux because of the dreaded "no RTCPeerConnection variable" error. But linux runs first and then macos for the same reason that we limit the number of parallel tests to 1 because we limit stream connections per user, so tests would start failing we if let them run together.
If something fails on CI you can download the artifact, unzip it and then open `playwright-report/data/<UUID>.zip` with https://trace.playwright.dev/ to see what happened.
#### Getting started writing a playwright test in our app
Besides following the instructions above and using the playwright docs, our app is weird because of the whole stream thing, which means our testing is weird. Because we've just figured out this stuff and therefore docs might go stale quick here's a 15min vid/tutorial
To display logging (to the terminal or console) set `ZOO_LOG=1`. This will log some warnings and simple performance metrics. To view these in test runs, use `-- --nocapture`.
To enable memory metrics, build with `--features dhat-heap`.
## Proposing changes
Before you submit a contribution PR to this repo, please ensure that:
- There is a corresponding issue for the changes you want to make, so that discussion of approach can be had before work begins.
- You have separated out refactoring commits from feature commits as much as possible
- You have run all of the following commands locally:
-`npm run fmt`
-`npm run tsc`
-`npm run test`
- Here they are all together: `npm run fmt && npm run tsc && npm run test`
## Shipping releases
#### 1. Create a 'Cut release $VERSION' issue
It will be used to document changelog discussions and release testing.
Decide on a `v`-prefixed semver `VERSION` (e.g. `v1.2.3`) with the team and tag the repo on the latest main:
```
git tag $VERSION --message=""
git push origin $VERSION
```
This will trigger the `build-apps` workflow to set the version, build & sign the apps, and generate release files.
The workflow should be listed right away [in this list](https://github.com/KittyCAD/modeling-app/actions/workflows/build-apps.yml?query=event%3Apush).
#### 3. Manually test artifacts
##### Release builds
The release builds can be found under the `out-{arch}-{platform}` zip files, at the very bottom of the `build-apps` summary page for the workflow (triggered by the tag in step 2).
Manually test against [this list](https://github.com/KittyCAD/modeling-app/issues/3588) across Windows, MacOS, Linux and posting results as comments in the issue.
A prompt should show up asking for a downgrade to the last release version. Running through that at the end of testing
and making sure the current release candidate has the ability to be updated to what electron-updater points to is critical,
but what is actually being downloaded and installed isn't.
If the prompt doesn't show up, start the app in command line to grab the electron-updater logs. This is likely an issue with the current build that needs addressing.
Follow the instructions [here](./rust/README.md) to publish new crates.
This ensures that the KCL accepted by the app is also accepted by the CLI.
#### 5. Publish the release
Head over to https://github.com/KittyCAD/modeling-app/releases/new, pick the newly created tag and type it in the **Release title** field as well.
Click **Generate release notes** as a starting point to discuss the changelog in the issue. Once done, make sure **Set as the latest release** is checked, and click **Publish release**.
A new `publish-apps-release` workflow will start and you should be able to find it [here](https://github.com/KittyCAD/modeling-app/actions?query=event%3Arelease). On success, the files will be uploaded to the public bucket as well as to the GitHub release, and the announcement on Discord will be sent.
#### 6. Close the issue
If everything is well and the release is out to the public, the issue tracking the release shall be closed.
@ -4,7 +4,7 @@ Compared to other CAD software, getting Zoo Design Studio up and running is quic
## Windows
1. Download the [Zoo Design Studio installer](https://zoo.dev/modeling-app/download) for Windows and for your processor type.
1. Download the [Zoo Design Studio installer](https://zoo.dev/design-studio/download) for Windows and for your processor type.
2. Once downloaded, run the installer `Zoo Design Studio-{version}-{arch}-win.exe` which should take a few seconds.
@ -12,16 +12,16 @@ Compared to other CAD software, getting Zoo Design Studio up and running is quic
## macOS
1. Download the [Zoo Design Studio installer](https://zoo.dev/modeling-app/download) for macOS and for your processor type.
1. Download the [Zoo Design Studio installer](https://zoo.dev/design-studio/download) for macOS and for your processor type.
2. Once downloaded, open the disk image `Zoo Design Studio-{version}-{arch}-mac.dmg` and drag the applications to your `Applications` directory.
3. You can then open your `Applications` directory and double-click on `Zoo Design Studio` to open.
## Linux
## Linux
1. Download the [Zoo Design Studio installer](https://zoo.dev/modeling-app/download) for Linux and for your processor type.
1. Download the [Zoo Design Studio installer](https://zoo.dev/design-studio/download) for Linux and for your processor type.
2. Install the dependencies needed to run the [AppImage format](https://appimage.org/).
- On Ubuntu, install the FUSE library with these commands in a terminal.
@ -29,7 +29,7 @@ Compared to other CAD software, getting Zoo Design Studio up and running is quic
sudo apt update
sudo apt install libfuse2
```
- Optionally, follow [these steps](https://github.com/probonopd/go-appimage/blob/master/src/appimaged/README.md#initial-setup) to install `appimaged`. It is a daemon that makes interacting with AppImage files more seamless.
- Optionally, follow [these steps](https://github.com/probonopd/go-appimage/blob/master/src/appimaged/README.md#initial-setup) to install `appimaged`. It is a daemon that makes interacting with AppImage files more seamless.
- Once installed, copy the downloaded `Zoo Design Studio-{version}-{arch}-linux.AppImage` to the directory of your choice, for instance `~/Applications`.
- `appimaged` should automatically find it and make it executable. If not, run:
We recommend downloading the latest application binary from our [releases](https://github.com/KittyCAD/modeling-app/releases) page. If you don't see your platform or architecture supported there, please file an issue.
If you'd like to try out upcoming changes sooner, you can also download those from our [nightly releases](https://zoo.dev/modeling-app/download/nightly) page.
We recommend downloading the latest application binary from our [website](https://zoo.dev/design-studio/download). If you don't see your platform or architecture supported there, please file an issue. See the [installation guide](INSTALL.md) for additional instructions.
## Developing
Finally, if you'd like to run a development build or contribute to the project, please visit our [contributor guide](CONTRIBUTING.md) to get started.
## KCL
To contribute to the KittyCAD Language, see the [README](https://github.com/KittyCAD/modeling-app/tree/main/rust/kcl-lib) for KCL.
Finally, if you'd like to run a development build or contribute to the project, please visit our [contributor guide](CONTRIBUTING.md) to get started. To contribute to the KittyCAD Language, see the dedicated [readme](rust/kcl-lib/README.md) for KCL.
excerpt: "Documentation of the KCL language for the Zoo Design Studio."
layout: manual
---
KCL supports the usual arithmetic operators on numbers and logic operators on booleans:
| Operator | Meaning |
|----------|---------|
| `+` | Addition |
| `-` | Subtraction or unary negation |
| `*` | Multiplication |
| `/` | Division |
| `%` | Modulus aka remainder |
| `^` | Power, e.g., `x ^ 2` means `x` squared |
| `&` | Logical 'and' |
| `|` | Logical 'or' |
| `!` | Unary logical 'not' |
KCL also supports comparsion operators which operate on numbers and produce booleans:
| Operator | Meaning |
|----------|---------|
| `==` | Equal |
| `!=` | Not equal |
| `<` | Less than |
| `>` | Greater than |
| `<=` | Less than or equal |
| `>=` | Greater than or equal |
Arithmetics and logic expressions can be arbitrairly combined with the usual rules of associativity and precedence, e.g.,
```
myMathExpression = 3 + 1 * 2 / 3 - 7
```
You can also nest expressions in parenthesis:
```
myMathExpression = 3 + (1 * 2 / (3 - 7))
```
KCL numbers are implemented using [floating point numbers](https://en.wikipedia.org/wiki/Floating-point_arithmetic). This means that there are occasionally representation and rounding issues, and some oddities such as supporting positive and negative zero.
Some operators can be applied to other types:
-`+` can be used to concatenate strings, e.g., `'hello' + ' ' + 'world!'`
- Unary `-` can be used with planes or line-like objects such as axes to produce an object with opposite orientation, e.g., `-XY` is a plain which is aligned with `XY` but whose normal aligns with the negative Z axis.
- The following operators can be used with solids as shorthand for CSG operations:
excerpt: "Documentation of the KCL language for the Zoo Design Studio."
layout: manual
---
Arrays are sequences of values.
Arrays can be written out as *array literals* using a sequence of expressions surrounded by square brackets, e.g., `['hello', 'world']` is an array of strings, `[x, x + 1, x + 2]` is an array of numbers (assuming `x` is a number), `[]` is an empty array, and `['hello', 42, true]` is a mixed array.
A value in an array can be accessed by indexing using square brackets where the index is a number, for example, `arr[0]`, `arr[42]`, `arr[i]` (where `arr` is an array and `i` is a (whole) number).
There are some useful functions for working with arrays in the standard library, see [std::array](/docs/kcl-std/modules/std-array) for details.
## Array types
Arrays have their own types: `[T]` where `T` is the type of the elements of the array, for example, `[string]` means an array of `string`s and `[any]` means an array of any values.
Array types can also include length information: `[T; n]` denotes an array of length `n` (where `n` is a number literal) and `[T; n+]` denotes an array whose length is at least `n`. The common case for that is `[T; 1+]`, i.e., a non-empty array. E.g., `[string; 1+]` and `[number(mm); 3]` are valid array types.
## Ranges
Ranges are a succinct way to create an array of sequential numbers. The syntax is `[start .. end]` where `start` and `end` evaluate to whole numbers (integers). Ranges are inclusive of the start and end. The end must be greater than the start. A range which is exclusive of its end is written with `<end`. Examples:
```kcl,norun
[0..3] // [0, 1, 2, 3]
[3..10] // [3, 4, 5, 6, 7, 8, 9, 10]
[3..<10] // [3, 4, 5, 6, 7, 8, 9]
x = 2
[x..x+1] // [2, 3]
```
The units of the start and end numbers must be the same and the result inherits those units.
excerpt: "Documentation of the KCL language for the Zoo Design Studio."
layout: manual
---
Attributes are syntax which affects the language item they annotate. In KCL they are indicated using `@`. For example, `@settings` affects the file in which it appears.
There are two kinds of attributes: named and unnamed attributes. Named attributes (e.g., `@settings`) have a name immediately after the `@` (e.g., `settings`) and affect their surrounding scope. Unnamed attributes have no name and affect the following item, e.g.,
```kcl,norun
@(lengthUnit = ft, coords = opengl)
import "tests/inputs/cube.obj"
```
has an unnamed attribute on the `import` statement.
Named and unnamed attributes may take a parenthesized list of arguments (like a function). Named attributes may also appear without any arguments (e.g., `@no_std`).
## Named attributes
The `@settings` attribute affects the current file and accepts the following arguments: `defaultLengthUnit`, `defaultAngleUnit`, and `kclVersion`. See [settings](/docs/kcl-lang/settings) for details.
The `@no_std` attribute affects the current file, takes no arguments, and causes the standard library to not be implicitly available. It can still be used by being explicitly imported.
## Unnamed attributes
Unnamed attributes may be used on `import` statements when importing non-KCL files. See [projects, modules, and imports](/docs/kcl-lang/modules) for details.
Other unnamed attributes are used on functions inside the standard library, but these are not available in user code.
// --- perform other operations and calculations here ---
cube
|> translate(z=10) // 2) Blocks only here
```
#### 2. Split heavy work into separate modules
Place computationally expensive or IO‑heavy work into its own module so it can render in parallel while `main.kcl` continues.
#### Future improvements
Upcoming releases will auto‑analyse dependencies and only block when truly necessary. Until then, explicit deferral will give you the best performance.
// --- perform other operations and calculations here ---
cube
|> translate(z=10) // 2) Blocks only here
```
#### 2. Split heavy work into separate modules
Place computationally expensive or IO‑heavy work into its own module so it can render in parallel while `main.kcl` continues.
#### Future improvements
Upcoming releases will auto‑analyse dependencies and only block when truly necessary. Until then, explicit deferral will give you the best performance.
excerpt: "Documentation of the KCL language for the Zoo Design Studio."
layout: manual
---
Numbers and numeric types in KCL include information about the units of the numbers. So rather than just having a number like `42`, we always have information about the units so we don't confuse 42 mm with 42 inches.
## Numeric literals
When writing a number literal, you can use a unit suffix to explicitly state the unit, e.g., `42mm`. The following units are available:
- Length units:
- metric: `mm`, `cm`, `m`
- imperial: `in`, `ft`, `yd`
- Angle units: `deg`, `rad`
-`_` to indicate a unitless number such as a count or ratio.
If you write a numeric literal without a suffix, then the defaults for the current file are used. These defaults are specified using the `@settings` attribute, see [settings](/docs/kcl-lang/settings) for details. Note that if using the defaults, the KCL interpreter won't know whether you intend the number to be a length, angle, or count and will treat it as being possibly any of them.
## Numeric types
Just like numbers carry units information, the `number` type also includes units information. Units are written in parentheses after the type, e.g., `number(mm)`.
Any of the suffixes described above can be used meaning that values with that type have the supplied units. E.g., `number(mm)` is the type of number values with mm units and `number(_)` is the type of number values with no units.
You can also use `number(Length)`, `number(Angle)`, or `number(Count)`. These types mean a number with any length, angle, or unitless (count) units, respectively (note that `number(_)` and `number(Count)` are equivalent since there is only one kind of unitless-ness).
Using just `number` means accepting any kind of number, even where the units are unknown by KCL.
## Function calls
When calling a function with an argument with numeric type, the declared numeric type in the function signature and the units of the argument value used in the function call must be compatible. Units are adjusted automatically. For example, if a function requires an argument with type `number(mm)`, then you can call it with `2in` and the units will be automatically adjusted, but calling it with `90deg` will cause an error.
## Mixing units with arithmetic
When doing arithmetic or comparisons, units will be adjusted as necessary if possible. However, often arithmetic expressions exceed the ability of KCL to accurately choose units which can result in warnings in your code or sometimes errors. In these cases, you will need to give KCL more information. Sometimes this can be done by making units explicit using suffixes. If not, then you will need to use *type ascription*, which asserts that an expression has the supplied type. For example, `(x * y): number(mm)` tells KCL that the units of `x * y` is mm. Note that type ascription does not do any adjustment of the numbers, e.g., `2mm: number(in)` has the value `2in` (note that this would be a very non-idiomatic way to use numeric type ascription, you could simply write `2in`. Usually type ascription is only necessary for supplying type information about the result of computation).
KCL has no support for area, volume, or other higher dimension units. When internal unit tracking requires multiple dimensions, KCL essentially gives up. This is usually where the extra type information described above is needed. If doing computation with higher dimensioned units, you must ensure that all adjustments occur before any computation. E.g., if you want to compute an area with unknown units, you must convert all numbers to the same unit before starting.
## Explicit conversions
You might sometimes need to convert from one unit to another for some calculation. You can do this implicitly when calling a function (see above), but if you can't or don't want to, then you can use the explicit conversion functions in the [`std::units`](/docs/kcl-std/modules/std-units) module.
excerpt: "Check a value meets some expected conditions at runtime. Program terminates with an error if conditions aren't met. If you provide multiple conditions, they will all be checked and all must be met."
layout: manual
---
Check a value meets some expected conditions at runtime. Program terminates with an error if conditions aren't met. If you provide multiple conditions, they will all be checked and all must be met.
```kcl
assert(
@actual: number,
isGreaterThan?: number,
isLessThan?: number,
isGreaterThanOrEqual?: number,
isLessThanOrEqual?: number,
isEqualTo?: number,
tolerance?: number,
error?: string,
)
```
### Arguments
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `actual` | [`number`](/docs/kcl-std/types/std-types-number) | Value to check. If this is the boolean value true, assert passes. Otherwise it fails.. | Yes |
| `isGreaterThan` | [`number`](/docs/kcl-std/types/std-types-number) | Comparison argument. If given, checks the `actual` value is greater than this. | No |
| `isLessThan` | [`number`](/docs/kcl-std/types/std-types-number) | Comparison argument. If given, checks the `actual` value is less than this. | No |
| `isGreaterThanOrEqual` | [`number`](/docs/kcl-std/types/std-types-number) | Comparison argument. If given, checks the `actual` value is greater than or equal to this. | No |
| `isLessThanOrEqual` | [`number`](/docs/kcl-std/types/std-types-number) | Comparison argument. If given, checks the `actual` value is less than or equal to this. | No |
| `isEqualTo` | [`number`](/docs/kcl-std/types/std-types-number) | Comparison argument. If given, checks the `actual` value is less than or equal to this. | No |
| `tolerance` | [`number`](/docs/kcl-std/types/std-types-number) | If `isEqualTo` is used, this is the tolerance to allow for the comparison. This tolerance is used because KCL's number system has some floating-point imprecision when used with very large decimal places. | No |
| `error` | [`string`](/docs/kcl-std/types/std-types-string) | If the value was false, the program will terminate with this error message | No |
### Examples
```kcl
n = 10
assert(n, isEqualTo = 10)
assert(n, isGreaterThanOrEqual = 0, isLessThan = 100, error = "number should be between 0 and 100")
assert(1.0000000000012, isEqualTo = 1, tolerance = 0.0001, error = "number should be almost exactly 1")
excerpt: "Asserts that a value is the boolean value true."
layout: manual
---
Asserts that a value is the boolean value true.
```kcl
assertIs(
@actual: bool,
error?: string,
)
```
### Arguments
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `actual` | [`bool`](/docs/kcl-std/types/std-types-bool) | Value to check. If this is the boolean value true, assert passes. Otherwise it fails.. | Yes |
| `error` | [`string`](/docs/kcl-std/types/std-types-string) | If the value was false, the program will terminate with this error message | No |
@ -10,13 +10,13 @@ Draw a line segment relative to the current origin using the polar measure of so
```kcl
angledLine(
@sketch: Sketch,
angle: number,
length?: number,
lengthX?: number,
lengthY?: number,
endAbsoluteX?: number,
endAbsoluteY?: number,
tag?: TagDeclarator,
angle: number(Angle),
length?: number(Length),
lengthX?: number(Length),
lengthY?: number(Length),
endAbsoluteX?: number(Length),
endAbsoluteY?: number(Length),
tag?: tag,
): Sketch
```
@ -27,13 +27,13 @@ angledLine(
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `sketch` | [`Sketch`](/docs/kcl-std/types/std-types-Sketch) | Which sketch should this path be added to? | Yes |
| `angle` | [`number`](/docs/kcl-std/types/std-types-number) | Which angle should the line be drawn at? | Yes |
| `length` | [`number`](/docs/kcl-std/types/std-types-number) | Draw the line this distance along the given angle. Only one of `length`, `lengthX`, `lengthY`, `endAbsoluteX`, `endAbsoluteY` can be given. | No |
| `lengthX` | [`number`](/docs/kcl-std/types/std-types-number) | Draw the line this distance along the X axis. Only one of `length`, `lengthX`, `lengthY`, `endAbsoluteX`, `endAbsoluteY` can be given. | No |
| `lengthY` | [`number`](/docs/kcl-std/types/std-types-number) | Draw the line this distance along the Y axis. Only one of `length`, `lengthX`, `lengthY`, `endAbsoluteX`, `endAbsoluteY` can be given. | No |
| `endAbsoluteX` | [`number`](/docs/kcl-std/types/std-types-number) | Draw the line along the given angle until it reaches this point along the X axis. Only one of `length`, `lengthX`, `lengthY`, `endAbsoluteX`, `endAbsoluteY` can be given. | No |
| `endAbsoluteY` | [`number`](/docs/kcl-std/types/std-types-number) | Draw the line along the given angle until it reaches this point along the Y axis. Only one of `length`, `lengthX`, `lengthY`, `endAbsoluteX`, `endAbsoluteY` can be given. | No |
| [`tag`](/docs/kcl-std/types/std-types-tag) | [`TagDeclarator`](/docs/kcl-lang/types#TagDeclarator) | Create a new tag which refers to this line | No |
| `angle` | [`number(Angle)`](/docs/kcl-std/types/std-types-number) | Which angle should the line be drawn at? | Yes |
| `length` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | Draw the line this distance along the given angle. Only one of `length`, `lengthX`, `lengthY`, `endAbsoluteX`, `endAbsoluteY` can be given. | No |
| `lengthX` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | Draw the line this distance along the X axis. Only one of `length`, `lengthX`, `lengthY`, `endAbsoluteX`, `endAbsoluteY` can be given. | No |
| `lengthY` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | Draw the line this distance along the Y axis. Only one of `length`, `lengthX`, `lengthY`, `endAbsoluteX`, `endAbsoluteY` can be given. | No |
| `endAbsoluteX` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | Draw the line along the given angle until it reaches this point along the X axis. Only one of `length`, `lengthX`, `lengthY`, `endAbsoluteX`, `endAbsoluteY` can be given. | No |
| `endAbsoluteY` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | Draw the line along the given angle until it reaches this point along the Y axis. Only one of `length`, `lengthX`, `lengthY`, `endAbsoluteX`, `endAbsoluteY` can be given. | No |
| [`tag`](/docs/kcl-std/types/std-types-tag) | [`tag`](/docs/kcl-std/types/std-types-tag) | Create a new tag which refers to this line. | No |
@ -10,10 +10,10 @@ Draw an angled line from the current origin, constructing a line segment such th
```kcl
angledLineThatIntersects(
@sketch: Sketch,
angle: number,
intersectTag: TagIdentifier,
offset?: number,
tag?: TagDeclarator,
angle: number(Angle),
intersectTag: tag,
offset?: number(Length),
tag?: tag,
): Sketch
```
@ -24,10 +24,10 @@ angledLineThatIntersects(
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `sketch` | [`Sketch`](/docs/kcl-std/types/std-types-Sketch) | Which sketch should this path be added to? | Yes |
| `angle` | [`number`](/docs/kcl-std/types/std-types-number) | Which angle should the line be drawn at? | Yes |
| `intersectTag` | [`TagIdentifier`](/docs/kcl-lang/types#TagIdentifier) | The tag of the line to intersect with | Yes |
| `offset` | [`number`](/docs/kcl-std/types/std-types-number) | The offset from the intersecting line. Defaults to 0. | No |
| [`tag`](/docs/kcl-std/types/std-types-tag) | [`TagDeclarator`](/docs/kcl-lang/types#TagDeclarator) | Create a new tag which refers to this line | No |
| `angle` | [`number(Angle)`](/docs/kcl-std/types/std-types-number) | Which angle should the line be drawn at? | Yes |
| `intersectTag` | [`tag`](/docs/kcl-std/types/std-types-tag) | The tag of the line to intersect with. | Yes |
| `offset` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | The offset from the intersecting line. | No |
| [`tag`](/docs/kcl-std/types/std-types-tag) | [`tag`](/docs/kcl-std/types/std-types-tag) | Create a new tag which refers to this line. | No |
@ -10,30 +10,37 @@ Draw a curved line segment along an imaginary circle.
```kcl
arc(
@sketch: Sketch,
angleStart?: number,
angleEnd?: number,
radius?: number,
angleStart?: number(Angle),
angleEnd?: number(Angle),
radius?: number(Length),
diameter?: number(Length),
interiorAbsolute?: Point2d,
endAbsolute?: Point2d,
tag?: TagDeclarator,
tag?: tag,
): Sketch
```
The arc is constructed such that the current position of the sketch is placed along an imaginary circle of the specified radius, at angleStart degrees. The resulting arc is the segment of the imaginary circle from that origin point to angleEnd, radius away from the center of the imaginary circle.
The arc is constructed such that the current position of the sketch is
placed along an imaginary circle of the specified radius, at angleStart
degrees. The resulting arc is the segment of the imaginary circle from
that origin point to angleEnd, radius away from the center of the imaginary
circle.
Unless this makes a lot of sense and feels like what you're looking for to construct your shape, you're likely looking for tangentialArc.
Unless this makes a lot of sense and feels like what you're looking
for to construct your shape, you're likely looking for tangentialArc.
### Arguments
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `sketch` | [`Sketch`](/docs/kcl-std/types/std-types-Sketch) | Which sketch should this path be added to? | Yes |
| `angleStart` | [`number`](/docs/kcl-std/types/std-types-number) | Where along the circle should this arc start? | No |
| `angleEnd` | [`number`](/docs/kcl-std/types/std-types-number) | Where along the circle should this arc end? | No |
| `radius` | [`number`](/docs/kcl-std/types/std-types-number) | How large should the circle be? | No |
| `interiorAbsolute` | [`Point2d`](/docs/kcl-std/types/std-types-Point2d) | Any point between the arc's start and end? Requires `endAbsolute`. Incompatible with `angleStart` or `angleEnd` | No |
| `endAbsolute` | [`Point2d`](/docs/kcl-std/types/std-types-Point2d) | Where should this arc end? Requires `interiorAbsolute`. Incompatible with `angleStart` or `angleEnd` | No |
| [`tag`](/docs/kcl-std/types/std-types-tag) | [`TagDeclarator`](/docs/kcl-lang/types#TagDeclarator) | Create a new tag which refers to this line | No |
| `angleStart` | [`number(Angle)`](/docs/kcl-std/types/std-types-number) | Where along the circle should this arc start? | No |
| `angleEnd` | [`number(Angle)`](/docs/kcl-std/types/std-types-number) | Where along the circle should this arc end? | No |
| `radius` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | How large should the circle be? Incompatible with `diameter`. | No |
| `diameter` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | How large should the circle be? Incompatible with `radius`. | No |
| `interiorAbsolute` | [`Point2d`](/docs/kcl-std/types/std-types-Point2d) | Any point between the arc's start and end? Requires `endAbsolute`. Incompatible with `angleStart` or `angleEnd`. | No |
| `endAbsolute` | [`Point2d`](/docs/kcl-std/types/std-types-Point2d) | Where should this arc end? Requires `interiorAbsolute`. Incompatible with `angleStart` or `angleEnd`. | No |
| [`tag`](/docs/kcl-std/types/std-types-tag) | [`tag`](/docs/kcl-std/types/std-types-tag) | Create a new tag which refers to this arc. | No |
### Returns
@ -46,7 +53,11 @@ Unless this makes a lot of sense and feels like what you're looking for to const
excerpt: "Construct a 2-dimensional circle, of the specified radius, centered at the provided (x, y) origin point."
layout: manual
---
Construct a 2-dimensional circle, of the specified radius, centered at the provided (x, y) origin point.
```kcl
circle(
@sketch_or_surface: Sketch | Plane | Face,
@sketchOrSurface: Sketch | Plane | Face,
center: Point2d,
radius: number(Length),
radius?: number(Length),
diameter?: number(Length),
tag?: tag,
): Sketch
```
Construct a 2-dimensional circle, of the specified radius, centered at
the provided (x, y) origin point.
### Arguments
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `sketch_or_surface` | [`Sketch`](/docs/kcl-std/types/std-types-Sketch) or [`Plane`](/docs/kcl-std/types/std-types-Plane) or [`Face`](/docs/kcl-std/types/std-types-Face) | Sketch to extend, or plane or surface to sketch on. | Yes |
| `sketchOrSurface` | [`Sketch`](/docs/kcl-std/types/std-types-Sketch) or [`Plane`](/docs/kcl-std/types/std-types-Plane) or [`Face`](/docs/kcl-std/types/std-types-Face) | Sketch to extend, or plane or surface to sketch on. | Yes |
| `center` | [`Point2d`](/docs/kcl-std/types/std-types-Point2d) | The center of the circle. | Yes |
| `radius` | `number(Length)` | The radius of the circle. | Yes |
| `radius` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | The radius of the circle. Incompatible with `diameter`. | No |
| `diameter` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | The diameter of the circle. Incompatible with `radius`. | No |
| [`tag`](/docs/kcl-std/types/std-types-tag) | [`tag`](/docs/kcl-std/types/std-types-tag) | Create a new tag which refers to this circle. | No |
@ -9,11 +9,11 @@ Construct a circle derived from 3 points.
```kcl
circleThreePoint(
@sketchSurfaceOrGroup: Sketch | Plane | Face,
@sketchOrSurface: Sketch | Plane | Face,
p1: Point2d,
p2: Point2d,
p3: Point2d,
tag?: TagDeclarator,
tag?: tag,
): Sketch
```
@ -23,11 +23,11 @@ circleThreePoint(
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `sketchSurfaceOrGroup` | [`Sketch`](/docs/kcl-std/types/std-types-Sketch) or [`Plane`](/docs/kcl-std/types/std-types-Plane) or [`Face`](/docs/kcl-std/types/std-types-Face) | Plane or surface to sketch on. | Yes |
| `sketchOrSurface` | [`Sketch`](/docs/kcl-std/types/std-types-Sketch) or [`Plane`](/docs/kcl-std/types/std-types-Plane) or [`Face`](/docs/kcl-std/types/std-types-Face) | Plane or surface to sketch on. | Yes |
| `p1` | [`Point2d`](/docs/kcl-std/types/std-types-Point2d) | 1st point to derive the circle. | Yes |
| `p2` | [`Point2d`](/docs/kcl-std/types/std-types-Point2d) | 2nd point to derive the circle. | Yes |
| `p3` | [`Point2d`](/docs/kcl-std/types/std-types-Point2d) | 3rd point to derive the circle. | Yes |
| [`tag`](/docs/kcl-std/types/std-types-tag) | [`TagDeclarator`](/docs/kcl-lang/types#TagDeclarator) | Identifier for the circle to reference elsewhere. | No |
| [`tag`](/docs/kcl-std/types/std-types-tag) | [`tag`](/docs/kcl-std/types/std-types-tag) | Identifier for the circle to reference elsewhere. | No |
@ -9,31 +9,32 @@ Extend a 2-dimensional sketch through a third dimension in order to create new 3
```kcl
extrude(
@sketches: [Sketch],
length: number,
@sketches: [Sketch; 1+],
length: number(Length),
symmetric?: bool,
bidirectionalLength?: number,
tagStart?: TagDeclarator,
tagEnd?: TagDeclarator,
): [Solid]
bidirectionalLength?: number(Length),
tagStart?: tag,
tagEnd?: tag,
): [Solid; 1+]
```
You can provide more than one sketch to extrude, and they will all be extruded in the same direction.
You can provide more than one sketch to extrude, and they will all be
extruded in the same direction.
### Arguments
| Name | Type | Description | Required |
|----------|------|-------------|----------|
| `sketches` | [`[Sketch]`](/docs/kcl-std/types/std-types-Sketch) | Which sketch or sketches should be extruded | Yes |
| `length` | [`number`](/docs/kcl-std/types/std-types-number) | How far to extrude the given sketches | Yes |
| `symmetric` | [`bool`](/docs/kcl-std/types/std-types-bool) | If true, the extrusion will happen symmetrically around the sketch. Otherwise, the | No |
| `bidirectionalLength` | [`number`](/docs/kcl-std/types/std-types-number) | If specified, will also extrude in the opposite direction to 'distance' to the specified distance. If 'symmetric' is true, this value is ignored. | No |
| `tagStart` | [`TagDeclarator`](/docs/kcl-lang/types#TagDeclarator) | A named tag for the face at the start of the extrusion, i.e. the original sketch | No |
| `tagEnd` | [`TagDeclarator`](/docs/kcl-lang/types#TagDeclarator) | A named tag for the face at the end of the extrusion, i.e. the new face created by extruding the original sketch | No |
| `sketches` | [`[Sketch; 1+]`](/docs/kcl-std/types/std-types-Sketch) | Which sketch or sketches should be extruded. | Yes |
| `length` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | How far to extrude the given sketches. | Yes |
| `symmetric` | [`bool`](/docs/kcl-std/types/std-types-bool) | If true, the extrusion will happen symmetrically around the sketch. Otherwise, the extrusion will happen on only one side of the sketch. | No |
| `bidirectionalLength` | [`number(Length)`](/docs/kcl-std/types/std-types-number) | If specified, will also extrude in the opposite direction to 'distance' to the specified distance. If 'symmetric' is true, this value is ignored. | No |
| `tagStart` | [`tag`](/docs/kcl-std/types/std-types-tag) | A named tag for the face at the start of the extrusion, i.e. the original sketch. | No |
| `tagEnd` | [`tag`](/docs/kcl-std/types/std-types-tag) | A named tag for the face at the end of the extrusion, i.e. the new face created by extruding the original sketch. | No |
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.