lineadraw 0.7.0 → 0.8.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
@@ -141,7 +141,8 @@ token; `--port`, `--token` and `LINEA_BRIDGE_TOKEN` override) — see
141
141
  docs/desktop-bridge.md in the linea repo.
142
142
 
143
143
  The manifest is deterministic (repo-relative paths, no git metadata), so
144
- `check` is a byte-for-byte diff — the included CI workflow runs it on every
144
+ `check` compares the parsed JSON (formatting, a trailing newline or CRLF
145
+ line endings never make it stale) — the included CI workflow runs it on every
145
146
  push and PR. `manifest`/`check` also **dry-run every block** through
146
147
  `lineadraw/sdk` and render thumbnails.
147
148
 
@@ -180,7 +181,7 @@ const walls = doc.addLayer({ name: "walls", color: "#e8e8e8", lineWidth: 0.5 });
180
181
  doc.add([
181
182
  { type: "polyline", layerId: walls, closed: true,
182
183
  points: [[0, 0], [6000, 0], [6000, 3000], [0, 3000]] },
183
- { type: "dimension", points: [[0, 0], [6000, 0]], offset: [0, -500],
184
+ { type: "dimension", points: [[0, 0], [6000, 0]], offset: -500,
184
185
  scale: 50 }, // annotations × drawing scale
185
186
  ]);
186
187
  doc.addLayout("Plan 1:50", { sheet: "A3", viewport: { scale: "1:50" } });
@@ -221,7 +222,11 @@ await doc.exportPdf("plan.pdf");
221
222
 
222
223
  ### API surface
223
224
 
224
- `newDrawing(name?)` / `drawingFromJson(text)` / `openDrawing(path)` → `Drawing`:
225
+ `newDrawing(name?, options?)` / `drawingFromJson(text)` / `openDrawing(path, options?)`
226
+ → `Drawing`; `options.marketplaces` lists the marketplaces to search and
227
+ install from (`{ kind: "github", spec: "owner/repo[@branch]", token? }` or
228
+ `{ kind: "folder", folder }`, priority order; the public collection is
229
+ appended when missing):
225
230
 
226
231
  - **Name**: `drawing.name` is the file name (set on `openDrawing`, updated
227
232
  by `save(path)`); `newDrawing(name)` names it until it is saved. The
@@ -240,9 +245,22 @@ await doc.exportPdf("plan.pdf");
240
245
  `updateTextStyle(nameOrId, patch)`, `removeTextStyle(nameOrId)` (refused
241
246
  while objects use it) — the same four for `DimStyle`; `setTextStyle` /
242
247
  `setDimStyle` remain as deprecated aliases of update
248
+ - **Line types / hatch patterns** (the document's own definitions, by
249
+ name, resolved ahead of the built-in catalogue): `listLineTypes()`,
250
+ `addLineTypes([{name, dashesMm}])`, `updateLineType(name, patch)`,
251
+ `removeLineType(name)`; `listHatchPatterns()`,
252
+ `addHatchPatterns([{name, lines}])`, `updateHatchPattern(name, patch)`,
253
+ `removeHatchPattern(name)`
243
254
  - **Modules**: `await addBlockDefinitions(sources)` / `removeBlockDefinition(id)`,
244
255
  `await addUserCommands(sources)` / `removeUserCommand(id)`,
245
256
  `await setBlockDefinitions(sources)`, `await setCommands(sources)`
257
+ - **Marketplaces**: `listMarketplaces()`, `await addMarketplaces(list)`
258
+ (verifies each catalog), `removeMarketplaces(names)`,
259
+ `await searchMarketplaces({ query?, kind?, marketplace? })` (entries with
260
+ install status), `await installMarketplaceEntries(ids, marketplace?)`
261
+ (declared block dependencies first, one undo step) — then insert a block
262
+ with `add([{ type: "block", definitionId }])`. Marketplaces are process
263
+ configuration, never written to the file.
246
264
  - **Scripts**: `await runScript(source, inputs?, params?)` runs a
247
265
  `defineCommand` module (the same one the editor palette runs) headlessly
248
266
  as ONE undo step — its declared `inputs` (points) are supplied up front,
@@ -277,8 +295,12 @@ Full parameter docs are in the bundled `dist/index.d.ts` JSDoc.
277
295
  `hatch` (loops — outer + holes, even-odd; fill solid/pattern/lines) ·
278
296
  `text` (position, content; **default alignment center/center**; optional
279
297
  leaderLines with the arrowhead at index 0) · `dimension` (linear/angular/
280
- radial/diameter; `offset` is a vector from points[0] to the dimension line;
281
- linear with >2 points = chain) · `block` (instances of script definitions) ·
298
+ radial/diameter; linear: `offset` is the signed distance of the dimension
299
+ line from points[0] (left of the measuring direction positive) and
300
+ `rotation` an optional locked measuring direction; angular: `offset` is the
301
+ signed arc radius; `labels[i]` place and word each segment's text —
302
+ `along`/`across` in mm, unset = automatic, `content` with `{value}` for the
303
+ measurement; linear with >2 points = chain) · `block` (instances of script definitions) ·
282
304
  `viewport` (layouts only) · `image` (placement of an asset).
283
305
 
284
306
  ### Block scripts
package/bin/lineadraw.mjs CHANGED
@@ -11,6 +11,7 @@
11
11
  // and the agent token; `--port` / `--token` / LINEA_BRIDGE_TOKEN override.
12
12
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
13
13
  import { homedir } from "node:os";
14
+ import { isDeepStrictEqual } from "node:util";
14
15
  import { dirname, join, resolve } from "node:path";
15
16
  import {
16
17
  buildManifest,
@@ -238,13 +239,27 @@ switch (command) {
238
239
  case "check": {
239
240
  const manifest = await validatedManifest();
240
241
  const committedPath = join(dir, MANIFEST_PATH);
241
- const committed = existsSync(committedPath)
242
- ? readFileSync(committedPath, "utf8")
243
- : null;
244
- if (committed !== manifestJson(manifest))
242
+ // Compared as parsed JSON, not bytes: a formatter, a web edit or a CRLF
243
+ // checkout must not fail a manifest whose content is current.
244
+ let committed = null;
245
+ if (existsSync(committedPath)) {
246
+ try {
247
+ committed = JSON.parse(readFileSync(committedPath, "utf8"));
248
+ } catch {
249
+ committed = "unreadable";
250
+ }
251
+ }
252
+ if (!isDeepStrictEqual(committed, JSON.parse(manifestJson(manifest)))) {
253
+ const why =
254
+ committed === null
255
+ ? "missing"
256
+ : committed === "unreadable"
257
+ ? "not valid JSON"
258
+ : "stale";
245
259
  fail(
246
- `${MANIFEST_PATH} is ${committed === null ? "missing" : "stale"} — run \`npx lineadraw manifest\` and commit the result.`,
260
+ `${MANIFEST_PATH} is ${why} — run \`npx lineadraw manifest\` and commit the result.`,
247
261
  );
262
+ }
248
263
  const libWarning = tsconfigLibWarning(dir);
249
264
  if (libWarning !== null) console.warn(`warning: ${libWarning}`);
250
265
  console.log(`OK: ${manifest.entries.length} entries, manifest is current.`);