← commercetoolsCONTENT HISTORY

Update to commercetools

Snapshot Nov 9, 2026 · 12:08 UTC · version 0.69.0

Collection source: downloaded plugin package.

WHAT CHANGED

First saved snapshot

No earlier snapshot is available to establish a change.

Save commercetools and check future changes in Following.

Up to 3 plugins free · no card required.

Compare saved observations

Download comparison JSON
Full technical diff · 0 changed fields
Full snapshot data
{
  "description": "Create a Merchant Center Custom Application and get it into the main nav: asks for your details in chat, scaffolds the app in its own git repo, deploys it to a host such as Vercel, registers it, installs it in the Organizations you choose (all projects or an allowlist), and opens the app. Use when the user wants a custom app or nav item, or it only works on localhost. Not for Custom Views, or for Connect service, event and job connectors (see commercetools-connect).",
  "included_files": [
    {
      "relative_path": "references/headless.md",
      "size_in_bytes": 7019
    },
    {
      "relative_path": "references/hosting/cloudflare.md",
      "size_in_bytes": 3026
    },
    {
      "relative_path": "references/hosting/connect.md",
      "size_in_bytes": 5445
    },
    {
      "relative_path": "references/hosting/netlify.md",
      "size_in_bytes": 3130
    },
    {
      "relative_path": "references/hosting/other.md",
      "size_in_bytes": 2570
    },
    {
      "relative_path": "references/hosting/surge.md",
      "size_in_bytes": 893
    },
    {
      "relative_path": "references/hosting/vercel.md",
      "size_in_bytes": 5095
    },
    {
      "relative_path": "references/manual-steps.md",
      "size_in_bytes": 11697
    },
    {
      "relative_path": "scripts/allow-builds.mjs",
      "size_in_bytes": 2223
    },
    {
      "relative_path": "scripts/docs-search.mjs",
      "size_in_bytes": 26516
    },
    {
      "relative_path": "scripts/headless.mjs",
      "size_in_bytes": 13688
    },
    {
      "relative_path": "scripts/install-plan.mjs",
      "size_in_bytes": 14976
    },
    {
      "relative_path": "scripts/intake.mjs",
      "size_in_bytes": 1453
    },
    {
      "relative_path": "scripts/lib/app-facts.mjs",
      "size_in_bytes": 1075
    },
    {
      "relative_path": "scripts/lib/cli-help.mjs",
      "size_in_bytes": 1795
    },
    {
      "relative_path": "scripts/lib/connect-api.mjs",
      "size_in_bytes": 3354
    },
    {
      "relative_path": "scripts/lib/credentials.mjs",
      "size_in_bytes": 1119
    },
    {
      "relative_path": "scripts/lib/drive.mjs",
      "size_in_bytes": 1209
    },
    {
      "relative_path": "scripts/lib/form.mjs",
      "size_in_bytes": 4117
    },
    {
      "relative_path": "scripts/lib/headless.mjs",
      "size_in_bytes": 5688
    },
    {
      "relative_path": "scripts/lib/hints.mjs",
      "size_in_bytes": 1102
    },
    {
      "relative_path": "scripts/lib/host-check.mjs",
      "size_in_bytes": 1234
    },
    {
      "relative_path": "scripts/lib/host-fetch.mjs",
      "size_in_bytes": 1797
    },
    {
      "relative_path": "scripts/lib/hosting.mjs",
      "size_in_bytes": 1713
    },
    {
      "relative_path": "scripts/lib/identity.mjs",
      "size_in_bytes": 750
    },
    {
      "relative_path": "scripts/lib/input-box.mjs",
      "size_in_bytes": 1465
    },
    {
      "relative_path": "scripts/lib/install-plan.mjs",
      "size_in_bytes": 4777
    },
    {
      "relative_path": "scripts/lib/install-tree.mjs",
      "size_in_bytes": 7771
    },
    {
      "relative_path": "scripts/lib/intake.mjs",
      "size_in_bytes": 4918
    },
    {
      "relative_path": "scripts/lib/layout.mjs",
      "size_in_bytes": 1365
    },
    {
      "relative_path": "scripts/lib/onboard-steps.mjs",
      "size_in_bytes": 14233
    },
    {
      "relative_path": "scripts/lib/open-browser.mjs",
      "size_in_bytes": 505
    },
    {
      "relative_path": "scripts/lib/paint.mjs",
      "size_in_bytes": 925
    },
    {
      "relative_path": "scripts/lib/patch-config.mjs",
      "size_in_bytes": 1767
    },
    {
      "relative_path": "scripts/lib/picker-text.mjs",
      "size_in_bytes": 661
    },
    {
      "relative_path": "scripts/lib/plan.mjs",
      "size_in_bytes": 3583
    },
    {
      "relative_path": "scripts/lib/pnpm-builds.mjs",
      "size_in_bytes": 1750
    },
    {
      "relative_path": "scripts/lib/port.mjs",
      "size_in_bytes": 897
    },
    {
      "relative_path": "scripts/lib/providers/cloudflare.mjs",
      "size_in_bytes": 4886
    },
    {
      "relative_path": "scripts/lib/providers/connect.mjs",
      "size_in_bytes": 12668
    },
    {
      "relative_path": "scripts/lib/providers/index.mjs",
      "size_in_bytes": 701
    },
    {
      "relative_path": "scripts/lib/providers/netlify.mjs",
      "size_in_bytes": 5432
    },
    {
      "relative_path": "scripts/lib/providers/vercel.mjs",
      "size_in_bytes": 5479
    },
    {
      "relative_path": "scripts/lib/real-deps.mjs",
      "size_in_bytes": 6626
    },
    {
      "relative_path": "scripts/lib/redact.mjs",
      "size_in_bytes": 746
    },
    {
      "relative_path": "scripts/lib/review.mjs",
      "size_in_bytes": 5800
    },
    {
      "relative_path": "scripts/lib/session-view.mjs",
      "size_in_bytes": 6564
    },
    {
      "relative_path": "scripts/lib/session.mjs",
      "size_in_bytes": 3467
    },
    {
      "relative_path": "scripts/lib/settings-api.mjs",
      "size_in_bytes": 4541
    },
    {
      "relative_path": "scripts/lib/style.mjs",
      "size_in_bytes": 1443
    },
    {
      "relative_path": "scripts/lib/validate.mjs",
      "size_in_bytes": 1788
    },
    {
      "relative_path": "scripts/lib/vercel.mjs",
      "size_in_bytes": 3131
    },
    {
      "relative_path": "scripts/onboard.mjs",
      "size_in_bytes": 24887
    },
    {
      "relative_path": "scripts/patch-config.mjs",
      "size_in_bytes": 1248
    },
    {
      "relative_path": "scripts/preflight.mjs",
      "size_in_bytes": 2606
    },
    {
      "relative_path": "scripts/register.mjs",
      "size_in_bytes": 12226
    },
    {
      "relative_path": "scripts/validate-queries.mjs",
      "size_in_bytes": 1467
    },
    {
      "relative_path": "scripts/verify.mjs",
      "size_in_bytes": 2592
    },
    {
      "relative_path": "tests/app-facts.test.mjs",
      "size_in_bytes": 2143
    },
    {
      "relative_path": "tests/cli-help.test.mjs",
      "size_in_bytes": 3431
    },
    {
      "relative_path": "tests/connect-api.test.mjs",
      "size_in_bytes": 5903
    },
    {
      "relative_path": "tests/credentials.test.mjs",
      "size_in_bytes": 2166
    },
    {
      "relative_path": "tests/drive.test.mjs",
      "size_in_bytes": 2284
    },
    {
      "relative_path": "tests/fixtures/empty.json",
      "size_in_bytes": 3
    },
    {
      "relative_path": "tests/fixtures/headless-signin.json",
      "size_in_bytes": 354
    },
    {
      "relative_path": "tests/form.test.mjs",
      "size_in_bytes": 6169
    },
    {
      "relative_path": "tests/headless-cli.test.mjs",
      "size_in_bytes": 3252
    },
    {
      "relative_path": "tests/headless.test.mjs",
      "size_in_bytes": 10167
    },
    {
      "relative_path": "tests/hints.test.mjs",
      "size_in_bytes": 2436
    },
    {
      "relative_path": "tests/host-check.test.mjs",
      "size_in_bytes": 1545
    },
    {
      "relative_path": "tests/host-fetch.test.mjs",
      "size_in_bytes": 3263
    },
    {
      "relative_path": "tests/hosting.test.mjs",
      "size_in_bytes": 1970
    },
    {
      "relative_path": "tests/identity.test.mjs",
      "size_in_bytes": 2050
    },
    {
      "relative_path": "tests/input-box.test.mjs",
      "size_in_bytes": 2113
    },
    {
      "relative_path": "tests/install-plan.test.mjs",
      "size_in_bytes": 6659
    },
    {
      "relative_path": "tests/install-tree.test.mjs",
      "size_in_bytes": 17260
    },
    {
      "relative_path": "tests/intake.test.mjs",
      "size_in_bytes": 3299
    },
    {
      "relative_path": "tests/layout.test.mjs",
      "size_in_bytes": 2177
    },
    {
      "relative_path": "tests/machine.mjs",
      "size_in_bytes": 2159
    },
    {
      "relative_path": "tests/onboard-steps.test.mjs",
      "size_in_bytes": 39725
    },
    {
      "relative_path": "tests/paint.test.mjs",
      "size_in_bytes": 1814
    },
    {
      "relative_path": "tests/patch-config.test.mjs",
      "size_in_bytes": 2383
    },
    {
      "relative_path": "tests/picker-text.test.mjs",
      "size_in_bytes": 1843
    },
    {
      "relative_path": "tests/plan.test.mjs",
      "size_in_bytes": 5596
    },
    {
      "relative_path": "tests/pnpm-builds.test.mjs",
      "size_in_bytes": 2071
    },
    {
      "relative_path": "tests/port.test.mjs",
      "size_in_bytes": 951
    },
    {
      "relative_path": "tests/provider-cloudflare.test.mjs",
      "size_in_bytes": 7680
    },
    {
      "relative_path": "tests/provider-connect.test.mjs",
      "size_in_bytes": 17054
    },
    {
      "relative_path": "tests/provider-netlify.test.mjs",
      "size_in_bytes": 8568
    },
    {
      "relative_path": "tests/providers.test.mjs",
      "size_in_bytes": 1247
    },
    {
      "relative_path": "tests/redact.test.mjs",
      "size_in_bytes": 1027
    },
    {
      "relative_path": "tests/review.test.mjs",
      "size_in_bytes": 9618
    },
    {
      "relative_path": "tests/session-view.test.mjs",
      "size_in_bytes": 11698
    },
    {
      "relative_path": "tests/session.test.mjs",
      "size_in_bytes": 8090
    },
    {
      "relative_path": "tests/settings-api.test.mjs",
      "size_in_bytes": 5783
    },
    {
      "relative_path": "tests/skill-flow.test.mjs",
      "size_in_bytes": 12362
    },
    {
      "relative_path": "tests/style.test.mjs",
      "size_in_bytes": 2425
    },
    {
      "relative_path": "tests/validate.test.mjs",
      "size_in_bytes": 1682
    },
    {
      "relative_path": "tests/vercel.test.mjs",
      "size_in_bytes": 7010
    },
    {
      "relative_path": "tests/verify-cli.test.mjs",
      "size_in_bytes": 2281
    }
  ],
  "name": "commercetools-custom-application",
  "skill_md_contents": "---\nname: commercetools-custom-application\ndescription: \"Create a Merchant Center Custom Application and get it into the main nav: asks for your details in chat, scaffolds the app in its own git repo, deploys it to a host such as Vercel, registers it, installs it in the Organizations you choose (all projects or an allowlist), and opens the app. Use when the user wants a custom app or nav item, or it only works on localhost. Not for Custom Views, or for Connect service, event and job connectors (see commercetools-connect).\"\nwhen_to_use:\n  - \"Creating a new Merchant Center Custom Application and getting it into the main nav of a Project\"\n  - \"Registering, deploying, or installing an existing custom app built with create-mc-app\"\n  - \"A custom app that works on localhost but is not showing up in the Merchant Center menu\"\n  - \"Installing a custom app into several Organizations, all projects or a project allowlist for each\"\nmetadata:\n  contentType: SKILL\n  area:\n    - Foundations\n  docsSearch:\n    products:\n      - Composable Commerce\n---\n\n# Merchant Center Custom Application, zero to nav\n\nEnd state: a Custom Application on a static host, registered in the user's Organization, Ready, installed in every Organization the user chose (all projects, or an allowlist per Organization), and in those Projects' main menu.\n\nAssumed: the user has a commercetools Project and is in the `Administrators` Team of an Organization. \"Nothing configured\" means no custom app yet, not no account. No Project: stop and say so.\n\n## How this skill works\n\nThe procedure lives in `scripts/`, not here. Registration is a dozen order-dependent calls, and its failures (wrong `applicationId` in the build, URL mismatch, Draft state) show up far from their cause. So the scripts read the real Merchant Center state, pick the next step, and act. A rerun after any interruption resumes. Your job: gather inputs, run the scripts in order, and handle what scripts cannot: the email click and, with deployment help off, the deploy.\n\nEvery script prints JSON. Read `ok`, `error`, `stoppedAt`, and `checks[].detail`; never assume a step worked. Run them as `node <skill-dir>/scripts/<name>.mjs`.\n\nThe scripts carry the procedure; the Merchant Center facts around it (what an `entryPointUriPath` may be, which permissions a Team needs, what a host must do) come from the documentation, so:\n\n1. <!-- ct:docs-search:begin -->\n   **Docs search (required, run first)** — The first time you use this skill in a session you must run this before answering. It gathers the latest verified documentation as your primary grounding, filtered to the products this skill covers. Use this script for documentation search while working with this skill; the Knowledge MCP covers everything else. Always confirm details against retrieved documentation rather than the skill text alone:\n\n   ```bash\n   node \"<this skill's directory>/scripts/docs-search.mjs\" \\\n     --query \"Merchant Center Custom Application <the user's situation: register, deploy, install, permissions, host>\" \\\n     --app-name \"<host app: claude-code, claude-chat, cursor, codex, copilot — or the host's own name>\" \\\n     --model \"<current-model>\" \\\n     --commercetools-project-key \"<if known>\" \\\n     --commercetools-region \"<if known>\" \\\n     --limit 5\n   ```\n\n   Pass the commercetools project key and region (as in `api.{region}.commercetools.com`) only if already in your context; otherwise omit both. Never search files or ask the user for them.\n   <!-- ct:docs-search:end -->\n\n2. Then run Step 0. Headless is the only route, always, whether or not the user has a terminal. The manual steps are for redoing one piece by hand, or for when you cannot run commands.\n\n## Step 0: run headless (the whole flow, from nothing)\n\nHeadless is the only route. You run `headless.mjs` and the user answers in chat, whether or not they have a terminal. Do not offer or run `onboard.mjs`. The protocol (exit codes, the plan file shape, what each step may ask for) is in [headless.md](./references/headless.md); read it first.\n\nStart by asking the user for the form data. Nothing touches their account until they have answered it and confirmed the last screen, and no answer is filled in for them. Two runs download and execute code, and each needs its own yes: the sign-in in step 2 and the work in step 4.\n\n1. Ask the user for the app name first: the entry path, menu label and folder default from it. Then get the questions with `node <skill-dir>/scripts/intake.mjs form --app-name <name> --email <email>` and ask them as written: region, project key, entry path, menu label, contact email, folder, language, hosting. Ask the deployment help question too (`--deploy-help on|off`, below). Validate the answers with `intake.mjs check --answers <file>`.\n2. Run `scripts/headless.mjs` with the answers as flags. It checks the tools and runs the Merchant Center sign-in. With no valid session, the sign-in downloads and runs the `@commercetools-frontend/mc-scripts` login from npm with `npx`, so first show that and get the user's yes: it prints `[session] https://...` on stderr and waits for the credentials file, so run it where you can read stderr and give the user that URL (exit 3 means it gave up waiting: rerun for a fresh URL). It then exits 4 with a `needs` object listing the Organizations and their projects. This is the Organization picker: ask which Organizations, and all projects or an allowlist for each, write the plan file (`installPlan`), and rerun with `--install-plan <file>`.\n3. Exit 0 with `stage: \"review\"` prints the review: the app's facts, the install targets, the owner Organization and the deployment help setting. Show it whole, and say plainly that the yes covers everything step 4 does: running the `create-mc-app` launcher, installing dependencies, `git init`, creating or linking the host project and deploying (with Connect: a GitHub push and a private Connector published and deployed), and registering and installing in the Merchant Center. Get an explicit yes. With several Organizations it exits 4 with `needs.ctx` `orgId`: ask which one owns the app, rerun with `--org-id <id>`. Nothing in the account changes before the yes.\n4. Rerun with `--confirmed`. Do not pass it before the yes. The work, with live progress on stderr: create the app (`create-mc-app`), `git init -b main` in the app folder (the repository root with Connect) with `.mc-onboarding/` gitignored, install dependencies and build, register in Draft (the verification email: ask the user to click it, and rerun after exit 3), deploy, host check, finish registration (Ready, installed everywhere chosen), open the browser. The host check polls on its own while the deploy propagates; a 401/403 or a certificate this machine cannot verify fails at once with what to do. A rerun resumes where it stopped. A step that needs a value the user must give (a team, a token, the production URL) exits 4 with `needs` (`ctx`, `label`, `options` or `env`): ask, then rerun with `--set <ctx>=<value>`, `--production-url <url>`, or the variable named in `needs.env` (tokens and secrets go in the environment only). The provider files under `references/hosting/` say what each host asks and runs.\n\nDeployment help on (the default for Vercel, Netlify, Cloudflare Pages and Connect) creates or links the site, builds locally and deploys, or for Connect pushes a tagged GitHub repository and publishes and deploys a private Connector; for Connect the folder named in the form is the repository root and the app is created one level down. Off, the user deploys and you pass the production URL.\n\n- `--deploy-help on|off` sets deployment help; ask, do not default it.\n- `--app-dir <dir>` pointing at an existing app skips creating it and resumes from wherever things stand; repeat `--hosting`, `--deploy-help` and `--org-id`, which are not stored.\n- Every command's output goes to `<app-dir>/.mc-onboarding/session.log`; `--help` lists every option.\n\nDo not answer the form or choose Organizations, the owner, or the deployment toggle for the user, and do not answer a `needs` for the user.\n\n## When to use the manual steps\n\nThe same work exists as seven separate commands in [manual-steps.md](./references/manual-steps.md): inputs, preflight, scaffold, install targets and registration, deploy, finish, verify. Read it when one piece must be redone by hand, or when you cannot run commands at all and the user runs each one. Otherwise run Step 0. Hosting is a contract, not a provider: [hosting/other.md](./references/hosting/other.md) states it, and the provider files say how Vercel, Netlify, Cloudflare Pages, Surge and Connect meet it.\n\n## Failure reading\n\n| Symptom | Cause | Fix |\n| --- | --- | --- |\n| App page reloads forever | `entryPointUriPath` in the Merchant Center differs from the config, or `applicationId` is wrong in the build ([proxy router](https://docs.commercetools.com/merchant-center-customizations/concepts/merchant-center-proxy-router.md)) | Compare `window.app.entryPointUriPath` in devtools with the URL; rebuild with the right `applicationId`. |\n| `FORBIDDEN` from the settings API | User is not in `Administrators` for the Organization | Add them, or use an Organization where they are. |\n| Blank page after install | Host does not rewrite all paths to `index.html` | Run `scripts/verify.mjs`; it says when the rewrite is missing. The rule per provider is in `references/hosting/`. |\n| Works on `localhost` but not in the nav | Local dev bypasses registration | Check Ready state and install with `register.mjs`, then Step 7 of the manual steps. |\n| Installed but not in the nav | Non-admins need the app's View permission on their Team | [Grant it on the Team](https://docs.commercetools.com/merchant-center/managing-custom-applications.md#assign-team-permissions). Admins see it at once. |\n| `register.mjs` stops at `INSTALL_MISMATCH` | The app is installed in that Organization in the other mode (all projects vs allowlist) | The user switches the mode in the Merchant Center ([Update Projects access](https://docs.commercetools.com/merchant-center/managing-custom-applications.md#update-projects-access)) or uninstalls and reruns. Team permissions may need granting again after a reinstall, so ask first. |\n| `register.mjs` reports \"No progress\" | An action ran but state did not change | Inspect the state of the step named in the error. Do not loop. |\n\n## Checklist\n\n- [ ] The user has a Project and is in the `Administrators` Team of the owner Organization\n- [ ] Every input came from the user: no guessed Organizations, owner, project key, hosting, or deployment toggle\n- [ ] The headless run ended with the app Ready (exit 0 with `productionUrl` and `opened`), or manual Steps 1 to 6 ended with `done: true` from `register.mjs`\n- [ ] The app folder is its own git repository (`git init -b main` ran there; the folder has a `.git`)\n- [ ] `scripts/verify.mjs` passed against the production URL (the app path and a deeper path both answer 200)\n- [ ] The app was seen in the main nav of a deployed Project, or the user confirmed it and the report says the nav was not seen\n- [ ] The config change (`applicationId`, `url`) is committed so the next deploy matches what is registered\n"
}

SHA-256 of public snapshot: cd33af60824b4bb026b2ba62f2cf1d9a3dec28df70dcd92c88e4519d5a513906