fix(cli): env-aware config, pull clobber guard, strict overlays, 409 hint

Four review fixes on the `pic` surface:

- `config --effective` gains `--env`: it now resolves through the same
  overlay as `plan`/`apply`, so the masked report targets the app those
  commands act on instead of silently reading the base slug's secrets.
- `pull` gains `--force` and refuses to overwrite an existing
  `picloud.toml` (and colliding `scripts/*.rhai`) without it — fail-fast
  before any network call or write, mirroring `init`.
- Overlays (`ManifestOverlay`/`OverlayApp`) get `deny_unknown_fields`: a
  `[[scripts]]`/`[[routes]]`/`[[triggers]]` table or a typo'd key in an
  overlay now errors loudly instead of being silently dropped. +unit test.
- `apply` 409 (StateMoved — the only 409 the endpoint emits) surfaces an
  actionable hint (re-run `pic plan`, or `--force`) instead of a bare
  `HTTP 409`.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
MechaCat02
2026-06-24 19:06:45 +02:00
parent aa3995ae05
commit 345f265062
5 changed files with 76 additions and 6 deletions

View File

@@ -18,13 +18,21 @@ use crate::config;
use crate::manifest::Manifest;
use crate::output::{OutputMode, Table};
pub async fn run(manifest_path: &Path, effective: bool, mode: OutputMode) -> Result<()> {
pub async fn run(
manifest_path: &Path,
effective: bool,
env: Option<&str>,
mode: OutputMode,
) -> Result<()> {
if !effective {
bail!("`pic config` currently supports only `--effective`");
}
let creds = config::resolve()?;
let client = Client::from_creds(&creds)?;
let manifest = Manifest::load(manifest_path)?;
// Resolve against the same env overlay as `pic plan`/`apply` so the
// masked report targets the app those commands would act on — not the
// base slug — when an overlay re-points slug/secrets.
let manifest = Manifest::load_with_env(manifest_path, env)?;
let declared: BTreeSet<String> = manifest.secrets.names.iter().cloned().collect();
let on_server: BTreeSet<String> = client