@quantbrasil/cli 0.1.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +272 -0
- package/bin/quantbrasil.js +4 -0
- package/dist/cli/auth.d.ts +20 -0
- package/dist/cli/auth.d.ts.map +1 -0
- package/dist/cli/auth.js +76 -0
- package/dist/cli/client.d.ts +17 -0
- package/dist/cli/client.d.ts.map +1 -0
- package/dist/cli/client.js +112 -0
- package/dist/cli/config.d.ts +33 -0
- package/dist/cli/config.d.ts.map +1 -0
- package/dist/cli/config.js +148 -0
- package/dist/cli/errors.d.ts +40 -0
- package/dist/cli/errors.d.ts.map +1 -0
- package/dist/cli/errors.js +122 -0
- package/dist/cli/index.d.ts +30 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +112 -0
- package/dist/cli/prompt.d.ts +2 -0
- package/dist/cli/prompt.d.ts.map +1 -0
- package/dist/cli/prompt.js +40 -0
- package/dist/cli/skills.d.ts +26 -0
- package/dist/cli/skills.d.ts.map +1 -0
- package/dist/cli/skills.js +94 -0
- package/dist/cli/terminal.d.ts +18 -0
- package/dist/cli/terminal.d.ts.map +1 -0
- package/dist/cli/terminal.js +43 -0
- package/dist/commands/analytics.d.ts +131 -0
- package/dist/commands/analytics.d.ts.map +1 -0
- package/dist/commands/analytics.js +291 -0
- package/dist/commands/assets.d.ts +69 -0
- package/dist/commands/assets.d.ts.map +1 -0
- package/dist/commands/assets.js +350 -0
- package/dist/commands/auth.d.ts +17 -0
- package/dist/commands/auth.d.ts.map +1 -0
- package/dist/commands/auth.js +48 -0
- package/dist/commands/capabilities.d.ts +25 -0
- package/dist/commands/capabilities.d.ts.map +1 -0
- package/dist/commands/capabilities.js +61 -0
- package/dist/commands/init.d.ts +17 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +89 -0
- package/dist/commands/market.d.ts +45 -0
- package/dist/commands/market.d.ts.map +1 -0
- package/dist/commands/market.js +162 -0
- package/dist/commands/portfolios.d.ts +60 -0
- package/dist/commands/portfolios.d.ts.map +1 -0
- package/dist/commands/portfolios.js +298 -0
- package/dist/commands/skills.d.ts +17 -0
- package/dist/commands/skills.d.ts.map +1 -0
- package/dist/commands/skills.js +38 -0
- package/dist/commands/status.d.ts +15 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +52 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/vendor/core/capabilities/analytics.d.ts +187 -0
- package/dist/vendor/core/capabilities/analytics.d.ts.map +1 -0
- package/dist/vendor/core/capabilities/analytics.js +214 -0
- package/dist/vendor/core/capabilities/assets.d.ts +48 -0
- package/dist/vendor/core/capabilities/assets.d.ts.map +1 -0
- package/dist/vendor/core/capabilities/assets.js +66 -0
- package/dist/vendor/core/capabilities/index.d.ts +8 -0
- package/dist/vendor/core/capabilities/index.d.ts.map +1 -0
- package/dist/vendor/core/capabilities/index.js +7 -0
- package/dist/vendor/core/capabilities/market.d.ts +90 -0
- package/dist/vendor/core/capabilities/market.d.ts.map +1 -0
- package/dist/vendor/core/capabilities/market.js +114 -0
- package/dist/vendor/core/capabilities/portfolios.d.ts +224 -0
- package/dist/vendor/core/capabilities/portfolios.d.ts.map +1 -0
- package/dist/vendor/core/capabilities/portfolios.js +244 -0
- package/dist/vendor/core/capabilities/registry.d.ts +1083 -0
- package/dist/vendor/core/capabilities/registry.d.ts.map +1 -0
- package/dist/vendor/core/capabilities/registry.js +14 -0
- package/dist/vendor/core/capabilities/shared.d.ts +3 -0
- package/dist/vendor/core/capabilities/shared.d.ts.map +1 -0
- package/dist/vendor/core/capabilities/shared.js +2 -0
- package/dist/vendor/core/capabilities/types.d.ts +75 -0
- package/dist/vendor/core/capabilities/types.d.ts.map +1 -0
- package/dist/vendor/core/capabilities/types.js +1 -0
- package/dist/vendor/core/errors.d.ts +22 -0
- package/dist/vendor/core/errors.d.ts.map +1 -0
- package/dist/vendor/core/errors.js +42 -0
- package/dist/vendor/core/http/client.d.ts +45 -0
- package/dist/vendor/core/http/client.d.ts.map +1 -0
- package/dist/vendor/core/http/client.js +170 -0
- package/dist/vendor/core/http/index.d.ts +2 -0
- package/dist/vendor/core/http/index.d.ts.map +1 -0
- package/dist/vendor/core/http/index.js +1 -0
- package/dist/vendor/core/index.d.ts +5 -0
- package/dist/vendor/core/index.d.ts.map +1 -0
- package/dist/vendor/core/index.js +4 -0
- package/dist/vendor/core/invoke.d.ts +17 -0
- package/dist/vendor/core/invoke.d.ts.map +1 -0
- package/dist/vendor/core/invoke.js +70 -0
- package/package.json +57 -0
- package/skills/quantbrasil/SKILL.md +29 -0
- package/skills/quantbrasil/references/cli.md +77 -0
- package/skills/quantbrasil/references/costs.md +30 -0
- package/skills/quantbrasil/references/errors.md +128 -0
- package/skills/quantbrasil/references/unsupported.md +20 -0
- package/skills/quantbrasil/references/workflows.md +99 -0
|
@@ -0,0 +1 @@
|
|
|
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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { analyticsCapabilities } from "./analytics.js";
|
|
2
|
+
import { assetCapabilities } from "./assets.js";
|
|
3
|
+
import { marketCapabilities } from "./market.js";
|
|
4
|
+
import { portfolioCapabilities } from "./portfolios.js";
|
|
5
|
+
export const capabilityRegistry = [
|
|
6
|
+
...marketCapabilities,
|
|
7
|
+
...assetCapabilities,
|
|
8
|
+
...portfolioCapabilities,
|
|
9
|
+
...analyticsCapabilities,
|
|
10
|
+
];
|
|
11
|
+
export const capabilityRegistryById = Object.fromEntries(capabilityRegistry.map(capability => [capability.id, capability]));
|
|
12
|
+
export function getCapabilityById(id) {
|
|
13
|
+
return capabilityRegistryById[id];
|
|
14
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../src/capabilities/shared.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,uBAAuB,8BAA+B,CAAC;AACpE,eAAO,MAAM,mBAAmB,4BAA6B,CAAC"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
export type CapabilityVisibility = "cli" | "opencode";
|
|
2
|
+
export type CapabilityKind = "read" | "mutation";
|
|
3
|
+
export type CapabilityGroup = "market" | "assets" | "portfolios" | "analytics";
|
|
4
|
+
export type CapabilityHttpMethod = "GET" | "POST";
|
|
5
|
+
export type CapabilityInputMode = "none" | "query" | "json_body";
|
|
6
|
+
export type CapabilityOutputMode = "json" | "human";
|
|
7
|
+
export type CapabilityParameterType = "string" | "integer" | "number" | "enum" | "string_array" | "enum_array";
|
|
8
|
+
export type CapabilityCollectionFormat = "repeatable" | "comma_separated" | "space_separated";
|
|
9
|
+
export type CapabilityDefaultValue = string | number | boolean | readonly (string | number | boolean)[];
|
|
10
|
+
/** Backend schema references for one deterministic capability. */
|
|
11
|
+
export interface CapabilitySchemaReference {
|
|
12
|
+
/** Request schema name, or `null` when the route takes no request payload. */
|
|
13
|
+
request: string | null;
|
|
14
|
+
/** Response schema name. This is always required. */
|
|
15
|
+
response: string;
|
|
16
|
+
}
|
|
17
|
+
/** Exact backend transport contract used by the capability executor. */
|
|
18
|
+
export interface CapabilityHttpMetadata {
|
|
19
|
+
method: CapabilityHttpMethod;
|
|
20
|
+
path: `/api/desk/tools/${string}`;
|
|
21
|
+
inputMode: CapabilityInputMode;
|
|
22
|
+
schemas: CapabilitySchemaReference;
|
|
23
|
+
}
|
|
24
|
+
/** Shared fields for CLI positional and option parameters. */
|
|
25
|
+
export interface CapabilityCliParameterBase {
|
|
26
|
+
name: string;
|
|
27
|
+
description: string;
|
|
28
|
+
type: CapabilityParameterType;
|
|
29
|
+
required: boolean;
|
|
30
|
+
placeholder?: string;
|
|
31
|
+
defaultValue?: CapabilityDefaultValue;
|
|
32
|
+
enumValues?: readonly string[];
|
|
33
|
+
multiple?: boolean;
|
|
34
|
+
collectionFormat?: CapabilityCollectionFormat;
|
|
35
|
+
exclusiveGroup?: string;
|
|
36
|
+
}
|
|
37
|
+
export interface CapabilityCliPositionalParameter extends CapabilityCliParameterBase {
|
|
38
|
+
kind: "positional";
|
|
39
|
+
}
|
|
40
|
+
export interface CapabilityCliOptionParameter extends CapabilityCliParameterBase {
|
|
41
|
+
kind: "option";
|
|
42
|
+
flag: `--${string}`;
|
|
43
|
+
}
|
|
44
|
+
export type CapabilityCliParameter = CapabilityCliPositionalParameter | CapabilityCliOptionParameter;
|
|
45
|
+
/** CLI-facing metadata for one published capability. */
|
|
46
|
+
export interface CapabilityCliMetadata {
|
|
47
|
+
group: CapabilityGroup;
|
|
48
|
+
command: string;
|
|
49
|
+
summary: string;
|
|
50
|
+
positional: readonly CapabilityCliPositionalParameter[];
|
|
51
|
+
options: readonly CapabilityCliOptionParameter[];
|
|
52
|
+
/**
|
|
53
|
+
* Copy-pasteable examples are required.
|
|
54
|
+
* Treat these as part of the product contract, especially for capabilities
|
|
55
|
+
* with mutually exclusive inputs, repeatable flags, or non-obvious defaults.
|
|
56
|
+
*/
|
|
57
|
+
examples: readonly string[];
|
|
58
|
+
}
|
|
59
|
+
/** Metadata exposed to the hosted OpenCode runtime. */
|
|
60
|
+
export interface CapabilityToolMetadata {
|
|
61
|
+
name: string;
|
|
62
|
+
title: string;
|
|
63
|
+
}
|
|
64
|
+
/** Canonical hand-authored contract for one deterministic Desk capability. */
|
|
65
|
+
export interface CapabilityDefinition {
|
|
66
|
+
id: string;
|
|
67
|
+
kind: CapabilityKind;
|
|
68
|
+
visibility: readonly CapabilityVisibility[];
|
|
69
|
+
description: string;
|
|
70
|
+
http: CapabilityHttpMetadata;
|
|
71
|
+
cli: CapabilityCliMetadata;
|
|
72
|
+
tool: CapabilityToolMetadata;
|
|
73
|
+
outputModes: readonly CapabilityOutputMode[];
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/capabilities/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export declare class DeskCoreError extends Error {
|
|
2
|
+
constructor(message: string, options?: ErrorOptions);
|
|
3
|
+
}
|
|
4
|
+
export declare class DeskConfigError extends DeskCoreError {
|
|
5
|
+
constructor(message: string, options?: ErrorOptions);
|
|
6
|
+
}
|
|
7
|
+
export declare class DeskJsonCompatibilityError extends DeskCoreError {
|
|
8
|
+
readonly valuePath: string;
|
|
9
|
+
readonly valueDescription: string;
|
|
10
|
+
constructor(valuePath: string, valueDescription: string);
|
|
11
|
+
}
|
|
12
|
+
export declare class DeskHttpError extends DeskCoreError {
|
|
13
|
+
readonly status: number;
|
|
14
|
+
readonly path: string;
|
|
15
|
+
readonly requestId: string;
|
|
16
|
+
readonly body: unknown;
|
|
17
|
+
constructor(status: number, path: string, requestId: string, body: unknown);
|
|
18
|
+
}
|
|
19
|
+
export declare class DeskInvocationError extends DeskCoreError {
|
|
20
|
+
constructor(message: string, options?: ErrorOptions);
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,qBAAa,aAAc,SAAQ,KAAK;gBAC1B,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY;CAIpD;AAED,qBAAa,eAAgB,SAAQ,aAAa;gBACpC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY;CAIpD;AAED,qBAAa,0BAA2B,SAAQ,aAAa;aAEzC,SAAS,EAAE,MAAM;aACjB,gBAAgB,EAAE,MAAM;gBADxB,SAAS,EAAE,MAAM,EACjB,gBAAgB,EAAE,MAAM;CAK3C;AAED,qBAAa,aAAc,SAAQ,aAAa;aAE5B,MAAM,EAAE,MAAM;aACd,IAAI,EAAE,MAAM;aACZ,SAAS,EAAE,MAAM;aACjB,IAAI,EAAE,OAAO;gBAHb,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,OAAO;CAKhC;AAED,qBAAa,mBAAoB,SAAQ,aAAa;gBACxC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY;CAIpD"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export class DeskCoreError extends Error {
|
|
2
|
+
constructor(message, options) {
|
|
3
|
+
super(message, options);
|
|
4
|
+
this.name = "DeskCoreError";
|
|
5
|
+
}
|
|
6
|
+
}
|
|
7
|
+
export class DeskConfigError extends DeskCoreError {
|
|
8
|
+
constructor(message, options) {
|
|
9
|
+
super(message, options);
|
|
10
|
+
this.name = "DeskConfigError";
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
export class DeskJsonCompatibilityError extends DeskCoreError {
|
|
14
|
+
valuePath;
|
|
15
|
+
valueDescription;
|
|
16
|
+
constructor(valuePath, valueDescription) {
|
|
17
|
+
super(`Value at ${valuePath} is not JSON-compatible: ${valueDescription}.`);
|
|
18
|
+
this.valuePath = valuePath;
|
|
19
|
+
this.valueDescription = valueDescription;
|
|
20
|
+
this.name = "DeskJsonCompatibilityError";
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
export class DeskHttpError extends DeskCoreError {
|
|
24
|
+
status;
|
|
25
|
+
path;
|
|
26
|
+
requestId;
|
|
27
|
+
body;
|
|
28
|
+
constructor(status, path, requestId, body) {
|
|
29
|
+
super(`Desk request failed (${status} ${path}, request ${requestId}).`);
|
|
30
|
+
this.status = status;
|
|
31
|
+
this.path = path;
|
|
32
|
+
this.requestId = requestId;
|
|
33
|
+
this.body = body;
|
|
34
|
+
this.name = "DeskHttpError";
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
export class DeskInvocationError extends DeskCoreError {
|
|
38
|
+
constructor(message, options) {
|
|
39
|
+
super(message, options);
|
|
40
|
+
this.name = "DeskInvocationError";
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { CapabilityHttpMethod } from "../capabilities/types.js";
|
|
2
|
+
export type JsonPrimitive = string | number | boolean | null;
|
|
3
|
+
export type JsonValue = JsonPrimitive | JsonValue[] | {
|
|
4
|
+
[key: string]: JsonValue;
|
|
5
|
+
};
|
|
6
|
+
export type JsonQueryScalar = string | number | boolean;
|
|
7
|
+
export type JsonQueryValue = JsonQueryScalar | readonly JsonQueryScalar[] | null | undefined;
|
|
8
|
+
export type JsonQueryParams = Record<string, JsonQueryValue>;
|
|
9
|
+
export interface DeskClientConfig {
|
|
10
|
+
baseUrl?: string;
|
|
11
|
+
fetch?: typeof fetch;
|
|
12
|
+
defaultHeaders?: Record<string, string>;
|
|
13
|
+
}
|
|
14
|
+
export interface DeskJsonRequest {
|
|
15
|
+
method: CapabilityHttpMethod;
|
|
16
|
+
path: `/api/desk/${string}`;
|
|
17
|
+
authHeaders?: Record<string, string>;
|
|
18
|
+
headers?: Record<string, string>;
|
|
19
|
+
requestId?: string;
|
|
20
|
+
query?: JsonQueryParams;
|
|
21
|
+
body?: JsonValue;
|
|
22
|
+
abort?: AbortSignal;
|
|
23
|
+
}
|
|
24
|
+
export interface DeskJsonResponse<T extends JsonValue = JsonValue> {
|
|
25
|
+
data: T;
|
|
26
|
+
requestId: string;
|
|
27
|
+
status: number;
|
|
28
|
+
}
|
|
29
|
+
export interface DeskHttpClient {
|
|
30
|
+
request<T extends JsonValue = JsonValue>(request: DeskJsonRequest): Promise<DeskJsonResponse<T>>;
|
|
31
|
+
}
|
|
32
|
+
export interface DeskInternalAuthHeadersInput {
|
|
33
|
+
sessionID: string;
|
|
34
|
+
messageID?: string;
|
|
35
|
+
token?: string;
|
|
36
|
+
}
|
|
37
|
+
export declare const DESK_REQUEST_ID_PREFIX = "qbreq_";
|
|
38
|
+
export declare const DESK_REQUEST_ID_HEADER = "x-request-id";
|
|
39
|
+
export declare function resolveDeskBackendUrl(raw?: string): string;
|
|
40
|
+
export declare function resolveDeskInternalToken(raw?: string): string;
|
|
41
|
+
export declare function createDeskRequestId(): string;
|
|
42
|
+
export declare function buildDeskInternalAuthHeaders(input: DeskInternalAuthHeadersInput): Record<string, string>;
|
|
43
|
+
export declare function assertJsonCompatible(value: unknown, valuePath?: string): asserts value is JsonValue;
|
|
44
|
+
export declare function createDeskHttpClient(config?: DeskClientConfig): DeskHttpClient;
|
|
45
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/http/client.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAOrE,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC;AAC7D,MAAM,MAAM,SAAS,GACjB,aAAa,GACb,SAAS,EAAE,GACX;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,CAAC;AACjC,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AACxD,MAAM,MAAM,cAAc,GACtB,eAAe,GACf,SAAS,eAAe,EAAE,GAC1B,IAAI,GACJ,SAAS,CAAC;AACd,MAAM,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;AAE7D,MAAM,WAAW,gBAAgB;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACzC;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,oBAAoB,CAAC;IAC7B,IAAI,EAAE,aAAa,MAAM,EAAE,CAAC;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,KAAK,CAAC,EAAE,WAAW,CAAC;CACrB;AAED,MAAM,WAAW,gBAAgB,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS;IAC/D,IAAI,EAAE,CAAC,CAAC;IACR,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS,EACrC,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC;CACjC;AAED,MAAM,WAAW,4BAA4B;IAC3C,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,eAAO,MAAM,sBAAsB,WAAW,CAAC;AAC/C,eAAO,MAAM,sBAAsB,iBAAiB,CAAC;AAErD,wBAAgB,qBAAqB,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAQ1D;AAED,wBAAgB,wBAAwB,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAU7D;AAED,wBAAgB,mBAAmB,IAAI,MAAM,CAE5C;AAED,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,4BAA4B,GAClC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAWxB;AAED,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,OAAO,EACd,SAAS,SAAM,GACd,OAAO,CAAC,KAAK,IAAI,SAAS,CA4C5B;AAED,wBAAgB,oBAAoB,CAClC,MAAM,GAAE,gBAAqB,GAC5B,cAAc,CAkEhB"}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { DeskConfigError, DeskHttpError, DeskJsonCompatibilityError, } from "../errors.js";
|
|
3
|
+
export const DESK_REQUEST_ID_PREFIX = "qbreq_";
|
|
4
|
+
export const DESK_REQUEST_ID_HEADER = "x-request-id";
|
|
5
|
+
export function resolveDeskBackendUrl(raw) {
|
|
6
|
+
const source = raw ??
|
|
7
|
+
process.env.QB_BACKEND_URL ??
|
|
8
|
+
process.env.DESK_API_URL ??
|
|
9
|
+
"http://127.0.0.1:8000";
|
|
10
|
+
return source.endsWith("/") ? source.slice(0, -1) : source;
|
|
11
|
+
}
|
|
12
|
+
export function resolveDeskInternalToken(raw) {
|
|
13
|
+
const token = raw ?? process.env.DESK_AGENT_SECRET ?? "";
|
|
14
|
+
if (!token) {
|
|
15
|
+
throw new DeskConfigError("DESK_AGENT_SECRET is not set. Internal Desk calls require machine auth.");
|
|
16
|
+
}
|
|
17
|
+
return token;
|
|
18
|
+
}
|
|
19
|
+
export function createDeskRequestId() {
|
|
20
|
+
return `${DESK_REQUEST_ID_PREFIX}${randomUUID()}`;
|
|
21
|
+
}
|
|
22
|
+
export function buildDeskInternalAuthHeaders(input) {
|
|
23
|
+
const headers = {
|
|
24
|
+
authorization: `Bearer ${resolveDeskInternalToken(input.token)}`,
|
|
25
|
+
"x-opencode-session-id": input.sessionID,
|
|
26
|
+
};
|
|
27
|
+
if (input.messageID) {
|
|
28
|
+
headers["x-opencode-message-id"] = input.messageID;
|
|
29
|
+
}
|
|
30
|
+
return headers;
|
|
31
|
+
}
|
|
32
|
+
export function assertJsonCompatible(value, valuePath = "$") {
|
|
33
|
+
if (value === null) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
if (typeof value === "string" || typeof value === "boolean") {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
if (typeof value === "number") {
|
|
40
|
+
if (!Number.isFinite(value)) {
|
|
41
|
+
throw new DeskJsonCompatibilityError(valuePath, `non-finite number ${value}`);
|
|
42
|
+
}
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
if (Array.isArray(value)) {
|
|
46
|
+
for (const [index, item] of value.entries()) {
|
|
47
|
+
assertJsonCompatible(item, `${valuePath}[${index}]`);
|
|
48
|
+
}
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
if (isPlainObject(value)) {
|
|
52
|
+
for (const [key, item] of Object.entries(value)) {
|
|
53
|
+
if (item === undefined) {
|
|
54
|
+
throw new DeskJsonCompatibilityError(`${valuePath}.${key}`, "undefined value");
|
|
55
|
+
}
|
|
56
|
+
assertJsonCompatible(item, `${valuePath}.${key}`);
|
|
57
|
+
}
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
throw new DeskJsonCompatibilityError(valuePath, describeValue(value));
|
|
61
|
+
}
|
|
62
|
+
export function createDeskHttpClient(config = {}) {
|
|
63
|
+
const fetchImpl = config.fetch ?? globalThis.fetch;
|
|
64
|
+
if (!fetchImpl) {
|
|
65
|
+
throw new DeskConfigError("Global fetch is unavailable. Pass a fetch implementation to createDeskHttpClient().");
|
|
66
|
+
}
|
|
67
|
+
const baseUrl = resolveDeskBackendUrl(config.baseUrl);
|
|
68
|
+
return {
|
|
69
|
+
async request(request) {
|
|
70
|
+
const requestId = request.requestId ?? createDeskRequestId();
|
|
71
|
+
const url = new URL(`${baseUrl}${request.path}`);
|
|
72
|
+
if (request.query) {
|
|
73
|
+
appendQueryParams(url, request.query);
|
|
74
|
+
}
|
|
75
|
+
const headers = {
|
|
76
|
+
accept: "application/json",
|
|
77
|
+
...config.defaultHeaders,
|
|
78
|
+
...request.headers,
|
|
79
|
+
...request.authHeaders,
|
|
80
|
+
[DESK_REQUEST_ID_HEADER]: requestId,
|
|
81
|
+
};
|
|
82
|
+
let body;
|
|
83
|
+
if (request.body !== undefined) {
|
|
84
|
+
assertJsonCompatible(request.body);
|
|
85
|
+
headers["content-type"] = "application/json";
|
|
86
|
+
body = JSON.stringify(request.body);
|
|
87
|
+
}
|
|
88
|
+
const response = await fetchImpl(url.toString(), {
|
|
89
|
+
method: request.method,
|
|
90
|
+
headers,
|
|
91
|
+
body,
|
|
92
|
+
signal: request.abort,
|
|
93
|
+
});
|
|
94
|
+
const resolvedRequestId = response.headers.get(DESK_REQUEST_ID_HEADER) ?? requestId;
|
|
95
|
+
const payload = await readResponsePayload(response, response.ok);
|
|
96
|
+
if (!response.ok) {
|
|
97
|
+
throw new DeskHttpError(response.status, request.path, resolvedRequestId, payload);
|
|
98
|
+
}
|
|
99
|
+
assertJsonCompatible(payload);
|
|
100
|
+
return {
|
|
101
|
+
data: payload,
|
|
102
|
+
requestId: resolvedRequestId,
|
|
103
|
+
status: response.status,
|
|
104
|
+
};
|
|
105
|
+
},
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
function appendQueryParams(url, query) {
|
|
109
|
+
for (const [key, rawValue] of Object.entries(query)) {
|
|
110
|
+
if (rawValue === undefined || rawValue === null) {
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
if (isQueryScalarArray(rawValue)) {
|
|
114
|
+
for (const item of rawValue) {
|
|
115
|
+
url.searchParams.append(key, serializeQueryScalar(item, key));
|
|
116
|
+
}
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
url.searchParams.set(key, serializeQueryScalar(rawValue, key));
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
function serializeQueryScalar(value, key) {
|
|
123
|
+
if (typeof value === "number" && !Number.isFinite(value)) {
|
|
124
|
+
throw new DeskJsonCompatibilityError(`$.${key}`, `non-finite number ${value}`);
|
|
125
|
+
}
|
|
126
|
+
return String(value);
|
|
127
|
+
}
|
|
128
|
+
function isQueryScalarArray(value) {
|
|
129
|
+
return Array.isArray(value);
|
|
130
|
+
}
|
|
131
|
+
async function readResponsePayload(response, requireJson) {
|
|
132
|
+
const text = await response.text();
|
|
133
|
+
if (!text.trim()) {
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
136
|
+
try {
|
|
137
|
+
return JSON.parse(text);
|
|
138
|
+
}
|
|
139
|
+
catch {
|
|
140
|
+
if (requireJson) {
|
|
141
|
+
throw new DeskConfigError(`Desk endpoint ${response.url} returned a non-JSON success payload.`);
|
|
142
|
+
}
|
|
143
|
+
return text;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
function isPlainObject(value) {
|
|
147
|
+
if (Object.prototype.toString.call(value) !== "[object Object]") {
|
|
148
|
+
return false;
|
|
149
|
+
}
|
|
150
|
+
const prototype = Object.getPrototypeOf(value);
|
|
151
|
+
return prototype === null || prototype === Object.prototype;
|
|
152
|
+
}
|
|
153
|
+
function describeValue(value) {
|
|
154
|
+
if (value === undefined) {
|
|
155
|
+
return "undefined";
|
|
156
|
+
}
|
|
157
|
+
if (typeof value === "bigint") {
|
|
158
|
+
return "bigint";
|
|
159
|
+
}
|
|
160
|
+
if (typeof value === "function") {
|
|
161
|
+
return "function";
|
|
162
|
+
}
|
|
163
|
+
if (typeof value === "symbol") {
|
|
164
|
+
return "symbol";
|
|
165
|
+
}
|
|
166
|
+
if (value instanceof Date) {
|
|
167
|
+
return "Date";
|
|
168
|
+
}
|
|
169
|
+
return Object.prototype.toString.call(value);
|
|
170
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/http/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./client.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,yBAAyB,CAAC;AACxC,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type CapabilityId } from "./capabilities/registry.js";
|
|
2
|
+
import type { CapabilityDefinition } from "./capabilities/types.js";
|
|
3
|
+
import { type DeskHttpClient, type DeskJsonResponse, type JsonQueryParams, type JsonValue } from "./http/client.js";
|
|
4
|
+
export interface InvokeCapabilityOptions {
|
|
5
|
+
capability: CapabilityDefinition | CapabilityId;
|
|
6
|
+
input?: JsonValue | JsonQueryParams;
|
|
7
|
+
client?: DeskHttpClient;
|
|
8
|
+
authHeaders?: Record<string, string>;
|
|
9
|
+
headers?: Record<string, string>;
|
|
10
|
+
requestId?: string;
|
|
11
|
+
abort?: AbortSignal;
|
|
12
|
+
}
|
|
13
|
+
export interface CapabilityInvocationResult<T extends JsonValue = JsonValue> extends DeskJsonResponse<T> {
|
|
14
|
+
capability: CapabilityDefinition;
|
|
15
|
+
}
|
|
16
|
+
export declare function invokeCapability<T extends JsonValue = JsonValue>(options: InvokeCapabilityOptions): Promise<CapabilityInvocationResult<T>>;
|
|
17
|
+
//# sourceMappingURL=invoke.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"invoke.d.ts","sourceRoot":"","sources":["../src/invoke.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,YAAY,EAClB,MAAM,4BAA4B,CAAC;AACpC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAEpE,OAAO,EAGL,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,SAAS,EACf,MAAM,kBAAkB,CAAC;AAE1B,MAAM,WAAW,uBAAuB;IACtC,UAAU,EAAE,oBAAoB,GAAG,YAAY,CAAC;IAChD,KAAK,CAAC,EAAE,SAAS,GAAG,eAAe,CAAC;IACpC,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,WAAW,CAAC;CACrB;AAED,MAAM,WAAW,0BAA0B,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS,CACzE,SAAQ,gBAAgB,CAAC,CAAC,CAAC;IAC3B,UAAU,EAAE,oBAAoB,CAAC;CAClC;AAED,wBAAsB,gBAAgB,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS,EACpE,OAAO,EAAE,uBAAuB,GAC/B,OAAO,CAAC,0BAA0B,CAAC,CAAC,CAAC,CAAC,CAkBxC"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { capabilityRegistryById, } from "./capabilities/registry.js";
|
|
2
|
+
import { DeskInvocationError } from "./errors.js";
|
|
3
|
+
import { assertJsonCompatible, createDeskHttpClient, } from "./http/client.js";
|
|
4
|
+
export async function invokeCapability(options) {
|
|
5
|
+
const capability = resolveCapability(options.capability);
|
|
6
|
+
const client = options.client ?? createDeskHttpClient();
|
|
7
|
+
const request = buildCapabilityRequest(capability, options.input);
|
|
8
|
+
const response = await client.request({
|
|
9
|
+
method: capability.http.method,
|
|
10
|
+
path: capability.http.path,
|
|
11
|
+
authHeaders: options.authHeaders,
|
|
12
|
+
headers: options.headers,
|
|
13
|
+
requestId: options.requestId,
|
|
14
|
+
abort: options.abort,
|
|
15
|
+
...request,
|
|
16
|
+
});
|
|
17
|
+
return {
|
|
18
|
+
capability,
|
|
19
|
+
...response,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
function resolveCapability(capability) {
|
|
23
|
+
if (typeof capability !== "string") {
|
|
24
|
+
return capability;
|
|
25
|
+
}
|
|
26
|
+
return capabilityRegistryById[capability];
|
|
27
|
+
}
|
|
28
|
+
function buildCapabilityRequest(capability, input) {
|
|
29
|
+
switch (capability.http.inputMode) {
|
|
30
|
+
case "none":
|
|
31
|
+
assertNoInput(capability, input);
|
|
32
|
+
return {};
|
|
33
|
+
case "query":
|
|
34
|
+
return {
|
|
35
|
+
query: normalizeQueryInput(capability, input),
|
|
36
|
+
};
|
|
37
|
+
case "json_body":
|
|
38
|
+
return {
|
|
39
|
+
body: normalizeJsonBodyInput(capability, input),
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function assertNoInput(capability, input) {
|
|
44
|
+
if (input === undefined || input === null) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
if (isRecord(input) && Object.keys(input).length === 0) {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
throw new DeskInvocationError(`${capability.id} does not accept input because its mode is "none".`);
|
|
51
|
+
}
|
|
52
|
+
function normalizeQueryInput(capability, input) {
|
|
53
|
+
if (input === undefined || input === null) {
|
|
54
|
+
return {};
|
|
55
|
+
}
|
|
56
|
+
if (!isRecord(input) || Array.isArray(input)) {
|
|
57
|
+
throw new DeskInvocationError(`${capability.id} requires a plain object input for query parameters.`);
|
|
58
|
+
}
|
|
59
|
+
return input;
|
|
60
|
+
}
|
|
61
|
+
function normalizeJsonBodyInput(capability, input) {
|
|
62
|
+
if (input === undefined) {
|
|
63
|
+
throw new DeskInvocationError(`${capability.id} requires JSON input because its mode is "json_body".`);
|
|
64
|
+
}
|
|
65
|
+
assertJsonCompatible(input);
|
|
66
|
+
return input;
|
|
67
|
+
}
|
|
68
|
+
function isRecord(value) {
|
|
69
|
+
return typeof value === "object" && value !== null;
|
|
70
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@quantbrasil/cli",
|
|
3
|
+
"version": "0.1.0-beta.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "Public QuantBrasil CLI for deterministic operations",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+ssh://git@github.com/quantbrasil/quantbrasil.git",
|
|
9
|
+
"directory": "monorepo/packages/cli"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"bin",
|
|
13
|
+
"dist",
|
|
14
|
+
"skills",
|
|
15
|
+
"README.md"
|
|
16
|
+
],
|
|
17
|
+
"publishConfig": {
|
|
18
|
+
"access": "public"
|
|
19
|
+
},
|
|
20
|
+
"main": "./dist/index.js",
|
|
21
|
+
"types": "./dist/index.d.ts",
|
|
22
|
+
"bin": {
|
|
23
|
+
"quantbrasil": "./bin/quantbrasil.js"
|
|
24
|
+
},
|
|
25
|
+
"exports": {
|
|
26
|
+
".": {
|
|
27
|
+
"import": "./dist/index.js",
|
|
28
|
+
"types": "./dist/index.d.ts"
|
|
29
|
+
},
|
|
30
|
+
"./cli": {
|
|
31
|
+
"import": "./dist/cli/index.js",
|
|
32
|
+
"types": "./dist/cli/index.d.ts"
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"commander": "^12.0.0"
|
|
37
|
+
},
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"@types/node": "^20.10.6",
|
|
40
|
+
"eslint": "^9.15.0",
|
|
41
|
+
"typescript": "^5.3.3",
|
|
42
|
+
"vitest": "^3.2.4",
|
|
43
|
+
"@repo/core": "0.0.0",
|
|
44
|
+
"@repo/eslint-config": "0.0.0",
|
|
45
|
+
"@repo/typescript-config": "0.0.0"
|
|
46
|
+
},
|
|
47
|
+
"scripts": {
|
|
48
|
+
"build": "pnpm --filter @repo/core build && pnpm run clean && tsc && node scripts/vendor-core.mjs",
|
|
49
|
+
"clean": "node scripts/clean.mjs",
|
|
50
|
+
"dev": "tsc --watch",
|
|
51
|
+
"lint": "eslint . --max-warnings 0",
|
|
52
|
+
"pack:smoke": "node scripts/smoke-packed-cli.mjs",
|
|
53
|
+
"typecheck": "tsc --noEmit",
|
|
54
|
+
"format": "prettier --write \"**/*.{ts,js,json,md}\"",
|
|
55
|
+
"test": "vitest run"
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: quantbrasil
|
|
3
|
+
description: Use QuantBrasil CLI for deterministic market, asset, portfolio, and analytics workflows.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# QuantBrasil CLI
|
|
7
|
+
|
|
8
|
+
Use this skill when user needs deterministic QuantBrasil data or analytics through CLI.
|
|
9
|
+
|
|
10
|
+
## Routing
|
|
11
|
+
|
|
12
|
+
- Check readiness first: `quantbrasil --status`
|
|
13
|
+
- Inspect public surface when unsure: `quantbrasil capabilities --json`
|
|
14
|
+
- Use narrow command first:
|
|
15
|
+
- asset discovery: `quantbrasil market assets`
|
|
16
|
+
- price lookup: `quantbrasil market price <ticker>`
|
|
17
|
+
- richer asset analysis: `quantbrasil assets overview <ticker> --sections ...`
|
|
18
|
+
- saved portfolio discovery: `quantbrasil portfolios list`
|
|
19
|
+
- saved portfolio details: `quantbrasil portfolios get <id>`
|
|
20
|
+
- portfolio analytics: `quantbrasil analytics historical-return|beta|var ...`
|
|
21
|
+
- Use `--json` when output will be parsed by agent or script
|
|
22
|
+
|
|
23
|
+
## References
|
|
24
|
+
|
|
25
|
+
- CLI surface: [`references/cli.md`](./references/cli.md)
|
|
26
|
+
- Common workflows: [`references/workflows.md`](./references/workflows.md)
|
|
27
|
+
- Cost-aware behavior: [`references/costs.md`](./references/costs.md)
|
|
28
|
+
- Failure handling: [`references/errors.md`](./references/errors.md)
|
|
29
|
+
- Unsupported / not-yet-public operations: [`references/unsupported.md`](./references/unsupported.md)
|