@kartik.doda/openclaw-plugin-test 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.
Files changed (95) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +128 -0
  3. package/dist/cli/admin-api.d.ts +58 -0
  4. package/dist/cli/admin-api.d.ts.map +1 -0
  5. package/dist/cli/admin-api.js +242 -0
  6. package/dist/cli/admin-api.js.map +1 -0
  7. package/dist/cli/auth.d.ts +5 -0
  8. package/dist/cli/auth.d.ts.map +1 -0
  9. package/dist/cli/auth.js +184 -0
  10. package/dist/cli/auth.js.map +1 -0
  11. package/dist/cli/bot.d.ts +3 -0
  12. package/dist/cli/bot.d.ts.map +1 -0
  13. package/dist/cli/bot.js +100 -0
  14. package/dist/cli/bot.js.map +1 -0
  15. package/dist/cli/config-updater.d.ts +70 -0
  16. package/dist/cli/config-updater.d.ts.map +1 -0
  17. package/dist/cli/config-updater.js +277 -0
  18. package/dist/cli/config-updater.js.map +1 -0
  19. package/dist/cli/credentials.d.ts +14 -0
  20. package/dist/cli/credentials.d.ts.map +1 -0
  21. package/dist/cli/credentials.js +45 -0
  22. package/dist/cli/credentials.js.map +1 -0
  23. package/dist/cli/rate-limiter.d.ts +17 -0
  24. package/dist/cli/rate-limiter.d.ts.map +1 -0
  25. package/dist/cli/rate-limiter.js +78 -0
  26. package/dist/cli/rate-limiter.js.map +1 -0
  27. package/dist/cli/setup.d.ts +2 -0
  28. package/dist/cli/setup.d.ts.map +1 -0
  29. package/dist/cli/setup.js +292 -0
  30. package/dist/cli/setup.js.map +1 -0
  31. package/dist/cli/ui.d.ts +30 -0
  32. package/dist/cli/ui.d.ts.map +1 -0
  33. package/dist/cli/ui.js +202 -0
  34. package/dist/cli/ui.js.map +1 -0
  35. package/dist/client/ddp.d.ts +31 -0
  36. package/dist/client/ddp.d.ts.map +1 -0
  37. package/dist/client/ddp.js +86 -0
  38. package/dist/client/ddp.js.map +1 -0
  39. package/dist/client/rest.d.ts +49 -0
  40. package/dist/client/rest.d.ts.map +1 -0
  41. package/dist/client/rest.js +347 -0
  42. package/dist/client/rest.js.map +1 -0
  43. package/dist/config/access-store.d.ts +29 -0
  44. package/dist/config/access-store.d.ts.map +1 -0
  45. package/dist/config/access-store.js +71 -0
  46. package/dist/config/access-store.js.map +1 -0
  47. package/dist/config/schema.d.ts +33 -0
  48. package/dist/config/schema.d.ts.map +1 -0
  49. package/dist/config/schema.js +52 -0
  50. package/dist/config/schema.js.map +1 -0
  51. package/dist/config/store.d.ts +11 -0
  52. package/dist/config/store.d.ts.map +1 -0
  53. package/dist/config/store.js +82 -0
  54. package/dist/config/store.js.map +1 -0
  55. package/dist/index.d.ts +4 -0
  56. package/dist/index.d.ts.map +1 -0
  57. package/dist/index.js +17 -0
  58. package/dist/index.js.map +1 -0
  59. package/dist/plugin.d.ts +5 -0
  60. package/dist/plugin.d.ts.map +1 -0
  61. package/dist/plugin.js +164 -0
  62. package/dist/plugin.js.map +1 -0
  63. package/dist/service/attachments.d.ts +10 -0
  64. package/dist/service/attachments.d.ts.map +1 -0
  65. package/dist/service/attachments.js +105 -0
  66. package/dist/service/attachments.js.map +1 -0
  67. package/dist/service/channel.d.ts +25 -0
  68. package/dist/service/channel.d.ts.map +1 -0
  69. package/dist/service/channel.js +747 -0
  70. package/dist/service/channel.js.map +1 -0
  71. package/dist/service/gateway.d.ts +7 -0
  72. package/dist/service/gateway.d.ts.map +1 -0
  73. package/dist/service/gateway.js +621 -0
  74. package/dist/service/gateway.js.map +1 -0
  75. package/dist/service/group-history.d.ts +8 -0
  76. package/dist/service/group-history.d.ts.map +1 -0
  77. package/dist/service/group-history.js +24 -0
  78. package/dist/service/group-history.js.map +1 -0
  79. package/dist/service/inbound.d.ts +16 -0
  80. package/dist/service/inbound.d.ts.map +1 -0
  81. package/dist/service/inbound.js +189 -0
  82. package/dist/service/inbound.js.map +1 -0
  83. package/dist/service/runtime-state.d.ts +8 -0
  84. package/dist/service/runtime-state.d.ts.map +1 -0
  85. package/dist/service/runtime-state.js +3 -0
  86. package/dist/service/runtime-state.js.map +1 -0
  87. package/dist/types.d.ts +220 -0
  88. package/dist/types.d.ts.map +1 -0
  89. package/dist/types.js +2 -0
  90. package/dist/types.js.map +1 -0
  91. package/dist/utils.d.ts +15 -0
  92. package/dist/utils.d.ts.map +1 -0
  93. package/dist/utils.js +68 -0
  94. package/dist/utils.js.map +1 -0
  95. package/package.json +57 -0
