* feat(config,cli,tarball): support `offline` / `preferOffline` settings
Adds the two settings to `Config`, `pnpm-workspace.yaml` parsing, and
`pacquet install` as `--offline` / `--prefer-offline` flags. CLI
flags merge into Config (boolean OR) before leak, so any source
(yaml, CLI) flips `true` and never the other way.
Upstream pnpm gates the metadata-fetch path in [`pickPackage`](https://github.com/pnpm/pnpm/blob/94240bc046/resolving/npm-resolver/src/pickPackage.ts):
when `offline: true` and no cached metadata exists, it fails with
`ERR_PNPM_NO_OFFLINE_META`; `preferOffline: true` biases the resolver
toward the cached copy. Pacquet's frozen-install path has **no
metadata fetch** (the lockfile pins every resolution), so the
upstream flag is semantically a no-op on pacquet's current flow.
To make the flag actually useful for frozen installs, pacquet adds a
**tarball-side gate** (no upstream equivalent — pnpm doesn't gate
tarball downloads on `offline`): when both the warm prefetch and the
SQLite `index.db` lookup miss, the fetcher refuses the network and
errors with `ERR_PACQUET_NO_OFFLINE_TARBALL`. Same shape as
`ERR_PNPM_NO_OFFLINE_META`, scoped to tarballs because that's what
pacquet's frozen install needs network for. Documented as a pacquet-
specific divergence in the field's rustdoc.
`prefer_offline` is a no-op today — the warm prefetch +
`load_cached_cas_paths` already prefer the local store. The field
exists so `.npmrc` / yaml / CLI all parse cleanly; Stage 2's resolver
will honour it on the metadata path.
- `Config.offline` / `Config.prefer_offline`: bool, default `false`.
- `WorkspaceYaml.offline` / `WorkspaceYaml.prefer_offline`:
`Option<bool>`; applied via the existing `apply!` macro.
- `InstallArgs.offline` / `InstallArgs.prefer_offline`: bool CLI
flags; merged into Config in `cli_args.rs` between `config()` and
`State::init` (the brief window when `Config::leak` returns
`&'static mut Config`).
- `DownloadTarballToStore.offline` / `DownloadZipArchiveToStore.offline`:
bool fields. Wired through the three construction sites in
`package-manager`.
- `TarballError::NoOfflineTarball { package_id, url }`: new variant.
`tarball_error_to_request_retry` updated for exhaustiveness;
`code: ERR_PACQUET_NO_OFFLINE_TARBALL` in the retry-logger
projection so a future surface that runs this error through the
retry path renders the right code.
- `offline_mode_skips_network_on_cache_miss` — `mockito` server with
`.expect(0)`; the offline gate must fire before the network is
touched. Asserts variant shape AND the diagnostic code (the code
is part of the user-facing surface).
- `offline_mode_still_uses_prefetched_cache` — same `.expect(0)`
guard but with a prefetched cache hit; pins that the prefetch
branch short-circuits *before* the offline check so warm installs
under `--offline` succeed.
Regression-catch verified: gating the gate behind `false &&` flipped
`offline_mode_skips_network_on_cache_miss` red with the wrong-variant
panic message. Reverted before commit.
All bulk-edit fixups (15 `DownloadTarballToStore` / `DownloadZipArchiveToStore`
literals in tests + micro-benchmark, 1 `Config` literal in package-
manager tests) get `offline: false` to match the prior implicit
default.
* docs(cli): pin pickPackage link to commit SHA (#513 review)
Per project guideline: upstream pnpm citations link to a specific
commit SHA (first 10 hex chars), not a branch name. Same SHA the
PR's rustdoc and commit body already use for the same file.
Resolves CodeRabbit review comment on `crates/cli/README.md`:
<https://github.com/pnpm/pacquet/pull/513#discussion_r3238182177>.
Frozen-install only: refuses network fetches; errors with ERR_PACQUET_NO_OFFLINE_TARBALL when a snapshot isn't cached. Stage 2 resolver will additionally gate metadata fetches like upstream's pickPackage.
✅
--prefer-offline
No-op on frozen-install (warm prefetch already prefers the local store). Reserved for Stage 2's resolver.