create-rulecad 0.1.2 → 0.2.1
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 +3 -1
- package/index.mjs +25 -2
- package/package.json +1 -1
- package/template/AGENTS.md +14 -1
package/README.md
CHANGED
|
@@ -8,4 +8,6 @@ npx cad check home/soap-tray
|
|
|
8
8
|
|
|
9
9
|
Makes a [rulecad](https://github.com/JoniBach/rulecad) workspace with one design to start from: a soap tray with
|
|
10
10
|
ribs and drain slots, every measurement a variable that names its rule. `--no-install` makes the files without
|
|
11
|
-
running `npm install`.
|
|
11
|
+
running `npm install`. It asks how you'll share models: short links keep each shared model in a secret GitHub Gist
|
|
12
|
+
(needs the `gh` command, signed in); long links carry the model and upload nothing. `--share gist` or `--share long`
|
|
13
|
+
answers in advance (without either, and with no one to ask, links stay long).
|
package/index.mjs
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
// npm create rulecad [folder]: a new rulecad workspace with a design to start from (a soap tray), then npm install.
|
|
3
3
|
// --no-install make the files only
|
|
4
|
+
// --share gist short model links: each model you share is stored in a secret GitHub Gist (needs gh, signed in)
|
|
5
|
+
// --share long links that carry the whole model (nothing is uploaded; too long for chat on bigger models)
|
|
6
|
+
// Without --share it asks, in a terminal; elsewhere it keeps links long, since nothing is uploaded without a choice.
|
|
4
7
|
import fs from 'node:fs';
|
|
5
8
|
import path from 'node:path';
|
|
6
|
-
import { execSync } from 'node:child_process';
|
|
9
|
+
import { execSync, execFileSync } from 'node:child_process';
|
|
10
|
+
import readline from 'node:readline/promises';
|
|
7
11
|
import { fileURLToPath } from 'node:url';
|
|
8
12
|
|
|
9
13
|
const args = process.argv.slice(2), install = !args.includes('--no-install');
|
|
@@ -16,7 +20,7 @@ fs.renameSync(path.join(dir, 'gitignore'), path.join(dir, '.gitignore')); // npm
|
|
|
16
20
|
const readme = path.join(dir, 'README.md');
|
|
17
21
|
fs.writeFileSync(readme, fs.readFileSync(readme, 'utf8').replaceAll('NAME', name));
|
|
18
22
|
// $RULECAD_LOCAL: a rulecad checkout to use instead of npm (to try unpublished changes)
|
|
19
|
-
const from = (pkg) => (process.env.RULECAD_LOCAL ? `file:${path.join(path.resolve(process.env.RULECAD_LOCAL), 'packages', pkg)}` : '^0.
|
|
23
|
+
const from = (pkg) => (process.env.RULECAD_LOCAL ? `file:${path.join(path.resolve(process.env.RULECAD_LOCAL), 'packages', pkg)}` : '^0.2.0');
|
|
20
24
|
fs.writeFileSync(path.join(dir, 'package.json'), `${JSON.stringify({
|
|
21
25
|
name, private: true, type: 'module',
|
|
22
26
|
scripts: { check: 'cad check home/soap-tray' },
|
|
@@ -24,5 +28,24 @@ fs.writeFileSync(path.join(dir, 'package.json'), `${JSON.stringify({
|
|
|
24
28
|
}, null, 2)}\n`);
|
|
25
29
|
|
|
26
30
|
console.log(`made ${path.relative(process.cwd(), dir) || '.'}: a soap tray to start from, in projects/home`);
|
|
31
|
+
|
|
32
|
+
// How models are shared: short links need somewhere to keep the model (a secret Gist); long links carry it
|
|
33
|
+
let share = args.includes('--share') ? args[args.indexOf('--share') + 1] : null;
|
|
34
|
+
if (share && !['gist', 'long'].includes(share)) { console.error(`--share is gist or long (got "${share}")`); process.exit(1); }
|
|
35
|
+
if (!share && process.stdin.isTTY && process.stdout.isTTY) {
|
|
36
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
37
|
+
const a = await rl.question('\nModel links: short ones are easy to paste into chat, but each model you share is stored in a secret\nGitHub Gist (needs the gh command, signed in). Long ones carry the model and upload nothing. Short links? [y/N] ');
|
|
38
|
+
rl.close();
|
|
39
|
+
share = /^y/i.test(a.trim()) ? 'gist' : 'long';
|
|
40
|
+
}
|
|
41
|
+
if (share === 'gist') {
|
|
42
|
+
const cfg = path.join(dir, 'cad.config.json'), c = JSON.parse(fs.readFileSync(cfg, 'utf8'));
|
|
43
|
+
c.targets = { ...c.targets, shorten: 'gist' };
|
|
44
|
+
fs.writeFileSync(cfg, `${JSON.stringify(c, null, 2)}\n`);
|
|
45
|
+
let ready = true;
|
|
46
|
+
try { execFileSync('gh', ['auth', 'status'], { stdio: 'ignore' }); } catch { ready = false; }
|
|
47
|
+
console.log(ready ? 'short links: models you share go into secret Gists (unlisted: only people with the link find them)'
|
|
48
|
+
: 'short links are on, but the gh command isn\'t installed or signed in: install it from cli.github.com and run gh auth login');
|
|
49
|
+
} else console.log(`model links carry the whole model${share ? '' : ' (no --share given)'}; for short ones later, add "shorten": "gist" to "targets" in cad.config.json`);
|
|
27
50
|
if (install) execSync('npm install', { cwd: dir, stdio: 'inherit' });
|
|
28
51
|
console.log(`\n cd ${path.relative(process.cwd(), dir)}\n npx cad check home/soap-tray\n npx cad preview home/soap-tray\n\nREADME.md says what's where.`);
|
package/package.json
CHANGED
package/template/AGENTS.md
CHANGED
|
@@ -47,10 +47,23 @@ variable says which rule it comes from. Follow these steps; they're what makes a
|
|
|
47
47
|
with ranges from rules. An overlap or gap outside its range is a finding: report it with the numbers, and never
|
|
48
48
|
widen a range to make it pass without saying why.
|
|
49
49
|
- Build bigger things from checked assemblies used as items, rather than placing their objects again.
|
|
50
|
+
- A part is named in fits as `<item>.<part>`; an object that returns one unnamed shape has one part, `body`.
|
|
51
|
+
- A gap fit can't tell whether holes line up. Where a board screws into a part, add a holes fit
|
|
52
|
+
(`{ "holes": "pcb.board", "into": "case.body", "depth": "m2.insert_length" }`).
|
|
53
|
+
- A part built around another (a case around its board) reads it: `"uses": ["node/carrier"]`, then
|
|
54
|
+
`carrier.board_w` and `v.carrier.board_holes`. Never copy another object's numbers by hand.
|
|
55
|
+
|
|
56
|
+
## Circuit boards
|
|
57
|
+
- `"engine": "pcb"` in the .json; `main(v)` returns a board built with `v.pcb` (see @rulecad/pcb's README).
|
|
58
|
+
- Parts come from rule sets where one exists (`v.pcb.xiao`, `qwiic`, `jstph`, `header`), or any standard footprint by
|
|
59
|
+
name (`v.pcb.part('U2', 'soic8', x, y)`). Turn parts in quarter turns with `rotation`, held in a variable.
|
|
60
|
+
- Join pins with `nets` (`GND: ['U1.GND', 'J1.GND']`) and let the autorouter draw them; `cad check` runs the fab's
|
|
61
|
+
design rules. Look at the copper preview: connectors should face the edge their plug comes from.
|
|
50
62
|
|
|
51
63
|
## Talking to the person
|
|
52
64
|
- Give links as one labelled line (`npx cad link <project>/<object> --md`), never a raw URL. If it says
|
|
53
|
-
"(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.
|
|
54
67
|
- Say what the checks found, with numbers. Ask before anything that leaves the computer: releases with `--push`,
|
|
55
68
|
ordering boards, publishing.
|
|
56
69
|
- Designs are code: only run designs you or the person trust. Links and rule files are data and never run.
|