@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.
Files changed (64) hide show
  1. package/.agent/AGENT.md +59 -0
  2. package/.agent/AGENT_zh.md +59 -0
  3. package/.agent/CLI-SPEC.md +1073 -0
  4. package/.agent/CLI-SPEC_zh.md +891 -0
  5. package/.agent/SEC-SPEC.md +158 -0
  6. package/.agent/SEC-SPEC_zh.md +132 -0
  7. package/.agent/SKILL-SPEC.md +266 -0
  8. package/.agent/SKILL-SPEC_zh.md +221 -0
  9. package/.agent/SPEC_VERSION +1 -0
  10. package/AGENTS.md +34 -0
  11. package/AGENTS_zh.md +33 -0
  12. package/CHANGELOG.md +795 -0
  13. package/CODE_OF_CONDUCT.md +35 -0
  14. package/CODE_OF_CONDUCT_zh.md +35 -0
  15. package/CONTRIBUTING.md +50 -0
  16. package/CONTRIBUTING_zh.md +42 -0
  17. package/LICENSE +21 -0
  18. package/NOTICE.md +16 -0
  19. package/NOTICE_zh.md +13 -0
  20. package/README.md +200 -0
  21. package/README_zh.md +178 -0
  22. package/SECURITY.md +108 -0
  23. package/SECURITY_zh.md +83 -0
  24. package/docs/AGENT_HARDENING_EVIDENCE.md +102 -0
  25. package/docs/AGENT_READS.md +74 -0
  26. package/docs/AGENT_READS_METRICS.json +216 -0
  27. package/docs/AGENT_READS_VALIDATION.json +13 -0
  28. package/docs/API_INVENTORY_BINDING_VALIDATION.json +16 -0
  29. package/docs/API_INVENTORY_DESIGN.md +90 -0
  30. package/docs/API_INVENTORY_REVIEW.md +59 -0
  31. package/docs/API_INVENTORY_VALIDATION.json +29 -0
  32. package/docs/API_INVENTORY_WINDOWS_VALIDATION.json +29 -0
  33. package/docs/COMPATIBILITY.md +499 -0
  34. package/docs/CONFIRMATION_CONCURRENCY_VALIDATION.json +33 -0
  35. package/docs/DIAGNOSTIC_BOUNDARIES.md +33 -0
  36. package/docs/DIAGNOSTIC_BOUNDARIES_VALIDATION.json +12 -0
  37. package/docs/E2E.md +445 -0
  38. package/docs/EVALS.md +134 -0
  39. package/docs/MCP.md +20 -0
  40. package/docs/NATIVE_ADAPTER.md +141 -0
  41. package/docs/OPEN_SOURCE_CHECKLIST.md +61 -0
  42. package/docs/OPEN_SOURCE_CHECKLIST_zh.md +61 -0
  43. package/docs/PIN_WORKFLOW_VALIDATION.json +28 -0
  44. package/docs/PLACEMENT_TASKS.md +99 -0
  45. package/docs/PLACEMENT_TASKS_VALIDATION.json +36 -0
  46. package/docs/REFERENCE_ADOPTION.md +67 -0
  47. package/package.json +48 -0
  48. package/scripts/run.js +46 -0
  49. package/skills/xpedition-cli/SKILL.md +300 -0
  50. package/skills/xpedition-cli/reference/agent-hardening.md +58 -0
  51. package/skills/xpedition-cli/reference/api-inventory.md +58 -0
  52. package/skills/xpedition-cli/reference/confirmation-safety.md +55 -0
  53. package/skills/xpedition-cli/test-prompts.json +62 -0
  54. package/skills/xpedition-pcb/SKILL.md +244 -0
  55. package/skills/xpedition-pcb/reference/fabrication.md +26 -0
  56. package/skills/xpedition-pcb/reference/hand-routing.md +33 -0
  57. package/skills/xpedition-pcb/reference/pcb-conventions.md +162 -0
  58. package/skills/xpedition-pcb/reference/placement-tasks.md +28 -0
  59. package/skills/xpedition-pcb/test-prompts.json +62 -0
  60. package/skills/xpedition-schematic/SKILL.md +244 -0
  61. package/skills/xpedition-schematic/reference/pin-assignment.md +61 -0
  62. package/skills/xpedition-schematic/reference/schematic-conventions.md +306 -0
  63. package/skills/xpedition-schematic/reference/schematic-design-format.md +219 -0
  64. package/skills/xpedition-schematic/test-prompts.json +52 -0
