@mylasertools/kerfscript 0.0.0-stage → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/CLA.md +73 -0
  3. package/COMMERCIAL-LICENSE.md +68 -0
  4. package/LANGUAGE.md +295 -0
  5. package/LICENSE +661 -0
  6. package/README.md +148 -2
  7. package/THIRD-PARTY-NOTICES.md +69 -0
  8. package/TRADEMARKS.md +39 -0
  9. package/dist/ast.d.cts +160 -0
  10. package/dist/ast.d.ts +160 -0
  11. package/dist/cli.d.cts +1 -0
  12. package/dist/cli.d.ts +1 -0
  13. package/dist/cli.js +19226 -0
  14. package/dist/customizer.d.cts +19 -0
  15. package/dist/customizer.d.ts +19 -0
  16. package/dist/evaluator.d.cts +106 -0
  17. package/dist/evaluator.d.ts +106 -0
  18. package/dist/export/dxf.d.cts +3 -0
  19. package/dist/export/dxf.d.ts +3 -0
  20. package/dist/export/svg.d.cts +13 -0
  21. package/dist/export/svg.d.ts +13 -0
  22. package/dist/functions.d.cts +4 -0
  23. package/dist/functions.d.ts +4 -0
  24. package/dist/geometry.d.cts +44 -0
  25. package/dist/geometry.d.ts +44 -0
  26. package/dist/index.cjs +44 -0
  27. package/dist/index.d.cts +10 -0
  28. package/dist/index.d.ts +10 -0
  29. package/dist/index.js +44 -0
  30. package/dist/joinery.d.cts +7 -0
  31. package/dist/joinery.d.ts +7 -0
  32. package/dist/lexer.d.cts +28 -0
  33. package/dist/lexer.d.ts +28 -0
  34. package/dist/parser.d.cts +6 -0
  35. package/dist/parser.d.ts +6 -0
  36. package/dist/paths.d.cts +28 -0
  37. package/dist/paths.d.ts +28 -0
  38. package/dist/render.d.cts +57 -0
  39. package/dist/render.d.ts +57 -0
  40. package/dist/stdlib.d.cts +1 -0
  41. package/dist/stdlib.d.ts +1 -0
  42. package/dist/text.d.cts +36 -0
  43. package/dist/text.d.ts +36 -0
  44. package/dist/values.d.cts +25 -0
  45. package/dist/values.d.ts +25 -0
  46. package/docs/cli.md +61 -0
  47. package/docs/compatibility.md +89 -0
  48. package/docs/customizer.md +62 -0
  49. package/docs/getting-started.md +98 -0
  50. package/docs/javascript.md +98 -0
  51. package/docs/kerf.md +70 -0
  52. package/docs/layers.md +74 -0
  53. package/docs/openscad.md +67 -0
  54. package/docs/parts-and-sheets.md +68 -0
  55. package/docs/versions.md +43 -0
  56. package/package.json +85 -4
