clawmoney 0.3.0 → 0.4.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.
@@ -27,8 +27,8 @@ export declare class BridgeServer {
27
27
  getPort(): number;
28
28
  }
29
29
  /**
30
- * Send an action to the extension via the running Bridge server.
31
- * Connects as a CLI client, sends action, waits for result, disconnects.
30
+ * Send an action to the Chrome Extension.
31
+ * Auto-starts bridge server if none is running, then waits for extension to connect.
32
32
  */
33
33
  export declare function sendAction(actionType: string, params: Record<string, unknown>, port?: number): Promise<{
34
34
  success: boolean;
@@ -161,12 +161,53 @@ export class BridgeServer {
161
161
  return this.port;
162
162
  }
163
163
  }
164
+ // Singleton bridge server — auto-started on first sendAction call
165
+ let _server = null;
164
166
  /**
165
- * Send an action to the extension via the running Bridge server.
166
- * Connects as a CLI client, sends action, waits for result, disconnects.
167
+ * Ensure a bridge server is running. Starts one if needed.
168
+ */
169
+ async function ensureBridge(port) {
170
+ if (_server)
171
+ return _server;
172
+ // Try connecting to an existing server first
173
+ const existing = await new Promise((resolve) => {
174
+ const ws = new WebSocket(`ws://127.0.0.1:${port}`);
175
+ const t = setTimeout(() => { ws.close(); resolve(false); }, 1000);
176
+ ws.on('open', () => { clearTimeout(t); ws.close(); resolve(true); });
177
+ ws.on('error', () => { clearTimeout(t); resolve(false); });
178
+ });
179
+ if (existing) {
180
+ // Another bridge (or `clawmoney serve`) is already running — use it as client
181
+ return null; // signal to use client mode
182
+ }
183
+ // Start our own bridge in-process
184
+ const server = new BridgeServer(port);
185
+ await server.start();
186
+ _server = server;
187
+ return server;
188
+ }
189
+ /**
190
+ * Send an action to the Chrome Extension.
191
+ * Auto-starts bridge server if none is running, then waits for extension to connect.
167
192
  */
168
193
  export async function sendAction(actionType, params, port) {
169
194
  const wsPort = port || DEFAULT_PORT;
195
+ // Ensure bridge is running
196
+ const server = await ensureBridge(wsPort).catch(() => null);
197
+ // If we own the server, wait for extension to connect (up to 30s)
198
+ if (server && _server === server) {
199
+ const waitStart = Date.now();
200
+ while (!server.isExtensionConnected() && Date.now() - waitStart < 30000) {
201
+ await new Promise(r => setTimeout(r, 500));
202
+ }
203
+ if (!server.isExtensionConnected()) {
204
+ return {
205
+ success: false,
206
+ error: 'Chrome Extension not connected. Make sure BNBot extension is running on a Twitter tab with OpenClaw integration enabled.',
207
+ };
208
+ }
209
+ }
210
+ // Send action via WebSocket client
170
211
  return new Promise((resolve, reject) => {
171
212
  const ws = new WebSocket(`ws://127.0.0.1:${wsPort}`);
172
213
  const requestId = randomUUID();
@@ -200,11 +241,11 @@ export async function sendAction(actionType, params, port) {
200
241
  // ignore
201
242
  }
202
243
  });
203
- ws.on('error', (err) => {
244
+ ws.on('error', () => {
204
245
  if (!settled) {
205
246
  settled = true;
206
247
  clearTimeout(timer);
207
- reject(new Error(`Cannot connect to bridge server on port ${wsPort}. Run 'clawmoney serve' first.`));
248
+ reject(new Error('Cannot connect to bridge. Make sure BNBot Chrome Extension is running.'));
208
249
  }
209
250
  });
210
251
  ws.on('close', () => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clawmoney",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "ClawMoney CLI -- Earn crypto with your AI agent",
5
5
  "type": "module",
6
6
  "bin": {