openclaw-channel-dmwork 0.5.20 → 0.6.0-dev.cea9ee46

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.
@@ -1,151 +1,245 @@
1
1
  /**
2
- * install command: install plugin via official CLI + interactive config setup.
2
+ * install command: install or update the DMWork plugin.
3
+ * Pure plugin management — does NOT configure bots or bindings.
3
4
  *
4
- * Only manages channels.dmwork account config. Agent creation (binding,
5
- * workspace, agent.md) is left to the user via `openclaw agents add`.
5
+ * Handles 5 scenarios:
6
+ * 1. Legacy migration (dmwork openclaw-channel-dmwork)
7
+ * 2. Normal update (check version, update if needed)
8
+ * 3. Fresh install (nothing installed)
9
+ * 4. Deadlock repair (channels.dmwork exists but no plugin)
10
+ * 5. Broken install cleanup
11
+ */
12
+ import { copyFileSync, existsSync, rmSync } from "node:fs";
13
+ import { execFileSync } from "node:child_process";
14
+ import { cleanupBrokenInstall, deleteLegacyBackup, detectScenario, ensurePluginsAllow, gatewayRestart, getConfigFilePathSafe, isHealthyInstall, pluginsInspect, pluginsInstall, readConfigFromFile, removeLegacyFromConfig, renameLegacyDir, restoreChannelConfigFromDisk, restoreLegacyDir, saveChannelConfigToDisk, removeChannelConfigFromFile, } from "./openclaw-cli.js";
15
+ import { PLUGIN_ID, ensureOpenClawCompat, } from "./utils.js";
16
+ function getLatestNpmVersion(tag) {
17
+ try {
18
+ return execFileSync("npm", ["view", `${PLUGIN_ID}@${tag}`, "version"], {
19
+ encoding: "utf-8",
20
+ stdio: ["pipe", "pipe", "pipe"],
21
+ }).trim();
22
+ }
23
+ catch {
24
+ return null;
25
+ }
26
+ }
27
+ /**
28
+ * install command: install or update the DMWork plugin.
29
+ * Pure plugin management — does NOT configure bots or bindings.
30
+ * Use `bind` or `quickstart` for bot configuration after install.
6
31
  */
