dsh-cad 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 (113) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +190 -0
  3. package/README.zh-CN.md +173 -0
  4. package/cordis.patch.yml +3 -0
  5. package/lib/b64.js +12 -0
  6. package/lib/cad_connector/builtin-executor.js +55 -0
  7. package/lib/cad_connector/builtin.js +8 -0
  8. package/lib/cad_connector/executor.js +76 -0
  9. package/lib/cad_connector/freecad-executor.js +398 -0
  10. package/lib/cad_connector/freecad.js +8 -0
  11. package/lib/cad_connector/fusion360-executor.js +398 -0
  12. package/lib/cad_connector/fusion360.js +8 -0
  13. package/lib/cad_connector/gstarcad3d.js +8 -0
  14. package/lib/cad_connector/index.js +20 -0
  15. package/lib/cad_connector/onshape.js +8 -0
  16. package/lib/cad_connector/solidworks.js +8 -0
  17. package/lib/cad_connector/types.js +6 -0
  18. package/lib/cad_connector/zw3d.js +8 -0
  19. package/lib/client.js +4117 -0
  20. package/lib/client.js.map +7 -0
  21. package/lib/convert/dcprt.js +38 -0
  22. package/lib/convert/detect.js +22 -0
  23. package/lib/convert/dxf.js +124 -0
  24. package/lib/convert/index.js +70 -0
  25. package/lib/convert/obj.js +106 -0
  26. package/lib/convert/png.js +114 -0
  27. package/lib/convert/step-worker.mjs +61 -0
  28. package/lib/convert/step.js +66 -0
  29. package/lib/convert/stl.js +110 -0
  30. package/lib/convert/svg.js +101 -0
  31. package/lib/demo-bracket.brep +668 -0
  32. package/lib/demo-flange.brep +709 -0
  33. package/lib/demo-shaft.brep +516 -0
  34. package/lib/feature_script/dc_asm.js +17 -0
  35. package/lib/feature_script/dc_engineering.js +19 -0
  36. package/lib/feature_script/dc_prt.js +21 -0
  37. package/lib/feature_script/index.js +7 -0
  38. package/lib/image/profile.js +218 -0
  39. package/lib/index.js +77 -0
  40. package/lib/modeling/assembly.js +63 -0
  41. package/lib/modeling/bin-format.js +80 -0
  42. package/lib/modeling/bin-store.js +67 -0
  43. package/lib/modeling/client.js +117 -0
  44. package/lib/modeling/document.js +55 -0
  45. package/lib/modeling/drawing.js +324 -0
  46. package/lib/modeling/hlr.cjs +328 -0
  47. package/lib/modeling/modeling-worker.cjs +235 -0
  48. package/lib/modeling/occt-adapter.cjs +271 -0
  49. package/lib/routes.js +142 -0
  50. package/lib/store.js +68 -0
  51. package/lib/tools/cad-freecad.js +160 -0
  52. package/lib/tools/cad-fusion.js +138 -0
  53. package/lib/tools/cad-image.js +121 -0
  54. package/lib/tools/cad-info.js +92 -0
  55. package/lib/tools/cad-model.js +816 -0
  56. package/lib/tools/cad-view.js +112 -0
  57. package/lib/tools/util.js +25 -0
  58. package/lib/types/b64.d.ts +8 -0
  59. package/lib/types/cad/builtin.d.ts +3 -0
  60. package/lib/types/cad/freecad.d.ts +3 -0
  61. package/lib/types/cad/fusion360.d.ts +3 -0
  62. package/lib/types/cad/gstarcad3d.d.ts +3 -0
  63. package/lib/types/cad/index.d.ts +8 -0
  64. package/lib/types/cad/onshape.d.ts +3 -0
  65. package/lib/types/cad/solidworks.d.ts +3 -0
  66. package/lib/types/cad/types.d.ts +21 -0
  67. package/lib/types/cad/zw3d.d.ts +3 -0
  68. package/lib/types/cad_connector/builtin-executor.d.ts +9 -0
  69. package/lib/types/cad_connector/builtin.d.ts +3 -0
  70. package/lib/types/cad_connector/executor.d.ts +69 -0
  71. package/lib/types/cad_connector/freecad-executor.d.ts +55 -0
  72. package/lib/types/cad_connector/freecad.d.ts +3 -0
  73. package/lib/types/cad_connector/fusion360-executor.d.ts +11 -0
  74. package/lib/types/cad_connector/fusion360.d.ts +3 -0
  75. package/lib/types/cad_connector/gstarcad3d.d.ts +3 -0
  76. package/lib/types/cad_connector/index.d.ts +8 -0
  77. package/lib/types/cad_connector/onshape.d.ts +3 -0
  78. package/lib/types/cad_connector/solidworks.d.ts +3 -0
  79. package/lib/types/cad_connector/types.d.ts +21 -0
  80. package/lib/types/cad_connector/zw3d.d.ts +3 -0
  81. package/lib/types/convert/dcprt.d.ts +14 -0
  82. package/lib/types/convert/detect.d.ts +7 -0
  83. package/lib/types/convert/dxf.d.ts +3 -0
  84. package/lib/types/convert/index.d.ts +9 -0
  85. package/lib/types/convert/obj.d.ts +7 -0
  86. package/lib/types/convert/png.d.ts +8 -0
  87. package/lib/types/convert/step.d.ts +4 -0
  88. package/lib/types/convert/stl.d.ts +7 -0
  89. package/lib/types/convert/svg.d.ts +8 -0
  90. package/lib/types/feature_script/dc_asm.d.ts +40 -0
  91. package/lib/types/feature_script/dc_engineering.d.ts +55 -0
  92. package/lib/types/feature_script/dc_prt.d.ts +37 -0
  93. package/lib/types/feature_script/index.d.ts +7 -0
  94. package/lib/types/image/profile.d.ts +28 -0
  95. package/lib/types/index.d.ts +18 -0
  96. package/lib/types/modeling/assembly.d.ts +17 -0
  97. package/lib/types/modeling/bin-format.d.ts +42 -0
  98. package/lib/types/modeling/bin-store.d.ts +20 -0
  99. package/lib/types/modeling/client.d.ts +125 -0
  100. package/lib/types/modeling/document.d.ts +26 -0
  101. package/lib/types/modeling/drawing.d.ts +38 -0
  102. package/lib/types/routes.d.ts +27 -0
  103. package/lib/types/store.d.ts +18 -0
  104. package/lib/types/tools/cad-freecad.d.ts +10 -0
  105. package/lib/types/tools/cad-fusion.d.ts +8 -0
  106. package/lib/types/tools/cad-image.d.ts +8 -0
  107. package/lib/types/tools/cad-info.d.ts +6 -0
  108. package/lib/types/tools/cad-model.d.ts +13 -0
  109. package/lib/types/tools/cad-view.d.ts +10 -0
  110. package/lib/types/tools/util.d.ts +4 -0
  111. package/lib/types/types.d.ts +142 -0
  112. package/lib/types.js +25 -0
  113. package/package.json +91 -0
