mozyfin-cli 0.2.6 → 0.2.7
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 +20 -8
- package/agent-skills/mozyfin-cli/SKILL.md +109 -74
- package/dist/index.js +35 -34
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -6,18 +6,18 @@ A Bun-powered command line interface for Vietnamese market data from the Mozyfin
|
|
|
6
6
|
|
|
7
7
|
- Human-readable Markdown output by default
|
|
8
8
|
- CSV export with `--csv <file>` for spreadsheets or agent pipelines
|
|
9
|
-
-
|
|
10
|
-
- Authenticated commands support `MOZYFIN_API_KEY`, saved config, or `--api-key`
|
|
9
|
+
- All commands require an API key — `MOZYFIN_API_KEY`, saved config, or `--api-key`
|
|
11
10
|
- Client-side 1 request/second rate limit for API friendliness
|
|
12
11
|
- Built-in technical indicators and risk metrics from OHLCV candles
|
|
12
|
+
- Automatic update check that warns when a newer CLI version is available on npm
|
|
13
13
|
- Mocked CLI test suite covering command wiring, auth, config, CSV, validation, and output shape
|
|
14
14
|
|
|
15
15
|
## Requirements
|
|
16
16
|
|
|
17
17
|
- [Bun](https://bun.sh) `>= 1.1.0`
|
|
18
|
-
- A Mozyfin API key for
|
|
18
|
+
- A Mozyfin API key — required for every command (run `mozyfin login` once before using the CLI)
|
|
19
19
|
|
|
20
|
-
Create an API key at: https://research.mozyfin.com/
|
|
20
|
+
Create an API key at: https://research.mozyfin.com/settings
|
|
21
21
|
|
|
22
22
|
## Install
|
|
23
23
|
|
|
@@ -64,6 +64,7 @@ mozyfin ask "compare VNM and MSN margin trend"
|
|
|
64
64
|
| `search` | Search ticker/company/entity | `mozyfin search --query VNM` |
|
|
65
65
|
| `profile` | Company/entity profile | `mozyfin profile VNM.VN` |
|
|
66
66
|
| `news` | Market headlines and article search | `mozyfin news --entities VNM.VN --topics stock,earning` |
|
|
67
|
+
| `indices` | List supported market indices | `mozyfin indices` |
|
|
67
68
|
| `ohlcv` | Historical candles | `mozyfin ohlcv VNM.VN --timeframe 1d --limit 200` |
|
|
68
69
|
| `quote` | Historical quote stats | `mozyfin quote VNM.VN --limit 10` |
|
|
69
70
|
| `officers` | Company officers/directors | `mozyfin officers VNM.VN` |
|
|
@@ -78,7 +79,8 @@ mozyfin ask "compare VNM and MSN margin trend"
|
|
|
78
79
|
| `ask` | Ask the Mozyfin agent | `mozyfin ask "analyze VNM" --timeout 300` |
|
|
79
80
|
| `credits` | Check subscription usage | `mozyfin credits` |
|
|
80
81
|
| `doctor` | Runtime/config/API health check | `mozyfin doctor` |
|
|
81
|
-
| `update` |
|
|
82
|
+
| `update` | Upgrade CLI and refresh installed agent skills | `mozyfin update` |
|
|
83
|
+
| `skill` | Install/remove/list agent skill packs | `mozyfin skill claude` |
|
|
82
84
|
|
|
83
85
|
## Command Reference
|
|
84
86
|
|
|
@@ -131,6 +133,7 @@ stock, crypto, forex, tariff, economic, earning, tech, housing, mergers_and_ipo
|
|
|
131
133
|
```bash
|
|
132
134
|
mozyfin ohlcv VNM.VN --timeframe 1d --limit 200
|
|
133
135
|
mozyfin ohlcv VNM.VN --timeframe 1w --to 2024-12-31 --limit 52
|
|
136
|
+
mozyfin ohlcv VNINDEX.VN --timeframe 1d --limit 100
|
|
134
137
|
mozyfin quote VNM.VN --to 2024-12-31 --limit 10
|
|
135
138
|
```
|
|
136
139
|
|
|
@@ -140,6 +143,8 @@ Allowed OHLCV timeframes:
|
|
|
140
143
|
1h, 1d, 1w, 1mo, 1y
|
|
141
144
|
```
|
|
142
145
|
|
|
146
|
+
`ohlcv` works for both equities and market indices. The CLI first calls the entity endpoint, and if no candles come back it automatically falls back to the market-index endpoint (`/api/v1/market/market-index/<id>/ohlcv`). The id is passed through unchanged, so `mozyfin ohlcv VNINDEX.VN`, `VN30.VN`, `VN100.VN`, `HNX30.VN`, `HNXIndex.VN`, etc. all work without special-casing. Run `mozyfin indices` to list every supported index id.
|
|
147
|
+
|
|
143
148
|
### Entity Details
|
|
144
149
|
|
|
145
150
|
```bash
|
|
@@ -191,11 +196,17 @@ Requires an API key.
|
|
|
191
196
|
### Agent
|
|
192
197
|
|
|
193
198
|
```bash
|
|
194
|
-
mozyfin ask "summarize VNM risks and catalysts"
|
|
199
|
+
mozyfin ask "summarize VNM risks and catalysts"
|
|
200
|
+
mozyfin ask "what is FPT's revenue growth outlook?" --timeout 600
|
|
195
201
|
```
|
|
196
202
|
|
|
197
203
|
The command creates an auto-mode chat, sends the prompt, polls until the message finishes, and prints the final text response.
|
|
198
204
|
|
|
205
|
+
Guidance:
|
|
206
|
+
|
|
207
|
+
- **Ask one focused question per call.** Don't stuff multiple questions into a single prompt — the agent answers better and faster with a clear, narrow ask. Run `mozyfin ask` again for the next question.
|
|
208
|
+
- `--timeout <seconds>` defaults to `300` (5 minutes). Raise it for deeper research prompts.
|
|
209
|
+
|
|
199
210
|
## Output
|
|
200
211
|
|
|
201
212
|
Default output is Markdown table or key-value text:
|
|
@@ -270,10 +281,11 @@ test/*.test.ts Unit and mocked CLI tests
|
|
|
270
281
|
|
|
271
282
|
- Prefer Markdown output for short responses and `--csv <file>` for large tables.
|
|
272
283
|
- Use `search --query <text>` to discover entity ids, then pass ids such as `VNM.VN` into detail commands.
|
|
273
|
-
- Do not use removed commands/options such as `markets`, `exchanges`, or `ask --no-wait`.
|
|
284
|
+
- Do not use removed commands/options such as `markets`, `exchanges`, `events`, or `ask --no-wait`.
|
|
274
285
|
- `officers` returns people and roles, not physical office addresses.
|
|
275
|
-
-
|
|
286
|
+
- Every command requires an API key — call `mozyfin login --api-key <key>` (or set `MOZYFIN_API_KEY`) before any other command.
|
|
276
287
|
- Use `doc` for natural language queries against analysis reports (RAG); use `ask` for open-ended AI research that may call multiple data sources.
|
|
288
|
+
- If your CLI version is outdated the CLI prints an `⚠️` warning to stderr at the end of each run; pipe stderr separately if you parse output.
|
|
277
289
|
|
|
278
290
|
## License
|
|
279
291
|
|
|
@@ -15,30 +15,30 @@ mozyfin --help
|
|
|
15
15
|
mozyfin <command> --help
|
|
16
16
|
```
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
Every command requires authentication — see below — then:
|
|
19
19
|
|
|
20
20
|
```bash
|
|
21
21
|
mozyfin search --query VNM
|
|
22
22
|
mozyfin profile VNM.VN
|
|
23
|
-
mozyfin quote VNM.VN
|
|
23
|
+
mozyfin quote VNM.VN --limit 1
|
|
24
24
|
mozyfin ohlcv VNM.VN --timeframe 1d --limit 30
|
|
25
|
-
mozyfin news VNM.VN --limit 10
|
|
25
|
+
mozyfin news --entities VNM.VN --limit 10
|
|
26
26
|
```
|
|
27
27
|
|
|
28
28
|
Use `--csv <file>` for large datasets that need further processing.
|
|
29
29
|
|
|
30
30
|
## Authentication
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
Every command requires an API key.
|
|
33
33
|
|
|
34
34
|
```bash
|
|
35
|
-
# Login and save credentials
|
|
35
|
+
# Login and save credentials (recommended — run once)
|
|
36
36
|
mozyfin login --api-key <your-key>
|
|
37
37
|
|
|
38
38
|
# Or use environment variable
|
|
39
39
|
export MOZYFIN_API_KEY=<your-key>
|
|
40
40
|
|
|
41
|
-
# Or pass directly
|
|
41
|
+
# Or pass directly per-call
|
|
42
42
|
mozyfin ask "Analyze VNM" --api-key <your-key>
|
|
43
43
|
```
|
|
44
44
|
|
|
@@ -53,14 +53,14 @@ Config location: `~/.config/mozyfin-cli/config.json`
|
|
|
53
53
|
|
|
54
54
|
## Ticker Format
|
|
55
55
|
|
|
56
|
-
|
|
56
|
+
Most commands use the format `SYMBOL.VN` (or any entity id returned by `search`):
|
|
57
57
|
|
|
58
58
|
```bash
|
|
59
59
|
mozyfin profile VNM.VN
|
|
60
|
-
mozyfin quote FPT.VN
|
|
60
|
+
mozyfin quote FPT.VN --limit 1
|
|
61
61
|
```
|
|
62
62
|
|
|
63
|
-
The `search` command
|
|
63
|
+
The `search` command accepts partial names or symbols instead:
|
|
64
64
|
|
|
65
65
|
```bash
|
|
66
66
|
mozyfin search --query vinamilk
|
|
@@ -88,46 +88,63 @@ mozyfin profile VNM.VN
|
|
|
88
88
|
# Officers and directors
|
|
89
89
|
mozyfin officers VNM.VN
|
|
90
90
|
|
|
91
|
-
#
|
|
92
|
-
mozyfin
|
|
91
|
+
# Subsidiaries
|
|
92
|
+
mozyfin subsidiary VNM.VN
|
|
93
|
+
|
|
94
|
+
# Major shareholders
|
|
95
|
+
mozyfin holder VNM.VN --is-organization true --is-foreigner false
|
|
96
|
+
|
|
97
|
+
# Shareholder transactions
|
|
98
|
+
mozyfin holder-tx VNM.VN --transaction-type buy --limit 100
|
|
93
99
|
```
|
|
94
100
|
|
|
95
101
|
### Market Data
|
|
96
102
|
|
|
97
103
|
```bash
|
|
98
|
-
#
|
|
99
|
-
mozyfin quote VNM.VN
|
|
100
|
-
mozyfin quote VNM.VN
|
|
104
|
+
# Historical quote snapshot (one row by default)
|
|
105
|
+
mozyfin quote VNM.VN --limit 1
|
|
106
|
+
mozyfin quote VNM.VN --to 2024-12-31 --limit 10
|
|
101
107
|
|
|
102
|
-
#
|
|
103
|
-
mozyfin quote VNM.VN --to 1746038400
|
|
104
|
-
|
|
105
|
-
# Historical OHLCV data
|
|
108
|
+
# Historical OHLCV candles
|
|
106
109
|
mozyfin ohlcv VNM.VN --timeframe 1d --limit 100
|
|
107
|
-
mozyfin ohlcv VNM.VN
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
#
|
|
113
|
-
#
|
|
110
|
+
mozyfin ohlcv VNM.VN --timeframe 1h --limit 200 --csv vnm-hourly.csv
|
|
111
|
+
mozyfin ohlcv VNM.VN --timeframe 1d --to 2024-12-31 --limit 365
|
|
112
|
+
|
|
113
|
+
# Market indices work too — the CLI auto-falls back to the
|
|
114
|
+
# market-index endpoint when the entity endpoint has no candles.
|
|
115
|
+
# Use the same `.VN` suffix (id is passed through unchanged):
|
|
116
|
+
# VNINDEX.VN, VN30.VN, VN100.VN, HNX30.VN, HNXIndex.VN
|
|
117
|
+
# Run `mozyfin indices` to see every supported index.
|
|
118
|
+
mozyfin indices
|
|
119
|
+
mozyfin ohlcv VNINDEX.VN --timeframe 1d --limit 100
|
|
120
|
+
mozyfin ohlcv VN30.VN --timeframe 1d --limit 100
|
|
121
|
+
|
|
122
|
+
# Allowed timeframes: 1h, 1d, 1w, 1mo, 1y
|
|
114
123
|
```
|
|
115
124
|
|
|
125
|
+
Each command accepts a single entity id. To compare multiple tickers, call the command once per ticker.
|
|
126
|
+
|
|
116
127
|
### News
|
|
117
128
|
|
|
129
|
+
`news` takes a query string and/or comma-separated entity ids and topics — there is no positional ticker argument:
|
|
130
|
+
|
|
118
131
|
```bash
|
|
119
|
-
mozyfin news
|
|
120
|
-
mozyfin news
|
|
132
|
+
mozyfin news --query "Vinamilk" --limit 10
|
|
133
|
+
mozyfin news --entities VNM.VN --limit 10
|
|
134
|
+
mozyfin news --entities VNM.VN,MSN.VN --topics stock,earning --limit 20
|
|
121
135
|
```
|
|
122
136
|
|
|
137
|
+
Allowed topics: `stock`, `crypto`, `forex`, `tariff`, `economic`, `earning`, `tech`, `housing`, `mergers_and_ipo`.
|
|
138
|
+
|
|
123
139
|
### Financials
|
|
124
140
|
|
|
125
141
|
```bash
|
|
126
|
-
# Financial statements
|
|
127
|
-
mozyfin financials VNM.VN
|
|
142
|
+
# Financial statements (summarized)
|
|
143
|
+
mozyfin financials VNM.VN --year 2024 --quarter 4
|
|
144
|
+
mozyfin financials VNM.VN --year 2024 --quarter 4 --statement-type BALANCE_SHEET
|
|
128
145
|
|
|
129
|
-
# Key statistics
|
|
130
|
-
mozyfin stats VNM.VN
|
|
146
|
+
# Key ratios / statistics
|
|
147
|
+
mozyfin stats VNM.VN --year 2024
|
|
131
148
|
|
|
132
149
|
# Export to CSV
|
|
133
150
|
mozyfin financials VNM.VN --csv financials.csv
|
|
@@ -135,17 +152,17 @@ mozyfin financials VNM.VN --csv financials.csv
|
|
|
135
152
|
|
|
136
153
|
### Technical Analysis
|
|
137
154
|
|
|
155
|
+
`ta` is hardcoded to daily candles; pick which indicators to compute via flags. `risk` is also daily.
|
|
156
|
+
|
|
138
157
|
```bash
|
|
139
|
-
#
|
|
140
|
-
mozyfin ta VNM.VN --
|
|
141
|
-
mozyfin ta VNM.VN -t 1h
|
|
158
|
+
# SMA(s), RSI, MACD over daily closes (limit = candles to fetch)
|
|
159
|
+
mozyfin ta VNM.VN --sma 20,50,200 --rsi 14 --macd --limit 300
|
|
142
160
|
|
|
143
|
-
#
|
|
144
|
-
mozyfin risk VNM.VN --
|
|
145
|
-
mozyfin risk VNM.VN -t 1w
|
|
161
|
+
# Return / volatility / Sharpe / max drawdown over daily closes
|
|
162
|
+
mozyfin risk VNM.VN --limit 252 --risk-free 0.03
|
|
146
163
|
```
|
|
147
164
|
|
|
148
|
-
### Document Query
|
|
165
|
+
### Document Query
|
|
149
166
|
|
|
150
167
|
Query analysis reports using natural language. Returns structured Markdown with entities, relationships, retrieved report chunks, source references, and grounding context.
|
|
151
168
|
|
|
@@ -165,17 +182,20 @@ Output sections (in order):
|
|
|
165
182
|
|
|
166
183
|
Use `doc` when you need grounded answers from actual report documents. Use `ask` for open-ended research that may synthesize multiple data sources.
|
|
167
184
|
|
|
168
|
-
### AI Research
|
|
185
|
+
### AI Research
|
|
169
186
|
|
|
170
|
-
**Recommended for agents**: Use `ask` instead of
|
|
187
|
+
**Recommended for agents**: Use `ask` instead of chaining many individual commands. It saves tokens and provides better analysis by leveraging server-side AI with full market context.
|
|
171
188
|
|
|
172
189
|
```bash
|
|
173
|
-
# Ask AI about stocks
|
|
174
190
|
mozyfin ask "Analyze VNM financial performance"
|
|
175
|
-
mozyfin ask "
|
|
176
|
-
mozyfin ask "
|
|
191
|
+
mozyfin ask "What are the risks for FPT?"
|
|
192
|
+
mozyfin ask "Deep-dive HPG valuation" --timeout 600
|
|
177
193
|
```
|
|
178
194
|
|
|
195
|
+
**Ask one focused question per call.** Do not bundle multiple questions into a single prompt — the agent answers better and faster with a narrow, well-scoped ask. If you have several questions, call `mozyfin ask` once per question.
|
|
196
|
+
|
|
197
|
+
`--timeout <seconds>` controls how long to wait for the agent to finish. Default is `300` seconds (5 minutes). There is no short flag.
|
|
198
|
+
|
|
179
199
|
**Why agents should prefer `ask`:**
|
|
180
200
|
- Single API call vs. multiple commands
|
|
181
201
|
- Server-side AI has access to full historical data and context
|
|
@@ -183,28 +203,38 @@ mozyfin ask "What are the risks for FPT?" -t 60
|
|
|
183
203
|
- More efficient token usage for the agent
|
|
184
204
|
- Better synthesis across multiple data sources
|
|
185
205
|
|
|
186
|
-
### Account
|
|
206
|
+
### Account & Diagnostics
|
|
187
207
|
|
|
188
208
|
```bash
|
|
189
209
|
# Check remaining credits
|
|
190
210
|
mozyfin credits
|
|
191
211
|
|
|
192
|
-
#
|
|
212
|
+
# Check Bun version, config path, base URL, and API health
|
|
213
|
+
mozyfin doctor
|
|
214
|
+
|
|
215
|
+
# Logout (clears saved API key)
|
|
216
|
+
mozyfin logout
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
### Updates
|
|
220
|
+
|
|
221
|
+
`mozyfin update` checks npm for the latest release, runs `npm install -g mozyfin-cli@latest` if needed, and auto-refreshes the `mozyfin-cli` skill for any agent that already has it installed.
|
|
222
|
+
|
|
223
|
+
```bash
|
|
224
|
+
# Update CLI + refresh skills for installed agents
|
|
193
225
|
mozyfin update
|
|
194
226
|
|
|
195
|
-
#
|
|
196
|
-
mozyfin update --skill
|
|
227
|
+
# Force-refresh skill for a specific agent (or all)
|
|
197
228
|
mozyfin update --skill claude
|
|
198
229
|
mozyfin update --skill all
|
|
199
|
-
|
|
200
|
-
# Logout
|
|
201
|
-
mozyfin logout
|
|
202
230
|
```
|
|
203
231
|
|
|
232
|
+
The CLI also prints `⚠️ mozyfin-cli v<x> is outdated (latest: v<y>). Run \`mozyfin update\` to upgrade.` to stderr at the end of any command when the installed version is behind the npm `latest` tag. The check is cached for 24h in `~/.config/mozyfin-cli/version-cache.json`.
|
|
233
|
+
|
|
204
234
|
### Install Skills for Agents
|
|
205
235
|
|
|
206
236
|
```bash
|
|
207
|
-
# Install skill for specific agent
|
|
237
|
+
# Install skill for a specific agent
|
|
208
238
|
mozyfin skill claude
|
|
209
239
|
mozyfin skill cursor
|
|
210
240
|
mozyfin skill copilot
|
|
@@ -213,11 +243,12 @@ mozyfin skill codex
|
|
|
213
243
|
mozyfin skill gemini
|
|
214
244
|
mozyfin skill hermes
|
|
215
245
|
mozyfin skill openclaw
|
|
246
|
+
mozyfin skill antigravity
|
|
216
247
|
|
|
217
248
|
# Install for all agents
|
|
218
249
|
mozyfin skill all
|
|
219
250
|
|
|
220
|
-
# List installed
|
|
251
|
+
# List available/installed agents
|
|
221
252
|
mozyfin skill --list
|
|
222
253
|
|
|
223
254
|
# Remove skill
|
|
@@ -226,18 +257,17 @@ mozyfin skill claude --remove
|
|
|
226
257
|
|
|
227
258
|
## Output Formats
|
|
228
259
|
|
|
229
|
-
Default output is human-readable Markdown tables. Use `--csv
|
|
260
|
+
Default output is human-readable Markdown tables (or key-value text for single-object responses). Use `--csv <file>` to write rows to a CSV file instead:
|
|
230
261
|
|
|
231
262
|
```bash
|
|
232
|
-
|
|
233
|
-
mozyfin ohlcv VNM.VN --limit
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
mozyfin ohlcv VNM.VN --limit 1000 --csv ohlcv.csv
|
|
237
|
-
mozyfin financials VNM.VN --csv financials.csv
|
|
238
|
-
mozyfin ta VNM.VN --csv technical.csv
|
|
263
|
+
mozyfin ohlcv VNM.VN --timeframe 1d --limit 10
|
|
264
|
+
mozyfin ohlcv VNM.VN --timeframe 1d --limit 1000 --csv ohlcv.csv
|
|
265
|
+
mozyfin financials VNM.VN --year 2024 --quarter 4 --csv financials.csv
|
|
266
|
+
mozyfin ta VNM.VN --sma 20,50 --rsi 14 --csv technical.csv
|
|
239
267
|
```
|
|
240
268
|
|
|
269
|
+
The `-m` / `--md` flag is the default and only exists to make agent invocations explicit.
|
|
270
|
+
|
|
241
271
|
## Common Workflows
|
|
242
272
|
|
|
243
273
|
### Research a Stock
|
|
@@ -245,26 +275,29 @@ mozyfin ta VNM.VN --csv technical.csv
|
|
|
245
275
|
```bash
|
|
246
276
|
mozyfin search --query vnm
|
|
247
277
|
mozyfin profile VNM.VN
|
|
248
|
-
mozyfin financials VNM.VN
|
|
249
|
-
mozyfin quote VNM.VN
|
|
250
|
-
mozyfin news VNM.VN --limit 10
|
|
251
|
-
mozyfin ta VNM.VN
|
|
252
|
-
mozyfin risk VNM.VN
|
|
278
|
+
mozyfin financials VNM.VN --year 2024 --quarter 4
|
|
279
|
+
mozyfin quote VNM.VN --limit 1
|
|
280
|
+
mozyfin news --entities VNM.VN --limit 10
|
|
281
|
+
mozyfin ta VNM.VN --sma 20,50 --rsi 14 --macd
|
|
282
|
+
mozyfin risk VNM.VN --limit 252
|
|
253
283
|
```
|
|
254
284
|
|
|
255
285
|
### Compare Multiple Stocks
|
|
256
286
|
|
|
287
|
+
Each data command takes one entity. Call it per ticker, or prefer `ask` for synthesis.
|
|
288
|
+
|
|
257
289
|
```bash
|
|
258
|
-
mozyfin
|
|
259
|
-
mozyfin stats
|
|
290
|
+
mozyfin stats VNM.VN --year 2024
|
|
291
|
+
mozyfin stats FPT.VN --year 2024
|
|
292
|
+
mozyfin ask "Compare VNM and FPT 2024 margins and growth"
|
|
260
293
|
```
|
|
261
294
|
|
|
262
295
|
### Export Data for Analysis
|
|
263
296
|
|
|
264
297
|
```bash
|
|
265
298
|
mozyfin ohlcv VNM.VN --timeframe 1d --limit 365 --csv vnm-yearly.csv
|
|
266
|
-
mozyfin financials VNM.VN --csv vnm-financials.csv
|
|
267
|
-
mozyfin ta VNM.VN --csv vnm-technical.csv
|
|
299
|
+
mozyfin financials VNM.VN --year 2024 --quarter 4 --csv vnm-financials.csv
|
|
300
|
+
mozyfin ta VNM.VN --sma 20,50,200 --rsi 14 --macd --csv vnm-technical.csv
|
|
268
301
|
```
|
|
269
302
|
|
|
270
303
|
### Document-Grounded Research
|
|
@@ -277,6 +310,8 @@ mozyfin doc "FPT revenue growth outlook"
|
|
|
277
310
|
|
|
278
311
|
### AI-Powered Analysis
|
|
279
312
|
|
|
313
|
+
One focused question per call:
|
|
314
|
+
|
|
280
315
|
```bash
|
|
281
316
|
mozyfin ask "What is VNM's competitive position in dairy?"
|
|
282
317
|
mozyfin ask "Analyze FPT's revenue growth over the last 5 years"
|
|
@@ -285,16 +320,16 @@ mozyfin ask "Compare banking sector stocks: TCB, VCB, BID"
|
|
|
285
320
|
|
|
286
321
|
## Error Handling
|
|
287
322
|
|
|
288
|
-
-
|
|
289
|
-
-
|
|
290
|
-
- Network errors include status codes for debugging
|
|
291
|
-
- Use `--help` on any command for usage details
|
|
323
|
+
- Without a saved/configured API key, every command exits with `Error: Missing API key. Run \`mozyfin login --api-key <key>\` …`.
|
|
324
|
+
- Commands return clear error messages for invalid tickers and validation failures (unknown timeframes, topics, etc.).
|
|
325
|
+
- Network errors include status codes for debugging.
|
|
326
|
+
- Use `--help` on any command for usage details.
|
|
292
327
|
|
|
293
328
|
## Notes
|
|
294
329
|
|
|
295
330
|
- All price data is in VND (Vietnamese Dong)
|
|
296
331
|
- Market hours: 9:00-11:30 and 13:00-15:00 ICT (UTC+7)
|
|
297
332
|
- Data sourced from HoSE and HNX exchanges
|
|
298
|
-
-
|
|
333
|
+
- Quote data may have a few seconds delay
|
|
299
334
|
- `doc` accepts both Vietnamese and English queries
|
|
300
335
|
- `doc` returns RAG context for grounded answers; `ask` performs open-ended AI reasoning
|
package/dist/index.js
CHANGED
|
@@ -1,49 +1,49 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
// @bun
|
|
3
|
-
var
|
|
4
|
-
`).replace(/^/gm," ".repeat(2))}let Z=[`Usage: ${q.commandUsage($)}`,""],_=q.commandDescription($);if(_.length>0)Z=Z.concat([q.wrap(_,z,0),""]);let U=q.visibleArguments($).map((
|
|
5
|
-
`)}padWidth($,q){return Math.max(q.longestOptionTermLength($,q),q.longestGlobalOptionTermLength($,q),q.longestSubcommandTermLength($,q),q.longestArgumentTermLength($,q))}wrap($,q,Q,z=40){let
|
|
3
|
+
var g0=Object.create;var{getPrototypeOf:c0,defineProperty:Y0,getOwnPropertyNames:l0}=Object;var m0=Object.prototype.hasOwnProperty;var d0=($,q,Q)=>{Q=$!=null?g0(c0($)):{};let z=q||!$||!$.__esModule?Y0(Q,"default",{value:$,enumerable:!0}):Q;for(let J of l0($))if(!m0.call(z,J))Y0(z,J,{get:()=>$[J],enumerable:!0});return z};var D=($,q)=>()=>(q||$((q={exports:{}}).exports,q),q.exports);var T=import.meta.require;var k=D((r0)=>{class d extends Error{constructor($,q,Q){super(Q);Error.captureStackTrace(this,this.constructor),this.name=this.constructor.name,this.code=q,this.exitCode=$,this.nestedError=void 0}}class M0 extends d{constructor($){super(1,"commander.invalidArgument",$);Error.captureStackTrace(this,this.constructor),this.name=this.constructor.name}}r0.CommanderError=d;r0.InvalidArgumentError=M0});var C=D((n0)=>{var{InvalidArgumentError:p0}=k();class X0{constructor($,q){switch(this.description=q||"",this.variadic=!1,this.parseArg=void 0,this.defaultValue=void 0,this.defaultValueDescription=void 0,this.argChoices=void 0,$[0]){case"<":this.required=!0,this._name=$.slice(1,-1);break;case"[":this.required=!1,this._name=$.slice(1,-1);break;default:this.required=!0,this._name=$;break}if(this._name.length>3&&this._name.slice(-3)==="...")this.variadic=!0,this._name=this._name.slice(0,-3)}name(){return this._name}_concatValue($,q){if(q===this.defaultValue||!Array.isArray(q))return[$];return q.concat($)}default($,q){return this.defaultValue=$,this.defaultValueDescription=q,this}argParser($){return this.parseArg=$,this}choices($){return this.argChoices=$.slice(),this.parseArg=(q,Q)=>{if(!this.argChoices.includes(q))throw new p0(`Allowed choices are ${this.argChoices.join(", ")}.`);if(this.variadic)return this._concatValue(q,Q);return q},this}argRequired(){return this.required=!0,this}argOptional(){return this.required=!1,this}}function t0($){let q=$.name()+($.variadic===!0?"...":"");return $.required?"<"+q+">":"["+q+"]"}n0.Argument=X0;n0.humanReadableArgName=t0});var r=D(($1)=>{var{humanReadableArgName:o0}=C();class Z0{constructor(){this.helpWidth=void 0,this.sortSubcommands=!1,this.sortOptions=!1,this.showGlobalOptions=!1}visibleCommands($){let q=$.commands.filter((z)=>!z._hidden),Q=$._getHelpCommand();if(Q&&!Q._hidden)q.push(Q);if(this.sortSubcommands)q.sort((z,J)=>{return z.name().localeCompare(J.name())});return q}compareOptions($,q){let Q=(z)=>{return z.short?z.short.replace(/^-/,""):z.long.replace(/^--/,"")};return Q($).localeCompare(Q(q))}visibleOptions($){let q=$.options.filter((z)=>!z.hidden),Q=$._getHelpOption();if(Q&&!Q.hidden){let z=Q.short&&$._findOption(Q.short),J=Q.long&&$._findOption(Q.long);if(!z&&!J)q.push(Q);else if(Q.long&&!J)q.push($.createOption(Q.long,Q.description));else if(Q.short&&!z)q.push($.createOption(Q.short,Q.description))}if(this.sortOptions)q.sort(this.compareOptions);return q}visibleGlobalOptions($){if(!this.showGlobalOptions)return[];let q=[];for(let Q=$.parent;Q;Q=Q.parent){let z=Q.options.filter((J)=>!J.hidden);q.push(...z)}if(this.sortOptions)q.sort(this.compareOptions);return q}visibleArguments($){if($._argsDescription)$.registeredArguments.forEach((q)=>{q.description=q.description||$._argsDescription[q.name()]||""});if($.registeredArguments.find((q)=>q.description))return $.registeredArguments;return[]}subcommandTerm($){let q=$.registeredArguments.map((Q)=>o0(Q)).join(" ");return $._name+($._aliases[0]?"|"+$._aliases[0]:"")+($.options.length?" [options]":"")+(q?" "+q:"")}optionTerm($){return $.flags}argumentTerm($){return $.name()}longestSubcommandTermLength($,q){return q.visibleCommands($).reduce((Q,z)=>{return Math.max(Q,q.subcommandTerm(z).length)},0)}longestOptionTermLength($,q){return q.visibleOptions($).reduce((Q,z)=>{return Math.max(Q,q.optionTerm(z).length)},0)}longestGlobalOptionTermLength($,q){return q.visibleGlobalOptions($).reduce((Q,z)=>{return Math.max(Q,q.optionTerm(z).length)},0)}longestArgumentTermLength($,q){return q.visibleArguments($).reduce((Q,z)=>{return Math.max(Q,q.argumentTerm(z).length)},0)}commandUsage($){let q=$._name;if($._aliases[0])q=q+"|"+$._aliases[0];let Q="";for(let z=$.parent;z;z=z.parent)Q=z.name()+" "+Q;return Q+q+" "+$.usage()}commandDescription($){return $.description()}subcommandDescription($){return $.summary()||$.description()}optionDescription($){let q=[];if($.argChoices)q.push(`choices: ${$.argChoices.map((Q)=>JSON.stringify(Q)).join(", ")}`);if($.defaultValue!==void 0){if($.required||$.optional||$.isBoolean()&&typeof $.defaultValue==="boolean")q.push(`default: ${$.defaultValueDescription||JSON.stringify($.defaultValue)}`)}if($.presetArg!==void 0&&$.optional)q.push(`preset: ${JSON.stringify($.presetArg)}`);if($.envVar!==void 0)q.push(`env: ${$.envVar}`);if(q.length>0)return`${$.description} (${q.join(", ")})`;return $.description}argumentDescription($){let q=[];if($.argChoices)q.push(`choices: ${$.argChoices.map((Q)=>JSON.stringify(Q)).join(", ")}`);if($.defaultValue!==void 0)q.push(`default: ${$.defaultValueDescription||JSON.stringify($.defaultValue)}`);if(q.length>0){let Q=`(${q.join(", ")})`;if($.description)return`${$.description} ${Q}`;return Q}return $.description}formatHelp($,q){let Q=q.padWidth($,q),z=q.helpWidth||80,J=2,Y=2;function X(G,N){if(N){let m=`${G.padEnd(Q+2)}${N}`;return q.wrap(m,z-2,Q+2)}return G}function M(G){return G.join(`
|
|
4
|
+
`).replace(/^/gm," ".repeat(2))}let Z=[`Usage: ${q.commandUsage($)}`,""],_=q.commandDescription($);if(_.length>0)Z=Z.concat([q.wrap(_,z,0),""]);let U=q.visibleArguments($).map((G)=>{return X(q.argumentTerm(G),q.argumentDescription(G))});if(U.length>0)Z=Z.concat(["Arguments:",M(U),""]);let W=q.visibleOptions($).map((G)=>{return X(q.optionTerm(G),q.optionDescription(G))});if(W.length>0)Z=Z.concat(["Options:",M(W),""]);if(this.showGlobalOptions){let G=q.visibleGlobalOptions($).map((N)=>{return X(q.optionTerm(N),q.optionDescription(N))});if(G.length>0)Z=Z.concat(["Global Options:",M(G),""])}let L=q.visibleCommands($).map((G)=>{return X(q.subcommandTerm(G),q.subcommandDescription(G))});if(L.length>0)Z=Z.concat(["Commands:",M(L),""]);return Z.join(`
|
|
5
|
+
`)}padWidth($,q){return Math.max(q.longestOptionTermLength($,q),q.longestGlobalOptionTermLength($,q),q.longestSubcommandTermLength($,q),q.longestArgumentTermLength($,q))}wrap($,q,Q,z=40){let Y=new RegExp(`[\\n][${" \\f\\t\\v\xA0\u1680\u2000-\u200A\u202F\u205F\u3000\uFEFF"}]+`);if($.match(Y))return $;let X=q-Q;if(X<z)return $;let M=$.slice(0,Q),Z=$.slice(Q).replace(`\r
|
|
6
6
|
`,`
|
|
7
|
-
`),_=" ".repeat(Q),
|
|
8
|
-
|.{1,${X-1}}([${
|
|
9
|
-
`)return"";return(
|
|
10
|
-
`)}}
|
|
7
|
+
`),_=" ".repeat(Q),W=`\\s${"\u200B"}`,L=new RegExp(`
|
|
8
|
+
|.{1,${X-1}}([${W}]|$)|[^${W}]+?([${W}]|$)`,"g"),G=Z.match(L)||[];return M+G.map((N,m)=>{if(N===`
|
|
9
|
+
`)return"";return(m>0?_:"")+N.trimEnd()}).join(`
|
|
10
|
+
`)}}$1.Help=Z0});var s=D((Y1)=>{var{InvalidArgumentError:Q1}=k();class _0{constructor($,q){this.flags=$,this.description=q||"",this.required=$.includes("<"),this.optional=$.includes("["),this.variadic=/\w\.\.\.[>\]]$/.test($),this.mandatory=!1;let Q=J1($);if(this.short=Q.shortFlag,this.long=Q.longFlag,this.negate=!1,this.long)this.negate=this.long.startsWith("--no-");this.defaultValue=void 0,this.defaultValueDescription=void 0,this.presetArg=void 0,this.envVar=void 0,this.parseArg=void 0,this.hidden=!1,this.argChoices=void 0,this.conflictsWith=[],this.implied=void 0}default($,q){return this.defaultValue=$,this.defaultValueDescription=q,this}preset($){return this.presetArg=$,this}conflicts($){return this.conflictsWith=this.conflictsWith.concat($),this}implies($){let q=$;if(typeof $==="string")q={[$]:!0};return this.implied=Object.assign(this.implied||{},q),this}env($){return this.envVar=$,this}argParser($){return this.parseArg=$,this}makeOptionMandatory($=!0){return this.mandatory=!!$,this}hideHelp($=!0){return this.hidden=!!$,this}_concatValue($,q){if(q===this.defaultValue||!Array.isArray(q))return[$];return q.concat($)}choices($){return this.argChoices=$.slice(),this.parseArg=(q,Q)=>{if(!this.argChoices.includes(q))throw new Q1(`Allowed choices are ${this.argChoices.join(", ")}.`);if(this.variadic)return this._concatValue(q,Q);return q},this}name(){if(this.long)return this.long.replace(/^--/,"");return this.short.replace(/^-/,"")}attributeName(){return z1(this.name().replace(/^no-/,""))}is($){return this.short===$||this.long===$}isBoolean(){return!this.required&&!this.optional&&!this.negate}}class U0{constructor($){this.positiveOptions=new Map,this.negativeOptions=new Map,this.dualOptions=new Set,$.forEach((q)=>{if(q.negate)this.negativeOptions.set(q.attributeName(),q);else this.positiveOptions.set(q.attributeName(),q)}),this.negativeOptions.forEach((q,Q)=>{if(this.positiveOptions.has(Q))this.dualOptions.add(Q)})}valueFromOption($,q){let Q=q.attributeName();if(!this.dualOptions.has(Q))return!0;let z=this.negativeOptions.get(Q).presetArg,J=z!==void 0?z:!1;return q.negate===(J===$)}}function z1($){return $.split("-").reduce((q,Q)=>{return q+Q[0].toUpperCase()+Q.slice(1)})}function J1($){let q,Q,z=$.split(/[ |,]+/);if(z.length>1&&!/^[[<]/.test(z[1]))q=z.shift();if(Q=z.shift(),!q&&/^-[^-]$/.test(Q))q=Q,Q=void 0;return{shortFlag:q,longFlag:Q}}Y1.Option=_0;Y1.DualOptions=U0});var B0=D((U1)=>{function Z1($,q){if(Math.abs($.length-q.length)>3)return Math.max($.length,q.length);let Q=[];for(let z=0;z<=$.length;z++)Q[z]=[z];for(let z=0;z<=q.length;z++)Q[0][z]=z;for(let z=1;z<=q.length;z++)for(let J=1;J<=$.length;J++){let Y=1;if($[J-1]===q[z-1])Y=0;else Y=1;if(Q[J][z]=Math.min(Q[J-1][z]+1,Q[J][z-1]+1,Q[J-1][z-1]+Y),J>1&&z>1&&$[J-1]===q[z-2]&&$[J-2]===q[z-1])Q[J][z]=Math.min(Q[J][z],Q[J-2][z-2]+1)}return Q[$.length][q.length]}function _1($,q){if(!q||q.length===0)return"";q=Array.from(new Set(q));let Q=$.startsWith("--");if(Q)$=$.slice(2),q=q.map((X)=>X.slice(2));let z=[],J=3,Y=0.4;if(q.forEach((X)=>{if(X.length<=1)return;let M=Z1($,X),Z=Math.max($.length,X.length);if((Z-M)/Z>Y){if(M<J)J=M,z=[X];else if(M===J)z.push(X)}}),z.sort((X,M)=>X.localeCompare(M)),Q)z=z.map((X)=>`--${X}`);if(z.length>1)return`
|
|
11
11
|
(Did you mean one of ${z.join(", ")}?)`;if(z.length===1)return`
|
|
12
|
-
(Did you mean ${z[0]}?)`;return""}
|
|
13
|
-
- specify the name in Command constructor or using .name()`);if(q=q||{},q.isDefault)this._defaultCommandName=$._name;if(q.noHelp||q.hidden)$._hidden=!0;return this._registerCommand($),$.parent=this,$._checkForBrokenPassThrough(),this}createArgument($,q){return new
|
|
14
|
-
Expecting one of '${Q.join("', '")}'`);if(this._lifeCycleHooks[$])this._lifeCycleHooks[$].push(q);else this._lifeCycleHooks[$]=[q];return this}exitOverride($){if($)this._exitCallback=$;else this._exitCallback=(q)=>{if(q.code!=="commander.executeSubCommandAsync")throw q};return this}_exit($,q,Q){if(this._exitCallback)this._exitCallback(new
|
|
15
|
-
- already used by option '${q.flags}'`)}this.options.push($)}_registerCommand($){let q=(z)=>{return[z.name()].concat(z.aliases())},Q=q($).find((z)=>this._findCommand(z));if(Q){let z=q(this._findCommand(Q)).join("|"),J=q($).join("|");throw Error(`cannot add command '${J}' as already have command '${z}'`)}this.commands.push($)}addOption($){this._registerOption($);let q=$.name(),Q=$.attributeName();if($.negate){let J=$.long.replace(/^--no-/,"--");if(!this._findOption(J))this.setOptionValueWithSource(Q,$.defaultValue===void 0?!0:$.defaultValue,"default")}else if($.defaultValue!==void 0)this.setOptionValueWithSource(Q,$.defaultValue,"default");let z=(J,
|
|
12
|
+
(Did you mean ${z[0]}?)`;return""}U1.suggestSimilar=_1});var H0=D((L1)=>{var K1=T("events").EventEmitter,i=T("child_process"),P=T("path"),p=T("fs"),H=T("process"),{Argument:G1,humanReadableArgName:W1}=C(),{CommanderError:t}=k(),{Help:H1}=r(),{Option:K0,DualOptions:R1}=s(),{suggestSimilar:G0}=B0();class n extends K1{constructor($){super();this.commands=[],this.options=[],this.parent=null,this._allowUnknownOption=!1,this._allowExcessArguments=!0,this.registeredArguments=[],this._args=this.registeredArguments,this.args=[],this.rawArgs=[],this.processedArgs=[],this._scriptPath=null,this._name=$||"",this._optionValues={},this._optionValueSources={},this._storeOptionsAsProperties=!1,this._actionHandler=null,this._executableHandler=!1,this._executableFile=null,this._executableDir=null,this._defaultCommandName=null,this._exitCallback=null,this._aliases=[],this._combineFlagAndOptionalValue=!0,this._description="",this._summary="",this._argsDescription=void 0,this._enablePositionalOptions=!1,this._passThroughOptions=!1,this._lifeCycleHooks={},this._showHelpAfterError=!1,this._showSuggestionAfterError=!0,this._outputConfiguration={writeOut:(q)=>H.stdout.write(q),writeErr:(q)=>H.stderr.write(q),getOutHelpWidth:()=>H.stdout.isTTY?H.stdout.columns:void 0,getErrHelpWidth:()=>H.stderr.isTTY?H.stderr.columns:void 0,outputError:(q,Q)=>Q(q)},this._hidden=!1,this._helpOption=void 0,this._addImplicitHelpCommand=void 0,this._helpCommand=void 0,this._helpConfiguration={}}copyInheritedSettings($){return this._outputConfiguration=$._outputConfiguration,this._helpOption=$._helpOption,this._helpCommand=$._helpCommand,this._helpConfiguration=$._helpConfiguration,this._exitCallback=$._exitCallback,this._storeOptionsAsProperties=$._storeOptionsAsProperties,this._combineFlagAndOptionalValue=$._combineFlagAndOptionalValue,this._allowExcessArguments=$._allowExcessArguments,this._enablePositionalOptions=$._enablePositionalOptions,this._showHelpAfterError=$._showHelpAfterError,this._showSuggestionAfterError=$._showSuggestionAfterError,this}_getCommandAndAncestors(){let $=[];for(let q=this;q;q=q.parent)$.push(q);return $}command($,q,Q){let z=q,J=Q;if(typeof z==="object"&&z!==null)J=z,z=null;J=J||{};let[,Y,X]=$.match(/([^ ]+) *(.*)/),M=this.createCommand(Y);if(z)M.description(z),M._executableHandler=!0;if(J.isDefault)this._defaultCommandName=M._name;if(M._hidden=!!(J.noHelp||J.hidden),M._executableFile=J.executableFile||null,X)M.arguments(X);if(this._registerCommand(M),M.parent=this,M.copyInheritedSettings(this),z)return this;return M}createCommand($){return new n($)}createHelp(){return Object.assign(new H1,this.configureHelp())}configureHelp($){if($===void 0)return this._helpConfiguration;return this._helpConfiguration=$,this}configureOutput($){if($===void 0)return this._outputConfiguration;return Object.assign(this._outputConfiguration,$),this}showHelpAfterError($=!0){if(typeof $!=="string")$=!!$;return this._showHelpAfterError=$,this}showSuggestionAfterError($=!0){return this._showSuggestionAfterError=!!$,this}addCommand($,q){if(!$._name)throw Error(`Command passed to .addCommand() must have a name
|
|
13
|
+
- specify the name in Command constructor or using .name()`);if(q=q||{},q.isDefault)this._defaultCommandName=$._name;if(q.noHelp||q.hidden)$._hidden=!0;return this._registerCommand($),$.parent=this,$._checkForBrokenPassThrough(),this}createArgument($,q){return new G1($,q)}argument($,q,Q,z){let J=this.createArgument($,q);if(typeof Q==="function")J.default(z).argParser(Q);else J.default(Q);return this.addArgument(J),this}arguments($){return $.trim().split(/ +/).forEach((q)=>{this.argument(q)}),this}addArgument($){let q=this.registeredArguments.slice(-1)[0];if(q&&q.variadic)throw Error(`only the last argument can be variadic '${q.name()}'`);if($.required&&$.defaultValue!==void 0&&$.parseArg===void 0)throw Error(`a default value for a required argument is never used: '${$.name()}'`);return this.registeredArguments.push($),this}helpCommand($,q){if(typeof $==="boolean")return this._addImplicitHelpCommand=$,this;$=$??"help [command]";let[,Q,z]=$.match(/([^ ]+) *(.*)/),J=q??"display help for command",Y=this.createCommand(Q);if(Y.helpOption(!1),z)Y.arguments(z);if(J)Y.description(J);return this._addImplicitHelpCommand=!0,this._helpCommand=Y,this}addHelpCommand($,q){if(typeof $!=="object")return this.helpCommand($,q),this;return this._addImplicitHelpCommand=!0,this._helpCommand=$,this}_getHelpCommand(){if(this._addImplicitHelpCommand??(this.commands.length&&!this._actionHandler&&!this._findCommand("help"))){if(this._helpCommand===void 0)this.helpCommand(void 0,void 0);return this._helpCommand}return null}hook($,q){let Q=["preSubcommand","preAction","postAction"];if(!Q.includes($))throw Error(`Unexpected value for event passed to hook : '${$}'.
|
|
14
|
+
Expecting one of '${Q.join("', '")}'`);if(this._lifeCycleHooks[$])this._lifeCycleHooks[$].push(q);else this._lifeCycleHooks[$]=[q];return this}exitOverride($){if($)this._exitCallback=$;else this._exitCallback=(q)=>{if(q.code!=="commander.executeSubCommandAsync")throw q};return this}_exit($,q,Q){if(this._exitCallback)this._exitCallback(new t($,q,Q));H.exit($)}action($){let q=(Q)=>{let z=this.registeredArguments.length,J=Q.slice(0,z);if(this._storeOptionsAsProperties)J[z]=this;else J[z]=this.opts();return J.push(this),$.apply(this,J)};return this._actionHandler=q,this}createOption($,q){return new K0($,q)}_callParseArg($,q,Q,z){try{return $.parseArg(q,Q)}catch(J){if(J.code==="commander.invalidArgument"){let Y=`${z} ${J.message}`;this.error(Y,{exitCode:J.exitCode,code:J.code})}throw J}}_registerOption($){let q=$.short&&this._findOption($.short)||$.long&&this._findOption($.long);if(q){let Q=$.long&&this._findOption($.long)?$.long:$.short;throw Error(`Cannot add option '${$.flags}'${this._name&&` to command '${this._name}'`} due to conflicting flag '${Q}'
|
|
15
|
+
- already used by option '${q.flags}'`)}this.options.push($)}_registerCommand($){let q=(z)=>{return[z.name()].concat(z.aliases())},Q=q($).find((z)=>this._findCommand(z));if(Q){let z=q(this._findCommand(Q)).join("|"),J=q($).join("|");throw Error(`cannot add command '${J}' as already have command '${z}'`)}this.commands.push($)}addOption($){this._registerOption($);let q=$.name(),Q=$.attributeName();if($.negate){let J=$.long.replace(/^--no-/,"--");if(!this._findOption(J))this.setOptionValueWithSource(Q,$.defaultValue===void 0?!0:$.defaultValue,"default")}else if($.defaultValue!==void 0)this.setOptionValueWithSource(Q,$.defaultValue,"default");let z=(J,Y,X)=>{if(J==null&&$.presetArg!==void 0)J=$.presetArg;let M=this.getOptionValue(Q);if(J!==null&&$.parseArg)J=this._callParseArg($,J,M,Y);else if(J!==null&&$.variadic)J=$._concatValue(J,M);if(J==null)if($.negate)J=!1;else if($.isBoolean()||$.optional)J=!0;else J="";this.setOptionValueWithSource(Q,J,X)};if(this.on("option:"+q,(J)=>{let Y=`error: option '${$.flags}' argument '${J}' is invalid.`;z(J,Y,"cli")}),$.envVar)this.on("optionEnv:"+q,(J)=>{let Y=`error: option '${$.flags}' value '${J}' from env '${$.envVar}' is invalid.`;z(J,Y,"env")});return this}_optionEx($,q,Q,z,J){if(typeof q==="object"&&q instanceof K0)throw Error("To add an Option object use addOption() instead of option() or requiredOption()");let Y=this.createOption(q,Q);if(Y.makeOptionMandatory(!!$.mandatory),typeof z==="function")Y.default(J).argParser(z);else if(z instanceof RegExp){let X=z;z=(M,Z)=>{let _=X.exec(M);return _?_[0]:Z},Y.default(J).argParser(z)}else Y.default(z);return this.addOption(Y)}option($,q,Q,z){return this._optionEx({},$,q,Q,z)}requiredOption($,q,Q,z){return this._optionEx({mandatory:!0},$,q,Q,z)}combineFlagAndOptionalValue($=!0){return this._combineFlagAndOptionalValue=!!$,this}allowUnknownOption($=!0){return this._allowUnknownOption=!!$,this}allowExcessArguments($=!0){return this._allowExcessArguments=!!$,this}enablePositionalOptions($=!0){return this._enablePositionalOptions=!!$,this}passThroughOptions($=!0){return this._passThroughOptions=!!$,this._checkForBrokenPassThrough(),this}_checkForBrokenPassThrough(){if(this.parent&&this._passThroughOptions&&!this.parent._enablePositionalOptions)throw Error(`passThroughOptions cannot be used for '${this._name}' without turning on enablePositionalOptions for parent command(s)`)}storeOptionsAsProperties($=!0){if(this.options.length)throw Error("call .storeOptionsAsProperties() before adding options");if(Object.keys(this._optionValues).length)throw Error("call .storeOptionsAsProperties() before setting option values");return this._storeOptionsAsProperties=!!$,this}getOptionValue($){if(this._storeOptionsAsProperties)return this[$];return this._optionValues[$]}setOptionValue($,q){return this.setOptionValueWithSource($,q,void 0)}setOptionValueWithSource($,q,Q){if(this._storeOptionsAsProperties)this[$]=q;else this._optionValues[$]=q;return this._optionValueSources[$]=Q,this}getOptionValueSource($){return this._optionValueSources[$]}getOptionValueSourceWithGlobals($){let q;return this._getCommandAndAncestors().forEach((Q)=>{if(Q.getOptionValueSource($)!==void 0)q=Q.getOptionValueSource($)}),q}_prepareUserArgs($,q){if($!==void 0&&!Array.isArray($))throw Error("first parameter to parse must be array or undefined");if(q=q||{},$===void 0&&q.from===void 0){if(H.versions?.electron)q.from="electron";let z=H.execArgv??[];if(z.includes("-e")||z.includes("--eval")||z.includes("-p")||z.includes("--print"))q.from="eval"}if($===void 0)$=H.argv;this.rawArgs=$.slice();let Q;switch(q.from){case void 0:case"node":this._scriptPath=$[1],Q=$.slice(2);break;case"electron":if(H.defaultApp)this._scriptPath=$[1],Q=$.slice(2);else Q=$.slice(1);break;case"user":Q=$.slice(0);break;case"eval":Q=$.slice(1);break;default:throw Error(`unexpected parse option { from: '${q.from}' }`)}if(!this._name&&this._scriptPath)this.nameFromFilename(this._scriptPath);return this._name=this._name||"program",Q}parse($,q){let Q=this._prepareUserArgs($,q);return this._parseCommand([],Q),this}async parseAsync($,q){let Q=this._prepareUserArgs($,q);return await this._parseCommand([],Q),this}_executeSubCommand($,q){q=q.slice();let Q=!1,z=[".js",".ts",".tsx",".mjs",".cjs"];function J(_,U){let W=P.resolve(_,U);if(p.existsSync(W))return W;if(z.includes(P.extname(U)))return;let L=z.find((G)=>p.existsSync(`${W}${G}`));if(L)return`${W}${L}`;return}this._checkForMissingMandatoryOptions(),this._checkForConflictingOptions();let Y=$._executableFile||`${this._name}-${$._name}`,X=this._executableDir||"";if(this._scriptPath){let _;try{_=p.realpathSync(this._scriptPath)}catch(U){_=this._scriptPath}X=P.resolve(P.dirname(_),X)}if(X){let _=J(X,Y);if(!_&&!$._executableFile&&this._scriptPath){let U=P.basename(this._scriptPath,P.extname(this._scriptPath));if(U!==this._name)_=J(X,`${U}-${$._name}`)}Y=_||Y}Q=z.includes(P.extname(Y));let M;if(H.platform!=="win32")if(Q)q.unshift(Y),q=W0(H.execArgv).concat(q),M=i.spawn(H.argv[0],q,{stdio:"inherit"});else M=i.spawn(Y,q,{stdio:"inherit"});else q.unshift(Y),q=W0(H.execArgv).concat(q),M=i.spawn(H.execPath,q,{stdio:"inherit"});if(!M.killed)["SIGUSR1","SIGUSR2","SIGTERM","SIGINT","SIGHUP"].forEach((U)=>{H.on(U,()=>{if(M.killed===!1&&M.exitCode===null)M.kill(U)})});let Z=this._exitCallback;M.on("close",(_)=>{if(_=_??1,!Z)H.exit(_);else Z(new t(_,"commander.executeSubCommandAsync","(close)"))}),M.on("error",(_)=>{if(_.code==="ENOENT"){let U=X?`searched for local subcommand relative to directory '${X}'`:"no directory for search for local subcommand, use .executableDir() to supply a custom directory",W=`'${Y}' does not exist
|
|
16
16
|
- if '${$._name}' is not meant to be an executable command, remove description parameter from '.command()' and use '.description()' instead
|
|
17
17
|
- if the default executable name is not suitable, use the executableFile option to supply a custom name or path
|
|
18
|
-
- ${U}`;throw Error(
|
|
18
|
+
- ${U}`;throw Error(W)}else if(_.code==="EACCES")throw Error(`'${Y}' not executable`);if(!Z)H.exit(1);else{let U=new t(1,"commander.executeSubCommandAsync","(error)");U.nestedError=_,Z(U)}}),this.runningCommand=M}_dispatchSubcommand($,q,Q){let z=this._findCommand($);if(!z)this.help({error:!0});let J;return J=this._chainOrCallSubCommandHook(J,z,"preSubcommand"),J=this._chainOrCall(J,()=>{if(z._executableHandler)this._executeSubCommand(z,q.concat(Q));else return z._parseCommand(q,Q)}),J}_dispatchHelpCommand($){if(!$)this.help();let q=this._findCommand($);if(q&&!q._executableHandler)q.help();return this._dispatchSubcommand($,[],[this._getHelpOption()?.long??this._getHelpOption()?.short??"--help"])}_checkNumberOfArguments(){if(this.registeredArguments.forEach(($,q)=>{if($.required&&this.args[q]==null)this.missingArgument($.name())}),this.registeredArguments.length>0&&this.registeredArguments[this.registeredArguments.length-1].variadic)return;if(this.args.length>this.registeredArguments.length)this._excessArguments(this.args)}_processArguments(){let $=(Q,z,J)=>{let Y=z;if(z!==null&&Q.parseArg){let X=`error: command-argument value '${z}' is invalid for argument '${Q.name()}'.`;Y=this._callParseArg(Q,z,J,X)}return Y};this._checkNumberOfArguments();let q=[];this.registeredArguments.forEach((Q,z)=>{let J=Q.defaultValue;if(Q.variadic){if(z<this.args.length){if(J=this.args.slice(z),Q.parseArg)J=J.reduce((Y,X)=>{return $(Q,X,Y)},Q.defaultValue)}else if(J===void 0)J=[]}else if(z<this.args.length){if(J=this.args[z],Q.parseArg)J=$(Q,J,Q.defaultValue)}q[z]=J}),this.processedArgs=q}_chainOrCall($,q){if($&&$.then&&typeof $.then==="function")return $.then(()=>q());return q()}_chainOrCallHooks($,q){let Q=$,z=[];if(this._getCommandAndAncestors().reverse().filter((J)=>J._lifeCycleHooks[q]!==void 0).forEach((J)=>{J._lifeCycleHooks[q].forEach((Y)=>{z.push({hookedCommand:J,callback:Y})})}),q==="postAction")z.reverse();return z.forEach((J)=>{Q=this._chainOrCall(Q,()=>{return J.callback(J.hookedCommand,this)})}),Q}_chainOrCallSubCommandHook($,q,Q){let z=$;if(this._lifeCycleHooks[Q]!==void 0)this._lifeCycleHooks[Q].forEach((J)=>{z=this._chainOrCall(z,()=>{return J(this,q)})});return z}_parseCommand($,q){let Q=this.parseOptions(q);if(this._parseOptionsEnv(),this._parseOptionsImplied(),$=$.concat(Q.operands),q=Q.unknown,this.args=$.concat(q),$&&this._findCommand($[0]))return this._dispatchSubcommand($[0],$.slice(1),q);if(this._getHelpCommand()&&$[0]===this._getHelpCommand().name())return this._dispatchHelpCommand($[1]);if(this._defaultCommandName)return this._outputHelpIfRequested(q),this._dispatchSubcommand(this._defaultCommandName,$,q);if(this.commands.length&&this.args.length===0&&!this._actionHandler&&!this._defaultCommandName)this.help({error:!0});this._outputHelpIfRequested(Q.unknown),this._checkForMissingMandatoryOptions(),this._checkForConflictingOptions();let z=()=>{if(Q.unknown.length>0)this.unknownOption(Q.unknown[0])},J=`command:${this.name()}`;if(this._actionHandler){z(),this._processArguments();let Y;if(Y=this._chainOrCallHooks(Y,"preAction"),Y=this._chainOrCall(Y,()=>this._actionHandler(this.processedArgs)),this.parent)Y=this._chainOrCall(Y,()=>{this.parent.emit(J,$,q)});return Y=this._chainOrCallHooks(Y,"postAction"),Y}if(this.parent&&this.parent.listenerCount(J))z(),this._processArguments(),this.parent.emit(J,$,q);else if($.length){if(this._findCommand("*"))return this._dispatchSubcommand("*",$,q);if(this.listenerCount("command:*"))this.emit("command:*",$,q);else if(this.commands.length)this.unknownCommand();else z(),this._processArguments()}else if(this.commands.length)z(),this.help({error:!0});else z(),this._processArguments()}_findCommand($){if(!$)return;return this.commands.find((q)=>q._name===$||q._aliases.includes($))}_findOption($){return this.options.find((q)=>q.is($))}_checkForMissingMandatoryOptions(){this._getCommandAndAncestors().forEach(($)=>{$.options.forEach((q)=>{if(q.mandatory&&$.getOptionValue(q.attributeName())===void 0)$.missingMandatoryOptionValue(q)})})}_checkForConflictingLocalOptions(){let $=this.options.filter((Q)=>{let z=Q.attributeName();if(this.getOptionValue(z)===void 0)return!1;return this.getOptionValueSource(z)!=="default"});$.filter((Q)=>Q.conflictsWith.length>0).forEach((Q)=>{let z=$.find((J)=>Q.conflictsWith.includes(J.attributeName()));if(z)this._conflictingOption(Q,z)})}_checkForConflictingOptions(){this._getCommandAndAncestors().forEach(($)=>{$._checkForConflictingLocalOptions()})}parseOptions($){let q=[],Q=[],z=q,J=$.slice();function Y(M){return M.length>1&&M[0]==="-"}let X=null;while(J.length){let M=J.shift();if(M==="--"){if(z===Q)z.push(M);z.push(...J);break}if(X&&!Y(M)){this.emit(`option:${X.name()}`,M);continue}if(X=null,Y(M)){let Z=this._findOption(M);if(Z){if(Z.required){let _=J.shift();if(_===void 0)this.optionMissingArgument(Z);this.emit(`option:${Z.name()}`,_)}else if(Z.optional){let _=null;if(J.length>0&&!Y(J[0]))_=J.shift();this.emit(`option:${Z.name()}`,_)}else this.emit(`option:${Z.name()}`);X=Z.variadic?Z:null;continue}}if(M.length>2&&M[0]==="-"&&M[1]!=="-"){let Z=this._findOption(`-${M[1]}`);if(Z){if(Z.required||Z.optional&&this._combineFlagAndOptionalValue)this.emit(`option:${Z.name()}`,M.slice(2));else this.emit(`option:${Z.name()}`),J.unshift(`-${M.slice(2)}`);continue}}if(/^--[^=]+=/.test(M)){let Z=M.indexOf("="),_=this._findOption(M.slice(0,Z));if(_&&(_.required||_.optional)){this.emit(`option:${_.name()}`,M.slice(Z+1));continue}}if(Y(M))z=Q;if((this._enablePositionalOptions||this._passThroughOptions)&&q.length===0&&Q.length===0){if(this._findCommand(M)){if(q.push(M),J.length>0)Q.push(...J);break}else if(this._getHelpCommand()&&M===this._getHelpCommand().name()){if(q.push(M),J.length>0)q.push(...J);break}else if(this._defaultCommandName){if(Q.push(M),J.length>0)Q.push(...J);break}}if(this._passThroughOptions){if(z.push(M),J.length>0)z.push(...J);break}z.push(M)}return{operands:q,unknown:Q}}opts(){if(this._storeOptionsAsProperties){let $={},q=this.options.length;for(let Q=0;Q<q;Q++){let z=this.options[Q].attributeName();$[z]=z===this._versionOptionName?this._version:this[z]}return $}return this._optionValues}optsWithGlobals(){return this._getCommandAndAncestors().reduce(($,q)=>Object.assign($,q.opts()),{})}error($,q){if(this._outputConfiguration.outputError(`${$}
|
|
19
19
|
`,this._outputConfiguration.writeErr),typeof this._showHelpAfterError==="string")this._outputConfiguration.writeErr(`${this._showHelpAfterError}
|
|
20
20
|
`);else if(this._showHelpAfterError)this._outputConfiguration.writeErr(`
|
|
21
|
-
`),this.outputHelp({error:!0});let Q=q||{},z=Q.exitCode||1,J=Q.code||"commander.error";this._exit(z,J,$)}_parseOptionsEnv(){this.options.forEach(($)=>{if($.envVar&&$.envVar in H.env){let q=$.attributeName();if(this.getOptionValue(q)===void 0||["default","config","env"].includes(this.getOptionValueSource(q)))if($.required||$.optional)this.emit(`optionEnv:${$.name()}`,H.env[$.envVar]);else this.emit(`optionEnv:${$.name()}`)}})}_parseOptionsImplied(){let $=new
|
|
22
|
-
`),this._exit(0,"commander.version",$)}),this}description($,q){if($===void 0&&q===void 0)return this._description;if(this._description=$,q)this._argsDescription=q;return this}summary($){if($===void 0)return this._summary;return this._summary=$,this}alias($){if($===void 0)return this._aliases[0];let q=this;if(this.commands.length!==0&&this.commands[this.commands.length-1]._executableHandler)q=this.commands[this.commands.length-1];if($===q._name)throw Error("Command alias can't be the same as its name");let Q=this.parent?._findCommand($);if(Q){let z=[Q.name()].concat(Q.aliases()).join("|");throw Error(`cannot add alias '${$}' to command '${this.name()}' as already have command '${z}'`)}return q._aliases.push($),this}aliases($){if($===void 0)return this._aliases;return $.forEach((q)=>this.alias(q)),this}usage($){if($===void 0){if(this._usage)return this._usage;let q=this.registeredArguments.map((Q)=>{return
|
|
23
|
-
Expecting one of '${Q.join("', '")}'`);let z=`${$}Help`;return this.on(z,(J)=>{let
|
|
24
|
-
`)}),this}_outputHelpIfRequested($){let q=this._getHelpOption();if(q&&$.find((z)=>q.is(z)))this.outputHelp(),this._exit(0,"commander.helpDisplayed","(outputHelp)")}}function
|
|
25
|
-
`,{mode:384})}async function
|
|
21
|
+
`),this.outputHelp({error:!0});let Q=q||{},z=Q.exitCode||1,J=Q.code||"commander.error";this._exit(z,J,$)}_parseOptionsEnv(){this.options.forEach(($)=>{if($.envVar&&$.envVar in H.env){let q=$.attributeName();if(this.getOptionValue(q)===void 0||["default","config","env"].includes(this.getOptionValueSource(q)))if($.required||$.optional)this.emit(`optionEnv:${$.name()}`,H.env[$.envVar]);else this.emit(`optionEnv:${$.name()}`)}})}_parseOptionsImplied(){let $=new R1(this.options),q=(Q)=>{return this.getOptionValue(Q)!==void 0&&!["default","implied"].includes(this.getOptionValueSource(Q))};this.options.filter((Q)=>Q.implied!==void 0&&q(Q.attributeName())&&$.valueFromOption(this.getOptionValue(Q.attributeName()),Q)).forEach((Q)=>{Object.keys(Q.implied).filter((z)=>!q(z)).forEach((z)=>{this.setOptionValueWithSource(z,Q.implied[z],"implied")})})}missingArgument($){let q=`error: missing required argument '${$}'`;this.error(q,{code:"commander.missingArgument"})}optionMissingArgument($){let q=`error: option '${$.flags}' argument missing`;this.error(q,{code:"commander.optionMissingArgument"})}missingMandatoryOptionValue($){let q=`error: required option '${$.flags}' not specified`;this.error(q,{code:"commander.missingMandatoryOptionValue"})}_conflictingOption($,q){let Q=(Y)=>{let X=Y.attributeName(),M=this.getOptionValue(X),Z=this.options.find((U)=>U.negate&&X===U.attributeName()),_=this.options.find((U)=>!U.negate&&X===U.attributeName());if(Z&&(Z.presetArg===void 0&&M===!1||Z.presetArg!==void 0&&M===Z.presetArg))return Z;return _||Y},z=(Y)=>{let X=Q(Y),M=X.attributeName();if(this.getOptionValueSource(M)==="env")return`environment variable '${X.envVar}'`;return`option '${X.flags}'`},J=`error: ${z($)} cannot be used with ${z(q)}`;this.error(J,{code:"commander.conflictingOption"})}unknownOption($){if(this._allowUnknownOption)return;let q="";if($.startsWith("--")&&this._showSuggestionAfterError){let z=[],J=this;do{let Y=J.createHelp().visibleOptions(J).filter((X)=>X.long).map((X)=>X.long);z=z.concat(Y),J=J.parent}while(J&&!J._enablePositionalOptions);q=G0($,z)}let Q=`error: unknown option '${$}'${q}`;this.error(Q,{code:"commander.unknownOption"})}_excessArguments($){if(this._allowExcessArguments)return;let q=this.registeredArguments.length,Q=q===1?"":"s",J=`error: too many arguments${this.parent?` for '${this.name()}'`:""}. Expected ${q} argument${Q} but got ${$.length}.`;this.error(J,{code:"commander.excessArguments"})}unknownCommand(){let $=this.args[0],q="";if(this._showSuggestionAfterError){let z=[];this.createHelp().visibleCommands(this).forEach((J)=>{if(z.push(J.name()),J.alias())z.push(J.alias())}),q=G0($,z)}let Q=`error: unknown command '${$}'${q}`;this.error(Q,{code:"commander.unknownCommand"})}version($,q,Q){if($===void 0)return this._version;this._version=$,q=q||"-V, --version",Q=Q||"output the version number";let z=this.createOption(q,Q);return this._versionOptionName=z.attributeName(),this._registerOption(z),this.on("option:"+z.name(),()=>{this._outputConfiguration.writeOut(`${$}
|
|
22
|
+
`),this._exit(0,"commander.version",$)}),this}description($,q){if($===void 0&&q===void 0)return this._description;if(this._description=$,q)this._argsDescription=q;return this}summary($){if($===void 0)return this._summary;return this._summary=$,this}alias($){if($===void 0)return this._aliases[0];let q=this;if(this.commands.length!==0&&this.commands[this.commands.length-1]._executableHandler)q=this.commands[this.commands.length-1];if($===q._name)throw Error("Command alias can't be the same as its name");let Q=this.parent?._findCommand($);if(Q){let z=[Q.name()].concat(Q.aliases()).join("|");throw Error(`cannot add alias '${$}' to command '${this.name()}' as already have command '${z}'`)}return q._aliases.push($),this}aliases($){if($===void 0)return this._aliases;return $.forEach((q)=>this.alias(q)),this}usage($){if($===void 0){if(this._usage)return this._usage;let q=this.registeredArguments.map((Q)=>{return W1(Q)});return[].concat(this.options.length||this._helpOption!==null?"[options]":[],this.commands.length?"[command]":[],this.registeredArguments.length?q:[]).join(" ")}return this._usage=$,this}name($){if($===void 0)return this._name;return this._name=$,this}nameFromFilename($){return this._name=P.basename($,P.extname($)),this}executableDir($){if($===void 0)return this._executableDir;return this._executableDir=$,this}helpInformation($){let q=this.createHelp();if(q.helpWidth===void 0)q.helpWidth=$&&$.error?this._outputConfiguration.getErrHelpWidth():this._outputConfiguration.getOutHelpWidth();return q.formatHelp(this,q)}_getHelpContext($){$=$||{};let q={error:!!$.error},Q;if(q.error)Q=(z)=>this._outputConfiguration.writeErr(z);else Q=(z)=>this._outputConfiguration.writeOut(z);return q.write=$.write||Q,q.command=this,q}outputHelp($){let q;if(typeof $==="function")q=$,$=void 0;let Q=this._getHelpContext($);this._getCommandAndAncestors().reverse().forEach((J)=>J.emit("beforeAllHelp",Q)),this.emit("beforeHelp",Q);let z=this.helpInformation(Q);if(q){if(z=q(z),typeof z!=="string"&&!Buffer.isBuffer(z))throw Error("outputHelp callback must return a string or a Buffer")}if(Q.write(z),this._getHelpOption()?.long)this.emit(this._getHelpOption().long);this.emit("afterHelp",Q),this._getCommandAndAncestors().forEach((J)=>J.emit("afterAllHelp",Q))}helpOption($,q){if(typeof $==="boolean"){if($)this._helpOption=this._helpOption??void 0;else this._helpOption=null;return this}return $=$??"-h, --help",q=q??"display help for command",this._helpOption=this.createOption($,q),this}_getHelpOption(){if(this._helpOption===void 0)this.helpOption(void 0,void 0);return this._helpOption}addHelpOption($){return this._helpOption=$,this}help($){this.outputHelp($);let q=H.exitCode||0;if(q===0&&$&&typeof $!=="function"&&$.error)q=1;this._exit(q,"commander.help","(outputHelp)")}addHelpText($,q){let Q=["beforeAll","before","after","afterAll"];if(!Q.includes($))throw Error(`Unexpected value for position to addHelpText.
|
|
23
|
+
Expecting one of '${Q.join("', '")}'`);let z=`${$}Help`;return this.on(z,(J)=>{let Y;if(typeof q==="function")Y=q({error:J.error,command:J.command});else Y=q;if(Y)J.write(`${Y}
|
|
24
|
+
`)}),this}_outputHelpIfRequested($){let q=this._getHelpOption();if(q&&$.find((z)=>q.is(z)))this.outputHelp(),this._exit(0,"commander.helpDisplayed","(outputHelp)")}}function W0($){return $.map((q)=>{if(!q.startsWith("--inspect"))return q;let Q,z="127.0.0.1",J="9229",Y;if((Y=q.match(/^(--inspect(-brk)?)$/))!==null)Q=Y[1];else if((Y=q.match(/^(--inspect(-brk|-port)?)=([^:]+)$/))!==null)if(Q=Y[1],/^\d+$/.test(Y[3]))J=Y[3];else z=Y[3];else if((Y=q.match(/^(--inspect(-brk|-port)?)=([^:]+):(\d+)$/))!==null)Q=Y[1],z=Y[3],J=Y[4];if(Q&&J!=="0")return`${Q}=${z}:${parseInt(J)+1}`;return q})}L1.Command=n});var E0=D((I1)=>{var{Argument:R0}=C(),{Command:a}=H0(),{CommanderError:E1,InvalidArgumentError:L0}=k(),{Help:T1}=r(),{Option:y0}=s();I1.program=new a;I1.createCommand=($)=>new a($);I1.createOption=($,q)=>new y0($,q);I1.createArgument=($,q)=>new R0($,q);I1.Command=a;I1.Option=y0;I1.Argument=R0;I1.Help=T1;I1.CommanderError=E1;I1.InvalidArgumentError=L0;I1.InvalidOptionArgumentError=L0});import{spawnSync as h0}from"child_process";import{cpSync as c,existsSync as y,mkdirSync as f,readFileSync as u,rmSync as g}from"fs";import{mkdir as s1,readFile as i1,writeFile as p1}from"fs/promises";import{homedir as F}from"os";import{dirname as l,join as K}from"path";import{fileURLToPath as t1}from"url";var T0=d0(E0(),1),{program:U$,createCommand:B$,createArgument:K$,createOption:G$,CommanderError:W$,InvalidArgumentError:H$,InvalidOptionArgumentError:R$,Command:I0,Argument:L$,Option:y$,Help:E$}=T0.default;function o($){return $.map((q)=>Number(q.close??q.c)).filter(Number.isFinite)}function j0($,q){return $.map((Q,z)=>{if(z+1<q)return null;let J=$.slice(z+1-q,z+1);return w(J)})}function e($,q){let Q=2/(q+1),z=null;return $.map((J,Y)=>{return z=Y===0||z===null?J:J*Q+z*(1-Q),z})}function P0($,q=14){return $.map((Q,z)=>{if(z<q)return null;let J=$.slice(z+1-q,z+1).map((Z,_,U)=>_===0?0:Z-U[_-1]),Y=J.filter((Z)=>Z>0),X=J.filter((Z)=>Z<0).map(Math.abs);return 100-100/(1+w(Y)/(w(X)||0.000000001))})}function F0($){let q=e($,12),Q=e($,26),z=q.map((Y,X)=>Y-Q[X]),J=e(z,9);return z.map((Y,X)=>({macd:Y,signal:J[X],histogram:Y-J[X]}))}function N0($,q=0){let Q=$.slice(1).map((M,Z)=>M/$[Z]-1).filter(Number.isFinite),z=w(Q),J=k1(Q)*Math.sqrt(252),Y=z*252,X=J===0?null:(Y-q)/J;return{count:$.length,annualReturn:Y,volatility:J,sharpe:X,maxDrawdown:x1($)}}function w($){return $.length?$.reduce((q,Q)=>q+Q,0)/$.length:0}function k1($){let q=w($);return Math.sqrt(w($.map((Q)=>(Q-q)**2)))}function x1($){let q=$[0]??0,Q=0;for(let z of $)q=Math.max(q,z),Q=Math.min(Q,z/q-1);return Q}import{mkdir as C1,readFile as O1,rm as h1,writeFile as v1}from"fs/promises";import{dirname as u1,join as D0}from"path";var V0=process.env.HOME??process.cwd(),V=D0(V0,".config","mozyfin-cli","config.json"),O=D0(V0,".config","mozyfin-cli","version-cache.json"),x="https://api.mozyfin.com";async function $0(){try{return JSON.parse(await O1(V,"utf8"))}catch{return{}}}async function S0($){await C1(u1(V),{recursive:!0}),await v1(V,`${JSON.stringify($,null,2)}
|
|
25
|
+
`,{mode:384})}async function w0(){await h1(V,{force:!0})}async function A0($){let q=await $0();return $??process.env.MOZYFIN_API_KEY??q.apiKey}function h(){return"Missing API key. Run `mozyfin login --api-key <key>` or create one at https://research.mozyfin.com/settings"}var f0=0;async function g1($=Date.now()){let q=Math.max(0,1000-($-f0));if(q>0)await new Promise((Q)=>setTimeout(Q,q));f0=Date.now()}function c1($,q,Q={}){let z=new URL(q,$);for(let[J,Y]of Object.entries(Q)){if(Y===void 0||Y==="")continue;if(Array.isArray(Y))for(let X of Y)z.searchParams.append(J,X);else z.searchParams.set(J,String(Y))}return z}function l1($){let q=$?.data??$,Q=Array.isArray(q)?q:q?.items??q?.data??[];return Array.isArray(Q)&&Q.length>0}class v{baseUrl;apiKey;constructor($={}){this.baseUrl=$.baseUrl??x,this.apiKey=$.apiKey}static async fromConfig($){let q=await $0();return new v({baseUrl:q.baseUrl??x,apiKey:await A0($)})}async request($,q={}){if(q.auth!==!1&&!this.apiKey)throw Error(h());await g1();let Q=await fetch(c1(this.baseUrl,$,q.query),{method:q.method??"GET",headers:{"content-type":"application/json",...this.apiKey?{"X-API-Key":this.apiKey,authorization:`Bearer ${this.apiKey}`}:{}},body:q.body?JSON.stringify(q.body):void 0}),z=await Q.text(),J=z?JSON.parse(z):null;if(!Q.ok)throw Error(J?.message??J?.detail??`HTTP ${Q.status}`);return J}entities($){return this.request("/api/v1/market/exchange/entity",{query:$})}entity($){return this.request(`/api/v1/market/exchange/entity/${$}`)}news($){return this.request("/api/v1/news",{query:$})}marketIndices(){return this.request("/api/v1/market/market-index")}async ohlcv($,q){let Q=null,z=null;try{if(Q=await this.request(`/api/v1/market/exchange/entity/${$}/ohlcv`,{query:q}),l1(Q))return Q}catch(J){z=J}try{return await this.request(`/api/v1/market/market-index/${$}/ohlcv`,{query:q})}catch(J){if(Q)return Q;throw z??J}}historicalQuote($,q){return this.request(`/api/v1/market/exchange/entity/${$}/historical-quote`,{query:q})}offices($){return this.request(`/api/v1/market/exchange/entity/${$}/office`)}subsidiaries($){return this.request(`/api/v1/market/exchange/entity/${$}/subsidiary`)}holders($,q){return this.request(`/api/v1/market/exchange/entity/${$}/holder`,{query:q})}holderTransactions($,q){return this.request(`/api/v1/market/exchange/entity/${$}/holder-transaction`,{query:q})}financialStatements($,q){return this.request(`/api/v1/market/exchange/entity/${$}/financial-statement`,{query:q})}financialStatistics($,q){return this.request(`/api/v1/market/exchange/entity/${$}/financial-statistic`,{query:q})}usage(){return this.request("/api/v1/subscription/usage")}createChat(){return this.request("/api/v1/chat",{method:"POST",body:{title:"mozyfin-cli",mode:"auto"}})}sendMessage($,q){return this.request(`/api/v1/chat/${$}/message`,{method:"POST",body:{content:q}})}getMessage($){return this.request(`/api/v1/chat/messages/${$}`)}queryReport($){return this.request("/api/v1/document/query-report",{method:"POST",body:{query:$}})}}import{writeFile as m1}from"fs/promises";function q0($){return $?.data??$?.result??$}function j($){let q=q0($);if(Array.isArray(q))return q;if(Array.isArray(q?.items))return q.items;if(Array.isArray(q?.results))return q.results;if(Array.isArray(q?.data))return q.data;return q?[q]:[]}function S($){let q=j($);if(q.length===0)return"_No data_";return Q0(q,Object.keys(q[0]).slice(0,8))}function Q0($,q){let Q=j($);if(Q.length===0)return"_No data_";let z=q.filter((M)=>Q.some((Z)=>Z?.[M]!==void 0));if(z.length===0)return S($);let J=`| ${z.join(" | ")} |`,Y=`| ${z.map(()=>"---").join(" | ")} |`,X=Q.map((M)=>`| ${z.map((Z)=>x0(M?.[Z])).join(" | ")} |`).join(`
|
|
26
26
|
`);return`${J}
|
|
27
|
-
${
|
|
28
|
-
${X}`}function
|
|
29
|
-
`)}function
|
|
30
|
-
`)}function
|
|
27
|
+
${Y}
|
|
28
|
+
${X}`}function b0($,q){let[Q]=j($);if(!Q)return"_No data_";return(q?.filter((J)=>Q[J]!==void 0)??Object.keys(Q)).map((J)=>`- ${J}: ${x0(Q[J])}`).join(`
|
|
29
|
+
`)}function k0($,q="content"){let Q=j($)[0]??q0($);return Q?.[q]??Q?.message?.[q]??Q?.data?.[q]??"_No content_"}function x0($){if($===null||$===void 0)return"";if(typeof $==="object"){let q=$,Q=q.symbol??q.id??q.name??q.title;if(Q!==void 0)return String(Q).replaceAll("|","\\|");return JSON.stringify($).replaceAll("|","\\|").slice(0,120)}return String($).replaceAll("|","\\|")}function d1($){let q=j($);if(q.length===0)return"";let Q=Array.from(new Set(q.flatMap((z)=>Object.keys(z))));return[Q.join(","),...q.map((z)=>Q.map((J)=>r1(z[J])).join(","))].join(`
|
|
30
|
+
`)}function r1($){let q=$===null||$===void 0?"":typeof $==="object"?JSON.stringify($):String($);return/[",\n]/.test(q)?`"${q.replaceAll('"','""')}"`:q}function C0($){let q=q0($),Q=[],z=q?.entities??[];if(z.length>0)Q.push(`### Entities (${z.length})
|
|
31
31
|
|
|
32
32
|
${S(z)}`);let J=q?.relationships??[];if(J.length>0)Q.push(`
|
|
33
33
|
### Relationships (${J.length})
|
|
34
34
|
|
|
35
|
-
${S(J)}`);let
|
|
36
|
-
### Document Chunks (${
|
|
35
|
+
${S(J)}`);let Y=q?.chunks??[];if(Y.length>0)Q.push(`
|
|
36
|
+
### Document Chunks (${Y.length})
|
|
37
37
|
|
|
38
|
-
${S(
|
|
38
|
+
${S(Y)}`);let X=q?.references??[];if(X.length>0)Q.push(`
|
|
39
39
|
### References (${X.length})
|
|
40
40
|
|
|
41
41
|
${S(X)}`);if(q?.instructions)Q.push(`
|
|
42
42
|
### Context
|
|
43
43
|
|
|
44
44
|
${q.instructions}`);return Q.length>0?Q.join(`
|
|
45
|
-
`):"_No data_"}async function
|
|
46
|
-
`),console.log(S([{ok:!0,file:q.csv,rows:
|
|
45
|
+
`):"_No data_"}async function A($,q){if(q.csv){await m1(q.csv,`${d1($)}
|
|
46
|
+
`),console.log(S([{ok:!0,file:q.csv,rows:j($).length}]));return}console.log(S($))}var z0=l(t1(import.meta.url)),v0=JSON.parse(u(K(z0,"..","package.json"),"utf8")),B=new I0;B.name("mozyfin").description("Vietnam stock market CLI for humans and AI agents").version(v0.version).showHelpAfterError().addHelpText("after",`
|
|
47
47
|
|
|
48
48
|
Examples:
|
|
49
49
|
$ mozyfin login --api-key <key>
|
|
@@ -53,23 +53,24 @@ Examples:
|
|
|
53
53
|
$ mozyfin ta VNM.VN --sma 20,50 --rsi 14 --macd --csv vnm-ta.csv
|
|
54
54
|
$ mozyfin doc "VNM Q4 2024 earnings analysis"
|
|
55
55
|
$ mozyfin ask "compare VNM and MSN margin trend"
|
|
56
|
-
`).option("--api-key <key>","API key, or set MOZYFIN_API_KEY").option("--base-url <url>","API base URL",
|
|
56
|
+
`).option("--api-key <key>","API key, or set MOZYFIN_API_KEY").option("--base-url <url>","API base URL",x).option("--no-color","reserved for scripts/agents; output stays plain text");function E($){return $.option("-m, --md","print Markdown table (default)").option("--csv <file>","write rows to CSV file")}async function R(){let $=B.opts(),q=await v.fromConfig($.apiKey);if(q.baseUrl=$.baseUrl,!q.apiKey)throw Error(h());return q}function O0($){if(!$)return;let q=$.split(",").map((Q)=>Q.trim()).filter(Boolean);return q.length?q:void 0}function u0($,q,Q){if(!q.includes($))throw Error(`${Q} must be one of: ${q.join(", ")}`);return $}async function I($,q,Q){if(q.csv)return A($,q);console.log(Q0($,Q))}async function J0($,q,Q){if(q.csv)return A($,q);console.log(b0($,Q))}function n1($){return j($).map((q)=>{let Q=q.values??{};return{year:q.year,quarter:q.quarter,type:q.type,net_sales:Q["Net sales"]??Q.Sales,gross_profit:Q["Gross Profit"],profit_after_tax:Q["Net profit/(loss) after tax"],total_assets:Q["Total Assets"],owner_equity:Q["Owner's Equity"],net_operating_cash_flow:Q["Net cash inflows/(outflows) from operating activities"],public_at:q.public_at}})}B.command("login").description("Save API key locally").option("--api-key <key>").action(async($)=>{let q=$.apiKey??B.opts().apiKey;if(!q)throw Error("Missing --api-key <key>");await S0({apiKey:q,baseUrl:B.opts().baseUrl}),await A([{ok:!0,configPath:V}],{})});B.command("logout").description("Remove saved API key").action(async()=>{await w0(),await A([{ok:!0}],{})});E(B.command("search").description("Search companies/entities by ticker, name or text")).option("-q, --query [text]","search query; empty means all","").action(async($)=>I(await(await R()).entities({search:$.query}),$,["symbol","ticker","name","exchange","market","price","market_cap","id"]));E(B.command("profile").argument("<tickerOrEntityId>").description("Company profile/entity details")).action(async($,q)=>J0(await(await R()).entity($),q,["symbol","ticker","name","exchange","market","sector","industry","website","description","entity_id","id"]));E(B.command("news").description("Market headlines and article search")).option("--query <text>","search query; empty means all","").option("--entities <ids>","comma-separated entity ids; OR semantics").option("--topics <topics>","comma-separated topics: stock,crypto,forex,tariff,economic,earning,tech,housing,mergers_and_ipo; OR semantics").option("--limit <n>","max rows","20").option("--page <n>","page hint for APIs that support it","1").action(async($)=>I(await(await R()).news(a1($)),$,["published_at","created_at","title","source","topics","entities","url","id"]));function a1($){let q=["stock","crypto","forex","tariff","economic","earning","tech","housing","mergers_and_ipo"],Q=O0($.topics);for(let z of Q??[])u0(z,q,"topic");return{search:$.query,entities:O0($.entities),topics:Q,limit:$.limit,page:$.page}}E(B.command("indices").description("List supported market indices (use the returned id with `ohlcv`)")).action(async($)=>I(await(await R()).marketIndices(),$,["symbol","name","current_value","change_value","change_percent","id"]));E(B.command("ohlcv").argument("<entity>").description("Historical OHLCV candles")).option("--timeframe <value>","1h, 1d, 1w, 1mo, 1y","1d").option("--to <timestamp>","end timestamp").option("--limit <n>","max rows").action(async($,q)=>{return u0(q.timeframe,["1h","1d","1w","1mo","1y"],"timeframe"),I(await(await R()).ohlcv($,q),q,["timestamp","time","date","open","high","low","close","volume"])});E(B.command("quote").argument("<entity>").description("Latest daily quote snapshot")).option("--to <timestamp>","end timestamp").option("--limit <n>","max rows","1").action(async($,q)=>I(await(await R()).historicalQuote($,{to:q.to,limit:q.limit}),q,["timestamp","total_volume","deal_volume","total_value","buy_foreign_quantity","sell_foreign_quantity","current_foreign_room"]));E(B.command("officers").argument("<entity>").description("Company officers/directors")).action(async($,q)=>I(await(await R()).offices($),q,["name","position","is_foreigner","sort_order"]));E(B.command("subsidiary").argument("<entity>").description("Company subsidiaries")).action(async($,q)=>I(await(await R()).subsidiaries($),q,["name","symbol","ownership_rate","charter_capital","business_area","id"]));E(B.command("holder").argument("<entity>").description("Major shareholders")).option("--is-organization <true|false>","filter organization holders").option("--is-foreigner <true|false>","filter foreign holders").action(async($,q)=>I(await(await R()).holders($,{is_organization:q.isOrganization,is_foreigner:q.isForeigner}),q,["name","holder_name","ownership_rate","shares","is_organization","is_foreigner"]));E(B.command("holder-tx").argument("<entity>").description("Shareholder transactions")).option("--cursor <cursor>","pagination cursor").option("--limit <n>","max rows","100").option("--transaction-type <type>","transaction type filter").action(async($,q)=>I(await(await R()).holderTransactions($,{cursor:q.cursor,limit:q.limit,transaction_type:q.transactionType}),q,["name","type","registered_volume","execution_volume","start_at","end_at","position"]));E(B.command("financials").argument("<entity>").description("Financial statements")).option("--year <year>","report year").option("--quarter <quarter>","report quarter").option("--statement-type <type>","statement type filter").action(async($,q)=>I(n1(await(await R()).financialStatements($,{year:q.year,quarter:q.quarter,statement_type:q.statementType})),q,["year","quarter","type","net_sales","gross_profit","profit_after_tax","total_assets","owner_equity","net_operating_cash_flow"]));E(B.command("stats").argument("<entity>").description("Financial statistics/ratios")).option("--year <year>","report year").option("--quarter <quarter>","report quarter").action(async($,q)=>I(await(await R()).financialStatistics($,{year:q.year,quarter:q.quarter}),q,["year","quarter","pe","pb","roe","roa","gross_margin","market_cap"]));E(B.command("ta").argument("<tickerOrEntityId>").description("Technical indicators over OHLCV close prices")).option("--sma <list>","comma-separated SMA periods","20").option("--rsi <n>","RSI period").option("--macd","include MACD").option("--limit <n>","max candles","300").action(async($,q)=>{let Q=await(await R()).ohlcv($,{timeframe:"1d",limit:q.limit}),J=[...j(Q)].reverse(),Y=o(J),X=String(q.sma).split(",").map(Number).filter(Number.isFinite),M=Object.fromEntries(X.map((W)=>[W,j0(Y,W)])),Z=q.rsi?P0(Y,Number(q.rsi)):[],_=q.macd?F0(Y):[],U=J.map((W,L)=>({...W,...Object.fromEntries(X.map((G)=>[`sma_${G}`,M[G][L]])),...q.rsi?{[`rsi_${q.rsi}`]:Z[L]}:{},...q.macd?_[L]:{}})).reverse();await I(U,q,["timestamp","time","date","close",...X.map((W)=>`sma_${W}`),...q.rsi?[`rsi_${q.rsi}`]:[],...q.macd?["macd","signal","histogram"]:[]])});B.command("risk").argument("<tickerOrEntityId>").description("Risk/performance metrics: return, volatility, Sharpe, max drawdown").option("--limit <n>","max candles","252").option("--risk-free <n>","annual risk-free rate","0").action(async($,q)=>{let Q=await(await R()).ohlcv($,{timeframe:"1d",limit:q.limit});await J0([N0(o([...j(Q)].reverse()),Number(q.riskFree))],{},["count","annualReturn","volatility","sharpe","maxDrawdown"])});B.command("doc").argument("<query...>").description("Query analysis reports using natural language").action(async($)=>{let q=await(await R()).queryReport($.join(" "));console.log(C0(q))});B.command("ask").argument("<prompt...>").description("Ask Mozyfin agent in auto mode (one focused question per call \u2014 avoid multi-question prompts)").option("--timeout <seconds>","max wait time in seconds (default 300 = 5 minutes)","300").action(async($,q)=>{let Q=await R(),z=await Q.createChat(),J=z?.data?.id??z?.id;if(!J)throw Error("Could not create chat");let X=await Q.sendMessage(J,$.join(" ")),M=X?.data?.id??X?.id,Z=Date.now()+Number(q.timeout)*1000;while(M&&Date.now()<Z){let _=X?.data?.status??X?.status;if(_&&_!=="thinking"&&_!=="streaming")break;await new Promise((U)=>setTimeout(U,2000)),X=await Q.getMessage(M)}console.log(k0(X))});B.command("credits").description("Check subscription usage/credits").action(async()=>J0(await(await R()).usage(),{},["credits_used","credits_cap","remaining","plan"]));B.command("doctor").description("Check runtime, config and API health").action(async()=>{let $=h0("bun",["--version"],{encoding:"utf8"}).stdout.trim(),q=await R(),Q=await q.request("/health",{auth:!1});await A([{bun:$,configPath:V,baseUrl:q.baseUrl,health:Q}],{})});B.command("update").description("Upgrade CLI to latest version; auto-updates skills for any agents that already have it installed").option("--skill [agent]","Force update skill for specific agent (claude, cursor, copilot, windsurf, codex, gemini, hermes, openclaw, or 'all')").action(async($)=>{let q=B.version(),Q=await fetch("https://registry.npmjs.org/mozyfin-cli/latest").then((X)=>X.json()).then((X)=>X.version).catch(()=>null);if(console.log(`Current version: ${q}`),Q)if(console.log(`Latest version: ${Q}`),q===Q)console.log(`
|
|
57
57
|
You're already on the latest version!`);else if(console.log(`
|
|
58
|
-
Updating CLI...`),
|
|
58
|
+
Updating CLI...`),h0("npm",["install","-g","mozyfin-cli@latest"],{encoding:"utf8",stdio:"inherit"}).status===0)console.log(`
|
|
59
59
|
\u2713 CLI updated successfully!`);else console.log(`
|
|
60
|
-
\u2717 CLI update failed. Try running manually:`),console.log(" npm install -g mozyfin-cli@latest");let z=K(
|
|
60
|
+
\u2717 CLI update failed. Try running manually:`),console.log(" npm install -g mozyfin-cli@latest");let z=K(z0,"..","agent-skills","mozyfin-cli"),J="mozyfin-cli",Y=[];if($.skill){let X=$.skill===!0?"all":$.skill;Y=X==="all"?Object.keys(b):[X]}else for(let[X,M]of Object.entries(b)){let Z=!1;if(M.format==="directory")Z=y(K(M.path,J,"SKILL.md"));else if(M.format==="file")Z=y(K(M.path,`${J}.md`));else if(M.format==="append"){if(y(M.path))Z=u(M.path,"utf8").includes(`<!-- ${J} -->`)}if(Z)Y.push(X)}if(Y.length===0)return;if(!y(z)){console.log(`
|
|
61
61
|
\u2717 Skill source not found in package`);return}console.log(`
|
|
62
|
-
Updating skills for: ${
|
|
62
|
+
Updating skills for: ${Y.join(", ")}`);for(let X of Y){let M=b[X];if(!M){console.log(`\u2717 Unknown agent: ${X}`);continue}let{path:Z,format:_}=M;try{if(_==="append"){f(l(Z),{recursive:!0});let U=u(K(z,"SKILL.md"),"utf8"),G=`${(y(Z)?u(Z,"utf8"):"").replace(new RegExp(`<!-- ${J} -->[\\s\\S]*<!-- /${J} -->`,"g"),"").trim()}
|
|
63
63
|
|
|
64
64
|
<!-- ${J} -->
|
|
65
65
|
${U}
|
|
66
66
|
<!-- /${J} -->
|
|
67
|
-
`;
|
|
68
|
-
`);for(let[
|
|
67
|
+
`;T("fs").writeFileSync(Z,G),console.log(`\u2713 Updated skill for ${X}`)}else if(_==="file"){f(Z,{recursive:!0});let U=K(Z,`${J}.md`);c(K(z,"SKILL.md"),U),console.log(`\u2713 Updated skill for ${X}`)}else if(_==="directory"){let U=K(Z,J);g(U,{recursive:!0,force:!0}),f(Z,{recursive:!0}),c(z,U,{recursive:!0}),console.log(`\u2713 Updated skill for ${X}`)}}catch(U){console.log(`\u2717 Failed to update skill for ${X}: ${U}`)}}});var b={claude:{path:K(F(),".claude","skills"),format:"directory"},cursor:{path:K(F(),".cursor","commands"),format:"file"},copilot:{path:K(F(),".github","copilot-instructions.md"),format:"append"},windsurf:{path:K(F(),".windsurf","workflows"),format:"file"},codex:{path:K(F(),".agents","skills"),format:"directory"},gemini:{path:K(F(),".gemini","instructions"),format:"file"},hermes:{path:K(F(),".hermes","skills"),format:"directory"},openclaw:{path:K(F(),".openclaw","skills"),format:"directory"},antigravity:{path:K(F(),".gemini","antigravity","skills"),format:"directory"}};B.command("skill").description("Install mozyfin-cli skill into AI agents (claude, cursor, copilot, windsurf, codex, gemini, hermes, openclaw, antigravity)").argument("[agent]","Target agent (claude, cursor, copilot, windsurf, codex, gemini, hermes, openclaw, antigravity) or 'all'").option("--list","List available agents").option("--remove","Remove skill from agent").action(($,q)=>{let Q=K(z0,"..","agent-skills","mozyfin-cli"),z="mozyfin-cli";if(q.list){console.log(`Available agents:
|
|
68
|
+
`);for(let[Y,X]of Object.entries(b)){let M=!1;if(X.format==="directory")M=y(K(X.path,"mozyfin-cli","SKILL.md"));else if(X.format==="file")M=y(K(X.path,"mozyfin-cli.md"));else if(X.format==="append"){if(y(X.path))M=T("fs").readFileSync(X.path,"utf8").includes("<!-- mozyfin-cli -->")}console.log(` ${Y.padEnd(10)} ${M?"\u2713 installed":"\u25CB not installed"}`),console.log(` ${X.path}`)}return}if(!$){console.log("Usage: mozyfin skill <agent>"),console.log(`
|
|
69
69
|
Available agents: claude, cursor, copilot, windsurf, codex, gemini, hermes, openclaw, all`),console.log(`
|
|
70
|
-
Options:`),console.log(" --list List available agents"),console.log(" --remove Remove skill from agent");return}let J=$==="all"?Object.keys(b):[$];for(let
|
|
70
|
+
Options:`),console.log(" --list List available agents"),console.log(" --remove Remove skill from agent");return}let J=$==="all"?Object.keys(b):[$];for(let Y of J){let X=b[Y];if(!X){console.log(`Unknown agent: ${Y}`),console.log("Available: claude, cursor, copilot, windsurf, codex, gemini, hermes, openclaw");continue}let{path:M,format:Z}=X;if(q.remove){if(Z==="append")if(y(M)){let U=T("fs").readFileSync(M,"utf8").replace(new RegExp("<!-- mozyfin-cli -->[\\s\\S]*<!-- /mozyfin-cli -->","g"),"").trim();T("fs").writeFileSync(M,U),console.log(`\u2713 Removed skill from ${Y}`)}else console.log(`Skill not installed in ${Y}`);else if(Z==="file"){let _=K(M,"mozyfin-cli.md");if(y(_))g(_),console.log(`\u2713 Removed skill from ${Y}`);else console.log(`Skill not installed in ${Y}`)}else if(Z==="directory"){let _=K(M,"mozyfin-cli");if(y(_))g(_,{recursive:!0,force:!0}),console.log(`\u2713 Removed skill from ${Y}`);else console.log(`Skill not installed in ${Y}`)}continue}if(!y(Q)){console.log(`Skill directory not found: ${Q}`);continue}if(Z==="append"){f(l(M),{recursive:!0});let _=T("fs").readFileSync(K(Q,"SKILL.md"),"utf8"),L=`${(y(M)?T("fs").readFileSync(M,"utf8"):"").replace(new RegExp("<!-- mozyfin-cli -->[\\s\\S]*<!-- /mozyfin-cli -->","g"),"").trim()}
|
|
71
71
|
|
|
72
72
|
<!-- mozyfin-cli -->
|
|
73
73
|
${_}
|
|
74
74
|
<!-- /mozyfin-cli -->
|
|
75
|
-
`;
|
|
75
|
+
`;T("fs").writeFileSync(M,L),console.log(`\u2713 Installed skill to ${Y}`)}else if(Z==="file"){f(M,{recursive:!0});let _=K(M,"mozyfin-cli.md");c(K(Q,"SKILL.md"),_),console.log(`\u2713 Installed skill to ${Y}`)}else if(Z==="directory"){let _=K(M,"mozyfin-cli");g(_,{recursive:!0,force:!0}),f(M,{recursive:!0}),c(Q,_,{recursive:!0}),console.log(`\u2713 Installed skill to ${Y}`)}}});var e1=86400000;async function o1(){try{let $=new AbortController,q=setTimeout(()=>$.abort(),1000),Q=await fetch("https://registry.npmjs.org/mozyfin-cli/latest",{signal:$.signal});clearTimeout(q);let z=await Q.json();if(!z.version)return null;return await s1(l(O),{recursive:!0}),await p1(O,JSON.stringify({latestVersion:z.version,checkedAt:Date.now()})),z.version}catch{return null}}async function $$(){try{let $=JSON.parse(await i1(O,"utf8"));if($?.latestVersion&&Date.now()-($.checkedAt??0)<e1)return $.latestVersion}catch{}return o1()}async function q$(){if(process.env.MOZYFIN_DISABLE_UPDATE_CHECK)return;if(process.argv.slice(2).find((z)=>!z.startsWith("-"))==="update")return;let q=await $$(),Q=v0.version;if(q&&q!==Q)console.error(`
|
|
76
|
+
\u26A0\uFE0F mozyfin-cli v${Q} is outdated (latest: v${q}). Run \`mozyfin update\` to upgrade.`)}B.parseAsync().catch(($)=>{console.error(`Error: ${$.message}`),process.exitCode=1}).finally(()=>q$());
|