@quantbrasil/cli 0.1.0-beta.1 → 0.1.0-beta.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/README.md +63 -11
  2. package/dist/cli/client.js +4 -0
  3. package/dist/cli/index.d.ts +12 -4
  4. package/dist/cli/index.d.ts.map +1 -1
  5. package/dist/cli/index.js +64 -14
  6. package/dist/cli/prompt.d.ts +1 -0
  7. package/dist/cli/prompt.d.ts.map +1 -1
  8. package/dist/cli/prompt.js +17 -0
  9. package/dist/cli/skills.d.ts +9 -0
  10. package/dist/cli/skills.d.ts.map +1 -1
  11. package/dist/cli/skills.js +68 -4
  12. package/dist/commands/auth.d.ts +18 -0
  13. package/dist/commands/auth.d.ts.map +1 -1
  14. package/dist/commands/auth.js +49 -0
  15. package/dist/commands/market.d.ts +1 -0
  16. package/dist/commands/market.d.ts.map +1 -1
  17. package/dist/commands/market.js +17 -1
  18. package/dist/commands/portfolios.d.ts +148 -8
  19. package/dist/commands/portfolios.d.ts.map +1 -1
  20. package/dist/commands/portfolios.js +557 -55
  21. package/dist/commands/rankings.d.ts +82 -0
  22. package/dist/commands/rankings.d.ts.map +1 -0
  23. package/dist/commands/rankings.js +235 -0
  24. package/dist/commands/screening.d.ts +120 -0
  25. package/dist/commands/screening.d.ts.map +1 -0
  26. package/dist/commands/screening.js +361 -0
  27. package/dist/commands/skills.js +7 -7
  28. package/dist/commands/update.d.ts +23 -0
  29. package/dist/commands/update.d.ts.map +1 -0
  30. package/dist/commands/update.js +209 -0
  31. package/dist/index.d.ts +3 -1
  32. package/dist/index.d.ts.map +1 -1
  33. package/dist/index.js +3 -1
  34. package/dist/vendor/core/capabilities/index.d.ts +2 -1
  35. package/dist/vendor/core/capabilities/index.d.ts.map +1 -1
  36. package/dist/vendor/core/capabilities/index.js +2 -1
  37. package/dist/vendor/core/capabilities/market.d.ts +9 -1
  38. package/dist/vendor/core/capabilities/market.d.ts.map +1 -1
  39. package/dist/vendor/core/capabilities/market.js +10 -0
  40. package/dist/vendor/core/capabilities/portfolios.d.ts +452 -56
  41. package/dist/vendor/core/capabilities/portfolios.d.ts.map +1 -1
  42. package/dist/vendor/core/capabilities/portfolios.js +434 -116
  43. package/dist/vendor/core/capabilities/rankings.d.ts +83 -0
  44. package/dist/vendor/core/capabilities/rankings.d.ts.map +1 -0
  45. package/dist/vendor/core/capabilities/rankings.js +95 -0
  46. package/dist/vendor/core/capabilities/registry.d.ts +1279 -413
  47. package/dist/vendor/core/capabilities/registry.d.ts.map +1 -1
  48. package/dist/vendor/core/capabilities/registry.js +4 -2
  49. package/dist/vendor/core/capabilities/screening.d.ts +136 -0
  50. package/dist/vendor/core/capabilities/screening.d.ts.map +1 -0
  51. package/dist/vendor/core/capabilities/screening.js +155 -0
  52. package/dist/vendor/core/capabilities/types.d.ts +1 -1
  53. package/dist/vendor/core/capabilities/types.d.ts.map +1 -1
  54. package/package.json +3 -3
  55. package/skills/quantbrasil/SKILL.md +28 -11
  56. package/skills/quantbrasil/references/cli.md +96 -20
  57. package/skills/quantbrasil/references/costs.md +9 -4
  58. package/skills/quantbrasil/references/errors.md +16 -5
  59. package/skills/quantbrasil/references/portfolios.md +114 -0
  60. package/skills/quantbrasil/references/quality-eval-queries.json +127 -0
  61. package/skills/quantbrasil/references/rankings.md +62 -0
  62. package/skills/quantbrasil/references/screening.md +212 -0
  63. package/skills/quantbrasil/references/unsupported.md +7 -2
  64. package/skills/quantbrasil/references/workflows.md +95 -23
  65. package/dist/commands/analytics.d.ts +0 -131
  66. package/dist/commands/analytics.d.ts.map +0 -1
  67. package/dist/commands/analytics.js +0 -291
  68. package/dist/vendor/core/capabilities/analytics.d.ts +0 -187
  69. package/dist/vendor/core/capabilities/analytics.d.ts.map +0 -1
  70. package/dist/vendor/core/capabilities/analytics.js +0 -214
package/README.md CHANGED
@@ -29,7 +29,9 @@ that file only exists inside this package.
29
29
  ```bash
30
30
  # from monorepo/packages/cli
31
31
  node ./bin/quantbrasil.js auth login --api-key qb_live_<id>.<secret>
32
+ node ./bin/quantbrasil.js whoami
32
33
  node ./bin/quantbrasil.js skills install --all
34
+ node ./bin/quantbrasil.js update
33
35
  node ./bin/quantbrasil.js --status
34
36
  node ./bin/quantbrasil.js auth logout
35
37
  ```
