@firela/billclaw-cli 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.
Files changed (68) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +204 -0
  3. package/bin/billclaw.js +10 -0
  4. package/dist/commands/config.d.ts +11 -0
  5. package/dist/commands/config.d.ts.map +1 -0
  6. package/dist/commands/config.js +112 -0
  7. package/dist/commands/config.js.map +1 -0
  8. package/dist/commands/export.d.ts +11 -0
  9. package/dist/commands/export.d.ts.map +1 -0
  10. package/dist/commands/export.js +106 -0
  11. package/dist/commands/export.js.map +1 -0
  12. package/dist/commands/index.d.ts +46 -0
  13. package/dist/commands/index.d.ts.map +1 -0
  14. package/dist/commands/index.js +22 -0
  15. package/dist/commands/index.js.map +1 -0
  16. package/dist/commands/registry.d.ts +62 -0
  17. package/dist/commands/registry.d.ts.map +1 -0
  18. package/dist/commands/registry.js +77 -0
  19. package/dist/commands/registry.js.map +1 -0
  20. package/dist/commands/setup.d.ts +11 -0
  21. package/dist/commands/setup.d.ts.map +1 -0
  22. package/dist/commands/setup.js +214 -0
  23. package/dist/commands/setup.js.map +1 -0
  24. package/dist/commands/status.d.ts +11 -0
  25. package/dist/commands/status.d.ts.map +1 -0
  26. package/dist/commands/status.js +187 -0
  27. package/dist/commands/status.js.map +1 -0
  28. package/dist/commands/sync.d.ts +11 -0
  29. package/dist/commands/sync.d.ts.map +1 -0
  30. package/dist/commands/sync.js +150 -0
  31. package/dist/commands/sync.js.map +1 -0
  32. package/dist/index.d.ts +15 -0
  33. package/dist/index.d.ts.map +1 -0
  34. package/dist/index.js +45 -0
  35. package/dist/index.js.map +1 -0
  36. package/dist/runtime/config.d.ts +32 -0
  37. package/dist/runtime/config.d.ts.map +1 -0
  38. package/dist/runtime/config.js +105 -0
  39. package/dist/runtime/config.js.map +1 -0
  40. package/dist/runtime/context.d.ts +33 -0
  41. package/dist/runtime/context.d.ts.map +1 -0
  42. package/dist/runtime/context.js +35 -0
  43. package/dist/runtime/context.js.map +1 -0
  44. package/dist/runtime/events.d.ts +24 -0
  45. package/dist/runtime/events.d.ts.map +1 -0
  46. package/dist/runtime/events.js +54 -0
  47. package/dist/runtime/events.js.map +1 -0
  48. package/dist/runtime/index.d.ts +10 -0
  49. package/dist/runtime/index.d.ts.map +1 -0
  50. package/dist/runtime/index.js +10 -0
  51. package/dist/runtime/index.js.map +1 -0
  52. package/dist/runtime/logger.d.ts +41 -0
  53. package/dist/runtime/logger.d.ts.map +1 -0
  54. package/dist/runtime/logger.js +95 -0
  55. package/dist/runtime/logger.js.map +1 -0
  56. package/dist/utils/format.d.ts +62 -0
  57. package/dist/utils/format.d.ts.map +1 -0
  58. package/dist/utils/format.js +153 -0
  59. package/dist/utils/format.js.map +1 -0
  60. package/dist/utils/index.d.ts +6 -0
  61. package/dist/utils/index.d.ts.map +1 -0
  62. package/dist/utils/index.js +6 -0
  63. package/dist/utils/index.js.map +1 -0
  64. package/dist/utils/progress.d.ts +38 -0
  65. package/dist/utils/progress.d.ts.map +1 -0
  66. package/dist/utils/progress.js +70 -0
  67. package/dist/utils/progress.js.map +1 -0
  68. package/package.json +72 -0
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,204 @@
1
+ # @firela/billclaw-cli
2
+
3
+ Standalone command-line interface for BillClaw financial data management.
4
+
5
+ ## Overview
6
+
7
+ The CLI package provides a command-line tool for managing financial data without requiring any AI framework. It includes:
8
+
9
+ - Interactive setup wizard for connecting accounts
10
+ - Manual transaction sync from Plaid and Gmail
11
+ - Account status monitoring
12
+ - Configuration management
13
+ - Export to Beancount and Ledger formats
14
+ - Import from CSV, OFX, and QFX files
15
+
16
+ ## Installation
17
+
18
+ ### Global Installation
19
+
20
+ ```bash
21
+ npm install -g @firela/billclaw-cli
22
+ ```
23
+
24
+ ### Local Installation
25
+
26
+ ```bash
27
+ npm install @firela/billclaw-cli
28
+ npx billclaw
29
+ ```
30
+
31
+ ## Quick Start
32
+
33
+ ```bash
34
+ # Interactive setup wizard
35
+ billclaw setup
36
+
37
+ # Sync all accounts
38
+ billclaw sync
39
+
40
+ # Sync specific account
41
+ billclaw sync --account plaid-123
42
+
43
+ # Show account status
44
+ billclaw status
45
+
46
+ # Export transactions
47
+ billclaw export --format beancount --output transactions.beancount
48
+ ```
49
+
50
+ ## Commands
51
+
52
+ ### setup
53
+
54
+ Interactive setup wizard for connecting accounts.
55
+
56
+ ```bash
57
+ billclaw setup
58
+ ```
59
+
60
+ Supports:
61
+ - Plaid (bank accounts via Plaid Link)
62
+ - Gmail (email bills)
63
+ - GoCardless (European open banking)
64
+
65
+ ### sync
66
+
67
+ Manually trigger transaction sync.
68
+
69
+ ```bash
70
+ # Sync all accounts
71
+ billclaw sync
72
+
73
+ # Sync specific account
74
+ billclaw sync --account <id>
75
+
76
+ # Sync all (explicit)
77
+ billclaw sync --all
78
+ ```
79
+
80
+ ### status
81
+
82
+ Show connection status and recent sync results.
83
+
84
+ ```bash
85
+ billclaw status
86
+ ```
87
+
88
+ Displays:
89
+ - Account ID and type
90
+ - Connection status
91
+ - Last sync time
92
+
93
+ ### config
94
+
95
+ Manage plugin configuration.
96
+
97
+ ```bash
98
+ # List all configuration
99
+ billclaw config --list
100
+
101
+ # Get specific value
102
+ billclaw config --key storage.path
103
+
104
+ # Set value
105
+ billclaw config --key storage.format --value json
106
+ ```
107
+
108
+ ### export
109
+
110
+ Export transactions to Beancount or Ledger format.
111
+
112
+ ```bash
113
+ # Export to Beancount
114
+ billclaw export --format beancount --output transactions.beancount
115
+
116
+ # Export specific account
117
+ billclaw export --account plaid-123 --format ledger
118
+
119
+ # Export specific period
120
+ billclaw export --year 2024 --month 1
121
+ ```
122
+
123
+ ### import
124
+
125
+ Import transactions from external files.
126
+
127
+ ```bash
128
+ # Import from CSV
129
+ billclaw import transactions.csv
130
+
131
+ # Import from OFX
132
+ billclaw import statement.ofx --account checking-123
133
+ ```
134
+
135
+ ## Configuration
136
+
137
+ Configuration is stored in `~/.billclaw/config.json`:
138
+
139
+ ```json
140
+ {
141
+ "accounts": [],
142
+ "webhooks": [],
143
+ "storage": {
144
+ "path": "~/.billclaw",
145
+ "format": "json",
146
+ "encryption": { "enabled": false }
147
+ },
148
+ "sync": {
149
+ "defaultFrequency": "daily",
150
+ "maxRetries": 3,
151
+ "retryOnFailure": true
152
+ },
153
+ "plaid": {
154
+ "environment": "sandbox"
155
+ }
156
+ }
157
+ ```
158
+
159
+ ## Data Storage
160
+
161
+ By default, data is stored in `~/.billclaw/`:
162
+
163
+ ```
164
+ ~/.billclaw/
165
+ ├── config.json # Configuration
166
+ ├── data/ # Transaction storage
167
+ │ ├── transactions/ # Per-account transactions
168
+ │ └── accounts/ # Account metadata
169
+ └── exports/ # Exported files
170
+ ```
171
+
172
+ ## Exit Codes
173
+
174
+ - `0` - Success
175
+ - `1` - Error occurred
176
+
177
+ ## Examples
178
+
179
+ ### Complete Workflow
180
+
181
+ ```bash
182
+ # 1. Setup accounts
183
+ billclaw setup
184
+
185
+ # 2. Sync transactions
186
+ billclaw sync
187
+
188
+ # 3. Check status
189
+ billclaw status
190
+
191
+ # 4. Export to Beancount
192
+ billclaw export --format beancount -o main.beancount
193
+ ```
194
+
195
+ ### Monthly Accounting Export
196
+
197
+ ```bash
198
+ # Export last month's transactions
199
+ billclaw export --format beancount --year 2024 --month 1 --output january.beancount
200
+ ```
201
+
202
+ ## License
203
+
204
+ MIT
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * BillClaw CLI binary
4
+ *
5
+ * Entry point for the billclaw command.
6
+ */
7
+
8
+ import { main } from "../dist/index.js";
9
+
10
+ main(process.argv);
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Config command
3
+ *
4
+ * Manage plugin configuration.
5
+ */
6
+ import type { CliCommand } from "./registry.js";
7
+ /**
8
+ * Config command definition
9
+ */
10
+ export declare const configCommand: CliCommand;
11
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAc,MAAM,eAAe,CAAA;AAuG3D;;GAEG;AACH,eAAO,MAAM,aAAa,EAAE,UAyB3B,CAAA"}
@@ -0,0 +1,112 @@
1
+ /**
2
+ * Config command
3
+ *
4
+ * Manage plugin configuration.
5
+ */
6
+ import { success, error } from "../utils/format.js";
7
+ /**
8
+ * Run config command
9
+ */
10
+ async function runConfig(context, args) {
11
+ const { runtime } = context;
12
+ const list = args?.list ?? false;
13
+ const key = args?.key;
14
+ const value = args?.value;
15
+ if (list || (!key && !value)) {
16
+ await listConfig(runtime);
17
+ }
18
+ else if (key && value) {
19
+ await setConfig(runtime, key, value);
20
+ }
21
+ else if (key) {
22
+ await getConfig(runtime, key);
23
+ }
24
+ }
25
+ /**
26
+ * List all configuration
27
+ */
28
+ async function listConfig(runtime) {
29
+ const config = await runtime.config.getConfig();
30
+ console.log(JSON.stringify(config, null, 2));
31
+ }
32
+ /**
33
+ * Get a config value
34
+ */
35
+ async function getConfig(runtime, key) {
36
+ const config = await runtime.config.getConfig();
37
+ // Support dot notation for nested keys
38
+ const keys = key.split(".");
39
+ let value = config;
40
+ for (const k of keys) {
41
+ value = value?.[k];
42
+ }
43
+ if (value === undefined) {
44
+ console.log(`Config key '${key}' not found`);
45
+ return;
46
+ }
47
+ if (typeof value === "object") {
48
+ console.log(JSON.stringify(value, null, 2));
49
+ }
50
+ else {
51
+ console.log(String(value));
52
+ }
53
+ }
54
+ /**
55
+ * Set a config value
56
+ */
57
+ async function setConfig(runtime, key, valueStr) {
58
+ const config = await runtime.config.getConfig();
59
+ // Support dot notation for nested keys
60
+ const keys = key.split(".");
61
+ let target = config;
62
+ for (let i = 0; i < keys.length - 1; i++) {
63
+ if (!(keys[i] in target)) {
64
+ target[keys[i]] = {};
65
+ }
66
+ target = target[keys[i]];
67
+ }
68
+ // Try to parse as JSON first
69
+ let parsedValue;
70
+ try {
71
+ parsedValue = JSON.parse(valueStr);
72
+ }
73
+ catch {
74
+ parsedValue = valueStr;
75
+ }
76
+ target[keys[keys.length - 1]] = parsedValue;
77
+ // Save the updated config
78
+ const provider = runtime.config;
79
+ if (typeof provider.saveConfig === "function") {
80
+ await provider.saveConfig(config);
81
+ success(`Config '${key}' updated`);
82
+ }
83
+ else {
84
+ error("Saving config not supported");
85
+ }
86
+ }
87
+ /**
88
+ * Config command definition
89
+ */
90
+ export const configCommand = {
91
+ name: "config",
92
+ description: "Manage plugin configuration",
93
+ options: [
94
+ {
95
+ flags: "-l, --list",
96
+ description: "List all configuration",
97
+ },
98
+ {
99
+ flags: "-k, --key <key>",
100
+ description: "Config key to view/set",
101
+ },
102
+ {
103
+ flags: "-v, --value <value>",
104
+ description: "Config value to set",
105
+ },
106
+ ],
107
+ handler: (context, args) => {
108
+ const typedArgs = args;
109
+ return runConfig(context, typedArgs ?? {});
110
+ },
111
+ };
112
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Export command
3
+ *
4
+ * Export transactions to Beancount or Ledger format.
5
+ */
6
+ import type { CliCommand } from "./registry.js";
7
+ /**
8
+ * Export command definition
9
+ */
10
+ export declare const exportCommand: CliCommand;
11
+ //# sourceMappingURL=export.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"export.d.ts","sourceRoot":"","sources":["../../src/commands/export.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAc,MAAM,eAAe,CAAA;AAuG3D;;GAEG;AACH,eAAO,MAAM,aAAa,EAAE,UAmC3B,CAAA"}
@@ -0,0 +1,106 @@
1
+ /**
2
+ * Export command
3
+ *
4
+ * Export transactions to Beancount or Ledger format.
5
+ */
6
+ import { Spinner } from "../utils/progress.js";
7
+ import { Billclaw, exportToBeancount, exportToLedger, } from "@firela/billclaw-core";
8
+ import * as fs from "node:fs/promises";
9
+ import * as path from "node:path";
10
+ /**
11
+ * Run export command
12
+ */
13
+ async function runExport(context, args) {
14
+ const { runtime } = context;
15
+ const billclaw = new Billclaw(runtime);
16
+ const format = args.format ?? "beancount";
17
+ const outputPath = args.output ?? getDefaultExportPath(format);
18
+ const spinner = new Spinner({
19
+ text: `Exporting transactions to ${format}...`,
20
+ }).start();
21
+ try {
22
+ const now = new Date();
23
+ const year = args.year ? parseInt(args.year, 10) : now.getFullYear();
24
+ const month = args.month ? parseInt(args.month, 10) : now.getMonth() + 1;
25
+ const accountId = args.account;
26
+ // Get transactions for the specified period
27
+ const transactions = await billclaw.getTransactions(accountId || "all", year, month);
28
+ // Export to requested format
29
+ let content;
30
+ switch (format) {
31
+ case "beancount": {
32
+ const options = {
33
+ accountId: accountId || "all",
34
+ year,
35
+ month,
36
+ commodity: "USD",
37
+ };
38
+ content = await exportToBeancount(transactions, options);
39
+ break;
40
+ }
41
+ case "ledger": {
42
+ const options = {
43
+ accountId: accountId || "all",
44
+ year,
45
+ month,
46
+ commodity: "USD",
47
+ };
48
+ content = await exportToLedger(transactions, options);
49
+ break;
50
+ }
51
+ default:
52
+ throw new Error(`Unknown export format: ${format}`);
53
+ }
54
+ // Ensure output directory exists
55
+ const outputDir = path.dirname(outputPath);
56
+ await fs.mkdir(outputDir, { recursive: true });
57
+ // Write to file
58
+ await fs.writeFile(outputPath, content, "utf-8");
59
+ spinner.succeed(`Exported ${transactions.length} transactions to ${outputPath}`);
60
+ }
61
+ catch (err) {
62
+ spinner.fail(`Export failed: ${err.message}`);
63
+ throw err;
64
+ }
65
+ }
66
+ /**
67
+ * Get default export path
68
+ */
69
+ function getDefaultExportPath(format) {
70
+ const date = new Date().toISOString().split("T")[0];
71
+ return `~/.billclaw/exports/${format}-${date}.${format === "beancount" ? "beancount" : "ldg"}`;
72
+ }
73
+ /**
74
+ * Export command definition
75
+ */
76
+ export const exportCommand = {
77
+ name: "export",
78
+ description: "Export transactions to Beancount or Ledger format",
79
+ options: [
80
+ {
81
+ flags: "-f, --format <format>",
82
+ description: "Export format: beancount or ledger (default: beancount)",
83
+ },
84
+ {
85
+ flags: "-o, --output <path>",
86
+ description: "Output file path",
87
+ },
88
+ {
89
+ flags: "-a, --account <id>",
90
+ description: "Account ID to export (default: all)",
91
+ },
92
+ {
93
+ flags: "-y, --year <year>",
94
+ description: "Year to export (default: current year)",
95
+ },
96
+ {
97
+ flags: "-m, --month <month>",
98
+ description: "Month to export (default: current month)",
99
+ },
100
+ ],
101
+ handler: (context, args) => {
102
+ const typedArgs = args;
103
+ return runExport(context, typedArgs ?? {});
104
+ },
105
+ };
106
+ //# sourceMappingURL=export.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"export.js","sourceRoot":"","sources":["../../src/commands/export.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * CLI commands module
3
+ *
4
+ * All available CLI commands.
5
+ */
6
+ export { CommandRegistry, type CliCommand, type CliContext, type CliCommandHandler, } from "./registry.js";
7
+ export { setupCommand } from "./setup.js";
8
+ export { syncCommand } from "./sync.js";
9
+ export { statusCommand } from "./status.js";
10
+ export { configCommand } from "./config.js";
11
+ export { exportCommand } from "./export.js";
12
+ /**
13
+ * All commands to register
14
+ */
15
+ export declare const allCommands: ({
16
+ setup: () => Promise<import("./registry.js").CliCommand>;
17
+ sync?: undefined;
18
+ status?: undefined;
19
+ config?: undefined;
20
+ export?: undefined;
21
+ } | {
22
+ sync: () => Promise<import("./registry.js").CliCommand>;
23
+ setup?: undefined;
24
+ status?: undefined;
25
+ config?: undefined;
26
+ export?: undefined;
27
+ } | {
28
+ status: () => Promise<import("./registry.js").CliCommand>;
29
+ setup?: undefined;
30
+ sync?: undefined;
31
+ config?: undefined;
32
+ export?: undefined;
33
+ } | {
34
+ config: () => Promise<import("./registry.js").CliCommand>;
35
+ setup?: undefined;
36
+ sync?: undefined;
37
+ status?: undefined;
38
+ export?: undefined;
39
+ } | {
40
+ export: () => Promise<import("./registry.js").CliCommand>;
41
+ setup?: undefined;
42
+ sync?: undefined;
43
+ status?: undefined;
44
+ config?: undefined;
45
+ })[];
46
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/commands/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,eAAe,EACf,KAAK,UAAU,EACf,KAAK,UAAU,EACf,KAAK,iBAAiB,GACvB,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC3C;;GAEG;AACH,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAMvB,CAAA"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * CLI commands module
3
+ *
4
+ * All available CLI commands.
5
+ */
6
+ export { CommandRegistry, } from "./registry.js";
7
+ export { setupCommand } from "./setup.js";
8
+ export { syncCommand } from "./sync.js";
9
+ export { statusCommand } from "./status.js";
10
+ export { configCommand } from "./config.js";
11
+ export { exportCommand } from "./export.js";
12
+ /**
13
+ * All commands to register
14
+ */
15
+ export const allCommands = [
16
+ { setup: () => import("./setup.js").then((m) => m.setupCommand) },
17
+ { sync: () => import("./sync.js").then((m) => m.syncCommand) },
18
+ { status: () => import("./status.js").then((m) => m.statusCommand) },
19
+ { config: () => import("./config.js").then((m) => m.configCommand) },
20
+ { export: () => import("./export.js").then((m) => m.exportCommand) },
21
+ ];
22
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/commands/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,eAAe,GAIhB,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC3C;;GAEG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,EAAE;IACjE,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE;IAC9D,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,EAAE;IACpE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,EAAE;IACpE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,EAAE;CACrE,CAAA"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * CLI command framework
3
+ *
4
+ * Base command interface and utilities using Commander.js.
5
+ */
6
+ import { Command } from "commander";
7
+ import type { CliRuntimeContext } from "../runtime/context.js";
8
+ /**
9
+ * CLI execution context
10
+ */
11
+ export interface CliContext {
12
+ runtime: CliRuntimeContext;
13
+ program: Command;
14
+ }
15
+ /**
16
+ * CLI command handler
17
+ */
18
+ export type CliCommandHandler = (context: CliContext, args?: Record<string, unknown>) => Promise<void> | void;
19
+ /**
20
+ * CLI command option
21
+ */
22
+ export interface CliCommandOption {
23
+ flags: string;
24
+ description: string;
25
+ default?: string | boolean | string[];
26
+ }
27
+ /**
28
+ * CLI command configuration
29
+ */
30
+ export interface CliCommand {
31
+ name: string;
32
+ description: string;
33
+ aliases?: string[];
34
+ arguments?: string;
35
+ options?: CliCommandOption[];
36
+ handler: CliCommandHandler;
37
+ }
38
+ /**
39
+ * CLI command registry
40
+ */
41
+ export declare class CommandRegistry {
42
+ private commands;
43
+ private program;
44
+ constructor(program: Command);
45
+ /**
46
+ * Register a command
47
+ */
48
+ register(command: CliCommand): void;
49
+ /**
50
+ * Get a registered command
51
+ */
52
+ get(name: string): CliCommand | undefined;
53
+ /**
54
+ * Get all registered commands
55
+ */
56
+ getAll(): CliCommand[];
57
+ /**
58
+ * Check if a command exists
59
+ */
60
+ has(name: string): boolean;
61
+ }
62
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/commands/registry.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAEnC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAA;AAE9D;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,iBAAiB,CAAA;IAC1B,OAAO,EAAE,OAAO,CAAA;CACjB;AAED;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG,CAC9B,OAAO,EAAE,UAAU,EACnB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC3B,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;AAEzB;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,MAAM,CAAA;IACnB,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,EAAE,CAAA;CACtC;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,OAAO,CAAC,EAAE,gBAAgB,EAAE,CAAA;IAC5B,OAAO,EAAE,iBAAiB,CAAA;CAC3B;AAED;;GAEG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAgC;IAChD,OAAO,CAAC,OAAO,CAAS;gBAEZ,OAAO,EAAE,OAAO;IAI5B;;OAEG;IACH,QAAQ,CAAC,OAAO,EAAE,UAAU,GAAG,IAAI;IAgDnC;;OAEG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS;IAIzC;;OAEG;IACH,MAAM,IAAI,UAAU,EAAE;IAItB;;OAEG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;CAG3B"}