@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 ADDED
@@ -0,0 +1,137 @@
1
+ # OpenClaw 汉化版更新检测插件
2
+
3
+ [![npm](https://img.shields.io/npm/v/@qingchencloud/openclaw-updater)](https://www.npmjs.com/package/@qingchencloud/openclaw-updater)
4
+ [![node](https://img.shields.io/node/v/@qingchencloud/openclaw-updater)](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;
@@ -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 };
@@ -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
+ }