@@ -0,0 +1,98 @@
1
+ # Getting started
2
+
3
+ This guide takes you from an empty file to a cut file in about ten minutes.
4
+ You need nothing installed: the [playground](https://kerfscript.mylasertools.com/playground/)
5
+ runs KerfScript in your browser.
6
+
7
+ ## Your first part
8
+
9
+ Open the playground, clear the editor and type:
10
+
11
+ ```kerf
12
+ rect([80, 50], r = 4);
13
+ ```
14
+
15
+ That is a rounded rectangle, 80 by 50 mm. Units are always millimetres. A
16
+ shape that is not on any other layer is **cut**, so this is a part you could
17
+ cut out now.
18
+
19
+ ## Holes
20
+
21
+ `difference()` keeps the first shape and removes the rest from it:
22
+
23
+ ```kerf
24
+ difference() {
25
+ rect([80, 50], r = 4);
26
+ translate([10, 25]) circle(d = 5);
27
+ translate([70, 25]) circle(d = 5);
28
+ }
29
+ ```
30
+
31
+ `translate([x, y])` moves what follows it. The y axis points up, and
32
+ `rect()` starts at `[0, 0]` unless you pass `center = true`.
33
+
34
+ ## Engraving and scoring
35
+
36
+ Wrap shapes in `engrave()` to engrave their area, or `score()` to mark their
37
+ outline without cutting through:
38
+
39
+ ```kerf
40
+ difference() {
41
+ rect([80, 50], r = 4);
42
+ translate([10, 25]) circle(d = 5);
43
+ translate([70, 25]) circle(d = 5);
44
+ }
45
+ score() translate([20, 10]) rect([40, 30], r = 2);
46
+ engrave() translate([40, 25]) text("Oak", size = 10, halign = "center", valign = "center");
47
+ ```
48
+
49
+ Engraving and scoring are clipped to the material, so nothing is marked over
50
+ a hole or off the edge. [Layers](layers.md) explains the rest.
51
+
52
+ ## Settings
53
+
54
+ A top-level variable with a comment in square brackets becomes a slider:
55
+
56
+ ```kerf
57
+ width = 80; // [40:5:200]
58
+ height = 50; // [30:5:120]
59
+ label = "Oak";
60
+
61
+ difference() {
62
+ rect([width, height], r = 4);
63
+ translate([10, height / 2]) circle(d = 5);
64
+ translate([width - 10, height / 2]) circle(d = 5);
65
+ }
66
+ engrave() translate([width / 2, height / 2])
67
+ text(label, size = 10, halign = "center", valign = "center");
68
+ ```
69
+
70
+ Move a slider in the playground and the number in the code changes with it.
71
+ [Settings](customizer.md) covers groups, captions and menus.
72
+
73
+ ## Kerf
74
+
75
+ The laser burns away a thin line of material, the **kerf**. Tell KerfScript
76
+ how wide it is and parts come out the size you typed:
77
+
78
+ ```kerf
79
+ $kerf = 0.15;
80
+ ```
81
+
82
+ Cut the [calibration square](../examples/calibration-square.kerf) once to
83
+ measure yours. [Kerf](kerf.md) explains how.
84
+
85
+ ## Getting the file
86
+
87
+ In the playground, press **SVG** or **DXF**. Open the SVG in your laser
88
+ software: cut lines are red, score lines blue and engraving black, each on its
89
+ own layer. Set power, speed and the order of operations there, as you would
90
+ for any other file. [Laser software](compatibility.md) has notes for the
91
+ programs we have checked.
92
+
93
+ ## Next
94
+
95
+ - [Layers](layers.md): cut, score, engrave and your own layers
96
+ - [Parts and sheets](parts-and-sheets.md): several pieces, quantities, materials
97
+ - [Coming from OpenSCAD](openscad.md): what is the same and what is not
98
+ - [Language reference](../LANGUAGE.md): everything in one page
@@ -0,0 +1,98 @@
1
+ # JavaScript API
2
+
3
+ The same interpreter that runs the command line and the playground is a
4
+ TypeScript library with no native code. It runs in browsers, web workers,
5
+ Node.js and edge runtimes.
6
+
7
+ ```sh
8
+ npm install @mylasertools/kerfscript
9
+ ```
10
+
11
+ ## render()
12
+
13
+ ```js
14
+ import { render } from '@mylasertools/kerfscript';
15
+
16
+ const result = render(source, {
17
+ params: { width: 200 },
18
+ fonts: { Inter: await (await fetch('/Inter.ttf')).arrayBuffer() },
19
+ defaultFont: 'Inter',
20
+ sheet: [600, 400],
21
+ });
22
+ ```
23
+
24
+ ### Options
25
+
26
+ | Option | Meaning |
27
+ | ------------- | ------------------------------------------------------------------------------------ |
28
+ | `params` | setting values by name, overriding the top-level assignments |
29
+ | `fonts` | font files by name, as `ArrayBuffer` or `Uint8Array` |
30
+ | `defaultFont` | font used when `text()` names none |
31
+ | `resolve` | `(path) => source` for `use <path>` and `include <path>` beyond the standard library |
32
+ | `kerf` | override kerf compensation for every part |
33
+ | `layout` | `"pack"` or `"none"` |
34
+ | `sheet` | `[width, height]` in mm |
35
+ | `gap` | space between packed parts |
36
+ | `margin` | space around the sheet edge (default: `gap`) |
37
+ | `guides` | include guide layer geometry |
38
+ | `maxSteps` | step limit before the program is stopped |
39
+
40
+ ### Result
41
+
42
+ | Field | Contents |
43
+ | ----------------- | ---------------------------------------------------------------------------------------------------------- |
44
+ | `svg` | every sheet in one SVG, for previews |
45
+ | `width`, `height` | size of that combined SVG in mm |
46
+ | `sheets` | one entry per sheet: `width`, `height`, `material`, `thickness`, `svg`, `dxf`, `paths`, `items` |
47
+ | `parts` | `name`, `qty`, `width`, `height`, `pieces`, `cutLength`, `thickness`, `kerf`, `material` |
48
+ | `paths` | per layer: `name`, `mode`, `color`, `d` (all path data), `regions` (closed outlines), `lines` (open lines) |
49
+ | `layers` | the layer definitions in output order |
50
+ | `warnings` | problems that did not stop the render |
51
+ | `echoes` | `echo()` output |
52
+
53
+ `paths` is for apps that draw the result themselves. Fill `regions` with the
54
+ even-odd rule on `fill` layers, and stroke `lines`.
55
+
56
+ ## parameters()
57
+
58
+ ```js
59
+ import { parameters } from '@mylasertools/kerfscript';
60
+
61
+ parameters(source).parameters;
62
+ // [{ name, caption, group, type, initial, min, max, step, options, span }]
63
+ ```
64
+
65
+ `type` is `"number"`, `"string"` or `"boolean"`; a list of numbers is
66
+ `"number"` with a list `initial`, as in OpenSCAD's parameter JSON. `span` is
67
+ `[start, end]`, the offsets of the value in the source, so an editor can change
68
+ a value without touching anything else:
69
+
70
+ ```js
71
+ const p = parameters(source).parameters.find((p) => p.name === 'width');
72
+ const next = source.slice(0, p.span[0]) + '200' + source.slice(p.span[1]);
73
+ ```
74
+
75
+ ## Errors
76
+
77
+ Errors are thrown as `KerfError` with `line` and `col`. They also carry
78
+ `echoes`, the `echo()` output up to the error, and `missingFonts` when a font
79
+ was not supplied, so an app can load those fonts and render again.
80
+
81
+ ```js
82
+ import { KerfError, render } from '@mylasertools/kerfscript';
83
+
84
+ try {
85
+ render(source, { fonts });
86
+ } catch (e) {
87
+ if (e instanceof KerfError && e.missingFonts) {
88
+ // load e.missingFonts, then render again
89
+ }
90
+ }
91
+ ```
92
+
93
+ ## Running untrusted code
94
+
95
+ Programs cannot read files or the network: `use` and `include` reach only the
96
+ standard library and whatever your `resolve` returns. Step and recursion limits
97
+ stop runaway programs. A render is still ordinary synchronous work, so run
98
+ it in a web worker, and stop the worker if it takes too long.
package/docs/kerf.md ADDED
@@ -0,0 +1,70 @@
1
+ # Kerf
2
+
3
+ The laser beam burns away a thin line of material as it cuts. That width is
4
+ the **kerf**, usually somewhere between 0.05 and 0.3 mm depending on the
5
+ machine, the lens, the material and its thickness. Without compensation every
6
+ part comes out smaller than drawn by about one kerf, and every hole bigger.
7
+ For a sign that hardly matters. For finger joints and press fits it decides
8
+ whether the box holds together.
9
+
10
+ ## Setting it
11
+
12
+ ```kerf
13
+ $kerf = 0.15;
14
+ ```
15
+
16
+ KerfScript offsets every cut outline outward by half the kerf when it writes
17
+ the file. The beam then runs half a kerf outside the part and burns away
18
+ material that was never part of it, so the part ends up the size you typed.
19
+ Holes are offset inward the same way, so they end up the size you typed too.
20
+
21
+ Only closed outlines on cut layers are offset. Engraving, scoring and open cut
22
+ lines (like a living hinge) are left as drawn.
23
+
24
+ You can set the kerf for one material only, together with its thickness:
25
+
26
+ ```kerf
27
+ material(thickness = 4, kerf = 0.12, name = "birch") {
28
+ part("side", qty = 2) finger_rect([100, 60], "out");
29
+ }
30
+ ```
31
+
32
+ On the command line, `--kerf 0.1` overrides the value for every part.
33
+
34
+ ## Measuring your kerf
35
+
36
+ 1. Cut the [calibration square](../examples/calibration-square.kerf) with
37
+ `$kerf = 0`.
38
+ 2. Measure the outside of the square with calipers, across the middle.
39
+ 3. Your kerf is `100 - measured`. If the square measures 99.82 mm, use
40
+ `$kerf = 0.18`.
41
+ 4. Cut it again with that value. The square should now be 100 mm and the hole
42
+ 20 mm. If the square is still small and the hole big, raise `$kerf` a
43
+ little; if the square is big, lower it.
44
+
45
+ Measure each material you use. Thicker material usually has a wider kerf, and
46
+ the kerf can differ between the top and bottom face.
47
+
48
+ ## Checking a fit
49
+
50
+ For joints, the [kerf and fit test](../examples/kerf-test.kerf) cuts a row of
51
+ slots from slightly narrower to slightly wider than `$thickness`. Push a scrap
52
+ of the same sheet into each slot:
53
+
54
+ - if the slot marked `0` is snug, your kerf and thickness are right;
55
+ - if a `+` slot fits best, the sheet is thicker than `$thickness` says
56
+ (plywood often is);
57
+ - if a `-` slot fits best, it is thinner.
58
+
59
+ Set `$thickness` to the thickness you measured rather than the one on the
60
+ label, and joints follow.
61
+
62
+ ## Limits
63
+
64
+ - A hole, slot or notch narrower than the kerf cannot be cut: the beam is
65
+ wider than the gap, so compensation closes it. KerfScript warns when that
66
+ happens to a hole.
67
+ - Thin bridges and fingers come out the right size but are fragile, and can
68
+ char in thin material. Keep them several times wider than the kerf.
69
+ - The beam is not perfectly straight in thick material, so cut faces taper a
70
+ little. Compensation works on the average width.
package/docs/layers.md ADDED
@@ -0,0 +1,74 @@
1
+ # Layers
2
+
3
+ Every shape in KerfScript is on a layer, and the layer decides what the
4
+ laser does with it. Shapes that are not wrapped in a layer module are on
5
+ `cut`.
6
+
7
+ ## The built-in layers
8
+
9
+ | Layer | Wrap shapes in | Colour in the file | What the laser does |
10
+ | --------- | -------------- | ------------------ | ------------------------------------------------- |
11
+ | `engrave` | `engrave()` | black `#000000` | engraves the area of the shapes |
12
+ | `score` | `score()` | blue `#0000ff` | marks lines and outlines without cutting through |
13
+ | `cut` | `cut()` | red `#ff0000` | cuts the outlines through, with kerf compensation |
14
+ | `guide` | `guide()` | light blue | nothing; shown only when you ask for guide lines |
15
+
16
+ ```kerf
17
+ difference() {
18
+ circle(d = 90);
19
+ circle(d = 6);
20
+ }
21
+ engrave() difference() { circle(d = 74); circle(d = 68); }
22
+ score() circle(d = 84);
23
+ ```
24
+
25
+ `#` and `%` in front of a module call move it to the guide layer, which is
26
+ handy for checking where something is without cutting it.
27
+
28
+ ## Areas and lines
29
+
30
+ Layers hold two kinds of geometry:
31
+
32
+ - **Areas** come from shapes like `rect()`, `circle()` and `text()`. On
33
+ `engrave` the area is filled; on `cut` and `score` its outline is followed.
34
+ - **Lines** come from `line()`, `polyline()`, `arc()` and `living_hinge()`.
35
+ They are followed as they are, on any layer. On `cut` they are cut through,
36
+ which is how a living hinge is made.
37
+
38
+ `stroke(width)` turns lines into areas, for engraving a line of a given
39
+ width. `outline()` turns areas into their outline lines.
40
+
41
+ ## The material
42
+
43
+ When a part is finished, KerfScript takes the union of everything on the cut
44
+ layer as the **material**. Then:
45
+
46
+ - engraving and scoring are clipped to the material, so nothing is marked
47
+ inside a hole or off the part;
48
+ - cut lines are clipped to the material too;
49
+ - if the material falls apart into separate pieces, you get a warning,
50
+ because that usually means a missing bridge.
51
+
52
+ ## Your own layers
53
+
54
+ `layer(name, mode, color)` makes a layer of your own, for example a second
55
+ engraving pass at a different power:
56
+
57
+ ```kerf
58
+ rect([60, 40]);
59
+ layer("deep", mode = "fill", color = "#00aa00") translate([10, 10]) rect([20, 20]);
60
+ engrave() translate([40, 20]) circle(d = 12);
61
+ ```
62
+
63
+ Modes are `"cut"`, `"line"` (score), `"fill"` (engrave) and `"guide"`.
64
+
65
+ ## Order in the file
66
+
67
+ Layers are written in this order: engrave, your own layers, score, cut,
68
+ guide. Within the cut layer, holes and inner cuts come before outer outlines,
69
+ so a part does not drop out before its holes are cut.
70
+
71
+ That order is a good default, but it does not control your machine. Most
72
+ laser software sorts and orders operations itself. Check the cut order, and
73
+ set power, speed and passes for each layer, in your laser software before you
74
+ run the job.
@@ -0,0 +1,67 @@
1
+ # Coming from OpenSCAD
2
+
3
+ KerfScript borrows OpenSCAD's syntax on purpose: if you have written
4
+ OpenSCAD, you can read KerfScript and write it within minutes. It is not a
5
+ drop-in replacement. It only makes flat parts, and a few rules are different.
6
+ OpenSCAD files do not run unchanged.
7
+
8
+ ## The same
9
+
10
+ - Statements, modules, functions, `for`, `if`, `let`, `each`, list
11
+ comprehensions, ranges like `[0:2:10]`, function literals.
12
+ - `children()`, `children(i)` and `$children`.
13
+ - Special variables that start with `$` are dynamically scoped, and `$fn`,
14
+ `$fa` and `$fs` set curve resolution.
15
+ - 2D shapes: `square()` (also called `rect()`), `circle(r)` or `circle(d =)`,
16
+ `polygon(points, paths)`, `text()`.
17
+ - Transforms: `translate`, `rotate`, `scale`, `mirror`, `multmatrix`.
18
+ - Combining: `union`, `difference`, `intersection`, `hull`, `offset(r)`,
19
+ `offset(delta, chamfer)`.
20
+ - `echo()`, `assert()`, `use <...>` and `include <...>`.
21
+ - Customizer comments: `// [40:5:400]`, `/* [Group] */`, `/* [Hidden] */`,
22
+ and captions on the line above. Tools that read OpenSCAD settings read
23
+ these.
24
+
25
+ ## Different
26
+
27
+ | | OpenSCAD | KerfScript |
28
+ | ----------- | --------------------------------------------- | --------------------------------------------------------------- |
29
+ | Output | a solid, as STL, 3MF and more | a cut file, as SVG or DXF |
30
+ | Dimensions | 3D, and 2D for export | 2D only |
31
+ | Assignments | the last one in a scope wins everywhere in it | run in order; a later one takes effect from that line |
32
+ | Errors | many mistakes give `undef` and a warning | type mistakes stop the program, naming the line |
33
+ | `color()` | colours a shape | not available; use `cut()`, `score()`, `engrave()` or `layer()` |
34
+ | Fonts | system fonts | only fonts you pass in, so a file renders the same everywhere |
35
+ | Libraries | any file on disk | the standard library and whatever the host allows |
36
+
37
+ ## Not in KerfScript
38
+
39
+ 3D modules (`cube`, `sphere`, `cylinder`, `polyhedron`,
40
+ `linear_extrude`, `rotate_extrude`, `projection`), `minkowski`, `resize`,
41
+ `color`, `import`, `surface` and `render`. Each stops with an error that
42
+ names it, so you find out at once.
43
+
44
+ ## Only in KerfScript
45
+
46
+ - Layers: `cut()`, `score()`, `engrave()`, `guide()` and `layer()`.
47
+ See [Layers](layers.md).
48
+ - Kerf compensation with `$kerf`. See [Kerf](kerf.md).
49
+ - Parts, quantities, materials and sheet packing: `part()`, `material()`,
50
+ `$sheet`, `$gap`. See [Parts and sheets](parts-and-sheets.md).
51
+ - Joinery that reads `$thickness`: `finger_rect`, `finger_holes`, `tslot`,
52
+ `living_hinge`.
53
+ - Lines as well as areas: `line()`, `polyline()`, `arc()`, `path()`,
54
+ `stroke()` and `outline()`.
55
+ - Shapes OpenSCAD lacks: `ellipse`, `regular_polygon`, `star`, rounded
56
+ `rect(r =)`.
57
+ - `text_width()` and `text_metrics()`, to size a part to its text.
58
+
59
+ ## Porting a 2D design
60
+
61
+ 1. Drop `linear_extrude()` and any 3D parts.
62
+ 2. Replace `color()` with the layer the shape belongs on.
63
+ 3. Check assignments: code that relied on a later assignment overriding an
64
+ earlier one should assign once.
65
+ 4. Pass the fonts your `text()` calls use.
66
+ 5. Add `$kerf` and `$thickness`, and replace hand-made finger joints with
67
+ `finger_rect()` if you want them to follow the material.
@@ -0,0 +1,68 @@
1
+ # Parts and sheets
2
+
3
+ A design often has more than one piece. KerfScript lets you name each piece,
4
+ say how many you need and what it is cut from, and lays them out on sheets.
5
+
6
+ ## Parts
7
+
8
+ ```kerf
9
+ part("side", qty = 2) rect([100, 60]);
10
+ part("base") rect([100, 100]);
11
+ ```
12
+
13
+ `part(name, qty = 1)` makes a named part. Everything inside it is one piece
14
+ with its own layers. Shapes outside any part form one part called `part`.
15
+
16
+ Parts show up in the part list with their size and cut length, which the
17
+ playground and `kerf check` print.
18
+
19
+ ## Materials
20
+
21
+ Each part records `$thickness`, `$kerf` and `$material` where it is made.
22
+ `material()` sets all three for the parts inside it:
23
+
24
+ ```kerf
25
+ material(thickness = 3, kerf = 0.15, name = "plywood") {
26
+ part("front") rect([100, 60]);
27
+ part("back") rect([100, 60]);
28
+ }
29
+ material(thickness = 2, kerf = 0.1, name = "acrylic") {
30
+ part("window") rect([80, 40]);
31
+ }
32
+ ```
33
+
34
+ ## Sheets
35
+
36
+ With the default `$layout = "pack"`, KerfScript:
37
+
38
+ 1. groups parts by material and thickness,
39
+ 2. copies each part `qty` times,
40
+ 3. turns a part 90° when that makes it fit,
41
+ 4. packs them in rows onto sheets of `$sheet` (600 by 400 mm by default),
42
+ with `$gap` millimetres between parts and around the edge.
43
+
44
+ A part bigger than the sheet gives a warning. With `$layout = "none"` parts
45
+ stay where your program put them.
46
+
47
+ ```kerf
48
+ $sheet = [300, 200];
49
+ $gap = 4;
50
+ ```
51
+
52
+ ## One file per sheet
53
+
54
+ The design above makes two sheets: one of plywood and one of acrylic. The
55
+ combined SVG shows every sheet stacked one above the other, which is useful
56
+ for a preview but is **not** a cutting job: the sheets are different
57
+ materials.
58
+
59
+ Cut each sheet as its own job:
60
+
61
+ - On the command line, `--split` writes one file per sheet
62
+ (`design-1.svg`, `design-2.svg`, ...). `kerf check` lists the sheets with
63
+ their material and thickness.
64
+ - From JavaScript, `result.sheets` has an SVG and a DXF for each sheet, with
65
+ its `material` and `thickness`.
66
+
67
+ Before cutting, check that each file's material and thickness match the
68
+ sheet in your machine.
@@ -0,0 +1,43 @@
1
+ # Versions
2
+
3
+ KerfScript has two version numbers.
4
+
5
+ - The **language version** (now 0.1) covers what `.kerf` files mean: the
6
+ syntax, the built-in modules and functions, and the rules for layers, kerf
7
+ and parts. The [language reference](../LANGUAGE.md) describes one language
8
+ version.
9
+ - The **package version** (now 0.2.0) is the version of the interpreter, the
10
+ `kerf` command and the JavaScript API. It changes more often: bug fixes,
11
+ new output options and API additions do not change the language.
12
+
13
+ The site footer, `kerf --version` and the `VERSION` and `LANGUAGE_VERSION`
14
+ exports show both.
15
+
16
+ ## Before 1.0
17
+
18
+ KerfScript is young, and the language may still change before 1.0. What we
19
+ promise in the meantime:
20
+
21
+ - **Changes are written down.** Every change that can alter what a file
22
+ produces is listed in the changelog under the version that made it.
23
+ - **Files keep running where we can manage it.** A program that worked keeps
24
+ working, or stops with an error that says what to change. It does not
25
+ silently start cutting something different.
26
+ - **Geometry changes are called out.** If the same file starts producing
27
+ different geometry, for example after a packing or text layout fix, the
28
+ changelog says which designs are affected.
29
+ - **Breaking changes raise the language version.** Package releases within
30
+ one language version do not remove or rename anything in the language.
31
+
32
+ ## From 1.0
33
+
34
+ From language version 1.0, `.kerf` files written for 1.x keep producing the
35
+ same parts in every later 1.x interpreter, apart from bug fixes listed in the
36
+ changelog. New features are additions. Anything that would change existing
37
+ files waits for 2.0.
38
+
39
+ ## Pinning a version
40
+
41
+ Hosts that store designs, like MyLaserTools, record which interpreter
42
+ version a design was published with, so a stored design can be checked
43
+ against later versions before it is upgraded.
package/package.json CHANGED
@@ -1,6 +1,87 @@
1
1
  {
2
2
  "name": "@mylasertools/kerfscript",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.2.0",
4
+ "description": "KerfScript: a programming language for laser cutting. Write parametric 2D parts with cut, score and engrave layers, kerf compensation and joinery, and export SVG or DXF.",
5
+ "type": "module",
6
+ "license": "AGPL-3.0-only",
7
+ "author": "MyLaserTools",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/mylasertools-com/kerfscript.git"
11
+ },
12
+ "bugs": "https://github.com/mylasertools-com/kerfscript/issues",
13
+ "keywords": [
14
+ "kerfscript",
15
+ "laser-cutting",
16
+ "parametric",
17
+ "cad",
18
+ "programming-language",
19
+ "svg",
20
+ "dxf",
21
+ "finger-joints",
22
+ "living-hinge",
23
+ "kerf"
24
+ ],
25
+ "sideEffects": false,
26
+ "main": "./dist/index.cjs",
27
+ "module": "./dist/index.js",
28
+ "types": "./dist/index.d.ts",
29
+ "exports": {
30
+ ".": {
31
+ "import": {
32
+ "types": "./dist/index.d.ts",
33
+ "default": "./dist/index.js"
34
+ },
35
+ "require": {
36
+ "types": "./dist/index.d.cts",
37
+ "default": "./dist/index.cjs"
38
+ }
39
+ },
40
+ "./cli": "./dist/cli.js",
41
+ "./package.json": "./package.json"
42
+ },
43
+ "bin": {
44
+ "kerf": "dist/cli.js"
45
+ },
46
+ "files": [
47
+ "dist",
48
+ "README.md",
49
+ "docs",
50
+ "LANGUAGE.md",
51
+ "LICENSE",
52
+ "COMMERCIAL-LICENSE.md",
53
+ "THIRD-PARTY-NOTICES.md",
54
+ "CHANGELOG.md",
55
+ "TRADEMARKS.md",
56
+ "CLA.md"
57
+ ],
58
+ "engines": {
59
+ "node": ">=20"
60
+ },
61
+ "publishConfig": {
62
+ "access": "public",
63
+ "registry": "https://registry.npmjs.org/"
64
+ },
65
+ "scripts": {
66
+ "build": "node scripts/stdlib.mjs && tsc -p tsconfig.json && node scripts/build.mjs",
67
+ "test": "node --test",
68
+ "check": "npm run build && npm test",
69
+ "examples": "node scripts/examples.mjs",
70
+ "site": "npm run build && npm --prefix site run build",
71
+ "site:serve": "npm --prefix site run preview",
72
+ "prepack": "npm run check",
73
+ "format": "prettier --write .",
74
+ "format:check": "prettier --check .",
75
+ "compat": "node scripts/compat.mjs"
76
+ },
77
+ "devDependencies": {
78
+ "@types/node": "20.19.43",
79
+ "clipper2-ts": "2.0.1-18",
80
+ "esbuild": "0.25.12",
81
+ "marked": "15.0.12",
82
+ "opentype.js": "1.3.4",
83
+ "prettier": "3.6.2",
84
+ "typescript": "5.9.3"
85
+ },
86
+ "homepage": "https://kerfscript.mylasertools.com"
87
+ }