@miclivs/cadcli 0.1.1 → 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.
package/README.md CHANGED
@@ -6,7 +6,7 @@ Agent-friendly CAD inspection, search, viewing, and editing for DWG/DXF files.
6
6
  npm install -g @miclivs/cadcli
7
7
  ```
8
8
 
9
- Common inspection/search commands use a pure TypeScript parser by default. Native LibreDWG tools are only needed for high-fidelity `view` and jq-backed `edit`.
9
+ Inspection, search, viewing, and editing use the pure TypeScript `acad-ts` backend. No native CAD tools are required.
10
10
 
11
11
  ## Why cadcli
12
12
 
@@ -17,7 +17,7 @@ cadcli info floorplan.dwg --json
17
17
  cadcli overview floorplan.dwg
18
18
  cadcli search floorplan.dwg "conference" --layer A-TEXT --json
19
19
  cadcli view floorplan.dwg -o preview.svg
20
- cadcli edit floorplan.dwg --jq '.OBJECTS[]' -o edited.dwg
20
+ cadcli edit floorplan.dwg --set-text "Conference" --text-id 2A -o edited.dwg
21
21
  ```
22
22
 
23
23
  ## Workflow
@@ -42,8 +42,17 @@ cadcli entities <file> # entities, optionally filtered
42
42
  cadcli search <file> [query] # search IDs, types, layers, text, raw fields
43
43
  --query "door" --type TEXT --layer A-TEXT --limit 10 --score --no-snippets
44
44
 
45
- cadcli view <file> [-o preview.svg] # high-fidelity SVG preview
46
- cadcli edit <file> --jq <expr> -o out.dwg
45
+ cadcli view <file> [-o preview.svg] # SVG preview
46
+ cadcli edit <file> --set-text <text> --text-id <id> -o out.dwg
47
+ cadcli edit <file> --set-layer <layer> --layer-id <id> -o out.dwg
48
+ cadcli edit <file> --set-color '#ff0000' --color-id <id> -o out.dwg
49
+ cadcli edit <file> --move <id> --dx 10 --dy 0 -o out.dwg
50
+ cadcli edit <file> --rotate <id> --angle 90 --origin 0,0 -o out.dwg
51
+ cadcli edit <file> --scale <id> --factor 2 -o out.dwg
52
+ cadcli edit <file> --copy <id> --dx 10 --dy 0 -o out.dwg
53
+ cadcli edit <file> --delete <id> -o out.dwg
54
+ cadcli edit <file> --add-line 0,0:10,0 --new-layer A-WALL -o out.dwg
55
+ cadcli edit <file> --add-text "Label" --at 5,5 --height 2.5 -o out.dwg
47
56
  cadcli json <file> [-o drawing.json] # normalized JSON
48
57
  cadcli svg <file> [-o sketch.svg] # best-effort SVG from normalized JSON
49
58
  cadcli thumbnail <file> [-o thumb.png] # embedded thumbnail when available
@@ -74,22 +83,24 @@ SEARCH HINTS
74
83
 
75
84
  ## Viewing vs SVG export
76
85
 
77
- `cadcli view` is the high-fidelity SVG path.
86
+ `cadcli view` renders SVG through acad-ts directly from the CAD document.
78
87
 
79
- `cadcli svg` renders a lightweight SVG from cadcli’s normalized JSON model. It is useful for quick agent previews and debugging, but it is not a replacement for `view`.
88
+ `cadcli svg` renders a lightweight SVG from cadcli’s normalized JSON model. It is useful for quick agent previews and debugging, while `view` preserves more of acad-ts’ CAD model semantics.
80
89
 
81
90
  ## Editing
82
91
 
83
- Editing is intentionally copy-first:
92
+ Editing is intentionally copy-first and typed. You can update text, layers, color, linetype, lineweight, transparency, visibility, block attributes, transforms, copies, and deletion; you can also add point, line, circle, arc, text, mtext, and lightweight polyline entities.
84
93
 
