@fateforge/xpedition-cli 1.0.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/.agent/AGENT.md +59 -0
- package/.agent/AGENT_zh.md +59 -0
- package/.agent/CLI-SPEC.md +1073 -0
- package/.agent/CLI-SPEC_zh.md +891 -0
- package/.agent/SEC-SPEC.md +158 -0
- package/.agent/SEC-SPEC_zh.md +132 -0
- package/.agent/SKILL-SPEC.md +266 -0
- package/.agent/SKILL-SPEC_zh.md +221 -0
- package/.agent/SPEC_VERSION +1 -0
- package/AGENTS.md +34 -0
- package/AGENTS_zh.md +33 -0
- package/CHANGELOG.md +795 -0
- package/CODE_OF_CONDUCT.md +35 -0
- package/CODE_OF_CONDUCT_zh.md +35 -0
- package/CONTRIBUTING.md +50 -0
- package/CONTRIBUTING_zh.md +42 -0
- package/LICENSE +21 -0
- package/NOTICE.md +16 -0
- package/NOTICE_zh.md +13 -0
- package/README.md +200 -0
- package/README_zh.md +178 -0
- package/SECURITY.md +108 -0
- package/SECURITY_zh.md +83 -0
- package/docs/AGENT_HARDENING_EVIDENCE.md +102 -0
- package/docs/AGENT_READS.md +74 -0
- package/docs/AGENT_READS_METRICS.json +216 -0
- package/docs/AGENT_READS_VALIDATION.json +13 -0
- package/docs/API_INVENTORY_BINDING_VALIDATION.json +16 -0
- package/docs/API_INVENTORY_DESIGN.md +90 -0
- package/docs/API_INVENTORY_REVIEW.md +59 -0
- package/docs/API_INVENTORY_VALIDATION.json +29 -0
- package/docs/API_INVENTORY_WINDOWS_VALIDATION.json +29 -0
- package/docs/COMPATIBILITY.md +499 -0
- package/docs/CONFIRMATION_CONCURRENCY_VALIDATION.json +33 -0
- package/docs/DIAGNOSTIC_BOUNDARIES.md +33 -0
- package/docs/DIAGNOSTIC_BOUNDARIES_VALIDATION.json +12 -0
- package/docs/E2E.md +445 -0
- package/docs/EVALS.md +134 -0
- package/docs/MCP.md +20 -0
- package/docs/NATIVE_ADAPTER.md +141 -0
- package/docs/OPEN_SOURCE_CHECKLIST.md +61 -0
- package/docs/OPEN_SOURCE_CHECKLIST_zh.md +61 -0
- package/docs/PIN_WORKFLOW_VALIDATION.json +28 -0
- package/docs/PLACEMENT_TASKS.md +99 -0
- package/docs/PLACEMENT_TASKS_VALIDATION.json +36 -0
- package/docs/REFERENCE_ADOPTION.md +67 -0
- package/package.json +48 -0
- package/scripts/run.js +46 -0
- package/skills/xpedition-cli/SKILL.md +300 -0
- package/skills/xpedition-cli/reference/agent-hardening.md +58 -0
- package/skills/xpedition-cli/reference/api-inventory.md +58 -0
- package/skills/xpedition-cli/reference/confirmation-safety.md +55 -0
- package/skills/xpedition-cli/test-prompts.json +62 -0
- package/skills/xpedition-pcb/SKILL.md +244 -0
- package/skills/xpedition-pcb/reference/fabrication.md +26 -0
- package/skills/xpedition-pcb/reference/hand-routing.md +33 -0
- package/skills/xpedition-pcb/reference/pcb-conventions.md +162 -0
- package/skills/xpedition-pcb/reference/placement-tasks.md +28 -0
- package/skills/xpedition-pcb/test-prompts.json +62 -0
- package/skills/xpedition-schematic/SKILL.md +244 -0
- package/skills/xpedition-schematic/reference/pin-assignment.md +61 -0
- package/skills/xpedition-schematic/reference/schematic-conventions.md +306 -0
- package/skills/xpedition-schematic/reference/schematic-design-format.md +219 -0
- package/skills/xpedition-schematic/test-prompts.json +52 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,795 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project are documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [1.0.0] - 2026-09-28
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- `library kicad-import` converts KiCad footprint libraries into cell partitions of a
|
|
15
|
+
project's central library as a guarded command. Its dry run reads only files -- the
|
|
16
|
+
libraries, their footprint counts, the partitions that exist already -- and binds the
|
|
17
|
+
token to that list; the result reports each library in `items[]` with a `summary`. It
|
|
18
|
+
replaces the earlier module entry point, which wrote with no dry run and is gone.
|
|
19
|
+
- `--dangerous`, the second gate of CLI-SPEC §15.4, on the writes that destroy work:
|
|
20
|
+
`pcb unroute`, `pcb create --replace` (which archives the layout folder first),
|
|
21
|
+
`pcb route --unroute`,
|
|
22
|
+
`pcb annotate --unroute`, and `pcb arrange` on a board with routing (its dry run
|
|
23
|
+
counts it). Without it the confirmed run is refused with `E_CONFIRMATION_REQUIRED`
|
|
24
|
+
and the token stays unspent. `reference` marks them `dangerous` with `dangerous_when`
|
|
25
|
+
in the `dangerous` permission tier, and the tool is now T2. `library kicad-import`
|
|
26
|
+
joins them when it merges into a partition that exists, and `schematic draw` always: every
|
|
27
|
+
sheet it draws is wiped first, hand edits included. SECURITY.md says why `session stop`
|
|
28
|
+
stays outside the tier.
|
|
29
|
+
- `--continue-on-error false` stops `pcb unroute` and `library kicad-import` at the first
|
|
30
|
+
failed item; the rest are listed in `skipped` and `summary` counts the attempted ones. The
|
|
31
|
+
token binds the choice, and other commands refuse the flag.
|
|
32
|
+
- `kb add --name NAME --url URL --about TEXT`, `kb list` and `kb remove --name NAME`
|
|
33
|
+
bind a company's knowledge-base documents -- layout rules, drawing conventions, review
|
|
34
|
+
checklists -- on this machine, and `context` lists them. Binding and unbinding are
|
|
35
|
+
writes, behind the usual dry run and token. The agent reads each document with its own
|
|
36
|
+
tools (for a Feishu wiki, lark-cli), every time, and the Skills say when: before work in
|
|
37
|
+
its area. A company rule replaces a bundled default and settles a TBD; verified facts,
|
|
38
|
+
the write safety rules and STOP CHECKPOINTs stand. The CLI stores http(s) links only;
|
|
39
|
+
it never fetches a document, so no document system is special-cased and no credential
|
|
40
|
+
is held.
|
|
41
|
+
- A failed `schematic draw` can be resumed (#30). Every sheet ends in a save, so the
|
|
42
|
+
failure now names the sheets it completed (`sheets_drawn`) and the rest
|
|
43
|
+
(`sheets_remaining`), with a hint, and `--sheets 3,4` draws only those; the netlist
|
|
44
|
+
check still covers the whole design, and the sheets left alone come back as
|
|
45
|
+
`sheets_kept`. The token binds the chosen sheets. `--pace` slows a draw for someone
|
|
46
|
+
watching Designer, as it does `pcb trace`. On a 4-sheet design interrupted on
|
|
47
|
+
sheet 3, the resume drew 132 of 207 operations and the netlist matched.
|
|
48
|
+
- `--timeout SECONDS` gives a native read -- the snapshot behind review, bom,
|
|
49
|
+
schematic, pcb, library and project reads -- the time a large design needs (#29).
|
|
50
|
+
The default is 120 s, up from a fixed 30 s that a 41-part design with an 8 MB
|
|
51
|
+
central library outran; a timeout names the time it had and the flag to raise.
|
|
52
|
+
- `schematic draw` notes when the partition's parts database does not exist. Designer
|
|
53
|
+
draws a part instance's value itself when the library has no part for it -- twice, the
|
|
54
|
+
horizontal copy landing on the reference designator -- and its own "Text alignment"
|
|
55
|
+
check then fires on every such part, which was the only thing between a generated
|
|
56
|
+
schematic and a clean review. `library build --package` clears both, so the draw says
|
|
57
|
+
so instead of leaving the findings to be chased.
|
|
58
|
+
|
|
59
|
+
- DS-16 reports a top or bottom edge whose pin names are wider than the pin pitch. Those
|
|
60
|
+
names are drawn horizontally inside the body at the pitch, and at `CHAR_WIDTH` per
|
|
61
|
+
character over 10 units about 1.6 characters fit, so a four-ground bottom edge rendered
|
|
62
|
+
as `AGNBPGNBCNE2AD` -- four names written over each other. Shortening them does not
|
|
63
|
+
help. The check names the pins and says where they can go instead; drawing them
|
|
64
|
+
readably needs a rotated name row, which is not done here.
|
|
65
|
+
|
|
66
|
+
- DS-15 checks, when the plan is built, that nothing belonging to one net lands on the
|
|
67
|
+
free end of another net's wire: a ground symbol reaches 40 units past its own end, four
|
|
68
|
+
slots at the 10-unit pin pitch, and a boxed label runs `CHAR_WIDTH` per character
|
|
69
|
+
sideways from a top-edge pin across its neighbours. Designer refuses those draws with
|
|
70
|
+
6031 and 6035, and a box that lands exactly on an end is worse -- it draws, merging two
|
|
71
|
+
nets, with nothing in the output to say so. DS-07 and DS-08 check symbol extents and
|
|
72
|
+
spacing; none of this was checked, so three draws failed on plans reported clean.
|
|
73
|
+
- A failed draw operation reports the sheet it fell on, the net or symbol it touched,
|
|
74
|
+
and how many operations had already been applied. An index alone was not locatable:
|
|
75
|
+
resolving "operation 269" meant importing the planner, rebuilding the plan and counting
|
|
76
|
+
`open_sheet` records, once per attempt, at several minutes per attempt.
|
|
77
|
+
- `schematic draw --dry-run` publishes the planned `operations`, each carrying its index
|
|
78
|
+
and the sheet it lands on, so a reported index can be looked up and a plan inspected
|
|
79
|
+
without importing the planner. Trim it with `--fields` on a large plan.
|
|
80
|
+
- The native adapter streams draw progress to stderr as it runs, and `--quiet` now does
|
|
81
|
+
what CLI-SPEC §4 says it does and suppresses it. The adapter's stderr was captured, so
|
|
82
|
+
a draw of several hundred operations printed nothing at all until it returned.
|
|
83
|
+
- `doctor` reports a `native_session` check naming which Xpedition application is
|
|
84
|
+
attached right now. `native_xpedition` passes as soon as an adapter is configured,
|
|
85
|
+
which says nothing about what is running, and Layout and Designer are separate
|
|
86
|
+
products with separate COM classes: `pcb *` reaches Layout while `schematic *` and
|
|
87
|
+
`agent snapshot` reach Designer. Nothing surfaced that split, so the first sign of
|
|
88
|
+
it was a task command failing. The probe is skipped when the native backend is not
|
|
89
|
+
ready, and a probe that fails cannot fail `doctor`.
|
|
90
|
+
- Failing to attach to a session now names the application, the commands it serves,
|
|
91
|
+
and the `session start --kind pcb|schematic` that starts it, instead of reporting
|
|
92
|
+
only the ProgIDs that were tried.
|
|
93
|
+
- Selected-origin placement tasks: offline `pcb placement-plan` and guarded native
|
|
94
|
+
`pcb placement` for explicit translate, rotation about an origin, alignment to
|
|
95
|
+
an anchor, and equal-origin-spacing distribution. Input JSON Schemas are exposed
|
|
96
|
+
by reference; native identity, units, side and protection are read, not guessed.
|
|
97
|
+
- One preview/confirmation for a serial batch, per-item and final target read-back,
|
|
98
|
+
native placement DRC enable/restore checks, stop-on-uncertainty results and one
|
|
99
|
+
save after verified completion. No routing deletion or unselected placement is
|
|
100
|
+
requested. This is not route repair, all-or-none rollback or a global write lock.
|
|
101
|
+
- Scoped reference discovery by exact command, top-level domain or existing
|
|
102
|
+
output-schema name. A command slice retains its success and dry-run schemas,
|
|
103
|
+
error tables and permission metadata; the full catalog remains the default.
|
|
104
|
+
Selectors are declared from one source and rejected on unrelated commands.
|
|
105
|
+
- Read-only `schematic pin-plan` and `schematic pin-check` compare exact CSV
|
|
106
|
+
pin/net assignments with supplied snapshots. Plans identify noop/connect/reassign
|
|
107
|
+
and shared-net review needs. Missing or conflicting observations never count as
|
|
108
|
+
verified. No native calls, automatic ChangeSets, write tokens or modifications.
|
|
109
|
+
- Bounded pages and peer samples, full-input assessment before paging, file hashes,
|
|
110
|
+
strict CSV/JSON validation and machine-readable input/observation contracts.
|
|
111
|
+
Source freshness and live electrical correctness are explicitly unverified.
|
|
112
|
+
- `system api-inventory` reads trusted standalone COM type-library metadata on
|
|
113
|
+
Windows without application activation, method invocation or registration.
|
|
114
|
+
Type headers and selected member pages report names, identities and raw type
|
|
115
|
+
descriptors; they do not become callable CLI capabilities or inferred schemas.
|
|
116
|
+
- Exact type selection, bounded pages and descriptor depth, incomplete-read
|
|
117
|
+
reporting, source hashes and safe projection. DLL/EXE/URL/UNC input, backend
|
|
118
|
+
selection and write flags are rejected. Xpedition semantics remain untested.
|
|
119
|
+
- A Windows smoke workflow exercises the real pywin32 loader against Windows'
|
|
120
|
+
standard OLE type library, without Xpedition. It is not a licensed-native test.
|
|
121
|
+
- Hand routing through the CLI — the person's own layout, not the autorouter's:
|
|
122
|
+
`pcb geometry` (the board as data: outline, pads with nets, traces with widths, vias,
|
|
123
|
+
planes, holes, silkscreen, and every part with its origin, extents and pins),
|
|
124
|
+
`pcb trace` (a trace from `--net`, `--layer`, `--width`, `--points "x,y x,y …"`, or a
|
|
125
|
+
whole plan file of traces and vias with `--file`; `Document.PutTrace`), `pcb via`
|
|
126
|
+
(`Document.PutVia`, the board's via padstack or the central library's), `pcb unroute`
|
|
127
|
+
(the routing of `--nets`, of `--all`, or one trace / via at `--at x,y [--layer N]`),
|
|
128
|
+
`pcb move` (one part to a position and rotation with the placement DRC on) and
|
|
129
|
+
`pcb labels` (every silkscreen designator to a free spot beside its part). The
|
|
130
|
+
preview of `pcb trace` names the nearest pin of each trace end; the result gives the
|
|
131
|
+
open count of every touched net before and after, and Layout's online DRC refuses an
|
|
132
|
+
item that violates a clearance while the rest go on.
|
|
133
|
+
- `pcb show --top-view`: a display scheme (`Loc: Top View`, written once into the
|
|
134
|
+
board's `Config` from `All On.dcs`) that shows Layout's own screen the way
|
|
135
|
+
`pcb render` draws the board — plane copper filled, the inner layers off, the
|
|
136
|
+
assembly texts and the drill drawing off. The stock `Loc: All On` draws the
|
|
137
|
+
pours as outlines only and every layer and text at once, which is why a board
|
|
138
|
+
with pours looked bare and crowded on screen. Layout lists a new scheme only
|
|
139
|
+
after the board reopens, so the first use closes and reopens it.
|
|
140
|
+
- `xpedition_cli.routing_plan`: the offline checker for a plan against `pcb geometry`'s
|
|
141
|
+
file (angles, clearances to pads, traces and vias of other nets, a via pad touching
|
|
142
|
+
any pad — Layout refuses those, its own net included), `PlanBuilder` for writing a
|
|
143
|
+
plan pin by pin, and `pcb stitch`, the plan for a ground via beside every
|
|
144
|
+
surface-mount ground pad where the checker finds room. `pcb trace --geometry` runs
|
|
145
|
+
the checker before Layout is touched and refuses a failing plan (`--dangerous` to let
|
|
146
|
+
Layout judge).
|
|
147
|
+
|
|
148
|
+
- Added `pcb rules` (adapter method `net_rules`): a net class with its trace widths on
|
|
149
|
+
every layer, through Constraint Manager's automation server (`ConstraintsAuto`, the
|
|
150
|
+
board loaded in its layout context), which Layout's own automation cannot write.
|
|
151
|
+
`--class POWER --nets VBAT,+3V3 --width 0.5` sets the typical width, `--min` and
|
|
152
|
+
`--expansion` the other two (80 % and 120 % of it by default); Layout re-reads the
|
|
153
|
+
constraints through `ProjectIntegration.SynchCES` and the result says
|
|
154
|
+
`seen_by_layout`. The next `pcb route --unroute` routes the class at that width.
|
|
155
|
+
- Added `pcb render` (adapter method `render_board`, drawing in
|
|
156
|
+
`xpedition_cli.board_render`): a PNG of the board from its geometry — outline with its
|
|
157
|
+
arcs, pads, traces at their widths, vias, generated planes with their cutouts, drills,
|
|
158
|
+
silkscreen graphics and texts — in KiCad's editor colours, top or bottom side. It
|
|
159
|
+
needs no screen, so it works with the desktop locked, where `pcb show --output`
|
|
160
|
+
captures a black window.
|
|
161
|
+
- `pcb arrange` places the parts of a cluster beside the IC pin they connect to: the
|
|
162
|
+
survey now reads every pin's offset, a satellite goes to the side of the IC where its
|
|
163
|
+
pin stands, level with it, turned so its own connecting pad faces the pin (a series
|
|
164
|
+
resistor at its signal pin, a decoupling capacitor at the supply pin, not the ground
|
|
165
|
+
one); a side may overhang the IC by about one designator and continues in a further
|
|
166
|
+
column or row when it fills up, and a row above or below the IC steps past a column
|
|
167
|
+
that reaches the corner.
|
|
168
|
+
- Added `pcb export`: the fabrication package (adapter method `manufacturing_output`,
|
|
169
|
+
pure parts in `xpedition_cli.fab_package`). Layout has no automation call for ODB++,
|
|
170
|
+
Gerber or NC drill, so their Output-menu dialogs (33017, 33016, 33018) are run with
|
|
171
|
+
the helper thread pressing OK. The dialogs keep their settings in memory while the
|
|
172
|
+
board is open and rewrite `Config/ODBSetup.ocf` and `Config/PlotSetup.gpf` on OK, so
|
|
173
|
+
the setups are patched with the board closed and it is opened again: the ODB++ job
|
|
174
|
+
gains its drill spans and board outline (`d_1_4 INCLUDE YES`, `BOARD_OUTLINE YES`),
|
|
175
|
+
the Gerber set gains the cells' silkscreen (`..CellType` / `..CellItemsSide` /
|
|
176
|
+
`...CellItem SilkscreenOutline` + `SilkscreenReferenceDesignator`; a `..BoardItem
|
|
177
|
+
SilkscreenTop` writes an empty file) and the board outline. The outputs are read back
|
|
178
|
+
(draw counts, drill hits, ODB++ layer matrix) and copied into a folder with fab-friendly
|
|
179
|
+
names — empty files and Layout's duplicate outer-copper files stay behind — plus the
|
|
180
|
+
ODB++ job as a zip, a centroid file, a BOM grouped by part number and footprint, a
|
|
181
|
+
README for the board house in Chinese and a manifest with the checks. The dry run is
|
|
182
|
+
offline (it reads the setups only).
|
|
183
|
+
|
|
184
|
+
- `pcb arrange` lays parts out the way a hand layout reads: every part keeps room above
|
|
185
|
+
it for its reference designator (Layout's extents stop at the placement outline, and
|
|
186
|
+
a 1 mm `R302` is wider than an 0603), the parts of one column or row share one pitch
|
|
187
|
+
(the largest of them plus the gap) with the first parts nearest the anchor, centres
|
|
188
|
+
snap to a 0.5 mm grid without ever moving outward past a margin, connectors on the
|
|
189
|
+
left edge turn by 270° and on the right by 90° so their designators face inward, a
|
|
190
|
+
new row keeps room for its sheet label, and once the corners hold mounting holes a
|
|
191
|
+
7 mm square in each corner stays empty (`corner_keepout`). A plan with parts past the
|
|
192
|
+
outline is refused with `E_VALIDATION` before anything moves (placing them lands on
|
|
193
|
+
the parked parts and Layout stops halfway with a DRC violation).
|
|
194
|
+
- `pcb route --layers 1,4` keeps the traces on the outer layers: `RoutePass.LayerSelect`
|
|
195
|
+
takes the inner layers only (the outer two are always the router's and count as
|
|
196
|
+
invalid parameters), so the list decides which inner layers join. The result reports
|
|
197
|
+
`traces_by_layer`. `--unroute` deletes every trace and via first, because the passes
|
|
198
|
+
only work on open connections.
|
|
199
|
+
- `pcb outline --radius R` rounds the corners: Layout's points array takes each corner
|
|
200
|
+
as the arc's start, its centre with a *negative* radius and its end (a positive
|
|
201
|
+
radius draws the other 270°); the route border is rounded by `R − 0.3` and the
|
|
202
|
+
manufacturing outline like the board. `Geometry.GetRect*` only answers for a plain
|
|
203
|
+
rectangle and calls a rounded outline incorrect geometry, so the board rectangle is
|
|
204
|
+
now read from the outline's extents.
|
|
205
|
+
- `pcb pour` follows the outline: the shape is inset from a rounded outline with the
|
|
206
|
+
corner radius less the margin (the radius is read back from the outline's points
|
|
207
|
+
array, which comes in thousandths of an inch), and `--replace` removes the shape the
|
|
208
|
+
board already has for that net and layer, because after `pcb outline` changed the
|
|
209
|
+
board the old rectangle stuck out past the rounded corners.
|
|
210
|
+
- Added `pcb holes`: a non-plated mounting hole in each corner of the outline (2.2 mm,
|
|
211
|
+
3.5 mm from both edges by default) through `Document.PutMountingHoleEx` with the
|
|
212
|
+
central library's `MH-C<diameter>-NONPLATED` padstack, which the library build and
|
|
213
|
+
the KiCad import both create (adapter method `mounting_holes`). Corners that already
|
|
214
|
+
hold a hole are left alone; `--replace` removes every existing hole first, for a
|
|
215
|
+
board whose outline grew.
|
|
216
|
+
- Added KiCad's footprint library as a source of real cells. `xpedition_cli.kicad_footprints`
|
|
217
|
+
reads `.kicad_mod` files (pads of every shape, drills and slots, silkscreen / fabrication
|
|
218
|
+
/ courtyard graphics, the reference-designator text) into the library model, and the
|
|
219
|
+
adapter method `kicad_import` (run by `library kicad-import`) turns every `.pretty`
|
|
220
|
+
folder into one cell partition of the project's
|
|
221
|
+
central library through the stock converters — 155 libraries, about fifteen thousand
|
|
222
|
+
cells, in a quarter of an hour. A design names a footprint as its package with a
|
|
223
|
+
`kicad:` key (`"packages": {"RES": "kicad:Resistor_SMD:R_0603_1608Metric"}`), and
|
|
224
|
+
`library build` then writes parts that reference the cell and registers its partition in
|
|
225
|
+
the project's `LIST 2dCellLibraries` (`cell_partitions`). The library model gained
|
|
226
|
+
radius-corner rectangles, oblongs, slotted holes, drawn outlines (`Graphic`), mounting
|
|
227
|
+
holes inside package cells and the placed reference designator (`RefDesText`, on the
|
|
228
|
+
silkscreen and on the assembly layer), which is what keeps the refdes at the
|
|
229
|
+
footprint's 1 mm instead of Layout's default. Cell names are
|
|
230
|
+
limited to 64 characters by `HKP2CellDB`, so longer KiCad names are cut and tagged with a
|
|
231
|
+
hash; a partition the converter refuses a cell of is imported again without it.
|
|
232
|
+
`examples/demo-sensor-board-kicad.json` is the example design on KiCad footprints.
|
|
233
|
+
|
|
234
|
+
- Added `pcb create`: the project's board from a layout template through `JobWizard
|
|
235
|
+
-createnew` (adapter method `pcb_create`). The wizard's command line takes the first
|
|
236
|
+
design in the `.prj`'s `LIST Designs` and fails with "failed to get design information"
|
|
237
|
+
when that is a schematic node, so the board design is listed first; the template is
|
|
238
|
+
copied from the installation's stock set into the central library when the library
|
|
239
|
+
lacks it; and `LIST 2dCellLibraries` gains the cell partition of every parts partition
|
|
240
|
+
the project lists, without which Layout's Database Load finds no cells. `library build`
|
|
241
|
+
registers the same list.
|
|
242
|
+
- Added `pcb annotate`: forward annotation through Layout's `Document.ProjectIntegration`
|
|
243
|
+
(adapter method `forward_annotate`), which has no type information, so `ForwardAnnotate`
|
|
244
|
+
runs on attribute access; the counts and verdict come from `PCB/LogFiles/
|
|
245
|
+
ForwardAnnotation.txt`, a board already in synch is reported without running (Layout
|
|
246
|
+
calls that a failure), and the board is saved afterwards.
|
|
247
|
+
- `session open --kind layout` and `pcb info` accept the `.prj`: the board comes from the
|
|
248
|
+
design's `PCBDesignPath`. While a board opens, a helper thread answers Layout's own
|
|
249
|
+
questions through UI Automation (`win_dialogs.answer_prompts`, needs `pywinauto`): a
|
|
250
|
+
stale lock from a killed session is opened, the recovery box loads the database the
|
|
251
|
+
user last saved, the offer to forward-annotate is declined, and every answer is
|
|
252
|
+
reported as `prompts`. A missing Layout is started through its launcher and waited
|
|
253
|
+
for, because an instance that COM activation starts never registers its automation
|
|
254
|
+
object. The adapter loads Layout's type library for its enumerations but keeps the
|
|
255
|
+
objects late-bound, and reads `Components` and `Nets` without filters: both wrappers
|
|
256
|
+
reject the filter arguments.
|
|
257
|
+
- `xpedition_cli.project_file`: pure-text reading and editing of a `.prj` (designs and
|
|
258
|
+
their sections, list entries, list creation, design order).
|
|
259
|
+
- Designer's `OpenProject` is wrapped the same way: switching projects while sheets are
|
|
260
|
+
open asks whether to close them, and the call waits for the answer; the adapter now
|
|
261
|
+
answers Yes.
|
|
262
|
+
- Added `pcb arrange`: a first placement of the board's parts that follows the
|
|
263
|
+
connections (adapter method `arrange_components`, planner `xpedition_cli.board_layout`):
|
|
264
|
+
one cluster per IC with the parts that connect to it around it, filled from the centre
|
|
265
|
+
outward so decoupling capacitors sit nearest, clusters in rows by sheet, connectors
|
|
266
|
+
turned by 90° on the side edge next to their cluster, test points along the bottom
|
|
267
|
+
edge, and a silkscreen zone label per sheet from the design file's `zone`
|
|
268
|
+
(`--design`). Layout has no extents for an unplaced part and drops its pins from
|
|
269
|
+
`Net.Pins`, so the dry run measures each part alone at the board's centre, parks the
|
|
270
|
+
unplaced ones in a grid below the outline, reads the nets, unplaces them again and
|
|
271
|
+
binds the token to the plan's digest; the confirmed run recomputes the plan, refuses a
|
|
272
|
+
changed board, lifts every planned part (Layout calls a part placed onto another one,
|
|
273
|
+
or its own old footprint, a DRC violation), places through `Component.Place`, replaces
|
|
274
|
+
earlier zone labels and saves.
|
|
275
|
+
- Added `pcb outline`: the board outline as a width × height millimetre rectangle from
|
|
276
|
+
the origin (`PutBoardOutline`), with the route border 0.3 mm inside it and the
|
|
277
|
+
manufacturing outline on it, because the template's copies keep their old size
|
|
278
|
+
otherwise (adapter method `board_outline`).
|
|
279
|
+
- Added `pcb pour`: a plane shape for a net on a layer, inset from the outline
|
|
280
|
+
(`PutPlaneShape`; GND on layer 2 by default), refusing a second shape for the same net
|
|
281
|
+
and layer (adapter method `plane_pour`). The optional component argument of these
|
|
282
|
+
calls must be passed as `None`: win32com cannot turn the type library's default `0`
|
|
283
|
+
into an object pointer, and the call fails with "The Python instance can not be
|
|
284
|
+
converted to a COM object".
|
|
285
|
+
- `pcb show` also fits the board outline into the view (`ActiveView.SetExtentsToBoard`,
|
|
286
|
+
once the toolbar's `VIEW_FITBOARD` button), so a resized outline fills the view.
|
|
287
|
+
- Added `pcb route`: Layout's batch autorouter through `Document.NewRoutePass`
|
|
288
|
+
(adapter method `route_board`). `--passes` names the passes and their effort range,
|
|
289
|
+
`route:1-5,viamin:1-3,smooth:1-3` by default (also `fanout`, `novia`, `spread`,
|
|
290
|
+
`expand`, `removehangers`); each pass runs over every net with `Go` and the result
|
|
291
|
+
reports the routed nets, open connections, traces and vias after each one and the
|
|
292
|
+
nets left open. The example board routes completely in three seconds.
|
|
293
|
+
- Added `pcb create --replace`: closes the board in Layout, removes the `PCB` folder,
|
|
294
|
+
clears the board keys in the `.prj` and creates the board again. That is the way to
|
|
295
|
+
pick up a cell that changed in the library: forward annotation never changes the cell
|
|
296
|
+
of a component that already exists on the board, placed or not, and JobWizard's own
|
|
297
|
+
`-deletePCB` fails on these projects.
|
|
298
|
+
- `pcb annotate` is now robust: the board is closed and opened again first (a Layout
|
|
299
|
+
session older than Designer's current project session fails the packaging phase),
|
|
300
|
+
Layout's own "annotate now?" prompt is answered Yes, the explicit call runs with
|
|
301
|
+
Designer's project closed (it fails with it open) and is retried once (the first call
|
|
302
|
+
on a freshly opened board fails, the second succeeds), Designer's project is reopened
|
|
303
|
+
afterwards, and `--unroute` deletes traces and vias first (Layout in its preventive
|
|
304
|
+
DRC mode cannot break traces back).
|
|
305
|
+
- `pcb arrange` deletes the board's traces and vias before re-placing (a part placed
|
|
306
|
+
onto a trace is a DRC violation, and a placement change makes every trace wrong) and
|
|
307
|
+
reports what it removed.
|
|
308
|
+
- Placeholder IC packages are routable under the stock rules: `SOIC` (1.27 mm pitch)
|
|
309
|
+
up to 16 pins and a 0.8 mm pitch `TSSOP` beyond, because a 0.65 mm pitch cannot be
|
|
310
|
+
reached with 0.254 mm traces and clearances (the template's read-only defaults).
|
|
311
|
+
- Board snapshots include traces and vias (net and layer), so `pcb info` counts them.
|
|
312
|
+
- Added `pcb drc`: Layout's Batch DRC (adapter method `batch_drc`). There is no
|
|
313
|
+
automation call and its driver refuses a command line, but the menu command runs
|
|
314
|
+
through `Gui.ProcessCommand(32769)`; its dialog is answered from the helper thread, the
|
|
315
|
+
run is waited out, and every hazard comes back from `Document.GetHazards` with its
|
|
316
|
+
type name, description, position, the objects involved and, for clearance checks, the
|
|
317
|
+
required and actual distance. `--no-run` only reads, `--online` adds the online DRC's
|
|
318
|
+
hazards. The first run found the dual-row placeholder pads overlapping (pad long side
|
|
319
|
+
along the pitch), fixed in `library_hkp`, and the ground vias dangling, fixed below.
|
|
320
|
+
- `pcb pour` switches the net's plane assignment from Draft to Dynamic so Layout
|
|
321
|
+
generates the copper (`PlaneAssignment.PlaneDataState`), and `pcb route` regenerates
|
|
322
|
+
every plane after its passes: vias the router adds only tie in after a regeneration.
|
|
323
|
+
The battery board then passes Batch DRC except for vias under the IC bodies.
|
|
324
|
+
- The prompt answerer thread no longer presses the default button of every `#32770`
|
|
325
|
+
dialog: doing so ended the packager's progress box during forward annotation, which
|
|
326
|
+
was the whole reason `pcb annotate` kept failing "in the packaging phase" while the
|
|
327
|
+
same call from a plain script succeeded. Annotation now succeeds at the first attempt
|
|
328
|
+
on a fresh board; the retry stays, with short waits.
|
|
329
|
+
- Window captures that are all black (a locked desktop) are reported with `blank`.
|
|
330
|
+
- Added `pcb show` (adapter method `show_board`): the board window to the front under a
|
|
331
|
+
display scheme that shows the parts, default `Loc: All On`, with an optional PNG
|
|
332
|
+
capture like `schematic show`. The stock templates open with `Loc: Assembly Bottom`,
|
|
333
|
+
under which a board of top-side parts looks empty. Layout lists the scheme names
|
|
334
|
+
(`Document.DisplaySchemes`); `pcb show` switches them through the view's display
|
|
335
|
+
control (below), with the toolbar combo driven through UI Automation as the fallback,
|
|
336
|
+
whose popup exposes only the rows on screen and is paged with the keyboard.
|
|
337
|
+
- Board component records carry `x`/`y` in millimetres with `unit`, whatever the
|
|
338
|
+
document's current unit (the stock template counts in mils), and `side` from `Side`
|
|
339
|
+
(1 top, 512 bottom) instead of the wrong layer test.
|
|
340
|
+
- Added `library build`: placeholder padstacks, cells and parts for a design, generated as
|
|
341
|
+
HKP text (`xpedition_cli.library_hkp`) and imported into the project's central library
|
|
342
|
+
through the stock `HKP2PadstackDB`, `HKP2CellDB` and `HKP2PartsDB` converters (adapter
|
|
343
|
+
method `library_import`); `--package` then runs the packager, which now replaces its cached
|
|
344
|
+
parts (`-Replace`) so a rebuilt library is seen. Symbols carry pin-label records and default
|
|
345
|
+
to the stock `PartQuest` partition, the one every template library registers.
|
|
346
|
+
- Added `project init --template` on the NativeBackend: a new Xpedition project copied from a
|
|
347
|
+
template project (adapter method `clone_project`), with an ASCII-path guard because Designer
|
|
348
|
+
cannot load new symbol files from a folder whose path has other characters.
|
|
349
|
+
- Added built-in `NTC`, `NMOS`, `PMOS`, `TP` (test point) and `HOLE` (mounting hole) symbol
|
|
350
|
+
kinds to the schematic planner and a four-sheet example design (a
|
|
351
|
+
battery-compartment temperature monitor with pull-ups, series resistors, test points and
|
|
352
|
+
thermal and interface notes).
|
|
353
|
+
- The I2C pull-up review rule now accepts a pull-up one series resistor away, so a host
|
|
354
|
+
connector behind 33 Ω series resistors is not reported.
|
|
355
|
+
- Generated passive, MOSFET and test-point symbols carry `ANALOG` pins, so Designer's
|
|
356
|
+
BI-to-power and BI-to-ground checks stay quiet on a correct design.
|
|
357
|
+
- Added `project tree`, embedded runtime changelog data, and the ExchangeBackend boundary.
|
|
358
|
+
- Added MockBackend read commands for schematic, PCB, constraints, analysis, manufacturing, and library data.
|
|
359
|
+
- Added schematic power-net, interface, and project-model support.
|
|
360
|
+
- Added read-only Agent integration commands and an NDJSON stdio server.
|
|
361
|
+
- Added ChangeSet history and backup rollback with the same dry-run/confirm gate.
|
|
362
|
+
- Added project diff against the latest automatic backup.
|
|
363
|
+
- Added MockBackend session status/log inspection with explicit native lifecycle boundaries.
|
|
364
|
+
- Added JSON/CSV/BOM ExchangeBackend inspection and guarded import.
|
|
365
|
+
- Added IPC-2581 XML component, net and pin-connection inspection/import.
|
|
366
|
+
- Added library validation and review findings/report read aliases.
|
|
367
|
+
- Added `schematic apply` as the unified guarded ChangeSet write entry point.
|
|
368
|
+
- Added guarded MockBackend project initialization.
|
|
369
|
+
- Added MCP JSON-RPC transport for read-only Agent tools.
|
|
370
|
+
- Added MCP protocol version negotiation and tool output schemas.
|
|
371
|
+
- Updated MCP negotiation to prefer protocol version 2025-11-25 while accepting older clients.
|
|
372
|
+
- Added deterministic MockBackend ERC/DRC/DFM analysis runs.
|
|
373
|
+
- Added BOM normalization, grouping, variant/missing/duplicate checks, validation and comparison.
|
|
374
|
+
- Added the optional Windows COM adapter for the public Xpedition automation API, including
|
|
375
|
+
installation discovery, COM-registration probing, structured health errors, session lifecycle,
|
|
376
|
+
PCB and Designer snapshots, and guarded component/net move/place operations.
|
|
377
|
+
|
|
378
|
+
- Added a `package` adapter method that runs forward annotation headless. Designer's
|
|
379
|
+
`Package Design for Layout` launches `packagerui.exe`, a separate GUI process that waits
|
|
380
|
+
for a human; `package.exe` does the same work as a console program. It has to be started
|
|
381
|
+
through the launcher in `common/win64/bin`, because the real binary under `wg/win64/bin`
|
|
382
|
+
cannot initialise its Qt platform plugin on its own and puts up a message box instead.
|
|
383
|
+
Errors and the verdict are read back from `<project>/Integration/PartPkg.log`.
|
|
384
|
+
- Added the Skill's drawing conventions: `reference/schematic-conventions.md` and
|
|
385
|
+
`reference/pcb-conventions.md`, with the non-negotiable subset in `SKILL.md` and a matching
|
|
386
|
+
eval prompt. The sheet unit was measured rather than assumed: one sheet unit is 10 mil, the
|
|
387
|
+
100 mil grid is 10 units, `V 53` symbol files share the sheet unit and `V 54` files (every
|
|
388
|
+
stock symbol) are in 10 nm. Each rule is marked verified, industry default or pending a
|
|
389
|
+
company decision; the PCB rules are defaults only.
|
|
390
|
+
- Added `schematic export`: renders a Designer project to a new PDF through the stock
|
|
391
|
+
`sch2pdf` console program (adapter method `export_pdf`) and reports the sheets it printed.
|
|
392
|
+
Designer's own `Generate PDF` is a dialog; `sch2pdf` runs headless while the project is
|
|
393
|
+
open and prints only what lies inside each sheet's border. An existing output file is never
|
|
394
|
+
replaced.
|
|
395
|
+
- Added `xpedition_cli.symbols`, a generator for `V 53` Designer symbols: IEC two-terminal
|
|
396
|
+
shapes, pin-grouped boxes and one power symbol per net, all on the 10-unit grid. Power
|
|
397
|
+
symbols are type 4 (`Y 4`) like the stock Globals symbols — a type-1 symbol carrying a
|
|
398
|
+
`NETNAME` attribute names no net — and Designer keeps the definition of a symbol it has
|
|
399
|
+
placed, so a changed symbol needs a new name.
|
|
400
|
+
- Added `schematic draw`: plans a whole schematic from a compact design description
|
|
401
|
+
(`xpedition_cli.schematic_layout`: IC blocks with a treatment per pin, vertical ladders and
|
|
402
|
+
horizontal chains of two-terminal parts between power, ground and labelled nodes, titles,
|
|
403
|
+
notes, overview boxes) and draws it through the adapter method `draw` after the usual
|
|
404
|
+
dry-run/confirm gate. The dry run is pure Python and reports the sheets, parts, netlist and
|
|
405
|
+
convention issues; the confirmed run wipes and redraws the listed sheets, sets them to the
|
|
406
|
+
requested size, writes content-named symbol files, reopens the project and compares every
|
|
407
|
+
net read back with the plan. `examples/demo-sensor-board.json` is the published example.
|
|
408
|
+
- Added `xpedition_cli.win_dialogs`, the modal-dialog dismisser the probes used, so the
|
|
409
|
+
adapter can settle after project and sheet operations without a human.
|
|
410
|
+
- Added `schematic show`: activates a sheet, fits it and brings Designer's window to the
|
|
411
|
+
front so a person can look at what was drawn, with an optional PNG capture of the window
|
|
412
|
+
for the agent's own check (no external imaging library; the PNG is encoded in-process).
|
|
413
|
+
`schematic draw` and `schematic show` were then exercised end to end through the CLI on
|
|
414
|
+
a four-sheet example design: plan, confirm token, 223 operations, netlist match, window
|
|
415
|
+
in front.
|
|
416
|
+
- Added schematic review on live designs. The native snapshot now carries every instance
|
|
417
|
+
attribute (part number, value, package), the sheet a part sits on (from its UID), each
|
|
418
|
+
pin's net through `LogicalNetName` with Designer's `$<sheet>N<id>` id for unlabelled
|
|
419
|
+
nets, and a `no_connect` flag for pins under a no-connect mark. Nets are merged across
|
|
420
|
+
sheets, so multi-sheet designs no longer report every rail as a duplicate, `bom export`
|
|
421
|
+
returns part numbers and values, and `schematic unconnected` no longer lists marked pins
|
|
422
|
+
or bare junctions.
|
|
423
|
+
- Added netlist rules to `review run` (`cli/open-pin`, `single-pin-net`, `unnamed-net`,
|
|
424
|
+
`missing-part-number`, `decoupling`, `i2c-pullup`, `net-name`, `refdes-prefix`) and, on the
|
|
425
|
+
NativeBackend, Designer's own verification: the adapter method `verify` runs `Full
|
|
426
|
+
Verification` (34155) and parses `LogFiles/vdrc.log` and `grc.log` into findings tagged
|
|
427
|
+
`xpedition/verify:<rule>` and `xpedition/grc:<check>`. `RunDesignIntegrityChecks` is only
|
|
428
|
+
a database integrity test and is not used for this.
|
|
429
|
+
- MockBackend project model and normalized design snapshots.
|
|
430
|
+
- Capability registry with explicit NativeBackend and ExchangeBackend boundaries.
|
|
431
|
+
- ChangeSet validation, dry-run previews, operation-bound confirmation tokens, atomic apply, backup, and post-write verification.
|
|
432
|
+
- Deterministic review and normalized BOM commands.
|
|
433
|
+
- JSON-first CLI contract, Skill, FCC guard, CI and npm/PyInstaller packaging seed.
|
|
434
|
+
|
|
435
|
+
### Changed
|
|
436
|
+
|
|
437
|
+
- Plural flags -- `--nets`, `--sheets`, `--layers`, `--formats`, `--libraries`,
|
|
438
|
+
`--fields` -- repeat as well as take a comma list, and `reference` marks them
|
|
439
|
+
`multiple`. A singular flag given twice with different values is a usage error; it
|
|
440
|
+
used to keep the last one silently.
|
|
441
|
+
- `pcb unroute` reports each net (or the point) in `items[]` with a `summary`, a net
|
|
442
|
+
named twice counts once, and an empty `--nets` is a validation error.
|
|
443
|
+
- A read whose `--project` does not exist is `E_NOT_FOUND`, not an empty design.
|
|
444
|
+
ChangeSet writes and imports still create their target.
|
|
445
|
+
- `doctor` and `session status` only look at a running Layout: they do not switch on its
|
|
446
|
+
dialog suppression and single-threaded mode, which the commands that drive Layout set
|
|
447
|
+
when they attach.
|
|
448
|
+
- `live_smoke_status` uses the spec's values: `missing`, with `reason` saying what the
|
|
449
|
+
recorded runs cover.
|
|
450
|
+
- The release binary's dependencies are locked -- `requirements.txt` (Pillow 12.3.0,
|
|
451
|
+
which fixes the 25 advisories against 12.2.0) and `requirements-build.txt`
|
|
452
|
+
(PyInstaller) -- and CI and the release workflow both audit them; the release also
|
|
453
|
+
runs `npm audit` and the full spec check, as CI does.
|
|
454
|
+
- The install instructions start from the repository with pip, which works before any
|
|
455
|
+
npm release.
|
|
456
|
+
- The bundled conventions keep to general defaults; a company's own practice belongs in
|
|
457
|
+
a bound knowledge-base document. Numbering reference designators per sheet in
|
|
458
|
+
hundreds, and the text-size ladder, are now defaults.
|
|
459
|
+
- The Skill is now three, on spec v1.6.3's rules for several Skills (SKILL-SPEC §7).
|
|
460
|
+
`xpedition-cli` stays the entry Skill: install, sessions, projects and ChangeSets, the
|
|
461
|
+
write recipe, errors and security. `xpedition-schematic` carries the schematic in
|
|
462
|
+
Designer: drawing conventions, design format, packaging after a draw, review, export,
|
|
463
|
+
pin assignment and footprint mapping. `xpedition-pcb` carries the board in Layout,
|
|
464
|
+
from creating it to the fabrication package, with its conventions, placement,
|
|
465
|
+
hand-routing and fabrication references. Both read the entry Skill first. Three writes
|
|
466
|
+
that discard work or cannot be previewed are now STOP CHECKPOINTs: a confirmed
|
|
467
|
+
`pcb arrange` deletes all routing, `schematic draw` wipes the sheets it redraws, and
|
|
468
|
+
`library kicad-import` overwrites the cells of a partition that exists. The same
|
|
469
|
+
`npx skills add fatecannotbealtered/xpedition-cli -y -g` installs all three.
|
|
470
|
+
- The vendored spec is v1.6.3.
|
|
471
|
+
- Runtime readiness is beta. `reference`'s `release_readiness.reason` says what the
|
|
472
|
+
recorded runs cover, the 2026-09-19 placement smoke included, and what keeps the
|
|
473
|
+
level short of stable.
|
|
474
|
+
- Routing-plan checks skip existing-existing segment and via pairs before
|
|
475
|
+
iteration and avoid repeated tail-list copies. The geometric predicates and
|
|
476
|
+
finding order are unchanged. Incremental edits no longer pay a quadratic
|
|
477
|
+
existing-board pair scan; new-new comparisons still require further indexing.
|
|
478
|
+
- Bounded local query pages stop after one matching lookahead record rather than
|
|
479
|
+
filtering every record. Unfiltered sequence reads slice directly; agent and
|
|
480
|
+
library queries no longer re-filter a materialized result. Matching and paging
|
|
481
|
+
semantics remain compatible, including zero limits and clamped offsets.
|
|
482
|
+
This is not native query pushdown or a COM-session optimization.
|
|
483
|
+
- `agent capabilities` no longer loads a project or requires the selected native
|
|
484
|
+
backend to be operational. Capability discovery now matches its streaming
|
|
485
|
+
counterpart and remains available when a design path is absent or malformed.
|
|
486
|
+
- `analysis run --backend native_xpedition` explicitly rejects the unsupported
|
|
487
|
+
combination before native access instead of running Mock checks on a native
|
|
488
|
+
snapshot. Native stored-result reads still run, but the native snapshot holds no
|
|
489
|
+
analysis results, so they return an empty list. This intentionally
|
|
490
|
+
tightens backend selection; it does not implement a native analysis engine.
|
|
491
|
+
- Confirmation consumption now serializes ledger check/update across cooperating
|
|
492
|
+
processes and threads, atomically replaces the ledger and rechecks expiry after
|
|
493
|
+
locking. Concurrent first-use secret creation no longer races; corrupt secrets
|
|
494
|
+
are rejected rather than silently reused or rotated.
|
|
495
|
+
- Reject alternate base64 token representations that could evade a consumed-token
|
|
496
|
+
fingerprint, non-ASCII signatures and nonfinite or malformed signed expiry data.
|
|
497
|
+
- Preserve the pinned spec's storage-failure degradation, with explicit secret-free
|
|
498
|
+
stderr warnings. Failed replacement preserves the old ledger; unavailable lock
|
|
499
|
+
storage never triggers an unlocked ledger rewrite. Lock contention is a conflict,
|
|
500
|
+
not degradation. This is not a project write lock or exactly-once native execution.
|
|
501
|
+
- The published example design is `examples/demo-sensor-board.json` (and its
|
|
502
|
+
`-kicad` variant with a KiCad footprint map): a generic 5 V / 3V3 sensor board that
|
|
503
|
+
exercises every block kind the planner supports. It replaces the two product-shaped
|
|
504
|
+
designs that were here before.
|
|
505
|
+
- `pcb create --replace` archives the design's existing layout folder to
|
|
506
|
+
`PCB-backup-<timestamp>.zip` beside the project before deleting it, and returns the
|
|
507
|
+
archive's path in `backup`. Deleting a board was the one irreversible operation in
|
|
508
|
+
the tool: the folder holds the placement, the routing, the pours and the output
|
|
509
|
+
setups, and none of that lives anywhere else. Its dry-run preview now says so —
|
|
510
|
+
the old `blast_radius` text described only the folder being created, while the
|
|
511
|
+
`changes` list beside it already said `remove_layout_data`.
|
|
512
|
+
- `pcb trace`, `pcb via` and `pcb arrange` take `--pace SECONDS`: a wait between placed
|
|
513
|
+
items (0 to 10 s) so a person at Layout's screen watches the parts land and the
|
|
514
|
+
routing grow one item at a time; 0, the default, is as fast as Layout takes it.
|
|
515
|
+
- `pcb show` switches the display scheme through Layout's automation
|
|
516
|
+
(`ActiveView.DisplayControl.LoadScheme`, read back from `DisplayControl.Name`) and fits
|
|
517
|
+
the board with `ActiveView.SetExtentsToBoard`; the toolbar combo and button through UI
|
|
518
|
+
Automation remain the fallback, which had started to come back empty on a Layout
|
|
519
|
+
started by `pcb annotate`.
|
|
520
|
+
- `pcb rules` also sets the widths of a class that exists, `(Default)` included: the
|
|
521
|
+
stock class allows exactly one width (minimum = typical = expansion = 0.254 mm), so a
|
|
522
|
+
0.3 mm ground stub was a TraceWidths hazard until its expansion width was raised.
|
|
523
|
+
- A board whose vias were all deleted lists no via padstack; `pcb via` then pulls the
|
|
524
|
+
central library's first via padstack (`Document.PutPadstack`, `026VIA` here).
|
|
525
|
+
- `pcb pour` lays the plane shape with `bRouteObstruct` false: an obstructing shape
|
|
526
|
+
blocks the autorouter on that layer entirely and, laid over traces that are already
|
|
527
|
+
routed, is refused as a DRC violation. The copper flows around the traces when the
|
|
528
|
+
plane data is generated. The board recipe pours the outer layers after routing.
|
|
529
|
+
- `pcb route` routes a second round after regenerating the planes when a net is still
|
|
530
|
+
open: a pin can be cut off once the copper flows around the new traces.
|
|
531
|
+
- `pcb drc` separates `errors` from `warnings` (`ViasUnderParts` — a via under a
|
|
532
|
+
surface-mount body, normal with tented vias) and says `passes` when there are no
|
|
533
|
+
errors; `clean` still means no hazards at all.
|
|
534
|
+
- The placement planner packs parts 0.6 mm apart (courtyards carry their own margin),
|
|
535
|
+
starts a new row of clusters for every sheet so the sheet labels sit over their own
|
|
536
|
+
clusters, and moves a connector to the other edge when one edge cannot hold its
|
|
537
|
+
column.
|
|
538
|
+
- The converter logs are read more carefully: every `HKP2*` log says "checking for file
|
|
539
|
+
format errors… none found", so only a leading or labelled error word, "cannot add" and
|
|
540
|
+
"N errors" count as failures (the old check on the bare word flagged nothing in the
|
|
541
|
+
Chinese logs and would have flagged everything in English ones).
|
|
542
|
+
- `session start`, `attach`, `open` and `stop` are declared by `reference` and pick their
|
|
543
|
+
target application with `--kind pcb|layout|schematic|designer`. Three of them were already
|
|
544
|
+
implemented but undeclared, so no agent reading `reference` could find them, and every one
|
|
545
|
+
of them silently targeted Layout — Designer was unreachable. `session stop` quits the
|
|
546
|
+
application, so it now goes through the dry-run/confirm gate; `native_session_lifecycle` is
|
|
547
|
+
no longer reported as a planned domain.
|
|
548
|
+
- The adapter suppresses Layout's modal dialogs on every attach (`SuppressTrivialDialogs`,
|
|
549
|
+
`SuppressNotepadDialogs`, `SuppressVariantDataOutOfDateDialog`, `SingleThreaded`). An unattended agent cannot answer a
|
|
550
|
+
message box, so a dialog raised mid-operation turns a COM call into a hang. Dialogs raised
|
|
551
|
+
while the application is still starting up happen before automation exists and are out of
|
|
552
|
+
reach — attach to an already-running instance to avoid them.
|
|
553
|
+
- Hardened output redaction, operation-bound confirmation scopes, pagination metadata, and native capability reporting.
|
|
554
|
+
- NativeBackend now discovers the installed adapter, reports the actual COM-registration state,
|
|
555
|
+
and routes verified reads and ChangeSet writes through the adapter.
|
|
556
|
+
|
|
557
|
+
### Fixed
|
|
558
|
+
|
|
559
|
+
- The plan-time checks for a covered wire end and for unreadable edge pin names reported
|
|
560
|
+
as DS-09 and DS-10, ids the checklist gives to the refdes-prefix and part-number
|
|
561
|
+
checks, so a reviewer looking an issue up found a different rule. They are DS-15 and
|
|
562
|
+
DS-16 now, with a row each in the checklist, and a test holds every id the planner
|
|
563
|
+
emits to a checklist row that names that dry-run issue.
|
|
564
|
+
- `changelog` returned only part of a release's entries: a release that repeats a heading
|
|
565
|
+
kept only its first section, and an entry lost its continuation lines.
|
|
566
|
+
- `manufacturing bom` ignored `--limit`, `agent review` ignored `--limit` and
|
|
567
|
+
`--offset`, and six query commands paged without declaring it in `reference`.
|
|
568
|
+
- Design text holding a double quote or a line break could write records of its own
|
|
569
|
+
into the generated HKP library files; it is refused now. The same holds for symbol
|
|
570
|
+
files, and a KiCad footprint whose text cannot be quoted is skipped with an issue.
|
|
571
|
+
- A symbol name or a symbol partition in a design file named a file path:
|
|
572
|
+
`../../../ESCAPE` would have been written outside the library's `sym` folder, and the
|
|
573
|
+
partition also into the `.prj`. Both are plain names now, and the adapter writes a symbol
|
|
574
|
+
file only inside its folder.
|
|
575
|
+
- `--limit` and `--offset` on a command that does not page were ignored -- `bom validate
|
|
576
|
+
--limit 1` returned every issue -- and are refused now. Review pages carry `count`, and
|
|
577
|
+
every paged command declares its `default_sort`.
|
|
578
|
+
- `doctor` suggested COM registration when the configured adapter file was missing; it
|
|
579
|
+
now names the fix for the reason the backend gives.
|
|
580
|
+
- `pcb trace --dangerous` and `pcb via --dangerous`, which skip the offline clearance
|
|
581
|
+
check, were refused by a global check and could not be used.
|
|
582
|
+
- A pip install that is not editable -- the one the README now leads with -- answered
|
|
583
|
+
`reference` with `E_UNKNOWN` and `changelog` with nothing: the wheel held neither
|
|
584
|
+
contract/contract.json nor CHANGELOG.md. `setup.py` now carries both into the package,
|
|
585
|
+
and neither command falls back to a file in the working directory, which would be
|
|
586
|
+
another project's.
|
|
587
|
+
- The tests run against their own configuration directory; some had been writing audit
|
|
588
|
+
records into the developer's `~/.xpedition-cli`.
|
|
589
|
+
- README said the release level was `stable` (it is `beta`) and listed a
|
|
590
|
+
`schematic plan` command that does not exist.
|
|
591
|
+
- A KiCad footprint that gives one number to several lands keeps them all (#28): each
|
|
592
|
+
becomes a pad of that pin, and forward annotation puts them on its net -- measured
|
|
593
|
+
with a 2x2 mm TDFN MOSFET whose drain owns four leads and the paddle. Only a pad
|
|
594
|
+
inside a larger one of its number (a thermal via) is dropped, now reported as
|
|
595
|
+
`inside_same_number`; two overlapping rectangles make an L-shaped land.
|
|
596
|
+
- A running Designer read as absent after a temp cleaner emptied win32com's
|
|
597
|
+
generated-wrapper cache (`has no attribute 'CLSIDToClassMap'`). The adapter
|
|
598
|
+
removes such entries before it attaches, and an attach failure now says what
|
|
599
|
+
failed instead of only "not found". Designer is bound through its generated
|
|
600
|
+
wrapper, created if missing: late-bound, `project init` failed on
|
|
601
|
+
`Documents.Open` ("parameter not optional"), which a fresh machine would hit too.
|
|
602
|
+
- `session stop` reported the application closed while a dialog a timed-out call had
|
|
603
|
+
left up held its `Quit`. Known questions are answered while it quits, and an
|
|
604
|
+
application still running afterwards is an `E_CONFLICT` naming the dialog.
|
|
605
|
+
- A draw that failed inside the adapter itself -- a sheet it could not make active --
|
|
606
|
+
reported no sheet or index; every draw failure now carries them.
|
|
607
|
+
- The `schematic_draw` output schema declares `sheets_drawn`, `sheets_not_drawn` and
|
|
608
|
+
`sheets_kept`, and the dry run's declares `operations`.
|
|
609
|
+
- Every confirm example in `reference` repeats the arguments of a dry-run example. The
|
|
610
|
+
token is bound to them, so the `pcb route`, `outline`, `rules`, `export`, `holes`,
|
|
611
|
+
`labels`, `create`, `trace`, `unroute` and `library build` examples failed with
|
|
612
|
+
`E_CONFLICT` when copied; a test now holds every command to it. `pcb arrange` declares
|
|
613
|
+
in its blast radius that it deletes every trace and via on the board first.
|
|
614
|
+
- `library build --dry-run` reports a cell pad that no symbol pin reaches. The pin check
|
|
615
|
+
ran one way only -- every symbol pin needed a cell pin -- so a cell with *more* pads
|
|
616
|
+
than the symbol has pins passed clean. A power MOSFET in DFN or PowerPAK carries
|
|
617
|
+
several pads per electrode and a drain paddle, so its converted cell had seven pads
|
|
618
|
+
against a three-pin symbol and the preview reported `issues: []`: a library that looks
|
|
619
|
+
built and is not. The unmapped pads and both counts are named.
|
|
620
|
+
|
|
621
|
+
- DS-07 checks the area a design may draw in rather than only the border. The sheet
|
|
622
|
+
title strip and the notes band are placed by the planner itself, so those are computed
|
|
623
|
+
from `MARGIN` and the note count; the border symbol's own frame and title block are
|
|
624
|
+
measured per sheet size (A4 and A3 recorded, others fall back to the computed area).
|
|
625
|
+
A sheet used to pass with `issues: []` while a whole stage was drawn through the notes
|
|
626
|
+
and two capacitors sat on the title block. The plan publishes the rectangle per sheet,
|
|
627
|
+
so a caller can lay out against it instead of measuring a rendered export.
|
|
628
|
+
|
|
629
|
+
- `--dry-run` and `--confirm` are refused on a command that is not a guarded write,
|
|
630
|
+
instead of being accepted and ignored. `schematic export` renders a PDF and has no
|
|
631
|
+
gate, so a dry run wrote the file and the next one failed because it already existed.
|
|
632
|
+
The reference already declared which commands the gate applies to; now it is enforced,
|
|
633
|
+
and probing a command that has no gate says so rather than performing the write.
|
|
634
|
+
|
|
635
|
+
- A design collection that cannot be read names the state that caused it. Two ordinary
|
|
636
|
+
mid-design states both surfaced as a bare `DesignComponents` type mismatch, stopping
|
|
637
|
+
`review run`, `bom export` and `schematic components` at once: a schematic changed
|
|
638
|
+
since the last `library build --package`, and a sheet added or removed, which needs the
|
|
639
|
+
project reopened instead. `GetActiveDesign` reporting the schematic rather than the
|
|
640
|
+
block separates them, so the error now carries the likely cause and the one command
|
|
641
|
+
that clears it. Being unpackaged is a normal state to be in, not a failure.
|
|
642
|
+
|
|
643
|
+
- A part's reference designator and value start where the plan puts them. Designer's
|
|
644
|
+
attributes carry a `VdOrigin` saying which corner of the text sits at the location, and
|
|
645
|
+
a symbol leaves its refdes at `VDALIGN_MR` -- middle *right* -- so setting a location
|
|
646
|
+
put the text's right edge there and the string ran back its own width. A 17-unit refdes
|
|
647
|
+
against the planner's +12 offset landed on the part's own centreline, on every part of
|
|
648
|
+
every drawn sheet. The planner now states the left-anchored origin it means.
|
|
649
|
+
- `project init --template` gives every user symbol partition a parts database instead of
|
|
650
|
+
leaving Designer to raise a modal dialog at draw time, which blocks the draw until a
|
|
651
|
+
human clicks. A missing one is filled by copying an unused stock database out of the
|
|
652
|
+
project's own library, and only when at least two unused databases are byte-identical --
|
|
653
|
+
enough to tell an empty database from a populated one rather than guess. A library where
|
|
654
|
+
that does not hold is reported in `parts_databases.missing` and left alone.
|
|
655
|
+
- `schematic draw` reports `sheets_drawn` and `sheets_not_drawn`. A draw wipes and redraws
|
|
656
|
+
the sheets its design names; any other sheet keeps what was on it, which for a cloned
|
|
657
|
+
project is the template's content and used to ship unremarked.
|
|
658
|
+
- A timed-out native call marks the session stale, and the next task command reports that
|
|
659
|
+
instead of failing somewhere unrelated. After a read timed out, `IsProjectOpened()`
|
|
660
|
+
reported false with the project still open, so the next command asked Designer to open a
|
|
661
|
+
project it already had and was refused with a message about scripts and GUIs. Recovery
|
|
662
|
+
commands (`session status`, `start`, `stop`) still run against a stale session.
|
|
663
|
+
- `_ensure_project` reads the open project's path whatever `IsProjectOpened()` claims, so
|
|
664
|
+
a project that is already open is not reopened, and product code 64185 maps to a
|
|
665
|
+
conflict naming the state that refused the request rather than a retryable server fault.
|
|
666
|
+
- A symbol that displays the same pin name twice is refused when the plan is built,
|
|
667
|
+
naming the repeated names and the pins that share them. Designer names a net after
|
|
668
|
+
the pin a wire meets, so repeated pin names put two wires on one auto-named net and
|
|
669
|
+
the second explicit label made the draw stop with 6035 "Net already labeled" minutes
|
|
670
|
+
in and partway through. Renaming automatically is not available: the pin's `L` record
|
|
671
|
+
is what the parts database maps to cell pin numbers. Give each pin a distinct name and
|
|
672
|
+
keep the shared net on the wire's label, which is what the netlist already uses.
|
|
673
|
+
- `session stop` quits the application that is attached rather than defaulting to pcb.
|
|
674
|
+
Quitting discards unsaved design work, and with only Designer running the old default
|
|
675
|
+
reported success against an application that was not there while leaving the one the
|
|
676
|
+
caller meant still running. The domain is resolved from the live session; both attached
|
|
677
|
+
is a `E_USAGE` asking for `--kind`, an explicitly named application that is not running
|
|
678
|
+
is `E_NOT_FOUND`, and the preview's blast radius now names the application instead of
|
|
679
|
+
saying "the running Xpedition application". Machines with no adapter to probe keep the
|
|
680
|
+
previous behaviour.
|
|
681
|
+
- `session start --kind schematic` starts Designer through `common\win64\bin\viewdraw.exe`
|
|
682
|
+
rather than the product under `wv`. The common launcher sets up the release environment
|
|
683
|
+
before starting the product; naming the product directly skipped that and the process
|
|
684
|
+
exited immediately with STATUS_DLL_NOT_FOUND (0xC0000135), so every native schematic
|
|
685
|
+
command was unusable unless someone had already started Designer by hand. The pcb domain
|
|
686
|
+
always went through the launcher and the comment above the code already stated the rule.
|
|
687
|
+
- A missing Xpedition automation-licensing call is classified from its EXCEPINFO
|
|
688
|
+
numbers (product code 10279, scode `0x8004022D`) instead of by searching the COM
|
|
689
|
+
description for "license". On a localised installation the description carries
|
|
690
|
+
neither that word nor "token" — a Chinese session reports 自动化代码不包含身份验证
|
|
691
|
+
所需的许可调用 — so the fault was reported as a retryable `E_SERVER` and an agent
|
|
692
|
+
would retry it indefinitely. It is now the non-retryable `E_AUTH` it always was.
|
|
693
|
+
Observed on XPED2604; ordinary faults such as `DISP_E_TYPEMISMATCH` arrive without
|
|
694
|
+
this EXCEPINFO and keep their existing classification.
|
|
695
|
+
- The reference-query test reads `contract/contract.json` as UTF-8 rather than with
|
|
696
|
+
the locale codec, so the suite no longer fails on a GBK Windows machine. The
|
|
697
|
+
hosted runners default to UTF-8, so CI could not observe this.
|
|
698
|
+
- Explicit NativeBackend project initialization without a template fails before
|
|
699
|
+
preview, token consumption or file creation; it never creates a mock project.
|
|
700
|
+
- Native ChangeSet results verify the requested final coordinates, properties,
|
|
701
|
+
part identities and connectivity against read-back instead of hardcoding
|
|
702
|
+
verification success. Missing observations or unsupported verification fail
|
|
703
|
+
closed; post-write read-back failures are non-retryable and report the stage.
|
|
704
|
+
Read-back is not a durability or electrical-correctness claim.
|
|
705
|
+
- `--fields` projects records inside arrays without changing their order or
|
|
706
|
+
cardinality. Paging controls and `_untrusted` annotations survive projection;
|
|
707
|
+
parent/child selectors are order-independent. Missing fields retain legacy
|
|
708
|
+
omission semantics; no post-write selector error is introduced.
|
|
709
|
+
- `reference` derives confirm/dry-run applicability from write-command metadata.
|
|
710
|
+
- Three things the first CI run found, none of which a Windows workstation could
|
|
711
|
+
show: `_layout_board_path` could not resolve a board off Windows, because a `.prj`
|
|
712
|
+
stores its relative board path with backslashes and those are ordinary filename
|
|
713
|
+
characters elsewhere; `pcb render`'s tests were skipped-by-crash wherever Pillow
|
|
714
|
+
was absent, since Pillow sat only in the `native` extra while the renderer is pure
|
|
715
|
+
Python (it is now in `dev` too); and a test encoded its fixture with `mbcs`, which
|
|
716
|
+
does not exist off Windows and cannot represent Chinese on a Windows runner whose
|
|
717
|
+
code page differs.
|
|
718
|
+
- The contract tests no longer depend on what is installed on the machine that runs
|
|
719
|
+
them. NativeBackend finds its adapter through `XPEDITION_NATIVE_COMMAND` or through
|
|
720
|
+
`xpedition-native-adapter` on PATH, so on a workstation with the native extra the
|
|
721
|
+
backend really is available and the write-gate test saw a successful snapshot where
|
|
722
|
+
it asserts `E_BACKEND_UNAVAILABLE`. The suite now points the variable at a path that
|
|
723
|
+
does not exist.
|
|
724
|
+
- `session start|attach|open|stop --backend native_xpedition --kind bogus` reports
|
|
725
|
+
`E_VALIDATION` again instead of `E_BACKEND_UNAVAILABLE`: the kind is validated before
|
|
726
|
+
the adapter is asked for, because a malformed flag is a usage error whether or not an
|
|
727
|
+
adapter is installed.
|
|
728
|
+
- Grid snapping rounded half-way values to the even side (Python's `round`), so a
|
|
729
|
+
column on a 2.5 mm step landed alternately high and low; they now always go up.
|
|
730
|
+
- `pcb create --replace` could not remove the old layout folder after an NC drill run:
|
|
731
|
+
Layout keeps `LogFiles/DrillPrefs.txt` open after the document closes, and
|
|
732
|
+
`Application.Quit` leaves it on its start page still holding the file. A Layout
|
|
733
|
+
with no document open is now ended by its process when the folder stays locked,
|
|
734
|
+
and the next step starts it again.
|
|
735
|
+
- `pcb export` runs the output dialogs a second time when one of them wrote its own
|
|
736
|
+
settings back over the patched setup file (the ODB++ job came out without its
|
|
737
|
+
drill layer once); the result says `rounds`.
|
|
738
|
+
- Fixed shared ground bars for several bottom-edge ground pins: the ground symbol now sits on
|
|
739
|
+
the bar's free end, where Designer connects it, instead of on the corner where it did not.
|
|
740
|
+
- The board ChangeSet operations called `Component.Place` and `Component.Move` with the
|
|
741
|
+
wrong arguments: `Place(x, y, orientation, bTop, eFixType, eUnit, eAngleUnit)` takes
|
|
742
|
+
"top side" where a mirror flag was passed, and `Move(x, y, eUnit)` was given no `y`.
|
|
743
|
+
Both now take an optional `unit` (`mm`, `mils`, `inch`, `um`; the document's unit by
|
|
744
|
+
default).
|
|
745
|
+
- `pcb arrange` measures a placed part unturned: Layout reports the extents of a part as
|
|
746
|
+
it stands, so a connector standing at 90° from the previous arrangement came back
|
|
747
|
+
5.5 mm wide and 10.9 mm tall and the next plan turned it again, onto its neighbour.
|
|
748
|
+
- `pcb route` regenerates a plane it finds in Draft instead of skipping it: the GND
|
|
749
|
+
plane of the board on KiCad footprints was back in Draft after its pour had been
|
|
750
|
+
saved, and Batch DRC reported the ground net partial with its vias dangling.
|
|
751
|
+
- The CLI and the native adapter now exchange UTF-8 on their pipes regardless of the console
|
|
752
|
+
code page. On a Chinese Windows the parent decoded the adapter's output as GBK and crashed in
|
|
753
|
+
its reader thread, so every native error surfaced as `E_UNKNOWN`/`TypeError` instead of the
|
|
754
|
+
adapter's structured error.
|
|
755
|
+
- Session liveness no longer probes with `os.kill(pid, 0)` on Windows. `signal.CTRL_C_EVENT`
|
|
756
|
+
is 0 there, so CPython routed signal 0 to `GenerateConsoleCtrlEvent`, which takes a process
|
|
757
|
+
*group* id: it reported every running Xpedition process as dead and made `doctor` warn
|
|
758
|
+
"recorded native process is no longer running" against a live session. The probe now uses
|
|
759
|
+
`OpenProcess` plus `WaitForSingleObject`.
|
|
760
|
+
- Native Designer snapshots return component coordinates again. `GetLocation` is a property
|
|
761
|
+
on current Xpedition Standard, not a method, so calling it yielded the point's default
|
|
762
|
+
member and every `x`/`y` came back as null.
|
|
763
|
+
- A native schematic placement whose reference-designator assignment fails now reports the
|
|
764
|
+
symbol it left on the sheet — `orphan_placed` with library, device, symbol and coordinates —
|
|
765
|
+
instead of failing silently with the instance still present. The API exposes no delete
|
|
766
|
+
entry point, so the orphan has to be removed in Designer.
|
|
767
|
+
- `doctor` reads `release_readiness` from its single source instead of restating it. The
|
|
768
|
+
hardcoded copy went stale the moment the smoke evidence changed, and `doctor` is what an
|
|
769
|
+
agent checks first.
|
|
770
|
+
- Native schematic reads resolve net names and connections. A Designer net carries no
|
|
771
|
+
`Name`; the name lives on the label attached to one of its segments
|
|
772
|
+
(`net.GetLabel(segment).TextString`), so reading `Name` reported every net on a live
|
|
773
|
+
sheet as unnamed and left `connections` empty.
|
|
774
|
+
- Native schematic placement no longer defaults the library to `MISC`. No such library
|
|
775
|
+
exists in a stock installation, so a missing parameter surfaced only as Designer error
|
|
776
|
+
2005 in the message window; the adapter now names the missing parameter instead.
|
|
777
|
+
- Native Designer reads return component pins again, and a schematic net can be labelled.
|
|
778
|
+
`GetConnections` and `GetSegments` are properties on current Xpedition Standard, not
|
|
779
|
+
methods; calling them raised DISP_E_PARAMNOTOPTIONAL inside a bare `except`, so every
|
|
780
|
+
snapshot reported `pins: []` and `connect` failed to find a pin by number. A shared
|
|
781
|
+
`_com_member` helper now reads either form, and a net that cannot carry its label fails
|
|
782
|
+
loudly instead of silently.
|
|
783
|
+
- `CO_E_SERVER_EXEC_FAILURE` from COM activation is reported as `E_BACKEND_UNAVAILABLE` with
|
|
784
|
+
a launcher hint. Xpedition `LocalServer32` entries point at binaries that need the release
|
|
785
|
+
environment established by the launcher in `common/win64/bin`, which COM activation skips.
|
|
786
|
+
- Native schematic reads no longer fail on every real design. `normalise_project` required a
|
|
787
|
+
reference designator on every component and a name on every net, which is right for an
|
|
788
|
+
authored project file but wrong for observed data: a live schematic always carries ground,
|
|
789
|
+
power, port and border symbols that have none, and a single one of them made `design
|
|
790
|
+
snapshot` and all nine `schematic *` commands return `E_PROJECT_INVALID`. Observed data now
|
|
791
|
+
separates those out and records a count under `metadata.unnamed`; authored files stay
|
|
792
|
+
strict.
|
|
793
|
+
|
|
794
|
+
[Unreleased]: https://github.com/fatecannotbealtered/xpedition-cli/compare/v1.0.0...HEAD
|
|
795
|
+
[1.0.0]: https://github.com/fatecannotbealtered/xpedition-cli/releases/tag/v1.0.0
|