@withandeo/cli 0.19.21 → 0.19.23

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 (49) hide show
  1. package/README.md +10 -10
  2. package/dist/capability-preflight.d.ts.map +1 -1
  3. package/dist/capability-preflight.js +4 -5
  4. package/dist/capability-preflight.js.map +1 -1
  5. package/dist/cloud-agent.d.ts.map +1 -1
  6. package/dist/cloud-agent.js +5 -2
  7. package/dist/cloud-agent.js.map +1 -1
  8. package/dist/files.d.ts +2 -0
  9. package/dist/files.d.ts.map +1 -1
  10. package/dist/files.js +18 -3
  11. package/dist/files.js.map +1 -1
  12. package/dist/flagship-package.d.ts.map +1 -1
  13. package/dist/flagship-package.js +3 -7
  14. package/dist/flagship-package.js.map +1 -1
  15. package/dist/main.js +47 -19
  16. package/dist/main.js.map +1 -1
  17. package/dist/oauth.js +6 -6
  18. package/dist/oauth.js.map +1 -1
  19. package/dist/starter.js +4 -4
  20. package/dist/starter.js.map +1 -1
  21. package/package.json +1 -1
  22. package/skill/andeo/SKILL.md +20 -8
  23. package/skill/andeo/references/authentication.md +6 -1
  24. package/skill/andeo/references/configuration-secrets.md +1 -1
  25. package/skill/andeo/references/delivery.md +13 -5
  26. package/skill/andeo/references/email.md +17 -11
  27. package/skill/andeo/references/feature-flags.md +7 -3
  28. package/skill/andeo/references/managed-source.md +8 -5
  29. package/skill/publication.json +1 -1
  30. package/templates/shopify-customer-account/AGENTS.md +4 -2
  31. package/templates/shopify-customer-account/README.md +4 -4
  32. package/templates/shopify-customer-account/apps/gateway/AGENTS.md +2 -2
  33. package/templates/shopify-customer-account/apps/gateway/README.md +1 -1
  34. package/templates/shopify-customer-account/apps/{portal/tender-accounts.json → gateway/andeo.json} +1 -1
  35. package/templates/shopify-customer-account/apps/gateway/dot.dev.vars.example +2 -2
  36. package/templates/shopify-customer-account/apps/gateway/package.json +3 -2
  37. package/templates/shopify-customer-account/apps/gateway/scripts/{pack-tender-artifact.mjs → pack-andeo-artifact.mjs} +1 -1
  38. package/templates/shopify-customer-account/apps/gateway/src/platform/customer-auth/hostname-policy.ts +2 -2
  39. package/templates/shopify-customer-account/apps/gateway/src/platform/customer-auth/shopify-route-adapter.ts +1 -1
  40. package/templates/shopify-customer-account/apps/gateway/src/portal-service.test.ts +2 -2
  41. package/templates/shopify-customer-account/apps/gateway/src/worker.ts +2 -2
  42. package/templates/shopify-customer-account/apps/portal/AGENTS.md +1 -1
  43. package/templates/shopify-customer-account/apps/{gateway/tender-accounts.json → portal/andeo.json} +1 -1
  44. package/templates/shopify-customer-account/apps/portal/package.json +3 -2
  45. package/templates/shopify-customer-account/apps/portal/scripts/{pack-tender-artifact.mjs → pack-andeo-artifact.mjs} +1 -1
  46. package/templates/shopify-customer-account/apps/portal/src/App.tsx +1 -1
  47. package/templates/shopify-customer-account/dot.dev.vars.example +2 -2
  48. /package/templates/shopify-customer-account/apps/gateway/{tender-app.config.json → andeo-app.config.json} +0 -0
  49. /package/templates/shopify-customer-account/apps/portal/{tender-app.config.json → andeo-app.config.json} +0 -0
package/dist/main.js CHANGED
@@ -116,8 +116,20 @@ async function execute(topic, options, cwd, runtime) {
116
116
  }
117
117
  if (topic.startsWith("workflows "))
118
118
  return { value: await workflowCommand(topic.slice(10), cwd, options, runtime) };