7
- import { configGet, configGetJson, configSet, configUnset, gatewayRestart, pluginsInspect, pluginsInstall, } from "./openclaw-cli.js";
8
- import { PLUGIN_ID, RECOMMENDED_DM_SCOPE, confirm, ensureOpenClawCompat, isInteractive, prompt, validateAccountId, } from "./utils.js";
9
32
  export async function runInstall(opts) {
10
- // 1. Pre-check
11
33
  ensureOpenClawCompat();
12
- // 2. Plugin install (delegate to official CLI)
13
- const inspect = pluginsInspect(PLUGIN_ID);
14
- if (inspect?.plugin && !opts.force) {
15
- console.log(`DMWork plugin is already installed (v${inspect.plugin.version}). Skipping install.`);
34
+ const scenario = detectScenario();
35
+ const tag = opts.dev ? "dev" : "latest";
36
+ const spec = opts.dev ? `${PLUGIN_ID}@dev` : PLUGIN_ID;
37
+ const quiet = false;
38
+ let didChange = false;
39
+ switch (scenario) {
40
+ case "legacy":
41
+ runLegacyMigration(spec, quiet, opts.force);
42
+ didChange = true;
43
+ break;
44
+ case "update": {
45
+ // Already installed — compare against target version
46
+ const inspect = pluginsInspect(PLUGIN_ID);
47
+ const currentVersion = inspect?.plugin?.version ?? "unknown";
48
+ if (opts.force) {
49
+ // --force: skip version check, always install target spec
50
+ console.log(`Force installing DMWork plugin${opts.dev ? " (dev)" : ""}...`);
51
+ pluginsInstall(spec, quiet, true);
52
+ console.log("Plugin installed successfully.");
53
+ didChange = true;
54
+ break;
55
+ }
56
+ const targetVersion = getLatestNpmVersion(tag);
57
+ if (!targetVersion) {
58
+ // Cannot determine target — skip install and restart
59
+ console.log(`Cannot reach npm registry to check ${tag} version.`);
60
+ console.log(`Current version: v${currentVersion}`);
61
+ return;
62
+ }
63
+ if (currentVersion === targetVersion) {
64
+ console.log(`DMWork plugin v${currentVersion} is already the target version${opts.dev ? " (dev)" : ""}. No update needed.`);
65
+ return; // Nothing changed — skip gateway restart
66
+ }
67
+ console.log(`Updating DMWork plugin: v${currentVersion} → v${targetVersion}${opts.dev ? " (dev)" : ""}...`);
68
+ pluginsInstall(spec, quiet, true); // Always use spec with tag so @dev is respected
69
+ console.log(`DMWork plugin updated from v${currentVersion} to v${targetVersion}${opts.dev ? " (dev)" : ""}.`);
70
+ didChange = true;
71
+ break;
72
+ }
73
+ case "broken": {
74
+ console.log("Detected broken plugin install. Cleaning up...");
75
+ const actions = cleanupBrokenInstall();
76
+ actions.forEach((a) => console.log(` ${a}`));
77
+ console.log(`Installing DMWork plugin${opts.dev ? " (dev)" : ""}...`);
78
+ pluginsInstall(spec, quiet, opts.force);
79
+ console.log("Plugin installed successfully.");
80
+ didChange = true;
81
+ break;
82
+ }
83
+ case "deadlock":
84
+ runDeadlockRepair(spec, quiet);
85
+ didChange = true;
86
+ break;
87
+ case "fresh":
88
+ console.log(`Installing DMWork plugin${opts.dev ? " (dev)" : ""}...`);
89
+ pluginsInstall(spec, quiet, opts.force);
90
+ console.log("Plugin installed successfully.");
91
+ didChange = true;
92
+ break;
16
93
  }
17
- else {
18
- const spec = opts.dev ? `${PLUGIN_ID}@dev` : PLUGIN_ID;
19
- console.log(`Installing DMWork plugin${opts.dev ? " (dev)" : ""}...`);
20
- pluginsInstall(spec, false, opts.force);
21
- console.log("Plugin installed successfully.");
22
- }
23
- // 3. Legacy config migration
24
- await migrateLegacyConfig();
25
- // 4. DMWork config (unless --skip-config)
26
- if (!opts.skipConfig) {
27
- await configureDmworkAccount(opts);
28
- }
29
- // 5. Gateway restart
94
+ if (!didChange)
95
+ return;
96
+ // Gateway restart (plugin lifecycle requires restart)
30
97
  console.log("Restarting gateway...");
31
98
  if (!gatewayRestart()) {
32
99
  console.log("Warning: Gateway restart failed. Run 'openclaw gateway restart' manually.");
33
100
  }
34
- // 6. Success
35
- console.log("\nDMWork plugin setup complete!");
101
+ console.log("\nDMWork plugin ready! Use BotFather /newbot or /quickstart to configure bots.");
36
102
  }
37
103
  // ---------------------------------------------------------------------------
38
- // Legacy config migration
104
+ // Scenario 1: Legacy migration (dmwork → openclaw-channel-dmwork)
39
105
  // ---------------------------------------------------------------------------
40
- async function migrateLegacyConfig() {
41
- const legacyToken = configGet("channels.dmwork.botToken");
42
- const accounts = configGetJson("channels.dmwork.accounts");
43
- // Has top-level botToken but no accounts map → legacy flat config
44
- if (legacyToken && (!accounts || Object.keys(accounts).length === 0)) {
45
- console.log("Detected legacy flat config. Migrating to accounts model...");
46
- // Copy token to accounts.default
47
- configSet("channels.dmwork.accounts.default.botToken", legacyToken);
48
- // Copy apiUrl if present
49
- const legacyApiUrl = configGet("channels.dmwork.apiUrl");
50
- if (legacyApiUrl) {
51
- configSet("channels.dmwork.accounts.default.apiUrl", legacyApiUrl);
52
- }
53
- // Remove top-level botToken (keep apiUrl as shared default)
54
- configUnset("channels.dmwork.botToken");
55
- console.log("Migrated legacy config to accounts.default.");
106
+ function runLegacyMigration(spec, quiet, force, skipConfig) {
107
+ console.log("Detected legacy DMWork plugin (dmwork). Starting migration...");
108
+ // 1. Backup everything to disk
109
+ const configPath = getConfigFilePathSafe();
110
+ const backupPath = configPath + ".dmwork-upgrade-backup";
111
+ copyFileSync(configPath, backupPath);
112
+ saveChannelConfigToDisk();
113
+ console.log(" Backed up config and channels.dmwork to disk.");
114
+ // 2. Clean up any broken new plugin install from a previous failed attempt
115
+ const brokenActions = cleanupBrokenInstall();
116
+ if (brokenActions.length > 0) {
117
+ console.log(" Cleaned up broken previous install:");
118
+ brokenActions.forEach((a) => console.log(` ${a}`));
56
119
  }
57
- }
58
- // ---------------------------------------------------------------------------
59
- // Account configuration
60
- // ---------------------------------------------------------------------------
61
- async function configureDmworkAccount(opts) {
62
- // Collect accountId
63
- let accountId = opts.accountId;
64
- if (!accountId) {
65
- accountId = await prompt("Enter bot account ID (e.g. my_bot):");
66
- if (!accountId) {
67
- console.log("No account ID provided. Skipping config.");
68
- return;
120
+ // 3. Remove legacy from config FIRST (breaks deadlock)
121
+ removeLegacyFromConfig();
122
+ console.log(" Removed legacy config entries.");
123
+ // 3. Rename legacy directory (not delete!)
124
+ const legacyDirExists = existsSync(getConfigFilePathSafe().replace(/openclaw\.json$/, "extensions/dmwork"));
125
+ let renamed = false;
126
+ if (legacyDirExists) {
127
+ renamed = renameLegacyDir();
128
+ if (renamed) {
129
+ console.log(" Renamed extensions/dmwork → .dmwork-backup.");
130
+ }
131
+ else {
132
+ // Cannot isolate old directory — abort to prevent conflict
133
+ console.error(" Failed to rename extensions/dmwork. Aborting migration.");
134
+ try {
135
+ copyFileSync(backupPath, configPath);
136
+ }
137
+ catch { /* best effort */ }
138
+ throw new Error("Legacy migration aborted: could not rename extensions/dmwork");
69
139
  }
70
140
  }
71
- if (!validateAccountId(accountId)) {
72
- console.error(`Error: Invalid account ID "${accountId}". Only letters, digits, and underscores are allowed.`);
73
- process.exit(1);
141
+ // 4. Install new plugin
142
+ try {
143
+ console.log(" Installing openclaw-channel-dmwork...");
144
+ pluginsInstall(spec, quiet, force);
74
145
  }
75
- // Check if account already exists
76
- const existingToken = configGet(`channels.dmwork.accounts.${accountId}.botToken`);
77
- if (existingToken) {
78
- if (!isInteractive()) {
79
- if (opts.botToken && opts.apiUrl) {
80
- console.log(`Overwriting existing account "${accountId}".`);
81
- }
82
- else if (opts.botToken || opts.apiUrl) {
83
- console.error(`Error: Account "${accountId}" already exists. Provide both --bot-token and --api-url to overwrite.`);
84
- process.exit(1);
85
- }
86
- else {
87
- console.log(`Account "${accountId}" already configured. Keeping existing config.`);
88
- ensureDmScope();
89
- printAgentHint(accountId);
90
- return;
91
- }
146
+ catch (installErr) {
147
+ // FAIL: restore everything
148
+ console.error(" Install failed! Restoring previous state...");
149
+ if (renamed)
150
+ restoreLegacyDir();
151
+ try {
152
+ copyFileSync(backupPath, configPath);
92
153
  }
93
- else {
94
- const keep = await confirm(`Bot account "${accountId}" is already configured. Keep current config?`, true);
95
- if (keep) {
96
- console.log("Keeping existing config.");
97
- ensureDmScope();
98
- printAgentHint(accountId);
99
- return;
100
- }
154
+ catch { /* best effort */ }
155
+ console.error(" Previous state restored. Legacy plugin should still work.");
156
+ throw installErr;
157
+ }
158
+ // 5. Verify healthy install
159
+ if (!isHealthyInstall()) {
160
+ console.error(" Install completed but verification failed. Restoring...");
161
+ if (renamed)
162
+ restoreLegacyDir();
163
+ try {
164
+ copyFileSync(backupPath, configPath);
101
165
  }
166
+ catch { /* best effort */ }
167
+ console.error(" Previous state restored.");
168
+ throw new Error("Legacy migration failed: post-install verification did not pass");
102
169
  }
103
- // Collect botToken
104
- let botToken = opts.botToken;
105
- if (!botToken) {
106
- botToken = await prompt("Enter bot token (bf_...):");
107
- }
108
- if (!botToken?.startsWith("bf_")) {
109
- console.error("Error: Bot token must start with 'bf_'.");
110
- process.exit(1);
111
- }
112
- // Collect apiUrl
113
- let apiUrl = opts.apiUrl;
114
- if (!apiUrl) {
115
- apiUrl = await prompt("Enter API server URL:");
116
- }
117
- if (!apiUrl) {
118
- console.error("Error: API URL is required.");
119
- process.exit(1);
120
- }
121
- // Write account config
122
- configSet(`channels.dmwork.accounts.${accountId}.botToken`, botToken);
123
- configSet(`channels.dmwork.accounts.${accountId}.apiUrl`, apiUrl);
124
- console.log(`Configured bot account: ${accountId}`);
125
- console.log(` API: ${apiUrl}`);
126
- ensureDmScope();
127
- printAgentHint(accountId);
170
+ // 6. Success: restore channels.dmwork + cleanup
171
+ ensurePluginsAllow();
172
+ restoreChannelConfigFromDisk();
173
+ // Verify config was actually restored before deleting backups
174
+ const restoredCfg = readConfigFromFile();
175
+ if (restoredCfg?.channels?.dmwork) {
176
+ // Config restore succeeded safe to delete backups
177
+ deleteLegacyBackup();
178
+ try {
179
+ rmSync(backupPath, { force: true });
180
+ }
181
+ catch { /* best effort */ }
182
+ }
183
+ else {
184
+ console.log(" Warning: channels.dmwork restore may not have succeeded. Keeping backups for safety.");
185
+ }
186
+ console.log(" Legacy migration complete!");
128
187
  }
129
188
  // ---------------------------------------------------------------------------
130
- // session.dmScope
189
+ // Scenario 4: Deadlock repair
131
190
  // ---------------------------------------------------------------------------
132
- function ensureDmScope() {
133
- const current = configGet("session.dmScope");
134
- if (!current) {
135
- configSet("session.dmScope", RECOMMENDED_DM_SCOPE);
191
+ function runDeadlockRepair(spec, quiet, skipConfig) {
192
+ console.log("Detected config deadlock (channels.dmwork exists but no plugin).");
193
+ // 1. Backup
194
+ const configPath = getConfigFilePathSafe();
195
+ const backupPath = configPath + ".dmwork-upgrade-backup";
196
+ copyFileSync(configPath, backupPath);
197
+ saveChannelConfigToDisk();
198
+ // 2. Remove channels.dmwork
199
+ removeChannelConfigFromFile();
200
+ console.log(" Temporarily removed channels.dmwork.");
201
+ // 3. Install
202
+ try {
203
+ console.log(" Installing openclaw-channel-dmwork...");
204
+ pluginsInstall(spec, quiet);
136
205
  }
137
- else if (current !== RECOMMENDED_DM_SCOPE) {
138
- console.log(`Warning: session.dmScope is "${current}" (recommended: ${RECOMMENDED_DM_SCOPE})`);
206
+ catch (installErr) {
207
+ console.error(" Install failed! Restoring config...");
208
+ try {
209
+ copyFileSync(backupPath, configPath);
210
+ }
211
+ catch { /* best effort */ }
212
+ throw installErr;
213
+ }
214
+ // 4. Verify
215
+ if (!isHealthyInstall()) {
216
+ console.error(" Install completed but verification failed. Restoring config...");
217
+ try {
218
+ copyFileSync(backupPath, configPath);
219
+ }
220
+ catch { /* best effort */ }
221
+ throw new Error("Deadlock repair failed: post-install verification did not pass");
222
+ }
223
+ // 5. Success
224
+ ensurePluginsAllow();
225
+ restoreChannelConfigFromDisk();
226
+ // Verify config was restored before deleting backup
227
+ const restoredCfg = readConfigFromFile();
228
+ if (restoredCfg?.channels?.dmwork) {
229
+ try {
230
+ rmSync(backupPath, { force: true });
231
+ }
232
+ catch { /* best effort */ }
233
+ console.log(" Deadlock repaired!");
234
+ }
235
+ else {
236
+ // Config restore failed — plugin is installed but bot config is missing
237
+ throw new Error("Deadlock repair incomplete: plugin installed but channels.dmwork could not be restored. Backup kept at " + backupPath);
139
238
  }
140
239
  }
141
240
  // ---------------------------------------------------------------------------
142
- // Agent hint
241
+ // Exported for update.ts and doctor.ts to reuse
143
242
  // ---------------------------------------------------------------------------
144
- function printAgentHint(accountId) {
145
- const agentName = accountId.replace(/_bot$/, "");
146
- console.log(`
147
- To create an independent agent for this bot (optional):
148
- openclaw agents add ${agentName}
149
- openclaw agents bind ${agentName} dmwork ${accountId}`);
150
- }
243
+ export { runLegacyMigration as runLegacyMigrationForUpdate };
244
+ export { runDeadlockRepair as runDeadlockRepairForUpdate };
151
245
  //# sourceMappingURL=install.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"install.js","sourceRoot":"","sources":["../../cli/install.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"install.js","sourceRoot":"","sources":["../../cli/install.ts"],"names":[],"mappings":"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"}
@@ -3,6 +3,8 @@
3
3
  * All openclaw invocations go through this module using execFileSync with
4
4
  * argument arrays to avoid shell-quoting issues.
5
5
  */
6
+ /** Get the resolved openclaw binary path */
7
+ export declare function getOpenClawBin(): string;
6
8
  export declare function getConfigFilePath(): string;
7
9
  export declare function configGet(path: string): string | null;
8
10
  export declare function configGetJson(path: string): any;
@@ -28,7 +30,41 @@ export interface PluginInspectResult {
28
30
  installPath: string;
29
31
  };
30
32
  }
33
+ export type InspectFailReason = "unsupported" | "not_found" | "error";
34
+ export interface PluginsInspectOutcome {
35
+ ok: boolean;
36
+ data: PluginInspectResult | null;
37
+ failReason: InspectFailReason | null;
38
+ }
39
+ /**
40
+ * Inspect a plugin. Returns structured outcome distinguishing:
41
+ * - ok + data: inspect succeeded
42
+ * - unsupported: old OpenClaw without `plugins inspect`
43
+ * - not_found: plugin genuinely not found
44
+ * - error: other failure (config corruption, plugin load crash, etc.)
45
+ */
46
+ export declare function pluginsInspectDetailed(id: string): PluginsInspectOutcome;
47
+ /** Backward-compatible wrapper: returns data or null. */
31
48
  export declare function pluginsInspect(id: string): PluginInspectResult | null;
49
+ export interface PluginResolvedState {
50
+ installed: boolean;
51
+ enabled: boolean | null;
52
+ version: string | null;
53
+ installPath: string | null;
54
+ source: "inspect" | "fallback";
55
+ /** Why inspect failed. null when source === "inspect". */
56
+ inspectFailReason: InspectFailReason | null;
57
+ }
58
+ /**
59
+ * Resolve plugin install state. Uses `plugins inspect` when available,
60
+ * falls back to config entries + directory + package.json for old OpenClaw
61
+ * versions that don't support `plugins inspect`.
62
+ *
63
+ * Fallback installed = all 3 artifacts present (entries + installs + dir),
64
+ * matching detectScenario()'s healthy definition. Partial presence is NOT
65
+ * considered installed — that's a broken state for doctor --fix to handle.
66
+ */
67
+ export declare function resolvePluginState(id: string): PluginResolvedState;
32
68
  export declare function gatewayStatus(): {
33
69
  running: boolean;
34
70
  };
@@ -45,6 +81,17 @@ export declare function saveChannelConfigFromFile(): Record<string, unknown> | n
45
81
  * Creates a .bak backup before writing.
46
82
  */
47
83
  export declare function restoreChannelConfigToFile(dmworkConfig: Record<string, unknown>): void;
84
+ /**
85
+ * Remove channels.dmwork directly from the JSON file.
86
+ * Used before uninstall to avoid config validation errors
87
+ * (openclaw config unset also fails when the channel id is unknown).
88
+ */
89
+ /**
90
+ * Get the openclaw config file path without calling the CLI.
91
+ * Falls back to the standard default when CLI is unavailable
92
+ * (e.g. during uninstall when config validation fails).
93
+ */
94
+ export declare function getConfigFilePathSafe(): string;
48
95
  export declare function removeChannelConfigFromFile(): void;
49
96
  /**
50
97
  * Read the full config object directly from file (for doctor phase-1 checks).
@@ -56,3 +103,49 @@ export declare function readConfigFromFile(): Record<string, any> | null;
56
103
  * not in that list. Otherwise removes all dmwork bindings.
57
104
  */
58
105
  export declare function removeOrphanedBindingsFromFile(channel: string, validAccountIds?: string[]): void;
106
+ /**
107
+ * Detect and clean up legacy DMWork plugin installations that conflict
108
+ * with the current openclaw-channel-dmwork plugin.
109
+ *
110
+ * Known legacy artifacts:
111
+ * - ~/.openclaw/extensions/dmwork/ (old plugin directory, id="dmwork")
112
+ * - plugins.entries.dmwork in openclaw.json
113
+ *
114
+ * Returns a list of actions taken (for logging).
115
+ */
116
+ export declare function cleanupLegacyPlugin(): string[];
117
+ /**
118
+ * Clean up stale openclaw-channel-dmwork directory that is not registered
119
+ * in plugins.installs (orphaned from a failed previous install).
120
+ *
121
+ * Only removes the directory if ALL of these are true:
122
+ * 1. The directory exists
123
+ * 2. pluginsInspect returns null (openclaw doesn't recognize it)
124
+ * 3. plugins.installs has no record for openclaw-channel-dmwork
125
+ */
126
+ export declare function cleanupStalePluginDir(): string[];
127
+ /**
128
+ * Clean up stale openclaw-install-stage directories that belong to DMWork.
129
+ * Only removes directories that:
130
+ * 1. Match .openclaw-install-stage-* pattern
131
+ * 2. Are older than 10 minutes (not a current installation)
132
+ * 3. Contain a package.json with name "openclaw-channel-dmwork"
133
+ */
134
+ export declare function cleanupStaleStageDirectories(): string[];
135
+ /**
136
+ * Write openclaw.json atomically: write to .tmp then rename.
137
+ * Prevents gateway watcher from reading half-written/truncated JSON.
138
+ */
139
+ export declare function writeConfigAtomic(cfg: Record<string, any>): void;
140
+ export type UpgradeScenario = "legacy" | "update" | "fresh" | "deadlock" | "broken";
141
+ export declare function detectScenario(): UpgradeScenario;
142
+ export declare function isHealthyInstall(): boolean;
143
+ export declare function ensurePluginsAllow(): void;
144
+ export declare function pluginsUpdateCompat(id: string, tag: string, quiet?: boolean): void;
145
+ export declare function renameLegacyDir(): boolean;
146
+ export declare function restoreLegacyDir(): void;
147
+ export declare function deleteLegacyBackup(): void;
148
+ export declare function removeLegacyFromConfig(): void;
149
+ export declare function saveChannelConfigToDisk(): void;
150
+ export declare function restoreChannelConfigFromDisk(): void;
151
+ export declare function cleanupBrokenInstall(): string[];