Skip to content

(v1) CLI managed preset blocks (preset apply / remove, markers, --preset) #1478

Description

@yamcodes

Problem

Hosting preset keys are mixed into generated/mutated schemas with no clear ownership boundary. Re-applying or updating a preset is ambiguous, and Day-2 mutation (add host) does not share the same safety model as bootstrap (init). Naming is still host-specific (--host-preset, add host) even though the product direction is a generic preset surface (see #1447decided here).

Decision summary (resolves #1447)

Generalize the CLI surface to presets now; keep the v1 catalog hosts-only (vercel, netlify). Non-host packs (Supabase, Sentry, etc.) are follow-ups once this plumbing ships.

Surface Canonical Notes
Bootstrap flag init --preset <id> Replace/alias --host-preset / -H
Apply / refresh arkenv preset apply <provider> Idempotent; nuke-and-pave owned blocks
Remove arkenv preset remove <provider> Deletes owned blocks + related .env.example keys when safe
Legacy arkenv add host Deprecated alias → preset apply

init bootstraps an ArkEnv project (and may seed managed preset blocks + persist schema entry). Day-2 preset lifecycle does not ride init.

Desired behavior

Managed blocks

Preset-owned schema text is delimited by comments:

// @arkenv-preset-start vercel
// ...
// @arkenv-preset-end vercel
  • Flat layout: one block per preset id (vercel).
  • Strict layout: role-suffixed blocks as needed, e.g. vercel:server, vercel:client. User runs preset apply vercel / remove vercel; the CLI manages all blocks for that base id.
  • Refresh: nuke-and-pave everything between matching markers.
  • Composability: multiple presets may stack (one owned region set each) as long as keys do not collide.

Ownership & collisions (fail closed)

  • Outside markers = user-owned. Sacred.
  • If preset apply needs a key that already exists outside this preset’s blocks → fail with a clear resolution message (no silent skip, no AST “definition match”, no steal).
  • Cross-preset key collision → fail the same way.
  • Legacy unmarked keys (from older init / add host): also fail closed. User deletes unmarked keys, then re-runs apply. No heuristic adoption.

.env / .env.example

  • Append missing keys to .env.example only if that file already exists.
  • Never write .env (secrets). Future --write-env is out of scope.
  • On remove: strip keys that preset owned from .env.example when ownership is clear; if cross-preset sharing of an example key is unclear, leave a stale empty key rather than risk breaking another preset.

Discovery

  • init persists an arkenv schema entry/root (including layout strategy) on the nearest package.json — not merely a single file path (must support flat and strict).
  • preset apply / remove read that pointer for zero-config Day 2.
  • Override with -f / --file (or equivalent schema path flag).
  • No path heuristics as the primary strategy for v1.

Git safety

  • Require a clean git working tree by default for preset apply / preset remove (and any writes they perform).
  • Bypass with --force.
  • Not a git repo → proceed. Unknown status → warn and proceed.

Malformed markers

  • If start/end markers are missing, unbalanced, or otherwise malformed → fail closed (especially on remove). Do not delete past an unmatched start marker.

Scope boundaries

  • preset apply / preset remove do not touch .gitignore or provider-specific dotfiles (.vercel, .netlify, …). Baseline .env ignores remain init-only.
  • v1 catalog: vercel, netlify only (plus any already-approved host ids if already in tree). No new SaaS/observability packs in this issue.
  • Does not require inventing a semantic validator AST differ across Zod / Valibot / ArkType.
  • preset remove does not remove the package.json arkenv workspace pointer.

Acceptance criteria

  • arkenv preset apply <provider> inserts or refreshes managed comment blocks for the provider (nuke-and-pave inside markers).
  • arkenv preset remove <provider> removes all blocks for that base id (including :server / :client suffixes) and updates .env.example per the rules above.
  • init --preset <id> seeds managed blocks and writes the package.json arkenv schema entry/root; --host-preset / -H remain as aliases or are clearly deprecated toward --preset.
  • arkenv add host remains as a deprecated alias of preset apply (or documented migration) without a second divergent code path long-term.
  • Multiple presets can coexist; key collisions (user-owned or cross-preset) fail closed with actionable errors.
  • Legacy unmarked colliding keys fail closed (no auto-adopt).
  • .env.example: append missing keys only if file exists; never touch .env.
  • Discovery uses package.json arkenv entry; -f overrides; no heuristics-first discovery.
  • Dirty git tree aborts apply/remove unless --force; non-repo OK; unknown warns.
  • Malformed/unbalanced markers → fail closed on remove (and apply when relevant).
  • Strict layout uses role-suffixed markers; flat uses unsuffixed id.
  • Docs updated for hosting presets / CLI: new commands, markers, collisions, git gate, scope vs init.
  • ArkEnv agent skill updated: document preset apply / preset remove, fail-closed collisions, and legacy unmarked→marked migration guidance. Skill reasons and prepares; CLI remains the authority for owned-region mutation (do not teach agents to bypass fail-closed apply).
  • Tests cover apply, refresh, remove, collisions, legacy unmarked failure, git gate, strict vs flat markers, .env.example append-only.
  • (v1) Generalize CLI --host-preset to --preset #1447 closed as decided by this issue.

Agent skill boundary

Judgment-heavy work (especially migrating legacy unmarked preset keys to managed blocks, and collision triage) may be guided by the ArkEnv agent skill. The skill interprets CLI refusals and proposes safe next steps; it must not become a soft auto-adopt path that rewrites user-owned unmarked keys. Deterministic apply/remove/git gates stay in the CLI.

Out of scope

  • Non-host preset catalogs (Supabase, Sentry, Stripe, …)
  • Writing .env / --write-env
  • .gitignore mutation from apply/remove
  • Heuristic adoption of unmarked legacy keys
  • Comment-preserving AST merge inside managed blocks
  • Forcing users from strict → flat layout

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    @arkenv/cliIssues or Pull Requests involving the ArkEnv CLIenhancementNew feature or improvementready for agentFully specified, ready for immediate implementation

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions