Skip to content

TRAC-137: Add native hosting option in catalyst CLI#3003

Open
jordanarldt wants to merge 1 commit intoalphafrom
feat/trac-137-catalyst-cli
Open

TRAC-137: Add native hosting option in catalyst CLI#3003
jordanarldt wants to merge 1 commit intoalphafrom
feat/trac-137-catalyst-cli

Conversation

@jordanarldt
Copy link
Copy Markdown
Contributor

@jordanarldt jordanarldt commented May 4, 2026

Jira: LTRAC-137

What/Why?

Following review of #2995, the team agreed that hosting/deploy concerns belong in catalyst (the CLI), not create-catalyst (the scaffolder). Since the broader plan is to absorb create-catalyst into catalyst anyway, this PR ports the work directly into packages/catalyst as a new catalyst create command, plus a few related improvements that fell out of building on that foundation.

catalyst create

New command. Scaffold-only by default — no interactive hosting prompt, since most users will reach Commerce Hosting via catalyst deploy. --hosting commerce opts into the full Commerce Hosting setup eagerly (proxy → middleware swap, OpenNext dep, .bigcommerce/project.json, core/.env.local symlink). Reuses the existing catalyst auth device flow.

setupCoreProject runs unconditionally at create time, wiring catalyst build / catalyst start / catalyst deploy scripts and the @bigcommerce/catalyst dep into core/package.json regardless of hosting choice — the polymorphic dispatcher (below) makes this safe for self-hosted projects too.

Polymorphic catalyst build / catalyst start

Both commands dispatch via lib/project-state.ts. Untransformed projects fall through to pnpm exec next build / next start; transformed projects run the OpenNext pipeline. Lets the create-time scripts work end-to-end whether or not the user opts into Commerce Hosting.

Shared lib/commerce-hosting.ts

Setup logic from #2995 extracted into a reusable module: setupCommerceHosting, promptForCommerceHostingProject, selectOrCreateInfrastructureProject, runCommerceHostingSetup, plus a NoLinkedProjectError sentinel for graceful decline handling. selectOrCreateInfrastructureProject is shared between catalyst project link and catalyst deploy, decorating the matching project with green [linked] and skipping the select prompt entirely on empty stores.

catalyst project link / list

list and link's select prompt now mark the currently linked project with green [linked]. After a successful link, link offers to run Commerce Hosting setup if the project isn't already transformed.

catalyst deploy

Verifies the linked project still exists on the store before any build/upload work. If missing or 404, falls through to selectOrCreateInfrastructureProject. Includes a transformation guard that prompts for Commerce Hosting setup when the project isn't transformed. Graceful info + exit on user decline.

Misc / quality

  • No more .bigcommerce/ cwd pollution. Telemetry moved to a user-scoped Conf (lives in OS config dir under catalyst-cli/); project state checks moved to a read-only getProjectState() helper that doesn't instantiate Conf.
  • Wired core scripts. core/package.json always gets build: "npm run generate && catalyst build" / start: "catalyst start" / deploy: "npm run generate && catalyst deploy".
  • Canonical package.json field order (lib/sort-package-json.ts) applied whenever we mutate a package.json.
  • Shared option helpers in lib/shared-options.ts now used across project, create, deploy (each helper accepts an optional description override).
  • Consistent HTTP layer. Removed lib/https.ts (stateful client class) and lib/user-agent.ts. All API code in lib/ (project.ts, channels.ts, localization.ts) now follows the same pattern: positional (...data, storeHash, accessToken, host) args, schemas + parsing internal to the lib, throws on bad responses. lib/channels.ts now owns all channel-related schemas/types (previously scattered across commands/create.ts).
  • --env and --channel-id validate at parse time. Custom argParsers throw InvalidArgumentError on malformed input; values containing = in --env are preserved.
  • buildWorkspacePackages runs after installDependencies at create time when the cloned repo is the catalyst monorepo (core/, packages/catalyst, packages/client all present), so core can resolve workspace deps.

Testing

228 unit tests, all passing. New: commands/create.spec.ts (12 tests covering happy paths, parser validation, ordering invariants, failure handling, --hosting commerce precondition), lib/project-state.spec.ts, lib/setup-core-project.spec.ts, lib/sort-package-json.spec.ts. Extended: commerce-hosting, project, deploy, build, start specs.

pnpm --filter @bigcommerce/catalyst test, typecheck, lint, and build all clean.

Manually verified the major paths against a real store: catalyst create (interactive, --hosting commerce, --hosting self-hosted), catalyst project link / list with [linked] markers, catalyst deploy first-run transformation prompt, catalyst deploy against a deleted project (re-link prompt + graceful decline).

Proof of life

catalyst_create.mov
catalyst_deploy.mov

Migration

packages/create-catalyst is not modified in this PR — the staged #2995 changes there were reverted. A follow-up PR will update create-catalyst create to shim into catalyst create so pnpm create @bigcommerce/catalyst keeps working.

External behavior changes:

  • BIGCOMMERCE_STOREFRONT_API_TOKEN env var (only ever written by the create flow, never read by the storefront) is now correctly BIGCOMMERCE_STOREFRONT_TOKEN.
  • The catalyst-CLI no longer sets a custom User-Agent header on requests to the cli-api gateway or BC store API. Server-side telemetry that buckets on catalyst-cli/... UA will see the Node default UA instead.

🤖 Generated with Claude Code

@vercel
Copy link
Copy Markdown

vercel Bot commented May 4, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
catalyst Ready Ready Preview, Comment May 5, 2026 4:36pm

Request Review

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 4, 2026

⚠️ No Changeset found

Latest commit: e4ae60e

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 4, 2026

Bundle Size Report

Comparing against baseline from ec92930 (2026-05-05).

No bundle size changes detected.

@jordanarldt jordanarldt force-pushed the feat/trac-137-catalyst-cli branch from 67f5265 to 8e3e01f Compare May 4, 2026 21:38
@jordanarldt jordanarldt force-pushed the feat/trac-137-catalyst-cli branch from 8e3e01f to e13fec9 Compare May 4, 2026 21:47
@jordanarldt jordanarldt marked this pull request as ready for review May 5, 2026 14:52
@jordanarldt jordanarldt requested a review from a team as a code owner May 5, 2026 14:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant