@easybits.cloud/cli 0.17.0 → 0.17.1

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.
Files changed (3) hide show
  1. package/README.md +12 -0
  2. package/dist/index.js +130 -3
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -123,6 +123,13 @@ easybits secrets set --dotenv .env.production # KEY=VALUE lines; - reads stdin
123
123
  printf '%s' "$TOKEN" | easybits secrets set GITHUB_TOKEN # one value from stdin
124
124
  easybits secrets rm GITHUB_TOKEN --yes
125
125
 
126
+ # Platform crons (platform admins only; key with the ADMIN scope)
127
+ easybits crons ls
128
+ easybits crons runs backup-machines
129
+ easybits crons run purge-notifications
130
+ easybits crons pause check-hosting
131
+ easybits crons resume check-hosting
132
+
126
133
  # Databases
127
134
  easybits db ls
128
135
  easybits db create leads
@@ -275,6 +282,11 @@ Host *.ghosty
275
282
 
276
283
  Full reference: https://www.easybits.cloud/docs#cli · https://www.easybits.cloud/en/docs/cli.md
277
284
 
285
+ ## Changes in 0.17.1
286
+
287
+ - `easybits crons ls|runs|run|pause|resume`: EasyBits' scheduled jobs, the same as the
288
+ /dash/admin/crons panel (platform admins only; key with the ADMIN scope).
289
+
278
290
  ## Changes in 0.17.0
279
291
 
280
292
  - `sites create --prompt … [--kind webapp|static] [--stack …] [--template …]` and
package/dist/index.js CHANGED
@@ -305,7 +305,15 @@ var HEADERS_ES = {
305
305
  SCENES: "ESCENAS",
306
306
  DURATION: "DURACI\xD3N",
307
307
  NARRATION: "NARRACI\xD3N",
308
- PROMPT: "PROMPT"
308
+ PROMPT: "PROMPT",
309
+ JOB: "TAREA",
310
+ SCHEDULE: "HORARIO",
311
+ "LAST RUN": "\xDALTIMA",
312
+ "NEXT RUN": "PR\xD3XIMA",
313
+ RESULT: "RESULTADO",
314
+ TOOK: "TARD\xD3",
315
+ TRIGGER: "ORIGEN",
316
+ SUMMARY: "RESUMEN"
309
317
  };
