@erdoai/cli 0.27.0 → 0.29.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/dist/index.js +78 -3
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -209,6 +209,12 @@ var ErdoClient = class {
|
|
|
209
209
|
setAutonomyMode(mode) {
|
|
210
210
|
return this.request("PUT", "/v1/autonomy-mode", { mode });
|
|
211
211
|
}
|
|
212
|
+
// Run a read-only HogQL query against the org's page-analytics events. Rows are
|
|
213
|
+
// positional per columns; enabled:false means page analytics is off for the org
|
|
214
|
+
// (not zero traffic). A rejected query surfaces PostHog's message as the error.
|
|
215
|
+
queryPageAnalytics(query) {
|
|
216
|
+
return this.request("POST", "/v1/page-analytics/query", { query });
|
|
217
|
+
}
|
|
212
218
|
listEvalSuites() {
|
|
213
219
|
return this.request("GET", "/v1/evals/suites");
|
|
214
220
|
}
|
|
@@ -524,6 +530,21 @@ var ErdoClient = class {
|
|
|
524
530
|
timezone
|
|
525
531
|
});
|
|
526
532
|
}
|
|
533
|
+
// Fetch rows from a dataset, optionally shaped by a SQL query and/or opting into
|
|
534
|
+
// named saved filters. filter_names are additive on top of the dataset's default
|
|
535
|
+
// filters — they narrow the result, never bypass a default. An unknown name is
|
|
536
|
+
// rejected server-side with the available names.
|
|
537
|
+
fetchDatasetContents(slug, opts) {
|
|
538
|
+
return this.request(
|
|
539
|
+
"POST",
|
|
540
|
+
`/v1/datasets/${encodeURIComponent(slug)}/fetch`,
|
|
541
|
+
{
|
|
542
|
+
sql_query: opts.sql_query,
|
|
543
|
+
limit: opts.limit,
|
|
544
|
+
filter_names: opts.filter_names
|
|
545
|
+
}
|
|
546
|
+
);
|
|
547
|
+
}
|
|
527
548
|
uploadDatasetFile(body) {
|
|
528
549
|
return this.request("POST", "/v1/datasets-upload", body);
|
|
529
550
|
}
|
|
@@ -2236,6 +2257,24 @@ datasetsCmd.command("query <slug> <question>").description("Ask a natural-langua
|
|
|
2236
2257
|
fail(e);
|
|
2237
2258
|
}
|
|
2238
2259
|
});
|
|
2260
|
+
datasetsCmd.command("fetch <slug>").description("Fetch rows from a dataset, optionally shaped by SQL and named filters").option("-q, --sql <query>", "SQL query to filter/transform the rows").option("-l, --limit <n>", "max rows to return", (v) => parseInt(v, 10)).option(
|
|
2261
|
+
"-f, --filter <name>",
|
|
2262
|
+
"opt into a saved filter by name (repeatable); additive on top of the dataset's default filters (see: erdo datasets filter list <slug>)",
|
|
2263
|
+
(v, acc) => acc.concat(v),
|
|
2264
|
+
[]
|
|
2265
|
+
).action(async (slug, opts) => {
|
|
2266
|
+
try {
|
|
2267
|
+
print(
|
|
2268
|
+
await new ErdoClient().fetchDatasetContents(slug, {
|
|
2269
|
+
sql_query: opts.sql,
|
|
2270
|
+
limit: opts.limit,
|
|
2271
|
+
filter_names: opts.filter.length ? opts.filter : void 0
|
|
2272
|
+
})
|
|
2273
|
+
);
|
|
2274
|
+
} catch (e) {
|
|
2275
|
+
fail(e);
|
|
2276
|
+
}
|
|
2277
|
+
});
|
|
2239
2278
|
var MAX_UPLOAD_BYTES = 20 * 1024 * 1024;
|
|
2240
2279
|
datasetsCmd.command("upload <file>").description("Upload a file (CSV, Excel, JSON, ...) and create a dataset from it").option("-n, --name <name>", "display name for the dataset (defaults to the filename)").option("-d, --description <text>", "description shown to agents analyzing the dataset").action(async (file, opts) => {
|
|
2241
2280
|
try {
|
|
@@ -2278,6 +2317,33 @@ datasetsCmd.command("from-integration <app>").description("Create a dataset back
|
|
|
2278
2317
|
fail(e);
|
|
2279
2318
|
}
|
|
2280
2319
|
});
|
|
2320
|
+
function printAnalyticsTable(columns, rows) {
|
|
2321
|
+
const cell = (v) => v === null || v === void 0 ? "" : typeof v === "object" ? JSON.stringify(v) : String(v);
|
|
2322
|
+
const widths = columns.map((c, i) => Math.max(c.length, ...rows.map((r) => cell(r[i]).length), 0));
|
|
2323
|
+
const line = (cells) => cells.map((c, i) => c.padEnd(widths[i])).join(" ").trimEnd();
|
|
2324
|
+
console.log(line(columns));
|
|
2325
|
+
console.log(widths.map((w) => "-".repeat(w)).join(" "));
|
|
2326
|
+
for (const r of rows) console.log(line(columns.map((_, i) => cell(r[i]))));
|
|
2327
|
+
}
|
|
2328
|
+
var analytics = program.command("analytics").description("Query page analytics (how published pages perform with real visitors)");
|
|
2329
|
+
analytics.command("query <hogql>").description("Run a read-only HogQL query against this org's page-analytics events").option("--json", "print the raw JSON result instead of a table").action(async (hogql, opts) => {
|
|
2330
|
+
try {
|
|
2331
|
+
const res = await new ErdoClient().queryPageAnalytics(hogql);
|
|
2332
|
+
if (opts.json) {
|
|
2333
|
+
print(res);
|
|
2334
|
+
return;
|
|
2335
|
+
}
|
|
2336
|
+
if (!res.enabled) {
|
|
2337
|
+
console.log("Page analytics is not enabled for this organization \u2014 turn it on in the Erdo app, then query real traffic here.");
|
|
2338
|
+
return;
|
|
2339
|
+
}
|
|
2340
|
+
printAnalyticsTable(res.columns, res.rows);
|
|
2341
|
+
if (res.truncated) console.log(`
|
|
2342
|
+
(rows truncated at the cap \u2014 aggregate further or add a tighter filter/LIMIT)`);
|
|
2343
|
+
} catch (e) {
|
|
2344
|
+
fail(e);
|
|
2345
|
+
}
|
|
2346
|
+
});
|
|
2281
2347
|
var OPERATORS = ["equals", "not_equals", "greater_than", "less_than", "contains", "between"];
|
|
2282
2348
|
function parseCondition(s) {
|
|
2283
2349
|
const m = s.trim().match(/^(\S+)\s+(\S+)\s+([\s\S]+)$/);
|
|
@@ -2375,15 +2441,24 @@ pipelinesCmd.command("get <slug>").description("Show one event pipeline \u2014 s
|
|
|
2375
2441
|
fail(e);
|
|
2376
2442
|
}
|
|
2377
2443
|
});
|
|
2378
|
-
filterCmd.command("add <slug>").description("Add a
|
|
2444
|
+
filterCmd.command("add <slug>").description("Add a filter to a dataset (default-on unless --no-default)").requiredOption(
|
|
2379
2445
|
"--where <condition>",
|
|
2380
2446
|
"a '<column> <operator> <value>' condition (repeatable, AND-combined), e.g. --where 'email contains @example.com'. Operators: " + OPERATORS.join(", ") + " (for 'between' use 'col between 10,100')",
|
|
2381
2447
|
collect,
|
|
2382
2448
|
[]
|
|
2383
|
-
).option("--name <name>", "optional human-readable label, e.g. 'Exclude test submissions'").
|
|
2449
|
+
).option("--name <name>", "optional human-readable label, e.g. 'Exclude test submissions'").option(
|
|
2450
|
+
"--no-default",
|
|
2451
|
+
"save as a named view that reads opt into with 'datasets fetch --filter <name>', instead of applying to every read"
|
|
2452
|
+
).action(async (slug, opts) => {
|
|
2384
2453
|
try {
|
|
2385
2454
|
const conditions = opts.where.map(parseCondition);
|
|
2386
|
-
print(
|
|
2455
|
+
print(
|
|
2456
|
+
await new ErdoClient().createDatasetFilter(slug, {
|
|
2457
|
+
name: opts.name,
|
|
2458
|
+
conditions,
|
|
2459
|
+
is_default: opts.default === false ? false : void 0
|
|
2460
|
+
})
|
|
2461
|
+
);
|
|
2387
2462
|
} catch (e) {
|
|
2388
2463
|
fail(e);
|
|
2389
2464
|
}
|