cadorange 0.1.0 → 0.3.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.
package/dist/cli.d.ts ADDED
@@ -0,0 +1,9 @@
1
+ //#region src/cli.d.ts
2
+ /**
3
+ * `cado` CLI — run / describe / export models from the command line.
4
+ *
5
+ * Skeleton stage: only --help works; subcommands land with the M0 milestone.
6
+ */
7
+ /** Entry point, exported for tests. Returns the desired process exit code. */
8
+ export declare function main(argv: string[]): number;
9
+ //#endregion
package/dist/cli.js ADDED
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env node
2
+ //#region src/cli.ts
3
+ /**
4
+ * `cado` CLI — run / describe / export models from the command line.
5
+ *
6
+ * Skeleton stage: only --help works; subcommands land with the M0 milestone.
7
+ */
8
+ const USAGE = `cado — agent-native CAD CLI (M0 skeleton)
9
+
10
+ Usage:
11
+ cado run <model.ts> [--render iso,top,front] [--export step,stl]
12
+ cado describe <model.ts> [--json]
13
+ cado --help
14
+
15
+ Subcommands are not implemented yet. See the roadmap in the repository README.
16
+ `;
17
+ /** Entry point, exported for tests. Returns the desired process exit code. */
18
+ function main(argv) {
19
+ const [cmd] = argv;
20
+ if (!cmd || cmd === "--help" || cmd === "-h") {
21
+ process.stdout.write(USAGE);
22
+ return cmd ? 0 : 1;
23
+ }
24
+ process.stderr.write(`cado: "${cmd}" is not implemented yet (M0 skeleton)\n`);
25
+ return 1;
26
+ }
27
+ if (typeof process !== "undefined" && (process.argv[1]?.endsWith("cli.ts") || process.argv[1]?.endsWith("cli.js"))) process.exitCode = main(process.argv.slice(2));
28
+ //#endregion
29
+ export { main };
@@ -80,12 +80,16 @@ type CurveKind = "line" | "circle" | "ellipse" | "bspline" | "other";
80
80
  /**
81
81
  * Metadata for one face, normalized from the kernel's interrogation output.
82
82
  * `index` is the kernel's 1-based selection index (fillet/draft/shell targets).
83
+ *
84
+ * `center` is a reference point on the face's axis of symmetry where one
85
+ * exists (kernel `axisPoint` — cylinder/cone/sphere/torus), the integral
86
+ * centroid for planes and generic surfaces. Selection semantics key on it;
87
+ * occt.ts ≥0.10.0 reports both, we keep the axis-stable one.
83
88
  */