119
- if (topic.startsWith("email "))
120
- return { value: await emailCommand(topic.slice(6), cwd, options, runtime) };
119
+ if (topic.startsWith("email ")) {
120
+ const action = topic.slice(6), value = await emailCommand(action, cwd, options, runtime);
121
+ if (!options.json && action === "list" && isRecord(value) && Array.isArray(value.inboxes)) {
122
+ const inboxes = value.inboxes.filter(isRecord);
123
+ const safeText = (value) => typeof value === "string" ? value.replace(/\r\n?/gu, "\n").replace(/\t/gu, " ")
124
+ .split("\n").map(line => line.replace(/[\p{Cc}\p{Cf}\p{Zl}\p{Zp}]/gu, "")).join("\n") : "";
125
+ const lines = inboxes.map(inbox => {
126
+ const note = safeText(inbox.usageNote);
127
+ return `${safeText(inbox.address)} (${safeText(inbox.id)})${note ? `\n ${note.replaceAll("\n", "\n ")}` : ""}`;
128
+ });
129
+ return { raw: lines.length ? lines.join("\n") : "No active inboxes available." };
130
+ }
131
+ return { value };
132
+ }
121
133
  if (topic.startsWith("agents "))
122
134
  return { value: await agentsCommand(topic.slice(7), cwd, options, runtime) };
123
135
  if (topic.startsWith("flagship "))
@@ -409,7 +421,7 @@ async function execute(topic, options, cwd, runtime) {
409
421
  case "delivery retry":
410
422
  return { value: await deliveryRetry(cwd, options, runtime) };
411
423
  default:
412
- throw new CliError("command_unknown", `Unknown command: ${topic}.`, "tender-accounts --help");
424
+ throw new CliError("command_unknown", `Unknown command: ${topic}.`, "andeo --help");
413
425
  }
414
426
  }
