@quantbrasil/cli 0.1.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +272 -0
- package/bin/quantbrasil.js +4 -0
- package/dist/cli/auth.d.ts +20 -0
- package/dist/cli/auth.d.ts.map +1 -0
- package/dist/cli/auth.js +76 -0
- package/dist/cli/client.d.ts +17 -0
- package/dist/cli/client.d.ts.map +1 -0
- package/dist/cli/client.js +112 -0
- package/dist/cli/config.d.ts +33 -0
- package/dist/cli/config.d.ts.map +1 -0
- package/dist/cli/config.js +148 -0
- package/dist/cli/errors.d.ts +40 -0
- package/dist/cli/errors.d.ts.map +1 -0
- package/dist/cli/errors.js +122 -0
- package/dist/cli/index.d.ts +30 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +112 -0
- package/dist/cli/prompt.d.ts +2 -0
- package/dist/cli/prompt.d.ts.map +1 -0
- package/dist/cli/prompt.js +40 -0
- package/dist/cli/skills.d.ts +26 -0
- package/dist/cli/skills.d.ts.map +1 -0
- package/dist/cli/skills.js +94 -0
- package/dist/cli/terminal.d.ts +18 -0
- package/dist/cli/terminal.d.ts.map +1 -0
- package/dist/cli/terminal.js +43 -0
- package/dist/commands/analytics.d.ts +131 -0
- package/dist/commands/analytics.d.ts.map +1 -0
- package/dist/commands/analytics.js +291 -0
- package/dist/commands/assets.d.ts +69 -0
- package/dist/commands/assets.d.ts.map +1 -0
- package/dist/commands/assets.js +350 -0
- package/dist/commands/auth.d.ts +17 -0
- package/dist/commands/auth.d.ts.map +1 -0
- package/dist/commands/auth.js +48 -0
- package/dist/commands/capabilities.d.ts +25 -0
- package/dist/commands/capabilities.d.ts.map +1 -0
- package/dist/commands/capabilities.js +61 -0
- package/dist/commands/init.d.ts +17 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +89 -0
- package/dist/commands/market.d.ts +45 -0
- package/dist/commands/market.d.ts.map +1 -0
- package/dist/commands/market.js +162 -0
- package/dist/commands/portfolios.d.ts +60 -0
- package/dist/commands/portfolios.d.ts.map +1 -0
- package/dist/commands/portfolios.js +298 -0
- package/dist/commands/skills.d.ts +17 -0
- package/dist/commands/skills.d.ts.map +1 -0
- package/dist/commands/skills.js +38 -0
- package/dist/commands/status.d.ts +15 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +52 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/vendor/core/capabilities/analytics.d.ts +187 -0
- package/dist/vendor/core/capabilities/analytics.d.ts.map +1 -0
- package/dist/vendor/core/capabilities/analytics.js +214 -0
- package/dist/vendor/core/capabilities/assets.d.ts +48 -0
- package/dist/vendor/core/capabilities/assets.d.ts.map +1 -0
- package/dist/vendor/core/capabilities/assets.js +66 -0
- package/dist/vendor/core/capabilities/index.d.ts +8 -0
- package/dist/vendor/core/capabilities/index.d.ts.map +1 -0
- package/dist/vendor/core/capabilities/index.js +7 -0
- package/dist/vendor/core/capabilities/market.d.ts +90 -0
- package/dist/vendor/core/capabilities/market.d.ts.map +1 -0
- package/dist/vendor/core/capabilities/market.js +114 -0
- package/dist/vendor/core/capabilities/portfolios.d.ts +224 -0
- package/dist/vendor/core/capabilities/portfolios.d.ts.map +1 -0
- package/dist/vendor/core/capabilities/portfolios.js +244 -0
- package/dist/vendor/core/capabilities/registry.d.ts +1083 -0
- package/dist/vendor/core/capabilities/registry.d.ts.map +1 -0
- package/dist/vendor/core/capabilities/registry.js +14 -0
- package/dist/vendor/core/capabilities/shared.d.ts +3 -0
- package/dist/vendor/core/capabilities/shared.d.ts.map +1 -0
- package/dist/vendor/core/capabilities/shared.js +2 -0
- package/dist/vendor/core/capabilities/types.d.ts +75 -0
- package/dist/vendor/core/capabilities/types.d.ts.map +1 -0
- package/dist/vendor/core/capabilities/types.js +1 -0
- package/dist/vendor/core/errors.d.ts +22 -0
- package/dist/vendor/core/errors.d.ts.map +1 -0
- package/dist/vendor/core/errors.js +42 -0
- package/dist/vendor/core/http/client.d.ts +45 -0
- package/dist/vendor/core/http/client.d.ts.map +1 -0
- package/dist/vendor/core/http/client.js +170 -0
- package/dist/vendor/core/http/index.d.ts +2 -0
- package/dist/vendor/core/http/index.d.ts.map +1 -0
- package/dist/vendor/core/http/index.js +1 -0
- package/dist/vendor/core/index.d.ts +5 -0
- package/dist/vendor/core/index.d.ts.map +1 -0
- package/dist/vendor/core/index.js +4 -0
- package/dist/vendor/core/invoke.d.ts +17 -0
- package/dist/vendor/core/invoke.d.ts.map +1 -0
- package/dist/vendor/core/invoke.js +70 -0
- package/package.json +57 -0
- package/skills/quantbrasil/SKILL.md +29 -0
- package/skills/quantbrasil/references/cli.md +77 -0
- package/skills/quantbrasil/references/costs.md +30 -0
- package/skills/quantbrasil/references/errors.md +128 -0
- package/skills/quantbrasil/references/unsupported.md +20 -0
- package/skills/quantbrasil/references/workflows.md +99 -0
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
import { assetOverviewSections } from "../vendor/core/capabilities/index.js";
|
|
2
|
+
import { invokeCliCapability } from "../cli/client.js";
|
|
3
|
+
import { createCliValidationError } from "../cli/errors.js";
|
|
4
|
+
import { createTerminalTheme } from "../cli/terminal.js";
|
|
5
|
+
export function registerAssetsCommands(program, context = {}) {
|
|
6
|
+
const assetsCommand = program
|
|
7
|
+
.command("assets")
|
|
8
|
+
.description("Read asset analysis operations");
|
|
9
|
+
assetsCommand
|
|
10
|
+
.command("overview")
|
|
11
|
+
.description("Get a section-based overview for one asset")
|
|
12
|
+
.argument("<ticker>", "Ticker symbol, for example PETR4")
|
|
13
|
+
.requiredOption("--sections <sections>", `Comma-separated section list. Valid sections: ${assetOverviewSections.join(", ")}`)
|
|
14
|
+
.option("--json", "Show JSON output")
|
|
15
|
+
.action(async (ticker, options) => {
|
|
16
|
+
await runAssetOverviewCommand(ticker, options, context);
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
export async function runAssetOverviewCommand(ticker, options, context = {}) {
|
|
20
|
+
const stdout = context.io?.stdout ?? process.stdout;
|
|
21
|
+
const theme = createTerminalTheme(stdout, context.env ?? process.env);
|
|
22
|
+
const sections = parseAssetOverviewSections(options.sections);
|
|
23
|
+
const response = await invokeCliCapability({
|
|
24
|
+
capability: "assets.overview",
|
|
25
|
+
input: {
|
|
26
|
+
ticker,
|
|
27
|
+
sections,
|
|
28
|
+
},
|
|
29
|
+
env: context.env,
|
|
30
|
+
fetch: context.fetch,
|
|
31
|
+
});
|
|
32
|
+
if (options.json) {
|
|
33
|
+
stdout.write(`${JSON.stringify(response.data, null, 2)}\n`);
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
const data = response.data;
|
|
37
|
+
stdout.write(`${formatAssetOverviewHuman(data, sections, theme)}\n`);
|
|
38
|
+
}
|
|
39
|
+
export function parseAssetOverviewSections(rawSections) {
|
|
40
|
+
const sections = rawSections
|
|
41
|
+
.split(",")
|
|
42
|
+
.map(section => section.trim())
|
|
43
|
+
.filter(Boolean);
|
|
44
|
+
if (sections.length === 0) {
|
|
45
|
+
throw createCliValidationError(`Missing sections. Use one or more of: ${assetOverviewSections.join(", ")}.`);
|
|
46
|
+
}
|
|
47
|
+
const uniqueSections = Array.from(new Set(sections));
|
|
48
|
+
for (const section of uniqueSections) {
|
|
49
|
+
if (!assetOverviewSections.includes(section)) {
|
|
50
|
+
throw createCliValidationError(`Invalid section "${section}". Use only: ${assetOverviewSections.join(", ")}.`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return uniqueSections;
|
|
54
|
+
}
|
|
55
|
+
export function formatAssetOverviewHuman(data, sections, theme = createTerminalTheme(process.stdout)) {
|
|
56
|
+
const lines = [theme.label("Asset overview"), ""];
|
|
57
|
+
const identity = data.asset?.symbol
|
|
58
|
+
? data.asset.name?.trim()
|
|
59
|
+
? `${theme.bold(data.asset.symbol)} ${theme.dim(`· ${data.asset.name}`)}`
|
|
60
|
+
: theme.bold(data.asset.symbol)
|
|
61
|
+
: theme.bold("Unknown asset");
|
|
62
|
+
lines.push(identity);
|
|
63
|
+
if (data.asset?.type) {
|
|
64
|
+
lines.push(`${theme.label("Type:")} ${data.asset.type}`);
|
|
65
|
+
}
|
|
66
|
+
if (data.as_of?.price_date) {
|
|
67
|
+
lines.push(`${theme.label("Price date:")} ${data.as_of.price_date}`);
|
|
68
|
+
}
|
|
69
|
+
if (data.as_of?.last_updated) {
|
|
70
|
+
lines.push(`${theme.label("Last updated:")} ${data.as_of.last_updated}`);
|
|
71
|
+
}
|
|
72
|
+
for (const section of sections) {
|
|
73
|
+
const sectionLines = formatAssetOverviewSection(data, section, theme);
|
|
74
|
+
if (sectionLines.length === 0) {
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
lines.push("");
|
|
78
|
+
lines.push(theme.label(sectionTitle(section)));
|
|
79
|
+
lines.push(...sectionLines);
|
|
80
|
+
}
|
|
81
|
+
return lines.join("\n");
|
|
82
|
+
}
|
|
83
|
+
function formatAssetOverviewSection(data, section, theme) {
|
|
84
|
+
switch (section) {
|
|
85
|
+
case "price":
|
|
86
|
+
return formatAssetOverviewPrice(data.price, theme);
|
|
87
|
+
case "performance":
|
|
88
|
+
return formatAssetOverviewValueItems(data.performance);
|
|
89
|
+
case "momentum":
|
|
90
|
+
return formatAssetOverviewMomentumItems(data.momentum);
|
|
91
|
+
case "rankings":
|
|
92
|
+
return formatAssetOverviewRankingItems(data.rankings);
|
|
93
|
+
case "technicals":
|
|
94
|
+
return formatStructuredBlock(data.technicals);
|
|
95
|
+
case "risk":
|
|
96
|
+
return formatStructuredBlock(data.risk);
|
|
97
|
+
case "fundamentals":
|
|
98
|
+
return formatStructuredBlock(data.fundamentals);
|
|
99
|
+
default:
|
|
100
|
+
return [];
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
function formatAssetOverviewPrice(price, theme) {
|
|
104
|
+
if (!price) {
|
|
105
|
+
return [" No data available."];
|
|
106
|
+
}
|
|
107
|
+
const lines = [
|
|
108
|
+
` Close: ${formatNumber(price.close)}`,
|
|
109
|
+
` Open: ${formatNumber(price.open)}`,
|
|
110
|
+
` High: ${formatNumber(price.high)}`,
|
|
111
|
+
` Low: ${formatNumber(price.low)}`,
|
|
112
|
+
];
|
|
113
|
+
if (price.volume !== null) {
|
|
114
|
+
lines.push(` Volume: ${formatNumber(price.volume)}`);
|
|
115
|
+
}
|
|
116
|
+
if (price.prev_close !== null && price.prev_close !== undefined) {
|
|
117
|
+
lines.push(` Previous close: ${formatNumber(price.prev_close)}`);
|
|
118
|
+
}
|
|
119
|
+
if (price.change_pct !== null && price.change_pct !== undefined) {
|
|
120
|
+
lines.push(` Change: ${formatChangePct(price.change_pct, theme)}`);
|
|
121
|
+
}
|
|
122
|
+
return lines;
|
|
123
|
+
}
|
|
124
|
+
function formatAssetOverviewValueItems(items) {
|
|
125
|
+
if (!items || items.length === 0) {
|
|
126
|
+
return [" No data available."];
|
|
127
|
+
}
|
|
128
|
+
return items.map(item => {
|
|
129
|
+
const value = item.value === null || item.value === undefined
|
|
130
|
+
? "n/a"
|
|
131
|
+
: formatNumber(item.value);
|
|
132
|
+
return ` ${resolvePerformanceLabel(item)}: ${value}`;
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
function formatAssetOverviewMomentumItems(items) {
|
|
136
|
+
if (!items || items.length === 0) {
|
|
137
|
+
return [" No data available."];
|
|
138
|
+
}
|
|
139
|
+
return items.map(item => {
|
|
140
|
+
const parts = [`momentum=${formatNullableNumber(item.momentum)}`];
|
|
141
|
+
if (item.r_squared !== null && item.r_squared !== undefined) {
|
|
142
|
+
parts.push(`r²=${formatNumber(item.r_squared)}`);
|
|
143
|
+
}
|
|
144
|
+
parts.push(`regression=${item.regression_type}`);
|
|
145
|
+
return ` ${item.label}: ${parts.join(", ")}`;
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
function formatAssetOverviewRankingItems(items) {
|
|
149
|
+
if (!items || items.length === 0) {
|
|
150
|
+
return [" No data available."];
|
|
151
|
+
}
|
|
152
|
+
return items.map(item => {
|
|
153
|
+
if (item.position !== null && item.position !== undefined) {
|
|
154
|
+
if (item.total !== null && item.total !== undefined) {
|
|
155
|
+
return ` ${item.label}: ${item.position}/${item.total}`;
|
|
156
|
+
}
|
|
157
|
+
return ` ${item.label}: ${item.position}`;
|
|
158
|
+
}
|
|
159
|
+
return ` ${item.label}: n/a`;
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
function formatStructuredBlock(value, indent = 2) {
|
|
163
|
+
if (value === null || value === undefined) {
|
|
164
|
+
return [`${pad(indent)}No data available.`];
|
|
165
|
+
}
|
|
166
|
+
if (Array.isArray(value)) {
|
|
167
|
+
if (value.length === 0) {
|
|
168
|
+
return [`${pad(indent)}No data available.`];
|
|
169
|
+
}
|
|
170
|
+
return value.flatMap(item => formatStructuredArrayItem(item, indent));
|
|
171
|
+
}
|
|
172
|
+
if (typeof value !== "object") {
|
|
173
|
+
return [`${pad(indent)}${formatScalar(value)}`];
|
|
174
|
+
}
|
|
175
|
+
const lines = [];
|
|
176
|
+
for (const [key, nestedValue] of Object.entries(value)) {
|
|
177
|
+
if (nestedValue === null || nestedValue === undefined) {
|
|
178
|
+
continue;
|
|
179
|
+
}
|
|
180
|
+
if (isScalar(nestedValue)) {
|
|
181
|
+
lines.push(`${pad(indent)}${humanizeKey(key)}: ${formatScalar(nestedValue)}`);
|
|
182
|
+
continue;
|
|
183
|
+
}
|
|
184
|
+
lines.push(`${pad(indent)}${humanizeKey(key)}:`);
|
|
185
|
+
lines.push(...formatStructuredBlock(nestedValue, indent + 2));
|
|
186
|
+
}
|
|
187
|
+
return lines.length > 0 ? lines : [`${pad(indent)}No data available.`];
|
|
188
|
+
}
|
|
189
|
+
function formatStructuredArrayItem(item, indent) {
|
|
190
|
+
if (item === null || item === undefined) {
|
|
191
|
+
return [`${pad(indent)}- n/a`];
|
|
192
|
+
}
|
|
193
|
+
if (isScalar(item)) {
|
|
194
|
+
return [`${pad(indent)}- ${formatScalar(item)}`];
|
|
195
|
+
}
|
|
196
|
+
if (Array.isArray(item)) {
|
|
197
|
+
const lines = [`${pad(indent)}-`];
|
|
198
|
+
lines.push(...formatStructuredBlock(item, indent + 2));
|
|
199
|
+
return lines;
|
|
200
|
+
}
|
|
201
|
+
const label = resolveObjectLabel(item) ??
|
|
202
|
+
Object.entries(item)
|
|
203
|
+
.map(([key, value]) => `${humanizeKey(key)}=${formatScalarValue(value)}`)
|
|
204
|
+
.join(", ");
|
|
205
|
+
return [`${pad(indent)}- ${label}`];
|
|
206
|
+
}
|
|
207
|
+
function resolveObjectLabel(value) {
|
|
208
|
+
if (typeof value.label === "string" && value.label.trim()) {
|
|
209
|
+
if ("value" in value) {
|
|
210
|
+
return `${value.label}: ${formatScalarValue(value.value)}`;
|
|
211
|
+
}
|
|
212
|
+
if ("position" in value) {
|
|
213
|
+
const position = formatScalarValue(value.position);
|
|
214
|
+
const total = formatScalarValue(value.total);
|
|
215
|
+
return `${value.label}: ${position}${total ? `/${total}` : ""}`;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
return null;
|
|
219
|
+
}
|
|
220
|
+
function formatScalarValue(value) {
|
|
221
|
+
if (value === null || value === undefined) {
|
|
222
|
+
return "n/a";
|
|
223
|
+
}
|
|
224
|
+
if (isScalar(value)) {
|
|
225
|
+
return formatScalar(value);
|
|
226
|
+
}
|
|
227
|
+
if (Array.isArray(value)) {
|
|
228
|
+
return value.length === 0 ? "[]" : JSON.stringify(value);
|
|
229
|
+
}
|
|
230
|
+
return JSON.stringify(value);
|
|
231
|
+
}
|
|
232
|
+
function formatScalar(value) {
|
|
233
|
+
if (typeof value === "number") {
|
|
234
|
+
return formatNumber(value);
|
|
235
|
+
}
|
|
236
|
+
if (typeof value === "boolean") {
|
|
237
|
+
return value ? "yes" : "no";
|
|
238
|
+
}
|
|
239
|
+
return value;
|
|
240
|
+
}
|
|
241
|
+
function formatNumber(value) {
|
|
242
|
+
return new Intl.NumberFormat("en-US", {
|
|
243
|
+
maximumFractionDigits: 4,
|
|
244
|
+
}).format(value);
|
|
245
|
+
}
|
|
246
|
+
function formatNullableNumber(value) {
|
|
247
|
+
if (value === null || value === undefined) {
|
|
248
|
+
return "n/a";
|
|
249
|
+
}
|
|
250
|
+
return formatNumber(value);
|
|
251
|
+
}
|
|
252
|
+
function formatChangePct(value, theme) {
|
|
253
|
+
const formatted = `${new Intl.NumberFormat("en-US", {
|
|
254
|
+
maximumFractionDigits: 2,
|
|
255
|
+
minimumFractionDigits: 2,
|
|
256
|
+
}).format(value)}%`;
|
|
257
|
+
if (value > 0) {
|
|
258
|
+
return theme.success(formatted);
|
|
259
|
+
}
|
|
260
|
+
if (value < 0) {
|
|
261
|
+
return theme.danger(formatted);
|
|
262
|
+
}
|
|
263
|
+
return formatted;
|
|
264
|
+
}
|
|
265
|
+
function resolvePerformanceLabel(item) {
|
|
266
|
+
switch (item.id) {
|
|
267
|
+
case "D1":
|
|
268
|
+
return "1D";
|
|
269
|
+
case "CURRENT_WEEK":
|
|
270
|
+
return "WTD";
|
|
271
|
+
case "CURRENT_MONTH":
|
|
272
|
+
return "MTD";
|
|
273
|
+
case "CURRENT_YEAR":
|
|
274
|
+
return "YTD";
|
|
275
|
+
case "DAYS_30":
|
|
276
|
+
return "30D";
|
|
277
|
+
case "DAYS_90":
|
|
278
|
+
return "90D";
|
|
279
|
+
case "DAYS_180":
|
|
280
|
+
return "180D";
|
|
281
|
+
case "DAYS_365":
|
|
282
|
+
return "1Y";
|
|
283
|
+
default:
|
|
284
|
+
return item.label;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
function sectionTitle(section) {
|
|
288
|
+
switch (section) {
|
|
289
|
+
case "technicals":
|
|
290
|
+
return "Technicals";
|
|
291
|
+
case "fundamentals":
|
|
292
|
+
return "Fundamentals";
|
|
293
|
+
case "performance":
|
|
294
|
+
return "Performance";
|
|
295
|
+
case "momentum":
|
|
296
|
+
return "Momentum";
|
|
297
|
+
case "rankings":
|
|
298
|
+
return "Rankings";
|
|
299
|
+
case "price":
|
|
300
|
+
return "Price";
|
|
301
|
+
case "risk":
|
|
302
|
+
return "Risk";
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
function humanizeKey(key) {
|
|
306
|
+
const exactLabels = {
|
|
307
|
+
p_l: "P/L",
|
|
308
|
+
p_vp: "P/VP",
|
|
309
|
+
roe: "ROE",
|
|
310
|
+
roic: "ROIC",
|
|
311
|
+
ev_ebit: "EV/EBIT",
|
|
312
|
+
ev_ebitda: "EV/EBITDA",
|
|
313
|
+
atr14: "ATR14",
|
|
314
|
+
rsi2: "RSI2",
|
|
315
|
+
rsi14: "RSI14",
|
|
316
|
+
sma20: "SMA20",
|
|
317
|
+
sma50: "SMA50",
|
|
318
|
+
sma200: "SMA200",
|
|
319
|
+
value: "Value",
|
|
320
|
+
target: "Target",
|
|
321
|
+
source: "Source",
|
|
322
|
+
max_lag: "Max lag",
|
|
323
|
+
upside_pct: "Upside %",
|
|
324
|
+
mm50_is_up: "MM50 uptrend",
|
|
325
|
+
distance_to_sma200_pct: "Distance to SMA200 %",
|
|
326
|
+
distance_to_high_pct: "Distance to high %",
|
|
327
|
+
max_drawdown_1y_pct: "Max drawdown 1Y %",
|
|
328
|
+
volatility_30d_ann: "Volatility 30D annualized",
|
|
329
|
+
range_52w: "52-week range",
|
|
330
|
+
k: "%K",
|
|
331
|
+
d: "%D",
|
|
332
|
+
};
|
|
333
|
+
if (exactLabels[key]) {
|
|
334
|
+
return exactLabels[key];
|
|
335
|
+
}
|
|
336
|
+
return key
|
|
337
|
+
.split("_")
|
|
338
|
+
.map(part => part.length <= 3
|
|
339
|
+
? part.toUpperCase()
|
|
340
|
+
: part[0].toUpperCase() + part.slice(1))
|
|
341
|
+
.join(" ");
|
|
342
|
+
}
|
|
343
|
+
function pad(size) {
|
|
344
|
+
return " ".repeat(size);
|
|
345
|
+
}
|
|
346
|
+
function isScalar(value) {
|
|
347
|
+
return (typeof value === "string" ||
|
|
348
|
+
typeof value === "number" ||
|
|
349
|
+
typeof value === "boolean");
|
|
350
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { type TerminalWriter } from "../cli/terminal.js";
|
|
3
|
+
export interface AuthCommandIO {
|
|
4
|
+
stdout: TerminalWriter;
|
|
5
|
+
}
|
|
6
|
+
export interface AuthCommandContext {
|
|
7
|
+
io?: AuthCommandIO;
|
|
8
|
+
env?: NodeJS.ProcessEnv;
|
|
9
|
+
fetch?: typeof fetch;
|
|
10
|
+
}
|
|
11
|
+
export interface AuthLoginCommandOptions {
|
|
12
|
+
apiKey: string;
|
|
13
|
+
}
|
|
14
|
+
export declare function registerAuthCommands(program: Command, context?: AuthCommandContext): void;
|
|
15
|
+
export declare function runAuthLoginCommand(options: AuthLoginCommandOptions, context?: AuthCommandContext): Promise<void>;
|
|
16
|
+
export declare function runAuthLogoutCommand(context?: AuthCommandContext): Promise<void>;
|
|
17
|
+
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,OAAO,EAAuB,KAAK,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAE9E,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,cAAc,CAAC;CACxB;AAED,MAAM,WAAW,kBAAkB;IACjC,EAAE,CAAC,EAAE,aAAa,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;CACtB;AAED,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,OAAO,EAChB,OAAO,GAAE,kBAAuB,GAC/B,IAAI,CAmBN;AAED,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,uBAAuB,EAChC,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,IAAI,CAAC,CAoBf;AAED,wBAAsB,oBAAoB,CACxC,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,IAAI,CAAC,CAiBf"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { verifyCliApiKey } from "../cli/auth.js";
|
|
2
|
+
import { clearCliStoredAuth, saveCliApiKey } from "../cli/config.js";
|
|
3
|
+
import { createTerminalTheme } from "../cli/terminal.js";
|
|
4
|
+
export function registerAuthCommands(program, context = {}) {
|
|
5
|
+
const authCommand = program
|
|
6
|
+
.command("auth")
|
|
7
|
+
.description("Manage local authentication");
|
|
8
|
+
authCommand
|
|
9
|
+
.command("login")
|
|
10
|
+
.description("Store an API key locally")
|
|
11
|
+
.requiredOption("--api-key <token>", "QuantBrasil API key")
|
|
12
|
+
.action(async (options) => {
|
|
13
|
+
await runAuthLoginCommand(options, context);
|
|
14
|
+
});
|
|
15
|
+
authCommand
|
|
16
|
+
.command("logout")
|
|
17
|
+
.description("Remove the locally stored API key")
|
|
18
|
+
.action(async () => {
|
|
19
|
+
await runAuthLogoutCommand(context);
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
export async function runAuthLoginCommand(options, context = {}) {
|
|
23
|
+
const stdout = getStdout(context);
|
|
24
|
+
const theme = createTerminalTheme(stdout, context.env ?? process.env);
|
|
25
|
+
const verifiedAuth = await verifyCliApiKey(options.apiKey, {
|
|
26
|
+
env: context.env,
|
|
27
|
+
fetch: context.fetch,
|
|
28
|
+
});
|
|
29
|
+
const configPath = await saveCliApiKey(options.apiKey, context.env ?? process.env);
|
|
30
|
+
stdout.write([
|
|
31
|
+
`${theme.success(theme.bold("API key saved."))} ${theme.info(verifiedAuth.email)}`,
|
|
32
|
+
`${theme.dim(`Key: ${verifiedAuth.apiKey.name} (${verifiedAuth.apiKey.keyPrefix})`)}`,
|
|
33
|
+
`${theme.dim(configPath)}`,
|
|
34
|
+
].join("\n") + "\n");
|
|
35
|
+
}
|
|
36
|
+
export async function runAuthLogoutCommand(context = {}) {
|
|
37
|
+
const stdout = getStdout(context);
|
|
38
|
+
const theme = createTerminalTheme(stdout, context.env ?? process.env);
|
|
39
|
+
const { configPath, removed } = await clearCliStoredAuth(context.env ?? process.env);
|
|
40
|
+
if (removed) {
|
|
41
|
+
stdout.write(`${theme.info(theme.bold("Local API key removed."))} ${theme.dim(configPath)}\n`);
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
stdout.write(`${theme.dim(`No local API key was stored at ${configPath}.`)}\n`);
|
|
45
|
+
}
|
|
46
|
+
function getStdout(context) {
|
|
47
|
+
return context.io?.stdout ?? process.stdout;
|
|
48
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { CapabilityDefinition } from "../vendor/core/capabilities/index.js";
|
|
2
|
+
import { Command } from "commander";
|
|
3
|
+
import { type TerminalWriter } from "../cli/terminal.js";
|
|
4
|
+
export interface CapabilitiesCommandOptions {
|
|
5
|
+
json?: boolean;
|
|
6
|
+
}
|
|
7
|
+
export interface CapabilitiesCommandIO {
|
|
8
|
+
stdout: TerminalWriter;
|
|
9
|
+
}
|
|
10
|
+
export interface CapabilityInspectionEntry {
|
|
11
|
+
id: string;
|
|
12
|
+
kind: CapabilityDefinition["kind"];
|
|
13
|
+
description: string;
|
|
14
|
+
visibility: readonly CapabilityDefinition["visibility"][number][];
|
|
15
|
+
http: CapabilityDefinition["http"];
|
|
16
|
+
cli: CapabilityDefinition["cli"];
|
|
17
|
+
tool: CapabilityDefinition["tool"];
|
|
18
|
+
outputModes: readonly CapabilityDefinition["outputModes"][number][];
|
|
19
|
+
}
|
|
20
|
+
export declare function registerCapabilitiesCommand(program: Command, io?: CapabilitiesCommandIO): void;
|
|
21
|
+
export declare function runCapabilitiesCommand(options: CapabilitiesCommandOptions, io?: CapabilitiesCommandIO): Promise<void>;
|
|
22
|
+
export declare function getCapabilityInspectionEntries(): CapabilityInspectionEntry[];
|
|
23
|
+
export declare function formatCapabilitiesJson(): string;
|
|
24
|
+
export declare function formatCapabilitiesHuman(theme?: import("../cli/terminal.js").TerminalTheme): string;
|
|
25
|
+
//# sourceMappingURL=capabilities.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capabilities.d.ts","sourceRoot":"","sources":["../../src/commands/capabilities.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AACpE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAuB,KAAK,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAE9E,MAAM,WAAW,0BAA0B;IACzC,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,cAAc,CAAC;CACxB;AAED,MAAM,WAAW,yBAAyB;IACxC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,oBAAoB,CAAC,MAAM,CAAC,CAAC;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,SAAS,oBAAoB,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC;IAClE,IAAI,EAAE,oBAAoB,CAAC,MAAM,CAAC,CAAC;IACnC,GAAG,EAAE,oBAAoB,CAAC,KAAK,CAAC,CAAC;IACjC,IAAI,EAAE,oBAAoB,CAAC,MAAM,CAAC,CAAC;IACnC,WAAW,EAAE,SAAS,oBAAoB,CAAC,aAAa,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC;CACrE;AAED,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,OAAO,EAChB,EAAE,GAAE,qBAAkD,GACrD,IAAI,CAQN;AAED,wBAAsB,sBAAsB,CAC1C,OAAO,EAAE,0BAA0B,EACnC,EAAE,GAAE,qBAAkD,GACrD,OAAO,CAAC,IAAI,CAAC,CAOf;AAED,wBAAgB,8BAA8B,IAAI,yBAAyB,EAAE,CAW5E;AAED,wBAAgB,sBAAsB,IAAI,MAAM,CAE/C;AAED,wBAAgB,uBAAuB,CACrC,KAAK,6CAAsC,GAC1C,MAAM,CA0BR"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { capabilityRegistry } from "../vendor/core/capabilities/index.js";
|
|
2
|
+
import { createTerminalTheme } from "../cli/terminal.js";
|
|
3
|
+
export function registerCapabilitiesCommand(program, io = { stdout: process.stdout }) {
|
|
4
|
+
program
|
|
5
|
+
.command("capabilities")
|
|
6
|
+
.description("List available operations")
|
|
7
|
+
.option("--json", "Show JSON output")
|
|
8
|
+
.action(async (options) => {
|
|
9
|
+
await runCapabilitiesCommand(options, io);
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
export async function runCapabilitiesCommand(options, io = { stdout: process.stdout }) {
|
|
13
|
+
const theme = createTerminalTheme(io.stdout);
|
|
14
|
+
const output = options.json
|
|
15
|
+
? formatCapabilitiesJson()
|
|
16
|
+
: formatCapabilitiesHuman(theme);
|
|
17
|
+
io.stdout.write(`${output}\n`);
|
|
18
|
+
}
|
|
19
|
+
export function getCapabilityInspectionEntries() {
|
|
20
|
+
return capabilityRegistry.map(capability => ({
|
|
21
|
+
id: capability.id,
|
|
22
|
+
kind: capability.kind,
|
|
23
|
+
description: capability.description,
|
|
24
|
+
visibility: capability.visibility,
|
|
25
|
+
http: capability.http,
|
|
26
|
+
cli: capability.cli,
|
|
27
|
+
tool: capability.tool,
|
|
28
|
+
outputModes: capability.outputModes,
|
|
29
|
+
}));
|
|
30
|
+
}
|
|
31
|
+
export function formatCapabilitiesJson() {
|
|
32
|
+
return JSON.stringify(getCapabilityInspectionEntries(), null, 2);
|
|
33
|
+
}
|
|
34
|
+
export function formatCapabilitiesHuman(theme = createTerminalTheme(process.stdout)) {
|
|
35
|
+
const grouped = groupCapabilitiesByCliGroup(capabilityRegistry);
|
|
36
|
+
const lines = [theme.label("Available operations"), ""];
|
|
37
|
+
for (const [group, capabilities] of grouped) {
|
|
38
|
+
lines.push(theme.label(group));
|
|
39
|
+
for (const capability of capabilities) {
|
|
40
|
+
lines.push(` ${theme.bold(capability.cli.command.padEnd(18))} ${capability.cli.summary}`);
|
|
41
|
+
lines.push(` ${theme.dim(`id: ${capability.id}`)}`);
|
|
42
|
+
lines.push(` ${theme.dim(`route: ${capability.http.method} ${capability.http.path}`)}`);
|
|
43
|
+
lines.push(` ${theme.dim(`examples: ${capability.cli.examples.join(" | ")}`)}`);
|
|
44
|
+
}
|
|
45
|
+
lines.push("");
|
|
46
|
+
}
|
|
47
|
+
lines.push(theme.dim("Use --json to show JSON output."));
|
|
48
|
+
return lines.join("\n");
|
|
49
|
+
}
|
|
50
|
+
function groupCapabilitiesByCliGroup(capabilities) {
|
|
51
|
+
const groups = new Map();
|
|
52
|
+
for (const capability of capabilities) {
|
|
53
|
+
const bucket = groups.get(capability.cli.group) ?? [];
|
|
54
|
+
bucket.push(capability);
|
|
55
|
+
groups.set(capability.cli.group, bucket);
|
|
56
|
+
}
|
|
57
|
+
return [...groups.entries()].map(([group, entries]) => [
|
|
58
|
+
group,
|
|
59
|
+
[...entries].sort((left, right) => left.cli.command.localeCompare(right.cli.command)),
|
|
60
|
+
]);
|
|
61
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { type TerminalWriter } from "../cli/terminal.js";
|
|
3
|
+
export interface InitCommandIO {
|
|
4
|
+
stdout: TerminalWriter;
|
|
5
|
+
}
|
|
6
|
+
export interface InitCommandContext {
|
|
7
|
+
io?: InitCommandIO;
|
|
8
|
+
env?: NodeJS.ProcessEnv;
|
|
9
|
+
fetch?: typeof fetch;
|
|
10
|
+
prompt?: (promptLabel: string) => Promise<string>;
|
|
11
|
+
}
|
|
12
|
+
export interface InitCommandOptions {
|
|
13
|
+
apiKey?: string;
|
|
14
|
+
}
|
|
15
|
+
export declare function registerInitCommand(program: Command, context?: InitCommandContext): void;
|
|
16
|
+
export declare function runInitCommand(options: InitCommandOptions, context?: InitCommandContext): Promise<void>;
|
|
17
|
+
//# sourceMappingURL=init.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAUpC,OAAO,EAAuB,KAAK,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAG9E,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,cAAc,CAAC;CACxB;AAED,MAAM,WAAW,kBAAkB;IACjC,EAAE,CAAC,EAAE,aAAa,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;IACrB,MAAM,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;CACnD;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,OAAO,EAChB,OAAO,GAAE,kBAAuB,GAC/B,IAAI,CAQN;AAED,wBAAsB,cAAc,CAClC,OAAO,EAAE,kBAAkB,EAC3B,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,IAAI,CAAC,CAqHf"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { verifyCliApiKey } from "../cli/auth.js";
|
|
2
|
+
import { resolveCliAuth, resolveCliStatusSnapshot, saveCliApiKey, } from "../cli/config.js";
|
|
3
|
+
import { CliError } from "../cli/errors.js";
|
|
4
|
+
import { promptForSecret } from "../cli/prompt.js";
|
|
5
|
+
import { installBundledSkillEverywhere } from "../cli/skills.js";
|
|
6
|
+
import { createTerminalTheme } from "../cli/terminal.js";
|
|
7
|
+
import { formatSkillsInstallResult } from "./skills.js";
|
|
8
|
+
export function registerInitCommand(program, context = {}) {
|
|
9
|
+
program
|
|
10
|
+
.command("init")
|
|
11
|
+
.description("Set up authentication and install bundled public skills")
|
|
12
|
+
.option("--api-key <token>", "QuantBrasil API key")
|
|
13
|
+
.action(async (options) => {
|
|
14
|
+
await runInitCommand(options, context);
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
export async function runInitCommand(options, context = {}) {
|
|
18
|
+
const env = context.env ?? process.env;
|
|
19
|
+
const stdout = context.io?.stdout ?? process.stdout;
|
|
20
|
+
const theme = createTerminalTheme(stdout, env);
|
|
21
|
+
const lines = [theme.label("QuantBrasil CLI Setup"), ""];
|
|
22
|
+
const resolvedAuth = await resolveCliAuth(env);
|
|
23
|
+
if (options.apiKey) {
|
|
24
|
+
const verifiedAuth = await verifyCliApiKey(options.apiKey, {
|
|
25
|
+
env,
|
|
26
|
+
fetch: context.fetch,
|
|
27
|
+
});
|
|
28
|
+
const configPath = await saveCliApiKey(options.apiKey, env);
|
|
29
|
+
lines.push(`${theme.success("API key verified and saved.")} ${theme.info(verifiedAuth.email)}`, `${theme.dim(`Key: ${verifiedAuth.apiKey.name} (${verifiedAuth.apiKey.keyPrefix})`)}`, `${theme.dim(configPath)}`);
|
|
30
|
+
}
|
|
31
|
+
else if (resolvedAuth !== null) {
|
|
32
|
+
try {
|
|
33
|
+
await verifyCliApiKey(resolvedAuth.apiKey, {
|
|
34
|
+
env,
|
|
35
|
+
fetch: context.fetch,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
if (resolvedAuth.source === "env") {
|
|
40
|
+
if (error instanceof CliError) {
|
|
41
|
+
throw new CliError(error.code, `Existing QUANTBRASIL_API_KEY is not valid for the current backend. ${error.message}`, {
|
|
42
|
+
category: error.category,
|
|
43
|
+
status: error.status,
|
|
44
|
+
path: error.path,
|
|
45
|
+
requestId: error.requestId,
|
|
46
|
+
cause: error,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
if (error instanceof Error) {
|
|
50
|
+
throw new CliError("auth_failed", `Existing QUANTBRASIL_API_KEY is not valid for the current backend. ${error.message}`, {
|
|
51
|
+
category: "auth",
|
|
52
|
+
cause: error,
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
throw error;
|
|
56
|
+
}
|
|
57
|
+
const replacementApiKey = await (context.prompt ?? promptForSecret)("Stored API key is invalid. Enter a replacement key (qb_live_<id>.<secret>): ");
|
|
58
|
+
const verifiedAuth = await verifyCliApiKey(replacementApiKey, {
|
|
59
|
+
env,
|
|
60
|
+
fetch: context.fetch,
|
|
61
|
+
});
|
|
62
|
+
const configPath = await saveCliApiKey(replacementApiKey, env);
|
|
63
|
+
lines.push(`${theme.success("Stored API key replaced.")} ${theme.info(verifiedAuth.email)}`, `${theme.dim(`Key: ${verifiedAuth.apiKey.name} (${verifiedAuth.apiKey.keyPrefix})`)}`, `${theme.dim(configPath)}`);
|
|
64
|
+
}
|
|
65
|
+
if (lines.length === 2) {
|
|
66
|
+
lines.push(`${theme.info("Authentication already configured and verified.")} ${theme.dim(`Source: ${resolvedAuth.source}`)}`);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
const apiKey = await (context.prompt ?? promptForSecret)("QuantBrasil API key (qb_live_<id>.<secret>): ");
|
|
71
|
+
const verifiedAuth = await verifyCliApiKey(apiKey, {
|
|
72
|
+
env,
|
|
73
|
+
fetch: context.fetch,
|
|
74
|
+
});
|
|
75
|
+
const configPath = await saveCliApiKey(apiKey, env);
|
|
76
|
+
lines.push(`${theme.success("API key verified and saved.")} ${theme.info(verifiedAuth.email)}`, `${theme.dim(`Key: ${verifiedAuth.apiKey.name} (${verifiedAuth.apiKey.keyPrefix})`)}`, `${theme.dim(configPath)}`);
|
|
77
|
+
}
|
|
78
|
+
const skillInstallResult = await installBundledSkillEverywhere(env);
|
|
79
|
+
const status = await resolveCliStatusSnapshot(env);
|
|
80
|
+
lines.push("");
|
|
81
|
+
lines.push(formatSkillsInstallResult(skillInstallResult, theme));
|
|
82
|
+
lines.push("");
|
|
83
|
+
lines.push(theme.label("Ready"));
|
|
84
|
+
lines.push(`${theme.label("Backend:")} ${status.backendUrl} ${theme.dim(status.backendSource === "override" ? "(QB_BACKEND_URL)" : "(default)")}`);
|
|
85
|
+
lines.push(`${theme.label("Authentication:")} ${status.isReady ? theme.success("yes") : theme.warning("no")}`);
|
|
86
|
+
lines.push(`${theme.label("Skills installed:")} ${theme.success(String(skillInstallResult.installed.length))}`);
|
|
87
|
+
lines.push(theme.dim("Restart your agent client if it was already running so it can discover the new skill."));
|
|
88
|
+
stdout.write(`${lines.join("\n")}\n`);
|
|
89
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import type { JsonValue } from "../vendor/core/index.js";
|
|
3
|
+
import { type CliInvokeContext } from "../cli/client.js";
|
|
4
|
+
import { type TerminalWriter } from "../cli/terminal.js";
|
|
5
|
+
export interface MarketCommandIO {
|
|
6
|
+
stdout: TerminalWriter;
|
|
7
|
+
}
|
|
8
|
+
export interface MarketAssetsCommandOptions {
|
|
9
|
+
type?: string;
|
|
10
|
+
json?: boolean;
|
|
11
|
+
}
|
|
12
|
+
export interface MarketPriceCommandOptions {
|
|
13
|
+
date?: string;
|
|
14
|
+
timeframe?: string;
|
|
15
|
+
json?: boolean;
|
|
16
|
+
}
|
|
17
|
+
export interface MonitoredAssetsResponse {
|
|
18
|
+
[key: string]: JsonValue;
|
|
19
|
+
total: number;
|
|
20
|
+
groups: Record<string, string[]>;
|
|
21
|
+
}
|
|
22
|
+
export interface MarketPriceResponse {
|
|
23
|
+
[key: string]: JsonValue;
|
|
24
|
+
ticker: string;
|
|
25
|
+
name: string | null;
|
|
26
|
+
type: string | null;
|
|
27
|
+
timeframe: string;
|
|
28
|
+
price_date: string;
|
|
29
|
+
close: number;
|
|
30
|
+
open: number;
|
|
31
|
+
high: number;
|
|
32
|
+
low: number;
|
|
33
|
+
volume: number | null;
|
|
34
|
+
prev_close: number | null;
|
|
35
|
+
change_pct: number | null;
|
|
36
|
+
}
|
|
37
|
+
export interface MarketCommandContext extends CliInvokeContext {
|
|
38
|
+
io?: MarketCommandIO;
|
|
39
|
+
}
|
|
40
|
+
export declare function registerMarketCommands(program: Command, context?: MarketCommandContext): void;
|
|
41
|
+
export declare function runMarketAssetsCommand(options: MarketAssetsCommandOptions, context?: MarketCommandContext): Promise<void>;
|
|
42
|
+
export declare function runMarketPriceCommand(ticker: string, options: MarketPriceCommandOptions, context?: MarketCommandContext): Promise<void>;
|
|
43
|
+
export declare function formatMarketAssetsHuman(data: MonitoredAssetsResponse, theme?: import("../cli/terminal.js").TerminalTheme): string;
|
|
44
|
+
export declare function formatMarketPriceHuman(data: MarketPriceResponse, theme?: import("../cli/terminal.js").TerminalTheme): string;
|
|
45
|
+
//# sourceMappingURL=market.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"market.d.ts","sourceRoot":"","sources":["../../src/commands/market.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C,OAAO,EAAuB,KAAK,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAE9E,OAAO,EAAuB,KAAK,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAE9E,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,cAAc,CAAC;CACxB;AAED,MAAM,WAAW,0BAA0B;IACzC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,yBAAyB;IACxC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,uBAAuB;IACtC,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;CAClC;AAED,MAAM,WAAW,mBAAmB;IAClC,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,MAAM,WAAW,oBAAqB,SAAQ,gBAAgB;IAC5D,EAAE,CAAC,EAAE,eAAe,CAAC;CACtB;AAED,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,OAAO,EAChB,OAAO,GAAE,oBAAyB,GACjC,IAAI,CA2BN;AAED,wBAAsB,sBAAsB,CAC1C,OAAO,EAAE,0BAA0B,EACnC,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,IAAI,CAAC,CAiBf;AAED,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,yBAAyB,EAClC,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,IAAI,CAAC,CAgBf;AA0CD,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,uBAAuB,EAC7B,KAAK,6CAAsC,GAC1C,MAAM,CAgBR;AAED,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,mBAAmB,EACzB,KAAK,6CAAsC,GAC1C,MAAM,CAoCR"}
|