@lchavezpozo/firefly-plugin-openclaw 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.
- package/LICENSE +21 -0
- package/README.md +121 -0
- package/index.ts +347 -0
- package/openclaw.plugin.json +39 -0
- package/package.json +33 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Luis Chavez
|
|
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,121 @@
|
|
|
1
|
+
# π₯ Firefly III Plugin for OpenClaw
|
|
2
|
+
|
|
3
|
+
A native OpenClaw plugin for [Firefly III](https://www.firefly-iii.org/) - the self-hosted personal finance manager.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- π° **Check balances** - View all your asset accounts
|
|
8
|
+
- π **Record transactions** - Log expenses, income, and transfers
|
|
9
|
+
- π **View recent transactions** - See your latest activity
|
|
10
|
+
- ποΈ **Delete transactions** - Remove incorrect entries
|
|
11
|
+
- π **Monthly summary** - Get spending overview
|
|
12
|
+
- π·οΈ **List categories** - View all your categories
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
openclaw plugins install @lchavezpozo/firefly-plugin-openclaw
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Or clone manually:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
git clone https://github.com/lchavezpozo/firefly-plugin-openclaw.git ~/.openclaw/plugins/firefly-iii
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Configuration
|
|
27
|
+
|
|
28
|
+
### 1. Get your Firefly III API Token
|
|
29
|
+
|
|
30
|
+
1. Go to your Firefly III instance
|
|
31
|
+
2. Navigate to **Options** β **Profile** β **OAuth**
|
|
32
|
+
3. Create a new Personal Access Token
|
|
33
|
+
4. Copy the token
|
|
34
|
+
|
|
35
|
+
### 2. Configure the plugin
|
|
36
|
+
|
|
37
|
+
Add to your `~/.openclaw/openclaw.json`:
|
|
38
|
+
|
|
39
|
+
```json
|
|
40
|
+
{
|
|
41
|
+
"plugins": {
|
|
42
|
+
"load": {
|
|
43
|
+
"paths": ["~/.openclaw/plugins/firefly-iii"]
|
|
44
|
+
},
|
|
45
|
+
"entries": {
|
|
46
|
+
"firefly-iii": {
|
|
47
|
+
"enabled": true,
|
|
48
|
+
"config": {
|
|
49
|
+
"url": "http://your-firefly-instance:8080",
|
|
50
|
+
"token": "your-api-token-here"
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Or use a credentials file:
|
|
59
|
+
|
|
60
|
+
```json
|
|
61
|
+
{
|
|
62
|
+
"plugins": {
|
|
63
|
+
"entries": {
|
|
64
|
+
"firefly-iii": {
|
|
65
|
+
"enabled": true,
|
|
66
|
+
"config": {
|
|
67
|
+
"credentialsPath": "/path/to/firefly-credentials.json"
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Credentials file format:
|
|
76
|
+
```json
|
|
77
|
+
{
|
|
78
|
+
"url": "http://your-firefly-instance:8080",
|
|
79
|
+
"token": "your-api-token-here"
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### 3. Restart OpenClaw
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
openclaw gateway restart
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Usage
|
|
90
|
+
|
|
91
|
+
Once configured, the AI will automatically use these tools when you ask about finances:
|
|
92
|
+
|
|
93
|
+
- "How much money do I have?" β `firefly_accounts`
|
|
94
|
+
- "I spent $50 on groceries" β `firefly_transaction`
|
|
95
|
+
- "Show my recent expenses" β `firefly_recent`
|
|
96
|
+
- "Monthly spending summary" β `firefly_summary`
|
|
97
|
+
|
|
98
|
+
## Available Tools
|
|
99
|
+
|
|
100
|
+
| Tool | Description |
|
|
101
|
+
|------|-------------|
|
|
102
|
+
| `firefly_accounts` | Get all asset account balances |
|
|
103
|
+
| `firefly_transaction` | Record expense/income/transfer |
|
|
104
|
+
| `firefly_recent` | List recent transactions |
|
|
105
|
+
| `firefly_delete` | Delete a transaction by ID |
|
|
106
|
+
| `firefly_summary` | Get current month summary |
|
|
107
|
+
| `firefly_categories` | List all categories |
|
|
108
|
+
|
|
109
|
+
## Requirements
|
|
110
|
+
|
|
111
|
+
- OpenClaw 2026.2.0 or later
|
|
112
|
+
- Firefly III instance with API access
|
|
113
|
+
- Personal Access Token from Firefly III
|
|
114
|
+
|
|
115
|
+
## License
|
|
116
|
+
|
|
117
|
+
MIT Β© Luis Chavez
|
|
118
|
+
|
|
119
|
+
## Contributing
|
|
120
|
+
|
|
121
|
+
PRs welcome! Feel free to open issues for bugs or feature requests.
|
package/index.ts
ADDED
|
@@ -0,0 +1,347 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Firefly III Plugin for OpenClaw
|
|
3
|
+
*
|
|
4
|
+
* Personal finance management - check balances, record transactions, view spending.
|
|
5
|
+
* https://github.com/lchavezpozo/firefly-plugin-openclaw
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { readFileSync } from "fs";
|
|
9
|
+
import { resolve } from "path";
|
|
10
|
+
import { homedir } from "os";
|
|
11
|
+
|
|
12
|
+
interface FireflyConfig {
|
|
13
|
+
url?: string;
|
|
14
|
+
token?: string;
|
|
15
|
+
credentialsPath?: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
interface Credentials {
|
|
19
|
+
url: string;
|
|
20
|
+
token: string;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function expandPath(p: string): string {
|
|
24
|
+
if (p.startsWith("~/")) {
|
|
25
|
+
return resolve(homedir(), p.slice(2));
|
|
26
|
+
}
|
|
27
|
+
return resolve(p);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function getCredentials(config: FireflyConfig): Credentials {
|
|
31
|
+
// Direct config takes precedence
|
|
32
|
+
if (config.url && config.token) {
|
|
33
|
+
return { url: config.url, token: config.token };
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Try credentials file
|
|
37
|
+
if (config.credentialsPath) {
|
|
38
|
+
const credPath = expandPath(config.credentialsPath);
|
|
39
|
+
const creds = JSON.parse(readFileSync(credPath, "utf-8"));
|
|
40
|
+
return { url: creds.url, token: creds.token };
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
throw new Error(
|
|
44
|
+
"Firefly III plugin not configured. Set url+token in config or provide credentialsPath."
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
async function fireflyFetch(creds: Credentials, endpoint: string, options: RequestInit = {}) {
|
|
49
|
+
const url = creds.url.replace(/\/$/, ""); // Remove trailing slash
|
|
50
|
+
const response = await fetch(`${url}${endpoint}`, {
|
|
51
|
+
...options,
|
|
52
|
+
headers: {
|
|
53
|
+
"Authorization": `Bearer ${creds.token}`,
|
|
54
|
+
"Content-Type": "application/json",
|
|
55
|
+
"Accept": "application/json",
|
|
56
|
+
...options.headers,
|
|
57
|
+
},
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
if (!response.ok) {
|
|
61
|
+
const text = await response.text();
|
|
62
|
+
throw new Error(`Firefly API error: ${response.status} ${response.statusText} - ${text}`);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (response.status === 204) return null;
|
|
66
|
+
return response.json();
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export default function (api: any) {
|
|
70
|
+
const config: FireflyConfig = api.config?.plugins?.entries?.["firefly-iii"]?.config || {};
|
|
71
|
+
|
|
72
|
+
// ============================================
|
|
73
|
+
// Tool: Get account balances
|
|
74
|
+
// ============================================
|
|
75
|
+
api.registerTool({
|
|
76
|
+
name: "firefly_accounts",
|
|
77
|
+
description: "Get all asset account balances from Firefly III. Use when user asks about their money, balances, or 'cuΓ‘nto tengo'.",
|
|
78
|
+
parameters: {
|
|
79
|
+
type: "object",
|
|
80
|
+
properties: {},
|
|
81
|
+
required: [],
|
|
82
|
+
},
|
|
83
|
+
async execute() {
|
|
84
|
+
const creds = getCredentials(config);
|
|
85
|
+
const data = await fireflyFetch(creds, "/api/v1/accounts?type=asset");
|
|
86
|
+
|
|
87
|
+
const accounts = data.data.map((acc: any) => ({
|
|
88
|
+
name: acc.attributes.name,
|
|
89
|
+
balance: parseFloat(acc.attributes.current_balance),
|
|
90
|
+
currency: acc.attributes.currency_symbol,
|
|
91
|
+
}));
|
|
92
|
+
|
|
93
|
+
const total = accounts.reduce((sum: number, acc: any) => sum + acc.balance, 0);
|
|
94
|
+
|
|
95
|
+
return {
|
|
96
|
+
content: [{
|
|
97
|
+
type: "text",
|
|
98
|
+
text: JSON.stringify({ accounts, total, currency: accounts[0]?.currency || "$" }, null, 2)
|
|
99
|
+
}]
|
|
100
|
+
};
|
|
101
|
+
},
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
// ============================================
|
|
105
|
+
// Tool: Record a transaction
|
|
106
|
+
// ============================================
|
|
107
|
+
api.registerTool({
|
|
108
|
+
name: "firefly_transaction",
|
|
109
|
+
description: "Record a new transaction (expense, income, or transfer) in Firefly III. Use for 'gastΓ©', 'paguΓ©', 'comprΓ©', 'recibΓ', 'transferΓ'.",
|
|
110
|
+
parameters: {
|
|
111
|
+
type: "object",
|
|
112
|
+
properties: {
|
|
113
|
+
type: {
|
|
114
|
+
type: "string",
|
|
115
|
+
enum: ["withdrawal", "deposit", "transfer"],
|
|
116
|
+
description: "Transaction type: withdrawal (expense), deposit (income), transfer"
|
|
117
|
+
},
|
|
118
|
+
amount: {
|
|
119
|
+
type: "number",
|
|
120
|
+
description: "Transaction amount (positive number)"
|
|
121
|
+
},
|
|
122
|
+
description: {
|
|
123
|
+
type: "string",
|
|
124
|
+
description: "What was this transaction for"
|
|
125
|
+
},
|
|
126
|
+
account: {
|
|
127
|
+
type: "string",
|
|
128
|
+
description: "Source account name (e.g., 'Checking', 'Savings')"
|
|
129
|
+
},
|
|
130
|
+
category: {
|
|
131
|
+
type: "string",
|
|
132
|
+
description: "Optional category (e.g., 'Food', 'Transport')"
|
|
133
|
+
},
|
|
134
|
+
destination_account: {
|
|
135
|
+
type: "string",
|
|
136
|
+
description: "Destination account (required for transfers)"
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
required: ["type", "amount", "description", "account"],
|
|
140
|
+
},
|
|
141
|
+
async execute(_id: string, params: any) {
|
|
142
|
+
const creds = getCredentials(config);
|
|
143
|
+
|
|
144
|
+
// Get source account ID
|
|
145
|
+
const accountsData = await fireflyFetch(creds, "/api/v1/accounts?type=asset");
|
|
146
|
+
const sourceAccount = accountsData.data.find((acc: any) =>
|
|
147
|
+
acc.attributes.name.toLowerCase() === params.account.toLowerCase()
|
|
148
|
+
);
|
|
149
|
+
|
|
150
|
+
if (!sourceAccount) {
|
|
151
|
+
const available = accountsData.data.map((a: any) => a.attributes.name).join(", ");
|
|
152
|
+
return {
|
|
153
|
+
content: [{
|
|
154
|
+
type: "text",
|
|
155
|
+
text: `Error: Account '${params.account}' not found. Available accounts: ${available}`
|
|
156
|
+
}]
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
const transaction: any = {
|
|
161
|
+
type: params.type,
|
|
162
|
+
date: new Date().toISOString().split("T")[0],
|
|
163
|
+
amount: params.amount.toString(),
|
|
164
|
+
description: params.description,
|
|
165
|
+
source_id: sourceAccount.id,
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
if (params.category) {
|
|
169
|
+
transaction.category_name = params.category;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
if (params.type === "transfer" && params.destination_account) {
|
|
173
|
+
const destAccount = accountsData.data.find((acc: any) =>
|
|
174
|
+
acc.attributes.name.toLowerCase() === params.destination_account.toLowerCase()
|
|
175
|
+
);
|
|
176
|
+
if (destAccount) {
|
|
177
|
+
transaction.destination_id = destAccount.id;
|
|
178
|
+
} else {
|
|
179
|
+
return {
|
|
180
|
+
content: [{
|
|
181
|
+
type: "text",
|
|
182
|
+
text: `Error: Destination account '${params.destination_account}' not found.`
|
|
183
|
+
}]
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
const result = await fireflyFetch(creds, "/api/v1/transactions", {
|
|
189
|
+
method: "POST",
|
|
190
|
+
body: JSON.stringify({ transactions: [transaction] }),
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
const tx = result.data.attributes.transactions[0];
|
|
194
|
+
return {
|
|
195
|
+
content: [{
|
|
196
|
+
type: "text",
|
|
197
|
+
text: JSON.stringify({
|
|
198
|
+
success: true,
|
|
199
|
+
id: result.data.id,
|
|
200
|
+
type: tx.type,
|
|
201
|
+
amount: tx.amount,
|
|
202
|
+
currency: tx.currency_symbol,
|
|
203
|
+
description: tx.description,
|
|
204
|
+
date: tx.date,
|
|
205
|
+
category: tx.category_name || null,
|
|
206
|
+
}, null, 2)
|
|
207
|
+
}]
|
|
208
|
+
};
|
|
209
|
+
},
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
// ============================================
|
|
213
|
+
// Tool: Get recent transactions
|
|
214
|
+
// ============================================
|
|
215
|
+
api.registerTool({
|
|
216
|
+
name: "firefly_recent",
|
|
217
|
+
description: "Get recent transactions from Firefly III. Use for 'ΓΊltimos gastos', 'transacciones recientes', 'en quΓ© gastΓ©'.",
|
|
218
|
+
parameters: {
|
|
219
|
+
type: "object",
|
|
220
|
+
properties: {
|
|
221
|
+
limit: {
|
|
222
|
+
type: "number",
|
|
223
|
+
description: "Number of transactions to return (default 10)"
|
|
224
|
+
},
|
|
225
|
+
},
|
|
226
|
+
required: [],
|
|
227
|
+
},
|
|
228
|
+
async execute(_id: string, params: any) {
|
|
229
|
+
const creds = getCredentials(config);
|
|
230
|
+
const limit = params.limit || 10;
|
|
231
|
+
const data = await fireflyFetch(creds, `/api/v1/transactions?limit=${limit}`);
|
|
232
|
+
|
|
233
|
+
const transactions = data.data.map((tx: any) => {
|
|
234
|
+
const t = tx.attributes.transactions[0];
|
|
235
|
+
return {
|
|
236
|
+
id: tx.id,
|
|
237
|
+
date: t.date?.split("T")[0],
|
|
238
|
+
type: t.type,
|
|
239
|
+
amount: `${t.currency_symbol}${t.amount}`,
|
|
240
|
+
description: t.description,
|
|
241
|
+
category: t.category_name || null,
|
|
242
|
+
source: t.source_name,
|
|
243
|
+
destination: t.destination_name,
|
|
244
|
+
};
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
return {
|
|
248
|
+
content: [{
|
|
249
|
+
type: "text",
|
|
250
|
+
text: JSON.stringify(transactions, null, 2)
|
|
251
|
+
}]
|
|
252
|
+
};
|
|
253
|
+
},
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
// ============================================
|
|
257
|
+
// Tool: Delete a transaction
|
|
258
|
+
// ============================================
|
|
259
|
+
api.registerTool({
|
|
260
|
+
name: "firefly_delete",
|
|
261
|
+
description: "Delete a transaction from Firefly III by its ID.",
|
|
262
|
+
parameters: {
|
|
263
|
+
type: "object",
|
|
264
|
+
properties: {
|
|
265
|
+
transaction_id: {
|
|
266
|
+
type: "string",
|
|
267
|
+
description: "The transaction ID to delete"
|
|
268
|
+
},
|
|
269
|
+
},
|
|
270
|
+
required: ["transaction_id"],
|
|
271
|
+
},
|
|
272
|
+
async execute(_id: string, params: any) {
|
|
273
|
+
const creds = getCredentials(config);
|
|
274
|
+
|
|
275
|
+
await fireflyFetch(creds, `/api/v1/transactions/${params.transaction_id}`, {
|
|
276
|
+
method: "DELETE",
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
return {
|
|
280
|
+
content: [{
|
|
281
|
+
type: "text",
|
|
282
|
+
text: JSON.stringify({ success: true, deleted: params.transaction_id })
|
|
283
|
+
}]
|
|
284
|
+
};
|
|
285
|
+
},
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
// ============================================
|
|
289
|
+
// Tool: Get monthly summary
|
|
290
|
+
// ============================================
|
|
291
|
+
api.registerTool({
|
|
292
|
+
name: "firefly_summary",
|
|
293
|
+
description: "Get a financial summary for the current month from Firefly III. Use for 'resumen del mes', 'cuΓ‘nto gastΓ© este mes'.",
|
|
294
|
+
parameters: {
|
|
295
|
+
type: "object",
|
|
296
|
+
properties: {},
|
|
297
|
+
required: [],
|
|
298
|
+
},
|
|
299
|
+
async execute() {
|
|
300
|
+
const creds = getCredentials(config);
|
|
301
|
+
|
|
302
|
+
const now = new Date();
|
|
303
|
+
const start = new Date(now.getFullYear(), now.getMonth(), 1).toISOString().split("T")[0];
|
|
304
|
+
const end = now.toISOString().split("T")[0];
|
|
305
|
+
|
|
306
|
+
const data = await fireflyFetch(creds, `/api/v1/summary/basic?start=${start}&end=${end}`);
|
|
307
|
+
|
|
308
|
+
return {
|
|
309
|
+
content: [{
|
|
310
|
+
type: "text",
|
|
311
|
+
text: JSON.stringify(data, null, 2)
|
|
312
|
+
}]
|
|
313
|
+
};
|
|
314
|
+
},
|
|
315
|
+
});
|
|
316
|
+
|
|
317
|
+
// ============================================
|
|
318
|
+
// Tool: Get categories
|
|
319
|
+
// ============================================
|
|
320
|
+
api.registerTool({
|
|
321
|
+
name: "firefly_categories",
|
|
322
|
+
description: "List all spending categories from Firefly III.",
|
|
323
|
+
parameters: {
|
|
324
|
+
type: "object",
|
|
325
|
+
properties: {},
|
|
326
|
+
required: [],
|
|
327
|
+
},
|
|
328
|
+
async execute() {
|
|
329
|
+
const creds = getCredentials(config);
|
|
330
|
+
const data = await fireflyFetch(creds, "/api/v1/categories");
|
|
331
|
+
|
|
332
|
+
const categories = data.data.map((cat: any) => ({
|
|
333
|
+
id: cat.id,
|
|
334
|
+
name: cat.attributes.name,
|
|
335
|
+
spent: cat.attributes.spent || null,
|
|
336
|
+
earned: cat.attributes.earned || null,
|
|
337
|
+
}));
|
|
338
|
+
|
|
339
|
+
return {
|
|
340
|
+
content: [{
|
|
341
|
+
type: "text",
|
|
342
|
+
text: JSON.stringify(categories, null, 2)
|
|
343
|
+
}]
|
|
344
|
+
};
|
|
345
|
+
},
|
|
346
|
+
});
|
|
347
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "firefly-iii",
|
|
3
|
+
"name": "Firefly III",
|
|
4
|
+
"description": "Personal finance management - check balances, record transactions, view spending",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"configSchema": {
|
|
7
|
+
"type": "object",
|
|
8
|
+
"additionalProperties": false,
|
|
9
|
+
"properties": {
|
|
10
|
+
"url": {
|
|
11
|
+
"type": "string",
|
|
12
|
+
"description": "Firefly III server URL (e.g., http://localhost:8080)"
|
|
13
|
+
},
|
|
14
|
+
"token": {
|
|
15
|
+
"type": "string",
|
|
16
|
+
"description": "Firefly III Personal Access Token"
|
|
17
|
+
},
|
|
18
|
+
"credentialsPath": {
|
|
19
|
+
"type": "string",
|
|
20
|
+
"description": "Path to JSON file with url and token (alternative to inline config)"
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"uiHints": {
|
|
25
|
+
"token": {
|
|
26
|
+
"sensitive": true,
|
|
27
|
+
"label": "API Token",
|
|
28
|
+
"placeholder": "eyJ0eXAiOiJKV1QiLCJhbGciOi..."
|
|
29
|
+
},
|
|
30
|
+
"url": {
|
|
31
|
+
"label": "Firefly III URL",
|
|
32
|
+
"placeholder": "http://localhost:8080"
|
|
33
|
+
},
|
|
34
|
+
"credentialsPath": {
|
|
35
|
+
"label": "Credentials File Path",
|
|
36
|
+
"placeholder": "~/.openclaw/credentials/firefly.json"
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@lchavezpozo/firefly-plugin-openclaw",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "OpenClaw plugin for Firefly III personal finance management",
|
|
5
|
+
"main": "index.ts",
|
|
6
|
+
"keywords": [
|
|
7
|
+
"openclaw",
|
|
8
|
+
"openclaw-plugin",
|
|
9
|
+
"firefly-iii",
|
|
10
|
+
"finance",
|
|
11
|
+
"personal-finance",
|
|
12
|
+
"budgeting"
|
|
13
|
+
],
|
|
14
|
+
"author": "Luis Chavez <lchavezpozo@gmail.com>",
|
|
15
|
+
"license": "MIT",
|
|
16
|
+
"repository": {
|
|
17
|
+
"type": "git",
|
|
18
|
+
"url": "https://github.com/lchavezpozo/firefly-plugin-openclaw.git"
|
|
19
|
+
},
|
|
20
|
+
"bugs": {
|
|
21
|
+
"url": "https://github.com/lchavezpozo/firefly-plugin-openclaw/issues"
|
|
22
|
+
},
|
|
23
|
+
"homepage": "https://github.com/lchavezpozo/firefly-plugin-openclaw#readme",
|
|
24
|
+
"engines": {
|
|
25
|
+
"node": ">=18.0.0"
|
|
26
|
+
},
|
|
27
|
+
"files": [
|
|
28
|
+
"index.ts",
|
|
29
|
+
"openclaw.plugin.json",
|
|
30
|
+
"README.md",
|
|
31
|
+
"LICENSE"
|
|
32
|
+
]
|
|
33
|
+
}
|