Documentation menu

Package and workspace model

Flog reads workspace membership from the root package.json workspaces array. The object form with a packages array is accepted for compatibility. Workspace paths are normalized to slash-separated paths and sorted before they enter the project model.

Supported workspace patterns use path-segment globs:

  • *, ?, and character classes match within one segment.
  • ** matches zero or more complete segments.
  • absolute paths, parent traversal, root selection, overlapping matches, and paths resolving outside the workspace through a symlink are rejected.

Discovery derives bounded traversal roots from the fixed prefix of each glob and prunes a directory as soon as no workspace pattern can match below it. A shallow declaration such as packages/* therefore inspects package directories but never generated descendants such as packages/core/lib. Recursive ** patterns continue to discover nested packages. .git, .rp, node_modules, and directory symlinks are never traversed.

An entry that vanishes while expanding a wildcard is revalidated and skipped before it becomes a workspace candidate. Once a candidate is confirmed, or when an exact workspace importer is declared, disappearance and missing or invalid package.json files remain errors rather than silently changing membership.

Workspace package names must be unique. Flog also accepts hierarchical local identifiers such as @primate/app/ts for application filtering, while registry dependency names retain normal npm scoped-name validation. When the workspace root is itself public, its package name must also differ from every workspace child. A private configuration root may share a name with a public child because it has no publication identity.

Dependency specifiers#

The shared model recognizes:

  • complete versions and npm-style SemVer ranges
  • npm dist-tags such as latest and next
  • npm: aliases, including scoped aliases and tagged aliases
  • workspace:*, workspace:^, and workspace:~
  • explicit workspace ranges such as workspace:^1.2.0

SemVer ranges support wildcards and partial versions, comparators, hyphen ranges, tilde ranges, caret ranges, AND by whitespace, and OR with ||. Prereleases follow npm's opt-in rule: a prerelease only matches a comparator set that includes a prerelease comparator with the same major, minor, and patch. Dist-tags are resolved through the registry's dist-tags map and pinned to the resulting exact version. Peer constraints must remain SemVer ranges because a peer provider is validated locally rather than selected from a registry tag.

Every workspace: dependency must name a discovered local package. Explicit ranges must match the local package version. The graph records dependency, development, optional, and peer edges and provides deterministic dependency-first traversal with field-aware cycle errors.