@odla-ai/cli 0.46.3 → 0.46.5

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
@@ -172,7 +172,7 @@ function absoluteEntryPath(entryPath) {
172
172
 
173
173
  // src/bin.ts
174
174
  var argv = process.argv.slice(2);
175
- requireCurrentCliForProvision(argv).then(() => requireCoherentProvisionRuntime(argv)).then(async () => (await import("./cli-UTMLBANX.js")).runCli()).catch((err) => {
175
+ requireCurrentCliForProvision(argv).then(() => requireCoherentProvisionRuntime(argv)).then(async () => (await import("./cli-NXZIUCZT.js")).runCli()).catch((err) => {
176
176
  console.error(redactSecrets(`odla-ai: ${err instanceof Error ? err.message : String(err)}`));
177
177
  process.exitCode = exitCodeFor(err);
178
178
  });
@@ -1194,7 +1194,7 @@ var COMMAND_SURFACE = {
1194
1194
  audit: {},
1195
1195
  credential: { set: {} }
1196
1196
  },
1197
- spend: { show: {}, reset: {} }
1197
+ spend: { show: {}, set: {}, reset: {} }
1198
1198
  },
1199
1199
  app: {
1200
1200
  archive: {},
@@ -1342,11 +1342,15 @@ function surfacePaths(node = COMMAND_SURFACE, prefix = []) {
1342
1342
  }
1343
1343
 
1344
1344
  // src/admin-spend.ts
1345
- async function call(ctx, method, scope) {
1345
+ async function call(ctx, method, scope, payload) {
1346
1346
  const url = `${ctx.platformUrl.replace(/\/$/, "")}/registry/platform/spend?scope=${encodeURIComponent(scope)}`;
1347
1347
  const response2 = await ctx.doFetch(url, {
1348
1348
  method,
1349
- headers: { authorization: `Bearer ${ctx.token}` }
1349
+ headers: {
1350
+ authorization: `Bearer ${ctx.token}`,
1351
+ ...payload === void 0 ? {} : { "content-type": "application/json" }
1352
+ },
1353
+ ...payload === void 0 ? {} : { body: JSON.stringify(payload) }
1350
1354
  });
1351
1355
  const body = await response2.json().catch(() => ({}));
1352
1356
  if (!response2.ok) {
@@ -1390,14 +1394,36 @@ async function spendReset(ctx, scope) {
1390
1394
  async function adminSpend(parsed, ctx) {
1391
1395
  const action2 = parsed.positionals[2];
1392
1396
  const scope = parsed.positionals[3] ?? stringOpt(parsed.options.scope);
1393
- if (action2 !== "show" && action2 !== "reset") rejectWord(["admin", "spend"], action2);
1397
+ if (action2 !== "show" && action2 !== "reset" && action2 !== "set") rejectWord(["admin", "spend"], action2);
1394
1398
  if (!scope) {
1395
1399
  throw new Error(
1396
1400
  `"admin spend ${action2}" needs a scope, e.g. odla-ai admin spend ${action2} app:my-app:<incarnation>`
1397
1401
  );
1398
1402
  }
1403
+ if (action2 === "set") return adminSpendSet(ctx, parsed, scope);
1399
1404
  return action2 === "show" ? spendShow(ctx, scope) : spendReset(ctx, scope);
1400
1405
  }
1406
+ async function adminSpendSet(ctx, parsed, scope) {
1407
+ const daily = stringOpt(parsed.options.daily);
1408
+ const none = parsed.options.none === true;
1409
+ if (none === (daily !== void 0)) {
1410
+ throw new Error("admin spend set needs exactly one of --daily <usd> or --none");
1411
+ }
1412
+ const dailyCapUsd = none ? null : Number(daily);
1413
+ if (dailyCapUsd !== null && (!Number.isFinite(dailyCapUsd) || dailyCapUsd < 0)) {
1414
+ throw new Error("--daily takes a non-negative dollar amount, for example --daily 25");
1415
+ }
1416
+ const result = await call(ctx, "PUT", scope, { dailyCapUsd });
1417
+ if (ctx.json) {
1418
+ ctx.out.log(JSON.stringify(result, null, 2));
1419
+ return;
1420
+ }
1421
+ ctx.out.log(`${result.scope}: ${result.message}`);
1422
+ ctx.out.log(` spent today ${money(result.spentUsd)}`);
1423
+ if (result.alreadyOverCap) {
1424
+ ctx.out.log(" today's spend already exceeds this cap \u2014 the next call will latch it.");
1425
+ }
1426
+ }
1401
1427
 
1402
1428
  // src/operator-context.ts
1403
1429
  import { existsSync as existsSync5 } from "fs";
@@ -2195,7 +2221,7 @@ async function adminCommand(parsed, deps = {}) {
2195
2221
  rejectWord(["admin", "ai", "credential"], parsed.positionals[3]);
2196
2222
  }
2197
2223
  if (area === "spend") {
2198
- assertArgs(parsed, JSON_OPTIONS, 4);
2224
+ assertArgs(parsed, [...JSON_OPTIONS, "daily", "none", "scope"], 4);
2199
2225
  const context2 = await resolveOperatorContext(parsed, { allowMissingConfig: true });
2200
2226
  const out = deps.stdout ?? console;
2201
2227
  const doFetch = deps.fetch ?? fetch;
@@ -11035,6 +11061,7 @@ Usage:
11035
11061
  odla-ai admin ai usage [--context <name>] [--app-id <id>] [--env <env>] [--run-id <id>] [--limit <1-500>] [--json]
11036
11062
  odla-ai admin ai audit [--context <name>] [--limit <1-200>] [--json]
11037
11063
  odla-ai admin spend show <app:<id>:<incarnation>> [--context <name>] [--json]
11064
+ odla-ai admin spend set <app:<id>:<incarnation>> (--daily <usd>|--none) [--context <name>] [--json]
11038
11065
  odla-ai admin spend reset <app:<id>:<incarnation>> [--context <name>] [--json]
11039
11066
  odla-ai security github connect [--repo owner/name] [--env dev] [continue in Studio; human session required]
11040
11067
  odla-ai security github disconnect --source <id> [--env dev] [continue in Studio; human session required]
@@ -16183,4 +16210,4 @@ export {
16183
16210
  isTerminalHostedSecurityStatus,
16184
16211
  runCli
16185
16212
  };
16186
- //# sourceMappingURL=chunk-PCEGBCLZ.js.map
16213
+ //# sourceMappingURL=chunk-PTOBFRCO.js.map