@miclivs/cadcli 0.1.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/LICENSE +21 -0
- package/README.md +132 -0
- package/dist/commands/blocks.d.ts +4 -0
- package/dist/commands/blocks.js +22 -0
- package/dist/commands/edit.d.ts +8 -0
- package/dist/commands/edit.js +24 -0
- package/dist/commands/entities.d.ts +7 -0
- package/dist/commands/entities.js +26 -0
- package/dist/commands/info.d.ts +2 -0
- package/dist/commands/info.js +22 -0
- package/dist/commands/json.d.ts +2 -0
- package/dist/commands/json.js +20 -0
- package/dist/commands/layers.d.ts +4 -0
- package/dist/commands/layers.js +22 -0
- package/dist/commands/overview.d.ts +5 -0
- package/dist/commands/overview.js +59 -0
- package/dist/commands/search.d.ts +11 -0
- package/dist/commands/search.js +45 -0
- package/dist/commands/shared.d.ts +16 -0
- package/dist/commands/shared.js +40 -0
- package/dist/commands/svg.d.ts +2 -0
- package/dist/commands/svg.js +27 -0
- package/dist/commands/thumbnail.d.ts +2 -0
- package/dist/commands/thumbnail.js +31 -0
- package/dist/commands/view.d.ts +6 -0
- package/dist/commands/view.js +27 -0
- package/dist/core/adapter.d.ts +14 -0
- package/dist/core/adapter.js +165 -0
- package/dist/core/drawing.d.ts +14 -0
- package/dist/core/drawing.js +61 -0
- package/dist/core/errors.d.ts +5 -0
- package/dist/core/errors.js +10 -0
- package/dist/core/files.d.ts +7 -0
- package/dist/core/files.js +27 -0
- package/dist/core/libredwg.d.ts +37 -0
- package/dist/core/libredwg.js +86 -0
- package/dist/core/normalize.d.ts +3 -0
- package/dist/core/normalize.js +156 -0
- package/dist/core/overview.d.ts +35 -0
- package/dist/core/overview.js +227 -0
- package/dist/core/search-cache.d.ts +17 -0
- package/dist/core/search-cache.js +69 -0
- package/dist/core/search.d.ts +18 -0
- package/dist/core/search.js +137 -0
- package/dist/core/svg.d.ts +2 -0
- package/dist/core/svg.js +105 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +1 -0
- package/dist/main.d.ts +2 -0
- package/dist/main.js +151 -0
- package/dist/sdk.d.ts +30 -0
- package/dist/sdk.js +57 -0
- package/dist/store.d.ts +6 -0
- package/dist/store.js +17 -0
- package/dist/types.d.ts +65 -0
- package/dist/types.js +1 -0
- package/dist/utils/exit-codes.d.ts +5 -0
- package/dist/utils/exit-codes.js +5 -0
- package/dist/utils/output.d.ts +19 -0
- package/dist/utils/output.js +26 -0
- package/package.json +76 -0
- package/patches/@node-projects%2Facad-ts@2.3.0.patch +48 -0
- package/skills/cadcli/SKILL.md +34 -0
package/dist/main.js
ADDED
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { createRequire } from "node:module";
|
|
3
|
+
import chalk from "chalk";
|
|
4
|
+
import { Command } from "commander";
|
|
5
|
+
import { blocks } from "./commands/blocks.js";
|
|
6
|
+
import { edit } from "./commands/edit.js";
|
|
7
|
+
import { entities } from "./commands/entities.js";
|
|
8
|
+
import { info } from "./commands/info.js";
|
|
9
|
+
import { json } from "./commands/json.js";
|
|
10
|
+
import { layers } from "./commands/layers.js";
|
|
11
|
+
import { overview } from "./commands/overview.js";
|
|
12
|
+
import { search } from "./commands/search.js";
|
|
13
|
+
import { svg } from "./commands/svg.js";
|
|
14
|
+
import { thumbnail } from "./commands/thumbnail.js";
|
|
15
|
+
import { view } from "./commands/view.js";
|
|
16
|
+
const require = createRequire(import.meta.url);
|
|
17
|
+
const { version } = require("../package.json");
|
|
18
|
+
const program = new Command();
|
|
19
|
+
function showHelp() {
|
|
20
|
+
console.log(`Usage: cadcli [options] [command]
|
|
21
|
+
|
|
22
|
+
Agent-friendly CAD inspection, search, viewing, and editing.
|
|
23
|
+
|
|
24
|
+
Examples:
|
|
25
|
+
$ cadcli info drawing.dwg Summarize a drawing
|
|
26
|
+
$ cadcli overview drawing.dwg Show search vocabulary
|
|
27
|
+
$ cadcli layers drawing.dwg --json List layers for scripts/agents
|
|
28
|
+
$ cadcli entities drawing.dwg --type LINE --limit 20
|
|
29
|
+
$ cadcli search drawing.dwg "conference" --layer A-TEXT
|
|
30
|
+
$ cadcli view drawing.dwg -o drawing.svg
|
|
31
|
+
$ cadcli edit drawing.dwg --jq '.OBJECTS[]' -o edited.dwg
|
|
32
|
+
|
|
33
|
+
Workflow: info → overview → search/entities → view/edit
|
|
34
|
+
|
|
35
|
+
Inspecting:
|
|
36
|
+
info <file> Drawing metadata and counts
|
|
37
|
+
overview <file> Search vocabulary by layer/type/block/text
|
|
38
|
+
layers <file> List layers
|
|
39
|
+
blocks <file> List blocks
|
|
40
|
+
entities <file> List/filter entities
|
|
41
|
+
search <file> Search entities by text, type, layer, and raw fields
|
|
42
|
+
|
|
43
|
+
Viewing and editing:
|
|
44
|
+
view <file> Render a high-fidelity SVG preview
|
|
45
|
+
edit <file> Edit DWG/DXF with jq-style expressions
|
|
46
|
+
|
|
47
|
+
Conversion:
|
|
48
|
+
json <file> Export normalized JSON
|
|
49
|
+
svg <file> Render best-effort SVG from normalized JSON
|
|
50
|
+
thumbnail <file> Extract embedded thumbnail when available
|
|
51
|
+
|
|
52
|
+
Options:
|
|
53
|
+
--json Output as JSON
|
|
54
|
+
-q, --quiet Suppress non-essential output
|
|
55
|
+
--no-color Disable color
|
|
56
|
+
-v, --version Show version
|
|
57
|
+
-h, --help Show this help
|
|
58
|
+
|
|
59
|
+
Docs: https://github.com/Michaelliv/cadcli`);
|
|
60
|
+
}
|
|
61
|
+
program
|
|
62
|
+
.name("cadcli")
|
|
63
|
+
.description("Agent-friendly CAD inspection, search, viewing, and editing.")
|
|
64
|
+
.version(`cadcli ${version}`, "-v, --version")
|
|
65
|
+
.option("--json", "Output as JSON")
|
|
66
|
+
.option("-q, --quiet", "Suppress output")
|
|
67
|
+
.option("--no-color", "Disable color")
|
|
68
|
+
.showSuggestionAfterError(true)
|
|
69
|
+
.helpCommand(false)
|
|
70
|
+
.addHelpText("before", () => {
|
|
71
|
+
showHelp();
|
|
72
|
+
process.exit(0);
|
|
73
|
+
});
|
|
74
|
+
program.hook("preAction", (cmd) => {
|
|
75
|
+
if (cmd.optsWithGlobals().color === false)
|
|
76
|
+
chalk.level = 0;
|
|
77
|
+
});
|
|
78
|
+
program
|
|
79
|
+
.command("info <file>")
|
|
80
|
+
.description("Show drawing metadata and summary")
|
|
81
|
+
.action(async (file, _opts, cmd) => info(file, cmd.optsWithGlobals()));
|
|
82
|
+
program
|
|
83
|
+
.command("overview <file>")
|
|
84
|
+
.description("Show search vocabulary by layer/type/block/text")
|
|
85
|
+
.option("--keywords <n>", "Max keywords/hints returned")
|
|
86
|
+
.option("--samples <n>", "Max text samples returned")
|
|
87
|
+
.action(async (file, opts, cmd) => overview(file, { ...cmd.optsWithGlobals(), ...opts }));
|
|
88
|
+
program
|
|
89
|
+
.command("layers <file>")
|
|
90
|
+
.description("List layers")
|
|
91
|
+
.option("--total", "Return layer count")
|
|
92
|
+
.action(async (file, opts, cmd) => layers(file, { ...cmd.optsWithGlobals(), ...opts }));
|
|
93
|
+
program
|
|
94
|
+
.command("blocks <file>")
|
|
95
|
+
.description("List blocks")
|
|
96
|
+
.option("--total", "Return block count")
|
|
97
|
+
.action(async (file, opts, cmd) => blocks(file, { ...cmd.optsWithGlobals(), ...opts }));
|
|
98
|
+
program
|
|
99
|
+
.command("entities <file>")
|
|
100
|
+
.description("List/filter entities")
|
|
101
|
+
.option("--type <name>", "Filter by entity type")
|
|
102
|
+
.option("--layer <name>", "Filter by layer")
|
|
103
|
+
.option("--limit <n>", "Limit entities returned")
|
|
104
|
+
.option("--total", "Return entity count")
|
|
105
|
+
.action(async (file, opts, cmd) => entities(file, { ...cmd.optsWithGlobals(), ...opts }));
|
|
106
|
+
program
|
|
107
|
+
.command("search <file> [query...]")
|
|
108
|
+
.description("Search entities by text, type, layer, and raw fields")
|
|
109
|
+
.option("--query <text>", "Search query")
|
|
110
|
+
.option("--type <name>", "Filter by entity type")
|
|
111
|
+
.option("--layer <name>", "Filter by layer")
|
|
112
|
+
.option("--limit <n>", "Limit results")
|
|
113
|
+
.option("--total", "Return result count")
|
|
114
|
+
.option("--score", "Include relevance scores")
|
|
115
|
+
.option("--no-snippets", "Omit matched snippets")
|
|
116
|
+
.action(async (file, queryWords, opts, cmd) => {
|
|
117
|
+
const root = { ...cmd.optsWithGlobals(), ...opts };
|
|
118
|
+
root.query = root.query || queryWords.join(" ");
|
|
119
|
+
await search(file, root);
|
|
120
|
+
});
|
|
121
|
+
program
|
|
122
|
+
.command("view <file>")
|
|
123
|
+
.description("Render a high-fidelity SVG preview")
|
|
124
|
+
.option("-o, --output <path>", "Output SVG file")
|
|
125
|
+
.action(async (file, opts, cmd) => view(file, { ...cmd.optsWithGlobals(), ...opts }));
|
|
126
|
+
program
|
|
127
|
+
.command("edit <file>")
|
|
128
|
+
.description("Edit DWG/DXF with jq-style expressions")
|
|
129
|
+
.requiredOption("--jq <expression>", "dwgfilter jq expression")
|
|
130
|
+
.option("-o, --output <path>", "Output file; defaults to input with --overwrite")
|
|
131
|
+
.option("--overwrite", "Allow editing the input file in place")
|
|
132
|
+
.action(async (file, opts, cmd) => edit(file, { ...cmd.optsWithGlobals(), ...opts }));
|
|
133
|
+
program
|
|
134
|
+
.command("json <file>")
|
|
135
|
+
.description("Export normalized JSON")
|
|
136
|
+
.option("-o, --output <path>", "Output file")
|
|
137
|
+
.action(async (file, opts, cmd) => json(file, { ...cmd.optsWithGlobals(), ...opts }));
|
|
138
|
+
program
|
|
139
|
+
.command("svg <file>")
|
|
140
|
+
.description("Render best-effort SVG from normalized JSON")
|
|
141
|
+
.option("-o, --output <path>", "Output file")
|
|
142
|
+
.action(async (file, opts, cmd) => svg(file, { ...cmd.optsWithGlobals(), ...opts }));
|
|
143
|
+
program
|
|
144
|
+
.command("thumbnail <file>")
|
|
145
|
+
.description("Extract embedded thumbnail when available")
|
|
146
|
+
.option("-o, --output <path>", "Output file")
|
|
147
|
+
.action(async (file, opts, cmd) => thumbnail(file, { ...cmd.optsWithGlobals(), ...opts }));
|
|
148
|
+
program.parseAsync(process.argv).catch((err) => {
|
|
149
|
+
console.error("Fatal error:", err.message);
|
|
150
|
+
process.exit(1);
|
|
151
|
+
});
|
package/dist/sdk.d.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { type LoadOptions } from "./core/drawing.js";
|
|
2
|
+
import { type LibreDwgEditResult, type LibreDwgViewResult } from "./core/libredwg.js";
|
|
3
|
+
import { type DrawingOverview, type DrawingOverviewOptions } from "./core/overview.js";
|
|
4
|
+
import { type DwgSearchOptions, type DwgSearchResult } from "./core/search.js";
|
|
5
|
+
import type { DwgBlock, DwgDocument, DwgEntity, DwgLayer, DwgSummary, EntityFilter, SvgResult, ThumbnailResult } from "./types.js";
|
|
6
|
+
export declare class Dwg {
|
|
7
|
+
readonly file: string;
|
|
8
|
+
private readonly opts;
|
|
9
|
+
constructor(file: string, opts?: LoadOptions);
|
|
10
|
+
document(): Promise<DwgDocument>;
|
|
11
|
+
info(): Promise<DwgSummary>;
|
|
12
|
+
layers(): Promise<DwgLayer[]>;
|
|
13
|
+
blocks(): Promise<DwgBlock[]>;
|
|
14
|
+
entities(filter?: EntityFilter): Promise<DwgEntity[]>;
|
|
15
|
+
search(opts?: DwgSearchOptions): Promise<DwgSearchResult[]>;
|
|
16
|
+
overview(opts?: DrawingOverviewOptions): Promise<DrawingOverview>;
|
|
17
|
+
json(): Promise<DwgDocument>;
|
|
18
|
+
svg(): Promise<SvgResult>;
|
|
19
|
+
view(opts?: {
|
|
20
|
+
toolDir?: string;
|
|
21
|
+
}): LibreDwgViewResult;
|
|
22
|
+
edit(opts: {
|
|
23
|
+
output: string;
|
|
24
|
+
expression: string;
|
|
25
|
+
overwrite?: boolean;
|
|
26
|
+
toolDir?: string;
|
|
27
|
+
}): LibreDwgEditResult;
|
|
28
|
+
thumbnail(): Promise<ThumbnailResult>;
|
|
29
|
+
static open(file: string, opts?: LoadOptions): Dwg;
|
|
30
|
+
}
|
package/dist/sdk.js
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { getBlocks, getEntities, getInfo, getLayers, getThumbnail, loadDrawing, toJson, toSvg, } from "./core/drawing.js";
|
|
2
|
+
import { editWithLibreDwgFilter, renderSvgWithLibreDwg, } from "./core/libredwg.js";
|
|
3
|
+
import { getOverview, } from "./core/overview.js";
|
|
4
|
+
import { searchDrawing, } from "./core/search.js";
|
|
5
|
+
export class Dwg {
|
|
6
|
+
file;
|
|
7
|
+
opts;
|
|
8
|
+
constructor(file, opts = {}) {
|
|
9
|
+
this.file = file;
|
|
10
|
+
this.opts = opts;
|
|
11
|
+
}
|
|
12
|
+
document() {
|
|
13
|
+
return loadDrawing(this.file, this.opts);
|
|
14
|
+
}
|
|
15
|
+
info() {
|
|
16
|
+
return getInfo(this.file, this.opts);
|
|
17
|
+
}
|
|
18
|
+
layers() {
|
|
19
|
+
return getLayers(this.file, this.opts);
|
|
20
|
+
}
|
|
21
|
+
blocks() {
|
|
22
|
+
return getBlocks(this.file, this.opts);
|
|
23
|
+
}
|
|
24
|
+
entities(filter) {
|
|
25
|
+
return getEntities(this.file, filter, this.opts);
|
|
26
|
+
}
|
|
27
|
+
search(opts) {
|
|
28
|
+
return searchDrawing(this.file, opts, this.opts);
|
|
29
|
+
}
|
|
30
|
+
overview(opts) {
|
|
31
|
+
return getOverview(this.file, opts, this.opts);
|
|
32
|
+
}
|
|
33
|
+
json() {
|
|
34
|
+
return toJson(this.file, this.opts);
|
|
35
|
+
}
|
|
36
|
+
svg() {
|
|
37
|
+
return toSvg(this.file, this.opts);
|
|
38
|
+
}
|
|
39
|
+
view(opts = {}) {
|
|
40
|
+
return renderSvgWithLibreDwg(this.file, opts);
|
|
41
|
+
}
|
|
42
|
+
edit(opts) {
|
|
43
|
+
return editWithLibreDwgFilter({
|
|
44
|
+
input: this.file,
|
|
45
|
+
output: opts.output,
|
|
46
|
+
expression: opts.expression,
|
|
47
|
+
overwrite: opts.overwrite,
|
|
48
|
+
toolDir: opts.toolDir,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
thumbnail() {
|
|
52
|
+
return getThumbnail(this.file, this.opts);
|
|
53
|
+
}
|
|
54
|
+
static open(file, opts) {
|
|
55
|
+
return new Dwg(file, opts);
|
|
56
|
+
}
|
|
57
|
+
}
|
package/dist/store.d.ts
ADDED
package/dist/store.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { homedir } from "node:os";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
const APP_NAME = "cadcli";
|
|
4
|
+
export function getCacheDir(options = {}) {
|
|
5
|
+
const env = options.env ?? process.env;
|
|
6
|
+
const platform = options.platform ?? process.platform;
|
|
7
|
+
const home = options.home ?? homedir();
|
|
8
|
+
if (env.CADCLI_CACHE_DIR)
|
|
9
|
+
return env.CADCLI_CACHE_DIR;
|
|
10
|
+
if (platform === "darwin") {
|
|
11
|
+
return join(home, "Library", "Caches", APP_NAME);
|
|
12
|
+
}
|
|
13
|
+
if (platform === "win32") {
|
|
14
|
+
return join(env.LOCALAPPDATA ?? join(home, "AppData", "Local"), APP_NAME, "Cache");
|
|
15
|
+
}
|
|
16
|
+
return join(env.XDG_CACHE_HOME ?? join(home, ".cache"), APP_NAME);
|
|
17
|
+
}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
export type DwgFormat = "DWG" | "DXF";
|
|
2
|
+
export interface DwgBounds {
|
|
3
|
+
minX: number;
|
|
4
|
+
minY: number;
|
|
5
|
+
maxX: number;
|
|
6
|
+
maxY: number;
|
|
7
|
+
}
|
|
8
|
+
export interface DwgEntity {
|
|
9
|
+
id: string;
|
|
10
|
+
type: string;
|
|
11
|
+
layer?: string;
|
|
12
|
+
color?: string | number;
|
|
13
|
+
data: Record<string, unknown>;
|
|
14
|
+
}
|
|
15
|
+
export interface DwgLayer {
|
|
16
|
+
name: string;
|
|
17
|
+
entityCount: number;
|
|
18
|
+
frozen?: boolean;
|
|
19
|
+
locked?: boolean;
|
|
20
|
+
color?: string | number;
|
|
21
|
+
}
|
|
22
|
+
export interface DwgBlock {
|
|
23
|
+
name: string;
|
|
24
|
+
entityCount: number;
|
|
25
|
+
}
|
|
26
|
+
export interface DwgSummary {
|
|
27
|
+
file: string;
|
|
28
|
+
format: DwgFormat;
|
|
29
|
+
version?: string;
|
|
30
|
+
counts: {
|
|
31
|
+
entities: number;
|
|
32
|
+
layers: number;
|
|
33
|
+
blocks: number;
|
|
34
|
+
unsupported: number;
|
|
35
|
+
};
|
|
36
|
+
bounds?: DwgBounds;
|
|
37
|
+
}
|
|
38
|
+
export interface DwgDocument {
|
|
39
|
+
summary: DwgSummary;
|
|
40
|
+
layers: DwgLayer[];
|
|
41
|
+
blocks: DwgBlock[];
|
|
42
|
+
entities: DwgEntity[];
|
|
43
|
+
unsupported: DwgEntity[];
|
|
44
|
+
raw: unknown;
|
|
45
|
+
}
|
|
46
|
+
export interface EntityFilter {
|
|
47
|
+
type?: string;
|
|
48
|
+
layer?: string;
|
|
49
|
+
limit?: number;
|
|
50
|
+
}
|
|
51
|
+
export interface SvgResult {
|
|
52
|
+
svg: string;
|
|
53
|
+
unsupported: number;
|
|
54
|
+
rendered: number;
|
|
55
|
+
bounds: DwgBounds;
|
|
56
|
+
}
|
|
57
|
+
export interface ThumbnailResult {
|
|
58
|
+
data: Uint8Array;
|
|
59
|
+
mimeType: string;
|
|
60
|
+
extension: string;
|
|
61
|
+
}
|
|
62
|
+
export interface DrawingReader {
|
|
63
|
+
parse(file: string, bytes: Uint8Array, format: DwgFormat): Promise<unknown>;
|
|
64
|
+
thumbnail?(file: string, bytes: Uint8Array, format: DwgFormat): Promise<ThumbnailResult | null>;
|
|
65
|
+
}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export interface OutputOptions {
|
|
2
|
+
json?: boolean;
|
|
3
|
+
quiet?: boolean;
|
|
4
|
+
}
|
|
5
|
+
export declare const success: (msg: string) => void;
|
|
6
|
+
export declare const info: (msg: string) => void;
|
|
7
|
+
export declare const warn: (msg: string) => void;
|
|
8
|
+
export declare const error: (msg: string) => void;
|
|
9
|
+
export declare const bold: (s: string) => string;
|
|
10
|
+
export declare const dim: (s: string) => string;
|
|
11
|
+
export declare const cmd: (s: string) => string;
|
|
12
|
+
export declare const hint: (msg: string) => void;
|
|
13
|
+
export declare function stringifyJson(data: unknown): string;
|
|
14
|
+
export declare function jsonOutput(data: unknown): void;
|
|
15
|
+
export declare function output(options: OutputOptions, handlers: {
|
|
16
|
+
json?: () => unknown;
|
|
17
|
+
quiet?: () => void;
|
|
18
|
+
human: () => void;
|
|
19
|
+
}): void;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
export const success = (msg) => console.log(chalk.green("✓"), msg);
|
|
3
|
+
export const info = (msg) => console.error(chalk.blue("ℹ"), msg);
|
|
4
|
+
export const warn = (msg) => console.error(chalk.yellow("⚠"), msg);
|
|
5
|
+
export const error = (msg) => console.error(chalk.red("✗"), msg);
|
|
6
|
+
export const bold = (s) => chalk.bold(s);
|
|
7
|
+
export const dim = (s) => chalk.dim(s);
|
|
8
|
+
export const cmd = (s) => chalk.cyan(s);
|
|
9
|
+
export const hint = (msg) => console.log(chalk.dim(` ${msg}`));
|
|
10
|
+
export function stringifyJson(data) {
|
|
11
|
+
return JSON.stringify(data, (_key, value) => (typeof value === "bigint" ? value.toString() : value), 2);
|
|
12
|
+
}
|
|
13
|
+
export function jsonOutput(data) {
|
|
14
|
+
console.log(stringifyJson(data));
|
|
15
|
+
}
|
|
16
|
+
export function output(options, handlers) {
|
|
17
|
+
if (options.json && handlers.json) {
|
|
18
|
+
jsonOutput(handlers.json());
|
|
19
|
+
}
|
|
20
|
+
else if (options.quiet && handlers.quiet) {
|
|
21
|
+
handlers.quiet();
|
|
22
|
+
}
|
|
23
|
+
else if (!options.quiet) {
|
|
24
|
+
handlers.human();
|
|
25
|
+
}
|
|
26
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@miclivs/cadcli",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Agent-friendly CAD inspection, search, viewing, and editing for DWG/DXF files.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"bin": {
|
|
15
|
+
"cadcli": "dist/main.js"
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"dist",
|
|
19
|
+
"patches",
|
|
20
|
+
"skills"
|
|
21
|
+
],
|
|
22
|
+
"scripts": {
|
|
23
|
+
"build": "tsc",
|
|
24
|
+
"prepublishOnly": "npm run build",
|
|
25
|
+
"ci": "bun test --coverage && bun run build && bunx biome check src/",
|
|
26
|
+
"dev": "bun run src/main.ts",
|
|
27
|
+
"build:bun": "bun build --compile src/main.ts --outfile cadcli",
|
|
28
|
+
"build:bun-linux": "bun build --compile --target=bun-linux-x64 src/main.ts --outfile cadcli-linux-x64",
|
|
29
|
+
"build:bun-mac-arm": "bun build --compile --target=bun-darwin-arm64 src/main.ts --outfile cadcli-darwin-arm64",
|
|
30
|
+
"build:bun-mac-x64": "bun build --compile --target=bun-darwin-x64 src/main.ts --outfile cadcli-darwin-x64",
|
|
31
|
+
"test": "bun test",
|
|
32
|
+
"format": "bunx biome format --write src/",
|
|
33
|
+
"lint": "bunx biome lint src/",
|
|
34
|
+
"check": "bunx biome check src/"
|
|
35
|
+
},
|
|
36
|
+
"repository": {
|
|
37
|
+
"type": "git",
|
|
38
|
+
"url": "git+https://github.com/Michaelliv/cadcli.git"
|
|
39
|
+
},
|
|
40
|
+
"homepage": "https://github.com/Michaelliv/cadcli#readme",
|
|
41
|
+
"bugs": {
|
|
42
|
+
"url": "https://github.com/Michaelliv/cadcli/issues"
|
|
43
|
+
},
|
|
44
|
+
"keywords": [
|
|
45
|
+
"dwg",
|
|
46
|
+
"dxf",
|
|
47
|
+
"cad",
|
|
48
|
+
"cli",
|
|
49
|
+
"sdk",
|
|
50
|
+
"libredwg",
|
|
51
|
+
"svg",
|
|
52
|
+
"conversion",
|
|
53
|
+
"pi-package"
|
|
54
|
+
],
|
|
55
|
+
"pi": {
|
|
56
|
+
"skills": [
|
|
57
|
+
"skills"
|
|
58
|
+
]
|
|
59
|
+
},
|
|
60
|
+
"license": "MIT",
|
|
61
|
+
"devDependencies": {
|
|
62
|
+
"@biomejs/biome": "^2.3.14",
|
|
63
|
+
"@types/bun": "latest",
|
|
64
|
+
"typescript": "^5.8.0"
|
|
65
|
+
},
|
|
66
|
+
"dependencies": {
|
|
67
|
+
"@node-projects/acad-ts": "2.3.0",
|
|
68
|
+
"chalk": "^5.6.2",
|
|
69
|
+
"commander": "^14.0.3",
|
|
70
|
+
"minisearch": "^7.2.0",
|
|
71
|
+
"nanoid": "^5.1.6"
|
|
72
|
+
},
|
|
73
|
+
"patchedDependencies": {
|
|
74
|
+
"@node-projects/acad-ts@2.3.0": "patches/@node-projects%2Facad-ts@2.3.0.patch"
|
|
75
|
+
}
|
|
76
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
diff --git a/dist/IO/DWG/DwgStreamReaders/DwgObjectReader.js b/dist/IO/DWG/DwgStreamReaders/DwgObjectReader.js
|
|
2
|
+
index 76143736c81f492d09c27def63a404575852ad2a..584a409e80755565792529c1982b155e066d2ef8 100644
|
|
3
|
+
--- a/dist/IO/DWG/DwgStreamReaders/DwgObjectReader.js
|
|
4
|
+
+++ b/dist/IO/DWG/DwgStreamReaders/DwgObjectReader.js
|
|
5
|
+
@@ -247,7 +247,7 @@ export class DwgObjectReader extends DwgSectionIO {
|
|
6
|
+
this._classes.set(c.classNumber, c);
|
|
7
|
+
}
|
|
8
|
+
this._memoryStream = new Uint8Array(reader.stream);
|
|
9
|
+
- this._crcReader = DwgStreamReaderBase.getStreamHandler(this._version, new Uint8Array(this._memoryStream));
|
|
10
|
+
+ this._crcReader = DwgStreamReaderBase.getStreamHandler(this._version, this._memoryStream);
|
|
11
|
+
}
|
|
12
|
+
read() {
|
|
13
|
+
while (this._handles.length > 0) {
|
|
14
|
+
@@ -291,20 +291,20 @@ export class DwgObjectReader extends DwgSectionIO {
|
|
15
|
+
if (this.r2010Plus) {
|
|
16
|
+
const handleSize = this._crcReader.readModularChar();
|
|
17
|
+
const handleSectionOffset = this._crcReader.positionInBits() + sizeInBits - handleSize;
|
|
18
|
+
- this._objectReader = DwgStreamReaderBase.getStreamHandler(this._version, new Uint8Array(this._memoryStream), this._reader.encoding);
|
|
19
|
+
+ this._objectReader = DwgStreamReaderBase.getStreamHandler(this._version, this._memoryStream, this._reader.encoding);
|
|
20
|
+
this._objectReader.setPositionInBits(this._crcReader.positionInBits());
|
|
21
|
+
this._objectInitialPos = this._objectReader.positionInBits();
|
|
22
|
+
type = this._objectReader.readObjectType();
|
|
23
|
+
- this._handlesReader = DwgStreamReaderBase.getStreamHandler(this._version, new Uint8Array(this._memoryStream), this._reader.encoding);
|
|
24
|
+
+ this._handlesReader = DwgStreamReaderBase.getStreamHandler(this._version, this._memoryStream, this._reader.encoding);
|
|
25
|
+
this._handlesReader.setPositionInBits(handleSectionOffset);
|
|
26
|
+
- this._textReader = DwgStreamReaderBase.getStreamHandler(this._version, new Uint8Array(this._memoryStream), this._reader.encoding);
|
|
27
|
+
+ this._textReader = DwgStreamReaderBase.getStreamHandler(this._version, this._memoryStream, this._reader.encoding);
|
|
28
|
+
this._textReader.setPositionByFlag(handleSectionOffset - 1);
|
|
29
|
+
this._mergedReaders = new DwgMergedReader(this._objectReader, this._textReader, this._handlesReader);
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
- this._objectReader = DwgStreamReaderBase.getStreamHandler(this._version, new Uint8Array(this._memoryStream), this._reader.encoding);
|
|
33
|
+
+ this._objectReader = DwgStreamReaderBase.getStreamHandler(this._version, this._memoryStream, this._reader.encoding);
|
|
34
|
+
this._objectReader.setPositionInBits(this._crcReader.positionInBits());
|
|
35
|
+
- this._handlesReader = DwgStreamReaderBase.getStreamHandler(this._version, new Uint8Array(this._memoryStream), this._reader.encoding);
|
|
36
|
+
+ this._handlesReader = DwgStreamReaderBase.getStreamHandler(this._version, this._memoryStream, this._reader.encoding);
|
|
37
|
+
this._textReader = this._objectReader;
|
|
38
|
+
this._objectInitialPos = this._objectReader.positionInBits();
|
|
39
|
+
type = this._objectReader.readObjectType();
|
|
40
|
+
@@ -532,7 +532,7 @@ export class DwgObjectReader extends DwgSectionIO {
|
|
41
|
+
const size = this._objectReader.readRawLong();
|
|
42
|
+
this._handlesReader.setPositionInBits(size + this._objectInitialPos);
|
|
43
|
+
if (this._version === ACadVersion.AC1021) {
|
|
44
|
+
- this._textReader = DwgStreamReaderBase.getStreamHandler(this._version, new Uint8Array(this._memoryStream), this._reader.encoding);
|
|
45
|
+
+ this._textReader = DwgStreamReaderBase.getStreamHandler(this._version, this._memoryStream, this._reader.encoding);
|
|
46
|
+
this._textReader.setPositionByFlag(size + this._objectInitialPos - 1);
|
|
47
|
+
}
|
|
48
|
+
this._mergedReaders = new DwgMergedReader(this._objectReader, this._textReader, this._handlesReader);
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: cadcli
|
|
3
|
+
description: Inspect, search, summarize, preview, and safely edit DWG/DXF CAD drawings with the cadcli CLI. Use when the user asks about CAD files, floorplans, DWG/DXF contents, layers, blocks, entities, text, previews, or jq-backed CAD edits.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# cadcli
|
|
7
|
+
|
|
8
|
+
Use `cadcli` for progressive CAD file discovery. Start broad, then narrow down:
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
cadcli info <file> --json
|
|
12
|
+
cadcli overview <file>
|
|
13
|
+
cadcli layers <file> --json
|
|
14
|
+
cadcli entities <file> --limit 20 --json
|
|
15
|
+
cadcli search <file> "query" --json
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
For visual checks, prefer the high-fidelity native path when available:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
cadcli view <file> -o preview.svg
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
For lightweight previews from the normalized model:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
cadcli svg <file> -o preview.svg
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
For edits, never overwrite by default. Write to a new file unless the user explicitly asks for in-place edits:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
cadcli edit <file> --jq '<jq expression>' -o edited.dwg
|
|
34
|
+
```
|