diff --git a/INSTALL.md b/INSTALL.md index 2971ae9..bdccdbd 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -6,7 +6,7 @@ ## 完成标准 -- 下载本文件所在的同一固定 Release,不使用默认分支; +- 从 Gitea `main` 解析安装开始时的最新完整 Commit SHA,并将本次安装的文档、源码和构建全部固定到该 Commit; - 只连接固定的 NocoBase API `https://justconn.top/api`; - MCP 在用户本机以 stdio 运行,默认只读; - 通过 NocoBase 原生 OAuth 2.1 认证当前用户,权限仍跟随本人的业务角色; @@ -20,28 +20,39 @@ - OAuth Token 不得进入聊天、命令参数、环境变量、CRM 配置、剪贴板日志或 MCP 客户端配置。 - 不使用 `sudo`,不执行 `curl | sh` 或 `wget | sh`。 - 不静默安装 Git、Node.js、包管理器或其他系统工具。 +- 解析 `main` 后只使用带完整 Commit SHA 的不可变 URL;一次安装中不得再次读取移动中的 `main` 文件。 +- 最新 Commit 无法下载、检查、测试或构建时必须停止,不得静默退回旧 Release、旧 Commit 或其他来源。 - 修改 MCP 客户端配置前展示目标文件与新增项,创建备份,并结构化合并;不得覆盖其他 server。 - 默认不启用写入、原始数据、后台服务或网络监听。 - 不询问或接受其他 NocoBase URL,也不允许通过参数、配置或凭证文件覆盖固定 API 地址。 ## 安装流程 -### 1. 确认本机位置与 Release 权限 +### 1. 解析并固定最新 Commit 确定当前 Agent/MCP 客户端及其配置路径,以及普通用户应用数据目录。NocoBase API 已固定为 `https://justconn.top/api`,不需要向用户询问地址。 -从本文件 URL 解析固定 Release Tag。读取同一 Release 的资产列表,只接受: +安装源固定为: -- `donaldttt-nocobase-crm-mcp-.tgz`; -- `SHA256SUMS`。 +- 仓库:`https://git.justconn.top/gitea-admin/nocobase-mcp` +- 分支:`main` +- 分支 API:`https://git.justconn.top/api/v1/repos/gitea-admin/nocobase-mcp/branches/main` -仓库访问受限时,必须使用当前用户已经授权的代码托管平台连接读取 Release;无权访问时停止,不得退回默认分支、源码 clone 或索取用户的访问令牌到聊天。 +通过当前用户已经授权的 Gitea API/连接读取分支 API,只解析一次 `commit.id`,并验证它是 40 位十六进制完整 SHA。记录为 `` 后,本次安装即使发现 `main` 又有新提交,也继续完成这个已固定快照;下一次安装才重新解析最新提交。 + +立即从以下不可变地址重新读取安装协议,后续不再依赖最初的 `main` 页面内容: + +```text +https://git.justconn.top/gitea-admin/nocobase-mcp/raw/commit//INSTALL.md +``` + +仓库访问受限时必须使用当前用户已有的授权连接;无权访问时停止,不得索取或接收用户在聊天中发送的 Gitea 访问令牌。 ### 2. 一次性说明本机变更 检查 `node --version` 和 `npm --version`。要求 Node.js `>=20.11`。 -如果 Node.js 缺失或版本过低,向用户说明需要安装或升级 Node.js、官方来源、目标位置和影响,取得明确同意后再使用操作系统的正规安装方式。不能因为 npm 不存在就直接尝试全局安装。 +如果 Node.js 缺失或版本过低,向用户说明需要安装或升级 Node.js、官方来源、目标位置和影响,取得明确同意后再使用操作系统的正规安装方式。不能因为 npm 不存在就直接尝试全局安装。还需确认 npm 能读取锁定依赖;不得改用未锁定的依赖版本。 正常安装只会留下: @@ -50,25 +61,46 @@ - 权限受限的本机凭证文件; - MCP 客户端配置及其备份。 -不会安装 Git、Python、uv、`nb CLI`、后台服务或本机监听端口。 +源码快照、构建期 `node_modules` 和本地 tarball 只放在新建的临时目录,安装完成后不作为持久文件保留。不会安装 Git、Python、uv、`nb CLI`、后台服务或本机监听端口。 -### 3. 下载并验证固定发布物 +### 3. 下载、验证并构建固定 Commit -通过当前 Gitea 实例或经批准分发渠道的已授权 API/连接,将两个 Release 资产下载到新建的临时目录。验证 tarball 的 SHA-256 与 `SHA256SUMS` 完全一致;不一致立即停止并删除未使用的下载文件。 +在新建的临时目录中下载 `` 的源码归档,不下载 Release 资产,也不从移动的 `main` URL 下载源码。Windows 使用 `.zip`,macOS/Linux 使用 `.tar.gz`;两种归档都必须包含同一个已解析的完整 Commit SHA: + +```text +Windows: https://git.justconn.top/gitea-admin/nocobase-mcp/archive/.zip +macOS/Linux: https://git.justconn.top/gitea-admin/nocobase-mcp/archive/.tar.gz +``` + +不要让用户选择版本,也不要因为操作系统不同而改用 Release。每次新的安装任务都重新解析当时 `main` 的最新 Commit,随后只下载并使用该 SHA。 + +下载后记录归档 SHA-256。解包前拒绝绝对路径、`..` 路径穿越或逃出临时目录的链接;源码根目录必须包含 `package.json`、`package-lock.json`、`install-manifest.json`、`INSTALL.md` 和 `src/`。 + +确认归档中的 `install-manifest.json` 声明 `distribution.branch` 为 `main`、`distribution.strategy` 为 `resolve-latest-commit-then-pin`。随后只在这个临时源码目录运行: + +```bash +npm ci +npm run check +npm test +npm run build +npm pack --pack-destination +``` + +任何一步失败都停止并报告 `` 与失败步骤,不得改装旧 Release。记录本地生成 npm tarball 的 SHA-256;安装结束时只报告哈希,不发送或上传 tarball。 选择用户级安装前缀,例如: -- Windows:`%LOCALAPPDATA%\NocoBaseMCP\app` -- macOS:`~/Library/Application Support/NocoBaseMCP/app` +- Windows:`%LOCALAPPDATA%\nocobase-crm-mcp\app` +- macOS:`~/Library/Application Support/nocobase-crm-mcp/app` - Linux:`${XDG_DATA_HOME:-~/.local/share}/nocobase-crm-mcp/app` 执行隔离安装,不使用全局目录: ```bash -npm install --prefix --omit=dev +npm install --prefix --omit=dev ``` -定位安装后的命令:POSIX 为 `/node_modules/.bin/nocobase-crm-mcp`,Windows 为相同目录下的 `nocobase-crm-mcp.cmd`。 +定位安装后的命令:POSIX 为 `/node_modules/.bin/nocobase-crm-mcp`,Windows 为相同目录下的 `nocobase-crm-mcp.cmd`。运行 `--version` 和 `--help`,确认版本等于源码 `package.json`,并且帮助中包含本 Commit 安装协议使用的 `setup --no-browser` 选项;不一致时停止,不得继续注册旧二进制。 ### 4. 浏览器登录 NocoBase @@ -88,6 +120,8 @@ npm install --prefix --omit=dev 然后由用户手动打开链接。设备授权约十分钟后失效;密码和浏览器会话始终留在 NocoBase,安装程序不会读取浏览器 Cookie。访问令牌临近过期时会自动使用刷新令牌续期,不影响日常 MCP 调用。 +在 Hermes Agent、OpenClaw 或其他远程无界面环境中,Agent 应在可持续读取输出的后台会话运行 `setup --no-browser --json`,取得授权链接和确认码后立即通过当前消息通道发给用户,同时让进程继续轮询。只能转发 HTTPS 授权链接、用户确认码和有效期,绝不能转发 OAuth Token、设备码或凭据文件内容。一个 MCP 进程只能服务一个受信任的用户身份;多用户必须使用相互隔离的 Agent/MCP 实例和凭据路径。 + POSIX 凭证目录使用 `0700`,凭证文件使用 `0600`。Windows 使用当前用户应用数据目录。凭证文件不保存或接受 API 地址,Token 不会出现在返回 JSON、命令参数、MCP 配置或日志中。不要复制其他用户的凭证文件;每个操作系统用户都必须单独登录。 只有在 OAuth 暂时不可用、管理员明确要求且用户拥有个人 Authorize Key 时,才使用: @@ -108,7 +142,7 @@ POSIX 凭证目录使用 `0700`,凭证文件使用 `0600`。Windows 使用当 4. 重载或重启 MCP 客户端; 5. 调用 `crm_health`,要求 `ok=true`。 -最终只报告 Release、安装目录、配置备份位置、认证方式和只读/写入模式,不显示任何 Token 或 Key。 +最终只报告完整 Commit SHA、源码版本、本地构建 tarball 的 SHA-256、安装目录、配置备份位置、认证方式和只读/写入模式,不显示任何 Token 或 Key。 ## 可选写入 @@ -121,11 +155,13 @@ POSIX 凭证目录使用 `0700`,凭证文件使用 `0600`。Windows 使用当 - `nocobase_auth_failed`:重新运行 `setup` 完成浏览器登录;不要换用共享高权限 Token 或 Key。 - `nocobase_request_failed` / `NO_PERMISSIONS`:检查用户角色、字段权限、行级权限与 `config.json` 映射,不得换用共享高权限身份。 - Node.js 缺失:报告前置条件并请求用户授权正规安装,不退回 Python/uv/nb CLI 方案。 -- 受限 Release 无权访问:报告 Gitea 或分发渠道的权限问题,不退回 clone 默认分支。 +- `main` 或 Commit 归档无权访问:报告 Gitea 权限问题,不索取聊天中的访问令牌,也不退回旧 Release。 +- 最新 Commit 的依赖安装、检查、测试或构建失败:报告 SHA 和原始失败步骤后停止;不得以“先装可用版本”为由降级。 +- 安装过程中 `main` 更新:不影响当前任务,继续完成开始时固定的 SHA;下次安装再取得新 SHA。 ## 用户可发送给 Agent 的最短指令 ```text -请按这个固定 Release 的协议帮我完成本机安装。默认只读;请运行 setup,让我只在 NocoBase 官方网页登录并确认授权。不要向我索要密码、Token 或 Authorize Key,也不要静默安装系统工具。完成前必须验证 crm_health: -<固定 Release 的 INSTALL.md 链接> +请按这个 INSTALL.md 帮我完成安装。每次先解析当前 Gitea 仓库 main 分支的最新完整 Commit SHA,并把本次安装固定在该 Commit;不要退回旧 Release。默认只读;请运行 setup,让我只在 NocoBase 官方网页登录并确认授权。不要向我索要密码、Token 或 Authorize Key,也不要静默安装系统工具。完成前必须验证 crm_health: +https://git.justconn.top/gitea-admin/nocobase-mcp/raw/branch/main/INSTALL.md ``` diff --git a/README.md b/README.md index 97dd281..2647f85 100644 --- a/README.md +++ b/README.md @@ -11,28 +11,33 @@ - Node.js 20.11 或更高版本; - 能访问 `https://justconn.top`; - 你自己的 NocoBase 账号; -- 能读取当前 Gitea 仓库对应 Release 的权限。 +- 能读取当前 Gitea 仓库 `main` 分支,并能访问 npm 软件源。 如果 Node.js 尚未安装,安装 Agent 会先说明需要进行的系统变更,并在获得你确认后再继续。 +支持 Windows、macOS 和 Linux。三个平台都会安装 `main` 在任务开始时的最新 Commit;Windows 下载该 Commit 的 `.zip`,macOS/Linux 下载同一 Commit 的 `.tar.gz`。 + 不需要提前创建或复制 Authorize Key。安装程序会打开 NocoBase 官方网页;你在网页中登录并确认授权后,本机安装会自动继续。 ### 最快安装方式 -1. 打开当前 Gitea 仓库的 **Releases(版本发布)** 页面,选择要安装的固定版本。 -2. 确认该版本包含 npm 安装包和 `SHA256SUMS`,然后打开同一版本下的 `INSTALL.md`。不要使用默认分支中的安装说明代替固定版本。 -3. 把这个固定版本的 `INSTALL.md` 链接和下面的文字一起发给安装 Agent: +把下面整段直接复制给安装 Agent: ```text -请按这个固定版本的安装协议帮我完成 NocoBase CRM MCP 本机安装。 +请按这个 INSTALL.md 帮我完成 NocoBase CRM MCP 安装。 +每次先解析当前 Gitea 仓库 main 分支的最新完整 Commit SHA,并把本次安装固定在该 Commit;不要退回旧 Release。 默认只读;请运行 setup,让我只在 NocoBase 官方网页完成登录和授权。 不要向我索要密码、Token 或 Authorize Key,也不要静默安装系统工具。完成前请验证 crm_health 返回 ok=true。 + +安装协议: +https://git.justconn.top/gitea-admin/nocobase-mcp/raw/branch/main/INSTALL.md ``` -4. 浏览器打开后,在 `justconn.top` 登录并核对页面与终端显示的确认码,然后点击授权。浏览器没有自动打开时,复制终端显示的授权链接手动打开。 -5. 安装完成后,确认 Agent 报告 `crm_health` 返回 `ok=true`。 +1. Agent 会读取 Gitea `main` 的最新 Commit,把源码快照、安装协议和构建过程固定到同一个 SHA,再在临时目录完成检查和打包。 +2. 浏览器打开后,在 `justconn.top` 登录并核对页面与终端显示的确认码,然后点击授权。远程或无界面 Agent 会把授权链接和确认码发到当前对话。 +3. 安装完成后,确认 Agent 报告完整 Commit SHA,并且 `crm_health` 返回 `ok=true`。 -完整的安装和验收规则见 [INSTALL.md](INSTALL.md)。实际安装时应使用所选 Release Tag 中的同一文件。 +完整的安装和验收规则见 [INSTALL.md](INSTALL.md)。该 `main` 链接是安装入口;Agent 必须先解析一次最新 Commit,然后重新读取该 Commit 中不可变的同一文件,不能在一次安装中混用不同提交。 ## 重要注意事项 @@ -40,8 +45,9 @@ - **默认只读:** 安装后默认只能查询 CRM,不会创建、更新或删除业务数据。 - **权限跟随本人:** MCP 不会绕过 NocoBase 的角色、字段权限和行级权限,也不会使用共享管理员账号。 - **只连接公司环境:** 程序固定连接 `https://justconn.top/api`,不会要求你填写其他 NocoBase 地址。 -- **安装在用户目录:** 不使用 `sudo`,不会全局安装本项目,也不需要 Git、Python、uv 或 `nb CLI`。 -- **受限仓库需要授权:** 如果 Agent 无法读取 Gitea Release,请联系仓库管理员开通权限,不要把访问令牌发到聊天中。 +- **始终安装最新提交:** 每次安装只解析一次 `main` 的最新 Commit SHA,随后固定该快照完成构建;不会因为旧 Release 可用而安装旧代码。 +- **安装在用户目录:** 不使用 `sudo`,不会全局安装本项目,也不需要 Git、Python、uv 或 `nb CLI`。源码和构建依赖只存在于临时目录,安装后仅保留打包运行文件。 +- **受限仓库需要授权:** 如果 Agent 无法读取 Gitea `main` 或对应 Commit 快照,请联系仓库管理员开通权限,不要把访问令牌发到聊天中。 ## 安装后可以做什么 @@ -75,13 +81,14 @@ - 仅在 OAuth 暂时不可用且管理员明确要求时,才使用 `setup --manual-key` 的隐藏输入备用模式;不要把 Key 发到聊天中。 - 返回 `NO_PERMISSIONS`:请检查本人 NocoBase 角色和数据权限。 - 请求超时:确认可以访问 `https://justconn.top`,或缩小查询范围。 -- Release 无法下载:确认当前账号或 Agent 已获得 Gitea 仓库和 Release 的读取权限。 +- 最新 Commit 无法解析或构建失败:停止安装并报告 Commit SHA 和失败步骤,不要退回旧 Release。 +- 源码快照无法下载:确认当前账号或 Agent 已获得 Gitea 仓库的读取权限。 更多故障处理和更新、回滚说明见 [本机交付与权限验收](docs/LOCAL_DELIVERY.md)。 ## 更多文档 -- [完整安装协议](INSTALL.md):供安装 Agent 执行的固定版本安装与验收流程。 +- [完整安装协议](INSTALL.md):供安装 Agent 解析并固定最新 Commit、构建、安装和验收。 - [命令与工具参考](docs/REFERENCE.md):CLI 命令、MCP 工具和可选运行开关。 - [内部架构](docs/ARCHITECTURE.md):模块边界、身份与网络安全设计。 - [本机交付与权限验收](docs/LOCAL_DELIVERY.md):运维、权限验收、更新和回滚。 @@ -98,4 +105,4 @@ npm run build node dist/index.js --help ``` -本项目要求 Node.js 20.11 或更高版本。正式 Release 已将运行代码和依赖打包,最终用户不需要源码开发环境。 +本项目要求 Node.js 20.11 或更高版本。安装 Agent 会在临时目录从锁定依赖构建最新 Commit;最终运行包不含额外 npm 运行时依赖,用户不需要长期保留源码开发环境。 diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md index 98dd2f6..6c7139b 100644 --- a/docs/ARCHITECTURE.md +++ b/docs/ARCHITECTURE.md @@ -15,7 +15,7 @@ MCP client → TypeScript tool boundary → CRM domain service → NocoBaseClien - `src/nocobase-client.ts` 是唯一远程适配器,直接实现 NocoBase resource action 协议、data-modeling 读取、项目附件关系和 ACL 检查。 - `src/crm-service.ts` 负责 CRM 查询、解析、分页、聚合和可读输出;`src/crm-helpers.ts` 与 `src/filters.ts` 保存纯函数。 - `src/project-service.ts` 只允许固定项目字段的 create/update;`src/tools.ts` 是稳定 MCP 契约和错误/原始数据策略边界。 -- `scripts/build.mjs` 用 esbuild 将 MCP SDK、Zod 和所有运行代码打成一个 ESM 文件。Release tarball 没有运行时 npm 依赖。 +- `scripts/build.mjs` 用 esbuild 将 MCP SDK、Zod 和所有运行代码打成一个 ESM 文件。按 Commit 构建的安装 tarball 和正式 Release tarball 都没有运行时 npm 依赖。 ## 身份与网络安全 @@ -33,4 +33,5 @@ MCP client → TypeScript tool boundary → CRM domain service → NocoBaseClien - 写模式只增加 `create_project`、`update_project`,不提供 delete/destroy。 - `include_raw` 默认在 MCP 边界拒绝。 - 配置继续接受 camelCase 与 snake_case 字段别名。 -- Release Tag、`package.json` 和 `install-manifest.json` 的版本必须一致。 +- 默认安装先解析 Gitea `main` 的最新完整 Commit SHA,再在同一快照中读取协议、检查、测试、构建和打包;失败时不回退旧 Release。 +- 正式 Release 仍要求 Tag、`package.json` 和 `install-manifest.json` 的版本一致,但 Release 不再是默认安装前提。 diff --git a/docs/LOCAL_DELIVERY.md b/docs/LOCAL_DELIVERY.md index e1b0a1b..1063b77 100644 --- a/docs/LOCAL_DELIVERY.md +++ b/docs/LOCAL_DELIVERY.md @@ -10,14 +10,19 @@ 项目不保存共享业务账号,也不需要多人共用的远程 MCP 服务。个人 Authorize Key 仅作为显式备用认证方式。 -## Release 发布物 +## 最新 Commit 交付 -Release workflow 会在带版本 Tag 时执行锁定安装、类型/格式检查、测试、bundle、npm pack 和生产依赖审计,并上传: +默认安装不等待 Release。Agent 在每次安装开始时读取 Gitea `main` 的最新完整 Commit SHA,然后把这次任务固定在该 SHA: -- npm tarball; -- `SHA256SUMS`。 +- 从带 SHA 的不可变 URL 重新读取 `INSTALL.md`; +- 下载同一 SHA 的源码归档; +- 在临时目录执行锁定依赖安装、检查、测试、bundle 和 npm pack; +- 将本地生成的运行 tarball 安装到用户级隔离前缀; +- 报告完整 Commit SHA 和本地 tarball SHA-256。 -Gitea 仓库访问受限时,外部用户必须具有 Release 下载权限,或通过另一个经过身份认证的分发渠道取得相同资产。受限仓库链接本身不能成为任意用户可访问的一键安装链接。 +解析 SHA 后,即使 `main` 在安装期间更新,也不混入新文件;下一次安装才采用更新后的提交。任何检查或构建失败都停止,不回退旧 Release。正式 Release 可以继续用于归档和人工回滚,但不是默认安装来源。 + +Gitea 仓库访问受限时,用户或 Agent 必须具有源码和 Commit 归档读取权限。受限仓库链接本身不能成为任意用户可访问的一键安装链接,也不得通过聊天传递访问令牌。 ## 用户电脑上的内容 @@ -27,7 +32,7 @@ Gitea 仓库访问受限时,外部用户必须具有 Release 下载权限, - 当前 OS 用户的私有凭证文件; - MCP 客户端配置和备份。 -不需要 Git、Python、uv、`nb CLI` 或项目源码 checkout。npm 只在隔离前缀安装一个已经 bundle 的包,运行时没有额外 npm 依赖。 +不需要 Git、Python、uv、`nb CLI` 或持久源码 checkout。npm 在临时目录安装锁定的构建依赖并生成 bundle,随后只在隔离前缀安装本地 tarball;运行时没有额外 npm 依赖。临时源码和构建依赖不属于持久安装内容。 ## 权限验收 @@ -43,9 +48,9 @@ Gitea 仓库访问受限时,外部用户必须具有 Release 下载权限, ## 更新与回滚 -Agent 下载新的固定 Release tarball并验证 SHA-256,再对同一隔离前缀运行 `npm install --prefix ... --omit=dev `。安装前备份 MCP 客户端配置和非秘密 CRM 配置。 +更新时,Agent 重新解析 `main` 的最新 Commit,在新临时目录完成全部检查和构建,再对同一隔离前缀运行 `npm install --prefix ... --omit=dev `。安装前备份 MCP 客户端配置和非秘密 CRM 配置,并记录更新前后的完整 Commit SHA。 -回滚时重新安装上一固定 Release 的已验证 tarball。凭证文件与 CRM 配置位于包目录之外,更新和回滚不应复制、覆盖或删除个人 OAuth 凭据。 +回滚是唯一允许选择旧提交的安装操作:使用上次记录的完整 Commit SHA 重建并安装该快照,不通过移动分支名猜测版本。凭证文件与 CRM 配置位于包目录之外,更新和回滚不应复制、覆盖或删除个人 OAuth 凭据。 ## 常见故障 diff --git a/docs/REFERENCE.md b/docs/REFERENCE.md index 76ae315..7a985e0 100644 --- a/docs/REFERENCE.md +++ b/docs/REFERENCE.md @@ -1,6 +1,6 @@ # 命令与工具参考 -本文面向集成者和维护者。普通用户请从仓库根目录的 [README](../README.md) 开始,安装 Agent 请使用固定 Release Tag 中的 [INSTALL.md](../INSTALL.md)。 +本文面向集成者和维护者。普通用户请从仓库根目录的 [README](../README.md) 开始;安装 Agent 应从 `main` 的 [INSTALL.md](../INSTALL.md) 进入,先解析最新完整 Commit SHA,再固定该快照完成安装。 ## CLI 命令 diff --git a/install-manifest.json b/install-manifest.json index 4476d1b..dd782b4 100644 --- a/install-manifest.json +++ b/install-manifest.json @@ -1,20 +1,23 @@ { - "schemaVersion": 2, + "schemaVersion": 3, "id": "com.nocobase.crm-mcp", "name": "NocoBase CRM MCP", "version": "0.4.0", "distribution": { - "repository": "https://git.justconn.top/admin/nocobase-mcp", - "releaseRef": "must-match-v", - "guide": "INSTALL.md from the exact Release tag", - "assets": ["donaldttt-nocobase-crm-mcp-.tgz", "SHA256SUMS"], - "accessRequirement": "Private Release download requires an authenticated user or Agent with explicit repository access." + "repository": "https://git.justconn.top/gitea-admin/nocobase-mcp", + "branch": "main", + "strategy": "resolve-latest-commit-then-pin", + "releaseRequired": false, + "guide": "INSTALL.md from the resolved full commit SHA", + "sourceArchive": "Gitea source archive for the resolved full commit SHA", + "build": ["npm ci", "npm run check", "npm test", "npm run build", "npm pack"], + "accessRequirement": "Source download requires an authenticated user or Agent with explicit Gitea repository access." }, "runtime": { "location": "user-device", "defaultTransport": "stdio", "node": ">=20.11", - "packageFormat": "bundled-npm-tarball", + "packageFormat": "commit-pinned locally bundled npm tarball", "runtimeNpmDependencies": 0, "nocobaseCli": false, "python": false @@ -28,6 +31,8 @@ "installation": { "requiredTools": ["node", "npm"], "sourceCheckout": false, + "temporarySourceArchiveBuild": true, + "fallbackToRelease": false, "globalPackageInstall": false, "persistentArtifacts": [ "isolated user-data npm prefix", diff --git a/test/cli-package.test.ts b/test/cli-package.test.ts index 6efbff7..84babb9 100644 --- a/test/cli-package.test.ts +++ b/test/cli-package.test.ts @@ -6,16 +6,40 @@ import test from "node:test"; import { clientConfig, runCli } from "../src/cli.js"; import { VERSION } from "../src/version.js"; -test("package, manifest, and runtime versions agree with no runtime npm dependencies", () => { +test("package, manifest, and runtime versions agree with commit-pinned installation", () => { const packageJson = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf8")); const manifest = JSON.parse(readFileSync(new URL("../install-manifest.json", import.meta.url), "utf8")); assert.equal(VERSION, "0.4.0"); assert.equal(packageJson.version, VERSION); assert.equal(manifest.version, VERSION); + assert.equal(manifest.schemaVersion, 3); + assert.equal(manifest.distribution.branch, "main"); + assert.equal(manifest.distribution.strategy, "resolve-latest-commit-then-pin"); + assert.equal(manifest.distribution.releaseRequired, false); + assert.equal(manifest.distribution.releaseRef, undefined); + assert.equal(manifest.installation.temporarySourceArchiveBuild, true); + assert.equal(manifest.installation.fallbackToRelease, false); assert.deepEqual(packageJson.dependencies, undefined); assert.equal(manifest.runtime.runtimeNpmDependencies, 0); }); +test("installation protocol resolves main once and never falls back to an old Release", () => { + const guide = readFileSync(new URL("../INSTALL.md", import.meta.url), "utf8"); + const readme = readFileSync(new URL("../README.md", import.meta.url), "utf8"); + const installUrl = "https://git.justconn.top/gitea-admin/nocobase-mcp/raw/branch/main/INSTALL.md"; + assert.match(guide, /branches\/main/); + assert.match(guide, /40 位十六进制完整 SHA/); + assert.match(guide, /resolve-latest-commit-then-pin/); + assert.match(guide, /archive\/\.zip/); + assert.match(guide, /archive\/\.tar\.gz/); + assert.match(guide, /Windows 使用 `.zip`/); + assert.match(guide, /不得.*退回旧 Release/); + assert.ok(guide.includes(installUrl)); + assert.ok(readme.includes(installUrl)); + assert.doesNotMatch(guide, /下载本文件所在的同一固定 Release/); + assert.doesNotMatch(readme, /
/); +}); + test("generated MCP config contains no Key, token, or environment secret", () => { const config = clientConfig("/private/config.json", false); const serialized = JSON.stringify(config);