Skip to content

feat(cli): strict config + integration v1 schema and /integration export#3261

Merged
ejhammond merged 1 commit into
xds-unprefix-integrationfrom
astryx/config-integration-foundation
Jun 30, 2026
Merged

feat(cli): strict config + integration v1 schema and /integration export#3261
ejhammond merged 1 commit into
xds-unprefix-integrationfrom
astryx/config-integration-foundation

Conversation

@ejhammond

Copy link
Copy Markdown
Contributor

Replaces the loose/passthrough config and integration API with a locked, strict v1 surface. This is a clean breaking change — the prior config/integration API was not in real use (no real astryx.config.* files or integration packages exist), so there is no migration path to preserve.

Config (@astryxdesign/cli/config)

AstryxConfig is now exactly:

interface AstryxConfig {
  integrations?: string[];
  issuesUrl?: string;
  hooks?: { postCodemod?: PostCodemodHook[] };
}

Validated by a strict Zod schema — unknown keys are hard errors, issuesUrl must be a URL, and integrations must be an array of strings. createConfig stays on @astryxdesign/cli/config.

Integration (@astryxdesign/cli/integration)

New subpath export. AstryxIntegration is now:

interface AstryxIntegration {
  components?: string;
  templates?: string;
  codemods?: string;
  issuesUrl?: string;
}

createIntegration moves out of config.mjs into its own module behind the new /integration export. Also strict.

Package-only resolution + sibling config loading

  • Integrations resolve by package name only. Each package declares a single conventional root manifest — astryx.integration.{ts,mjs,js} — sibling to its package.json (multiple present is an error, missing is an error). Identity (name/version) comes from package.json, not the manifest. Contribution roots (components/templates/codemods) are normalized to absolute paths.
  • App config loads from astryx.config.{ts,mjs,js} sibling to the nearest package.json (no upward closest-config walk). Multiple configs at that root is an error; a missing config yields an empty config. .ts config/manifests load via jiti.

Post-codemod hooks

Hooks now come from app config (hooks.postCodemod) rather than integrations. Each hook's buildCommand({ packageDir, files }) returns a command run via execFile: dry-run previews only, apply executes in order and fails the upgrade on a nonzero exit (or a buildCommand throw). Hooks are skipped entirely when no files changed.

Folded out the now-unused surfaces: packages/gapReport/template.get config, integration name/version/displayName/description/docs/category/blocks/postCodemod, AstryxIntegrationCodemod, the old AstryxPostCodemodContext, the template get command and its template.get response type, and the ERR_TEMPLATE_CONFIG/ERR_TEMPLATE_GET codes.

File-based codemod discovery, static templates, the validate-integration command, component ownership, and swizzle config-routing are deliberately left for follow-up changes.

@vercel

vercel Bot commented Jun 30, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
astryx Ready Ready Preview, Comment Jun 30, 2026 12:57am

Request Review

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Meta Open Source bot. label Jun 30, 2026
@ejhammond ejhammond changed the base branch from astryx/remove-gap-report to xds-unprefix-integration June 30, 2026 00:51
Replace the loose passthrough config and integration API with a locked,
strict v1 surface.

AstryxConfig is now { integrations?: string[]; issuesUrl?: string;
hooks?: { postCodemod?: PostCodemodHook[] } } and validates with a strict
Zod schema — unknown keys are hard errors. AstryxIntegration is now
{ components?; templates?; codemods?; issuesUrl? }, also strict.

- New @astryxdesign/cli/integration subpath export with createIntegration;
  createConfig stays on @astryxdesign/cli/config.
- Integrations resolve by package name only. Each package declares a single
  conventional root manifest (astryx.integration.{ts,mjs,js}) sibling to its
  package.json; identity (name/version) comes from package.json. .ts manifests
  load via jiti.
- App config loads from astryx.config.{ts,mjs,js} sibling to the nearest
  package.json (no upward closest-config walk); multiple configs is an error,
  missing yields an empty config.
- Post-codemod hooks now come from app config (hooks.postCodemod) and run via
  execFile; dry-run previews, apply executes in order and fails on nonzero exit.

Clean breaking change — the prior config/integration API was not in real use.
@github-actions

Copy link
Copy Markdown
Contributor

PR Analysis Report

📚 Storybook Preview

View Storybook for this PR
GitHub Pages may take up to a minute to hydrate after deploy.

🧪 Sandbox Preview

View Sandbox for this PR
GitHub Pages may take up to a minute to hydrate after deploy.

No new or modified components detected.

Bundle Size Summary

Package Size (ESM) Size (CJS) Gzipped
@astryxdesign/core N/A 4.6KB 0B

Accessibility Audit

Status: No accessibility violations detected.


Generated by PR Enrichment workflow | Storybook | Sandbox | View full report

github-actions Bot added a commit that referenced this pull request Jun 30, 2026
@ejhammond ejhammond merged commit 434f023 into xds-unprefix-integration Jun 30, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Meta Open Source bot.

1 participant