@withandeo/cli 0.19.19 → 0.19.21

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 (30) hide show
  1. package/README.md +36 -0
  2. package/dist/api.d.ts +24 -0
  3. package/dist/api.d.ts.map +1 -1
  4. package/dist/api.js +16 -0
  5. package/dist/api.js.map +1 -1
  6. package/dist/documentation.js +1 -1
  7. package/dist/documentation.js.map +1 -1
  8. package/dist/feedback.d.ts +12 -0
  9. package/dist/feedback.d.ts.map +1 -0
  10. package/dist/feedback.js +40 -0
  11. package/dist/feedback.js.map +1 -0
  12. package/dist/main.d.ts.map +1 -1
  13. package/dist/main.js +73 -8
  14. package/dist/main.js.map +1 -1
  15. package/package.json +1 -1
  16. package/skill/{tender-accounts → andeo}/SKILL.md +20 -1
  17. package/skill/{tender-accounts → andeo}/references/authentication.md +40 -0
  18. package/skill/{tender-accounts → andeo}/references/managed-source.md +37 -7
  19. package/skill/{tender-accounts → andeo}/references/releases-recovery.md +18 -0
  20. package/skill/{tender-accounts → andeo}/references/skills.md +1 -0
  21. package/skill/publication.json +1 -1
  22. /package/skill/{tender-accounts → andeo}/references/configuration-secrets.md +0 -0
  23. /package/skill/{tender-accounts → andeo}/references/delivery.md +0 -0
  24. /package/skill/{tender-accounts → andeo}/references/domains-auth.md +0 -0
  25. /package/skill/{tender-accounts → andeo}/references/email.md +0 -0
  26. /package/skill/{tender-accounts → andeo}/references/feature-flags.md +0 -0
  27. /package/skill/{tender-accounts → andeo}/references/observability.md +0 -0
  28. /package/skill/{tender-accounts → andeo}/references/services.md +0 -0
  29. /package/skill/{tender-accounts → andeo}/references/storage.md +0 -0
  30. /package/skill/{tender-accounts → andeo}/references/workflows.md +0 -0
package/dist/main.js CHANGED
@@ -5,6 +5,7 @@ import { lstat, mkdtemp, readFile, readdir, realpath, rm } from "node:fs/promise
5
5
  import { basename, join, relative, resolve, sep } from "node:path";
6
6
  import { homedir, hostname, tmpdir } from "node:os";
7
7
  import { createHash } from "node:crypto";
8
+ import { readFeedbackInput } from "./feedback.js";
8
9
  import { AgentApiClient } from "./api.js";
9
10
  import { emailDuration, waitForEmail } from "./email.js";
10
11
  import { CLI_AUTH_SCHEMA, DEFAULT_AUTH_PROFILE, createDefaultAuthStore, validateAuthProfile, validateNamedAuthProfile, } from "./auth-store.js";
@@ -75,7 +76,7 @@ export async function runCli(argv, overrides = {}) {
75
76
  runtime.stdout.write(`${CLI_VERSION}\n`);
76
77
  return 0;
77
78
  }
78
- const options = parseOptions(values);
79
+ const options = parseOptions(values, topic === "source change edit" ? "description" : undefined);
79
80
  assertAllowedOptions(topic, options);
80
81
  const cwd = resolve(runtime.cwd, options.flags.get("cwd") ?? ".");
81
82
  const result = await execute(topic, options, cwd, runtime);
