@tencent-weixin/openclaw-weixin-cli 2.1.2 → 2.1.3

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.
Files changed (2) hide show
  1. package/cli.mjs +85 -0
  2. package/package.json +1 -1
package/cli.mjs CHANGED
@@ -16,6 +16,16 @@ const CHANNEL_ID = "openclaw-weixin";
16
16
  /** Only OpenClaw 2026.3.22–2026.3.23 need node_modules/openclaw symlink for jiti. */
17
17
  const SYMLINK_OPENCLAW_MIN = "2026.3.22";
18
18
  const SYMLINK_OPENCLAW_MAX = "2026.3.23";
19
+ /**
20
+ * OpenClaw 2026.5.2 之前的 5.x 版本里,channel-catalog-registry 调
21
+ * discoverOpenClawPlugins 时漏传 installRecords,导致 npm 装的第三方插件
22
+ * 不被 CLI catalog 收录(`channels add/login` 报 Unsupported channel)。
23
+ * 我们通过把 plugin 同时软链到 ~/.openclaw/extensions/<id> 让它走 global
24
+ * 发现路径,绕开 ledger。host 修复发布后需要把上界 EXT_SYMLINK_OPENCLAW_MAX
25
+ * 收紧到具体的修复版本号。
26
+ */
27
+ const EXT_SYMLINK_OPENCLAW_MIN = "2026.5.2";
28
+ const EXT_SYMLINK_OPENCLAW_MAX = "2026.5.99";
19
29
 
20
30
  const LEGACY_TAG_ALIASES = {
21
31
  legacy: "compat-host-gte2026.3.0-lt2026.3.22",
@@ -171,6 +181,76 @@ function ensureOpenclawSymlink(hostVersion) {
171
181
  log(`已创建 symlink: node_modules/openclaw → ${hostRoot}`);
172
182
  }
173
183
 
184
+ // ── extensions symlink (host 5.2 catalog bug workaround) ────────────────────
185
+
186
+ function hostVersionNeedsExtSymlink(hostVersion) {
187
+ if (!hostVersion) return false;
188
+ const geMin = compareVersions(hostVersion, EXT_SYMLINK_OPENCLAW_MIN);
189
+ const leMax = compareVersions(hostVersion, EXT_SYMLINK_OPENCLAW_MAX);
190
+ return (
191
+ !Number.isNaN(geMin) &&
192
+ !Number.isNaN(leMax) &&
193
+ geMin >= 0 &&
194
+ leMax <= 0
195
+ );
196
+ }
197
+
198
+ function resolveNpmInstalledPluginRoot() {
199
+ const stateDir = process.env.OPENCLAW_STATE_DIR || path.join(os.homedir(), ".openclaw");
200
+ const dir = path.join(stateDir, "npm", "node_modules", PLUGIN_SPEC);
201
+ try {
202
+ if (fs.existsSync(path.join(dir, "package.json"))) return dir;
203
+ } catch {}
204
+ return null;
205
+ }
206
+
207
+ /**
208
+ * Make ~/.openclaw/extensions/openclaw-weixin a symlink pointing to the
209
+ * npm-installed plugin root. This lets host 5.2's CLI catalog (which scans
210
+ * the global extensions root) discover the plugin even though
211
+ * channel-catalog-registry forgets to forward installRecords to discovery.
212
+ */
213
+ function ensurePluginExtSymlink(hostVersion) {
214
+ if (!hostVersionNeedsExtSymlink(hostVersion)) {
215
+ return;
216
+ }
217
+
218
+ const npmRoot = resolveNpmInstalledPluginRoot();
219
+ if (!npmRoot) {
220
+ return;
221
+ }
222
+
223
+ const linkPath = resolvePluginExtDir();
224
+ let linkDirReal;
225
+ try {
226
+ linkDirReal = fs.realpathSync(npmRoot);
227
+ } catch {
228
+ return;
229
+ }
230
+
231
+ // Already correct?
232
+ try {
233
+ const stat = fs.lstatSync(linkPath);
234
+ if (stat.isSymbolicLink()) {
235
+ const existingReal = fs.realpathSync(linkPath);
236
+ if (existingReal === linkDirReal) return;
237
+ }
238
+ fs.rmSync(linkPath, { recursive: true, force: true });
239
+ } catch {
240
+ // doesn't exist — fine
241
+ }
242
+
243
+ fs.mkdirSync(path.dirname(linkPath), { recursive: true });
244
+ try {
245
+ fs.symlinkSync(npmRoot, linkPath, "dir");
246
+ log(`已创建 symlink: extensions/${CHANNEL_ID} → ${npmRoot}`);
247
+ } catch (err) {
248
+ error(
249
+ `创建 extensions symlink 失败 (${err?.message ?? err});CLI 可能仍会报 Unsupported channel。`,
250
+ );
251
+ }
252
+ }
253
+
174
254
  // ── installed plugin detection ───────────────────────────────────────────────
175
255
 
176
256
  /**
@@ -273,6 +353,11 @@ function install() {
273
353
  // so jiti can resolve openclaw/plugin-sdk/* without a runtime dependency.
274
354
  ensureOpenclawSymlink(hostVersion);
275
355
 
356
+ // 5b. Symlink npm-installed plugin into ~/.openclaw/extensions/<id>
357
+ // (2026.5.2 only) so the CLI catalog can discover this channel despite
358
+ // the channel-catalog-registry installRecords bug.
359
+ ensurePluginExtSymlink(hostVersion);
360
+
276
361
  // 6. Login (interactive QR scan)
277
362
  log("插件就绪,开始首次连接...");
278
363
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tencent-weixin/openclaw-weixin-cli",
3
- "version": "2.1.2",
3
+ "version": "2.1.3",
4
4
  "description": "Lightweight installer for the OpenClaw Weixin channel plugin",
5
5
  "license": "MIT",
6
6
  "author": "Tencent",