@@ -0,0 +1,37 @@
1
+ /**
2
+ * dsh-cad part document (`.dcprt`) — the standalone, shareable counterpart of
3
+ * the workspace modeling document: a replayable feature history plus a body
4
+ * manifest. Replaying `features` through the OCCT modeling worker reproduces
5
+ * every body exactly, which keeps the file itself geometry-free.
6
+ *
7
+ * Format definition only — runtime persistence/exchange (cad_export filters,
8
+ * loaders) lands together with the assembly and drawing pipelines.
9
+ */
10
+ import type { ModelOp } from '../modeling/client.js';
11
+ import type { ModelDoc } from '../modeling/document.js';
12
+ export declare const DC_PRT_FORMAT: "dcprt";
13
+ export declare const DC_PRT_EXTENSION = ".dcprt";
14
+ export interface DcPrtHeader {
15
+ format: typeof DC_PRT_FORMAT;
16
+ version: 1;
17
+ units: 'mm';
18
+ upAxis: 'Z';
19
+ }
20
+ export interface DcPrtBody {
21
+ bodyId: string;
22
+ name?: string;
23
+ }
24
+ export interface DcPrtDocument {
25
+ header: DcPrtHeader;
26
+ /** Document id from the originating workspace; doubles as the scene viewId. */
27
+ docId: string;
28
+ /** Document version at export time (monotonic op counter). */
29
+ version?: number;
30
+ /** Feature history — replayable by the OCCT modeling worker, in order. */
31
+ features: ModelOp[];
32
+ bodies: DcPrtBody[];
33
+ createdAt?: string;
34
+ }
35
+ /** Serialize a live workspace modeling document into the shareable .dcprt form. */
36
+ export declare function toDcPrtDocument(doc: ModelDoc): DcPrtDocument;
37
+ export declare function isDcPrtDocument(value: unknown): value is DcPrtDocument;
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Native document formats ("feature scripts"): part, assembly and engineering
3
+ * drawing. See each module for its format contract.
4
+ */
5
+ export * from './dc_prt.js';
6
+ export * from './dc_asm.js';
7
+ export * from './dc_engineering.js';
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Image → 2D profile extraction: Otsu binarization, connected components,
3
+ * Moore boundary tracing, Douglas-Peucker simplification. Coordinates flip
4
+ * to CAD orientation (y up, mm via `scale`, default 1 px = 1 mm).
5
+ */
6
+ import type { GrayImage } from '../convert/png.js';
7
+ export interface ExtractOptions {
8
+ /** Manual binarization threshold (0–255); omit for Otsu. */
9
+ threshold?: number;
10
+ /** Trace light-on-dark shapes instead of dark-on-light. */
11
+ invert?: boolean;
12
+ /** Simplification tolerance in pixels (default 1.5). */
13
+ tolerance?: number;
14
+ /** Pixels per mm (default 1). */
15
+ scale?: number;
16
+ /** Ignore components smaller than this pixel area (default 24). */
17
+ minArea?: number;
18
+ }
19
+ export interface ExtractedProfile {
20
+ /** Flat [x0,y0, x1,y1, …] closed loop, mm, y-up. */
21
+ points: number[];
22
+ /** Pixel area of the source component (rough size ranking). */
23
+ area: number;
24
+ }
25
+ /** Otsu's threshold for a luma image. */
26
+ export declare function otsuThreshold(gray: Uint8Array): number;
27
+ /** Extract simplified outer contours from a luma image, largest first. */
28
+ export declare function extractProfiles(image: GrayImage, options?: ExtractOptions): ExtractedProfile[];
@@ -0,0 +1,18 @@
1
+ /**
2
+ * dsh-cad host plugin: registers the `cad_view` / `cad_info` tools and the
3
+ * same-origin scene route on the Web composition's shared HTTP server.
4
+ *
5
+ * The HTTP server is an optional backend: fibers may activate before the web
6
+ * composition defines it (and headless never does), so the route registers
7
+ * lazily at first `cad_view` execution — the platform's use-time-resolution
8
+ * idiom rather than a hard inject.
9
+ */
10
+ import type { Context } from '@deepseek-ai/cordis';
11
+ export declare const name = "dsh-cad";
12
+ /** Hard dependencies: the tool registry. */
13
+ export declare const inject: string[];
14
+ export interface Config {
15
+ /** Directory the scene spill store uses; defaults to the workspace root. */
16
+ root?: string;
17
+ }
18
+ export declare function apply(ctx: Context, config?: Config): void;
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Assembly composition (main thread): instances reference body meshes by id
3
+ * and place them with translate + XYZ-Euler rotate (degrees, the same
4
+ * "translate → rotate" convention as cad_transform / the worker's
5
+ * BRepBuilderAPI_Transform path: p' = T + Rx·(Ry·(Rz·p))). Composition is
6
+ * pure typed-array math on the already-tessellated body meshes — no worker
7
+ * round-trip, no re-tessellation.
8
+ */
9
+ import type { BinMeshData } from './bin-format.js';
10
+ import type { AssemblyInstance } from './client.js';
11
+ /**
12
+ * Compose the assembly scene: one transformed mesh copy per instance.
13
+ * Instances referencing bodies missing from `bodies` (consumed by a later
14
+ * boolean) are skipped — the worker's live list already filters them, this is
15
+ * the replay-side double guard. Duplicate names get a ·N suffix.
16
+ */
17
+ export declare function composeAssemblyMeshes(bodies: Map<string, BinMeshData>, instances: AssemblyInstance[]): BinMeshData[];
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Binary scene format: the direct worker→three.js transport. One packed
3
+ * buffer (JSON header + raw f32/u32 payloads) that the browser decodes with
4
+ * typed-array views — no base64, no JSON number arrays, no intermediate file
5
+ * unless the debounced disk mirror or an explicit cad_export happens.
6
+ *
7
+ * Layout (little-endian):
8
+ * [4B magic "DCB1"][4B headerByteLength][header JSON utf8][payload bytes]
9
+ * Header: { meshes: [{ name, color?, vertexCount, triangleCount,
10
+ * posOffset, posBytes, nrmOffset?, nrmBytes, idxOffset, idxBytes }],
11
+ * bounds: { min: [x,y,z], max: [x,y,z] }, units }
12
+ * Offsets/lengths are byte counts relative to the payload start.
13
+ */
14
+ export interface BinMeshDesc {
15
+ name: string;
16
+ color?: number;
17
+ vertexCount: number;
18
+ triangleCount: number;
19
+ posOffset: number;
20
+ posBytes: number;
21
+ nrmOffset?: number;
22
+ nrmBytes?: number;
23
+ idxOffset: number;
24
+ idxBytes: number;
25
+ }
26
+ export interface BinHeader {
27
+ meshes: BinMeshDesc[];
28
+ bounds: {
29
+ min: [number, number, number];
30
+ max: [number, number, number];
31
+ };
32
+ units: string;
33
+ }
34
+ export interface BinMeshData {
35
+ name: string;
36
+ color?: number;
37
+ positions: Float32Array;
38
+ normals?: Float32Array;
39
+ indices: Uint32Array;
40
+ }
41
+ /** Pack meshes into the binary transport buffer. */
42
+ export declare function packBinaryScene(meshes: BinMeshData[]): Buffer;
@@ -0,0 +1,20 @@
1
+ import type { BinMeshData } from './bin-format.js';
2
+ interface Entry {
3
+ buffer: Buffer;
4
+ version: number;
5
+ etag: string;
6
+ }
7
+ export declare class BinarySceneStore {
8
+ private readonly root;
9
+ private readonly memory;
10
+ private readonly diskTimers;
11
+ constructor(root: string);
12
+ private get directory();
13
+ /** Publish a new version under a stable viewId; returns the version. */
14
+ publish(viewId: string, meshes: BinMeshData[]): Promise<number>;
15
+ /** Fetch for serving: memory first, disk mirror as the restart fallback. */
16
+ get(viewId: string): Promise<Entry | null>;
17
+ /** Debounced disk mirror: one write after modeling quiesces, not per step. */
18
+ private scheduleDiskMirror;
19
+ }
20
+ export {};
@@ -0,0 +1,125 @@
1
+ export interface WorkerMesh {
2
+ name: string;
3
+ positions: Float32Array;
4
+ normals: Float32Array;
5
+ indices: Uint32Array;
6
+ vertexCount: number;
7
+ triangleCount: number;
8
+ }
9
+ /** One placed reference of a body inside the assembly. */
10
+ export interface AssemblyInstance {
11
+ instanceId: string;
12
+ bodyId: string;
13
+ name: string;
14
+ translate: [number, number, number];
15
+ rotate: [number, number, number];
16
+ }
17
+ /** One projected hidden-line drawing view (flat [x,y, x,y, …] polylines, mm). */
18
+ export interface DrawingView {
19
+ name: string;
20
+ visible: number[][];
21
+ hidden: number[][];
22
+ }
23
+ export interface OpResult {
24
+ bodyId?: string;
25
+ name?: string;
26
+ removed?: string[];
27
+ edges?: number;
28
+ mesh?: WorkerMesh;
29
+ meshes?: Array<WorkerMesh & {
30
+ bodyId: string;
31
+ }>;
32
+ bytes?: ArrayBuffer;
33
+ volume?: number;
34
+ deleted?: string;
35
+ cleared?: boolean;
36
+ views?: DrawingView[];
37
+ instanceId?: string;
38
+ instances?: AssemblyInstance[];
39
+ }
40
+ export interface DrawingViewSpec {
41
+ name: string;
42
+ dir: [number, number, number];
43
+ xDir: [number, number, number];
44
+ }
45
+ export type ModelOp = {
46
+ kind: 'create_prim';
47
+ bodyId: string;
48
+ prim: string;
49
+ params?: Record<string, unknown>;
50
+ name?: string;
51
+ } | {
52
+ kind: 'extrude_profile';
53
+ bodyId: string;
54
+ points: number[];
55
+ height?: number;
56
+ base?: number;
57
+ name?: string;
58
+ } | {
59
+ kind: 'boolean';
60
+ op: 'fuse' | 'cut' | 'common';
61
+ target: string;
62
+ tools: string[];
63
+ } | {
64
+ kind: 'fillet';
65
+ target: string;
66
+ radius: number;
67
+ } | {
68
+ kind: 'transform';
69
+ target: string;
70
+ translate?: [number, number, number];
71
+ rotate?: [number, number, number];
72
+ mirror?: [number, number, number];
73
+ } | {
74
+ kind: 'tessellate_all';
75
+ } | {
76
+ kind: 'export';
77
+ target: string;
78
+ format: 'step' | 'stl';
79
+ } | {
80
+ kind: 'volume';
81
+ target: string;
82
+ } | {
83
+ kind: 'delete';
84
+ target: string;
85
+ } | {
86
+ kind: 'reset';
87
+ } | {
88
+ kind: 'drawing';
89
+ target: string;
90
+ views: DrawingViewSpec[];
91
+ sceneViewId?: string;
92
+ name?: string;
93
+ paper?: 'A4' | 'A3';
94
+ } | {
95
+ kind: 'assembly_insert';
96
+ instanceId: string;
97
+ bodyId: string;
98
+ name?: string;
99
+ translate?: [number, number, number];
100
+ rotate?: [number, number, number];
101
+ } | {
102
+ kind: 'assembly_transform';
103
+ instanceId: string;
104
+ translate?: [number, number, number];
105
+ rotate?: [number, number, number];
106
+ } | {
107
+ kind: 'assembly_remove';
108
+ instanceId: string;
109
+ } | {
110
+ kind: 'export_assembly';
111
+ format: 'step' | 'stl';
112
+ };
113
+ export interface ModelClient {
114
+ /** Run one modeling operation on this client's worker. */
115
+ run(op: ModelOp, timeoutMs?: number): Promise<OpResult>;
116
+ /** Terminate the worker and fail any in-flight jobs. */
117
+ dispose(): void;
118
+ }
119
+ export declare function createModelClient(): ModelClient;
120
+ /** Run one modeling operation on the shared session worker. */
121
+ export declare function runModelOp(op: ModelOp, timeoutMs?: number): Promise<OpResult>;
122
+ /** Current reset epoch of the shared worker (see above). */
123
+ export declare function workerResetEpoch(): number;
124
+ /** Test/Dev helper: hard worker file path (used by the vitest suite). */
125
+ export declare function workerEntryPath(): string;
@@ -0,0 +1,26 @@
1
+ import type { ModelOp } from './client.js';
2
+ export interface ModelDoc {
3
+ /** Stable document id; doubles as the viewer scene viewId. */
4
+ docId: string;
5
+ /** Monotonic operation counter; the viewer uses it as a cache-busting version. */
6
+ version: number;
7
+ ops: ModelOp[];
8
+ /** Body display names, kept in the manifest for cad_list without a worker round-trip. */
9
+ bodyNames: Record<string, string>;
10
+ }
11
+ export declare class ModelDocument {
12
+ readonly root: string;
13
+ doc: ModelDoc;
14
+ constructor(root: string);
15
+ private get directory();
16
+ private get file();
17
+ /** Load the persisted document if one exists. */
18
+ restore(): Promise<void>;
19
+ /** Append an applied operation and persist. */
20
+ record(op: ModelOp, bodyName: {
21
+ bodyId: string;
22
+ name: string;
23
+ } | null): Promise<void>;
24
+ /** Clear the document (cad_new / tests). */
25
+ clear(): Promise<void>;
26
+ }
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Engineering-drawing sheet assembly (main thread, pure geometry — unit
3
+ * tested). Takes projected hidden-line views (from the modeling worker's mesh
4
+ * HLR) and lays them out on a GB-flavoured first-angle sheet: 主视图 front,
5
+ * 左视图 right of front, 俯视图 below front, 轴测 in the free corner; frame,
6
+ * title block, overall-dimension annotations, and a uniform standard scale
7
+ * for the three standard views.
8
+ *
9
+ * Output is the plain 2D entity subset the client viewport already renders
10
+ * (polylines + text, layer-classified), plus SVG/DXF serializations for
11
+ * cad_export.
12
+ */
13
+ import type { CadBounds2, CadEntity2D } from '../types.js';
14
+ import type { DrawingView } from './client.js';
15
+ export type PaperSize = 'A4' | 'A3';
16
+ export interface DrawingSheetInput {
17
+ partName: string;
18
+ views: DrawingView[];
19
+ paper?: PaperSize;
20
+ drawingNo?: string;
21
+ date?: string;
22
+ }
23
+ export interface DrawingSheet {
24
+ entities: CadEntity2D[];
25
+ bounds: CadBounds2;
26
+ layers: string[];
27
+ width: number;
28
+ height: number;
29
+ /** Standard scale of the three standard views (iso is fit independently). */
30
+ scale: number;
31
+ entityCount: number;
32
+ }
33
+ /** Build the full drawing sheet (frame, title block, views, dimensions). */
34
+ export declare function buildDrawingSheet(input: DrawingSheetInput): DrawingSheet;
35
+ /** Serialize the sheet to a standalone SVG (paper mm = user units, Y flipped). */
36
+ export declare function drawingToSvg(sheet: DrawingSheet): string;
37
+ /** Minimal R12 ASCII DXF (LINE + TEXT entities; polylines expand to lines). */
38
+ export declare function drawingToDxf(sheet: DrawingSheet): string;
@@ -0,0 +1,27 @@
1
+ import type { IncomingMessage, ServerResponse } from 'node:http';
2
+ import type { SceneStore } from './store.js';
3
+ import type { BinarySceneStore } from './modeling/bin-store.js';
4
+ export declare const SCENE_ROUTE_PATH = "/dsh-cad/scene";
5
+ export declare const BIN_ROUTE_PATH = "/dsh-cad/bin";
6
+ export declare const DEMO_SCENE_ROUTE_PATH = "/dsh-cad/demo-scene";
7
+ /** The built-in demo examples (packaged as lib/demo-<part>.brep). */
8
+ export declare const DEMO_PARTS: readonly ["bracket", "flange", "shaft"];
9
+ export type DemoPart = (typeof DEMO_PARTS)[number];
10
+ /** Register the scene route on the shared HTTP server. Returns a disposer. */
11
+ export declare function registerSceneRoute(server: {
12
+ register: (route: SceneRoute) => () => void;
13
+ }, store: SceneStore): () => void;
14
+ interface SceneRoute {
15
+ kind: 'prefix' | 'exact';
16
+ path: string;
17
+ handler: (req: IncomingMessage, res: ServerResponse) => void | Promise<void>;
18
+ }
19
+ /** Register the binary scene route. Returns a disposer. */
20
+ export declare function registerBinRoute(server: {
21
+ register: (route: SceneRoute) => () => void;
22
+ }, store: BinarySceneStore): () => void;
23
+ /** Register the demo-scene route: GET /dsh-cad/demo-scene?part=<bracket|flange|shaft>. */
24
+ export declare function registerDemoRoute(server: {
25
+ register: (route: SceneRoute) => () => void;
26
+ }): () => void;
27
+ export type { SceneRoute };
@@ -0,0 +1,18 @@
1
+ import type { CadScene } from './types.js';
2
+ export declare class SceneStore {
3
+ private readonly root;
4
+ private readonly memory;
5
+ constructor(root: string);
6
+ private get directory();
7
+ /** Persist a scene and return its viewId. */
8
+ put(scene: CadScene): Promise<string>;
9
+ /** Persist a scene under a stable viewId (overwrites; used by the modeling
10
+ * document so every operation refreshes the same viewer card). */
11
+ putAt(viewId: string, scene: CadScene): Promise<void>;
12
+ /** Fetch a scene by viewId, restoring from disk when the memory copy aged out. */
13
+ get(viewId: string): Promise<CadScene | null>;
14
+ /** Best-effort removal (unused for now; kept for completeness of the API). */
15
+ delete(viewId: string): Promise<void>;
16
+ /** ETag for a scene payload (cache helper for the route handler). */
17
+ etag(scene: CadScene): string;
18
+ }
@@ -0,0 +1,10 @@
1
+ import type { ToolDefinition } from '@deepseek-ai/dsh-tools';
2
+ import type { BinarySceneStore } from '../modeling/bin-store.js';
3
+ import { normalizeOps } from '../cad_connector/executor.js';
4
+ export declare const normalizeFreeCadSteps: typeof normalizeOps;
5
+ export interface FreeCadToolDeps {
6
+ store: BinarySceneStore;
7
+ workspaceRoot: string;
8
+ ensureSceneRoute: () => string | null;
9
+ }
10
+ export declare function createFreeCadTool(deps: FreeCadToolDeps): ToolDefinition;
@@ -0,0 +1,8 @@
1
+ import type { ToolDefinition } from '@deepseek-ai/dsh-tools';
2
+ import type { BinarySceneStore } from '../modeling/bin-store.js';
3
+ export interface FusionToolDeps {
4
+ store: BinarySceneStore;
5
+ workspaceRoot: string;
6
+ ensureSceneRoute: () => string | null;
7
+ }
8
+ export declare function createFusionTool(deps: FusionToolDeps): ToolDefinition;
@@ -0,0 +1,8 @@
1
+ import type { ToolDefinition } from '@deepseek-ai/dsh-tools';
2
+ import type { SceneStore } from '../store.js';
3
+ export interface CadImageToolDeps {
4
+ store: SceneStore;
5
+ workspaceRoot: string;
6
+ ensureSceneRoute: () => string | null;
7
+ }
8
+ export declare function createCadImageTool(deps: CadImageToolDeps): ToolDefinition;
@@ -0,0 +1,6 @@
1
+ import type { ToolDefinition } from '@deepseek-ai/dsh-tools';
2
+ export interface CadInfoToolDeps {
3
+ workspaceRoot: string;
4
+ }
5
+ /** Build the cad_info tool definition. */
6
+ export declare function createCadInfoTool(deps: CadInfoToolDeps): ToolDefinition;
@@ -0,0 +1,13 @@
1
+ import type { ToolDefinition } from '@deepseek-ai/dsh-tools';
2
+ import type { BinarySceneStore } from '../modeling/bin-store.js';
3
+ import type { SceneStore } from '../store.js';
4
+ export interface ModelToolDeps {
5
+ store: BinarySceneStore;
6
+ /** JSON scene store (drawing sheets). */
7
+ sceneStore: SceneStore;
8
+ workspaceRoot: string;
9
+ ensureSceneRoute: () => string | null;
10
+ }
11
+ /** Build the whole tool family over one document + worker + scene store. */
12
+ export declare function createModelTools(deps: ModelToolDeps): ToolDefinition[];
13
+ export declare const MODEL_TOOL_NAMES: readonly ["cad_create_prim", "cad_extrude_profile", "cad_boolean", "cad_fillet", "cad_transform", "cad_export", "cad_delete", "cad_volume", "cad_drawing", "cad_assembly_insert", "cad_assembly_move", "cad_assembly_remove"];
@@ -0,0 +1,10 @@
1
+ import type { ToolDefinition } from '@deepseek-ai/dsh-tools';
2
+ import type { SceneStore } from '../store.js';
3
+ export interface CadViewToolDeps {
4
+ store: SceneStore;
5
+ workspaceRoot: string;
6
+ /** Idempotent lazy route registration; returns the scene URL base or null. */
7
+ ensureSceneRoute: () => string | null;
8
+ }
9
+ /** Build the cad_view tool definition over the scene store. */
10
+ export declare function createCadViewTool(deps: CadViewToolDeps): ToolDefinition;
@@ -0,0 +1,4 @@
1
+ /** Resolve a model-supplied path against the workspace root. */
2
+ export declare function resolveWorkspacePath(input: string, workspaceRoot: string): string;
3
+ /** Load a CAD file buffer, failing with model-friendly errors. */
4
+ export declare function loadCadFile(resolvedPath: string): Promise<Buffer>;
@@ -0,0 +1,142 @@
1
+ /**
2
+ * Shared CAD scene model: the normalized JSON the host produces from a CAD
3
+ * file and the browser card renders. Binary payloads (positions, normals,
4
+ * indices) are base64-encoded typed arrays to keep large meshes transportable.
5
+ */
6
+ /** 3D axis-aligned bounds. */
7
+ export interface CadBounds3 {
8
+ min: {
9
+ x: number;
10
+ y: number;
11
+ z: number;
12
+ };
13
+ max: {
14
+ x: number;
15
+ y: number;
16
+ z: number;
17
+ };
18
+ }
19
+ /** 2D axis-aligned bounds. */
20
+ export interface CadBounds2 {
21
+ min: {
22
+ x: number;
23
+ y: number;
24
+ };
25
+ max: {
26
+ x: number;
27
+ y: number;
28
+ };
29
+ }
30
+ /** One tessellated solid, ready for WebGL. */
31
+ export interface CadMesh {
32
+ /** Human-readable part name (STEP product name, OBJ group, file stem, …). */
33
+ name: string;
34
+ /** base64 Float32Array of xyz vertex triplets. */
35
+ positions: string;
36
+ /** base64 Float32Array of xyz normal triplets, parallel to positions. */
37
+ normals?: string;
38
+ /** base64 Uint32Array of triangle vertex indices. */
39
+ indices: string;
40
+ /** Vertex count (one entry per xyz triplet). */
41
+ vertexCount: number;
42
+ /** Triangle count. */
43
+ triangleCount: number;
44
+ /** Optional 0xRRGGBB part color. */
45
+ color?: number;
46
+ }
47
+ /** A tessellated 3D scene. */
48
+ export interface CadScene3D {
49
+ kind: '3d';
50
+ /** Source format: stl | obj | step | iges | brep. */
51
+ format: string;
52
+ meshes: CadMesh[];
53
+ bounds: CadBounds3;
54
+ /** Source units (STEP carries them; mesh formats are unitless → assumed mm). */
55
+ units: 'mm' | 'm' | 'in' | 'unitless';
56
+ }
57
+ /** 2D drawing entity, the lossless subset the 2D viewport renders. */
58
+ export type CadEntity2D = {
59
+ type: 'line';
60
+ x1: number;
61
+ y1: number;
62
+ x2: number;
63
+ y2: number;
64
+ layer?: string;
65
+ color?: number;
66
+ } | {
67
+ type: 'circle';
68
+ cx: number;
69
+ cy: number;
70
+ r: number;
71
+ layer?: string;
72
+ color?: number;
73
+ } | {
74
+ type: 'arc';
75
+ cx: number;
76
+ cy: number;
77
+ r: number;
78
+ startAngle: number;
79
+ endAngle: number;
80
+ layer?: string;
81
+ color?: number;
82
+ } | {
83
+ type: 'polyline';
84
+ points: number[];
85
+ closed: boolean;
86
+ layer?: string;
87
+ color?: number;
88
+ } | {
89
+ type: 'text';
90
+ x: number;
91
+ y: number;
92
+ text: string;
93
+ height: number;
94
+ rotation?: number;
95
+ layer?: string;
96
+ color?: number;
97
+ };
98
+ /** A 2D drawing. */
99
+ export interface CadDrawing2D {
100
+ kind: '2d';
101
+ /** Source format: dxf | svg. */
102
+ format: string;
103
+ entities: CadEntity2D[];
104
+ bounds: CadBounds2;
105
+ layers: string[];
106
+ /** Raw SVG source when format === 'svg' (rendered verbatim in a sandboxed img). */
107
+ svgText?: string;
108
+ }
109
+ /** The union a `cad_view` scene payload carries. */
110
+ export type CadScene = CadScene3D | CadDrawing2D;
111
+ /** Presentation metadata projected through the tool's `output.presentationMeta`. */
112
+ export interface CadViewMeta {
113
+ viewId: string;
114
+ kind: '3d' | '2d';
115
+ format: string;
116
+ file: string;
117
+ /** Same-origin URL serving the scene JSON (absent without a web composition). */
118
+ sceneUrl?: string;
119
+ title: string;
120
+ stats: {
121
+ meshes?: number;
122
+ triangles?: number;
123
+ entities?: number;
124
+ layers?: number;
125
+ boundsMin?: [number, number, number] | [number, number];
126
+ boundsMax?: [number, number, number] | [number, number];
127
+ units?: string;
128
+ };
129
+ }
130
+ /** Geometric summary shared by cad_view and cad_info. */
131
+ export interface CadStats {
132
+ format: string;
133
+ meshes?: number;
134
+ triangles?: number;
135
+ entities?: number;
136
+ layers?: string[];
137
+ boundsMin?: [number, number, number] | [number, number];
138
+ boundsMax?: [number, number, number] | [number, number];
139
+ units?: string;
140
+ }
141
+ /** Flatten a converted scene into the model/card-facing summary. */
142
+ export declare function sceneStats(scene: CadScene): CadStats;
package/lib/types.js ADDED
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Shared CAD scene model: the normalized JSON the host produces from a CAD
3
+ * file and the browser card renders. Binary payloads (positions, normals,
4
+ * indices) are base64-encoded typed arrays to keep large meshes transportable.
5
+ */
6
+ /** Flatten a converted scene into the model/card-facing summary. */
7
+ export function sceneStats(scene) {
8
+ if (scene.kind === '3d') {
9
+ return {
10
+ format: scene.format,
11
+ meshes: scene.meshes.length,
12
+ triangles: scene.meshes.reduce((sum, mesh) => sum + mesh.triangleCount, 0),
13
+ boundsMin: [scene.bounds.min.x, scene.bounds.min.y, scene.bounds.min.z],
14
+ boundsMax: [scene.bounds.max.x, scene.bounds.max.y, scene.bounds.max.z],
15
+ units: scene.units,
16
+ };
17
+ }
18
+ return {
19
+ format: scene.format,
20
+ entities: scene.entities.length,
21
+ layers: scene.layers,
22
+ boundsMin: [scene.bounds.min.x, scene.bounds.min.y],
23
+ boundsMax: [scene.bounds.max.x, scene.bounds.max.y],
24
+ };
25
+ }