@clawrent/cli 0.4.3 → 0.5.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.
package/dist/lib.d.ts CHANGED
@@ -1,204 +1 @@
1
- import { EventEmitter } from 'node:events';
2
- import WebSocket from 'ws';
3
-
4
- interface ClawRentConfig {
5
- apiUrl: string;
6
- wsUrl: string;
7
- token?: string;
8
- apiKey?: string;
9
- userId?: string;
10
- email?: string;
11
- name?: string;
12
- }
13
- declare function getConfigPath(): string;
14
- declare function loadConfig(): ClawRentConfig;
15
- declare function saveConfig(partial: Partial<ClawRentConfig>): void;
16
- declare function clearConfig(): void;
17
-
18
- declare class ApiClient {
19
- private config;
20
- /** When set (e.g. by ProviderAgent.start), overrides config.token for REST auth. */
21
- private agentTokenOverride;
22
- constructor(config: ClawRentConfig);
23
- /**
24
- * Set a token that overrides config.token for subsequent REST requests.
25
- * Used by the in-process provider agent: once serving with an agentToken,
26
- * provider REST calls (approve/list/end + internal autoApprove) authenticate
27
- * as the agent owner via this token, so they work without a separate user
28
- * JWT login. The backend's resolveAuth accepts the agt_clawrent_* prefix.
29
- * Pass null to clear (e.g. on stop_serving).
30
- */
31
- setAgentToken(token: string | null): void;
32
- get apiUrl(): string;
33
- get wsUrl(): string;
34
- get userId(): string | undefined;
35
- sendVerification(email: string): Promise<{
36
- message: string;
37
- }>;
38
- registerUser(input: {
39
- email: string;
40
- password: string;
41
- name: string;
42
- verificationCode: string;
43
- }): Promise<{
44
- user: {
45
- id: string;
46
- email: string;
47
- name: string;
48
- role: string;
49
- };
50
- token: string;
51
- apiKey: string;
52
- }>;
53
- login(email: string, password: string): Promise<{
54
- user: {
55
- id: string;
56
- email: string;
57
- name: string;
58
- role: string;
59
- };
60
- token: string;
61
- }>;
62
- getMe(): Promise<Record<string, unknown>>;
63
- browse(query?: {
64
- search?: string;
65
- category?: string;
66
- page?: number;
67
- limit?: number;
68
- }): Promise<unknown>;
69
- getAgent(slug: string): Promise<unknown>;
70
- rent(options: {
71
- agentId: string;
72
- taskDescription: string;
73
- grantedPermissions?: Record<string, unknown>;
74
- }): Promise<unknown>;
75
- getSessions(query?: {
76
- role?: string;
77
- status?: string;
78
- page?: number;
79
- limit?: number;
80
- }): Promise<unknown>;
81
- getSession(sessionId: string): Promise<Record<string, unknown>>;
82
- getSessionMessages(sessionId: string): Promise<unknown>;
83
- endSession(sessionId: string): Promise<unknown>;
84
- approveSession(sessionId: string): Promise<unknown>;
85
- getBalance(): Promise<{
86
- balance: string;
87
- }>;
88
- topUp(amount: string): Promise<{
89
- balance: string;
90
- }>;
91
- registerAgent(data: Record<string, unknown>): Promise<unknown>;
92
- getMyAgents(query?: {
93
- page?: number;
94
- limit?: number;
95
- roles?: string;
96
- }): Promise<unknown>;
97
- /** Resolve the current agent from agentToken. Requires agt_clawrent_ token auth. */
98
- getMyAgent(): Promise<Record<string, unknown>>;
99
- applyProvider(agentId: string, data: Record<string, unknown>): Promise<unknown>;
100
- /** Publish agent — simplified apply-provider with defaults, submits for admin review */
101
- publishAgent(agentId: string, data?: Record<string, unknown>): Promise<unknown>;
102
- /** Activate agent — verify admin-approved + WebSocket connected, then go online */
103
- activateAgent(agentId: string): Promise<unknown>;
104
- setOnlineStatus(agentId: string, onlineStatus: string): Promise<unknown>;
105
- generateAgentToken(agentId: string): Promise<{
106
- agentId: string;
107
- token: string;
108
- createdAt: string;
109
- warning: string;
110
- }>;
111
- revokeAgentToken(agentId: string): Promise<{
112
- message: string;
113
- }>;
114
- createOrder(data: {
115
- items: Array<{
116
- providerAgentId: string;
117
- consumerAgentId?: string;
118
- taskDescription: string;
119
- grantedPermissions?: Record<string, unknown>;
120
- }>;
121
- note?: string;
122
- fromCart?: boolean;
123
- }): Promise<unknown>;
124
- getOrders(query?: {
125
- status?: string;
126
- page?: number;
127
- limit?: number;
128
- }): Promise<unknown>;
129
- getOrder(orderId: string): Promise<unknown>;
130
- cancelOrder(orderId: string): Promise<unknown>;
131
- getCart(): Promise<unknown>;
132
- addToCart(data: {
133
- providerAgentId: string;
134
- taskDescription: string;
135
- }): Promise<unknown>;
136
- updateCartItem(itemId: string, data: {
137
- taskDescription: string;
138
- }): Promise<unknown>;
139
- removeFromCart(itemId: string): Promise<unknown>;
140
- clearCart(): Promise<unknown>;
141
- listFavorites(query?: {
142
- page?: number;
143
- limit?: number;
144
- }): Promise<unknown>;
145
- addFavorite(agentId: string): Promise<unknown>;
146
- removeFavorite(agentId: string): Promise<unknown>;
147
- health(): Promise<unknown>;
148
- getDocsTree(): Promise<unknown>;
149
- getDocByPath(path: string): Promise<unknown>;
150
- searchDocs(query: string): Promise<unknown>;
151
- getDoc(id: string): Promise<unknown>;
152
- createDoc(data: {
153
- type: string;
154
- title: string;
155
- parentId?: string;
156
- content?: string;
157
- slug?: string;
158
- icon?: string;
159
- }): Promise<unknown>;
160
- updateDoc(id: string, data: {
161
- title?: string;
162
- content?: string;
163
- changeSummary?: string;
164
- }): Promise<unknown>;
165
- deleteDoc(id: string): Promise<unknown>;
166
- publishDoc(id: string): Promise<unknown>;
167
- unpublishDoc(id: string): Promise<unknown>;
168
- private request;
169
- }
170
-
171
- interface SessionConnection {
172
- sessionId: string;
173
- sessionToken: string;
174
- ws: WebSocket;
175
- heartbeatTimer: ReturnType<typeof setInterval> | null;
176
- reconnectAttempts: number;
177
- }
178
- /**
179
- * SessionManager manages multiple concurrent WebSocket connections,
180
- * one per active session.
181
- */
182
- declare class SessionManager extends EventEmitter {
183
- private sessions;
184
- private wsUrl;
185
- private heartbeatInterval;
186
- private maxReconnectDelay;
187
- agentId?: string;
188
- constructor(wsUrl: string, heartbeatInterval?: number, maxReconnectDelay?: number);
189
- /** Connect to a session via WebSocket as provider */
190
- connect(sessionId: string, sessionToken: string): void;
191
- /** Send a message to a specific session, auto-wrapping with protocol envelope */
192
- send(sessionId: string, message: Record<string, unknown>): boolean;
193
- /** Disconnect a specific session */
194
- disconnect(sessionId: string): void;
195
- /** Disconnect all sessions */
196
- disconnectAll(): void;
197
- /** Get active session count */
198
- get activeCount(): number;
199
- /** Check if a session is connected */
200
- isConnected(sessionId: string): boolean;
201
- private clearHeartbeat;
202
- }
203
-
204
- export { ApiClient, type ClawRentConfig, type SessionConnection, SessionManager, clearConfig, getConfigPath, loadConfig, saveConfig };
1
+ export { ApiClient, ClawRentConfig, SessionConnection, SessionManager, clearConfig, getConfigPath, loadConfig, saveConfig } from '@clawrent/provider';
package/dist/lib.js CHANGED
@@ -1,434 +1,12 @@
1
- // src/api-client.ts
2
- var ApiClient = class {
3
- config;
4
- /** When set (e.g. by ProviderAgent.start), overrides config.token for REST auth. */
5
- agentTokenOverride = null;
6
- constructor(config) {
7
- this.config = config;
8
- }
9
- /**
10
- * Set a token that overrides config.token for subsequent REST requests.
11
- * Used by the in-process provider agent: once serving with an agentToken,
12
- * provider REST calls (approve/list/end + internal autoApprove) authenticate
13
- * as the agent owner via this token, so they work without a separate user
14
- * JWT login. The backend's resolveAuth accepts the agt_clawrent_* prefix.
15
- * Pass null to clear (e.g. on stop_serving).
16
- */
17
- setAgentToken(token) {
18
- this.agentTokenOverride = token;
19
- }
20
- get apiUrl() {
21
- return this.config.apiUrl;
22
- }
23
- get wsUrl() {
24
- return this.config.wsUrl;
25
- }
26
- get userId() {
27
- return this.config.userId;
28
- }
29
- // --- Auth (no auth needed) ---
30
- async sendVerification(email) {
31
- return this.request("POST", "/api/auth/send-verification", { email }, false);
32
- }
33
- async registerUser(input) {
34
- return this.request("POST", "/api/auth/register", input, false);
35
- }
36
- async login(email, password) {
37
- return this.request("POST", "/api/auth/login", { email, password }, false);
38
- }
39
- async getMe() {
40
- return this.request("GET", "/api/auth/me");
41
- }
42
- // --- Marketplace ---
43
- async browse(query) {
44
- const params = new URLSearchParams();
45
- if (query?.search) params.set("search", query.search);
46
- if (query?.category) params.set("category", query.category);
47
- if (query?.page) params.set("page", String(query.page));
48
- if (query?.limit) params.set("limit", String(query.limit));
49
- const qs = params.toString();
50
- return this.request("GET", `/api/marketplace/browse${qs ? `?${qs}` : ""}`);
51
- }
52
- async getAgent(slug) {
53
- return this.request("GET", `/api/marketplace/agents/${encodeURIComponent(slug)}`);
54
- }
55
- // --- Sessions ---
56
- async rent(options) {
57
- return this.request("POST", "/api/sessions", {
58
- agentId: options.agentId,
59
- taskDescription: options.taskDescription,
60
- grantedPermissions: options.grantedPermissions ?? {}
61
- });
62
- }
63
- async getSessions(query) {
64
- const params = new URLSearchParams();
65
- if (query?.role) params.set("role", query.role);
66
- if (query?.status) params.set("status", query.status);
67
- if (query?.page) params.set("page", String(query.page));
68
- if (query?.limit) params.set("limit", String(query.limit));
69
- const qs = params.toString();
70
- return this.request("GET", `/api/sessions${qs ? `?${qs}` : ""}`);
71
- }
72
- async getSession(sessionId) {
73
- return this.request("GET", `/api/sessions/${encodeURIComponent(sessionId)}`);
74
- }
75
- async getSessionMessages(sessionId) {
76
- return this.request("GET", `/api/sessions/${encodeURIComponent(sessionId)}/messages`);
77
- }
78
- async endSession(sessionId) {
79
- return this.request("POST", `/api/sessions/${encodeURIComponent(sessionId)}/end`);
80
- }
81
- async approveSession(sessionId) {
82
- return this.request("POST", `/api/sessions/${encodeURIComponent(sessionId)}/approve`);
83
- }
84
- // --- Billing ---
85
- async getBalance() {
86
- return this.request("GET", "/api/billing/wallet");
87
- }
88
- async topUp(amount) {
89
- return this.request("POST", "/api/billing/wallet/topup", { amount });
90
- }
91
- // --- Provider: Agents ---
92
- async registerAgent(data) {
93
- return this.request("POST", "/api/agents", data);
94
- }
95
- async getMyAgents(query) {
96
- const params = new URLSearchParams();
97
- if (query?.page) params.set("page", String(query.page));
98
- if (query?.limit) params.set("limit", String(query.limit));
99
- if (query?.roles) params.set("roles", query.roles);
100
- const qs = params.toString();
101
- return this.request("GET", `/api/agents/my${qs ? `?${qs}` : ""}`);
102
- }
103
- /** Resolve the current agent from agentToken. Requires agt_clawrent_ token auth. */
104
- async getMyAgent() {
105
- return this.request("GET", "/api/agents/me/agent");
106
- }
107
- async applyProvider(agentId, data) {
108
- return this.request("POST", `/api/agents/${encodeURIComponent(agentId)}/apply-provider`, data);
109
- }
110
- /** Publish agent — simplified apply-provider with defaults, submits for admin review */
111
- async publishAgent(agentId, data) {
112
- return this.request("POST", `/api/agents/${encodeURIComponent(agentId)}/publish`, data ?? {});
113
- }
114
- /** Activate agent — verify admin-approved + WebSocket connected, then go online */
115
- async activateAgent(agentId) {
116
- return this.request("POST", `/api/agents/${encodeURIComponent(agentId)}/activate`);
117
- }
118
- async setOnlineStatus(agentId, onlineStatus) {
119
- return this.request("PATCH", `/api/agents/${encodeURIComponent(agentId)}/status`, { onlineStatus });
120
- }
121
- async generateAgentToken(agentId) {
122
- return this.request("POST", `/api/agents/${encodeURIComponent(agentId)}/token`);
123
- }
124
- async revokeAgentToken(agentId) {
125
- return this.request("DELETE", `/api/agents/${encodeURIComponent(agentId)}/token`);
126
- }
127
- // --- Orders ---
128
- async createOrder(data) {
129
- return this.request("POST", "/api/orders", data);
130
- }
131
- async getOrders(query) {
132
- const params = new URLSearchParams();
133
- if (query?.status) params.set("status", query.status);
134
- if (query?.page) params.set("page", String(query.page));
135
- if (query?.limit) params.set("limit", String(query.limit));
136
- const qs = params.toString();
137
- return this.request("GET", `/api/orders${qs ? `?${qs}` : ""}`);
138
- }
139
- async getOrder(orderId) {
140
- return this.request("GET", `/api/orders/${encodeURIComponent(orderId)}`);
141
- }
142
- async cancelOrder(orderId) {
143
- return this.request("POST", `/api/orders/${encodeURIComponent(orderId)}/cancel`);
144
- }
145
- // --- Cart ---
146
- async getCart() {
147
- return this.request("GET", "/api/cart");
148
- }
149
- async addToCart(data) {
150
- return this.request("POST", "/api/cart", data);
151
- }
152
- async updateCartItem(itemId, data) {
153
- return this.request("PATCH", `/api/cart/${encodeURIComponent(itemId)}`, data);
154
- }
155
- async removeFromCart(itemId) {
156
- return this.request("DELETE", `/api/cart/${encodeURIComponent(itemId)}`);
157
- }
158
- async clearCart() {
159
- return this.request("DELETE", "/api/cart");
160
- }
161
- // --- Favorites ---
162
- async listFavorites(query) {
163
- const params = new URLSearchParams();
164
- if (query?.page) params.set("page", String(query.page));
165
- if (query?.limit) params.set("limit", String(query.limit));
166
- const qs = params.toString();
167
- return this.request("GET", `/api/favorites${qs ? `?${qs}` : ""}`);
168
- }
169
- async addFavorite(agentId) {
170
- return this.request("POST", `/api/favorites/${encodeURIComponent(agentId)}`);
171
- }
172
- async removeFavorite(agentId) {
173
- return this.request("DELETE", `/api/favorites/${encodeURIComponent(agentId)}`);
174
- }
175
- // --- Health ---
176
- async health() {
177
- return this.request("GET", "/api/health", void 0, false);
178
- }
179
- // --- Docs (MCP interface) ---
180
- async getDocsTree() {
181
- return this.request("GET", "/api/mcp/docs/tree", void 0, false);
182
- }
183
- async getDocByPath(path) {
184
- return this.request("GET", `/api/mcp/docs/by-path/${encodeURI(path)}`, void 0, false);
185
- }
186
- async searchDocs(query) {
187
- const params = new URLSearchParams({ q: query });
188
- return this.request("GET", `/api/mcp/docs/search?${params.toString()}`, void 0, false);
189
- }
190
- async getDoc(id) {
191
- return this.request("GET", `/api/mcp/docs/${encodeURIComponent(id)}`, void 0, false);
192
- }
193
- async createDoc(data) {
194
- return this.request("POST", "/api/mcp/docs", data);
195
- }
196
- async updateDoc(id, data) {
197
- return this.request("PATCH", `/api/mcp/docs/${encodeURIComponent(id)}`, data);
198
- }
199
- async deleteDoc(id) {
200
- return this.request("DELETE", `/api/mcp/docs/${encodeURIComponent(id)}`);
201
- }
202
- async publishDoc(id) {
203
- return this.request("POST", `/api/mcp/docs/${encodeURIComponent(id)}/publish`);
204
- }
205
- async unpublishDoc(id) {
206
- return this.request("POST", `/api/mcp/docs/${encodeURIComponent(id)}/unpublish`);
207
- }
208
- // --- Private ---
209
- async request(method, path, body, requireAuth = true) {
210
- const url = `${this.config.apiUrl}${path}`;
211
- const headers = {};
212
- if (body !== void 0) {
213
- headers["Content-Type"] = "application/json";
214
- }
215
- if (requireAuth) {
216
- if (this.agentTokenOverride) {
217
- headers["Authorization"] = `Bearer ${this.agentTokenOverride}`;
218
- } else if (this.config.token) {
219
- headers["Authorization"] = `Bearer ${this.config.token}`;
220
- } else if (this.config.apiKey) {
221
- headers["x-api-key"] = this.config.apiKey;
222
- } else {
223
- throw new Error("Not authenticated. Run `clawrent auth login` first.");
224
- }
225
- }
226
- const response = await fetch(url, {
227
- method,
228
- headers,
229
- body: body ? JSON.stringify(body) : void 0
230
- });
231
- if (!response.ok) {
232
- const errBody = await response.json().catch(() => ({ message: response.statusText }));
233
- throw new Error(`API error ${response.status}: ${errBody["message"] ?? JSON.stringify(errBody)}`);
234
- }
235
- return response.json();
236
- }
237
- };
238
-
239
- // src/config.ts
240
- import { readFileSync, writeFileSync, mkdirSync, unlinkSync, existsSync } from "fs";
241
- import { join } from "path";
242
- import { homedir } from "os";
243
- var DEFAULT_CONFIG = {
244
- apiUrl: "https://clawrent.cloud",
245
- wsUrl: "wss://clawrent.cloud"
246
- };
247
- function getConfigDir() {
248
- return join(homedir(), ".clawrent");
249
- }
250
- function getConfigFilePath() {
251
- return join(getConfigDir(), "config.json");
252
- }
253
- function getConfigPath() {
254
- return getConfigFilePath();
255
- }
256
- function loadConfig() {
257
- let fileConfig = {};
258
- const configPath = getConfigFilePath();
259
- if (existsSync(configPath)) {
260
- try {
261
- const raw = readFileSync(configPath, "utf-8");
262
- fileConfig = JSON.parse(raw);
263
- } catch {
264
- }
265
- }
266
- if (fileConfig.apiUrl?.includes("localhost") || fileConfig.wsUrl?.includes("localhost")) {
267
- delete fileConfig.apiUrl;
268
- delete fileConfig.wsUrl;
269
- try {
270
- const cleaned = { ...fileConfig };
271
- writeFileSync(configPath, JSON.stringify(cleaned, null, 2), "utf-8");
272
- } catch {
273
- }
274
- }
275
- const config = {
276
- ...DEFAULT_CONFIG,
277
- ...fileConfig
278
- };
279
- const envApiUrl = process.env["CLAWRENT_API_URL"];
280
- const envWsUrl = process.env["CLAWRENT_WS_URL"];
281
- const envToken = process.env["CLAWRENT_TOKEN"];
282
- const envApiKey = process.env["CLAWRENT_API_KEY"];
283
- const envUserId = process.env["CLAWRENT_USER_ID"];
284
- if (envApiUrl) config.apiUrl = envApiUrl;
285
- if (envWsUrl) config.wsUrl = envWsUrl;
286
- if (envToken) config.token = envToken;
287
- if (envApiKey) config.apiKey = envApiKey;
288
- if (envUserId) config.userId = envUserId;
289
- return config;
290
- }
291
- function saveConfig(partial) {
292
- const configDir = getConfigDir();
293
- if (!existsSync(configDir)) {
294
- mkdirSync(configDir, { recursive: true });
295
- }
296
- let existing = {};
297
- const configPath = getConfigFilePath();
298
- if (existsSync(configPath)) {
299
- try {
300
- existing = JSON.parse(readFileSync(configPath, "utf-8"));
301
- } catch {
302
- }
303
- }
304
- const merged = { ...existing, ...partial };
305
- writeFileSync(configPath, JSON.stringify(merged, null, 2), "utf-8");
306
- }
307
- function clearConfig() {
308
- const configPath = getConfigFilePath();
309
- if (existsSync(configPath)) {
310
- unlinkSync(configPath);
311
- }
312
- }
313
-
314
- // src/serve/session-manager.ts
315
- import { EventEmitter } from "events";
316
- import WebSocket from "ws";
317
- var SessionManager = class extends EventEmitter {
318
- sessions = /* @__PURE__ */ new Map();
319
- wsUrl;
320
- heartbeatInterval;
321
- maxReconnectDelay;
322
- agentId;
323
- constructor(wsUrl, heartbeatInterval = 25e3, maxReconnectDelay = 3e4) {
324
- super();
325
- this.wsUrl = wsUrl;
326
- this.heartbeatInterval = heartbeatInterval;
327
- this.maxReconnectDelay = maxReconnectDelay;
328
- }
329
- /** Connect to a session via WebSocket as provider */
330
- connect(sessionId, sessionToken) {
331
- if (this.sessions.has(sessionId)) {
332
- return;
333
- }
334
- const url = `${this.wsUrl}/ws/session?sessionId=${sessionId}&token=${sessionToken}&role=provider`;
335
- const ws = new WebSocket(url);
336
- const conn = {
337
- sessionId,
338
- sessionToken,
339
- ws,
340
- heartbeatTimer: null,
341
- reconnectAttempts: 0
342
- };
343
- this.sessions.set(sessionId, conn);
344
- ws.on("open", () => {
345
- conn.reconnectAttempts = 0;
346
- conn.heartbeatTimer = setInterval(() => {
347
- if (ws.readyState === WebSocket.OPEN) {
348
- ws.send(JSON.stringify({ type: "system.heartbeat", payload: {} }));
349
- }
350
- }, this.heartbeatInterval);
351
- this.emit("session:connected", sessionId);
352
- });
353
- ws.on("message", (raw) => {
354
- try {
355
- const message = JSON.parse(raw.toString());
356
- if (message["type"] === "system.heartbeat_ack") return;
357
- this.emit("session:message", sessionId, message);
358
- } catch {
359
- }
360
- });
361
- ws.on("close", (code, reason) => {
362
- this.clearHeartbeat(conn);
363
- if (code !== 1e3) {
364
- const delay = Math.min(
365
- 1e3 * Math.pow(2, conn.reconnectAttempts),
366
- this.maxReconnectDelay
367
- );
368
- conn.reconnectAttempts++;
369
- this.emit("session:reconnecting", sessionId, delay);
370
- setTimeout(() => {
371
- this.sessions.delete(sessionId);
372
- this.connect(sessionId, sessionToken);
373
- }, delay);
374
- } else {
375
- this.sessions.delete(sessionId);
376
- this.emit("session:disconnected", sessionId, reason.toString());
377
- }
378
- });
379
- ws.on("error", (err) => {
380
- this.emit("session:error", sessionId, err);
381
- });
382
- }
383
- /** Send a message to a specific session, auto-wrapping with protocol envelope */
384
- send(sessionId, message) {
385
- const conn = this.sessions.get(sessionId);
386
- if (!conn || conn.ws.readyState !== WebSocket.OPEN) {
387
- return false;
388
- }
389
- const envelope = {
390
- id: message["id"] ?? `msg_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`,
391
- sessionId: message["sessionId"] ?? sessionId,
392
- timestamp: message["timestamp"] ?? Date.now(),
393
- sender: message["sender"] ?? { role: "provider", agentId: this.agentId ?? "unknown" },
394
- type: message["type"] ?? "result.success",
395
- payload: message["payload"] ?? {}
396
- };
397
- conn.ws.send(JSON.stringify(envelope));
398
- return true;
399
- }
400
- /** Disconnect a specific session */
401
- disconnect(sessionId) {
402
- const conn = this.sessions.get(sessionId);
403
- if (!conn) return;
404
- this.clearHeartbeat(conn);
405
- if (conn.ws.readyState === WebSocket.OPEN || conn.ws.readyState === WebSocket.CONNECTING) {
406
- conn.ws.close(1e3, "Provider disconnecting");
407
- }
408
- this.sessions.delete(sessionId);
409
- }
410
- /** Disconnect all sessions */
411
- disconnectAll() {
412
- for (const sessionId of this.sessions.keys()) {
413
- this.disconnect(sessionId);
414
- }
415
- }
416
- /** Get active session count */
417
- get activeCount() {
418
- return this.sessions.size;
419
- }
420
- /** Check if a session is connected */
421
- isConnected(sessionId) {
422
- const conn = this.sessions.get(sessionId);
423
- return conn?.ws.readyState === WebSocket.OPEN;
424
- }
425
- clearHeartbeat(conn) {
426
- if (conn.heartbeatTimer) {
427
- clearInterval(conn.heartbeatTimer);
428
- conn.heartbeatTimer = null;
429
- }
430
- }
431
- };
1
+ // src/lib.ts
2
+ import {
3
+ ApiClient,
4
+ SessionManager,
5
+ loadConfig,
6
+ saveConfig,
7
+ clearConfig,
8
+ getConfigPath
9
+ } from "@clawrent/provider";
432
10
  export {
433
11
  ApiClient,
434
12
  SessionManager,