@cargo-ai/cli 1.0.41 → 1.0.43

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.
@@ -0,0 +1,4 @@
1
+ import type { Command } from "commander";
2
+ import type { Api } from "../../api.js";
3
+ export declare function registerAlertCommands(parent: Command, getApi: () => Api): void;
4
+ //# sourceMappingURL=alert.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"alert.d.ts","sourceRoot":"","sources":["../../../src/commands/observability/alert.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AA0BxC,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,OAAO,EACf,MAAM,EAAE,MAAM,GAAG,GAChB,IAAI,CAsMN"}
@@ -0,0 +1,131 @@
1
+ import { ExitCodes, failWith, handleApiCall, outputJson, parseJson, } from "../runHandler.js";
2
+ // Strict on purpose: `--enabled yes` silently DISABLING the alert (anything
3
+ // but the literal "true" used to read as false) is the kind of surprise a
4
+ // usage error prevents.
5
+ function parseBooleanOption(value, optionName) {
6
+ if (value === "true") {
7
+ return true;
8
+ }
9
+ if (value === "false") {
10
+ return false;
11
+ }
12
+ failWith(`${optionName} must be "true" or "false", got "${value}".`, {
13
+ code: ExitCodes.InvalidUsage,
14
+ });
15
+ }
16
+ export function registerAlertCommands(parent, getApi) {
17
+ const alert = parent
18
+ .command("alert")
19
+ .description("Alert operations (scheduled threshold alerts on spans, runs, records, SQL or a model)");
20
+ alert
21
+ .command("list")
22
+ .description("List all alerts")
23
+ .action(async () => {
24
+ const api = getApi();
25
+ const result = await handleApiCall(() => api.observability.alert.list());
26
+ outputJson(result);
27
+ });
28
+ alert
29
+ .command("get <uuid>")
30
+ .description("Get an alert")
31
+ .action(async (uuid) => {
32
+ const api = getApi();
33
+ const result = await handleApiCall(() => api.observability.alert.get(uuid));
34
+ outputJson(result);
35
+ });
36
+ alert
37
+ .command("create")
38
+ .description("Create an alert")
39
+ .requiredOption("--name <name>", "Alert name")
40
+ .requiredOption("--cron <cron>", 'Evaluation schedule: 5-field cron or "@every <interval>" (UTC), at most once a minute')
41
+ .requiredOption("--scope <json>", 'Scope (JSON), one of: {"kind":"spans","workflowUuid":"..."}, {"kind":"runs","workflowUuid":"...","statuses":["error"]}, {"kind":"records","workflowUuid":"...","statuses":["error"]}, {"kind":"orchestrationQuery","query":"select ..."}, {"kind":"storageQuery","query":"select ..."} or {"kind":"model","modelUuid":"...","filter":{...}}')
42
+ .requiredOption("--threshold <json>", 'Threshold (JSON). Spans, runs and records scopes: {"metric":"errorRate","operator":"gte","value":10}, {"metric":"duration","aggregation":"p95","operator":"gte","value":30}, {"metric":"credits","aggregation":"sum","operator":"gte","value":500} or {"metric":"count","operator":"lte","value":0}; model scopes: {"metric":"recordsCount","operator":"lte","value":0}, {"metric":"recordsShare","operator":"gte","value":30} (needs a scope filter), {"metric":"freshness","operator":"gte","value":60} or {"metric":"syncDuration","operator":"gte","value":300}; query scopes: {"metric":"query","operator":"gte","value":10}')
43
+ .option("--actions <json>", "Actions fired as runs on breach (JSON Action[]: connector, tool, or agent nodes)")
44
+ .option("--disabled", "Create the alert disabled")
45
+ .option("--description <text>", "What this alert watches")
46
+ .option("--folder <uuid>", "Folder UUID to file the alert under")
47
+ .action(async (opts) => {
48
+ const api = getApi();
49
+ const result = await handleApiCall(() => api.observability.alert.create({
50
+ name: opts.name,
51
+ description: opts.description,
52
+ cron: opts.cron,
53
+ isEnabled: opts.disabled === true ? false : undefined,
54
+ scope: parseJson(opts.scope, "--scope"),
55
+ threshold: parseJson(opts.threshold, "--threshold"),
56
+ actions: opts.actions !== undefined
57
+ ? parseJson(opts.actions, "--actions")
58
+ : undefined,
59
+ folderUuid: opts.folder,
60
+ }));
61
+ outputJson(result);
62
+ });
63
+ alert
64
+ .command("update")
65
+ .description("Update an alert")
66
+ .requiredOption("--uuid <uuid>", "Alert UUID")
67
+ .option("--name <name>", "Alert name")
68
+ .option("--cron <cron>", 'Evaluation schedule: 5-field cron or "@every <interval>" (UTC), at most once a minute')
69
+ .option("--enabled <boolean>", "Enable or disable the alert (true/false)")
70
+ .option("--scope <json>", "Scope (JSON). See `alert create`")
71
+ .option("--threshold <json>", "Threshold (JSON). See `alert create`")
72
+ .option("--actions <json>", "Actions fired as runs on breach (JSON Action[])")
73
+ .option("--description <text>", 'What this alert watches, or "none" to clear it')
74
+ .option("--folder <uuid>", 'Folder UUID to move the alert to, or "none" to remove it from its folder')
75
+ .action(async (opts) => {
76
+ const api = getApi();
77
+ const result = await handleApiCall(() => api.observability.alert.update({
78
+ uuid: opts.uuid,
79
+ name: opts.name,
80
+ cron: opts.cron,
81
+ isEnabled: opts.enabled !== undefined
82
+ ? parseBooleanOption(opts.enabled, "--enabled")
83
+ : undefined,
84
+ scope: opts.scope !== undefined
85
+ ? parseJson(opts.scope, "--scope")
86
+ : undefined,
87
+ threshold: opts.threshold !== undefined
88
+ ? parseJson(opts.threshold, "--threshold")
89
+ : undefined,
90
+ actions: opts.actions !== undefined
91
+ ? parseJson(opts.actions, "--actions")
92
+ : undefined,
93
+ description: opts.description === undefined
94
+ ? undefined
95
+ : opts.description === "none"
96
+ ? null
97
+ : opts.description,
98
+ // "none" is the explicit "take it out of its folder" spelling —
99
+ // omitting --folder leaves the alert where it is.
100
+ folderUuid: opts.folder === undefined
101
+ ? undefined
102
+ : opts.folder === "none"
103
+ ? null
104
+ : opts.folder,
105
+ }));
106
+ outputJson(result);
107
+ });
108
+ alert
109
+ .command("remove <uuid>")
110
+ .description("Remove an alert")
111
+ .action(async (uuid) => {
112
+ const api = getApi();
113
+ await handleApiCall(() => api.observability.alert.remove(uuid));
114
+ outputJson({ ok: true });
115
+ });
116
+ alert
117
+ .command("preview")
118
+ .description("Evaluate a scope + threshold now, without firing actions")
119
+ .requiredOption("--scope <json>", "Scope (JSON). See `alert create`")
120
+ .requiredOption("--threshold <json>", "Threshold (JSON). See `alert create`")
121
+ .option("--window-minutes <minutes>", "Evaluation window ending now (spans, runs and records scopes only; a model is measured as it stands, and a query windows itself)", "60")
122
+ .action(async (opts) => {
123
+ const api = getApi();
124
+ const result = await handleApiCall(() => api.observability.alert.preview({
125
+ scope: parseJson(opts.scope, "--scope"),
126
+ threshold: parseJson(opts.threshold, "--threshold"),
127
+ windowMinutes: parseInt(opts.windowMinutes, 10),
128
+ }));
129
+ outputJson(result);
130
+ });
131
+ }
@@ -0,0 +1,4 @@
1
+ import type { Command } from "commander";
2
+ import type { Api } from "../../api.js";
3
+ export declare function registerEventCommands(parent: Command, getApi: () => Api): void;
4
+ //# sourceMappingURL=event.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event.d.ts","sourceRoot":"","sources":["../../../src/commands/observability/event.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAGxC,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,OAAO,EACf,MAAM,EAAE,MAAM,GAAG,GAChB,IAAI,CAaN"}
@@ -0,0 +1,12 @@
1
+ import { handleApiCall, outputJson } from "../runHandler.js";
2
+ export function registerEventCommands(parent, getApi) {
3
+ const event = parent.command("event").description("Alert evaluation events");
4
+ event
5
+ .command("list <alertUuid>")
6
+ .description("List the latest evaluation events of an alert")
7
+ .action(async (alertUuid) => {
8
+ const api = getApi();
9
+ const result = await handleApiCall(() => api.observability.event.list({ alertUuid }));
10
+ outputJson(result);
11
+ });
12
+ }
@@ -0,0 +1,4 @@
1
+ import type { Command } from "commander";
2
+ import type { Api } from "../../api.js";
3
+ export declare function registerObservabilityCommands(parent: Command, getApi: () => Api): void;
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/observability/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAIxC,wBAAgB,6BAA6B,CAC3C,MAAM,EAAE,OAAO,EACf,MAAM,EAAE,MAAM,GAAG,GAChB,IAAI,CAON"}
@@ -0,0 +1,9 @@
1
+ import { registerAlertCommands } from "./alert.js";
2
+ import { registerEventCommands } from "./event.js";
3
+ export function registerObservabilityCommands(parent, getApi) {
4
+ const observability = parent
5
+ .command("observability")
6
+ .description("Alerts and alert events");
7
+ registerAlertCommands(observability, getApi);
8
+ registerEventCommands(observability, getApi);
9
+ }
@@ -2,11 +2,11 @@ import { handleApiCall, outputJson } from "../runHandler.js";
2
2
  export function registerQueryCommands(parent, getApi) {
3
3
  const query = parent
4
4
  .command("query")
5
- .description("Execute SQL queries against orchestration tables");
5
+ .description("Execute ClickHouse SQL queries against orchestration tables");
6
6
  query
7
7
  .command("execute")
8
- .description("Execute a read-only SQL query")
9
- .argument("<sql>", "SQL query string")
8
+ .description("Execute a read-only ClickHouse SQL query")
9
+ .argument("<sql>", "ClickHouse SQL query string")
10
10
  .addHelpText("after", `
11
11
  Available tables: spans, runs, batches, records
12
12
 
package/build/index.js CHANGED
@@ -14,6 +14,7 @@ import { registerExpressionCommands } from "./commands/expression/index.js";
14
14
  import { registerHostingCommands } from "./commands/hosting/index.js";
15
15
  import { registerInitCommand } from "./commands/init.js";
16
16
  import { registerMcpCommand } from "./commands/mcp.js";
17
+ import { registerObservabilityCommands } from "./commands/observability/index.js";
17
18
  import { registerOrchestrationCommands } from "./commands/orchestration/index.js";
18
19
  import { registerRevenueOrganizationCommands } from "./commands/revenueOrganization/index.js";
19
20
  import { ExitCodes, failWith } from "./commands/runHandler.js";
@@ -62,6 +63,7 @@ registerAuthCommands(program, getApi);
62
63
  registerVersionCommand(program, version);
63
64
  registerDoctorCommand(program, version);
64
65
  registerInitCommand(program, getApi);
66
+ registerObservabilityCommands(program, getApi);
65
67
  registerOrchestrationCommands(program, getApi);
66
68
  registerWorkspaceManagementCommands(program, getApi);
67
69
  registerStorageCommands(program, getApi);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cargo-ai/cli",
3
- "version": "1.0.41",
3
+ "version": "1.0.43",
4
4
  "private": false,
5
5
  "license": "UNLICENSED",
6
6
  "description": "Command-line interface for the Cargo API",
@@ -30,7 +30,7 @@
30
30
  "format:check": "prettier --check ."
31
31
  },
32
32
  "dependencies": {
33
- "@cargo-ai/api": "^1.0.52",
33
+ "@cargo-ai/api": "^1.0.54",
34
34
  "@cargo-ai/app-sdk": "^1.0.5",
35
35
  "@cargo-ai/cdk": "*",
36
36
  "@cargo-ai/types": "*",