@@ -48,6 +50,7 @@ compatible local or staging backend.
48
50
  ```bash
49
51
  quantbrasil market assets
50
52
  quantbrasil market assets --type B3
53
+ quantbrasil market assets --search BTC
51
54
  quantbrasil market assets --json
52
55
  quantbrasil market price PETR4
53
56
  quantbrasil market price PETR4 --date 2026-04-10
@@ -55,16 +58,59 @@ quantbrasil market price PETR4 --json
55
58
  quantbrasil assets overview PETR4 --sections price,performance
56
59
  quantbrasil assets overview PETR4 --sections price,technicals
57
60
  quantbrasil assets overview PETR4 --sections price,fundamentals --json
58
- quantbrasil portfolios list
59
- quantbrasil portfolios get 93
60
- quantbrasil portfolios get 93 --json
61
- quantbrasil portfolios create "Dividendos"
62
- quantbrasil portfolios rename 93 "Longo Prazo"
63
- quantbrasil portfolios add-assets 93 PETR4 VALE3
64
- quantbrasil portfolios remove-assets 93 PETR4
65
- quantbrasil analytics historical-return --portfolio 93 --from 2025-01-01 --to 2026-01-01
66
- quantbrasil analytics beta --portfolio 93 --years 3
67
- quantbrasil analytics var --portfolio 93 --years 1 --confidence 95
61
+ quantbrasil watchlists list
62
+ quantbrasil watchlists get 93
63
+ quantbrasil watchlists create "Dividendos"
64
+ quantbrasil watchlists add-assets 93 PETR4 VALE3
65
+ quantbrasil holdings list
66
+ quantbrasil holdings get 182
67
+ quantbrasil holdings create "Longo Prazo"
68
+ quantbrasil holdings create "Longo Prazo" --target PETR4:50 --target VALE3:50
69
+ quantbrasil holdings create "Carteira Real" --mode position
70
+ quantbrasil holdings set-targets 182 PETR4:50 VALE3:50
71
+ quantbrasil holdings set-positions 182 PRIO3:1600 BTC-USD:0.25 QQQ:10
72
+ quantbrasil holdings historical-return 182 --from 2025-01-01 --to 2026-01-01
73
+ quantbrasil holdings historical-return 182 --period 1y
74
+ quantbrasil holdings beta 182 --years 3
75
+ quantbrasil holdings var 182 --years 1 --confidence 95
76
+ quantbrasil rankings list
77
+ quantbrasil rankings current --system momentum-90d --top 20
78
+ quantbrasil rankings current --system magic-formula --top 10
79
+ quantbrasil rankings current --id 123 --top 20
80
+ quantbrasil screening universes
81
+ quantbrasil screening indicators
82
+ quantbrasil screening run --system acoes-mais-liquidas --query-file ./screening.json
83
+ quantbrasil screening run --watchlist 93 --query-file ./screening.json --limit 25
84
+ cat ./screening.json | quantbrasil screening run --holding 182 --query-file -
85
+ ```
86
+
87
+ Example `screening.json`:
88
+
89
+ ```json
90
+ {
91
+ "query": {
92
+ "comparison": {
93
+ "left": {
94
+ "indicator": {
95
+ "name": "RSI",
96
+ "timeframe": "D1",
97
+ "offset": 0,
98
+ "params": {
99
+ "period": 14
100
+ }
101
+ }
102
+ },
103
+ "operator": "lt",
104
+ "right": {
105
+ "constant": {
106
+ "value": 30
107
+ }
108
+ }
109
+ }
110
+ },
111
+ "limit": 50,
112
+ "sort": "ticker"
113
+ }
68
114
  ```
69
115
 
70
116
  ## Local config
@@ -104,8 +150,14 @@ quantbrasil init
104
150
  quantbrasil --status
105
151
  quantbrasil auth login --api-key qb_live_<id>.<secret>
106
152
  quantbrasil skills install --all
