@erdoai/cli 0.76.0 → 0.77.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 +36 -13
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import { readFileSync as readFileSync4 } from "fs";
|
|
5
5
|
import { basename } from "path";
|
|
6
6
|
import { select } from "@inquirer/prompts";
|
|
7
|
-
import { Command } from "commander";
|
|
7
|
+
import { Command as Command2 } from "commander";
|
|
8
8
|
|
|
9
9
|
// src/config.ts
|
|
10
10
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
@@ -1582,6 +1582,32 @@ function readMaybeFile(value) {
|
|
|
1582
1582
|
return value.startsWith("@") ? readFileSync2(value.slice(1), "utf8") : value;
|
|
1583
1583
|
}
|
|
1584
1584
|
|
|
1585
|
+
// src/scope.ts
|
|
1586
|
+
import { Option } from "commander";
|
|
1587
|
+
var ORG_ENV = "ERDO_ORG";
|
|
1588
|
+
var PROJECT_ENV = "ERDO_PROJECT";
|
|
1589
|
+
function bindScopeFlags(program2) {
|
|
1590
|
+
program2.option("--org <idOrSlug>", "org to target for this command (overrides the active org)").option(
|
|
1591
|
+
"--project <slugOrId>",
|
|
1592
|
+
"project context for this command \u2014 slug or UUID (must belong to the active org)"
|
|
1593
|
+
);
|
|
1594
|
+
program2.on("option:org", (value) => {
|
|
1595
|
+
process.env[ORG_ENV] = value;
|
|
1596
|
+
});
|
|
1597
|
+
program2.on("option:project", (value) => {
|
|
1598
|
+
process.env[PROJECT_ENV] = value;
|
|
1599
|
+
});
|
|
1600
|
+
return program2;
|
|
1601
|
+
}
|
|
1602
|
+
function projectOption(description, opts = {}) {
|
|
1603
|
+
const option = new Option("--project <slug>", description).env(PROJECT_ENV);
|
|
1604
|
+
if (opts.mandatory) option.makeOptionMandatory();
|
|
1605
|
+
return option;
|
|
1606
|
+
}
|
|
1607
|
+
function orgOption(description) {
|
|
1608
|
+
return new Option("--org <idOrSlug>", description).env(ORG_ENV);
|
|
1609
|
+
}
|
|
1610
|
+
|
|
1585
1611
|
// src/update.ts
|
|
1586
1612
|
import { spawn as spawn2, spawnSync } from "child_process";
|
|
1587
1613
|
import { existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "fs";
|
|
@@ -1796,14 +1822,9 @@ function compactEvalRunAttribution(run) {
|
|
|
1796
1822
|
].filter((part) => part !== void 0);
|
|
1797
1823
|
return [run.triggered_by, ...revisions].join(" ");
|
|
1798
1824
|
}
|
|
1799
|
-
var program = new
|
|
1800
|
-
program.name("erdo").description("Erdo CLI").version(pkg.version)
|
|
1801
|
-
program
|
|
1802
|
-
const opts = thisCommand.opts();
|
|
1803
|
-
const org2 = opts.org;
|
|
1804
|
-
if (org2) process.env.ERDO_ORG = org2;
|
|
1805
|
-
if (opts.project) process.env.ERDO_PROJECT = opts.project;
|
|
1806
|
-
});
|
|
1825
|
+
var program = new Command2();
|
|
1826
|
+
program.name("erdo").description("Erdo CLI").version(pkg.version);
|
|
1827
|
+
bindScopeFlags(program);
|
|
1807
1828
|
async function doLogin(opts) {
|
|
1808
1829
|
let token;
|
|
1809
1830
|
let me;
|
|
@@ -2170,7 +2191,9 @@ This key operates every org you manage; target one with X-Organization-ID (or \`
|
|
|
2170
2191
|
}
|
|
2171
2192
|
});
|
|
2172
2193
|
var tokenCmd = program.command("token").description("Manage your API tokens (account-level credentials)");
|
|
2173
|
-
tokenCmd.command("create").description("Mint a new API token; the secret is printed ONCE").requiredOption("--name <name>", "a label for the token").option("--expires-days <n>", "days until expiry (default: 30)", (v) => parseInt(v, 10)).
|
|
2194
|
+
tokenCmd.command("create").description("Mint a new API token; the secret is printed ONCE").requiredOption("--name <name>", "a label for the token").option("--expires-days <n>", "days until expiry (default: 30)", (v) => parseInt(v, 10)).addOption(
|
|
2195
|
+
orgOption("the token's default org (defaults to your active org; must be one you belong to)")
|
|
2196
|
+
).action(async (opts) => {
|
|
2174
2197
|
try {
|
|
2175
2198
|
const res = await new ErdoClient().createToken({
|
|
2176
2199
|
name: opts.name,
|
|
@@ -2272,7 +2295,7 @@ wsCmd.command("get <slug>").description("Show a workstream \u2014 status, phases
|
|
|
2272
2295
|
fail(e);
|
|
2273
2296
|
}
|
|
2274
2297
|
});
|
|
2275
|
-
wsCmd.command("create").description("Create a workstream in a project").
|
|
2298
|
+
wsCmd.command("create").description("Create a workstream in a project").addOption(projectOption("project slug", { mandatory: true })).requiredOption("--slug <slug>", "workstream slug (unique per org)").requiredOption("--title <title>", "human-readable title").option("--description <text>", "free-form description").option(
|
|
2276
2299
|
"--token-budget <millicents>",
|
|
2277
2300
|
"spend ceiling in millicents \u2014 100,000 per dollar, so 10000000 = $100 and 25000000 = $250; omit for unlimited",
|
|
2278
2301
|
(v) => parseInt(v, 10)
|
|
@@ -2566,7 +2589,7 @@ expCmd.command("policy <slug>").description(
|
|
|
2566
2589
|
fail(e);
|
|
2567
2590
|
}
|
|
2568
2591
|
});
|
|
2569
|
-
expCmd.command("create").description("Create an experiment with its variants, evidence datasets and decision rule").
|
|
2592
|
+
expCmd.command("create").description("Create an experiment with its variants, evidence datasets and decision rule").addOption(projectOption("project slug", { mandatory: true })).requiredOption("--slug <slug>", "experiment slug (unique per org)").requiredOption("--title <title>", "title").option("--workstream <slug>", "host workstream").option("--scope <scope>", "local (default), platform_canary, platform_global").option("--hypothesis <text>", "hypothesis markdown").option("--primary-metric <metric>", "the metric the decision rule reads").option("--decision-rule <text>", "the rule that decides ship/stop from the primary metric").option("--guardrail <metric>", "a metric that must not regress (repeatable)", collect, []).option(
|
|
2570
2593
|
"--variant <spec>",
|
|
2571
2594
|
`a variant "key=b,label=3-field form,page=<artifact-id>,alloc=50,class=form_length_change,control" (repeatable). Fields: key=, label=, page= (Erdo artifact id) OR url=<https://\u2026> (an external page the persona panel visits, e.g. a client's live landing page \u2014 mutually exclusive with page=), alloc=, class=, and the bare flag control (or control=true) to mark the baseline. class= declares the structural change vs control for cross-experiment learning: headline_change | hero_media_change | cta_change | form_length_change | social_proof_add | layout_reorder | offer_change | full_page_rebuild`,
|
|
2572
2595
|
collect,
|
|
@@ -2704,7 +2727,7 @@ expCmd.command("set-status <slug> <status>").description("Set an experiment's st
|
|
|
2704
2727
|
});
|
|
2705
2728
|
expCmd.command("calibration").description(
|
|
2706
2729
|
"Read each judge's track record \u2014 paired predictions and pairwise agreement vs measured reality (the trust dial)"
|
|
2707
|
-
).
|
|
2730
|
+
).addOption(projectOption("limit to one project (default: every project you can view)")).option("--judge <slug>", "show only judges whose slug contains this text").option("-n, --limit <n>", "max ledger rows scanned (default 5000)", (v) => parseInt(v, 10)).action(async (opts) => {
|
|
2708
2731
|
try {
|
|
2709
2732
|
const res = await new ErdoClient().judgeCalibration({
|
|
2710
2733
|
project_slug: opts.project,
|