@tarileo/avileo-catalog-cli 0.3.11 → 0.3.12

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/README.md CHANGED
@@ -81,3 +81,42 @@ Profile updates use a direct JSON object with `business profile update --from
81
81
  profile-update.json`. Without `--apply` the command returns a local diff; with
82
82
  `--apply` it creates a `business.profile.update` proposal. After approval, run
83
83
  `operation apply <id> --json` and re-read the profile.
84
+
85
+ ## Kuati on the existing retail cell (`tienda`)
86
+
87
+ Kuati uses the existing Tiendas deployment, API, account and data boundaries.
88
+ There is no separate Kuati cell or catalog. The `tienda` catalog retains the
89
+ 10-day Professional trial and existing PEN subscription/payment flow.
90
+ An active owner, active membership/store, canonical company approval and a
91
+ usable subscription are required. Branding does not grant marketplace access
92
+ or approve sensitive operations.
93
+
94
+ The operator supplies `AVILEO_AGENT_BASE_URL` and injects a temporary read-only
95
+ `AVILEO_AGENT_API_KEY` only into the process. Never put a key in arguments, URLs,
96
+ prompts, source, browser configuration or evidence. Before injecting a secret,
97
+ probe `/api/v1/public/deployment` without authentication and confirm the
98
+ `tienda` identity, Kuati brand and expected fingerprint at the selected origin.
99
+
100
+ Enable `AVILEO_AGENT_REQUIRE_EXPLICIT_ORIGIN` with its strict value `1` for this
101
+ development flow. Missing/blank origins fail rather than choosing production.
102
+ For `auth login`/`auth configure` in strict mode, an explicitly private
103
+ `AVILEO_AGENT_CONFIG_PATH` is also mandatory; the global credential file is not
104
+ an acceptable development pairing destination. Environment-only reads do not
105
+ write a credential file.
106
+
107
+ After preparing the workspace SDK as described above, the existing read-only
108
+ CLI command is:
109
+
110
+ ```sh
111
+ : "${AVILEO_AGENT_BASE_URL:?operator-selected API origin required}"
112
+ : "${AVILEO_AGENT_API_KEY:?private process-only Agent Key required}"
113
+ : "${AVILEO_AGENT_REQUIRE_EXPLICIT_ORIGIN:?strict development mode required}"
114
+ bun --no-env-file apps/avileo/agent-cli/src/index.ts --json business show
115
+ ```
116
+
117
+ Check business identity, canonical approval, usable subscription and
118
+ `grantedActions`. A Public Client Key or System Admin credential cannot replace
119
+ an Agent Key. Mutating credentials still need existing exact-payload human
120
+ authorization; use read mode for the initial smoke. Device approval links use
121
+ the app origin selected on the backend, which may have a different port from
122
+ the API. Never switch to a production origin to recover a failed dev connection.
package/dist/index.js CHANGED
@@ -19852,6 +19852,29 @@ function createAbortSignal(timeoutMs) {
19852
19852
  const timer = setTimeout(() => controller.abort(), timeoutMs);
19853
19853
  return { signal: controller.signal, cancel: () => clearTimeout(timer) };
19854
19854
  }