@@ -0,0 +1,141 @@
1
+ # Native Xpedition adapter
2
+
3
+ The repository includes an opt-in adapter for the public Xpedition PCB
4
+ automation interface. It uses the `MGCPCB.ExpeditionPCBApplication` and
5
+ `MGCPCBAutomationLicensing.Application` COM classes documented by the
6
+ installation's own automation examples. The adapter never edits Xpedition
7
+ private databases and does not bypass licensing.
8
+
9
+ ## Install and configure
10
+
11
+ Install the optional Windows dependency from the checkout:
12
+
13
+ ```powershell
14
+ python -m pip install -e ".[native]"
15
+ ```
16
+
17
+ `xpedition-native-adapter` is installed as a console entry point. The CLI
18
+ discovers it automatically when it is on `PATH`; `XPEDITION_NATIVE_COMMAND`
19
+ can be set to an explicit adapter executable when several installations are
20
+ present. Set `XPEDITION_SDD_HOME` when the installation cannot be found from
21
+ `SDD_HOME` or the `MGLS_LICENSE_FILE` location.
22
+
23
+ The Xpedition automation classes must be registered by the product's official
24
+ post-install step. If `xpedition-cli doctor` reports that COM automation is
25
+ not registered, first try the current-user helper (no elevation required). The
26
+ `scripts/` helpers ship in neither the wheel nor the npm package, so run them from
27
+ a clone of this repository:
28
+
29
+ ```powershell
30
+ # Substitute the SDD_HOME of the installed release, for example
31
+ # D:\Xpedition\home\XPED2604\SDD_HOME
32
+ $env:XPEDITION_SDD_HOME = "<install>\home\<release>\SDD_HOME"
33
+ powershell -ExecutionPolicy Bypass -File .\scripts\register-xpedition-user.ps1
34
+ ```
35
+
36
+ If the current-user registration is rejected by the local policy, run
37
+ `scripts/register-xpedition.ps1` from the clone in an elevated PowerShell. The
38
+ helper then invokes the installation's own `registrator.exe`:
39
+
40
+ ```powershell
41
+ $env:SDD_HOME = "<install>\home\<release>\SDD_HOME"
42
+ $env:SDD_PLATFORM = "win64"
43
+ $env:SDD_VERSION = "<release>"
44
+ Set-Location "$env:SDD_HOME\..\win64"
45
+ & "$env:SDD_HOME\common\win64\_bin\registrator.exe" "-version=$env:SDD_VERSION"
46
+ ```
47
+
48
+ Use the paths for the installed release. A successful registration is visible
49
+ without opening a project:
50
+
51
+ ```powershell
52
+ xpedition-cli doctor --compact
53
+ xpedition-cli system license --compact
54
+ ```
55
+
56
+ The CLI keeps the native status unavailable until both the adapter and the
57
+ COM registration are present. It reports license failures as `E_AUTH` and
58
+ does not claim that a license is valid merely because a license file path is
59
+ configured.
60
+
61
+ ## Adapter protocol
62
+
63
+ The adapter receives one JSON object on stdin and returns one CLI envelope on
64
+ stdout. Diagnostics belong on stderr:
65
+
66
+ ```json
67
+ {"method":"health","params":{}}
68
+ ```
69
+
70
+ ```json
71
+ {"ok":true,"schema_version":"1.0","data":{"ready":true},"meta":{"duration_ms":0}}
72
+ ```
73
+
74
+ The current bridge implements `health`, `start`, `attach`, `open`,
75
+ `snapshot`, `save`, `close`, controlled component placement/move and
76
+ schematic net operations used by `apply_changeset`, and the project-level
77
+ methods behind the guarded commands: `clone_project`, `draw`, `show`,
78
+ `verify`, `export_pdf`, `package`, `library_import`, `kicad_import` (every KiCad
79
+ `.pretty` footprint library as a cell partition, through the stock HKP converters;
80
+ `library kicad-import`), `pcb_create` (JobWizard's command line),
81
+ `forward_annotate` (Layout's Project Integration), `board_outline` (rounded corners
82
+ through the points array), `mounting_holes` (`PutMountingHoleEx`), `arrange_components`,
83
+ `placement_batch` (`pcb placement`: the selected parts previewed, then moved one at a
84
+ time with the placement DRC on and each read back), `show_board` (`pcb show`: the board
85
+ window to the front under a display scheme, fitted, optionally captured to a PNG),
86
+ `plane_pour` (`bRouteObstruct` false, so the copper flows around traces), `route_board`
87
+ (`LayerSelect` for the inner layers; a second round after the planes regenerate),
88
+ `net_rules` (a net class and its trace widths through the `ConstraintsAuto` server, then
89
+ `ProjectIntegration.SynchCES`), `render_board` (the board's geometry drawn to a PNG by
90
+ `xpedition_cli.board_render`), `board_geometry` (the same data as JSON), `hand_route`
91
+ (`PutTrace` / `PutVia` where the person says), `unroute_nets` (by net, all, or one item
92
+ at a point), `move_component` (with the placement DRC on), `tidy_labels` (silkscreen
93
+ designators moved beside their parts), `batch_drc` and `manufacturing_output` (the ODB++ /
94
+ Gerber / NC drill dialogs with their setups patched while the board is closed, gathered
95
+ into a package folder). It
96
+ supports the PCB `MGCPCB.ExpeditionPCBApplication` and schematic
97
+ `Viewdraw.Application` COM classes. The bridge attaches to an already running
98
+ Xpedition process when possible; otherwise `start` or `open` creates one
99
+ through the launcher. Layout's own questions while a board opens (a stale lock,
100
+ database recovery, the offer to forward-annotate) are answered from a helper
101
+ thread through UI Automation, which needs the optional `pywinauto` package (the
102
+ `native` extra, installed from a checkout as above or with
103
+ `python -m pip install "xpedition-cli[native] @ git+https://github.com/fatecannotbealtered/xpedition-cli"`);
104
+ without it those prompts wait for a person.
105
+
106
+ Prefer starting through the product launcher rather than through COM. Every
107
+ Xpedition `LocalServer32` entry points at the real binary under
108
+ `SDD_HOME/<product>/win64/bin`, and those binaries need the release environment
109
+ that the small launcher in `SDD_HOME/common/win64/bin` establishes. COM
110
+ activation bypasses the launcher, so `CoCreateInstance` fails with
111
+ `CO_E_SERVER_EXEC_FAILURE` (0x80080005); `start` therefore launches the launcher
112
+ binary and then attaches. The adapter maps that COM status to
113
+ `E_BACKEND_UNAVAILABLE` with a launcher hint instead of a bare server error.
114
+
115
+ All document reads request an automation license token using the same
116
+ `Validate(0)` → `GetToken` → `Validate(token)` sequence as the vendor
117
+ examples. A failed token exchange is returned as a structured error.
118
+
119
+ ## Placement is not transactional
120
+
121
+ `AddPartInstance` puts the symbol on the sheet before the reference designator
122
+ is assigned, and neither the component nor the block exposes a delete entry
123
+ point in this API. When the refdes assignment fails — a power or ground symbol
124
+ rejects one outright — the instance cannot be rolled back. The adapter reports
125
+ that case with `orphan_placed`, the library/device/symbol it came from and the
126
+ coordinates, so the caller can remove it in Designer; it never reports the
127
+ operation as applied.
128
+
129
+ ## End-to-end evidence
130
+
131
+ Native E2E still requires a disposable project in a licensed Windows
132
+ environment. The first smoke run places `R1` and `C1`, creates the `3V3` net,
133
+ connects `R1.1` to `C1.1`, saves, closes, reopens and compares the reread
134
+ snapshot; it is recorded in [`E2E.md`](E2E.md), together with the runs that took
135
+ a project from an empty schematic to a fabrication package.
136
+
137
+ Attach, snapshot, placement and coordinate read-back have each been verified
138
+ against a running Designer session. The smoke loop itself passed on 2026-09-12
139
+ against a hand-built library: the installation ships no component library, so the
140
+ `R` and `C` symbols were authored into a writable copy of its empty template
141
+ library — see [`COMPATIBILITY.md`](COMPATIBILITY.md).
@@ -0,0 +1,61 @@
1
+ # Open-Source Checklist
2
+
3
+ [English](OPEN_SOURCE_CHECKLIST.md) | [中文](OPEN_SOURCE_CHECKLIST_zh.md)
4
+
5
+ Run through this gate **before every release** of `xpedition-cli` (before its `vX.Y.Z` tag is pushed). It is a security and quality checkpoint, not documentation — every box must be ticked (or consciously waived with a note) for the commit being released; the boxes in this file stay blank as the template for the next release. The repository is already public, so a secret pushed to it cannot be un-leaked: the Secrets checks apply to every push, not only to a release.
6
+
7
+ ## Secrets
8
+
9
+ - [ ] No credentials, tokens, API keys, or passwords anywhere in the working tree.
10
+ - [ ] No secrets in **git history** — checked with a scanner (e.g. `gitleaks detect`, `git log -p | grep`); if found, the history is rewritten or the repo re-created, not just deleted from `HEAD`.
11
+ - [ ] No internal hostnames, private IPs, internal URLs, or employer-internal identifiers in code, config, or comments.
12
+ - [ ] Test fixtures and recorded responses contain only synthetic / redacted data — no real account data, no real tokens.
13
+ - [ ] `.env`, `*.local`, credential files, and `~/.xpedition-cli/` artifacts are listed in `.gitignore` and confirmed untracked (`git status --ignored`).
14
+ - [ ] Credentials are stored encrypted at rest (OS keyring or encrypted envelope, `0600`), never plaintext in the config file.
15
+
16
+ ## Docs
17
+
18
+ - [ ] `README.md` follows the REPO-SPEC §2 skeleton (Title/badges → Agent Install → What It Does → Capabilities → Agent Workflow → Machine Contract → Configuration → Project Structure → Development → Links).
19
+ - [ ] `README.md` and `README_zh.md` are **content-synced** — same sections, same commands, same placeholders resolved to the same real values.
20
+ - [ ] `CHANGELOG.md` exists, uses Keep a Changelog format, and has an `## [Unreleased]` section on top.
21
+ - [ ] `LICENSE` is present, the license is chosen deliberately (default MIT), and the year and copyright holder are filled in (`2026`, `Sean Guo <guosong6886@gmail.com>`).
22
+ - [ ] Install blocks are copy-paste-runnable and use the real published `@fateforge/xpedition-cli` / `fatecannotbealtered/xpedition-cli`.
23
+
24
+ ## Governance
25
+
26
+ - [ ] `SECURITY.md` is present with a working disclosure channel (`guosong6886@gmail.com`) and a supported-versions table.
27
+ - [ ] `CONTRIBUTING.md` is present (env setup, branch/commit, test, PR flow).
28
+ - [ ] `CODE_OF_CONDUCT.md` is present (Contributor Covenant) if the project accepts external contributions.
29
+ - [ ] If `xpedition-cli` wraps a third-party product (Siemens Xpedition), `NOTICE.md` carries the trademark / non-affiliation notice and `docs/COMPATIBILITY.md` lists the verified backend version matrix.
30
+
31
+ ## Build / CI
32
+
33
+ - [ ] CI (`.github/workflows/ci.yml`) is **green** on the commit being pushed.
34
+ - [ ] CI **enforces** lint and tests — a red lint or failing test blocks merge (not advisory-only).
35
+ - [ ] Functional Contract Coverage is 100%: every public behavior documented in README, Skill, `reference`, `--help`, `context`, `doctor`, or `changelog` has automated command-level tests. (`update` is not shipped in this phase.)
36
+ - [ ] `reference.release_readiness.level` is accurate: `stable` has FCC 100%, mock upstream/contract tests, and recorded live smoke/E2E evidence; missing live evidence is `beta`; missing command-level coverage is `unpublishable`.
37
+ - [ ] `doctor` includes a `release_readiness` check whose status matches the declared release level.
38
+ - [ ] The formatter config is committed (ruff / golangci-lint / prettier, by language) and CI runs the format check.
39
+ - [ ] No build artifacts, caches, venvs, or IDE config are committed (covered by `.gitignore`).
40
+
41
+ ## Distribution
42
+
43
+ - [ ] `package.json` `version` matches the git tag being released (`vX.Y.Z` ↔ `X.Y.Z`); `release.yml` guards this and fails on mismatch.
44
+ - [ ] The binary itself (`bin/`, `*.exe`, `dist/`) is **not committed** — it is produced by CI and gitignored.
45
+ - [ ] GitHub Release artifacts ship a `checksums.txt`; any future standalone binary install/update path must verify the checksum and **fail closed** on mismatch or missing entries.
46
+ - [ ] Release pipeline signs `checksums.txt` with Sigstore/Cosign keyless signing, publishes the bundle, and any future standalone install/update path reports signature verification separately from checksum verification.
47
+ - [ ] npm distribution publishes the main wrapper package plus every supported OS/CPU platform package from CI-built artifacts, with `npm publish --provenance`.
48
+ - [ ] The version number has a single source of truth; the runtime `changelog` command and the GitHub Release body are derived from `CHANGELOG.md`, not hand-copied.
49
+
50
+ ## AI-native
51
+
52
+ - [ ] Root `AGENTS.md` is present and points to `.agent/AGENT.md`.
53
+ - [ ] `.agent/{AGENT,CLI-SPEC,SKILL-SPEC,SEC-SPEC}.md` specs are present; the shared repo skeleton standard is referenced from `ai-native-cli-spec/REPO-SPEC.md`.
54
+ - [ ] `skills/xpedition-cli/SKILL.md` (the entry Skill), `skills/xpedition-schematic/SKILL.md` and `skills/xpedition-pcb/SKILL.md` are present; each frontmatter includes `version`, `license: MIT`, `user-invocable: true`, and `metadata.requires.min_version` matching the CLI version; both domain Skills also declare `metadata.requires.skills: ["xpedition-cli"]` and open by reading `../xpedition-cli/SKILL.md`, stopping at a `STOP CHECKPOINT` when that file is missing.
55
+ - [ ] Each Skill's `description` says what it does not cover and which Skill does, and the entry Skill names the file of each domain Skill it hands work to.
56
+ - [ ] The entry `SKILL.md` includes `When to use`, `Do not use`, `First Step`, agent defaults, JSON contract, write recipe or explicit read-only boundary, `STOP CHECKPOINT`, error decision tree, security boundary, an honest update boundary, and eval scenarios. Each domain Skill carries its own triggers, `STOP CHECKPOINT`s, playbooks and eval scenarios, and points at the entry Skill for the rest.
57
+ - [ ] Each Skill's `test-prompts.json` is present and valid JSON; together they cover fresh-agent read, write safety or read-only boundary, permission boundary, `_untrusted` handling, and the package-update boundary.
58
+ - [ ] Self-update is explicitly N/A for this phase. If a future release adds a bare `update`, it must sync every Skill directory under `skills/` or return `skill_sync_command` and report `stage` + `current_version` + `binary_replaced` + `skill_sync_status` on failure or interruption.
59
+ - [ ] `xpedition-cli reference`, `xpedition-cli context`, and `xpedition-cli doctor` run and emit valid JSON envelopes — an agent can self-onboard from a clean checkout.
60
+ - [ ] `xpedition-cli reference` exposes `release_readiness`, and `xpedition-cli doctor` reports the matching check.
61
+ - [ ] The risk tier in `SECURITY.md` matches `reference.risk_tier` (`T2`), classified under `.agent/SEC-SPEC.md`.
@@ -0,0 +1,61 @@
1
+ # 开源检查清单
2
+
3
+ [English](OPEN_SOURCE_CHECKLIST.md) | [中文](OPEN_SOURCE_CHECKLIST_zh.md)
4
+
5
+ `xpedition-cli` **每次发布之前**(推送 `vX.Y.Z` tag 之前)逐项走查。这是一道安全与质量关卡,不是文档 —— 待发布的提交必须勾选每一项(或明确写明理由后豁免);本文件中的复选框保持空白,作为下一次发布的模板。仓库已经公开,推送上去的密钥无法收回:“密钥”一节的检查适用于每一次推送,而不只是发布。
6
+
7
+ ## 密钥
8
+
9
+ - [ ] 工作区任何位置都没有凭据、token、API key 或密码。
10
+ - [ ] **git 历史**中没有密钥 —— 已用扫描工具检查(如 `gitleaks detect`、`git log -p | grep`);若发现,需重写历史或重建仓库,而不是只从 `HEAD` 删除。
11
+ - [ ] 代码、配置、注释中没有内部主机名、内网 IP、内部 URL 或公司内部标识符。
12
+ - [ ] 测试夹具和录制的响应只含合成 / 脱敏数据 —— 没有真实账户数据,没有真实 token。
13
+ - [ ] `.env`、`*.local`、凭据文件以及 `~/.xpedition-cli/` 产物已列入 `.gitignore` 并确认未被跟踪(`git status --ignored`)。
14
+ - [ ] 凭据静态加密存储(操作系统钥匙串或加密信封,`0600`),绝不以明文写入配置文件。
15
+
16
+ ## 文档
17
+
18
+ - [ ] `README.md` 遵循 REPO-SPEC §2 骨架(标题/徽章 → Agent 安装 → 它做什么 → 能力 → Agent 工作流 → 机器契约 → 配置 → 项目结构 → 开发 → 链接)。
19
+ - [ ] `README.md` 与 `README_zh.md` **内容同步** —— 章节一致、命令一致、占位符解析为相同的真实值。
20
+ - [ ] `CHANGELOG.md` 存在,使用 Keep a Changelog 格式,顶部有 `## [Unreleased]` 小节。
21
+ - [ ] `LICENSE` 存在,许可证经过有意选择(默认 MIT),年份和版权方已填写(`2026`、`Sean Guo <guosong6886@gmail.com>`)。
22
+ - [ ] 安装块可直接复制运行,使用真实已发布的 `@fateforge/xpedition-cli` / `fatecannotbealtered/xpedition-cli`。
23
+
24
+ ## 治理
25
+
26
+ - [ ] `SECURITY.md` 存在,含可用的披露渠道(`guosong6886@gmail.com`)和受支持版本表。
27
+ - [ ] `CONTRIBUTING.md` 存在(环境搭建、分支/提交、测试、PR 流程)。
28
+ - [ ] 若项目接受外部贡献,`CODE_OF_CONDUCT.md` 存在(Contributor Covenant)。
29
+ - [ ] 若 `xpedition-cli` 包装第三方产品(Siemens Xpedition),`NOTICE.md` 载明商标 / 非隶属声明,且 `docs/COMPATIBILITY.md` 列出已验证的后端版本矩阵。
30
+
31
+ ## 构建 / CI
32
+
33
+ - [ ] 待推送的提交上 CI(`.github/workflows/ci.yml`)为**绿色**。
34
+ - [ ] CI **强制**执行 lint 和测试 —— lint 失败或测试失败会阻断合并(不仅仅是提示性的)。
35
+ - [ ] 功能契约覆盖率为 100%:README、Skill、`reference`、`--help`、`context`、`doctor` 或 `changelog` 中记录的每个公开行为,都有自动化命令级测试。(本阶段不提供 `update`。)
36
+ - [ ] `reference.release_readiness.level` 准确:`stable` 具备 FCC 100%、mock upstream / contract tests 和真实环境 smoke/E2E 记录;缺真实证据为 `beta`;缺命令级覆盖为 `unpublishable`。
37
+ - [ ] `doctor` 包含 `release_readiness` 检查,且状态与声明的发布等级一致。
38
+ - [ ] 格式化工具配置已提交(按语言:ruff / golangci-lint / prettier),且 CI 运行格式校验。
39
+ - [ ] 没有提交构建产物、缓存、虚拟环境或 IDE 配置(已由 `.gitignore` 覆盖)。
40
+
41
+ ## 分发
42
+
43
+ - [ ] `package.json` 的 `version` 与待发布的 git tag 一致(`vX.Y.Z` ↔ `X.Y.Z`);`release.yml` 对此做守卫,不一致即失败。
44
+ - [ ] 二进制本身(`bin/`、`*.exe`、`dist/`)**不提交** —— 由 CI 产出并被 gitignore。
45
+ - [ ] GitHub Release 发布产物附带 `checksums.txt`;未来的 standalone 二进制安装/更新路径必须校验 checksum,且在不匹配或缺少条目时**失败关闭**。
46
+ - [ ] release pipeline 使用 Sigstore/Cosign keyless 签署 `checksums.txt`,发布 bundle;未来的 standalone 安装/更新路径必须把签名验证状态与 checksum 校验分开报告。
47
+ - [ ] npm 分发从 CI 构建产物发布主 wrapper 包和每个受支持 OS/CPU 的平台包,并使用 `npm publish --provenance`。
48
+ - [ ] 版本号有唯一真相来源;运行时 `changelog` 命令和 GitHub Release 正文均派生自 `CHANGELOG.md`,而非手工复制。
49
+
50
+ ## AI 原生
51
+
52
+ - [ ] 根目录 `AGENTS.md` 存在并指向 `.agent/AGENT.md`。
53
+ - [ ] `.agent/{AGENT,CLI-SPEC,SKILL-SPEC,SEC-SPEC}.md` 规格文件齐全;共享仓库骨架标准引用 `ai-native-cli-spec/REPO-SPEC.md`。
54
+ - [ ] `skills/xpedition-cli/SKILL.md`(入口 Skill)、`skills/xpedition-schematic/SKILL.md` 与 `skills/xpedition-pcb/SKILL.md` 存在;各自的 frontmatter 包含 `version`、`license: MIT`、`user-invocable: true`,且 `metadata.requires.min_version` 匹配 CLI 版本;两个领域 Skill 另外都声明 `metadata.requires.skills: ["xpedition-cli"]`,正文开头先读 `../xpedition-cli/SKILL.md`,该文件不存在时停在 `STOP CHECKPOINT`。
55
+ - [ ] 每个 Skill 的 `description` 写清不负责什么、该找哪个 Skill;入口 Skill 写明它把工作交给的每个领域 Skill 的文件。
56
+ - [ ] 入口 `SKILL.md` 包含 `When to use`、`Do not use`、`First Step`、Agent 默认规则、JSON contract、写操作配方或明确只读边界、`STOP CHECKPOINT`、错误决策树、安全边界、诚实的更新边界和评估场景。每个领域 Skill 带自己的触发条件、`STOP CHECKPOINT`、剧本和评估场景,其余部分指向入口 Skill。
57
+ - [ ] 每个 Skill 的 `test-prompts.json` 存在、JSON 合法,合起来覆盖 fresh-agent read、写操作安全或只读边界、权限边界、`_untrusted` 处理和包管理器更新边界。
58
+ - [ ] 本阶段自更新明确标记为 N/A。未来若增加裸 `update`,必须同步 `skills/` 下的每个 Skill 目录或返回 `skill_sync_command`,并在失败/中断时报告 `stage` + `current_version` + `binary_replaced` + `skill_sync_status`。
59
+ - [ ] `xpedition-cli reference`、`xpedition-cli context`、`xpedition-cli doctor` 可运行并输出合法的 JSON 信封 —— 代理能从干净的检出自助上手。
60
+ - [ ] `xpedition-cli reference` 暴露 `release_readiness`,`xpedition-cli doctor` 报告匹配的检查项。
61
+ - [ ] `SECURITY.md` 中的风险等级与 `reference.risk_tier` 一致(`T2`),分级依据 `.agent/SEC-SPEC.md`。
@@ -0,0 +1,28 @@
1
+ {
2
+ "baseline": "d42b226a5b1812b2937ded096bf618b8692c4f9a",
3
+ "run_id": "35296848583",
4
+ "platform": "Linux-6.17.0-1022-azure-x86_64-with-glibc2.39",
5
+ "before": {
6
+ "tests": 2,
7
+ "failures": 2,
8
+ "errors": 0,
9
+ "skipped": 0
10
+ },
11
+ "full_suite": {
12
+ "tests": 261,
13
+ "failures": 0,
14
+ "errors": 0,
15
+ "skipped": 0
16
+ },
17
+ "ruff": "passed",
18
+ "version_sync": "passed",
19
+ "contract_local_only": "passed",
20
+ "native_xpedition_executed": false,
21
+ "scope": "offline comparison of supplied observations; not native execution",
22
+ "source_sha256": {
23
+ "xpedition_cli/pin_assignment.py": "39dc1c337897a1c9dc7fc07dc3b9d94c7d2e6b8b12eff16199d319fb790cf7cb",
24
+ "xpedition_cli/pin_assignment_contract.py": "baacde879cd5b69f2a2802309c67084d87fbd5066d9a372c40556460c8cd0348",
25
+ "xpedition_cli/main.py": "a799454b993578d0088600fa03f2fedddcc5c925cb9e72fa75608b502f30a1dc",
26
+ "xpedition_cli/reference_data.py": "0c62f966691c00c8ae79b31e80901bf91353c38bef78e8558bc5243db0465a8e"
27
+ }
28
+ }
@@ -0,0 +1,99 @@
1
+ # Selected-origin placement tasks (native smoke partial)
2
+
3
+ ## Scope and public references
4
+
5
+ This change turns familiar selection/translate/rotate/align/distribute workflows
6
+ into one deterministic task, not a new auto-placer or a UI click macro. Its baseline
7
+ included confirmation concurrency PR #7 (`8e40dc910b09e5f0ca58b975739bc4bba7cef031`)
8
+ but not PRs #4–#6; all of them, and this change (PR #10), were merged on 2026-09-18.
9
+
10
+ The native binding cross-checks the published API surface in
11
+ [SiemensEDA_Python_Interface](https://github.com/EdgarMerger/SiemensEDA_Python_Interface/blob/main/xpedition_layout/layout_ifc.py),
12
+ blob `8d70329e7a838328affac2d62a53a3f46a34eb39`: `IMGCPCBComponent`,
13
+ `GetPositionX/Y`, `GetOrientation`, `Anchor`, `FixLock`, `UniqueId`, `Side`,
14
+ `UnPlace`, and `Place(x,y,orientation,bTop,eFixType,eUnit,eAngleUnit)`.
15
+ The repository's Layout directory declares MIT. No generated interface, external
16
+ implementation, dependency, or bundled proprietary manual was copied here.
17
+ The community type hints are not authoritative types; notably an integer COM
18
+ Anchor is annotated as a string. We validate the actual observations instead.
19
+
20
+ [XACT](https://github.com/RedHeadIvan/XpeditionAdvancedCapabilityToolkit)
21
+ (tree `a1945aac520cc3c7983c54a49bd6013950533ff5`, LabelAligner and AddCluster)
22
+ informed the task-level emphasis on explicit selections and local edits. Its
23
+ implementation was not copied. We did not adopt DRC-disabling batch patterns,
24
+ unqualified transactions, global selection, or automatic pop-up acceptance.
25
+ These references are evidence for API/task design, not proof of compatibility
26
+ with XPED2604 or any licensed installation.
27
+
28
+ ## Two entry points
29
+
30
+ `pcb placement-plan --file TASK --input OBSERVATIONS` computes targets offline.
31
+ `pcb placement --file TASK --backend native_xpedition --project BOARD --dry-run`
32
+ reads selected native placements and previews; repeat with the returned `--confirm`
33
+ token to execute. The new native path requires an already-running Layout session.
34
+ Use the installed binary's `reference` to discover exact input JSON Schemas,
35
+ required fields, bounds, preconditions and examples. The two example files in
36
+ `examples/placement-{task,observations}.json` exercise only offline planning.
37
+
38
+ Each task selects explicit unique reference designators. Coordinates are component
39
+ CELL ORIGINS in board millimetres, on either board side, not bounding-box centres.
40
+ Rotation is counter-clockwise in board coordinates around an explicit origin;
41
+ orientation changes with it. Alignment fixes one coordinate to a selected anchor;
42
+ distribution uses explicit selection order and evenly spaced origins, not equal
43
+ body clearances. Steps calculate a final target; only one final move per changed
44
+ part is executed. A protected part may be an unchanged anchor, never a moved target.
45
+
46
+ `Anchor` values 1/2/3 and ANY nonzero `FixLock` are conservatively protected.
47
+ Unknown identity, side, units, placement or protection state fails closed. We do
48
+ not interpret every FixLock bit, override a lock, support embedded/flex-specific
49
+ placement layers, flip sides or place previously unplaced components.
50
+
51
+ ## Execution and failure semantics
52
+
53
+ Preview never calls UnPlace, Place or Save. Confirm re-reads the preview and binds
54
+ the selected identities, positions, angles, sides, protection and semantic task
55
+ into the token. The adapter checks that digest again under a bounded sidecar lock
56
+ shared by this batch entry point in the same configuration directory. Other CLI
57
+ commands, other config directories, old versions, humans and external tools do
58
+ not cooperate. This is NOT a global engineering lock or a full-board revision.
59
+
60
+ The batch explicitly enables native placement DRC and requires read-back of that
61
+ setting before moving anything. Parts execute serially in selection order; after
62
+ each move and at the end, positions and identities are compared. The previous DRC
63
+ setting is restored and checked. Save is requested once only after all selected
64
+ targets verify. The CLI also checks the returned observed targets, not only a
65
+ `verification.valid` boolean. Numeric tolerance is 1e-6 mm/degrees, not a clearance.
66
+ Native quantization outside that tolerance correctly reports a mismatch.
67
+
68
+ On refusal or uncertainty, stop. Earlier moves can remain; the current part can
69
+ be unplaced. No blind rollback, all-or-none guarantee, or save of partial batches
70
+ is attempted. Results account for every selected item as unchanged, verified,
71
+ not_attempted, outcome_unknown or verification_failed. Execution/save failures
72
+ are non-retryable; transport failure after submit is explicitly outcome unknown.
73
+ Inspect the live board before another preview. There is not yet a durable operation
74
+ journal or restart recovery. Save/close/reopen durability has one licensed record, the
75
+ 2026-09-19 smoke in [`E2E.md`](E2E.md).
76
+
77
+ No routing deletion/repair or unselected placement is requested. This is not proof
78
+ that Xpedition made no incidental changes; routing topology and whole-board DRC
79
+ remain unchecked. Component swaps may fail because sequential placement sees the
80
+ other part still in the target position; DRC is not disabled to make them pass.
81
+
82
+ ## Evidence and remaining native gate
83
+
84
+ Pure planning and fake COM-object tests cover transforms, strict input bounds,
85
+ protection, bottom-side placement, no preview mutation, one collection pass,
86
+ per-item verification, refusals, silent failure, DRC cleanup and save uncertainty.
87
+ CLI tests exercise preview/confirm, stale state, response mismatch, partial results,
88
+ request counts and machine discovery. CI executes no licensed Xpedition.
89
+
90
+ A licensed smoke on a disposable board (2026-09-19, [`E2E.md`](E2E.md)) covered
91
+ top-side parts, a `FixLock` part refused as a moved target, unknown components,
92
+ a stale preview, save/close/reopen read-back and a full DRC with no placement hazard.
93
+ Still not run on a licensed board: bottom-side parts (`Side` is read-only and this
94
+ tool does not flip sides), the `Anchor` states and other `FixLock` values, a
95
+ deliberate refused move after a prior success, DRC-setting restoration, a save
96
+ failure, and a check of unselected parts and routing afterwards (that board was
97
+ unrouted). The first confirmed run applied part of a task and then reported it
98
+ incomplete; its per-item report was lost, later runs did not reproduce it, and the
99
+ cause is unknown. Runtime readiness stays beta until that native evidence exists.
@@ -0,0 +1,36 @@
1
+ {
2
+ "baseline": "8e40dc910b09e5f0ca58b975739bc4bba7cef031",
3
+ "dependency_pr": 7,
4
+ "run_id": "35298684673",
5
+ "python": "3.12.14 (main, Aug 13 2026, 02:47:42) [GCC 13.3.0]",
6
+ "platform": "Linux-6.17.0-1022-azure-x86_64-with-glibc2.39",
7
+ "baseline_selected": {
8
+ "tests": 3,
9
+ "failures": 3,
10
+ "errors": 0,
11
+ "skipped": 0
12
+ },
13
+ "full_suite": {
14
+ "tests": 323,
15
+ "failures": 0,
16
+ "errors": 0,
17
+ "skipped": 0
18
+ },
19
+ "ruff": "passed",
20
+ "version_sync": "passed",
21
+ "contract_local_only": "passed",
22
+ "linux_pyinstaller_offline_smoke": "passed",
23
+ "native_xpedition_executed": false,
24
+ "source_sha256": {
25
+ "xpedition_cli/native_placement.py": "17e4755448f5b84ace3178d467a80c344712afba76103ba73ca672200348b2ab",
26
+ "xpedition_cli/placement_contract.py": "9f3e683f4b999813df178d05562632279cadff4a888bf37c632b533dca6ab221",
27
+ "xpedition_cli/placement_command.py": "8b88867aa2af7ae00e70ab9b88f29430d506ac95ddfb0fa10cc50b052506a8fe",
28
+ "xpedition_cli/placement.py": "666f319f68c62d59209301f5432ad8db4eb3a46e7cbafae5418bb203151fb6d3",
29
+ "tests/test_native_placement.py": "6412c5f6e051fdf906585631a6229153f97f90ab5a1bfa75afe9107e1efabbfd",
30
+ "tests/test_placement.py": "7c682a59d8fe000a650d0c9654e21096e1d4bbbd4d06dd79da8a8aa65d0a4f65",
31
+ "tests/test_placement_cli.py": "cbbf719774c14fb85df21b142facba88590aace7e5b4925cc4d3bf263e2b75ef",
32
+ "xpedition_cli/main.py": "a0ed65de3a20c77a547316ce1b472ebdceba98ad982b5a500e559ca20efe9ef0",
33
+ "xpedition_cli/native_com_adapter.py": "5e5d0694ebc653f2d4da8575aa52a8500014a20b7559760a5f3f7014596a5cf9",
34
+ "xpedition_cli/reference_data.py": "abe1aed0bb52b875f2050eef33767f2d38cb528cb2dd9fa0c6094594680504af"
35
+ }
36
+ }
@@ -0,0 +1,67 @@
1
+ # Public-reference adoption and evidence boundaries
2
+
3
+ *Historical record: written for pull request #8 before it was merged on 2026-09-18;
4
+ kept as the design and evidence record. The current contract is
5
+ `xpedition-cli reference`.*
6
+
7
+ This work advances engineer-level task coverage without claiming an untested
8
+ Xpedition version behaves like someone else's installation. No third-party source
9
+ code, manuals, binaries or library assets are included by this change. New code
10
+ and fixtures are independently authored; links document task/API investigation,
11
+ not a blanket license to copy upstream code. Review date: 2026-09-18.
12
+
13
+ ## Evidence vocabulary
14
+
15
+ `public_example`: an upstream source demonstrates a task or API name.
16
+ `offline_tested`: our deterministic code is tested against saved/synthetic data.
17
+ `adapter_tested`: our adapter path is exercised with a simulated native object.
18
+ `licensed_run`: an identified target installation and disposable project were
19
+ actually used. These labels must never be silently promoted into each other.
20
+ Historical licensed evidence elsewhere in this repo does not validate new paths.
21
+
22
+ ## Adoption register
23
+
24
+ | Engineer task | Public reference | Our implementation / next gate |
25
+ |---|---|---|
26
+ | Assign pin nets from a table | XACT NetAssigner [1] | Offline plan and check implemented here; native mutation deliberately unavailable. |
27
+ | Select the right component and pin | XACT uses active selection and integer pin comparison [1] | Explicit refdes + exact string pin IDs; ambiguous/missing observations block. |
28
+ | Review effects on shared nets | XACT changes labels near pins [1] | Reassign is distinguished from connect/noop; bounded peer sample and total require isolation review. No promise of safe global rename. |
29
+ | Inspect available Designer APIs | SiemensEDA interface generator [2] | Candidate for local read-only type-library inventory; no new COM execution claimed here. |
30
+ | Batch native changes / transactions | EETB_2412 Constraint/SetPadEntry.vbs [3] | Investigate transaction and LockServer semantics on target installation; not an engineering write lock or proven rollback. |
31
+ | React to forward-annotation completion | XACT faReporter.js [4] | Candidate event/report source. Complete warnings and result provenance required; not a substitute for fresh state validation. |
32
+
33
+ [1] [XACT NetAssigner at a1945aa](https://github.com/RedHeadIvan/XpeditionAdvancedCapabilityToolkit/blob/a1945aac520cc3c7983c54a49bd6013950533ff5/NetAssigner/net_assigner.js)
34
+ ([blob 674e32f](https://api.github.com/repos/RedHeadIvan/XpeditionAdvancedCapabilityToolkit/git/blobs/674e32f4fb51c688ed66259a0cdc7cd51088a879)).
35
+ Its workflow motivates table-based assignment; no JavaScript, CSV library or UI code
36
+ was copied. Its active-selection, skipped-row, integer pin and success-reporting
37
+ behavior is not our safety contract. License clearance is required before any code
38
+ reuse; this change does not rely on such reuse.
39
+
40
+ [2] [SiemensEDA interface project at 54b3c3f](https://github.com/EdgarMerger/SiemensEDA_Python_Interface/tree/54b3c3f85d9fbcf10259705e5a3a11399794c12f).
41
+ The generator is a discovery reference, not authoritative typing for our installed
42
+ version. A type-library member does not establish a safe or supported CLI operation.
43
+
44
+ [3] [EETB batch/constraint example](https://github.com/Aragornian/EETB_2412/blob/main/Constraint/SetPadEntry.vbs).
45
+ Prior investigation only; this mutable link is NOT a pinned implementation input.
46
+ No transaction calls, DRC disabling or error suppression from it were adopted.
47
+
48
+ [4] [XACT report workflow at a1945aa](https://github.com/RedHeadIvan/XpeditionAdvancedCapabilityToolkit/blob/a1945aac520cc3c7983c54a49bd6013950533ff5/faReporter.js).
49
+ A future event implementation needs its own installation-specific tests.
50
+
51
+ ## Native integration gate
52
+
53
+ Before implementing/exposing pin mutations: verify actual typed pin identity,
54
+ component hierarchy, wire/label ownership and disconnection semantics; bind plans
55
+ to a freshly read target; serialize engineering writes; record partial/unknown
56
+ outcomes; compare requested postconditions and unaffected peers; save/close/reopen.
57
+ Do not map `reassign` to existing additive `connect` and assume the old net vanished.
58
+
59
+ ## Tests and review
60
+
61
+ Helper tests cover exact IDs, unknown and contradictory observations, duplicate
62
+ targets, stale preconditions, post-edit checks, paging and bounded peers, malformed
63
+ CSV/JSON and immutability. CLI tests reject native/write/output arguments before
64
+ file/backend access, preserve JSON/trust controls and exercise both new leaves.
65
+ The generated validation record records actual CI results. No native design is
66
+ opened by this work. PRs #4--#7 remain independent; combined-tree behavior must be
67
+ validated before release. Preserve all Unreleased notes when combining branches.
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "@fateforge/xpedition-cli",
3
+ "version": "1.0.0",
4
+ "description": "read, validate, preview, and apply controlled Xpedition design changes with mock-first verification",
5
+ "license": "MIT",
6
+ "author": "Sean Guo <guosong6886@gmail.com>",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/fatecannotbealtered/xpedition-cli.git"
10
+ },
11
+ "publishConfig": {
12
+ "access": "public"
13
+ },
14
+ "bin": {
15
+ "xpedition-cli": "scripts/run.js"
16
+ },
17
+ "scripts": {
18
+ "version": "node scripts/sync-version.js",
19
+ "check-version": "node scripts/check-version.js"
20
+ },
21
+ "optionalDependencies": {
22
+ "@fateforge/xpedition-cli-darwin-arm64": "1.0.0",
23
+ "@fateforge/xpedition-cli-darwin-x64": "1.0.0",
24
+ "@fateforge/xpedition-cli-linux-arm64": "1.0.0",
25
+ "@fateforge/xpedition-cli-linux-x64": "1.0.0",
26
+ "@fateforge/xpedition-cli-win32-arm64": "1.0.0",
27
+ "@fateforge/xpedition-cli-win32-x64": "1.0.0"
28
+ },
29
+ "files": [
30
+ "scripts/run.js",
31
+ "skills/",
32
+ "README.md",
33
+ "README_zh.md",
34
+ "*_zh.md",
35
+ "LICENSE",
36
+ "NOTICE.md",
37
+ "CHANGELOG.md",
38
+ "CONTRIBUTING.md",
39
+ "SECURITY.md",
40
+ "CODE_OF_CONDUCT.md",
41
+ "AGENTS.md",
42
+ ".agent/",
43
+ "docs/"
44
+ ],
45
+ "engines": {
46
+ "node": ">=16"
47
+ }
48
+ }
package/scripts/run.js ADDED
@@ -0,0 +1,46 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+
4
+ // Thin forwarder: exec the binary shipped by the npm platform package.
5
+ const { execFileSync } = require("child_process");
6
+ const path = require("path");
7
+
8
+ const rootPackage = require("../package.json");
9
+ const toolName = Object.keys(rootPackage.bin || {})[0] || "xpedition-cli";
10
+ const ext = process.platform === "win32" ? ".exe" : "";
11
+ const platformKey = `${process.platform}-${process.arch}`;
12
+ const platformPackage = `${rootPackage.name}-${platformKey}`;
13
+ const optionalDependencies = rootPackage.optionalDependencies || {};
14
+
15
+ if (!Object.prototype.hasOwnProperty.call(optionalDependencies, platformPackage)) {
16
+ console.error(
17
+ `${toolName} does not ship an npm platform package for ${platformKey}.\n` +
18
+ "Install a supported platform package or use the GitHub standalone binary."
19
+ );
20
+ process.exit(1);
21
+ }
22
+
23
+ let bin;
24
+ try {
25
+ const platformPackageJson = require.resolve(`${platformPackage}/package.json`);
26
+ bin = path.join(path.dirname(platformPackageJson), "bin", toolName + ext);
27
+ } catch {
28
+ console.error(
29
+ `${toolName} platform package ${platformPackage} is not installed.\n` +
30
+ "This usually means npm optional dependencies were omitted.\n" +
31
+ `Reinstall with: npm install -g ${rootPackage.name} --include=optional`
32
+ );
33
+ process.exit(1);
34
+ }
35
+
36
+ try {
37
+ execFileSync(bin, process.argv.slice(2), { stdio: "inherit" });
38
+ } catch (e) {
39
+ if (e.code === "ENOENT") {
40
+ console.error(
41
+ `${toolName} binary not found inside ${platformPackage}.\n` +
42
+ `Reinstall with: npm install -g ${rootPackage.name} --include=optional`
43
+ );
44
+ }
45
+ process.exit(e.status || 1);
46
+ }