@formo/cli 0.1.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/README.md ADDED
@@ -0,0 +1,142 @@
1
+ # @formo/cli
2
+
3
+ Command-line interface for the Formo API. Query wallet profiles and run analytics SQL queries directly from your terminal or via AI agents.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install -g @formo/cli
9
+ # or use without installing:
10
+ npx @formo/cli
11
+ ```
12
+
13
+ ## Authentication
14
+
15
+ Authenticate by saving your API key:
16
+
17
+ ```bash
18
+ formo login <apiKey>
19
+ ```
20
+
21
+ Or set the `FORMO_API_KEY` environment variable — it takes precedence over the saved config:
22
+
23
+ ```bash
24
+ export FORMO_API_KEY=formo_abc123
25
+ ```
26
+
27
+ ## Commands
28
+
29
+ ### `formo login`
30
+
31
+ Save your API key to `~/.config/formo/config.json`.
32
+
33
+ | Argument | Description |
34
+ |---|---|
35
+ | `apiKey` | Your `formo_` API key |
36
+
37
+ ```bash
38
+ formo login formo_abc123
39
+ ```
40
+
41
+ ---
42
+
43
+ ### `formo profiles get`
44
+
45
+ Fetch a single wallet profile by address or ENS name.
46
+
47
+ | Argument | Description |
48
+ |---|---|
49
+ | `address` | Wallet address (`0x…`) or ENS name |
50
+
51
+ | Option | Description |
52
+ |---|---|
53
+ | `--expand` | Comma-separated fields to expand: `apps`, `chains`, `tokens`, `labels` |
54
+
55
+ ```bash
56
+ formo profiles get 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045
57
+ formo profiles get vitalik.eth --expand labels,chains
58
+ ```
59
+
60
+ ---
61
+
62
+ ### `formo profiles search`
63
+
64
+ Search wallet profiles with optional filters and sorting.
65
+
66
+ | Option | Description |
67
+ |---|---|
68
+ | `--address` | Filter by wallet address |
69
+ | `--limit` | Max results to return |
70
+ | `--offset` | Pagination offset |
71
+ | `--orderBy` | Field to sort by (see values below) |
72
+ | `--orderDir` | Sort direction: `asc` or `desc` |
73
+ | `--expand` | Comma-separated fields to expand |
74
+ | `--conditions` | JSON array of `FilterCondition` objects (see below) |
75
+
76
+ **`--orderBy` values:** `last_onchain`, `first_onchain`, `net_worth_usd`, `updated_at`, `tx_count`, `first_seen`, `last_seen`, `num_sessions`, `revenue`, `volume`, `points`
77
+
78
+ ```bash
79
+ # First 10 profiles
80
+ formo profiles search --limit 10
81
+
82
+ # Top 5 by net worth
83
+ formo profiles search --orderBy net_worth_usd --orderDir desc --limit 5
84
+
85
+ # Advanced filter with conditions
86
+ formo profiles search --conditions '[{"field":"net_worth_usd","op":"gt","value":10000}]' --limit 20
87
+ ```
88
+
89
+ ---
90
+
91
+ ### `formo query run`
92
+
93
+ Run a SQL query against your Formo analytics data.
94
+
95
+ ```bash
96
+ formo query run "SELECT count(*) FROM events"
97
+ formo query run "SELECT address, net_worth_usd FROM wallet_profiles ORDER BY net_worth_usd DESC LIMIT 10"
98
+ ```
99
+
100
+ > Requires `query:read` scope on your API key.
101
+
102
+ ---
103
+
104
+ ## FilterCondition reference
105
+
106
+ The `--conditions` option accepts a JSON array of filter condition objects:
107
+
108
+ ```json
109
+ [
110
+ { "field": "net_worth_usd", "op": "gt", "value": 10000 },
111
+ { "field": "tx_count", "op": "gte", "value": 5 }
112
+ ]
113
+ ```
114
+
115
+ | Field | Type | Description |
116
+ |---|---|---|
117
+ | `field` | `string` | Profile field to filter on |
118
+ | `op` | `string` | Operator: `eq`, `neq`, `gt`, `gte`, `lt`, `lte`, `in`, `nin` |
119
+ | `value` | `any` | Value to compare against |
120
+
121
+ Multiple conditions are combined with `AND` logic.
122
+
123
+ ---
124
+
125
+ ## Development
126
+
127
+ ```bash
128
+ # Install dependencies
129
+ pnpm install
130
+
131
+ # Run in development mode
132
+ pnpm --filter @formo/cli dev
133
+
134
+ # Build TypeScript
135
+ pnpm --filter @formo/cli build
136
+
137
+ # Run tests
138
+ pnpm --filter @formo/cli test
139
+
140
+ # Watch tests
141
+ pnpm --filter @formo/cli test:watch
142
+ ```
@@ -0,0 +1,22 @@
1
+ import { Cli } from 'incur';
2
+ export declare const alerts: Cli.Cli<{}, undefined, undefined>;
3
+ export declare function listAlertsRun(): Promise<import("axios").AxiosResponse<any, any, {}>>;
4
+ export declare function getAlertRun(alertId: string): Promise<import("axios").AxiosResponse<any, any, {}>>;
5
+ export interface CreateAlertOptions {
6
+ name: string;
7
+ triggerType: string;
8
+ triggerFilters?: string;
9
+ recipient?: string;
10
+ secret?: string;
11
+ }
12
+ export declare function createAlertRun(options: CreateAlertOptions): Promise<import("axios").AxiosResponse<any, any, {}>>;
13
+ export interface UpdateAlertOptions {
14
+ name: string;
15
+ triggerType: string;
16
+ triggerFilters?: string;
17
+ recipient?: string;
18
+ secret?: string;
19
+ }
20
+ export declare function updateAlertRun(alertId: string, options: UpdateAlertOptions): Promise<import("axios").AxiosResponse<any, any, {}>>;
21
+ export declare function deleteAlertRun(alertId: string): Promise<import("axios").AxiosResponse<any, any, {}>>;
22
+ export declare function toggleAlertRun(alertId: string, status: string): Promise<import("axios").AxiosResponse<any, any, {}>>;
@@ -0,0 +1,204 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.alerts = void 0;
4
+ exports.listAlertsRun = listAlertsRun;
5
+ exports.getAlertRun = getAlertRun;
6
+ exports.createAlertRun = createAlertRun;
7
+ exports.updateAlertRun = updateAlertRun;
8
+ exports.deleteAlertRun = deleteAlertRun;
9
+ exports.toggleAlertRun = toggleAlertRun;
10
+ const incur_1 = require("incur");
11
+ const client_1 = require("../lib/client");
12
+ exports.alerts = incur_1.Cli.create('alerts', {
13
+ description: 'Project alert commands — create, list, update, and delete alerts',
14
+ });
15
+ // ── List alerts ──
16
+ function listAlertsRun() {
17
+ (0, client_1.requireApiKey)();
18
+ const client = (0, client_1.createClient)();
19
+ return client.get('/v0/alerts/');
20
+ }
21
+ exports.alerts.command('list', {
22
+ description: 'List all alerts for the project',
23
+ examples: [{ description: 'List all project alerts' }],
24
+ hint: 'Requires alerts:read scope on your API key.',
25
+ run() {
26
+ return listAlertsRun();
27
+ },
28
+ });
29
+ // ── Get a single alert ──
30
+ function getAlertRun(alertId) {
31
+ (0, client_1.requireApiKey)();
32
+ const client = (0, client_1.createClient)();
33
+ return client.get(`/v0/alerts/${encodeURIComponent(alertId)}`);
34
+ }
35
+ exports.alerts.command('get', {
36
+ description: 'Get a single alert by ID',
37
+ args: incur_1.z.object({
38
+ alertId: incur_1.z.string().describe('Alert ID'),
39
+ }),
40
+ examples: [
41
+ { args: { alertId: 'alert_abc123' }, description: 'Get alert details' },
42
+ ],
43
+ hint: 'Requires alerts:read scope on your API key.',
44
+ run({ args }) {
45
+ return getAlertRun(args.alertId);
46
+ },
47
+ });
48
+ function createAlertRun(options) {
49
+ (0, client_1.requireApiKey)();
50
+ const client = (0, client_1.createClient)();
51
+ const body = {
52
+ name: options.name,
53
+ trigger_type: options.triggerType,
54
+ };
55
+ if (options.triggerFilters) {
56
+ try {
57
+ body.trigger_filters = JSON.parse(options.triggerFilters);
58
+ }
59
+ catch {
60
+ throw new Error('--triggerFilters must be a valid JSON array');
61
+ }
62
+ }
63
+ if (options.recipient) {
64
+ try {
65
+ body.recipient = JSON.parse(options.recipient);
66
+ }
67
+ catch {
68
+ throw new Error('--recipient must be a valid JSON array');
69
+ }
70
+ }
71
+ if (options.secret) {
72
+ body.secret = options.secret;
73
+ }
74
+ return client.post('/v0/alerts/', body);
75
+ }
76
+ exports.alerts.command('create', {
77
+ description: 'Create a new project alert',
78
+ options: incur_1.z.object({
79
+ name: incur_1.z.string().describe('Alert name'),
80
+ triggerType: incur_1.z.string().describe('Trigger type (e.g. "event", "threshold")'),
81
+ triggerFilters: incur_1.z
82
+ .string()
83
+ .optional()
84
+ .describe('JSON array of trigger filter objects'),
85
+ recipient: incur_1.z
86
+ .string()
87
+ .optional()
88
+ .describe('JSON array of recipient objects'),
89
+ secret: incur_1.z.string().optional().describe('Webhook secret for the alert'),
90
+ }),
91
+ examples: [
92
+ {
93
+ options: { name: 'High value tx', triggerType: 'event' },
94
+ description: 'Create a basic event alert',
95
+ },
96
+ ],
97
+ hint: 'Requires alerts:write scope on your API key.',
98
+ run({ options }) {
99
+ return createAlertRun(options);
100
+ },
101
+ });
102
+ function updateAlertRun(alertId, options) {
103
+ (0, client_1.requireApiKey)();
104
+ const client = (0, client_1.createClient)();
105
+ const body = {
106
+ name: options.name,
107
+ trigger_type: options.triggerType,
108
+ };
109
+ if (options.triggerFilters) {
110
+ try {
111
+ body.trigger_filters = JSON.parse(options.triggerFilters);
112
+ }
113
+ catch {
114
+ throw new Error('--triggerFilters must be a valid JSON array');
115
+ }
116
+ }
117
+ if (options.recipient) {
118
+ try {
119
+ body.recipient = JSON.parse(options.recipient);
120
+ }
121
+ catch {
122
+ throw new Error('--recipient must be a valid JSON array');
123
+ }
124
+ }
125
+ if (options.secret !== undefined) {
126
+ body.secret = options.secret;
127
+ }
128
+ return client.put(`/v0/alerts/${encodeURIComponent(alertId)}`, body);
129
+ }
130
+ exports.alerts.command('update', {
131
+ description: 'Update an existing alert',
132
+ args: incur_1.z.object({
133
+ alertId: incur_1.z.string().describe('Alert ID to update'),
134
+ }),
135
+ options: incur_1.z.object({
136
+ name: incur_1.z.string().describe('Alert name'),
137
+ triggerType: incur_1.z.string().describe('Trigger type'),
138
+ triggerFilters: incur_1.z
139
+ .string()
140
+ .optional()
141
+ .describe('JSON array of trigger filter objects'),
142
+ recipient: incur_1.z
143
+ .string()
144
+ .optional()
145
+ .describe('JSON array of recipient objects'),
146
+ secret: incur_1.z.string().optional().describe('Webhook secret for the alert'),
147
+ }),
148
+ examples: [
149
+ {
150
+ args: { alertId: 'alert_abc123' },
151
+ options: { name: 'Renamed alert', triggerType: 'event' },
152
+ description: 'Update alert name',
153
+ },
154
+ ],
155
+ hint: 'Requires alerts:write scope on your API key.',
156
+ run({ args, options }) {
157
+ return updateAlertRun(args.alertId, options);
158
+ },
159
+ });
160
+ // ── Delete an alert ──
161
+ function deleteAlertRun(alertId) {
162
+ (0, client_1.requireApiKey)();
163
+ const client = (0, client_1.createClient)();
164
+ return client.delete(`/v0/alerts/${encodeURIComponent(alertId)}`);
165
+ }
166
+ exports.alerts.command('delete', {
167
+ description: 'Delete an alert',
168
+ args: incur_1.z.object({
169
+ alertId: incur_1.z.string().describe('Alert ID to delete'),
170
+ }),
171
+ examples: [
172
+ { args: { alertId: 'alert_abc123' }, description: 'Delete an alert' },
173
+ ],
174
+ hint: 'Requires alerts:write scope on your API key.',
175
+ run({ args }) {
176
+ return deleteAlertRun(args.alertId);
177
+ },
178
+ });
179
+ // ── Toggle alert status ──
180
+ function toggleAlertRun(alertId, status) {
181
+ (0, client_1.requireApiKey)();
182
+ const client = (0, client_1.createClient)();
183
+ return client.patch(`/v0/alerts/${encodeURIComponent(alertId)}`, { status });
184
+ }
185
+ exports.alerts.command('toggle', {
186
+ description: 'Toggle an alert status (active/paused)',
187
+ args: incur_1.z.object({
188
+ alertId: incur_1.z.string().describe('Alert ID to toggle'),
189
+ }),
190
+ options: incur_1.z.object({
191
+ status: incur_1.z.enum(['active', 'paused']).describe('New status'),
192
+ }),
193
+ examples: [
194
+ {
195
+ args: { alertId: 'alert_abc123' },
196
+ options: { status: 'paused' },
197
+ description: 'Pause an alert',
198
+ },
199
+ ],
200
+ hint: 'Requires alerts:write scope on your API key.',
201
+ run({ args, options }) {
202
+ return toggleAlertRun(args.alertId, options.status);
203
+ },
204
+ });
@@ -0,0 +1,15 @@
1
+ import { Cli } from 'incur';
2
+ export declare const boards: Cli.Cli<{}, undefined, undefined>;
3
+ export declare function listBoardsRun(): Promise<import("axios").AxiosResponse<any, any, {}>>;
4
+ export declare function getBoardRun(boardId: string): Promise<import("axios").AxiosResponse<any, any, {}>>;
5
+ export interface CreateBoardOptions {
6
+ name: string;
7
+ description?: string;
8
+ }
9
+ export declare function createBoardRun(options: CreateBoardOptions): Promise<import("axios").AxiosResponse<any, any, {}>>;
10
+ export interface UpdateBoardOptions {
11
+ name?: string;
12
+ description?: string;
13
+ }
14
+ export declare function updateBoardRun(boardId: string, options: UpdateBoardOptions): Promise<import("axios").AxiosResponse<any, any, {}>>;
15
+ export declare function deleteBoardRun(boardId: string): Promise<import("axios").AxiosResponse<any, any, {}>>;
@@ -0,0 +1,126 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.boards = void 0;
4
+ exports.listBoardsRun = listBoardsRun;
5
+ exports.getBoardRun = getBoardRun;
6
+ exports.createBoardRun = createBoardRun;
7
+ exports.updateBoardRun = updateBoardRun;
8
+ exports.deleteBoardRun = deleteBoardRun;
9
+ const incur_1 = require("incur");
10
+ const client_1 = require("../lib/client");
11
+ exports.boards = incur_1.Cli.create('boards', {
12
+ description: 'Dashboard board commands — create, list, update, and delete boards',
13
+ });
14
+ // ── List boards ──
15
+ function listBoardsRun() {
16
+ (0, client_1.requireApiKey)();
17
+ const client = (0, client_1.createClient)();
18
+ return client.get('/v0/boards/');
19
+ }
20
+ exports.boards.command('list', {
21
+ description: 'List all boards for the project',
22
+ examples: [{ description: 'List all dashboard boards' }],
23
+ hint: 'Requires boards:read scope on your API key.',
24
+ run() {
25
+ return listBoardsRun();
26
+ },
27
+ });
28
+ // ── Get a single board ──
29
+ function getBoardRun(boardId) {
30
+ (0, client_1.requireApiKey)();
31
+ const client = (0, client_1.createClient)();
32
+ return client.get(`/v0/boards/${encodeURIComponent(boardId)}`);
33
+ }
34
+ exports.boards.command('get', {
35
+ description: 'Get a single board by ID',
36
+ args: incur_1.z.object({
37
+ boardId: incur_1.z.string().describe('Board ID'),
38
+ }),
39
+ examples: [
40
+ { args: { boardId: 'board_abc123' }, description: 'Get board details' },
41
+ ],
42
+ hint: 'Requires boards:read scope on your API key.',
43
+ run({ args }) {
44
+ return getBoardRun(args.boardId);
45
+ },
46
+ });
47
+ function createBoardRun(options) {
48
+ (0, client_1.requireApiKey)();
49
+ const client = (0, client_1.createClient)();
50
+ const body = { name: options.name };
51
+ if (options.description) {
52
+ body.description = options.description;
53
+ }
54
+ return client.post('/v0/boards/', body);
55
+ }
56
+ exports.boards.command('create', {
57
+ description: 'Create a new dashboard board',
58
+ options: incur_1.z.object({
59
+ name: incur_1.z.string().describe('Board name'),
60
+ description: incur_1.z.string().optional().describe('Board description'),
61
+ }),
62
+ examples: [
63
+ {
64
+ options: { name: 'KPI Dashboard' },
65
+ description: 'Create a board',
66
+ },
67
+ {
68
+ options: { name: 'Revenue Metrics', description: 'Weekly revenue tracking' },
69
+ description: 'Create a board with description',
70
+ },
71
+ ],
72
+ hint: 'Requires boards:write scope on your API key.',
73
+ run({ options }) {
74
+ return createBoardRun(options);
75
+ },
76
+ });
77
+ function updateBoardRun(boardId, options) {
78
+ (0, client_1.requireApiKey)();
79
+ const client = (0, client_1.createClient)();
80
+ const body = {};
81
+ if (options.name !== undefined)
82
+ body.name = options.name;
83
+ if (options.description !== undefined)
84
+ body.description = options.description;
85
+ return client.patch(`/v0/boards/${encodeURIComponent(boardId)}`, body);
86
+ }
87
+ exports.boards.command('update', {
88
+ description: 'Update an existing board',
89
+ args: incur_1.z.object({
90
+ boardId: incur_1.z.string().describe('Board ID to update'),
91
+ }),
92
+ options: incur_1.z.object({
93
+ name: incur_1.z.string().optional().describe('New board name'),
94
+ description: incur_1.z.string().optional().describe('New board description'),
95
+ }),
96
+ examples: [
97
+ {
98
+ args: { boardId: 'board_abc123' },
99
+ options: { name: 'Renamed Board' },
100
+ description: 'Rename a board',
101
+ },
102
+ ],
103
+ hint: 'Requires boards:write scope on your API key.',
104
+ run({ args, options }) {
105
+ return updateBoardRun(args.boardId, options);
106
+ },
107
+ });
108
+ // ── Delete a board ──
109
+ function deleteBoardRun(boardId) {
110
+ (0, client_1.requireApiKey)();
111
+ const client = (0, client_1.createClient)();
112
+ return client.delete(`/v0/boards/${encodeURIComponent(boardId)}`);
113
+ }
114
+ exports.boards.command('delete', {
115
+ description: 'Delete a board',
116
+ args: incur_1.z.object({
117
+ boardId: incur_1.z.string().describe('Board ID to delete'),
118
+ }),
119
+ examples: [
120
+ { args: { boardId: 'board_abc123' }, description: 'Delete a board' },
121
+ ],
122
+ hint: 'Requires boards:write scope on your API key.',
123
+ run({ args }) {
124
+ return deleteBoardRun(args.boardId);
125
+ },
126
+ });
@@ -0,0 +1,7 @@
1
+ import { Cli } from 'incur';
2
+ export declare const charts: Cli.Cli<{}, undefined, undefined>;
3
+ export declare function listChartsRun(boardId: string): Promise<import("axios").AxiosResponse<any, any, {}>>;
4
+ export declare function getChartRun(boardId: string, chartId: string): Promise<import("axios").AxiosResponse<any, any, {}>>;
5
+ export declare function createChartRun(boardId: string, body: string): Promise<import("axios").AxiosResponse<any, any, {}>>;
6
+ export declare function updateChartRun(boardId: string, chartId: string, body: string): Promise<import("axios").AxiosResponse<any, any, {}>>;
7
+ export declare function deleteChartRun(boardId: string, chartId: string): Promise<import("axios").AxiosResponse<any, any, {}>>;
@@ -0,0 +1,157 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.charts = void 0;
4
+ exports.listChartsRun = listChartsRun;
5
+ exports.getChartRun = getChartRun;
6
+ exports.createChartRun = createChartRun;
7
+ exports.updateChartRun = updateChartRun;
8
+ exports.deleteChartRun = deleteChartRun;
9
+ const incur_1 = require("incur");
10
+ const client_1 = require("../lib/client");
11
+ exports.charts = incur_1.Cli.create('charts', {
12
+ description: 'Chart commands — create, list, update, and delete charts within boards',
13
+ });
14
+ // ── List charts for a board ──
15
+ function listChartsRun(boardId) {
16
+ (0, client_1.requireApiKey)();
17
+ const client = (0, client_1.createClient)();
18
+ return client.get(`/v0/boards/${encodeURIComponent(boardId)}/charts/`);
19
+ }
20
+ exports.charts.command('list', {
21
+ description: 'List all charts for a board',
22
+ options: incur_1.z.object({
23
+ boardId: incur_1.z.string().describe('Board ID to list charts from'),
24
+ }),
25
+ examples: [
26
+ {
27
+ options: { boardId: 'board_abc123' },
28
+ description: 'List all charts in a board',
29
+ },
30
+ ],
31
+ hint: 'Requires boards:read scope on your API key.',
32
+ run({ options }) {
33
+ return listChartsRun(options.boardId);
34
+ },
35
+ });
36
+ // ── Get a single chart ──
37
+ function getChartRun(boardId, chartId) {
38
+ (0, client_1.requireApiKey)();
39
+ const client = (0, client_1.createClient)();
40
+ return client.get(`/v0/boards/${encodeURIComponent(boardId)}/charts/${encodeURIComponent(chartId)}`);
41
+ }
42
+ exports.charts.command('get', {
43
+ description: 'Get a single chart by ID',
44
+ args: incur_1.z.object({
45
+ chartId: incur_1.z.string().describe('Chart ID'),
46
+ }),
47
+ options: incur_1.z.object({
48
+ boardId: incur_1.z.string().describe('Board ID the chart belongs to'),
49
+ }),
50
+ examples: [
51
+ {
52
+ args: { chartId: 'chart_abc123' },
53
+ options: { boardId: 'board_abc123' },
54
+ description: 'Get chart details',
55
+ },
56
+ ],
57
+ hint: 'Requires boards:read scope on your API key.',
58
+ run({ args, options }) {
59
+ return getChartRun(options.boardId, args.chartId);
60
+ },
61
+ });
62
+ // ── Create a chart ──
63
+ function createChartRun(boardId, body) {
64
+ (0, client_1.requireApiKey)();
65
+ const client = (0, client_1.createClient)();
66
+ let parsed;
67
+ try {
68
+ parsed = JSON.parse(body);
69
+ }
70
+ catch {
71
+ throw new Error('--body must be valid JSON');
72
+ }
73
+ return client.post(`/v0/boards/${encodeURIComponent(boardId)}/charts/`, parsed);
74
+ }
75
+ exports.charts.command('create', {
76
+ description: 'Create a new chart in a board',
77
+ options: incur_1.z.object({
78
+ boardId: incur_1.z.string().describe('Board ID to add the chart to'),
79
+ body: incur_1.z.string().describe('JSON string with chart configuration'),
80
+ }),
81
+ examples: [
82
+ {
83
+ options: {
84
+ boardId: 'board_abc123',
85
+ body: '{"name":"Daily active users","chartType":"line"}',
86
+ },
87
+ description: 'Create a line chart',
88
+ },
89
+ ],
90
+ hint: 'Requires boards:write scope on your API key.',
91
+ run({ options }) {
92
+ return createChartRun(options.boardId, options.body);
93
+ },
94
+ });
95
+ // ── Update a chart ──
96
+ function updateChartRun(boardId, chartId, body) {
97
+ (0, client_1.requireApiKey)();
98
+ const client = (0, client_1.createClient)();
99
+ let parsed;
100
+ try {
101
+ parsed = JSON.parse(body);
102
+ }
103
+ catch {
104
+ throw new Error('--body must be valid JSON');
105
+ }
106
+ return client.put(`/v0/boards/${encodeURIComponent(boardId)}/charts/${encodeURIComponent(chartId)}`, parsed);
107
+ }
108
+ exports.charts.command('update', {
109
+ description: 'Update an existing chart',
110
+ args: incur_1.z.object({
111
+ chartId: incur_1.z.string().describe('Chart ID to update'),
112
+ }),
113
+ options: incur_1.z.object({
114
+ boardId: incur_1.z.string().describe('Board ID the chart belongs to'),
115
+ body: incur_1.z.string().describe('JSON string with updated chart configuration'),
116
+ }),
117
+ examples: [
118
+ {
119
+ args: { chartId: 'chart_abc123' },
120
+ options: {
121
+ boardId: 'board_abc123',
122
+ body: '{"name":"Updated chart name"}',
123
+ },
124
+ description: 'Update a chart',
125
+ },
126
+ ],
127
+ hint: 'Requires boards:write scope on your API key.',
128
+ run({ args, options }) {
129
+ return updateChartRun(options.boardId, args.chartId, options.body);
130
+ },
131
+ });
132
+ // ── Delete a chart ──
133
+ function deleteChartRun(boardId, chartId) {
134
+ (0, client_1.requireApiKey)();
135
+ const client = (0, client_1.createClient)();
136
+ return client.delete(`/v0/boards/${encodeURIComponent(boardId)}/charts/${encodeURIComponent(chartId)}`);
137
+ }
138
+ exports.charts.command('delete', {
139
+ description: 'Delete a chart',
140
+ args: incur_1.z.object({
141
+ chartId: incur_1.z.string().describe('Chart ID to delete'),
142
+ }),
143
+ options: incur_1.z.object({
144
+ boardId: incur_1.z.string().describe('Board ID the chart belongs to'),
145
+ }),
146
+ examples: [
147
+ {
148
+ args: { chartId: 'chart_abc123' },
149
+ options: { boardId: 'board_abc123' },
150
+ description: 'Delete a chart',
151
+ },
152
+ ],
153
+ hint: 'Requires boards:write scope on your API key.',
154
+ run({ args, options }) {
155
+ return deleteChartRun(options.boardId, args.chartId);
156
+ },
157
+ });
@@ -0,0 +1,18 @@
1
+ import { Cli } from 'incur';
2
+ export declare const contracts: Cli.Cli<{}, undefined, undefined>;
3
+ export declare function listContractsRun(): Promise<import("axios").AxiosResponse<any, any, {}>>;
4
+ export interface CreateContractOptions {
5
+ address: string;
6
+ chain: number;
7
+ name: string;
8
+ abi: string;
9
+ events: string;
10
+ }
11
+ export declare function createContractRun(options: CreateContractOptions): Promise<import("axios").AxiosResponse<any, any, {}>>;
12
+ export interface UpdateContractOptions {
13
+ name: string;
14
+ abi: string;
15
+ events: string;
16
+ }
17
+ export declare function updateContractRun(chain: string, address: string, options: UpdateContractOptions): Promise<import("axios").AxiosResponse<any, any, {}>>;
18
+ export declare function deleteContractRun(chain: string, address: string): Promise<import("axios").AxiosResponse<any, any, {}>>;