153
+ quantbrasil update
107
154
  ```
108
155
 
156
+ `quantbrasil update` checks the current global package against
157
+ `@quantbrasil/cli@beta`, checks whether the bundled skill is missing or stale,
158
+ shows the planned actions, and asks for confirmation before updating. Use
159
+ `quantbrasil update --yes` only in noninteractive automation.
160
+
109
161
  ## Publishing
110
162
 
111
163
  Publish from `monorepo/packages/cli`. The package build vendors the private
@@ -183,7 +235,7 @@ For commands that expose `--json`, failures are written to stderr as JSON:
183
235
  "category": "auth",
184
236
  "exit_code": 1,
185
237
  "status": 401,
186
- "path": "/api/desk/tools/portfolio/list",
238
+ "path": "/api/desk/tools/watchlist/list",
187
239
  "request_id": "req_..."
188
240
  }
189
241
  }
@@ -80,6 +80,7 @@ function resolveErrorDetail(payload) {
80
80
  }
81
81
  const detail = payload.detail;
82
82
  const message = payload.message;
83
+ const error = payload.error;
83
84
  if (typeof detail === "string" && detail.trim()) {
84
85
  return detail;
85
86
  }
@@ -94,6 +95,9 @@ function resolveErrorDetail(payload) {
94
95
  if (typeof message === "string" && message.trim()) {
95
96
  return message;
96
97
  }
98
+ if (typeof error === "string" && error.trim()) {
99
+ return error;
100
+ }
97
101
  return null;
98
102
  }
99
103
  function formatValidationDetail(value) {
@@ -2,29 +2,37 @@ import { Command } from "commander";
2
2
  import { type CapabilitiesCommandIO, runCapabilitiesCommand } from "../commands/capabilities.js";
3
3
  import { runMarketAssetsCommand, runMarketPriceCommand } from "../commands/market.js";
4
4
  import { runInitCommand } from "../commands/init.js";
5
- import { runPortfolioAddAssetsCommand, runPortfolioCreateCommand, runPortfolioGetCommand, runPortfolioListCommand, runPortfolioRemoveAssetsCommand, runPortfolioRenameCommand } from "../commands/portfolios.js";
5
+ import { runHoldingCreateCommand, runHoldingBetaCommand, runHoldingGetCommand, runHoldingHistoricalReturnCommand, runHoldingListCommand, runHoldingRenameCommand, runHoldingSetPositionsCommand, runHoldingSetTargetsCommand, runHoldingVarCommand, runWatchlistAddAssetsCommand, runWatchlistCreateCommand, runWatchlistGetCommand, runWatchlistListCommand, runWatchlistRemoveAssetsCommand, runWatchlistRenameCommand } from "../commands/portfolios.js";
6
+ import { runRankingsCurrentCommand, runRankingsListCommand } from "../commands/rankings.js";
7
+ import { runScreeningIndicatorsCommand, runScreeningRunCommand, runScreeningUniversesCommand } from "../commands/screening.js";
6
8
  import { runSkillsInstallCommand } from "../commands/skills.js";
7
9
  import { runStatusCommand } from "../commands/status.js";
10
+ import { runUpdateCommand, type UpdateCommandRunner } from "../commands/update.js";
8
11
  import { type TerminalWriter } from "./terminal.js";
9
12
  export interface CliProgramOptions {
10
13
  io?: CapabilitiesCommandIO;
11
14
  env?: NodeJS.ProcessEnv;
12
15
  fetch?: typeof fetch;
13
16
  prompt?: (promptLabel: string) => Promise<string>;
17
+ now?: Date;
14
18
  stderr?: TerminalWriter;
15
19
  suppressCommanderErrors?: boolean;
20
+ updateCommandRunner?: UpdateCommandRunner;
21
+ currentVersion?: string;
16
22
  }
17
23
  export interface CliRunOptions extends CliProgramOptions {
18
24
  stderr?: TerminalWriter;
19
25
  }
20
26
  export declare function createCliProgram(options?: CliProgramOptions): Command;
21
27
  export declare function run(argv?: string[], options?: CliRunOptions): Promise<void>;
22
- export { runBetaCommand, runHistoricalReturnCommand, runVarCommand, } from "../commands/analytics.js";
23
- export { runAuthLoginCommand, runAuthLogoutCommand } from "../commands/auth.js";
28
+ export { runAuthLoginCommand, runAuthLogoutCommand, runAuthWhoamiCommand, } from "../commands/auth.js";
24
29
  export { runAssetOverviewCommand } from "../commands/assets.js";
25
30
  export { runCapabilitiesCommand, runStatusCommand };
26
31
  export { runInitCommand };
27
32
  export { runMarketAssetsCommand, runMarketPriceCommand };
28
- export { runPortfolioAddAssetsCommand, runPortfolioCreateCommand, runPortfolioGetCommand, runPortfolioListCommand, runPortfolioRemoveAssetsCommand, runPortfolioRenameCommand, };
33
+ export { runRankingsCurrentCommand, runRankingsListCommand };
34
+ export { runScreeningIndicatorsCommand, runScreeningRunCommand, runScreeningUniversesCommand, };
35
+ export { runHoldingBetaCommand, runHoldingCreateCommand, runHoldingGetCommand, runHoldingHistoricalReturnCommand, runHoldingListCommand, runHoldingRenameCommand, runHoldingSetPositionsCommand, runHoldingSetTargetsCommand, runHoldingVarCommand, runWatchlistAddAssetsCommand, runWatchlistCreateCommand, runWatchlistGetCommand, runWatchlistListCommand, runWatchlistRemoveAssetsCommand, runWatchlistRenameCommand, };
29
36
  export { runSkillsInstallCommand };
37
+ export { runUpdateCommand };
30
38
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAapC,OAAO,EACL,KAAK,qBAAqB,EAE1B,sBAAsB,EACvB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAGL,sBAAsB,EACtB,qBAAqB,EACtB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAGL,cAAc,EACf,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAGL,4BAA4B,EAC5B,yBAAyB,EACzB,sBAAsB,EACtB,uBAAuB,EACvB,+BAA+B,EAC/B,yBAAyB,EAC1B,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAGL,uBAAuB,EACxB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAGL,gBAAgB,EACjB,MAAM,uBAAuB,CAAC;AAO/B,OAAO,EAAqB,KAAK,cAAc,EAAE,MAAM,eAAe,CAAC;AAEvE,MAAM,WAAW,iBAAiB;IAChC,EAAE,CAAC,EAAE,qBAAqB,CAAC;IAC3B,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;IAClD,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,uBAAuB,CAAC,EAAE,OAAO,CAAC;CACnC;AAED,MAAM,WAAW,aAAc,SAAQ,iBAAiB;IACtD,MAAM,CAAC,EAAE,cAAc,CAAC;CACzB;AAED,wBAAgB,gBAAgB,CAAC,OAAO,GAAE,iBAAsB,GAAG,OAAO,CA+DzE;AAED,wBAAsB,GAAG,CACvB,IAAI,WAAe,EACnB,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,IAAI,CAAC,CA0Bf;AAiBD,OAAO,EACL,cAAc,EACd,0BAA0B,EAC1B,aAAa,GACd,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAChF,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,CAAC;AAC1B,OAAO,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,CAAC;AACzD,OAAO,EACL,4BAA4B,EAC5B,yBAAyB,EACzB,sBAAsB,EACtB,uBAAuB,EACvB,+BAA+B,EAC/B,yBAAyB,GAC1B,CAAC;AACF,OAAO,EAAE,uBAAuB,EAAE,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAUpC,OAAO,EACL,KAAK,qBAAqB,EAE1B,sBAAsB,EACvB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAGL,sBAAsB,EACtB,qBAAqB,EACtB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAGL,cAAc,EACf,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAGL,uBAAuB,EACvB,qBAAqB,EACrB,oBAAoB,EACpB,iCAAiC,EACjC,qBAAqB,EACrB,uBAAuB,EACvB,6BAA6B,EAC7B,2BAA2B,EAC3B,oBAAoB,EACpB,4BAA4B,EAC5B,yBAAyB,EACzB,sBAAsB,EACtB,uBAAuB,EACvB,+BAA+B,EAC/B,yBAAyB,EAC1B,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAGL,yBAAyB,EACzB,sBAAsB,EACvB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAGL,6BAA6B,EAC7B,sBAAsB,EACtB,4BAA4B,EAC7B,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAGL,uBAAuB,EACxB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAGL,gBAAgB,EACjB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAEL,gBAAgB,EAEhB,KAAK,mBAAmB,EACzB,MAAM,uBAAuB,CAAC;AAO/B,OAAO,EAAqB,KAAK,cAAc,EAAE,MAAM,eAAe,CAAC;AAQvE,MAAM,WAAW,iBAAiB;IAChC,EAAE,CAAC,EAAE,qBAAqB,CAAC;IAC3B,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;IAClD,GAAG,CAAC,EAAE,IAAI,CAAC;IACX,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,mBAAmB,CAAC,EAAE,mBAAmB,CAAC;IAC1C,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,aAAc,SAAQ,iBAAiB;IACtD,MAAM,CAAC,EAAE,cAAc,CAAC;CACzB;AAED,wBAAgB,gBAAgB,CAAC,OAAO,GAAE,iBAAsB,GAAG,OAAO,CAgFzE;AAeD,wBAAsB,GAAG,CACvB,IAAI,WAAe,EACnB,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,IAAI,CAAC,CA8Bf;AAoCD,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,CAAC;AAC1B,OAAO,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,CAAC;AACzD,OAAO,EAAE,yBAAyB,EAAE,sBAAsB,EAAE,CAAC;AAC7D,OAAO,EACL,6BAA6B,EAC7B,sBAAsB,EACtB,4BAA4B,GAC7B,CAAC;AACF,OAAO,EACL,qBAAqB,EACrB,uBAAuB,EACvB,oBAAoB,EACpB,iCAAiC,EACjC,qBAAqB,EACrB,uBAAuB,EACvB,6BAA6B,EAC7B,2BAA2B,EAC3B,oBAAoB,EACpB,4BAA4B,EAC5B,yBAAyB,EACzB,sBAAsB,EACtB,uBAAuB,EACvB,+BAA+B,EAC/B,yBAAyB,GAC1B,CAAC;AACF,OAAO,EAAE,uBAAuB,EAAE,CAAC;AACnC,OAAO,EAAE,gBAAgB,EAAE,CAAC"}
package/dist/cli/index.js CHANGED
@@ -1,15 +1,21 @@
1
+ import { createRequire } from "node:module";
1
2
  import { Command } from "commander";
2
- import { registerAnalyticsCommands, } from "../commands/analytics.js";
3
3
  import { registerAssetsCommands, } from "../commands/assets.js";
4
- import { registerAuthCommands, } from "../commands/auth.js";
4
+ import { registerAuthCommands, runAuthWhoamiCommand, } from "../commands/auth.js";
5
5
  import { registerCapabilitiesCommand, runCapabilitiesCommand, } from "../commands/capabilities.js";
6
6
  import { registerMarketCommands, runMarketAssetsCommand, runMarketPriceCommand, } from "../commands/market.js";
7
7
  import { registerInitCommand, runInitCommand, } from "../commands/init.js";
8
- import { registerPortfoliosCommands, runPortfolioAddAssetsCommand, runPortfolioCreateCommand, runPortfolioGetCommand, runPortfolioListCommand, runPortfolioRemoveAssetsCommand, runPortfolioRenameCommand, } from "../commands/portfolios.js";
8
+ import { registerPortfoliosCommands, runHoldingCreateCommand, runHoldingBetaCommand, runHoldingGetCommand, runHoldingHistoricalReturnCommand, runHoldingListCommand, runHoldingRenameCommand, runHoldingSetPositionsCommand, runHoldingSetTargetsCommand, runHoldingVarCommand, runWatchlistAddAssetsCommand, runWatchlistCreateCommand, runWatchlistGetCommand, runWatchlistListCommand, runWatchlistRemoveAssetsCommand, runWatchlistRenameCommand, } from "../commands/portfolios.js";
9
+ import { registerRankingsCommands, runRankingsCurrentCommand, runRankingsListCommand, } from "../commands/rankings.js";
10
+ import { registerScreeningCommands, runScreeningIndicatorsCommand, runScreeningRunCommand, runScreeningUniversesCommand, } from "../commands/screening.js";
9
11
  import { registerSkillsCommands, runSkillsInstallCommand, } from "../commands/skills.js";
10
12
  import { registerStatusFlag, runStatusCommand, } from "../commands/status.js";
13
+ import { registerUpdateCommand, runUpdateCommand, } from "../commands/update.js";
11
14
  import { buildCliErrorPayload, formatCliErrorMessage, normalizeCliError, shouldEmitJsonError, } from "./errors.js";
12
15
  import { styleErrorMessage } from "./terminal.js";
16
+ const requirePackage = createRequire(import.meta.url);
17
+ const cliPackageJson = requirePackage("../../package.json");
18
+ const CLI_VERSION = cliPackageJson.version ?? "0.0.0";
13
19
  export function createCliProgram(options = {}) {
14
20
  const program = new Command();
15
21
  const authContext = {
@@ -22,11 +28,6 @@ export function createCliProgram(options = {}) {
22
28
  env: options.env,
23
29
  fetch: options.fetch,
24
30
  };
25
- const analyticsContext = {
26
- io: options.io,
27
- env: options.env,
28
- fetch: options.fetch,
29
- };
30
31
  const marketContext = {
31
32
  io: options.io,
32
33
  env: options.env,
@@ -42,6 +43,17 @@ export function createCliProgram(options = {}) {
42
43
  io: options.io,
43
44
  env: options.env,
44
45
  fetch: options.fetch,
46
+ now: options.now,
47
+ };
48
+ const rankingsContext = {
49
+ io: options.io,
50
+ env: options.env,
51
+ fetch: options.fetch,
52
+ };
53
+ const screeningContext = {
54
+ io: options.io,
55
+ env: options.env,
56
+ fetch: options.fetch,
45
57
  };
46
58
  const skillsContext = {
47
59
  io: options.io,
@@ -51,25 +63,45 @@ export function createCliProgram(options = {}) {
51
63
  io: options.io,
52
64
  env: options.env,
53
65
  };
66
+ const updateContext = {
67
+ io: options.io,
68
+ env: options.env,
69
+ prompt: options.prompt,
70
+ commandRunner: options.updateCommandRunner,
71
+ currentVersion: options.currentVersion ?? CLI_VERSION,
72
+ };
54
73
  program
55
74
  .name("quantbrasil")
56
- .description("Public QuantBrasil CLI for deterministic operations")
57
- .version("0.0.0")
75
+ .description("CLI pública do QuantBrasil para operações determinísticas")
76
+ .version(CLI_VERSION)
77
+ .helpOption("-h, --help", "Exibe ajuda do comando")
58
78
  .exitOverride()
59
79
  .showHelpAfterError()
60
80
  .showSuggestionAfterError();
61
81
  configureCommanderOutput(program, options);
62
82
  registerCapabilitiesCommand(program, options.io);
63
83
  registerAuthCommands(program, authContext);
84
+ registerWhoamiCommand(program, authContext);
64
85
  registerAssetsCommands(program, assetsContext);
65
- registerAnalyticsCommands(program, analyticsContext);
66
86
  registerInitCommand(program, initContext);
67
87
  registerMarketCommands(program, marketContext);
68
88
  registerPortfoliosCommands(program, portfoliosContext);
89
+ registerRankingsCommands(program, rankingsContext);
90
+ registerScreeningCommands(program, screeningContext);
69
91
  registerSkillsCommands(program, skillsContext);
92
+ registerUpdateCommand(program, updateContext);
70
93
  registerStatusFlag(program, statusContext);
71
94
  return program;
72
95
  }
96
+ function registerWhoamiCommand(program, context) {
97
+ program
98
+ .command("whoami")
99
+ .description("Show the authenticated QuantBrasil user")
100
+ .option("--json", "Show JSON output")
101
+ .action(async (options) => {
102
+ await runAuthWhoamiCommand(options, context);
103
+ });
104
+ }
73
105
  export async function run(argv = process.argv, options = {}) {
74
106
  const emitJsonError = shouldEmitJsonError(argv);
75
107
  const program = createCliProgram({
@@ -82,6 +114,9 @@ export async function run(argv = process.argv, options = {}) {
82
114
  await program.parseAsync(argv);
83
115
  }
84
116
  catch (error) {
117
+ if (isCommanderDisplayExit(error)) {
118
+ return;
119
+ }
85
120
  const cliError = normalizeCliError(error);
86
121
  if (emitJsonError) {
87
122
  stderr.write(`${JSON.stringify(buildCliErrorPayload(cliError), null, 2)}\n`);
@@ -93,8 +128,12 @@ export async function run(argv = process.argv, options = {}) {
93
128
  }
94
129
  }
95
130
  function configureCommanderOutput(program, options) {
131
+ const stdout = options.io?.stdout ?? process.stdout;
96
132
  const stderr = options.stderr ?? process.stderr;
97
133
  program.configureOutput({
134
+ writeOut: chunk => {
135
+ stdout.write(chunk);
136
+ },
98
137
  writeErr: chunk => {
99
138
  if (!options.suppressCommanderErrors) {
100
139
  stderr.write(chunk);
@@ -102,11 +141,22 @@ function configureCommanderOutput(program, options) {
102
141
  },
103
142
  });
104
143
  }
105
- export { runBetaCommand, runHistoricalReturnCommand, runVarCommand, } from "../commands/analytics.js";
106
- export { runAuthLoginCommand, runAuthLogoutCommand } from "../commands/auth.js";
144
+ function isCommanderDisplayExit(error) {
145
+ if (!(error instanceof Error) ||
146
+ !("code" in error) ||
147
+ typeof error.code !== "string") {
148
+ return false;
149
+ }
150
+ return (error.code === "commander.helpDisplayed" ||
151
+ error.code === "commander.version");
152
+ }
153
+ export { runAuthLoginCommand, runAuthLogoutCommand, runAuthWhoamiCommand, } from "../commands/auth.js";
107
154
  export { runAssetOverviewCommand } from "../commands/assets.js";
108
155
  export { runCapabilitiesCommand, runStatusCommand };
109
156
  export { runInitCommand };
110
157
  export { runMarketAssetsCommand, runMarketPriceCommand };
111
- export { runPortfolioAddAssetsCommand, runPortfolioCreateCommand, runPortfolioGetCommand, runPortfolioListCommand, runPortfolioRemoveAssetsCommand, runPortfolioRenameCommand, };
158
+ export { runRankingsCurrentCommand, runRankingsListCommand };
159
+ export { runScreeningIndicatorsCommand, runScreeningRunCommand, runScreeningUniversesCommand, };
160
+ export { runHoldingBetaCommand, runHoldingCreateCommand, runHoldingGetCommand, runHoldingHistoricalReturnCommand, runHoldingListCommand, runHoldingRenameCommand, runHoldingSetPositionsCommand, runHoldingSetTargetsCommand, runHoldingVarCommand, runWatchlistAddAssetsCommand, runWatchlistCreateCommand, runWatchlistGetCommand, runWatchlistListCommand, runWatchlistRemoveAssetsCommand, runWatchlistRenameCommand, };
112
161
  export { runSkillsInstallCommand };
162
+ export { runUpdateCommand };
@@ -1,2 +1,3 @@
1
1
  export declare function promptForSecret(promptLabel: string): Promise<string>;
2
+ export declare function promptForConfirmation(promptLabel: string): Promise<boolean>;
2
3
  //# sourceMappingURL=prompt.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../../src/cli/prompt.ts"],"names":[],"mappings":"AAyBA,wBAAsB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAwB1E"}
1
+ {"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../../src/cli/prompt.ts"],"names":[],"mappings":"AAyBA,wBAAsB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAwB1E;AAED,wBAAsB,qBAAqB,CACzC,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,OAAO,CAAC,CAmBlB"}
@@ -38,3 +38,20 @@ export async function promptForSecret(promptLabel) {
38
38
  readline.close();
39
39
  }
40
40
  }
41
+ export async function promptForConfirmation(promptLabel) {
42
+ if (!input.isTTY || !output.isTTY) {
43
+ throw createCliConfigError("Confirmação interativa requer um TTY. Use --yes para aplicar a atualização.");
44
+ }
45
+ const readline = createInterface({
46
+ input,
47
+ output,
48
+ terminal: true,
49
+ });
50
+ try {
51
+ const answer = await readline.question(promptLabel);
52
+ return ["s", "sim", "y", "yes"].includes(answer.trim().toLowerCase());
53
+ }
54
+ finally {
55
+ readline.close();
56
+ }
57
+ }
@@ -20,7 +20,16 @@ export interface SkillInstallResult {
20
20
  installed: InstalledSkillTarget[];
21
21
  skipped: SkippedSkillTarget[];
22
22
  }
23
+ export type SkillInstallStatus = "current" | "missing" | "stale" | "skipped";
24
+ export interface SkillInstallTargetStatus extends SkillInstallTarget {
25
+ status: SkillInstallStatus;
26
+ }
27
+ export interface SkillInstallState {
28
+ targets: SkillInstallTargetStatus[];
29
+ needsInstall: boolean;
30
+ }
23
31
  export declare function installBundledSkillEverywhere(env?: NodeJS.ProcessEnv): Promise<SkillInstallResult>;
32
+ export declare function getBundledSkillInstallState(env?: NodeJS.ProcessEnv): Promise<SkillInstallState>;
24
33
  export declare function resolveSkillInstallTargets(env?: NodeJS.ProcessEnv): SkillInstallTarget[];
25
34
  export declare function resolveBundledSkillSourcePath(): string;
26
35
  //# sourceMappingURL=skills.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"skills.d.ts","sourceRoot":"","sources":["../../src/cli/skills.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,sBAAsB,GAAG,OAAO,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAEnE,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,sBAAsB,CAAC;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,sBAAsB,CAAC;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,sBAAsB,CAAC;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,oBAAoB,EAAE,CAAC;IAClC,OAAO,EAAE,kBAAkB,EAAE,CAAC;CAC/B;AAcD,wBAAsB,6BAA6B,CACjD,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,OAAO,CAAC,kBAAkB,CAAC,CAmD7B;AAED,wBAAgB,0BAA0B,CACxC,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,kBAAkB,EAAE,CAetB;AAED,wBAAgB,6BAA6B,IAAI,MAAM,CAEtD"}
1
+ {"version":3,"file":"skills.d.ts","sourceRoot":"","sources":["../../src/cli/skills.ts"],"names":[],"mappings":"AAOA,MAAM,MAAM,sBAAsB,GAAG,OAAO,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAEnE,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,sBAAsB,CAAC;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,sBAAsB,CAAC;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,sBAAsB,CAAC;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,oBAAoB,EAAE,CAAC;IAClC,OAAO,EAAE,kBAAkB,EAAE,CAAC;CAC/B;AAED,MAAM,MAAM,kBAAkB,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;AAE7E,MAAM,WAAW,wBAAyB,SAAQ,kBAAkB;IAClE,MAAM,EAAE,kBAAkB,CAAC;CAC5B;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,wBAAwB,EAAE,CAAC;IACpC,YAAY,EAAE,OAAO,CAAC;CACvB;AAcD,wBAAsB,6BAA6B,CACjD,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,OAAO,CAAC,kBAAkB,CAAC,CAmD7B;AAED,wBAAsB,2BAA2B,CAC/C,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,OAAO,CAAC,iBAAiB,CAAC,CA0C5B;AAED,wBAAgB,0BAA0B,CACxC,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,kBAAkB,EAAE,CAetB;AAED,wBAAgB,6BAA6B,IAAI,MAAM,CAEtD"}
@@ -1,4 +1,5 @@
1
- import { access, cp, mkdir, rm } from "node:fs/promises";
1
+ import { createHash } from "node:crypto";
2
+ import { access, cp, mkdir, readdir, readFile, rm } from "node:fs/promises";
2
3
  import { homedir } from "node:os";
3
4
  import { dirname, join } from "node:path";
4
5
  import { fileURLToPath } from "node:url";
@@ -45,13 +46,46 @@ export async function installBundledSkillEverywhere(env = process.env) {
45
46
  }
46
47
  if (installed.length === 0) {
47
48
  const checkedRoots = targets.map(target => target.rootDir).join(", ");
48
- throw createCliConfigError(`No supported agent clients detected. Checked: ${checkedRoots}.`);
49
+ throw createCliConfigError(`Nenhum cliente de agente compatível detectado. Verificados: ${checkedRoots}.`);
49
50
  }
50
51
  return {
51
52
  installed,
52
53
  skipped,
53
54
  };
54
55
  }
56
+ export async function getBundledSkillInstallState(env = process.env) {
57
+ const bundledSkillPath = resolveBundledSkillSourcePath();
58
+ await assertBundledSkillExists(bundledSkillPath);
59
+ const bundledHash = await hashDirectory(bundledSkillPath);
60
+ const targets = [];
61
+ for (const target of resolveSkillInstallTargets(env)) {
62
+ if (target.id !== AGENT_SKILLS_CONVENTION_ID &&
63
+ !(await pathExists(target.rootDir))) {
64
+ targets.push({
65
+ ...target,
66
+ status: "skipped",
67
+ });
68
+ continue;
69
+ }
70
+ if (!(await pathExists(join(target.installDir, "SKILL.md")))) {
71
+ targets.push({
72
+ ...target,
73
+ status: "missing",
74
+ });
75
+ continue;
76
+ }
77
+ targets.push({
78
+ ...target,
79
+ status: (await hashDirectory(target.installDir)) === bundledHash
80
+ ? "current"
81
+ : "stale",
82
+ });
83
+ }
84
+ return {
85
+ targets,
86
+ needsInstall: targets.some(target => target.status === "missing" || target.status === "stale"),
87
+ };
88
+ }
55
89
  export function resolveSkillInstallTargets(env = process.env) {
56
90
  const home = resolveCliHomeDirectory(env);
57
91
  return SUPPORTED_SKILL_CLIENTS.map(client => {
@@ -74,12 +108,42 @@ async function assertBundledSkillExists(skillPath) {
74
108
  if (await pathExists(skillEntryPath)) {
75
109
  return;
76
110
  }
77
- throw createCliConfigError(`Bundled QuantBrasil skill not found at ${skillEntryPath}. Reinstall the CLI package.`);
111
+ throw createCliConfigError(`Skill QuantBrasil empacotada não encontrada em ${skillEntryPath}. Reinstale o pacote da CLI.`);
112
+ }
113
+ async function hashDirectory(directory) {
114
+ const hash = createHash("sha256");
115
+ const files = await collectDirectoryFiles(directory);
116
+ for (const file of files) {
117
+ hash.update(file.relativePath);
118
+ hash.update("\0");
119
+ hash.update(await readFile(file.fullPath));
120
+ hash.update("\0");
121
+ }
122
+ return hash.digest("hex");
123
+ }
124
+ async function collectDirectoryFiles(current, relativePrefix = "") {
125
+ const entries = await readdir(current, { withFileTypes: true });
126
+ const sortedEntries = entries.sort((left, right) => left.name.localeCompare(right.name));
127
+ const files = [];
128
+ for (const entry of sortedEntries) {
129
+ const fullPath = join(current, entry.name);
130
+ const relativePath = relativePrefix
131
+ ? `${relativePrefix}/${entry.name}`
132
+ : entry.name;
133
+ if (entry.isDirectory()) {
134
+ files.push(...(await collectDirectoryFiles(fullPath, relativePath)));
135
+ continue;
136
+ }
137
+ if (entry.isFile()) {
138
+ files.push({ fullPath, relativePath });
139
+ }
140
+ }
141
+ return files;
78
142
  }
79
143
  function resolveCliHomeDirectory(env) {
80
144
  const home = env.HOME?.trim() || homedir();
81
145
  if (!home) {
82
- throw createCliConfigError("Could not resolve the HOME directory for skill install.");
146
+ throw createCliConfigError("Não foi possível resolver o diretório HOME para instalar a skill.");
83
147
  }
84
148
  return home;
85
149
  }
@@ -11,7 +11,25 @@ export interface AuthCommandContext {
11
11
  export interface AuthLoginCommandOptions {
12
12
  apiKey: string;
13
13
  }
14
+ export interface AuthWhoamiCommandOptions {
15
+ json?: boolean;
16
+ }
17
+ export interface AuthWhoamiOutput {
18
+ ok: true;
19
+ user_id: number;
20
+ email: string;
21
+ name: string;
22
+ is_premium: boolean;
23
+ auth_source: "env" | "config";
24
+ api_key: {
25
+ id: number;
26
+ name: string;
27
+ key_prefix: string;
28
+ scopes: string[];
29
+ };
30
+ }
14
31
  export declare function registerAuthCommands(program: Command, context?: AuthCommandContext): void;
15
32
  export declare function runAuthLoginCommand(options: AuthLoginCommandOptions, context?: AuthCommandContext): Promise<void>;
16
33
  export declare function runAuthLogoutCommand(context?: AuthCommandContext): Promise<void>;
34
+ export declare function runAuthWhoamiCommand(options?: AuthWhoamiCommandOptions, context?: AuthCommandContext): Promise<void>;
17
35
  //# sourceMappingURL=auth.d.ts.map
@@ -1 +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"}
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,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,MAAM,WAAW,wBAAwB;IACvC,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,IAAI,CAAC;IACT,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,OAAO,CAAC;IACpB,WAAW,EAAE,KAAK,GAAG,QAAQ,CAAC;IAC9B,OAAO,EAAE;QACP,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,UAAU,EAAE,MAAM,CAAC;QACnB,MAAM,EAAE,MAAM,EAAE,CAAC;KAClB,CAAC;CACH;AAED,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,OAAO,EAChB,OAAO,GAAE,kBAAuB,GAC/B,IAAI,CA2BN;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;AAED,wBAAsB,oBAAoB,CACxC,OAAO,GAAE,wBAA6B,EACtC,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,IAAI,CAAC,CA6Bf"}
@@ -1,4 +1,5 @@
1
1
  import { verifyCliApiKey } from "../cli/auth.js";
2
+ import { resolveRequiredCliAuth } from "../cli/client.js";
2
3
  import { clearCliStoredAuth, saveCliApiKey } from "../cli/config.js";
3
4
  import { createTerminalTheme } from "../cli/terminal.js";
4
5
  export function registerAuthCommands(program, context = {}) {
@@ -18,6 +19,13 @@ export function registerAuthCommands(program, context = {}) {
18
19
  .action(async () => {
19
20
  await runAuthLogoutCommand(context);
20
21
  });
22
+ authCommand
23
+ .command("whoami")
24
+ .description("Show the authenticated QuantBrasil user")
25
+ .option("--json", "Show JSON output")
26
+ .action(async (options) => {
27
+ await runAuthWhoamiCommand(options, context);
28
+ });
21
29
  }
22
30
  export async function runAuthLoginCommand(options, context = {}) {
23
31
  const stdout = getStdout(context);
@@ -43,6 +51,47 @@ export async function runAuthLogoutCommand(context = {}) {
43
51
  }
44
52
  stdout.write(`${theme.dim(`No local API key was stored at ${configPath}.`)}\n`);
45
53
  }
54
+ export async function runAuthWhoamiCommand(options = {}, context = {}) {
55
+ const stdout = getStdout(context);
56
+ const theme = createTerminalTheme(stdout, context.env ?? process.env);
57
+ const auth = await resolveRequiredCliAuth(context.env ?? process.env);
58
+ const verifiedAuth = await verifyCliApiKey(auth.apiKey, {
59
+ env: context.env,
60
+ fetch: context.fetch,
61
+ });
62
+ const output = {
63
+ ok: true,
64
+ user_id: verifiedAuth.userId,
65
+ email: verifiedAuth.email,
66
+ name: verifiedAuth.name,
67
+ is_premium: verifiedAuth.isPremium,
68
+ auth_source: auth.source,
69
+ api_key: {
70
+ id: verifiedAuth.apiKey.id,
71
+ name: verifiedAuth.apiKey.name,
72
+ key_prefix: verifiedAuth.apiKey.keyPrefix,
73
+ scopes: verifiedAuth.apiKey.scopes,
74
+ },
75
+ };
76
+ if (options.json) {
77
+ stdout.write(`${JSON.stringify(output, null, 2)}\n`);
78
+ return;
79
+ }
80
+ stdout.write(`${formatAuthWhoamiHuman(output, theme)}\n`);
81
+ }
82
+ function formatAuthWhoamiHuman(data, theme) {
83
+ const source = data.auth_source === "env" ? "QUANTBRASIL_API_KEY" : "local config";
84
+ return [
85
+ theme.label("QuantBrasil user"),
86
+ "",
87
+ `${theme.label("Email:")} ${theme.bold(data.email)}`,
88
+ `${theme.label("Name:")} ${data.name}`,
89
+ `${theme.label("User ID:")} ${data.user_id}`,
90
+ `${theme.label("Premium:")} ${data.is_premium ? "yes" : "no"}`,
91
+ `${theme.label("API key:")} ${data.api_key.name} ${theme.dim(`(${data.api_key.key_prefix})`)}`,
92
+ `${theme.label("Auth source:")} ${source}`,
93
+ ].join("\n");
94
+ }
46
95
  function getStdout(context) {
47
96
  return context.io?.stdout ?? process.stdout;
48
97
  }
@@ -7,6 +7,7 @@ export interface MarketCommandIO {
7
7
  }
8
8
  export interface MarketAssetsCommandOptions {
9
9
  type?: string;
10
+ search?: string;
10
11
  json?: boolean;
11
12
  }
12
13
  export interface MarketPriceCommandOptions {
@@ -1 +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"}
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,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,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,CA4BN;AAED,wBAAsB,sBAAsB,CAC1C,OAAO,EAAE,0BAA0B,EACnC,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,IAAI,CAAC,CAyBf;AAED,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,yBAAyB,EAClC,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,IAAI,CAAC,CAgBf;AAmDD,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"}
@@ -10,6 +10,7 @@ export function registerMarketCommands(program, context = {}) {
10
10
  .command("assets")
11
11
  .description("List the monitored QuantBrasil asset universe")
12
12
  .option("--type <type>", `Filter by exact asset type (${monitoredAssetTypes.join(", ")})`)
13
+ .option("--search <text>", "Filter monitored tickers by text")
13
14
  .option("--json", "Show JSON output")
14
15
  .action(async (options) => {
15
16
  await runMarketAssetsCommand(options, context);
@@ -29,9 +30,17 @@ export async function runMarketAssetsCommand(options, context = {}) {
29
30
  const stdout = context.io?.stdout ?? process.stdout;
30
31
  const theme = createTerminalTheme(stdout, context.env ?? process.env);
31
32
  const assetType = normalizeMarketAssetType(options.type);
33
+ const search = normalizeMarketAssetSearch(options.search);
34
+ const input = {};
35
+ if (assetType) {
36
+ input.type = assetType;
37
+ }
38
+ if (search) {
39
+ input.search = search;
40
+ }
32
41
  const response = await invokeCliCapability({
33
42
  capability: "market.assets",
34
- input: assetType ? { type: assetType } : {},
43
+ input,
35
44
  env: context.env,
36
45
  fetch: context.fetch,
37
46
  });
@@ -69,6 +78,13 @@ function normalizeMarketAssetType(rawType) {
69
78
  }
70
79
  return normalized;
71
80
  }
81
+ function normalizeMarketAssetSearch(rawSearch) {
82
+ if (!rawSearch) {
83
+ return undefined;
84
+ }
85
+ const normalized = rawSearch.trim();
86
+ return normalized || undefined;
87
+ }
72
88
  function buildMarketPriceInput(ticker, options) {
73
89
  const payload = {
74
90
  ticker,