@erdoai/cli 0.31.0 → 0.33.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 +93 -4
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -180,10 +180,13 @@ function looksLikeHTML(text) {
|
|
|
180
180
|
function fetchMe(token, orgId) {
|
|
181
181
|
return rawRequest(resolveApiUrl(), token, orgId, "GET", "/v1/me");
|
|
182
182
|
}
|
|
183
|
+
var announcedOrg = false;
|
|
183
184
|
var ErdoClient = class {
|
|
184
185
|
baseURL;
|
|
185
186
|
token;
|
|
186
187
|
orgId;
|
|
188
|
+
orgPinned;
|
|
189
|
+
orgName;
|
|
187
190
|
constructor(orgOverride) {
|
|
188
191
|
this.baseURL = resolveApiUrl();
|
|
189
192
|
const acct = activeAccount();
|
|
@@ -193,8 +196,27 @@ var ErdoClient = class {
|
|
|
193
196
|
}
|
|
194
197
|
this.token = token;
|
|
195
198
|
this.orgId = resolveOrgId(acct, orgOverride);
|
|
199
|
+
this.orgPinned = Boolean(orgOverride || process.env.ERDO_ORG);
|
|
200
|
+
this.orgName = acct?.organizationName;
|
|
201
|
+
}
|
|
202
|
+
announceOrgOnce(method) {
|
|
203
|
+
if (announcedOrg) return;
|
|
204
|
+
if (method.toUpperCase() === "GET") return;
|
|
205
|
+
announcedOrg = true;
|
|
206
|
+
if (this.orgPinned && this.orgId) {
|
|
207
|
+
process.stderr.write(`org: ${this.orgId} (pinned)
|
|
208
|
+
`);
|
|
209
|
+
} else if (this.orgId) {
|
|
210
|
+
process.stderr.write(
|
|
211
|
+
`org: ${this.orgName ?? this.orgId} (active org \u2014 pass --org to pin)
|
|
212
|
+
`
|
|
213
|
+
);
|
|
214
|
+
} else {
|
|
215
|
+
process.stderr.write("org: token default (no org resolved \u2014 pass --org to pin)\n");
|
|
216
|
+
}
|
|
196
217
|
}
|
|
197
218
|
request(method, path, body) {
|
|
219
|
+
this.announceOrgOnce(method);
|
|
198
220
|
return rawRequest(this.baseURL, this.token, this.orgId, method, path, body);
|
|
199
221
|
}
|
|
200
222
|
me() {
|
|
@@ -288,6 +310,29 @@ var ErdoClient = class {
|
|
|
288
310
|
createProject(input) {
|
|
289
311
|
return this.request("POST", "/v1/projects", input);
|
|
290
312
|
}
|
|
313
|
+
// --- pages ---
|
|
314
|
+
listPages(params) {
|
|
315
|
+
const q = new URLSearchParams();
|
|
316
|
+
if (params?.query) q.set("query", params.query);
|
|
317
|
+
if (params?.createdAfter) q.set("created_after", params.createdAfter);
|
|
318
|
+
if (params?.createdBefore) q.set("created_before", params.createdBefore);
|
|
319
|
+
if (params?.limit) q.set("limit", String(params.limit));
|
|
320
|
+
if (params?.offset) q.set("offset", String(params.offset));
|
|
321
|
+
const qs = q.toString();
|
|
322
|
+
return this.request("GET", `/v1/pages${qs ? `?${qs}` : ""}`);
|
|
323
|
+
}
|
|
324
|
+
deletePage(id) {
|
|
325
|
+
return this.request(
|
|
326
|
+
"DELETE",
|
|
327
|
+
`/v1/pages/${encodeURIComponent(id)}`
|
|
328
|
+
);
|
|
329
|
+
}
|
|
330
|
+
restorePage(id) {
|
|
331
|
+
return this.request(
|
|
332
|
+
"POST",
|
|
333
|
+
`/v1/pages/restore/${encodeURIComponent(id)}`
|
|
334
|
+
);
|
|
335
|
+
}
|
|
291
336
|
// --- workstreams ---
|
|
292
337
|
listWorkstreams(status) {
|
|
293
338
|
const q = new URLSearchParams();
|
|
@@ -1825,6 +1870,19 @@ evalCmd.command("create <name>").description("Create a suite (in the active org)
|
|
|
1825
1870
|
evalCmd.command("run <slug>").description("Run a suite; --watch polls until it completes").option("-w, --watch", "poll until the run finishes and print results").option("-c, --concurrency <n>", "parallel cases", (v) => parseInt(v, 10)).action(async (slug, opts) => {
|
|
1826
1871
|
try {
|
|
1827
1872
|
const api = new ErdoClient();
|
|
1873
|
+
const { suite } = await api.getEvalSuite(slug);
|
|
1874
|
+
if (suite.evaluate_artifact && !process.env.ERDO_ORG) {
|
|
1875
|
+
const resolved = resolveOrgId(activeAccount()) ?? "<org>";
|
|
1876
|
+
console.error(
|
|
1877
|
+
[
|
|
1878
|
+
`Refusing to run "${slug}": it builds real artifacts in the resolved org.`,
|
|
1879
|
+
"The active org is machine-global \u2014 a concurrent session can switch it, so this",
|
|
1880
|
+
"run could land in the wrong org. Re-run with the org pinned:",
|
|
1881
|
+
` erdo --org ${resolved} eval run ${slug}`
|
|
1882
|
+
].join("\n")
|
|
1883
|
+
);
|
|
1884
|
+
process.exit(1);
|
|
1885
|
+
}
|
|
1828
1886
|
const { run_id } = await api.runEvalSuite(slug, opts.concurrency);
|
|
1829
1887
|
console.log(`run_id: ${run_id}`);
|
|
1830
1888
|
if (!opts.watch) return;
|
|
@@ -2066,8 +2124,9 @@ approvalsCmd.command("list").description("List approval requests, optionally fil
|
|
|
2066
2124
|
return;
|
|
2067
2125
|
}
|
|
2068
2126
|
for (const r of res.requests) {
|
|
2127
|
+
const occ = r.occurrence_count && r.occurrence_count > 1 ? ` \xD7${r.occurrence_count}` : "";
|
|
2069
2128
|
console.log(
|
|
2070
|
-
`${r.id} ${r.status} ${r.action_key} ${r.action_display} ${r.created_at}`
|
|
2129
|
+
`${r.id} ${r.status} ${r.action_key} ${r.action_display} ${r.created_at}${occ}`
|
|
2071
2130
|
);
|
|
2072
2131
|
}
|
|
2073
2132
|
} catch (e) {
|
|
@@ -2293,10 +2352,40 @@ pagesCmd.command("validate").description("Validate page content without deployin
|
|
|
2293
2352
|
fail(e);
|
|
2294
2353
|
}
|
|
2295
2354
|
});
|
|
2296
|
-
pagesCmd.command("list").description("List
|
|
2355
|
+
pagesCmd.command("list").description("List pages (newest first). With --type, lists any artifact type instead.").option("-t, --type <type>", "list all artifacts of this type (e.g. html) rather than just pages").option("--query <substr>", "case-insensitive title substring filter (pages only)").option("--created-after <iso>", "only pages created at/after this RFC3339 timestamp (pages only)").option("--created-before <iso>", "only pages created at/before this RFC3339 timestamp (pages only)").option("-l, --limit <n>", "max results", (v) => parseInt(v, 10)).option("--offset <n>", "pagination offset", (v) => parseInt(v, 10)).action(
|
|
2356
|
+
async (opts) => {
|
|
2357
|
+
try {
|
|
2358
|
+
if (opts.type) {
|
|
2359
|
+
const { artifacts } = await new ErdoClient().listArtifacts(opts.type, opts.limit);
|
|
2360
|
+
for (const a of artifacts) console.log(`${a.id} ${a.type} ${a.title}`);
|
|
2361
|
+
return;
|
|
2362
|
+
}
|
|
2363
|
+
const { pages } = await new ErdoClient().listPages({
|
|
2364
|
+
query: opts.query,
|
|
2365
|
+
createdAfter: opts.createdAfter,
|
|
2366
|
+
createdBefore: opts.createdBefore,
|
|
2367
|
+
limit: opts.limit,
|
|
2368
|
+
offset: opts.offset
|
|
2369
|
+
});
|
|
2370
|
+
for (const p of pages) {
|
|
2371
|
+
const vis = p.public ? p.public_url || "public" : "private";
|
|
2372
|
+
console.log(`${p.id} ${p.created_at} ${vis} ${p.title}`);
|
|
2373
|
+
}
|
|
2374
|
+
} catch (e) {
|
|
2375
|
+
fail(e);
|
|
2376
|
+
}
|
|
2377
|
+
}
|
|
2378
|
+
);
|
|
2379
|
+
pagesCmd.command("delete <id>").description("Delete a page (soft delete \u2014 unpublishes it and hides it from listings; restorable)").action(async (id) => {
|
|
2380
|
+
try {
|
|
2381
|
+
print(await new ErdoClient().deletePage(id));
|
|
2382
|
+
} catch (e) {
|
|
2383
|
+
fail(e);
|
|
2384
|
+
}
|
|
2385
|
+
});
|
|
2386
|
+
pagesCmd.command("restore <id>").description("Restore a previously deleted page (comes back private)").action(async (id) => {
|
|
2297
2387
|
try {
|
|
2298
|
-
|
|
2299
|
-
for (const a of artifacts) console.log(`${a.id} ${a.type} ${a.title}`);
|
|
2388
|
+
print(await new ErdoClient().restorePage(id));
|
|
2300
2389
|
} catch (e) {
|
|
2301
2390
|
fail(e);
|
|
2302
2391
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@erdoai/cli",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Erdo CLI
|
|
3
|
+
"version": "0.33.0",
|
|
4
|
+
"description": "Erdo CLI — drive datasets, pages, and evals from the terminal or CI",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"erdo": "dist/index.js"
|