copperhead 0.9.0 → 0.11.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/NOTICE +1 -1
- package/README.md +47 -8
- package/dist/agent/context.js +2 -0
- package/dist/agent/context.js.map +1 -0
- package/dist/agent/dock-renderer.js +2 -2
- package/dist/agent/dock-renderer.js.map +1 -1
- package/dist/agent/envelope.js +105 -0
- package/dist/agent/envelope.js.map +1 -0
- package/dist/agent/filetools.js +24 -1
- package/dist/agent/filetools.js.map +1 -1
- package/dist/agent/ledger.js +24 -0
- package/dist/agent/ledger.js.map +1 -1
- package/dist/agent/loop.js +63 -72
- package/dist/agent/loop.js.map +1 -1
- package/dist/agent/prompts.js +4 -3
- package/dist/agent/prompts.js.map +1 -1
- package/dist/agent/providers/claude-code.js +17 -1
- package/dist/agent/providers/claude-code.js.map +1 -1
- package/dist/agent/providers/codex.js +84 -39
- package/dist/agent/providers/codex.js.map +1 -1
- package/dist/agent/providers/tool-protocol.js +21 -0
- package/dist/agent/providers/tool-protocol.js.map +1 -1
- package/dist/agent/recovery.js +186 -15
- package/dist/agent/recovery.js.map +1 -1
- package/dist/agent/registry.js +49 -0
- package/dist/agent/registry.js.map +1 -0
- package/dist/agent/render.js +2 -2
- package/dist/agent/render.js.map +1 -1
- package/dist/agent/theme.js +10 -5
- package/dist/agent/theme.js.map +1 -1
- package/dist/agent/tools.js +100 -586
- package/dist/agent/tools.js.map +1 -1
- package/dist/agent/transcript.js +2 -0
- package/dist/agent/transcript.js.map +1 -1
- package/dist/capabilities/define.js +35 -0
- package/dist/capabilities/define.js.map +1 -0
- package/dist/capabilities/handlers.js +744 -0
- package/dist/capabilities/handlers.js.map +1 -0
- package/dist/capabilities/helpers.js +39 -0
- package/dist/capabilities/helpers.js.map +1 -0
- package/dist/capabilities/index.js +50 -0
- package/dist/capabilities/index.js.map +1 -0
- package/dist/capabilities/skills/generate-report.js +23 -0
- package/dist/capabilities/skills/generate-report.js.map +1 -0
- package/dist/cli.js +158 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/check.js +33 -1
- package/dist/commands/check.js.map +1 -1
- package/dist/commands/create.js +181 -26
- package/dist/commands/create.js.map +1 -1
- package/dist/commands/doctor.js +83 -6
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/skill.js +109 -0
- package/dist/commands/skill.js.map +1 -0
- package/dist/commands/sync.js +3 -1
- package/dist/commands/sync.js.map +1 -1
- package/dist/config.js +19 -6
- package/dist/config.js.map +1 -1
- package/dist/kicad/bootstrap.js +24 -3
- package/dist/kicad/bootstrap.js.map +1 -1
- package/dist/kicad/cli.js +106 -18
- package/dist/kicad/cli.js.map +1 -1
- package/dist/kicad/dossier.js +207 -0
- package/dist/kicad/dossier.js.map +1 -0
- package/dist/kicad/draft/draft.js +135 -0
- package/dist/kicad/draft/draft.js.map +1 -0
- package/dist/kicad/draft/engine.js +5310 -0
- package/dist/kicad/draft/engine.js.map +1 -0
- package/dist/kicad/draft/ir.js +368 -0
- package/dist/kicad/draft/ir.js.map +1 -0
- package/dist/kicad/draft/symsource.js +504 -0
- package/dist/kicad/draft/symsource.js.map +1 -0
- package/dist/kicad/emit.js +220 -0
- package/dist/kicad/emit.js.map +1 -0
- package/dist/kicad/fab.js +13 -0
- package/dist/kicad/fab.js.map +1 -1
- package/dist/kicad/legibility.js +608 -0
- package/dist/kicad/legibility.js.map +1 -0
- package/dist/kicad/score.js +431 -0
- package/dist/kicad/score.js.map +1 -0
- package/dist/kicad/sexp.js +265 -6
- package/dist/kicad/sexp.js.map +1 -1
- package/dist/kicad/symlib.js +346 -16
- package/dist/kicad/symlib.js.map +1 -1
- package/dist/mcp/server.js +485 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/memory/bom-table.js +75 -39
- package/dist/memory/bom-table.js.map +1 -1
- package/dist/memory/scaffold.js +14 -1
- package/dist/memory/scaffold.js.map +1 -1
- package/dist/util/redact.js +6 -0
- package/dist/util/redact.js.map +1 -1
- package/package.json +13 -8
- package/src/agent/context.ts +35 -0
- package/src/agent/dock-renderer.ts +3 -2
- package/src/agent/envelope.ts +124 -0
- package/src/agent/filetools.ts +26 -1
- package/src/agent/ledger.ts +24 -0
- package/src/agent/loop.ts +73 -78
- package/src/agent/prompts.ts +4 -3
- package/src/agent/providers/claude-code.ts +22 -1
- package/src/agent/providers/codex.ts +91 -42
- package/src/agent/providers/tool-protocol.ts +22 -0
- package/src/agent/recovery.ts +183 -13
- package/src/agent/registry.ts +58 -0
- package/src/agent/render.ts +4 -3
- package/src/agent/theme.ts +15 -5
- package/src/agent/tools.ts +124 -628
- package/src/agent/transcript.ts +6 -0
- package/src/agent/types.ts +10 -5
- package/src/capabilities/define.ts +88 -0
- package/src/capabilities/handlers.ts +769 -0
- package/src/capabilities/helpers.ts +37 -0
- package/src/capabilities/index.ts +53 -0
- package/src/capabilities/skills/generate-report.ts +25 -0
- package/src/cli.ts +154 -0
- package/src/commands/check.ts +51 -1
- package/src/commands/create.ts +183 -21
- package/src/commands/doctor.ts +85 -6
- package/src/commands/skill.ts +127 -0
- package/src/commands/sync.ts +5 -3
- package/src/config.ts +56 -8
- package/src/kicad/bootstrap.ts +24 -3
- package/src/kicad/cli.ts +129 -18
- package/src/kicad/dossier.ts +217 -0
- package/src/kicad/draft/draft.ts +173 -0
- package/src/kicad/draft/engine.ts +5274 -0
- package/src/kicad/draft/ir.ts +416 -0
- package/src/kicad/draft/symsource.ts +549 -0
- package/src/kicad/emit.ts +300 -0
- package/src/kicad/fab.ts +15 -0
- package/src/kicad/legibility.ts +695 -0
- package/src/kicad/score.ts +502 -0
- package/src/kicad/sexp.ts +346 -6
- package/src/kicad/symlib.ts +364 -18
- package/src/mcp/server.ts +560 -0
- package/src/memory/bom-table.ts +85 -38
- package/src/memory/scaffold.ts +14 -1
- package/src/util/redact.ts +6 -0
- package/dist/memory/synap.js +0 -152
- package/dist/memory/synap.js.map +0 -1
- package/src/memory/synap.ts +0 -217
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The stage-4 entry pin dossier: every BOM part resolved against the installed
|
|
3
|
+
* KiCad libraries, rendered as a prompt block, so the schematic agent starts
|
|
4
|
+
* with the pin facts it would otherwise spend turns reconstructing.
|
|
5
|
+
*
|
|
6
|
+
* The BOM is frozen when stage 4 starts, which makes this computable before the
|
|
7
|
+
* first agent turn — the same insight `symbolAvailabilityFacts` applies at
|
|
8
|
+
* recovery time, moved to entry. Like that block, coverage is stated rather
|
|
9
|
+
* than implied: parts past the size cap are named as NOT INCLUDED, parts a
|
|
10
|
+
* probe error skipped are named as UNRESOLVED, and parts whose only name is
|
|
11
|
+
* too short to search are named as NOT SEARCHED — never silently dropped,
|
|
12
|
+
* because absence from the dossier must never read as absence from the
|
|
13
|
+
* libraries.
|
|
14
|
+
*
|
|
15
|
+
* Advisory only. It changes prompt content, not gates: a missing BOM, an
|
|
16
|
+
* unreadable library, or any error degrades to an empty string and the stage
|
|
17
|
+
* runs exactly as it did before this block existed.
|
|
18
|
+
*/
|
|
19
|
+
import { parseBomTable } from '../memory/bom-table.js';
|
|
20
|
+
import { resolveLibrarySymbol, searchInstalledSymbols, listInstalledLibraries, comparePinNumbers, } from './symlib.js';
|
|
21
|
+
/** R/C/L refdes (with optional multi-part suffix like R12A) draw from their
|
|
22
|
+
* canonical `Device:*` symbols; a two-pin table per resistor is noise. */
|
|
23
|
+
const PASSIVE_REFDES = /^[RCL]\d+[A-Za-z]?$/i;
|
|
24
|
+
/** `1=PE2/bidirectional 2(passive) …` — name omitted when the library leaves
|
|
25
|
+
* the pin unnamed (`~` or empty), since `1=~/passive` reads as line noise. */
|
|
26
|
+
function pinTable(pins) {
|
|
27
|
+
return [...pins]
|
|
28
|
+
.sort((a, b) => comparePinNumbers(a.number, b.number))
|
|
29
|
+
.map((p) => {
|
|
30
|
+
const name = p.name === '~' ? '' : p.name;
|
|
31
|
+
return name ? `${p.number}=${name}/${p.type}` : `${p.number}(${p.type})`;
|
|
32
|
+
})
|
|
33
|
+
.join(' ');
|
|
34
|
+
}
|
|
35
|
+
/** Render `prefix + as many names as fit + suffix` within `budget` chars; the
|
|
36
|
+
* tail that does not fit becomes "…and N more". The budget is a hard bound:
|
|
37
|
+
* when even the minimal form exceeds it, the string is truncated outright, so
|
|
38
|
+
* the trailer can never blow the size cap it exists to disclose. */
|
|
39
|
+
function boundedList(prefix, names, suffix, budget) {
|
|
40
|
+
let line = '';
|
|
41
|
+
let shown = 0;
|
|
42
|
+
for (let i = 0; i < names.length; i++) {
|
|
43
|
+
const sep = shown === 0 ? '' : '; ';
|
|
44
|
+
const tail = `…and ${names.length - i} more`;
|
|
45
|
+
const candidate = `${line}${sep}${names[i]}`;
|
|
46
|
+
// Reserve room for the worst-case continuation marker after this name.
|
|
47
|
+
if (prefix.length + candidate.length + tail.length + 2 + suffix.length > budget)
|
|
48
|
+
break;
|
|
49
|
+
line = candidate;
|
|
50
|
+
shown++;
|
|
51
|
+
}
|
|
52
|
+
const rest = names.length - shown;
|
|
53
|
+
const full = rest === 0
|
|
54
|
+
? `${prefix}${line}${suffix}`
|
|
55
|
+
: `${prefix}${line ? `${line}; ` : ''}…and ${rest} more${suffix}`;
|
|
56
|
+
if (full.length <= budget)
|
|
57
|
+
return full;
|
|
58
|
+
return full.slice(0, Math.max(1, budget - 1)) + '…';
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Render the dossier block from BOM markdown. Returns `''` when there is
|
|
62
|
+
* nothing to say (no rows survive the passive filter, no search dirs, or any
|
|
63
|
+
* error) — the caller injects nothing rather than an empty heading.
|
|
64
|
+
*/
|
|
65
|
+
export async function bomSymbolDossier(bomMd, dirs, opts = {}) {
|
|
66
|
+
const searchCap = opts.searchCap ?? 3;
|
|
67
|
+
const maxChars = opts.maxChars ?? 24_000;
|
|
68
|
+
try {
|
|
69
|
+
if (!dirs.length)
|
|
70
|
+
return '';
|
|
71
|
+
// No readable library at all must yield no dossier, not a page of
|
|
72
|
+
// NO-INSTALLED-SYMBOL lines: a false absence claim in a machine-verified
|
|
73
|
+
// block is the exact failure mode this file exists to prevent (I15).
|
|
74
|
+
if (!(await listInstalledLibraries(dirs)).size)
|
|
75
|
+
return '';
|
|
76
|
+
// Group refdes by primary query so a part used five times renders once.
|
|
77
|
+
// The MPN is the stronger name when present; the stage-3 scaffold's
|
|
78
|
+
// UNVERIFIED flag word is not part of it. The Value is kept as a fallback
|
|
79
|
+
// query, searched only when the MPN finds nothing — a bogus MPN over a
|
|
80
|
+
// resolvable Value must not read as NO INSTALLED SYMBOL.
|
|
81
|
+
const byQuery = new Map();
|
|
82
|
+
const unsearchable = [];
|
|
83
|
+
for (const row of parseBomTable(bomMd)) {
|
|
84
|
+
if (PASSIVE_REFDES.test(row.refdes))
|
|
85
|
+
continue;
|
|
86
|
+
const mpn = (row.mpn ?? '').replace(/^UNVERIFIED[:\s]*/i, '').trim();
|
|
87
|
+
const value = (row.value ?? '').trim();
|
|
88
|
+
const query = mpn || value;
|
|
89
|
+
if (query.length < 3) {
|
|
90
|
+
// Disclosed, not dropped: a crystal named "8M" was never searched, and
|
|
91
|
+
// silence here would read as "checked" under a machine-verified label.
|
|
92
|
+
unsearchable.push(`${row.refdes} (${query || 'no name'})`);
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
const entry = byQuery.get(query) ?? { refs: [] };
|
|
96
|
+
entry.refs.push(row.refdes);
|
|
97
|
+
if (mpn && value.length >= 3 && value !== mpn)
|
|
98
|
+
entry.fallback = value;
|
|
99
|
+
byQuery.set(query, entry);
|
|
100
|
+
}
|
|
101
|
+
if (!byQuery.size && !unsearchable.length)
|
|
102
|
+
return '';
|
|
103
|
+
const lines = [];
|
|
104
|
+
const overflow = [];
|
|
105
|
+
const errored = [];
|
|
106
|
+
// Reserve room for the disclosure trailers up front, so the complete
|
|
107
|
+
// rendered block — disclosures included — stays within maxChars.
|
|
108
|
+
const TRAILER_BUDGET = Math.min(1200, Math.floor(maxChars / 4));
|
|
109
|
+
const bodyBudget = maxChars - TRAILER_BUDGET;
|
|
110
|
+
let spent = 0;
|
|
111
|
+
// Once a line fails to fit, later parts skip their library scans entirely:
|
|
112
|
+
// the cap bounds the work, not just the rendered output. (Lines have a
|
|
113
|
+
// floor of ~60 chars, so a later part fitting where this one did not is
|
|
114
|
+
// rare enough not to pay a full scan hoping for it.)
|
|
115
|
+
let bodyFull = false;
|
|
116
|
+
for (const [query, { refs, fallback }] of byQuery) {
|
|
117
|
+
const who = `${refs.join(', ')} (${query})`;
|
|
118
|
+
if (bodyFull) {
|
|
119
|
+
overflow.push(who);
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
let line;
|
|
123
|
+
try {
|
|
124
|
+
let hits = await searchInstalledSymbols(query, dirs, searchCap);
|
|
125
|
+
let matchedBy = '';
|
|
126
|
+
if (!hits.length && fallback) {
|
|
127
|
+
hits = await searchInstalledSymbols(fallback, dirs, searchCap);
|
|
128
|
+
if (hits.length)
|
|
129
|
+
matchedBy = ` (matched by Value "${fallback}")`;
|
|
130
|
+
}
|
|
131
|
+
const top = hits[0];
|
|
132
|
+
if (!top) {
|
|
133
|
+
line = `- ${who}: NO INSTALLED SYMBOL matches — not capturable as named; substitute a part whose symbol exists (search_symbols to find one)`;
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
const r = await resolveLibrarySymbol(top, dirs);
|
|
137
|
+
if (r.status !== 'ok') {
|
|
138
|
+
// A hit that fails to re-resolve is a library race or parse quirk;
|
|
139
|
+
// report the candidates without claiming pins we could not read.
|
|
140
|
+
line = `- ${who}: candidates ${hits.join(', ')} — pins unreadable here; confirm with symbol_pins`;
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
const multi = r.units >= 2 ? ` — MULTI-UNIT (${r.units} units): the drafting engine places each unit separately under this refdes` : '';
|
|
144
|
+
const also = hits.length > 1 ? `\n also installed: ${hits.slice(1).join(', ')}` : '';
|
|
145
|
+
line = `- ${who}: ${top}${matchedBy} — ${r.pins.length} pin(s): ${pinTable(r.pins)}${multi}${also}`;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
catch {
|
|
150
|
+
errored.push(who); // one failed probe must not sink the block
|
|
151
|
+
continue;
|
|
152
|
+
}
|
|
153
|
+
if (spent + line.length > bodyBudget) {
|
|
154
|
+
overflow.push(who);
|
|
155
|
+
bodyFull = true;
|
|
156
|
+
continue;
|
|
157
|
+
}
|
|
158
|
+
spent += line.length;
|
|
159
|
+
lines.push(line);
|
|
160
|
+
}
|
|
161
|
+
if (!lines.length && !overflow.length && !errored.length && !unsearchable.length)
|
|
162
|
+
return '';
|
|
163
|
+
// Distinct disclosures: a probe error is not a size decision, an
|
|
164
|
+
// unsearchable name is neither, and labeling any of them "size cap" would
|
|
165
|
+
// misreport why coverage is missing. Each trailer shares the reserved
|
|
166
|
+
// budget so the complete block stays within maxChars.
|
|
167
|
+
const trailers = [];
|
|
168
|
+
if (errored.length) {
|
|
169
|
+
trailers.push([
|
|
170
|
+
'- UNRESOLVED (probe error): ',
|
|
171
|
+
errored,
|
|
172
|
+
' — the probe failed for these; an error says nothing about availability, call symbol_pins for each.',
|
|
173
|
+
]);
|
|
174
|
+
}
|
|
175
|
+
if (unsearchable.length) {
|
|
176
|
+
trailers.push([
|
|
177
|
+
'- NOT SEARCHED (name shorter than 3 chars): ',
|
|
178
|
+
unsearchable,
|
|
179
|
+
' — too short to search reliably; nothing here says whether these resolve. Give them an MPN, or verify by hand.',
|
|
180
|
+
]);
|
|
181
|
+
}
|
|
182
|
+
if (overflow.length) {
|
|
183
|
+
trailers.push([
|
|
184
|
+
`- NOT INCLUDED (size cap ${maxChars} chars): `,
|
|
185
|
+
overflow,
|
|
186
|
+
' — call symbol_pins for each; nothing above says whether these resolve.',
|
|
187
|
+
]);
|
|
188
|
+
}
|
|
189
|
+
// Allocate from what is actually left of maxChars (body lines plus the
|
|
190
|
+
// newlines join() will add), splitting the remainder across the trailers
|
|
191
|
+
// still to render — a fixed per-trailer share of the reserve could exceed
|
|
192
|
+
// the whole-block bound when the shares themselves cannot fit.
|
|
193
|
+
let used = lines.reduce((a, l) => a + l.length + 1, 0);
|
|
194
|
+
for (let i = 0; i < trailers.length; i++) {
|
|
195
|
+
const [prefix, names, suffix] = trailers[i];
|
|
196
|
+
const budget = Math.floor((maxChars - used) / (trailers.length - i));
|
|
197
|
+
const rendered = boundedList(prefix, names, suffix, budget);
|
|
198
|
+
lines.push(rendered);
|
|
199
|
+
used += rendered.length + 1;
|
|
200
|
+
}
|
|
201
|
+
return lines.join('\n');
|
|
202
|
+
}
|
|
203
|
+
catch {
|
|
204
|
+
return '';
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
//# sourceMappingURL=dossier.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dossier.js","sourceRoot":"","sources":["../../src/kicad/dossier.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { readFile, writeFile } from 'node:fs/promises';
|
|
2
|
+
import { existsSync } from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { emitSchematic } from '../emit.js';
|
|
5
|
+
import { SymbolSource } from './symsource.js';
|
|
6
|
+
import { parseIntent, validateIntent, formatIrFindings, INTENT_FILENAME } from './ir.js';
|
|
7
|
+
import { draftSchematicPlacement } from './engine.js';
|
|
8
|
+
export function defaultIntentPath(schematic) {
|
|
9
|
+
return path.join(path.dirname(schematic), INTENT_FILENAME);
|
|
10
|
+
}
|
|
11
|
+
/** Draft to text without touching disk (staleness checks, dry runs). */
|
|
12
|
+
export async function draftSchematicToText(opts) {
|
|
13
|
+
const intentRel = opts.intentPath ?? defaultIntentPath(opts.schematic);
|
|
14
|
+
const intentAbs = path.join(opts.repoRoot, intentRel);
|
|
15
|
+
if (!existsSync(intentAbs)) {
|
|
16
|
+
return { ok: false, findings: [{ detail: `intent file ${intentRel} does not exist` }], message: `intent file ${intentRel} does not exist` };
|
|
17
|
+
}
|
|
18
|
+
const { intent, findings: parseFindings } = parseIntent(await readFile(intentAbs, 'utf8'));
|
|
19
|
+
if (!intent)
|
|
20
|
+
return { ok: false, findings: parseFindings, message: formatIrFindings(parseFindings) };
|
|
21
|
+
// vendor: false — this path is documented as not touching disk, and it backs
|
|
22
|
+
// read-shaped callers (the stage-4 staleness probe); `draftSchematic` re-resolves
|
|
23
|
+
// with a vendoring source after it decides to write
|
|
24
|
+
const symsource = new SymbolSource(opts.repoRoot, opts.symbolDirs, false);
|
|
25
|
+
// docsDir may arrive repo-relative (config.docs); resolve against the repo
|
|
26
|
+
const docsDir = opts.docsDir === undefined || opts.docsDir === null ? null : path.resolve(opts.repoRoot, opts.docsDir);
|
|
27
|
+
const { ok, findings, validated } = await validateIntent(intent, symsource, docsDir);
|
|
28
|
+
if (!ok || !validated)
|
|
29
|
+
return { ok: false, findings, message: formatIrFindings(findings) };
|
|
30
|
+
const projectName = path.basename(opts.schematic).replace(/\.kicad_sch$/, '');
|
|
31
|
+
// Date comes from the IR (hints.date), never the wall clock: the same IR
|
|
32
|
+
// must emit identical bytes on every run and every day (design D4).
|
|
33
|
+
const { model, report } = draftSchematicPlacement(validated, projectName, opts.today ?? intent.hints?.date ?? '2020-01-01');
|
|
34
|
+
// A merged net means the sheet does not implement the IR: two distinct nets
|
|
35
|
+
// share a label point, and KiCad resolves them to one. Refused rather than
|
|
36
|
+
// written, because the alternative is an electrically wrong board that ERC
|
|
37
|
+
// reports only as a `multiple_net_names` warning — quiet enough to reach
|
|
38
|
+
// layout and fabrication outputs. Nothing is written, exactly as on a
|
|
39
|
+
// validation failure, so a previously good sheet survives.
|
|
40
|
+
if (report.mergedNets.length) {
|
|
41
|
+
const findings = report.mergedNets.map((m) => ({
|
|
42
|
+
detail: m.via === 'wires'
|
|
43
|
+
? `nets ${m.nets.join(' and ')} come into WIRE contact at (${m.x}, ${m.y}) — a wire endpoint or label of one ` +
|
|
44
|
+
`rests on the other's wire, which KiCad joins into one net, so the drawn netlist would not match the ` +
|
|
45
|
+
`intent. This is an engine routing/placement fault, not an intent error; the engine's own avoidance ` +
|
|
46
|
+
`should have prevented it. Reshaping the IR is unlikely to help and should not be attempted more than ` +
|
|
47
|
+
`once — report it against the engine with the intent that produced it.`
|
|
48
|
+
: `nets ${m.nets.join(' and ')} share a label position at (${m.x}, ${m.y}), which merges them into one net — ` +
|
|
49
|
+
`the drawn netlist would not match the intent. This is an engine placement fault, not an intent error: the ` +
|
|
50
|
+
`de-collision pass already treats foreign labels as obstacles and, failing that, moves a label off a shared ` +
|
|
51
|
+
`point even at the cost of overlapping text, so reaching this state means both labels were immovable ` +
|
|
52
|
+
`(wired-net labels carry no stub to ride) or the sheet is too dense to separate them. Reshaping the IR is ` +
|
|
53
|
+
`unlikely to help and should not be attempted more than once — report it against the engine with the intent ` +
|
|
54
|
+
`that produced it.`,
|
|
55
|
+
}));
|
|
56
|
+
return { ok: false, findings, message: formatIrFindings(findings) };
|
|
57
|
+
}
|
|
58
|
+
const text = emitSchematic(model);
|
|
59
|
+
return {
|
|
60
|
+
ok: true,
|
|
61
|
+
report,
|
|
62
|
+
text,
|
|
63
|
+
schematicPath: path.join(opts.repoRoot, opts.schematic),
|
|
64
|
+
generatedLibs: model.libSymbols.filter((l) => l.libId.startsWith('copperhead_power:')),
|
|
65
|
+
vendoredLibIds: [...validated.symbols.values()].map((s) => s.libId),
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
/** Draft and write the schematic, the vendored power lib, and the sym-lib-table. */
|
|
69
|
+
export async function draftSchematic(opts) {
|
|
70
|
+
const res = await draftSchematicToText(opts);
|
|
71
|
+
if (!res.ok)
|
|
72
|
+
return res;
|
|
73
|
+
await writeFile(res.schematicPath, res.text, 'utf8');
|
|
74
|
+
// Vendor the engine-generated power symbols and point a project
|
|
75
|
+
// sym-lib-table at every vendored nickname: without the table, ERC raises a
|
|
76
|
+
// lib_symbol_issues warning per symbol ("configuration does not include the
|
|
77
|
+
// library"), and `ok` requires a violation-free report.
|
|
78
|
+
const symsource = new SymbolSource(opts.repoRoot, opts.symbolDirs);
|
|
79
|
+
for (const lib of res.generatedLibs)
|
|
80
|
+
await symsource.vendorGenerated(lib.libId, lib.sourceText);
|
|
81
|
+
for (const libId of res.vendoredLibIds)
|
|
82
|
+
await symsource.resolve(libId);
|
|
83
|
+
const schDir = path.dirname(path.join(opts.repoRoot, opts.schematic));
|
|
84
|
+
// Without a project file KiCad never loads the project sym-lib-table (or
|
|
85
|
+
// resolves ${KIPRJMOD}), so every embedded symbol raises a lib_symbol_issues
|
|
86
|
+
// warning and ERC can never report clean. The create pipeline's bootstrap
|
|
87
|
+
// already provides one; standalone drafts get a minimal project.
|
|
88
|
+
const proPath = path.join(schDir, path.basename(opts.schematic).replace(/\.kicad_sch$/, '.kicad_pro'));
|
|
89
|
+
if (!existsSync(proPath)) {
|
|
90
|
+
const pro = {
|
|
91
|
+
board: { design_settings: { defaults: {}, rules: {} } },
|
|
92
|
+
erc: { rule_severities: {} },
|
|
93
|
+
libraries: { pinned_footprint_libs: [], pinned_symbol_libs: [] },
|
|
94
|
+
meta: { filename: path.basename(proPath), version: 1 },
|
|
95
|
+
schematic: { legacy_lib_dir: '', legacy_lib_list: [] },
|
|
96
|
+
};
|
|
97
|
+
await writeFile(proPath, JSON.stringify(pro, null, 2) + '\n', 'utf8');
|
|
98
|
+
}
|
|
99
|
+
const cacheRel = path.relative(schDir, symsource.cacheDir()).split(path.sep).join('/');
|
|
100
|
+
const rows = symsource
|
|
101
|
+
.vendoredLibs()
|
|
102
|
+
.map((lib) => `\t(lib (name "${lib}")(type "KiCad")(uri "\${KIPRJMOD}/${cacheRel ? cacheRel + '/' : ''}${lib}.kicad_sym")(options "")(descr "copperhead vendored"))`);
|
|
103
|
+
await writeFile(path.join(schDir, 'sym-lib-table'), `(sym_lib_table\n\t(version 7)\n${rows.join('\n')}\n)\n`, 'utf8');
|
|
104
|
+
return res;
|
|
105
|
+
}
|
|
106
|
+
export function formatSchematicDraftReport(report) {
|
|
107
|
+
const lines = [
|
|
108
|
+
`drafted: ${report.groups.length} group(s), ${report.wireCount} wire segment(s), ${report.labelCount} label(s), ${report.noConnects} no-connect(s) on ${report.paper}`,
|
|
109
|
+
];
|
|
110
|
+
for (const g of report.groups)
|
|
111
|
+
lines.push(` group "${g.name}": ${g.members.join(', ') || '(empty)'}`);
|
|
112
|
+
// The basis is part of the class, not decoration: `~` marks a class no pin
|
|
113
|
+
// attests, inferred from the net's NAME alone, which is the one inference a
|
|
114
|
+
// reader has to check and the IR's `kind` is there to correct.
|
|
115
|
+
// `~` marks the one classification no pin attests: a POWER class taken from
|
|
116
|
+
// the net's name alone. A signal is what a net is when nothing said
|
|
117
|
+
// otherwise, so marking every defaulted signal would decorate almost the
|
|
118
|
+
// whole line and tell a reader nothing.
|
|
119
|
+
const nameInferred = (n) => !n.overridden && n.basis === 'name' && n.class !== 'signal';
|
|
120
|
+
const mark = (n) => n.overridden ? '*' : nameInferred(n) ? '~' : '';
|
|
121
|
+
const legend = [
|
|
122
|
+
report.netClasses.some((n) => n.overridden) ? '*=IR override' : '',
|
|
123
|
+
report.netClasses.some(nameInferred) ? '~=inferred from the net name, not from any pin type' : '',
|
|
124
|
+
].filter(Boolean);
|
|
125
|
+
lines.push(` net classes: ${report.netClasses.map((n) => `${n.name}=${n.class}${mark(n)}`).join(', ')}${legend.length ? ` (${legend.join(', ')})` : ''}`);
|
|
126
|
+
if (report.pwrFlags.length)
|
|
127
|
+
lines.push(` PWR_FLAG synthesized on: ${report.pwrFlags.join(', ')}`);
|
|
128
|
+
const sf = report.sheetFit;
|
|
129
|
+
if (sf)
|
|
130
|
+
lines.push(` sheet fit: ${sf.paper}, ink ${Math.round(sf.inkUtilization * 100)}% of the usable frame, compaction ${sf.compaction}`);
|
|
131
|
+
for (const n of report.notes)
|
|
132
|
+
lines.push(` note: ${n}`);
|
|
133
|
+
return lines.join('\n');
|
|
134
|
+
}
|
|
135
|
+
//# sourceMappingURL=draft.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"draft.js","sourceRoot":"","sources":["../../../src/kicad/draft/draft.ts"],"names":[],"mappings":"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"}
|