84
89
  interface FaceMeta {
85
90
  readonly index: number;
86
91
  readonly surface: SurfaceKind;
87
92
  readonly area: number;
88
- /** A reference point: plane origin, cylinder/cone axis point, sphere/torus center. */
89
93
  readonly center: Vec3;
90
94
  /** Plane only — unit normal. */
91
95
  readonly normal?: Vec3;
@@ -99,7 +103,11 @@ interface EdgeMeta {
99
103
  readonly index: number;
100
104
  readonly curve: CurveKind;
101
105
  readonly length: number;
102
- /** Line: midpoint. Circle/ellipse: center. Others: bounding-box midpoint. */
106
+ /**
107
+ * Line: midpoint. Circle/ellipse: the underlying circle/ellipse center
108
+ * (kernel `axisPoint`, not the arc's integral centroid — matches
109
+ * build123d selector semantics). Others: integral centroid.
110
+ */
103
111
  readonly center: Vec3;
104
112
  /** Line only — unit direction (start → end). */
105
113
  readonly direction?: Vec3;
@@ -146,7 +154,14 @@ interface Kernel {
146
154
  makeSphere(radius: number, at?: Vec3): ShapeHandle;
147
155
  makeCone(radius1: number, radius2: number, height: number, at?: Vec3): ShapeHandle;
148
156
  makeTorus(radius1: number, radius2: number, at?: Vec3): ShapeHandle;
149
- boolean(op: "fuse" | "cut" | "common", a: ShapeHandle, b: ShapeHandle): ShapeHandle;
157
+ /**
158
+ * Booleans clean by default (UnifySameDomain — same as build123d/CadQuery):
159
+ * coplanar faces merge, collinear edges join. `clean: false` keeps raw
160
+ * fragment topology for callers that count fragments.
161
+ */
162
+ boolean(op: "fuse" | "cut" | "common", a: ShapeHandle, b: ShapeHandle, opts?: {
163
+ clean?: boolean;
164
+ }): ShapeHandle;
150
165
  /** `edgeIndices` are 1-based indices into `meta(s).edges`. Empty = all edges. */
151
166
  fillet(s: ShapeHandle, radius: number, edgeIndices: number[]): ShapeHandle;
152
167
  chamfer(s: ShapeHandle, distance: number, edgeIndices: number[]): ShapeHandle;
@@ -200,10 +215,17 @@ declare class Shape {
200
215
  * records (docs/occt-requirements.md R5). Will land with that kernel API.
201
216
  */
202
217
  vertices(): ShapeList<never>;
203
- cut(b: Shape): Solid;
204
- fuse(b: Shape): Solid;
218
+ /** See `Kernel.boolean` — cleaned by default (UnifySameDomain). */
219
+ cut(b: Shape, opts?: {
220
+ clean?: boolean;
221
+ }): Solid;
222
+ fuse(b: Shape, opts?: {
223
+ clean?: boolean;
224
+ }): Solid;
205
225
  /** build123d's `intersect` (OCCT `common`). */
206
- common(b: Shape): Solid;
226
+ common(b: Shape, opts?: {
227
+ clean?: boolean;
228
+ }): Solid;
207
229
  /** Immediate-bake transform (occt.ts has no lazy location chain). */
208
230
  translate(by: Vec3): Solid;
209
231
  fillet(edges: ShapeList<Edge> | readonly Edge[], radius: number): Solid;
@@ -0,0 +1,108 @@
1
+ import { a as ShapeList, f as ShapeHandle, i as Shape, n as Edge, o as Solid, r as Face, y as Loc } from "./index-DceghC4N.js";
2
+ import "occt.ts";
3
+ //#region src/io/index.d.ts
4
+ type ExportFormat = "step" | "stl" | "glb";
5
+ declare function exportStep(s: Shape): Uint8Array;
6
+ declare function exportStl(s: Shape, tolerance?: number): string;
7
+ declare function exportGlb(s: Shape): Uint8Array;
8
+ declare function importStep(data: Uint8Array | string): Promise<Solid>;
9
+ /** Writes a shape to disk (Node). Extension picks the format. */
10
+ declare function exportShape(s: Shape, path: string, opts?: {
11
+ tolerance?: number;
12
+ }): Promise<void>;
13
+ //#endregion
14
+ //#region src/kernel/occt.d.ts
15
+ interface InitOptions {
16
+ /** Explicit URL or path to the OCCT WASM binary (file, http(s) or data:). */
17
+ wasmUrl?: string;
18
+ }
19
+ /** Loads the OCCT WASM kernel exactly once per process (idempotent). */
20
+ declare function init(opts?: InitOptions): Promise<void>;
21
+ //#endregion
22
+ //#region src/ops/index.d.ts
23
+ declare function fuse(a: Solid, b: Shape, opts?: {
24
+ clean?: boolean;
25
+ }): Solid;
26
+ declare function cut(a: Solid, b: Shape, opts?: {
27
+ clean?: boolean;
28
+ }): Solid;
29
+ /** build123d `intersect` — OCCT `common`. */
30
+ declare function intersect(a: Solid, b: Shape, opts?: {
31
+ clean?: boolean;
32
+ }): Solid;
33
+ /** Keep the OCCT name for code translated from CadQuery. */
34
+ declare const common: typeof intersect;
35
+ declare function fillet(s: Shape, edges: ShapeList<Edge> | readonly Edge[], radius: number): Solid;
36
+ /** Equal-distance chamfer; asymmetric needs kernel support (R3). */
37
+ declare function chamfer(s: Shape, edges: ShapeList<Edge> | readonly Edge[], distance: number): Solid;
38
+ declare function translate(s: Shape, by: readonly [number, number, number]): Solid;
39
+ /** M1: extrude a 2D sketch into a solid. */
40
+ declare function extrude(_sketch: unknown, _height: number): Solid;
41
+ /** M1: revolve a 2D sketch around an axis. */
42
+ declare function revolve(_sketch: unknown, _axis: unknown, _angle?: number): Solid;
43
+ //#endregion
44
+ //#region src/primitives/index.d.ts
45
+ declare function Box(dx: number, dy: number, dz: number, loc?: Loc): Solid;
46
+ declare function Cylinder(opts: {
47
+ radius: number;
48
+ height: number;
49
+ loc?: Loc;
50
+ }): Solid;
51
+ declare function Sphere(opts: {
52
+ radius: number;
53
+ loc?: Loc;
54
+ }): Solid;
55
+ declare function Cone(opts: {
56
+ radius1: number;
57
+ radius2: number;
58
+ height: number;
59
+ loc?: Loc;
60
+ }): Solid;
61
+ declare function Torus(opts: {
62
+ radius1: number;
63
+ radius2: number;
64
+ loc?: Loc;
65
+ }): Solid;
66
+ //#endregion
67
+ //#region src/record.d.ts
68
+ /**
69
+ * Op recording — the day-one rule from docs/architecture.md §3.3:
70
+ * every mutating core operation goes through `record()`, so the runtime
71
+ * Session/OpLog can observe, snapshot and replay the exact same stream
72
+ * regardless of which API style (core algebra or workplane facade) produced it.
73
+ *
74
+ * With no subscribers installed this is a transparent pass-through.
75
+ */
76
+ interface OpRecord {
77
+ /** Monotonic, process-wide — the id the OpLog keys snapshots by. */
78
+ readonly id: number;
79
+ readonly type: string;
80
+ readonly args: unknown;
81
+ }
82
+ type OpStatus = "done" | "error";
83
+ interface OpEvent {
84
+ readonly op: OpRecord;
85
+ readonly status: OpStatus;
86
+ readonly result?: ShapeHandle;
87
+ readonly error?: unknown;
88
+ }
89
+ type OpListener = (event: OpEvent) => void;
90
+ /** Subscribe to every recorded operation. Returns an unsubscribe function. */
91
+ declare function onOp(listener: OpListener): () => void;
92
+ /**
93
+ * Runs `run()` and records it as one op. Errors propagate unchanged after
94
+ * being recorded — structured error mapping (runtime) subscribes via onOp.
95
+ */
96
+ declare function record<T>(type: string, args: unknown, run: () => T): T;
97
+ //#endregion
98
+ //#region src/selectors/index.d.ts
99
+ type SubShape = Face | Edge;
100
+ interface Selector {
101
+ /** The source string, for error messages and op-log readability. */
102
+ readonly source: string;
103
+ select(items: readonly SubShape[]): SubShape[];
104
+ }
105
+ /** Parses a CadQuery-style selector string into an executable selector. */
106
+ declare function parseSelector(source: string): Selector;
107
+ //#endregion
108
+ export { exportStl as A, translate as C, exportGlb as D, ExportFormat as E, exportShape as O, revolve as S, init as T, cut as _, OpListener as a, fuse as b, onOp as c, Cone as d, Cylinder as f, common as g, chamfer as h, OpEvent as i, importStep as j, exportStep as k, record as l, Torus as m, SubShape as n, OpRecord as o, Sphere as p, parseSelector as r, OpStatus as s, Selector as t, Box as u, extrude as v, InitOptions as w, intersect as x, fillet as y };
package/dist/index.d.ts CHANGED
@@ -1,102 +1,3 @@
1
- import { C as Vec3, E as v, S as Plane, T as planeFrom, _ as AxisName, a as ShapeList, b as Location, c as EdgeMeta, d as Kernel, f as ShapeHandle, g as Axis3, h as Axis, i as Shape, l as FaceMeta, m as SurfaceKind, n as Edge, o as Solid, p as ShapeMeta, r as Face, s as CurveKind, t as Describe, u as HoleMeta, v as BBox, w as axisByName, x as Mesh, y as Loc } from "./index-CBGNe8Hy.js";
2
- import "occt.ts";
3
- //#region src/io/index.d.ts
4
- type ExportFormat = "step" | "stl" | "glb";
5
- export declare function exportStep(s: Shape): Uint8Array;
6
- export declare function exportStl(s: Shape, tolerance?: number): string;
7
- export declare function exportGlb(s: Shape): Uint8Array;
8
- export declare function importStep(data: Uint8Array | string): Promise<Solid>;
9
- /** Writes a shape to disk (Node). Extension picks the format. */
10
- export declare function exportShape(s: Shape, path: string, opts?: {
11
- tolerance?: number;
12
- }): Promise<void>;
13
- //#endregion
14
- //#region src/kernel/occt.d.ts
15
- interface InitOptions {
16
- /** Explicit URL or path to the OCCT WASM binary (file, http(s) or data:). */
17
- wasmUrl?: string;
18
- }
19
- /** Loads the OCCT WASM kernel exactly once per process (idempotent). */
20
- export declare function init(opts?: InitOptions): Promise<void>;
21
- //#endregion
22
- //#region src/ops/index.d.ts
23
- export declare function fuse(a: Solid, b: Shape): Solid;
24
- export declare function cut(a: Solid, b: Shape): Solid;
25
- /** build123d `intersect` — OCCT `common`. */
26
- export declare function intersect(a: Solid, b: Shape): Solid;
27
- /** Keep the OCCT name for code translated from CadQuery. */
28
- export declare const common: typeof intersect;
29
- export declare function fillet(s: Shape, edges: ShapeList<Edge> | readonly Edge[], radius: number): Solid;
30
- /** Equal-distance chamfer; asymmetric needs kernel support (R3). */
31
- export declare function chamfer(s: Shape, edges: ShapeList<Edge> | readonly Edge[], distance: number): Solid;
32
- export declare function translate(s: Shape, by: readonly [number, number, number]): Solid;
33
- /** M1: extrude a 2D sketch into a solid. */
34
- export declare function extrude(_sketch: unknown, _height: number): Solid;
35
- /** M1: revolve a 2D sketch around an axis. */
36
- export declare function revolve(_sketch: unknown, _axis: unknown, _angle?: number): Solid;
37
- //#endregion
38
- //#region src/primitives/index.d.ts
39
- export declare function Box(dx: number, dy: number, dz: number, loc?: Loc): Solid;
40
- export declare function Cylinder(opts: {
41
- radius: number;
42
- height: number;
43
- loc?: Loc;
44
- }): Solid;
45
- export declare function Sphere(opts: {
46
- radius: number;
47
- loc?: Loc;
48
- }): Solid;
49
- export declare function Cone(opts: {
50
- radius1: number;
51
- radius2: number;
52
- height: number;
53
- loc?: Loc;
54
- }): Solid;
55
- export declare function Torus(opts: {
56
- radius1: number;
57
- radius2: number;
58
- loc?: Loc;
59
- }): Solid;
60
- //#endregion
61
- //#region src/record.d.ts
62
- /**
63
- * Op recording — the day-one rule from docs/architecture.md §3.3:
64
- * every mutating core operation goes through `record()`, so the runtime
65
- * Session/OpLog can observe, snapshot and replay the exact same stream
66
- * regardless of which API style (core algebra or workplane facade) produced it.
67
- *
68
- * With no subscribers installed this is a transparent pass-through.
69
- */
70
- interface OpRecord {
71
- /** Monotonic, process-wide — the id the OpLog keys snapshots by. */
72
- readonly id: number;
73
- readonly type: string;
74
- readonly args: unknown;
75
- }
76
- type OpStatus = "done" | "error";
77
- interface OpEvent {
78
- readonly op: OpRecord;
79
- readonly status: OpStatus;
80
- readonly result?: ShapeHandle;
81
- readonly error?: unknown;
82
- }
83
- type OpListener = (event: OpEvent) => void;
84
- /** Subscribe to every recorded operation. Returns an unsubscribe function. */
85
- export declare function onOp(listener: OpListener): () => void;
86
- /**
87
- * Runs `run()` and records it as one op. Errors propagate unchanged after
88
- * being recorded — structured error mapping (runtime) subscribes via onOp.
89
- */
90
- export declare function record<T>(type: string, args: unknown, run: () => T): T;
91
- //#endregion
92
- //#region src/selectors/index.d.ts
93
- type SubShape = Face | Edge;
94
- interface Selector {
95
- /** The source string, for error messages and op-log readability. */
96
- readonly source: string;
97
- select(items: readonly SubShape[]): SubShape[];
98
- }
99
- /** Parses a CadQuery-style selector string into an executable selector. */
100
- export declare function parseSelector(source: string): Selector;
101
- //#endregion
102
- export { Axis, type Axis3, type AxisName, type BBox, type CurveKind, type Describe, Edge, type EdgeMeta, type ExportFormat, Face, type FaceMeta, type HoleMeta, type InitOptions, type Kernel, type Loc, type Location, type Mesh, type OpEvent, type OpListener, type OpRecord, type OpStatus, type Plane, type Selector, Shape, type ShapeHandle, ShapeList, type ShapeMeta, Solid, type SubShape, type SurfaceKind, type Vec3, axisByName, planeFrom, v };
1
+ import { C as Vec3, E as v, S as Plane, T as planeFrom, _ as AxisName, a as ShapeList, b as Location, c as EdgeMeta, d as Kernel, f as ShapeHandle, g as Axis3, h as Axis, i as Shape, l as FaceMeta, m as SurfaceKind, n as Edge, o as Solid, p as ShapeMeta, r as Face, s as CurveKind, t as Describe, u as HoleMeta, v as BBox, w as axisByName, x as Mesh, y as Loc } from "./index-DceghC4N.js";
2
+ import { A as exportStl, C as translate, D as exportGlb, E as ExportFormat, O as exportShape, S as revolve, T as init, _ as cut, a as OpListener, b as fuse, c as onOp, d as Cone, f as Cylinder, g as common, h as chamfer, i as OpEvent, j as importStep, k as exportStep, l as record, m as Torus, n as SubShape, o as OpRecord, p as Sphere, r as parseSelector, s as OpStatus, t as Selector, u as Box, v as extrude, w as InitOptions, x as intersect, y as fillet } from "./index-DzJsXME9.js";
3
+ export { Axis, type Axis3, type AxisName, type BBox, Box, Cone, type CurveKind, Cylinder, type Describe, Edge, type EdgeMeta, type ExportFormat, Face, type FaceMeta, type HoleMeta, type InitOptions, type Kernel, type Loc, type Location, type Mesh, type OpEvent, type OpListener, type OpRecord, type OpStatus, type Plane, type Selector, Shape, type ShapeHandle, ShapeList, type ShapeMeta, Solid, Sphere, type SubShape, type SurfaceKind, Torus, type Vec3, axisByName, chamfer, common, cut, exportGlb, exportShape, exportStep, exportStl, extrude, fillet, fuse, importStep, init, intersect, onOp, parseSelector, planeFrom, record, revolve, translate, v };
package/dist/index.js CHANGED
@@ -1,28 +1,16 @@
1
- import { a as importStep, i as exportStl, n as exportShape, r as exportStep, t as exportGlb } from "./io-N0C2K1hO.js";
2
- import { _ as Axis, a as Sphere, b as v, c as Face, d as Solid, g as init, i as Cylinder, l as Shape, m as record, n as Box, o as Torus, p as onOp, r as Cone, s as Edge, t as parseSelector, u as ShapeList, v as axisByName, y as planeFrom } from "./selectors-CEhRDaf2.js";
3
- //#region src/util.ts
4
- /** Thrown by every skeleton stub until the real M0 implementation lands. */
5
- var NotImplementedError = class extends Error {
6
- constructor(what) {
7
- super(`${what} is not implemented yet — this is the M0 repository skeleton.`);
8
- this.name = "NotImplementedError";
9
- }
10
- };
11
- /** Stub body helper: keeps signatures real while bodies wait for M0. */
12
- function todo(what) {
13
- throw new NotImplementedError(what);
14
- }
15
- //#endregion
1
+ import { a as importStep, i as exportStl, n as exportShape, r as exportStep, t as exportGlb } from "./io-DD2D1UYF.js";
2
+ import { _ as Axis, a as Sphere, b as v, c as Face, d as Solid, g as init, i as Cylinder, l as Shape, m as record, n as Box, o as Torus, p as onOp, r as Cone, s as Edge, t as parseSelector, u as ShapeList, v as axisByName, y as planeFrom } from "./selectors-C0-da9aQ.js";
3
+ import { t as todo } from "./util-DeKC5Om9.js";
16
4
  //#region src/ops/index.ts
17
- function fuse(a, b) {
18
- return a.fuse(b);
5
+ function fuse(a, b, opts) {
6
+ return a.fuse(b, opts);
19
7
  }
20
- function cut(a, b) {
21
- return a.cut(b);
8
+ function cut(a, b, opts) {
9
+ return a.cut(b, opts);
22
10
  }
23
11
  /** build123d `intersect` — OCCT `common`. */
24
- function intersect(a, b) {
25
- return a.common(b);
12
+ function intersect(a, b, opts) {
13
+ return a.common(b, opts);
26
14
  }
27
15
  /** Keep the OCCT name for code translated from CadQuery. */
28
16
  const common = intersect;
@@ -1,4 +1,4 @@
1
- import { f as solidFromKernel, h as getKernel, m as record } from "./selectors-CEhRDaf2.js";
1
+ import { f as solidFromKernel, h as getKernel, m as record } from "./selectors-C0-da9aQ.js";
2
2
  //#region \0rolldown/runtime.js
3
3
  var __defProp = Object.defineProperty;
4
4
  var __exportAll = (all, no_symbols) => {
@@ -0,0 +1,14 @@
1
+ //#region src/mcp/index.d.ts
2
+ export interface McpServerOptions {
3
+ name?: string;
4
+ version?: string;
5
+ /** stdio is the only transport planned for M0. */
6
+ transport?: "stdio";
7
+ }
8
+ /** Starts the cadorange MCP server (tools: run, describe, render, export). */
9
+ export declare function startMcpServer(_opts?: McpServerOptions): Promise<void>;
10
+ /** Thrown by every skeleton stub until the real M0 implementation lands. */
11
+ export declare class NotImplementedError extends Error {
12
+ constructor(what: string);
13
+ }
14
+ //#endregion
@@ -0,0 +1,17 @@
1
+ //#region src/mcp/index.ts
2
+ /** Starts the cadorange MCP server (tools: run, describe, render, export). */
3
+ async function startMcpServer(_opts = {}) {
4
+ todo("startMcpServer");
5
+ }
6
+ /** Thrown by every skeleton stub until the real M0 implementation lands. */
7
+ var NotImplementedError = class extends Error {
8
+ constructor(what) {
9
+ super(`${what} is not implemented yet — this is the M0 repository skeleton.`);
10
+ this.name = "NotImplementedError";
11
+ }
12
+ };
13
+ function todo(what) {
14
+ throw new NotImplementedError(what);
15
+ }
16
+ //#endregion
17
+ export { NotImplementedError, startMcpServer };
@@ -0,0 +1,21 @@
1
+ import { i as Shape } from "../index-DceghC4N.js";
2
+ import "../index-DzJsXME9.js";
3
+ //#region src/render/index.d.ts
4
+ export type View = "iso" | "top" | "front" | "back" | "left" | "right" | "bottom";
5
+ export interface RenderOptions {
6
+ views?: View[];
7
+ /** Square output size in pixels (default 512). */
8
+ size?: number;
9
+ format?: "png" | "svg";
10
+ }
11
+ export interface Rendered {
12
+ view: View;
13
+ format: "png" | "svg";
14
+ data: Uint8Array;
15
+ }
16
+ /**
17
+ * Renders a shape from multiple views without a GPU or a browser window,
18
+ * so vision models can check their own work.
19
+ */
20
+ export declare function render(shape: Shape, opts?: RenderOptions): Promise<Rendered[]>;
21
+ //#endregion
@@ -0,0 +1,11 @@
1
+ import { t as todo } from "../util-DeKC5Om9.js";
2
+ //#region src/render/index.ts
3
+ /**
4
+ * Renders a shape from multiple views without a GPU or a browser window,
5
+ * so vision models can check their own work.
6
+ */
7
+ async function render(shape, opts = {}) {
8
+ todo("render");
9
+ }
10
+ //#endregion
11
+ export { render };
@@ -0,0 +1,83 @@
1
+ import { t as Describe } from "../index-DceghC4N.js";
2
+ import "../index-DzJsXME9.js";
3
+ //#region src/runtime/types.d.ts
4
+ type Op = {
5
+ id: number;
6
+ type: string;
7
+ args: Record<string, unknown>;
8
+ inputs: number[];
9
+ };
10
+ interface OpLog {
11
+ ops: Op[];
12
+ append(op: Op): number;
13
+ slice(to: number): OpLog;
14
+ }
15
+ interface Snapshot {
16
+ id: string;
17
+ opIndex: number;
18
+ hash: string;
19
+ }
20
+ /** Enumerable error codes — exhaustiveness matters for eval/RL statistics. */
21
+ type ErrorCode = "NOT_IMPLEMENTED" | "FILLET_RADIUS_TOO_LARGE" | "BOOLEAN_FAILED" | "INVALID_SHAPE" | "INVALID_OP" | "TIMEOUT" | "OUT_OF_MEMORY" | "OP_LIMIT_EXCEEDED" | "UNKNOWN";
22
+ interface OpError {
23
+ code: ErrorCode;
24
+ op?: Op;
25
+ message: string;
26
+ /** Executable fix suggestion, aimed at agents. */
27
+ hint?: string;
28
+ context?: {
29
+ maxRadius?: number;
30
+ failingEdges?: number[];
31
+ };
32
+ }
33
+ type RunResult = {
34
+ ok: true;
35
+ snapshot: Snapshot;
36
+ describe: Describe;
37
+ warnings: string[];
38
+ } | {
39
+ ok: false;
40
+ error: OpError;
41
+ lastGood: Snapshot;
42
+ };
43
+ interface Limits {
44
+ timeoutMs?: number;
45
+ memoryMB?: number;
46
+ maxOps?: number;
47
+ }
48
+ interface SessionOptions {
49
+ limits?: Limits;
50
+ seed?: number;
51
+ }
52
+ //#endregion
53
+ //#region src/runtime/index.d.ts
54
+ export interface RenderOpts {
55
+ views?: string[];
56
+ size?: number;
57
+ format?: "png" | "svg";
58
+ }
59
+ export type ExportFormat = "step" | "stl" | "glb" | "brep";
60
+ /**
61
+ * An agent-facing modeling session.
62
+ *
63
+ * `run` and `apply` both write into the same OpLog; every core op funnels
64
+ * through a single record() entry point so the log is always complete.
65
+ * That invariant is fixed from day one — retrofitting it later is painful.
66
+ */
67
+ export declare class Session {
68
+ static create(_opts?: SessionOptions): Promise<Session>;
69
+ /** Runs TypeScript modeling code in the sandbox. */
70
+ run(_code: string): Promise<RunResult>;
71
+ /** Applies one structured action (same log, no code). */
72
+ apply(_op: Op): Promise<RunResult>;
73
+ /** Cheap: op index plus cached shape hashes, no geometry copy. */
74
+ snapshot(): Snapshot;
75
+ fork(_snap?: Snapshot): Session;
76
+ rollback(_snap: Snapshot): void;
77
+ describe(): Describe;
78
+ render(_opts: RenderOpts): Promise<Uint8Array[]>;
79
+ export(_fmt: ExportFormat): Promise<Uint8Array>;
80
+ get limits(): Limits;
81
+ }
82
+ //#endregion
83
+ export type { ErrorCode, Limits, Op, OpError, OpLog, RunResult, SessionOptions, Snapshot };
@@ -0,0 +1,46 @@
1
+ import { t as todo } from "../util-DeKC5Om9.js";
2
+ //#region src/runtime/index.ts
3
+ /**
4
+ * An agent-facing modeling session.
5
+ *
6
+ * `run` and `apply` both write into the same OpLog; every core op funnels
7
+ * through a single record() entry point so the log is always complete.
8
+ * That invariant is fixed from day one — retrofitting it later is painful.
9
+ */
10
+ var Session = class {
11
+ static async create(_opts = {}) {
12
+ todo("Session.create");
13
+ }
14
+ /** Runs TypeScript modeling code in the sandbox. */
15
+ async run(_code) {
16
+ todo("Session.run");
17
+ }
18
+ /** Applies one structured action (same log, no code). */
19
+ async apply(_op) {
20
+ todo("Session.apply");
21
+ }
22
+ /** Cheap: op index plus cached shape hashes, no geometry copy. */
23
+ snapshot() {
24
+ todo("Session.snapshot");
25
+ }
26
+ fork(_snap) {
27
+ todo("Session.fork");
28
+ }
29
+ rollback(_snap) {
30
+ todo("Session.rollback");
31
+ }
32
+ describe() {
33
+ todo("Session.describe");
34
+ }
35
+ async render(_opts) {
36
+ todo("Session.render");
37
+ }
38
+ async export(_fmt) {
39
+ todo("Session.export");
40
+ }
41
+ get limits() {
42
+ return todo("Session.limits");
43
+ }
44
+ };
45
+ //#endregion
46
+ export { Session };
@@ -226,10 +226,10 @@ var OcctKernel = class {
226
226
  const s = this.#occ.makeTorus(radius1, radius2);
227
227
  return this.#adopt(at ? this.#occ.translate(s, at) : s);
228
228
  }
229
- boolean(op, a, b) {
229
+ boolean(op, a, b, opts) {
230
230
  const ra = this.#raw(a);
231
231
  const rb = this.#raw(b);
232
- const result = op === "fuse" ? this.#occ.fuse(ra, rb) : op === "cut" ? this.#occ.cut(ra, rb) : this.#occ.common(ra, rb);
232
+ const result = op === "fuse" ? this.#occ.fuse(ra, rb, opts) : op === "cut" ? this.#occ.cut(ra, rb, opts) : this.#occ.common(ra, rb, opts);
233
233
  return this.#adopt(result);
234
234
  }
235
235
  fillet(s, radius, edgeIndices) {
@@ -254,25 +254,18 @@ var OcctKernel = class {
254
254
  const bbox = raw.bounds();
255
255
  const edges = d.edges.map((e) => {
256
256
  const curve = CURVE_KINDS.has(e.curve) ? e.curve : "other";
257
- if (e.curve === "line") {
258
- const center = [
259
- (e.start[0] + e.end[0]) / 2,
260
- (e.start[1] + e.end[1]) / 2,
261
- (e.start[2] + e.end[2]) / 2
262
- ];
263
- return {
264
- index: e.index,
265
- curve,
266
- length: e.length,
267
- center,
268
- direction: e.direction
269
- };
270
- }
271
- if (e.curve === "circle") return {
257
+ if (e.curve === "line") return {
272
258
  index: e.index,
273
259
  curve,
274
260
  length: e.length,
275
261
  center: e.center,
262
+ direction: e.direction
263
+ };
264
+ if (e.curve === "circle") return {
265
+ index: e.index,
266
+ curve,
267
+ length: e.length,
268
+ center: e.axisPoint,
276
269
  axis: e.axis,
277
270
  radius: e.radius
278
271
  };
@@ -280,39 +273,25 @@ var OcctKernel = class {
280
273
  index: e.index,
281
274
  curve,
282
275
  length: e.length,
283
- center: e.center,
276
+ center: e.axisPoint,
284
277
  axis: e.axis
285
278
  };
286
- const fallback = [
287
- (bbox.min[0] + bbox.max[0]) / 2,
288
- (bbox.min[1] + bbox.max[1]) / 2,
289
- (bbox.min[2] + bbox.max[2]) / 2
290
- ];
291
279
  return {
292
280
  index: e.index,
293
281
  curve,
294
282
  length: e.length,
295
- center: fallback
283
+ center: e.center
296
284
  };
297
285
  });
298
286
  const faces = d.faces.map((f) => {
299
287
  const surface = SURFACE_KINDS.has(f.surface) ? f.surface : "other";
300
- if (f.surface === "plane") {
301
- const refPoint = f.origin;
302
- const onPlane = edges.filter((e) => Math.abs(v.dot(e.center, f.normal) - v.dot(refPoint, f.normal)) <= 1e-4);
303
- const center = onPlane.length > 0 ? [
304
- onPlane.reduce((acc, e) => acc + e.center[0], 0) / onPlane.length,
305
- onPlane.reduce((acc, e) => acc + e.center[1], 0) / onPlane.length,
306
- onPlane.reduce((acc, e) => acc + e.center[2], 0) / onPlane.length
307
- ] : refPoint;
308
- return {
309
- index: f.index,
310
- surface,
311
- area: f.area,
312
- center,
313
- normal: f.normal
314
- };
315
- }
288
+ if (f.surface === "plane") return {
289
+ index: f.index,
290
+ surface,
291
+ area: f.area,
292
+ center: f.center,
293
+ normal: f.normal
294
+ };
316
295
  if (f.surface === "cylinder") return {
317
296
  index: f.index,
318
297
  surface,
@@ -332,27 +311,22 @@ var OcctKernel = class {
332
311
  index: f.index,
333
312
  surface,
334
313
  area: f.area,
335
- center: f.center,
314
+ center: f.axisPoint,
336
315
  radius: f.radius
337
316
  };
338
317
  if (f.surface === "torus") return {
339
318
  index: f.index,
340
319
  surface,
341
320
  area: f.area,
342
- center: f.center,
321
+ center: f.axisPoint,
343
322
  axis: f.axis,
344
323
  radius: f.majorRadius
345
324
  };
346
- const genericCenter = [
347
- (bbox.min[0] + bbox.max[0]) / 2,
348
- (bbox.min[1] + bbox.max[1]) / 2,
349
- (bbox.min[2] + bbox.max[2]) / 2
350
- ];
351
325
  return {
352
326
  index: f.index,
353
327
  surface,
354
328
  area: f.area,
355
- center: genericCenter
329
+ center: f.center
356
330
  };
357
331
  });
358
332
  const meta = {
@@ -514,24 +488,28 @@ var Shape = class {
514
488
  vertices() {
515
489
  throw new Error("vertices() requires kernel support (occt.ts R5: describe() vertex records) — not available yet.");
516
490
  }
517
- cut(b) {
491
+ /** See `Kernel.boolean` — cleaned by default (UnifySameDomain). */
492
+ cut(b, opts) {
518
493
  return record("cut", {
519
494
  target: this.handle.id,
520
- tool: b.handle.id
521
- }, () => solidFromKernel(getKernel().boolean("cut", this.handle, b.handle)));
495
+ tool: b.handle.id,
496
+ ...opts
497
+ }, () => solidFromKernel(getKernel().boolean("cut", this.handle, b.handle, opts)));
522
498
  }
523
- fuse(b) {
499
+ fuse(b, opts) {
524
500
  return record("fuse", {
525
501
  target: this.handle.id,
526
- tool: b.handle.id
527
- }, () => solidFromKernel(getKernel().boolean("fuse", this.handle, b.handle)));
502
+ tool: b.handle.id,
503
+ ...opts
504
+ }, () => solidFromKernel(getKernel().boolean("fuse", this.handle, b.handle, opts)));
528
505
  }
529
506
  /** build123d's `intersect` (OCCT `common`). */
530
- common(b) {
507
+ common(b, opts) {
531
508
  return record("common", {
532
509
  target: this.handle.id,
533
- tool: b.handle.id
534
- }, () => solidFromKernel(getKernel().boolean("common", this.handle, b.handle)));
510
+ tool: b.handle.id,
511
+ ...opts
512
+ }, () => solidFromKernel(getKernel().boolean("common", this.handle, b.handle, opts)));
535
513
  }
536
514
  /** Immediate-bake transform (occt.ts has no lazy location chain). */
537
515
  translate(by) {
@@ -548,7 +526,7 @@ var Shape = class {
548
526
  }
549
527
  /** Export by file extension (.step/.stl/.glb). Node writes to disk. */
550
528
  async export(path, opts) {
551
- const { exportShape } = await import("./io-N0C2K1hO.js").then((n) => n.o);
529
+ const { exportShape } = await import("./io-DD2D1UYF.js").then((n) => n.o);
552
530
  await exportShape(this, path, opts);
553
531
  }
554
532
  dispose() {
@@ -0,0 +1,14 @@
1
+ //#region src/util.ts
2
+ /** Thrown by every skeleton stub until the real M0 implementation lands. */
3
+ var NotImplementedError = class extends Error {
4
+ constructor(what) {
5
+ super(`${what} is not implemented yet — this is the M0 repository skeleton.`);
6
+ this.name = "NotImplementedError";
7
+ }
8
+ };
9
+ /** Stub body helper: keeps signatures real while bodies wait for M0. */
10
+ function todo(what) {
11
+ throw new NotImplementedError(what);
12
+ }
13
+ //#endregion
14
+ export { todo as t };
@@ -1,4 +1,4 @@
1
- import { S as Plane, o as Solid } from "../index-CBGNe8Hy.js";
1
+ import { S as Plane, o as Solid } from "../index-DceghC4N.js";
2
2
  //#region src/workplane/index.d.ts
3
3
  export type PlaneName = "XY" | "YZ" | "XZ" | "front" | "back" | "left" | "right" | "top" | "bottom";
4
4
  export type Selector = string;
@@ -1,4 +1,4 @@
1
- import { b as v, i as Cylinder, n as Box, t as parseSelector, y as planeFrom } from "../selectors-CEhRDaf2.js";
1
+ import { b as v, i as Cylinder, n as Box, t as parseSelector, y as planeFrom } from "../selectors-C0-da9aQ.js";
2
2
  //#region src/workplane/index.ts
3
3
  /**
4
4
  * CadQuery-style fluent facade over the explicit core API.
package/package.json CHANGED
@@ -1,15 +1,17 @@
1
1
  {
2
2
  "name": "cadorange",
3
- "version": "0.1.0",
3
+ "version": "0.3.0",
4
4
  "description": "Agent-native CAD runtime in TypeScript, powered by occt.ts (OCCT/WASM). Core modeling API: shapes, selectors, booleans, features, import/export.",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
7
7
  "repository": {
8
8
  "type": "git",
9
- "url": "git+https://github.com/LAU-MARS/cadorange.git",
10
- "directory": "packages/cadorange"
9
+ "url": "git+https://github.com/LAU-MARS/cadorange.git"
11
10
  },
12
11
  "sideEffects": false,
12
+ "bin": {
13
+ "cado": "./dist/cli.js"
14
+ },
13
15
  "exports": {
14
16
  ".": {
15
17
  "types": "./dist/index.d.ts",
@@ -18,13 +20,25 @@
18
20
  "./workplane": {
19
21
  "types": "./dist/workplane/index.d.ts",
20
22
  "default": "./dist/workplane/index.js"
23
+ },
24
+ "./runtime": {
25
+ "types": "./dist/runtime/index.d.ts",
26
+ "default": "./dist/runtime/index.js"
27
+ },
28
+ "./render": {
29
+ "types": "./dist/render/index.d.ts",
30
+ "default": "./dist/render/index.js"
31
+ },
32
+ "./mcp": {
33
+ "types": "./dist/mcp/index.d.ts",
34
+ "default": "./dist/mcp/index.js"
21
35
  }
22
36
  },
23
37
  "files": [
24
38
  "dist"
25
39
  ],
26
40
  "dependencies": {
27
- "occt.ts": "^0.7.0"
41
+ "occt.ts": "^0.10.0"
28
42
  },
29
43
  "devDependencies": {
30
44
  "@types/node": "^26.6.4"