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 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
+ });