@@ -0,0 +1,184 @@
1
+ import { loginAs, TwoFactorRequiredError, isTimeoutError, verifyAdmin, } from "./admin-api.js";
2
+ import { saveAdmin, loadAdmin } from "./credentials.js";
3
+ import { color, promptPassword, promptSelect, promptText, promptTwoFactorCode, prompts as p, withSpinner, } from "./ui.js";
4
+ export async function tryBotLogin(rcUrl, username, password) {
5
+ return loginForServer(rcUrl, username, password, username);
6
+ }
7
+ export async function loginForServer(rcUrl, user, password, label) {
8
+ return loginWithTwoFactor(rcUrl, user, password, label);
9
+ }
10
+ /** Log in, prompting for a 2FA code when the server requires it. */
11
+ async function loginWithTwoFactor(rcUrl, user, password, label) {
12
+ const maxAttempts = 4;
13
+ let transactionId;
14
+ let methods = ["totp"];
15
+ // Initial login attempt — triggers the 2FA challenge from the server.
16
+ try {
17
+ return await loginAs(rcUrl, user, password);
18
+ }
19
+ catch (e) {
20
+ if (!(e instanceof TwoFactorRequiredError)) {
21
+ if (isTimeoutError(e)) {
22
+ p.log.error("Server timed out during login. Check your connection and try again.");
23
+ }
24
+ else {
25
+ p.log.error(`Login failed: ${e instanceof Error ? e.message : String(e)}`);
26
+ }
27
+ return null;
28
+ }
29
+ transactionId = e.challenge.transactionId || undefined;
30
+ methods = e.challenge.methods.length > 0 ? e.challenge.methods : ["totp"];
31
+ }
32
+ // Re-prompt and resubmit with the same transaction ID, avoiding a
33
+ // redundant challenge round-trip on each retry.
34
+ for (let attempt = 0; attempt < maxAttempts; attempt++) {
35
+ const method = methods.length > 1
36
+ ? await promptSelect({
37
+ message: "Two-factor method",
38
+ options: methods.map((m) => ({ value: m, label: m })),
39
+ })
40
+ : methods[0] ?? "totp";
41
+ if (method === "email") {
42
+ p.log.info(`A verification code should have been emailed to ${color.cyan(label)}. If you don't receive it, the account may not have email 2FA enabled — leave empty to abort.`);
43
+ }
44
+ const code = await promptTwoFactorCode({
45
+ message: `Two-factor code for ${label}`,
46
+ method,
47
+ allowEmpty: method === "email",
48
+ });
49
+ if (!code) {
50
+ p.log.error("No code entered. Aborting two-factor login.");
51
+ return null;
52
+ }
53
+ try {
54
+ return await loginAs(rcUrl, user, password, {
55
+ code,
56
+ ...(transactionId ? { transactionId } : {}),
57
+ });
58
+ }
59
+ catch (inner) {
60
+ if (inner instanceof TwoFactorRequiredError) {
61
+ transactionId = inner.challenge.transactionId || transactionId;
62
+ methods = inner.challenge.methods.length > 0 ? inner.challenge.methods : methods;
63
+ const retryMethod = inner.challenge.methods[0] ?? method;
64
+ const hint = retryMethod === "email"
65
+ ? "Invalid or expired email code. Check your inbox and try again (leave empty to abort)."
66
+ : "Invalid or expired two-factor code. Please try again.";
67
+ p.log.error(hint);
68
+ continue;
69
+ }
70
+ const msg = inner instanceof Error ? inner.message : String(inner);
71
+ if (isTimeoutError(inner)) {
72
+ p.log.error("Server timed out while verifying the code. Check your connection and try again.");
73
+ return null;
74
+ }
75
+ if (/rate.?limit|too many|too many requests/i.test(msg)) {
76
+ p.log.error("Too many login attempts. Rocket.Chat has rate-limited this endpoint. Wait a moment and re-run setup.");
77
+ return null;
78
+ }
79
+ p.log.error(`Login failed: ${msg}`);
80
+ return null;
81
+ }
82
+ }
83
+ p.log.error("Too many two-factor attempts. Re-run setup to try again.");
84
+ return null;
85
+ }
86
+ export async function resolveAdminAuth(rcUrl, forceFresh = false) {
87
+ if (!forceFresh) {
88
+ const savedAdmin = (await loadAdmin(rcUrl)) ?? (await loadAdmin());
89
+ if (savedAdmin) {
90
+ const candidateAuth = { userId: savedAdmin.userId, authToken: savedAdmin.authToken };
91
+ const verdict = await verifyAdmin(rcUrl, candidateAuth);
92
+ if (verdict.ok) {
93
+ p.log.success(`Reusing saved admin credentials for ${color.cyan(rcUrl)}`);
94
+ return candidateAuth;
95
+ }
96
+ p.log.warn("Saved admin credentials are invalid for this server. Please log in again.");
97
+ }
98
+ }
99
+ const adminUser = await promptText({
100
+ message: "Admin username",
101
+ validate: (value) => ((value ?? "").trim() ? undefined : "Username is required"),
102
+ });
103
+ for (let attempt = 1; attempt <= 3; attempt++) {
104
+ const adminPass = await promptPassword({
105
+ message: attempt === 1
106
+ ? "Admin password"
107
+ : `Wrong password — re-enter for ${adminUser} (${3 - attempt} attempt${3 - attempt === 1 ? "" : "s"} left)`,
108
+ validate: (value) => (value ? undefined : "Password is required"),
109
+ });
110
+ let adminAuth = null;
111
+ try {
112
+ adminAuth = await loginForServer(rcUrl, adminUser, adminPass, adminUser);
113
+ }
114
+ catch (e) {
115
+ if (isTimeoutError(e)) {
116
+ p.log.error("Server timed out during login. Check your connection and try again.");
117
+ return null;
118
+ }
119
+ const message = e instanceof Error ? e.message : String(e);
120
+ p.log.error(`Login failed: ${message}`);
121
+ if (attempt === 3) {
122
+ p.log.error("Too many failed attempts. Re-run setup to try again.");
123
+ return null;
124
+ }
125
+ continue;
126
+ }
127
+ if (!adminAuth) {
128
+ p.log.error("Login failed: Unauthorized. Check the password and try again.");
129
+ if (attempt === 3) {
130
+ p.log.error("Too many failed attempts. Re-run setup to try again.");
131
+ return null;
132
+ }
133
+ continue;
134
+ }
135
+ const result = await withSpinner("Verifying admin access", async () => {
136
+ try {
137
+ const verdict = await verifyAdmin(rcUrl, adminAuth);
138
+ if (!verdict.ok) {
139
+ return { ok: false, reason: verdict.reason };
140
+ }
141
+ await saveAdmin({
142
+ serverUrl: rcUrl,
143
+ userId: adminAuth.userId,
144
+ authToken: adminAuth.authToken,
145
+ });
146
+ p.log.success(`Logged in as ${color.cyan(adminUser)}`);
147
+ return { ok: true, auth: adminAuth };
148
+ }
149
+ catch (e) {
150
+ if (isTimeoutError(e)) {
151
+ return {
152
+ ok: false,
153
+ reason: "error",
154
+ message: "Server timed out while verifying admin status. Check your connection and try again.",
155
+ };
156
+ }
157
+ const message = e instanceof Error ? e.message : String(e);
158
+ return { ok: false, reason: "error", message };
159
+ }
160
+ });
161
+ if (result.ok)
162
+ return result.auth;
163
+ if (result.reason === "not-admin") {
164
+ p.log.error(`"${adminUser}" is not an admin (missing 'admin' role). Bot creation requires an admin account.`);
165
+ return null;
166
+ }
167
+ else if (result.reason === "unauthorized") {
168
+ p.log.error("Admin login expired or invalid. Please log in again.");
169
+ }
170
+ else if (result.reason === "unreachable") {
171
+ p.log.error("Could not verify admin status — Rocket.Chat server unreachable.");
172
+ return null;
173
+ }
174
+ else if (result.reason === "error") {
175
+ p.log.error(`Login failed: ${result.message}`);
176
+ }
177
+ if (attempt === 3) {
178
+ p.log.error("Too many failed attempts. Re-run setup to try again.");
179
+ return null;
180
+ }
181
+ }
182
+ return null;
183
+ }
184
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/cli/auth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { RCLoginResult } from "../types.js";
2
+ export declare function resolveBotAuth(rcUrl: string, adminAuth: RCLoginResult, botUsername: string): Promise<RCLoginResult | null>;
3
+ //# sourceMappingURL=bot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bot.d.ts","sourceRoot":"","sources":["../../src/cli/bot.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAmBjD,wBAAsB,cAAc,CAClC,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,aAAa,EACxB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAa/B"}
@@ -0,0 +1,100 @@
1
+ import { createBotUser, getUserInfo, } from "./admin-api.js";
2
+ import { checkBotCreationLimit, recordBotCreation } from "./rate-limiter.js";
3
+ import { saveBotCredentials, loadBotCredentials } from "./credentials.js";
4
+ import { color, promptPassword, promptPasswordConfirm, promptText, prompts as p, withSpinner, } from "./ui.js";
5
+ import { loginForServer, tryBotLogin } from "./auth.js";
6
+ async function promptBotPassword(botUsername) {
7
+ const savedBot = await loadBotCredentials(botUsername);
8
+ if (savedBot?.password) {
9
+ p.log.info(`Reusing saved password for ${color.cyan(`@${botUsername}`)}`);
10
+ return savedBot.password;
11
+ }
12
+ return promptPasswordConfirm({
13
+ message: "Bot password (min 6 characters)",
14
+ validate: (value) => {
15
+ if (!value)
16
+ return "Password is required";
17
+ if (value.length < 6)
18
+ return "Password must be at least 6 characters";
19
+ return undefined;
20
+ },
21
+ });
22
+ }
23
+ export async function resolveBotAuth(rcUrl, adminAuth, botUsername) {
24
+ const existingUser = await withSpinner(`Checking @${botUsername} on Rocket.Chat`, () => getUserInfo(rcUrl, adminAuth, { username: botUsername }));
25
+ if (existingUser) {
26
+ p.log.success(`Bot ${color.cyan(`@${botUsername}`)} already exists — verifying its credentials`);
27
+ return verifyExistingBot(rcUrl, botUsername);
28
+ }
29
+ return createNewBot(rcUrl, adminAuth, botUsername);
30
+ }
31
+ async function verifyExistingBot(rcUrl, botUsername) {
32
+ const savedBot = await loadBotCredentials(botUsername);
33
+ if (savedBot?.password) {
34
+ const cached = await tryBotLogin(rcUrl, botUsername, savedBot.password);
35
+ if (cached) {
36
+ await saveBotCredentials(botUsername, { userId: cached.userId, password: savedBot.password });
37
+ p.log.success(`Verified bot ${color.cyan(`@${botUsername}`)}`);
38
+ return cached;
39
+ }
40
+ }
41
+ for (let attempt = 1; attempt <= 3; attempt++) {
42
+ const botPassword = await promptPassword({
43
+ message: attempt === 1
44
+ ? `Password for existing bot @${botUsername}`
45
+ : `Wrong password — re-enter for @${botUsername} (${3 - attempt} attempt${3 - attempt === 1 ? "" : "s"} left)`,
46
+ validate: (value) => (value ? undefined : "Password is required"),
47
+ });
48
+ const auth = await loginForServer(rcUrl, botUsername, botPassword, botUsername);
49
+ if (auth) {
50
+ await saveBotCredentials(botUsername, { userId: auth.userId, password: botPassword });
51
+ p.log.success(`Verified bot ${color.cyan(`@${botUsername}`)}`);
52
+ return auth;
53
+ }
54
+ p.log.error("Login failed: Unauthorized. Check the password and try again.");
55
+ }
56
+ p.log.error("Too many failed attempts. Re-run setup with the correct bot password.");
57
+ return null;
58
+ }
59
+ async function createNewBot(rcUrl, adminAuth, botUsername) {
60
+ const limitCheck = checkBotCreationLimit("cli", { serverUrl: rcUrl });
61
+ if (!limitCheck.allowed) {
62
+ p.log.error(limitCheck.reason ?? "Bot creation limit reached.");
63
+ return null;
64
+ }
65
+ const botName = await promptText({ message: "Bot display name", defaultValue: botUsername });
66
+ const botEmail = await promptText({
67
+ message: "Bot email",
68
+ defaultValue: `${botUsername.toLowerCase()}@openclaw.local`,
69
+ validate: (value) => ((value ?? "").includes("@") ? undefined : "Enter a valid email"),
70
+ });
71
+ const botPassword = await promptBotPassword(botUsername);
72
+ const botUser = await withSpinner(`Creating bot ${color.cyan(`@${botUsername}`)}`, async () => {
73
+ try {
74
+ return await createBotUser(rcUrl, adminAuth, {
75
+ username: botUsername,
76
+ name: botName,
77
+ password: botPassword,
78
+ email: botEmail,
79
+ });
80
+ }
81
+ catch (e) {
82
+ p.log.error(`Failed to create bot: ${e instanceof Error ? e.message : String(e)}`);
83
+ return null;
84
+ }
85
+ });
86
+ if (!botUser)
87
+ return null;
88
+ recordBotCreation(botUsername, "cli");
89
+ p.log.success(`Created bot ${color.cyan(`@${botUser.username}`)} ${color.dim(`(${botUser._id})`)}`);
90
+ const auth = await loginForServer(rcUrl, botUsername, botPassword, botUsername);
91
+ if (auth) {
92
+ await saveBotCredentials(botUsername, { userId: auth.userId, password: botPassword });
93
+ }
94
+ if (!auth) {
95
+ p.log.error("Bot login failed after creation. Check the bot's credentials and re-run setup.");
96
+ return null;
97
+ }
98
+ return auth;
99
+ }
100
+ //# sourceMappingURL=bot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bot.js","sourceRoot":"","sources":["../../src/cli/bot.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,WAAW,GACZ,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAC7E,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAC1E,OAAO,EACL,KAAK,EACL,cAAc,EACd,qBAAqB,EACrB,UAAU,EACV,OAAO,IAAI,CAAC,EACZ,WAAW,GACZ,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAGxD,KAAK,UAAU,iBAAiB,CAAC,WAAmB;IAClD,MAAM,QAAQ,GAAG,MAAM,kBAAkB,CAAC,WAAW,CAAC,CAAC;IACvD,IAAI,QAAQ,EAAE,QAAQ,EAAE,CAAC;QACvB,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,8BAA8B,KAAK,CAAC,IAAI,CAAC,IAAI,WAAW,EAAE,CAAC,EAAE,CAAC,CAAC;QAC1E,OAAO,QAAQ,CAAC,QAAQ,CAAC;IAC3B,CAAC;IAED,OAAO,qBAAqB,CAAC;QAC3B,OAAO,EAAE,iCAAiC;QAC1C,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE;YAClB,IAAI,CAAC,KAAK;gBAAE,OAAO,sBAAsB,CAAC;YAC1C,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;gBAAE,OAAO,wCAAwC,CAAC;YACtE,OAAO,SAAS,CAAC;QACnB,CAAC;KACF,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,KAAa,EACb,SAAwB,EACxB,WAAmB;IAEnB,MAAM,YAAY,GAAG,MAAM,WAAW,CAAC,aAAa,WAAW,iBAAiB,EAAE,GAAG,EAAE,CACrF,WAAW,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC,CACzD,CAAC;IAEF,IAAI,YAAY,EAAE,CAAC;QACjB,CAAC,CAAC,GAAG,CAAC,OAAO,CACX,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,WAAW,EAAE,CAAC,6CAA6C,CAClF,CAAC;QACF,OAAO,iBAAiB,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;IAC/C,CAAC;IAED,OAAO,YAAY,CAAC,KAAK,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC;AACrD,CAAC;AAED,KAAK,UAAU,iBAAiB,CAC9B,KAAa,EACb,WAAmB;IAEnB,MAAM,QAAQ,GAAG,MAAM,kBAAkB,CAAC,WAAW,CAAC,CAAC;IACvD,IAAI,QAAQ,EAAE,QAAQ,EAAE,CAAC;QACvB,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,KAAK,EAAE,WAAW,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACxE,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,kBAAkB,CAAC,WAAW,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC;YAC9F,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,gBAAgB,KAAK,CAAC,IAAI,CAAC,IAAI,WAAW,EAAE,CAAC,EAAE,CAAC,CAAC;YAC/D,OAAO,MAAM,CAAC;QAChB,CAAC;IACH,CAAC;IAED,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,CAAC,EAAE,OAAO,EAAE,EAAE,CAAC;QAC9C,MAAM,WAAW,GAAG,MAAM,cAAc,CAAC;YACvC,OAAO,EACL,OAAO,KAAK,CAAC;gBACX,CAAC,CAAC,8BAA8B,WAAW,EAAE;gBAC7C,CAAC,CAAC,kCAAkC,WAAW,KAAK,CAAC,GAAG,OAAO,WAAW,CAAC,GAAG,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,QAAQ;YAClH,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,sBAAsB,CAAC;SAClE,CAAC,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,cAAc,CAAC,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,CAAC,CAAC;QAChF,IAAI,IAAI,EAAE,CAAC;YACT,MAAM,kBAAkB,CAAC,WAAW,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC,CAAC;YACtF,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,gBAAgB,KAAK,CAAC,IAAI,CAAC,IAAI,WAAW,EAAE,CAAC,EAAE,CAAC,CAAC;YAC/D,OAAO,IAAI,CAAC;QACd,CAAC;QACD,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,+DAA+D,CAAC,CAAC;IAC/E,CAAC;IAED,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,uEAAuE,CAAC,CAAC;IACrF,OAAO,IAAI,CAAC;AACd,CAAC;AAED,KAAK,UAAU,YAAY,CACzB,KAAa,EACb,SAAwB,EACxB,WAAmB;IAEnB,MAAM,UAAU,GAAG,qBAAqB,CAAC,KAAK,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;IACtE,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;QACxB,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,IAAI,6BAA6B,CAAC,CAAC;QAChE,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC,EAAE,OAAO,EAAE,kBAAkB,EAAE,YAAY,EAAE,WAAW,EAAE,CAAC,CAAC;IAC7F,MAAM,QAAQ,GAAG,MAAM,UAAU,CAAC;QAChC,OAAO,EAAE,WAAW;QACpB,YAAY,EAAE,GAAG,WAAW,CAAC,WAAW,EAAE,iBAAiB;QAC3D,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,qBAAqB,CAAC;KACvF,CAAC,CAAC;IACH,MAAM,WAAW,GAAG,MAAM,iBAAiB,CAAC,WAAW,CAAC,CAAC;IAEzD,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,gBAAgB,KAAK,CAAC,IAAI,CAAC,IAAI,WAAW,EAAE,CAAC,EAAE,EAAE,KAAK,IAAI,EAAE;QAC5F,IAAI,CAAC;YACH,OAAO,MAAM,aAAa,CAAC,KAAK,EAAE,SAAS,EAAE;gBAC3C,QAAQ,EAAE,WAAW;gBACrB,IAAI,EAAE,OAAO;gBACb,QAAQ,EAAE,WAAW;gBACrB,KAAK,EAAE,QAAQ;aAChB,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,CAAU,EAAE,CAAC;YACpB,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,yBAAyB,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACnF,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC,CAAC,CAAC;IACH,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAC1B,iBAAiB,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;IACtC,CAAC,CAAC,GAAG,CAAC,OAAO,CACX,eAAe,KAAK,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,GAAG,GAAG,CAAC,EAAE,CACrF,CAAC;IAEF,MAAM,IAAI,GAAG,MAAM,cAAc,CAAC,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,CAAC,CAAC;IAChF,IAAI,IAAI,EAAE,CAAC;QACT,MAAM,kBAAkB,CAAC,WAAW,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC,CAAC;IACxF,CAAC;IACD,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,gFAAgF,CAAC,CAAC;QAC9F,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,70 @@
1
+ import type { AuthCredentials, JsonObject } from "../types.js";
2
+ export type TokenAuth = Extract<AuthCredentials, {
3
+ mode: "token";
4
+ }>;
5
+ export declare function readConfig(): JsonObject;
6
+ export type ExistingAccount = {
7
+ accountId: string;
8
+ serverUrl: string;
9
+ mentionNames: string[];
10
+ auth: TokenAuth;
11
+ owner?: string;
12
+ };
13
+ export declare function readAllAccounts(): ExistingAccount[];
14
+ export declare function collectBotUserIdsForServer(serverUrl: string): Set<string>;
15
+ export declare function collectBotUsernamesForServer(serverUrl: string): Set<string>;
16
+ export declare function readAccount(accountId?: string): ExistingAccount | null;
17
+ export declare function updateConfig(opts: {
18
+ pluginPath: string;
19
+ pluginId: string;
20
+ accountId: string;
21
+ serverUrl: string;
22
+ transport?: {
23
+ mode: "websocket";
24
+ };
25
+ mentionNames?: string[];
26
+ auth: TokenAuth;
27
+ owner?: string;
28
+ replaceConnection?: boolean;
29
+ }): void;
30
+ export declare function readAgentsList(): Array<{
31
+ id: string;
32
+ name?: string;
33
+ }>;
34
+ export declare function readBindingsForAccount(accountId: string): Array<{
35
+ agentId: string;
36
+ peer?: {
37
+ kind: string;
38
+ id: string;
39
+ };
40
+ }>;
41
+ export declare function addAccount(opts: {
42
+ accountId: string;
43
+ serverUrl: string;
44
+ auth: TokenAuth;
45
+ mentionNames: string[];
46
+ transport?: {
47
+ mode: "websocket";
48
+ };
49
+ owner?: string;
50
+ }): void;
51
+ export declare function readOwner(accountId: string): string | undefined;
52
+ export declare function ensureAgentForBot(accountId: string): {
53
+ agentId: string;
54
+ created: boolean;
55
+ fallback: boolean;
56
+ };
57
+ export declare function isAgentBound(agentId: string): boolean;
58
+ export declare function addBinding(opts: {
59
+ channel: string;
60
+ accountId: string;
61
+ agentId: string;
62
+ peer?: {
63
+ kind: string;
64
+ id: string;
65
+ };
66
+ }): void;
67
+ export declare function removeBindingsForAccount(accountId: string): void;
68
+ export declare function removeAccount(accountId: string): void;
69
+ export declare function removeAgentDir(accountId: string): void;
70
+ //# sourceMappingURL=config-updater.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-updater.d.ts","sourceRoot":"","sources":["../../src/cli/config-updater.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAI/D,MAAM,MAAM,SAAS,GAAG,OAAO,CAAC,eAAe,EAAE;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,CAAC,CAAC;AAEpE,wBAAgB,UAAU,IAAI,UAAU,CAGvC;AAQD,MAAM,MAAM,eAAe,GAAG;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,wBAAgB,eAAe,IAAI,eAAe,EAAE,CAOnD;AAED,wBAAgB,0BAA0B,CAAC,SAAS,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAMzE;AAED,wBAAgB,4BAA4B,CAAC,SAAS,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAM3E;AAED,wBAAgB,WAAW,CAAC,SAAS,SAAS,GAAG,eAAe,GAAG,IAAI,CA2BtE;AAMD,wBAAgB,YAAY,CAAC,IAAI,EAAE;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE;QAAE,IAAI,EAAE,WAAW,CAAA;KAAE,CAAC;IAClC,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B,QAsDA;AAED,wBAAgB,cAAc,IAAI,KAAK,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CA6BrE;AAED,wBAAgB,sBAAsB,CACpC,SAAS,EAAE,MAAM,GAChB,KAAK,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,CAAC,CAejE;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,SAAS,CAAC;IAChB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,SAAS,CAAC,EAAE;QAAE,IAAI,EAAE,WAAW,CAAA;KAAE,CAAC;IAClC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,IAAI,CAyBP;AAED,wBAAgB,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAK/D;AAED,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG;IACpD,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;CACnB,CAkBA;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAUrD;AAMD,wBAAgB,UAAU,CAAC,IAAI,EAAE;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;CACrC,GAAG,IAAI,CAgCP;AAED,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAUhE;AAED,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAOrD;AAED,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAGtD"}
@@ -0,0 +1,277 @@
1
+ import { existsSync, readFileSync, writeFileSync, renameSync, readdirSync, rmSync } from "node:fs";
2
+ import { resolve } from "node:path";
3
+ import { homedir } from "node:os";
4
+ import { execFileSync } from "node:child_process";
5
+ import JSON5 from "json5";
6
+ const OC_CONFIG_PATH = resolve(homedir(), ".openclaw", "openclaw.json");
7
+ export function readConfig() {
8
+ if (!existsSync(OC_CONFIG_PATH))
9
+ return {};
10
+ return JSON5.parse(readFileSync(OC_CONFIG_PATH, "utf-8"));
11
+ }
12
+ function writeConfig(cfg) {
13
+ const tmp = OC_CONFIG_PATH + ".tmp";
14
+ writeFileSync(tmp, JSON.stringify(cfg, null, 2) + "\n", "utf-8");
15
+ renameSync(tmp, OC_CONFIG_PATH);
16
+ }
17
+ export function readAllAccounts() {
18
+ const cfg = readConfig();
19
+ const accounts = cfg?.channels?.rocketchat?.accounts;
20
+ if (!accounts || typeof accounts !== "object")
21
+ return [];
22
+ return Object.keys(accounts)
23
+ .map((id) => readAccount(id))
24
+ .filter((a) => a !== null);
25
+ }
26
+ export function collectBotUserIdsForServer(serverUrl) {
27
+ return new Set(readAllAccounts()
28
+ .filter((a) => a.serverUrl === serverUrl)
29
+ .map((a) => a.auth.userId));
30
+ }
31
+ export function collectBotUsernamesForServer(serverUrl) {
32
+ return new Set(readAllAccounts()
33
+ .filter((a) => a.serverUrl === serverUrl)
34
+ .flatMap((a) => (a.mentionNames.length > 0 ? a.mentionNames : [a.accountId])));
35
+ }
36
+ export function readAccount(accountId = "main") {
37
+ const cfg = readConfig();
38
+ const accounts = cfg?.channels?.rocketchat?.accounts;
39
+ if (!accounts || typeof accounts !== "object")
40
+ return null;
41
+ const target = accountId.toLowerCase();
42
+ const key = Object.keys(accounts).find((k) => k.toLowerCase() === target);
43
+ const account = key ? accounts[key] : undefined;
44
+ if (!account || typeof account !== "object")
45
+ return null;
46
+ const serverUrl = typeof account.serverUrl === "string" ? account.serverUrl : "";
47
+ const auth = account.auth;
48
+ if (!serverUrl || !auth || auth.mode !== "token")
49
+ return null;
50
+ if (typeof auth.userId !== "string" || typeof auth.accessToken !== "string")
51
+ return null;
52
+ if (!auth.userId || !auth.accessToken)
53
+ return null;
54
+ const mentionNames = Array.isArray(account.mentionNames)
55
+ ? account.mentionNames.filter((n) => typeof n === "string" && n.length > 0)
56
+ : [];
57
+ const owner = typeof account.owner === "string" && account.owner.length > 0 ? account.owner : undefined;
58
+ return {
59
+ accountId,
60
+ serverUrl,
61
+ mentionNames,
62
+ auth: { mode: "token", userId: auth.userId, accessToken: auth.accessToken },
63
+ ...(owner ? { owner } : {}),
64
+ };
65
+ }
66
+ function normalizeMention(name) {
67
+ return name.trim().replace(/^@+/, "");
68
+ }
69
+ export function updateConfig(opts) {
70
+ const cfg = readConfig();
71
+ if (!cfg.plugins)
72
+ cfg.plugins = {};
73
+ if (!cfg.plugins.load)
74
+ cfg.plugins.load = {};
75
+ if (!cfg.plugins.load.paths)
76
+ cfg.plugins.load.paths = [];
77
+ if (!cfg.plugins.load.paths.includes(opts.pluginPath)) {
78
+ cfg.plugins.load.paths.push(opts.pluginPath);
79
+ }
80
+ if (!cfg.plugins.allow)
81
+ cfg.plugins.allow = [];
82
+ if (!cfg.plugins.allow.includes(opts.pluginId)) {
83
+ cfg.plugins.allow.push(opts.pluginId);
84
+ }
85
+ if (!cfg.channels)
86
+ cfg.channels = {};
87
+ if (!cfg.channels.rocketchat)
88
+ cfg.channels.rocketchat = {};
89
+ if (!cfg.channels.rocketchat.accounts)
90
+ cfg.channels.rocketchat.accounts = {};
91
+ const accounts = cfg.channels.rocketchat.accounts;
92
+ const existing = accounts[opts.accountId];
93
+ const existingMentions = Array.isArray(existing?.mentionNames)
94
+ ? existing.mentionNames
95
+ .map((n) => (typeof n === "string" ? normalizeMention(n) : ""))
96
+ .filter(Boolean)
97
+ : [];
98
+ const incomingMentions = (opts.mentionNames ?? []).map(normalizeMention).filter(Boolean);
99
+ const mergedMentions = [...existingMentions];
100
+ for (const m of incomingMentions) {
101
+ if (!mergedMentions.includes(m))
102
+ mergedMentions.push(m);
103
+ }
104
+ const serverUrl = opts.replaceConnection
105
+ ? opts.serverUrl
106
+ : (existing?.serverUrl ?? opts.serverUrl);
107
+ const auth = opts.replaceConnection
108
+ ? { mode: "token", userId: opts.auth.userId, accessToken: opts.auth.accessToken }
109
+ : (existing?.auth ?? {
110
+ mode: "token",
111
+ userId: opts.auth.userId,
112
+ accessToken: opts.auth.accessToken,
113
+ });
114
+ accounts[opts.accountId] = {
115
+ ...(existing ?? {}),
116
+ enabled: true,
117
+ serverUrl,
118
+ auth,
119
+ transport: existing?.transport ?? opts.transport ?? { mode: "websocket" },
120
+ mentionNames: opts.replaceConnection ? incomingMentions : mergedMentions,
121
+ ...(opts.owner ? { owner: opts.owner.trim().replace(/^@+/, "") } : {}),
122
+ };
123
+ writeConfig(cfg);
124
+ }
125
+ export function readAgentsList() {
126
+ // OpenClaw 2026+ stores agents as directories under ~/.openclaw/agents/
127
+ const agentsDir = resolve(homedir(), ".openclaw", "agents");
128
+ if (existsSync(agentsDir)) {
129
+ try {
130
+ const entries = readdirSync(agentsDir, { withFileTypes: true });
131
+ return entries.filter((e) => e.isDirectory()).map((e) => ({ id: e.name }));
132
+ }
133
+ catch {
134
+ // fall through
135
+ }
136
+ }
137
+ // Fallback: agents.list array in config
138
+ const cfg = readConfig();
139
+ const list = cfg?.agents?.list;
140
+ if (Array.isArray(list)) {
141
+ return list
142
+ .filter((a) => a && typeof a === "object")
143
+ .map((a) => {
144
+ const id = typeof a.id === "string" ? a.id : "";
145
+ const name = typeof a.name === "string" ? a.name : undefined;
146
+ const result = { id };
147
+ if (name !== undefined)
148
+ result.name = name;
149
+ return result;
150
+ })
151
+ .filter((a) => a.id.length > 0);
152
+ }
153
+ return [];
154
+ }
155
+ export function readBindingsForAccount(accountId) {
156
+ const cfg = readConfig();
157
+ const bindings = cfg?.bindings;
158
+ if (!Array.isArray(bindings))
159
+ return [];
160
+ return bindings
161
+ .filter((b) => b?.match?.channel === "rocketchat" && b?.match?.accountId === accountId)
162
+ .map((b) => {
163
+ const result = {
164
+ agentId: typeof b.agentId === "string" ? b.agentId : "(unknown)",
165
+ };
166
+ if (b.match?.peer) {
167
+ result.peer = { kind: b.match.peer.kind, id: b.match.peer.id };
168
+ }
169
+ return result;
170
+ });
171
+ }
172
+ export function addAccount(opts) {
173
+ const cfg = readConfig();
174
+ if (!cfg.channels)
175
+ cfg.channels = {};
176
+ if (!cfg.channels.rocketchat)
177
+ cfg.channels.rocketchat = {};
178
+ if (!cfg.channels.rocketchat.accounts)
179
+ cfg.channels.rocketchat.accounts = {};
180
+ const accounts = cfg.channels.rocketchat.accounts;
181
+ const owner = opts.owner?.trim().replace(/^@+/, "");
182
+ accounts[opts.accountId] = {
183
+ ...(accounts[opts.accountId] ?? {}),
184
+ enabled: true,
185
+ serverUrl: opts.serverUrl,
186
+ auth: {
187
+ mode: "token",
188
+ userId: opts.auth.userId,
189
+ accessToken: opts.auth.accessToken,
190
+ },
191
+ transport: opts.transport ?? { mode: "websocket" },
192
+ mentionNames: opts.mentionNames.map(normalizeMention).filter(Boolean),
193
+ ...(owner ? { owner } : {}),
194
+ };
195
+ writeConfig(cfg);
196
+ }
197
+ export function readOwner(accountId) {
198
+ const cfg = readConfig();
199
+ const account = cfg?.channels?.rocketchat?.accounts?.[accountId];
200
+ const owner = account?.owner;
201
+ return typeof owner === "string" && owner.length > 0 ? owner : undefined;
202
+ }
203
+ export function ensureAgentForBot(accountId) {
204
+ const dedicatedId = `rc-${accountId}`;
205
+ const existing = readAgentsList();
206
+ if (existing.some((a) => a.id === dedicatedId)) {
207
+ return { agentId: dedicatedId, created: false, fallback: false };
208
+ }
209
+ try {
210
+ const workspace = resolve(homedir(), ".openclaw", "agents", dedicatedId);
211
+ execFileSync("openclaw", ["agents", "add", dedicatedId, "--non-interactive", "--workspace", workspace], { stdio: "ignore" });
212
+ return { agentId: dedicatedId, created: true, fallback: false };
213
+ }
214
+ catch {
215
+ return { agentId: "main", created: false, fallback: true };
216
+ }
217
+ }
218
+ export function isAgentBound(agentId) {
219
+ const cfg = readConfig();
220
+ const bindings = cfg?.bindings;
221
+ if (!Array.isArray(bindings))
222
+ return false;
223
+ return bindings.some((b) => b?.match?.channel === "rocketchat" &&
224
+ typeof b.agentId === "string" &&
225
+ normalizeAgentId(b.agentId) === normalizeAgentId(agentId));
226
+ }
227
+ function normalizeAgentId(id) {
228
+ return id.trim().toLowerCase();
229
+ }
230
+ export function addBinding(opts) {
231
+ const cfg = readConfig();
232
+ if (!cfg.bindings)
233
+ cfg.bindings = [];
234
+ const bindings = cfg.bindings;
235
+ const existingIndex = bindings.findIndex((b) => b.match?.channel === opts.channel &&
236
+ b.match?.accountId === opts.accountId &&
237
+ (!opts.peer || JSON.stringify(b.match?.peer) === JSON.stringify(opts.peer)));
238
+ const binding = {
239
+ agentId: opts.agentId,
240
+ match: {
241
+ channel: opts.channel,
242
+ accountId: opts.accountId,
243
+ },
244
+ };
245
+ if (opts.peer) {
246
+ binding.match.peer = opts.peer;
247
+ }
248
+ if (existingIndex >= 0) {
249
+ bindings[existingIndex] = binding;
250
+ }
251
+ else {
252
+ bindings.push(binding);
253
+ }
254
+ writeConfig(cfg);
255
+ }
256
+ export function removeBindingsForAccount(accountId) {
257
+ const cfg = readConfig();
258
+ const bindings = cfg?.bindings;
259
+ if (!bindings)
260
+ return;
261
+ cfg.bindings = bindings.filter((b) => !(b.match?.channel === "rocketchat" && b.match?.accountId === accountId));
262
+ writeConfig(cfg);
263
+ }
264
+ export function removeAccount(accountId) {
265
+ const cfg = readConfig();
266
+ const accounts = cfg?.channels?.rocketchat?.accounts;
267
+ if (accounts) {
268
+ delete accounts[accountId];
269
+ }
270
+ writeConfig(cfg);
271
+ }
272
+ export function removeAgentDir(accountId) {
273
+ const dir = resolve(homedir(), ".openclaw", "agents", `rc-${accountId}`);
274
+ if (existsSync(dir))
275
+ rmSync(dir, { recursive: true, force: true });
276
+ }
277
+ //# sourceMappingURL=config-updater.js.map