85
94
  ```bash
86
- cadcli edit drawing.dwg --jq '.OBJECTS[]' -o edited.dwg
95
+ cadcli edit drawing.dwg --set-text "New label" --text-id 2A -o edited.dwg
96
+ cadcli edit drawing.dwg --set-attr ROOM=204 --insert-id 3F -o edited.dwg
97
+ cadcli edit drawing.dwg --points '0,0;10,0;10,5' --closed --new-layer A-WALL -o edited.dwg
87
98
  ```
88
99
 
89
100
  In-place edits are refused unless you explicitly pass `--overwrite`:
90
101
 
91
102
  ```bash
92
- cadcli edit drawing.dwg --jq '.OBJECTS[]' --overwrite
103
+ cadcli edit drawing.dwg --set-text "New label" --text-id 2A --overwrite
93
104
  ```
94
105
 
95
106
  ## SDK
@@ -107,11 +118,11 @@ const preview = drawing.view();
107
118
  console.log(preview.svg);
108
119
  ```
109
120
 
110
- The public SDK is intentionally small: `Dwg` plus stable CAD/result types. Native tool details stay behind the SDK methods.
121
+ The public SDK is intentionally small: `Dwg` plus stable CAD/result types.
111
122
 
112
123
  ## Cache
113
124
 
114
- Search indexes are cached automatically in the platform-standard cache directory:
125
+ Search indexes are cached automatically in the platform-standard cache directory. On Node.js installs, `cadcli search` uses a disk-backed SQLite FTS index when the optional SQLite dependency is available; otherwise it falls back to a low-memory scan.
115
126
 
116
127
  ```txt
117
128
  macOS ~/Library/Caches/cadcli
@@ -123,9 +134,7 @@ Set `CADCLI_CACHE_DIR` to override this location.
123
134
 
124
135
  ## Requirements
125
136
 
126
- Inspection, overview, layers, blocks, entities, search, JSON, and lightweight SVG export work through the default pure TypeScript parser.
127
-
128
- Install native LibreDWG tools for advanced workflows: `dwgread` for high-fidelity `view`, and `dwgfilter` for edits.
137
+ Inspection, overview, layers, blocks, entities, search, JSON, SVG export, viewing, and editing work through the default pure TypeScript acad-ts backend.
129
138
 
130
139
  ## License
131
140
 
@@ -1,8 +1,48 @@
1
1
  import type { OutputOptions } from "../utils/output.js";
2
2
  export interface EditOptions extends OutputOptions {
3
- jq?: string;
4
3
  output?: string;
5
4
  overwrite?: boolean;
6
- toolDir?: string;
5
+ setText?: string;
6
+ textId?: string;
7
+ delete?: string;
8
+ move?: string;
9
+ dx?: string;
10
+ dy?: string;
11
+ dz?: string;
12
+ setLayer?: string;
13
+ layerId?: string;
14
+ setColor?: string;
15
+ colorId?: string;
16
+ setLinetype?: string;
17
+ linetypeId?: string;
18
+ setLineweight?: string;
19
+ lineweightId?: string;
20
+ setTransparency?: string;
21
+ transparencyId?: string;
22
+ hide?: string;
23
+ show?: string;
24
+ rotate?: string;
25
+ angle?: string;
26
+ origin?: string;
27
+ scale?: string;
28
+ factor?: string;
29
+ copy?: string;
30
+ matchProperties?: string;
31
+ sourceId?: string;
32
+ setAttr?: string;
33
+ insertId?: string;
34
+ addPoint?: string;
35
+ addLine?: string;
36
+ addCircle?: string;
37
+ addArc?: string;
38
+ addText?: string;
39
+ addMtext?: string;
40
+ at?: string;
41
+ height?: string;
42
+ width?: string;
43
+ closed?: boolean;
44
+ points?: string;
45
+ newLayer?: string;
46
+ newColor?: string;
7
47
  }
8
48
  export declare function edit(file: string, options: EditOptions): Promise<void>;
