@quantbrasil/cli 0.1.0-beta.7 → 0.1.0-beta.8
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 +8 -0
- package/dist/cli/index.d.ts +6 -2
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +14 -3
- package/dist/cli/prompt.d.ts +1 -0
- package/dist/cli/prompt.d.ts.map +1 -1
- package/dist/cli/prompt.js +17 -0
- package/dist/cli/skills.d.ts +9 -0
- package/dist/cli/skills.d.ts.map +1 -1
- package/dist/cli/skills.js +68 -4
- package/dist/commands/screening.d.ts +44 -0
- package/dist/commands/screening.d.ts.map +1 -1
- package/dist/commands/screening.js +63 -0
- package/dist/commands/skills.js +7 -7
- package/dist/commands/update.d.ts +23 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/update.js +209 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/vendor/core/capabilities/registry.d.ts +54 -0
- package/dist/vendor/core/capabilities/registry.d.ts.map +1 -1
- package/dist/vendor/core/capabilities/screening.d.ts +27 -0
- package/dist/vendor/core/capabilities/screening.d.ts.map +1 -1
- package/dist/vendor/core/capabilities/screening.js +31 -0
- package/package.json +3 -3
- package/skills/quantbrasil/SKILL.md +3 -1
- package/skills/quantbrasil/references/cli.md +5 -0
- package/skills/quantbrasil/references/costs.md +2 -0
- package/skills/quantbrasil/references/quality-eval-queries.json +5 -0
- package/skills/quantbrasil/references/screening.md +212 -0
- package/skills/quantbrasil/references/workflows.md +6 -3
package/README.md
CHANGED
|
@@ -31,6 +31,7 @@ that file only exists inside this package.
|
|
|
31
31
|
node ./bin/quantbrasil.js auth login --api-key qb_live_<id>.<secret>
|
|
32
32
|
node ./bin/quantbrasil.js whoami
|
|
33
33
|
node ./bin/quantbrasil.js skills install --all
|
|
34
|
+
node ./bin/quantbrasil.js update
|
|
34
35
|
node ./bin/quantbrasil.js --status
|
|
35
36
|
node ./bin/quantbrasil.js auth logout
|
|
36
37
|
```
|
|
@@ -73,6 +74,7 @@ quantbrasil holdings historical-return 182 --period 1y
|
|
|
73
74
|
quantbrasil holdings beta 182 --years 3
|
|
74
75
|
quantbrasil holdings var 182 --years 1 --confidence 95
|
|
75
76
|
quantbrasil screening universes
|
|
77
|
+
quantbrasil screening indicators
|
|
76
78
|
quantbrasil screening run --system acoes-mais-liquidas --query-file ./screening.json
|
|
77
79
|
quantbrasil screening run --watchlist 93 --query-file ./screening.json --limit 25
|
|
78
80
|
cat ./screening.json | quantbrasil screening run --holding 182 --query-file -
|
|
@@ -144,8 +146,14 @@ quantbrasil init
|
|
|
144
146
|
quantbrasil --status
|
|
145
147
|
quantbrasil auth login --api-key qb_live_<id>.<secret>
|
|
146
148
|
quantbrasil skills install --all
|
|
149
|
+
quantbrasil update
|
|
147
150
|
```
|
|
148
151
|
|
|
152
|
+
`quantbrasil update` checks the current global package against
|
|
153
|
+
`@quantbrasil/cli@beta`, checks whether the bundled skill is missing or stale,
|
|
154
|
+
shows the planned actions, and asks for confirmation before updating. Use
|
|
155
|
+
`quantbrasil update --yes` only in noninteractive automation.
|
|
156
|
+
|
|
149
157
|
## Publishing
|
|
150
158
|
|
|
151
159
|
Publish from `monorepo/packages/cli`. The package build vendors the private
|
package/dist/cli/index.d.ts
CHANGED
|
@@ -3,9 +3,10 @@ import { type CapabilitiesCommandIO, runCapabilitiesCommand } from "../commands/
|
|
|
3
3
|
import { runMarketAssetsCommand, runMarketPriceCommand } from "../commands/market.js";
|
|
4
4
|
import { runInitCommand } from "../commands/init.js";
|
|
5
5
|
import { runHoldingCreateCommand, runHoldingBetaCommand, runHoldingGetCommand, runHoldingHistoricalReturnCommand, runHoldingListCommand, runHoldingRenameCommand, runHoldingSetPositionsCommand, runHoldingSetTargetsCommand, runHoldingVarCommand, runWatchlistAddAssetsCommand, runWatchlistCreateCommand, runWatchlistGetCommand, runWatchlistListCommand, runWatchlistRemoveAssetsCommand, runWatchlistRenameCommand } from "../commands/portfolios.js";
|
|
6
|
-
import { runScreeningRunCommand, runScreeningUniversesCommand } from "../commands/screening.js";
|
|
6
|
+
import { runScreeningIndicatorsCommand, runScreeningRunCommand, runScreeningUniversesCommand } from "../commands/screening.js";
|
|
7
7
|
import { runSkillsInstallCommand } from "../commands/skills.js";
|
|
8
8
|
import { runStatusCommand } from "../commands/status.js";
|
|
9
|
+
import { runUpdateCommand, type UpdateCommandRunner } from "../commands/update.js";
|
|
9
10
|
import { type TerminalWriter } from "./terminal.js";
|
|
10
11
|
export interface CliProgramOptions {
|
|
11
12
|
io?: CapabilitiesCommandIO;
|
|
@@ -15,6 +16,8 @@ export interface CliProgramOptions {
|
|
|
15
16
|
now?: Date;
|
|
16
17
|
stderr?: TerminalWriter;
|
|
17
18
|
suppressCommanderErrors?: boolean;
|
|
19
|
+
updateCommandRunner?: UpdateCommandRunner;
|
|
20
|
+
currentVersion?: string;
|
|
18
21
|
}
|
|
19
22
|
export interface CliRunOptions extends CliProgramOptions {
|
|
20
23
|
stderr?: TerminalWriter;
|
|
@@ -26,7 +29,8 @@ export { runAssetOverviewCommand } from "../commands/assets.js";
|
|
|
26
29
|
export { runCapabilitiesCommand, runStatusCommand };
|
|
27
30
|
export { runInitCommand };
|
|
28
31
|
export { runMarketAssetsCommand, runMarketPriceCommand };
|
|
29
|
-
export { runScreeningRunCommand, runScreeningUniversesCommand };
|
|
32
|
+
export { runScreeningIndicatorsCommand, runScreeningRunCommand, runScreeningUniversesCommand, };
|
|
30
33
|
export { runHoldingBetaCommand, runHoldingCreateCommand, runHoldingGetCommand, runHoldingHistoricalReturnCommand, runHoldingListCommand, runHoldingRenameCommand, runHoldingSetPositionsCommand, runHoldingSetTargetsCommand, runHoldingVarCommand, runWatchlistAddAssetsCommand, runWatchlistCreateCommand, runWatchlistGetCommand, runWatchlistListCommand, runWatchlistRemoveAssetsCommand, runWatchlistRenameCommand, };
|
|
31
34
|
export { runSkillsInstallCommand };
|
|
35
|
+
export { runUpdateCommand };
|
|
32
36
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/cli/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
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,sBAAsB,EACtB,4BAA4B,EAC7B,MAAM,0BAA0B,CAAC;AAClC,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;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;
|
|
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,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,CA0EzE;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,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
|
@@ -6,9 +6,10 @@ import { registerCapabilitiesCommand, runCapabilitiesCommand, } from "../command
|
|
|
6
6
|
import { registerMarketCommands, runMarketAssetsCommand, runMarketPriceCommand, } from "../commands/market.js";
|
|
7
7
|
import { registerInitCommand, runInitCommand, } from "../commands/init.js";
|
|
8
8
|
import { registerPortfoliosCommands, runHoldingCreateCommand, runHoldingBetaCommand, runHoldingGetCommand, runHoldingHistoricalReturnCommand, runHoldingListCommand, runHoldingRenameCommand, runHoldingSetPositionsCommand, runHoldingSetTargetsCommand, runHoldingVarCommand, runWatchlistAddAssetsCommand, runWatchlistCreateCommand, runWatchlistGetCommand, runWatchlistListCommand, runWatchlistRemoveAssetsCommand, runWatchlistRenameCommand, } from "../commands/portfolios.js";
|
|
9
|
-
import { registerScreeningCommands, runScreeningRunCommand, runScreeningUniversesCommand, } from "../commands/screening.js";
|
|
9
|
+
import { registerScreeningCommands, runScreeningIndicatorsCommand, runScreeningRunCommand, runScreeningUniversesCommand, } from "../commands/screening.js";
|
|
10
10
|
import { registerSkillsCommands, runSkillsInstallCommand, } from "../commands/skills.js";
|
|
11
11
|
import { registerStatusFlag, runStatusCommand, } from "../commands/status.js";
|
|
12
|
+
import { registerUpdateCommand, runUpdateCommand, } from "../commands/update.js";
|
|
12
13
|
import { buildCliErrorPayload, formatCliErrorMessage, normalizeCliError, shouldEmitJsonError, } from "./errors.js";
|
|
13
14
|
import { styleErrorMessage } from "./terminal.js";
|
|
14
15
|
const requirePackage = createRequire(import.meta.url);
|
|
@@ -56,10 +57,18 @@ export function createCliProgram(options = {}) {
|
|
|
56
57
|
io: options.io,
|
|
57
58
|
env: options.env,
|
|
58
59
|
};
|
|
60
|
+
const updateContext = {
|
|
61
|
+
io: options.io,
|
|
62
|
+
env: options.env,
|
|
63
|
+
prompt: options.prompt,
|
|
64
|
+
commandRunner: options.updateCommandRunner,
|
|
65
|
+
currentVersion: options.currentVersion ?? CLI_VERSION,
|
|
66
|
+
};
|
|
59
67
|
program
|
|
60
68
|
.name("quantbrasil")
|
|
61
|
-
.description("
|
|
69
|
+
.description("CLI pública do QuantBrasil para operações determinísticas")
|
|
62
70
|
.version(CLI_VERSION)
|
|
71
|
+
.helpOption("-h, --help", "Exibe ajuda do comando")
|
|
63
72
|
.exitOverride()
|
|
64
73
|
.showHelpAfterError()
|
|
65
74
|
.showSuggestionAfterError();
|
|
@@ -73,6 +82,7 @@ export function createCliProgram(options = {}) {
|
|
|
73
82
|
registerPortfoliosCommands(program, portfoliosContext);
|
|
74
83
|
registerScreeningCommands(program, screeningContext);
|
|
75
84
|
registerSkillsCommands(program, skillsContext);
|
|
85
|
+
registerUpdateCommand(program, updateContext);
|
|
76
86
|
registerStatusFlag(program, statusContext);
|
|
77
87
|
return program;
|
|
78
88
|
}
|
|
@@ -138,6 +148,7 @@ export { runAssetOverviewCommand } from "../commands/assets.js";
|
|
|
138
148
|
export { runCapabilitiesCommand, runStatusCommand };
|
|
139
149
|
export { runInitCommand };
|
|
140
150
|
export { runMarketAssetsCommand, runMarketPriceCommand };
|
|
141
|
-
export { runScreeningRunCommand, runScreeningUniversesCommand };
|
|
151
|
+
export { runScreeningIndicatorsCommand, runScreeningRunCommand, runScreeningUniversesCommand, };
|
|
142
152
|
export { runHoldingBetaCommand, runHoldingCreateCommand, runHoldingGetCommand, runHoldingHistoricalReturnCommand, runHoldingListCommand, runHoldingRenameCommand, runHoldingSetPositionsCommand, runHoldingSetTargetsCommand, runHoldingVarCommand, runWatchlistAddAssetsCommand, runWatchlistCreateCommand, runWatchlistGetCommand, runWatchlistListCommand, runWatchlistRemoveAssetsCommand, runWatchlistRenameCommand, };
|
|
143
153
|
export { runSkillsInstallCommand };
|
|
154
|
+
export { runUpdateCommand };
|
package/dist/cli/prompt.d.ts
CHANGED
package/dist/cli/prompt.d.ts.map
CHANGED
|
@@ -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"}
|
package/dist/cli/prompt.js
CHANGED
|
@@ -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
|
+
}
|
package/dist/cli/skills.d.ts
CHANGED
|
@@ -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
|
package/dist/cli/skills.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skills.d.ts","sourceRoot":"","sources":["../../src/cli/skills.ts"],"names":[],"mappings":"
|
|
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"}
|
package/dist/cli/skills.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
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(`
|
|
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(`
|
|
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("
|
|
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
|
}
|
|
@@ -8,6 +8,9 @@ export interface ScreeningCommandIO {
|
|
|
8
8
|
export interface ScreeningUniversesCommandOptions {
|
|
9
9
|
json?: boolean;
|
|
10
10
|
}
|
|
11
|
+
export interface ScreeningIndicatorsCommandOptions {
|
|
12
|
+
json?: boolean;
|
|
13
|
+
}
|
|
11
14
|
export interface ScreeningRunCommandOptions {
|
|
12
15
|
system?: string;
|
|
13
16
|
watchlist?: string;
|
|
@@ -33,6 +36,45 @@ export interface ScreeningUniversesResponse {
|
|
|
33
36
|
holdings: ScreeningUniverseOut[];
|
|
34
37
|
total: number;
|
|
35
38
|
}
|
|
39
|
+
export type ScreeningIndicatorScalar = string | number | boolean;
|
|
40
|
+
export interface ScreeningIndicatorParamOut {
|
|
41
|
+
[key: string]: JsonValue;
|
|
42
|
+
name: string;
|
|
43
|
+
type: "integer" | "number" | "enum" | "string" | "boolean";
|
|
44
|
+
required: boolean;
|
|
45
|
+
default: ScreeningIndicatorScalar | null;
|
|
46
|
+
description: string;
|
|
47
|
+
enum_values: string[] | null;
|
|
48
|
+
examples: ScreeningIndicatorScalar[];
|
|
49
|
+
}
|
|
50
|
+
export interface ScreeningIndicatorRef {
|
|
51
|
+
[key: string]: JsonValue;
|
|
52
|
+
name: string;
|
|
53
|
+
timeframe: string;
|
|
54
|
+
offset: number;
|
|
55
|
+
params: Record<string, JsonValue>;
|
|
56
|
+
}
|
|
57
|
+
export interface ScreeningIndicatorExampleOut {
|
|
58
|
+
[key: string]: JsonValue;
|
|
59
|
+
label: string;
|
|
60
|
+
description: string;
|
|
61
|
+
indicator: ScreeningIndicatorRef;
|
|
62
|
+
}
|
|
63
|
+
export interface ScreeningIndicatorOut {
|
|
64
|
+
[key: string]: JsonValue;
|
|
65
|
+
name: string;
|
|
66
|
+
display_name: string;
|
|
67
|
+
description: string;
|
|
68
|
+
timeframes: string[];
|
|
69
|
+
params: ScreeningIndicatorParamOut[];
|
|
70
|
+
examples: ScreeningIndicatorExampleOut[];
|
|
71
|
+
}
|
|
72
|
+
export interface ScreeningIndicatorsResponse {
|
|
73
|
+
[key: string]: JsonValue;
|
|
74
|
+
ok: boolean;
|
|
75
|
+
indicators: ScreeningIndicatorOut[];
|
|
76
|
+
operators: string[];
|
|
77
|
+
}
|
|
36
78
|
export interface IndicatorResult {
|
|
37
79
|
[key: string]: JsonValue;
|
|
38
80
|
value: number;
|
|
@@ -68,9 +110,11 @@ type JsonRecord = {
|
|
|
68
110
|
};
|
|
69
111
|
export declare function registerScreeningCommands(program: Command, context?: ScreeningCommandContext): void;
|
|
70
112
|
export declare function runScreeningUniversesCommand(options: ScreeningUniversesCommandOptions, context?: ScreeningCommandContext): Promise<void>;
|
|
113
|
+
export declare function runScreeningIndicatorsCommand(options: ScreeningIndicatorsCommandOptions, context?: ScreeningCommandContext): Promise<void>;
|
|
71
114
|
export declare function runScreeningRunCommand(options: ScreeningRunCommandOptions, context?: ScreeningCommandContext): Promise<void>;
|
|
72
115
|
export declare function buildScreeningRunInput(options: ScreeningRunCommandOptions): Promise<JsonRecord>;
|
|
73
116
|
export declare function formatScreeningUniversesHuman(data: ScreeningUniversesResponse, theme?: import("../cli/terminal.js").TerminalTheme): string;
|
|
117
|
+
export declare function formatScreeningIndicatorsHuman(data: ScreeningIndicatorsResponse, theme?: import("../cli/terminal.js").TerminalTheme): string;
|
|
74
118
|
export declare function formatScreeningRunHuman(data: ScreeningRunResponse, theme?: import("../cli/terminal.js").TerminalTheme): string;
|
|
75
119
|
export {};
|
|
76
120
|
//# sourceMappingURL=screening.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"screening.d.ts","sourceRoot":"","sources":["../../src/commands/screening.ts"],"names":[],"mappings":"AACA,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,kBAAkB;IACjC,MAAM,EAAE,cAAc,CAAC;CACxB;AAED,MAAM,WAAW,gCAAgC;IAC/C,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,0BAA0B;IACzC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,oBAAoB;IACnC,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,QAAQ,GAAG,WAAW,GAAG,SAAS,CAAC;IACzC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,0BAA0B;IACzC,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,oBAAoB,EAAE,CAAC;IAC/B,UAAU,EAAE,oBAAoB,EAAE,CAAC;IACnC,QAAQ,EAAE,oBAAoB,EAAE,CAAC;IACjC,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,eAAe;IAC9B,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,OAAO,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE,GAAG,IAAI,CAAC;CAC9C;AAED,MAAM,WAAW,kBAAkB;IACjC,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;CAC7C;AAED,MAAM,WAAW,gBAAgB;IAC/B,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,kBAAkB,EAAE,CAAC;CAC/B;AAED,MAAM,WAAW,oBAAoB;IACnC,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,EAAE,EAAE,OAAO,CAAC;IACZ,gBAAgB,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,oBAAoB,CAAC;IAC/B,MAAM,EAAE,gBAAgB,CAAC;CAC1B;AAED,MAAM,WAAW,uBAAwB,SAAQ,gBAAgB;IAC/D,EAAE,CAAC,EAAE,kBAAkB,CAAC;CACzB;AAED,KAAK,UAAU,GAAG;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,CAAC;AAE/C,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,OAAO,EAChB,OAAO,GAAE,uBAA4B,GACpC,IAAI,
|
|
1
|
+
{"version":3,"file":"screening.d.ts","sourceRoot":"","sources":["../../src/commands/screening.ts"],"names":[],"mappings":"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"}
|
|
@@ -14,6 +14,13 @@ export function registerScreeningCommands(program, context = {}) {
|
|
|
14
14
|
.action(async (options) => {
|
|
15
15
|
await runScreeningUniversesCommand(options, context);
|
|
16
16
|
});
|
|
17
|
+
screeningCommand
|
|
18
|
+
.command("indicators")
|
|
19
|
+
.description("Lista indicadores disponíveis para screening")
|
|
20
|
+
.option("--json", "Exibe saída JSON")
|
|
21
|
+
.action(async (options) => {
|
|
22
|
+
await runScreeningIndicatorsCommand(options, context);
|
|
23
|
+
});
|
|
17
24
|
screeningCommand
|
|
18
25
|
.command("run")
|
|
19
26
|
.description("Executa screening de indicadores a partir de um ScreenerRequest JSON")
|
|
@@ -42,6 +49,20 @@ export async function runScreeningUniversesCommand(options, context = {}) {
|
|
|
42
49
|
}
|
|
43
50
|
stdout.write(`${formatScreeningUniversesHuman(response.data, theme)}\n`);
|
|
44
51
|
}
|
|
52
|
+
export async function runScreeningIndicatorsCommand(options, context = {}) {
|
|
53
|
+
const stdout = context.io?.stdout ?? process.stdout;
|
|
54
|
+
const theme = createTerminalTheme(stdout, context.env ?? process.env);
|
|
55
|
+
const response = await invokeCliCapability({
|
|
56
|
+
capability: "screening.indicators",
|
|
57
|
+
env: context.env,
|
|
58
|
+
fetch: context.fetch,
|
|
59
|
+
});
|
|
60
|
+
if (options.json) {
|
|
61
|
+
stdout.write(`${JSON.stringify(response.data, null, 2)}\n`);
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
stdout.write(`${formatScreeningIndicatorsHuman(response.data, theme)}\n`);
|
|
65
|
+
}
|
|
45
66
|
export async function runScreeningRunCommand(options, context = {}) {
|
|
46
67
|
const stdout = context.io?.stdout ?? process.stdout;
|
|
47
68
|
const theme = createTerminalTheme(stdout, context.env ?? process.env);
|
|
@@ -84,6 +105,32 @@ export function formatScreeningUniversesHuman(data, theme = createTerminalTheme(
|
|
|
84
105
|
appendUniverseGroup(lines, theme, "Carteiras", data.holdings);
|
|
85
106
|
return lines.join("\n");
|
|
86
107
|
}
|
|
108
|
+
export function formatScreeningIndicatorsHuman(data, theme = createTerminalTheme(process.stdout)) {
|
|
109
|
+
const lines = [
|
|
110
|
+
theme.label("Indicadores de screening"),
|
|
111
|
+
"",
|
|
112
|
+
`${theme.label("Total:")} ${formatInteger(data.indicators.length)}`,
|
|
113
|
+
`${theme.label("Operadores:")} ${data.operators.join(", ")}`,
|
|
114
|
+
];
|
|
115
|
+
for (const indicator of data.indicators) {
|
|
116
|
+
lines.push("");
|
|
117
|
+
lines.push(`${theme.bold(indicator.name)} ${theme.dim("-")} ${indicator.display_name}`);
|
|
118
|
+
lines.push(` ${indicator.description}`);
|
|
119
|
+
lines.push(` ${theme.label("Timeframes:")} ${indicator.timeframes.join(", ")}`);
|
|
120
|
+
if (indicator.params.length > 0) {
|
|
121
|
+
lines.push(` ${theme.label("Parâmetros:")}`);
|
|
122
|
+
for (const param of indicator.params) {
|
|
123
|
+
lines.push(` ${formatIndicatorParam(param)}`);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
if (indicator.examples.length > 0) {
|
|
127
|
+
lines.push(` ${theme.label("Exemplos:")} ${indicator.examples
|
|
128
|
+
.map(example => example.label)
|
|
129
|
+
.join(", ")}`);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return lines.join("\n");
|
|
133
|
+
}
|
|
87
134
|
export function formatScreeningRunHuman(data, theme = createTerminalTheme(process.stdout)) {
|
|
88
135
|
const lines = [
|
|
89
136
|
theme.label("Screening de indicadores"),
|
|
@@ -227,6 +274,22 @@ function formatUniverseKind(kind) {
|
|
|
227
274
|
}
|
|
228
275
|
return "Carteira";
|
|
229
276
|
}
|
|
277
|
+
function formatIndicatorParam(param) {
|
|
278
|
+
const details = [param.type];
|
|
279
|
+
if (param.required) {
|
|
280
|
+
details.push("obrigatório");
|
|
281
|
+
}
|
|
282
|
+
if (param.default !== null) {
|
|
283
|
+
details.push(`padrão ${formatScalar(param.default)}`);
|
|
284
|
+
}
|
|
285
|
+
if (param.enum_values !== null && param.enum_values.length > 0) {
|
|
286
|
+
details.push(`opções ${param.enum_values.join("|")}`);
|
|
287
|
+
}
|
|
288
|
+
return `${param.name}: ${details.join(", ")} - ${param.description}`;
|
|
289
|
+
}
|
|
290
|
+
function formatScalar(value) {
|
|
291
|
+
return typeof value === "string" ? JSON.stringify(value) : String(value);
|
|
292
|
+
}
|
|
230
293
|
function collectIndicatorKeys(results) {
|
|
231
294
|
const keys = [];
|
|
232
295
|
const seen = new Set();
|
package/dist/commands/skills.js
CHANGED
|
@@ -4,18 +4,18 @@ import { createTerminalTheme } from "../cli/terminal.js";
|
|
|
4
4
|
export function registerSkillsCommands(program, context = {}) {
|
|
5
5
|
const skillsCommand = program
|
|
6
6
|
.command("skills")
|
|
7
|
-
.description("
|
|
7
|
+
.description("Gerencia skills públicas empacotadas");
|
|
8
8
|
skillsCommand
|
|
9
9
|
.command("install")
|
|
10
|
-
.description("
|
|
11
|
-
.option("--all", "
|
|
10
|
+
.description("Instala a skill pública do QuantBrasil nos clientes de agente detectados")
|
|
11
|
+
.option("--all", "Instala todas as skills públicas empacotadas")
|
|
12
12
|
.action(async (options) => {
|
|
13
13
|
await runSkillsInstallCommand(options, context);
|
|
14
14
|
});
|
|
15
15
|
}
|
|
16
16
|
export async function runSkillsInstallCommand(options, context = {}) {
|
|
17
17
|
if (!options.all) {
|
|
18
|
-
throw createCliValidationError("Use --all
|
|
18
|
+
throw createCliValidationError("Use --all para instalar a skill QuantBrasil nos clientes de agente detectados.");
|
|
19
19
|
}
|
|
20
20
|
const stdout = context.io?.stdout ?? process.stdout;
|
|
21
21
|
const theme = createTerminalTheme(stdout, context.env ?? process.env);
|
|
@@ -23,15 +23,15 @@ export async function runSkillsInstallCommand(options, context = {}) {
|
|
|
23
23
|
stdout.write(`${formatSkillsInstallResult(result, theme)}\n`);
|
|
24
24
|
}
|
|
25
25
|
export function formatSkillsInstallResult(result, theme = createTerminalTheme(process.stdout)) {
|
|
26
|
-
const lines = [theme.label("
|
|
26
|
+
const lines = [theme.label("Skill QuantBrasil instalada"), ""];
|
|
27
27
|
for (const target of result.installed) {
|
|
28
28
|
lines.push(`${theme.success(target.label)} ${theme.dim(`→ ${target.installDir}`)}`);
|
|
29
29
|
}
|
|
30
30
|
if (result.skipped.length > 0) {
|
|
31
31
|
lines.push("");
|
|
32
|
-
lines.push(theme.label("
|
|
32
|
+
lines.push(theme.label("Ignorados"));
|
|
33
33
|
for (const target of result.skipped) {
|
|
34
|
-
lines.push(`${theme.dim(`${target.label}
|
|
34
|
+
lines.push(`${theme.dim(`${target.label} não detectado em ${target.rootDir}`)}`);
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
37
|
return lines.join("\n");
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { type TerminalWriter } from "../cli/terminal.js";
|
|
3
|
+
export interface UpdateCommandIO {
|
|
4
|
+
stdout: TerminalWriter;
|
|
5
|
+
}
|
|
6
|
+
export interface UpdateCommandOptions {
|
|
7
|
+
yes?: boolean;
|
|
8
|
+
}
|
|
9
|
+
export interface UpdateCommandResult {
|
|
10
|
+
stdout: string;
|
|
11
|
+
stderr: string;
|
|
12
|
+
}
|
|
13
|
+
export type UpdateCommandRunner = (command: string, args: readonly string[], env: NodeJS.ProcessEnv) => Promise<UpdateCommandResult>;
|
|
14
|
+
export interface UpdateCommandContext {
|
|
15
|
+
io?: UpdateCommandIO;
|
|
16
|
+
env?: NodeJS.ProcessEnv;
|
|
17
|
+
prompt?: (promptLabel: string) => Promise<string>;
|
|
18
|
+
commandRunner?: UpdateCommandRunner;
|
|
19
|
+
currentVersion?: string;
|
|
20
|
+
}
|
|
21
|
+
export declare function registerUpdateCommand(program: Command, context?: UpdateCommandContext): void;
|
|
22
|
+
export declare function runUpdateCommand(options: UpdateCommandOptions, context?: UpdateCommandContext): Promise<void>;
|
|
23
|
+
//# sourceMappingURL=update.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../src/commands/update.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQpC,OAAO,EAAuB,KAAK,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAG9E,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,cAAc,CAAC;CACxB;AAED,MAAM,WAAW,oBAAoB;IACnC,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,mBAAmB,GAAG,CAChC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,GAAG,EAAE,MAAM,CAAC,UAAU,KACnB,OAAO,CAAC,mBAAmB,CAAC,CAAC;AAElC,MAAM,WAAW,oBAAoB;IACnC,EAAE,CAAC,EAAE,eAAe,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,MAAM,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAClD,aAAa,CAAC,EAAE,mBAAmB,CAAC;IACpC,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAID,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,OAAO,EAChB,OAAO,GAAE,oBAAyB,GACjC,IAAI,CAQN;AAED,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,oBAAoB,EAC7B,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,IAAI,CAAC,CA2Cf"}
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import { createCliConfigError } from "../cli/errors.js";
|
|
3
|
+
import { promptForConfirmation } from "../cli/prompt.js";
|
|
4
|
+
import { getBundledSkillInstallState, installBundledSkillEverywhere, } from "../cli/skills.js";
|
|
5
|
+
import { createTerminalTheme } from "../cli/terminal.js";
|
|
6
|
+
import { formatSkillsInstallResult } from "./skills.js";
|
|
7
|
+
const CLI_PACKAGE_SPEC = "@quantbrasil/cli@beta";
|
|
8
|
+
export function registerUpdateCommand(program, context = {}) {
|
|
9
|
+
program
|
|
10
|
+
.command("update")
|
|
11
|
+
.description("Atualiza o pacote global e a skill pública do QuantBrasil")
|
|
12
|
+
.option("--yes", "Atualiza sem confirmação interativa")
|
|
13
|
+
.action(async (options) => {
|
|
14
|
+
await runUpdateCommand(options, context);
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
export async function runUpdateCommand(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 runner = context.commandRunner ?? runExternalCommand;
|
|
22
|
+
const currentVersion = context.currentVersion ?? "0.0.0";
|
|
23
|
+
const latestVersion = await getLatestBetaVersion(runner, env);
|
|
24
|
+
const cliNeedsUpdate = compareVersions(currentVersion, latestVersion) < 0;
|
|
25
|
+
const skillState = await getBundledSkillInstallState(env);
|
|
26
|
+
const skillNeedsUpdate = skillState.needsInstall;
|
|
27
|
+
if (!cliNeedsUpdate && !skillNeedsUpdate) {
|
|
28
|
+
stdout.write(`${theme.success("QuantBrasil CLI já está atualizado.")}\n`);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
stdout.write(`${formatUpdatePlan({
|
|
32
|
+
currentVersion,
|
|
33
|
+
latestVersion,
|
|
34
|
+
cliNeedsUpdate,
|
|
35
|
+
skillState,
|
|
36
|
+
}, theme)}\n`);
|
|
37
|
+
if (!(await shouldContinue(options, context))) {
|
|
38
|
+
stdout.write(`${theme.warning("Atualização cancelada.")}\n`);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
if (cliNeedsUpdate) {
|
|
42
|
+
await runner("npm", ["install", "-g", CLI_PACKAGE_SPEC], env);
|
|
43
|
+
await runner("quantbrasil", ["skills", "install", "--all"], env);
|
|
44
|
+
stdout.write(`${theme.success("Atualização concluída.")}\n`);
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
const skillInstallResult = await installBundledSkillEverywhere(env);
|
|
48
|
+
stdout.write(`${formatSkillsInstallResult(skillInstallResult, theme)}\n`);
|
|
49
|
+
stdout.write(`${theme.success("Atualização concluída.")}\n`);
|
|
50
|
+
}
|
|
51
|
+
function formatUpdatePlan(data, theme) {
|
|
52
|
+
const lines = [
|
|
53
|
+
theme.label("Atualização do QuantBrasil CLI"),
|
|
54
|
+
"",
|
|
55
|
+
`${theme.label("Versão instalada:")} ${data.currentVersion}`,
|
|
56
|
+
`${theme.label("Versão beta publicada:")} ${data.latestVersion}`,
|
|
57
|
+
];
|
|
58
|
+
const skillTargets = data.skillState.targets.filter(target => target.status === "missing" || target.status === "stale");
|
|
59
|
+
if (skillTargets.length > 0) {
|
|
60
|
+
lines.push(`${theme.label("Skills:")} ${skillTargets.length} alvo(s) precisam ser atualizados`);
|
|
61
|
+
for (const target of skillTargets) {
|
|
62
|
+
lines.push(` ${target.label}: ${formatSkillStatus(target.status)} ${theme.dim(`(${target.installDir})`)}`);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
lines.push(`${theme.label("Skills:")} já estão atualizadas`);
|
|
67
|
+
}
|
|
68
|
+
lines.push("");
|
|
69
|
+
lines.push(theme.label("Ações"));
|
|
70
|
+
if (data.cliNeedsUpdate) {
|
|
71
|
+
lines.push(` npm install -g ${CLI_PACKAGE_SPEC}`);
|
|
72
|
+
lines.push(" quantbrasil skills install --all");
|
|
73
|
+
}
|
|
74
|
+
else if (skillTargets.length > 0) {
|
|
75
|
+
lines.push(" quantbrasil skills install --all");
|
|
76
|
+
}
|
|
77
|
+
return lines.join("\n");
|
|
78
|
+
}
|
|
79
|
+
async function shouldContinue(options, context) {
|
|
80
|
+
if (options.yes) {
|
|
81
|
+
return true;
|
|
82
|
+
}
|
|
83
|
+
if (context.prompt) {
|
|
84
|
+
return parseConfirmationAnswer(await context.prompt("Atualizar agora? [s/N] "));
|
|
85
|
+
}
|
|
86
|
+
return promptForConfirmation("Atualizar agora? [s/N] ");
|
|
87
|
+
}
|
|
88
|
+
function formatSkillStatus(status) {
|
|
89
|
+
if (status === "missing") {
|
|
90
|
+
return "não instalada";
|
|
91
|
+
}
|
|
92
|
+
if (status === "stale") {
|
|
93
|
+
return "desatualizada";
|
|
94
|
+
}
|
|
95
|
+
return status;
|
|
96
|
+
}
|
|
97
|
+
function parseConfirmationAnswer(answer) {
|
|
98
|
+
return ["s", "sim", "y", "yes"].includes(answer.trim().toLowerCase());
|
|
99
|
+
}
|
|
100
|
+
async function getLatestBetaVersion(runner, env) {
|
|
101
|
+
const result = await runner("npm", ["view", CLI_PACKAGE_SPEC, "version"], env);
|
|
102
|
+
const version = result.stdout.trim();
|
|
103
|
+
if (!version) {
|
|
104
|
+
throw createCliConfigError(`Não foi possível resolver a versão publicada de ${CLI_PACKAGE_SPEC}.`);
|
|
105
|
+
}
|
|
106
|
+
return version;
|
|
107
|
+
}
|
|
108
|
+
function compareVersions(left, right) {
|
|
109
|
+
const parsedLeft = parseVersion(left);
|
|
110
|
+
const parsedRight = parseVersion(right);
|
|
111
|
+
for (let index = 0; index < 3; index += 1) {
|
|
112
|
+
const diff = (parsedLeft.main[index] ?? 0) - (parsedRight.main[index] ?? 0);
|
|
113
|
+
if (diff !== 0) {
|
|
114
|
+
return diff;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
if (parsedLeft.prerelease.length === 0 &&
|
|
118
|
+
parsedRight.prerelease.length === 0) {
|
|
119
|
+
return 0;
|
|
120
|
+
}
|
|
121
|
+
if (parsedLeft.prerelease.length === 0) {
|
|
122
|
+
return 1;
|
|
123
|
+
}
|
|
124
|
+
if (parsedRight.prerelease.length === 0) {
|
|
125
|
+
return -1;
|
|
126
|
+
}
|
|
127
|
+
const length = Math.max(parsedLeft.prerelease.length, parsedRight.prerelease.length);
|
|
128
|
+
for (let index = 0; index < length; index += 1) {
|
|
129
|
+
const leftPart = parsedLeft.prerelease[index];
|
|
130
|
+
const rightPart = parsedRight.prerelease[index];
|
|
131
|
+
if (leftPart === undefined) {
|
|
132
|
+
return -1;
|
|
133
|
+
}
|
|
134
|
+
if (rightPart === undefined) {
|
|
135
|
+
return 1;
|
|
136
|
+
}
|
|
137
|
+
const diff = comparePrereleasePart(leftPart, rightPart);
|
|
138
|
+
if (diff !== 0) {
|
|
139
|
+
return diff;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return 0;
|
|
143
|
+
}
|
|
144
|
+
function parseVersion(version) {
|
|
145
|
+
const [mainVersion = "0.0.0", prerelease = ""] = version
|
|
146
|
+
.trim()
|
|
147
|
+
.replace(/^v/, "")
|
|
148
|
+
.split("-");
|
|
149
|
+
const mainParts = mainVersion.split(".").map(part => Number(part));
|
|
150
|
+
const main = [
|
|
151
|
+
normalizeVersionPart(mainParts[0]),
|
|
152
|
+
normalizeVersionPart(mainParts[1]),
|
|
153
|
+
normalizeVersionPart(mainParts[2]),
|
|
154
|
+
];
|
|
155
|
+
return {
|
|
156
|
+
main,
|
|
157
|
+
prerelease: prerelease ? prerelease.split(".") : [],
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
function normalizeVersionPart(part) {
|
|
161
|
+
return Number.isFinite(part) ? Number(part) : 0;
|
|
162
|
+
}
|
|
163
|
+
function comparePrereleasePart(left, right) {
|
|
164
|
+
const leftNumber = Number(left);
|
|
165
|
+
const rightNumber = Number(right);
|
|
166
|
+
const leftIsNumeric = /^\d+$/.test(left);
|
|
167
|
+
const rightIsNumeric = /^\d+$/.test(right);
|
|
168
|
+
if (leftIsNumeric && rightIsNumeric) {
|
|
169
|
+
return leftNumber - rightNumber;
|
|
170
|
+
}
|
|
171
|
+
if (leftIsNumeric) {
|
|
172
|
+
return -1;
|
|
173
|
+
}
|
|
174
|
+
if (rightIsNumeric) {
|
|
175
|
+
return 1;
|
|
176
|
+
}
|
|
177
|
+
return left.localeCompare(right);
|
|
178
|
+
}
|
|
179
|
+
function runExternalCommand(command, args, env) {
|
|
180
|
+
return new Promise((resolve, reject) => {
|
|
181
|
+
const child = spawn(command, args, {
|
|
182
|
+
env,
|
|
183
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
184
|
+
});
|
|
185
|
+
let stdout = "";
|
|
186
|
+
let stderr = "";
|
|
187
|
+
child.stdout.on("data", chunk => {
|
|
188
|
+
stdout += chunk;
|
|
189
|
+
});
|
|
190
|
+
child.stderr.on("data", chunk => {
|
|
191
|
+
stderr += chunk;
|
|
192
|
+
});
|
|
193
|
+
child.on("error", error => {
|
|
194
|
+
reject(createCliConfigError(`Não foi possível executar ${command}: ${error.message}`));
|
|
195
|
+
});
|
|
196
|
+
child.on("close", code => {
|
|
197
|
+
if (code === 0) {
|
|
198
|
+
resolve({ stdout, stderr });
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
reject(createCliConfigError([
|
|
202
|
+
`${command} ${args.join(" ")} falhou com exit ${code}.`,
|
|
203
|
+
stderr.trim() || stdout.trim(),
|
|
204
|
+
]
|
|
205
|
+
.filter(Boolean)
|
|
206
|
+
.join("\n")));
|
|
207
|
+
});
|
|
208
|
+
});
|
|
209
|
+
}
|
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,0BAA0B,CAAC;AACzC,cAAc,yBAAyB,CAAC;AACxC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,0BAA0B,CAAC;AACzC,cAAc,yBAAyB,CAAC;AACxC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -165,6 +165,33 @@ export declare const capabilityRegistry: readonly [{
|
|
|
165
165
|
readonly title: "Listar universos de screening";
|
|
166
166
|
};
|
|
167
167
|
readonly outputModes: readonly ["json", "human"];
|
|
168
|
+
}, {
|
|
169
|
+
readonly id: "screening.indicators";
|
|
170
|
+
readonly kind: "read";
|
|
171
|
+
readonly visibility: readonly ["cli", "opencode"];
|
|
172
|
+
readonly description: "Lista indicadores, parâmetros e operadores disponíveis para screening.";
|
|
173
|
+
readonly http: {
|
|
174
|
+
readonly method: "GET";
|
|
175
|
+
readonly path: "/api/desk/tools/screening/indicators";
|
|
176
|
+
readonly inputMode: "none";
|
|
177
|
+
readonly schemas: {
|
|
178
|
+
readonly request: null;
|
|
179
|
+
readonly response: "ScreeningIndicatorsResponse";
|
|
180
|
+
};
|
|
181
|
+
};
|
|
182
|
+
readonly cli: {
|
|
183
|
+
readonly group: "screening";
|
|
184
|
+
readonly command: "indicators";
|
|
185
|
+
readonly summary: "Lista indicadores, parâmetros e exemplos disponíveis para screening.";
|
|
186
|
+
readonly positional: readonly [];
|
|
187
|
+
readonly options: readonly [];
|
|
188
|
+
readonly examples: readonly ["quantbrasil screening indicators", "quantbrasil screening indicators --json"];
|
|
189
|
+
};
|
|
190
|
+
readonly tool: {
|
|
191
|
+
readonly name: "qb_screening_indicators";
|
|
192
|
+
readonly title: "Listar indicadores de screening";
|
|
193
|
+
};
|
|
194
|
+
readonly outputModes: readonly ["json", "human"];
|
|
168
195
|
}, {
|
|
169
196
|
readonly id: "screening.run";
|
|
170
197
|
readonly kind: "read";
|
|
@@ -1032,6 +1059,33 @@ export declare function getCapabilityById(id: CapabilityId): {
|
|
|
1032
1059
|
readonly title: "Listar universos de screening";
|
|
1033
1060
|
};
|
|
1034
1061
|
readonly outputModes: readonly ["json", "human"];
|
|
1062
|
+
} | {
|
|
1063
|
+
readonly id: "screening.indicators";
|
|
1064
|
+
readonly kind: "read";
|
|
1065
|
+
readonly visibility: readonly ["cli", "opencode"];
|
|
1066
|
+
readonly description: "Lista indicadores, parâmetros e operadores disponíveis para screening.";
|
|
1067
|
+
readonly http: {
|
|
1068
|
+
readonly method: "GET";
|
|
1069
|
+
readonly path: "/api/desk/tools/screening/indicators";
|
|
1070
|
+
readonly inputMode: "none";
|
|
1071
|
+
readonly schemas: {
|
|
1072
|
+
readonly request: null;
|
|
1073
|
+
readonly response: "ScreeningIndicatorsResponse";
|
|
1074
|
+
};
|
|
1075
|
+
};
|
|
1076
|
+
readonly cli: {
|
|
1077
|
+
readonly group: "screening";
|
|
1078
|
+
readonly command: "indicators";
|
|
1079
|
+
readonly summary: "Lista indicadores, parâmetros e exemplos disponíveis para screening.";
|
|
1080
|
+
readonly positional: readonly [];
|
|
1081
|
+
readonly options: readonly [];
|
|
1082
|
+
readonly examples: readonly ["quantbrasil screening indicators", "quantbrasil screening indicators --json"];
|
|
1083
|
+
};
|
|
1084
|
+
readonly tool: {
|
|
1085
|
+
readonly name: "qb_screening_indicators";
|
|
1086
|
+
readonly title: "Listar indicadores de screening";
|
|
1087
|
+
};
|
|
1088
|
+
readonly outputModes: readonly ["json", "human"];
|
|
1035
1089
|
} | {
|
|
1036
1090
|
readonly id: "screening.run";
|
|
1037
1091
|
readonly kind: "read";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/capabilities/registry.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,kBAAkB
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/capabilities/registry.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAKrB,CAAC;AAEX,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,kBAAkB,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC;AAErE,eAAO,MAAM,sBAAsB,EAE9B,MAAM,CAAC,YAAY,EAAE,CAAC,OAAO,kBAAkB,EAAE,MAAM,CAAC,CAAC,CAAC;AAE/D,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAEjD"}
|
|
@@ -26,6 +26,33 @@ export declare const screeningCapabilities: readonly [{
|
|
|
26
26
|
readonly title: "Listar universos de screening";
|
|
27
27
|
};
|
|
28
28
|
readonly outputModes: readonly ["json", "human"];
|
|
29
|
+
}, {
|
|
30
|
+
readonly id: "screening.indicators";
|
|
31
|
+
readonly kind: "read";
|
|
32
|
+
readonly visibility: readonly ["cli", "opencode"];
|
|
33
|
+
readonly description: "Lista indicadores, parâmetros e operadores disponíveis para screening.";
|
|
34
|
+
readonly http: {
|
|
35
|
+
readonly method: "GET";
|
|
36
|
+
readonly path: "/api/desk/tools/screening/indicators";
|
|
37
|
+
readonly inputMode: "none";
|
|
38
|
+
readonly schemas: {
|
|
39
|
+
readonly request: null;
|
|
40
|
+
readonly response: "ScreeningIndicatorsResponse";
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
readonly cli: {
|
|
44
|
+
readonly group: "screening";
|
|
45
|
+
readonly command: "indicators";
|
|
46
|
+
readonly summary: "Lista indicadores, parâmetros e exemplos disponíveis para screening.";
|
|
47
|
+
readonly positional: readonly [];
|
|
48
|
+
readonly options: readonly [];
|
|
49
|
+
readonly examples: readonly ["quantbrasil screening indicators", "quantbrasil screening indicators --json"];
|
|
50
|
+
};
|
|
51
|
+
readonly tool: {
|
|
52
|
+
readonly name: "qb_screening_indicators";
|
|
53
|
+
readonly title: "Listar indicadores de screening";
|
|
54
|
+
};
|
|
55
|
+
readonly outputModes: readonly ["json", "human"];
|
|
29
56
|
}, {
|
|
30
57
|
readonly id: "screening.run";
|
|
31
58
|
readonly kind: "read";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"screening.d.ts","sourceRoot":"","sources":["../../src/capabilities/screening.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,mBAAmB,8BAA+B,CAAC;AAEhE,eAAO,MAAM,qBAAqB
|
|
1
|
+
{"version":3,"file":"screening.d.ts","sourceRoot":"","sources":["../../src/capabilities/screening.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,mBAAmB,8BAA+B,CAAC;AAEhE,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiKkB,CAAC"}
|
|
@@ -30,6 +30,37 @@ export const screeningCapabilities = [
|
|
|
30
30
|
},
|
|
31
31
|
outputModes: standardOutputModes,
|
|
32
32
|
},
|
|
33
|
+
{
|
|
34
|
+
id: "screening.indicators",
|
|
35
|
+
kind: "read",
|
|
36
|
+
visibility: publicRuntimeVisibility,
|
|
37
|
+
description: "Lista indicadores, parâmetros e operadores disponíveis para screening.",
|
|
38
|
+
http: {
|
|
39
|
+
method: "GET",
|
|
40
|
+
path: "/api/desk/tools/screening/indicators",
|
|
41
|
+
inputMode: "none",
|
|
42
|
+
schemas: {
|
|
43
|
+
request: null,
|
|
44
|
+
response: "ScreeningIndicatorsResponse",
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
cli: {
|
|
48
|
+
group: "screening",
|
|
49
|
+
command: "indicators",
|
|
50
|
+
summary: "Lista indicadores, parâmetros e exemplos disponíveis para screening.",
|
|
51
|
+
positional: [],
|
|
52
|
+
options: [],
|
|
53
|
+
examples: [
|
|
54
|
+
"quantbrasil screening indicators",
|
|
55
|
+
"quantbrasil screening indicators --json",
|
|
56
|
+
],
|
|
57
|
+
},
|
|
58
|
+
tool: {
|
|
59
|
+
name: "qb_screening_indicators",
|
|
60
|
+
title: "Listar indicadores de screening",
|
|
61
|
+
},
|
|
62
|
+
outputModes: standardOutputModes,
|
|
63
|
+
},
|
|
33
64
|
{
|
|
34
65
|
id: "screening.run",
|
|
35
66
|
kind: "read",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quantbrasil/cli",
|
|
3
|
-
"version": "0.1.0-beta.
|
|
3
|
+
"version": "0.1.0-beta.8",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Public QuantBrasil CLI for deterministic operations",
|
|
6
6
|
"repository": {
|
|
@@ -41,8 +41,8 @@
|
|
|
41
41
|
"typescript": "^5.3.3",
|
|
42
42
|
"vitest": "^3.2.4",
|
|
43
43
|
"@repo/core": "0.0.0",
|
|
44
|
-
"@repo/
|
|
45
|
-
"@repo/
|
|
44
|
+
"@repo/typescript-config": "0.0.0",
|
|
45
|
+
"@repo/eslint-config": "0.0.0"
|
|
46
46
|
},
|
|
47
47
|
"scripts": {
|
|
48
48
|
"build": "pnpm --filter @repo/core build && pnpm run clean && tsc && node scripts/vendor-core.mjs",
|
|
@@ -13,6 +13,7 @@ Use this skill when the user asks for market or investing data/actions that Quan
|
|
|
13
13
|
- Most end-user QuantBrasil requests are expected in pt-BR; Portuguese prompts about ativos, carteiras, cotações, screening, retorno, beta, VaR, watchlists, or Ibovespa should trigger this skill when they map to the supported CLI surface.
|
|
14
14
|
- For QuantBrasil-supported market, asset, screening, watchlist, holding, or holding metric data, use the CLI before generic web or finance search.
|
|
15
15
|
- When the request mentions portfolios, carteiras, watchlists, holdings, target weights, positions, historical return, beta, VaR, screening universes, or saved compositions, load [`references/portfolios.md`](./references/portfolios.md) before choosing commands.
|
|
16
|
+
- When the request mentions IFR/RSI filters, sobrevendido, sobrecomprado, indicator screening, technical screening rules, or screening indicators, load [`references/screening.md`](./references/screening.md) before building the request JSON.
|
|
16
17
|
- Use `quantbrasil` when available on PATH.
|
|
17
18
|
- If `quantbrasil` is not found, report that the CLI binary is not on PATH and ask the user to install it or fix PATH.
|
|
18
19
|
- Check readiness first: `quantbrasil --status`
|
|
@@ -24,7 +25,7 @@ Use this skill when the user asks for market or investing data/actions that Quan
|
|
|
24
25
|
- richer asset analysis: `quantbrasil assets overview <ticker> --sections ...`
|
|
25
26
|
- watchlist details and changes: `quantbrasil watchlists ...`
|
|
26
27
|
- holding details and historical return: `quantbrasil holdings ...`
|
|
27
|
-
- indicator screening over saved universes: `quantbrasil screening ...`
|
|
28
|
+
- indicator screening over saved universes: `quantbrasil screening universes|indicators|run ...`
|
|
28
29
|
- holding metrics: `quantbrasil holdings historical-return|beta|var ...`
|
|
29
30
|
- Use `--json` when output will be parsed by agent or script
|
|
30
31
|
- Use generic web or finance search only if the CLI is unavailable, the requested data is outside the QuantBrasil-supported surface, or the user explicitly asks for an external source.
|
|
@@ -35,6 +36,7 @@ Use this skill when the user asks for market or investing data/actions that Quan
|
|
|
35
36
|
- Load [`references/workflows.md`](./references/workflows.md) when the user describes an investing task but does not name an exact command, or when a task spans discovery plus a follow-up action.
|
|
36
37
|
- Load [`references/cli.md`](./references/cli.md) when you need exact command syntax, flags, examples, or supported `--sections` values.
|
|
37
38
|
- Load [`references/portfolios.md`](./references/portfolios.md) when the request mentions portfolios, carteiras, watchlists, holdings, target weights, positions, historical return, beta, VaR, screening universes, or saved compositions.
|
|
39
|
+
- Load [`references/screening.md`](./references/screening.md) when the user asks for IFR/RSI filters, sobrevendido/sobrecomprado assets, indicator screening, technical filter JSON, screening indicators, or examples of `ScreenerRequest`.
|
|
38
40
|
- Load [`references/costs.md`](./references/costs.md) before chaining heavy reads, choosing between overview/screening/holding metrics, or answering cost-sensitive agent workflow questions.
|
|
39
41
|
- Load [`references/errors.md`](./references/errors.md) when a CLI command fails, auth/config is unclear, or the user asks how to fix a QuantBrasil CLI error.
|
|
40
42
|
- Load [`references/unsupported.md`](./references/unsupported.md) when the user asks for deletion, file export, ad-hoc ticker-list screening, unsupported commands, or a capability that may not be public yet.
|
|
@@ -82,6 +82,7 @@ Use `--json` on any holding metric command when machine parsing needed.
|
|
|
82
82
|
|
|
83
83
|
```bash
|
|
84
84
|
quantbrasil screening universes
|
|
85
|
+
quantbrasil screening indicators
|
|
85
86
|
quantbrasil screening run --system acoes-mais-liquidas --query-file ./screening.json
|
|
86
87
|
quantbrasil screening run --watchlist 93 --query-file ./screening.json --limit 25
|
|
87
88
|
quantbrasil screening run --holding 182 --query-file ./screening.json --sort ticker
|
|
@@ -96,6 +97,10 @@ Rules:
|
|
|
96
97
|
- `--query-file` must contain the full backend `ScreenerRequest` JSON shape
|
|
97
98
|
- `--query-file -` reads the same JSON shape from stdin
|
|
98
99
|
- `--limit` and `--sort` override only top-level fields from the query JSON
|
|
100
|
+
- use `screening indicators` to discover supported indicator names, params, examples, timeframes, and operators
|
|
101
|
+
|
|
102
|
+
Load [`screening.md`](./screening.md) for detailed screening examples, including
|
|
103
|
+
IFR14, IFR2, and logical `AND` JSON payloads.
|
|
99
104
|
|
|
100
105
|
Example query JSON:
|
|
101
106
|
|
|
@@ -14,6 +14,7 @@ Current guidance uses backend qualitative classes only:
|
|
|
14
14
|
- `market price` is narrow read path
|
|
15
15
|
- `assets overview` is richer and should use minimal `--sections`
|
|
16
16
|
- `screening universes` is a discovery path for saved screening universes
|
|
17
|
+
- `screening indicators` is a discovery path for supported screening JSON
|
|
17
18
|
- `screening run` is a heavy read and should be targeted to one selected universe
|
|
18
19
|
- holding metrics (`historical-return`, `beta`, `var`) are heaviest current public reads
|
|
19
20
|
|
|
@@ -22,6 +23,7 @@ Current guidance uses backend qualitative classes only:
|
|
|
22
23
|
- prefer narrow command that answers question
|
|
23
24
|
- prefer `market price` over `assets overview` for quote-only requests
|
|
24
25
|
- run `screening universes` before `screening run` when the universe selector is not known
|
|
26
|
+
- run `screening indicators` before `screening run` when the indicator JSON is not known
|
|
25
27
|
- prefer one holding metric call targeted to actual question
|
|
26
28
|
- do not chain multiple heavy holding metric or screening calls unless user asked for them
|
|
27
29
|
- use `--json` only when structured output needed
|
|
@@ -44,6 +44,11 @@
|
|
|
44
44
|
"should_trigger": true,
|
|
45
45
|
"expected_behavior": "Use screening universes and present system portfolios, watchlists, and holdings."
|
|
46
46
|
},
|
|
47
|
+
{
|
|
48
|
+
"query": "Quais indicadores posso usar no screening?",
|
|
49
|
+
"should_trigger": true,
|
|
50
|
+
"expected_behavior": "Use screening indicators and present supported indicator names, params, examples, timeframes, and operators."
|
|
51
|
+
},
|
|
47
52
|
{
|
|
48
53
|
"query": "Rode um screening de IFR na carteira do sistema Ações Mais Líquidas.",
|
|
49
54
|
"should_trigger": true,
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
# Screening
|
|
2
|
+
|
|
3
|
+
Use screening for indicator filters over saved QuantBrasil universes.
|
|
4
|
+
|
|
5
|
+
## Discovery
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
quantbrasil screening universes
|
|
9
|
+
quantbrasil screening indicators
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
Use `screening universes` to pick the asset set. The CLI supports only saved,
|
|
13
|
+
portfolio-backed universes:
|
|
14
|
+
|
|
15
|
+
- system portfolios via `--system <slug>`
|
|
16
|
+
- watchlists via `--watchlist <id>`
|
|
17
|
+
- holdings via `--holding <id>`
|
|
18
|
+
|
|
19
|
+
Do not invent ad-hoc ticker-list screening. If the user gives loose tickers,
|
|
20
|
+
explain that this CLI slice only screens saved universes.
|
|
21
|
+
|
|
22
|
+
Use `screening indicators` before building JSON when the indicator name,
|
|
23
|
+
parameters, timeframes, or comparison operators are unclear.
|
|
24
|
+
|
|
25
|
+
## Common Portuguese mappings
|
|
26
|
+
|
|
27
|
+
- `IFR`, `IFR14`, `IFR(14)` -> `RSI` with `params.period = 14`
|
|
28
|
+
- `IFR2`, `IFR(2)` -> `RSI` with `params.period = 2`
|
|
29
|
+
- `sobrevendido` usually means low RSI, commonly `< 30` or a threshold supplied by the user
|
|
30
|
+
- `sobrecomprado` usually means high RSI, commonly `> 70` or a threshold supplied by the user
|
|
31
|
+
- `Ações Mais Líquidas` -> system universe slug `acoes-mais-liquidas` when present in `screening universes`
|
|
32
|
+
|
|
33
|
+
## Operators
|
|
34
|
+
|
|
35
|
+
- `lt` means less than
|
|
36
|
+
- `lte` means less than or equal to
|
|
37
|
+
- `gt` means greater than
|
|
38
|
+
- `gte` means greater than or equal to
|
|
39
|
+
- `eq` means equal to
|
|
40
|
+
- `neq` means not equal to
|
|
41
|
+
|
|
42
|
+
## IFR14 abaixo de 25
|
|
43
|
+
|
|
44
|
+
```json
|
|
45
|
+
{
|
|
46
|
+
"query": {
|
|
47
|
+
"comparison": {
|
|
48
|
+
"left": {
|
|
49
|
+
"indicator": {
|
|
50
|
+
"name": "RSI",
|
|
51
|
+
"timeframe": "D1",
|
|
52
|
+
"offset": 0,
|
|
53
|
+
"params": {
|
|
54
|
+
"period": 14
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
"operator": "lt",
|
|
59
|
+
"right": {
|
|
60
|
+
"constant": {
|
|
61
|
+
"value": 25
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
"limit": 500,
|
|
67
|
+
"sort": "ticker"
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Run it:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
quantbrasil screening run --system acoes-mais-liquidas --query-file ./screening-ifr14-lt-25.json
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
For agent/script parsing:
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
quantbrasil screening run --system acoes-mais-liquidas --query-file ./screening-ifr14-lt-25.json --json
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## IFR14 acima de 70
|
|
84
|
+
|
|
85
|
+
```json
|
|
86
|
+
{
|
|
87
|
+
"query": {
|
|
88
|
+
"comparison": {
|
|
89
|
+
"left": {
|
|
90
|
+
"indicator": {
|
|
91
|
+
"name": "RSI",
|
|
92
|
+
"timeframe": "D1",
|
|
93
|
+
"offset": 0,
|
|
94
|
+
"params": {
|
|
95
|
+
"period": 14
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
"operator": "gt",
|
|
100
|
+
"right": {
|
|
101
|
+
"constant": {
|
|
102
|
+
"value": 70
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
"limit": 500,
|
|
108
|
+
"sort": "ticker"
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## IFR2 abaixo de 10
|
|
113
|
+
|
|
114
|
+
```json
|
|
115
|
+
{
|
|
116
|
+
"query": {
|
|
117
|
+
"comparison": {
|
|
118
|
+
"left": {
|
|
119
|
+
"indicator": {
|
|
120
|
+
"name": "RSI",
|
|
121
|
+
"timeframe": "D1",
|
|
122
|
+
"offset": 0,
|
|
123
|
+
"params": {
|
|
124
|
+
"period": 2
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
},
|
|
128
|
+
"operator": "lt",
|
|
129
|
+
"right": {
|
|
130
|
+
"constant": {
|
|
131
|
+
"value": 10
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
},
|
|
136
|
+
"limit": 500,
|
|
137
|
+
"sort": "ticker"
|
|
138
|
+
}
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
## Exemplo com AND lógico
|
|
142
|
+
|
|
143
|
+
Este exemplo filtra ativos com fechamento acima da média móvel de 20 períodos e
|
|
144
|
+
IFR14 abaixo de 30.
|
|
145
|
+
|
|
146
|
+
```json
|
|
147
|
+
{
|
|
148
|
+
"query": {
|
|
149
|
+
"logical": {
|
|
150
|
+
"op": "AND",
|
|
151
|
+
"expressions": [
|
|
152
|
+
{
|
|
153
|
+
"comparison": {
|
|
154
|
+
"left": {
|
|
155
|
+
"indicator": {
|
|
156
|
+
"name": "OHLC",
|
|
157
|
+
"timeframe": "D1",
|
|
158
|
+
"offset": 0,
|
|
159
|
+
"params": {
|
|
160
|
+
"price_type": "close"
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
},
|
|
164
|
+
"operator": "gt",
|
|
165
|
+
"right": {
|
|
166
|
+
"indicator": {
|
|
167
|
+
"name": "RollingWindow",
|
|
168
|
+
"timeframe": "D1",
|
|
169
|
+
"offset": 0,
|
|
170
|
+
"params": {
|
|
171
|
+
"window": 20,
|
|
172
|
+
"method": "mean"
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
"comparison": {
|
|
180
|
+
"left": {
|
|
181
|
+
"indicator": {
|
|
182
|
+
"name": "RSI",
|
|
183
|
+
"timeframe": "D1",
|
|
184
|
+
"offset": 0,
|
|
185
|
+
"params": {
|
|
186
|
+
"period": 14
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
},
|
|
190
|
+
"operator": "lt",
|
|
191
|
+
"right": {
|
|
192
|
+
"constant": {
|
|
193
|
+
"value": 30
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
]
|
|
199
|
+
}
|
|
200
|
+
},
|
|
201
|
+
"limit": 100,
|
|
202
|
+
"sort": "ticker"
|
|
203
|
+
}
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
## Stdin
|
|
207
|
+
|
|
208
|
+
Use stdin when creating the JSON dynamically:
|
|
209
|
+
|
|
210
|
+
```bash
|
|
211
|
+
cat ./screening-ifr14-lt-25.json | quantbrasil screening run --system acoes-mais-liquidas --query-file -
|
|
212
|
+
```
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
- watchlist details or changes → `watchlists ...`
|
|
9
9
|
- holding details or changes → `holdings ...`
|
|
10
10
|
- holding return, beta, risk, VaR, or comparison → `holdings historical-return|beta|var`
|
|
11
|
-
- indicator screening over saved asset sets → `screening universes`, then `screening run`
|
|
11
|
+
- indicator screening over saved asset sets → `screening universes`, `screening indicators` when needed, then `screening run`
|
|
12
12
|
|
|
13
13
|
## Find supported ticker, then get price
|
|
14
14
|
|
|
@@ -79,11 +79,13 @@ quantbrasil holdings var 93 --years 1 --confidence 95
|
|
|
79
79
|
## Run indicator screening
|
|
80
80
|
|
|
81
81
|
1. Discover available universes.
|
|
82
|
-
2.
|
|
83
|
-
3.
|
|
82
|
+
2. Discover available indicators when the filter JSON is not already known.
|
|
83
|
+
3. Pick exactly one system portfolio, watchlist, or holding.
|
|
84
|
+
4. Run screening with a full `ScreenerRequest` JSON file.
|
|
84
85
|
|
|
85
86
|
```bash
|
|
86
87
|
quantbrasil screening universes
|
|
88
|
+
quantbrasil screening indicators
|
|
87
89
|
quantbrasil screening run --system acoes-mais-liquidas --query-file ./screening.json
|
|
88
90
|
quantbrasil screening run --watchlist 93 --query-file ./screening.json --limit 25
|
|
89
91
|
quantbrasil screening run --holding 182 --query-file ./screening.json --sort ticker
|
|
@@ -94,6 +96,7 @@ Rules:
|
|
|
94
96
|
- screening universes are portfolio-backed only: system portfolios, watchlists, or holdings
|
|
95
97
|
- a holding used as a screening universe contributes only its asset set
|
|
96
98
|
- do not invent ad-hoc ticker-list screening commands
|
|
99
|
+
- load `references/screening.md` for IFR/RSI examples and full JSON payloads
|
|
97
100
|
- use `--json` when the result will be parsed by an agent or script
|
|
98
101
|
|
|
99
102
|
## Analyze a theoretical composition
|