415
427
  async function agentsCommand(action, cwd, options, runtime) {
@@ -476,7 +488,13 @@ async function emailCommand(action, cwd, options, runtime) {
476
488
  }
477
489
  if (action === "capabilities")
478
490
  return client.email(tenantId, ["capabilities"]);
479
- if (!principal.projects.some(p => p.role === "developer"))
491
+ const persistent = principal.actorKind === "persistent_agent";
492
+ if (action === "default") {
493
+ if (!persistent)
494
+ throw new CliError("email_default_run_required", "Only persistent agent runs have a default inbox.", "Use andeo email list --json.");
495
+ return client.email(tenantId, ["default"]);
496
+ }
497
+ if (!persistent && !principal.projects.some(p => p.role === "developer"))
480
498
  throw new CliError("developer_required", "Developer access to an app in this merchant is required to access email.");
481
499
  if (action === "create")
482
500
  return client.email(tenantId, [], { body: {
@@ -495,7 +513,15 @@ async function emailCommand(action, cwd, options, runtime) {
495
513
  return client.email(tenantId, [inboxId, "messages", "list"], { query: {
496
514
  ...filters, ...Object.fromEntries(["after", "limit"].flatMap(key => options.flags.has(key) ? [[key, options.flags.get(key)]] : [])),
497
515
  } });
498
- return waitForEmail(client, tenantId, inboxId, after, timeout, runtime, Date.now, filters);
516
+ try {
517
+ return await waitForEmail(client, tenantId, inboxId, after, timeout, runtime, Date.now, filters);
518
+ }
519
+ catch (error) {
520
+ if (persistent && error instanceof CliError && ["email_inbox_not_found", "email_inbox_inactive"].includes(error.code)) {
521
+ throw new CliError(error.code, error.message, "Run andeo email default --json. If the inbox changed, capture a new cursor and restart sign-in.");
522
+ }
523
+ throw error;
524
+ }
499
525
  }
500
526
  async function workflowCommand(action, cwd, options, runtime) {
501
527
  const context = await optionalContext(cwd);
@@ -1010,7 +1036,7 @@ async function sourcePull(cwd, options, runtime) {
1010
1036
  async function compatibleManagedSourceContext(appRoot, projectId, apiUrl) {
1011
1037
  const context = await loadProjectContext(appRoot).catch((error) => {
1012
1038
  if (error instanceof CliError && error.code === "file_missing") {
1013
- throw new CliError("source_checkout_config_missing", `The connected repository does not contain tender-accounts.json at ${appRoot}.`, "Ask a merchant administrator to repair the managed source working directory before continuing.");
1039
+ throw new CliError("source_checkout_config_missing", `The connected repository does not contain andeo.json or legacy tender-accounts.json at ${appRoot}.`, "Ask a merchant administrator to repair the managed source working directory before continuing.");
1014
1040
  }
1015
1041
  throw error;
1016
1042
  });
@@ -1678,7 +1704,7 @@ function assertGitBranchName(branch) {
1678
1704
  }
1679
1705
  function safeRepositoryName(value) {
1680
1706
  const normalized = value.replaceAll(/[^A-Za-z0-9._-]+/gu, "-").replace(/^-+|-+$/gu, "");
1681
- return normalized.length >= 2 ? normalized.slice(0, 100) : "tender-app";
1707
+ return normalized.length >= 2 ? normalized.slice(0, 100) : "andeo-app";
1682
1708
  }
1683
1709
  async function tail(cwd, options, runtime) {
1684
1710
  const context = await loadProjectContext(cwd);
@@ -1968,7 +1994,7 @@ function assertNoEnvironmentCredentialForProfileManagement(environment) {
1968
1994
  }
1969
1995
  if (!environment.TENDER_ACCOUNTS_TOKEN)
1970
1996
  return;
1971
- throw new CliError("auth_profile_environment_override", "TENDER_ACCOUNTS_TOKEN overrides local auth profiles, so profile management is disabled for this command.", "Unset TENDER_ACCOUNTS_TOKEN, then retry the auth profile command.");
1997
+ throw new CliError("auth_profile_environment_override", "ANDEO_TOKEN (or legacy TENDER_ACCOUNTS_TOKEN) overrides local auth profiles, so profile management is disabled for this command.", "Unset ANDEO_TOKEN and TENDER_ACCOUNTS_TOKEN, then retry the auth profile command.");
1972
1998
  }
1973
1999
  async function authLogout(_cwd, options, runtime) {
1974
2000
  if (runtime.environment.ANDEO_NETWORK_TOKEN !== undefined || runtime.environment.ANDEO_CLOUD_BOOTSTRAP !== undefined) {
@@ -2131,7 +2157,7 @@ async function runDev(cwd, options, runtime) {
2131
2157
  return { value: { status: "stopped", workflowExecution: "local" } };
2132
2158
  }
2133
2159
  if (!context.config.commands.dev) {
2134
- throw new CliError("dev_command_missing", "This app does not declare commands.dev in tender-accounts.json.");
2160
+ throw new CliError("dev_command_missing", "This app does not declare commands.dev in its Andeo configuration.");
2135
2161
  }
2136
2162
  await runtime.runProjectCommand({
2137
2163
  command: context.config.commands.dev,
@@ -2144,7 +2170,7 @@ async function runDev(cwd, options, runtime) {
2144
2170
  async function runBuildStage(cwd, options, runtime, stage, extraEnvironment = {}) {
2145
2171
  const context = await loadProjectContext(cwd);
2146
2172
  const command = context.config.commands[stage];
2147
- runtime.stderr.write(`tender-accounts: ${stage}\n`);
2173
+ runtime.stderr.write(`andeo: ${stage}\n`);
2148
2174
  await runtime.runProjectCommand({
2149
2175
  command,
2150
2176
  cwd: context.root,
@@ -2755,7 +2781,7 @@ function exampleConfig() {
2755
2781
  commands: {
2756
2782
  dev: "npm run dev",
2757
2783
  check: "npm run check",
2758
- package: "npm run pack:tender",
2784
+ package: "npm run pack:andeo",
2759
2785
  },
2760
2786
  artifactDirectory: ".tender/artifacts/current",
2761
2787
  returnPath: "/account",
@@ -2959,6 +2985,7 @@ function assertAllowedOptions(topic, options) {
2959
2985
  docs: common,
2960
2986
  capabilities: [...common, ...authentication, "project"],
2961
2987
  "email capabilities": [...common, ...authentication, "tenant", "project"],
2988
+ "email default": [...common, ...authentication, "tenant", "project"],
2962
2989
  "email create": [...common, ...authentication, "tenant", "project", "name", "expires-in"],
2963
2990
  "email list": [...common, ...authentication, "tenant", "project"],
2964
2991
  "email cursor": [...common, ...authentication, "tenant", "project", "inbox"],
@@ -3113,7 +3140,7 @@ function assertAllowedOptions(topic, options) {
3113
3140
  const provided = [...options.flags.keys(), ...options.booleans];
3114
3141
  const unexpected = provided.find((name) => !accepted.has(name));
3115
3142
  if (unexpected) {
3116
- throw new CliError("argument_unknown", `Option --${unexpected} is not valid for ${topic}.`, `tender-accounts ${topic} --help`);
3143
+ throw new CliError("argument_unknown", `Option --${unexpected} is not valid for ${topic}.`, `andeo ${topic} --help`);
3117
3144
  }
3118
3145
  const positionalLimits = {
3119
3146
  docs: { minimum: 0, maximum: 1 },
@@ -3132,10 +3159,10 @@ function assertAllowedOptions(topic, options) {
3132
3159
  };
3133
3160
  const limit = positionalLimits[topic] ?? { minimum: 0, maximum: 0 };
3134
3161
  if (options.positionals.length < limit.minimum) {
3135
- throw new CliError("argument_required", `Missing ${topic.startsWith("auth ") ? "profile name" : "argument"}.`, `tender-accounts ${topic} --help`);
3162
+ throw new CliError("argument_required", `Missing ${topic.startsWith("auth ") ? "profile name" : "argument"}.`, `andeo ${topic} --help`);
3136
3163
  }
3137
3164
  if (options.positionals.length > limit.maximum) {
3138
- throw new CliError("argument_unexpected", `Unexpected argument: ${options.positionals[limit.maximum] ?? ""}.`, `tender-accounts ${topic} --help`);
3165
+ throw new CliError("argument_unexpected", `Unexpected argument: ${options.positionals[limit.maximum] ?? ""}.`, `andeo ${topic} --help`);
3139
3166
  }
3140
3167
  }
3141
3168
  function requiredPositional(options, index, label) {
@@ -3234,7 +3261,7 @@ Agents are separate from human login profiles; agent task credentials cannot man
3234
3261
  return `Usage: andeo agent <status|complete|cancel> [--json]
3235
3262
 
3236
3263
  Inspect or end this Cloud task's exact admitted run. Complete and cancel remove local task keys only after Andeo confirms the outcome. A completed, cancelled or expired task cannot re-admit with the same state directory.
3237
- Requires the Cloud bootstrap placeholder, dedicated admission origin, private task state directory, explicit scope and run duration. Human profiles and legacy tokens cannot be combined with Cloud mode.`;
3264
+ Requires the Cloud bootstrap placeholder and a private task state directory. Task scope and run duration are optional. Set ANDEO_AGENT_QA_EMAIL=on or off before admission to override assigned inbox eligibility. Human profiles and legacy tokens cannot be combined with Cloud mode.`;
3238
3265
  if (topic?.startsWith("config autoupgrade "))
3239
3266
  topic = "config autoupgrade";
3240
3267
  if (topic === "flagship")
@@ -3255,11 +3282,12 @@ Flag deletion requires a disabled saved flag and exact --confirm KEY after clean
3255
3282
  if (topic === "artifact" || topic === "artifact finalize")
3256
3283
  return "Usage: andeo artifact finalize --artifact-directory DIR [--json]\n\nFinalize workflow coordinators and native Flagship declarations after producer packaging, retaining the attested source revision. Runs offline in the build checkout.";
3257
3284
  if (topic === "email" || topic?.startsWith("email "))
3258
- return `Usage: andeo email <capabilities|create|list|cursor|wait|read|messages|retire> [options]
3285
+ return `Usage: andeo email <capabilities|default|create|list|cursor|wait|read|messages|retire> [options]
3259
3286
 
3260
3287
  Create: [--name shop-test] [--expires-in 1h]. Without expiration the address is persistent.
3261
- List: discover active inboxes shared across the selected merchant's apps.
3262
- Capabilities: inspect merchant email availability, permissions, and limits.
3288
+ Default: find this persistent run's assigned QA inbox and usage note.
3289
+ List: discover the active inboxes and usage notes this login or run can read.
3290
+ Capabilities: inspect email availability, read scope, permissions, and limits.
3263
3291
  Cursor: --inbox INBOX_ID. Capture this BEFORE triggering the external email.
3264
3292
  Wait: --inbox INBOX_ID --after CURSOR [--timeout 120s]. Maximum wait: 10 minutes.
3265
3293
  Read: --inbox INBOX_ID --message MESSAGE_ID.
@@ -3377,7 +3405,7 @@ Account workflow entitlement is required for new starts. Run status is authorita
3377
3405
  "skills get": "Usage: andeo skills get SKILL_ID [--profile NAME] [--api-url URL] [--json]\n\nRead one skill entrypoint for the current invocation.\n\nExample:\n andeo skills get guardrailed-design-system",
3378
3406
  "skills file": "Usage: andeo skills file SKILL_ID --path PATH [--profile NAME] [--api-url URL] [--json]\n\nRead one catalog-listed supporting file for the current invocation.\n\nExample:\n andeo skills file recharge-customer-operations --path references/subscriptions.md",
3379
3407
  config: "Usage: andeo config example [--json]\n andeo config autoupgrade <on|off|status> [--json]",
3380
- "config example": "Usage: andeo config example [--json]\n\nPrint the committed tender-accounts.json contract.",
3408
+ "config example": "Usage: andeo config example [--json]\n\nPrint the andeo.json contract (legacy tender-accounts.json is also supported).",
3381
3409
  };
3382
3410
  if (topic && topics[topic])
3383
3411
  return topics[topic];