Dashboard › craft › Distillation
0ff62e73-15df-4dcd-8d7b-afe9ed54d874["lore_tm_v1_oO9ywKexLyv9f4HuSrGb5osTpbRhTb2smtdAKlej-tg","lore_tm_v1_ER7s6nUrJ2t0LXliG5ye3Mddf9xFwJJwHwMtAOH0Pgg","lore_tm_v1_XWF0WMMBd2dWUVkyyGGrUqbrtlxijk0FEwHWqtKKodw","lore_tm_v1_6cwKp1s2szVXHFIhjHPy5SmSm0i4F902DdyFlxikNBY","lore_tm_v1_ZIvjt0elG41VgQb5bJyN5j1XQu34rA1J_2McIVnA-2M","lore_tm_v1_Ks8ajtZlwti57HPrwbWV0NIHDL4HGOV8V_3flTXsVvQ"]
Date: Aug 26, 2026
--workspace --dry-run must never be mistaken for a workspace name.src/utils/helpers.ts implements extractWorkspaceSelection(argv, env = process.env), which reads CRAFT_WORKSPACE, parses raw arguments with Node parseArgs({ options: { workspace: { type: 'string' } }, allowPositionals: true, strict: false, tokens: true }), and returns the final valid --workspace value or the environment value.extractWorkspaceSelection() supports both --workspace foo and --workspace=foo; the last workspace option occurrence decides. A bare/empty final --workspace clears any prior CLI value and falls back to CRAFT_WORKSPACE.extractWorkspaceSelection() accepts a dash-prefixed workspace only as an inline value (for example, --workspace=-foo); a separate following dash-prefixed token is rejected as a workspace value. The CLI takes precedence over CRAFT_WORKSPACE only when it contains a valid value.src/config.ts defines WORKSPACES_MIN_VERSION = '2.29.0'; dev builds such as 2.29.0-dev.0 satisfy this gate through checkMinimalConfigVersion prerelease relaxation.setActiveWorkspace(name) stores _activeWorkspaceName, clears _configCache and _globalGitHubConfigCache, and must run before configuration is first resolved so subsequent reads apply the new selection; getActiveWorkspace() returns the selected workspace or undefined.resolveWorkspaceConfig() requires the requested workspace name to be an own key of base.workspaces; otherwise it throws ConfigurationError naming the unknown workspace and listing available workspaces, or stating that none are defined.resolveWorkspaceConfig() shallowly overrides each defined workspace release-relevant field over the top-level config, strips workspaces and minVersion from the resolved result, does not deep-merge arrays/objects, and shallow-merges github so workspace projectPath can inherit base owner/repo.github merging, if the resulting object lacks owner or repo, resolveWorkspaceConfig() deletes resolved.github; this intentionally permits getGlobalGitHubConfig() to fall back to Git remote detection instead of treating an incomplete GitHub object as configured.applyWorkspaceSelection() behavior: no configured workspaces plus no selection returns config unchanged; selected workspace without configured workspaces throws; configured workspaces without explicit selection throws and lists available names; both present require minVersion >= 2.29.0 and return the merged workspace config.getGlobalGitHubConfig(clearCache = false) reads the active resolved config’s github block; absent config, it creates a Git client at the config directory (or .), selects origin or the first remote, and derives { owner, repo } only from a github.com remote. It caches a frozen config or null; cached null throws ConfigurationError.getGitTagPrefix() uses the first github target’s tagPrefix from the active configuration. If multiple GitHub targets have differing prefixes, it warns and still returns the first; for independently versioned monorepo products it advises one top-level workspaces entry per product, or separate .craft.yml files, each with one GitHub target and its own tagPrefix.