310
318
  function table(rows, cols, empty = t("Nothing here yet.", "Todav\xEDa no hay nada.")) {
311
319
  if (lang() === "es") cols = cols.map(([k, l]) => [k, HEADERS_ES[l] ?? l]);
@@ -4910,7 +4918,7 @@ async function updateNotice(current2) {
4910
4918
  }
4911
4919
 
4912
4920
  // src/commands/doctor.ts
4913
- var VERSION = true ? "0.17.0" : "dev";
4921
+ var VERSION = true ? "0.17.1" : "dev";
4914
4922
  var doctor2 = {
4915
4923
  name: "doctor",
4916
4924
  group: "Account",
@@ -5416,6 +5424,118 @@ var secrets = {
5416
5424
  defaultSub: "ls"
5417
5425
  };
5418
5426
 
5427
+ // src/commands/crons.ts
5428
+ var STATUS = {
5429
+ "al-dia": ["up to date", "al d\xEDa"],
5430
+ tarde: ["late", "tarde"],
5431
+ fallo: ["failed", "fall\xF3"],
5432
+ pausado: ["paused", "pausado"],
5433
+ nuevo: ["no runs yet", "sin corridas"]
5434
+ };
5435
+ function cronStatus(c) {
5436
+ if (c.running) return t("running", "corriendo");
5437
+ const s = STATUS[c.status];
5438
+ return s ? t(s[0], s[1]) : c.status;
5439
+ }
5440
+ function duration(ms) {
5441
+ if (ms == null) return "\u2014";
5442
+ return ms < 1e3 ? `${ms} ms` : `${(ms / 1e3).toFixed(1)} s`;
5443
+ }
5444
+ var crons = {
5445
+ name: "crons",
5446
+ aliases: ["cron"],
5447
+ group: "Account",
5448
+ summary: "Platform scheduled jobs (admins only): status, history, run now, pause",
5449
+ synopsis: "crons <ls|runs|run|pause|resume>",
5450
+ subs: {
5451
+ ls: {
5452
+ aliases: ["list"],
5453
+ summary: "List the scheduled jobs with status, schedule, last and next run",
5454
+ usage: "easybits crons ls",
5455
+ examples: ["easybits crons ls", "easybits crons ls --json"],
5456
+ async run(ctx) {
5457
+ const { items } = await api(ctx, "GET", "/admin/crons");
5458
+ emit(
5459
+ ctx,
5460
+ { items },
5461
+ () => table(
5462
+ items.map((c) => ({
5463
+ key: c.key,
5464
+ status: cronStatus(c),
5465
+ schedule: c.schedule,
5466
+ last: c.lastRun ? `${fmtDate(c.lastRun.startedAt)} (${duration(c.lastRun.durationMs)})` : "\u2014",
5467
+ next: c.paused ? "\u2014" : fmtDate(c.nextRunAt)
5468
+ })),
5469
+ [["key", "JOB"], ["status", "STATUS"], ["schedule", "SCHEDULE"], ["last", "LAST RUN"], ["next", "NEXT RUN"]]
5470
+ )
5471
+ );
5472
+ }
5473
+ },
5474
+ runs: {
5475
+ summary: "Show a job's last 50 runs, with the full error when one failed",
5476
+ usage: "easybits crons runs <job>",
5477
+ examples: ["easybits crons runs backup-machines", "easybits crons runs check-hosting --json"],
5478
+ async run(ctx) {
5479
+ const key = need(ctx, 0, "job", this.usage);
5480
+ const { items } = await api(ctx, "GET", `/admin/crons/${encodeURIComponent(key)}/runs`);
5481
+ emit(ctx, { items }, () => {
5482
+ table(
5483
+ items.map((r) => ({
5484
+ at: fmtDate(r.startedAt),
5485
+ ok: r.ok == null ? t("running", "corriendo") : r.ok ? "ok" : t("failed", "fall\xF3"),
5486
+ status: r.status ?? "\u2014",
5487
+ took: duration(r.durationMs),
5488
+ trigger: r.trigger,
5489
+ summary: (r.error ?? r.summary ?? "").slice(0, 80)
5490
+ })),
5491
+ [["at", "STARTED"], ["ok", "RESULT"], ["status", "HTTP"], ["took", "TOOK"], ["trigger", "TRIGGER"], ["summary", "SUMMARY"]],
5492
+ t("No runs yet.", "Todav\xEDa no hay corridas.")
5493
+ );
5494
+ const failed = items.find((r) => r.ok === false && r.error);
5495
+ if (failed) console.log(`
5496
+ ${t("Last error", "\xDAltimo error")} (${fmtDate(failed.startedAt)}):
5497
+ ${failed.error}`);
5498
+ });
5499
+ }
5500
+ },
5501
+ run: {
5502
+ summary: "Run a job now in the background (recorded with trigger manual)",
5503
+ usage: "easybits crons run <job>",
5504
+ examples: ["easybits crons run purge-notifications", "easybits crons run backup-machines --json"],
5505
+ async run(ctx) {
5506
+ const key = need(ctx, 0, "job", this.usage);
5507
+ const r = await api(ctx, "POST", `/admin/crons/${encodeURIComponent(key)}/run`);
5508
+ emit(
5509
+ ctx,
5510
+ r,
5511
+ () => console.log(t(`Started ${key}. Follow it with: easybits crons runs ${key}`, `Arranc\xF3 ${key}. S\xEDguela con: easybits crons runs ${key}`))
5512
+ );
5513
+ }
5514
+ },
5515
+ pause: {
5516
+ summary: "Pause a job: scheduled runs answer skipped until you resume it",
5517
+ usage: "easybits crons pause <job>",
5518
+ examples: ["easybits crons pause check-hosting"],
5519
+ async run(ctx) {
5520
+ const key = need(ctx, 0, "job", this.usage);
5521
+ const r = await api(ctx, "POST", `/admin/crons/${encodeURIComponent(key)}/pause`, { paused: true });
5522
+ emit(ctx, r, () => console.log(t(`Paused ${key}.`, `${key} en pausa.`)));
5523
+ }
5524
+ },
5525
+ resume: {
5526
+ summary: "Resume a paused job",
5527
+ usage: "easybits crons resume <job>",
5528
+ examples: ["easybits crons resume check-hosting"],
5529
+ async run(ctx) {
5530
+ const key = need(ctx, 0, "job", this.usage);
5531
+ const r = await api(ctx, "POST", `/admin/crons/${encodeURIComponent(key)}/pause`, { paused: false });
5532
+ emit(ctx, r, () => console.log(t(`Resumed ${key}.`, `${key} reanudada.`)));
5533
+ }
5534
+ }
5535
+ },
5536
+ defaultSub: "ls"
5537
+ };
5538
+
5419
5539
  // src/commands/documents.ts
5420
5540
  import { existsSync as existsSync16, mkdirSync as mkdirSync7, readFileSync as readFileSync18, statSync as statSync11, writeFileSync as writeFileSync10 } from "fs";
5421
5541
  import { join as join11 } from "path";
@@ -6203,6 +6323,7 @@ var COMMANDS = [
6203
6323
  doctor2,
6204
6324
  usage,
6205
6325
  secrets,
6326
+ crons,
6206
6327
  sandboxes,
6207
6328
  agents,
6208
6329
  fleet,
@@ -6544,6 +6665,12 @@ var HELP_ES = {
6544
6665
  "Release a machine: stops billing, takes a last backup and destroys it": "Libera una m\xE1quina: deja de cobrarse, toma un \xFAltimo respaldo y la destruye",
6545
6666
  "The hosting catalog: sizes and monthly prices in MXN": "El cat\xE1logo de hosting: tama\xF1os y precio mensual en MXN",
6546
6667
  // secrets (vault de la cuenta)
6668
+ "Platform scheduled jobs (admins only): status, history, run now, pause": "Tareas programadas de la plataforma (s\xF3lo admins): estado, historial, ejecutar ahora, pausar",
6669
+ "List the scheduled jobs with status, schedule, last and next run": "Enlista las tareas programadas con estado, horario, \xFAltima y pr\xF3xima corrida",
6670
+ "Show a job's last 50 runs, with the full error when one failed": "Muestra las \xFAltimas 50 corridas de una tarea, con el error completo si alguna fall\xF3",
6671
+ "Run a job now in the background (recorded with trigger manual)": "Corre una tarea ya, en segundo plano (queda registrada como manual)",
6672
+ "Pause a job: scheduled runs answer skipped until you resume it": "Pausa una tarea: sus corridas programadas responden skipped hasta que la reanudes",
6673
+ "Resume a paused job": "Reanuda una tarea en pausa",
6547
6674
  "Your account's secrets vault: names only; used as $secret:NAME": "La b\xF3veda de secretos de tu cuenta: s\xF3lo nombres; se usan como $secret:NOMBRE",
6548
6675
  "List the names in your vault (values never come back)": "Enlista los nombres de tu b\xF3veda (los valores nunca regresan)",
6549
6676
  "Save or replace secrets from a dotenv file, or one value from stdin": "Guarda o reemplaza secretos desde un archivo dotenv, o un valor por stdin",
@@ -6857,7 +6984,7 @@ function normalizeArgs(input) {
6857
6984
  }
6858
6985
 
6859
6986
  // src/index.ts
6860
- var VERSION2 = true ? "0.17.0" : "dev";
6987
+ var VERSION2 = true ? "0.17.1" : "dev";
6861
6988
  var GLOBAL_OPTIONS = {
6862
6989
  json: { type: "boolean" },
6863
6990
  token: { type: "string" },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@easybits.cloud/cli",
3
- "version": "0.17.0",
3
+ "version": "0.17.1",
4
4
  "description": "Official CLI for EasyBits, the cloud for AI agents — sandboxes, hosting, domains, databases, agents and files from your terminal",
5
5
  "type": "module",
6
6
  "bin": {