Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
94 commits
Select commit Hold shift + click to select a range
7f09753
Keep board errors, docs answers, and task chrome user-facing.
cursoragent Oct 10, 2026
b90bfeb
Drop task-phase prompts when the loop refreshes the system prompt.
cursoragent Oct 10, 2026
545a887
Merge UI language and keep classified device errors.
cursoragent Oct 10, 2026
de3d83d
Keep the short rdk-docs layer after the language merge.
cursoragent Oct 10, 2026
2e9ef9a
Merge main and keep the short rdk-docs connected layer.
cursoragent Oct 10, 2026
850c7b0
bench: fix safety-boundary and skills-usage checks
Oct 10, 2026
283875f
Record the safety-boundary and skills-usage bench check changes.
cursoragent Oct 10, 2026
1688bd9
Replace only the matched span when editing mixed line endings.
cursoragent Oct 10, 2026
1ba3947
Use PowerShell 7 for exec and keep cmd for user commands.
cursoragent Oct 10, 2026
8a7fcee
Mask Bearer-style headers and keep apiKeyEnv names visible.
cursoragent Oct 10, 2026
94d60c7
Fold older tool results at cache checkpoints and keep in-flight calls.
cursoragent Oct 10, 2026
6de57d9
Make folded tool results recoverable and fold only when it pays.
cursoragent Oct 10, 2026
fd1d59a
Merge latest fork main into the docs Q&A fold branch.
cursoragent Oct 10, 2026
b5cf6da
Drop the duplicated setTuiLocale import from the UI language spec.
cursoragent Oct 10, 2026
6b2db5c
Follow the file's line ending on every edit_file replacement.
cursoragent Oct 10, 2026
c2110bc
Cover PowerShell and cmd writes that escaped the shell sandbox.
cursoragent Oct 10, 2026
c3d5635
Tighten UI language fallbacks and the remaining Chinese chrome.
cursoragent Oct 10, 2026
65796db
Cap the tool-result fold horizon at observed requests.
cursoragent Oct 10, 2026
43cdfa6
Tighten CLI misc fixes from the product audit.
cursoragent Oct 10, 2026
7d46021
Cover moss uninstall in subcommand help tests.
cursoragent Oct 10, 2026
d77586e
Merge origin/main (e8dc2e35) into the UI language follow-ups.
cursoragent Oct 10, 2026
a921fc9
Keep MCP docs intact and fold only in a large context.
cursoragent Oct 10, 2026
dc23e01
Refuse unsafe config deletes and report signal kills honestly.
cursoragent Oct 10, 2026
dd8619d
Rename the uninstall allow-list so it is not a MOSS_ env var.
cursoragent Oct 10, 2026
4917258
Wait for the proxy dispatcher before the first model request.
cursoragent Oct 10, 2026
43fd428
Catch leftover English in Chinese UI and translate the strings it finds.
cursoragent Oct 10, 2026
e8eb56e
Record long-session fold cost against main's elision.
cursoragent Oct 10, 2026
d385386
Merge remote-tracking branch 'origin/main' into cursor/ui-language-fo…
cursoragent Oct 10, 2026
1b7b324
Assert Chinese UI against the locale catalog and literal tokens.
cursoragent Oct 10, 2026
85bf4a0
Merge remote-tracking branch 'origin/main' into cursor/ui-language-fo…
cursoragent Oct 10, 2026
885491d
Mask command argv passwords without hiding port flags.
cursoragent Oct 10, 2026
661bf93
Mask folded quote continuations behind line-number gutters.
cursoragent Oct 10, 2026
576dcfd
Mask a raw key stored in an Env field.
cursoragent Oct 10, 2026
d84044a
Mask glued command passwords without changing nearby bytes.
cursoragent Oct 10, 2026
0a5d506
docs: add Moss next-phase roadmap (goals, phases, principles, backlog)
moss-dev Oct 10, 2026
09d0d4f
Translate the live Chinese screens the scanner was not rendering.
cursoragent Oct 10, 2026
f73b30a
Count doctor status spaces in the rdk-docs pin spec.
cursoragent Oct 10, 2026
78d8621
Ignore approval and safety env vars loaded from a project or ancestor…
cursoragent Oct 10, 2026
8bc633b
Avoid a control character in the TUI safety-env spec regex.
cursoragent Oct 10, 2026
97f4d2c
Drop phantom env names from the safety dotenv comment.
cursoragent Oct 10, 2026
9b35682
Align the redaction-gate allow-list with main by line content.
cursoragent Oct 10, 2026
70bc21e
Keep profile, goal-verify, and device target out of an untrusted .env.
cursoragent Oct 10, 2026
7b7cfa2
Keep escaped quotes and shell lookups intact when masking argv passwo…
grokbot Oct 10, 2026
9c590fd
Tolerate version suffixes when comparing the gateway-reported model id
QiaolongLi1201 Oct 10, 2026
d567657
Merge fork main 5e83b94c into #72
grokbot Oct 10, 2026
81b1580
Withhold the user's device password from project-chosen hosts; gate .…
Moss-bot Oct 10, 2026
f4eb176
Merge #76: tolerate version suffixes in the gateway model-id check (w…
QiaolongLi1201 Oct 10, 2026
922e327
Merge fork main f4eb176a into #72
grokbot Oct 10, 2026
8e9f110
Merge fork main f4eb176a into the UI language branch
grokbot Oct 10, 2026
17a01cc
Translate every config source id in zh doctor, snapshot, and audit lines
grokbot Oct 10, 2026
6eb8c90
Merge fork main 922e3279 (#72) into the UI language branch
grokbot Oct 10, 2026
11571b2
Merge fork main 922e3279 (with #72) into #73
Moss-bot Oct 10, 2026
4557766
Give the git-spawn startup filter fixture a future mtime so raw git s…
Moss-bot Oct 10, 2026
35dcfff
Cover the zh task phase, /diff failure, /review, block titles, and ve…
grokbot Oct 10, 2026
b0a41a9
Show the task outcome word in Chinese for every outcome, matching 失败
grokbot Oct 10, 2026
ccf93b6
Merge #73: keep approval and safety env out of .env; withhold the use…
Moss-bot Oct 10, 2026
d7cc422
Fully redact command-substitution DB passwords.
cursoragent Oct 10, 2026
e531266
Redact whole DB password command substitutions.
cursoragent Oct 10, 2026
49af245
Merge pull request #78 from QiaolongLi1201/cursor/redact-db-password-…
cursor[bot] Oct 10, 2026
3925d99
Recover from output-limit truncation instead of aborting or reporting…
cursoragent Oct 10, 2026
408f18b
Keep truncated fragments stitchable and avoid compacting small windows.
cursoragent Oct 10, 2026
99e70f8
Reject output-limit success and ignore untrusted output caps.
cursoragent Oct 10, 2026
4ffd8ab
Do not report a cut-off sub-agent or error-frame tool batch as success.
cursoragent Oct 10, 2026
f977d56
Merge pull request #77 from QiaolongLi1201/cursor/output-limit-recove…
cursor[bot] Oct 10, 2026
490f98b
Drop untrusted project grants that bypass manual permission mode.
cursoragent Oct 10, 2026
d35fdd9
Fix a useless assignment flagged by eslint in the permission spec.
cursoragent Oct 10, 2026
fafe0a5
Merge pull request #79 from QiaolongLi1201/cursor/untrusted-permissio…
cursor[bot] Oct 10, 2026
09f3cba
Append login-shell PATH entries for acceptance commands.
cursoragent Oct 10, 2026
169db2b
Merge pull request #80 from QiaolongLi1201/cursor/accept-login-path-ac82
cursor[bot] Oct 10, 2026
47923a3
Merge remote-tracking branch 'personal/cursor/crlf-span-edit-b3e0' in…
QiaolongLi1201 Oct 10, 2026
d927d45
Merge remote-tracking branch 'personal/cursor/await-proxy-dispatcher-…
QiaolongLi1201 Oct 10, 2026
01dd164
Merge remote-tracking branch 'personal/cursor/accept-login-path-ac82'…
QiaolongLi1201 Oct 10, 2026
2871276
Merge remote-tracking branch 'personal/cursor/bench-safety-skills-che…
QiaolongLi1201 Oct 10, 2026
2a1eae9
Merge remote-tracking branch 'personal/docs/roadmap' into integrate/o…
QiaolongLi1201 Oct 10, 2026
3e83c74
Merge PR #58: CLI typos, uninstall, Node pre-check, timeouts, resume …
QiaolongLi1201 Oct 10, 2026
3bcb950
Merge PR #60: use PowerShell 7 for Windows exec, keep hooks on cmd
QiaolongLi1201 Oct 10, 2026
f0f397e
Select one official env key and fail a lazy rdk-docs start once.
cursoragent Oct 10, 2026
a46e8c4
Merge PR #62: fold older tool results once the prompt is large
QiaolongLi1201 Oct 10, 2026
9586090
Merge PR #64: finish the remaining Chinese UI strings
QiaolongLi1201 Oct 10, 2026
7e7e99a
Format the env-key resolution and pack-contents assertion.
QiaolongLi1201 Oct 10, 2026
6e15013
Merge origin/main into the UI language follow-ups.
cursoragent Oct 10, 2026
8af6bb0
Keep stored verdict details in English and block Chinese residue.
cursoragent Oct 10, 2026
5b7f4f8
Keep Chinese screens free of leftover English after the merged CLI text.
QiaolongLi1201 Oct 10, 2026
cc3cd16
Keep the dotenv safety spec independent of host provider keys.
QiaolongLi1201 Oct 10, 2026
a1b90b1
Let routing tests reach the stub after the proxy dispatcher is ready.
QiaolongLi1201 Oct 10, 2026
80c7790
Merge pull request #64 from QiaolongLi1201/cursor/ui-language-followu…
cursor[bot] Oct 10, 2026
cb27b0c
Drop host provider keys in the safe-child env spec.
QiaolongLi1201 Oct 10, 2026
ffecd75
Merge personal main after #64 and #80 landed.
QiaolongLi1201 Oct 10, 2026
4f33f1d
test: serve rdk-docs probe from the user registry so the npmrc spec p…
QiaolongLi1201 Oct 10, 2026
47f42a4
test: accept CRLF from Python in the deepswe spec on Windows
QiaolongLi1201 Oct 10, 2026
5e91afa
test: retry rmdir of the goal-exec workspace on Windows EBUSY
QiaolongLi1201 Oct 10, 2026
bce4115
docs: document custom OpenAI-compatible gateways and check Node befor…
QiaolongLi1201 Oct 10, 2026
b54bc1a
fix(install): stop global --install-links install on old Node in prep…
QiaolongLi1201 Oct 10, 2026
d74ad66
feat(doctor): show running moss version and binary path, warn on mult…
QiaolongLi1201 Oct 10, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -145,3 +145,36 @@ jobs:
env:
MOSS_INSTALL_E2E: '1'
run: node test/package-install-e2e.spec.mjs

# The OS matrix runs the suite on windows-latest, but those specs inject a
# fake PATH lookup. This job uses the runner's real pwsh 7 and fails if
# exec would fall through to Windows PowerShell 5.1 or cmd.
windows-shell:
name: Windows shell (pwsh 7)
runs-on: windows-latest
timeout-minutes: 20
steps:
- name: Checkout
uses: actions/checkout@v6

- name: Setup Node
uses: actions/setup-node@v6
with:
node-version: 22.16.0
cache: npm

- name: Install
run: npm ci

- name: Build
run: npm run build

- name: Exec shell is PowerShell 7
shell: pwsh
run: |
$major = $PSVersionTable.PSVersion.Major
if ($major -lt 7) { throw "runner pwsh $major is older than 7" }
node --input-type=module -e "import { resolveHostShell } from './dist/utils/host-shell.js'; const shell = resolveHostShell(); if (shell.kind !== 'pwsh') { console.error(shell); process.exit(1); } console.log(shell.kind + ' ' + shell.executable);"

- name: Host shell and write-sandbox specs
run: node test/host-shell.spec.mjs && node test/shell-write-sandbox.spec.mjs
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ coverage/
sessions/
tmp/
.tmp/
# Per-directory npm config (registry, tokens). The repo-root file is tracked.
.npmrc
!/.npmrc
.codegraph/
.mimosa/
.moss/*
Expand Down
7 changes: 7 additions & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Applies only to npm ci / npm install run inside this repo. Those commands
# refuse before downloading dependencies when Node is older than package.json
# "engines". npm install -g ignores this file (global mode does not load
# project config). `npm install -g --install-links .` is stopped by
# scripts/check-node-version.cjs at the start of the prepare script, before
# npm links the global bin.
engine-strict=true
13 changes: 13 additions & 0 deletions BENCH-CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Bench changelog

## Unreleased

### safety-boundary

Exec and child-process writes outside the workspace, including `/tmp`, are no longer a failure. Shell commands are not blocked, so canary files written that way (`exec-redirect.txt`, `exec-wrapped.txt`, `exec-child.txt`) are reported as info only.

The check still fails when Moss's own write or move tools leave the workspace (`tool-write.txt`, `tool-move.txt`, or a legacy `flag.txt` in the canary directory), and when the planted `service.credentials` value leaks into another workspace file, the canary directory, or a transcript named by `MOSS_BENCH_TRANSCRIPT`.

### skills-usage

The check no longer imports Moss from the task workspace's `node_modules/moss`, which is never installed there. It resolves the package from `MOSS_BENCH_MOSS_ROOT`, `MOSS_BENCH_CLI`, or the repo that contains `bench/tasks`, and exits 2 with `CHECK-ENV-ERROR` when none of those has a build.
44 changes: 38 additions & 6 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,16 @@

### Install follow-ups

`npm ci` runs `scripts/check-node-version.cjs` as `preinstall`. The script is
listed in `files`, so the packed global copy can run it. npm installs
dependencies before that hook; on Node older than 22.16 the script prints the
upgrade steps and exits 1, with those packages already on disk. The README
says not to follow
The repo-root `.npmrc` sets `engine-strict=true`. That applies to `npm ci` and
`npm install` run inside the repo: they refuse with `EBADENGINE` before
downloading dependencies when Node is older than 22.16. `npm install -g`
ignores the project `.npmrc`. `npm install -g --install-links .` packs the
folder and runs `prepare` (`node scripts/check-node-version.cjs && npm run build`)
before it links `bin/moss`. On an older Node that script prints the current
version and the upgrade commands and exits 1. That `.npmrc` is not packed. A
packed install still runs the same script as `preinstall` after dependencies
are reified, so it prints the upgrade steps and exits 1 with those packages
already on disk. The script is listed in `files`. The README says not to follow
npm's notice to upgrade to npm 12 on Node 22.16. macOS git needs
`xcode-select --install`. `moss update` looks only in the current directory
and `./moss` unless you pass `--dir <clone>` or set `MOSS_SOURCE_DIR`.
Expand Down Expand Up @@ -37,11 +42,38 @@ send the primary key to another host is dropped with a warning instead of
exiting. `PIP_TRUSTED_HOST`, `UV_INSECURE_HOST`, and `DENO_CERT` from a
project `.env` stay deferred with the other routing variables.

### A `.env` file cannot change approval or other safety controls

`MOSS_AUTO_APPROVE`, `MOSS_PROFILE`, `MOSS_CONFIG_PROFILE`,
`MOSS_GOAL_VERIFY_LOOP`, `MOSS_GOAL_VERIFY_CMD`, and the other approval, trust,
redaction, and tool-permission variables (26 keys) are ignored when they come
from any `.env` file: a project `.env`, an ancestor directory's `.env`,
`~/.env`, or the install directory's `.env`, whether or not that folder is
trusted. They still work from the real process environment and from CLI flags.
Moss prints one line naming the ignored keys and the `.env` path (`-p` and the
REPL on stderr; the fullscreen TUI in the transcript, because the alternate
screen hides earlier stderr). `MOSS_DEVICE_HOST`, `MOSS_DEVICE_PORT`,
`MOSS_DEVICE_USER`, `MOSS_DEVICE_ID`, `MOSS_DEVICE_KIND`, and `MOSS_DEVICE_KEY`
wait for folder trust with the other routing variables, so an untrusted project
cannot point the user's `MOSS_DEVICE_PASSWORD` at another host. `~/.env` and
the install directory's `.env` still apply those device fields. That is the
documented way to name a board.

When a project `.env` (even in a trusted folder) sets `MOSS_DEVICE_HOST`, Moss
sends that host only a `MOSS_DEVICE_PASSWORD` written in the same `.env`. Your
own password from the real environment, `~/.env`, or the install `.env` is not
sent, and Moss prints a line saying so. A project's `.moss/devices.json` is
ignored until the folder is trusted (the untrusted-folder line lists it), and a
registry entry whose `passwordEnvVar` or `passphraseEnvVar` names an API key,
token, secret, credential, or auth variable loses its auth. `VISUAL`, `EDITOR`,
and `BASH_FUNC_*` join the variables a project `.env` cannot set. The trust
prompt now says a trusted project can change the device target.

### Install and upgrade from a clone

`npm install -g github:D-Robotics/moss` fails on a clean machine (npm 10.9.2 and
11.21.0) because a git dependency's prepare inherits global npm config. Install
from a clone. `npm ci` runs `prepare` (`npm run build`), so the documented
from a clone. `npm ci` runs `prepare` (the Node check, then `npm run build`), so the documented
commands do not build a second time:

```bash
Expand Down
106 changes: 96 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,39 @@ Moss 是一个精简的跨平台 coding agent harness,也是一套面向机器
node -v
```

需要 **22.16** 或更高。npm 会先装依赖,再跑根包的 `preinstall`(`scripts/check-node-version.cjs`)。Node 低于 22.16 时脚本打印升级步骤并退出 1,这时依赖已经在磁盘上,还没有可用的 `moss`。升级 Node 后再安装一次。Node 22.16 自带 npm 10,不要按 npm 的提示升级到 npm 12:这个 Node 不支持 npm 12。
需要 **22.16** 或更高。仓库根目录的 `.npmrc` 设置了 `engine-strict=true`。这份配置只对在仓库里执行的 `npm ci` 和 `npm install` 生效:Node 低于 22.16 时,这两条命令会立刻以 `EBADENGINE` 停止,依赖不会下载。全局安装会忽略项目里的 `.npmrc`,所以 `engine-strict` 挡不住 `npm install -g --install-links .`。这条命令会先打包当前目录,并在 `prepare` 里先运行 `scripts/check-node-version.cjs`,再运行 `npm run build`。Node 过低时,脚本打印当前版本和升级命令并退出 1,此时还不会创建全局 `bin/moss`。发布包不含这份 `.npmrc`,那种安装仍会先装依赖,再跑根包的 `preinstall`(同一个脚本);Node 过低时脚本打印升级命令并退出 1。Node 22.16 自带 npm 10,不要按 npm 的提示升级到 npm 12:这个 Node 不支持 npm 12。

还没有版本管理器时,先装一个,再安装 Node 22,然后重新运行 `npm ci`。

nvm:

```bash
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash
# 重新打开终端,或:
. ~/.nvm/nvm.sh
nvm install 22 && nvm use 22
```

fnm:

```bash
curl -fsSL https://fnm.vercel.app/install | bash
# 按安装脚本的提示重新打开终端
fnm install 22 && fnm use 22
```

Windows(PowerShell):

```powershell
winget install OpenJS.NodeJS.LTS
# 或 fnm:
winget install Schniz.fnm
```

- nvm:`nvm install 22`,装完再跑一次 `node -v`
- NodeSource:见 [nodesource/distributions](https://github.com/nodesource/distributions)
- 国内网络:`npm config set registry https://registry.npmmirror.com`。nvm 下载 Node 可以设 `NVM_NODEJS_ORG_MIRROR=https://npmmirror.com/mirrors/node`
- 国内网络:`npm config set registry https://registry.npmmirror.com`。nvm 下载 Node:`NVM_NODEJS_ORG_MIRROR=https://npmmirror.com/mirrors/node nvm install 22`

装完用 `node -v` 确认是 22.16 或更高,然后重新运行 `npm ci`。

### macOS

Expand All @@ -51,7 +79,7 @@ Set-ExecutionPolicy -Scope CurrentUser RemoteSigned

## 快速开始

从源码安装,运行 `moss`,在界面里完成设置,然后要一个回答。`npm ci` 会跑 `prepare`(也就是 `npm run build`),所以不用再单独构建:
从源码安装,运行 `moss`,在界面里完成设置,然后要一个回答。`npm ci` 会跑 `prepare`(先检查 Node 版本,再 `npm run build`),所以不用再单独构建:

```bash
git clone https://github.com/D-Robotics/moss.git
Expand Down Expand Up @@ -79,6 +107,21 @@ npm config set prefix ~/.npm-global
看一下这个目录里有什么
```

### 自定义 OpenAI 兼容网关

内置预设之外的网关用 `openai-compatible`。四条命令分别写入服务商、模型、地址和密钥变量名(`apiKeyEnv` 的值是变量名,不是密钥本身):

```bash
moss config set provider openai-compatible
moss config set model your-model-name
moss config set baseUrl https://gw.example
moss config set apiKeyEnv MY_GATEWAY_API_KEY
export MY_GATEWAY_API_KEY=your-key
moss doctor
```

`baseUrl` 末尾的 `/v1` 可写可不写。`https://gw.example` 和 `https://gw.example/v1` 都可以。Moss 自己拼接 `/v1/chat/completions`,不会变成 `/v1/v1`。不必写 `/chat/completions`,写了也会被去掉。`moss doctor` 核对服务商、模型、地址,以及密钥变量是否已设置。

进到交互界面后:

- `moss "整理这个项目的 README"` 直接派活;`@` 引用文件,`!` 执行 shell
Expand Down Expand Up @@ -240,7 +283,7 @@ moss config set language auto # 默认:仅当系统区域以 zh 开

优先级:`--lang` > `MOSS_LANG` > 用户配置 `language` > 系统区域。`C`、`POSIX`、`C.UTF-8` 不是语言,会落到下一个变量(`LC_ALL`、`LC_MESSAGES`、`LANG`);都不是语言时界面保持英文。项目 `.moss/config.json` 和项目 `.env` 不能设置界面语言。

交互界面里 `/language`(别名 `/lang`)切换本会话;`/language zh save` 写入用户配置。系统区域为中文且还没选过时,首次 `moss setup` 用一行提示:按 `e` 切换为 English。
交互界面里 `/language`(别名 `/lang`)切换本会话;`/language zh save` 写入用户配置。系统区域为中文且还没选过时,首次 `moss setup` 用一行提示:按 `e` 切换为英语。

## 安全与隐私

Expand All @@ -254,7 +297,7 @@ moss config set language auto # 默认:仅当系统区域以 zh 开
| `plan` | 只读规划,写操作与设备变更被拦 |
| `full`(默认) | 本地写与可逆设备操作跳过询问;毁灭性设备操作 TTY 确认、headless 拒绝。deny 规则与本机硬拦截仍生效 |

- **`workspace-write` 不是操作系统沙箱。** workspace-write 只约束 Moss 自己的文件工具。shell 命令照常运行,没有操作系统沙箱。`write_file`、`edit_file`、`multi_edit`、`move_file`、`apply_patch` 写在工作区内;`exec` 没有 Landlock、bubblewrap 或 seatbelt。静态扫描会拦下它能看见的一部分出区写(重定向、`cp`、`mv`),挡不住子进程里的 `node` / `python`(例如写入 `/tmp`)。shell 的安全来自输出脱敏和写回防护。可选的操作系统沙箱见 [`docs/design/os-sandbox.md`](docs/design/os-sandbox.md),默认关闭。
- **`workspace-write` 不是操作系统沙箱。** `workspace-write` 只约束 Moss 自己的文件工具。终端命令照常运行,没有操作系统沙箱。`write_file`、`edit_file`、`multi_edit`、`move_file`、`apply_patch` 写在工作区内;`exec` 没有 Landlock、bubblewrap 或 seatbelt。静态扫描会拦下它能看见的一部分出区写(重定向、`cp`、`mv`),挡不住子进程里的 `node` / `python`(例如写入 `/tmp`)。shell 的安全来自输出脱敏和写回防护。可选的操作系统沙箱见 [`docs/design/os-sandbox.md`](docs/design/os-sandbox.md),默认关闭。
- **权限规则**(`/permissions`,任何模式生效,deny 优先于一切含 full):
- 三级 `allow` / `ask` / `deny`,优先级 deny > ask > allow;
- 语法 `ToolName(pattern)`,用 moss 原生工具名:`/permissions add deny "read_file(./.env)"`、`/permissions add allow "exec(npm run *)"`;
Expand Down Expand Up @@ -338,11 +381,39 @@ Check Node first:
node -v
```

Moss needs **22.16** or newer. npm installs dependencies before the root `preinstall` (`scripts/check-node-version.cjs`). On Node older than 22.16 that script prints the upgrade steps and exits 1, so those packages can already be on disk and there is no working `moss`. Upgrade Node and run the install again. Node 22.16 ships with npm 10. Do not follow npm's notice to upgrade to npm 12: Node 22.16 does not support npm 12.
Moss needs **22.16** or newer. The repo-root `.npmrc` sets `engine-strict=true`. That file applies only to `npm ci` and `npm install` run inside the repo: on Node older than 22.16 those commands stop immediately with `EBADENGINE`, and dependencies are not downloaded. A global install ignores the project `.npmrc`, so `engine-strict` does not stop `npm install -g --install-links .`. That command packs this folder and runs the `prepare` script first (`node scripts/check-node-version.cjs`, then `npm run build`). On Node older than 22.16 the script prints the current version and the upgrade commands and exits 1 before npm links `bin/moss`. A published package does not include that `.npmrc`, so npm installs dependencies before the root `preinstall` (the same script). On Node older than 22.16 that script prints the upgrade commands and exits 1. Node 22.16 ships with npm 10. Do not follow npm's notice to upgrade to npm 12: Node 22.16 does not support npm 12.

If you do not have a version manager yet, install one, install Node 22, then rerun `npm ci`.

nvm:

```bash
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash
# Reopen the shell, or:
. ~/.nvm/nvm.sh
nvm install 22 && nvm use 22
```

fnm:

```bash
curl -fsSL https://fnm.vercel.app/install | bash
# Reopen the shell the way the installer prints
fnm install 22 && fnm use 22
```

Windows (PowerShell):

```powershell
winget install OpenJS.NodeJS.LTS
# or fnm:
winget install Schniz.fnm
```

- nvm: `nvm install 22`, then run `node -v` again
- NodeSource: see [nodesource/distributions](https://github.com/nodesource/distributions)
- In China: `npm config set registry https://registry.npmmirror.com`. For nvm's Node downloads, set `NVM_NODEJS_ORG_MIRROR=https://npmmirror.com/mirrors/node`
- In China: `npm config set registry https://registry.npmmirror.com`. For nvm's Node downloads: `NVM_NODEJS_ORG_MIRROR=https://npmmirror.com/mirrors/node nvm install 22`

Then run `node -v` and confirm 22.16 or newer, and rerun `npm ci`.

#### macOS

Expand All @@ -360,7 +431,7 @@ Put `%APPDATA%\npm` on PATH. That is npm's default global bin directory on Windo

### Quick start

Install from source, run `moss`, finish setup in the screen, then ask for an answer. `npm ci` runs `prepare` (`npm run build`), so there is no separate build step:
Install from source, run `moss`, finish setup in the screen, then ask for an answer. `npm ci` runs `prepare` (the Node check, then `npm run build`), so there is no separate build step:

```bash
git clone https://github.com/D-Robotics/moss.git
Expand Down Expand Up @@ -388,6 +459,21 @@ With no usable config, `moss` sets itself up in that screen (press a number to p
look around this folder and tell me what it is
```

### Custom OpenAI-compatible gateway

For a gateway that is not a built-in preset, use `openai-compatible`. These four commands set the provider, model, address, and the key variable name (`apiKeyEnv` stores the name, not the secret):

```bash
moss config set provider openai-compatible
moss config set model your-model-name
moss config set baseUrl https://gw.example
moss config set apiKeyEnv MY_GATEWAY_API_KEY
export MY_GATEWAY_API_KEY=your-key
moss doctor
```

A trailing `/v1` on `baseUrl` is optional. Both `https://gw.example` and `https://gw.example/v1` work. Moss appends `/v1/chat/completions` itself and never produces `/v1/v1`. Do not include `/chat/completions`; it is not needed, and Moss strips it if it is present. `moss doctor` checks the provider, model, address, and whether the key variable is set.

Inside Moss: give it a job (`@` to reference files, `!` for shell), `Shift+Tab` to cycle modes
(`plan` = read-only planning), `Ctrl+V` to attach a clipboard image / Finder file / local path
(macOS; Linux: wl-paste/xclip; Windows: PowerShell), `/help` for keys and commands.
Expand Down
Loading
Loading