# Astryx CLI Discover Command Component Resolution Algorithm

> Explore the component resolution algorithm in Astryx CLI's discover command. Learn how it scans workspace packages and routes queries for efficient package lists, docs, and search results.

- Repository: [Meta/astryx](https://github.com/facebook/astryx)
- Tags: internals
- Published: 2026-08-04

---

**The Astryx CLI's `discover` command resolves components by scanning workspace packages via package.json metadata, then routing queries through a dispatcher-leaf architecture to return package lists, component documentation, or search results.**

The `discover` command serves as the entry point for exploring external Astryx packages and their exported components. According to the source code in `packages/cli/api/discover/discover.mjs`, the component resolution algorithm follows a systematic discovery-and-route pattern that separates package detection from query-specific retrieval logic.

## How the Discover Command Works

### Phase 1: External Package Discovery

The resolution process begins with `discoverPackages()`—implemented in `packages/cli/api/discover/_adapter.mjs`. This function scans the workspace for Astryx-compatible packages by:

- Reading the [`package.json`](https://github.com/facebook/astryx/blob/main/package.json) of each workspace package
- Identifying packages that contain an `astryx` field
- Recognizing packages that export `@astryxdesign/*` entry points
- Recording package names and their component source directory locations

If `discoverPackages()` returns an empty list, the command immediately returns the **list leaf** with an empty result set and a `configured: false` flag, maintaining backward compatibility with the legacy flat command behavior.

### Phase 2: Query Routing and Component Resolution

The `discover` dispatcher in `packages/cli/api/discover/discover.mjs` analyzes the query shape and delegates to specialized leaf modules:

| Query Pattern | Destination Leaf | Resolution Behavior |
|-------------|----------------|-------------------|
| No query provided | `list` | Returns catalog of all discovered packages |
| `@scope/name` (single slash) | `detail` | Returns package-level metadata |
| `@scope/name/Component` (second slash) | `doc` | Resolves component source directory and returns documentation |
| Free-text string | `search` | Performs full-text search across all packages |

### Scoped Package + Component Resolution Path

The most complex resolution occurs for component-specific queries. When the dispatcher detects a second slash in a scoped query:

1. **Package isolation**: The segment before the second slash (`@scope/name`) is extracted as the package identifier
2. **Component identification**: The segment after the second slash (`Component`) is treated as the component name
3. **Leaf delegation**: The dispatcher calls `doc(packages, pkgName, compName, {lang, zh})` in `packages/cli/api/discover/detail/doc/doc.mjs`
4. **Source file resolution**: The **doc leaf** locates the component's directory, which must contain:
   - An entry point ([`index.ts`](https://github.com/facebook/astryx/blob/main/index.ts) or [`index.js`](https://github.com/facebook/astryx/blob/main/index.js))
   - A documentation file (`{Component}.doc.mjs`)
5. **Documentation extraction**: The leaf returns the parsed documentation object containing component props, examples, and metadata

### Error Contract

If the `query` parameter is not a string, the dispatcher throws an `AstryxError` with code `ERR_INVALID_ARGUMENT`. This maintains type safety and provides predictable error handling for programmatic consumers.

## File Structure and Implementation Details

The discover command's architecture separates concerns across multiple modules under `packages/cli/api/discover/`:

- **`discover.mjs`** – Main dispatcher; implements package discovery call and query routing logic
- **`_adapter.mjs`** – Workspace scanner; implements `discoverPackages()` for external package detection
- **`list/list.mjs`** – Leaf module for package catalog retrieval
- **`detail/detail.mjs`** – Leaf module for package metadata
- **`detail/doc/doc.mjs`** – Leaf module for component documentation resolution
- **`search/search.mjs`** – Leaf module for full-text search across packages

## Code Examples

List all external Astryx packages in your workspace:

```bash
astryx discover

```

Retrieve metadata for a specific package:

```bash
astryx discover @myorg/ui

```

Resolve and display component documentation (triggers component source file resolution):

```bash
astryx discover @myorg/ui/Button

```

Search for components across all discovered packages:

```bash
astryx discover "date picker"

```

## Key Design Characteristics

- **Declarative package registration**: Packages opt into discovery via the `astryx` field in [`package.json`](https://github.com/facebook/astryx/blob/main/package.json), not filesystem conventions alone
- **Strict query parsing**: The double-slash pattern (`@scope/pkg/Component`) provides unambiguous component addressing
- **Leaf-based extensibility**: New query patterns can be supported by adding leaf modules without modifying the core dispatcher
- **Workspace-scoped discovery**: Resolution is limited to packages visible in the current workspace, not global installations

## Summary

- The **Astryx CLI discover command** uses a two-phase resolution algorithm: first discovering external packages via [`package.json`](https://github.com/facebook/astryx/blob/main/package.json) metadata, then routing queries to specialized leaf modules
- **Component resolution** for queries like `@scope/pkg/Component` delegates to the **doc leaf**, which locates the component's source directory and extracts documentation from `{Component}.doc.mjs` files
- **Package discovery** is implemented in `_adapter.mjs` and relies on the `astryx` field or `@astryxdesign/*` entry points for registration
- The **dispatcher-leaf architecture** separates package detection from query handling, enabling modular extensions for list, detail, doc, and search operations

## Frequently Asked Questions

### How does Astryx CLI know which packages to include in discovery?

The `discoverPackages()` function in `packages/cli/api/discover/_adapter.mjs` scans workspace package.json files and selects those containing an `astryx` configuration field or exporting `@astryxdesign/*` entry points. This declarative approach ensures only explicitly registered packages appear in discovery results.

### What happens if I query a component that doesn't exist?

If the doc leaf cannot locate the component directory or its `.doc.mjs` file for the requested component name, it returns an appropriate error response. The dispatcher does not perform fuzzy matching for component names—queries must match the exact exported component identifier.

### Can I use the discover command without a workspace configuration?

Running `astryx discover` in a workspace with no Astryx-registered packages returns an empty list via the list leaf with `configured: false`. The command does not fail—instead, it signals that no external packages were detected, allowing users to verify their workspace setup before adding dependencies.