@@ -227,6 +228,8 @@ async function execute(topic, options, cwd, runtime) {
227
228
  return { value: await linkProject(cwd, options, runtime) };
228
229
  case "doctor":
229
230
  return await doctor(cwd, options, runtime);
231
+ case "feedback":
232
+ return { value: await sendFeedback(cwd, options, runtime) };
230
233
  case "preview": {
231
234
  const value = await preview(cwd, options, runtime);
232
235
  return { value, exitCode: value.status === "timeout" ? 3 : 0 };
@@ -236,6 +239,7 @@ async function execute(topic, options, cwd, runtime) {
236
239
  case "preview open":
237
240
  return { value: await previewOpen(cwd, options, runtime) };
238
241
  case "production releases":
242
+ case "production verify":
239
243
  case "production rollback": {
240
244
  const context = await optionalContext(cwd);
241
245
  const { client, projectId } = await sourceProjectAccess(cwd, context?.link ?? null, options, runtime, false);
@@ -244,6 +248,12 @@ async function execute(topic, options, cwd, runtime) {
244
248
  const revision = Number(requiredFlag(options, "expected-revision"));
245
249
  if (!Number.isSafeInteger(revision) || revision < 1)
246
250
  throw new CliError("argument_invalid", "--expected-revision must be a positive integer.");
251
+ if (topic === "production verify") {
252
+ const value = await client.verifyProduction(projectId, requiredFlag(options, "activation"), {
253
+ compositionId: requiredFlag(options, "composition"), expectedRuntimeRevision: revision,
254
+ });
255
+ return { value, exitCode: value.status === "verified" ? 0 : 2 };
256
+ }
247
257
  return { value: await client.rollbackProduction(projectId, { productionReleaseId: requiredFlag(options, "release"),
248
258
  expectedProductionReleaseId: requiredFlag(options, "expected-release"), expectedRuntimeRevision: revision,
249
259
  idempotencyKey: requiredFlag(options, "idempotency-key") }) };
@@ -285,6 +295,8 @@ async function execute(topic, options, cwd, runtime) {
285
295
  return { value: await sourceOperationRetry(cwd, options, runtime) };
286
296
  case "source change create":
287
297
  return { value: await sourceChangeCreate(cwd, options, runtime) };
298
+ case "source change edit":
299
+ return { value: await sourceChangeEdit(cwd, options, runtime) };
288
300
  case "source merge": {
289
301
  const value = await sourceMerge(cwd, options, runtime);
290
302
  return { value, exitCode: value.status === "timeout" ? 3 : value.merge && ["awaiting_approval", "needs_attention", "superseded", "authorization_required", "reconciliation_required", "cancelled"].includes(value.merge.stage) ? 2 : 0 };
@@ -1564,6 +1576,38 @@ async function sourceChangeCreate(cwd, options, runtime) {
1564
1576
  };
1565
1577
  });
1566
1578
  }
1579
+ async function sourceChangeEdit(cwd, options, runtime) {
1580
+ const rawChangeId = options.flags.get("change");
1581
+ if (!rawChangeId)
1582
+ throw new CliError("argument_required", "Supply the change ID with --change.", "andeo source change list --json");
1583
+ const changeId = requiredSourceChangeRequestId(rawChangeId);
1584
+ const rawSnapshot = options.flags.get("expected-snapshot");
1585
+ if (!rawSnapshot) {
1586
+ throw new CliError("argument_required", "Supply the current snapshotVersion with --expected-snapshot.", `andeo source change show --change ${changeId} --json`);
1587
+ }
1588
+ const expectedSnapshot = Number(rawSnapshot);
1589
+ if (!/^[0-9]+$/u.test(rawSnapshot) || !Number.isSafeInteger(expectedSnapshot) || expectedSnapshot < 1) {
1590
+ throw new CliError("argument_invalid", "--expected-snapshot must be a positive integer.");
1591
+ }
1592
+ const title = options.flags.get("title")?.trim();
1593
+ const description = options.flags.get("description")?.trim();
1594
+ if (title === undefined && description === undefined) {
1595
+ throw new CliError("argument_required", "Supply --title, --description, or both.");
1596
+ }
1597
+ if (title === "" || (title?.length ?? 0) > 160 || (description?.length ?? 0) > 4000) {
1598
+ throw new CliError("argument_invalid", "A title must contain 1–160 characters and a description at most 4,000 characters.");
1599
+ }
1600
+ const access = await sourceReadAccess(cwd, options, runtime);
1601
+ const { changeRequest } = await access.client.sourceChangeRequest(changeId);
1602
+ requireLinkedSourceChange(access.projectId, changeRequest.projectId);
1603
+ if (changeRequest.id !== changeId || changeRequest.repositoryId !== access.repository.id) {
1604
+ throw new CliError("source_change_repository_mismatch", "The returned change does not match this repository and change ID.");
1605
+ }
1606
+ if (access.repository.assignedFeatureBranch && changeRequest.headBranch !== access.repository.assignedFeatureBranch) {
1607
+ throw new CliError("agent_branch_scope_mismatch", "This run may edit reviews only for its assigned feature branch.");
1608
+ }
1609
+ return access.client.editSourceChangeRequest(changeId, { expectedSnapshot, title, description });
1610
+ }
1567
1611
  async function sourceChangeList(cwd, options, runtime) {
1568
1612
  const access = await sourceReadAccess(cwd, options, runtime);
1569
1613
  const state = (options.flags.get("state") ?? "open");
@@ -2324,6 +2368,21 @@ async function deliveryRetry(cwd, options, runtime) {
2324
2368
  const { client } = await authenticatedClient(cwd, context.link, options, runtime);
2325
2369
  return await client.retryDelivery(requiredDeliveryId(options), options.booleans.has("reauthorize") ? context.link.projectId : undefined);
2326
2370
  }
2371
+ async function sendFeedback(cwd, options, runtime) {
2372
+ const bodyFile = requiredFlag(options, "body-file");
2373
+ if (bodyFile === "-" && options.booleans.has("token-stdin")) {
2374
+ throw new CliError("feedback_stdin_conflict", "--body-file - cannot be combined with --token-stdin.");
2375
+ }
2376
+ const input = await readFeedbackInput({ title: requiredFlag(options, "title"), category: options.flags.get("category") ?? "other", bodyFile }, cwd, runtime.stdin);
2377
+ const context = await optionalContext(cwd);
2378
+ const explicitProject = options.flags.get("project");
2379
+ const projectId = explicitProject ? requiredProjectId(explicitProject) : context?.link?.projectId;
2380
+ if (options.booleans.has("dry-run")) {
2381
+ return { status: "dry_run", title: input.title, category: input.category, projectId: projectId ?? null, bodyCharacters: input.body.length, body: input.body };
2382
+ }
2383
+ const { client } = await authenticatedClient(cwd, context?.link ?? null, options, runtime);
2384
+ return client.feedback({ ...input, ...(projectId ? { projectId } : {}), cliVersion: CLI_VERSION });
2385
+ }
2327
2386
  async function authenticatedClient(cwd, link, options, runtime) {
2328
2387
  let apiUrl = selectedApiUrl(options, link, runtime.environment, runtime.defaultApiUrl);
2329
2388
  const cloud = await cloudAgentClient(runtime.environment, cwd, runtime.fetcher, { tokenStdin: options.booleans.has("token-stdin"), profile: options.flags.has("profile"), apiUrl });
@@ -2688,7 +2747,7 @@ function requiredSkillArgument(options) {
2688
2747
  return skillId;
2689
2748
  }
2690
2749
  function skillPath() {
2691
- return fileURLToPath(new URL("../skill/tender-accounts/SKILL.md", import.meta.url));
2750
+ return fileURLToPath(new URL("../skill/andeo/SKILL.md", import.meta.url));
2692
2751
  }
2693
2752
  function exampleConfig() {
2694
2753
  return {
@@ -2840,7 +2899,7 @@ function commandTopic(argv) {
2840
2899
  };
2841
2900
  return { topic: legacy[parent] ?? parent ?? "help", values: argv.slice(1) };
2842
2901
  }
2843
- function parseOptions(values) {
2902
+ function parseOptions(values, allowEmptyFlag) {
2844
2903
  const flags = new Map();
2845
2904
  const booleans = new Set();
2846
2905
  const positionals = [];
@@ -2866,7 +2925,7 @@ function parseOptions(values) {
2866
2925
  continue;
2867
2926
  }
2868
2927
  const value = values[index + 1];
2869
- if (!value || value.startsWith("--") || flags.has(name)) {
2928
+ if (value === undefined || (value === "" && name !== allowEmptyFlag) || value.startsWith("--") || flags.has(name)) {
2870
2929
  throw new CliError("argument_value_missing", `Option --${name} requires exactly one value.`);
2871
2930
  }
2872
2931
  flags.set(name, value);
@@ -2955,6 +3014,7 @@ function assertAllowedOptions(topic, options) {
2955
3014
  "agents complete": [...common, ...authentication, "expected-revision", "run"],
2956
3015
  link: [...common, ...authentication, "project"],
2957
3016
  doctor: [...common, ...authentication],
3017
+ feedback: [...common, ...authentication, "project", "title", "category", "body-file", "dry-run"],
2958
3018
  preview: [
2959
3019
  ...common,
2960
3020
  ...authentication,
@@ -2972,6 +3032,7 @@ function assertAllowedOptions(topic, options) {
2972
3032
  "source status": [...common, ...authentication, "project"],
2973
3033
  "source continue": [...common, ...authentication, "change", "work"],
2974
3034
  "production releases": [...common, ...authentication, "project"],
3035
+ "production verify": [...common, ...authentication, "project", "activation", "composition", "expected-revision"],
2975
3036
  "production rollback": [...common, ...authentication, "project", "release", "expected-release", "expected-revision", "idempotency-key"],
2976
3037
  "source branches": [...common, ...authentication, "project"],
2977
3038
  "source reconnect prepare": [...common, ...authentication, "project", "repository", "idempotency-key"],
@@ -3006,6 +3067,7 @@ function assertAllowedOptions(topic, options) {
3006
3067
  "source operation status": [...common, ...authentication, "operation"],
3007
3068
  "source operation retry": [...common, ...authentication, "operation", "no-wait", "timeout-seconds"],
3008
3069
  "source change create": [...common, ...authentication, "project", "title", "description", "base", "head"],
3070
+ "source change edit": [...common, ...authentication, "project", "change", "expected-snapshot", "title", "description"],
3009
3071
  "source merge": [...common, ...authentication, "project", "head", "title", "change", "expected-head", "expected-snapshot", "idempotency-key", "dry-run", "wait", "no-wait", "timeout-seconds",
3010
3072
  "expected-base", "expected-policy-revision", "validation-mode", "authorize", "continuation", "note"],
3011
3073
  "source merge status": [...common, ...authentication, "project", "merge"],
@@ -3244,12 +3306,14 @@ Account workflow entitlement is required for new starts. Run status is authorita
3244
3306
  "auth logout": "Usage: andeo auth logout [--all] [--local] [--json]\n\nRevoke the default login. --local removes only the local copy; --all must be explicit to remove every login and directory binding.",
3245
3307
  link: "Usage: andeo link [--project PROJECT_ID] [--profile NAME] [--api-url URL] [--json]\n\nLink this checkout to exactly one project. The project ID remains a target guard; profile activation stays machine-local.",
3246
3308
  doctor: "Usage: andeo doctor [--json]\n\nValidate configuration, authentication, project scope, and local artifact readiness.",
3309
+ feedback: "Usage: andeo feedback --title TEXT --body-file PATH [--category bug|docs|feature|other] [--project PROJECT_ID] [--dry-run] [--json]\n\nSend feedback to the Andeo team. Requires login. Use --body-file - to read the body from stdin. Bodies can be up to 65,000 characters, so include the context that helps. Leave out credentials and customer data. --dry-run prints what would be sent, without sending it. Sending identical feedback again returns the original receipt.\n\nExamples:\n andeo feedback --title \"Preview logs omit build errors\" --category bug --body-file notes.md --json\n andeo feedback --title \"Clarify workflow retries\" --category docs --body-file - --dry-run --json",
3247
3310
  dev: "Usage: andeo dev\n\nRun the app's declared local development command. This starts local development and does not create an Andeo deployment.",
3248
3311
  check: "Usage: andeo check [--json]\n\nRun the app's declared validation command.",
3249
3312
  build: "Usage: andeo build [--json]\n\nRun validation and packaging, then verify the complete portable artifact.",
3250
3313
  upload: "Usage: andeo upload [--dry-run] [--submission-key KEY] [--json]\n\nValidate, package and retain an exact artifact for administrator review. Does not create a preview or publish production.",
3251
3314
  preview: "Usage: andeo preview [--through PROJECT_ID] [--return-path /account] [--dry-run] [--no-wait] [--idempotency-key KEY] [--json]\n\nBuild an exact app preview. Persistent Cloud agents with preview.build/open request an isolated build of their assigned pushed branch. Explicit preview.share consent automatically resolves its published gateway and issues a handoff lasting up to seven days, independently of normal run completion. --through overrides an eligible entry when needed. Without sharing consent, access stays run-bound. Unsupported bindings fail closed. Use preview open --from sbl_... (persistent) or dly_... to reopen without rebuilding.",
3252
- production: "Usage: andeo production <releases|rollback> [options]",
3315
+ production: "Usage: andeo production <releases|verify|rollback> [options]",
3316
+ "production verify": "Usage: andeo production verify [--project PROJECT_ID] --activation ACTIVATION_ID --composition COMPOSITION_ID --expected-revision N [--json]\n\nAdministrators recheck the exact current activation without building, uploading or changing production. Exit 2 means verification remains incomplete.",
3253
3317
  "production releases": "Usage: andeo production releases [--project PROJECT_ID] [--json]\n\nList immutable production releases and rollback eligibility.",
3254
3318
  "production rollback": "Usage: andeo production rollback [--project PROJECT_ID] --release RELEASE_ID --expected-release CURRENT_ID --expected-revision N --idempotency-key KEY [--json]\n\nMerchant administrators restore a previously successful app release without building or uploading code.",
3255
3319
  source: "Usage: andeo source <status|branches|branch|log|compare|connect|reconnect|policy|pull|push|change|default|promote|history|operation> [options]\n\nUse standard Git through Andeo for a gateway or service project. Default-branch changes follow the saved publication policy.",
@@ -3271,7 +3335,7 @@ Account workflow entitlement is required for new starts. Run status is authorita
3271
3335
  "source operation": "Usage: andeo source operation <status|retry> --operation sop_... [--json]",
3272
3336
  "source operation status": "Usage: andeo source operation status --operation sop_... [--json]\n\nRead durable status and safe evidence for one exact source operation.",
3273
3337
  "source operation retry": "Usage: andeo source operation retry --operation sop_... [--no-wait] [--timeout-seconds N] [--json]\n\nRetry or resume the same durable source operation without changing its reviewed intent. This never publishes production.",
3274
- "source change": "Usage: andeo source change <create|list|show|close|resume|cancel|take-over> [options]\n\nCreate and inspect exact preview-backed changes, or recover an accepted merge intent.",
3338
+ "source change": "Usage: andeo source change <create|edit|list|show|close|resume|cancel|take-over> [options]\n\nCreate, edit, and inspect exact preview-backed changes, or recover an accepted merge intent.",
3275
3339
  "source change cancel": "Usage: andeo source change cancel --change scr_... [--json]\n\nWithdraw new work for an accepted intent. Already-issued effects require readback; source may already be merged.",
3276
3340
  "source change take-over": "Usage: andeo source change take-over --change scr_... --idempotency-key KEY [--json]\n\nAdministrator only. Records a new bounded authorization for the same exact inputs; then use source change resume.",
3277
3341
  "source merge": "Usage: andeo source merge --head BRANCH --title TITLE --idempotency-key KEY [--dry-run] [--wait] [--timeout-seconds N] [--json]\n andeo source merge --change scr_... --idempotency-key KEY [--wait] [--json]\n andeo source merge --head BRANCH --title TITLE --validation-mode administrator_authorized --expected-base SHA --expected-head SHA --expected-policy-revision N --authorize --idempotency-key KEY [--continuation source_only] [--note TEXT] [--wait] [--json]\n andeo source merge <status|resume|cancel|take-over> --merge smi_... [options]\n\nRequest exact fast-forward landing. Persistent agents require source.merge for the assigned branch and review.prepare for implicit review creation. The grant delegates source approval without per-change administrator approval; a successful exact isolated preview is required. Landing may deploy under the saved publication policy. Human/legacy native review keeps its existing approval contract. Administrator-authorized source-only mode requires saved policy and a current administrator; Andeo does not independently verify checks. Inspect refs and blockers with --dry-run before authorizing. Waiting is bounded and never cancels hosted work.\n\nExamples:\n andeo source merge --head feature/copy --title \"Update copy\" --idempotency-key account-copy-v1 --dry-run --json\n andeo source merge --head feature/copy --title \"Update copy\" --idempotency-key account-copy-v1 --wait --json",
@@ -3283,7 +3347,8 @@ Account workflow entitlement is required for new starts. Run status is authorita
3283
3347
  "source change resume": "Usage: andeo source change resume --change scr_... [--json]\n\nResume the same eligible merge intent or exact failed publication. Revalidates authority and retained lineage; never creates a replacement build.\n\nExample:\n andeo source change resume --change scr_... --json",
3284
3348
  "source merge-policy show": "Usage: andeo source merge-policy show [--json]\n\nRead the saved merge policy and explicit principal grants.",
3285
3349
  "source merge-policy set": "Usage: andeo source merge-policy set --mode human-review|agent|administrator-authorized [--principals PRINCIPAL_IDS] --expected-revision N --idempotency-key KEY [--json]\n\nAdministrator only. Agent grants are comma-separated stable principal IDs. Administrator-authorized mode requires controlled transport, source-only continuation and exact per-operation approval; omit --principals. This never changes publication policy.\n\nExample:\n andeo source merge-policy set --mode agent --principals principal_example --expected-revision 0 --idempotency-key merge-policy-v1 --json",
3286
- "source change create": "Usage: andeo source change create --head BRANCH --title TITLE [--description TEXT] [--base BRANCH] [--json]\n\nOpen or refresh the review for the exact protected-base and feature-branch SHAs. An existing open review keeps its ID and number; changed refs create a new snapshot and invalidate prior approval. Unchanged refs are a no-op. A landing review cannot be refreshed.",
3350
+ "source change create": "Usage: andeo source change create --head BRANCH --title TITLE [--description TEXT] [--base BRANCH] [--json]\n\nOpen or refresh the review for the exact protected-base and feature-branch SHAs. A refresh keeps the ID, number, title, and description. Changed refs create a new snapshot and invalidate prior approval. A landing review cannot be refreshed. Use source change edit to correct the title or description.",
3351
+ "source change edit": "Usage: andeo source change edit --change scr_... --expected-snapshot N [--title TITLE] [--description TEXT] [--json]\n\nEdit an open review's title or description. Read snapshotVersion with source change show first. Supply at least one field. Use --description '' to clear the description. A metadata change creates a new snapshot, preserves the ID, number, and exact preview, and requires fresh approval if previously approved.\n\nExample:\n andeo source change edit --change scr_... --expected-snapshot 3 --title \"Update account copy\" --json",
3287
3352
  "source change list": "Usage: andeo source change list [--state open|closed|all] [--json]\n\nList reviewed source changes for this exact linked project.",
3288
3353
  "source change show": "Usage: andeo source change show --change scr_... [--json]\n\nRead exact snapshot, preview, decision, and landing state.",
3289
3354
  "source change close": "Usage: andeo source change close --change scr_... [--json]\n\nClose an unlanded change without changing source or production.",
@@ -3316,7 +3381,7 @@ Account workflow entitlement is required for new starts. Run status is authorita
3316
3381
  };
3317
3382
  if (topic && topics[topic])
3318
3383
  return topics[topic];
3319
- return `Andeo merchant developer CLI ${CLI_VERSION}\n\nCommands:\n docs Read version-matched offline guides\n capabilities Inspect scoped support, enablement and permissions\n init Create a new Shopify account starter\n auth login Create or refresh the default login\n auth create Create or re-authorize a named login\n auth activate Bind a named login to a directory tree\n auth deactivate Remove an exact directory binding\n auth status Validate one login or scoped credential\n auth list List local login profiles and bindings\n auth delete Revoke one named login\n auth logout Revoke the default or every login\n agents Human administration of persistent agents\n agent Inspect or end this Cloud task's run\n link Link this checkout to one permitted project\n doctor Check developer readiness\n dev Run the project-owned local dev command\n check Run project validation\n build Package and verify a portable artifact\n upload Retain a build for administrator publication\n preview Build and deploy an exact preview\n preview entries List eligible connected entry apps\n preview open Reopen an exact deployed preview\n source status Inspect Andeo-managed Git and recent builds\n source branches List exact managed branches and default policy\n source compare Compare two managed branches\n source connect Connect this linked project to managed Git\n source reconnect Prepare, inspect, complete or cancel a tenant namespace cutover\n source pull Clone or fast-forward the exact connected repository\n source token Issue a short-lived repository credential\n source push Push the exact commit without persisting a token\n source promote Fast-forward the default after successful preview checks\n source history Run guarded, archived source-history migration\n email Create and reuse merchant email identities\n workflows Inspect and control app-defined background runs\n vars Manage saved per-environment runtime variables\n source policy Inspect or change automatic publication\n tail Stream logs for one exact linked project\n delivery status Read preview workflow state\n delivery retry Retry a failed preview workflow\n upgrade Upgrade a verified global CLI installation\n config autoupgrade Configure automatic CLI upgrades\n skill install Install the Andeo agent skill\n skill status Inspect installed guidance freshness\n skill sync Refresh unchanged managed guidance\n skills list Discover authenticated practice skills\n skills get Read an authenticated practice skill\n skills file Read one authenticated skill resource\n config example Print the project configuration contract\n\nThere is intentionally no production publish command.\nRun andeo <command> --help for examples.`;
3384
+ return `Andeo merchant developer CLI ${CLI_VERSION}\n\nCommands:\n docs Read version-matched offline guides\n capabilities Inspect scoped support, enablement and permissions\n feedback Send feedback to the Andeo team\n init Create a new Shopify account starter\n auth login Create or refresh the default login\n auth create Create or re-authorize a named login\n auth activate Bind a named login to a directory tree\n auth deactivate Remove an exact directory binding\n auth status Validate one login or scoped credential\n auth list List local login profiles and bindings\n auth delete Revoke one named login\n auth logout Revoke the default or every login\n agents Human administration of persistent agents\n agent Inspect or end this Cloud task's run\n link Link this checkout to one permitted project\n doctor Check developer readiness\n dev Run the project-owned local dev command\n check Run project validation\n build Package and verify a portable artifact\n upload Retain a build for administrator publication\n preview Build and deploy an exact preview\n preview entries List eligible connected entry apps\n preview open Reopen an exact deployed preview\n source status Inspect Andeo-managed Git and recent builds\n source branches List exact managed branches and default policy\n source compare Compare two managed branches\n source connect Connect this linked project to managed Git\n source reconnect Prepare, inspect, complete or cancel a tenant namespace cutover\n source pull Clone or fast-forward the exact connected repository\n source token Issue a short-lived repository credential\n source push Push the exact commit without persisting a token\n source promote Fast-forward the default after successful preview checks\n source history Run guarded, archived source-history migration\n email Create and reuse merchant email identities\n workflows Inspect and control app-defined background runs\n vars Manage saved per-environment runtime variables\n source policy Inspect or change automatic publication\n tail Stream logs for one exact linked project\n delivery status Read preview workflow state\n delivery retry Retry a failed preview workflow\n upgrade Upgrade a verified global CLI installation\n config autoupgrade Configure automatic CLI upgrades\n skill install Install the Andeo agent skill\n skill status Inspect installed guidance freshness\n skill sync Refresh unchanged managed guidance\n skills list Discover authenticated practice skills\n skills get Read an authenticated practice skill\n skills file Read one authenticated skill resource\n config example Print the project configuration contract\n\nThere is intentionally no production publish command.\nRun andeo <command> --help for examples.`;
3320
3385
  }
3321
3386
  function normalizeError(error) {
3322
3387
  if (error instanceof FlagCompatibilityError)