mason4agents 0.1.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/README.md +290 -0
- package/README.zh.md +290 -0
- package/dist/bin/mason4agents.js +113 -0
- package/dist/pi/extension.js +4301 -0
- package/dist/test-working.js +18 -0
- package/native/mason4agents +0 -0
- package/native/mason4agents-linux-x64 +0 -0
- package/package.json +47 -0
package/README.md
ADDED
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
# mason4agents
|
|
2
|
+
|
|
3
|
+
**Mason Registry powered tool installer for coding agents.**
|
|
4
|
+
|
|
5
|
+
mason4agents downloads and manages LSP servers, formatters, linters, and other development tools from the [Mason Registry](https://github.com/mason-org/mason-registry) — the same registry used by mason.nvim. It installs tools to XDG-compliant directories and makes them available via PATH to coding agents such as [Oh My Pi](https://ohmyPi.com).
|
|
6
|
+
|
|
7
|
+
v1 supports **Pi CLI** (v0.75.5+). Future versions may add Claude Code, Codex CLI, Copilot, OpenCode, and MCP adapters.
|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
- **Mason Registry compatible** — consumes the same registry, package schema, and release assets as mason.nvim
|
|
12
|
+
- **No Neovim dependency** — standalone Rust CLI, no shelling out to Neovim
|
|
13
|
+
- **Pi extension** — `/mason` interactive package manager, CLI-equivalent slash subcommands, 7 LLM-callable tools, automatic PATH injection
|
|
14
|
+
- **XDG Base Directory** — data, config, cache, and state follow `$XDG_*` conventions
|
|
15
|
+
- **Safe by default** — no build script execution without `--allow-build-scripts`, zip-slip protection, path traversal rejection, sandboxed temp directories with atomic rename
|
|
16
|
+
- **JSON protocol** — all CLI commands support `--json` for machine-readable output
|
|
17
|
+
- **Cross-platform** — Linux, macOS, Windows (Unix symlinks on \*nix, `.cmd` wrappers on Windows)
|
|
18
|
+
- **No shell profile modification** — `mason4agents env` outputs `export PATH=...` for manual sourcing
|
|
19
|
+
|
|
20
|
+
## Prerequisites
|
|
21
|
+
|
|
22
|
+
- **Rust toolchain** (stable, edition 2021) — for building from source
|
|
23
|
+
- **Bun** (v1.x) — for TypeScript Pi adapter
|
|
24
|
+
- **Pi CLI** (v0.75.5+) — for Pi extension integration
|
|
25
|
+
- **External package managers** (optional, per source type):
|
|
26
|
+
- `npm` — for npm-based packages
|
|
27
|
+
- `python3` + `pip` — for PyPI packages
|
|
28
|
+
- `cargo` — for crates.io packages
|
|
29
|
+
- `go` — for Go packages
|
|
30
|
+
- `gem` — for Ruby packages
|
|
31
|
+
- `composer` — for PHP packages
|
|
32
|
+
- `luarocks` — for Lua packages
|
|
33
|
+
- `nuget` — for NuGet packages
|
|
34
|
+
|
|
35
|
+
Run `mason4agents doctor` to check which managers are available on your system.
|
|
36
|
+
|
|
37
|
+
## Installation
|
|
38
|
+
|
|
39
|
+
### From source
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
git clone <repo-url>
|
|
43
|
+
cd mason4agents
|
|
44
|
+
cargo build --release
|
|
45
|
+
# binary at target/release/mason4agents
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Via npm / Pi (when published)
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
# Install the package (locally or from npm)
|
|
52
|
+
pi install npm:mason4agents
|
|
53
|
+
|
|
54
|
+
# Or test locally without publishing
|
|
55
|
+
pi --offline -e dist/pi/extension.js
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Binary resolution order
|
|
59
|
+
|
|
60
|
+
The npm shim and Pi extension locate the Rust binary by checking (in order):
|
|
61
|
+
|
|
62
|
+
1. `MASON4AGENTS_BIN` environment variable
|
|
63
|
+
2. Bundled `native/mason4agents-{platform}-{arch}` (built by `bun run build`)
|
|
64
|
+
3. Development `target/debug/mason4agents` (after `cargo build`)
|
|
65
|
+
|
|
66
|
+
## Quick Start
|
|
67
|
+
|
|
68
|
+
### CLI
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
# Refresh the Mason Registry cache
|
|
72
|
+
mason4agents refresh
|
|
73
|
+
|
|
74
|
+
# Search for packages
|
|
75
|
+
mason4agents search lua
|
|
76
|
+
mason4agents search --category LSP --language TypeScript
|
|
77
|
+
|
|
78
|
+
# Install a package
|
|
79
|
+
mason4agents install stylua
|
|
80
|
+
mason4agents install typescript-language-server
|
|
81
|
+
|
|
82
|
+
# List installed packages
|
|
83
|
+
mason4agents list --installed
|
|
84
|
+
|
|
85
|
+
# Check which directory a binary was installed to
|
|
86
|
+
mason4agents which stylua
|
|
87
|
+
|
|
88
|
+
# Get shell PATH setup
|
|
89
|
+
eval "$(mason4agents env --shell bash)"
|
|
90
|
+
|
|
91
|
+
# Run diagnostics
|
|
92
|
+
mason4agents doctor
|
|
93
|
+
|
|
94
|
+
# Uninstall
|
|
95
|
+
mason4agents uninstall stylua
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### Pi Extension
|
|
99
|
+
|
|
100
|
+
Open the interactive package manager in Pi:
|
|
101
|
+
|
|
102
|
+
```
|
|
103
|
+
/mason
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
The panel shows command tabs at the top (`search`, `list`, `installed`, `install`, `uninstall`, `update`, `which`, `refresh`, `doctor`, `env`, `bin-dir`) and a formatted output area below. Table views show installed status directly and support `/` local filtering, `↑`/`↓` scrolling, `e` to edit the active command input, and `l` to edit the `search --language` filter.
|
|
107
|
+
|
|
108
|
+
Run CLI-equivalent slash subcommands directly when you do not need the panel:
|
|
109
|
+
|
|
110
|
+
```text
|
|
111
|
+
/mason search stylua --language Lua
|
|
112
|
+
/mason installed
|
|
113
|
+
/mason list --outdated
|
|
114
|
+
/mason install stylua
|
|
115
|
+
/mason uninstall stylua
|
|
116
|
+
/mason doctor
|
|
117
|
+
/mason-doctor
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Direct slash-command results are rendered as human-readable tables or summaries, not raw JSON.
|
|
121
|
+
|
|
122
|
+
Use the following tools from Pi (they call the Rust CLI under the hood):
|
|
123
|
+
|
|
124
|
+
| Tool | Description |
|
|
125
|
+
|---|---|
|
|
126
|
+
| `mason_list` | List installed/outdated packages |
|
|
127
|
+
| `mason_search` | Search registry with query, category, language filters |
|
|
128
|
+
| `mason_install` | Install one or more packages |
|
|
129
|
+
| `mason_uninstall` | Uninstall packages |
|
|
130
|
+
| `mason_update` | Update packages (all or specific) |
|
|
131
|
+
| `mason_which` | Resolve an installed binary path |
|
|
132
|
+
| `mason_env` | Generate shell PATH setup |
|
|
133
|
+
|
|
134
|
+
### All CLI Commands
|
|
135
|
+
|
|
136
|
+
```text
|
|
137
|
+
mason4agents refresh [--registry <url|file>]
|
|
138
|
+
mason4agents search [query] [--category LSP|Formatter|Linter] [--language <lang>]
|
|
139
|
+
mason4agents list [--installed|--outdated]
|
|
140
|
+
mason4agents install <pkg[@version]>... [--registry <url|file>] [--allow-build-scripts]
|
|
141
|
+
mason4agents uninstall <pkg>...
|
|
142
|
+
mason4agents update [pkg...] [--registry <url|file>] [--allow-build-scripts]
|
|
143
|
+
mason4agents which <executable>
|
|
144
|
+
mason4agents bin-dir
|
|
145
|
+
mason4agents env --shell bash|zsh|fish|powershell|cmd|json
|
|
146
|
+
mason4agents doctor
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
By default, all commands output human-readable text. Add `--json` for structured JSON output wrapped in `{"ok": true, "data": ...}`.
|
|
150
|
+
|
|
151
|
+
Example text output:
|
|
152
|
+
|
|
153
|
+
```text
|
|
154
|
+
$ mason4agents doctor
|
|
155
|
+
mason4agents doctor
|
|
156
|
+
Bin dir: /home/user/.local/share/mason4agents/bin
|
|
157
|
+
Bin dir exists: ✓
|
|
158
|
+
Data writable: ✓
|
|
159
|
+
Registry cache: 1200 packages
|
|
160
|
+
PATH contains: ✓
|
|
161
|
+
PATH is first: ✓
|
|
162
|
+
Managers:
|
|
163
|
+
npm ✓ installed
|
|
164
|
+
cargo ✓ installed
|
|
165
|
+
...
|
|
166
|
+
Overall: ✓ ok
|
|
167
|
+
|
|
168
|
+
$ mason4agents which stylua
|
|
169
|
+
/home/user/.local/share/mason4agents/bin/stylua
|
|
170
|
+
|
|
171
|
+
$ mason4agents install stylua
|
|
172
|
+
✓ stylua v2.5.2 bins: stylua
|
|
173
|
+
|
|
174
|
+
$ mason4agents env --shell bash
|
|
175
|
+
export PATH='/home/user/.local/share/mason4agents/bin':"$PATH"
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
## Building the Plugin
|
|
179
|
+
|
|
180
|
+
The plugin has two components: the **Rust CLI** (core) and the **Pi extension** (TypeScript).
|
|
181
|
+
|
|
182
|
+
### Build everything (recommended)
|
|
183
|
+
|
|
184
|
+
```bash
|
|
185
|
+
bun run build
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
This runs:
|
|
189
|
+
1. `bun build` to bundle the TypeScript npm shim (`dist/bin/mason4agents.js`)
|
|
190
|
+
2. `bun build` to bundle the Pi extension (`dist/pi/extension.js`)
|
|
191
|
+
3. `cargo build --release` to compile the Rust CLI
|
|
192
|
+
4. Copies the release binary to `native/mason4agents-{platform}-{arch}`
|
|
193
|
+
|
|
194
|
+
### Build components separately
|
|
195
|
+
|
|
196
|
+
```bash
|
|
197
|
+
# Rust CLI only
|
|
198
|
+
cargo build --release # binary: target/release/mason4agents
|
|
199
|
+
cargo build # debug binary: target/debug/mason4agents
|
|
200
|
+
|
|
201
|
+
# Pi extension only (TypeScript bundle)
|
|
202
|
+
./node_modules/.bin/tsc --noEmit # typecheck
|
|
203
|
+
bun build src/pi/extension.ts --outdir dist/pi --target bun
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### Output artifacts
|
|
207
|
+
|
|
208
|
+
| Artifact | Path | Used by |
|
|
209
|
+
|---|---|---|
|
|
210
|
+
| Rust CLI | `target/release/mason4agents` | Direct shell usage |
|
|
211
|
+
| Rust CLI (dev) | `target/debug/mason4agents` | Pi extension dev fallback |
|
|
212
|
+
| Native binary | `native/mason4agents-{platform}-{arch}` | Bundled Pi extension lookup |
|
|
213
|
+
| npm shim | `dist/bin/mason4agents.js` | `npx mason4agents` |
|
|
214
|
+
| Pi extension | `dist/pi/extension.js` | `pi --offline -e dist/pi/extension.js` |
|
|
215
|
+
|
|
216
|
+
### Package and publish the current platform
|
|
217
|
+
|
|
218
|
+
```bash
|
|
219
|
+
# Full local publish rehearsal: verify, build, validate npm contents, then npm publish --dry-run
|
|
220
|
+
bun run publish:local
|
|
221
|
+
|
|
222
|
+
# Build a local tarball for install testing
|
|
223
|
+
bun run pack:local
|
|
224
|
+
|
|
225
|
+
# Real npm publish
|
|
226
|
+
bun run publish:npm
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
These commands package the current platform binary as `native/mason4agents-{platform}-{arch}`. For a multi-platform npm package, add the other `native/mason4agents-*` binaries before running the publish command.
|
|
230
|
+
|
|
231
|
+
## Tests
|
|
232
|
+
|
|
233
|
+
### Rust
|
|
234
|
+
|
|
235
|
+
```bash
|
|
236
|
+
cargo test # 42 tests (40 unit + 2 integration)
|
|
237
|
+
cargo test cli_fixture # CLI integration tests only
|
|
238
|
+
cargo test -- --ignored # including network smoke test
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
### TypeScript
|
|
242
|
+
|
|
243
|
+
```bash
|
|
244
|
+
bun test # 19 tests
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
### Full verification
|
|
248
|
+
|
|
249
|
+
```bash
|
|
250
|
+
cargo fmt --check && cargo clippy --all-targets -- -D warnings && cargo test && ./node_modules/.bin/tsc --noEmit && bun test
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
## XDG Directory Layout
|
|
254
|
+
|
|
255
|
+
```text
|
|
256
|
+
~/.config/mason4agents/ # Configuration
|
|
257
|
+
~/.local/share/mason4agents/
|
|
258
|
+
bin/ # Symlinks to installed tools (on PATH)
|
|
259
|
+
packages/<name>/... # Installed package contents
|
|
260
|
+
share/ # Mason share links
|
|
261
|
+
opt/ # Mason opt links
|
|
262
|
+
state/installed.json # Install state database
|
|
263
|
+
~/.cache/mason4agents/
|
|
264
|
+
registry/ # Cached registry index + checksum
|
|
265
|
+
downloads/ # Downloaded archives (cacheable)
|
|
266
|
+
logs/ # Install logs
|
|
267
|
+
~/.local/state/mason4agents/
|
|
268
|
+
locks/ # Install/update lock files
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
Override any directory via `MASON4AGENTS_CONFIG_HOME`, `MASON4AGENTS_DATA_HOME`, `MASON4AGENTS_CACHE_HOME`, `MASON4AGENTS_STATE_HOME`.
|
|
272
|
+
|
|
273
|
+
## Unsupported Source Types in v1
|
|
274
|
+
|
|
275
|
+
The following Mason source types are recognized but require external package managers (`mason4agents doctor` will report them):
|
|
276
|
+
|
|
277
|
+
- `npm`, `pypi`, `cargo`, `golang`, `gem`, `composer`, `luarocks`, `nuget`
|
|
278
|
+
|
|
279
|
+
Build scripts (`source.build.run`) are **disabled by default** and require explicit `--allow-build-scripts`.
|
|
280
|
+
|
|
281
|
+
## What is NOT in v1
|
|
282
|
+
|
|
283
|
+
- Claude Code, Codex CLI, GitHub Copilot CLI, OpenCode adapters
|
|
284
|
+
- MCP server
|
|
285
|
+
- Automatic shell profile modification
|
|
286
|
+
- Neovim/mason.nvim integration or dependency
|
|
287
|
+
|
|
288
|
+
## License
|
|
289
|
+
|
|
290
|
+
Apache-2.0
|
package/README.zh.md
ADDED
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
# mason4agents
|
|
2
|
+
|
|
3
|
+
**基于 Mason Registry 的 coding agent 工具安装器。**
|
|
4
|
+
|
|
5
|
+
mason4agents 从 [Mason Registry](https://github.com/mason-org/mason-registry)(与 mason.nvim 使用同一 registry)下载和管理 LSP server、formatter、linter 等开发工具。工具安装到符合 XDG 规范的目录,并通过 PATH 注入使 coding agent(如 [Oh My Pi](https://ohmyPi.com))可直接调用。
|
|
6
|
+
|
|
7
|
+
v1 支持 **Pi CLI**(v0.75.5+)。后续版本可能增加 Claude Code、Codex CLI、Copilot、OpenCode 及 MCP 适配。
|
|
8
|
+
|
|
9
|
+
## 功能
|
|
10
|
+
|
|
11
|
+
- **Mason Registry 兼容** — 使用与 mason.nvim 相同的 registry、包 schema 和 release assets
|
|
12
|
+
- **不依赖 Neovim** — 独立 Rust CLI,无需 shell out 到 Neovim
|
|
13
|
+
- **Pi 扩展** — `/mason` 交互式包管理器、等价 CLI 的 slash 子命令、7 个 LLM 可调用工具、自动 PATH 注入
|
|
14
|
+
- **XDG Base Directory** — data、config、cache、state 遵循 `$XDG_*` 规范
|
|
15
|
+
- **默认安全** — 无 `--allow-build-scripts` 不执行构建脚本、zip-slip 防护、路径穿越拒绝、临时目录原子重命名
|
|
16
|
+
- **JSON 协议** — 所有 CLI 命令支持 `--json` 机器可读输出
|
|
17
|
+
- **跨平台** — Linux、macOS、Windows(\*nix 用符号链接,Windows 用 `.cmd` wrapper)
|
|
18
|
+
- **不修改 shell profile** — `mason4agents env` 输出 `export PATH=...`,用户自行 sourcing
|
|
19
|
+
|
|
20
|
+
## 前置依赖
|
|
21
|
+
|
|
22
|
+
- **Rust 工具链**(stable,edition 2021)— 从源码构建
|
|
23
|
+
- **Bun**(v1.x)— TypeScript Pi adapter
|
|
24
|
+
- **Pi CLI**(v0.75.5+)— Pi 扩展集成
|
|
25
|
+
- **外部包管理器**(按 source 类型可选):
|
|
26
|
+
- `npm` — npm 源包
|
|
27
|
+
- `python3` + `pip` — PyPI 源包
|
|
28
|
+
- `cargo` — crates.io 源包
|
|
29
|
+
- `go` — Go 源包
|
|
30
|
+
- `gem` — Ruby 源包
|
|
31
|
+
- `composer` — PHP 源包
|
|
32
|
+
- `luarocks` — Lua 源包
|
|
33
|
+
- `nuget` — NuGet 源包
|
|
34
|
+
|
|
35
|
+
运行 `mason4agents doctor` 检查系统中可用的管理器。
|
|
36
|
+
|
|
37
|
+
## 安装
|
|
38
|
+
|
|
39
|
+
### 从源码安装
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
git clone <repo-url>
|
|
43
|
+
cd mason4agents
|
|
44
|
+
cargo build --release
|
|
45
|
+
# 二进制文件位于 target/release/mason4agents
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### 通过 npm / Pi 安装(发布后)
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
# 安装包(从 npm 或本地)
|
|
52
|
+
pi install npm:mason4agents
|
|
53
|
+
|
|
54
|
+
# 本地测试
|
|
55
|
+
pi --offline -e dist/pi/extension.js
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### 二进制文件查找顺序
|
|
59
|
+
|
|
60
|
+
npm shim 和 Pi 扩展按以下顺序定位 Rust 二进制文件:
|
|
61
|
+
|
|
62
|
+
1. `MASON4AGENTS_BIN` 环境变量
|
|
63
|
+
2. 内置的 `native/mason4agents-{platform}-{arch}`(由 `bun run build` 构建)
|
|
64
|
+
3. 开发目录 `target/debug/mason4agents`(`cargo build` 后)
|
|
65
|
+
|
|
66
|
+
## 快速开始
|
|
67
|
+
|
|
68
|
+
### CLI
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
# 刷新 Mason Registry 缓存
|
|
72
|
+
mason4agents refresh
|
|
73
|
+
|
|
74
|
+
# 搜索包
|
|
75
|
+
mason4agents search lua
|
|
76
|
+
mason4agents search --category LSP --language TypeScript
|
|
77
|
+
|
|
78
|
+
# 安装包
|
|
79
|
+
mason4agents install stylua
|
|
80
|
+
mason4agents install typescript-language-server
|
|
81
|
+
|
|
82
|
+
# 列出已安装的包
|
|
83
|
+
mason4agents list --installed
|
|
84
|
+
|
|
85
|
+
# 查看二进制安装位置
|
|
86
|
+
mason4agents which stylua
|
|
87
|
+
|
|
88
|
+
# 获取 shell PATH 设置
|
|
89
|
+
eval "$(mason4agents env --shell bash)"
|
|
90
|
+
|
|
91
|
+
# 运行诊断
|
|
92
|
+
mason4agents doctor
|
|
93
|
+
|
|
94
|
+
# 卸载
|
|
95
|
+
mason4agents uninstall stylua
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### Pi 扩展
|
|
99
|
+
|
|
100
|
+
在 Pi 中打开交互式包管理器:
|
|
101
|
+
|
|
102
|
+
```
|
|
103
|
+
/mason
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Panel 顶部展示命令 tabs(`search`、`list`、`installed`、`install`、`uninstall`、`update`、`which`、`refresh`、`doctor`、`env`、`bin-dir`),下方是格式化输出区域。表格视图会直接显示 installed 状态,并支持 `/` 本地过滤、`↑`/`↓` 滚动、`e` 编辑当前命令输入,以及 `l` 编辑 `search --language` 过滤器。
|
|
107
|
+
|
|
108
|
+
不需要打开 panel 时,可直接运行等价 CLI 的 slash 子命令:
|
|
109
|
+
|
|
110
|
+
```text
|
|
111
|
+
/mason search stylua --language Lua
|
|
112
|
+
/mason installed
|
|
113
|
+
/mason list --outdated
|
|
114
|
+
/mason install stylua
|
|
115
|
+
/mason uninstall stylua
|
|
116
|
+
/mason doctor
|
|
117
|
+
/mason-doctor
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
直接 slash 命令结果会渲染为人类可读的表格或摘要,不会输出原始 JSON。
|
|
121
|
+
|
|
122
|
+
Pi 中可使用以下工具(底层调用 Rust CLI):
|
|
123
|
+
|
|
124
|
+
| 工具 | 说明 |
|
|
125
|
+
|---|---|
|
|
126
|
+
| `mason_list` | 列出已安装/过期的包 |
|
|
127
|
+
| `mason_search` | 搜索 registry(支持 query、category、language 过滤) |
|
|
128
|
+
| `mason_install` | 安装一个或多个包 |
|
|
129
|
+
| `mason_uninstall` | 卸载包 |
|
|
130
|
+
| `mason_update` | 更新包(全部或指定) |
|
|
131
|
+
| `mason_which` | 查找已安装的二进制路径 |
|
|
132
|
+
| `mason_env` | 生成 shell PATH 设置 |
|
|
133
|
+
|
|
134
|
+
### 全部 CLI 命令
|
|
135
|
+
|
|
136
|
+
```text
|
|
137
|
+
mason4agents refresh [--registry <url|file>]
|
|
138
|
+
mason4agents search [query] [--category LSP|Formatter|Linter] [--language <lang>]
|
|
139
|
+
mason4agents list [--installed|--outdated]
|
|
140
|
+
mason4agents install <pkg[@version]>... [--registry <url|file>] [--allow-build-scripts]
|
|
141
|
+
mason4agents uninstall <pkg>...
|
|
142
|
+
mason4agents update [pkg...] [--registry <url|file>] [--allow-build-scripts]
|
|
143
|
+
mason4agents which <executable>
|
|
144
|
+
mason4agents bin-dir
|
|
145
|
+
mason4agents env --shell bash|zsh|fish|powershell|cmd|json
|
|
146
|
+
mason4agents doctor
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
默认情况下,所有命令输出人类可读文本。添加 `--json` 可获取结构化的 JSON 输出,包裹在 `{"ok": true, "data": ...}` 中。
|
|
150
|
+
|
|
151
|
+
示例文本输出:
|
|
152
|
+
|
|
153
|
+
```text
|
|
154
|
+
$ mason4agents doctor
|
|
155
|
+
mason4agents doctor
|
|
156
|
+
Bin dir: /home/user/.local/share/mason4agents/bin
|
|
157
|
+
Bin dir exists: ✓
|
|
158
|
+
Data writable: ✓
|
|
159
|
+
Registry cache: 1200 packages
|
|
160
|
+
PATH contains: ✓
|
|
161
|
+
PATH is first: ✓
|
|
162
|
+
Managers:
|
|
163
|
+
npm ✓ installed
|
|
164
|
+
cargo ✓ installed
|
|
165
|
+
...
|
|
166
|
+
Overall: ✓ ok
|
|
167
|
+
|
|
168
|
+
$ mason4agents which stylua
|
|
169
|
+
/home/user/.local/share/mason4agents/bin/stylua
|
|
170
|
+
|
|
171
|
+
$ mason4agents install stylua
|
|
172
|
+
✓ stylua v2.5.2 bins: stylua
|
|
173
|
+
|
|
174
|
+
$ mason4agents env --shell bash
|
|
175
|
+
export PATH='/home/user/.local/share/mason4agents/bin':"$PATH"
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
## 构建 Plugin
|
|
179
|
+
|
|
180
|
+
插件包含两个组件:**Rust CLI**(核心)和 **Pi 扩展**(TypeScript)。
|
|
181
|
+
|
|
182
|
+
### 一键构建(推荐)
|
|
183
|
+
|
|
184
|
+
```bash
|
|
185
|
+
bun run build
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
此命令依次执行:
|
|
189
|
+
1. `bun build` 打包 TypeScript npm shim(`dist/bin/mason4agents.js`)
|
|
190
|
+
2. `bun build` 打包 Pi 扩展(`dist/pi/extension.js`)
|
|
191
|
+
3. `cargo build --release` 编译 Rust CLI
|
|
192
|
+
4. 将 release 二进制复制到 `native/mason4agents-{platform}-{arch}`
|
|
193
|
+
|
|
194
|
+
### 单独构建各组件
|
|
195
|
+
|
|
196
|
+
```bash
|
|
197
|
+
# 仅 Rust CLI
|
|
198
|
+
cargo build --release # 二进制: target/release/mason4agents
|
|
199
|
+
cargo build # 调试二进制: target/debug/mason4agents
|
|
200
|
+
|
|
201
|
+
# 仅 Pi 扩展(TypeScript 打包)
|
|
202
|
+
./node_modules/.bin/tsc --noEmit # 类型检查
|
|
203
|
+
bun build src/pi/extension.ts --outdir dist/pi --target bun
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### 构建产物
|
|
207
|
+
|
|
208
|
+
| 产物 | 路径 | 用途 |
|
|
209
|
+
|---|---|---|
|
|
210
|
+
| Rust CLI | `target/release/mason4agents` | 直接命令行使用 |
|
|
211
|
+
| Rust CLI (开发) | `target/debug/mason4agents` | Pi 扩展开发回退 |
|
|
212
|
+
| 原生二进制 | `native/mason4agents-{platform}-{arch}` | Pi 扩展内置查找 |
|
|
213
|
+
| npm shim | `dist/bin/mason4agents.js` | `npx mason4agents` |
|
|
214
|
+
| Pi 扩展 | `dist/pi/extension.js` | `pi --offline -e dist/pi/extension.js` |
|
|
215
|
+
|
|
216
|
+
### 打包并发布当前平台
|
|
217
|
+
|
|
218
|
+
```bash
|
|
219
|
+
# 本地完整发布预演:验证、构建、校验 npm 内容,然后执行 npm publish --dry-run
|
|
220
|
+
bun run publish:local
|
|
221
|
+
|
|
222
|
+
# 构建本地 tarball,用于安装测试
|
|
223
|
+
bun run pack:local
|
|
224
|
+
|
|
225
|
+
# 真正发布到 npm
|
|
226
|
+
bun run publish:npm
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
这些命令会把当前平台二进制打包为 `native/mason4agents-{platform}-{arch}`。如果要发布多平台 npm 包,请先补齐其它 `native/mason4agents-*` 二进制,再执行发布命令。
|
|
230
|
+
|
|
231
|
+
## 测试
|
|
232
|
+
|
|
233
|
+
### Rust
|
|
234
|
+
|
|
235
|
+
```bash
|
|
236
|
+
cargo test # 42 个测试(40 单元 + 2 集成)
|
|
237
|
+
cargo test cli_fixture # 仅 CLI 集成测试
|
|
238
|
+
cargo test -- --ignored # 包含网络 smoke 测试
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
### TypeScript
|
|
242
|
+
|
|
243
|
+
```bash
|
|
244
|
+
bun test # 19 个测试
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
### 完整验证
|
|
248
|
+
|
|
249
|
+
```bash
|
|
250
|
+
cargo fmt --check && cargo clippy --all-targets -- -D warnings && cargo test && ./node_modules/.bin/tsc --noEmit && bun test
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
## XDG 目录布局
|
|
254
|
+
|
|
255
|
+
```text
|
|
256
|
+
~/.config/mason4agents/ # 配置文件
|
|
257
|
+
~/.local/share/mason4agents/
|
|
258
|
+
bin/ # 已安装工具的符号链接(在 PATH 中)
|
|
259
|
+
packages/<name>/... # 已安装包的内容
|
|
260
|
+
share/ # Mason share 链接
|
|
261
|
+
opt/ # Mason opt 链接
|
|
262
|
+
state/installed.json # 安装状态数据库
|
|
263
|
+
~/.cache/mason4agents/
|
|
264
|
+
registry/ # Registry 缓存 + 校验和
|
|
265
|
+
downloads/ # 下载的归档文件(可清理)
|
|
266
|
+
logs/ # 安装日志
|
|
267
|
+
~/.local/state/mason4agents/
|
|
268
|
+
locks/ # 安装/更新锁文件
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
可通过 `MASON4AGENTS_CONFIG_HOME`、`MASON4AGENTS_DATA_HOME`、`MASON4AGENTS_CACHE_HOME`、`MASON4AGENTS_STATE_HOME` 覆盖默认目录。
|
|
272
|
+
|
|
273
|
+
## v1 不支持的 Source 类型
|
|
274
|
+
|
|
275
|
+
以下 Mason source 类型已被识别但需要外部包管理器(`mason4agents doctor` 会报告它们的状态):
|
|
276
|
+
|
|
277
|
+
- `npm`、`pypi`、`cargo`、`golang`、`gem`、`composer`、`luarocks`、`nuget`
|
|
278
|
+
|
|
279
|
+
构建脚本(`source.build.run`)**默认禁用**,需显式传递 `--allow-build-scripts`。
|
|
280
|
+
|
|
281
|
+
## v1 不包含
|
|
282
|
+
|
|
283
|
+
- Claude Code、Codex CLI、GitHub Copilot CLI、OpenCode 适配
|
|
284
|
+
- MCP server
|
|
285
|
+
- 自动修改 shell profile
|
|
286
|
+
- Neovim/mason.nvim 集成或依赖
|
|
287
|
+
|
|
288
|
+
## 许可证
|
|
289
|
+
|
|
290
|
+
Apache-2.0
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
// @bun
|
|
3
|
+
|
|
4
|
+
// src/bin/mason4agents.ts
|
|
5
|
+
import { spawn } from "child_process";
|
|
6
|
+
|
|
7
|
+
// src/pi/binary.ts
|
|
8
|
+
import { accessSync, constants, existsSync, statSync } from "fs";
|
|
9
|
+
import { dirname, join, resolve } from "path";
|
|
10
|
+
import { fileURLToPath } from "url";
|
|
11
|
+
function resolveMasonBinary(env = process.env, startUrl = import.meta.url) {
|
|
12
|
+
return resolveMasonBinaryDetailed(env, startUrl).path;
|
|
13
|
+
}
|
|
14
|
+
function resolveMasonBinaryDetailed(env = process.env, startUrl = import.meta.url) {
|
|
15
|
+
if (env.MASON4AGENTS_BIN && env.MASON4AGENTS_BIN.length > 0) {
|
|
16
|
+
const explicit = resolve(env.MASON4AGENTS_BIN);
|
|
17
|
+
if (!existsSync(explicit)) {
|
|
18
|
+
throw new Error(`MASON4AGENTS_BIN points to a missing file: ${explicit}`);
|
|
19
|
+
}
|
|
20
|
+
const stat = statSync(explicit);
|
|
21
|
+
if (!stat.isFile()) {
|
|
22
|
+
throw new Error(`MASON4AGENTS_BIN points to a non-file path: ${explicit}`);
|
|
23
|
+
}
|
|
24
|
+
if (process.platform !== "win32" && (stat.mode & 73) === 0) {
|
|
25
|
+
throw new Error(`MASON4AGENTS_BIN points to a non-executable file: ${explicit}`);
|
|
26
|
+
}
|
|
27
|
+
return { path: explicit, source: "env" };
|
|
28
|
+
}
|
|
29
|
+
const root = packageRoot(startUrl);
|
|
30
|
+
for (const candidate of bundledCandidates(root)) {
|
|
31
|
+
if (existsSync(candidate) && isExecutable(candidate)) {
|
|
32
|
+
return { path: candidate, source: "bundled" };
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
for (const candidate of developmentCandidates(root)) {
|
|
36
|
+
if (existsSync(candidate) && isExecutable(candidate)) {
|
|
37
|
+
return { path: candidate, source: "development" };
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
throw new Error(`Unable to locate mason4agents native binary. Set MASON4AGENTS_BIN or build crates/mason4agents.`);
|
|
41
|
+
}
|
|
42
|
+
function isExecutable(filePath) {
|
|
43
|
+
if (process.platform === "win32") {
|
|
44
|
+
return existsSync(filePath) && statSync(filePath).isFile();
|
|
45
|
+
}
|
|
46
|
+
try {
|
|
47
|
+
return statSync(filePath).isFile() && (accessSync(filePath, constants.X_OK), true);
|
|
48
|
+
} catch {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
function packageRoot(startUrl = import.meta.url) {
|
|
53
|
+
let dir = dirname(fileURLToPath(startUrl));
|
|
54
|
+
for (let i = 0;i < 8; i += 1) {
|
|
55
|
+
if (existsSync(join(dir, "package.json"))) {
|
|
56
|
+
return dir;
|
|
57
|
+
}
|
|
58
|
+
const parent = dirname(dir);
|
|
59
|
+
if (parent === dir) {
|
|
60
|
+
break;
|
|
61
|
+
}
|
|
62
|
+
dir = parent;
|
|
63
|
+
}
|
|
64
|
+
return resolve(dirname(fileURLToPath(startUrl)), "..", "..");
|
|
65
|
+
}
|
|
66
|
+
function bundledCandidates(root) {
|
|
67
|
+
const platform = process.platform;
|
|
68
|
+
const arch = normalizeArch(process.arch);
|
|
69
|
+
const exe = platform === "win32" ? ".exe" : "";
|
|
70
|
+
const candidates = [
|
|
71
|
+
join(root, "native", `mason4agents-${platform}-${arch}${exe}`),
|
|
72
|
+
join(root, "native", `mason4agents${exe}`),
|
|
73
|
+
join(root, "dist", "native", `mason4agents-${platform}-${arch}${exe}`),
|
|
74
|
+
join(root, "dist", "native", `mason4agents${exe}`)
|
|
75
|
+
];
|
|
76
|
+
if (platform === "win32") {
|
|
77
|
+
candidates.unshift(join(root, "native", `mason4agents-${platform}-${arch}`), join(root, "dist", "native", `mason4agents-${platform}-${arch}`));
|
|
78
|
+
}
|
|
79
|
+
return candidates;
|
|
80
|
+
}
|
|
81
|
+
function developmentCandidates(root) {
|
|
82
|
+
const exe = process.platform === "win32" ? ".exe" : "";
|
|
83
|
+
return [
|
|
84
|
+
join(root, "target", "debug", "mason4agents" + exe),
|
|
85
|
+
join(root, "target", "release", "mason4agents" + exe),
|
|
86
|
+
join(root, "..", "target", "debug", "mason4agents" + exe),
|
|
87
|
+
join(root, "..", "target", "release", "mason4agents" + exe)
|
|
88
|
+
];
|
|
89
|
+
}
|
|
90
|
+
function normalizeArch(arch) {
|
|
91
|
+
if (arch === "x64")
|
|
92
|
+
return "x64";
|
|
93
|
+
if (arch === "arm64")
|
|
94
|
+
return "arm64";
|
|
95
|
+
return arch;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// src/bin/mason4agents.ts
|
|
99
|
+
var binary = resolveMasonBinary();
|
|
100
|
+
var child = spawn(binary, process.argv.slice(2), { stdio: "inherit", env: process.env });
|
|
101
|
+
for (const signal of ["SIGINT", "SIGTERM"]) {
|
|
102
|
+
process.on(signal, () => child.kill(signal));
|
|
103
|
+
}
|
|
104
|
+
child.on("exit", (code, signal) => {
|
|
105
|
+
for (const sig of ["SIGINT", "SIGTERM"]) {
|
|
106
|
+
process.removeAllListeners(sig);
|
|
107
|
+
}
|
|
108
|
+
if (signal) {
|
|
109
|
+
process.kill(process.pid, signal);
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
process.exit(code ?? 1);
|
|
113
|
+
});
|