@@ -1,21 +1,295 @@
1
- import { editWithLibreDwgFilter } from "../core/libredwg.js";
1
+ import { editWithAcadTs, } from "../core/acad-edit.js";
2
2
  import { output, success } from "../utils/output.js";
3
3
  import { handleCommandError, userError } from "./shared.js";
4
+ function numberOption(value, name) {
5
+ const parsed = Number(value);
6
+ if (!Number.isFinite(parsed)) {
7
+ throw userError(`Invalid ${name}: ${value}`, "INVALID_NUMBER");
8
+ }
9
+ return parsed;
10
+ }
11
+ function pointOption(value, name) {
12
+ if (!value)
13
+ throw userError(`${name} requires x,y[,z].`, "INVALID_POINT");
14
+ const parts = value.split(",").map((part) => numberOption(part, name));
15
+ if (parts.length < 2 || parts.length > 3) {
16
+ throw userError(`${name} requires x,y[,z].`, "INVALID_POINT");
17
+ }
18
+ return { x: parts[0], y: parts[1], z: parts[2] };
19
+ }
20
+ function pointsOption(value, name) {
21
+ if (!value)
22
+ throw userError(`${name} requires x,y pairs.`, "INVALID_POINT");
23
+ const points = value.split(/[;|]/).map((part) => pointOption(part, name));
24
+ if (points.length < 2) {
25
+ throw userError(`${name} requires at least two points.`, "INVALID_POINT");
26
+ }
27
+ return points;
28
+ }
29
+ function colorOption(value, name) {
30
+ if (!value)
31
+ throw userError(`${name} requires a color.`, "INVALID_COLOR");
32
+ const normalized = value.toLowerCase();
33
+ if (normalized === "bylayer")
34
+ return { mode: "byLayer" };
35
+ if (normalized === "byblock")
36
+ return { mode: "byBlock" };
37
+ if (/^#?[0-9a-f]{6}$/i.test(value)) {
38
+ const hex = value.replace("#", "");
39
+ return {
40
+ mode: "rgb",
41
+ r: Number.parseInt(hex.slice(0, 2), 16),
42
+ g: Number.parseInt(hex.slice(2, 4), 16),
43
+ b: Number.parseInt(hex.slice(4, 6), 16),
44
+ };
45
+ }
46
+ if (value.includes(",")) {
47
+ const [r, g, b] = value.split(",").map((part) => numberOption(part, name));
48
+ return { mode: "rgb", r, g, b };
49
+ }
50
+ return { mode: "index", index: numberOption(value, name) };
51
+ }
52
+ function createOptions(options) {
53
+ return {
54
+ layer: options.newLayer,
55
+ color: options.newColor
56
+ ? colorOption(options.newColor, "--new-color")
57
+ : undefined,
58
+ };
59
+ }
60
+ function acadOperations(options) {
61
+ const operations = [];
62
+ if (options.setText !== undefined) {
63
+ if (!options.textId) {
64
+ throw userError("--set-text requires --text-id <id>.", "MISSING_TEXT_ID");
65
+ }
66
+ operations.push({
67
+ kind: "setText",
68
+ entityId: options.textId,
69
+ text: options.setText,
70
+ });
71
+ }
72
+ if (options.setLayer !== undefined) {
73
+ if (!options.layerId) {
74
+ throw userError("--set-layer requires --layer-id <id>.", "MISSING_LAYER_ID");
75
+ }
76
+ operations.push({
77
+ kind: "setLayer",
78
+ entityId: options.layerId,
79
+ layer: options.setLayer,
80
+ });
81
+ }
82
+ if (options.setColor !== undefined) {
83
+ if (!options.colorId) {
84
+ throw userError("--set-color requires --color-id <id>.", "MISSING_COLOR_ID");
85
+ }
86
+ operations.push({
87
+ kind: "setColor",
88
+ entityId: options.colorId,
89
+ color: colorOption(options.setColor, "--set-color"),
90
+ });
91
+ }
92
+ if (options.setLinetype !== undefined) {
93
+ if (!options.linetypeId) {
94
+ throw userError("--set-linetype requires --linetype-id <id>.", "MISSING_LINETYPE_ID");
95
+ }
96
+ operations.push({
97
+ kind: "setLineType",
98
+ entityId: options.linetypeId,
99
+ lineType: options.setLinetype,
100
+ });
101
+ }
102
+ if (options.setLineweight !== undefined) {
103
+ if (!options.lineweightId) {
104
+ throw userError("--set-lineweight requires --lineweight-id <id>.", "MISSING_LINEWEIGHT_ID");
105
+ }
106
+ operations.push({
107
+ kind: "setLineWeight",
108
+ entityId: options.lineweightId,
109
+ weight: numberOption(options.setLineweight, "--set-lineweight"),
110
+ });
111
+ }
112
+ if (options.setTransparency !== undefined) {
113
+ if (!options.transparencyId) {
114
+ throw userError("--set-transparency requires --transparency-id <id>.", "MISSING_TRANSPARENCY_ID");
115
+ }
116
+ operations.push({
117
+ kind: "setTransparency",
118
+ entityId: options.transparencyId,
119
+ alpha: numberOption(options.setTransparency, "--set-transparency"),
120
+ });
121
+ }
122
+ if (options.hide !== undefined) {
123
+ operations.push({
124
+ kind: "setVisibility",
125
+ entityId: options.hide,
126
+ visible: false,
127
+ });
128
+ }
129
+ if (options.show !== undefined) {
130
+ operations.push({
131
+ kind: "setVisibility",
132
+ entityId: options.show,
133
+ visible: true,
134
+ });
135
+ }
136
+ if (options.move !== undefined) {
137
+ operations.push({
138
+ kind: "move",
139
+ entityId: options.move,
140
+ dx: numberOption(options.dx ?? "0", "--dx"),
141
+ dy: numberOption(options.dy ?? "0", "--dy"),
142
+ dz: options.dz === undefined ? undefined : numberOption(options.dz, "--dz"),
143
+ });
144
+ }
145
+ if (options.rotate !== undefined) {
146
+ operations.push({
147
+ kind: "rotate",
148
+ entityId: options.rotate,
149
+ angleDegrees: numberOption(options.angle, "--angle"),
150
+ origin: options.origin
151
+ ? pointOption(options.origin, "--origin")
152
+ : undefined,
153
+ });
154
+ }
155
+ if (options.scale !== undefined) {
156
+ operations.push({
157
+ kind: "scale",
158
+ entityId: options.scale,
159
+ factor: numberOption(options.factor, "--factor"),
160
+ origin: options.origin
161
+ ? pointOption(options.origin, "--origin")
162
+ : undefined,
163
+ });
164
+ }
165
+ if (options.copy !== undefined) {
166
+ operations.push({
167
+ kind: "copy",
168
+ entityId: options.copy,
169
+ dx: options.dx === undefined ? undefined : numberOption(options.dx, "--dx"),
170
+ dy: options.dy === undefined ? undefined : numberOption(options.dy, "--dy"),
171
+ dz: options.dz === undefined ? undefined : numberOption(options.dz, "--dz"),
172
+ });
173
+ }
174
+ if (options.matchProperties !== undefined) {
175
+ if (!options.sourceId) {
176
+ throw userError("--match-properties requires --source-id <id>.", "MISSING_SOURCE_ID");
177
+ }
178
+ operations.push({
179
+ kind: "matchProperties",
180
+ entityId: options.matchProperties,
181
+ sourceId: options.sourceId,
182
+ });
183
+ }
184
+ if (options.setAttr !== undefined) {
185
+ if (!options.insertId) {
186
+ throw userError("--set-attr requires --insert-id <id>.", "MISSING_INSERT_ID");
187
+ }
188
+ const [tag, ...valueParts] = options.setAttr.split("=");
189
+ if (!tag || valueParts.length === 0) {
190
+ throw userError("--set-attr requires TAG=VALUE.", "INVALID_ATTRIBUTE_EDIT");
191
+ }
192
+ operations.push({
193
+ kind: "setAttribute",
194
+ entityId: options.insertId,
195
+ tag,
196
+ value: valueParts.join("="),
197
+ });
198
+ }
199
+ if (options.delete !== undefined) {
200
+ operations.push({ kind: "delete", entityId: options.delete });
201
+ }
202
+ const common = createOptions(options);
203
+ if (options.addPoint !== undefined) {
204
+ operations.push({
205
+ kind: "addPoint",
206
+ at: pointOption(options.addPoint, "--add-point"),
207
+ ...common,
208
+ });
209
+ }
210
+ if (options.addLine !== undefined) {
211
+ const [from, to] = options.addLine.split(":");
212
+ operations.push({
213
+ kind: "addLine",
214
+ from: pointOption(from, "--add-line"),
215
+ to: pointOption(to, "--add-line"),
216
+ ...common,
217
+ });
218
+ }
219
+ if (options.addCircle !== undefined) {
220
+ const [center, radius] = options.addCircle.split(":");
221
+ operations.push({
222
+ kind: "addCircle",
223
+ center: pointOption(center, "--add-circle"),
224
+ radius: numberOption(radius, "--add-circle radius"),
225
+ ...common,
226
+ });
227
+ }
228
+ if (options.addArc !== undefined) {
229
+ const [center, radius, start, end] = options.addArc.split(":");
230
+ operations.push({
231
+ kind: "addArc",
232
+ center: pointOption(center, "--add-arc"),
233
+ radius: numberOption(radius, "--add-arc radius"),
234
+ startAngleDegrees: numberOption(start, "--add-arc start angle"),
235
+ endAngleDegrees: numberOption(end, "--add-arc end angle"),
236
+ ...common,
237
+ });
238
+ }
239
+ if (options.addText !== undefined) {
240
+ operations.push({
241
+ kind: "addText",
242
+ text: options.addText,
243
+ at: pointOption(options.at, "--at"),
244
+ height: options.height
245
+ ? numberOption(options.height, "--height")
246
+ : undefined,
247
+ rotationDegrees: options.angle
248
+ ? numberOption(options.angle, "--angle")
249
+ : undefined,
250
+ ...common,
251
+ });
252
+ }
253
+ if (options.addMtext !== undefined) {
254
+ operations.push({
255
+ kind: "addMText",
256
+ text: options.addMtext,
257
+ at: pointOption(options.at, "--at"),
258
+ height: options.height
259
+ ? numberOption(options.height, "--height")
260
+ : undefined,
261
+ width: options.width ? numberOption(options.width, "--width") : undefined,
262
+ rotationDegrees: options.angle
263
+ ? numberOption(options.angle, "--angle")
264
+ : undefined,
265
+ ...common,
266
+ });
267
+ }
268
+ if (options.points !== undefined) {
269
+ operations.push({
270
+ kind: "addPolyline",
271
+ points: pointsOption(options.points, "--points"),
272
+ closed: options.closed,
273
+ ...common,
274
+ });
275
+ }
276
+ return operations;
277
+ }
4
278
  export async function edit(file, options) {
5
279
  try {
6
- if (!options.jq) {
7
- throw userError("No edit expression specified. Use --jq <expression>.", "MISSING_EDIT_EXPRESSION");
280
+ const operations = acadOperations(options);
281
+ if (operations.length === 0) {
282
+ throw userError("No edit operation specified. Use --set-text, --set-layer, --move, --delete, or an add-* operation.", "MISSING_EDIT_OPERATION");
8
283
  }
9
- const result = editWithLibreDwgFilter({
284
+ const result = editWithAcadTs({
10
285
  input: file,
11
286
  output: options.output ?? file,
12
- expression: options.jq,
287
+ operations,
13
288
  overwrite: options.overwrite,
14
- toolDir: options.toolDir,
15
289
  });
16
290
  output(options, {
17
291
  json: () => ({ success: true, ...result }),
18
- human: () => success(`Edited ${result.output} with LibreDWG dwgfilter`),
292
+ human: () => success(`Edited ${result.output} with acad-ts`),
19
293
  });
20
294
  }
21
295
  catch (err) {
@@ -5,7 +5,6 @@ export async function json(file, options) {
5
5
  try {
6
6
  const doc = await toJson(file, {
7
7
  reader: options.reader,
8
- toolDir: options.toolDir,
9
8
  });
10
9
  const content = `${stringifyJson(doc)}\n`;
11
10
  if (options.output) {
@@ -4,7 +4,6 @@ import type { DrawingReader } from "../types.js";
4
4
  import type { OutputOptions } from "../utils/output.js";
5
5
  export interface DrawingCommandOptions extends OutputOptions {
6
6
  reader?: DrawingReader;
7
- toolDir?: string;
8
7
  }
9
8
  export interface OutputFileOptions extends OutputOptions {
10
9
  output?: string;
@@ -6,7 +6,6 @@ import { error, output, success } from "../utils/output.js";
6
6
  export function drawingFor(file, options) {
7
7
  return Dwg.open(file, {
8
8
  reader: options.reader,
9
- toolDir: options.toolDir,
10
9
  });
11
10
  }
12
11
  export function userError(message, code = "USER_ERROR") {
@@ -4,7 +4,6 @@ export async function svg(file, options) {
4
4
  try {
5
5
  const result = await toSvg(file, {
6
6
  reader: options.reader,
7
- toolDir: options.toolDir,
8
7
  });
9
8
  if (options.output) {
10
9
  writeCommandOutput(options, result.svg, () => ({
@@ -5,7 +5,6 @@ export async function thumbnail(file, options) {
5
5
  try {
6
6
  const result = await getThumbnail(file, {
7
7
  reader: options.reader,
8
- toolDir: options.toolDir,
9
8
  });
10
9
  if (!options.output) {
11
10
  output(options, {
@@ -1,6 +1,5 @@
1
1
  import type { OutputOptions } from "../utils/output.js";
2
2
  export interface ViewOptions extends OutputOptions {
3
3
  output?: string;
4
- toolDir?: string;
5
4
  }
6
5
  export declare function view(file: string, options: ViewOptions): Promise<void>;
@@ -1,21 +1,19 @@
1
- import { renderSvgWithLibreDwg } from "../core/libredwg.js";
1
+ import { renderSvgWithAcadTs } from "../core/acad-view.js";
2
2
  import { handleCommandError, writeCommandOutput } from "./shared.js";
3
3
  export async function view(file, options) {
4
4
  try {
5
- const result = renderSvgWithLibreDwg(file, { toolDir: options.toolDir });
5
+ const result = renderSvgWithAcadTs(file);
6
6
  const svg = result.svg;
7
- const tool = result.tool;
8
7
  if (options.output) {
9
8
  writeCommandOutput(options, svg, () => ({
10
9
  success: true,
11
10
  file: options.output,
12
- backend: "LibreDWG",
13
- tool,
14
- }), `Wrote ${options.output} with ${tool}`);
11
+ backend: "acad-ts",
12
+ }), `Wrote ${options.output} with acad-ts`);
15
13
  return;
16
14
  }
17
15
  if (options.json) {
18
- console.log(JSON.stringify({ backend: "LibreDWG", tool, svg }, null, 2));
16
+ console.log(JSON.stringify({ backend: "acad-ts", svg }, null, 2));
19
17
  }
20
18
  else {
21
19
  console.log(svg.trimEnd());
@@ -0,0 +1,142 @@
1
+ export type AcadPoint = {
2
+ x: number;
3
+ y: number;
4
+ z?: number;
5
+ };
6
+ export type AcadColor = {
7
+ mode: "byLayer";
8
+ } | {
9
+ mode: "byBlock";
10
+ } | {
11
+ mode: "index";
12
+ index: number;
13
+ } | {
14
+ mode: "rgb";
15
+ r: number;
16
+ g: number;
17
+ b: number;
18
+ };
19
+ export type AcadEditOperation = {
20
+ kind: "setText";
21
+ entityId: string;
22
+ text: string;
23
+ } | {
24
+ kind: "setLayer";
25
+ entityId: string;
26
+ layer: string;
27
+ } | {
28
+ kind: "setColor";
29
+ entityId: string;
30
+ color: AcadColor;
31
+ } | {
32
+ kind: "setLineType";
33
+ entityId: string;
34
+ lineType: string;
35
+ } | {
36
+ kind: "setLineWeight";
37
+ entityId: string;
38
+ weight: number;
39
+ } | {
40
+ kind: "setTransparency";
41
+ entityId: string;
42
+ alpha: number;
43
+ } | {
44
+ kind: "setVisibility";
45
+ entityId: string;
46
+ visible: boolean;
47
+ } | {
48
+ kind: "move";
49
+ entityId: string;
50
+ dx: number;
51
+ dy: number;
52
+ dz?: number;
53
+ } | {
54
+ kind: "rotate";
55
+ entityId: string;
56
+ angleDegrees: number;
57
+ origin?: AcadPoint;
58
+ } | {
59
+ kind: "scale";
60
+ entityId: string;
61
+ factor: number;
62
+ origin?: AcadPoint;
63
+ } | {
64
+ kind: "copy";
65
+ entityId: string;
66
+ dx?: number;
67
+ dy?: number;
68
+ dz?: number;
69
+ } | {
70
+ kind: "matchProperties";
71
+ entityId: string;
72
+ sourceId: string;
73
+ } | {
74
+ kind: "setAttribute";
75
+ entityId: string;
76
+ tag: string;
77
+ value: string;
78
+ } | {
79
+ kind: "delete";
80
+ entityId: string;
81
+ } | {
82
+ kind: "addPoint";
83
+ at: AcadPoint;
84
+ layer?: string;
85
+ color?: AcadColor;
86
+ } | {
87
+ kind: "addLine";
88
+ from: AcadPoint;
89
+ to: AcadPoint;
90
+ layer?: string;
91
+ color?: AcadColor;
92
+ } | {
93
+ kind: "addCircle";
94
+ center: AcadPoint;
95
+ radius: number;
96
+ layer?: string;
97
+ color?: AcadColor;
98
+ } | {
99
+ kind: "addArc";
100
+ center: AcadPoint;
101
+ radius: number;
102
+ startAngleDegrees: number;
103
+ endAngleDegrees: number;
104
+ layer?: string;
105
+ color?: AcadColor;
106
+ } | {
107
+ kind: "addText";
108
+ text: string;
109
+ at: AcadPoint;
110
+ height?: number;
111
+ rotationDegrees?: number;
112
+ layer?: string;
113
+ color?: AcadColor;
114
+ } | {
115
+ kind: "addMText";
116
+ text: string;
117
+ at: AcadPoint;
118
+ height?: number;
119
+ width?: number;
120
+ rotationDegrees?: number;
121
+ layer?: string;
122
+ color?: AcadColor;
123
+ } | {
124
+ kind: "addPolyline";
125
+ points: AcadPoint[];
126
+ closed?: boolean;
127
+ layer?: string;
128
+ color?: AcadColor;
129
+ };
130
+ export interface AcadEditResult {
131
+ input: string;
132
+ output: string;
133
+ backend: "acad-ts";
134
+ operations: AcadEditOperation[];
135
+ changed: number;
136
+ }
137
+ export declare function editWithAcadTs(opts: {
138
+ input: string;
139
+ output: string;
140
+ operations: AcadEditOperation[];
141
+ overwrite?: boolean;
142
+ }): AcadEditResult;