@firela/billclaw-openclaw 0.1.3

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 fire-la
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,275 @@
1
+ # @firela/billclaw-openclaw
2
+
3
+ OpenClaw plugin adapter for BillClaw financial data import.
4
+
5
+ ## Overview
6
+
7
+ This package provides an OpenClaw plugin that integrates BillClaw's financial data capabilities with the OpenClaw AI framework. It exposes:
8
+
9
+ - **Agent Tools**: Plaid sync, Gmail fetch, bill parsing, conversational interface
10
+ - **CLI Commands**: `bills setup`, `bills sync`, `bills status`, `bills config`
11
+ - **OAuth Providers**: Plaid Link and Gmail OAuth flows
12
+ - **Background Services**: Sync service and webhook handler
13
+
14
+ ## Installation
15
+
16
+ ### As OpenClaw Extension
17
+
18
+ ```bash
19
+ cd ~/.openclaw/extensions
20
+ npm install @firela/billclaw-openclaw
21
+ ```
22
+
23
+ ### Manual Registration
24
+
25
+ Add to your OpenClaw configuration:
26
+
27
+ ```json
28
+ {
29
+ "extensions": ["@firela/billclaw-openclaw"]
30
+ }
31
+ ```
32
+
33
+ ## Quick Start
34
+
35
+ ### Using Agent Tools
36
+
37
+ ```typescript
38
+ // In an OpenClaw agent context
39
+ const result = await agent.useTool("plaid_sync", {
40
+ accountId: "plaid-123"
41
+ });
42
+ // Returns: { success: true, transactionsAdded: 42, ... }
43
+ ```
44
+
45
+ ### Using CLI Commands
46
+
47
+ ```bash
48
+ # In OpenClaw CLI
49
+ openclaw bills setup
50
+ openclaw bills sync
51
+ openclaw bills status
52
+ openclaw bills config storage.path
53
+ ```
54
+
55
+ ### OAuth Integration
56
+
57
+ ```typescript
58
+ // In OpenClaw OAuth flow
59
+ const oauth = await openclaw.getOAuthProvider("plaid");
60
+ const { url, token } = await oauth.handler(context);
61
+ ```
62
+
63
+ ## Available Tools
64
+
65
+ ### plaid_sync
66
+
67
+ Sync transactions from Plaid-connected bank accounts.
68
+
69
+ ```typescript
70
+ await agent.useTool("plaid_sync", {
71
+ accountId: "plaid-123" // Optional - syncs all if omitted
72
+ });
73
+ ```
74
+
75
+ **Response:**
76
+ ```json
77
+ {
78
+ "success": true,
79
+ "accountsSynced": 1,
80
+ "transactionsAdded": 42,
81
+ "transactionsUpdated": 5
82
+ }
83
+ ```
84
+
85
+ ### gmail_fetch_bills
86
+
87
+ Fetch and parse bills from Gmail.
88
+
89
+ ```typescript
90
+ await agent.useTool("gmail_fetch_bills", {
91
+ accountId: "gmail-123",
92
+ days: 30 // Optional - default 30
93
+ });
94
+ ```
95
+
96
+ **Response:**
97
+ ```json
98
+ {
99
+ "success": true,
100
+ "accountsProcessed": 1,
101
+ "emailsProcessed": 150,
102
+ "billsExtracted": 12,
103
+ "transactionsAdded": 12
104
+ }
105
+ ```
106
+
107
+ ### bill_parse
108
+
109
+ Parse bill data from various formats.
110
+
111
+ ```typescript
112
+ await agent.useTool("bill_parse", {
113
+ source: "email",
114
+ data: "raw email content"
115
+ });
116
+ ```
117
+
118
+ ### conversational_sync
119
+
120
+ Sync with natural language support.
121
+
122
+ ```typescript
123
+ await agent.useTool("conversational_sync", {
124
+ prompt: "Sync my accounts"
125
+ });
126
+ ```
127
+
128
+ ### conversational_status
129
+
130
+ Show account status with natural language.
131
+
132
+ ```typescript
133
+ await agent.useTool("conversational_status", {});
134
+ ```
135
+
136
+ ### conversational_help
137
+
138
+ Get help with BillClaw commands.
139
+
140
+ ```typescript
141
+ await agent.useTool("conversational_help", {
142
+ topic: "sync"
143
+ });
144
+ ```
145
+
146
+ ## CLI Commands
147
+
148
+ ### bills setup
149
+
150
+ Interactive setup wizard for connecting accounts.
151
+
152
+ ```bash
153
+ openclaw bills setup
154
+ ```
155
+
156
+ ### bills sync
157
+
158
+ Manually trigger transaction sync.
159
+
160
+ ```bash
161
+ # Sync all accounts
162
+ openclaw bills sync
163
+
164
+ # Sync specific account
165
+ openclaw bills sync plaid-123
166
+ ```
167
+
168
+ ### bills status
169
+
170
+ Show connection status and recent sync results.
171
+
172
+ ```bash
173
+ openclaw bills status
174
+ ```
175
+
176
+ ### bills config
177
+
178
+ Manage plugin configuration.
179
+
180
+ ```bash
181
+ # View all config
182
+ openclaw bills config
183
+
184
+ # View specific key
185
+ openclaw bills config storage.path
186
+
187
+ # Set value
188
+ openclaw bills config storage.format json
189
+ ```
190
+
191
+ ## OAuth Providers
192
+
193
+ ### Plaid
194
+
195
+ ```typescript
196
+ const oauth = await openclaw.getOAuthProvider("plaid");
197
+ const { url } = await oauth.handler(context);
198
+ // Redirect user to Plaid Link
199
+ ```
200
+
201
+ ### Gmail
202
+
203
+ ```typescript
204
+ const oauth = await openclaw.getOAuthProvider("gmail");
205
+ const { url } = await oauth.handler(context);
206
+ // Redirect user to Google OAuth
207
+ ```
208
+
209
+ ## Background Services
210
+
211
+ ### billclaw-sync
212
+
213
+ Automatic sync service that runs on configured intervals.
214
+
215
+ ### billclaw-webhook
216
+
217
+ HTTP webhook handler for real-time transaction updates from Plaid.
218
+
219
+ ## Configuration
220
+
221
+ Plugin configuration is managed through OpenClaw's plugin config system:
222
+
223
+ ```json
224
+ {
225
+ "accounts": [],
226
+ "storage": {
227
+ "path": "~/.openclaw/billclaw",
228
+ "format": "json"
229
+ },
230
+ "sync": {
231
+ "defaultFrequency": "daily",
232
+ "maxRetries": 3
233
+ }
234
+ }
235
+ ```
236
+
237
+ ## Architecture
238
+
239
+ ```
240
+ ┌─────────────────────────────────────────┐
241
+ │ OpenClaw Framework │
242
+ ├─────────────────────────────────────────┤
243
+ │ BillClaw Plugin │
244
+ │ ├── Agent Tools (6) │
245
+ │ ├── CLI Commands (4) │
246
+ │ ├── OAuth Providers (2) │
247
+ │ └── Background Services (2) │
248
+ ├─────────────────────────────────────────┤
249
+ │ @firela/billclaw-core │
250
+ │ (Framework-agnostic core logic) │
251
+ └─────────────────────────────────────────┘
252
+ ```
253
+
254
+ ## Development
255
+
256
+ ```bash
257
+ # Build
258
+ pnpm build
259
+
260
+ # Watch mode
261
+ pnpm dev
262
+
263
+ # Test
264
+ pnpm test
265
+ ```
266
+
267
+ ## License
268
+
269
+ MIT
270
+
271
+ ## See Also
272
+
273
+ - [@firela/billclaw-core](https://github.com/fire-la/billclaw/tree/main/packages/core)
274
+ - [@firela/billclaw-cli](https://github.com/fire-la/billclaw/tree/main/packages/cli)
275
+ - [OpenClaw Documentation](https://openclaw.dev)
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAGrC,OAAO,EACL,aAAa,EACb,cAAc,EACd,aAAa,EACb,sBAAsB,EACtB,wBAAwB,EACxB,sBAAsB,GACvB,MAAM,kBAAkB,CAAA"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/oauth/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plaid.d.ts","sourceRoot":"","sources":["../../src/oauth/plaid.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAA;AAwFpE;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,iBAAiB,EACtB,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC;IACT,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB,CAAC,CA2BD"}
@@ -0,0 +1,108 @@
1
+ /**
2
+ * Plaid OAuth handler - implements Plaid Link flow
3
+ *
4
+ * This module handles the Plaid Link OAuth flow for connecting bank accounts.
5
+ * It supports two modes:
6
+ * 1. Link token creation (for initializing Plaid Link frontend)
7
+ * 2. Public token exchange (for completing the connection)
8
+ */
9
+ import { createPlaidClient } from "@firela/billclaw-core";
10
+ /**
11
+ * Get Plaid configuration from OpenClaw config
12
+ *
13
+ * Checks both pluginConfig and environment variables for credentials.
14
+ */
15
+ function getPlaidConfig(api) {
16
+ const pluginConfig = api.pluginConfig;
17
+ const plaidConfig = pluginConfig?.plaid || {};
18
+ const clientId = plaidConfig.clientId || process.env.PLAID_CLIENT_ID;
19
+ const secret = plaidConfig.secret || process.env.PLAID_SECRET;
20
+ const environment = plaidConfig.environment || "sandbox";
21
+ if (!clientId || !secret) {
22
+ throw new Error("Plaid credentials not configured. Set PLAID_CLIENT_ID and PLAID_SECRET environment variables, or configure them in billclaw settings.");
23
+ }
24
+ return {
25
+ clientId,
26
+ secret,
27
+ environment: environment,
28
+ };
29
+ }
30
+ /**
31
+ * Create Plaid Link token for initializing Link frontend
32
+ */
33
+ async function createLinkToken(api, accountId) {
34
+ const plaidConfig = getPlaidConfig(api);
35
+ const plaidClient = createPlaidClient(plaidConfig);
36
+ const request = {
37
+ user: {
38
+ client_user_id: accountId || `user_${Date.now()}`,
39
+ },
40
+ client_name: "BillClaw",
41
+ products: ["transactions"],
42
+ country_codes: ["US"],
43
+ language: "en",
44
+ };
45
+ const axiosResponse = await plaidClient.linkTokenCreate(request);
46
+ const response = axiosResponse.data;
47
+ api.logger.info?.("Plaid Link token created successfully");
48
+ return { linkToken: response.link_token };
49
+ }
50
+ /**
51
+ * Exchange Plaid public token for access token
52
+ */
53
+ async function exchangePublicToken(api, publicToken) {
54
+ const plaidConfig = getPlaidConfig(api);
55
+ const plaidClient = createPlaidClient(plaidConfig);
56
+ const request = {
57
+ public_token: publicToken,
58
+ };
59
+ const axiosResponse = await plaidClient.itemPublicTokenExchange(request);
60
+ const response = axiosResponse.data;
61
+ api.logger.info?.("Plaid public token exchanged successfully");
62
+ return {
63
+ accessToken: response.access_token,
64
+ itemId: response.item_id,
65
+ };
66
+ }
67
+ /**
68
+ * Handle Plaid Link OAuth flow
69
+ *
70
+ * This integrates Plaid Link (https://plaid.com/docs/link/)
71
+ * for secure bank account connection.
72
+ *
73
+ * Flow:
74
+ * 1. Create Link token (no params) - Returns { url, token: linkToken }
75
+ * 2. Handle Link success callback - Receives publicToken
76
+ * 3. Exchange public_token for access_token - Returns { url: "", token: accessToken, itemId }
77
+ *
78
+ * @param api - OpenClaw plugin API
79
+ * @param publicToken - Optional public token from Plaid Link callback
80
+ * @returns OAuthResult with URL and token
81
+ */
82
+ export async function plaidOAuthHandler(api, publicToken) {
83
+ try {
84
+ if (!publicToken) {
85
+ // No public token provided - create Link token for initializing Link
86
+ const { linkToken } = await createLinkToken(api);
87
+ // Return Plaid Link URL and the link token
88
+ return {
89
+ url: "https://cdn.plaid.com/link/v2/stable/link.html",
90
+ token: linkToken,
91
+ };
92
+ }
93
+ // Public token provided - exchange for access token
94
+ const { accessToken, itemId } = await exchangePublicToken(api, publicToken);
95
+ // Return the access token and item ID for storage
96
+ return {
97
+ url: "",
98
+ token: accessToken,
99
+ itemId,
100
+ accessToken,
101
+ };
102
+ }
103
+ catch (error) {
104
+ api.logger.error?.("Plaid OAuth error:", error);
105
+ throw error;
106
+ }
107
+ }
108
+ //# sourceMappingURL=plaid.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plaid.js","sourceRoot":"","sources":["../../src/oauth/plaid.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAA;AAYnE;;GAEG;;;;;;kBAQa,iBAAiB;;AAPjC,wBA0NC"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * OpenClaw runtime context adapter
3
+ *
4
+ * Adapts OpenClaw's plugin API to BillClaw's runtime abstractions.
5
+ */
6
+ import type { OpenClawPluginApi } from "../types/openclaw-plugin.js";
7
+ import type { RuntimeContext, ConfigProvider, Logger, EventEmitter } from "@firela/billclaw-core";
8
+ import type { BillclawConfig } from "@firela/billclaw-core";
9
+ /**
10
+ * OpenClaw logger adapter
11
+ */
12
+ export declare class OpenClawLogger implements Logger {
13
+ private api;
14
+ constructor(api: OpenClawPluginApi);
15
+ info(...args: unknown[]): void;
16
+ error(...args: unknown[]): void;
17
+ warn(...args: unknown[]): void;
18
+ debug(...args: unknown[]): void;
19
+ }
20
+ /**
21
+ * OpenClaw config provider
22
+ */
23
+ export declare class OpenClawConfigProvider implements ConfigProvider {
24
+ private api;
25
+ private cachedConfig?;
26
+ constructor(api: OpenClawPluginApi);
27
+ getConfig(): Promise<BillclawConfig>;
28
+ getStorageConfig(): Promise<any>;
29
+ updateAccount(accountId: string, updates: Partial<any>): Promise<void>;
30
+ getAccount(accountId: string): Promise<any | null>;
31
+ }
32
+ /**
33
+ * OpenClaw event emitter adapter
34
+ */
35
+ export declare class OpenClawEventEmitter implements EventEmitter {
36
+ private listeners;
37
+ emit(event: string, data?: unknown): void;
38
+ on(event: string, handler: (...args: any[]) => void): void;
39
+ off(event: string, handler: (...args: any[]) => void): void;
40
+ }
41
+ /**
42
+ * OpenClaw runtime context
43
+ */
44
+ export declare class OpenClawRuntimeContext implements RuntimeContext {
45
+ private _logger;
46
+ private _config;
47
+ private _events;
48
+ constructor(api: OpenClawPluginApi);
49
+ get logger(): Logger;
50
+ get config(): ConfigProvider;
51
+ get events(): EventEmitter;
52
+ }
53
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/runtime/context.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAA;AACpE,OAAO,KAAK,EACV,cAAc,EACd,cAAc,EACd,MAAM,EACN,YAAY,EACb,MAAM,uBAAuB,CAAA;AAC9B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAE3D;;GAEG;AACH,qBAAa,cAAe,YAAW,MAAM;IAC/B,OAAO,CAAC,GAAG;gBAAH,GAAG,EAAE,iBAAiB;IAE1C,IAAI,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI;IAI9B,KAAK,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI;IAI/B,IAAI,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI;IAI9B,KAAK,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI;CAKhC;AAED;;GAEG;AACH,qBAAa,sBAAuB,YAAW,cAAc;IAG/C,OAAO,CAAC,GAAG;IAFvB,OAAO,CAAC,YAAY,CAAC,CAAgB;gBAEjB,GAAG,EAAE,iBAAiB;IAEpC,SAAS,IAAI,OAAO,CAAC,cAAc,CAAC;IAUpC,gBAAgB,IAAI,OAAO,CAAC,GAAG,CAAC;IAWhC,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAMtE,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC;CAIzD;AAED;;GAEG;AACH,qBAAa,oBAAqB,YAAW,YAAY;IACvD,OAAO,CAAC,SAAS,CAAmD;IAEpE,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI;IAazC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,GAAG,IAAI;IAO1D,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,GAAG,IAAI;CAM5D;AAED;;GAEG;AACH,qBAAa,sBAAuB,YAAW,cAAc;IAC3D,OAAO,CAAC,OAAO,CAAQ;IACvB,OAAO,CAAC,OAAO,CAAgB;IAC/B,OAAO,CAAC,OAAO,CAAc;gBAEjB,GAAG,EAAE,iBAAiB;IA4BlC,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED,IAAI,MAAM,IAAI,cAAc,CAE3B;IAED,IAAI,MAAM,IAAI,YAAY,CAEzB;CACF"}
@@ -0,0 +1,136 @@
1
+ /**
2
+ * OpenClaw runtime context adapter
3
+ *
4
+ * Adapts OpenClaw's plugin API to BillClaw's runtime abstractions.
5
+ */
6
+ /**
7
+ * OpenClaw logger adapter
8
+ */
9
+ export class OpenClawLogger {
10
+ api;
11
+ constructor(api) {
12
+ this.api = api;
13
+ }
14
+ info(...args) {
15
+ this.api.logger.info?.(...args);
16
+ }
17
+ error(...args) {
18
+ this.api.logger.error?.(...args);
19
+ }
20
+ warn(...args) {
21
+ this.api.logger.warn?.(...args);
22
+ }
23
+ debug(...args) {
24
+ if (process.env.DEBUG) {
25
+ this.api.logger.debug?.(...args);
26
+ }
27
+ }
28
+ }
29
+ /**
30
+ * OpenClaw config provider
31
+ */
32
+ export class OpenClawConfigProvider {
33
+ api;
34
+ cachedConfig;
35
+ constructor(api) {
36
+ this.api = api;
37
+ }
38
+ async getConfig() {
39
+ if (!this.cachedConfig) {
40
+ // Get config from OpenClaw's plugin config
41
+ const config = this.api.pluginConfig;
42
+ this.cachedConfig = config;
43
+ }
44
+ return this.cachedConfig;
45
+ }
46
+ async getStorageConfig() {
47
+ const config = await this.getConfig();
48
+ return (config.storage || {
49
+ path: "~/.openclaw/billclaw",
50
+ format: "json",
51
+ encryption: { enabled: false },
52
+ });
53
+ }
54
+ async updateAccount(accountId, updates) {
55
+ // This would need to update OpenClaw's config
56
+ // For now, just log the update
57
+ this.api.logger.info?.(`Account ${accountId} updated:`, updates);
58
+ }
59
+ async getAccount(accountId) {
60
+ const config = await this.getConfig();
61
+ return config.accounts.find((a) => a.id === accountId) || null;
62
+ }
63
+ }
64
+ /**
65
+ * OpenClaw event emitter adapter
66
+ */
67
+ export class OpenClawEventEmitter {
68
+ listeners = new Map();
69
+ emit(event, data) {
70
+ const handlers = this.listeners.get(event);
71
+ if (handlers) {
72
+ for (const handler of handlers) {
73
+ try {
74
+ handler(data);
75
+ }
76
+ catch (error) {
77
+ console.error(`Error in event handler for ${event}:`, error);
78
+ }
79
+ }
80
+ }
81
+ }
82
+ on(event, handler) {
83
+ if (!this.listeners.has(event)) {
84
+ this.listeners.set(event, new Set());
85
+ }
86
+ this.listeners.get(event).add(handler);
87
+ }
88
+ off(event, handler) {
89
+ const handlers = this.listeners.get(event);
90
+ if (handlers) {
91
+ handlers.delete(handler);
92
+ }
93
+ }
94
+ }
95
+ /**
96
+ * OpenClaw runtime context
97
+ */
98
+ export class OpenClawRuntimeContext {
99
+ _logger;
100
+ _config;
101
+ _events;
102
+ constructor(api) {
103
+ this._logger = new OpenClawLogger(api);
104
+ this._config = new OpenClawConfigProvider(api);
105
+ this._events = new OpenClawEventEmitter();
106
+ // Define readonly properties at runtime
107
+ Object.defineProperty(this, "logger", {
108
+ value: this._logger,
109
+ writable: false,
110
+ enumerable: true,
111
+ configurable: false,
112
+ });
113
+ Object.defineProperty(this, "config", {
114
+ value: this._config,
115
+ writable: false,
116
+ enumerable: true,
117
+ configurable: false,
118
+ });
119
+ Object.defineProperty(this, "events", {
120
+ value: this._events,
121
+ writable: false,
122
+ enumerable: true,
123
+ configurable: false,
124
+ });
125
+ }
126
+ get logger() {
127
+ return this._logger;
128
+ }
129
+ get config() {
130
+ return this._config;
131
+ }
132
+ get events() {
133
+ return this._events;
134
+ }
135
+ }
136
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/runtime/context.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/services/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAA"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webhook-handler.d.ts","sourceRoot":"","sources":["../../src/services/webhook-handler.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAA;AAIpE;;GAEG;AACH,UAAU,0BAA0B;IAClC,GAAG,EAAE,iBAAiB,CAAA;IACtB,kBAAkB,CAAC,EAAE,MAAM,CAAA;CAC5B;AAgCD;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CACrC,YAAY,EAAE,0BAA0B,GACvC,IAAI,CA+BN"}
@@ -0,0 +1,176 @@
1
+ /**
2
+ * Webhook handlers for BillClaw OpenClaw plugin
3
+ *
4
+ * This module provides HTTP route handlers for receiving webhooks from
5
+ * external services (Plaid, GoCardless, etc.) and forwarding them to
6
+ * configured external webhook endpoints.
7
+ */
8
+ import { emitEvent, verifySignature } from "@firela/billclaw-core";
9
+ // Global API reference for webhook handlers
10
+ let api = null;
11
+ let configWebhooks = [];
12
+ let plaidWebhookSecret;
13
+ /**
14
+ * Convert OpenClaw logger to BillClaw Logger interface
15
+ */
16
+ function toLogger(logger) {
17
+ // Ensure all methods are defined and callable
18
+ const log = logger?.info || (() => { });
19
+ const logError = logger?.error || (() => { });
20
+ const logWarn = logger?.warn || (() => console.warn);
21
+ const logDebug = logger?.debug || (() => { });
22
+ return {
23
+ info: log,
24
+ error: logError,
25
+ warn: logWarn,
26
+ debug: logDebug,
27
+ };
28
+ }
29
+ /**
30
+ * Register webhook handlers with OpenClaw HTTP routes
31
+ *
32
+ * This function registers HTTP routes for:
33
+ * - /webhook/plaid - Plaid webhook handler
34
+ * - /webhook/gocardless - GoCardless webhook handler
35
+ * - /webhook/test - Test webhook endpoint
36
+ */
37
+ export function registerWebhookHandlers(dependencies) {
38
+ api = dependencies.api;
39
+ plaidWebhookSecret = dependencies.plaidWebhookSecret;
40
+ // Get webhooks from config
41
+ const pluginConfig = api.pluginConfig;
42
+ configWebhooks = pluginConfig?.webhooks || [];
43
+ api.logger.info?.("billclaw webhook handler registered");
44
+ // Register HTTP routes
45
+ api.http?.register({
46
+ path: "/webhook/plaid",
47
+ method: "POST",
48
+ description: "Plaid webhook handler",
49
+ handler: handlePlaidWebhook,
50
+ });
51
+ api.http?.register({
52
+ path: "/webhook/gocardless",
53
+ method: "POST",
54
+ description: "GoCardless webhook handler",
55
+ handler: handleGoCardlessWebhook,
56
+ });
57
+ api.http?.register({
58
+ path: "/webhook/test",
59
+ method: "POST",
60
+ description: "Test webhook endpoint",
61
+ handler: handleTestWebhook,
62
+ });
63
+ }
64
+ /**
65
+ * Handle Plaid webhook
66
+ *
67
+ * Processes webhooks from Plaid:
68
+ * - TRANSACTIONS/SYNC_UPDATES_AVAILABLE: Trigger sync for the item
69
+ * - ITEM/ERROR: Emit account.error event
70
+ * - ITEM/LOGIN_REQUIRED: Notify user to re-authenticate
71
+ */
72
+ async function handlePlaidWebhook(request) {
73
+ try {
74
+ const body = request.body;
75
+ const webhookType = body.webhook_type;
76
+ const webhookCode = body.webhook_code;
77
+ const itemId = body.item_id;
78
+ api?.logger.info?.(`Received Plaid webhook: ${webhookType}.${webhookCode} for item ${itemId}`);
79
+ // Verify signature if configured
80
+ const signature = request.headers["plaid-verification"];
81
+ const timestamp = request.headers["plaid-timestamp"];
82
+ if (plaidWebhookSecret && signature && timestamp) {
83
+ const payload = JSON.stringify(body);
84
+ if (!verifySignature(payload, signature, plaidWebhookSecret)) {
85
+ return {
86
+ status: 401,
87
+ body: { received: false, error: "Invalid signature" },
88
+ };
89
+ }
90
+ }
91
+ // Handle webhook events
92
+ switch (webhookType) {
93
+ case "TRANSACTIONS":
94
+ if (webhookCode === "SYNC_UPDATES_AVAILABLE") {
95
+ // Find the account associated with this item
96
+ const pluginConfig = api?.pluginConfig;
97
+ const account = pluginConfig?.accounts?.find((acc) => acc.type === "plaid" && acc.plaidItemId === itemId && acc.enabled);
98
+ if (account && api) {
99
+ // Trigger async sync (don't wait for completion)
100
+ const { plaidSyncTool } = await import("../tools/index.js");
101
+ plaidSyncTool
102
+ .execute(api, { accountId: account.id })
103
+ .catch((error) => {
104
+ api?.logger.error?.(`Webhook-triggered sync failed:`, error);
105
+ });
106
+ }
107
+ }
108
+ break;
109
+ case "ITEM":
110
+ if (webhookCode === "ERROR" || webhookCode === "LOGIN_REQUIRED") {
111
+ const error = body.error ?? {
112
+ error_code: webhookCode,
113
+ error_message: "Item login required",
114
+ };
115
+ // Emit account error event
116
+ await emitEvent(toLogger(api.logger), configWebhooks, "account.error", {
117
+ accountId: itemId,
118
+ accountType: "plaid",
119
+ error: JSON.stringify(error),
120
+ }).catch((err) => api?.logger.debug?.(`Event emission failed:`, err));
121
+ }
122
+ break;
123
+ }
124
+ return { status: 200, body: { received: true } };
125
+ }
126
+ catch (error) {
127
+ api?.logger.error?.(`Error handling Plaid webhook:`, error);
128
+ return {
129
+ status: 500,
130
+ body: { received: false, error: "Internal server error" },
131
+ };
132
+ }
133
+ }
134
+ /**
135
+ * Handle GoCardless webhook
136
+ *
137
+ * Processes webhooks from GoCardless (placeholder implementation)
138
+ */
139
+ async function handleGoCardlessWebhook(_request) {
140
+ try {
141
+ api?.logger.info?.("Received GoCardless webhook");
142
+ // TODO: Implement GoCardless webhook handling
143
+ // - Verify signature
144
+ // - Process mandate events
145
+ // - Trigger sync if needed
146
+ return { status: 200, body: { received: true } };
147
+ }
148
+ catch (error) {
149
+ api?.logger.error?.(`Error handling GoCardless webhook:`, error);
150
+ return { status: 500, body: { received: false } };
151
+ }
152
+ }
153
+ /**
154
+ * Handle test webhook
155
+ *
156
+ * Sends a test event to all configured webhooks to verify connectivity
157
+ */
158
+ async function handleTestWebhook(_request) {
159
+ try {
160
+ api?.logger.info?.("Received test webhook request");
161
+ // Emit test event to all configured webhooks
162
+ await emitEvent(toLogger(api.logger), configWebhooks, "webhook.test", {
163
+ message: "Test webhook from BillClaw",
164
+ triggeredBy: "user",
165
+ });
166
+ return { status: 200, body: { sent: true } };
167
+ }
168
+ catch (error) {
169
+ api?.logger.error?.(`Error handling test webhook:`, error);
170
+ return {
171
+ status: 500,
172
+ body: { sent: false, error: "Internal server error" },
173
+ };
174
+ }
175
+ }
176
+ //# sourceMappingURL=webhook-handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webhook-handler.js","sourceRoot":"","sources":["../../src/services/webhook-handler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAA;AAYpE;;GAEG;AACH,eAAO,MAAM,aAAa;;;;;;;;;;;iBAYL,iBAAiB,UAAU;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE;;;;;;CAgCrE,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;iBAkBlB,iBAAiB,UACd;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE;;;;;;CAiChD,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,aAAa;;;;;;;;;;;;;;kBAgBhB,iBAAiB,UACf;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE;;;;;;CAqB3C,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;iBAkB1B,iBAAiB,UACd;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE;;;;;;CAsClD,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,wBAAwB;;;;;;;;;;;iBAYhB,iBAAiB,WAAW;QAAE,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE;;;;;;CAoBnE,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,sBAAsB;;;;;;;;;;;kBAYb,iBAAiB,UAAU;QAAE,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE;;;;;;CAmBlE,CAAA"}
@@ -0,0 +1,253 @@
1
+ /**
2
+ * OpenClaw tool adapters for BillClaw
3
+ *
4
+ * These adapters wrap the core BillClaw functionality to work with
5
+ * OpenClaw's tool API.
6
+ */
7
+ import { Billclaw } from "@firela/billclaw-core";
8
+ import { OpenClawRuntimeContext } from "../runtime/context.js";
9
+ /**
10
+ * Create a BillClaw instance from OpenClaw API
11
+ */
12
+ function createBillclaw(api) {
13
+ const runtime = new OpenClawRuntimeContext(api);
14
+ return new Billclaw(runtime);
15
+ }
16
+ /**
17
+ * Plaid sync tool
18
+ */
19
+ export const plaidSyncTool = {
20
+ name: "plaid_sync",
21
+ label: "Plaid Sync",
22
+ description: "Sync transactions from Plaid-connected bank accounts",
23
+ parameters: {
24
+ accountId: {
25
+ type: "string",
26
+ optional: true,
27
+ description: "Specific account ID to sync (omits to sync all)",
28
+ },
29
+ },
30
+ async execute(api, params) {
31
+ const billclaw = createBillclaw(api);
32
+ const results = await billclaw.syncPlaid(params.accountId ? [params.accountId] : undefined);
33
+ const totalAdded = results.reduce((sum, r) => sum + r.transactionsAdded, 0);
34
+ const totalUpdated = results.reduce((sum, r) => sum + r.transactionsUpdated, 0);
35
+ const errors = results.flatMap((r) => r.errors || []);
36
+ return {
37
+ content: [
38
+ {
39
+ type: "text",
40
+ text: JSON.stringify({
41
+ success: errors.length === 0,
42
+ accountsSynced: results.length,
43
+ transactionsAdded: totalAdded,
44
+ transactionsUpdated: totalUpdated,
45
+ errors: errors.length > 0 ? errors : undefined,
46
+ }, null, 2),
47
+ },
48
+ ],
49
+ };
50
+ },
51
+ };
52
+ /**
53
+ * Gmail fetch bills tool
54
+ */
55
+ export const gmailFetchTool = {
56
+ name: "gmail_fetch_bills",
57
+ label: "Gmail Fetch Bills",
58
+ description: "Fetch and parse bills from Gmail",
59
+ parameters: {
60
+ accountId: {
61
+ type: "string",
62
+ optional: true,
63
+ description: "Specific Gmail account ID to sync (omit for all)",
64
+ },
65
+ days: {
66
+ type: "number",
67
+ optional: true,
68
+ description: "Number of days to look back (default: 30)",
69
+ },
70
+ },
71
+ async execute(api, params) {
72
+ const billclaw = createBillclaw(api);
73
+ const results = await billclaw.syncGmail(params.accountId ? [params.accountId] : undefined, params.days ?? 30);
74
+ const totalEmails = results.reduce((sum, r) => sum + r.emailsProcessed, 0);
75
+ const totalBills = results.reduce((sum, r) => sum + r.billsExtracted, 0);
76
+ const totalAdded = results.reduce((sum, r) => sum + r.transactionsAdded, 0);
77
+ const errors = results.flatMap((r) => r.errors || []);
78
+ return {
79
+ content: [
80
+ {
81
+ type: "text",
82
+ text: JSON.stringify({
83
+ success: errors.length === 0,
84
+ accountsProcessed: results.length,
85
+ emailsProcessed: totalEmails,
86
+ billsExtracted: totalBills,
87
+ transactionsAdded: totalAdded,
88
+ errors: errors.length > 0 ? errors : undefined,
89
+ }, null, 2),
90
+ },
91
+ ],
92
+ };
93
+ },
94
+ };
95
+ /**
96
+ * Bill parse tool
97
+ */
98
+ export const billParseTool = {
99
+ name: "bill_parse",
100
+ label: "Bill Parse",
101
+ description: "Parse bill data from various formats (PDF, CSV, email)",
102
+ parameters: {
103
+ source: {
104
+ type: "string",
105
+ description: "Source type: plaid, gmail, file, or email",
106
+ },
107
+ data: {
108
+ type: "string",
109
+ description: "Raw data or file path to parse",
110
+ },
111
+ },
112
+ async execute(_api, params) {
113
+ // This is a stub - the actual implementation would depend on the source type
114
+ return {
115
+ content: [
116
+ {
117
+ type: "text",
118
+ text: JSON.stringify({
119
+ success: false,
120
+ source: params.source,
121
+ transactions: [],
122
+ errors: ["Bill parsing not yet implemented"],
123
+ }, null, 2),
124
+ },
125
+ ],
126
+ };
127
+ },
128
+ };
129
+ /**
130
+ * Conversational sync tool
131
+ */
132
+ export const conversationalSyncTool = {
133
+ name: "conversational_sync",
134
+ label: "Conversational Sync",
135
+ description: "Sync transactions with natural language support",
136
+ parameters: {
137
+ prompt: {
138
+ type: "string",
139
+ optional: true,
140
+ description: "Natural language prompt (e.g., 'Sync my accounts')",
141
+ },
142
+ accountId: {
143
+ type: "string",
144
+ optional: true,
145
+ description: "Explicit account ID to sync",
146
+ },
147
+ },
148
+ async execute(api, params) {
149
+ const billclaw = createBillclaw(api);
150
+ // If accountId is specified, sync that account
151
+ if (params.accountId) {
152
+ return plaidSyncTool.execute(api, { accountId: params.accountId });
153
+ }
154
+ // Otherwise, sync all due accounts
155
+ const results = await billclaw.syncDueAccounts();
156
+ const totalAdded = results.reduce((sum, r) => sum + r.transactionsAdded, 0);
157
+ const totalUpdated = results.reduce((sum, r) => sum + r.transactionsUpdated, 0);
158
+ const errors = results.flatMap((r) => r.errors || []);
159
+ return {
160
+ content: [
161
+ {
162
+ type: "text",
163
+ text: JSON.stringify({
164
+ success: errors.length === 0,
165
+ accountsSynced: results.length,
166
+ transactionsAdded: totalAdded,
167
+ transactionsUpdated: totalUpdated,
168
+ errors: errors.length > 0 ? errors : undefined,
169
+ }, null, 2),
170
+ },
171
+ ],
172
+ };
173
+ },
174
+ };
175
+ /**
176
+ * Conversational status tool
177
+ */
178
+ export const conversationalStatusTool = {
179
+ name: "conversational_status",
180
+ label: "Conversational Status",
181
+ description: "Show account status with natural language",
182
+ parameters: {
183
+ prompt: {
184
+ type: "string",
185
+ optional: true,
186
+ description: "Natural language prompt",
187
+ },
188
+ },
189
+ async execute(api, _params) {
190
+ const billclaw = createBillclaw(api);
191
+ const accounts = await billclaw.getAccounts();
192
+ return {
193
+ content: [
194
+ {
195
+ type: "text",
196
+ text: JSON.stringify({
197
+ accounts,
198
+ message: `Found ${accounts.length} configured accounts`,
199
+ }, null, 2),
200
+ },
201
+ ],
202
+ };
203
+ },
204
+ };
205
+ /**
206
+ * Conversational help tool
207
+ */
208
+ export const conversationalHelpTool = {
209
+ name: "conversational_help",
210
+ label: "Conversational Help",
211
+ description: "Get help with billclaw commands and features",
212
+ parameters: {
213
+ topic: {
214
+ type: "string",
215
+ optional: true,
216
+ description: "Specific help topic (sync, export, webhook, etc.)",
217
+ },
218
+ },
219
+ async execute(_api, params) {
220
+ const helpText = getHelpText(params.topic);
221
+ return {
222
+ content: [
223
+ {
224
+ type: "text",
225
+ text: JSON.stringify({
226
+ topic: params.topic || "general",
227
+ help: helpText,
228
+ }, null, 2),
229
+ },
230
+ ],
231
+ };
232
+ },
233
+ };
234
+ /**
235
+ * Get help text for a topic
236
+ */
237
+ function getHelpText(topic) {
238
+ const helps = {
239
+ sync: "Sync transactions from connected accounts. Use 'bills sync' to manually trigger sync.",
240
+ export: "Export transactions to Beancount or Ledger format. Configure export options in config.",
241
+ webhook: "Configure webhooks for real-time transaction updates. Set webhook URL and HMAC secret in config.",
242
+ setup: "Run 'bills setup' to connect new bank accounts via Plaid Link or Gmail OAuth.",
243
+ };
244
+ if (topic && helps[topic]) {
245
+ return helps[topic];
246
+ }
247
+ return `Available commands: bills setup, bills sync, bills status, bills config
248
+
249
+ Available topics: ${Object.keys(helps).join(", ")}
250
+
251
+ For more information, visit: https://github.com/fire-la/billclaw`;
252
+ }
253
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,79 @@
1
+ {
2
+ "$schema": "https://openclaw.dev/plugin.schema.json",
3
+ "name": "@firela/billclaw-openclaw",
4
+ "version": "0.0.1",
5
+ "description": "Financial data sovereignty plugin - Plaid, Gmail, GoCardless integration",
6
+ "author": "fire-zu",
7
+ "license": "MIT",
8
+ "capabilities": {
9
+ "tools": [
10
+ {
11
+ "name": "plaid_sync",
12
+ "description": "Sync transactions from Plaid-linked bank accounts"
13
+ },
14
+ {
15
+ "name": "gmail_fetch_bills",
16
+ "description": "Fetch bill statements from Gmail"
17
+ },
18
+ {
19
+ "name": "bill_parse",
20
+ "description": "Parse bill documents and extract transaction data"
21
+ },
22
+ {
23
+ "name": "conversational_sync",
24
+ "description": "Sync transactions with natural language support"
25
+ },
26
+ {
27
+ "name": "conversational_status",
28
+ "description": "Show account status with natural language"
29
+ },
30
+ {
31
+ "name": "conversational_help",
32
+ "description": "Get help with billclaw commands and features"
33
+ }
34
+ ],
35
+ "cliCommands": [
36
+ {
37
+ "name": "bills",
38
+ "description": "Manage financial data accounts and sync",
39
+ "subcommands": ["setup", "sync", "status", "config"]
40
+ }
41
+ ],
42
+ "oauthProviders": [
43
+ {
44
+ "name": "plaid",
45
+ "description": "Plaid Link OAuth flow for bank account linking"
46
+ },
47
+ {
48
+ "name": "gmail",
49
+ "description": "Gmail OAuth 2.0 flow for accessing email bills"
50
+ }
51
+ ],
52
+ "backgroundServices": [
53
+ {
54
+ "name": "billclaw-sync",
55
+ "description": "Automated transaction sync scheduler"
56
+ },
57
+ {
58
+ "name": "billclaw-webhook",
59
+ "description": "Webhook handler for bank notifications"
60
+ }
61
+ ],
62
+ "httpRoutes": [
63
+ {
64
+ "path": "/webhook/plaid",
65
+ "method": "POST",
66
+ "description": "Plaid webhook handler for transaction updates"
67
+ },
68
+ {
69
+ "path": "/webhook/gocardless",
70
+ "method": "POST",
71
+ "description": "GoCardless webhook handler for mandate events"
72
+ }
73
+ ]
74
+ },
75
+ "config": {
76
+ "schema": "./dist/config.schema.js",
77
+ "uiHints": "./dist/config-ui-hints.js"
78
+ }
79
+ }
package/package.json ADDED
@@ -0,0 +1,76 @@
1
+ {
2
+ "name": "@firela/billclaw-openclaw",
3
+ "version": "0.1.3",
4
+ "description": "BillClaw OpenClaw Plugin - Adapter for OpenClaw AI framework",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js",
12
+ "default": "./dist/index.js"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist",
17
+ "openclaw.plugin.json",
18
+ "README.md"
19
+ ],
20
+ "publishConfig": {
21
+ "access": "public"
22
+ },
23
+ "keywords": [
24
+ "openclaw",
25
+ "plugin",
26
+ "financial-data",
27
+ "plaid",
28
+ "gocardless",
29
+ "banking",
30
+ "transactions",
31
+ "bills"
32
+ ],
33
+ "author": "fire-la",
34
+ "license": "MIT",
35
+ "repository": {
36
+ "type": "git",
37
+ "url": "https://github.com/fire-la/billclaw.git",
38
+ "directory": "packages/openclaw"
39
+ },
40
+ "devDependencies": {
41
+ "@sinclair/typebox": "^0.34.48",
42
+ "@types/node": "^25.2.0",
43
+ "@vitest/coverage-v8": "^4.0.18",
44
+ "openclaw": "^0.0.1",
45
+ "oxfmt": "^0.1.0",
46
+ "oxlint": "^0.15.0",
47
+ "typescript": "^5.8.0",
48
+ "vitest": "^3.0.0"
49
+ },
50
+ "dependencies": {
51
+ "plaid": "^32.0.0",
52
+ "zod": "^3.25.0",
53
+ "@firela/billclaw-core": "0.1.3"
54
+ },
55
+ "peerDependencies": {
56
+ "openclaw": "^0.0.1"
57
+ },
58
+ "openclaw": {
59
+ "extensions": [
60
+ "./dist/index.js"
61
+ ]
62
+ },
63
+ "engines": {
64
+ "node": ">=20.0.0"
65
+ },
66
+ "scripts": {
67
+ "build": "tsc",
68
+ "dev": "tsc --watch",
69
+ "test": "vitest",
70
+ "test:coverage": "vitest --coverage",
71
+ "lint": "oxlint",
72
+ "format": "oxfmt src/",
73
+ "format:write": "oxfmt -w src/",
74
+ "clean": "rm -rf dist"
75
+ }
76
+ }