Debug and gap reports
Receive a record of each CLI run in apps that use your package, and handle the gap reports they send about it.Record runs with debug
Export a debug function from astryx.integration.mjs, and the CLI calls it once for each command run in an app that loads your package.
js// astryx.integration.mjsimport {appendFileSync} from 'node:fs';/** @param {import('@astryxdesign/cli/authoring').DebugEvent} event */export function debug(event) {if (event.outcome !== 'ok') {appendFileSync('acme-failed-runs.ndjson', JSON.stringify(event) + '\n');}}export default {components: './components',};
The event is a DebugEvent with command, outcome, exitCode, durationMs, error, and more, its values scrubbed (redacted: true). Every field is in astryx docs authoring.
Keep the function synchronous: the CLI calls it as the process exits and never waits for a promise. The app's own debug handler runs first, then yours. A handler that throws is skipped, and the command's output and exit code stay the same.
An app records every command only when its astryx.config names integrations or debug, as listing your package does. Otherwise your handler runs only for commands that load the app's project, such as component and docs, and not for --version or a mistyped command. In an app whose config names neither word, each of those commands also prints a warning on stderr.
debug is a named export, not a manifest field, so a CLI that does not know it ignores it and loads the rest of your manifest.
Turn off debug in an app
An app can refuse every integration's debug handler and keep its own. It sets inheritDebug in its package.json:
json{"astryx": {"inheritDebug": false}}
From then on, your handler no longer runs in that app.
Handle gap reports
Export a gapReport handler, and astryx gap-report in an app sends it each gap report, such as a missing component or variant. The handler files the report and returns a receipt.
js/** @type {import('@astryxdesign/cli/authoring').GapReportHandler} */export const gapReport = {audience: 'public',async handle(report, {signal}) {if (report.target.package !== '@acme/astryx-widgets') return {status: 'skipped'};const body = JSON.stringify(report);const response = await fetch('https://tracker.example.com/issues', {method: 'POST', body, signal});const {url} = await response.json();return {status: 'filed', url};},};
Every handler in the app gets every report, so check report.target.package and skip reports about other packages. The receipt status is one of:
| `status` | Meaning |
|---|---|
filed | You created or queued the report. Return url or message. |
routed_only | You point the caller to where to file it. url is required. |
skipped | You chose not to act, for example on a duplicate. |
The CLI waits 30 seconds, then aborts signal. A throw, a timeout, or an invalid receipt fails your delivery, and the command exits 1; the other handlers still run. Like debug, gapReport is a named export that older CLIs ignore.
Ask before filing in public
Set audience: 'public' when your handler writes somewhere the public can read. The CLI runs it only when the caller passes --confirm-public; an 'internal' handler always runs.
bashnpx astryx gap-report AcmeCarousel --category missing_variant --reason 'Need a vertical layout'
texthandlerType: integrationhandler: @acme/astryx-widgetsaudience: publicstatus: consent_requiredmessage: Rerun with --confirm-public to file this report.
With --confirm-public, the same delivery reads status: filed and shows your url. The report goes to the package named by --package, else the package that owns the component, else Core.
Fall back to issuesUrl
When the app has no gapReport handler at all, the CLI routes the report to the target package's issuesUrl from its manifest instead.
- A GitHub issues URL, such as
https://github.com/acme/widgets/issues, gets an issue filed with the GitHub CLI,gh, once the caller passes--confirm-public. - Any other URL comes back as a
routed_onlyreceipt for the caller to open. - With no
issuesUrl, the command fails:Package "@acme/astryx-widgets" provides neither a report handler nor an issues URL.
One handler anywhere in the app, from the app or from any package, turns the fallback off for every report. See astryx docs cli/commands/gap-report.