@odla-ai/cli 0.25.7 → 0.25.8

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/bin.js CHANGED
@@ -3,7 +3,7 @@ import {
3
3
  exitCodeFor,
4
4
  redactSecrets,
5
5
  runCli
6
- } from "./chunk-5U3EXWCR.js";
6
+ } from "./chunk-PM5FBL3S.js";
7
7
 
8
8
  // src/bin.ts
9
9
  runCli().catch((err) => {
@@ -1617,6 +1617,7 @@ var CAPABILITIES = {
1617
1617
  "apply Google Calendar booking config, then drive state-bound consent, status, discovery, and disconnect flows (bookings run live through the platform proxy)",
1618
1618
  "validate integration contracts offline and smoke-test a provisioned db environment plus anonymous capability routes",
1619
1619
  "read one versioned o11y status envelope spanning application RED, current live-sync freshness/load, the protected commit-to-visible canary, collector ingest/scheduler trust, provider-owned runtime metrics, and a bounded machine verdict",
1620
+ "inspect durable agent wakeups as a versioned JSON envelope and explicitly requeue one dead-lettered job with a scoped environment credential",
1620
1621
  "run app-attributed hosted security discovery and independent validation without provider keys",
1621
1622
  "connect/revoke source-read-only GitHub sources and drive commit-pinned hosted security jobs without PATs or provider keys",
1622
1623
  "let admins manage system AI policy and credentials, inspect attributed usage, and read immutable admin changes through separate short-lived capability-only approvals"
@@ -5995,6 +5996,8 @@ Usage:
5995
5996
  odla-ai discuss resolve <topic> [--reopen] [--mutation-id <id>]
5996
5997
  odla-ai discuss who --q <text> [--app <id>] [--kinds user,pm:task] [--json]
5997
5998
  odla-ai discuss watch [<topic>] [--by <authorId>] [--self <authorId>] [--interval <s>] [--timeout <s>] [--json]
5999
+ odla-ai agent jobs [--env dev] [--state pending|running|succeeded|dead_letter] [--limit 50] [--email <email>] [--json]
6000
+ odla-ai agent retry <job-id> [--env dev] [--email <email>] [--json]
5998
6001
  odla-ai o11y status [--app <id>] [--env prod] [--minutes 60] [--json]
5999
6002
  odla-ai whoami [--json]
6000
6003
  odla-ai runbook ask "<question>" [--app <id>] [--all] [--json]
@@ -6042,6 +6045,8 @@ Usage:
6042
6045
  odla-ai version
6043
6046
 
6044
6047
  Commands:
6048
+ agent Inspect durable agent wakeups and explicitly requeue a
6049
+ dead-lettered job; JSON output is stable for remote operators.
6045
6050
  runbook odla's operational procedures, stored in the database and read at
6046
6051
  the moment they are followed. "ask" gives a written, cited answer;
6047
6052
  "search" the passages behind it; "get" the whole document.
@@ -6817,6 +6822,7 @@ var PM_ENTITIES = Object.fromEntries(
6817
6822
  ["goal", "conformance", "task", "kanban", "decision", "bug"].map((entity) => [entity, PM_ACTIONS])
6818
6823
  );
6819
6824
  var COMMAND_SURFACE = {
6825
+ agent: { jobs: {}, retry: {} },
6820
6826
  admin: {
6821
6827
  ai: {
6822
6828
  show: {},
@@ -7353,11 +7359,6 @@ async function adminCommand(parsed) {
7353
7359
  });
7354
7360
  }
7355
7361
 
7356
- // src/app-export.ts
7357
- import { createWriteStream } from "fs";
7358
- import { Readable } from "stream";
7359
- import { pipeline } from "stream/promises";
7360
-
7361
7362
  // src/tenant.ts
7362
7363
  import { tenantIdFor as tenantIdFor5 } from "@odla-ai/apps";
7363
7364
  function resolveEnv(cfg, requested) {
@@ -7382,7 +7383,90 @@ function bothTenants(cfg) {
7382
7383
  return { sandbox: tenantIdFor5(cfg.app.id, "dev"), live: tenantIdFor5(cfg.app.id, "prod") };
7383
7384
  }
7384
7385
 
7386
+ // src/agent-command.ts
7387
+ async function agentCommand(parsed, deps = {}) {
7388
+ const action = parsed.positionals[1];
7389
+ if (action !== "jobs" && action !== "retry") {
7390
+ throw new Error(`unknown agent action "${action ?? ""}". Try "odla-ai agent jobs --json".`);
7391
+ }
7392
+ assertArgs(parsed, ["config", "env", "state", "limit", "json", "token", "email"], action === "jobs" ? 2 : 3);
7393
+ if (action === "retry" && (parsed.options.state !== void 0 || parsed.options.limit !== void 0)) {
7394
+ throw new Error('--state and --limit are supported only by "agent jobs"');
7395
+ }
7396
+ const cfg = await loadProjectConfig(stringOpt(parsed.options.config) ?? "odla.config.mjs");
7397
+ const { env, tenant } = resolveTenant(cfg, stringOpt(parsed.options.env));
7398
+ const doFetch = deps.fetch ?? fetch;
7399
+ const out = deps.stdout ?? console;
7400
+ const credential2 = await getDeveloperToken(
7401
+ cfg,
7402
+ {
7403
+ configPath: cfg.configPath,
7404
+ token: stringOpt(parsed.options.token),
7405
+ email: stringOpt(parsed.options.email),
7406
+ open: false
7407
+ },
7408
+ doFetch,
7409
+ out
7410
+ );
7411
+ const base = `${cfg.dbEndpoint}/app/${encodeURIComponent(tenant)}/admin/agent-jobs`;
7412
+ const headers = { authorization: `Bearer ${credential2}` };
7413
+ if (action === "retry") {
7414
+ const id = parsed.positionals[2];
7415
+ const res2 = await doFetch(`${base}/${encodeURIComponent(id)}/retry`, { method: "POST", headers });
7416
+ const body2 = await readJson(res2);
7417
+ if (!res2.ok) throw new Error(`agent retry failed (${res2.status}): ${errorMessage(body2)}`);
7418
+ const result2 = { v: 1, appId: cfg.app.id, env, tenant, ...body2 };
7419
+ if (parsed.options.json === true) out.log(JSON.stringify(result2, null, 2));
7420
+ else out.log(`${tenant}: requeued ${id}`);
7421
+ return;
7422
+ }
7423
+ const state2 = stringOpt(parsed.options.state);
7424
+ const allowed = ["pending", "running", "succeeded", "dead_letter"];
7425
+ if (state2 && !allowed.includes(state2)) {
7426
+ throw new Error(`--state must be one of ${allowed.join(", ")}`);
7427
+ }
7428
+ const url = new URL(base);
7429
+ if (state2) url.searchParams.set("state", state2);
7430
+ const limit = numberOpt(parsed.options.limit, "--limit");
7431
+ if (limit) url.searchParams.set("limit", String(limit));
7432
+ const res = await doFetch(url, { headers });
7433
+ const body = await readJson(res);
7434
+ if (!res.ok) throw new Error(`agent jobs failed (${res.status}): ${errorMessage(body)}`);
7435
+ const result = { v: 1, appId: cfg.app.id, env, tenant, jobs: body.jobs ?? [], summary: body.summary };
7436
+ if (parsed.options.json === true) {
7437
+ out.log(JSON.stringify(result, null, 2));
7438
+ return;
7439
+ }
7440
+ const summary = body.summary;
7441
+ out.log(
7442
+ `${tenant}: ${summary?.pending ?? 0} pending, ${summary?.running ?? 0} running, ${summary?.deadLetter ?? 0} dead-letter, ${summary?.succeeded ?? 0} succeeded`
7443
+ );
7444
+ for (const job of body.jobs ?? []) {
7445
+ out.log(
7446
+ [job.state, job.id, job.triggerId, `${job.entityNs}/${job.entityId}`, `attempts=${job.attempts}`, job.lastErrorCode ?? ""].filter(Boolean).join(" ")
7447
+ );
7448
+ }
7449
+ }
7450
+ async function readJson(res) {
7451
+ try {
7452
+ return await res.json();
7453
+ } catch {
7454
+ return {};
7455
+ }
7456
+ }
7457
+ function errorMessage(body) {
7458
+ const error = body.error;
7459
+ if (typeof error === "string") return error;
7460
+ if (error && typeof error === "object" && typeof error.message === "string") {
7461
+ return error.message;
7462
+ }
7463
+ return "request failed";
7464
+ }
7465
+
7385
7466
  // src/app-export.ts
7467
+ import { createWriteStream } from "fs";
7468
+ import { Readable } from "stream";
7469
+ import { pipeline } from "stream/promises";
7386
7470
  async function appExport(options) {
7387
7471
  const cfg = await loadProjectConfig(options.configPath);
7388
7472
  const out = options.stdout ?? console;
@@ -10333,6 +10417,10 @@ async function runCli(argv = process.argv.slice(2), dependencies = {}) {
10333
10417
  await adminCommand(parsed);
10334
10418
  return;
10335
10419
  }
10420
+ if (command === "agent") {
10421
+ await agentCommand(parsed, runtime);
10422
+ return;
10423
+ }
10336
10424
  if (command === "app") {
10337
10425
  await appCommand(parsed, runtime);
10338
10426
  return;
@@ -10472,4 +10560,4 @@ export {
10472
10560
  exitCodeFor,
10473
10561
  runCli
10474
10562
  };
10475
- //# sourceMappingURL=chunk-5U3EXWCR.js.map
10563
+ //# sourceMappingURL=chunk-PM5FBL3S.js.map