Skip to content

feat(worktree): mirror Doppler scopes into worktrees automatically#50

Merged
mathix420 merged 1 commit into
masterfrom
doppler-first-class-integration
Jul 13, 2026
Merged

feat(worktree): mirror Doppler scopes into worktrees automatically#50
mathix420 merged 1 commit into
masterfrom
doppler-first-class-integration

Conversation

@mathix420

Copy link
Copy Markdown
Owner

Problem

Doppler binds project/config to absolute directory paths in ~/.doppler/.doppler.yaml, so a fresh git worktree starts unscoped and doppler run fails:

Doppler Error: You must specify a project
Doppler Error: The fallback file does not exist
error: script "dev" exited with code 1

Until now the fix was re-running doppler setup by hand in every single worktree.

What this does

New doppler.rs module reads all scopes via doppler configure --all --json and mirrors every scope under a project's main checkout to the rebased path inside the worktree — including per-subdirectory scopes in monorepos (e.g. <main>/apps/web<worktree>/apps/web), which env-var injection could not express. All writes go through the doppler CLI so we never fight its on-disk format.

Hooked in three places:

  • Worktree creation — mirrored right after the LLM-config copy, with a "Linked N Doppler scope(s)" step in the create modal, so the worktree works even outside alacritree.
  • First shell in a worktree — a lazy pass (once per worktree per app run) covers worktrees created outside alacritree that the create hook never saw.
  • Worktree deletion — drops the mirrored project/config options under the deleted path so the config file stops accumulating entries for dead paths.

Safety

  • Existing worktree scopes are never overwritten — a deliberate per-worktree doppler setup (different config, say dev vs dev_personal) survives.
  • Cleanup only unsets project/config; tokens and other options are preserved (doppler configure set merges and unset prunes only emptied entries — verified live against doppler v3.76.0).
  • No doppler binary installed → silent no-op everywhere.

Testing

  • 3 unit tests pin the scope-rebasing rules: root scope → worktree root, subdirectory rebase, and no false match of /repo-other against a /repo prefix (component-wise strip_prefix).
  • CLI semantics (--all --json shape, set merge, unset token preservation, parent-scope resolution) verified against a live doppler v3.76.0 using an isolated --config-dir.

🤖 Generated with Claude Code

Doppler binds project/config to absolute directory paths in
~/.doppler/.doppler.yaml, so a fresh worktree starts unscoped and
`doppler run` fails with "You must specify a project" until the user
re-runs `doppler setup` by hand.

Copy the main checkout's scopes (including per-subdirectory scopes in
monorepos) to the equivalent paths inside the worktree, via the doppler
CLI so we never fight its on-disk format:

- on worktree creation, with a progress step in the create modal
- on the first shell spawned in a worktree, covering worktrees created
  outside alacritree
- on worktree deletion, drop the project/config options again so the
  config file stops accumulating entries for dead paths (tokens and
  other options are preserved)

Existing worktree scopes are never overwritten, and a missing doppler
binary is a silent no-op.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@mathix420 mathix420 merged commit 8df8d3b into master Jul 13, 2026
2 checks passed
@mathix420 mathix420 deleted the doppler-first-class-integration branch July 13, 2026 09:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant