@badgerclaw/connect 1.4.13 → 1.4.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.ts CHANGED
@@ -65,6 +65,9 @@ async function startPairWatcher(logger: { info?: (msg: string) => void; warn?: (
65
65
 
66
66
  // Write to config via openclaw config set — triggers hot-reload, bot starts immediately
67
67
  const { execSync } = await import("child_process");
68
+ const path = await import("path");
69
+ const os = await import("os");
70
+ const fs = await import("fs");
68
71
  const localpart = bot.user_id.split(":")[0].replace("@", "").replace(/_bot$/, "");
69
72
  const base = `channels.badgerclaw.accounts.${localpart}`;
70
73
  const opts = { encoding: "utf-8" as const, timeout: 10000, stdio: "pipe" as const };
@@ -74,6 +77,9 @@ async function startPairWatcher(logger: { info?: (msg: string) => void; warn?: (
74
77
  execSync(`openclaw config set ${base}.encryption true`, opts);
75
78
  if (bot.device_id) execSync(`openclaw config set ${base}.deviceId "${bot.device_id}"`, opts);
76
79
 
80
+ // Auto-provision agent with separate context for this bot
81
+ provisionBotAgent({ localpart, botName: bot.bot_name, fs, path, os, execSync, opts });
82
+
77
83
  // Mark claimed
78
84
  await fetch(`${API_BASE}/api/v1/openclaw/pending-pairs/${data.pair_code}/claim`, {
79
85
  method: "POST",
@@ -94,6 +100,62 @@ async function startPairWatcher(logger: { info?: (msg: string) => void; warn?: (
94
100
  connect();
95
101
  }
96
102
 
103
+ function provisionBotAgent(params: {
104
+ localpart: string;
105
+ botName: string;
106
+ fs: any;
107
+ path: any;
108
+ os: any;
109
+ execSync: any;
110
+ opts: any;
111
+ }): void {
112
+ const { localpart, botName, fs, path, os, execSync, opts } = params;
113
+ try {
114
+ // 1. Create agent workspace dir with SOUL.md
115
+ const agentDir = path.join(os.homedir(), ".openclaw", "agents", localpart);
116
+ fs.mkdirSync(agentDir, { recursive: true });
117
+ const soulPath = path.join(agentDir, "SOUL.md");
118
+ if (!fs.existsSync(soulPath)) {
119
+ fs.writeFileSync(soulPath, `# SOUL.md — ${botName}\n\nI am ${botName}, a helpful AI assistant on BadgerClaw. I respond directly and helpfully. My name is ${botName}.\n`);
120
+ }
121
+ const agentsPath = path.join(agentDir, "AGENTS.md");
122
+ if (!fs.existsSync(agentsPath)) {
123
+ fs.writeFileSync(agentsPath, `# AGENTS.md\n## Session Startup\nRead SOUL.md\n`);
124
+ }
125
+
126
+ // 2. Add agent to agents.list
127
+ const cfgPath = path.join(os.homedir(), ".openclaw", "openclaw.json");
128
+ const cfg = JSON.parse(fs.readFileSync(cfgPath, "utf-8"));
129
+ const agentsList: any[] = cfg.agents?.list ?? [];
130
+ if (!agentsList.find((a: any) => a.id === localpart)) {
131
+ agentsList.push({
132
+ id: localpart,
133
+ name: botName,
134
+ model: "anthropic/claude-sonnet-4-6",
135
+ workspace: agentDir,
136
+ agentDir: path.join(agentDir, "agent"),
137
+ identity: { name: botName, emoji: "🤖" },
138
+ });
139
+ cfg.agents = cfg.agents ?? {};
140
+ cfg.agents.list = agentsList;
141
+ }
142
+
143
+ // 3. Add binding: badgerclaw.<localpart> → agent:<localpart>
144
+ const bindings: any[] = cfg.bindings ?? [];
145
+ if (!bindings.find((b: any) => b.match?.channel === "badgerclaw" && b.match?.accountId === localpart)) {
146
+ bindings.push({ type: "route", agentId: localpart, match: { channel: "badgerclaw", accountId: localpart } });
147
+ cfg.bindings = bindings;
148
+ }
149
+
150
+ fs.writeFileSync(cfgPath, JSON.stringify(cfg, null, 2));
151
+
152
+ // Trigger hot-reload via a harmless config set touch
153
+ try { execSync(`openclaw config set channels.badgerclaw.accounts.${localpart}.agentId "${localpart}"`, opts); } catch {}
154
+ } catch (e: any) {
155
+ console.log(`[badgerclaw] agent provision warning for ${localpart}: ${e.message}`);
156
+ }
157
+ }
158
+
97
159
  async function checkPluginUpdate(log: (msg: string) => void): Promise<void> {
98
160
  try {
99
161
  const CURRENT = "1.4.4";
@@ -159,11 +221,20 @@ const plugin = {
159
221
  };
160
222
  await writeConfigFile(snapshot.path, cfg);
161
223
 
224
+ // Auto-provision separate agent with its own context
225
+ const { execSync } = await import("child_process");
226
+ const pathMod = await import("path");
227
+ const osMod = await import("os");
228
+ const fsMod = await import("fs");
229
+ const opts = { encoding: "utf-8" as const, timeout: 10000, stdio: "pipe" as const };
230
+ provisionBotAgent({ localpart, botName: result.bot_name, fs: fsMod, path: pathMod, os: osMod, execSync, opts });
231
+
162
232
  console.log("\n✅ Connected to BadgerClaw bot!");
163
233
  console.log(" Bot name: " + result.bot_name);
164
234
  console.log(" Bot user: " + result.user_id);
165
235
  console.log(" Account: " + localpart);
166
- console.log("\n⚡ Bot account written to OpenClaw config — hot-reloading...");
236
+ console.log(" Agent: agent:" + localpart + " (separate context)");
237
+ console.log("\n⚡ Bot account + agent written to OpenClaw config — hot-reloading...");
167
238
  } catch (err: any) {
168
239
  console.error("\n❌ Failed to connect: " + (err.message || err));
169
240
  process.exit(1);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@badgerclaw/connect",
3
- "version": "1.4.13",
3
+ "version": "1.4.15",
4
4
  "description": "BadgerClaw channel plugin for OpenClaw",
5
5
  "type": "module",
6
6
  "dependencies": {
@@ -36,7 +36,7 @@ export type MonitorMatrixOpts = {
36
36
  };
37
37
 
38
38
  const DEFAULT_MEDIA_MAX_MB = 20;
39
- export const DEFAULT_STARTUP_GRACE_MS = 5000;
39
+ export const DEFAULT_STARTUP_GRACE_MS = 300_000; // 5 minutes — process messages from before/after startup
40
40
 
41
41
  export function isConfiguredMatrixRoomEntry(entry: string): boolean {
42
42
  return entry.startsWith("!") || (entry.startsWith("#") && entry.includes(":"));