@okclaw-build/cli 1.0.0-beta.6 → 1.0.0-beta.60

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 (121) hide show
  1. package/dist/bridge/daemon/config.d.ts +24 -0
  2. package/dist/bridge/daemon/config.js +96 -0
  3. package/dist/bridge/daemon/config.js.map +1 -0
  4. package/dist/bridge/daemon/daemon.d.ts +7 -0
  5. package/dist/bridge/daemon/daemon.js +23 -0
  6. package/dist/bridge/daemon/daemon.js.map +1 -0
  7. package/dist/bridge/daemon/event-id.d.ts +2 -0
  8. package/dist/bridge/daemon/event-id.js +18 -0
  9. package/dist/bridge/daemon/event-id.js.map +1 -0
  10. package/dist/bridge/daemon/frames.d.ts +81 -0
  11. package/dist/bridge/daemon/frames.js +64 -0
  12. package/dist/bridge/daemon/frames.js.map +1 -0
  13. package/dist/bridge/daemon/openclaw-chat-runtime.d.ts +80 -0
  14. package/dist/bridge/daemon/openclaw-chat-runtime.js +1222 -0
  15. package/dist/bridge/daemon/openclaw-chat-runtime.js.map +1 -0
  16. package/dist/bridge/daemon/openclaw-gateway-client.d.ts +58 -0
  17. package/dist/bridge/daemon/openclaw-gateway-client.js +251 -0
  18. package/dist/bridge/daemon/openclaw-gateway-client.js.map +1 -0
  19. package/dist/bridge/daemon/relay-client.d.ts +75 -0
  20. package/dist/bridge/daemon/relay-client.js +369 -0
  21. package/dist/bridge/daemon/relay-client.js.map +1 -0
  22. package/dist/bridge/daemon/stub-chat-runtime.d.ts +4 -0
  23. package/dist/bridge/daemon/stub-chat-runtime.js +91 -0
  24. package/dist/bridge/daemon/stub-chat-runtime.js.map +1 -0
  25. package/dist/bridge/service.d.ts +12 -0
  26. package/dist/bridge/service.js +86 -0
  27. package/dist/bridge/service.js.map +1 -0
  28. package/dist/commands/backup.d.ts +16 -0
  29. package/dist/commands/backup.js +99 -0
  30. package/dist/commands/backup.js.map +1 -0
  31. package/dist/commands/bridge.d.ts +7 -0
  32. package/dist/commands/bridge.js +100 -0
  33. package/dist/commands/bridge.js.map +1 -0
  34. package/dist/commands/check.js +22 -6
  35. package/dist/commands/check.js.map +1 -1
  36. package/dist/commands/edit.d.ts +2 -7
  37. package/dist/commands/edit.js +28 -16
  38. package/dist/commands/edit.js.map +1 -1
  39. package/dist/commands/feed.js +48 -16
  40. package/dist/commands/feed.js.map +1 -1
  41. package/dist/commands/install.js +99 -18
  42. package/dist/commands/install.js.map +1 -1
  43. package/dist/commands/migration.d.ts +1 -0
  44. package/dist/commands/migration.js +205 -0
  45. package/dist/commands/migration.js.map +1 -0
  46. package/dist/commands/openclaw-channel-login.d.ts +54 -0
  47. package/dist/commands/openclaw-channel-login.js +334 -0
  48. package/dist/commands/openclaw-channel-login.js.map +1 -0
  49. package/dist/commands/restore.d.ts +16 -0
  50. package/dist/commands/restore.js +94 -0
  51. package/dist/commands/restore.js.map +1 -0
  52. package/dist/commands/service.js +56 -13
  53. package/dist/commands/service.js.map +1 -1
  54. package/dist/commands/show.d.ts +13 -0
  55. package/dist/commands/show.js +70 -0
  56. package/dist/commands/show.js.map +1 -0
  57. package/dist/commands/skill.d.ts +1 -0
  58. package/dist/commands/skill.js +137 -0
  59. package/dist/commands/skill.js.map +1 -0
  60. package/dist/commands/uninstall.d.ts +1 -0
  61. package/dist/commands/uninstall.js +46 -0
  62. package/dist/commands/uninstall.js.map +1 -0
  63. package/dist/index.js +121 -12
  64. package/dist/index.js.map +1 -1
  65. package/dist/installers/base.d.ts +3 -1
  66. package/dist/installers/channel.d.ts +10 -2
  67. package/dist/installers/channel.js +143 -24
  68. package/dist/installers/channel.js.map +1 -1
  69. package/dist/installers/openclaw.d.ts +19 -2
  70. package/dist/installers/openclaw.js +186 -55
  71. package/dist/installers/openclaw.js.map +1 -1
  72. package/dist/installers/openviking-purge.d.ts +52 -0
  73. package/dist/installers/openviking-purge.js +380 -0
  74. package/dist/installers/openviking-purge.js.map +1 -0
  75. package/dist/installers/openviking.js +1 -2
  76. package/dist/installers/openviking.js.map +1 -1
  77. package/dist/installers/skill.d.ts +5 -2
  78. package/dist/installers/skill.js +67 -18
  79. package/dist/installers/skill.js.map +1 -1
  80. package/dist/migration/archive.d.ts +14 -0
  81. package/dist/migration/archive.js +84 -0
  82. package/dist/migration/archive.js.map +1 -0
  83. package/dist/migration/crypto.d.ts +16 -0
  84. package/dist/migration/crypto.js +56 -0
  85. package/dist/migration/crypto.js.map +1 -0
  86. package/dist/migration/manifest.d.ts +39 -0
  87. package/dist/migration/manifest.js +140 -0
  88. package/dist/migration/manifest.js.map +1 -0
  89. package/dist/openclaw-user-data.d.ts +86 -0
  90. package/dist/openclaw-user-data.js +422 -0
  91. package/dist/openclaw-user-data.js.map +1 -0
  92. package/dist/output/mode.d.ts +11 -0
  93. package/dist/output/mode.js +27 -0
  94. package/dist/output/mode.js.map +1 -0
  95. package/dist/output/ndjson.d.ts +57 -0
  96. package/dist/output/ndjson.js +136 -0
  97. package/dist/output/ndjson.js.map +1 -0
  98. package/dist/utils/constants.d.ts +14 -13
  99. package/dist/utils/constants.js +40 -21
  100. package/dist/utils/constants.js.map +1 -1
  101. package/dist/utils/deps.d.ts +34 -3
  102. package/dist/utils/deps.js +62 -100
  103. package/dist/utils/deps.js.map +1 -1
  104. package/dist/utils/install-safety.d.ts +25 -0
  105. package/dist/utils/install-safety.js +97 -0
  106. package/dist/utils/install-safety.js.map +1 -0
  107. package/dist/utils/logger.d.ts +10 -0
  108. package/dist/utils/logger.js +31 -4
  109. package/dist/utils/logger.js.map +1 -1
  110. package/dist/utils/mirror.js +14 -0
  111. package/dist/utils/mirror.js.map +1 -1
  112. package/dist/utils/openclaw-config-cli.d.ts +19 -0
  113. package/dist/utils/openclaw-config-cli.js +81 -0
  114. package/dist/utils/openclaw-config-cli.js.map +1 -0
  115. package/dist/utils/openclaw-daemon.d.ts +58 -0
  116. package/dist/utils/openclaw-daemon.js +154 -0
  117. package/dist/utils/openclaw-daemon.js.map +1 -0
  118. package/dist/utils/shell.d.ts +23 -2
  119. package/dist/utils/shell.js +138 -5
  120. package/dist/utils/shell.js.map +1 -1
  121. package/package.json +6 -4
