@yottameta/yotta-dev-mcp 0.0.0 → 0.2.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/CHANGELOG.md +44 -0
- package/LICENSE +21 -0
- package/NOTICE +7 -0
- package/README.md +132 -0
- package/README.zh-CN.md +120 -0
- package/SKILL.md +81 -0
- package/assets/banner.png +0 -0
- package/bin/install.js +142 -0
- package/bin/yotta-dev-mcp.js +57 -0
- package/install.sh +9 -0
- package/package.json +38 -12
- package/references/adapters.md +69 -0
- package/references/architecture-contract.md +256 -0
- package/references/tools.md +257 -0
- package/scripts/dev_adapters.py +609 -0
- package/scripts/dev_architecture.py +379 -0
- package/scripts/dev_common.py +144 -0
- package/scripts/dev_contract.py +830 -0
- package/scripts/dev_engine.py +1138 -0
- package/scripts/dev_impact.py +556 -0
- package/scripts/dev_model.py +435 -0
- package/scripts/dev_rules.py +25 -0
- package/scripts/dev_selftest.py +534 -0
- package/scripts/dev_verify.py +450 -0
- package/scripts/yotta_dev_mcp.py +659 -0
- package/server.json +20 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## v0.2.0 (2026-09-25)
|
|
4
|
+
|
|
5
|
+
- 新增 `system_model`:模块、依赖、入口、测试映射、配置与数据归属的确定性系统模型,
|
|
6
|
+
附带 `.yotta/architecture.json` 契约分层。
|
|
7
|
+
- 新增 `architecture_review`:按契约评审依赖规则、边界可见性与数据归属,
|
|
8
|
+
每条产出 file / line / severity 证据;critical / high 判 FAIL,medium / low 只告警,
|
|
9
|
+
无法判定的部分进 UNKNOWN,声明的不变量一律进 `unverified_claims`。
|
|
10
|
+
- 新增 `impact_analysis`:从 changed_files / unified diff / 目标符号生成变更影响锥,
|
|
11
|
+
含直接消费者、受影响层与边界、数据存储、不变量、映射测试、可解释风险分级与回滚探针。
|
|
12
|
+
- 新增 `verify_change`:L0-L5 验证阶梯与确定性证据账本;L0 / L1 默认运行,
|
|
13
|
+
L2-L4 必须同时有 `.yotta/verification.json` 白名单声明与 `allow_execute=true`,
|
|
14
|
+
L5 人工复核始终留在 `unverified_claims`;账本以 output hash 与 ledger digest 复算。
|
|
15
|
+
- 新增 `self_test`:检查必需文件、版本五件、协议工具 schema / engine dispatch 漂移、
|
|
16
|
+
写入与执行闸门是否 fail-closed,并用 seeded defect 与 mutation control 反证验证器会红。
|
|
17
|
+
- 新增 `run_adapter`:探测或显式运行项目已安装的 import-linter /
|
|
18
|
+
dependency-cruiser / Repomix;固定 argv、项目内 cwd、有界输出与 hash,
|
|
19
|
+
缺工具 / 缺配置 / 超时 / 非法输出一律返回 UNKNOWN,且不自动安装、不下载、不访问远端。
|
|
20
|
+
- 新增架构契约(版本 1):分层、依赖规则、边界、数据归属、不变量、风险权重;
|
|
21
|
+
校验输出 code / severity / JSON pointer / evidence。
|
|
22
|
+
- 新增可选验证策略(版本 1):只允许白名单 runner、仓库内相对 cwd 与显式执行;
|
|
23
|
+
拒绝任意命令、绝对路径与越界 cwd。
|
|
24
|
+
- 结论只给 `PASS` / `FAIL` / `UNKNOWN`;缺证据项写入 `unknowns`,未执行的验证级别
|
|
25
|
+
写入 `unverified_claims`;模型带稳定 `model_digest`。
|
|
26
|
+
- 引擎按共享层拆分:`dev_common` / `dev_model` / `dev_architecture` /
|
|
27
|
+
`dev_impact` / `dev_verify` / `dev_selftest` / `dev_adapters`;`dev_engine`
|
|
28
|
+
保留原公开函数与 dispatch 作为稳定门面。
|
|
29
|
+
- 原 12 个工具行为不变;新增的六个工具离线、零依赖(适配器只在用户已安装时调用),默认只读。
|
|
30
|
+
|
|
31
|
+
## v0.1.1 (2026-09-25)
|
|
32
|
+
|
|
33
|
+
- 品牌改名:对外显示名统一为「元开(yotta-dev-mcp)」,不再把功能描述「开发能力 MCP」当产品名。
|
|
34
|
+
- 功能与 12 个工具保持不变;协议、参数、输出与 0.1.0 兼容。
|
|
35
|
+
|
|
36
|
+
## v0.1.0 (2026-09-25)
|
|
37
|
+
|
|
38
|
+
- 首个本地候选:MCP 双时代协议内核(2026-07-28 modern + 2025-11-25 legacy)。
|
|
39
|
+
- 十二个确定性工具:`repo_map` / `find_code` / `compress_output` /
|
|
40
|
+
`review_code` / `review_diff` / `mcp_doctor` / `scan_secrets` /
|
|
41
|
+
`scan_dependencies` / `check_publish_readiness` / `run_checks` /
|
|
42
|
+
`scaffold_skill` / `workflow_state`。
|
|
43
|
+
- Python 3.8+ 标准库实现;离线默认运行;输出带证据、排序稳定。
|
|
44
|
+
- `run_checks` 默认关闭执行;`scaffold_skill` / `workflow_state` 默认只预览。
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 YottaMeta
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/NOTICE
ADDED
package/README.md
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
<p align="center"><img src="assets/banner.png" alt="YuanKai banner" width="100%"></p>
|
|
2
|
+
<h1 align="center">YuanKai (yotta-dev-mcp)</h1>
|
|
3
|
+
<p align="center"><b>Language</b>: English · <a href="README.zh-CN.md">中文</a></p>
|
|
4
|
+
|
|
5
|
+
Deterministic local development tools exposed over a stdio MCP server.
|
|
6
|
+
|
|
7
|
+
## What it does
|
|
8
|
+
|
|
9
|
+
| Tool | Purpose |
|
|
10
|
+
|---|---|
|
|
11
|
+
| `repo_map` | Map modules, imports and entrypoints in a repository. |
|
|
12
|
+
| `system_model` | Build a system model with layer data from the architecture contract. |
|
|
13
|
+
| `architecture_review` | Review dependency rules, boundaries and data ownership with evidence. |
|
|
14
|
+
| `impact_analysis` | Build the change impact cone with tests, blast radius and rollback probes. |
|
|
15
|
+
| `verify_change` | Run the L0-L5 verification ladder and return an evidence ledger. |
|
|
16
|
+
| `self_test` | Check files, versions, tool contracts, write gates and seeded-defect counterexamples. |
|
|
17
|
+
| `run_adapter` | Probe or explicitly run optional import-linter / dependency-cruiser / Repomix adapters. |
|
|
18
|
+
| `find_code` | Locate symbols and text with bounded results. |
|
|
19
|
+
| `compress_output` | Compress long logs while keeping errors and head/tail context. |
|
|
20
|
+
| `review_code` | Apply deterministic review rules with file, line and evidence. |
|
|
21
|
+
| `review_diff` | Review only added lines in a unified diff. |
|
|
22
|
+
| `mcp_doctor` | Inspect installed skills and MCP JSON configuration files. |
|
|
23
|
+
| `scan_secrets` | Scan for credentials and high-entropy tokens with redacted evidence. |
|
|
24
|
+
| `scan_dependencies` | Check manifests, lockfiles, insecure sources and typosquat suspicion. |
|
|
25
|
+
| `check_publish_readiness` | Check version alignment, release files and package metadata. |
|
|
26
|
+
| `run_checks` | Run whitelisted tests, lint or compile checks; execution is explicit. |
|
|
27
|
+
| `scaffold_skill` | Plan or create a minimal skill scaffold; dry-run by default. |
|
|
28
|
+
| `workflow_state` | Read `.workflow` and optionally append an explicit log entry. |
|
|
29
|
+
|
|
30
|
+
Tools are read-only by default; `run_checks`, the L2-L4 policy checks in
|
|
31
|
+
`verify_change`, the test subset in `self_test`, and `run_adapter` with
|
|
32
|
+
`action=run` require `allow_execute=true`. `scaffold_skill` / `workflow_state`
|
|
33
|
+
require `apply=true` before writing. Python 3.8+ standard library is sufficient;
|
|
34
|
+
no network access is required.
|
|
35
|
+
|
|
36
|
+
### Architecture contract
|
|
37
|
+
|
|
38
|
+
`system_model` reads an optional `.yotta/architecture.json` (version 1) that declares
|
|
39
|
+
layers, dependency rules, boundaries, data ownership, invariants and risk weights. The
|
|
40
|
+
result reports `PASS`, `FAIL` or `UNKNOWN`, lists every unknown that still needs
|
|
41
|
+
evidence, and keeps verification levels that were not executed in `unverified_claims`.
|
|
42
|
+
`architecture_review` then checks that contract: dependency rules, boundary visibility
|
|
43
|
+
and data ownership each produce findings with file, line and severity. `critical` and
|
|
44
|
+
`high` findings fail the review, `medium` and `low` stay advisory, and anything that
|
|
45
|
+
cannot be decided from the model becomes `UNKNOWN` instead of a silent pass.
|
|
46
|
+
|
|
47
|
+
`impact_analysis` starts from `changed_files`, a unified diff or target symbols and
|
|
48
|
+
walks reverse dependencies into a bounded cone: direct consumers, affected layers,
|
|
49
|
+
boundaries, data stores, invariants, mapped tests, an explainable blast radius and
|
|
50
|
+
rollback probes. It executes nothing.
|
|
51
|
+
|
|
52
|
+
`verify_change` runs the post-change ladder: L0 syntax and contract schema, L1
|
|
53
|
+
architecture checks inside the impact cone, L2-L4 whitelisted checks declared in
|
|
54
|
+
`.yotta/verification.json` with explicit `allow_execute=true`, and L5 independent
|
|
55
|
+
review kept as unverified work. Ledger entries carry a claim, status, evidence,
|
|
56
|
+
check name and output hash so the result can be recomputed; skipped levels are never
|
|
57
|
+
written as passing.
|
|
58
|
+
|
|
59
|
+
`self_test` checks the integrity of yotta-dev-mcp itself: required files, version
|
|
60
|
+
alignment across package / SKILL / CHANGELOG / server / engine, protocol tool schema
|
|
61
|
+
drift, fail-closed write gates, and seeded-defect plus mutation controls that prove
|
|
62
|
+
the verifier turns red or unknown. The test suite is not executed by default.
|
|
63
|
+
|
|
64
|
+
`run_adapter` is an optional enhancement layer. `action=list` only probes the
|
|
65
|
+
project-local `node_modules/.bin`, project virtualenvs and `PATH`; `action=run`
|
|
66
|
+
requires `allow_execute=true` and runs one fixed adapter command. Missing tools,
|
|
67
|
+
missing config, invalid output and timeouts return `UNKNOWN` with a next step.
|
|
68
|
+
No package is installed or downloaded, and adapter results do not silently change
|
|
69
|
+
the status of the core architecture tools. Details: `references/adapters.md`.
|
|
70
|
+
|
|
71
|
+
Schema, glob rules, finding codes and cone fields: `references/architecture-contract.md`.
|
|
72
|
+
|
|
73
|
+
## Install
|
|
74
|
+
|
|
75
|
+
### Start the MCP server
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
npx -y @yottameta/yotta-dev-mcp
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Install the skill payload
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
npx -y @yottameta/yotta-dev-mcp --agent codex
|
|
85
|
+
npx -y @yottameta/yotta-dev-mcp --dir <skill-directory>
|
|
86
|
+
npx -y @yottameta/yotta-dev-mcp --list
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
The installer uses explicit targets. `--global` additionally requires `--yes`, and
|
|
90
|
+
`--dry-run` prints the target without writing.
|
|
91
|
+
|
|
92
|
+
Other installation methods:
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
git clone https://github.com/YottaMeta/yotta-dev-mcp.git <skill-directory>/yotta-dev-mcp
|
|
96
|
+
bash <skill-directory>/yotta-dev-mcp/install.sh --agent codex
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
You can also use GitHub's **Download ZIP** action and unpack the archive into the
|
|
100
|
+
skill directory.
|
|
101
|
+
|
|
102
|
+
## Direct CLI
|
|
103
|
+
|
|
104
|
+
The engine can also be used without MCP:
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
python scripts/dev_engine.py repo-map .
|
|
108
|
+
python scripts/dev_engine.py system-model .
|
|
109
|
+
python scripts/dev_engine.py architecture-review .
|
|
110
|
+
python scripts/dev_engine.py impact-analysis . --changed src/core/store.py
|
|
111
|
+
python scripts/dev_engine.py verify-change . --changed src/core/store.py
|
|
112
|
+
python scripts/dev_engine.py verify-change . --changed src/core/store.py --level L2 --allow-execute
|
|
113
|
+
python scripts/dev_engine.py self-test .
|
|
114
|
+
python scripts/dev_engine.py adapter . --action list
|
|
115
|
+
python scripts/dev_engine.py adapter . --action run --adapter dependency-cruiser --allow-execute
|
|
116
|
+
python scripts/dev_engine.py find-code . "helper"
|
|
117
|
+
python scripts/dev_engine.py review-code .
|
|
118
|
+
python scripts/dev_engine.py mcp-doctor
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## Boundaries
|
|
122
|
+
|
|
123
|
+
- No code execution, no automatic edits, no commits.
|
|
124
|
+
- No network access, no package-existence lookup.
|
|
125
|
+
- Static deterministic findings only; human review remains the final decision.
|
|
126
|
+
|
|
127
|
+
## Current version
|
|
128
|
+
|
|
129
|
+
`0.2.0` (2026-09-25) adds `system_model`, `architecture_review`,
|
|
130
|
+
`impact_analysis`, `verify_change`, `self_test`, `run_adapter`, and the
|
|
131
|
+
`.yotta/architecture.json` plus optional `.yotta/verification.json` contracts on
|
|
132
|
+
top of the twelve deterministic tools.
|
package/README.zh-CN.md
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
<p align="center"><img src="assets/banner.png" alt="元开 banner" width="100%"></p>
|
|
2
|
+
<h1 align="center">元开(yotta-dev-mcp)</h1>
|
|
3
|
+
<p align="center"><b>Language</b>: <a href="README.md">English</a> · 中文</p>
|
|
4
|
+
|
|
5
|
+
把本地、确定性的开发工具做成 stdio MCP server,任何支持 MCP 的客户端接上即可使用。
|
|
6
|
+
|
|
7
|
+
## 能做什么
|
|
8
|
+
|
|
9
|
+
| 工具 | 用途 |
|
|
10
|
+
|---|---|
|
|
11
|
+
| `repo_map` | 代码库模块、导入关系与入口点地图。 |
|
|
12
|
+
| `system_model` | 系统模型:模块、依赖、入口、测试映射、配置与数据归属,附带契约分层。 |
|
|
13
|
+
| `architecture_review` | 按契约评审依赖规则、边界可见性与数据归属,逐条给出证据。 |
|
|
14
|
+
| `impact_analysis` | 变更影响锥:消费者、受影响层与存储、映射测试、风险分级与回滚探针。 |
|
|
15
|
+
| `verify_change` | L0-L5 验证阶梯与证据账本;未执行级别保留在 `unverified_claims`。 |
|
|
16
|
+
| `self_test` | 文件、版本、工具契约、写闸门与 seeded defect / mutation 反证自测。 |
|
|
17
|
+
| `run_adapter` | 探测或显式运行 import-linter / dependency-cruiser / Repomix 可选适配器。 |
|
|
18
|
+
| `find_code` | 符号与文本定位,结果有数量上限。 |
|
|
19
|
+
| `compress_output` | 压缩长日志,保留错误、错误栈和首尾上下文。 |
|
|
20
|
+
| `review_code` | 规则化代码评审,输出文件、行号、证据与建议。 |
|
|
21
|
+
| `review_diff` | 只评审 unified diff 的新增行。 |
|
|
22
|
+
| `mcp_doctor` | 只读检查技能目录与 MCP JSON 配置。 |
|
|
23
|
+
| `scan_secrets` | 密钥 / 凭据 / 高熵令牌扫描,证据强制脱敏。 |
|
|
24
|
+
| `scan_dependencies` | 依赖清单、lockfile、来源与 typosquat 启发式检查。 |
|
|
25
|
+
| `check_publish_readiness` | 版本对齐、发布文件与包元数据检查。 |
|
|
26
|
+
| `run_checks` | 运行白名单测试 / lint / compile,执行必须显式开启。 |
|
|
27
|
+
| `scaffold_skill` | 规划或生成最小技能脚手架,默认 dry-run。 |
|
|
28
|
+
| `workflow_state` | 读取 `.workflow`,可选显式追加快照日志。 |
|
|
29
|
+
|
|
30
|
+
默认只读;`run_checks`、`verify_change` 的 L2-L4 策略检查、`self_test` 的测试子集,
|
|
31
|
+
以及 `run_adapter` 的 `action=run` 必须显式 `allow_execute=true`,
|
|
32
|
+
`scaffold_skill` / `workflow_state` 必须显式 `apply=true` 才写入。
|
|
33
|
+
核心只用 Python 3.8+ 标准库,默认不联网。
|
|
34
|
+
|
|
35
|
+
### 架构契约
|
|
36
|
+
|
|
37
|
+
`system_model` 读取可选的 `.yotta/architecture.json`(版本 1),其中声明分层、依赖规则、
|
|
38
|
+
边界、数据归属、不变量与风险权重。结果只给 `PASS` / `FAIL` / `UNKNOWN`,把还缺证据的
|
|
39
|
+
未知项列进 `unknowns`,未执行的验证级别保留在 `unverified_claims`。schema、glob 规则与
|
|
40
|
+
错误码见 `references/architecture-contract.md`。
|
|
41
|
+
|
|
42
|
+
`architecture_review` 在这份契约上做评审:依赖规则、边界可见性与数据归属逐条产出
|
|
43
|
+
文件、行号与严重级;`critical` / `high` 判 FAIL,`medium` / `low` 只告警,
|
|
44
|
+
模型无法判定的部分进 `UNKNOWN`,不会被静默放行。
|
|
45
|
+
|
|
46
|
+
`impact_analysis` 从 `changed_files`、unified diff 或目标符号出发,沿反向依赖走出一棵
|
|
47
|
+
有上限的影响锥:直接消费者、受影响层与边界、数据存储、不变量、映射测试、
|
|
48
|
+
可解释的风险分级与回滚探针;全程不执行任何命令。
|
|
49
|
+
|
|
50
|
+
`verify_change` 在改动后跑同一份模型:L0 检查语法与契约 schema,L1 检查影响锥内架构规则,
|
|
51
|
+
L2-L4 只执行 `.yotta/verification.json` 中声明的白名单检查且必须显式 `allow_execute=true`,
|
|
52
|
+
L5 独立复核始终保留在未验证项。账本中的每个结论都带 claim、status、evidence、check 与
|
|
53
|
+
output hash,便于复算;未跑级别不会被写成“已通过”。
|
|
54
|
+
|
|
55
|
+
`self_test` 对元开自身做完整性检查:必需文件、版本五件、协议工具 schema 与引擎
|
|
56
|
+
dispatch 是否漂移、写 / 执行闸门是否仍 fail-closed,并用临时仓库里的 seeded defect
|
|
57
|
+
与 mutation control 证明验证器会变红或变 UNKNOWN。测试子集默认不跑。
|
|
58
|
+
|
|
59
|
+
`run_adapter` 是可选增强层:`action=list` 只探测项目 `node_modules/.bin`、
|
|
60
|
+
项目虚拟环境和 `PATH`;`action=run` 必须显式 `allow_execute=true`,且只运行固定
|
|
61
|
+
适配器命令。缺工具、缺配置、非法输出或超时都返回 `UNKNOWN` 并给出下一步;
|
|
62
|
+
不安装、不下载,适配器结果也不会悄悄改写核心架构工具的状态。详见
|
|
63
|
+
`references/adapters.md`。
|
|
64
|
+
|
|
65
|
+
## 安装
|
|
66
|
+
|
|
67
|
+
### 启动 MCP server
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
npx -y @yottameta/yotta-dev-mcp
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### 安装技能载荷
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
npx -y @yottameta/yotta-dev-mcp --agent codex
|
|
77
|
+
npx -y @yottameta/yotta-dev-mcp --dir <技能目录>
|
|
78
|
+
npx -y @yottameta/yotta-dev-mcp --list
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
安装器只写入显式目标。`--global` 必须同时给 `--yes`;`--dry-run` 只预览不写入。
|
|
82
|
+
|
|
83
|
+
其他安装方式:
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
git clone https://github.com/YottaMeta/yotta-dev-mcp.git <技能目录>/yotta-dev-mcp
|
|
87
|
+
bash <技能目录>/yotta-dev-mcp/install.sh --agent codex
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
也可以使用 GitHub 的 **Download ZIP**,解压到技能目录。
|
|
91
|
+
|
|
92
|
+
## 直接使用 CLI
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
python scripts/dev_engine.py repo-map .
|
|
96
|
+
python scripts/dev_engine.py system-model .
|
|
97
|
+
python scripts/dev_engine.py architecture-review .
|
|
98
|
+
python scripts/dev_engine.py impact-analysis . --changed src/core/store.py
|
|
99
|
+
python scripts/dev_engine.py verify-change . --changed src/core/store.py
|
|
100
|
+
python scripts/dev_engine.py verify-change . --changed src/core/store.py --level L2 --allow-execute
|
|
101
|
+
python scripts/dev_engine.py self-test .
|
|
102
|
+
python scripts/dev_engine.py adapter . --action list
|
|
103
|
+
python scripts/dev_engine.py adapter . --action run --adapter dependency-cruiser --allow-execute
|
|
104
|
+
python scripts/dev_engine.py find-code . "helper"
|
|
105
|
+
python scripts/dev_engine.py review-code .
|
|
106
|
+
python scripts/dev_engine.py mcp-doctor
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## 边界
|
|
110
|
+
|
|
111
|
+
- 不执行代码、不自动改文件、不自动提交。
|
|
112
|
+
- 不联网,不查询公共仓库中包是否存在。
|
|
113
|
+
- 仅做确定性静态判断,最终评审由人负责。
|
|
114
|
+
|
|
115
|
+
## 当前版本
|
|
116
|
+
|
|
117
|
+
`0.2.0`(2026-09-25)在原有十二个确定性工具之上新增 `system_model`、
|
|
118
|
+
`architecture_review`、`impact_analysis`、`verify_change`、`self_test`、
|
|
119
|
+
`run_adapter`,以及 `.yotta/architecture.json` 与可选
|
|
120
|
+
`.yotta/verification.json` 契约(版本 1)。
|
package/SKILL.md
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: yotta-dev-mcp
|
|
3
|
+
description: 元开(yotta-dev-mcp)—— 本地、确定性的开发工具 MCP,把只读默认的开发能力暴露为 stdio MCP server:repo_map / system_model / architecture_review / impact_analysis / verify_change / self_test / run_adapter / find_code / compress_output / review_code / review_diff / mcp_doctor / scan_secrets / scan_dependencies / check_publish_readiness / run_checks / scaffold_skill / workflow_state。触发:让 AI 在陌生项目里先做结构盘点、构建系统模型或架构契约(.yotta/architecture.json)、按契约评审架构、分析改动影响锥与回归面、按验证阶梯产出证据账本、对元开自身做完整性 / 反证自测、探测或显式运行 import-linter / dependency-cruiser / Repomix 可选适配器、定位代码、评审改动、扫描密钥/依赖、检查发布就绪、运行白名单检查、生成脚手架或读取 .workflow 状态时;或用户说 元开 / 开发能力 MCP / yotta-dev-mcp / 代码库地图 / 系统模型 / 架构契约 / 架构评审 / 影响分析 / 验证账本 / 反证自测 / 代码评审 MCP / 适配器 等。边界:Python 3.8+ 标准库、离线默认;除 run_checks(显式 allow_execute)、verify_change 的 L2-L4 策略检查(显式 allow_execute)与 self_test 的测试子集(显式 allow_execute)、run_adapter 的 action=run(显式 allow_execute)、scaffold_skill / workflow_state 的显式 apply 外均为只读;不上传源码、不自动修改、不提交、不联网查询包是否存在、不自动安装或下载适配器。
|
|
4
|
+
version: 0.2.0
|
|
5
|
+
license: MIT
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# 元开(yotta-dev-mcp)
|
|
9
|
+
|
|
10
|
+
元开(YuanKai)把一组本地、确定性的开发工具做成一个 stdio MCP server。任何支持 MCP 的客户端接上后,
|
|
11
|
+
都能在真实开发任务里调用这些工具;输出带文件、行号、规则和证据,便于直接进入修复清单。
|
|
12
|
+
|
|
13
|
+
## 何时使用
|
|
14
|
+
|
|
15
|
+
- 接手陌生项目:先 `repo_map` 看模块、依赖和入口,再 `find_code` 定位。
|
|
16
|
+
- 架构与影响分析:先写 `.yotta/architecture.json`,再用 `system_model` 拿分层、依赖、测试映射与 `UNKNOWN` 清单。
|
|
17
|
+
- 契约评审:用 `architecture_review` 查依赖规则、边界可见性与数据归属,每条给证据与严重级。
|
|
18
|
+
- 改动前评估:用 `impact_analysis` 从改动文件 / diff / 目标符号走出影响锥、映射测试与回滚探针。
|
|
19
|
+
- 改动后验证:用 `verify_change` 跑 L0 / L1 默认检查,按需结合 `.yotta/verification.json` 与 `allow_execute=true` 执行 L2-L4 白名单检查,产出可复算账本。
|
|
20
|
+
- 自身完整性:用 `self_test` 检查文件、版本、工具契约、写闸门与 seeded defect / mutation 反证。
|
|
21
|
+
- 可选增强:用 `run_adapter` 先 `action=list` 探测 import-linter / dependency-cruiser / Repomix,再按需 `action=run` + `allow_execute=true`;缺工具或配置返回 UNKNOWN,不自动安装、不自动下载。
|
|
22
|
+
- 评审改动:`review_diff` 只看新增行;`review_code` 对文件或仓库做规则检查。
|
|
23
|
+
- 长日志 / 长命令输出:`compress_output` 保错误、错误栈和首尾上下文。
|
|
24
|
+
- 本机排查:`mcp_doctor` 只读检查技能目录和 MCP JSON 配置。
|
|
25
|
+
|
|
26
|
+
## MCP 接入
|
|
27
|
+
|
|
28
|
+
启动命令:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npx -y @yottameta/yotta-dev-mcp
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
或直接用本地脚本:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
python scripts/yotta_dev_mcp.py
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
自动接入说明:AI 首次协助配置时,必须先展示目标配置文件、完整配置片段和影响,
|
|
41
|
+
并获得用户明确同意后再写入 `mcpServers`。用户拒绝时不要写文件,直接提供上面的启动命令
|
|
42
|
+
让用户手动接入。
|
|
43
|
+
|
|
44
|
+
## 工具
|
|
45
|
+
|
|
46
|
+
| 工具 | 用途 | 写入 |
|
|
47
|
+
|---|---|---|
|
|
48
|
+
| `repo_map` | 模块、导入、入口点地图 | 否 |
|
|
49
|
+
| `system_model` | 系统模型:模块、依赖、入口、测试映射、配置与数据归属;附带契约分层,输出 PASS / FAIL / UNKNOWN | 否 |
|
|
50
|
+
| `architecture_review` | 按契约评审依赖规则、边界可见性与数据归属;critical / high 判 FAIL,medium / low 只告警 | 否 |
|
|
51
|
+
| `impact_analysis` | 变更影响锥:直接消费者、受影响层 / 边界 / 存储 / 不变量、映射测试、风险分级与回滚探针 | 否 |
|
|
52
|
+
| `verify_change` | L0-L5 验证阶梯与证据账本:L0 / L1 默认,L2-L4 需策略声明 + 显式执行,L5 始终留在未验证项 | 仅显式 allow_execute 的 L2-L4 |
|
|
53
|
+
| `self_test` | 文件 / 版本 / 工具契约 / 写闸门 / seeded defect 与 mutation 反证自测 | 仅显式 allow_execute 的测试子集 |
|
|
54
|
+
| `run_adapter` | 探测或显式运行 import-linter / dependency-cruiser / Repomix;固定 argv、项目内 cwd、有界输出与哈希 | 仅 action=run + 显式 allow_execute |
|
|
55
|
+
| `find_code` | 符号 / 文本定位,结果有上限 | 否 |
|
|
56
|
+
| `compress_output` | 保留错误与首尾的长输出压缩 | 否 |
|
|
57
|
+
| `review_code` | 规则化代码评审,带行号与建议 | 否 |
|
|
58
|
+
| `review_diff` | 只评审 diff 的新增行 | 否 |
|
|
59
|
+
| `mcp_doctor` | 技能版本与 MCP JSON 配置体检 | 否 |
|
|
60
|
+
| `scan_secrets` | 密钥 / 凭据 / 高熵令牌扫描(强制脱敏) | 否 |
|
|
61
|
+
| `scan_dependencies` | 依赖清单、lockfile、来源与 typosquat 启发式检查 | 否 |
|
|
62
|
+
| `check_publish_readiness` | 版本四件、发布文件、仓库与 publishConfig 检查 | 否 |
|
|
63
|
+
| `run_checks` | 白名单测试 / lint / compile 并返回结构化摘要 | 仅显式 allow_execute |
|
|
64
|
+
| `scaffold_skill` | 生成最小技能脚手架,默认 dry-run | 仅显式 apply |
|
|
65
|
+
| `workflow_state` | 读取 `.workflow`,可选显式追加日志 | 仅显式 apply |
|
|
66
|
+
|
|
67
|
+
详细契约见 `references/tools.md`;架构契约、评审语义与影响锥字段见 `references/architecture-contract.md`。
|
|
68
|
+
|
|
69
|
+
## 边界
|
|
70
|
+
|
|
71
|
+
- 会执行项目代码的工具默认关闭:`run_checks`、`verify_change` 的 L2-L4 策略检查、`self_test` 的测试子集都必须显式 `allow_execute=true`,且只运行白名单检查或已声明的策略检查。
|
|
72
|
+
- 外部适配器只在用户已安装时接入:`run_adapter` 不安装、不下载、不访问远端、不接收任意命令参数;工具缺失或配置缺失一律返回 `UNKNOWN` 并给出 next_step。
|
|
73
|
+
- `scaffold_skill` / `workflow_state` 默认只预览,显式 `apply=true` 才写入;脚手架拒绝覆盖已有非空目录,状态写入使用原子替换并为被覆盖文件保留 `.bak`。
|
|
74
|
+
- 不联网,不查询包是否存在于公共仓库。
|
|
75
|
+
- 不读取或修改 YottaCode 仓库。
|
|
76
|
+
- 结论是确定性静态判断,不替代人工评审与最终决策。
|
|
77
|
+
|
|
78
|
+
## 当前版本
|
|
79
|
+
|
|
80
|
+
- v0.2.0(2026-09-25):新增 `system_model`、`architecture_review`、`impact_analysis`、`verify_change`、`self_test`、`run_adapter`,以及 `.yotta/architecture.json` 与可选 `.yotta/verification.json` 契约(版本 1);工具总数 18,原 12 个工具行为不变。
|
|
81
|
+
- v0.1.1:品牌显示名统一为「元开」;功能与 12 个工具不变。
|
|
Binary file
|
package/bin/install.js
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* yotta-dev-mcp installer.
|
|
4
|
+
*
|
|
5
|
+
* Safe defaults:
|
|
6
|
+
* --agent <name> install to one agent's user-level skill directory
|
|
7
|
+
* --dir <path> install to an explicit skill directory
|
|
8
|
+
* --list print the supported agent directory map
|
|
9
|
+
* --global install to all known user-level directories, requires --yes
|
|
10
|
+
* --dry-run print the target without writing
|
|
11
|
+
*/
|
|
12
|
+
'use strict';
|
|
13
|
+
const fs = require('fs');
|
|
14
|
+
const os = require('os');
|
|
15
|
+
const path = require('path');
|
|
16
|
+
|
|
17
|
+
const SKILL_NAME = 'yotta-dev-mcp';
|
|
18
|
+
const PKG_ROOT = path.join(__dirname, '..');
|
|
19
|
+
const AGENT_DIRS = {
|
|
20
|
+
claude: { label: 'Claude Code', dirs: ['.claude/skills'] },
|
|
21
|
+
cursor: { label: 'Cursor', dirs: ['.cursor/skills', '.agents/skills'] },
|
|
22
|
+
codex: { label: 'Codex', dirs: ['.codex/skills'] },
|
|
23
|
+
gemini: { label: 'Gemini CLI', dirs: ['.gemini/skills', '.agents/skills'] },
|
|
24
|
+
goose: { label: 'Goose', dirs: ['.config/goose/skills', '.agents/skills'] },
|
|
25
|
+
amp: { label: 'Amp', dirs: ['.config/agents/skills', '.agents/skills'] },
|
|
26
|
+
opencode: { label: 'OpenCode', dirs: ['.config/opencode/skills'] },
|
|
27
|
+
windsurf: { label: 'Windsurf', dirs: ['.codeium/windsurf/skills'] },
|
|
28
|
+
workbuddy: { label: 'WorkBuddy', dirs: ['.workbuddy/skills'] },
|
|
29
|
+
kiro: { label: 'Kiro', dirs: ['.kiro/skills'] },
|
|
30
|
+
trae: { label: 'Trae Code CLI', dirs: ['.traecli/skills'] },
|
|
31
|
+
'trae-cn': { label: 'Trae IDE', dirs: ['.trae-cn/skills'] },
|
|
32
|
+
qwen: { label: 'Qwen Code', dirs: ['.qwen/skills'] },
|
|
33
|
+
comate: { label: 'Comate', dirs: ['.comate/skills'] },
|
|
34
|
+
codebuddy: { label: 'CodeBuddy Code', dirs: ['.codebuddy/skills'] },
|
|
35
|
+
kimi: { label: 'Kimi Code CLI', dirs: ['.kimi/skills'] },
|
|
36
|
+
agents: { label: 'AGENTS.md', dirs: ['.agents/skills'] },
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
function codexUserDir() {
|
|
40
|
+
const base = process.env.CODEX_HOME || path.join(os.homedir(), '.codex');
|
|
41
|
+
return path.join(base, 'skills');
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function opencodeUserDir() {
|
|
45
|
+
const base = process.env.XDG_CONFIG_HOME || path.join(os.homedir(), '.config');
|
|
46
|
+
return path.join(base, 'opencode', 'skills');
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function resolveUserDir(rel) {
|
|
50
|
+
if (rel === '.codex/skills') return codexUserDir();
|
|
51
|
+
if (rel === '.config/opencode/skills') return opencodeUserDir();
|
|
52
|
+
return path.join(os.homedir(), rel);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function shouldSkip(name) {
|
|
56
|
+
return name === 'package.json' || name === 'bin' || name === 'node_modules' ||
|
|
57
|
+
name === '.git' || name === '__pycache__' || name.indexOf('test_') === 0 ||
|
|
58
|
+
name.endsWith('.pyc') || name.endsWith('.pyo');
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function copyDir(source, target) {
|
|
62
|
+
fs.mkdirSync(target, { recursive: true });
|
|
63
|
+
for (const entry of fs.readdirSync(source, { withFileTypes: true })) {
|
|
64
|
+
if (shouldSkip(entry.name)) continue;
|
|
65
|
+
const sourcePath = path.join(source, entry.name);
|
|
66
|
+
const targetPath = path.join(target, entry.name);
|
|
67
|
+
if (entry.isDirectory()) {
|
|
68
|
+
copyDir(sourcePath, targetPath);
|
|
69
|
+
} else if (entry.isFile()) {
|
|
70
|
+
fs.copyFileSync(sourcePath, targetPath);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function installTo(directory, dryRun) {
|
|
76
|
+
const target = path.join(directory, SKILL_NAME);
|
|
77
|
+
if (dryRun) {
|
|
78
|
+
console.log('[dry-run] install -> ' + target);
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
copyDir(PKG_ROOT, target);
|
|
82
|
+
console.log('installed -> ' + target);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function displayDir(rel) {
|
|
86
|
+
if (process.platform === 'win32') return '%USERPROFILE%\\' + rel.replace(/\//g, '\\');
|
|
87
|
+
return '~/' + rel;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function main() {
|
|
91
|
+
const args = process.argv.slice(2);
|
|
92
|
+
const dryRun = args.indexOf('--dry-run') !== -1;
|
|
93
|
+
const yes = args.indexOf('--yes') !== -1 || args.indexOf('-y') !== -1;
|
|
94
|
+
const list = args.indexOf('--list') !== -1 || args.indexOf('-l') !== -1;
|
|
95
|
+
const global = args.indexOf('-g') !== -1 || args.indexOf('--global') !== -1;
|
|
96
|
+
const dirIndex = args.indexOf('--dir');
|
|
97
|
+
const agentIndex = args.indexOf('--agent');
|
|
98
|
+
const explicitDir = dirIndex !== -1 ? args[dirIndex + 1] : null;
|
|
99
|
+
const agent = agentIndex !== -1 ? String(args[agentIndex + 1]).toLowerCase() : null;
|
|
100
|
+
|
|
101
|
+
if (list) {
|
|
102
|
+
for (const [key, value] of Object.entries(AGENT_DIRS)) {
|
|
103
|
+
console.log(' ' + key.padEnd(10) + value.label.padEnd(18) +
|
|
104
|
+
value.dirs.map(displayDir).join(', '));
|
|
105
|
+
}
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
if (explicitDir) {
|
|
109
|
+
installTo(explicitDir, dryRun);
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
if (agent) {
|
|
113
|
+
const info = AGENT_DIRS[agent];
|
|
114
|
+
if (!info) {
|
|
115
|
+
console.error('Unknown agent: ' + agent + '. Use --dir <path>.');
|
|
116
|
+
process.exitCode = 2;
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
installTo(resolveUserDir(info.dirs[0]), dryRun);
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
if (global) {
|
|
123
|
+
if (!yes) {
|
|
124
|
+
console.error('Refusing --global without --yes. Use --dry-run to preview.');
|
|
125
|
+
process.exitCode = 2;
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
const seen = new Set();
|
|
129
|
+
for (const value of Object.values(AGENT_DIRS)) {
|
|
130
|
+
for (const rel of value.dirs) {
|
|
131
|
+
if (seen.has(rel)) continue;
|
|
132
|
+
seen.add(rel);
|
|
133
|
+
installTo(resolveUserDir(rel), dryRun);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
console.error('Choose --agent <name>, --dir <path>, or --list. Use --global --yes explicitly.');
|
|
139
|
+
process.exitCode = 2;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
main();
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* yotta-dev-mcp launcher.
|
|
4
|
+
*
|
|
5
|
+
* Default: start the stdio MCP server.
|
|
6
|
+
* Install flags: delegate to bin/install.js.
|
|
7
|
+
*/
|
|
8
|
+
'use strict';
|
|
9
|
+
const { spawn, spawnSync } = require('child_process');
|
|
10
|
+
const path = require('path');
|
|
11
|
+
|
|
12
|
+
const PKG_ROOT = path.join(__dirname, '..');
|
|
13
|
+
const SERVER = path.join(PKG_ROOT, 'scripts', 'yotta_dev_mcp.py');
|
|
14
|
+
const INSTALL_FLAGS = ['--agent', '--dir', '--list', '-l', '-g', '--global', '--dry-run', '--yes'];
|
|
15
|
+
|
|
16
|
+
function isInstallRequest(args) {
|
|
17
|
+
return args.some(function (item) {
|
|
18
|
+
if (INSTALL_FLAGS.indexOf(item) !== -1) return true;
|
|
19
|
+
return item.indexOf('--agent=') === 0 || item.indexOf('--dir=') === 0;
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function findPython() {
|
|
24
|
+
const candidates = [];
|
|
25
|
+
if (process.env.YOTTA_MCP_PYTHON) candidates.push(process.env.YOTTA_MCP_PYTHON);
|
|
26
|
+
candidates.push('python3', 'python', 'py');
|
|
27
|
+
for (let i = 0; i < candidates.length; i++) {
|
|
28
|
+
try {
|
|
29
|
+
const result = spawnSync(candidates[i], ['--version'], { encoding: 'utf8', timeout: 5000 });
|
|
30
|
+
if (result.status === 0) return candidates[i];
|
|
31
|
+
} catch (error) {
|
|
32
|
+
// Try the next candidate.
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return 'python';
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function main() {
|
|
39
|
+
const args = process.argv.slice(2);
|
|
40
|
+
if (args.indexOf('--version') !== -1 || args.indexOf('-v') !== -1) {
|
|
41
|
+
process.stdout.write(require(path.join(PKG_ROOT, 'package.json')).version + '\n');
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
if (isInstallRequest(args)) {
|
|
45
|
+
require(path.join(__dirname, 'install.js'));
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
const python = findPython();
|
|
49
|
+
const child = spawn(python, [SERVER].concat(args), { stdio: 'inherit' });
|
|
50
|
+
child.on('exit', function (code) { process.exit(code || 0); });
|
|
51
|
+
child.on('error', function (error) {
|
|
52
|
+
process.stderr.write('yotta-dev-mcp: cannot start Python MCP server: ' + error.message + '\n');
|
|
53
|
+
process.exit(1);
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
main();
|
package/install.sh
ADDED