mingdao-harness 0.6.6 → 0.6.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.en.md +132 -0
- package/README.md +18 -6
- package/SECURITY.md +128 -0
- package/docs/ARCHITECTURE.md +261 -79
- package/docs/CONFIG.md +10 -3
- package/docs/DEVELOPER.md +19 -13
- package/docs/MIGRATION-DEYI-v0.5.md +2 -2
- package/docs/PACK-API.md +4 -4
- package/docs/PROVIDERS.md +13 -2
- package/docs/SAVINGS-BENCHMARK.md +1 -1
- package/install.sh +14 -2
- package/package.json +12 -3
- package/src/agent.js +90 -15
- package/src/batch.js +57 -4
- package/src/cachestats.js +36 -4
- package/src/commands/pack.js +6 -1
- package/src/commands/repl.js +4 -1
- package/src/config.js +9 -1
- package/src/constraints.js +10 -6
- package/src/context.js +8 -1
- package/src/cost-guard.js +63 -22
- package/src/credentials.js +11 -2
- package/src/help.js +6 -1
- package/src/hooks.js +27 -11
- package/src/ledger.js +12 -2
- package/src/model-caps.js +1 -1
- package/src/net-guard.js +108 -26
- package/src/packs.js +1 -1
- package/src/permissions.js +29 -2
- package/src/providers/index.js +9 -1
- package/src/redact.js +41 -6
- package/src/regex-safety.js +137 -0
- package/src/replay.js +1 -1
- package/src/safe-fetch.js +22 -32
- package/src/schedule.js +34 -29
- package/src/session.js +13 -2
- package/src/skill-lib.js +1 -2
- package/src/ssrf-guard.js +156 -0
- package/src/sync-server.js +40 -32
- package/src/tasks/worker.js +8 -1
- package/src/tools/bash.js +46 -2
- package/src/tools/fetch.js +33 -186
- package/src/tools/fs-tools.js +1 -11
- package/src/web/app.js +24 -2
- package/src/web/index.html +1 -0
- package/src/web/routes/domains/config.js +8 -3
- package/src/web/routes/domains/workspace.js +11 -3
- package/src/web/server.js +17 -19
- package/src/workspace.js +1 -1
- package/docs/AUDIT-v0.4.6.md +0 -241
- package/docs/AUDIT-v0.6.1-/347/254/254/344/270/211/346/226/271/346/212/245/345/221/212/347/231/273/350/256/260.md +0 -1193
- package/docs/CHANGELOG-PACK.md +0 -42
- package/docs/DESKTOP-EVALUATION.md +0 -48
- package/docs/EVALUATION-ROUND2.md +0 -58
- package/docs/EVALUATION-SYNTHESIS.md +0 -85
- package/docs/HANDOVER.md +0 -51
- package/docs/PLAN-v0.3.0.md +0 -109
- package/docs/PLAN-v0.3.2.md +0 -65
- package/docs/PLAN-v0.4.0.md +0 -38
- package/docs/PLAN-v0.4.1.md +0 -65
- package/docs/PLAN-v0.5.0.md +0 -171
- package/docs/PLAN-v0.6.0.md +0 -228
- package/docs/QA-REPORT.md +0 -335
- package/docs/QUALITY-REVIEW-0.1.68.md +0 -123
- package/docs/RELEASE-CHECKLIST.md +0 -468
- package/docs/RELEASE-TRAIN.md +0 -179
- package/docs/ROADMAP-NEXT.md +0 -55
- package/docs/STRATEGY-0.3.md +0 -121
- package/docs/STRATEGY-0.5.md +0 -262
- package/docs/STRATEGY-NEXT.md +0 -175
package/README.en.md
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# MingDao Harness — English README
|
|
2
|
+
|
|
3
|
+
> **Language policy.** The canonical documentation of this project is **Chinese**.
|
|
4
|
+
> The Chinese [`README.md`](README.md) and everything under [`docs/`](docs/) are the reference.
|
|
5
|
+
> This English README covers only the minimum needed to **evaluate and deploy** the project.
|
|
6
|
+
> Where this file and the Chinese docs disagree, **the Chinese docs and the code win**.
|
|
7
|
+
> (中文:规范文档为中文,本英文 README 只覆盖评估与部署所需的最低限度内容;两者不一致时以中文文档与代码为准。)
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## What it is
|
|
12
|
+
|
|
13
|
+
MingDao Harness (`mingdao`, short alias `mdh`) is a **zero-runtime-dependency** agent harness written
|
|
14
|
+
in plain Node.js: a model loop plus tools plus a permission layer, driven from a terminal TUI, a local
|
|
15
|
+
WebUI, an Electron desktop shell, or an IDE plugin. It ships with a declarative-plus-programmable
|
|
16
|
+
"Pack" system for domain packages. It is **not** a sandbox and **not** a security boundary for
|
|
17
|
+
untrusted code you choose to load — see the security model below, including the parts it deliberately
|
|
18
|
+
does not cover (this file is written so a reviewer can decide that, not to make the project look safer
|
|
19
|
+
than it is).
|
|
20
|
+
|
|
21
|
+
- Node.js **>= 18.17** (`package.json` `engines`), no build step, no npm runtime dependencies.
|
|
22
|
+
- Current version: **0.6.8** · License: **MIT**.
|
|
23
|
+
- Repo: <https://github.com/MingDaoTCM/MingDao-Harness> · Package: `mingdao-harness` on npm.
|
|
24
|
+
|
|
25
|
+
## Quickstart (3 steps)
|
|
26
|
+
|
|
27
|
+
**1. Install.**
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
# Any platform, via npm (installs both `mingdao` and `mdh`)
|
|
31
|
+
npm i -g mingdao-harness
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Or take the **desktop build** from GitHub Releases (Electron; unsigned — see "Known boundaries" in
|
|
35
|
+
[`SECURITY.md`](SECURITY.md)): <https://github.com/MingDaoTCM/MingDao-Harness/releases>
|
|
36
|
+
|
|
37
|
+
**2. Configure a key.**
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
mingdao init # wizard: provider -> API Key (hidden input) -> model -> permission -> sandbox
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
**3. Run.**
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
mingdao # interactive TUI (REPL)
|
|
47
|
+
mingdao web # WebUI on http://127.0.0.1:3820 by default
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
One-shot / scripted use:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
mingdao "explain this stack trace"
|
|
54
|
+
mingdao --format json "summarize the diff" # single-line structured output
|
|
55
|
+
mingdao run "run the test suite and fix failures" # background task
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Security model
|
|
59
|
+
|
|
60
|
+
Every row states a **mechanism** and, in the same row, **its boundary**. A mechanism that is not
|
|
61
|
+
enforced by the kernel is described as a declaration, not as a control.
|
|
62
|
+
|
|
63
|
+
| Mechanism | What it does | Its boundary (read this) |
|
|
64
|
+
| --- | --- | --- |
|
|
65
|
+
| **Permission modes** — `config.permission` | `"ask"` (default), `"auto"`, `"readonly"`, or an object `{ "mode": "ask", "allow": [...], "deny": [...], "denyStrict": false }`. Rules match a tool name or `tool:argument-prefix*`. Read-only tools (`read`, `glob`, `grep`, `ls`, `skill`, `git`, `fetch`) auto-pass in every mode. | `deny` is **not** a hard block by default: a hit prompts "force allow this once?" and a `y` bypasses your own rule. Only `denyStrict: true` removes that override (and additionally refuses `sh -c` / `eval`-wrapped commands, because a deny rule cannot see the real command inside the argument). Under `auto` nothing else prompts, so `deny` is the only rule that can intervene — and it remains bypassable with a `y` until `denyStrict` is set. `allow` prefix rules for `bash` deliberately refuse to match any command containing shell metacharacters. |
|
|
66
|
+
| **Sandbox** — `config.sandbox` | `"off"` (default), `"readonly"` (whole filesystem read-only, `/tmp` writable, network available), `"safe"` (read-only + no network via `unshare-net`; working dir and `/tmp` writable). Implemented with **bubblewrap** on **Linux only**. | If the platform is not Linux or `bwrap` is missing/incapable, it **downgrades to `off`** and says so in the tool result — it never silently pretends to be sandboxed. It wraps the `bash` tool only; the file tools are governed by the permission modes, not by this. |
|
|
67
|
+
| **Credential separation** | API keys live in `<home>/credentials.json` (`<home>` defaults to `~/.mingdao`, overridable with `MINGDAO_HOME`), written atomically and forced to mode **600**. `config.json` is key-free, so it is shareable and committable. Resolution order: environment variable → local credential store → legacy `config.json` field. Manage with `mingdao key`. | The legacy `config.json` `"apiKey"` field is still **read** for backward compatibility — do not use it. Keys are stored as plaintext in your home directory (no OS keychain), so any process running as your user can read them. `mingdao key status` and logs only ever print a masked form. |
|
|
68
|
+
| **Telemetry opt-out** | Only **packaged desktop builds** send anything, and only one event: after an update finishes downloading, a `POST` to `https://harness.mingdao.ai/updok` with `{"kind":"update","os":...,"ver":...}` — no user identifier, no session, no code. | It is **opt-out, not opt-in**: on by default in packaged builds. Disable with `MINGDAO_NO_TELEMETRY=1` or `"telemetry": false` in `config.json`; updates still download and install. The CLI and the WebUI send **no** telemetry at all. |
|
|
69
|
+
| **PID ownership** | Before `killTask` / `stopDaemon` signals a pid, it verifies the pid still belongs to the process we started (Linux reads `/proc/<pid>/cmdline`, macOS falls back to `ps -ww -o command=`). Three-valued: ours / definitely not ours / unknown. | **Windows has neither `/proc` nor `ps`**, and the project deliberately does not take a PowerShell/WMI dependency for this check, so ownership is reported as unknown and the caller falls back to best-effort "process is alive". Deploy on Linux or macOS if you need precise pid-ownership checks. |
|
|
70
|
+
| **Egress gate** — `config.net` | `{ "allow": ["api.deepseek.com", "*.internal.corp", "10.0.0.0/8"], "mode": "warn", "allowLoopback": true }` — `warn` (default) logs and allows, `block` refuses. Decisions are made at a single HTTP exit and recorded per event (host, port, decision, matched rule); `mingdao net report` exports the record as evidence. Non-`fetch` paths (`node:https` sync, `safe-fetch` for skill/registry/model discovery) are wired into the same decision point. Loopback is exempt; private ranges are not. | **It does not cover child processes.** Your own `curl` inside `bash`, **MCP server processes**, `config.tools` and Pack-spawned subprocesses, and the Electron shell's update check all make their own requests that the gate never sees. It proves *"the kernel did not exfiltrate"*, **not** *"this machine never egressed"*. `net.jsonl` records hosts/ports/decisions, never request bodies or full URLs. If unconfigured, the gate is not installed at all. For process-level enforcement use an egress proxy or firewall. |
|
|
71
|
+
| **SSRF protection** | One implementation (`src/ssrf-guard.js`): literal private / loopback / link-local / cloud-metadata hosts are refused (IPv4 plus all IPv6 forms, including IPv4-mapped, NAT64 and zone-ids); a hostname is resolved and **every** resolved address is checked; a hostname that fails to resolve is refused. The **validated IP is pinned to the connection layer** (via the `lookup` option of `node:http(s)`), so the check-time and connect-time resolutions cannot differ — this closes DNS rebinding. Redirects are re-checked per hop and cross-origin hops drop credential headers using a reverse allowlist. | The rule is fail-closed by design, which means it can over-block unusual-but-legitimate targets (odd IPv6 forms, `%`-scoped hosts); the fix is to use a literal, routable address or a proper hostname. It protects harness-initiated requests; it cannot constrain a subprocess' own networking (see the row above). |
|
|
72
|
+
| **Pack trust** | A project-level `.mingdao/packs/**` is **not mounted** until you explicitly run `mingdao pack trust <project-dir>`. Trust is pinned to content: if the Pack's content changes afterwards, trust lapses automatically. `mingdao pack verify <dir>` is **static by default** and does not execute Pack code; only `--runtime` imports it. | `manifest.permissions` (`fs` / `net` / `env`) is a **declaration, not enforcement**. The kernel does not enforce it: `pack.mjs` is imported into the **host process** and runs with full Node privileges — it can read and write any file and reach the network — and Pack-contributed tools are **not** subject to `config.permission`. Packs you list explicitly in `config.packs` bypass the trust gate, because that is your own written authorization. Treat installing a Pack as equivalent to running its code. |
|
|
73
|
+
| **Execution ledger** | Per-turn event streams under `<home>/ledger/`, each event chained to the previous one by a truncated SHA-256 digest starting from a fixed genesis value, plus a `run.end` seal sidecar. Details are redacted on write and again on export. Inspect with `mingdao ledger list\|show\|export\|verify` (there is also `replay`, which re-evaluates recorded calls against your *current* rules offline). | Hash chain + seal prove "unchanged and not truncated **since it was written**". There is **no trusted timestamp and no signature** (optional signing is not implemented), so it is **not** audit-grade non-repudiation — `verify` says so in its own output. |
|
|
74
|
+
| **WebUI exposure** | Binds `127.0.0.1:3820` by default. When bound to a non-loopback address without a configured token, the server generates a random token for that run and prints a `?token=` URL. Tokens also accepted via `X-MingDao-Token` or `Authorization: Bearer`. Host header is checked against loopback/bind names (anti-DNS-rebinding), cross-site browser requests are rejected, and cloud-metadata endpoints are always refused. | On loopback with no token configured there is **no authentication** (local trust by design). With `host: 0.0.0.0` the Host-header check is relaxed and the **token becomes the only boundary**, so a token is mandatory in that mode. The token is deployment-level: everyone sharing it is the same user, and task/session lists are mutually visible. |
|
|
75
|
+
|
|
76
|
+
## Command index
|
|
77
|
+
|
|
78
|
+
Commands are grouped here for evaluation; `mingdao --help` and `src/help.js` are the source of truth.
|
|
79
|
+
|
|
80
|
+
| Command | Purpose |
|
|
81
|
+
| --- | --- |
|
|
82
|
+
| `mingdao` | Interactive TUI (REPL). |
|
|
83
|
+
| `mingdao "question"` | One-shot question; `--format json` for structured output. |
|
|
84
|
+
| `mingdao init` | First-run wizard (provider → API Key → model → permission → sandbox). |
|
|
85
|
+
| `mingdao run "<task>"` | Start a background task (managed via `mingdao tasks`). |
|
|
86
|
+
| `mingdao tasks [watch\|kill <id>]` | List / live-refresh / stop background tasks. |
|
|
87
|
+
| `mingdao web [port]` | Start the WebUI (default `http://127.0.0.1:3820`); `--auth-token` (or `--auth-token=-` from stdin). |
|
|
88
|
+
| `mingdao diagnose` | Build one redacted diagnostic bundle (logs / audit / config) for bug reports. |
|
|
89
|
+
| `mingdao audit [n]` | Show the tool-call audit log (default last 20 entries). |
|
|
90
|
+
| `mingdao ledger list\|show\|export\|verify\|replay` | Execution ledger: inspect, export, verify the hash chain, or replay against current rules. |
|
|
91
|
+
| `mingdao net report\|policy` | Egress record export and current `config.net` policy. |
|
|
92
|
+
| `mingdao key [status\|set\|remove\|import] [provider]` | Manage the local credential store (never writes keys into `config.json`). |
|
|
93
|
+
| `mingdao pack list\|verify\|info\|new\|trust\|untrust` | Discover, statically validate, scaffold, and trust domain Packs. |
|
|
94
|
+
| `mingdao batch <file\|->` | Batch API (half price) over one question per line; `--model`, `--max-tokens`, `--max-cost`. |
|
|
95
|
+
| `mingdao cost [report [YYYY-MM\|all]]` | Cost report / monthly export; `--by pack` for per-Pack attribution. |
|
|
96
|
+
| `mingdao schedule add\|list\|remove\|pause\|resume\|chain` | Scheduled and chained tasks. |
|
|
97
|
+
| `mingdao sync login\|status\|push\|pull\|logout` | Cross-device session sync client; also `passwd` (change password), `share` / `shares` / `accept` / `unshare` (session sharing) and `conflicts` / `conflict-resolve`. |
|
|
98
|
+
| `mingdao sync-server [port]` | Self-hosted zero-dependency sync server. |
|
|
99
|
+
| `mingdao skill search\|install\|uninstall\|update\|trust` | Skill library (built-in plus a remote registry). |
|
|
100
|
+
| `mingdao sessions search <keyword>` | Full-text search over historical sessions. |
|
|
101
|
+
| `mingdao workspace add\|list\|use\|path\|remove` | Register and switch project directories. |
|
|
102
|
+
| `mingdao mcp preset list\|add <name>` | MCP ecosystem presets; `mcpServers` in `config.json` for arbitrary servers. |
|
|
103
|
+
| `mingdao update [--check]` / `mingdao rollback` | Self-update (git installs) / roll back to the previous revision; `update --pricing` refreshes the price table. |
|
|
104
|
+
| `mingdao desktop` | Launch the Electron desktop build. |
|
|
105
|
+
| `mingdao autostart on\|off` | Start the server automatically at login. |
|
|
106
|
+
| `mingdao --preset <name>` | Apply a declarative agent preset (tool allowlist / permission / model). In-session the equivalent is `/preset`. |
|
|
107
|
+
| `mingdao --help` / `--version` | Help / version. |
|
|
108
|
+
|
|
109
|
+
## Docs index
|
|
110
|
+
|
|
111
|
+
The full reference is **Chinese**; these are the entry points worth knowing:
|
|
112
|
+
|
|
113
|
+
- [`docs/CONFIG.md`](docs/CONFIG.md) — every `config.json` field: permission rules, sandbox, `config.net`, hooks, MCP, sync, cost guard.
|
|
114
|
+
- [`docs/PACK-API.md`](docs/PACK-API.md) — the Pack contract (manifest, contributions, constraint kinds, and which of them are **not** implemented).
|
|
115
|
+
- [`docs/PROVIDERS.md`](docs/PROVIDERS.md) — built-in providers and writing a custom OpenAI-compatible provider.
|
|
116
|
+
- [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) — module map and data flow.
|
|
117
|
+
- [`docs/DEVELOPER.md`](docs/DEVELOPER.md) — stable export surface and embedding the harness as a library.
|
|
118
|
+
- [`docs/CODE-SIGNING.md`](docs/CODE-SIGNING.md) — desktop code-signing / notarization status and the steps to sign.
|
|
119
|
+
- [`docs/internal/AUDIT-v0.6.1-第三方报告登记.md`](docs/internal/AUDIT-v0.6.1-第三方报告登记.md) — third-party audit register, including the sections that list **what is still unclosed**. (`docs/internal/` holds internal process records and is not shipped in the npm package.)
|
|
120
|
+
- [`SECURITY.md`](SECURITY.md) — how to report a vulnerability, scope, hardening checklist, known boundaries.
|
|
121
|
+
- [`docs/internal/`](docs/internal/) — plan/strategy/release/audit records (Chinese, not shipped in the npm package).
|
|
122
|
+
|
|
123
|
+
**Language policy (restated).** Canonical docs are Chinese; this English README covers the minimum
|
|
124
|
+
needed to evaluate and deploy; **when they disagree, the Chinese docs and the code win.**
|
|
125
|
+
|
|
126
|
+
## Reporting security issues
|
|
127
|
+
|
|
128
|
+
Please use GitHub Security Advisories (private) rather than a public issue — see [`SECURITY.md`](SECURITY.md).
|
|
129
|
+
|
|
130
|
+
## License
|
|
131
|
+
|
|
132
|
+
[MIT](LICENSE)
|
package/README.md
CHANGED
|
@@ -6,9 +6,12 @@
|
|
|
6
6
|
|
|
7
7
|
轻量的「模型循环 + 工具 + 权限」内核,能力以 ESM 库导出、接口全部开放。架构见 [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md)。
|
|
8
8
|
|
|
9
|
+
> **语言政策**:本仓的**规范文档是中文**(`README.md` 与 `docs/`);`README.en.md` 只覆盖"评估与部署所需的最小面"
|
|
10
|
+
> (这是什么、3 步上手、安全模型与边界、命令索引)。两者冲突时,以**中文文档与代码**为准。
|
|
11
|
+
|
|
9
12
|
## 为什么选 MingDao
|
|
10
13
|
|
|
11
|
-
- ⚡
|
|
14
|
+
- ⚡ **真正的零依赖**:内核与 CLI 纯 Node.js ≥ 18,**无任何 npm 运行时依赖**、无构建步骤——装完即用,不拖 node_modules(桌面版外壳另需 Electron / electron-updater,见下文"桌面版")
|
|
12
15
|
- 💰 **DeepSeek-V4 深度省钱**:1M 上下文预设(单次输出上限 384K)、**缓存命中计价**(命中价仅为未命中的 1/30)+ 命中率仪表盘、峰谷计价(高峰=北京工作日 9:00–12:00、14:00–18:00,闲时半价自动识别)、自动路由(pro 规划 / flash 执行 + 分类缓存 + 会话粘滞)、精确 tokenizer(官方词表 BPE)、滞回自动压缩、**Batch API 半价批处理**(`mingdao batch`)、**避峰调度**(`--offpeak` 高峰顺延到最近闲时 12:00/18:00)、**费用护栏**(每日上限防超支)
|
|
13
16
|
- 🖥 **双界面 + IDE 全家桶**:产品级 TUI(流式 Markdown、代码高亮、编辑 diff、Ctrl+C 中断、Tab 补全)与 `mingdao web` 一键 WebUI(PWA 可装桌面、多任务并行、全项设置面板);VS Code 侧边栏与 JetBrains 工具窗深度集成
|
|
14
17
|
- 🧠 **36 个技能开箱即用**:14 个内置常驻 + 22 个可安装技能库(线上 registry 逐文件 sha256 校验防供应链篡改,`mingdao skill install sql` 一键装,可自建企业内 registry)
|
|
@@ -18,7 +21,7 @@
|
|
|
18
21
|
- 🖼 **多模态**:DeepSeek-V4-Flash-Vision-Exp 视觉模型内置,WebUI 直接上传图片;模型列表以官方 `/models` 线上名单为准,新模型发布自动出现
|
|
19
22
|
- ♻ **长会话不丢上下文**:超预算自动压缩——早期段落由 executor 模型压成摘要注入(`/compact` 可手动),绝不静默失忆
|
|
20
23
|
- 🔎 **历史会话秒搜**:增量索引全文检索(中文 bigram 分词,`mingdao sessions search` / WebUI 搜索框共用);WebUI **会话级工作空间**——每个会话记住自己的项目目录,多任务并行互不串目录
|
|
21
|
-
- 🌍 **真·跨平台**:Linux / macOS / Windows
|
|
24
|
+
- 🌍 **真·跨平台**:Linux / macOS / Windows 全程实测,CI 矩阵常驻守护——Linux(Node 18/20/22)+ Windows(Node 20)+ macOS(Node 20);覆盖率门禁只在 Linux/Node 20 腿执行(`--coverage` 需要 v8 覆盖率数据,其它腿跑普通测试)
|
|
22
25
|
|
|
23
26
|
## 快速开始(3 步)
|
|
24
27
|
|
|
@@ -232,7 +235,7 @@ mingdao cost --by pack # 垂域费用分账
|
|
|
232
235
|
|
|
233
236
|
### 模型与 Key
|
|
234
237
|
|
|
235
|
-
- 内置:DeepSeek
|
|
238
|
+
- 内置:DeepSeek(`deepseek-v4-pro` / `deepseek-flash`〔旧名 `deepseek-v4-flash` 仍兼容,官方已改名〕/ `deepseek-v4-flash-vision-exp`)、OpenAI(GPT-5 系列)、Qwen(qwen3.7-max)、GLM(GLM-5)、Kimi(kimi-latest)
|
|
236
239
|
- **动态模型列表**:下拉框只显示已设置 Key 的服务商,名单以官方 `/models` 接口线上拉取为准(缓存 1 小时,设置面板可手动「刷新模型」),新模型发布自动出现
|
|
237
240
|
- 自定义 OpenAI 兼容端点:WebUI 设置面板直接添加/修改/删除(名称/标签/API 地址/Key,可标 `vision` 支持图片)
|
|
238
241
|
- 其他协议:`~/.mingdao/providers/<name>.mjs` 写 `createProvider(cfg)`,见 [docs/PROVIDERS.md](docs/PROVIDERS.md)
|
|
@@ -289,12 +292,21 @@ mingdao cost --by pack # 垂域费用分账
|
|
|
289
292
|
## 目录结构
|
|
290
293
|
|
|
291
294
|
```
|
|
292
|
-
src/ CLI / Agent 循环 / 工具 / 权限 / 技能库 / MCP / 云同步 / WebUI
|
|
295
|
+
src/ CLI / Agent 循环 / 工具 / 权限 / 技能库 / MCP / 云同步 / WebUI(内核与 CLI 全部零依赖)
|
|
296
|
+
src/web/ WebUI 服务端与前端(app.js / index.html / routes 各域)
|
|
297
|
+
src/commands/ CLI 子命令(init/run/web/key/pack/batch/ledger/schedule/sync/update…)
|
|
298
|
+
src/tools/ 工具实现(read/write/edit/ls/glob/grep/bash/git/fetch/skill/task…)
|
|
293
299
|
skills/ 14 个内置常驻技能
|
|
294
300
|
skills-lib/ 22 个可安装技能库预设
|
|
295
301
|
registry/ 线上技能 registry 索引
|
|
296
|
-
|
|
297
|
-
|
|
302
|
+
presets/ 内置 Agent 预设(如 local-audit)
|
|
303
|
+
packs/ 内置示例 Pack(example-hello)
|
|
304
|
+
assets/ 内置分词器数据(tokenizer-data.json.gz,约 762 KB,`src/tokenizer.js` 使用)
|
|
305
|
+
desktop/ Electron 桌面版外壳(含自动更新、原生目录选择器)
|
|
306
|
+
ide/ VS Code / JetBrains 插件
|
|
307
|
+
scripts/ 发布与质量脚本(覆盖率、棘轮、发布校验、文档守卫…)
|
|
308
|
+
test/ smoke(离线)/ e2e(真实进程与 HTTP)/ api-contracts / bench / mutate(变异验证)
|
|
309
|
+
docs/ 架构与扩展文档(`docs/internal/` 是内部过程文档,不随 npm 包分发)
|
|
298
310
|
install.sh / install.bat / install.ps1 一键安装
|
|
299
311
|
```
|
|
300
312
|
|
package/SECURITY.md
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# Security Policy
|
|
2
|
+
|
|
3
|
+
MingDao Harness (`mingdao`) is a zero-dependency agent harness that runs tools, executes shell
|
|
4
|
+
commands, stores model API keys locally, can host a sync server, and loads third-party "Packs" into
|
|
5
|
+
its own process. This document states what is supported, how to report a problem privately, what is in
|
|
6
|
+
scope, and — importantly — **which security boundaries are known to be incomplete**.
|
|
7
|
+
|
|
8
|
+
## Supported versions
|
|
9
|
+
|
|
10
|
+
Security fixes are provided for the **latest minor release only**.
|
|
11
|
+
|
|
12
|
+
| Version | Supported |
|
|
13
|
+
| --- | --- |
|
|
14
|
+
| **0.6.x** (current: **0.6.8**) | Yes |
|
|
15
|
+
| 0.5.x and older | No |
|
|
16
|
+
|
|
17
|
+
Upgrade with `npm i -g mingdao-harness@latest` (npm installs), or `mingdao update` / `mingdao rollback`
|
|
18
|
+
for git installs. Fixes are not backported to older minors.
|
|
19
|
+
|
|
20
|
+
## How to report
|
|
21
|
+
|
|
22
|
+
**Preferred: GitHub Security Advisories (private).**
|
|
23
|
+
<https://github.com/MingDaoTCM/MingDao-Harness/security/advisories/new>
|
|
24
|
+
|
|
25
|
+
**Fallback email:** `netmi@foxmail.com` — use this if you cannot use GitHub, or if the report includes
|
|
26
|
+
data you would rather not attach to a GitHub account.
|
|
27
|
+
|
|
28
|
+
Please include: the affected version (`mingdao --version`), your platform, a minimal reproduction, the
|
|
29
|
+
concrete impact, and whether the issue requires a malicious Pack, a malicious MCP server, or an
|
|
30
|
+
already-authenticated local user.
|
|
31
|
+
|
|
32
|
+
**Acknowledgement target: within 72 hours.** This is a goal we aim for, **not a contractual
|
|
33
|
+
commitment** — this is a small project without an on-call rotation. If you do not hear back, please
|
|
34
|
+
follow up on the same channel.
|
|
35
|
+
|
|
36
|
+
Please do not open a public issue for an unfixed vulnerability. Credit is offered on request.
|
|
37
|
+
|
|
38
|
+
## What's in scope
|
|
39
|
+
|
|
40
|
+
- `src/web/**` — the local WebUI server: token handling, Host-header check, cross-site request
|
|
41
|
+
rejection, task/session API authorization.
|
|
42
|
+
- `src/sync-server.js` — the self-hosted sync server: authentication, registration modes, path
|
|
43
|
+
handling, data isolation between accounts.
|
|
44
|
+
- `src/packs.js` + `src/constraints.js` — Pack loading, the trust gate, manifest validation, and
|
|
45
|
+
constraint evaluation (a bypass of the trust gate is in scope).
|
|
46
|
+
- `src/tools/**` — tool implementations: filesystem fence (`withinRoot`), shell execution and
|
|
47
|
+
sandboxing, the fetch tool's SSRF checks, credential/env exposure to subprocesses.
|
|
48
|
+
- `src/permissions.js` — the permission decision engine: `allow` / `deny` / `denyStrict` matching and
|
|
49
|
+
the `readonly` / `ask` / `auto` modes.
|
|
50
|
+
- `desktop/**` — the Electron shell: window navigation and `openExternal` handling, the contextBridge
|
|
51
|
+
preload surface, IPC handlers.
|
|
52
|
+
|
|
53
|
+
Reports that affect anything else in `src/` are welcome too; the list above is where the trust
|
|
54
|
+
boundaries live.
|
|
55
|
+
|
|
56
|
+
## Out of scope
|
|
57
|
+
|
|
58
|
+
- **A local, already-authorized user reading their own API key.** Keys are stored in plaintext at
|
|
59
|
+
`<home>/credentials.json` with mode 600 and are readable by anything running as that user. This is
|
|
60
|
+
the documented design (there is no OS keychain integration); it is not a vulnerability.
|
|
61
|
+
- **Windows PID ownership is best-effort.** Before killing a task or a scheduler daemon, ownership of
|
|
62
|
+
the pid is verified on Linux (`/proc/<pid>/cmdline`) and macOS (`ps`). Windows has neither, and the
|
|
63
|
+
project deliberately does not add a PowerShell/WMI dependency, so the check reports "unknown" and the
|
|
64
|
+
caller falls back to "the process is alive". A pid-reuse mis-kill on Windows is a **known design
|
|
65
|
+
boundary**, documented in the security-model table of [`README.en.md`](README.en.md) — not a bug
|
|
66
|
+
report we can act on.
|
|
67
|
+
- **Pack code running inside the host process.** `pack.mjs` is imported into the harness process with
|
|
68
|
+
full Node privileges, and `manifest.permissions` is a declaration that the kernel does **not**
|
|
69
|
+
enforce. Installing a Pack is equivalent to running its code; the mitigation is the explicit
|
|
70
|
+
`mingdao pack trust` gate plus your own review. See the Pack trust row of the
|
|
71
|
+
[`README.en.md`](README.en.md) security-model table. (This boundary is real, not acceptable — it is
|
|
72
|
+
listed again under "Known boundaries" below.)
|
|
73
|
+
- **Upstream model providers and third-party endpoints.** Key leakage, prompt handling, abuse
|
|
74
|
+
detection, availability and content issues on a model vendor's side are theirs to fix.
|
|
75
|
+
- **Anything that requires an attacker who already has code execution as your user**, unless it
|
|
76
|
+
escalates beyond what that access already grants.
|
|
77
|
+
|
|
78
|
+
## Hardening checklist for deployers
|
|
79
|
+
|
|
80
|
+
1. **Prefer `readonly` or `ask` over `auto`.** If you rely on `deny` rules, set `denyStrict: true` —
|
|
81
|
+
otherwise a `deny` hit merely prompts, and answering `y` bypasses the rule you wrote.
|
|
82
|
+
2. **Keep the WebUI on loopback.** If you must expose it, configure `web.token` (or
|
|
83
|
+
`MINGDAO_WEB_TOKEN`) and terminate TLS in front of it. Never pass a token as a literal argument
|
|
84
|
+
(`--auth-token=<token>` lands in `argv`, `ps` and shell history); use `--auth-token=-` with the
|
|
85
|
+
token on stdin.
|
|
86
|
+
3. **Use `config.net` with an explicit `allow` list and `mode: "block"`** so unexpected kernel egress
|
|
87
|
+
fails closed — and remember it does not constrain subprocesses (see Known boundaries).
|
|
88
|
+
4. **Do not use `config.json` as a key store.** Keep keys in the credential store or environment
|
|
89
|
+
variables, keep `credentials.json` at mode 600, and keep `MINGDAO_HOME` on a path only you can read.
|
|
90
|
+
5. **Treat Packs as untrusted code.** Run `mingdao pack verify <dir>` (static; `--runtime` executes the
|
|
91
|
+
Pack) and read `pack.mjs` before `mingdao pack trust`; never trust a freshly cloned repository you
|
|
92
|
+
have not reviewed.
|
|
93
|
+
6. **Enable the audit trail and the ledger.** Keep `config.audit` on, review `mingdao audit`
|
|
94
|
+
periodically, and run `mingdao ledger verify` on turns you care about. For unattended jobs, prefer
|
|
95
|
+
`readonly` or `denyStrict` over `auto`.
|
|
96
|
+
7. **Sandbox shell execution where you can.** On Linux with `bubblewrap` installed, set
|
|
97
|
+
`config.sandbox` to `readonly` or `safe` (no network). Elsewhere the sandbox downgrades to `off` and
|
|
98
|
+
says so — compensate with OS-level isolation or a container.
|
|
99
|
+
8. **Run the desktop build only from a source you trust** and verify the checksum published on the
|
|
100
|
+
Release page; current desktop builds are unsigned (see below).
|
|
101
|
+
|
|
102
|
+
## Known boundaries
|
|
103
|
+
|
|
104
|
+
These are **real, currently unclosed** items, registered in
|
|
105
|
+
[`docs/internal/AUDIT-v0.6.1-第三方报告登记.md`](docs/internal/AUDIT-v0.6.1-第三方报告登记.md) (sections
|
|
106
|
+
"未闭合(如实登记)" and "未纳入本批(如实登记)"). They are listed here rather than omitted so a reviewer can
|
|
107
|
+
price them in.
|
|
108
|
+
|
|
109
|
+
1. **The egress gate (`config.net`) does not cover child processes.** Bash subprocesses (your own
|
|
110
|
+
`curl`), MCP server processes, `config.tools` / Pack-spawned subprocesses, and the Electron shell's
|
|
111
|
+
update check make their own network requests that the gate never sees. It demonstrates "the kernel
|
|
112
|
+
did not exfiltrate", not "this machine never egressed". Process-level enforcement requires an egress
|
|
113
|
+
proxy or firewall.
|
|
114
|
+
2. **Packs have no isolation.** `pack.mjs` runs in the host process with full Node privileges, and
|
|
115
|
+
`manifest.permissions` is not enforced by the kernel. Capability brokering or subprocess isolation
|
|
116
|
+
for Packs requires an architectural change and is not implemented.
|
|
117
|
+
3. **Electron code signing and update-package signature verification are not done.** Current builds
|
|
118
|
+
are unsigned (see [`docs/CODE-SIGNING.md`](docs/CODE-SIGNING.md), which describes the steps to sign);
|
|
119
|
+
the auto-updater does not verify a signature on the downloaded update package beyond the transport.
|
|
120
|
+
4. **IDE plugin token storage needs hardening.** The VS Code and JetBrains plugins drive the local
|
|
121
|
+
WebUI over loopback; the broader item (secure token storage, and distinguishing HTTP 401 from
|
|
122
|
+
"server unreachable") is registered as open work.
|
|
123
|
+
5. **Ledger events are tamper-evident but not signed.** The hash chain plus the `run.end` seal detect
|
|
124
|
+
modification and truncation after the fact, but there is no trusted timestamp and optional signing
|
|
125
|
+
(`--sign-key`) is not implemented — so the ledger is not audit-grade non-repudiation, and
|
|
126
|
+
`mingdao ledger verify` says exactly that in its own output.
|
|
127
|
+
|
|
128
|
+
We do not claim this project is vulnerability-free, and this document is not a marketing statement.
|