@@ -1,27 +1,41 @@
1
- import { existsSync, mkdirSync, rmSync, readFileSync, writeFileSync } from 'node:fs';
2
- import { shell, shellCapture } from '../utils/shell.js';
1
+ import { copyFileSync, existsSync, mkdirSync, rmSync, readFileSync, writeFileSync } from 'node:fs';
2
+ import { runCommand, runCommandCapture } from '../utils/shell.js';
3
3
  import { ensureCommand, checkDiskSpace } from '../utils/deps.js';
4
4
  import { info, warn } from '../utils/logger.js';
5
+ import { stopDaemonForExclusiveAccess } from '../utils/openclaw-daemon.js';
5
6
  import { CHANNEL_NPM_PACKAGES, BUNDLED_PLUGINS, OKCLAW_TMP_DIR, OPENCLAW_HOME, NPM_REGISTRY } from '../utils/constants.js';
7
+ import { assertSafeInstallName, channelExtensionDir, tmpInstallPath } from '../utils/install-safety.js';
6
8
  export class ChannelInstaller {
7
9
  channelName;
8
10
  constructor(channelName) {
9
- this.channelName = channelName;
11
+ this.channelName = assertSafeInstallName('channel', channelName);
10
12
  }
11
13
  async checkDeps() {
12
14
  await checkDiskSpace(200);
13
15
  await ensureCommand('openclaw');
14
16
  }
15
- async install(version, packageUrl) {
17
+ async install(version, packageSource) {
16
18
  if (BUNDLED_PLUGINS.has(this.channelName)) {
17
19
  info(`${this.channelName} is bundled with openclaw, skipping install (config only).`);
18
20
  return;
19
21
  }
22
+ // Stop the openclaw gateway daemon before touching extensions/<name> or
23
+ // openclaw.json. The daemon has a file watcher that writes its own metadata
24
+ // back into openclaw.json on every config change, which races with our
25
+ // cleanup/install/configure writes:
26
+ // - rmSync extensions/<name>/node_modules/.cache/jiti vs daemon writing
27
+ // fresh transpile cache → ENOTEMPTY
28
+ // - openclaw plugins install hash check vs daemon reload write →
29
+ // ConfigMutationConflictError: config changed since last load
30
+ // The bootstrap orchestrator (commands/install.ts) is responsible for
31
+ // restarting the daemon after the full component install pipeline finishes.
32
+ await stopDaemonForExclusiveAccess(`${this.channelName} install`);
20
33
  // Clean up any stale state (both the extension dir AND config entries) so openclaw's
21
34
  // config validation passes when `openclaw plugins install` runs.
22
35
  this.cleanupStaleState();
23
- if (packageUrl) {
24
- await this.installFromLocalPackage(packageUrl);
36
+ this.reportLegacyWechatAliasState();
37
+ if (packageSource) {
38
+ await this.installFromLocalPackage(packageSource);
25
39
  }
26
40
  else {
27
41
  await this.installViaNpmPack(version);
@@ -31,10 +45,14 @@ export class ChannelInstaller {
31
45
  this.verifyInstalled();
32
46
  // Add to plugins.allow so openclaw trusts this plugin
33
47
  await this.addToPluginsAllow();
48
+ // Add to plugins.load.paths so the gateway actually scans this plugin dir on
49
+ // startup. `openclaw plugins install <tgz>`(archive 模式)只写 plugins.installs
50
+ // metadata,不会自动维护 load.paths;不补这一步会让 gateway ready (0 plugins,...)。
51
+ await this.addToLoadPaths();
34
52
  info(`${this.channelName}@${version} installed.`);
35
53
  }
36
54
  verifyInstalled() {
37
- const pluginDir = `${OPENCLAW_HOME}/extensions/${this.channelName}`;
55
+ const pluginDir = channelExtensionDir(this.channelName);
38
56
  if (!existsSync(pluginDir)) {
39
57
  throw new Error(`Install verification failed: ${pluginDir} not found after "openclaw plugins install". ` +
40
58
  `The install command may have silently skipped due to stale config; aborting before configure() runs.`);
@@ -43,6 +61,12 @@ export class ChannelInstaller {
43
61
  async configure(config) {
44
62
  if (!config || Object.keys(config).length === 0)
45
63
  return;
64
+ // configure() runs N back-to-back `openclaw config set` commands; every one
65
+ // does a hash-checked atomic replace on openclaw.json. If the daemon was
66
+ // restarted between install() and configure() its file-watcher write will
67
+ // race the next config set and raise ConfigMutationConflictError. Re-stop
68
+ // here so configure() sees the same exclusive-access window install() did.
69
+ await stopDaemonForExclusiveAccess(`${this.channelName} configure`);
46
70
  // All channel configs go to channels.<name> (both bundled and external plugins)
47
71
  // plugins.entries is managed by openclaw plugins install, we don't touch it
48
72
  const configPrefix = `channels.${this.channelName}`;
@@ -59,7 +83,7 @@ export class ChannelInstaller {
59
83
  * `openclaw ...` commands ("unknown channel id: <name>").
60
84
  */
61
85
  cleanupStaleState() {
62
- const pluginDir = `${OPENCLAW_HOME}/extensions/${this.channelName}`;
86
+ const pluginDir = channelExtensionDir(this.channelName);
63
87
  const configFile = `${OPENCLAW_HOME}/openclaw.json`;
64
88
  const hadDir = existsSync(pluginDir);
65
89
  const hadJsonRef = this.hasJsonRef(configFile);
@@ -78,6 +102,16 @@ export class ChannelInstaller {
78
102
  if (Array.isArray(cfg.plugins?.allow)) {
79
103
  cfg.plugins.allow = cfg.plugins.allow.filter((p) => p !== this.channelName);
80
104
  }
105
+ // Also strip any plugins.load.paths entry pointing at the channel's
106
+ // extension dir. Without this the dir gets rm'd below but the json keeps
107
+ // a stale reference, so the next `openclaw config validate` (run inside
108
+ // `openclaw plugins install`) fails with "plugin path not found",
109
+ // bricking the install AND every subsequent openclaw config command.
110
+ const pluginPathSuffix = `/extensions/${this.channelName}`;
111
+ if (Array.isArray(cfg.plugins?.load?.paths)) {
112
+ cfg.plugins.load.paths = cfg.plugins.load.paths.filter((p) => (typeof p !== 'string'
113
+ || (!p.endsWith(pluginPathSuffix) && !p.endsWith(`${pluginPathSuffix}/`))));
114
+ }
81
115
  writeFileSync(configFile, JSON.stringify(cfg, null, 2) + '\n', 'utf8');
82
116
  }
83
117
  catch (e) {
@@ -101,6 +135,11 @@ export class ChannelInstaller {
101
135
  return true;
102
136
  if (Array.isArray(cfg.plugins?.allow) && cfg.plugins.allow.includes(this.channelName))
103
137
  return true;
138
+ // load.paths can leak even when nothing else does — must trigger cleanup
139
+ // so the stale path gets stripped before `openclaw plugins install` runs.
140
+ const pluginPathSuffix = `/extensions/${this.channelName}`;
141
+ if (Array.isArray(cfg.plugins?.load?.paths) && cfg.plugins.load.paths.some((p) => (typeof p === 'string' && (p.endsWith(pluginPathSuffix) || p.endsWith(`${pluginPathSuffix}/`)))))
142
+ return true;
104
143
  }
105
144
  catch {
106
145
  // corrupted JSON — let cleanup run anyway
@@ -108,22 +147,61 @@ export class ChannelInstaller {
108
147
  }
109
148
  return false;
110
149
  }
111
- async installFromLocalPackage(packageUrl) {
150
+ reportLegacyWechatAliasState() {
151
+ if (this.channelName !== 'openclaw-weixin')
152
+ return;
153
+ const configFile = `${OPENCLAW_HOME}/openclaw.json`;
154
+ const legacyDir = channelExtensionDir('wechat');
155
+ const hits = [];
156
+ if (existsSync(legacyDir)) {
157
+ hits.push(legacyDir);
158
+ }
159
+ if (existsSync(configFile)) {
160
+ try {
161
+ const cfg = JSON.parse(readFileSync(configFile, 'utf8'));
162
+ if (cfg.channels?.wechat)
163
+ hits.push('channels.wechat');
164
+ if (cfg.plugins?.entries?.wechat)
165
+ hits.push('plugins.entries.wechat');
166
+ if (cfg.plugins?.installs?.wechat)
167
+ hits.push('plugins.installs.wechat');
168
+ if (Array.isArray(cfg.plugins?.allow) && cfg.plugins.allow.includes('wechat')) {
169
+ hits.push('plugins.allow contains "wechat"');
170
+ }
171
+ const legacyPathSuffix = '/extensions/wechat';
172
+ if (Array.isArray(cfg.plugins?.load?.paths)) {
173
+ for (const item of cfg.plugins.load.paths) {
174
+ if (typeof item === 'string' && (item.endsWith(legacyPathSuffix) || item.endsWith(`${legacyPathSuffix}/`))) {
175
+ hits.push(`plugins.load.paths contains "${item}"`);
176
+ }
177
+ }
178
+ }
179
+ }
180
+ catch (e) {
181
+ warn(`Failed to inspect legacy wechat channel state: ${e}`);
182
+ }
183
+ }
184
+ if (hits.length === 0)
185
+ return;
186
+ warn('Detected legacy wechat channel residue. It is not modified automatically; ' +
187
+ `review and clean manually before relying on openclaw-weixin: ${hits.join(', ')}`);
188
+ }
189
+ async installFromLocalPackage(packageSource) {
190
+ const archive = tmpInstallPath(`${this.channelName}-plugin.tgz`);
112
191
  mkdirSync(OKCLAW_TMP_DIR, { recursive: true });
113
- const archive = `${OKCLAW_TMP_DIR}/${this.channelName}-plugin.tgz`;
114
- if (packageUrl.startsWith('http')) {
115
- info(`Downloading ${this.channelName} from ${packageUrl}...`);
116
- await shell(`curl -fsSL --connect-timeout 30 --retry 3 -o "${archive}" "${packageUrl}"`);
192
+ if (packageSource.kind === 'remote') {
193
+ info(`Downloading ${this.channelName} from ${packageSource.url}...`);
194
+ await runCommand('curl', ['-fsSL', '--connect-timeout', '30', '--retry', '3', '-o', archive, packageSource.url]);
117
195
  }
118
- else if (existsSync(packageUrl)) {
119
- await shell(`cp "${packageUrl}" "${archive}"`);
196
+ else if (existsSync(packageSource.path)) {
197
+ copyFileSync(packageSource.path, archive);
120
198
  }
121
199
  else {
122
- throw new Error(`Package not found: ${packageUrl}`);
200
+ throw new Error(`Package not found: ${packageSource.path}`);
123
201
  }
124
202
  info(`Installing ${this.channelName} from local package...`);
125
- await shell(`openclaw plugins install "${archive}"`);
126
- await shell(`rm -f "${archive}"`).catch(() => { });
203
+ await runCommand('openclaw', ['plugins', 'install', archive]);
204
+ rmSync(archive, { force: true });
127
205
  }
128
206
  /**
129
207
  * Download tgz from npm (npmmirror) first, then install locally.
@@ -138,17 +216,23 @@ export class ChannelInstaller {
138
216
  const pkgSpec = `${npmPkg}@${version}`;
139
217
  mkdirSync(OKCLAW_TMP_DIR, { recursive: true });
140
218
  info(`Downloading ${pkgSpec} from npm...`);
141
- const packResult = await shellCapture(`cd "${OKCLAW_TMP_DIR}" && npm pack "${pkgSpec}" --registry ${NPM_REGISTRY} 2>&1 | tail -1`);
219
+ const packResult = await runCommandCapture('npm', ['pack', pkgSpec, '--registry', NPM_REGISTRY], {
220
+ cwd: OKCLAW_TMP_DIR,
221
+ });
142
222
  if (packResult.code !== 0) {
143
223
  throw new Error(`npm pack failed for ${pkgSpec}: ${packResult.stderr}`);
144
224
  }
145
- const tgzFile = `${OKCLAW_TMP_DIR}/${packResult.stdout.trim()}`;
225
+ const tgzName = packResult.stdout.split('\n').map((line) => line.trim()).filter(Boolean).at(-1);
226
+ if (!tgzName) {
227
+ throw new Error(`npm pack did not report an output file for ${pkgSpec}`);
228
+ }
229
+ const tgzFile = tmpInstallPath(tgzName);
146
230
  if (!existsSync(tgzFile)) {
147
231
  throw new Error(`npm pack did not produce expected file: ${tgzFile}`);
148
232
  }
149
233
  info(`Installing ${this.channelName} from ${tgzFile}...`);
150
- await shell(`openclaw plugins install "${tgzFile}"`);
151
- await shell(`rm -f "${tgzFile}"`).catch(() => { });
234
+ await runCommand('openclaw', ['plugins', 'install', tgzFile]);
235
+ rmSync(tgzFile, { force: true });
152
236
  }
153
237
  async addToPluginsAllow() {
154
238
  const configFile = `${OPENCLAW_HOME}/openclaw.json`;
@@ -170,6 +254,39 @@ export class ChannelInstaller {
170
254
  warn(`Failed to update plugins.allow: ${e}`);
171
255
  }
172
256
  }
257
+ /**
258
+ * Push the absolute extension dir into plugins.load.paths so the gateway
259
+ * scans it on startup. Idempotent — dedup against trailing-slash variants
260
+ * (e.g. `/.../dingtalk` vs `/.../dingtalk/` both count as the same entry).
261
+ */
262
+ async addToLoadPaths() {
263
+ const configFile = `${OPENCLAW_HOME}/openclaw.json`;
264
+ if (!existsSync(configFile))
265
+ return;
266
+ const pluginPath = `${OPENCLAW_HOME}/extensions/${this.channelName}`;
267
+ const stripTrailingSlash = (p) => p.replace(/\/+$/, '');
268
+ const targetNormalized = stripTrailingSlash(pluginPath);
269
+ try {
270
+ const cfg = JSON.parse(readFileSync(configFile, 'utf8'));
271
+ if (!cfg.plugins)
272
+ cfg.plugins = {};
273
+ if (!cfg.plugins.load)
274
+ cfg.plugins.load = {};
275
+ if (!Array.isArray(cfg.plugins.load.paths))
276
+ cfg.plugins.load.paths = [];
277
+ const exists = cfg.plugins.load.paths.some((p) => (typeof p === 'string' && stripTrailingSlash(p) === targetNormalized));
278
+ if (exists) {
279
+ info(`plugins.load.paths already contains ${pluginPath}, skipping write`);
280
+ return;
281
+ }
282
+ cfg.plugins.load.paths.push(pluginPath);
283
+ writeFileSync(configFile, JSON.stringify(cfg, null, 2) + '\n', 'utf8');
284
+ info(`Added ${pluginPath} to plugins.load.paths`);
285
+ }
286
+ catch (e) {
287
+ warn(`Failed to update plugins.load.paths: ${e}`);
288
+ }
289
+ }
173
290
  async applyConfig(obj, prefix) {
174
291
  for (const [key, value] of Object.entries(obj)) {
175
292
  if (value === null || value === undefined)
@@ -179,10 +296,12 @@ export class ChannelInstaller {
179
296
  await this.applyConfig(value, path);
180
297
  }
181
298
  else {
182
- const strVal = String(value).replace(/'/g, "'\\''");
299
+ const isJsonValue = Array.isArray(value);
183
300
  // Let errors propagate — silently skipping a config set leaves openclaw.json
184
301
  // in a half-written state that breaks config validation at runtime.
185
- await shell(`openclaw config set '${path}' '${strVal}'`);
302
+ await runCommand('openclaw', isJsonValue
303
+ ? ['config', 'set', path, JSON.stringify(value), '--strict-json']
304
+ : ['config', 'set', path, '--', String(value)]);
186
305
  }
187
306
  }
188
307
  }
@@ -1 +1 @@
1
- {"version":3,"file":"channel.js","sourceRoot":"","sources":["../../src/installers/channel.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"channel.js","sourceRoot":"","sources":["../../src/installers/channel.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,14 @@
1
1
  import type { Installer } from './base.js';
2
+ export { backupOpenclawUserData } from '../openclaw-user-data.js';
3
+ type OpenclawProviderConfig = {
4
+ providers: Record<string, unknown>;
5
+ defaultModel: string;
6
+ };
7
+ export declare function resolveOpenclawProviderConfig(config: Record<string, unknown>): OpenclawProviderConfig;
2
8
  export declare class OpenclawInstaller implements Installer {
3
9
  checkDeps(): Promise<void>;
4
10
  install(version: string): Promise<void>;
11
+ private installBundledWeixinChannel;
5
12
  /**
6
13
  * Config format (directly the providers map):
7
14
  * {
@@ -11,8 +18,18 @@ export declare class OpenclawInstaller implements Installer {
11
18
  * }
12
19
  * }
13
20
  *
14
- * Merges into openclaw.json -> models.providers
15
- * Sets agents.defaults.model to first provider's first model
21
+ * REPLACES openclaw.json -> models.providers entirely. The old merge
22
+ * semantics left stale providers behind on every deploy: switching from
23
+ * deepseek to qwen would still leave deepseek under models.providers.
24
+ * models.providers is a protected map in openclaw — full replacement
25
+ * requires the --replace flag, otherwise `openclaw config set` refuses
26
+ * to drop existing keys.
27
+ *
28
+ * New config files may wrap providers as `{ providers, defaultModel }` so
29
+ * deployment can set the user's selected primary model explicitly. Legacy
30
+ * provider-map-only config still falls back to the first provider's first
31
+ * model for compatibility.
16
32
  */
17
33
  configure(config: Record<string, unknown>): Promise<void>;
34
+ uninstall(): Promise<void>;
18
35
  }
@@ -1,9 +1,36 @@
1
- import { readFileSync, writeFileSync, existsSync, cpSync, mkdirSync } from 'node:fs';
2
- import { shell, shellRetry } from '../utils/shell.js';
1
+ import { existsSync, cpSync, mkdirSync, rmSync } from 'node:fs';
2
+ import { runCommand, runCommandRetry, shell, shellCapture } from '../utils/shell.js';
3
3
  import { ensureNodeVersion, checkDiskSpace } from '../utils/deps.js';
4
4
  import { info, warn } from '../utils/logger.js';
5
+ import { stopDaemonForExclusiveAccess, stopGateway, cleanupGatewayServiceFiles, } from '../utils/openclaw-daemon.js';
5
6
  import { OPENCLAW_HOME, OKCLAW_BACKUP_DIR, NPM_REGISTRY } from '../utils/constants.js';
7
+ import { assertSafePackageVersion } from '../utils/install-safety.js';
8
+ import { purgePhaseB } from './openviking-purge.js';
9
+ import { backupOpenclawUserData } from '../openclaw-user-data.js';
10
+ import { uninstallBridgeService } from '../bridge/service.js';
11
+ import { ChannelInstaller } from './channel.js';
12
+ export { backupOpenclawUserData } from '../openclaw-user-data.js';
6
13
  const OPENCLAW_CONFIG = `${OPENCLAW_HOME}/openclaw.json`;
14
+ const OPENCLAW_WEIXIN_VERSION = assertSafePackageVersion('2.4.6');
15
+ function isObjectRecord(value) {
16
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
17
+ }
18
+ export function resolveOpenclawProviderConfig(config) {
19
+ const wrapperProviders = config.providers;
20
+ const providers = isObjectRecord(wrapperProviders) ? wrapperProviders : config;
21
+ const explicitDefaultModel = typeof config.defaultModel === 'string' ? config.defaultModel.trim() : '';
22
+ if (explicitDefaultModel) {
23
+ return { providers, defaultModel: explicitDefaultModel };
24
+ }
25
+ for (const [providerName, providerConfig] of Object.entries(providers)) {
26
+ const pc = providerConfig;
27
+ const modelList = pc.models;
28
+ if (modelList?.[0]?.id) {
29
+ return { providers, defaultModel: `${providerName}/${modelList[0].id}` };
30
+ }
31
+ }
32
+ return { providers, defaultModel: '' };
33
+ }
7
34
  export class OpenclawInstaller {
8
35
  async checkDeps() {
9
36
  await checkDiskSpace(500);
@@ -20,19 +47,71 @@ export class OpenclawInstaller {
20
47
  info(`Installing openclaw@${version}...`);
21
48
  // --ignore-scripts: skip postinstall to avoid @matrix-org/matrix-sdk-crypto-nodejs
22
49
  // which downloads ~40MB binary from GitHub (blocked/slow in China)
23
- await shellRetry(`npm install -g openclaw@${version} --registry ${NPM_REGISTRY} --no-audit --no-fund --ignore-scripts`);
50
+ await runCommandRetry('npm', [
51
+ 'install',
52
+ '-g',
53
+ `openclaw@${version}`,
54
+ '--registry',
55
+ NPM_REGISTRY,
56
+ '--no-audit',
57
+ '--no-fund',
58
+ '--ignore-scripts',
59
+ ]);
24
60
  // Remove the problematic postinstall script, then rebuild everything else
25
61
  info('Running native module builds...');
26
62
  await shell(`rm -f $(npm root -g)/openclaw/node_modules/@matrix-org/matrix-sdk-crypto-nodejs/download-lib.js 2>/dev/null || true`);
27
63
  await shell(`cd $(npm root -g)/openclaw && npm rebuild --no-audit --no-fund 2>&1 || true`);
28
- // Set gateway.mode=local so gateway can start without --allow-unconfigured
29
- await shell("openclaw config set gateway.mode local").catch(() => { });
30
- info('Registering openclaw gateway as system service...');
31
- await shell('openclaw gateway install --force').catch(() => {
32
- warn('gateway install skipped (may not be supported on this platform)');
64
+ // OpenViking purge phase B: after the new openclaw CLI is installed, but
65
+ // before onboard reads config. No residue means purgePhaseB returns quickly.
66
+ info('Running openviking purge phase B (config + extensions cleanup)...');
67
+ await purgePhaseB();
68
+ // Initialize openclaw non-interactively. Replaces an older
69
+ // `openclaw config set gateway.mode local` call that targeted a config key
70
+ // removed in current openclaw — the silent catch was hiding the failure and
71
+ // leaving gateway in a half-configured state that kept asking for device pairing.
72
+ info('Initializing openclaw (non-interactive)...');
73
+ // openclaw 要求 headless 调用显式承认风险(默认模式,不锁定 local/remote)。
74
+ // 见 https://docs.openclaw.ai/security
75
+ // --skip-health:部署阶段会在 onboard 之后单独起 gateway 进程,
76
+ // 这里跳过健康检查,避免在 daemon 尚未启动时误判失败。
77
+ await shell('openclaw onboard --non-interactive --accept-risk --skip-health');
78
+ // Some hosts have an openclaw gateway daemon already running (e.g.
79
+ // re-install on a host that previously hosted a shrimp, or systemd unit
80
+ // installed on a prior install pulls it back). When that daemon is up,
81
+ // its config-file watcher writes its own metadata back into openclaw.json
82
+ // on every change, racing the `openclaw config set` atomic write hash
83
+ // check below and producing ConfigMutationConflictError. Stop the daemon
84
+ // before mutating openclaw.json; the bootstrap orchestrator restarts it
85
+ // after the full install pipeline completes.
86
+ await stopDaemonForExclusiveAccess('openclaw deployment defaults');
87
+ info('Applying openclaw deployment defaults...');
88
+ await runCommand('openclaw', ['config', 'unset', 'plugins.slots.contextEngine']).catch(() => {
89
+ warn('Failed to unset legacy contextEngine slot, continuing...');
90
+ });
91
+ // openclaw 2026.4.26 起,bundled plugin 注册路径变了:dist/extensions/memory-core
92
+ // 物理存在但不会被自动注册进 plugin registry,这里 set 会以
93
+ // "plugin not found: memory-core" 失败。当前没找到 v2026.4.26 下注册它的官方手段
94
+ // (doctor/onboard/postinstall 都不补),先 catch 住不让整个安装挂掉,让 onboard
95
+ // 留下的默认 memory slot 跑起来;后续找到正解再去掉这层兜底。
96
+ await runCommand('openclaw', ['config', 'set', 'plugins.slots.memory', '--', 'memory-core']).catch(() => {
97
+ warn('Failed to set memory slot to memory-core (plugin not registered), continuing...');
33
98
  });
99
+ // OKClaw 部署的 OpenClaw 实例不需要主动 agent heartbeat;设为 0m
100
+ // 是持久关闭,必须在 gateway 启动前写入配置。
101
+ await runCommand('openclaw', ['config', 'set', 'agents.defaults.heartbeat.every', '--', '0m']).catch(() => {
102
+ warn('Failed to disable OpenClaw heartbeat, continuing...');
103
+ });
104
+ await runCommand('openclaw', ['config', 'set', 'tools.profile', '--', 'full']);
105
+ await this.installBundledWeixinChannel();
34
106
  info(`openclaw@${version} installed.`);
35
107
  }
108
+ async installBundledWeixinChannel() {
109
+ info(`Installing bundled WeChat channel openclaw-weixin@${OPENCLAW_WEIXIN_VERSION}...`);
110
+ const channelInstaller = new ChannelInstaller('openclaw-weixin');
111
+ await channelInstaller.checkDeps();
112
+ await channelInstaller.install(OPENCLAW_WEIXIN_VERSION);
113
+ info(`openclaw-weixin@${OPENCLAW_WEIXIN_VERSION} installed.`);
114
+ }
36
115
  /**
37
116
  * Config format (directly the providers map):
38
117
  * {
@@ -42,63 +121,115 @@ export class OpenclawInstaller {
42
121
  * }
43
122
  * }
44
123
  *
45
- * Merges into openclaw.json -> models.providers
46
- * Sets agents.defaults.model to first provider's first model
124
+ * REPLACES openclaw.json -> models.providers entirely. The old merge
125
+ * semantics left stale providers behind on every deploy: switching from
126
+ * deepseek to qwen would still leave deepseek under models.providers.
127
+ * models.providers is a protected map in openclaw — full replacement
128
+ * requires the --replace flag, otherwise `openclaw config set` refuses
129
+ * to drop existing keys.
130
+ *
131
+ * New config files may wrap providers as `{ providers, defaultModel }` so
132
+ * deployment can set the user's selected primary model explicitly. Legacy
133
+ * provider-map-only config still falls back to the first provider's first
134
+ * model for compatibility.
47
135
  */
48
136
  async configure(config) {
49
137
  if (Object.keys(config).length === 0)
50
138
  return;
139
+ const resolved = resolveOpenclawProviderConfig(config);
140
+ if (Object.keys(resolved.providers).length === 0)
141
+ return;
142
+ // `openclaw config set` does a hash-checked atomic replace on
143
+ // openclaw.json; if the daemon's file-watcher writes its own snapshot
144
+ // back mid-flight the cli set either fails with
145
+ // ConfigMutationConflictError or silently overwrites cli-written
146
+ // fields with a stale view (e.g. dingtalk.clientSecret disappears
147
+ // after a successful-looking deploy). Stop the daemon for the entire
148
+ // configure() window.
149
+ await stopDaemonForExclusiveAccess('openclaw provider config');
51
150
  info('Configuring openclaw models & providers...');
52
- let openclawConfig = {};
53
- if (existsSync(OPENCLAW_CONFIG)) {
54
- try {
55
- openclawConfig = JSON.parse(readFileSync(OPENCLAW_CONFIG, 'utf8'));
56
- }
57
- catch {
58
- warn('Failed to parse existing openclaw.json, starting fresh for models section.');
59
- }
151
+ // Full replace via `openclaw config set ... --replace`. --strict-json
152
+ // forces JSON parsing (no raw-string fallback).
153
+ await runCommand('openclaw', [
154
+ 'config',
155
+ 'set',
156
+ 'models.providers',
157
+ JSON.stringify(resolved.providers),
158
+ '--strict-json',
159
+ '--replace',
160
+ ]);
161
+ info(`Replaced models.providers with: ${Object.keys(resolved.providers).join(', ')}`);
162
+ if (resolved.defaultModel) {
163
+ await runCommand('openclaw', ['config', 'set', 'agents.defaults.model.primary', '--', resolved.defaultModel]);
164
+ info(`Default model: ${resolved.defaultModel}`);
60
165
  }
61
- // Ensure models.providers exists
62
- if (!openclawConfig.models || typeof openclawConfig.models !== 'object') {
63
- openclawConfig.models = { mode: 'merge', providers: {} };
166
+ info('openclaw configured.');
167
+ }
168
+ async uninstall() {
169
+ info('Uninstalling bridge service...');
170
+ await uninstallBridgeService();
171
+ info('Stopping openclaw...');
172
+ // okclaw command may not exist (CLI early state), tolerate
173
+ await shell(`okclaw stop 2>/dev/null || true`).catch(() => { });
174
+ const userDataBackupDir = backupOpenclawUserData();
175
+ if (userDataBackupDir) {
176
+ info(`Backed up openclaw user data to ${userDataBackupDir}`);
64
177
  }
65
- const models = openclawConfig.models;
66
- if (!models.providers || typeof models.providers !== 'object') {
67
- models.providers = {};
178
+ else {
179
+ info('No openclaw user data found to back up before uninstall.');
68
180
  }
69
- const existingProviders = models.providers;
70
- // Merge providers and find default model
71
- let defaultModel = '';
72
- for (const [providerName, providerConfig] of Object.entries(config)) {
73
- existingProviders[providerName] = providerConfig;
74
- info(`Added provider: ${providerName}`);
75
- if (!defaultModel) {
76
- const pc = providerConfig;
77
- const modelList = pc.models;
78
- if (modelList?.[0]?.id) {
79
- defaultModel = `${providerName}/${modelList[0].id}`;
80
- }
81
- }
181
+ // 先让 openclaw 自己卸掉 systemd user unit(stop + disable + 删 .service 文件),
182
+ // 否则 pkill + npm uninstall 只删二进制,service 文件留着仍指向旧路径,新版装完
183
+ // systemd 会在旧 ExecStart 上无限 restart 直到下次手工 restart。
184
+ await shell(`openclaw gateway uninstall 2>/dev/null || true`).catch(() => { });
185
+ // `openclaw gateway uninstall` 只删主 .service,残留的 .bak / .service.d/
186
+ // drop-in 会污染下次 install,一并清掉。
187
+ await cleanupGatewayServiceFiles();
188
+ // 兜底停掉残留 gateway 进程(systemd 没接管的情况)。按监听端口杀 ——
189
+ // gateway 进程名在新版 openclaw 下是 `openclaw` / `node`,旧的
190
+ // `pkill -f openclaw-gateway` 匹配不到;按端口杀也绝不会误命中本 CLI 进程。
191
+ await stopGateway().catch(() => { });
192
+ // 多 package manager 容忍:主机可能用 npm / pnpm / yarn 任一装过 openclaw,
193
+ // 没装的包管理器跑也 tolerate,各自清各自的 store。
194
+ // 见 P5 真机排障:测试主机 which openclaw 指向 /root/.local/share/pnpm/openclaw,
195
+ // 单跑 npm uninstall 清不掉 pnpm 位置 → verifier 在 sudo 下(PATH 不含 pnpm bin)
196
+ // 假阴性通过,但用户 shell 仍能跑。
197
+ info('Uninstalling openclaw via known package managers (best-effort)...');
198
+ await shell(`npm uninstall -g openclaw --no-audit --no-fund 2>/dev/null || true`).catch(() => { });
199
+ await shell(`pnpm rm -g openclaw 2>/dev/null || true`).catch(() => { });
200
+ await shell(`yarn global remove openclaw 2>/dev/null || true`).catch(() => { });
201
+ // openclaw 可能自己写过 /usr/local/bin/openclaw 这类 PATH 入口,
202
+ // 这一层不受 npm uninstall 管辖,所以这里额外清理。
203
+ await shell(`rm -f /usr/local/bin/openclaw 2>/dev/null || true`).catch(() => { });
204
+ // 兜底扫描:用增广 PATH(涵盖 pnpm / yarn / user-local / nvm 各全局 bin)跑
205
+ // command -v 定位任意残留,循环 rm 直到找不到。覆盖:
206
+ // - sudo secure_path 剔除了 ~/.local/share/pnpm 导致 verifier 假阴性
207
+ // - symlink 链(bin → 真文件 → 再有一层 symlink)
208
+ // - 未来新增 pm 装到新位置(npm cache / corepack 等)
209
+ const PATH_AUG = '/usr/local/bin:/usr/bin:/bin:/root/.local/share/pnpm:/root/.yarn/bin:/root/.local/bin';
210
+ info('Scanning & removing any leftover openclaw binaries...');
211
+ for (let i = 0; i < 3; i++) {
212
+ const scan = await shellCapture(`PATH="${PATH_AUG}:$PATH" command -v openclaw || true`);
213
+ const leftover = (scan.stdout ?? '').trim();
214
+ if (!leftover)
215
+ break;
216
+ info(` found leftover: ${leftover}, removing`);
217
+ // 命令里路径用单引号包住,防空格 / 特殊字符;内部 ' 转义成 '\''
218
+ const safe = leftover.replace(/'/g, `'\\''`);
219
+ await shell(`rm -f '${safe}' 2>/dev/null || true`).catch(() => { });
82
220
  }
83
- // Write config
84
- mkdirSync(OPENCLAW_HOME, { recursive: true });
85
- writeFileSync(OPENCLAW_CONFIG, JSON.stringify(openclawConfig, null, 2) + '\n', 'utf8');
86
- info(`Written ${OPENCLAW_CONFIG}`);
87
- // Set default model agents.defaults.model is { "primary": "provider/modelId" }
88
- if (defaultModel) {
89
- info(`Setting default model: ${defaultModel}`);
90
- await shell(`openclaw config set agents.defaults.model.primary '${defaultModel}'`).catch(() => {
91
- warn('Failed to set default model via CLI, patching directly...');
92
- const agents = (openclawConfig.agents ?? {});
93
- const defaults = (agents.defaults ?? {});
94
- defaults.model = { primary: defaultModel };
95
- agents.defaults = defaults;
96
- openclawConfig.agents = agents;
97
- writeFileSync(OPENCLAW_CONFIG, JSON.stringify(openclawConfig, null, 2) + '\n', 'utf8');
98
- });
99
- info(`Default model: ${defaultModel}`);
221
+ info('Verifying openclaw fully removed...');
222
+ const check = await shellCapture(`PATH="${PATH_AUG}:$PATH" command -v openclaw || true`);
223
+ const resolvedPath = (check.stdout ?? '').trim();
224
+ if (resolvedPath) {
225
+ throw new Error(`openclaw still found after uninstall: ${resolvedPath}`);
100
226
  }
101
- info('openclaw configured.');
227
+ info(`Removing ${OPENCLAW_HOME}...`);
228
+ rmSync(OPENCLAW_HOME, { recursive: true, force: true });
229
+ if (existsSync(OPENCLAW_HOME)) {
230
+ throw new Error(`${OPENCLAW_HOME} still exists after removal`);
231
+ }
232
+ info('openclaw uninstalled.');
102
233
  }
103
234
  }
104
235
  //# sourceMappingURL=openclaw.js.map