@rulecad/cad 0.2.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/AGENTS.md +2 -1
- package/README.md +15 -4
- package/bin/cad.mjs +3 -0
- package/lib/design.mjs +2 -2
- package/package.json +4 -4
package/AGENTS.md
CHANGED
|
@@ -62,7 +62,8 @@ variable says which rule it comes from. Follow these steps; they're what makes a
|
|
|
62
62
|
|
|
63
63
|
## Talking to the person
|
|
64
64
|
- Give links as one labelled line (`npx cad link <project>/<object> --md`), never a raw URL. If it says
|
|
65
|
-
"(not a release)", say so.
|
|
65
|
+
"(not a release)", say so. If it says the link is too long for chat, don't paste it: tell the person, and offer
|
|
66
|
+
short links (a secret Gist), which upload the model, so ask first.
|
|
66
67
|
- Say what the checks found, with numbers. Ask before anything that leaves the computer: releases with `--push`,
|
|
67
68
|
ordering boards, publishing.
|
|
68
69
|
- Designs are code: only run designs you or the person trust. Links and rule files are data and never run.
|
package/README.md
CHANGED
|
@@ -69,9 +69,13 @@ fragment, which never reaches the web host, so the public page can open private
|
|
|
69
69
|
which version it holds (`keyboard/keycap@0.1.0`, or `+changes` if it isn't a release). The page is to become `@rulecad/viewer`;
|
|
70
70
|
`scripts/publish-view.sh "message"` publishes it (only that folder) to the public repo.
|
|
71
71
|
|
|
72
|
-
- **Short links** (`--short`, and the default for `--md`
|
|
73
|
-
|
|
74
|
-
GitHub's API. The same model reuses its Gist
|
|
72
|
+
- **Short links** (`--short`, and the default for `--md`, once `"shorten": "gist"` is in `cad.config.json`'s
|
|
73
|
+
`targets`): the link's data goes in a secret GitHub Gist (unlisted, but anyone with the link can open it) and the
|
|
74
|
+
link carries only its ID: `…/#s=<id>`. The page fetches it from GitHub's API. The same model reuses its Gist
|
|
75
|
+
(`.cache/links.json`). `npm create rulecad` asks which you want. Without it, links carry the model, and `cad link`
|
|
76
|
+
says when one is too long for chat or email (over 8,000 characters).
|
|
77
|
+
- **Boards** travel light: the board drawn from both sides (the page makes the front and back views from its layers)
|
|
78
|
+
and the schematic, with coordinates rounded to what a screen can show.
|
|
75
79
|
- **Parts panel:** the page lists parts by kind (keycap ×9), opening to each copy (key-1-1). Each row shows or hides
|
|
76
80
|
its parts and sets their style (solid, wireframe, x-ray, faint); the view has a mode, an explode slider, and
|
|
77
81
|
switches for supports and references. Click a part in the model to select its copy and see its size.
|
|
@@ -94,7 +98,8 @@ which version it holds (`keyboard/keycap@0.1.0`, or `+changes` if it isn't a rel
|
|
|
94
98
|
`<namespace>.<rule>`; the object's own variables are bare names. Parsed, never evaluated as code.
|
|
95
99
|
- **Other objects' numbers:** `"uses": ["node/carrier"]` reads another object as a rule set named after it:
|
|
96
100
|
`carrier.board_w` in an expression, `v.carrier.board_w` in code. It gets the object's variables and, from a board, its
|
|
97
|
-
outline (`board_x`, `board_y`, `board_w`, `board_d`) and, in code, its
|
|
101
|
+
outline (`board_x`, `board_y`, `board_w`, `board_d`) and, in code, where each of its parts is (`v.carrier.board_parts`),
|
|
102
|
+
a shaped board's outline (`board_outline`) and its mounting holes (`v.carrier.board_holes`, each
|
|
98
103
|
`{ x, y, d }`). So a case follows its board: change the board and the case rebuilds around it. `"node/carrier@^0.2.0"`
|
|
99
104
|
also checks the version; `"node/carrier@0.2.0"` reads that release. `cad rules` shows each borrowed number with the
|
|
100
105
|
object and version it came from; two objects can't read each other.
|
|
@@ -117,6 +122,10 @@ which version it holds (`keyboard/keycap@0.1.0`, or `+changes` if it isn't a rel
|
|
|
117
122
|
text so punctuation stays small, each straight stroke thickened to whole print lines, dots drawn round, and ↑ ↓ ← →
|
|
118
123
|
as arrows), `anchor(face, size, at)` (where something goes on a face, by anchor), and `cut(a, b)` (a subtract that
|
|
119
124
|
only touches a's faces near b; JSCAD's own splits every face along b's planes, which can leave slivers far away).
|
|
125
|
+
- A rule set can also carry `"footprints"` (pad data from @rulecad/pcb's `fromKicad`, with its source), which a
|
|
126
|
+
board's code reads as `v.parts.footprints.usb_c`.
|
|
127
|
+
- An object or rule set named with a hyphen (`pod-th`) is read with an underscore in expressions (`pod_th.width`),
|
|
128
|
+
since a hyphen there is a minus.
|
|
120
129
|
- Rules carry `kind`: spec (manufacturer), default (slicer), community (rule of thumb) or measured (your own test
|
|
121
130
|
print, which beats the rest), plus `source` and `checked`.
|
|
122
131
|
|
|
@@ -187,6 +196,8 @@ other items' variables, so a keycap can sit exactly where its slot meets the swi
|
|
|
187
196
|
Objects with `"role": "reference"` (the MX switch) model things you don't print: drawn faint, never exported.
|
|
188
197
|
- **plate** assemblies lay objects out on the bed: they're checked as one print and `export` writes one 3MF with an
|
|
189
198
|
object per part. Supports are kept.
|
|
199
|
+
- **Turning:** `"rotate": [0, 180, 0]` turns an item (degrees about x, y, z, in that order) about its own origin
|
|
200
|
+
before `at` moves it: a pod on a side mount, or a lid modelled face down as it prints.
|
|
190
201
|
- **Components:** an item can be a whole assembly (`"assembly": "keycap-on-switch"`). Its parts, fits and `requires`
|
|
191
202
|
come along, named per copy (`key-1-1.cap.cap`), and its overlaps are still checked inside each copy.
|
|
192
203
|
- **Repeats:** `"repeat": { "x": { "count": "plate.cols", "step": "plate.pitch" }, "y": { … } }` places a grid of
|
package/bin/cad.mjs
CHANGED
|
@@ -330,8 +330,11 @@ async function shorten(l) {
|
|
|
330
330
|
|
|
331
331
|
// --md: one line of labelled Markdown links, the form agents paste into chat (CLAUDE.md, "Replies with links").
|
|
332
332
|
// Short (a Gist) unless --long; plain output is long (nothing uploaded) unless --short.
|
|
333
|
+
const TOO_LONG = 8000; // characters: past this, chat apps and email cut a link short or refuse it
|
|
333
334
|
async function printLinks(l) {
|
|
334
335
|
if ((opt('md') && !opt('long')) || opt('short')) l = await shorten(l);
|
|
336
|
+
if (!l.short && l.view.length > TOO_LONG) console.error(`this link is ${(l.view.length / 1024).toFixed(0)} KB, too long for chat or email. ${hasTarget('shorten')
|
|
337
|
+
? 'Leave out --long for a short one.' : 'For short links, add "shorten": "gist" to "targets" in cad.config.json: each model you share is then stored in a secret GitHub Gist (needs the gh command, signed in).'}`);
|
|
335
338
|
// One link: the page picks which parts go in a download (all of them, one key, only the case)
|
|
336
339
|
if (opt('md')) return console.log(`**${[l.title, l.version].filter(Boolean).join(' ')}**${l.src.includes('+') ? ' (not a release)' : ''}: [View and download](${l.view})`);
|
|
337
340
|
console.log(`${l.src}, ${l.short ? 'short links (data in a secret Gist)' : `${(l.size / 1024).toFixed(1)} KB links`}${l.src.includes('+') ? ' (not a release: the link shows it)' : ''}`);
|
package/lib/design.mjs
CHANGED
|
@@ -48,7 +48,7 @@ export function locate(ref) {
|
|
|
48
48
|
// ---------- objects that read each other ----------
|
|
49
49
|
// "uses": ["node/carrier"] reads another object's numbers as a rule set named after it (carrier.board_w in an
|
|
50
50
|
// expression, v.carrier.board_w in code): its variables, and what a board tells the parts around it (board_x, board_y,
|
|
51
|
-
// board_w, board_d, and board_holes for
|
|
51
|
+
// board_w, board_d, and for code board_holes, board_parts (where each part is) and board_outline, for a shaped board). The object is built (cached) first. "node/carrier@^0.2.0" also checks
|
|
52
52
|
// its version; "node/carrier@0.2.0" reads that release instead of the working copy.
|
|
53
53
|
export const isObjectRef = (u) => String(u).includes('/');
|
|
54
54
|
const building = new Set();
|
|
@@ -69,7 +69,7 @@ export async function objectSets(d, object) {
|
|
|
69
69
|
rules[k] = { value: v, unit: units[k] ?? 'mm', rule: `${ref}'s ${k}`, kind: 'design', source: `${ref}@${version}` };
|
|
70
70
|
}
|
|
71
71
|
sets[u] = { name: base.name, rules };
|
|
72
|
-
if (b.circuit) extra[base.name] = { board_holes: (
|
|
72
|
+
if (b.circuit) { const e = await pcbEngine(), board = b.circuit.find((x) => x.type === 'pcb_board'); extra[base.name] = { board_holes: e.holes(b.circuit), board_parts: e.parts ? e.parts(b.circuit) : {}, ...(board.outline ? { board_outline: board.outline } : {}) }; }
|
|
73
73
|
}
|
|
74
74
|
} finally { building.delete(self); }
|
|
75
75
|
return { sets, extra };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rulecad/cad",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "The cad command: JSCAD designs from traceable rules, checked for printing and fit, versioned by what fits, shared as links and exported as Bambu 3MF.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -43,19 +43,19 @@
|
|
|
43
43
|
"directory": "packages/cad"
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
|
-
"@rulecad/variables": "^0.1.
|
|
46
|
+
"@rulecad/variables": "^0.1.4",
|
|
47
47
|
"@rulecad/keyboard-layout": "^0.1.2",
|
|
48
48
|
"@rulecad/printcheck": "^0.1.0",
|
|
49
49
|
"@rulecad/fit": "^0.2.0",
|
|
50
50
|
"@rulecad/model-link": "^0.1.2",
|
|
51
51
|
"@rulecad/versions": "^0.1.0",
|
|
52
|
-
"@rulecad/shapes": "^0.
|
|
52
|
+
"@rulecad/shapes": "^0.2.0",
|
|
53
53
|
"@rulecad/rules": "^0.2.0",
|
|
54
54
|
"@jscad/modeling": "^2.12.0",
|
|
55
55
|
"three": "^0.186.1"
|
|
56
56
|
},
|
|
57
57
|
"peerDependencies": {
|
|
58
|
-
"@rulecad/pcb": "^0.1.0 || ^0.2.0"
|
|
58
|
+
"@rulecad/pcb": "^0.1.0 || ^0.2.0 || ^0.3.0"
|
|
59
59
|
},
|
|
60
60
|
"peerDependenciesMeta": {
|
|
61
61
|
"@rulecad/pcb": {
|