@qingchencloud/openclaw-updater 1.0.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 +137 -0
- package/dist/index.cjs +17 -0
- package/dist/index.d.cts +133 -0
- package/dist/index.d.ts +133 -0
- package/dist/index.js +17 -0
- package/openclaw.plugin.json +32 -0
- package/package.json +61 -0
package/README.md
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
# OpenClaw 汉化版更新检测插件
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@qingchencloud/openclaw-updater)
|
|
4
|
+
[](https://nodejs.org/)
|
|
5
|
+
|
|
6
|
+
检测 [OpenClaw 汉化版](https://openclaw.qt.cool/) 更新并支持一键升级。
|
|
7
|
+
|
|
8
|
+
## 功能特点
|
|
9
|
+
|
|
10
|
+
- 🔍 **自动检测** - 启动时自动检查最新版本
|
|
11
|
+
- 📊 **版本对比** - 显示当前版本与最新版本对比
|
|
12
|
+
- 🚀 **一键升级** - 支持命令行直接升级
|
|
13
|
+
- 🐳 **Docker 智能提示** - 检测 Docker 环境并给出正确升级方式
|
|
14
|
+
- ✅ **全平台支持** - Windows / Linux / macOS
|
|
15
|
+
|
|
16
|
+
## 安装
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install @qingchencloud/openclaw-updater
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
或使用 pnpm / yarn:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
pnpm add @qingchencloud/openclaw-updater
|
|
26
|
+
yarn add @qingchencloud/openclaw-updater
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## 使用方法
|
|
30
|
+
|
|
31
|
+
### 自动检测
|
|
32
|
+
|
|
33
|
+
安装插件后,OpenClaw 启动时会自动检测更新:
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
[更新检测] 发现新版本!
|
|
37
|
+
当前版本: v2026.2.1-zh.1 (全局安装)
|
|
38
|
+
最新版本: v2026.2.5-zh.1
|
|
39
|
+
|
|
40
|
+
运行以下命令升级:
|
|
41
|
+
npm update -g @qingchencloud/openclaw-zh
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### 手动检查
|
|
45
|
+
|
|
46
|
+
使用 `/update` 命令手动检查更新:
|
|
47
|
+
|
|
48
|
+
```
|
|
49
|
+
/update
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### 查看当前版本
|
|
53
|
+
|
|
54
|
+
使用 `/version` 命令查看当前安装的版本:
|
|
55
|
+
|
|
56
|
+
```
|
|
57
|
+
/version
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
输出示例:
|
|
61
|
+
```
|
|
62
|
+
OpenClaw 汉化版: v2026.2.1-zh.1 (全局安装)
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## 升级方式
|
|
66
|
+
|
|
67
|
+
### npm 安装用户
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
# 全局安装
|
|
71
|
+
npm update -g @qingchencloud/openclaw-zh
|
|
72
|
+
|
|
73
|
+
# 本地安装
|
|
74
|
+
npm update @qingchencloud/openclaw-zh
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Docker 用户
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
# 拉取最新镜像
|
|
81
|
+
docker pull ghcr.io/1186258278/openclaw-zh:latest
|
|
82
|
+
|
|
83
|
+
# 重新创建容器
|
|
84
|
+
docker-compose down
|
|
85
|
+
docker-compose up -d
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## 配置选项
|
|
89
|
+
|
|
90
|
+
| 选项 | 类型 | 默认值 | 说明 |
|
|
91
|
+
|------|------|--------|------|
|
|
92
|
+
| `autoCheck` | boolean | `true` | 启动时自动检查更新 |
|
|
93
|
+
| `checkInterval` | number | `24` | 自动检查间隔 (小时) |
|
|
94
|
+
|
|
95
|
+
### 配置示例
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
# 禁用自动检查
|
|
99
|
+
openclaw config set plugins.openclaw-updater.autoCheck false
|
|
100
|
+
|
|
101
|
+
# 设置检查间隔为 12 小时
|
|
102
|
+
openclaw config set plugins.openclaw-updater.checkInterval 12
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## AI 工具
|
|
106
|
+
|
|
107
|
+
本插件注册了两个 AI 可调用的工具:
|
|
108
|
+
|
|
109
|
+
| 工具名 | 功能 |
|
|
110
|
+
|--------|------|
|
|
111
|
+
| `check_openclaw_update` | 检测是否有新版本 |
|
|
112
|
+
| `update_openclaw` | 执行升级操作 |
|
|
113
|
+
|
|
114
|
+
## 常见问题
|
|
115
|
+
|
|
116
|
+
### Q: 为什么显示权限不足?
|
|
117
|
+
|
|
118
|
+
全局安装的包升级可能需要管理员权限:
|
|
119
|
+
- **Windows**: 使用管理员权限运行终端
|
|
120
|
+
- **Linux/macOS**: 使用 `sudo npm update -g @qingchencloud/openclaw-zh`
|
|
121
|
+
|
|
122
|
+
### Q: Docker 容器内如何升级?
|
|
123
|
+
|
|
124
|
+
Docker 容器内无法直接升级,需要拉取新镜像并重建容器。插件会自动检测 Docker 环境并给出正确提示。
|
|
125
|
+
|
|
126
|
+
### Q: 升级后需要重启吗?
|
|
127
|
+
|
|
128
|
+
是的,升级完成后需要重启 OpenClaw 以使更新生效。
|
|
129
|
+
|
|
130
|
+
## 相关链接
|
|
131
|
+
|
|
132
|
+
- [OpenClaw 汉化版](https://openclaw.qt.cool/)
|
|
133
|
+
- [晴辰导航](https://qt.cool/)
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
**晴辰天下** - 让 AI 更懂中文
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
'use strict';Object.defineProperty(exports,'__esModule',{value:true});var child_process=require('child_process');/* OpenClaw 汉化版更新检测插件 - 晴辰天下 - https://nav.qingchencloud.com */
|
|
2
|
+
var o="@qingchencloud/openclaw-zh",v="https://registry.npmjs.org";async function x(){try{let e=child_process.execSync(`npm list -g ${o} --depth=0 --json`,{encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),n=JSON.parse(e);if(n.dependencies?.[o]?.version)return {version:n.dependencies[o].version,isGlobal:!0}}catch{}try{let e=child_process.execSync(`npm list ${o} --depth=0 --json`,{encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),n=JSON.parse(e);if(n.dependencies?.[o]?.version)return {version:n.dependencies[o].version,isGlobal:!1}}catch{}return {version:null,isGlobal:false}}async function k(){try{let e=`${v}/${o}/latest`,n=await fetch(e,{headers:{Accept:"application/json"}});return n.ok&&(await n.json()).version||null}catch{return null}}function U(e,n){let r=s=>s.replace(/^v/,""),t=r(e).split(/[.-]/).map(s=>parseInt(s,10)||0),a=r(n).split(/[.-]/).map(s=>parseInt(s,10)||0),c=Math.max(t.length,a.length);for(let s=0;s<c;s++){let u=t[s]||0,d=a[s]||0;if(u<d)return true;if(u>d)return false}return false}async function p(){try{let[e,n]=await Promise.all([x(),k()]),{version:r,isGlobal:t}=e;if(!r)return {current:null,latest:n,hasUpdate:!1,isGlobal:!1,error:`${o} \u672A\u5B89\u88C5`};if(!n)return {current:r,latest:null,hasUpdate:!1,isGlobal:t,error:"\u65E0\u6CD5\u83B7\u53D6\u6700\u65B0\u7248\u672C\u4FE1\u606F\uFF0C\u8BF7\u68C0\u67E5\u7F51\u7EDC\u8FDE\u63A5"};let a=U(r,n);return {current:r,latest:n,hasUpdate:a,isGlobal:t}}catch(e){return {current:null,latest:null,hasUpdate:false,isGlobal:false,error:`\u68C0\u67E5\u66F4\u65B0\u65F6\u51FA\u9519: ${e}`}}}function m(e){if(e.error)return `[\u66F4\u65B0\u68C0\u6D4B] \u9519\u8BEF: ${e.error}`;if(!e.hasUpdate)return `[\u66F4\u65B0\u68C0\u6D4B] \u5F53\u524D\u7248\u672C ${e.current} \u5DF2\u662F\u6700\u65B0`;let n=e.isGlobal?"\u5168\u5C40":"\u672C\u5730",r=e.isGlobal?`npm update -g ${o}`:`npm update ${o}`;return `[\u66F4\u65B0\u68C0\u6D4B] \u53D1\u73B0\u65B0\u7248\u672C\uFF01
|
|
3
|
+
\u5F53\u524D\u7248\u672C: ${e.current} (${n}\u5B89\u88C5)
|
|
4
|
+
\u6700\u65B0\u7248\u672C: ${e.latest}
|
|
5
|
+
|
|
6
|
+
\u8FD0\u884C\u4EE5\u4E0B\u547D\u4EE4\u5347\u7EA7:
|
|
7
|
+
${r}`}function f(){let e=G(),n=process.platform;return {isDocker:e,isWindows:n==="win32",isLinux:n==="linux",isMac:n==="darwin",needsSudo:n==="linux"&&!e&&process.getuid?.()!==0}}function G(){try{return child_process.execSync("test -f /.dockerenv",{stdio:"ignore"}),!0}catch{try{let e=child_process.execSync('cat /proc/1/cgroup 2>/dev/null || echo ""',{encoding:"utf-8"});return e.includes("docker")||e.includes("kubepods")}catch{return false}}}function h(e,n){let r=e?`npm update -g ${o}`:`npm update ${o}`;return n.needsSudo&&e?`sudo ${r}`:r}function C(e){return new Promise(n=>{let r=f();if(r.isDocker){n({success:false,message:`[\u5347\u7EA7] Docker \u5BB9\u5668\u5185\u65E0\u6CD5\u76F4\u63A5\u5347\u7EA7\uFF01
|
|
8
|
+
\u8BF7\u4F7F\u7528\u4EE5\u4E0B\u65B9\u5F0F\u66F4\u65B0:
|
|
9
|
+
1. \u62C9\u53D6\u6700\u65B0\u955C\u50CF: docker pull ghcr.io/1186258278/openclaw-zh:latest
|
|
10
|
+
2. \u91CD\u65B0\u521B\u5EFA\u5BB9\u5668
|
|
11
|
+
|
|
12
|
+
\u6216\u4F7F\u7528 Docker Compose:
|
|
13
|
+
docker-compose pull && docker-compose up -d`});return}let t=e?["update","-g",o]:["update",o],a="npm",c=t;r.needsSudo&&e&&(a="sudo",c=["npm",...t]);let s=child_process.spawn(a,c,{shell:true,stdio:"pipe"}),u="",d="";s.stdout?.on("data",l=>{u+=l.toString();}),s.stderr?.on("data",l=>{d+=l.toString();}),s.on("close",l=>{if(l===0)try{let i=child_process.execSync(`npm list ${e?"-g":""} ${o} --depth=0 --json`,{encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),w=JSON.parse(i).dependencies?.[o]?.version;n({success:!0,message:`[\u5347\u7EA7] \u5347\u7EA7\u6210\u529F\uFF01\u65B0\u7248\u672C: ${w||"\u672A\u77E5"}
|
|
14
|
+
\u8BF7\u91CD\u542F OpenClaw \u4EE5\u4F7F\u66F4\u65B0\u751F\u6548\u3002`,newVersion:w});}catch{n({success:true,message:"[\u5347\u7EA7] \u5347\u7EA7\u6210\u529F\uFF01\u8BF7\u91CD\u542F OpenClaw \u4EE5\u4F7F\u66F4\u65B0\u751F\u6548\u3002"});}else {let i=d||u||"\u672A\u77E5\u9519\u8BEF";i.includes("EACCES")||i.includes("permission denied")?i=`[\u5347\u7EA7] \u6743\u9650\u4E0D\u8DB3\uFF01${r.isWindows?"\u8BF7\u4F7F\u7528\u7BA1\u7406\u5458\u6743\u9650\u8FD0\u884C\u7EC8\u7AEF":"\u8BF7\u4F7F\u7528 sudo \u8FD0\u884C\u5347\u7EA7\u547D\u4EE4"}
|
|
15
|
+
\u624B\u52A8\u5347\u7EA7\u547D\u4EE4: ${h(e,r)}`:i=`[\u5347\u7EA7] \u5347\u7EA7\u5931\u8D25: ${i}`,n({success:false,message:i});}}),s.on("error",l=>{n({success:false,message:`[\u5347\u7EA7] \u6267\u884C\u5931\u8D25: ${l.message}`});});})}function $(e){let n=e.isWindows?"Windows":e.isMac?"macOS":"Linux",r=e.isDocker?"Docker \u5BB9\u5668":"\u672C\u5730\u73AF\u5883";return `\u8FD0\u884C\u73AF\u5883: ${n} (${r})`}var I={id:"openclaw-updater",name:"OpenClaw \u6C49\u5316\u7248\u66F4\u65B0\u68C0\u6D4B",description:"\u68C0\u6D4B OpenClaw \u6C49\u5316\u7248\u66F4\u65B0\u5E76\u652F\u6301\u4E00\u952E\u5347\u7EA7",version:"1.0.0",author:"\u6674\u8FB0\u5929\u4E0B",homepage:"https://openclaw.qt.cool/",configSchema:{type:"object",additionalProperties:false,properties:{autoCheck:{type:"boolean",default:true,description:"\u542F\u52A8\u65F6\u81EA\u52A8\u68C0\u67E5\u66F4\u65B0"},checkInterval:{type:"number",default:24,description:"\u81EA\u52A8\u68C0\u67E5\u95F4\u9694 (\u5C0F\u65F6)"}}},register(e){let{logger:n,config:r}=e;n.info("\u6B63\u5728\u52A0\u8F7D OpenClaw \u6C49\u5316\u7248\u66F4\u65B0\u68C0\u6D4B\u63D2\u4EF6..."),e.registerTool&&(e.registerTool({name:"check_openclaw_update",description:"\u68C0\u6D4B OpenClaw \u6C49\u5316\u7248\u662F\u5426\u6709\u65B0\u7248\u672C\u53EF\u7528",parameters:{type:"object",properties:{},required:[]},execute:async()=>{let t=await p();return {hasUpdate:t.hasUpdate,currentVersion:t.current,latestVersion:t.latest,isGlobal:t.isGlobal,message:m(t),updateCommand:t.hasUpdate&&t.isGlobal!==void 0?h(t.isGlobal,f()):null}}}),e.registerTool({name:"update_openclaw",description:"\u5C06 OpenClaw \u6C49\u5316\u7248\u5347\u7EA7\u5230\u6700\u65B0\u7248\u672C",parameters:{type:"object",properties:{confirm:{type:"boolean",description:"\u786E\u8BA4\u6267\u884C\u5347\u7EA7"}},required:["confirm"]},execute:async t=>{if(!t.confirm)return {success:false,message:"\u5347\u7EA7\u5DF2\u53D6\u6D88"};let a=await p();return a.hasUpdate?await C(a.isGlobal):{success:true,message:"\u5F53\u524D\u5DF2\u662F\u6700\u65B0\u7248\u672C\uFF0C\u65E0\u9700\u5347\u7EA7"}}}),n.info("\u5DF2\u6CE8\u518C\u5DE5\u5177: check_openclaw_update, update_openclaw")),e.registerCommand&&(e.registerCommand({name:"update",description:"\u68C0\u67E5\u5E76\u5347\u7EA7 OpenClaw \u6C49\u5316\u7248",handler:async()=>{let t=await p(),a=m(t);if(t.hasUpdate){let c=f();return `${a}
|
|
16
|
+
|
|
17
|
+
${$(c)}`}return a}}),e.registerCommand({name:"version",description:"\u663E\u793A\u5F53\u524D OpenClaw \u6C49\u5316\u7248\u7248\u672C",handler:async()=>{let t=await p();return t.current?`OpenClaw \u6C49\u5316\u7248: ${t.current} (${t.isGlobal?"\u5168\u5C40":"\u672C\u5730"}\u5B89\u88C5)`:`${o} \u672A\u5B89\u88C5`}}),n.info("\u5DF2\u6CE8\u518C\u547D\u4EE4: /update, /version")),r.autoCheck!==false&&setTimeout(async()=>{try{let t=await p();t.hasUpdate?(n.warn(`\u53D1\u73B0 OpenClaw \u6C49\u5316\u7248\u65B0\u7248\u672C: ${t.latest}`),n.warn(`\u5F53\u524D\u7248\u672C: ${t.current}`),n.warn("\u8FD0\u884C /update \u67E5\u770B\u8BE6\u60C5")):t.current&&n.info(`OpenClaw \u6C49\u5316\u7248 ${t.current} \u5DF2\u662F\u6700\u65B0`);}catch(t){n.error(`\u68C0\u67E5\u66F4\u65B0\u5931\u8D25: ${t}`);}},3e3),n.info("OpenClaw \u6C49\u5316\u7248\u66F4\u65B0\u68C0\u6D4B\u63D2\u4EF6\u52A0\u8F7D\u5B8C\u6210\uFF01");}},_=I;exports.TARGET_PACKAGE=o;exports.checkForUpdate=p;exports.default=_;exports.detectEnvironment=f;exports.executeUpdate=C;exports.formatVersionInfo=m;exports.getUpdateCommand=h;
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 版本检测模块
|
|
3
|
+
* @author 晴辰天下
|
|
4
|
+
* @description 检测 OpenClaw 汉化版的最新版本
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* 目标包名 - OpenClaw 汉化版
|
|
8
|
+
*/
|
|
9
|
+
declare const TARGET_PACKAGE = "@qingchencloud/openclaw-zh";
|
|
10
|
+
/**
|
|
11
|
+
* 版本信息接口
|
|
12
|
+
*/
|
|
13
|
+
interface VersionInfo {
|
|
14
|
+
current: string | null;
|
|
15
|
+
latest: string | null;
|
|
16
|
+
hasUpdate: boolean;
|
|
17
|
+
isGlobal: boolean;
|
|
18
|
+
error?: string;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* 检查更新
|
|
22
|
+
*/
|
|
23
|
+
declare function checkForUpdate(): Promise<VersionInfo>;
|
|
24
|
+
/**
|
|
25
|
+
* 格式化版本信息用于显示
|
|
26
|
+
*/
|
|
27
|
+
declare function formatVersionInfo(info: VersionInfo): string;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* 升级执行模块
|
|
31
|
+
* @author 晴辰天下
|
|
32
|
+
* @description 执行 OpenClaw 汉化版的升级操作
|
|
33
|
+
*/
|
|
34
|
+
/**
|
|
35
|
+
* 升级结果接口
|
|
36
|
+
*/
|
|
37
|
+
interface UpdateResult {
|
|
38
|
+
success: boolean;
|
|
39
|
+
message: string;
|
|
40
|
+
newVersion?: string;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* 检测运行环境
|
|
44
|
+
*/
|
|
45
|
+
interface EnvironmentInfo {
|
|
46
|
+
isDocker: boolean;
|
|
47
|
+
isWindows: boolean;
|
|
48
|
+
isLinux: boolean;
|
|
49
|
+
isMac: boolean;
|
|
50
|
+
needsSudo: boolean;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* 检测当前运行环境
|
|
54
|
+
*/
|
|
55
|
+
declare function detectEnvironment(): EnvironmentInfo;
|
|
56
|
+
/**
|
|
57
|
+
* 获取升级命令
|
|
58
|
+
*/
|
|
59
|
+
declare function getUpdateCommand(isGlobal: boolean, env: EnvironmentInfo): string;
|
|
60
|
+
/**
|
|
61
|
+
* 执行升级(异步,返回 Promise)
|
|
62
|
+
*/
|
|
63
|
+
declare function executeUpdate(isGlobal: boolean): Promise<UpdateResult>;
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* OpenClaw 汉化版更新检测插件
|
|
67
|
+
*
|
|
68
|
+
* @author 晴辰天下
|
|
69
|
+
* @homepage https://openclaw.qt.cool/
|
|
70
|
+
* @description 检测 OpenClaw 汉化版更新并支持一键升级
|
|
71
|
+
*
|
|
72
|
+
* 功能:
|
|
73
|
+
* - 自动检测最新版本
|
|
74
|
+
* - 显示版本对比信息
|
|
75
|
+
* - 一键升级到最新版
|
|
76
|
+
* - 支持全局/本地安装检测
|
|
77
|
+
* - Docker 环境智能提示
|
|
78
|
+
*/
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* 插件配置类型
|
|
82
|
+
*/
|
|
83
|
+
interface UpdaterPluginConfig {
|
|
84
|
+
autoCheck?: boolean;
|
|
85
|
+
checkInterval?: number;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* OpenClaw 插件 API 类型
|
|
89
|
+
*/
|
|
90
|
+
interface OpenClawPluginApi {
|
|
91
|
+
id: string;
|
|
92
|
+
logger: {
|
|
93
|
+
info: (msg: string) => void;
|
|
94
|
+
warn: (msg: string) => void;
|
|
95
|
+
error: (msg: string) => void;
|
|
96
|
+
};
|
|
97
|
+
config: UpdaterPluginConfig;
|
|
98
|
+
registerTool?: (tool: any) => void;
|
|
99
|
+
registerCommand?: (command: any) => void;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* 插件定义
|
|
103
|
+
*/
|
|
104
|
+
declare const plugin: {
|
|
105
|
+
id: string;
|
|
106
|
+
name: string;
|
|
107
|
+
description: string;
|
|
108
|
+
version: string;
|
|
109
|
+
author: string;
|
|
110
|
+
homepage: string;
|
|
111
|
+
configSchema: {
|
|
112
|
+
type: "object";
|
|
113
|
+
additionalProperties: boolean;
|
|
114
|
+
properties: {
|
|
115
|
+
autoCheck: {
|
|
116
|
+
type: string;
|
|
117
|
+
default: boolean;
|
|
118
|
+
description: string;
|
|
119
|
+
};
|
|
120
|
+
checkInterval: {
|
|
121
|
+
type: string;
|
|
122
|
+
default: number;
|
|
123
|
+
description: string;
|
|
124
|
+
};
|
|
125
|
+
};
|
|
126
|
+
};
|
|
127
|
+
/**
|
|
128
|
+
* 插件注册函数
|
|
129
|
+
*/
|
|
130
|
+
register(api: OpenClawPluginApi): void;
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
export { TARGET_PACKAGE, type VersionInfo, checkForUpdate, plugin as default, detectEnvironment, executeUpdate, formatVersionInfo, getUpdateCommand };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 版本检测模块
|
|
3
|
+
* @author 晴辰天下
|
|
4
|
+
* @description 检测 OpenClaw 汉化版的最新版本
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* 目标包名 - OpenClaw 汉化版
|
|
8
|
+
*/
|
|
9
|
+
declare const TARGET_PACKAGE = "@qingchencloud/openclaw-zh";
|
|
10
|
+
/**
|
|
11
|
+
* 版本信息接口
|
|
12
|
+
*/
|
|
13
|
+
interface VersionInfo {
|
|
14
|
+
current: string | null;
|
|
15
|
+
latest: string | null;
|
|
16
|
+
hasUpdate: boolean;
|
|
17
|
+
isGlobal: boolean;
|
|
18
|
+
error?: string;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* 检查更新
|
|
22
|
+
*/
|
|
23
|
+
declare function checkForUpdate(): Promise<VersionInfo>;
|
|
24
|
+
/**
|
|
25
|
+
* 格式化版本信息用于显示
|
|
26
|
+
*/
|
|
27
|
+
declare function formatVersionInfo(info: VersionInfo): string;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* 升级执行模块
|
|
31
|
+
* @author 晴辰天下
|
|
32
|
+
* @description 执行 OpenClaw 汉化版的升级操作
|
|
33
|
+
*/
|
|
34
|
+
/**
|
|
35
|
+
* 升级结果接口
|
|
36
|
+
*/
|
|
37
|
+
interface UpdateResult {
|
|
38
|
+
success: boolean;
|
|
39
|
+
message: string;
|
|
40
|
+
newVersion?: string;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* 检测运行环境
|
|
44
|
+
*/
|
|
45
|
+
interface EnvironmentInfo {
|
|
46
|
+
isDocker: boolean;
|
|
47
|
+
isWindows: boolean;
|
|
48
|
+
isLinux: boolean;
|
|
49
|
+
isMac: boolean;
|
|
50
|
+
needsSudo: boolean;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* 检测当前运行环境
|
|
54
|
+
*/
|
|
55
|
+
declare function detectEnvironment(): EnvironmentInfo;
|
|
56
|
+
/**
|
|
57
|
+
* 获取升级命令
|
|
58
|
+
*/
|
|
59
|
+
declare function getUpdateCommand(isGlobal: boolean, env: EnvironmentInfo): string;
|
|
60
|
+
/**
|
|
61
|
+
* 执行升级(异步,返回 Promise)
|
|
62
|
+
*/
|
|
63
|
+
declare function executeUpdate(isGlobal: boolean): Promise<UpdateResult>;
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* OpenClaw 汉化版更新检测插件
|
|
67
|
+
*
|
|
68
|
+
* @author 晴辰天下
|
|
69
|
+
* @homepage https://openclaw.qt.cool/
|
|
70
|
+
* @description 检测 OpenClaw 汉化版更新并支持一键升级
|
|
71
|
+
*
|
|
72
|
+
* 功能:
|
|
73
|
+
* - 自动检测最新版本
|
|
74
|
+
* - 显示版本对比信息
|
|
75
|
+
* - 一键升级到最新版
|
|
76
|
+
* - 支持全局/本地安装检测
|
|
77
|
+
* - Docker 环境智能提示
|
|
78
|
+
*/
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* 插件配置类型
|
|
82
|
+
*/
|
|
83
|
+
interface UpdaterPluginConfig {
|
|
84
|
+
autoCheck?: boolean;
|
|
85
|
+
checkInterval?: number;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* OpenClaw 插件 API 类型
|
|
89
|
+
*/
|
|
90
|
+
interface OpenClawPluginApi {
|
|
91
|
+
id: string;
|
|
92
|
+
logger: {
|
|
93
|
+
info: (msg: string) => void;
|
|
94
|
+
warn: (msg: string) => void;
|
|
95
|
+
error: (msg: string) => void;
|
|
96
|
+
};
|
|
97
|
+
config: UpdaterPluginConfig;
|
|
98
|
+
registerTool?: (tool: any) => void;
|
|
99
|
+
registerCommand?: (command: any) => void;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* 插件定义
|
|
103
|
+
*/
|
|
104
|
+
declare const plugin: {
|
|
105
|
+
id: string;
|
|
106
|
+
name: string;
|
|
107
|
+
description: string;
|
|
108
|
+
version: string;
|
|
109
|
+
author: string;
|
|
110
|
+
homepage: string;
|
|
111
|
+
configSchema: {
|
|
112
|
+
type: "object";
|
|
113
|
+
additionalProperties: boolean;
|
|
114
|
+
properties: {
|
|
115
|
+
autoCheck: {
|
|
116
|
+
type: string;
|
|
117
|
+
default: boolean;
|
|
118
|
+
description: string;
|
|
119
|
+
};
|
|
120
|
+
checkInterval: {
|
|
121
|
+
type: string;
|
|
122
|
+
default: number;
|
|
123
|
+
description: string;
|
|
124
|
+
};
|
|
125
|
+
};
|
|
126
|
+
};
|
|
127
|
+
/**
|
|
128
|
+
* 插件注册函数
|
|
129
|
+
*/
|
|
130
|
+
register(api: OpenClawPluginApi): void;
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
export { TARGET_PACKAGE, type VersionInfo, checkForUpdate, plugin as default, detectEnvironment, executeUpdate, formatVersionInfo, getUpdateCommand };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import {execSync,spawn}from'child_process';/* OpenClaw 汉化版更新检测插件 - 晴辰天下 - https://nav.qingchencloud.com */
|
|
2
|
+
var o="@qingchencloud/openclaw-zh",v="https://registry.npmjs.org";async function x(){try{let e=execSync(`npm list -g ${o} --depth=0 --json`,{encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),n=JSON.parse(e);if(n.dependencies?.[o]?.version)return {version:n.dependencies[o].version,isGlobal:!0}}catch{}try{let e=execSync(`npm list ${o} --depth=0 --json`,{encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),n=JSON.parse(e);if(n.dependencies?.[o]?.version)return {version:n.dependencies[o].version,isGlobal:!1}}catch{}return {version:null,isGlobal:false}}async function k(){try{let e=`${v}/${o}/latest`,n=await fetch(e,{headers:{Accept:"application/json"}});return n.ok&&(await n.json()).version||null}catch{return null}}function U(e,n){let r=s=>s.replace(/^v/,""),t=r(e).split(/[.-]/).map(s=>parseInt(s,10)||0),a=r(n).split(/[.-]/).map(s=>parseInt(s,10)||0),c=Math.max(t.length,a.length);for(let s=0;s<c;s++){let u=t[s]||0,d=a[s]||0;if(u<d)return true;if(u>d)return false}return false}async function p(){try{let[e,n]=await Promise.all([x(),k()]),{version:r,isGlobal:t}=e;if(!r)return {current:null,latest:n,hasUpdate:!1,isGlobal:!1,error:`${o} \u672A\u5B89\u88C5`};if(!n)return {current:r,latest:null,hasUpdate:!1,isGlobal:t,error:"\u65E0\u6CD5\u83B7\u53D6\u6700\u65B0\u7248\u672C\u4FE1\u606F\uFF0C\u8BF7\u68C0\u67E5\u7F51\u7EDC\u8FDE\u63A5"};let a=U(r,n);return {current:r,latest:n,hasUpdate:a,isGlobal:t}}catch(e){return {current:null,latest:null,hasUpdate:false,isGlobal:false,error:`\u68C0\u67E5\u66F4\u65B0\u65F6\u51FA\u9519: ${e}`}}}function m(e){if(e.error)return `[\u66F4\u65B0\u68C0\u6D4B] \u9519\u8BEF: ${e.error}`;if(!e.hasUpdate)return `[\u66F4\u65B0\u68C0\u6D4B] \u5F53\u524D\u7248\u672C ${e.current} \u5DF2\u662F\u6700\u65B0`;let n=e.isGlobal?"\u5168\u5C40":"\u672C\u5730",r=e.isGlobal?`npm update -g ${o}`:`npm update ${o}`;return `[\u66F4\u65B0\u68C0\u6D4B] \u53D1\u73B0\u65B0\u7248\u672C\uFF01
|
|
3
|
+
\u5F53\u524D\u7248\u672C: ${e.current} (${n}\u5B89\u88C5)
|
|
4
|
+
\u6700\u65B0\u7248\u672C: ${e.latest}
|
|
5
|
+
|
|
6
|
+
\u8FD0\u884C\u4EE5\u4E0B\u547D\u4EE4\u5347\u7EA7:
|
|
7
|
+
${r}`}function f(){let e=G(),n=process.platform;return {isDocker:e,isWindows:n==="win32",isLinux:n==="linux",isMac:n==="darwin",needsSudo:n==="linux"&&!e&&process.getuid?.()!==0}}function G(){try{return execSync("test -f /.dockerenv",{stdio:"ignore"}),!0}catch{try{let e=execSync('cat /proc/1/cgroup 2>/dev/null || echo ""',{encoding:"utf-8"});return e.includes("docker")||e.includes("kubepods")}catch{return false}}}function h(e,n){let r=e?`npm update -g ${o}`:`npm update ${o}`;return n.needsSudo&&e?`sudo ${r}`:r}function C(e){return new Promise(n=>{let r=f();if(r.isDocker){n({success:false,message:`[\u5347\u7EA7] Docker \u5BB9\u5668\u5185\u65E0\u6CD5\u76F4\u63A5\u5347\u7EA7\uFF01
|
|
8
|
+
\u8BF7\u4F7F\u7528\u4EE5\u4E0B\u65B9\u5F0F\u66F4\u65B0:
|
|
9
|
+
1. \u62C9\u53D6\u6700\u65B0\u955C\u50CF: docker pull ghcr.io/1186258278/openclaw-zh:latest
|
|
10
|
+
2. \u91CD\u65B0\u521B\u5EFA\u5BB9\u5668
|
|
11
|
+
|
|
12
|
+
\u6216\u4F7F\u7528 Docker Compose:
|
|
13
|
+
docker-compose pull && docker-compose up -d`});return}let t=e?["update","-g",o]:["update",o],a="npm",c=t;r.needsSudo&&e&&(a="sudo",c=["npm",...t]);let s=spawn(a,c,{shell:true,stdio:"pipe"}),u="",d="";s.stdout?.on("data",l=>{u+=l.toString();}),s.stderr?.on("data",l=>{d+=l.toString();}),s.on("close",l=>{if(l===0)try{let i=execSync(`npm list ${e?"-g":""} ${o} --depth=0 --json`,{encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),w=JSON.parse(i).dependencies?.[o]?.version;n({success:!0,message:`[\u5347\u7EA7] \u5347\u7EA7\u6210\u529F\uFF01\u65B0\u7248\u672C: ${w||"\u672A\u77E5"}
|
|
14
|
+
\u8BF7\u91CD\u542F OpenClaw \u4EE5\u4F7F\u66F4\u65B0\u751F\u6548\u3002`,newVersion:w});}catch{n({success:true,message:"[\u5347\u7EA7] \u5347\u7EA7\u6210\u529F\uFF01\u8BF7\u91CD\u542F OpenClaw \u4EE5\u4F7F\u66F4\u65B0\u751F\u6548\u3002"});}else {let i=d||u||"\u672A\u77E5\u9519\u8BEF";i.includes("EACCES")||i.includes("permission denied")?i=`[\u5347\u7EA7] \u6743\u9650\u4E0D\u8DB3\uFF01${r.isWindows?"\u8BF7\u4F7F\u7528\u7BA1\u7406\u5458\u6743\u9650\u8FD0\u884C\u7EC8\u7AEF":"\u8BF7\u4F7F\u7528 sudo \u8FD0\u884C\u5347\u7EA7\u547D\u4EE4"}
|
|
15
|
+
\u624B\u52A8\u5347\u7EA7\u547D\u4EE4: ${h(e,r)}`:i=`[\u5347\u7EA7] \u5347\u7EA7\u5931\u8D25: ${i}`,n({success:false,message:i});}}),s.on("error",l=>{n({success:false,message:`[\u5347\u7EA7] \u6267\u884C\u5931\u8D25: ${l.message}`});});})}function $(e){let n=e.isWindows?"Windows":e.isMac?"macOS":"Linux",r=e.isDocker?"Docker \u5BB9\u5668":"\u672C\u5730\u73AF\u5883";return `\u8FD0\u884C\u73AF\u5883: ${n} (${r})`}var I={id:"openclaw-updater",name:"OpenClaw \u6C49\u5316\u7248\u66F4\u65B0\u68C0\u6D4B",description:"\u68C0\u6D4B OpenClaw \u6C49\u5316\u7248\u66F4\u65B0\u5E76\u652F\u6301\u4E00\u952E\u5347\u7EA7",version:"1.0.0",author:"\u6674\u8FB0\u5929\u4E0B",homepage:"https://openclaw.qt.cool/",configSchema:{type:"object",additionalProperties:false,properties:{autoCheck:{type:"boolean",default:true,description:"\u542F\u52A8\u65F6\u81EA\u52A8\u68C0\u67E5\u66F4\u65B0"},checkInterval:{type:"number",default:24,description:"\u81EA\u52A8\u68C0\u67E5\u95F4\u9694 (\u5C0F\u65F6)"}}},register(e){let{logger:n,config:r}=e;n.info("\u6B63\u5728\u52A0\u8F7D OpenClaw \u6C49\u5316\u7248\u66F4\u65B0\u68C0\u6D4B\u63D2\u4EF6..."),e.registerTool&&(e.registerTool({name:"check_openclaw_update",description:"\u68C0\u6D4B OpenClaw \u6C49\u5316\u7248\u662F\u5426\u6709\u65B0\u7248\u672C\u53EF\u7528",parameters:{type:"object",properties:{},required:[]},execute:async()=>{let t=await p();return {hasUpdate:t.hasUpdate,currentVersion:t.current,latestVersion:t.latest,isGlobal:t.isGlobal,message:m(t),updateCommand:t.hasUpdate&&t.isGlobal!==void 0?h(t.isGlobal,f()):null}}}),e.registerTool({name:"update_openclaw",description:"\u5C06 OpenClaw \u6C49\u5316\u7248\u5347\u7EA7\u5230\u6700\u65B0\u7248\u672C",parameters:{type:"object",properties:{confirm:{type:"boolean",description:"\u786E\u8BA4\u6267\u884C\u5347\u7EA7"}},required:["confirm"]},execute:async t=>{if(!t.confirm)return {success:false,message:"\u5347\u7EA7\u5DF2\u53D6\u6D88"};let a=await p();return a.hasUpdate?await C(a.isGlobal):{success:true,message:"\u5F53\u524D\u5DF2\u662F\u6700\u65B0\u7248\u672C\uFF0C\u65E0\u9700\u5347\u7EA7"}}}),n.info("\u5DF2\u6CE8\u518C\u5DE5\u5177: check_openclaw_update, update_openclaw")),e.registerCommand&&(e.registerCommand({name:"update",description:"\u68C0\u67E5\u5E76\u5347\u7EA7 OpenClaw \u6C49\u5316\u7248",handler:async()=>{let t=await p(),a=m(t);if(t.hasUpdate){let c=f();return `${a}
|
|
16
|
+
|
|
17
|
+
${$(c)}`}return a}}),e.registerCommand({name:"version",description:"\u663E\u793A\u5F53\u524D OpenClaw \u6C49\u5316\u7248\u7248\u672C",handler:async()=>{let t=await p();return t.current?`OpenClaw \u6C49\u5316\u7248: ${t.current} (${t.isGlobal?"\u5168\u5C40":"\u672C\u5730"}\u5B89\u88C5)`:`${o} \u672A\u5B89\u88C5`}}),n.info("\u5DF2\u6CE8\u518C\u547D\u4EE4: /update, /version")),r.autoCheck!==false&&setTimeout(async()=>{try{let t=await p();t.hasUpdate?(n.warn(`\u53D1\u73B0 OpenClaw \u6C49\u5316\u7248\u65B0\u7248\u672C: ${t.latest}`),n.warn(`\u5F53\u524D\u7248\u672C: ${t.current}`),n.warn("\u8FD0\u884C /update \u67E5\u770B\u8BE6\u60C5")):t.current&&n.info(`OpenClaw \u6C49\u5316\u7248 ${t.current} \u5DF2\u662F\u6700\u65B0`);}catch(t){n.error(`\u68C0\u67E5\u66F4\u65B0\u5931\u8D25: ${t}`);}},3e3),n.info("OpenClaw \u6C49\u5316\u7248\u66F4\u65B0\u68C0\u6D4B\u63D2\u4EF6\u52A0\u8F7D\u5B8C\u6210\uFF01");}},_=I;export{o as TARGET_PACKAGE,p as checkForUpdate,_ as default,f as detectEnvironment,C as executeUpdate,m as formatVersionInfo,h as getUpdateCommand};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "openclaw-updater",
|
|
3
|
+
"name": "OpenClaw 汉化版更新检测",
|
|
4
|
+
"description": "检测 OpenClaw 汉化版更新并支持一键升级,包含自动检测、版本对比、Docker 环境智能提示等功能",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"author": "晴辰天下",
|
|
7
|
+
"homepage": "https://openclaw.qt.cool/",
|
|
8
|
+
"configSchema": {
|
|
9
|
+
"type": "object",
|
|
10
|
+
"additionalProperties": false,
|
|
11
|
+
"properties": {
|
|
12
|
+
"autoCheck": {
|
|
13
|
+
"type": "boolean",
|
|
14
|
+
"default": true,
|
|
15
|
+
"description": "启动时自动检查更新"
|
|
16
|
+
},
|
|
17
|
+
"checkInterval": {
|
|
18
|
+
"type": "number",
|
|
19
|
+
"default": 24,
|
|
20
|
+
"description": "自动检查间隔 (小时)"
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"tools": [
|
|
25
|
+
"check_openclaw_update",
|
|
26
|
+
"update_openclaw"
|
|
27
|
+
],
|
|
28
|
+
"commands": [
|
|
29
|
+
"update",
|
|
30
|
+
"version"
|
|
31
|
+
]
|
|
32
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@qingchencloud/openclaw-updater",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "OpenClaw 汉化版更新检测插件 - 一键检测并升级到最新版本",
|
|
5
|
+
"author": "晴辰天下 <contact@qingchencloud.com>",
|
|
6
|
+
"license": "UNLICENSED",
|
|
7
|
+
"private": false,
|
|
8
|
+
"type": "module",
|
|
9
|
+
"main": "./dist/index.cjs",
|
|
10
|
+
"module": "./dist/index.js",
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"exports": {
|
|
13
|
+
".": {
|
|
14
|
+
"types": "./dist/index.d.ts",
|
|
15
|
+
"import": "./dist/index.js",
|
|
16
|
+
"require": "./dist/index.cjs"
|
|
17
|
+
},
|
|
18
|
+
"./package.json": "./package.json"
|
|
19
|
+
},
|
|
20
|
+
"files": [
|
|
21
|
+
"dist",
|
|
22
|
+
"openclaw.plugin.json",
|
|
23
|
+
"README.md"
|
|
24
|
+
],
|
|
25
|
+
"scripts": {
|
|
26
|
+
"build": "tsup",
|
|
27
|
+
"dev": "tsup --watch",
|
|
28
|
+
"prepublishOnly": "npm run build",
|
|
29
|
+
"clean": "rimraf dist"
|
|
30
|
+
},
|
|
31
|
+
"keywords": [
|
|
32
|
+
"openclaw",
|
|
33
|
+
"updater",
|
|
34
|
+
"update",
|
|
35
|
+
"版本更新",
|
|
36
|
+
"自动升级",
|
|
37
|
+
"汉化版"
|
|
38
|
+
],
|
|
39
|
+
"homepage": "https://openclaw.qt.cool/",
|
|
40
|
+
"bugs": {
|
|
41
|
+
"url": "https://openclaw.qt.cool/feedback"
|
|
42
|
+
},
|
|
43
|
+
"engines": {
|
|
44
|
+
"node": ">=18.0.0"
|
|
45
|
+
},
|
|
46
|
+
"peerDependencies": {
|
|
47
|
+
"openclaw": ">=0.5.0"
|
|
48
|
+
},
|
|
49
|
+
"devDependencies": {
|
|
50
|
+
"rimraf": "^5.0.0",
|
|
51
|
+
"tsup": "^8.0.0",
|
|
52
|
+
"typescript": "^5.0.0"
|
|
53
|
+
},
|
|
54
|
+
"openclaw": {
|
|
55
|
+
"extensions": ["./dist/index.js"],
|
|
56
|
+
"install": {
|
|
57
|
+
"npmSpec": "@qingchencloud/openclaw-updater",
|
|
58
|
+
"defaultChoice": "npm"
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|