19855
+ function agentBaseUrl(config2) {
19856
+ if (config2.requireExplicitBaseUrl && config2.baseUrl === void 0) {
19857
+ throw new AgentValidationError("Esta conexi\xF3n requiere un origen de API expl\xEDcito.", {
19858
+ code: "INVALID_AGENT_CONFIG",
19859
+ status: 0
19860
+ });
19861
+ }
19862
+ const raw = config2.baseUrl ?? AVILEO_AGENT_API_URL;
19863
+ try {
19864
+ const parsed = new URL(raw.trim());
19865
+ if (!raw.trim() || !["http:", "https:"].includes(parsed.protocol) || parsed.username || parsed.password || parsed.search || parsed.hash)
19866
+ throw new Error();
19867
+ return parsed.toString().replace(/\/+$/, "");
19868
+ } catch {
19869
+ throw new AgentValidationError(
19870
+ "El origen de API debe ser absoluto, sin credenciales, query ni fragmento.",
19871
+ {
19872
+ code: "INVALID_AGENT_CONFIG",
19873
+ status: 0
19874
+ }
19875
+ );
19876
+ }
19877
+ }
19855
19878
  var AgentHttpClient = class {
19856
19879
  #apiKey;
19857
19880
  #baseUrl;
@@ -19859,7 +19882,7 @@ var AgentHttpClient = class {
19859
19882
  #timeoutMs;
19860
19883
  constructor(config2) {
19861
19884
  this.#apiKey = configuredApiKey(config2);
19862
- this.#baseUrl = (config2.baseUrl ?? AVILEO_AGENT_API_URL).replace(/\/$/, "");
19885
+ this.#baseUrl = agentBaseUrl(config2);
19863
19886
  this.#fetchImpl = config2.fetch ?? ((...args) => fetch(...args));
19864
19887
  this.#timeoutMs = config2.timeoutMs;
19865
19888
  }
@@ -19878,6 +19901,8 @@ var AgentHttpClient = class {
19878
19901
  try {
19879
19902
  response = await this.#fetchImpl(url2, {
19880
19903
  method: options.method ?? "GET",
19904
+ // Custom Agent Key headers must not follow redirects to another origin.
19905
+ redirect: "error",
19881
19906
  headers: {
19882
19907
  ...formData || options.body === void 0 ? {} : { "content-type": "application/json" },
19883
19908
  ...options.approvalId ? { "x-avileo-approval-id": options.approvalId } : {},
@@ -21258,8 +21283,8 @@ function apiOrigin(baseUrl) {
21258
21283
  return `${parsed.protocol}//${parsed.host}`;
21259
21284
  }
21260
21285
  function overrideBaseUrl(env) {
21261
- const raw = env.AVILEO_AGENT_BASE_URL?.trim();
21262
- return raw ? normalizeApiBaseUrl(raw) : void 0;
21286
+ const raw = env.AVILEO_AGENT_BASE_URL;
21287
+ return raw === void 0 ? void 0 : normalizeApiBaseUrl(raw);
21263
21288
  }
21264
21289
  var AGENT_KEY_PATTERN = /^avileo_sk_[^\s]+$/;
21265
21290
  function normalizeAgentKey(value, message) {
@@ -21300,6 +21325,11 @@ function readLocalCredential(env = process.env) {
21300
21325
  }
21301
21326
  function resolveCredential(env = process.env) {
21302
21327
  const override = overrideBaseUrl(env);
21328
+ if (env.AVILEO_AGENT_REQUIRE_EXPLICIT_ORIGIN === "1" && override === void 0) {
21329
+ throw new CliOriginUnsupportedError(
21330
+ "Esta conexi\xF3n requiere AVILEO_AGENT_BASE_URL expl\xEDcito; no se usar\xE1 el origen de producci\xF3n."
21331
+ );
21332
+ }
21303
21333
  const environmentValue = env.AVILEO_AGENT_API_KEY;
21304
21334
  if (environmentValue !== void 0) {
21305
21335
  return {
@@ -21354,7 +21384,8 @@ function createClientFromEnvironment({
21354
21384
  }
21355
21385
  return clientFactory({
21356
21386
  apiKey: credential.apiKey,
21357
- baseUrl: credential.baseUrl
21387
+ baseUrl: credential.baseUrl,
21388
+ ...env.AVILEO_AGENT_REQUIRE_EXPLICIT_ORIGIN === "1" ? { requireExplicitBaseUrl: true } : {}
21358
21389
  });
21359
21390
  }
21360
21391
  var CliConfigurationError = class extends Error {
@@ -22299,13 +22330,27 @@ async function openVerificationUri(uri) {
22299
22330
  return false;
22300
22331
  }
22301
22332
  function resolveSelectedBaseUrl(options) {
22302
- const explicit = options.baseUrl?.trim();
22303
- if (explicit) return normalizeApiBaseUrl(explicit);
22304
- const fromEnvironment = options.env.AVILEO_AGENT_BASE_URL?.trim();
22305
- return fromEnvironment ? normalizeApiBaseUrl(fromEnvironment) : AVILEO_AGENT_API_URL;
22333
+ if (options.baseUrl !== void 0) return normalizeApiBaseUrl(options.baseUrl);
22334
+ const fromEnvironment = options.env.AVILEO_AGENT_BASE_URL;
22335
+ if (fromEnvironment !== void 0) return normalizeApiBaseUrl(fromEnvironment);
22336
+ if (options.env.AVILEO_AGENT_REQUIRE_EXPLICIT_ORIGIN === "1") {
22337
+ throw new CliOriginUnsupportedError(
22338
+ "Esta conexi\xF3n requiere --base-url o AVILEO_AGENT_BASE_URL expl\xEDcito."
22339
+ );
22340
+ }
22341
+ return AVILEO_AGENT_API_URL;
22342
+ }
22343
+ function assertIsolatedDevelopmentPairing(options) {
22344
+ if (options.env.AVILEO_AGENT_REQUIRE_EXPLICIT_ORIGIN === "1" && !options.env.AVILEO_AGENT_CONFIG_PATH?.trim()) {
22345
+ throw new CliProtocolError(
22346
+ "CLI_CONFIGURATION_ERROR",
22347
+ "La conexi\xF3n de desarrollo requiere AVILEO_AGENT_CONFIG_PATH privado; no se modificar\xE1 la credencial global."
22348
+ );
22349
+ }
22306
22350
  }
22307
22351
  async function login(options) {
22308
22352
  const baseUrl = resolveSelectedBaseUrl(options);
22353
+ assertIsolatedDevelopmentPairing(options);
22309
22354
  const deviceAuth = options.deviceAuthFactory({ baseUrl });
22310
22355
  const start = await deviceAuth.start({ name: "Avileo CLI" });
22311
22356
  const browserOpened = await options.openBrowser(start.verificationUri);
@@ -22362,6 +22407,7 @@ async function login(options) {
22362
22407
  }
22363
22408
  async function configure(options) {
22364
22409
  const baseUrl = resolveSelectedBaseUrl(options);
22410
+ assertIsolatedDevelopmentPairing(options);
22365
22411
  const apiKey = await options.readSecret("Agent Key de Avileo (no se mostrar\xE1): ");
22366
22412
  saveLocalCredential({ apiKey, baseUrl }, options.env);
22367
22413
  emitSuccess({